nftables/0001-table-Embed-creating-nft-version-into-userdata.patch
Phil Sutter ab440e86fa nftables-1.1.5-1.el10
* Thu Nov 20 2025 Phil Sutter <psutter@redhat.com> [1.1.5-1.el10]
- doc: libnftables-json: Describe RULESET object (Phil Sutter) [RHEL-121194]
- doc: don't suggest to disable GSO (Phil Sutter) [RHEL-121194]
- build: don't install ancillary files without systemd service file (Phil Sutter) [RHEL-121194]
- tests: shell: fix typo in vmap_timeout test script (Phil Sutter) [RHEL-121194]
- tests: py: inet/osf.t: Fix element ordering in JSON equivalents (Phil Sutter) [RHEL-121194]
- tests: py: any/ct.t.json.output: Drop leftover entry (Phil Sutter) [RHEL-121194]
- tests: py: any/tcpopt.t.json: Fix JSON equivalent (Phil Sutter) [RHEL-121194]
- optimize: Fix verdict expression comparison (Phil Sutter) [RHEL-121194]
- datatype: Fix boolean type on Big Endian (Phil Sutter) [RHEL-121194]
- src: parser_json: fix format string bugs (Phil Sutter) [RHEL-121194]
- doc: fix tcpdump example (Phil Sutter) [RHEL-121194]
- libnftables: do not re-add default include directory in include search path (Phil Sutter) [RHEL-121194]
- monitor: Inform JSON printer when reporting an object delete event (Phil Sutter) [RHEL-121194]
- tests: shell: skip two bitwise tests if multi-register support isn't available (Phil Sutter) [RHEL-121194]
- tests: monitor: Fix regex collecting expected echo output (Phil Sutter) [RHEL-121194]
- monitor: Quote device names in chain declarations, too (Phil Sutter) [RHEL-121194]
- tools: gitignore nftables.service file (Phil Sutter) [RHEL-121194]
- parser_bison: remove leftover utf-8 character in error (Phil Sutter) [RHEL-121194]
- Rebase onto version 1.1.5 (Phil Sutter) [RHEL-121194]
Resolves: RHEL-121194
2025-11-20 20:23:40 +01:00

232 lines
6.9 KiB
Diff

From df4f84d17daf107d9dc21d5b42ae6255b53f0ffd Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Tue, 9 Sep 2025 16:49:27 +0200
Subject: [PATCH] table: Embed creating nft version into userdata
JIRA: https://issues.redhat.com/browse/RHEL-108851
Upstream Status: nftables commit 64c07e38f0494093a399a68a31056f5866c4d705
commit 64c07e38f0494093a399a68a31056f5866c4d705
Author: Phil Sutter <phil@nwl.cc>
Date: Mon May 12 22:59:26 2025 +0200
table: Embed creating nft version into userdata
Upon listing a table which was created by a newer version of nftables,
warn about the potentially incomplete content.
Suggested-by: Florian Westphal <fw@strlen.de>
Cc: Dan Winship <danwinship@redhat.com>
Signed-off-by: Phil Sutter <phil@nwl.cc>
Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
Makefile.am | 3 +++
configure.ac | 24 ++++++++++++++++++++++++
include/rule.h | 1 +
src/mnl.c | 21 +++++++++++++++------
src/netlink.c | 33 +++++++++++++++++++++++++++++++++
src/rule.c | 4 ++++
6 files changed, 80 insertions(+), 6 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index e292d3b..243071e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -33,6 +33,7 @@ sbin_PROGRAMS =
check_PROGRAMS =
dist_man_MANS =
CLEANFILES =
+DISTCLEANFILES =
###############################################################################
@@ -106,6 +107,8 @@ noinst_HEADERS = \
\
$(NULL)
+DISTCLEANFILES += nftversion.h
+
###############################################################################
AM_CPPFLAGS = \
diff --git a/configure.ac b/configure.ac
index 3a751cb..da16a6e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -131,6 +131,30 @@ AC_ARG_WITH([unitdir],
)
AC_SUBST([unitdir])
+AC_ARG_WITH([stable-release], [AS_HELP_STRING([--with-stable-release],
+ [Stable release number])],
+ [], [with_stable_release=0])
+AC_CONFIG_COMMANDS([stable_release],
+ [STABLE_RELEASE=$stable_release],
+ [stable_release=$with_stable_release])
+AC_CONFIG_COMMANDS([nftversion.h], [
+(
+ echo "static char nftversion[[]] = {"
+ echo " ${VERSION}," | tr '.' ','
+ echo " ${STABLE_RELEASE}"
+ echo "};"
+ echo "static char nftbuildstamp[[]] = {"
+ for ((i = 56; i >= 0; i-= 8)); do
+ echo " ((uint64_t)MAKE_STAMP >> $i) & 0xff,"
+ done
+ echo "};"
+) >nftversion.h
+])
+# Current date should be fetched exactly once per build,
+# so have 'make' call date and pass the value to every 'gcc' call
+AC_SUBST([MAKE_STAMP], ["\$(shell date +%s)"])
+CFLAGS="${CFLAGS} -DMAKE_STAMP=\${MAKE_STAMP}"
+
AC_CONFIG_FILES([ \
Makefile \
libnftables.pc \
diff --git a/include/rule.h b/include/rule.h
index 470ae10..319f9c3 100644
--- a/include/rule.h
+++ b/include/rule.h
@@ -170,6 +170,7 @@ struct table {
uint32_t owner;
const char *comment;
bool has_xt_stmts;
+ bool is_from_future;
};
extern struct table *table_alloc(void);
diff --git a/src/mnl.c b/src/mnl.c
index 892fb8b..25cd872 100644
--- a/src/mnl.c
+++ b/src/mnl.c
@@ -10,6 +10,7 @@
#include <nft.h>
#include <iface.h>
+#include <nftversion.h>
#include <libmnl/libmnl.h>
#include <libnftnl/common.h>
@@ -1082,24 +1083,32 @@ int mnl_nft_table_add(struct netlink_ctx *ctx, struct cmd *cmd,
if (nlt == NULL)
memory_allocation_error();
+ udbuf = nftnl_udata_buf_alloc(NFT_USERDATA_MAXLEN);
+ if (!udbuf)
+ memory_allocation_error();
+
nftnl_table_set_u32(nlt, NFTNL_TABLE_FAMILY, cmd->handle.family);
if (cmd->table) {
nftnl_table_set_u32(nlt, NFTNL_TABLE_FLAGS, cmd->table->flags);
if (cmd->table->comment) {
- udbuf = nftnl_udata_buf_alloc(NFT_USERDATA_MAXLEN);
- if (!udbuf)
- memory_allocation_error();
if (!nftnl_udata_put_strz(udbuf, NFTNL_UDATA_TABLE_COMMENT, cmd->table->comment))
memory_allocation_error();
- nftnl_table_set_data(nlt, NFTNL_TABLE_USERDATA, nftnl_udata_buf_data(udbuf),
- nftnl_udata_buf_len(udbuf));
- nftnl_udata_buf_free(udbuf);
}
} else {
nftnl_table_set_u32(nlt, NFTNL_TABLE_FLAGS, 0);
}
+ if (!nftnl_udata_put(udbuf, NFTNL_UDATA_TABLE_NFTVER,
+ sizeof(nftversion), nftversion) ||
+ !nftnl_udata_put(udbuf, NFTNL_UDATA_TABLE_NFTBLD,
+ sizeof(nftbuildstamp), nftbuildstamp))
+ memory_allocation_error();
+ nftnl_table_set_data(nlt, NFTNL_TABLE_USERDATA,
+ nftnl_udata_buf_data(udbuf),
+ nftnl_udata_buf_len(udbuf));
+ nftnl_udata_buf_free(udbuf);
+
nlh = nftnl_nlmsg_build_hdr(nftnl_batch_buffer(ctx->batch),
NFT_MSG_NEWTABLE,
cmd->handle.family,
diff --git a/src/netlink.c b/src/netlink.c
index 94cbcbf..b5da33e 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -10,6 +10,7 @@
*/
#include <nft.h>
+#include <nftversion.h>
#include <errno.h>
#include <libmnl/libmnl.h>
@@ -799,6 +800,14 @@ static int table_parse_udata_cb(const struct nftnl_udata *attr, void *data)
if (value[len - 1] != '\0')
return -1;
break;
+ case NFTNL_UDATA_TABLE_NFTVER:
+ if (len != sizeof(nftversion))
+ return -1;
+ break;
+ case NFTNL_UDATA_TABLE_NFTBLD:
+ if (len != sizeof(nftbuildstamp))
+ return -1;
+ break;
default:
return 0;
}
@@ -806,6 +815,29 @@ static int table_parse_udata_cb(const struct nftnl_udata *attr, void *data)
return 0;
}
+static int version_cmp(const struct nftnl_udata **ud)
+{
+ const char *udbuf;
+ size_t i;
+
+ /* netlink attribute lengths checked by table_parse_udata_cb() */
+ if (ud[NFTNL_UDATA_TABLE_NFTVER]) {
+ udbuf = nftnl_udata_get(ud[NFTNL_UDATA_TABLE_NFTVER]);
+ for (i = 0; i < sizeof(nftversion); i++) {
+ if (nftversion[i] != udbuf[i])
+ return nftversion[i] - udbuf[i];
+ }
+ }
+ if (ud[NFTNL_UDATA_TABLE_NFTBLD]) {
+ udbuf = nftnl_udata_get(ud[NFTNL_UDATA_TABLE_NFTBLD]);
+ for (i = 0; i < sizeof(nftbuildstamp); i++) {
+ if (nftbuildstamp[i] != udbuf[i])
+ return nftbuildstamp[i] - udbuf[i];
+ }
+ }
+ return 0;
+}
+
struct table *netlink_delinearize_table(struct netlink_ctx *ctx,
const struct nftnl_table *nlt)
{
@@ -830,6 +862,7 @@ struct table *netlink_delinearize_table(struct netlink_ctx *ctx,
}
if (ud[NFTNL_UDATA_TABLE_COMMENT])
table->comment = xstrdup(nftnl_udata_get(ud[NFTNL_UDATA_TABLE_COMMENT]));
+ table->is_from_future = version_cmp(ud) < 0;
}
return table;
diff --git a/src/rule.c b/src/rule.c
index 0ad948e..398e5bd 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -1298,6 +1298,10 @@ static void table_print(const struct table *table, struct output_ctx *octx)
fprintf(octx->error_fp,
"# Warning: table %s %s is managed by iptables-nft, do not touch!\n",
family, table->handle.table.name);
+ if (table->is_from_future)
+ fprintf(octx->error_fp,
+ "# Warning: table %s %s was created by a newer version of nftables? Content may be incomplete!\n",
+ family, table->handle.table.name);
nft_print(octx, "table %s %s {", family, table->handle.table.name);
if (nft_output_handle(octx) || table->flags & TABLE_F_OWNER)