[nft RFC] table: Embed creating nft version into userdata

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Upon listing a table which was created by a newer version of nftables,
warn about the potentially incomplete content.

Suggested-by: Florian Westphal <fw@xxxxxxxxx>
Cc: Dan Winship <danwinship@xxxxxxxxxx>
Signed-off-by: Phil Sutter <phil@xxxxxx>
---
 include/nft.h  |  2 ++
 include/rule.h |  1 +
 src/mnl.c      | 18 ++++++++++++------
 src/netlink.c  | 25 ++++++++++++++++++++++++-
 src/rule.c     |  4 ++++
 5 files changed, 43 insertions(+), 7 deletions(-)

diff --git a/include/nft.h b/include/nft.h
index a2d62dbf4808a..b406a68ffeb18 100644
--- a/include/nft.h
+++ b/include/nft.h
@@ -15,4 +15,6 @@
  * something we frequently need to do and it's intentional. */
 #define free_const(ptr) free((void *)(ptr))
 
+#define NFTNL_UDATA_TABLE_NFTVER 1
+
 #endif /* NFTABLES_NFT_H */
diff --git a/include/rule.h b/include/rule.h
index 85a0d9c0b524b..c4fecb2a8faeb 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 ee51933798580..174e97ccb74f6 100644
--- a/src/mnl.c
+++ b/src/mnl.c
@@ -1069,24 +1069,30 @@ 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_strz(udbuf, NFTNL_UDATA_TABLE_NFTVER,
+				  PACKAGE_VERSION))
+		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 86ca32144f029..88d4cf73352f6 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -751,6 +751,7 @@ static int table_parse_udata_cb(const struct nftnl_udata *attr, void *data)
 
 	switch (type) {
 		case NFTNL_UDATA_TABLE_COMMENT:
+		case NFTNL_UDATA_TABLE_NFTVER:
 			if (value[len - 1] != '\0')
 				return -1;
 			break;
@@ -761,10 +762,28 @@ static int table_parse_udata_cb(const struct nftnl_udata *attr, void *data)
 	return 0;
 }
 
+static int version_cmp(const char *ver_a, const char *ver_b)
+{
+	int ax, ay, az, bx, by, bz;
+
+	if (sscanf(ver_a, "%d.%d.%d", &ax, &ay, &az) != 3 ||
+	    sscanf(ver_b, "%d.%d.%d", &bx, &by, &bz) != 3)
+		return 0;
+
+	if (ax != bx)
+		return ax - bx;
+	if (ay != by)
+		return ay - by;
+	if (az != bz)
+		return az - bz;
+
+	return strcmp(ver_a, ver_b);
+}
+
 struct table *netlink_delinearize_table(struct netlink_ctx *ctx,
 					const struct nftnl_table *nlt)
 {
-	const struct nftnl_udata *ud[NFTNL_UDATA_TABLE_MAX + 1] = {};
+	const struct nftnl_udata *ud[NFTNL_UDATA_TABLE_MAX + 2] = {}, *udtmp;
 	struct table *table;
 	const char *udata;
 	uint32_t ulen;
@@ -785,6 +804,10 @@ 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]));
+		udtmp = ud[NFTNL_UDATA_TABLE_NFTVER];
+		if (udtmp && version_cmp(PACKAGE_VERSION,
+					 nftnl_udata_get(udtmp)) < 0)
+			table->is_from_future = true;
 	}
 
 	return table;
diff --git a/src/rule.c b/src/rule.c
index 80315837baf06..9b9a7e1e080ab 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -1285,6 +1285,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)
-- 
2.49.0





[Index of Archives]     [Netfitler Users]     [Berkeley Packet Filter]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux