diff --git a/0006-nft-Fix-for-zeroing-non-existent-builtin-chains.patch b/0006-nft-Fix-for-zeroing-non-existent-builtin-chains.patch new file mode 100644 index 0000000..55c7b5b --- /dev/null +++ b/0006-nft-Fix-for-zeroing-non-existent-builtin-chains.patch @@ -0,0 +1,122 @@ +From 312ff073e117d6207c3ba304ca01532e723d6e54 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Wed, 14 Aug 2024 14:23:33 +0200 +Subject: [PATCH] nft: Fix for zeroing non-existent builtin chains + +JIRA: https://issues.redhat.com/browse/RHEL-49497 +Upstream Status: iptables commit f462975fb8049b9b565cb35cc98302331dbd1548 + +commit f462975fb8049b9b565cb35cc98302331dbd1548 +Author: Phil Sutter +Date: Tue Jul 16 21:07:31 2024 +0200 + + nft: Fix for zeroing non-existent builtin chains + + Trying to zero a specific rule in an entirely empty ruleset caused an + error: + + | # nft flush ruleset + | # iptables-nft -Z INPUT + | iptables v1.8.10 (nf_tables): CHAIN_ZERO failed (No such file or directory): chain INPUT + + To fix this, start by faking any non-existing builtin chains so verbose + mode prints all the would-be-flushed chains. Later set 'skip' flag if + given chain is a fake one (indicated by missing HANDLE attribute). + Finally cover for concurrent ruleset updates by checking whether the + chain exists. + + This bug seems to exist for a long time already, Fixes tag identified + via git-bisect. This patch won't apply to such old trees though, but + calling nft_xt_builtin_init() from nft_chain_zero_counters() should work + there. + + Fixes: a6ce0c65d3a39 ("xtables: Optimize nft_chain_zero_counters()") + Signed-off-by: Phil Sutter + +Signed-off-by: Phil Sutter +--- + iptables/nft.c | 22 +++++++++++++++++-- + .../nft-only/0013-zero-non-existent_0 | 17 ++++++++++++++ + 2 files changed, 37 insertions(+), 2 deletions(-) + create mode 100755 iptables/tests/shell/testcases/nft-only/0013-zero-non-existent_0 + +diff --git a/iptables/nft.c b/iptables/nft.c +index c4caf29..82eab48 100644 +--- a/iptables/nft.c ++++ b/iptables/nft.c +@@ -3109,9 +3109,21 @@ static void nft_refresh_transaction(struct nft_handle *h) + break; + n->skip = !nft_may_delete_chain(n->chain); + break; ++ case NFT_COMPAT_CHAIN_ZERO: ++ tablename = nftnl_chain_get_str(n->chain, NFTNL_CHAIN_TABLE); ++ if (!tablename) ++ continue; ++ ++ chainname = nftnl_chain_get_str(n->chain, NFTNL_CHAIN_NAME); ++ if (!chainname) ++ continue; ++ ++ n->skip = nftnl_chain_is_set(n->chain, ++ NFTNL_CHAIN_HOOKNUM) && ++ !nft_chain_find(h, tablename, chainname); ++ break; + case NFT_COMPAT_TABLE_ADD: + case NFT_COMPAT_CHAIN_ADD: +- case NFT_COMPAT_CHAIN_ZERO: + case NFT_COMPAT_CHAIN_USER_FLUSH: + case NFT_COMPAT_CHAIN_UPDATE: + case NFT_COMPAT_CHAIN_RENAME: +@@ -3748,6 +3760,7 @@ static int __nft_chain_zero_counters(struct nft_chain *nc, void *data) + struct nft_handle *h = d->handle; + struct nftnl_rule_iter *iter; + struct nftnl_rule *r; ++ struct obj_update *o; + + if (d->verbose) + fprintf(stdout, "Zeroing chain `%s'\n", +@@ -3758,8 +3771,11 @@ static int __nft_chain_zero_counters(struct nft_chain *nc, void *data) + nftnl_chain_set_u64(c, NFTNL_CHAIN_PACKETS, 0); + nftnl_chain_set_u64(c, NFTNL_CHAIN_BYTES, 0); + nftnl_chain_unset(c, NFTNL_CHAIN_HANDLE); +- if (!batch_chain_add(h, NFT_COMPAT_CHAIN_ZERO, c)) ++ o = batch_chain_add(h, NFT_COMPAT_CHAIN_ZERO, c); ++ if (!o) + return -1; ++ /* may skip if it is a fake entry */ ++ o->skip = !nftnl_chain_is_set(c, NFTNL_CHAIN_HANDLE); + } + + iter = nftnl_rule_iter_create(c); +@@ -3823,6 +3839,8 @@ int nft_chain_zero_counters(struct nft_handle *h, const char *chain, + struct nft_chain *c; + int ret = 0; + ++ nft_xt_fake_builtin_chains(h, table, chain); ++ + if (chain) { + c = nft_chain_find(h, table, chain); + if (!c) { +diff --git a/iptables/tests/shell/testcases/nft-only/0013-zero-non-existent_0 b/iptables/tests/shell/testcases/nft-only/0013-zero-non-existent_0 +new file mode 100755 +index 0000000..bbf1af7 +--- /dev/null ++++ b/iptables/tests/shell/testcases/nft-only/0013-zero-non-existent_0 +@@ -0,0 +1,17 @@ ++#!/bin/bash ++ ++[[ $XT_MULTI == *xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; } ++nft --version >/dev/null 2>&1 || { echo "skip nft"; exit 0; } ++ ++set -e ++ ++nft flush ruleset ++$XT_MULTI iptables -Z INPUT ++ ++EXP="Zeroing chain \`INPUT'" ++diff -u <(echo "$EXP") <($XT_MULTI iptables -v -Z INPUT) ++ ++EXP="Zeroing chain \`INPUT' ++Zeroing chain \`FORWARD' ++Zeroing chain \`OUTPUT'" ++diff -u <(echo "$EXP") <($XT_MULTI iptables -v -Z) diff --git a/0007-nft-cache-Annotate-faked-base-chains-as-such.patch b/0007-nft-cache-Annotate-faked-base-chains-as-such.patch new file mode 100644 index 0000000..896bd69 --- /dev/null +++ b/0007-nft-cache-Annotate-faked-base-chains-as-such.patch @@ -0,0 +1,193 @@ +From 82ad0504599d894e62dff2e062cb4d6093ce12a5 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Wed, 14 Aug 2024 14:23:33 +0200 +Subject: [PATCH] nft: cache: Annotate faked base chains as such + +JIRA: https://issues.redhat.com/browse/RHEL-49497 +Upstream Status: iptables commit f65d1e9a216468d5287fa05894a08e29c0fc8278 + +commit f65d1e9a216468d5287fa05894a08e29c0fc8278 +Author: Phil Sutter +Date: Sat Jul 27 19:13:40 2024 +0200 + + nft: cache: Annotate faked base chains as such + + To avoid pointless kernel ruleset modifications without too many + workarounds in user space, code sometimes adds "fake" base chains to + cache. Yet these fake entries happen to prevent base chain creation for + a following command which actually requires them. Fix this by annotating + the fake entries as such so *_builtin_init() functions may convert them + into real ones. + + Fixes: fd4b9bf08b9eb ("nft: Avoid pointless table/chain creation") + Signed-off-by: Phil Sutter + +Signed-off-by: Phil Sutter +--- + iptables/nft-cache.c | 6 +++--- + iptables/nft-cache.h | 2 +- + iptables/nft-chain.c | 3 ++- + iptables/nft-chain.h | 3 ++- + iptables/nft.c | 31 ++++++++++++++++++++----------- + 5 files changed, 28 insertions(+), 17 deletions(-) + +diff --git a/iptables/nft-cache.c b/iptables/nft-cache.c +index 91d2967..da2d4d7 100644 +--- a/iptables/nft-cache.c ++++ b/iptables/nft-cache.c +@@ -244,10 +244,10 @@ nft_cache_add_base_chain(struct nft_handle *h, const struct builtin_table *t, + } + + int nft_cache_add_chain(struct nft_handle *h, const struct builtin_table *t, +- struct nftnl_chain *c) ++ struct nftnl_chain *c, bool fake) + { + const char *cname = nftnl_chain_get_str(c, NFTNL_CHAIN_NAME); +- struct nft_chain *nc = nft_chain_alloc(c); ++ struct nft_chain *nc = nft_chain_alloc(c, fake); + int ret; + + if (nftnl_chain_is_set(c, NFTNL_CHAIN_HOOKNUM)) { +@@ -349,7 +349,7 @@ static int nftnl_chain_list_cb(const struct nlmsghdr *nlh, void *data) + goto out; + } + +- nft_cache_add_chain(h, t, c); ++ nft_cache_add_chain(h, t, c, false); + return MNL_CB_OK; + out: + nftnl_chain_free(c); +diff --git a/iptables/nft-cache.h b/iptables/nft-cache.h +index 29ec6b5..e9f5755 100644 +--- a/iptables/nft-cache.h ++++ b/iptables/nft-cache.h +@@ -17,7 +17,7 @@ int flush_rule_cache(struct nft_handle *h, const char *table, + struct nft_chain *c); + void nft_cache_build(struct nft_handle *h); + int nft_cache_add_chain(struct nft_handle *h, const struct builtin_table *t, +- struct nftnl_chain *c); ++ struct nftnl_chain *c, bool fake); + int nft_cache_sort_chains(struct nft_handle *h, const char *table); + + struct nft_chain * +diff --git a/iptables/nft-chain.c b/iptables/nft-chain.c +index e954170..c24e6c9 100644 +--- a/iptables/nft-chain.c ++++ b/iptables/nft-chain.c +@@ -12,12 +12,13 @@ + + #include "nft-chain.h" + +-struct nft_chain *nft_chain_alloc(struct nftnl_chain *nftnl) ++struct nft_chain *nft_chain_alloc(struct nftnl_chain *nftnl, bool fake) + { + struct nft_chain *c = xtables_malloc(sizeof(*c)); + + INIT_LIST_HEAD(&c->head); + c->nftnl = nftnl; ++ c->fake = fake; + + return c; + } +diff --git a/iptables/nft-chain.h b/iptables/nft-chain.h +index 9adf173..166504c 100644 +--- a/iptables/nft-chain.h ++++ b/iptables/nft-chain.h +@@ -11,6 +11,7 @@ struct nft_chain { + struct hlist_node hnode; + struct nft_chain **base_slot; + struct nftnl_chain *nftnl; ++ bool fake; + }; + + #define CHAIN_NAME_HSIZE 512 +@@ -20,7 +21,7 @@ struct nft_chain_list { + struct hlist_head names[CHAIN_NAME_HSIZE]; + }; + +-struct nft_chain *nft_chain_alloc(struct nftnl_chain *nftnl); ++struct nft_chain *nft_chain_alloc(struct nftnl_chain *nftnl, bool fake); + void nft_chain_free(struct nft_chain *c); + + struct nft_chain_list *nft_chain_list_alloc(void); +diff --git a/iptables/nft.c b/iptables/nft.c +index 82eab48..aa4b3f2 100644 +--- a/iptables/nft.c ++++ b/iptables/nft.c +@@ -720,7 +720,7 @@ static void nft_chain_builtin_add(struct nft_handle *h, + + if (!fake) + batch_chain_add(h, NFT_COMPAT_CHAIN_ADD, c); +- nft_cache_add_chain(h, table, c); ++ nft_cache_add_chain(h, table, c, fake); + } + + /* find if built-in table already exists */ +@@ -764,14 +764,19 @@ nft_chain_builtin_find(const struct builtin_table *t, const char *chain) + static void nft_chain_builtin_init(struct nft_handle *h, + const struct builtin_table *table) + { ++ struct nft_chain *c; + int i; + + /* Initialize built-in chains if they don't exist yet */ + for (i=0; i < NF_INET_NUMHOOKS && table->chains[i].name != NULL; i++) { +- if (nft_chain_find(h, table->name, table->chains[i].name)) +- continue; +- +- nft_chain_builtin_add(h, table, &table->chains[i], false); ++ c = nft_chain_find(h, table->name, table->chains[i].name); ++ if (!c) { ++ nft_chain_builtin_add(h, table, ++ &table->chains[i], false); ++ } else if (c->fake) { ++ batch_chain_add(h, NFT_COMPAT_CHAIN_ADD, c->nftnl); ++ c->fake = false; ++ } + } + } + +@@ -798,6 +803,7 @@ static int nft_xt_builtin_init(struct nft_handle *h, const char *table, + { + const struct builtin_table *t; + const struct builtin_chain *c; ++ struct nft_chain *nc; + + if (!h->cache_init) + return 0; +@@ -818,10 +824,13 @@ static int nft_xt_builtin_init(struct nft_handle *h, const char *table, + if (!c) + return -1; + +- if (h->cache->table[t->type].base_chains[c->hook]) +- return 0; +- +- nft_chain_builtin_add(h, t, c, false); ++ nc = h->cache->table[t->type].base_chains[c->hook]; ++ if (!nc) { ++ nft_chain_builtin_add(h, t, c, false); ++ } else if (nc->fake) { ++ batch_chain_add(h, NFT_COMPAT_CHAIN_ADD, nc->nftnl); ++ nc->fake = false; ++ } + return 0; + } + +@@ -2092,7 +2101,7 @@ int nft_chain_user_add(struct nft_handle *h, const char *chain, const char *tabl + if (!batch_chain_add(h, NFT_COMPAT_CHAIN_USER_ADD, c)) + return 0; + +- nft_cache_add_chain(h, t, c); ++ nft_cache_add_chain(h, t, c, false); + + /* the core expects 1 for success and 0 for error */ + return 1; +@@ -2119,7 +2128,7 @@ int nft_chain_restore(struct nft_handle *h, const char *chain, const char *table + nftnl_chain_set_str(c, NFTNL_CHAIN_NAME, chain); + created = true; + +- nft_cache_add_chain(h, t, c); ++ nft_cache_add_chain(h, t, c, false); + } else { + c = nc->nftnl; + diff --git a/0008-nft-Fix-for-zeroing-existent-builtin-chains.patch b/0008-nft-Fix-for-zeroing-existent-builtin-chains.patch new file mode 100644 index 0000000..d3572ef --- /dev/null +++ b/0008-nft-Fix-for-zeroing-existent-builtin-chains.patch @@ -0,0 +1,46 @@ +From 5766ffbf98583fcc50f3607850d63bb0e87d4abe Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Wed, 14 Aug 2024 14:23:33 +0200 +Subject: [PATCH] nft: Fix for zeroing existent builtin chains + +JIRA: https://issues.redhat.com/browse/RHEL-49497 +Upstream Status: iptables commit 6a2aeda7585e07c0fcccb0c788299ab5a6a85881 + +commit 6a2aeda7585e07c0fcccb0c788299ab5a6a85881 +Author: Phil Sutter +Date: Sat Jul 27 16:04:31 2024 +0200 + + nft: Fix for zeroing existent builtin chains + + Previous attempt at fixing for non-existent chains actually broke + functionality by adding a check for NFTNL_CHAIN_HANDLE right after + unsetting the attribute. + + The approach was flawed for another reason, too: Base chains added in + the same batch (cf. iptables-restore) have no handle either but zeroing + them may still be sensible. + + Instead, make use of the new fake chain annotation which identifies + fakes more reliably. + + Fixes: f462975fb8049 ("nft: Fix for zeroing non-existent builtin chains") + Signed-off-by: Phil Sutter + +Signed-off-by: Phil Sutter +--- + iptables/nft.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/iptables/nft.c b/iptables/nft.c +index aa4b3f2..ad4c866 100644 +--- a/iptables/nft.c ++++ b/iptables/nft.c +@@ -3784,7 +3784,7 @@ static int __nft_chain_zero_counters(struct nft_chain *nc, void *data) + if (!o) + return -1; + /* may skip if it is a fake entry */ +- o->skip = !nftnl_chain_is_set(c, NFTNL_CHAIN_HANDLE); ++ o->skip = nc->fake; + } + + iter = nftnl_rule_iter_create(c); diff --git a/0009-xtables-monitor-Proper-re-init-for-rule-s-family.patch b/0009-xtables-monitor-Proper-re-init-for-rule-s-family.patch new file mode 100644 index 0000000..d8574e7 --- /dev/null +++ b/0009-xtables-monitor-Proper-re-init-for-rule-s-family.patch @@ -0,0 +1,51 @@ +From 78cc3761b83a08b6782dfa52887fbd8c9c28bf61 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Wed, 14 Aug 2024 14:30:11 +0200 +Subject: [PATCH] xtables-monitor: Proper re-init for rule's family + +JIRA: https://issues.redhat.com/browse/RHEL-47264 +Upstream Status: iptables commit a5e7f9d14ee404544e2751232e69f993b16e7396 + +commit a5e7f9d14ee404544e2751232e69f993b16e7396 +Author: Phil Sutter +Date: Fri Jul 12 12:49:22 2024 +0200 + + xtables-monitor: Proper re-init for rule's family + + When not running for a specific family only (via -4/-6 flags), + xtables-monitor potentially sees events/traces for all families. To + correctly parse rules when printing for NEWRULE, DELRULE or TRACE + messages, nft_handle has to be reinitialized for the rule's family. + + It is not sufficient to reset nft_handle::ops: Some expression parsers + rely upon nft_handle::family to be properly set, too (cf. references to + 'ctx->h->family in nft-ruleparse.c). Adjusting the 'afinfo' pointer + provided by libxtables is even more crucial, as e.g. do_parse() in + xshared.c relies upon it for the proper optstring. + + This is actually a day-1 bug in xtables-monitor which surfaced due to + commit 9075c3aa983d9 ("nft: Increase rule parser strictness"). Therefore + make this fix the commit it is following-up. + + Fixes: ca69b0290dc50 ("xtables-monitor: Fix ip6tables rule printing") + Signed-off-by: Phil Sutter + +Signed-off-by: Phil Sutter +--- + iptables/xtables-monitor.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/iptables/xtables-monitor.c b/iptables/xtables-monitor.c +index cf2729d..cf92355 100644 +--- a/iptables/xtables-monitor.c ++++ b/iptables/xtables-monitor.c +@@ -92,7 +92,9 @@ static int rule_cb(const struct nlmsghdr *nlh, void *data) + if (arg->nfproto && arg->nfproto != family) + goto err_free; + ++ xtables_set_nfproto(family); + arg->h->ops = nft_family_ops_lookup(family); ++ arg->h->family = family; + + if (arg->is_event) + printf(" EVENT: "); diff --git a/0010-xtables-monitor-Flush-stdout-after-all-lines-of-outp.patch b/0010-xtables-monitor-Flush-stdout-after-all-lines-of-outp.patch new file mode 100644 index 0000000..98bbc50 --- /dev/null +++ b/0010-xtables-monitor-Flush-stdout-after-all-lines-of-outp.patch @@ -0,0 +1,46 @@ +From b40d2d0b3381c68a0f0e5d040d2f632191112dcb Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Wed, 14 Aug 2024 14:30:11 +0200 +Subject: [PATCH] xtables-monitor: Flush stdout after all lines of output + +JIRA: https://issues.redhat.com/browse/RHEL-47264 +Upstream Status: iptables commit 69da16a7790048a176a44530eb57e4b60184ce6e + +commit 69da16a7790048a176a44530eb57e4b60184ce6e +Author: Phil Sutter +Date: Fri Jul 12 13:03:18 2024 +0200 + + xtables-monitor: Flush stdout after all lines of output + + Writing an xtables-monitor testsuite is pretty much impossible without + this due to unreliable output flushing. Just move the fflush() call from + trace_cb() to its caller so monitor events benefit from it as well. + + Fixes: 07af4da52ab30 ("xtables-monitor: fix rule printing") + Signed-off-by: Phil Sutter + +Signed-off-by: Phil Sutter +--- + iptables/xtables-monitor.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/iptables/xtables-monitor.c b/iptables/xtables-monitor.c +index cf92355..90d1cc5 100644 +--- a/iptables/xtables-monitor.c ++++ b/iptables/xtables-monitor.c +@@ -544,7 +544,6 @@ static int trace_cb(const struct nlmsghdr *nlh, struct cb_arg *arg) + err_free: + nftnl_trace_free(nlt); + err: +- fflush(stdout); + return MNL_CB_OK; + } + +@@ -576,6 +575,7 @@ static int monitor_cb(const struct nlmsghdr *nlh, void *data) + break; + } + ++ fflush(stdout); + return ret; + } + diff --git a/0011-xtables-monitor-Align-builtin-chain-and-table-output.patch b/0011-xtables-monitor-Align-builtin-chain-and-table-output.patch new file mode 100644 index 0000000..92e5697 --- /dev/null +++ b/0011-xtables-monitor-Align-builtin-chain-and-table-output.patch @@ -0,0 +1,37 @@ +From 8a3ce49b4400b6027367d7b7b11cc8c694c17961 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Wed, 14 Aug 2024 14:30:11 +0200 +Subject: [PATCH] xtables-monitor: Align builtin chain and table output + +JIRA: https://issues.redhat.com/browse/RHEL-47264 +Upstream Status: iptables commit 90fb6635c8b7d1ad22108d838105c01c17a5de44 + +commit 90fb6635c8b7d1ad22108d838105c01c17a5de44 +Author: Phil Sutter +Date: Fri Jul 12 13:37:12 2024 +0200 + + xtables-monitor: Align builtin chain and table output + + Drop the leading hash sign and add "NEW/DEL chain" annotation. + + Signed-off-by: Phil Sutter + +Signed-off-by: Phil Sutter +--- + iptables/xtables-monitor.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/iptables/xtables-monitor.c b/iptables/xtables-monitor.c +index 90d1cc5..e136e9b 100644 +--- a/iptables/xtables-monitor.c ++++ b/iptables/xtables-monitor.c +@@ -153,7 +153,8 @@ static int chain_cb(const struct nlmsghdr *nlh, void *data) + break; + default: + nftnl_chain_snprintf(buf, sizeof(buf), c, NFTNL_OUTPUT_DEFAULT, 0); +- printf("# nft: %s\n", buf); ++ printf("nft: %s chain: %s\n", ++ type == NFT_MSG_NEWCHAIN ? "NEW" : "DEL", buf); + goto err_free; + } + diff --git a/0012-xtables-monitor-Support-arptables-chain-events.patch b/0012-xtables-monitor-Support-arptables-chain-events.patch new file mode 100644 index 0000000..b6f6f34 --- /dev/null +++ b/0012-xtables-monitor-Support-arptables-chain-events.patch @@ -0,0 +1,38 @@ +From 3ca04d4228f6f1e1d604cd4810e79a19c4ab5400 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Wed, 14 Aug 2024 14:30:11 +0200 +Subject: [PATCH] xtables-monitor: Support arptables chain events + +JIRA: https://issues.redhat.com/browse/RHEL-47264 +Upstream Status: iptables commit de18b0da0312b81698c1dee76b1a36c47aed52d7 + +commit de18b0da0312b81698c1dee76b1a36c47aed52d7 +Author: Phil Sutter +Date: Fri Jul 12 15:48:49 2024 +0200 + + xtables-monitor: Support arptables chain events + + Print arptables NEWCHAIN/DELCHAIN events just like for iptables, using + the '-0' prefix rule callback already uses. + + Signed-off-by: Phil Sutter + +Signed-off-by: Phil Sutter +--- + iptables/xtables-monitor.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/iptables/xtables-monitor.c b/iptables/xtables-monitor.c +index e136e9b..714a2df 100644 +--- a/iptables/xtables-monitor.c ++++ b/iptables/xtables-monitor.c +@@ -151,6 +151,9 @@ static int chain_cb(const struct nlmsghdr *nlh, void *data) + case NFPROTO_IPV6: + family = 6; + break; ++ case NFPROTO_ARP: ++ family = 0; ++ break; + default: + nftnl_chain_snprintf(buf, sizeof(buf), c, NFTNL_OUTPUT_DEFAULT, 0); + printf("nft: %s chain: %s\n", diff --git a/0013-tests-shell-New-xtables-monitor-test.patch b/0013-tests-shell-New-xtables-monitor-test.patch new file mode 100644 index 0000000..9965f91 --- /dev/null +++ b/0013-tests-shell-New-xtables-monitor-test.patch @@ -0,0 +1,179 @@ +From ba52fc13241a72ad26b7ea0cd38a1e8ded693961 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Wed, 14 Aug 2024 14:30:11 +0200 +Subject: [PATCH] tests: shell: New xtables-monitor test + +JIRA: https://issues.redhat.com/browse/RHEL-47264 +Upstream Status: iptables commit 876a71bf7ad573dea998ca61a03fd35f2b04557b + +commit 876a71bf7ad573dea998ca61a03fd35f2b04557b +Author: Phil Sutter +Date: Fri Jul 12 13:10:08 2024 +0200 + + tests: shell: New xtables-monitor test + + Only events monitoring for now. + + Signed-off-by: Phil Sutter + +Signed-off-by: Phil Sutter +--- + .../testcases/nft-only/0012-xtables-monitor_0 | 149 ++++++++++++++++++ + 1 file changed, 149 insertions(+) + create mode 100755 iptables/tests/shell/testcases/nft-only/0012-xtables-monitor_0 + +diff --git a/iptables/tests/shell/testcases/nft-only/0012-xtables-monitor_0 b/iptables/tests/shell/testcases/nft-only/0012-xtables-monitor_0 +new file mode 100755 +index 0000000..7b028ba +--- /dev/null ++++ b/iptables/tests/shell/testcases/nft-only/0012-xtables-monitor_0 +@@ -0,0 +1,149 @@ ++#!/bin/bash ++ ++[[ $XT_MULTI == *xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; } ++ ++log=$(mktemp) ++trap "rm -f $log" EXIT ++echo "logging into file $log" ++rc=0 ++ ++# Filter monitor output: ++# - NEWGEN event is moot: ++# - GENID/PID are arbitrary, ++# - NAME always "xtables-nft-mul" ++# - handle is arbitrary as well ++logfilter() { # (logfile) ++ grep -v '^NEWGEN:' "$1" | sed -e 's/handle [0-9]\+/handle 0/' ++} ++ ++# Compare monitor output for given command against content of the global $EXP ++monitorcheck() { # (cmd ...) ++ $XT_MULTI xtables-monitor -e >"$log"& ++ monpid=$! ++ sleep 0.5 ++ ++ $XT_MULTI "$@" || { ++ echo "Error: command failed: $@" ++ let "rc++" ++ kill $monpid ++ wait ++ return ++ } ++ sleep 0.5 ++ kill $monpid ++ wait ++ diffout=$(diff -u <(echo "$EXP") <(logfilter "$log")) || { ++ echo "Fail: unexpected result for command: '$@':" ++ grep -v '^\(---\|+++\|@@\)' <<< "$diffout" ++ let "rc++" ++ } ++} ++ ++EXP="\ ++ EVENT: nft: NEW table: table filter ip flags 0 use 1 handle 0 ++ EVENT: nft: NEW chain: ip filter FORWARD use 1 type filter hook forward prio 0 policy accept packets 0 bytes 0 flags 1 ++ EVENT: -4 -t filter -A FORWARD -j ACCEPT" ++monitorcheck iptables -A FORWARD -j ACCEPT ++ ++EXP="\ ++ EVENT: nft: NEW table: table filter ip6 flags 0 use 1 handle 0 ++ EVENT: nft: NEW chain: ip6 filter FORWARD use 1 type filter hook forward prio 0 policy accept packets 0 bytes 0 flags 1 ++ EVENT: -6 -t filter -A FORWARD -j ACCEPT" ++monitorcheck ip6tables -A FORWARD -j ACCEPT ++ ++# FIXME ++EXP="\ ++ EVENT: nft: NEW table: table filter bridge flags 0 use 1 handle 0 ++ EVENT: nft: NEW chain: bridge filter FORWARD use 1 type filter hook forward prio -200 policy accept packets 0 bytes 0 flags 1 ++ EVENT: " ++monitorcheck ebtables -A FORWARD -j ACCEPT ++ ++EXP="\ ++ EVENT: nft: NEW table: table filter arp flags 0 use 1 handle 0 ++ EVENT: nft: NEW chain: arp filter INPUT use 1 type filter hook input prio 0 policy accept packets 0 bytes 0 flags 1 ++ EVENT: -0 -t filter -A INPUT -j ACCEPT" ++monitorcheck arptables -A INPUT -j ACCEPT ++ ++EXP=" EVENT: -4 -t filter -N foo" ++monitorcheck iptables -N foo ++ ++EXP=" EVENT: -6 -t filter -N foo" ++monitorcheck ip6tables -N foo ++ ++# FIXME ++EXP="\ ++ EVENT: nft: NEW chain: bridge filter foo use 1 ++ EVENT: " ++monitorcheck ebtables -N foo ++ ++EXP=" EVENT: -0 -t filter -N foo" ++monitorcheck arptables -N foo ++ ++# meta l4proto matches require proper nft_handle:family value ++EXP=" EVENT: -4 -t filter -A FORWARD -i eth1 -o eth2 -p tcp -m tcp --dport 22 -j ACCEPT" ++monitorcheck iptables -A FORWARD -i eth1 -o eth2 -p tcp --dport 22 -j ACCEPT ++ ++EXP=" EVENT: -6 -t filter -A FORWARD -i eth1 -o eth2 -p udp -m udp --sport 1337 -j ACCEPT" ++monitorcheck ip6tables -A FORWARD -i eth1 -o eth2 -p udp --sport 1337 -j ACCEPT ++ ++# FIXME ++EXP=" EVENT: " ++monitorcheck ebtables -A FORWARD -i eth1 -o eth2 -p ip --ip-protocol udp --ip-source-port 1337 -j ACCEPT ++ ++EXP=" EVENT: -0 -t filter -A INPUT -j ACCEPT -i eth1 -s 1.2.3.4 --src-mac 01:02:03:04:05:06" ++monitorcheck arptables -A INPUT -i eth1 -s 1.2.3.4 --src-mac 01:02:03:04:05:06 -j ACCEPT ++ ++EXP=" EVENT: -4 -t filter -D FORWARD -i eth1 -o eth2 -p tcp -m tcp --dport 22 -j ACCEPT" ++monitorcheck iptables -D FORWARD -i eth1 -o eth2 -p tcp --dport 22 -j ACCEPT ++ ++EXP=" EVENT: -6 -t filter -D FORWARD -i eth1 -o eth2 -p udp -m udp --sport 1337 -j ACCEPT" ++monitorcheck ip6tables -D FORWARD -i eth1 -o eth2 -p udp --sport 1337 -j ACCEPT ++ ++# FIXME ++EXP=" EVENT: " ++monitorcheck ebtables -D FORWARD -i eth1 -o eth2 -p ip --ip-protocol udp --ip-source-port 1337 -j ACCEPT ++ ++EXP=" EVENT: -0 -t filter -D INPUT -j ACCEPT -i eth1 -s 1.2.3.4 --src-mac 01:02:03:04:05:06" ++monitorcheck arptables -D INPUT -i eth1 -s 1.2.3.4 --src-mac 01:02:03:04:05:06 -j ACCEPT ++ ++EXP=" EVENT: -4 -t filter -X foo" ++monitorcheck iptables -X foo ++ ++EXP=" EVENT: -6 -t filter -X foo" ++monitorcheck ip6tables -X foo ++ ++# FIXME ++EXP="\ ++ EVENT: ++ EVENT: nft: DEL chain: bridge filter foo use 0" ++monitorcheck ebtables -X foo ++ ++EXP=" EVENT: -0 -t filter -X foo" ++monitorcheck arptables -X foo ++ ++EXP=" EVENT: -4 -t filter -D FORWARD -j ACCEPT" ++monitorcheck iptables -F FORWARD ++ ++EXP=" EVENT: -6 -t filter -D FORWARD -j ACCEPT" ++monitorcheck ip6tables -F FORWARD ++ ++# FIXME ++EXP=" EVENT: " ++monitorcheck ebtables -F FORWARD ++ ++EXP=" EVENT: -0 -t filter -D INPUT -j ACCEPT" ++monitorcheck arptables -F INPUT ++ ++EXP=" EVENT: nft: DEL chain: ip filter FORWARD use 0 type filter hook forward prio 0 policy accept packets 0 bytes 0 flags 1" ++monitorcheck iptables -X FORWARD ++ ++EXP=" EVENT: nft: DEL chain: ip6 filter FORWARD use 0 type filter hook forward prio 0 policy accept packets 0 bytes 0 flags 1" ++monitorcheck ip6tables -X FORWARD ++ ++EXP=" EVENT: nft: DEL chain: bridge filter FORWARD use 0 type filter hook forward prio -200 policy accept packets 0 bytes 0 flags 1" ++monitorcheck ebtables -X FORWARD ++ ++EXP=" EVENT: nft: DEL chain: arp filter INPUT use 0 type filter hook input prio 0 policy accept packets 0 bytes 0 flags 1" ++monitorcheck arptables -X INPUT ++ ++exit $rc diff --git a/0014-xtables-monitor-Fix-for-ebtables-rule-events.patch b/0014-xtables-monitor-Fix-for-ebtables-rule-events.patch new file mode 100644 index 0000000..fb4f8ac --- /dev/null +++ b/0014-xtables-monitor-Fix-for-ebtables-rule-events.patch @@ -0,0 +1,102 @@ +From 08754c9274e81f2fcb96ce0e2169e0333d2a8dcf Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Wed, 14 Aug 2024 14:30:11 +0200 +Subject: [PATCH] xtables-monitor: Fix for ebtables rule events + +JIRA: https://issues.redhat.com/browse/RHEL-47264 +Upstream Status: iptables commit 56217d37aa38938ec3e118ae761481522155ff21 + +commit 56217d37aa38938ec3e118ae761481522155ff21 +Author: Phil Sutter +Date: Fri Jul 12 14:01:45 2024 +0200 + + xtables-monitor: Fix for ebtables rule events + + Bridge family wasn't recognized in rule_cb(), so merely an empty + "EVENT:" line was printed for ebtables rule changes. For lack of a + well-known family modifier flag for bridge family, simply prefix rules + by "ebtables". + + Signed-off-by: Phil Sutter + +Signed-off-by: Phil Sutter +--- + .../testcases/nft-only/0012-xtables-monitor_0 | 15 ++++++--------- + iptables/xtables-monitor.c | 3 +++ + 2 files changed, 9 insertions(+), 9 deletions(-) + +diff --git a/iptables/tests/shell/testcases/nft-only/0012-xtables-monitor_0 b/iptables/tests/shell/testcases/nft-only/0012-xtables-monitor_0 +index 7b028ba..0f0295b 100755 +--- a/iptables/tests/shell/testcases/nft-only/0012-xtables-monitor_0 ++++ b/iptables/tests/shell/testcases/nft-only/0012-xtables-monitor_0 +@@ -55,7 +55,7 @@ monitorcheck ip6tables -A FORWARD -j ACCEPT + EXP="\ + EVENT: nft: NEW table: table filter bridge flags 0 use 1 handle 0 + EVENT: nft: NEW chain: bridge filter FORWARD use 1 type filter hook forward prio -200 policy accept packets 0 bytes 0 flags 1 +- EVENT: " ++ EVENT: ebtables -t filter -A FORWARD -j ACCEPT" + monitorcheck ebtables -A FORWARD -j ACCEPT + + EXP="\ +@@ -73,7 +73,7 @@ monitorcheck ip6tables -N foo + # FIXME + EXP="\ + EVENT: nft: NEW chain: bridge filter foo use 1 +- EVENT: " ++ EVENT: ebtables -t filter -A foo -j ACCEPT" + monitorcheck ebtables -N foo + + EXP=" EVENT: -0 -t filter -N foo" +@@ -86,8 +86,7 @@ monitorcheck iptables -A FORWARD -i eth1 -o eth2 -p tcp --dport 22 -j ACCEPT + EXP=" EVENT: -6 -t filter -A FORWARD -i eth1 -o eth2 -p udp -m udp --sport 1337 -j ACCEPT" + monitorcheck ip6tables -A FORWARD -i eth1 -o eth2 -p udp --sport 1337 -j ACCEPT + +-# FIXME +-EXP=" EVENT: " ++EXP=" EVENT: ebtables -t filter -A FORWARD -p IPv4 -i eth1 -o eth2 --ip-proto udp --ip-sport 1337 -j ACCEPT" + monitorcheck ebtables -A FORWARD -i eth1 -o eth2 -p ip --ip-protocol udp --ip-source-port 1337 -j ACCEPT + + EXP=" EVENT: -0 -t filter -A INPUT -j ACCEPT -i eth1 -s 1.2.3.4 --src-mac 01:02:03:04:05:06" +@@ -99,8 +98,7 @@ monitorcheck iptables -D FORWARD -i eth1 -o eth2 -p tcp --dport 22 -j ACCEPT + EXP=" EVENT: -6 -t filter -D FORWARD -i eth1 -o eth2 -p udp -m udp --sport 1337 -j ACCEPT" + monitorcheck ip6tables -D FORWARD -i eth1 -o eth2 -p udp --sport 1337 -j ACCEPT + +-# FIXME +-EXP=" EVENT: " ++EXP=" EVENT: ebtables -t filter -D FORWARD -p IPv4 -i eth1 -o eth2 --ip-proto udp --ip-sport 1337 -j ACCEPT" + monitorcheck ebtables -D FORWARD -i eth1 -o eth2 -p ip --ip-protocol udp --ip-source-port 1337 -j ACCEPT + + EXP=" EVENT: -0 -t filter -D INPUT -j ACCEPT -i eth1 -s 1.2.3.4 --src-mac 01:02:03:04:05:06" +@@ -114,7 +112,7 @@ monitorcheck ip6tables -X foo + + # FIXME + EXP="\ +- EVENT: ++ EVENT: ebtables -t filter -D foo -j ACCEPT + EVENT: nft: DEL chain: bridge filter foo use 0" + monitorcheck ebtables -X foo + +@@ -127,8 +125,7 @@ monitorcheck iptables -F FORWARD + EXP=" EVENT: -6 -t filter -D FORWARD -j ACCEPT" + monitorcheck ip6tables -F FORWARD + +-# FIXME +-EXP=" EVENT: " ++EXP=" EVENT: ebtables -t filter -D FORWARD -j ACCEPT" + monitorcheck ebtables -F FORWARD + + EXP=" EVENT: -0 -t filter -D INPUT -j ACCEPT" +diff --git a/iptables/xtables-monitor.c b/iptables/xtables-monitor.c +index 714a2df..7079a03 100644 +--- a/iptables/xtables-monitor.c ++++ b/iptables/xtables-monitor.c +@@ -106,6 +106,9 @@ static int rule_cb(const struct nlmsghdr *nlh, void *data) + case NFPROTO_ARP: + printf("-0 "); + break; ++ case NFPROTO_BRIDGE: ++ printf("ebtables "); ++ break; + default: + puts(""); + goto err_free; diff --git a/0015-xtables-monitor-Ignore-ebtables-policy-rules-unless-.patch b/0015-xtables-monitor-Ignore-ebtables-policy-rules-unless-.patch new file mode 100644 index 0000000..0e10e12 --- /dev/null +++ b/0015-xtables-monitor-Ignore-ebtables-policy-rules-unless-.patch @@ -0,0 +1,109 @@ +From 4a0811c0db13ccc7217123be907d6946ded384a1 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Wed, 14 Aug 2024 14:30:12 +0200 +Subject: [PATCH] xtables-monitor: Ignore ebtables policy rules unless tracing + +JIRA: https://issues.redhat.com/browse/RHEL-47264 +Upstream Status: iptables commit 5aa4935bc88fd8acf90cce4535e58fc3be85f055 + +commit 5aa4935bc88fd8acf90cce4535e58fc3be85f055 +Author: Phil Sutter +Date: Fri Jul 12 18:07:16 2024 +0200 + + xtables-monitor: Ignore ebtables policy rules unless tracing + + Do not expose this implementation detail to users, otherwise new + user-defined chains are followed by a new rule event. + + When tracing, they are useful as they potentially terminate rule + traversal. + + Signed-off-by: Phil Sutter + +Signed-off-by: Phil Sutter +--- + iptables/nft.c | 2 +- + iptables/nft.h | 1 + + .../shell/testcases/nft-only/0012-xtables-monitor_0 | 11 ++--------- + iptables/xtables-monitor.c | 7 +++++++ + 4 files changed, 11 insertions(+), 10 deletions(-) + +diff --git a/iptables/nft.c b/iptables/nft.c +index ad4c866..81e8f76 100644 +--- a/iptables/nft.c ++++ b/iptables/nft.c +@@ -1823,7 +1823,7 @@ nft_rule_print_save(struct nft_handle *h, const struct nftnl_rule *r, + return ret; + } + +-static bool nft_rule_is_policy_rule(struct nftnl_rule *r) ++bool nft_rule_is_policy_rule(struct nftnl_rule *r) + { + const struct nftnl_udata *tb[UDATA_TYPE_MAX + 1] = {}; + const void *data; +diff --git a/iptables/nft.h b/iptables/nft.h +index 5acbbf8..8b173d1 100644 +--- a/iptables/nft.h ++++ b/iptables/nft.h +@@ -184,6 +184,7 @@ int nft_rule_list_save(struct nft_handle *h, const char *chain, const char *tabl + int nft_rule_save(struct nft_handle *h, const char *table, unsigned int format); + int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table, bool verbose); + int nft_rule_zero_counters(struct nft_handle *h, const char *chain, const char *table, int rulenum); ++bool nft_rule_is_policy_rule(struct nftnl_rule *r); + + /* + * Operations used in userspace tools +diff --git a/iptables/tests/shell/testcases/nft-only/0012-xtables-monitor_0 b/iptables/tests/shell/testcases/nft-only/0012-xtables-monitor_0 +index 0f0295b..ef1ec3c 100755 +--- a/iptables/tests/shell/testcases/nft-only/0012-xtables-monitor_0 ++++ b/iptables/tests/shell/testcases/nft-only/0012-xtables-monitor_0 +@@ -51,7 +51,6 @@ EXP="\ + EVENT: -6 -t filter -A FORWARD -j ACCEPT" + monitorcheck ip6tables -A FORWARD -j ACCEPT + +-# FIXME + EXP="\ + EVENT: nft: NEW table: table filter bridge flags 0 use 1 handle 0 + EVENT: nft: NEW chain: bridge filter FORWARD use 1 type filter hook forward prio -200 policy accept packets 0 bytes 0 flags 1 +@@ -70,10 +69,7 @@ monitorcheck iptables -N foo + EXP=" EVENT: -6 -t filter -N foo" + monitorcheck ip6tables -N foo + +-# FIXME +-EXP="\ +- EVENT: nft: NEW chain: bridge filter foo use 1 +- EVENT: ebtables -t filter -A foo -j ACCEPT" ++EXP=" EVENT: nft: NEW chain: bridge filter foo use 1" + monitorcheck ebtables -N foo + + EXP=" EVENT: -0 -t filter -N foo" +@@ -110,10 +106,7 @@ monitorcheck iptables -X foo + EXP=" EVENT: -6 -t filter -X foo" + monitorcheck ip6tables -X foo + +-# FIXME +-EXP="\ +- EVENT: ebtables -t filter -D foo -j ACCEPT +- EVENT: nft: DEL chain: bridge filter foo use 0" ++EXP=" EVENT: nft: DEL chain: bridge filter foo use 0" + monitorcheck ebtables -X foo + + EXP=" EVENT: -0 -t filter -X foo" +diff --git a/iptables/xtables-monitor.c b/iptables/xtables-monitor.c +index 7079a03..b54a704 100644 +--- a/iptables/xtables-monitor.c ++++ b/iptables/xtables-monitor.c +@@ -96,6 +96,13 @@ static int rule_cb(const struct nlmsghdr *nlh, void *data) + arg->h->ops = nft_family_ops_lookup(family); + arg->h->family = family; + ++ /* ignore policy rules unless tracing, ++ * they are reported when deleting user-defined chains */ ++ if (family == NFPROTO_BRIDGE && ++ arg->is_event && ++ nft_rule_is_policy_rule(r)) ++ goto err_free; ++ + if (arg->is_event) + printf(" EVENT: "); + switch (family) { diff --git a/iptables.spec b/iptables.spec index dfe8685..1d3d332 100644 --- a/iptables.spec +++ b/iptables.spec @@ -1,5 +1,5 @@ %define iptables_rpmversion 1.8.10 -%define iptables_specrelease 4 +%define iptables_specrelease 5 # install init scripts to /usr/libexec with systemd %global script_path %{_libexecdir}/iptables @@ -38,6 +38,16 @@ Patch2: 0002-extensions-SECMARK-Use-a-better-context-in-test-case.pa Patch3: 0003-ebtables-Fix-corner-case-noflush-restore-bug.patch Patch4: 0004-nft-Fix-for-broken-recover_rule_compat.patch Patch5: 0005-extensions-libxt_sctp-Add-an-extra-assert.patch +Patch6: 0006-nft-Fix-for-zeroing-non-existent-builtin-chains.patch +Patch7: 0007-nft-cache-Annotate-faked-base-chains-as-such.patch +Patch8: 0008-nft-Fix-for-zeroing-existent-builtin-chains.patch +Patch9: 0009-xtables-monitor-Proper-re-init-for-rule-s-family.patch +Patch10: 0010-xtables-monitor-Flush-stdout-after-all-lines-of-outp.patch +Patch11: 0011-xtables-monitor-Align-builtin-chain-and-table-output.patch +Patch12: 0012-xtables-monitor-Support-arptables-chain-events.patch +Patch13: 0013-tests-shell-New-xtables-monitor-test.patch +Patch14: 0014-xtables-monitor-Fix-for-ebtables-rule-events.patch +Patch15: 0015-xtables-monitor-Ignore-ebtables-policy-rules-unless-.patch # pf.os: ISC license # iptables-apply: Artistic 2.0 @@ -472,6 +482,18 @@ fi %ghost %{_mandir}/man8/ebtables{,-translate}.8.gz %changelog +* Wed Aug 14 2024 Phil Sutter [1.8.10-5.el9] +- xtables-monitor: Ignore ebtables policy rules unless tracing (Phil Sutter) [RHEL-47264] +- xtables-monitor: Fix for ebtables rule events (Phil Sutter) [RHEL-47264] +- tests: shell: New xtables-monitor test (Phil Sutter) [RHEL-47264] +- xtables-monitor: Support arptables chain events (Phil Sutter) [RHEL-47264] +- xtables-monitor: Align builtin chain and table output (Phil Sutter) [RHEL-47264] +- xtables-monitor: Flush stdout after all lines of output (Phil Sutter) [RHEL-47264] +- xtables-monitor: Proper re-init for rule's family (Phil Sutter) [RHEL-47264] +- nft: Fix for zeroing existent builtin chains (Phil Sutter) [RHEL-49497] +- nft: cache: Annotate faked base chains as such (Phil Sutter) [RHEL-49497] +- nft: Fix for zeroing non-existent builtin chains (Phil Sutter) [RHEL-49497] + * Wed Jul 03 2024 Phil Sutter [1.8.10-4.el9] - spec: Simplify legacy package integration (Phil Sutter) [RHEL-5797]