nftables-1.0.4-5.el8

* Wed Aug 14 2024 Phil Sutter <psutter@redhat.com> [1.0.4-5.el8]
- xt: Fix fallback printing for extensions matching keywords (Phil Sutter) [RHEL-5806]
- xt: Fall back to generic printing from translation (Phil Sutter) [RHEL-5806]
- xt: Rewrite unsupported compat expression dumping (Phil Sutter) [RHEL-5806]
- xt: Purify enum nft_xt_type (Phil Sutter) [RHEL-5806]
- xt: Delay libxtables access until translation (Phil Sutter) [RHEL-5806]
- Warn for tables with compat expressions in rules (Phil Sutter) [RHEL-5806]
Resolves: RHEL-5806
This commit is contained in:
Phil Sutter 2024-08-14 16:25:11 +02:00
parent 85e363f157
commit 2f6aefdd21
7 changed files with 969 additions and 1 deletions

View File

@ -0,0 +1,106 @@
From 87b57721997aaa9f3938d2f700e13879b5cb9f72 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Wed, 14 Aug 2024 16:20:37 +0200
Subject: [PATCH] Warn for tables with compat expressions in rules
JIRA: https://issues.redhat.com/browse/RHEL-5806
Upstream Status: nftables commit c327e9331e50d7b4d6cfd0a82fb38bec73703bfb
commit c327e9331e50d7b4d6cfd0a82fb38bec73703bfb
Author: Phil Sutter <phil@nwl.cc>
Date: Tue Oct 11 18:46:55 2022 +0200
Warn for tables with compat expressions in rules
While being able to "look inside" compat expressions using nft is a nice
feature, it is also (yet another) pitfall for unaware users, deceiving
them into assuming interchangeability (or at least compatibility)
between iptables-nft and nft.
In reality, which involves 'nft list ruleset | nft -f -', any correctly
translated compat expressions will turn into native nftables ones not
understood by (the version of) iptables-nft which created them in the
first place. Other compat expressions will vanish, potentially
compromising the firewall ruleset.
Emit a warning (as comment) to give users a chance to stop and
reconsider before shooting their own foot.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
include/rule.h | 1 +
src/rule.c | 16 +++++++++++++---
src/xt.c | 2 ++
3 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/include/rule.h b/include/rule.h
index 9081225..c77146a 100644
--- a/include/rule.h
+++ b/include/rule.h
@@ -169,6 +169,7 @@ struct table {
unsigned int refcnt;
uint32_t owner;
const char *comment;
+ bool has_xt_stmts;
};
extern struct table *table_alloc(void);
diff --git a/src/rule.c b/src/rule.c
index 3b60cca..2fe29b1 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -1227,6 +1227,11 @@ static void table_print(const struct table *table, struct output_ctx *octx)
const char *delim = "";
const char *family = family2str(table->handle.family);
+ if (table->has_xt_stmts)
+ fprintf(octx->error_fp,
+ "# Warning: table %s %s is managed by iptables-nft, do not touch!\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)
nft_print(octx, " #");
@@ -2373,9 +2378,14 @@ static int do_list_tables(struct netlink_ctx *ctx, struct cmd *cmd)
static void table_print_declaration(struct table *table,
struct output_ctx *octx)
{
- nft_print(octx, "table %s %s {\n",
- family2str(table->handle.family),
- table->handle.table.name);
+ const char *family = family2str(table->handle.family);
+
+ if (table->has_xt_stmts)
+ fprintf(octx->error_fp,
+ "# Warning: table %s %s is managed by iptables-nft, do not touch!\n",
+ family, table->handle.table.name);
+
+ nft_print(octx, "table %s %s {\n", family, table->handle.table.name);
}
static int do_list_chain(struct netlink_ctx *ctx, struct cmd *cmd,
diff --git a/src/xt.c b/src/xt.c
index 789de99..a541735 100644
--- a/src/xt.c
+++ b/src/xt.c
@@ -238,6 +238,7 @@ void netlink_parse_match(struct netlink_parse_ctx *ctx,
stmt->xt.name = strdup(name);
stmt->xt.type = NFT_XT_MATCH;
#endif
+ ctx->table->has_xt_stmts = true;
rule_stmt_append(ctx->rule, stmt);
}
@@ -283,6 +284,7 @@ void netlink_parse_target(struct netlink_parse_ctx *ctx,
stmt->xt.name = strdup(name);
stmt->xt.type = NFT_XT_TARGET;
#endif
+ ctx->table->has_xt_stmts = true;
rule_stmt_append(ctx->rule, stmt);
}
--
2.45.0

View File

@ -0,0 +1,348 @@
From 2664d616defd4f63edba2cabe7966d092ea6569f Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Wed, 14 Aug 2024 16:20:37 +0200
Subject: [PATCH] xt: Delay libxtables access until translation
JIRA: https://issues.redhat.com/browse/RHEL-5806
Upstream Status: nftables commit 5c30feeee5cfee74840444b63329fa5a13b471d2
commit 5c30feeee5cfee74840444b63329fa5a13b471d2
Author: Phil Sutter <phil@nwl.cc>
Date: Thu Nov 10 18:44:43 2022 +0100
xt: Delay libxtables access until translation
There is no point in spending efforts setting up the xt match/target
when it is not printed afterwards. So just store the statement data from
libnftnl in struct xt_stmt and perform the extension lookup from
xt_stmt_xlate() instead.
This means some data structures are only temporarily allocated for the
sake of passing to libxtables callbacks, no need to drag them around.
Also no need to clone the looked up extension, it is needed only to call
the functions it provides.
While being at it, select numeric output in xt_xlate_*_params -
otherwise there will be reverse DNS lookups which should not happen by
default.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
include/statement.h | 9 +--
src/xt.c | 192 ++++++++++++++++++--------------------------
2 files changed, 80 insertions(+), 121 deletions(-)
diff --git a/include/statement.h b/include/statement.h
index 2a2d300..8651fc7 100644
--- a/include/statement.h
+++ b/include/statement.h
@@ -264,12 +264,11 @@ struct xtables_target;
struct xt_stmt {
const char *name;
enum nft_xt_type type;
+ uint32_t rev;
+ uint32_t family;
+ size_t infolen;
+ void *info;
uint32_t proto;
- union {
- struct xtables_match *match;
- struct xtables_target *target;
- };
- void *entry;
};
extern struct stmt *xt_stmt_alloc(const struct location *loc);
diff --git a/src/xt.c b/src/xt.c
index a541735..7880fa1 100644
--- a/src/xt.c
+++ b/src/xt.c
@@ -28,51 +28,94 @@
#ifdef HAVE_LIBXTABLES
#include <xtables.h>
+
+static void *xt_entry_alloc(const struct xt_stmt *xt, uint32_t af);
#endif
void xt_stmt_xlate(const struct stmt *stmt, struct output_ctx *octx)
{
#ifdef HAVE_LIBXTABLES
struct xt_xlate *xl = xt_xlate_alloc(10240);
+ struct xtables_target *tg;
+ struct xt_entry_target *t;
+ struct xtables_match *mt;
+ struct xt_entry_match *m;
+ size_t size;
+ void *entry;
+
+ xtables_set_nfproto(stmt->xt.family);
+ entry = xt_entry_alloc(&stmt->xt, stmt->xt.family);
switch (stmt->xt.type) {
case NFT_XT_MATCH:
- if (stmt->xt.match->xlate) {
+ mt = xtables_find_match(stmt->xt.name, XTF_TRY_LOAD, NULL);
+ if (!mt) {
+ fprintf(stderr, "XT match %s not found\n",
+ stmt->xt.name);
+ return;
+ }
+ size = XT_ALIGN(sizeof(*m)) + stmt->xt.infolen;
+
+ m = xzalloc(size);
+ memcpy(&m->data, stmt->xt.info, stmt->xt.infolen);
+
+ m->u.match_size = size;
+ m->u.user.revision = stmt->xt.rev;
+
+ if (mt->xlate) {
struct xt_xlate_mt_params params = {
- .ip = stmt->xt.entry,
- .match = stmt->xt.match->m,
- .numeric = 0,
+ .ip = entry,
+ .match = m,
+ .numeric = 1,
};
- stmt->xt.match->xlate(xl, &params);
+ mt->xlate(xl, &params);
nft_print(octx, "%s", xt_xlate_get(xl));
- } else if (stmt->xt.match->print) {
+ } else if (mt->print) {
printf("#");
- stmt->xt.match->print(&stmt->xt.entry,
- stmt->xt.match->m, 0);
+ mt->print(&entry, m, 0);
}
+ xfree(m);
break;
case NFT_XT_WATCHER:
case NFT_XT_TARGET:
- if (stmt->xt.target->xlate) {
+ tg = xtables_find_target(stmt->xt.name, XTF_TRY_LOAD);
+ if (!tg) {
+ fprintf(stderr, "XT target %s not found\n",
+ stmt->xt.name);
+ return;
+ }
+ size = XT_ALIGN(sizeof(*t)) + stmt->xt.infolen;
+
+ t = xzalloc(size);
+ memcpy(&t->data, stmt->xt.info, stmt->xt.infolen);
+
+ t->u.target_size = size;
+ t->u.user.revision = stmt->xt.rev;
+
+ strcpy(t->u.user.name, tg->name);
+
+ if (tg->xlate) {
struct xt_xlate_tg_params params = {
- .ip = stmt->xt.entry,
- .target = stmt->xt.target->t,
- .numeric = 0,
+ .ip = entry,
+ .target = t,
+ .numeric = 1,
};
- stmt->xt.target->xlate(xl, &params);
+ tg->xlate(xl, &params);
nft_print(octx, "%s", xt_xlate_get(xl));
- } else if (stmt->xt.target->print) {
+ } else if (tg->print) {
printf("#");
- stmt->xt.target->print(NULL, stmt->xt.target->t, 0);
+ tg->print(NULL, t, 0);
}
+ xfree(t);
break;
default:
break;
}
xt_xlate_free(xl);
+ xfree(entry);
#else
nft_print(octx, "# xt_%s", stmt->xt.name);
#endif
@@ -80,33 +123,12 @@ void xt_stmt_xlate(const struct stmt *stmt, struct output_ctx *octx)
void xt_stmt_destroy(struct stmt *stmt)
{
-#ifdef HAVE_LIBXTABLES
- switch (stmt->xt.type) {
- case NFT_XT_MATCH:
- if (!stmt->xt.match)
- break;
- if (stmt->xt.match->m)
- xfree(stmt->xt.match->m);
- xfree(stmt->xt.match);
- break;
- case NFT_XT_WATCHER:
- case NFT_XT_TARGET:
- if (!stmt->xt.target)
- break;
- if (stmt->xt.target->t)
- xfree(stmt->xt.target->t);
- xfree(stmt->xt.target);
- break;
- default:
- break;
- }
-#endif
- xfree(stmt->xt.entry);
xfree(stmt->xt.name);
+ xfree(stmt->xt.info);
}
#ifdef HAVE_LIBXTABLES
-static void *xt_entry_alloc(struct xt_stmt *xt, uint32_t af)
+static void *xt_entry_alloc(const struct xt_stmt *xt, uint32_t af)
{
union nft_entry {
struct ipt_entry ipt;
@@ -173,24 +195,6 @@ static uint32_t xt_proto(const struct proto_ctx *pctx)
return 0;
}
-
-static struct xtables_target *xt_target_clone(struct xtables_target *t)
-{
- struct xtables_target *clone;
-
- clone = xzalloc(sizeof(struct xtables_target));
- memcpy(clone, t, sizeof(struct xtables_target));
- return clone;
-}
-
-static struct xtables_match *xt_match_clone(struct xtables_match *m)
-{
- struct xtables_match *clone;
-
- clone = xzalloc(sizeof(struct xtables_match));
- memcpy(clone, m, sizeof(struct xtables_match));
- return clone;
-}
#endif
/*
@@ -201,43 +205,22 @@ void netlink_parse_match(struct netlink_parse_ctx *ctx,
const struct location *loc,
const struct nftnl_expr *nle)
{
- struct stmt *stmt;
- const char *name;
-#ifdef HAVE_LIBXTABLES
- struct xtables_match *mt;
const char *mtinfo;
- struct xt_entry_match *m;
+ struct stmt *stmt;
uint32_t mt_len;
- xtables_set_nfproto(ctx->table->handle.family);
-
- name = nftnl_expr_get_str(nle, NFTNL_EXPR_MT_NAME);
-
- mt = xtables_find_match(name, XTF_TRY_LOAD, NULL);
- if (!mt) {
- fprintf(stderr, "XT match %s not found\n", name);
- return;
- }
mtinfo = nftnl_expr_get(nle, NFTNL_EXPR_MT_INFO, &mt_len);
- m = xzalloc(sizeof(struct xt_entry_match) + mt_len);
- memcpy(&m->data, mtinfo, mt_len);
-
- m->u.match_size = mt_len + XT_ALIGN(sizeof(struct xt_entry_match));
- m->u.user.revision = nftnl_expr_get_u32(nle, NFTNL_EXPR_MT_REV);
-
stmt = xt_stmt_alloc(loc);
- stmt->xt.name = strdup(name);
+ stmt->xt.name = strdup(nftnl_expr_get_str(nle, NFTNL_EXPR_MT_NAME));
stmt->xt.type = NFT_XT_MATCH;
- stmt->xt.match = xt_match_clone(mt);
- stmt->xt.match->m = m;
-#else
- name = nftnl_expr_get_str(nle, NFTNL_EXPR_MT_NAME);
+ stmt->xt.rev = nftnl_expr_get_u32(nle, NFTNL_EXPR_MT_REV);
+ stmt->xt.family = ctx->table->handle.family;
+
+ stmt->xt.infolen = mt_len;
+ stmt->xt.info = xmalloc(mt_len);
+ memcpy(stmt->xt.info, mtinfo, mt_len);
- stmt = xt_stmt_alloc(loc);
- stmt->xt.name = strdup(name);
- stmt->xt.type = NFT_XT_MATCH;
-#endif
ctx->table->has_xt_stmts = true;
rule_stmt_append(ctx->rule, stmt);
}
@@ -246,44 +229,22 @@ void netlink_parse_target(struct netlink_parse_ctx *ctx,
const struct location *loc,
const struct nftnl_expr *nle)
{
- struct stmt *stmt;
- const char *name;
-#ifdef HAVE_LIBXTABLES
- struct xtables_target *tg;
const void *tginfo;
- struct xt_entry_target *t;
- size_t size;
+ struct stmt *stmt;
uint32_t tg_len;
- xtables_set_nfproto(ctx->table->handle.family);
-
- name = nftnl_expr_get_str(nle, NFTNL_EXPR_TG_NAME);
- tg = xtables_find_target(name, XTF_TRY_LOAD);
- if (!tg) {
- fprintf(stderr, "XT target %s not found\n", name);
- return;
- }
tginfo = nftnl_expr_get(nle, NFTNL_EXPR_TG_INFO, &tg_len);
- size = XT_ALIGN(sizeof(struct xt_entry_target)) + tg_len;
- t = xzalloc(size);
- memcpy(&t->data, tginfo, tg_len);
- t->u.target_size = size;
- t->u.user.revision = nftnl_expr_get_u32(nle, NFTNL_EXPR_TG_REV);
- strcpy(t->u.user.name, tg->name);
-
stmt = xt_stmt_alloc(loc);
- stmt->xt.name = strdup(name);
+ stmt->xt.name = strdup(nftnl_expr_get_str(nle, NFTNL_EXPR_TG_NAME));
stmt->xt.type = NFT_XT_TARGET;
- stmt->xt.target = xt_target_clone(tg);
- stmt->xt.target->t = t;
-#else
- name = nftnl_expr_get_str(nle, NFTNL_EXPR_TG_NAME);
+ stmt->xt.rev = nftnl_expr_get_u32(nle, NFTNL_EXPR_TG_REV);
+ stmt->xt.family = ctx->table->handle.family;
+
+ stmt->xt.infolen = tg_len;
+ stmt->xt.info = xmalloc(tg_len);
+ memcpy(stmt->xt.info, tginfo, tg_len);
- stmt = xt_stmt_alloc(loc);
- stmt->xt.name = strdup(name);
- stmt->xt.type = NFT_XT_TARGET;
-#endif
ctx->table->has_xt_stmts = true;
rule_stmt_append(ctx->rule, stmt);
}
@@ -311,7 +272,6 @@ void stmt_xt_postprocess(struct rule_pp_ctx *rctx, struct stmt *stmt,
stmt->xt.type = NFT_XT_WATCHER;
stmt->xt.proto = xt_proto(&rctx->pctx);
- stmt->xt.entry = xt_entry_alloc(&stmt->xt, rctx->pctx.family);
}
static int nft_xt_compatible_revision(const char *name, uint8_t rev, int opt)
--
2.45.0

View File

@ -0,0 +1,54 @@
From 89e01c6c9c9197193e83ec2b2adf14d1c6eb6f1f Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Wed, 14 Aug 2024 16:20:37 +0200
Subject: [PATCH] xt: Purify enum nft_xt_type
JIRA: https://issues.redhat.com/browse/RHEL-5806
Upstream Status: nftables commit e432477f5c013d0ca56f9fc5f9ac7cf35301b0b9
commit e432477f5c013d0ca56f9fc5f9ac7cf35301b0b9
Author: Phil Sutter <phil@nwl.cc>
Date: Thu Nov 24 16:24:05 2022 +0100
xt: Purify enum nft_xt_type
Remove NFT_XT_MAX from the enum, it is not a valid xt type.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
include/statement.h | 2 +-
src/xt.c | 2 --
2 files changed, 1 insertion(+), 3 deletions(-)
diff --git a/include/statement.h b/include/statement.h
index 8651fc7..e648fb1 100644
--- a/include/statement.h
+++ b/include/statement.h
@@ -255,8 +255,8 @@ enum nft_xt_type {
NFT_XT_MATCH = 0,
NFT_XT_TARGET,
NFT_XT_WATCHER,
- NFT_XT_MAX
};
+#define NFT_XT_MAX (NFT_XT_WATCHER + 1)
struct xtables_match;
struct xtables_target;
diff --git a/src/xt.c b/src/xt.c
index 7880fa1..300416a 100644
--- a/src/xt.c
+++ b/src/xt.c
@@ -110,8 +110,6 @@ void xt_stmt_xlate(const struct stmt *stmt, struct output_ctx *octx)
}
xfree(t);
break;
- default:
- break;
}
xt_xlate_free(xl);
--
2.45.0

View File

@ -0,0 +1,283 @@
From 5b2f626cb8770f485c20ae4f815763deac89a632 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Wed, 14 Aug 2024 16:20:37 +0200
Subject: [PATCH] xt: Rewrite unsupported compat expression dumping
JIRA: https://issues.redhat.com/browse/RHEL-5806
Upstream Status: nftables commit 79195a8cc9e9d9cf2d17165bf07ac4cc9d55539f
Conflicts:
* One chunk manually applied, upstream moved stmt_print_json() in commit
e66f3187d891a ("json: add table map statement support").
commit 79195a8cc9e9d9cf2d17165bf07ac4cc9d55539f
Author: Phil Sutter <phil@nwl.cc>
Date: Thu Nov 24 14:17:17 2022 +0100
xt: Rewrite unsupported compat expression dumping
Choose a format which provides more information and is easily parseable.
Then teach parsers about it and make it explicitly reject the ruleset
giving a meaningful explanation. Also update the man pages with some
more details.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
doc/libnftables-json.adoc | 18 +++++++++++++++---
doc/statements.txt | 17 +++++++++++++++++
include/json.h | 2 ++
include/parser.h | 1 +
src/json.c | 19 +++++++++++++------
src/parser_bison.y | 18 ++++++++++++++++++
src/parser_json.c | 5 +++++
src/scanner.l | 3 +++
src/statement.c | 1 +
src/xt.c | 8 +++++++-
10 files changed, 82 insertions(+), 10 deletions(-)
diff --git a/doc/libnftables-json.adoc b/doc/libnftables-json.adoc
index 9cc17ff..284ffab 100644
--- a/doc/libnftables-json.adoc
+++ b/doc/libnftables-json.adoc
@@ -1059,10 +1059,22 @@ Assign connection tracking expectation.
=== XT
[verse]
-*{ "xt": null }*
+____
+*{ "xt": {
+ "type":* 'TYPENAME'*,
+ "name":* 'STRING'
+*}}*
+
+'TYPENAME' := *match* | *target* | *watcher*
+____
+
+This represents an xt statement from xtables compat interface. It is a
+fallback if translation is not available or not complete.
+
+Seeing this means the ruleset (or parts of it) were created by *iptables-nft*
+and one should use that to manage it.
-This represents an xt statement from xtables compat interface. Sadly, at this
-point, it is not possible to provide any further information about its content.
+*BEWARE:* nftables won't restore these statements.
== EXPRESSIONS
Expressions are the building blocks of (most) statements. In their most basic
diff --git a/doc/statements.txt b/doc/statements.txt
index 6aaf806..a00bd5d 100644
--- a/doc/statements.txt
+++ b/doc/statements.txt
@@ -778,3 +778,20 @@ ____
# jump to different chains depending on layer 4 protocol type:
nft add rule ip filter input ip protocol vmap { tcp : jump tcp-chain, udp : jump udp-chain , icmp : jump icmp-chain }
------------------------
+
+XT STATEMENT
+~~~~~~~~~~~~
+This represents an xt statement from xtables compat interface. It is a
+fallback if translation is not available or not complete.
+
+[verse]
+____
+*xt* 'TYPE' 'NAME'
+
+'TYPE' := *match* | *target* | *watcher*
+____
+
+Seeing this means the ruleset (or parts of it) were created by *iptables-nft*
+and one should use that to manage it.
+
+*BEWARE:* nftables won't restore these statements.
diff --git a/include/json.h b/include/json.h
index b0d78eb..f691678 100644
--- a/include/json.h
+++ b/include/json.h
@@ -92,6 +92,7 @@ json_t *connlimit_stmt_json(const struct stmt *stmt, struct output_ctx *octx);
json_t *tproxy_stmt_json(const struct stmt *stmt, struct output_ctx *octx);
json_t *synproxy_stmt_json(const struct stmt *stmt, struct output_ctx *octx);
json_t *optstrip_stmt_json(const struct stmt *stmt, struct output_ctx *octx);
+json_t *xt_stmt_json(const struct stmt *stmt, struct output_ctx *octx);
int do_command_list_json(struct netlink_ctx *ctx, struct cmd *cmd);
@@ -194,6 +195,7 @@ STMT_PRINT_STUB(connlimit)
STMT_PRINT_STUB(tproxy)
STMT_PRINT_STUB(synproxy)
STMT_PRINT_STUB(optstrip)
+STMT_PRINT_STUB(xt)
#undef STMT_PRINT_STUB
#undef EXPR_PRINT_STUB
diff --git a/include/parser.h b/include/parser.h
index 5e5ad28..bd61b8f 100644
--- a/include/parser.h
+++ b/include/parser.h
@@ -50,6 +50,7 @@ enum startcond_type {
PARSER_SC_TCP,
PARSER_SC_TYPE,
PARSER_SC_VLAN,
+ PARSER_SC_XT,
PARSER_SC_CMD_EXPORT,
PARSER_SC_CMD_IMPORT,
PARSER_SC_CMD_LIST,
diff --git a/src/json.c b/src/json.c
index a525fd1..622fe08 100644
--- a/src/json.c
+++ b/src/json.c
@@ -173,12 +173,6 @@ static json_t *stmt_print_json(const struct stmt *stmt, struct output_ctx *octx)
char buf[1024];
FILE *fp;
- /* XXX: Can't be supported at this point:
- * xt_stmt_xlate() ignores output_fp.
- */
- if (stmt->ops->type == STMT_XT)
- return json_pack("{s:n}", "xt");
-
if (stmt->ops->json)
return stmt->ops->json(stmt, octx);
@@ -1584,6 +1578,19 @@ json_t *optstrip_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
expr_print_json(stmt->optstrip.expr, octx));
}
+json_t *xt_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
+{
+ static const char *xt_typename[NFT_XT_MAX] = {
+ [NFT_XT_MATCH] = "match",
+ [NFT_XT_TARGET] = "target",
+ [NFT_XT_WATCHER] = "watcher",
+ };
+
+ return json_pack("{s:{s:s, s:s}}", "xt",
+ "type", xt_typename[stmt->xt.type],
+ "name", stmt->xt.name);
+}
+
static json_t *table_print_json_full(struct netlink_ctx *ctx,
struct table *table)
{
diff --git a/src/parser_bison.y b/src/parser_bison.y
index b882f3b..a9d16f8 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -615,6 +615,8 @@ int nft_lex(void *, void *, void *);
%token IN "in"
%token OUT "out"
+%token XT "xt"
+
%type <limit_rate> limit_rate_pkts
%type <limit_rate> limit_rate_bytes
@@ -889,6 +891,9 @@ int nft_lex(void *, void *, void *);
%type <stmt> optstrip_stmt
%destructor { stmt_free($$); } optstrip_stmt
+%type <stmt> xt_stmt
+%destructor { stmt_free($$); } xt_stmt
+
%type <expr> boolean_expr
%destructor { expr_free($$); } boolean_expr
%type <val8> boolean_keys
@@ -981,6 +986,7 @@ close_scope_udplite : { scanner_pop_start_cond(nft->scanner, PARSER_SC_EXPR_UDPL
close_scope_log : { scanner_pop_start_cond(nft->scanner, PARSER_SC_STMT_LOG); }
close_scope_synproxy : { scanner_pop_start_cond(nft->scanner, PARSER_SC_STMT_SYNPROXY); }
+close_scope_xt : { scanner_pop_start_cond(nft->scanner, PARSER_SC_XT); }
common_block : INCLUDE QUOTED_STRING stmt_separator
{
@@ -2861,6 +2867,18 @@ stmt : verdict_stmt
| synproxy_stmt close_scope_synproxy
| chain_stmt
| optstrip_stmt
+ | xt_stmt close_scope_xt
+ ;
+
+xt_stmt : XT STRING STRING
+ {
+ $$ = NULL;
+ xfree($2);
+ xfree($3);
+ erec_queue(error(&@$, "unsupported xtables compat expression, use iptables-nft with this ruleset"),
+ state->msgs);
+ YYERROR;
+ }
;
chain_stmt_type : JUMP { $$ = NFT_JUMP; }
diff --git a/src/parser_json.c b/src/parser_json.c
index fb40100..1699a44 100644
--- a/src/parser_json.c
+++ b/src/parser_json.c
@@ -2716,6 +2716,11 @@ static struct stmt *json_parse_stmt(struct json_ctx *ctx, json_t *root)
return verdict_stmt_alloc(int_loc, expr);
}
+ if (!strcmp(type, "xt")) {
+ json_error(ctx, "unsupported xtables compat expression, use iptables-nft with this ruleset");
+ return NULL;
+ }
+
for (i = 0; i < array_size(stmt_parser_tbl); i++) {
if (!strcmp(type, stmt_parser_tbl[i].key))
return stmt_parser_tbl[i].cb(ctx, stmt_parser_tbl[i].key, tmp);
diff --git a/src/scanner.l b/src/scanner.l
index ed7256b..64d21df 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -215,6 +215,7 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr})
%s SCANSTATE_TCP
%s SCANSTATE_TYPE
%s SCANSTATE_VLAN
+%s SCANSTATE_XT
%s SCANSTATE_CMD_EXPORT
%s SCANSTATE_CMD_IMPORT
%s SCANSTATE_CMD_LIST
@@ -803,6 +804,8 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr})
"secmark" { scanner_push_start_cond(yyscanner, SCANSTATE_SECMARK); return SECMARK; }
+"xt" { scanner_push_start_cond(yyscanner, SCANSTATE_XT); return XT; }
+
{addrstring} {
yylval->string = xstrdup(yytext);
return STRING;
diff --git a/src/statement.c b/src/statement.c
index 30caf9c..0448c85 100644
--- a/src/statement.c
+++ b/src/statement.c
@@ -997,6 +997,7 @@ static const struct stmt_ops xt_stmt_ops = {
.name = "xt",
.print = xt_stmt_print,
.destroy = xt_stmt_destroy,
+ .json = xt_stmt_json,
};
struct stmt *xt_stmt_alloc(const struct location *loc)
diff --git a/src/xt.c b/src/xt.c
index 300416a..12b52aa 100644
--- a/src/xt.c
+++ b/src/xt.c
@@ -115,7 +115,13 @@ void xt_stmt_xlate(const struct stmt *stmt, struct output_ctx *octx)
xt_xlate_free(xl);
xfree(entry);
#else
- nft_print(octx, "# xt_%s", stmt->xt.name);
+ static const char *typename[NFT_XT_MAX] = {
+ [NFT_XT_MATCH] = "match",
+ [NFT_XT_TARGET] = "target",
+ [NFT_XT_WATCHER] = "watcher",
+ };
+
+ nft_print(octx, "xt %s %s", typename[stmt->xt.type], stmt->xt.name);
#endif
}
--
2.45.0

View File

@ -0,0 +1,92 @@
From e0a2f227d1d3cfb60561144318e81f74a7516d38 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Wed, 14 Aug 2024 16:21:18 +0200
Subject: [PATCH] xt: Fall back to generic printing from translation
JIRA: https://issues.redhat.com/browse/RHEL-5806
Upstream Status: nftables commit e41c53ca5b043e8cee493bf4a7f78195827279d2
commit e41c53ca5b043e8cee493bf4a7f78195827279d2
Author: Phil Sutter <phil@nwl.cc>
Date: Thu Nov 24 16:16:41 2022 +0100
xt: Fall back to generic printing from translation
If translation is not available or fails, print the generic format
instead of calling the print callback (which does not respect
output_fp) or silently failing.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
src/xt.c | 31 +++++++++++++------------------
1 file changed, 13 insertions(+), 18 deletions(-)
diff --git a/src/xt.c b/src/xt.c
index 12b52aa..b75c94e 100644
--- a/src/xt.c
+++ b/src/xt.c
@@ -34,6 +34,12 @@ static void *xt_entry_alloc(const struct xt_stmt *xt, uint32_t af);
void xt_stmt_xlate(const struct stmt *stmt, struct output_ctx *octx)
{
+ static const char *typename[NFT_XT_MAX] = {
+ [NFT_XT_MATCH] = "match",
+ [NFT_XT_TARGET] = "target",
+ [NFT_XT_WATCHER] = "watcher",
+ };
+ int rc = 0;
#ifdef HAVE_LIBXTABLES
struct xt_xlate *xl = xt_xlate_alloc(10240);
struct xtables_target *tg;
@@ -69,11 +75,7 @@ void xt_stmt_xlate(const struct stmt *stmt, struct output_ctx *octx)
.numeric = 1,
};
- mt->xlate(xl, &params);
- nft_print(octx, "%s", xt_xlate_get(xl));
- } else if (mt->print) {
- printf("#");
- mt->print(&entry, m, 0);
+ rc = mt->xlate(xl, &params);
}
xfree(m);
break;
@@ -102,27 +104,20 @@ void xt_stmt_xlate(const struct stmt *stmt, struct output_ctx *octx)
.numeric = 1,
};
- tg->xlate(xl, &params);
- nft_print(octx, "%s", xt_xlate_get(xl));
- } else if (tg->print) {
- printf("#");
- tg->print(NULL, t, 0);
+ rc = tg->xlate(xl, &params);
}
xfree(t);
break;
}
+ if (rc == 1)
+ nft_print(octx, "%s", xt_xlate_get(xl));
xt_xlate_free(xl);
xfree(entry);
-#else
- static const char *typename[NFT_XT_MAX] = {
- [NFT_XT_MATCH] = "match",
- [NFT_XT_TARGET] = "target",
- [NFT_XT_WATCHER] = "watcher",
- };
-
- nft_print(octx, "xt %s %s", typename[stmt->xt.type], stmt->xt.name);
#endif
+ if (!rc)
+ nft_print(octx, "xt %s %s",
+ typename[stmt->xt.type], stmt->xt.name);
}
void xt_stmt_destroy(struct stmt *stmt)
--
2.45.0

View File

@ -0,0 +1,71 @@
From eafc3f2d2dbc367b022a51a9208cc6d861b9e10d Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Wed, 14 Aug 2024 16:21:19 +0200
Subject: [PATCH] xt: Fix fallback printing for extensions matching keywords
JIRA: https://issues.redhat.com/browse/RHEL-5806
Upstream Status: nftables commit aef5330fe7827f760b70d5d27010445c3adb3d3c
commit aef5330fe7827f760b70d5d27010445c3adb3d3c
Author: Phil Sutter <phil@nwl.cc>
Date: Thu Mar 9 14:31:31 2023 +0100
xt: Fix fallback printing for extensions matching keywords
Yet another Bison workaround: Instead of the fancy error message, an
incomprehensible syntax error is emitted:
| # iptables-nft -A FORWARD -p tcp -m osf --genre linux
| # nft list ruleset | nft -f -
| # Warning: table ip filter is managed by iptables-nft, do not touch!
| /dev/stdin:4:29-31: Error: syntax error, unexpected osf, expecting string
| meta l4proto tcp xt match osf counter packets 0 bytes 0
| ^^^
Avoid this by quoting the extension name when printing:
| # nft list ruleset | sudo ./src/nft -f -
| # Warning: table ip filter is managed by iptables-nft, do not touch!
| /dev/stdin:4:20-33: Error: unsupported xtables compat expression, use iptables-nft with this ruleset
| meta l4proto tcp xt match "osf" counter packets 0 bytes 0
| ^^^^^^^^^^^^^^
Fixes: 79195a8cc9e9d ("xt: Rewrite unsupported compat expression dumping")
Fixes: e41c53ca5b043 ("xt: Fall back to generic printing from translation")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
src/parser_bison.y | 2 +-
src/xt.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/parser_bison.y b/src/parser_bison.y
index a9d16f8..1ca0c25 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -2870,7 +2870,7 @@ stmt : verdict_stmt
| xt_stmt close_scope_xt
;
-xt_stmt : XT STRING STRING
+xt_stmt : XT STRING string
{
$$ = NULL;
xfree($2);
diff --git a/src/xt.c b/src/xt.c
index b75c94e..31cf40e 100644
--- a/src/xt.c
+++ b/src/xt.c
@@ -116,7 +116,7 @@ void xt_stmt_xlate(const struct stmt *stmt, struct output_ctx *octx)
xfree(entry);
#endif
if (!rc)
- nft_print(octx, "xt %s %s",
+ nft_print(octx, "xt %s \"%s\"",
typename[stmt->xt.type], stmt->xt.name);
}
--
2.45.0

View File

@ -1,5 +1,5 @@
%define nft_rpmversion 1.0.4 %define nft_rpmversion 1.0.4
%define nft_specrelease 4 %define nft_specrelease 5
%define libnftnl_ver 1.2.2-1 %define libnftnl_ver 1.2.2-1
Name: nftables Name: nftables
@ -55,6 +55,12 @@ Patch31: 0031-netlink_delinearize-Sanitize-concat-data-element-dec.pa
Patch32: 0032-tests-monitor-Summarize-failures-per-test-case.patch Patch32: 0032-tests-monitor-Summarize-failures-per-test-case.patch
Patch33: 0033-rule-check-address-family-in-set-collapse.patch Patch33: 0033-rule-check-address-family-in-set-collapse.patch
Patch34: 0034-parser_bison-Fix-for-broken-compatibility-with-older.patch Patch34: 0034-parser_bison-Fix-for-broken-compatibility-with-older.patch
Patch35: 0035-Warn-for-tables-with-compat-expressions-in-rules.patch
Patch36: 0036-xt-Delay-libxtables-access-until-translation.patch
Patch37: 0037-xt-Purify-enum-nft_xt_type.patch
Patch38: 0038-xt-Rewrite-unsupported-compat-expression-dumping.patch
Patch39: 0039-xt-Fall-back-to-generic-printing-from-translation.patch
Patch40: 0040-xt-Fix-fallback-printing-for-extensions-matching-key.patch
BuildRequires: autoconf BuildRequires: autoconf
BuildRequires: automake BuildRequires: automake
@ -174,6 +180,14 @@ touch -r %{SOURCE2} $RPM_BUILD_ROOT/%{python3_sitelib}/nftables/nftables.py
%{python3_sitelib}/nftables/ %{python3_sitelib}/nftables/
%changelog %changelog
* Wed Aug 14 2024 Phil Sutter <psutter@redhat.com> [1.0.4-5.el8]
- xt: Fix fallback printing for extensions matching keywords (Phil Sutter) [RHEL-5806]
- xt: Fall back to generic printing from translation (Phil Sutter) [RHEL-5806]
- xt: Rewrite unsupported compat expression dumping (Phil Sutter) [RHEL-5806]
- xt: Purify enum nft_xt_type (Phil Sutter) [RHEL-5806]
- xt: Delay libxtables access until translation (Phil Sutter) [RHEL-5806]
- Warn for tables with compat expressions in rules (Phil Sutter) [RHEL-5806]
* Wed Nov 15 2023 Phil Sutter <psutter@redhat.com> [1.0.4-4.el8] * Wed Nov 15 2023 Phil Sutter <psutter@redhat.com> [1.0.4-4.el8]
- parser_bison: Fix for broken compatibility with older dumps (Phil Sutter) [RHEL-2596] - parser_bison: Fix for broken compatibility with older dumps (Phil Sutter) [RHEL-2596]