diff --git a/.gitignore b/.gitignore index 7de58d2..bb24871 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -libnftnl-1.2.8.tar.xz +libnftnl-1.3.0.tar.xz diff --git a/0001-set-Fix-for-array-overrun-when-setting-NFTNL_SET_DES.patch b/0001-set-Fix-for-array-overrun-when-setting-NFTNL_SET_DES.patch deleted file mode 100644 index 58facdb..0000000 --- a/0001-set-Fix-for-array-overrun-when-setting-NFTNL_SET_DES.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 73e56f12f39cf114532eb37119ac84865ffd71fd Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Wed, 4 Dec 2024 16:20:16 +0100 -Subject: [PATCH] set: Fix for array overrun when setting NFTNL_SET_DESC_CONCAT - -JIRA: https://issues.redhat.com/browse/RHEL-34697 -Upstream Status: libnftnl commit 7cb2a63d67af14576988631e916404592f261fd4 - -commit 7cb2a63d67af14576988631e916404592f261fd4 -Author: Phil Sutter -Date: Wed Nov 27 16:30:08 2024 +0100 - - set: Fix for array overrun when setting NFTNL_SET_DESC_CONCAT - - Assuming max data_len of 16 * 4B and no zero bytes in 'data': - The while loop will increment field_count, use it as index for the - field_len array and afterwards make sure it hasn't increased to - NFT_REG32_COUNT. Thus a value of NFT_REG32_COUNT - 1 (= 15) will pass - the check, get incremented to 16 and used as index to the 16 fields long - array. - Use a less fancy for-loop to avoid the increment vs. check problem. - - Fixes: 407f616ea5318 ("set: buffer overflow in NFTNL_SET_DESC_CONCAT setter") - Signed-off-by: Phil Sutter - Reviewed-by: Pablo Neira Ayuso - -Signed-off-by: Phil Sutter ---- - src/set.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/src/set.c b/src/set.c -index 75ad64e..e9048e0 100644 ---- a/src/set.c -+++ b/src/set.c -@@ -189,8 +189,10 @@ int nftnl_set_set_data(struct nftnl_set *s, uint16_t attr, const void *data, - return -1; - - memcpy(&s->desc.field_len, data, data_len); -- while (s->desc.field_len[++s->desc.field_count]) { -- if (s->desc.field_count >= NFT_REG32_COUNT) -+ for (s->desc.field_count = 0; -+ s->desc.field_count < NFT_REG32_COUNT; -+ s->desc.field_count++) { -+ if (!s->desc.field_len[s->desc.field_count]) - break; - } - break; diff --git a/0003-udata-Introduce-NFTNL_UDATA_TABLE_NFT-VER-BLD.patch b/0001-udata-Introduce-NFTNL_UDATA_TABLE_NFT-VER-BLD.patch similarity index 94% rename from 0003-udata-Introduce-NFTNL_UDATA_TABLE_NFT-VER-BLD.patch rename to 0001-udata-Introduce-NFTNL_UDATA_TABLE_NFT-VER-BLD.patch index 61e3591..49c19ef 100644 --- a/0003-udata-Introduce-NFTNL_UDATA_TABLE_NFT-VER-BLD.patch +++ b/0001-udata-Introduce-NFTNL_UDATA_TABLE_NFT-VER-BLD.patch @@ -1,4 +1,4 @@ -From 775bf5eba066f61c7737d6995f276765f76328d9 Mon Sep 17 00:00:00 2001 +From 143387be5e15b030381df3ab3970cbc66c35cd48 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Wed, 10 Sep 2025 17:29:07 +0200 Subject: [PATCH] udata: Introduce NFTNL_UDATA_TABLE_NFT{VER,BLD} diff --git a/0002-trace-add-support-for-TRACE_CT-information.patch b/0002-trace-add-support-for-TRACE_CT-information.patch deleted file mode 100644 index f6e2db2..0000000 --- a/0002-trace-add-support-for-TRACE_CT-information.patch +++ /dev/null @@ -1,153 +0,0 @@ -From 486a9c5ed53e3f1bea1bc4b8668eefa9453e1aa8 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Tue, 15 Jul 2025 20:42:30 +0200 -Subject: [PATCH] trace: add support for TRACE_CT information - -JIRA: https://issues.redhat.com/browse/RHEL-103864 -Upstream Status: libnftnl commit 56e37303ed30a4f9b73ec1f90b53da7dda645748 - -commit 56e37303ed30a4f9b73ec1f90b53da7dda645748 -Author: Florian Westphal -Date: Thu May 22 15:51:15 2025 +0200 - - trace: add support for TRACE_CT information - - Decode direction/id/state/status information. - This will be used by 'nftables monitor trace' to print a packets - conntrack state. - - Signed-off-by: Florian Westphal - Reviewed-by: Pablo Neira Ayuso - -Signed-off-by: Phil Sutter ---- - include/libnftnl/trace.h | 4 +++ - include/linux/netfilter/nf_tables.h | 8 +++++ - src/trace.c | 46 +++++++++++++++++++++++++++++ - 3 files changed, 58 insertions(+) - -diff --git a/include/libnftnl/trace.h b/include/libnftnl/trace.h -index 18ab0c3..5d66b50 100644 ---- a/include/libnftnl/trace.h -+++ b/include/libnftnl/trace.h -@@ -28,6 +28,10 @@ enum nftnl_trace_attr { - NFTNL_TRACE_VERDICT, - NFTNL_TRACE_NFPROTO, - NFTNL_TRACE_POLICY, -+ NFTNL_TRACE_CT_DIRECTION, -+ NFTNL_TRACE_CT_ID, -+ NFTNL_TRACE_CT_STATE, -+ NFTNL_TRACE_CT_STATUS, - __NFTNL_TRACE_MAX, - }; - #define NFTNL_TRACE_MAX (__NFTNL_TRACE_MAX - 1) -diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h -index c48b193..2c9f833 100644 ---- a/include/linux/netfilter/nf_tables.h -+++ b/include/linux/netfilter/nf_tables.h -@@ -1797,6 +1797,10 @@ enum nft_xfrm_keys { - * @NFTA_TRACE_MARK: nfmark (NLA_U32) - * @NFTA_TRACE_NFPROTO: nf protocol processed (NLA_U32) - * @NFTA_TRACE_POLICY: policy that decided fate of packet (NLA_U32) -+ * @NFTA_TRACE_CT_ID: conntrack id (NLA_U32) -+ * @NFTA_TRACE_CT_DIRECTION: packets direction (NLA_U8) -+ * @NFTA_TRACE_CT_STATUS: conntrack status (NLA_U32) -+ * @NFTA_TRACE_CT_STATE: packet state (new, established, ...) (NLA_U32) - */ - enum nft_trace_attributes { - NFTA_TRACE_UNSPEC, -@@ -1817,6 +1821,10 @@ enum nft_trace_attributes { - NFTA_TRACE_NFPROTO, - NFTA_TRACE_POLICY, - NFTA_TRACE_PAD, -+ NFTA_TRACE_CT_ID, -+ NFTA_TRACE_CT_DIRECTION, -+ NFTA_TRACE_CT_STATUS, -+ NFTA_TRACE_CT_STATE, - __NFTA_TRACE_MAX - }; - #define NFTA_TRACE_MAX (__NFTA_TRACE_MAX - 1) -diff --git a/src/trace.c b/src/trace.c -index f426437..26bf8d7 100644 ---- a/src/trace.c -+++ b/src/trace.c -@@ -48,6 +48,12 @@ struct nftnl_trace { - uint32_t policy; - uint16_t iiftype; - uint16_t oiftype; -+ struct { -+ uint16_t dir; -+ uint32_t id; -+ uint32_t state; -+ uint32_t status; -+ } ct; - - uint32_t flags; - }; -@@ -92,6 +98,10 @@ static int nftnl_trace_parse_attr_cb(const struct nlattr *attr, void *data) - if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0) - abi_breakage(); - break; -+ case NFTA_TRACE_CT_DIRECTION: -+ if (mnl_attr_validate(attr, MNL_TYPE_U8) < 0) -+ abi_breakage(); -+ break; - case NFTA_TRACE_IIFTYPE: - case NFTA_TRACE_OIFTYPE: - if (mnl_attr_validate(attr, MNL_TYPE_U16) < 0) -@@ -104,6 +114,9 @@ static int nftnl_trace_parse_attr_cb(const struct nlattr *attr, void *data) - case NFTA_TRACE_POLICY: - case NFTA_TRACE_NFPROTO: - case NFTA_TRACE_TYPE: -+ case NFTA_TRACE_CT_ID: -+ case NFTA_TRACE_CT_STATE: -+ case NFTA_TRACE_CT_STATUS: - if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) - abi_breakage(); - break; -@@ -194,6 +207,18 @@ const void *nftnl_trace_get_data(const struct nftnl_trace *trace, - case NFTNL_TRACE_POLICY: - *data_len = sizeof(uint32_t); - return &trace->policy; -+ case NFTNL_TRACE_CT_DIRECTION: -+ *data_len = sizeof(uint16_t); -+ return &trace->ct.dir; -+ case NFTNL_TRACE_CT_ID: -+ *data_len = sizeof(uint32_t); -+ return &trace->ct.id; -+ case NFTNL_TRACE_CT_STATE: -+ *data_len = sizeof(uint32_t); -+ return &trace->ct.state; -+ case NFTNL_TRACE_CT_STATUS: -+ *data_len = sizeof(uint32_t); -+ return &trace->ct.status; - case __NFTNL_TRACE_MAX: - break; - } -@@ -423,5 +448,26 @@ int nftnl_trace_nlmsg_parse(const struct nlmsghdr *nlh, struct nftnl_trace *t) - t->flags |= (1 << NFTNL_TRACE_MARK); - } - -+ if (tb[NFTA_TRACE_CT_DIRECTION]) { -+ t->ct.dir = mnl_attr_get_u8(tb[NFTA_TRACE_CT_DIRECTION]); -+ t->flags |= (1 << NFTNL_TRACE_CT_DIRECTION); -+ } -+ -+ if (tb[NFTA_TRACE_CT_ID]) { -+ /* NFT_CT_ID is expected to be in big endian */ -+ t->ct.id = mnl_attr_get_u32(tb[NFTA_TRACE_CT_ID]); -+ t->flags |= (1 << NFTNL_TRACE_CT_ID); -+ } -+ -+ if (tb[NFTA_TRACE_CT_STATE]) { -+ t->ct.state = ntohl(mnl_attr_get_u32(tb[NFTA_TRACE_CT_STATE])); -+ t->flags |= (1 << NFTNL_TRACE_CT_STATE); -+ } -+ -+ if (tb[NFTA_TRACE_CT_STATUS]) { -+ t->ct.status = ntohl(mnl_attr_get_u32(tb[NFTA_TRACE_CT_STATUS])); -+ t->flags |= (1 << NFTNL_TRACE_CT_STATUS); -+ } -+ - return 0; - } diff --git a/0002-utils-Add-helpers-for-interface-name-wildcards.patch b/0002-utils-Add-helpers-for-interface-name-wildcards.patch new file mode 100644 index 0000000..6bf9528 --- /dev/null +++ b/0002-utils-Add-helpers-for-interface-name-wildcards.patch @@ -0,0 +1,181 @@ +From 34248b6810a186fb214d2fd4a7f047ee0b95818a Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 27 Nov 2025 10:57:03 +0100 +Subject: [PATCH] utils: Add helpers for interface name wildcards + +JIRA: https://issues.redhat.com/browse/RHEL-108860 +Upstream Status: libnftnl commit f30eae26d813e54897caa1def6501d662dd79228 + +commit f30eae26d813e54897caa1def6501d662dd79228 +Author: Phil Sutter +Date: Tue Oct 1 12:59:29 2024 +0200 + + utils: Add helpers for interface name wildcards + + Support simple (suffix) wildcards in NFTNL_{CHAIN,FLOWTABLE}_DEVICES + identified by NFTA_DEVICE_PREFIX attribute. Add helpers converting to + and from the human-readable asterisk-suffix notation. + + Signed-off-by: Phil Sutter + +Signed-off-by: Phil Sutter +--- + include/linux/netfilter/nf_tables.h | 2 ++ + include/utils.h | 5 ++++ + src/chain.c | 4 ++- + src/flowtable.c | 2 +- + src/str_array.c | 10 +++++--- + src/utils.c | 39 +++++++++++++++++++++++++++++ + 6 files changed, 57 insertions(+), 5 deletions(-) + +diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h +index 2beb30b..8e0eb83 100644 +--- a/include/linux/netfilter/nf_tables.h ++++ b/include/linux/netfilter/nf_tables.h +@@ -1784,10 +1784,12 @@ enum nft_synproxy_attributes { + * enum nft_device_attributes - nf_tables device netlink attributes + * + * @NFTA_DEVICE_NAME: name of this device (NLA_STRING) ++ * @NFTA_DEVICE_PREFIX: device name prefix, a simple wildcard (NLA_STRING) + */ + enum nft_devices_attributes { + NFTA_DEVICE_UNSPEC, + NFTA_DEVICE_NAME, ++ NFTA_DEVICE_PREFIX, + __NFTA_DEVICE_MAX + }; + #define NFTA_DEVICE_MAX (__NFTA_DEVICE_MAX - 1) +diff --git a/include/utils.h b/include/utils.h +index 247d99d..5a3379f 100644 +--- a/include/utils.h ++++ b/include/utils.h +@@ -83,4 +83,9 @@ int nftnl_fprintf(FILE *fpconst, const void *obj, uint32_t cmd, uint32_t type, + int nftnl_set_str_attr(const char **dptr, uint32_t *flags, + uint16_t attr, const void *data, uint32_t data_len); + ++struct nlattr; ++ ++void nftnl_attr_put_ifname(struct nlmsghdr *nlh, const char *ifname); ++char *nftnl_attr_get_ifname(const struct nlattr *attr); ++ + #endif +diff --git a/src/chain.c b/src/chain.c +index 895108c..8396114 100644 +--- a/src/chain.c ++++ b/src/chain.c +@@ -464,7 +464,7 @@ void nftnl_chain_nlmsg_build_payload(struct nlmsghdr *nlh, const struct nftnl_ch + + nest_dev = mnl_attr_nest_start(nlh, NFTA_HOOK_DEVS); + nftnl_str_array_foreach(dev, &c->dev_array, i) +- mnl_attr_put_strz(nlh, NFTA_DEVICE_NAME, dev); ++ nftnl_attr_put_ifname(nlh, dev); + mnl_attr_nest_end(nlh, nest_dev); + } + +@@ -648,6 +648,8 @@ static int nftnl_chain_parse_hook(struct nlattr *attr, struct nftnl_chain *c) + c->flags |= (1 << NFTNL_CHAIN_PRIO); + } + if (tb[NFTA_HOOK_DEV]) { ++ if (c->flags & (1 << NFTNL_CHAIN_DEV)) ++ xfree(c->dev); + c->dev = strdup(mnl_attr_get_str(tb[NFTA_HOOK_DEV])); + if (!c->dev) + return -1; +diff --git a/src/flowtable.c b/src/flowtable.c +index fbbe0a8..59991d6 100644 +--- a/src/flowtable.c ++++ b/src/flowtable.c +@@ -299,7 +299,7 @@ void nftnl_flowtable_nlmsg_build_payload(struct nlmsghdr *nlh, + + nest_dev = mnl_attr_nest_start(nlh, NFTA_FLOWTABLE_HOOK_DEVS); + nftnl_str_array_foreach(dev, &c->dev_array, i) +- mnl_attr_put_strz(nlh, NFTA_DEVICE_NAME, dev); ++ nftnl_attr_put_ifname(nlh, dev); + mnl_attr_nest_end(nlh, nest_dev); + } + +diff --git a/src/str_array.c b/src/str_array.c +index 5669c61..4292c98 100644 +--- a/src/str_array.c ++++ b/src/str_array.c +@@ -45,9 +45,13 @@ int nftnl_parse_devs(struct nftnl_str_array *sa, const struct nlattr *nest) + int len = 0; + + mnl_attr_for_each_nested(attr, nest) { +- if (mnl_attr_get_type(attr) != NFTA_DEVICE_NAME) ++ switch(mnl_attr_get_type(attr)) { ++ default: + return -1; +- len++; ++ case NFTA_DEVICE_NAME: ++ case NFTA_DEVICE_PREFIX: ++ len++; ++ } + } + + nftnl_str_array_clear(sa); +@@ -56,7 +60,7 @@ int nftnl_parse_devs(struct nftnl_str_array *sa, const struct nlattr *nest) + return -1; + + mnl_attr_for_each_nested(attr, nest) { +- sa->array[sa->len] = strdup(mnl_attr_get_str(attr)); ++ sa->array[sa->len] = nftnl_attr_get_ifname(attr); + if (!sa->array[sa->len]) { + nftnl_str_array_clear(sa); + return -1; +diff --git a/src/utils.c b/src/utils.c +index 5f2c5bf..c4bbd4f 100644 +--- a/src/utils.c ++++ b/src/utils.c +@@ -13,8 +13,11 @@ + #include + #include + ++#include ++ + #include + ++#include + #include + #include + +@@ -146,3 +149,39 @@ int nftnl_set_str_attr(const char **dptr, uint32_t *flags, + *flags |= (1 << attr); + return 0; + } ++ ++static bool is_wildcard_str(const char *str) ++{ ++ size_t len = strlen(str); ++ ++ if (len < 1 || str[len - 1] != '*') ++ return false; ++ if (len < 2 || str[len - 2] != '\\') ++ return true; ++ /* XXX: ignore backslash escaping for now */ ++ return false; ++} ++ ++void nftnl_attr_put_ifname(struct nlmsghdr *nlh, const char *ifname) ++{ ++ uint16_t attr = is_wildcard_str(ifname) ? ++ NFTA_DEVICE_PREFIX : NFTA_DEVICE_NAME; ++ ++ mnl_attr_put_strz(nlh, attr, ifname); ++} ++ ++char *nftnl_attr_get_ifname(const struct nlattr *attr) ++{ ++ const char *dev = mnl_attr_get_str(attr); ++ char buf[IFNAMSIZ]; ++ ++ switch (mnl_attr_get_type(attr)) { ++ case NFTA_DEVICE_NAME: ++ return strdup(dev); ++ case NFTA_DEVICE_PREFIX: ++ snprintf(buf, IFNAMSIZ, "%s*", dev); ++ return strdup(buf); ++ default: ++ return NULL; ++ } ++} diff --git a/0003-utils-Drop-asterisk-from-end-of-NFTA_DEVICE_PREFIX-s.patch b/0003-utils-Drop-asterisk-from-end-of-NFTA_DEVICE_PREFIX-s.patch new file mode 100644 index 0000000..e1951b6 --- /dev/null +++ b/0003-utils-Drop-asterisk-from-end-of-NFTA_DEVICE_PREFIX-s.patch @@ -0,0 +1,49 @@ +From 5282d94c17c8fd08229687639d5c5f48c7bc1fc5 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 27 Nov 2025 10:57:03 +0100 +Subject: [PATCH] utils: Drop asterisk from end of NFTA_DEVICE_PREFIX strings + +JIRA: https://issues.redhat.com/browse/RHEL-108860 +Upstream Status: libnftnl commit 6f24a13a19b8690444564f50e1866fae5abf7687 + +commit 6f24a13a19b8690444564f50e1866fae5abf7687 +Author: Phil Sutter +Date: Tue Oct 7 17:45:25 2025 +0200 + + utils: Drop asterisk from end of NFTA_DEVICE_PREFIX strings + + The asterisk left in place becomes part of the prefix by accident and is thus + both included when matching interface names as well as dumped back to user + space. + + Fixes: f30eae26d813e ("utils: Add helpers for interface name wildcards") + Signed-off-by: Phil Sutter + +Signed-off-by: Phil Sutter +--- + src/utils.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/src/utils.c b/src/utils.c +index c4bbd4f..d73c5f6 100644 +--- a/src/utils.c ++++ b/src/utils.c +@@ -164,9 +164,16 @@ static bool is_wildcard_str(const char *str) + + void nftnl_attr_put_ifname(struct nlmsghdr *nlh, const char *ifname) + { +- uint16_t attr = is_wildcard_str(ifname) ? +- NFTA_DEVICE_PREFIX : NFTA_DEVICE_NAME; ++ uint16_t attr = NFTA_DEVICE_NAME; ++ char pfx[IFNAMSIZ]; + ++ if (is_wildcard_str(ifname)) { ++ snprintf(pfx, IFNAMSIZ, "%s", ifname); ++ pfx[strlen(pfx) - 1] = '\0'; ++ ++ attr = NFTA_DEVICE_PREFIX; ++ ifname = pfx; ++ } + mnl_attr_put_strz(nlh, attr, ifname); + } + diff --git a/0004-set_elem-Review-debug-output.patch b/0004-set_elem-Review-debug-output.patch new file mode 100644 index 0000000..730850a --- /dev/null +++ b/0004-set_elem-Review-debug-output.patch @@ -0,0 +1,78 @@ +From e0bf0507725f8a778094eac30e51328b6a0ff059 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 24 Feb 2026 15:05:32 +0100 +Subject: [PATCH] set_elem: Review debug output + +JIRA: https://issues.redhat.com/browse/RHEL-119650 +Upstream Status: libnftnl commit 5f72061e6e34328ad40e0f1ffd2b8188356bd5f9 + +commit 5f72061e6e34328ad40e0f1ffd2b8188356bd5f9 +Author: Phil Sutter +Date: Wed Sep 10 16:22:21 2025 +0200 + + set_elem: Review debug output + + * Do not print a colon if no data part is present + * Include the object's name for objmap elements + * Print flags only if non-zero, but prefixed by 'flags' keyword to avoid + confusion with data values + + Signed-off-by: Phil Sutter + +Signed-off-by: Phil Sutter +--- + src/set_elem.c | 31 +++++++++++++++++++++---------- + 1 file changed, 21 insertions(+), 10 deletions(-) + +diff --git a/src/set_elem.c b/src/set_elem.c +index 848adf1..1f81e76 100644 +--- a/src/set_elem.c ++++ b/src/set_elem.c +@@ -699,7 +699,7 @@ int nftnl_set_elem_parse_file(struct nftnl_set_elem *e, enum nftnl_parse_type ty + int nftnl_set_elem_snprintf_default(char *buf, size_t remain, + const struct nftnl_set_elem *e) + { +- int ret, dregtype = DATA_VALUE, offset = 0, i; ++ int ret, dregtype = DATA_NONE, offset = 0, i; + + ret = snprintf(buf, remain, "element "); + SNPRINTF_BUFFER_SIZE(ret, remain, offset); +@@ -717,18 +717,29 @@ int nftnl_set_elem_snprintf_default(char *buf, size_t remain, + SNPRINTF_BUFFER_SIZE(ret, remain, offset); + } + +- ret = snprintf(buf + offset, remain, " : "); +- SNPRINTF_BUFFER_SIZE(ret, remain, offset); +- +- if (e->flags & (1 << NFTNL_SET_ELEM_VERDICT)) ++ if (e->flags & (1 << NFTNL_SET_ELEM_DATA)) ++ dregtype = DATA_VALUE; ++ else if (e->flags & (1 << NFTNL_SET_ELEM_CHAIN)) ++ dregtype = DATA_CHAIN; ++ else if (e->flags & (1 << NFTNL_SET_ELEM_VERDICT)) + dregtype = DATA_VERDICT; + +- ret = nftnl_data_reg_snprintf(buf + offset, remain, &e->data, +- DATA_F_NOPFX, dregtype); +- SNPRINTF_BUFFER_SIZE(ret, remain, offset); ++ if (dregtype != DATA_NONE) { ++ ret = snprintf(buf + offset, remain, " : "); ++ SNPRINTF_BUFFER_SIZE(ret, remain, offset); + +- ret = snprintf(buf + offset, remain, "%u [end]", e->set_elem_flags); +- SNPRINTF_BUFFER_SIZE(ret, remain, offset); ++ ret = nftnl_data_reg_snprintf(buf + offset, remain, &e->data, ++ DATA_F_NOPFX, dregtype); ++ SNPRINTF_BUFFER_SIZE(ret, remain, offset); ++ } else if (e->flags & (1 << NFTNL_SET_ELEM_OBJREF)) { ++ ret = snprintf(buf + offset, remain, " : %s ", e->objref); ++ SNPRINTF_BUFFER_SIZE(ret, remain, offset); ++ } ++ ++ if (e->set_elem_flags) { ++ ret = snprintf(buf + offset, remain, "flags %u ", e->set_elem_flags); ++ SNPRINTF_BUFFER_SIZE(ret, remain, offset); ++ } + + if (e->user.len) { + ret = snprintf(buf + offset, remain, " userdata = { "); diff --git a/0005-expr-data_reg-Avoid-extra-whitespace.patch b/0005-expr-data_reg-Avoid-extra-whitespace.patch new file mode 100644 index 0000000..9897732 --- /dev/null +++ b/0005-expr-data_reg-Avoid-extra-whitespace.patch @@ -0,0 +1,165 @@ +From 0ded90fadf65fb61f17464ca3c3c50b1592ac77f Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 24 Feb 2026 15:05:32 +0100 +Subject: [PATCH] expr: data_reg: Avoid extra whitespace + +JIRA: https://issues.redhat.com/browse/RHEL-119650 +Upstream Status: libnftnl commit 7daf5a4fde637dfc2aee4480c48777b6e5b22aa2 + +commit 7daf5a4fde637dfc2aee4480c48777b6e5b22aa2 +Author: Phil Sutter +Date: Wed Oct 15 23:41:36 2025 +0200 + + expr: data_reg: Avoid extra whitespace + + Do not append a space to data regs, they may appear at end of line or + followed by a tab. Have callers print the space if needed. + + Signed-off-by: Phil Sutter + +Signed-off-by: Phil Sutter +--- + src/expr/bitwise.c | 7 +++++-- + src/expr/cmp.c | 3 +++ + src/expr/data_reg.c | 11 +++++------ + src/expr/immediate.c | 3 +++ + src/expr/range.c | 6 ++++++ + src/set_elem.c | 4 ++-- + 6 files changed, 24 insertions(+), 10 deletions(-) + +diff --git a/src/expr/bitwise.c b/src/expr/bitwise.c +index cac47a5..2da83b7 100644 +--- a/src/expr/bitwise.c ++++ b/src/expr/bitwise.c +@@ -225,13 +225,16 @@ nftnl_expr_bitwise_snprintf_mask_xor(char *buf, size_t remain, + 0, DATA_VALUE); + SNPRINTF_BUFFER_SIZE(ret, remain, offset); + +- ret = snprintf(buf + offset, remain, ") ^ "); ++ ret = snprintf(buf + offset, remain, " ) ^ "); + SNPRINTF_BUFFER_SIZE(ret, remain, offset); + + ret = nftnl_data_reg_snprintf(buf + offset, remain, &bitwise->xor, + 0, DATA_VALUE); + SNPRINTF_BUFFER_SIZE(ret, remain, offset); + ++ ret = snprintf(buf + offset, remain, " "); ++ SNPRINTF_BUFFER_SIZE(ret, remain, offset); ++ + return offset; + } + +@@ -248,7 +251,7 @@ nftnl_expr_bitwise_snprintf_shift(char *buf, size_t remain, const char *op, + 0, DATA_VALUE); + SNPRINTF_BUFFER_SIZE(ret, remain, offset); + +- ret = snprintf(buf + offset, remain, ") "); ++ ret = snprintf(buf + offset, remain, " ) "); + SNPRINTF_BUFFER_SIZE(ret, remain, offset); + + return offset; +diff --git a/src/expr/cmp.c b/src/expr/cmp.c +index 2908f56..ec1dc31 100644 +--- a/src/expr/cmp.c ++++ b/src/expr/cmp.c +@@ -163,6 +163,9 @@ nftnl_expr_cmp_snprintf(char *buf, size_t remain, + 0, DATA_VALUE); + SNPRINTF_BUFFER_SIZE(ret, remain, offset); + ++ ret = snprintf(buf + offset, remain, " "); ++ SNPRINTF_BUFFER_SIZE(ret, remain, offset); ++ + return offset; + } + +diff --git a/src/expr/data_reg.c b/src/expr/data_reg.c +index fd5e0d6..bf4153c 100644 +--- a/src/expr/data_reg.c ++++ b/src/expr/data_reg.c +@@ -25,15 +25,14 @@ nftnl_data_reg_value_snprintf_default(char *buf, size_t remain, + const union nftnl_data_reg *reg, + uint32_t flags) + { +- const char *pfx = flags & DATA_F_NOPFX ? "" : "0x"; ++ const char *pfx = flags & DATA_F_NOPFX ? "" : "0x", *sep = ""; + int offset = 0, ret, i; + +- +- + for (i = 0; i < div_round_up(reg->len, sizeof(uint32_t)); i++) { + ret = snprintf(buf + offset, remain, +- "%s%.8x ", pfx, reg->val[i]); ++ "%s%s%.8x", sep, pfx, reg->val[i]); + SNPRINTF_BUFFER_SIZE(ret, remain, offset); ++ sep = " "; + } + + return offset; +@@ -46,11 +45,11 @@ nftnl_data_reg_verdict_snprintf_def(char *buf, size_t size, + { + int remain = size, offset = 0, ret = 0; + +- ret = snprintf(buf, size, "%s ", nftnl_verdict2str(reg->verdict)); ++ ret = snprintf(buf, size, "%s", nftnl_verdict2str(reg->verdict)); + SNPRINTF_BUFFER_SIZE(ret, remain, offset); + + if (reg->chain != NULL) { +- ret = snprintf(buf + offset, remain, "-> %s ", reg->chain); ++ ret = snprintf(buf + offset, remain, " -> %s", reg->chain); + SNPRINTF_BUFFER_SIZE(ret, remain, offset); + } + +diff --git a/src/expr/immediate.c b/src/expr/immediate.c +index f0e0a78..6dffaf9 100644 +--- a/src/expr/immediate.c ++++ b/src/expr/immediate.c +@@ -201,6 +201,9 @@ nftnl_expr_immediate_snprintf(char *buf, size_t remain, + SNPRINTF_BUFFER_SIZE(ret, remain, offset); + } + ++ ret = snprintf(buf + offset, remain, " "); ++ SNPRINTF_BUFFER_SIZE(ret, remain, offset); ++ + return offset; + } + +diff --git a/src/expr/range.c b/src/expr/range.c +index 50a8ed0..564d14f 100644 +--- a/src/expr/range.c ++++ b/src/expr/range.c +@@ -176,10 +176,16 @@ static int nftnl_expr_range_snprintf(char *buf, size_t remain, + 0, DATA_VALUE); + SNPRINTF_BUFFER_SIZE(ret, remain, offset); + ++ ret = snprintf(buf + offset, remain, " "); ++ SNPRINTF_BUFFER_SIZE(ret, remain, offset); ++ + ret = nftnl_data_reg_snprintf(buf + offset, remain, &range->data_to, + 0, DATA_VALUE); + SNPRINTF_BUFFER_SIZE(ret, remain, offset); + ++ ret = snprintf(buf + offset, remain, " "); ++ SNPRINTF_BUFFER_SIZE(ret, remain, offset); ++ + return offset; + } + +diff --git a/src/set_elem.c b/src/set_elem.c +index 1f81e76..60ee5f4 100644 +--- a/src/set_elem.c ++++ b/src/set_elem.c +@@ -732,12 +732,12 @@ int nftnl_set_elem_snprintf_default(char *buf, size_t remain, + DATA_F_NOPFX, dregtype); + SNPRINTF_BUFFER_SIZE(ret, remain, offset); + } else if (e->flags & (1 << NFTNL_SET_ELEM_OBJREF)) { +- ret = snprintf(buf + offset, remain, " : %s ", e->objref); ++ ret = snprintf(buf + offset, remain, " : %s", e->objref); + SNPRINTF_BUFFER_SIZE(ret, remain, offset); + } + + if (e->set_elem_flags) { +- ret = snprintf(buf + offset, remain, "flags %u ", e->set_elem_flags); ++ ret = snprintf(buf + offset, remain, " flags %u", e->set_elem_flags); + SNPRINTF_BUFFER_SIZE(ret, remain, offset); + } + diff --git a/0006-expr-Pass-byteorder-to-struct-expr_ops-set-callback.patch b/0006-expr-Pass-byteorder-to-struct-expr_ops-set-callback.patch new file mode 100644 index 0000000..353ef7b --- /dev/null +++ b/0006-expr-Pass-byteorder-to-struct-expr_ops-set-callback.patch @@ -0,0 +1,664 @@ +From 21e7c9d93008b9ded927496a2d6de43ef8e3208a Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 24 Feb 2026 15:05:32 +0100 +Subject: [PATCH] expr: Pass byteorder to struct expr_ops::set callback + +JIRA: https://issues.redhat.com/browse/RHEL-119650 +Upstream Status: libnftnl commit 823a26e9557a7b0c8bd4b412ca1a583bbf5533ae + +commit 823a26e9557a7b0c8bd4b412ca1a583bbf5533ae +Author: Phil Sutter +Date: Wed Oct 1 14:57:36 2025 +0200 + + expr: Pass byteorder to struct expr_ops::set callback + + Prepare for storing data reg byteorder, no functional change intended. + + Note the odd case in expr/byteorder.c since there is a local variable + with same name already. + + Signed-off-by: Phil Sutter + +Signed-off-by: Phil Sutter +--- + include/expr_ops.h | 2 +- + src/expr.c | 15 +++++++++++---- + src/expr/bitwise.c | 2 +- + src/expr/byteorder.c | 2 +- + src/expr/cmp.c | 2 +- + src/expr/connlimit.c | 2 +- + src/expr/counter.c | 2 +- + src/expr/ct.c | 2 +- + src/expr/dup.c | 5 +++-- + src/expr/dynset.c | 2 +- + src/expr/exthdr.c | 2 +- + src/expr/fib.c | 2 +- + src/expr/flow_offload.c | 5 +++-- + src/expr/fwd.c | 5 +++-- + src/expr/hash.c | 2 +- + src/expr/immediate.c | 2 +- + src/expr/inner.c | 2 +- + src/expr/last.c | 5 +++-- + src/expr/limit.c | 2 +- + src/expr/log.c | 5 +++-- + src/expr/lookup.c | 2 +- + src/expr/masq.c | 2 +- + src/expr/match.c | 2 +- + src/expr/meta.c | 2 +- + src/expr/nat.c | 2 +- + src/expr/numgen.c | 2 +- + src/expr/objref.c | 5 +++-- + src/expr/osf.c | 5 +++-- + src/expr/payload.c | 2 +- + src/expr/queue.c | 5 +++-- + src/expr/quota.c | 5 +++-- + src/expr/range.c | 5 +++-- + src/expr/redir.c | 2 +- + src/expr/reject.c | 5 +++-- + src/expr/rt.c | 2 +- + src/expr/socket.c | 2 +- + src/expr/synproxy.c | 5 +++-- + src/expr/target.c | 2 +- + src/expr/tproxy.c | 2 +- + src/expr/tunnel.c | 5 +++-- + src/expr/xfrm.c | 2 +- + 41 files changed, 77 insertions(+), 57 deletions(-) + +diff --git a/include/expr_ops.h b/include/expr_ops.h +index 6cfb3b5..9c816c0 100644 +--- a/include/expr_ops.h ++++ b/include/expr_ops.h +@@ -19,7 +19,7 @@ struct expr_ops { + struct attr_policy *attr_policy; + void (*init)(const struct nftnl_expr *e); + void (*free)(const struct nftnl_expr *e); +- int (*set)(struct nftnl_expr *e, uint16_t type, const void *data, uint32_t data_len); ++ int (*set)(struct nftnl_expr *e, uint16_t type, const void *data, uint32_t data_len, uint32_t byteorder); + const void *(*get)(const struct nftnl_expr *e, uint16_t type, uint32_t *data_len); + int (*parse)(struct nftnl_expr *e, struct nlattr *attr); + void (*build)(struct nlmsghdr *nlh, const struct nftnl_expr *e); +diff --git a/src/expr.c b/src/expr.c +index 65180d6..d07e733 100644 +--- a/src/expr.c ++++ b/src/expr.c +@@ -59,9 +59,9 @@ bool nftnl_expr_is_set(const struct nftnl_expr *expr, uint16_t type) + return expr->flags & (1 << type); + } + +-EXPORT_SYMBOL(nftnl_expr_set); +-int nftnl_expr_set(struct nftnl_expr *expr, uint16_t type, +- const void *data, uint32_t data_len) ++static int __nftnl_expr_set(struct nftnl_expr *expr, uint16_t type, ++ const void *data, uint32_t data_len, ++ uint32_t byteorder) + { + switch(type) { + case NFTNL_EXPR_NAME: /* cannot be modified */ +@@ -77,13 +77,20 @@ int nftnl_expr_set(struct nftnl_expr *expr, uint16_t type, + expr->ops->attr_policy[type].maxlen < data_len) + return -1; + +- if (expr->ops->set(expr, type, data, data_len) < 0) ++ if (expr->ops->set(expr, type, data, data_len, byteorder) < 0) + return -1; + } + expr->flags |= (1 << type); + return 0; + } + ++EXPORT_SYMBOL(nftnl_expr_set); ++int nftnl_expr_set(struct nftnl_expr *expr, uint16_t type, ++ const void *data, uint32_t data_len) ++{ ++ return __nftnl_expr_set(expr, type, data, data_len, 0); ++} ++ + EXPORT_SYMBOL(nftnl_expr_set_u8); + void + nftnl_expr_set_u8(struct nftnl_expr *expr, uint16_t type, uint8_t data) +diff --git a/src/expr/bitwise.c b/src/expr/bitwise.c +index 2da83b7..da2b6d2 100644 +--- a/src/expr/bitwise.c ++++ b/src/expr/bitwise.c +@@ -30,7 +30,7 @@ struct nftnl_expr_bitwise { + + static int + nftnl_expr_bitwise_set(struct nftnl_expr *e, uint16_t type, +- const void *data, uint32_t data_len) ++ const void *data, uint32_t data_len, uint32_t byteorder) + { + struct nftnl_expr_bitwise *bitwise = nftnl_expr_data(e); + +diff --git a/src/expr/byteorder.c b/src/expr/byteorder.c +index 4171d06..baa11a1 100644 +--- a/src/expr/byteorder.c ++++ b/src/expr/byteorder.c +@@ -27,7 +27,7 @@ struct nftnl_expr_byteorder { + + static int + nftnl_expr_byteorder_set(struct nftnl_expr *e, uint16_t type, +- const void *data, uint32_t data_len) ++ const void *data, uint32_t data_len, uint32_t byteorderp) + { + struct nftnl_expr_byteorder *byteorder = nftnl_expr_data(e); + +diff --git a/src/expr/cmp.c b/src/expr/cmp.c +index ec1dc31..4bcf2e4 100644 +--- a/src/expr/cmp.c ++++ b/src/expr/cmp.c +@@ -26,7 +26,7 @@ struct nftnl_expr_cmp { + + static int + nftnl_expr_cmp_set(struct nftnl_expr *e, uint16_t type, +- const void *data, uint32_t data_len) ++ const void *data, uint32_t data_len, uint32_t byteorder) + { + struct nftnl_expr_cmp *cmp = nftnl_expr_data(e); + +diff --git a/src/expr/connlimit.c b/src/expr/connlimit.c +index 02b9ecc..f45129d 100644 +--- a/src/expr/connlimit.c ++++ b/src/expr/connlimit.c +@@ -23,7 +23,7 @@ struct nftnl_expr_connlimit { + + static int + nftnl_expr_connlimit_set(struct nftnl_expr *e, uint16_t type, +- const void *data, uint32_t data_len) ++ const void *data, uint32_t data_len, uint32_t byteorder) + { + struct nftnl_expr_connlimit *connlimit = nftnl_expr_data(e); + +diff --git a/src/expr/counter.c b/src/expr/counter.c +index 80f21d7..21e641b 100644 +--- a/src/expr/counter.c ++++ b/src/expr/counter.c +@@ -25,7 +25,7 @@ struct nftnl_expr_counter { + + static int + nftnl_expr_counter_set(struct nftnl_expr *e, uint16_t type, +- const void *data, uint32_t data_len) ++ const void *data, uint32_t data_len, uint32_t byteorder) + { + struct nftnl_expr_counter *ctr = nftnl_expr_data(e); + +diff --git a/src/expr/ct.c b/src/expr/ct.c +index 8f8c2a6..4117eee 100644 +--- a/src/expr/ct.c ++++ b/src/expr/ct.c +@@ -29,7 +29,7 @@ struct nftnl_expr_ct { + + static int + nftnl_expr_ct_set(struct nftnl_expr *e, uint16_t type, +- const void *data, uint32_t data_len) ++ const void *data, uint32_t data_len, uint32_t byteorder) + { + struct nftnl_expr_ct *ct = nftnl_expr_data(e); + +diff --git a/src/expr/dup.c b/src/expr/dup.c +index d49cdb7..bb0f9c6 100644 +--- a/src/expr/dup.c ++++ b/src/expr/dup.c +@@ -21,8 +21,9 @@ struct nftnl_expr_dup { + enum nft_registers sreg_dev; + }; + +-static int nftnl_expr_dup_set(struct nftnl_expr *e, uint16_t type, +- const void *data, uint32_t data_len) ++static int ++nftnl_expr_dup_set(struct nftnl_expr *e, uint16_t type, ++ const void *data, uint32_t data_len, uint32_t byteorder) + { + struct nftnl_expr_dup *dup = nftnl_expr_data(e); + +diff --git a/src/expr/dynset.c b/src/expr/dynset.c +index 40f9136..f42eeff 100644 +--- a/src/expr/dynset.c ++++ b/src/expr/dynset.c +@@ -30,7 +30,7 @@ struct nftnl_expr_dynset { + + static int + nftnl_expr_dynset_set(struct nftnl_expr *e, uint16_t type, +- const void *data, uint32_t data_len) ++ const void *data, uint32_t data_len, uint32_t byteorder) + { + struct nftnl_expr_dynset *dynset = nftnl_expr_data(e); + struct nftnl_expr *expr, *next; +diff --git a/src/expr/exthdr.c b/src/expr/exthdr.c +index ddebe43..c936ac0 100644 +--- a/src/expr/exthdr.c ++++ b/src/expr/exthdr.c +@@ -36,7 +36,7 @@ struct nftnl_expr_exthdr { + + static int + nftnl_expr_exthdr_set(struct nftnl_expr *e, uint16_t type, +- const void *data, uint32_t data_len) ++ const void *data, uint32_t data_len, uint32_t byteorder) + { + struct nftnl_expr_exthdr *exthdr = nftnl_expr_data(e); + +diff --git a/src/expr/fib.c b/src/expr/fib.c +index c378f4f..31750da 100644 +--- a/src/expr/fib.c ++++ b/src/expr/fib.c +@@ -25,7 +25,7 @@ struct nftnl_expr_fib { + + static int + nftnl_expr_fib_set(struct nftnl_expr *e, uint16_t result, +- const void *data, uint32_t data_len) ++ const void *data, uint32_t data_len, uint32_t byteorder) + { + struct nftnl_expr_fib *fib = nftnl_expr_data(e); + +diff --git a/src/expr/flow_offload.c b/src/expr/flow_offload.c +index 5f209a6..adb6986 100644 +--- a/src/expr/flow_offload.c ++++ b/src/expr/flow_offload.c +@@ -14,8 +14,9 @@ struct nftnl_expr_flow { + char *table_name; + }; + +-static int nftnl_expr_flow_set(struct nftnl_expr *e, uint16_t type, +- const void *data, uint32_t data_len) ++static int ++nftnl_expr_flow_set(struct nftnl_expr *e, uint16_t type, ++ const void *data, uint32_t data_len, uint32_t byteorder) + { + struct nftnl_expr_flow *flow = nftnl_expr_data(e); + +diff --git a/src/expr/fwd.c b/src/expr/fwd.c +index d543e22..5f6a56c 100644 +--- a/src/expr/fwd.c ++++ b/src/expr/fwd.c +@@ -22,8 +22,9 @@ struct nftnl_expr_fwd { + uint32_t nfproto; + }; + +-static int nftnl_expr_fwd_set(struct nftnl_expr *e, uint16_t type, +- const void *data, uint32_t data_len) ++static int ++nftnl_expr_fwd_set(struct nftnl_expr *e, uint16_t type, ++ const void *data, uint32_t data_len, uint32_t byteorder) + { + struct nftnl_expr_fwd *fwd = nftnl_expr_data(e); + +diff --git a/src/expr/hash.c b/src/expr/hash.c +index 050e4b9..c0cf8d9 100644 +--- a/src/expr/hash.c ++++ b/src/expr/hash.c +@@ -27,7 +27,7 @@ struct nftnl_expr_hash { + + static int + nftnl_expr_hash_set(struct nftnl_expr *e, uint16_t type, +- const void *data, uint32_t data_len) ++ const void *data, uint32_t data_len, uint32_t byteorder) + { + struct nftnl_expr_hash *hash = nftnl_expr_data(e); + switch (type) { +diff --git a/src/expr/immediate.c b/src/expr/immediate.c +index 6dffaf9..27ee600 100644 +--- a/src/expr/immediate.c ++++ b/src/expr/immediate.c +@@ -23,7 +23,7 @@ struct nftnl_expr_immediate { + + static int + nftnl_expr_immediate_set(struct nftnl_expr *e, uint16_t type, +- const void *data, uint32_t data_len) ++ const void *data, uint32_t data_len, uint32_t byteorder) + { + struct nftnl_expr_immediate *imm = nftnl_expr_data(e); + +diff --git a/src/expr/inner.c b/src/expr/inner.c +index 8a56bb3..516cda6 100644 +--- a/src/expr/inner.c ++++ b/src/expr/inner.c +@@ -35,7 +35,7 @@ static void nftnl_expr_inner_free(const struct nftnl_expr *e) + + static int + nftnl_expr_inner_set(struct nftnl_expr *e, uint16_t type, +- const void *data, uint32_t data_len) ++ const void *data, uint32_t data_len, uint32_t byteorder) + { + struct nftnl_expr_inner *inner = nftnl_expr_data(e); + +diff --git a/src/expr/last.c b/src/expr/last.c +index 427d4b5..ebdaf2a 100644 +--- a/src/expr/last.c ++++ b/src/expr/last.c +@@ -21,8 +21,9 @@ struct nftnl_expr_last { + uint32_t set; + }; + +-static int nftnl_expr_last_set(struct nftnl_expr *e, uint16_t type, +- const void *data, uint32_t data_len) ++static int ++nftnl_expr_last_set(struct nftnl_expr *e, uint16_t type, ++ const void *data, uint32_t data_len, uint32_t byteorder) + { + struct nftnl_expr_last *last = nftnl_expr_data(e); + +diff --git a/src/expr/limit.c b/src/expr/limit.c +index b77b27e..3644497 100644 +--- a/src/expr/limit.c ++++ b/src/expr/limit.c +@@ -28,7 +28,7 @@ struct nftnl_expr_limit { + + static int + nftnl_expr_limit_set(struct nftnl_expr *e, uint16_t type, +- const void *data, uint32_t data_len) ++ const void *data, uint32_t data_len, uint32_t byteorder) + { + struct nftnl_expr_limit *limit = nftnl_expr_data(e); + +diff --git a/src/expr/log.c b/src/expr/log.c +index d4b53e6..ca3931f 100644 +--- a/src/expr/log.c ++++ b/src/expr/log.c +@@ -27,8 +27,9 @@ struct nftnl_expr_log { + const char *prefix; + }; + +-static int nftnl_expr_log_set(struct nftnl_expr *e, uint16_t type, +- const void *data, uint32_t data_len) ++static int ++nftnl_expr_log_set(struct nftnl_expr *e, uint16_t type, ++ const void *data, uint32_t data_len, uint32_t byteorder) + { + struct nftnl_expr_log *log = nftnl_expr_data(e); + +diff --git a/src/expr/lookup.c b/src/expr/lookup.c +index 7f85ecc..ddf78a7 100644 +--- a/src/expr/lookup.c ++++ b/src/expr/lookup.c +@@ -27,7 +27,7 @@ struct nftnl_expr_lookup { + + static int + nftnl_expr_lookup_set(struct nftnl_expr *e, uint16_t type, +- const void *data, uint32_t data_len) ++ const void *data, uint32_t data_len, uint32_t byteorder) + { + struct nftnl_expr_lookup *lookup = nftnl_expr_data(e); + +diff --git a/src/expr/masq.c b/src/expr/masq.c +index da4f437..e0d9eb6 100644 +--- a/src/expr/masq.c ++++ b/src/expr/masq.c +@@ -24,7 +24,7 @@ struct nftnl_expr_masq { + + static int + nftnl_expr_masq_set(struct nftnl_expr *e, uint16_t type, +- const void *data, uint32_t data_len) ++ const void *data, uint32_t data_len, uint32_t byteorder) + { + struct nftnl_expr_masq *masq = nftnl_expr_data(e); + +diff --git a/src/expr/match.c b/src/expr/match.c +index 2c5bd6b..b7e99b8 100644 +--- a/src/expr/match.c ++++ b/src/expr/match.c +@@ -32,7 +32,7 @@ struct nftnl_expr_match { + + static int + nftnl_expr_match_set(struct nftnl_expr *e, uint16_t type, +- const void *data, uint32_t data_len) ++ const void *data, uint32_t data_len, uint32_t byteorder) + { + struct nftnl_expr_match *mt = nftnl_expr_data(e); + +diff --git a/src/expr/meta.c b/src/expr/meta.c +index d1ff6c4..6670d03 100644 +--- a/src/expr/meta.c ++++ b/src/expr/meta.c +@@ -29,7 +29,7 @@ struct nftnl_expr_meta { + + static int + nftnl_expr_meta_set(struct nftnl_expr *e, uint16_t type, +- const void *data, uint32_t data_len) ++ const void *data, uint32_t data_len, uint32_t byteorder) + { + struct nftnl_expr_meta *meta = nftnl_expr_data(e); + +diff --git a/src/expr/nat.c b/src/expr/nat.c +index f7e24cb..89e7f15 100644 +--- a/src/expr/nat.c ++++ b/src/expr/nat.c +@@ -32,7 +32,7 @@ struct nftnl_expr_nat { + + static int + nftnl_expr_nat_set(struct nftnl_expr *e, uint16_t type, +- const void *data, uint32_t data_len) ++ const void *data, uint32_t data_len, uint32_t byteorder) + { + struct nftnl_expr_nat *nat = nftnl_expr_data(e); + +diff --git a/src/expr/numgen.c b/src/expr/numgen.c +index e3af372..5243d9d 100644 +--- a/src/expr/numgen.c ++++ b/src/expr/numgen.c +@@ -24,7 +24,7 @@ struct nftnl_expr_ng { + + static int + nftnl_expr_ng_set(struct nftnl_expr *e, uint16_t type, +- const void *data, uint32_t data_len) ++ const void *data, uint32_t data_len, uint32_t byteorder) + { + struct nftnl_expr_ng *ng = nftnl_expr_data(e); + +diff --git a/src/expr/objref.c b/src/expr/objref.c +index 5fe09c2..42cf816 100644 +--- a/src/expr/objref.c ++++ b/src/expr/objref.c +@@ -28,8 +28,9 @@ struct nftnl_expr_objref { + } set; + }; + +-static int nftnl_expr_objref_set(struct nftnl_expr *e, uint16_t type, +- const void *data, uint32_t data_len) ++static int ++nftnl_expr_objref_set(struct nftnl_expr *e, uint16_t type, ++ const void *data, uint32_t data_len, uint32_t byteorder) + { + struct nftnl_expr_objref *objref = nftnl_expr_data(e); + +diff --git a/src/expr/osf.c b/src/expr/osf.c +index 293a814..35a31cf 100644 +--- a/src/expr/osf.c ++++ b/src/expr/osf.c +@@ -18,8 +18,9 @@ struct nftnl_expr_osf { + uint32_t flags; + }; + +-static int nftnl_expr_osf_set(struct nftnl_expr *e, uint16_t type, +- const void *data, uint32_t data_len) ++static int ++nftnl_expr_osf_set(struct nftnl_expr *e, uint16_t type, ++ const void *data, uint32_t data_len, uint32_t byteorder) + { + struct nftnl_expr_osf *osf = nftnl_expr_data(e); + +diff --git a/src/expr/payload.c b/src/expr/payload.c +index 593b842..476eaab 100644 +--- a/src/expr/payload.c ++++ b/src/expr/payload.c +@@ -33,7 +33,7 @@ struct nftnl_expr_payload { + + static int + nftnl_expr_payload_set(struct nftnl_expr *e, uint16_t type, +- const void *data, uint32_t data_len) ++ const void *data, uint32_t data_len, uint32_t byteorder) + { + struct nftnl_expr_payload *payload = nftnl_expr_data(e); + +diff --git a/src/expr/queue.c b/src/expr/queue.c +index 0160d5e..f5e3f32 100644 +--- a/src/expr/queue.c ++++ b/src/expr/queue.c +@@ -22,8 +22,9 @@ struct nftnl_expr_queue { + uint16_t flags; + }; + +-static int nftnl_expr_queue_set(struct nftnl_expr *e, uint16_t type, +- const void *data, uint32_t data_len) ++static int ++nftnl_expr_queue_set(struct nftnl_expr *e, uint16_t type, ++ const void *data, uint32_t data_len, uint32_t byteorder) + { + struct nftnl_expr_queue *queue = nftnl_expr_data(e); + +diff --git a/src/expr/quota.c b/src/expr/quota.c +index 108c87c..6a8dc94 100644 +--- a/src/expr/quota.c ++++ b/src/expr/quota.c +@@ -22,8 +22,9 @@ struct nftnl_expr_quota { + uint32_t flags; + }; + +-static int nftnl_expr_quota_set(struct nftnl_expr *e, uint16_t type, +- const void *data, uint32_t data_len) ++static int ++nftnl_expr_quota_set(struct nftnl_expr *e, uint16_t type, ++ const void *data, uint32_t data_len, uint32_t byteorder) + { + struct nftnl_expr_quota *quota = nftnl_expr_data(e); + +diff --git a/src/expr/range.c b/src/expr/range.c +index 564d14f..cd6d6fb 100644 +--- a/src/expr/range.c ++++ b/src/expr/range.c +@@ -23,8 +23,9 @@ struct nftnl_expr_range { + enum nft_range_ops op; + }; + +-static int nftnl_expr_range_set(struct nftnl_expr *e, uint16_t type, +- const void *data, uint32_t data_len) ++static int ++nftnl_expr_range_set(struct nftnl_expr *e, uint16_t type, ++ const void *data, uint32_t data_len, uint32_t byteorder) + { + struct nftnl_expr_range *range = nftnl_expr_data(e); + +diff --git a/src/expr/redir.c b/src/expr/redir.c +index be38f62..3565d3f 100644 +--- a/src/expr/redir.c ++++ b/src/expr/redir.c +@@ -24,7 +24,7 @@ struct nftnl_expr_redir { + + static int + nftnl_expr_redir_set(struct nftnl_expr *e, uint16_t type, +- const void *data, uint32_t data_len) ++ const void *data, uint32_t data_len, uint32_t byteorder) + { + struct nftnl_expr_redir *redir = nftnl_expr_data(e); + +diff --git a/src/expr/reject.c b/src/expr/reject.c +index 5d8763e..df8f926 100644 +--- a/src/expr/reject.c ++++ b/src/expr/reject.c +@@ -22,8 +22,9 @@ struct nftnl_expr_reject { + uint8_t icmp_code; + }; + +-static int nftnl_expr_reject_set(struct nftnl_expr *e, uint16_t type, +- const void *data, uint32_t data_len) ++static int ++nftnl_expr_reject_set(struct nftnl_expr *e, uint16_t type, ++ const void *data, uint32_t data_len, uint32_t byteorder) + { + struct nftnl_expr_reject *reject = nftnl_expr_data(e); + +diff --git a/src/expr/rt.c b/src/expr/rt.c +index 4f2e96b..c0d4311 100644 +--- a/src/expr/rt.c ++++ b/src/expr/rt.c +@@ -22,7 +22,7 @@ struct nftnl_expr_rt { + + static int + nftnl_expr_rt_set(struct nftnl_expr *e, uint16_t type, +- const void *data, uint32_t data_len) ++ const void *data, uint32_t data_len, uint32_t byteorder) + { + struct nftnl_expr_rt *rt = nftnl_expr_data(e); + +diff --git a/src/expr/socket.c b/src/expr/socket.c +index 822ee8b..98a8565 100644 +--- a/src/expr/socket.c ++++ b/src/expr/socket.c +@@ -23,7 +23,7 @@ struct nftnl_expr_socket { + + static int + nftnl_expr_socket_set(struct nftnl_expr *e, uint16_t type, +- const void *data, uint32_t data_len) ++ const void *data, uint32_t data_len, uint32_t byteorder) + { + struct nftnl_expr_socket *socket = nftnl_expr_data(e); + +diff --git a/src/expr/synproxy.c b/src/expr/synproxy.c +index b5a1fef..ad2f0f0 100644 +--- a/src/expr/synproxy.c ++++ b/src/expr/synproxy.c +@@ -16,8 +16,9 @@ struct nftnl_expr_synproxy { + uint32_t flags; + }; + +-static int nftnl_expr_synproxy_set(struct nftnl_expr *e, uint16_t type, +- const void *data, uint32_t data_len) ++static int ++nftnl_expr_synproxy_set(struct nftnl_expr *e, uint16_t type, ++ const void *data, uint32_t data_len, uint32_t byteorder) + { + struct nftnl_expr_synproxy *synproxy = nftnl_expr_data(e); + +diff --git a/src/expr/target.c b/src/expr/target.c +index 3549456..6b590f5 100644 +--- a/src/expr/target.c ++++ b/src/expr/target.c +@@ -32,7 +32,7 @@ struct nftnl_expr_target { + + static int + nftnl_expr_target_set(struct nftnl_expr *e, uint16_t type, +- const void *data, uint32_t data_len) ++ const void *data, uint32_t data_len, uint32_t byteorder) + { + struct nftnl_expr_target *tg = nftnl_expr_data(e); + +diff --git a/src/expr/tproxy.c b/src/expr/tproxy.c +index 4cc9125..630dffe 100644 +--- a/src/expr/tproxy.c ++++ b/src/expr/tproxy.c +@@ -24,7 +24,7 @@ struct nftnl_expr_tproxy { + + static int + nftnl_expr_tproxy_set(struct nftnl_expr *e, uint16_t type, +- const void *data, uint32_t data_len) ++ const void *data, uint32_t data_len, uint32_t byteorder) + { + struct nftnl_expr_tproxy *tproxy = nftnl_expr_data(e); + +diff --git a/src/expr/tunnel.c b/src/expr/tunnel.c +index b51b6c7..bdfbc29 100644 +--- a/src/expr/tunnel.c ++++ b/src/expr/tunnel.c +@@ -20,8 +20,9 @@ struct nftnl_expr_tunnel { + enum nft_registers dreg; + }; + +-static int nftnl_expr_tunnel_set(struct nftnl_expr *e, uint16_t type, +- const void *data, uint32_t data_len) ++static int ++nftnl_expr_tunnel_set(struct nftnl_expr *e, uint16_t type, ++ const void *data, uint32_t data_len, uint32_t byteorder) + { + struct nftnl_expr_tunnel *tunnel = nftnl_expr_data(e); + +diff --git a/src/expr/xfrm.c b/src/expr/xfrm.c +index ba2107d..d247b74 100644 +--- a/src/expr/xfrm.c ++++ b/src/expr/xfrm.c +@@ -22,7 +22,7 @@ struct nftnl_expr_xfrm { + + static int + nftnl_expr_xfrm_set(struct nftnl_expr *e, uint16_t type, +- const void *data, uint32_t data_len) ++ const void *data, uint32_t data_len, uint32_t byteorder) + { + struct nftnl_expr_xfrm *x = nftnl_expr_data(e); + diff --git a/0007-data_reg-Introduce-struct-nftnl_data_reg-byteorder-f.patch b/0007-data_reg-Introduce-struct-nftnl_data_reg-byteorder-f.patch new file mode 100644 index 0000000..48dca35 --- /dev/null +++ b/0007-data_reg-Introduce-struct-nftnl_data_reg-byteorder-f.patch @@ -0,0 +1,161 @@ +From 34f62900a8be9d4a840d42b1b9eabed53074953d Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 24 Feb 2026 15:05:32 +0100 +Subject: [PATCH] data_reg: Introduce struct nftnl_data_reg::byteorder field + +JIRA: https://issues.redhat.com/browse/RHEL-119650 +Upstream Status: libnftnl commit cb5f02ae63923fd129efd1ccef91ba87c66e9cc0 + +commit cb5f02ae63923fd129efd1ccef91ba87c66e9cc0 +Author: Phil Sutter +Date: Wed Oct 1 14:59:39 2025 +0200 + + data_reg: Introduce struct nftnl_data_reg::byteorder field + + Expression setters populate it from the passed 'byteorder' parameter. + + Signed-off-by: Phil Sutter + +Signed-off-by: Phil Sutter +--- + include/data_reg.h | 4 +++- + src/expr/bitwise.c | 6 +++--- + src/expr/cmp.c | 2 +- + src/expr/data_reg.c | 4 +++- + src/expr/immediate.c | 2 +- + src/expr/range.c | 6 ++++-- + src/set_elem.c | 6 +++--- + 7 files changed, 18 insertions(+), 12 deletions(-) + +diff --git a/include/data_reg.h b/include/data_reg.h +index 946354d..e22acd1 100644 +--- a/include/data_reg.h ++++ b/include/data_reg.h +@@ -21,6 +21,7 @@ union nftnl_data_reg { + struct { + uint32_t val[NFT_DATA_VALUE_MAXLEN / sizeof(uint32_t)]; + uint32_t len; ++ uint32_t byteorder; + }; + struct { + uint32_t verdict; +@@ -35,6 +36,7 @@ int nftnl_data_reg_snprintf(char *buf, size_t size, + struct nlattr; + + int nftnl_parse_data(union nftnl_data_reg *data, struct nlattr *attr, int *type); +-int nftnl_data_cpy(union nftnl_data_reg *dreg, const void *src, uint32_t len); ++int nftnl_data_cpy(union nftnl_data_reg *dreg, const void *src, ++ uint32_t len, uint32_t byteorder); + + #endif +diff --git a/src/expr/bitwise.c b/src/expr/bitwise.c +index da2b6d2..a775285 100644 +--- a/src/expr/bitwise.c ++++ b/src/expr/bitwise.c +@@ -51,11 +51,11 @@ nftnl_expr_bitwise_set(struct nftnl_expr *e, uint16_t type, + memcpy(&bitwise->len, data, data_len); + break; + case NFTNL_EXPR_BITWISE_MASK: +- return nftnl_data_cpy(&bitwise->mask, data, data_len); ++ return nftnl_data_cpy(&bitwise->mask, data, data_len, byteorder); + case NFTNL_EXPR_BITWISE_XOR: +- return nftnl_data_cpy(&bitwise->xor, data, data_len); ++ return nftnl_data_cpy(&bitwise->xor, data, data_len, byteorder); + case NFTNL_EXPR_BITWISE_DATA: +- return nftnl_data_cpy(&bitwise->data, data, data_len); ++ return nftnl_data_cpy(&bitwise->data, data, data_len, byteorder); + } + return 0; + } +diff --git a/src/expr/cmp.c b/src/expr/cmp.c +index 4bcf2e4..c88e06a 100644 +--- a/src/expr/cmp.c ++++ b/src/expr/cmp.c +@@ -38,7 +38,7 @@ nftnl_expr_cmp_set(struct nftnl_expr *e, uint16_t type, + memcpy(&cmp->op, data, data_len); + break; + case NFTNL_EXPR_CMP_DATA: +- return nftnl_data_cpy(&cmp->data, data, data_len); ++ return nftnl_data_cpy(&cmp->data, data, data_len, byteorder); + } + return 0; + } +diff --git a/src/expr/data_reg.c b/src/expr/data_reg.c +index bf4153c..45f2d94 100644 +--- a/src/expr/data_reg.c ++++ b/src/expr/data_reg.c +@@ -201,7 +201,8 @@ int nftnl_parse_data(union nftnl_data_reg *data, struct nlattr *attr, int *type) + return ret; + } + +-int nftnl_data_cpy(union nftnl_data_reg *dreg, const void *src, uint32_t len) ++int nftnl_data_cpy(union nftnl_data_reg *dreg, const void *src, ++ uint32_t len, uint32_t byteorder) + { + int ret = 0; + +@@ -212,5 +213,6 @@ int nftnl_data_cpy(union nftnl_data_reg *dreg, const void *src, uint32_t len) + + memcpy(dreg->val, src, len); + dreg->len = len; ++ dreg->byteorder = byteorder; + return ret; + } +diff --git a/src/expr/immediate.c b/src/expr/immediate.c +index 27ee600..f27b6e6 100644 +--- a/src/expr/immediate.c ++++ b/src/expr/immediate.c +@@ -32,7 +32,7 @@ nftnl_expr_immediate_set(struct nftnl_expr *e, uint16_t type, + memcpy(&imm->dreg, data, data_len); + break; + case NFTNL_EXPR_IMM_DATA: +- return nftnl_data_cpy(&imm->data, data, data_len); ++ return nftnl_data_cpy(&imm->data, data, data_len, byteorder); + case NFTNL_EXPR_IMM_VERDICT: + memcpy(&imm->data.verdict, data, data_len); + break; +diff --git a/src/expr/range.c b/src/expr/range.c +index cd6d6fb..4b3101e 100644 +--- a/src/expr/range.c ++++ b/src/expr/range.c +@@ -37,9 +37,11 @@ nftnl_expr_range_set(struct nftnl_expr *e, uint16_t type, + memcpy(&range->op, data, data_len); + break; + case NFTNL_EXPR_RANGE_FROM_DATA: +- return nftnl_data_cpy(&range->data_from, data, data_len); ++ return nftnl_data_cpy(&range->data_from, data, ++ data_len, byteorder); + case NFTNL_EXPR_RANGE_TO_DATA: +- return nftnl_data_cpy(&range->data_to, data, data_len); ++ return nftnl_data_cpy(&range->data_to, data, ++ data_len, byteorder); + } + return 0; + } +diff --git a/src/set_elem.c b/src/set_elem.c +index 60ee5f4..1c2780b 100644 +--- a/src/set_elem.c ++++ b/src/set_elem.c +@@ -122,11 +122,11 @@ int nftnl_set_elem_set(struct nftnl_set_elem *s, uint16_t attr, + memcpy(&s->set_elem_flags, data, sizeof(s->set_elem_flags)); + break; + case NFTNL_SET_ELEM_KEY: /* NFTA_SET_ELEM_KEY */ +- if (nftnl_data_cpy(&s->key, data, data_len) < 0) ++ if (nftnl_data_cpy(&s->key, data, data_len, 0) < 0) + return -1; + break; + case NFTNL_SET_ELEM_KEY_END: /* NFTA_SET_ELEM_KEY_END */ +- if (nftnl_data_cpy(&s->key_end, data, data_len) < 0) ++ if (nftnl_data_cpy(&s->key_end, data, data_len, 0) < 0) + return -1; + break; + case NFTNL_SET_ELEM_VERDICT: /* NFTA_SET_ELEM_DATA */ +@@ -141,7 +141,7 @@ int nftnl_set_elem_set(struct nftnl_set_elem *s, uint16_t attr, + return -1; + break; + case NFTNL_SET_ELEM_DATA: /* NFTA_SET_ELEM_DATA */ +- if (nftnl_data_cpy(&s->data, data, data_len) < 0) ++ if (nftnl_data_cpy(&s->data, data, data_len, 0) < 0) + return -1; + break; + case NFTNL_SET_ELEM_TIMEOUT: /* NFTA_SET_ELEM_TIMEOUT */ diff --git a/0008-data_reg-Introduce-struct-nftnl_data_reg-sizes-array.patch b/0008-data_reg-Introduce-struct-nftnl_data_reg-sizes-array.patch new file mode 100644 index 0000000..b7e0c37 --- /dev/null +++ b/0008-data_reg-Introduce-struct-nftnl_data_reg-sizes-array.patch @@ -0,0 +1,166 @@ +From 3ad775bd24ef85034ec38f73d3eb359e15ad2c25 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 24 Feb 2026 15:05:32 +0100 +Subject: [PATCH] data_reg: Introduce struct nftnl_data_reg::sizes array + +JIRA: https://issues.redhat.com/browse/RHEL-119650 +Upstream Status: libnftnl commit 6077bf5cadd980038c223841c886aa8bc1d5abec + +commit 6077bf5cadd980038c223841c886aa8bc1d5abec +Author: Phil Sutter +Date: Thu Oct 16 01:30:20 2025 +0200 + + data_reg: Introduce struct nftnl_data_reg::sizes array + + This will hold the actual size of each component in concatenated data. + + Signed-off-by: Phil Sutter + +Signed-off-by: Phil Sutter +--- + include/data_reg.h | 3 ++- + src/expr/bitwise.c | 9 ++++++--- + src/expr/cmp.c | 3 ++- + src/expr/data_reg.c | 6 +++++- + src/expr/immediate.c | 3 ++- + src/expr/range.c | 4 ++-- + src/set_elem.c | 6 +++--- + 7 files changed, 22 insertions(+), 12 deletions(-) + +diff --git a/include/data_reg.h b/include/data_reg.h +index e22acd1..5cdeba0 100644 +--- a/include/data_reg.h ++++ b/include/data_reg.h +@@ -22,6 +22,7 @@ union nftnl_data_reg { + uint32_t val[NFT_DATA_VALUE_MAXLEN / sizeof(uint32_t)]; + uint32_t len; + uint32_t byteorder; ++ uint8_t sizes[NFT_REG32_COUNT]; + }; + struct { + uint32_t verdict; +@@ -37,6 +38,6 @@ struct nlattr; + + int nftnl_parse_data(union nftnl_data_reg *data, struct nlattr *attr, int *type); + int nftnl_data_cpy(union nftnl_data_reg *dreg, const void *src, +- uint32_t len, uint32_t byteorder); ++ uint32_t len, uint32_t byteorder, uint8_t *sizes); + + #endif +diff --git a/src/expr/bitwise.c b/src/expr/bitwise.c +index a775285..a838e6c 100644 +--- a/src/expr/bitwise.c ++++ b/src/expr/bitwise.c +@@ -51,11 +51,14 @@ nftnl_expr_bitwise_set(struct nftnl_expr *e, uint16_t type, + memcpy(&bitwise->len, data, data_len); + break; + case NFTNL_EXPR_BITWISE_MASK: +- return nftnl_data_cpy(&bitwise->mask, data, data_len, byteorder); ++ return nftnl_data_cpy(&bitwise->mask, data, ++ data_len, byteorder, NULL); + case NFTNL_EXPR_BITWISE_XOR: +- return nftnl_data_cpy(&bitwise->xor, data, data_len, byteorder); ++ return nftnl_data_cpy(&bitwise->xor, data, ++ data_len, byteorder, NULL); + case NFTNL_EXPR_BITWISE_DATA: +- return nftnl_data_cpy(&bitwise->data, data, data_len, byteorder); ++ return nftnl_data_cpy(&bitwise->data, data, ++ data_len, byteorder, NULL); + } + return 0; + } +diff --git a/src/expr/cmp.c b/src/expr/cmp.c +index c88e06a..ec5dd62 100644 +--- a/src/expr/cmp.c ++++ b/src/expr/cmp.c +@@ -38,7 +38,8 @@ nftnl_expr_cmp_set(struct nftnl_expr *e, uint16_t type, + memcpy(&cmp->op, data, data_len); + break; + case NFTNL_EXPR_CMP_DATA: +- return nftnl_data_cpy(&cmp->data, data, data_len, byteorder); ++ return nftnl_data_cpy(&cmp->data, data, ++ data_len, byteorder, NULL); + } + return 0; + } +diff --git a/src/expr/data_reg.c b/src/expr/data_reg.c +index 45f2d94..d1aadcc 100644 +--- a/src/expr/data_reg.c ++++ b/src/expr/data_reg.c +@@ -202,7 +202,7 @@ int nftnl_parse_data(union nftnl_data_reg *data, struct nlattr *attr, int *type) + } + + int nftnl_data_cpy(union nftnl_data_reg *dreg, const void *src, +- uint32_t len, uint32_t byteorder) ++ uint32_t len, uint32_t byteorder, uint8_t *sizes) + { + int ret = 0; + +@@ -214,5 +214,9 @@ int nftnl_data_cpy(union nftnl_data_reg *dreg, const void *src, + memcpy(dreg->val, src, len); + dreg->len = len; + dreg->byteorder = byteorder; ++ if (sizes) ++ memcpy(dreg->sizes, sizes, sizeof(dreg->sizes)); ++ else ++ memset(dreg->sizes, 0, sizeof(dreg->sizes)); + return ret; + } +diff --git a/src/expr/immediate.c b/src/expr/immediate.c +index f27b6e6..9453198 100644 +--- a/src/expr/immediate.c ++++ b/src/expr/immediate.c +@@ -32,7 +32,8 @@ nftnl_expr_immediate_set(struct nftnl_expr *e, uint16_t type, + memcpy(&imm->dreg, data, data_len); + break; + case NFTNL_EXPR_IMM_DATA: +- return nftnl_data_cpy(&imm->data, data, data_len, byteorder); ++ return nftnl_data_cpy(&imm->data, data, ++ data_len, byteorder, NULL); + case NFTNL_EXPR_IMM_VERDICT: + memcpy(&imm->data.verdict, data, data_len); + break; +diff --git a/src/expr/range.c b/src/expr/range.c +index 4b3101e..12c91e9 100644 +--- a/src/expr/range.c ++++ b/src/expr/range.c +@@ -38,10 +38,10 @@ nftnl_expr_range_set(struct nftnl_expr *e, uint16_t type, + break; + case NFTNL_EXPR_RANGE_FROM_DATA: + return nftnl_data_cpy(&range->data_from, data, +- data_len, byteorder); ++ data_len, byteorder, NULL); + case NFTNL_EXPR_RANGE_TO_DATA: + return nftnl_data_cpy(&range->data_to, data, +- data_len, byteorder); ++ data_len, byteorder, NULL); + } + return 0; + } +diff --git a/src/set_elem.c b/src/set_elem.c +index 1c2780b..7ec65b9 100644 +--- a/src/set_elem.c ++++ b/src/set_elem.c +@@ -122,11 +122,11 @@ int nftnl_set_elem_set(struct nftnl_set_elem *s, uint16_t attr, + memcpy(&s->set_elem_flags, data, sizeof(s->set_elem_flags)); + break; + case NFTNL_SET_ELEM_KEY: /* NFTA_SET_ELEM_KEY */ +- if (nftnl_data_cpy(&s->key, data, data_len, 0) < 0) ++ if (nftnl_data_cpy(&s->key, data, data_len, 0, NULL) < 0) + return -1; + break; + case NFTNL_SET_ELEM_KEY_END: /* NFTA_SET_ELEM_KEY_END */ +- if (nftnl_data_cpy(&s->key_end, data, data_len, 0) < 0) ++ if (nftnl_data_cpy(&s->key_end, data, data_len, 0, NULL) < 0) + return -1; + break; + case NFTNL_SET_ELEM_VERDICT: /* NFTA_SET_ELEM_DATA */ +@@ -141,7 +141,7 @@ int nftnl_set_elem_set(struct nftnl_set_elem *s, uint16_t attr, + return -1; + break; + case NFTNL_SET_ELEM_DATA: /* NFTA_SET_ELEM_DATA */ +- if (nftnl_data_cpy(&s->data, data, data_len, 0) < 0) ++ if (nftnl_data_cpy(&s->data, data, data_len, 0, NULL) < 0) + return -1; + break; + case NFTNL_SET_ELEM_TIMEOUT: /* NFTA_SET_ELEM_TIMEOUT */ diff --git a/0009-Introduce-nftnl_-expr-set_elem-_set_imm.patch b/0009-Introduce-nftnl_-expr-set_elem-_set_imm.patch new file mode 100644 index 0000000..4e1962f --- /dev/null +++ b/0009-Introduce-nftnl_-expr-set_elem-_set_imm.patch @@ -0,0 +1,150 @@ +From 6ad4f08650282114a4129993c781717929a4eee7 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 24 Feb 2026 15:05:32 +0100 +Subject: [PATCH] Introduce nftnl_{expr,set_elem}_set_imm() + +JIRA: https://issues.redhat.com/browse/RHEL-119650 +Upstream Status: libnftnl commit b5676703947cc9fec2aedab91fc28ab864c97647 +Conflicts: No LIBNFTNL_18 in RHEL, define LIBNFTNL_RHEL_18 instead which + exports upstream's LIBNFTNL_19 symbols. + +commit b5676703947cc9fec2aedab91fc28ab864c97647 +Author: Phil Sutter +Date: Wed Oct 1 15:05:19 2025 +0200 + + Introduce nftnl_{expr,set_elem}_set_imm() + + These are alternatives to nftnl_{expr,set_elem}_set() which accept + byteorder and concat component size information. + + Signed-off-by: Phil Sutter + +Signed-off-by: Phil Sutter +--- + include/libnftnl/expr.h | 1 + + include/libnftnl/set.h | 1 + + src/expr.c | 7 +++++++ + src/libnftnl.map | 5 +++++ + src/set_elem.c | 30 ++++++++++++++++++++++++------ + 5 files changed, 38 insertions(+), 6 deletions(-) + +diff --git a/include/libnftnl/expr.h b/include/libnftnl/expr.h +index 1c07b54..41e9f30 100644 +--- a/include/libnftnl/expr.h ++++ b/include/libnftnl/expr.h +@@ -21,6 +21,7 @@ void nftnl_expr_free(const struct nftnl_expr *expr); + + bool nftnl_expr_is_set(const struct nftnl_expr *expr, uint16_t type); + int nftnl_expr_set(struct nftnl_expr *expr, uint16_t type, const void *data, uint32_t data_len); ++int nftnl_expr_set_imm(struct nftnl_expr *expr, uint16_t type, const void *data, uint32_t data_len, uint32_t byteorder); + #define nftnl_expr_set_data nftnl_expr_set + void nftnl_expr_set_u8(struct nftnl_expr *expr, uint16_t type, uint8_t data); + void nftnl_expr_set_u16(struct nftnl_expr *expr, uint16_t type, uint16_t data); +diff --git a/include/libnftnl/set.h b/include/libnftnl/set.h +index cad5e8e..f2edca2 100644 +--- a/include/libnftnl/set.h ++++ b/include/libnftnl/set.h +@@ -131,6 +131,7 @@ void nftnl_set_elem_add(struct nftnl_set *s, struct nftnl_set_elem *elem); + + void nftnl_set_elem_unset(struct nftnl_set_elem *s, uint16_t attr); + int nftnl_set_elem_set(struct nftnl_set_elem *s, uint16_t attr, const void *data, uint32_t data_len); ++int nftnl_set_elem_set_imm(struct nftnl_set_elem *s, uint16_t attr, const void *data, uint32_t data_len, uint32_t byteorder, uint8_t *sizes); + void nftnl_set_elem_set_u32(struct nftnl_set_elem *s, uint16_t attr, uint32_t val); + void nftnl_set_elem_set_u64(struct nftnl_set_elem *s, uint16_t attr, uint64_t val); + int nftnl_set_elem_set_str(struct nftnl_set_elem *s, uint16_t attr, const char *str); +diff --git a/src/expr.c b/src/expr.c +index d07e733..0fec358 100644 +--- a/src/expr.c ++++ b/src/expr.c +@@ -91,6 +91,13 @@ int nftnl_expr_set(struct nftnl_expr *expr, uint16_t type, + return __nftnl_expr_set(expr, type, data, data_len, 0); + } + ++EXPORT_SYMBOL(nftnl_expr_set_imm); ++int nftnl_expr_set_imm(struct nftnl_expr *expr, uint16_t type, ++ const void *data, uint32_t data_len, uint32_t byteorder) ++{ ++ return __nftnl_expr_set(expr, type, data, data_len, byteorder); ++} ++ + EXPORT_SYMBOL(nftnl_expr_set_u8); + void + nftnl_expr_set_u8(struct nftnl_expr *expr, uint16_t type, uint8_t data) +diff --git a/src/libnftnl.map b/src/libnftnl.map +index 8fffff1..ccf1bc4 100644 +--- a/src/libnftnl.map ++++ b/src/libnftnl.map +@@ -383,3 +383,8 @@ LIBNFTNL_16 { + LIBNFTNL_17 { + nftnl_set_elem_nlmsg_build; + } LIBNFTNL_16; ++ ++LIBNFTNL_RHEL_18 { ++ nftnl_expr_set_imm; ++ nftnl_set_elem_set_imm; ++} LIBNFTNL_17; +diff --git a/src/set_elem.c b/src/set_elem.c +index 7ec65b9..86b4752 100644 +--- a/src/set_elem.c ++++ b/src/set_elem.c +@@ -108,9 +108,9 @@ static uint32_t nftnl_set_elem_validate[NFTNL_SET_ELEM_MAX + 1] = { + [NFTNL_SET_ELEM_EXPIRATION] = sizeof(uint64_t), + }; + +-EXPORT_SYMBOL(nftnl_set_elem_set); +-int nftnl_set_elem_set(struct nftnl_set_elem *s, uint16_t attr, +- const void *data, uint32_t data_len) ++static int ++__nftnl_set_elem_set(struct nftnl_set_elem *s, uint16_t attr, const void *data, ++ uint32_t data_len, uint32_t byteorder, uint8_t *sizes) + { + struct nftnl_expr *expr, *tmp; + +@@ -122,11 +122,13 @@ int nftnl_set_elem_set(struct nftnl_set_elem *s, uint16_t attr, + memcpy(&s->set_elem_flags, data, sizeof(s->set_elem_flags)); + break; + case NFTNL_SET_ELEM_KEY: /* NFTA_SET_ELEM_KEY */ +- if (nftnl_data_cpy(&s->key, data, data_len, 0, NULL) < 0) ++ if (nftnl_data_cpy(&s->key, data, ++ data_len, byteorder, sizes) < 0) + return -1; + break; + case NFTNL_SET_ELEM_KEY_END: /* NFTA_SET_ELEM_KEY_END */ +- if (nftnl_data_cpy(&s->key_end, data, data_len, 0, NULL) < 0) ++ if (nftnl_data_cpy(&s->key_end, data, ++ data_len, byteorder, sizes) < 0) + return -1; + break; + case NFTNL_SET_ELEM_VERDICT: /* NFTA_SET_ELEM_DATA */ +@@ -141,7 +143,8 @@ int nftnl_set_elem_set(struct nftnl_set_elem *s, uint16_t attr, + return -1; + break; + case NFTNL_SET_ELEM_DATA: /* NFTA_SET_ELEM_DATA */ +- if (nftnl_data_cpy(&s->data, data, data_len, 0, NULL) < 0) ++ if (nftnl_data_cpy(&s->data, data, ++ data_len, byteorder, sizes) < 0) + return -1; + break; + case NFTNL_SET_ELEM_TIMEOUT: /* NFTA_SET_ELEM_TIMEOUT */ +@@ -180,6 +183,21 @@ int nftnl_set_elem_set(struct nftnl_set_elem *s, uint16_t attr, + return 0; + } + ++EXPORT_SYMBOL(nftnl_set_elem_set); ++int nftnl_set_elem_set(struct nftnl_set_elem *s, uint16_t attr, ++ const void *data, uint32_t data_len) ++{ ++ return __nftnl_set_elem_set(s, attr, data, data_len, 0, NULL); ++} ++ ++EXPORT_SYMBOL(nftnl_set_elem_set_imm); ++int nftnl_set_elem_set_imm(struct nftnl_set_elem *s, uint16_t attr, ++ const void *data, uint32_t data_len, ++ uint32_t byteorder, uint8_t *sizes) ++{ ++ return __nftnl_set_elem_set(s, attr, data, data_len, byteorder, sizes); ++} ++ + EXPORT_SYMBOL(nftnl_set_elem_set_u32); + void nftnl_set_elem_set_u32(struct nftnl_set_elem *s, uint16_t attr, uint32_t val) + { diff --git a/0010-data_reg-Respect-data-byteorder-when-printing.patch b/0010-data_reg-Respect-data-byteorder-when-printing.patch new file mode 100644 index 0000000..2dba4f0 --- /dev/null +++ b/0010-data_reg-Respect-data-byteorder-when-printing.patch @@ -0,0 +1,72 @@ +From d88565eec1a9c5fde538f00a3591f7f8e8fdec9b Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 24 Feb 2026 15:06:55 +0100 +Subject: [PATCH] data_reg: Respect data byteorder when printing + +JIRA: https://issues.redhat.com/browse/RHEL-119650 +Upstream Status: libnftnl commit 84b7adedf98fbf738632d07e585d621588d45500 + +commit 84b7adedf98fbf738632d07e585d621588d45500 +Author: Phil Sutter +Date: Wed Sep 10 17:51:55 2025 +0200 + + data_reg: Respect data byteorder when printing + + Print data from most significant byte to least significant one. Also + print only reg->len bytes of data, not every non-empty u32. Still + separate four byte blocks by whitespace, though. + + Signed-off-by: Phil Sutter + +Signed-off-by: Phil Sutter +--- + src/expr/data_reg.c | 29 +++++++++++++++++++++++------ + 1 file changed, 23 insertions(+), 6 deletions(-) + +diff --git a/src/expr/data_reg.c b/src/expr/data_reg.c +index d1aadcc..de5d235 100644 +--- a/src/expr/data_reg.c ++++ b/src/expr/data_reg.c +@@ -20,19 +20,36 @@ + #include + #include "internal.h" + ++static bool big_endian_host(void) ++{ ++ uint16_t v = 1; ++ ++ return v == htons(v); ++} ++ + static int + nftnl_data_reg_value_snprintf_default(char *buf, size_t remain, + const union nftnl_data_reg *reg, + uint32_t flags) + { + const char *pfx = flags & DATA_F_NOPFX ? "" : "0x", *sep = ""; +- int offset = 0, ret, i; +- +- for (i = 0; i < div_round_up(reg->len, sizeof(uint32_t)); i++) { +- ret = snprintf(buf + offset, remain, +- "%s%s%.8x", sep, pfx, reg->val[i]); ++ bool reverse = reg->byteorder && !big_endian_host(); ++ int offset = 0, ret, i, idx; ++ ++ for (i = 0; i < reg->len; i++) { ++ if ((i % 4) == 0) { ++ ret = snprintf(buf + offset, remain, "%s%s", sep, pfx); ++ SNPRINTF_BUFFER_SIZE(ret, remain, offset); ++ sep = " "; ++ } ++ if (reverse) ++ idx = reg->len - i - 1; ++ else ++ idx = i; ++ ++ ret = snprintf(buf + offset, remain, "%.2x", ++ ((uint8_t *)reg->val)[idx]); + SNPRINTF_BUFFER_SIZE(ret, remain, offset); +- sep = " "; + } + + return offset; diff --git a/0011-data_reg-Support-concatenated-data.patch b/0011-data_reg-Support-concatenated-data.patch new file mode 100644 index 0000000..befa5af --- /dev/null +++ b/0011-data_reg-Support-concatenated-data.patch @@ -0,0 +1,102 @@ +From f5309200e4fd545a6375d6f8d20a9f8e5a1985ce Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 24 Feb 2026 15:06:55 +0100 +Subject: [PATCH] data_reg: Support concatenated data + +JIRA: https://issues.redhat.com/browse/RHEL-119650 +Upstream Status: libnftnl commit 4562e2418575d58df36d214c242f5d04613f52dd + +commit 4562e2418575d58df36d214c242f5d04613f52dd +Author: Phil Sutter +Date: Tue Oct 14 15:56:26 2025 +0200 + + data_reg: Support concatenated data + + If sizes array has non-zero field values, interpret byteorder field as + bitfield indicating each compontent's byteorder and print the components + separated by a dot. + + Signed-off-by: Phil Sutter + +Signed-off-by: Phil Sutter +--- + src/expr/data_reg.c | 48 +++++++++++++++++++++++++++++++++++---------- + 1 file changed, 38 insertions(+), 10 deletions(-) + +diff --git a/src/expr/data_reg.c b/src/expr/data_reg.c +index de5d235..d01e0f7 100644 +--- a/src/expr/data_reg.c ++++ b/src/expr/data_reg.c +@@ -27,34 +27,62 @@ static bool big_endian_host(void) + return v == htons(v); + } + +-static int +-nftnl_data_reg_value_snprintf_default(char *buf, size_t remain, +- const union nftnl_data_reg *reg, +- uint32_t flags) ++static int __reg_value_snprintf(char *buf, size_t remain, ++ uint8_t *data, size_t datalen, ++ bool reverse, const char *pfx) + { +- const char *pfx = flags & DATA_F_NOPFX ? "" : "0x", *sep = ""; +- bool reverse = reg->byteorder && !big_endian_host(); + int offset = 0, ret, i, idx; ++ const char *sep = ""; + +- for (i = 0; i < reg->len; i++) { ++ for (i = 0; i < datalen; i++) { + if ((i % 4) == 0) { + ret = snprintf(buf + offset, remain, "%s%s", sep, pfx); + SNPRINTF_BUFFER_SIZE(ret, remain, offset); + sep = " "; + } + if (reverse) +- idx = reg->len - i - 1; ++ idx = datalen - i - 1; + else + idx = i; + +- ret = snprintf(buf + offset, remain, "%.2x", +- ((uint8_t *)reg->val)[idx]); ++ ret = snprintf(buf + offset, remain, "%.2x", data[idx]); + SNPRINTF_BUFFER_SIZE(ret, remain, offset); + } + + return offset; + } + ++static int ++nftnl_data_reg_value_snprintf_default(char *buf, size_t remain, ++ const union nftnl_data_reg *reg, ++ uint32_t flags) ++{ ++ uint32_t byteorder = big_endian_host() ? 0 : reg->byteorder; ++ const char *pfx = flags & DATA_F_NOPFX ? "" : "0x"; ++ int offset = 0, ret, i, pos = 0; ++ ++ for (i = 0; i < array_size(reg->sizes); i++) { ++ int curlen = reg->sizes[i] ?: reg->len; ++ bool reverse = byteorder & (1 << i); ++ ++ if (i > 0) { ++ ret = snprintf(buf + offset, remain, " . "); ++ SNPRINTF_BUFFER_SIZE(ret, remain, offset); ++ } ++ ++ ret = __reg_value_snprintf(buf + offset, remain, ++ (void *)®->val[pos], ++ curlen, reverse, pfx); ++ SNPRINTF_BUFFER_SIZE(ret, remain, offset); ++ ++ pos += div_round_up(curlen, sizeof(uint32_t)); ++ if (pos >= reg->len / sizeof(uint32_t)) ++ break; ++ } ++ ++ return offset; ++} ++ + static int + nftnl_data_reg_verdict_snprintf_def(char *buf, size_t size, + const union nftnl_data_reg *reg, diff --git a/0012-udata-Store-u32-udata-values-in-Big-Endian.patch b/0012-udata-Store-u32-udata-values-in-Big-Endian.patch new file mode 100644 index 0000000..51c09b6 --- /dev/null +++ b/0012-udata-Store-u32-udata-values-in-Big-Endian.patch @@ -0,0 +1,56 @@ +From 787affd697749be3920017a39097c0bdb0354e03 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 24 Feb 2026 15:06:55 +0100 +Subject: [PATCH] udata: Store u32 udata values in Big Endian + +JIRA: https://issues.redhat.com/browse/RHEL-119650 +Upstream Status: libnftnl commit f20dfa7824860a9ac14425a3f7ca970a6c981597 + +commit f20dfa7824860a9ac14425a3f7ca970a6c981597 +Author: Phil Sutter +Date: Fri Oct 17 18:08:11 2025 +0200 + + udata: Store u32 udata values in Big Endian + + Avoid deviation of this data in between different byte orders. Assume + that direct callers of nftnl_udata_put() know what they do. + + Signed-off-by: Phil Sutter + +Signed-off-by: Phil Sutter +--- + src/udata.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/src/udata.c b/src/udata.c +index a195657..8cf4e7c 100644 +--- a/src/udata.c ++++ b/src/udata.c +@@ -8,6 +8,7 @@ + #include + #include + ++#include + #include + #include + #include +@@ -100,7 +101,9 @@ EXPORT_SYMBOL(nftnl_udata_put_u32); + bool nftnl_udata_put_u32(struct nftnl_udata_buf *buf, uint8_t type, + uint32_t data) + { +- return nftnl_udata_put(buf, type, sizeof(data), &data); ++ uint32_t data_be = htonl(data); ++ ++ return nftnl_udata_put(buf, type, sizeof(data_be), &data_be); + } + + EXPORT_SYMBOL(nftnl_udata_type); +@@ -128,7 +131,7 @@ uint32_t nftnl_udata_get_u32(const struct nftnl_udata *attr) + + memcpy(&data, attr->value, sizeof(data)); + +- return data; ++ return ntohl(data); + } + + EXPORT_SYMBOL(nftnl_udata_next); diff --git a/0013-Revert-udata-Store-u32-udata-values-in-Big-Endian.patch b/0013-Revert-udata-Store-u32-udata-values-in-Big-Endian.patch new file mode 100644 index 0000000..1e688a6 --- /dev/null +++ b/0013-Revert-udata-Store-u32-udata-values-in-Big-Endian.patch @@ -0,0 +1,59 @@ +From 0302fcd912efc9b45eb1a5f2af4dc5f94f6b6c28 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 24 Feb 2026 15:06:55 +0100 +Subject: [PATCH] Revert "udata: Store u32 udata values in Big Endian" + +JIRA: https://issues.redhat.com/browse/RHEL-119650 +Upstream Status: libnftnl commit b587e4a7bbc8d6b574545617f2639dbd8905ec5d + +commit b587e4a7bbc8d6b574545617f2639dbd8905ec5d +Author: Phil Sutter +Date: Thu Jan 29 14:24:49 2026 +0100 + + Revert "udata: Store u32 udata values in Big Endian" + + This reverts commit f20dfa7824860a9ac14425a3f7ca970a6c981597. + + This change to payload (interpretation) is problematic with package + updates at run-time: The new version might trip over userdata in the + running ruleset, avoid this. + + Signed-off-by: Phil Sutter + +Signed-off-by: Phil Sutter +--- + src/udata.c | 7 ++----- + 1 file changed, 2 insertions(+), 5 deletions(-) + +diff --git a/src/udata.c b/src/udata.c +index 8cf4e7c..a195657 100644 +--- a/src/udata.c ++++ b/src/udata.c +@@ -8,7 +8,6 @@ + #include + #include + +-#include + #include + #include + #include +@@ -101,9 +100,7 @@ EXPORT_SYMBOL(nftnl_udata_put_u32); + bool nftnl_udata_put_u32(struct nftnl_udata_buf *buf, uint8_t type, + uint32_t data) + { +- uint32_t data_be = htonl(data); +- +- return nftnl_udata_put(buf, type, sizeof(data_be), &data_be); ++ return nftnl_udata_put(buf, type, sizeof(data), &data); + } + + EXPORT_SYMBOL(nftnl_udata_type); +@@ -131,7 +128,7 @@ uint32_t nftnl_udata_get_u32(const struct nftnl_udata *attr) + + memcpy(&data, attr->value, sizeof(data)); + +- return ntohl(data); ++ return data; + } + + EXPORT_SYMBOL(nftnl_udata_next); diff --git a/0014-src-Do-not-include-userdata-content-in-debug-output.patch b/0014-src-Do-not-include-userdata-content-in-debug-output.patch new file mode 100644 index 0000000..239ec3d --- /dev/null +++ b/0014-src-Do-not-include-userdata-content-in-debug-output.patch @@ -0,0 +1,126 @@ +From 6e53b109d8f565bb84b82ac8462959ae60e4b1a0 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 24 Feb 2026 15:06:55 +0100 +Subject: [PATCH] src: Do not include userdata content in debug output + +JIRA: https://issues.redhat.com/browse/RHEL-119650 +Upstream Status: libnftnl commit 5c5a8385dc974ea7887119963022ae988e2a16cc +Conflicts: Context change due to missing nftnl_parse_str_attr() in RHEL. + +commit 5c5a8385dc974ea7887119963022ae988e2a16cc +Author: Phil Sutter +Date: Thu Jan 29 00:08:27 2026 +0100 + + src: Do not include userdata content in debug output + + This storage in rules and set elements is opaque by design, neither + libnftnl nor kernel should deal with its content. Yet nftables enters data + in host byte order which will lead to changing output depending on + host's byte order. Avoid this problem for test suites checking the debug + output by merely printing the number and sum of all the bytes in the + buffer. This likely detects changes in userdata but deliberately ignores + data reordering. + + Signed-off-by: Phil Sutter + +Signed-off-by: Phil Sutter +--- + include/utils.h | 10 ++++++++++ + src/rule.c | 19 ++++--------------- + src/set_elem.c | 18 ++++-------------- + 3 files changed, 18 insertions(+), 29 deletions(-) + +diff --git a/include/utils.h b/include/utils.h +index 5a3379f..bfa3336 100644 +--- a/include/utils.h ++++ b/include/utils.h +@@ -88,4 +88,14 @@ struct nlattr; + void nftnl_attr_put_ifname(struct nlmsghdr *nlh, const char *ifname); + char *nftnl_attr_get_ifname(const struct nlattr *attr); + ++static inline uint32_t bytesum(uint8_t *buf, size_t buflen) ++{ ++ uint32_t ret = 0; ++ ++ while (buflen--) ++ ret += buf[buflen]; ++ ++ return ret; ++} ++ + #endif +diff --git a/src/rule.c b/src/rule.c +index 3948a74..283cac9 100644 +--- a/src/rule.c ++++ b/src/rule.c +@@ -519,8 +519,8 @@ static int nftnl_rule_snprintf_default(char *buf, size_t remain, + uint32_t type, uint32_t flags) + { + struct nftnl_expr *expr; +- int ret, offset = 0, i; + const char *sep = ""; ++ int ret, offset = 0; + + if (r->flags & (1 << NFTNL_RULE_FAMILY)) { + ret = snprintf(buf + offset, remain, "%s%s", sep, +@@ -583,21 +583,10 @@ static int nftnl_rule_snprintf_default(char *buf, size_t remain, + } + + if (r->user.len) { +- ret = snprintf(buf + offset, remain, "\n userdata = { "); +- SNPRINTF_BUFFER_SIZE(ret, remain, offset); +- +- for (i = 0; i < r->user.len; i++) { +- char *c = r->user.data; +- +- ret = snprintf(buf + offset, remain, +- isprint(c[i]) ? "%c" : "\\x%02hhx", +- c[i]); +- SNPRINTF_BUFFER_SIZE(ret, remain, offset); +- } +- +- ret = snprintf(buf + offset, remain, " }"); ++ ret = snprintf(buf + offset, remain, ++ "\n userdata len %d sum 0x%x", ++ r->user.len, bytesum(r->user.data, r->user.len)); + SNPRINTF_BUFFER_SIZE(ret, remain, offset); +- + } + + return offset; +diff --git a/src/set_elem.c b/src/set_elem.c +index 86b4752..4a092f8 100644 +--- a/src/set_elem.c ++++ b/src/set_elem.c +@@ -717,7 +717,7 @@ int nftnl_set_elem_parse_file(struct nftnl_set_elem *e, enum nftnl_parse_type ty + int nftnl_set_elem_snprintf_default(char *buf, size_t remain, + const struct nftnl_set_elem *e) + { +- int ret, dregtype = DATA_NONE, offset = 0, i; ++ int ret, dregtype = DATA_NONE, offset = 0; + + ret = snprintf(buf, remain, "element "); + SNPRINTF_BUFFER_SIZE(ret, remain, offset); +@@ -760,19 +760,9 @@ int nftnl_set_elem_snprintf_default(char *buf, size_t remain, + } + + if (e->user.len) { +- ret = snprintf(buf + offset, remain, " userdata = { "); +- SNPRINTF_BUFFER_SIZE(ret, remain, offset); +- +- for (i = 0; i < e->user.len; i++) { +- char *c = e->user.data; +- +- ret = snprintf(buf + offset, remain, +- isprint(c[i]) ? "%c" : "\\x%02hhx", +- c[i]); +- SNPRINTF_BUFFER_SIZE(ret, remain, offset); +- } +- +- ret = snprintf(buf + offset, remain, " }"); ++ ret = snprintf(buf + offset, remain, ++ " userdata len %d sum 0x%x", ++ e->user.len, bytesum(e->user.data, e->user.len)); + SNPRINTF_BUFFER_SIZE(ret, remain, offset); + } + diff --git a/libnftnl.spec b/libnftnl.spec index fa1f238..d4c695d 100644 --- a/libnftnl.spec +++ b/libnftnl.spec @@ -1,14 +1,25 @@ Name: libnftnl -Version: 1.2.8 -Release: 4%{?dist} +Version: 1.3.0 +Release: 3%{?dist} Summary: Library for low-level interaction with nftables Netlink's API over libmnl License: GPL-2.0-or-later URL: https://netfilter.org/projects/libnftnl/ Source0: %{url}/files/%{name}-%{version}.tar.xz -Patch1: 0001-set-Fix-for-array-overrun-when-setting-NFTNL_SET_DES.patch -Patch2: 0002-trace-add-support-for-TRACE_CT-information.patch -Patch3: 0003-udata-Introduce-NFTNL_UDATA_TABLE_NFT-VER-BLD.patch +Patch1: 0001-udata-Introduce-NFTNL_UDATA_TABLE_NFT-VER-BLD.patch +Patch2: 0002-utils-Add-helpers-for-interface-name-wildcards.patch +Patch3: 0003-utils-Drop-asterisk-from-end-of-NFTA_DEVICE_PREFIX-s.patch +Patch4: 0004-set_elem-Review-debug-output.patch +Patch5: 0005-expr-data_reg-Avoid-extra-whitespace.patch +Patch6: 0006-expr-Pass-byteorder-to-struct-expr_ops-set-callback.patch +Patch7: 0007-data_reg-Introduce-struct-nftnl_data_reg-byteorder-f.patch +Patch8: 0008-data_reg-Introduce-struct-nftnl_data_reg-sizes-array.patch +Patch9: 0009-Introduce-nftnl_-expr-set_elem-_set_imm.patch +Patch10: 0010-data_reg-Respect-data-byteorder-when-printing.patch +Patch11: 0011-data_reg-Support-concatenated-data.patch +Patch12: 0012-udata-Store-u32-udata-values-in-Big-Endian.patch +Patch13: 0013-Revert-udata-Store-u32-udata-values-in-Big-Endian.patch +Patch14: 0014-src-Do-not-include-userdata-content-in-debug-output.patch BuildRequires: libmnl-devel BuildRequires: gcc @@ -57,6 +68,29 @@ find $RPM_BUILD_ROOT -name '*.la' -exec rm -f {} ';' %{_includedir}/libnftnl %changelog +* Tue Feb 24 2026 Phil Sutter [1.3.0-3.el10] +- src: Do not include userdata content in debug output (Phil Sutter) [RHEL-119650] +- Revert "udata: Store u32 udata values in Big Endian" (Phil Sutter) [RHEL-119650] +- udata: Store u32 udata values in Big Endian (Phil Sutter) [RHEL-119650] +- data_reg: Support concatenated data (Phil Sutter) [RHEL-119650] +- data_reg: Respect data byteorder when printing (Phil Sutter) [RHEL-119650] +- Introduce nftnl_{expr,set_elem}_set_imm() (Phil Sutter) [RHEL-119650] +- data_reg: Introduce struct nftnl_data_reg::sizes array (Phil Sutter) [RHEL-119650] +- data_reg: Introduce struct nftnl_data_reg::byteorder field (Phil Sutter) [RHEL-119650] +- expr: Pass byteorder to struct expr_ops::set callback (Phil Sutter) [RHEL-119650] +- expr: data_reg: Avoid extra whitespace (Phil Sutter) [RHEL-119650] +- set_elem: Review debug output (Phil Sutter) [RHEL-119650] + +* Thu Nov 27 2025 Phil Sutter [1.3.0-2.el10] +- utils: Drop asterisk from end of NFTA_DEVICE_PREFIX strings (Phil Sutter) [RHEL-108860] +- utils: Add helpers for interface name wildcards (Phil Sutter) [RHEL-108860] + +* Thu Nov 20 2025 Phil Sutter [1.3.0-1.el10] +- Rebase onto version 1.3.0 (Phil Sutter) [RHEL-121193] + +* Thu Oct 30 2025 Phil Sutter [1.2.8-5.el10] +- Bump release for a side-tag build (Phil Sutter) [RHEL-125122] + * Wed Sep 10 2025 Phil Sutter [1.2.8-4.el10] - udata: Introduce NFTNL_UDATA_TABLE_NFT{VER,BLD} (Phil Sutter) [RHEL-113823] diff --git a/sources b/sources index 7dffdf8..db07b00 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (libnftnl-1.2.8.tar.xz) = c57030f34c50b09ae2fbf8dac5d9cf431eaaa5a5a08098e3e4c146a8bd4ae9b7753f5d2de5f2d0a6c15e5ba0c39f51275c9d8b03bdedeaadbafa6c96f9a972b6 +SHA512 (libnftnl-1.3.0.tar.xz) = a2220dba97cc9a1bbd0d093a0bd0afd491120a814be6343aef35cbeba0e4781289fa84ced36510b6b9d76e99b3ba35f3964a9a40a21f38e2e0fad90c34fd3916