From: Tobias Brunner Date: Tue, 30 Apr 2024 09:39:00 +0000 (+0200) Subject: kernel-netlink: Add SA direction attribute X-Git-Tag: 6.0.0rc1~58^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=661f6bd0ad9eee61968c30652b4c707c1779b3f5;p=thirdparty%2Fstrongswan.git kernel-netlink: Add SA direction attribute --- diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c b/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c index 493a22910a..88734b0dab 100644 --- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c +++ b/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c @@ -1187,6 +1187,112 @@ METHOD(kernel_ipsec_t, get_features, kernel_feature_t, (this->sa_lastused ? KERNEL_SA_USE_TIME : 0); } +/** + * Format the mark for debug messages + */ +static void format_mark(char *buf, int buflen, mark_t mark) +{ + if (mark.value | mark.mask) + { + snprintf(buf, buflen, " (mark %u/0x%08x)", mark.value, mark.mask); + } +} + +/** + * Add a XFRM mark to message if required + */ +static bool add_mark(struct nlmsghdr *hdr, int buflen, mark_t mark) +{ + if (mark.value | mark.mask) + { + struct xfrm_mark *xmrk; + + xmrk = netlink_reserve(hdr, buflen, XFRMA_MARK, sizeof(*xmrk)); + if (!xmrk) + { + return FALSE; + } + xmrk->v = mark.value; + xmrk->m = mark.mask; + } + return TRUE; +} + +/** + * Format the security label for debug messages + */ +static void format_label(char *buf, int buflen, sec_label_t *label) +{ + if (label) + { + snprintf(buf, buflen, " (ctx %s)", label->get_string(label)); + } +} + +/** + * Add a security label to message if required + */ +static bool add_label(struct nlmsghdr *hdr, int buflen, sec_label_t *label) +{ + if (label) + { +#ifdef USE_SELINUX + struct xfrm_user_sec_ctx *ctx; + chunk_t enc = label->get_encoding(label); + int len = sizeof(*ctx) + enc.len; + + ctx = netlink_reserve(hdr, buflen, XFRMA_SEC_CTX, len); + if (!ctx) + { + return FALSE; + } + /* this attribute for some reason duplicates the generic header */ + ctx->exttype = XFRMA_SEC_CTX; + ctx->len = len; + + ctx->ctx_doi = XFRM_SC_DOI_LSM; + ctx->ctx_alg = XFRM_SC_ALG_SELINUX; + ctx->ctx_len = enc.len; + memcpy((void*)(ctx + 1), enc.ptr, enc.len); +#endif + } + return TRUE; +} + +/** + * Add a uint32 attribute to message + */ +static bool add_uint32(struct nlmsghdr *hdr, int buflen, + enum xfrm_attr_type_t type, uint32_t value) +{ + uint32_t *xvalue; + + xvalue = netlink_reserve(hdr, buflen, type, sizeof(*xvalue)); + if (!xvalue) + { + return FALSE; + } + *xvalue = value; + return TRUE; +} + +/** + * Add a uint8 attribute to message + */ +static bool add_uint8(struct nlmsghdr *hdr, int buflen, + enum xfrm_attr_type_t type, uint8_t value) +{ + uint8_t *xvalue; + + xvalue = netlink_reserve(hdr, buflen, type, sizeof(*xvalue)); + if (!xvalue) + { + return FALSE; + } + *xvalue = value; + return TRUE; +} + /** * Get an SPI for a specific protocol from the kernel. */ @@ -1216,6 +1322,11 @@ static status_t get_spi_internal(private_kernel_netlink_ipsec_t *this, userspi->min = min; userspi->max = max; + if (!add_uint8(hdr, sizeof(request), XFRMA_SA_DIR, XFRM_SA_DIR_IN)) + { + return FAILED; + } + if (this->socket_xfrm->send(this->socket_xfrm, hdr, &out, &len) == SUCCESS) { hdr = out; @@ -1295,95 +1406,6 @@ METHOD(kernel_ipsec_t, get_cpi, status_t, return SUCCESS; } -/** - * Format the mark for debug messages - */ -static void format_mark(char *buf, int buflen, mark_t mark) -{ - if (mark.value | mark.mask) - { - snprintf(buf, buflen, " (mark %u/0x%08x)", mark.value, mark.mask); - } -} - -/** - * Add a XFRM mark to message if required - */ -static bool add_mark(struct nlmsghdr *hdr, int buflen, mark_t mark) -{ - if (mark.value | mark.mask) - { - struct xfrm_mark *xmrk; - - xmrk = netlink_reserve(hdr, buflen, XFRMA_MARK, sizeof(*xmrk)); - if (!xmrk) - { - return FALSE; - } - xmrk->v = mark.value; - xmrk->m = mark.mask; - } - return TRUE; -} - -/** - * Format the security label for debug messages - */ -static void format_label(char *buf, int buflen, sec_label_t *label) -{ - if (label) - { - snprintf(buf, buflen, " (ctx %s)", label->get_string(label)); - } -} - -/** - * Add a security label to message if required - */ -static bool add_label(struct nlmsghdr *hdr, int buflen, sec_label_t *label) -{ - if (label) - { -#ifdef USE_SELINUX - struct xfrm_user_sec_ctx *ctx; - chunk_t enc = label->get_encoding(label); - int len = sizeof(*ctx) + enc.len; - - ctx = netlink_reserve(hdr, buflen, XFRMA_SEC_CTX, len); - if (!ctx) - { - return FALSE; - } - /* this attribute for some reason duplicates the generic header */ - ctx->exttype = XFRMA_SEC_CTX; - ctx->len = len; - - ctx->ctx_doi = XFRM_SC_DOI_LSM; - ctx->ctx_alg = XFRM_SC_ALG_SELINUX; - ctx->ctx_len = enc.len; - memcpy((void*)(ctx + 1), enc.ptr, enc.len); -#endif - } - return TRUE; -} - -/** - * Add a uint32 attribute to message - */ -static bool add_uint32(struct nlmsghdr *hdr, int buflen, - enum xfrm_attr_type_t type, uint32_t value) -{ - uint32_t *xvalue; - - xvalue = netlink_reserve(hdr, buflen, type, sizeof(*xvalue)); - if (!xvalue) - { - return FALSE; - } - *xvalue = value; - return TRUE; -} - /* ETHTOOL_GSSET_INFO is available since 2.6.34 and ETH_SS_FEATURES (enum) and * ETHTOOL_GFEATURES since 2.6.39, so check for the latter */ #ifdef ETHTOOL_GFEATURES @@ -2046,6 +2068,12 @@ METHOD(kernel_ipsec_t, add_sa, status_t, } } + if (!add_uint8(hdr, sizeof(request), XFRMA_SA_DIR, + data->inbound ? XFRM_SA_DIR_IN : XFRM_SA_DIR_OUT)) + { + goto failed; + } + if (id->proto != IPPROTO_COMP) { /* generally, we don't need a replay window for outbound SAs, however,