import iptables-1.8.4-15.el8_3.3
This commit is contained in:
parent
ec7bd8a053
commit
d24e02cc5e
@ -0,0 +1,167 @@
|
||||
From d1b516014e4883f30ee2faf264dd89a6d7940e2c Mon Sep 17 00:00:00 2001
|
||||
From: Phil Sutter <phil@nwl.cc>
|
||||
Date: Sat, 3 Oct 2020 17:46:09 +0200
|
||||
Subject: [PATCH] nft: Make batch_add_chain() return the added batch object
|
||||
|
||||
Do this so in a later patch the 'skip' field can be adjusted.
|
||||
|
||||
While being at it, simplify a few callers and eliminate the need for a
|
||||
'ret' variable.
|
||||
|
||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
||||
Reviewed-by: Florian Westphal <fw@strlen.de>
|
||||
(cherry picked from commit 0d77e64e8d9b8a3984b01a4951524dc40f61f4b6)
|
||||
|
||||
Conflicts:
|
||||
iptables/nft.c
|
||||
-> Upstream changed good/bad return codes of nft_chain_restore()
|
||||
function.
|
||||
|
||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
||||
---
|
||||
iptables/nft.c | 35 +++++++++++++++++------------------
|
||||
1 file changed, 17 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/iptables/nft.c b/iptables/nft.c
|
||||
index e95e99f1d8d71..0efd18d57320f 100644
|
||||
--- a/iptables/nft.c
|
||||
+++ b/iptables/nft.c
|
||||
@@ -398,10 +398,11 @@ batch_set_add(struct nft_handle *h, enum obj_update_type type,
|
||||
return batch_add(h, type, s);
|
||||
}
|
||||
|
||||
-static int batch_chain_add(struct nft_handle *h, enum obj_update_type type,
|
||||
+static struct obj_update *
|
||||
+batch_chain_add(struct nft_handle *h, enum obj_update_type type,
|
||||
struct nftnl_chain *c)
|
||||
{
|
||||
- return batch_add(h, type, c) ? 0 : -1;
|
||||
+ return batch_add(h, type, c);
|
||||
}
|
||||
|
||||
static struct obj_update *
|
||||
@@ -910,7 +911,6 @@ int nft_chain_set(struct nft_handle *h, const char *table,
|
||||
const struct xt_counters *counters)
|
||||
{
|
||||
struct nftnl_chain *c = NULL;
|
||||
- int ret;
|
||||
|
||||
nft_fn = nft_chain_set;
|
||||
|
||||
@@ -924,10 +924,11 @@ int nft_chain_set(struct nft_handle *h, const char *table,
|
||||
if (c == NULL)
|
||||
return 0;
|
||||
|
||||
- ret = batch_chain_add(h, NFT_COMPAT_CHAIN_UPDATE, c);
|
||||
+ if (!batch_chain_add(h, NFT_COMPAT_CHAIN_UPDATE, c))
|
||||
+ return 0;
|
||||
|
||||
/* the core expects 1 for success and 0 for error */
|
||||
- return ret == 0 ? 1 : 0;
|
||||
+ return 1;
|
||||
}
|
||||
|
||||
static int __add_match(struct nftnl_expr *e, struct xt_entry_match *m)
|
||||
@@ -1734,7 +1735,6 @@ int nft_chain_user_add(struct nft_handle *h, const char *chain, const char *tabl
|
||||
{
|
||||
struct nftnl_chain_list *list;
|
||||
struct nftnl_chain *c;
|
||||
- int ret;
|
||||
|
||||
nft_fn = nft_chain_user_add;
|
||||
|
||||
@@ -1754,14 +1754,15 @@ int nft_chain_user_add(struct nft_handle *h, const char *chain, const char *tabl
|
||||
if (h->family == NFPROTO_BRIDGE)
|
||||
nftnl_chain_set_u32(c, NFTNL_CHAIN_POLICY, NF_ACCEPT);
|
||||
|
||||
- ret = batch_chain_add(h, NFT_COMPAT_CHAIN_USER_ADD, c);
|
||||
+ if (!batch_chain_add(h, NFT_COMPAT_CHAIN_USER_ADD, c))
|
||||
+ return 0;
|
||||
|
||||
list = nft_chain_list_get(h, table, chain);
|
||||
if (list)
|
||||
nftnl_chain_list_add(c, list);
|
||||
|
||||
/* the core expects 1 for success and 0 for error */
|
||||
- return ret == 0 ? 1 : 0;
|
||||
+ return 1;
|
||||
}
|
||||
|
||||
int nft_chain_restore(struct nft_handle *h, const char *chain, const char *table)
|
||||
@@ -1769,7 +1770,6 @@ int nft_chain_restore(struct nft_handle *h, const char *chain, const char *table
|
||||
struct nftnl_chain_list *list;
|
||||
struct nftnl_chain *c;
|
||||
bool created = false;
|
||||
- int ret;
|
||||
|
||||
c = nft_chain_find(h, table, chain);
|
||||
if (c) {
|
||||
@@ -1794,13 +1794,14 @@ int nft_chain_restore(struct nft_handle *h, const char *chain, const char *table
|
||||
if (!created)
|
||||
return 0;
|
||||
|
||||
- ret = batch_chain_add(h, NFT_COMPAT_CHAIN_USER_ADD, c);
|
||||
+ if (!batch_chain_add(h, NFT_COMPAT_CHAIN_USER_ADD, c))
|
||||
+ return -1;
|
||||
|
||||
list = nft_chain_list_get(h, table, chain);
|
||||
if (list)
|
||||
nftnl_chain_list_add(c, list);
|
||||
|
||||
- return ret;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
/* From linux/netlink.h */
|
||||
@@ -1818,7 +1819,6 @@ static int __nft_chain_user_del(struct nftnl_chain *c, void *data)
|
||||
{
|
||||
struct chain_user_del_data *d = data;
|
||||
struct nft_handle *h = d->handle;
|
||||
- int ret;
|
||||
|
||||
/* don't delete built-in chain */
|
||||
if (nft_chain_builtin(c))
|
||||
@@ -1834,8 +1834,7 @@ static int __nft_chain_user_del(struct nftnl_chain *c, void *data)
|
||||
|
||||
/* XXX This triggers a fast lookup from the kernel. */
|
||||
nftnl_chain_unset(c, NFTNL_CHAIN_HANDLE);
|
||||
- ret = batch_chain_add(h, NFT_COMPAT_CHAIN_USER_DEL, c);
|
||||
- if (ret)
|
||||
+ if (!batch_chain_add(h, NFT_COMPAT_CHAIN_USER_DEL, c))
|
||||
return -1;
|
||||
|
||||
nftnl_chain_list_del(c);
|
||||
@@ -1910,7 +1909,6 @@ int nft_chain_user_rename(struct nft_handle *h,const char *chain,
|
||||
{
|
||||
struct nftnl_chain *c;
|
||||
uint64_t handle;
|
||||
- int ret;
|
||||
|
||||
nft_fn = nft_chain_user_rename;
|
||||
|
||||
@@ -1941,10 +1939,11 @@ int nft_chain_user_rename(struct nft_handle *h,const char *chain,
|
||||
nftnl_chain_set_str(c, NFTNL_CHAIN_NAME, newname);
|
||||
nftnl_chain_set_u64(c, NFTNL_CHAIN_HANDLE, handle);
|
||||
|
||||
- ret = batch_chain_add(h, NFT_COMPAT_CHAIN_RENAME, c);
|
||||
+ if (!batch_chain_add(h, NFT_COMPAT_CHAIN_RENAME, c))
|
||||
+ return 0;
|
||||
|
||||
/* the core expects 1 for success and 0 for error */
|
||||
- return ret == 0 ? 1 : 0;
|
||||
+ return 1;
|
||||
}
|
||||
|
||||
bool nft_table_find(struct nft_handle *h, const char *tablename)
|
||||
@@ -3217,7 +3216,7 @@ static int __nft_chain_zero_counters(struct nftnl_chain *c, 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))
|
||||
+ if (!batch_chain_add(h, NFT_COMPAT_CHAIN_ZERO, c))
|
||||
return -1;
|
||||
}
|
||||
|
||||
--
|
||||
2.28.0
|
||||
|
@ -0,0 +1,42 @@
|
||||
From 2dff9a669400644ec1e66d394b03d743eec2cd55 Mon Sep 17 00:00:00 2001
|
||||
From: Phil Sutter <phil@nwl.cc>
|
||||
Date: Mon, 5 Oct 2020 15:54:35 +0200
|
||||
Subject: [PATCH] nft: Fix error reporting for refreshed transactions
|
||||
|
||||
When preparing a batch from the list of batch objects in nft_action(),
|
||||
the sequence number used for each object is stored within that object
|
||||
for later matching against returned error messages. Though if the
|
||||
transaction has to be refreshed, some of those objects may be skipped,
|
||||
other objects take over their sequence number and errors are matched to
|
||||
skipped objects. Avoid this by resetting the skipped object's sequence
|
||||
number to zero.
|
||||
|
||||
Fixes: 58d7de0181f61 ("xtables: handle concurrent ruleset modifications")
|
||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
||||
Reviewed-by: Florian Westphal <fw@strlen.de>
|
||||
(cherry picked from commit e98b825a037807bf6c918eb66ee9682cc4c46183)
|
||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
||||
---
|
||||
iptables/nft.c | 5 +++--
|
||||
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/iptables/nft.c b/iptables/nft.c
|
||||
index 0efd18d57320f..d661ac2cafda6 100644
|
||||
--- a/iptables/nft.c
|
||||
+++ b/iptables/nft.c
|
||||
@@ -2767,9 +2767,10 @@ retry:
|
||||
h->nft_genid++;
|
||||
|
||||
list_for_each_entry(n, &h->obj_list, head) {
|
||||
-
|
||||
- if (n->skip)
|
||||
+ if (n->skip) {
|
||||
+ n->seq = 0;
|
||||
continue;
|
||||
+ }
|
||||
|
||||
n->seq = seq++;
|
||||
switch (n->type) {
|
||||
--
|
||||
2.28.0
|
||||
|
242
SOURCES/0028-nft-Fix-for-concurrent-noflush-restore-calls.patch
Normal file
242
SOURCES/0028-nft-Fix-for-concurrent-noflush-restore-calls.patch
Normal file
@ -0,0 +1,242 @@
|
||||
From 575a1e5589f813af7e838c045863b510b4740353 Mon Sep 17 00:00:00 2001
|
||||
From: Phil Sutter <phil@nwl.cc>
|
||||
Date: Mon, 5 Oct 2020 16:06:49 +0200
|
||||
Subject: [PATCH] nft: Fix for concurrent noflush restore calls
|
||||
|
||||
Transaction refresh was broken with regards to nft_chain_restore(): It
|
||||
created a rule flush batch object only if the chain was found in cache
|
||||
and a chain add object only if the chain was not found. Yet with
|
||||
concurrent ruleset updates, one has to expect both situations:
|
||||
|
||||
* If a chain vanishes, the rule flush job must be skipped and instead
|
||||
the chain add job become active.
|
||||
|
||||
* If a chain appears, the chain add job must be skipped and instead
|
||||
rules flushed.
|
||||
|
||||
Change the code accordingly: Create both batch objects and set their
|
||||
'skip' field depending on the situation in cache and adjust both in
|
||||
nft_refresh_transaction().
|
||||
|
||||
As a side-effect, the implicit rule flush becomes explicit and all
|
||||
handling of implicit batch jobs is dropped along with the related field
|
||||
indicating such.
|
||||
|
||||
Reuse the 'implicit' parameter of __nft_rule_flush() to control the
|
||||
initial 'skip' field value instead.
|
||||
|
||||
A subtle caveat is vanishing of existing chains: Creating the chain add
|
||||
job based on the chain in cache causes a netlink message containing that
|
||||
chain's handle which the kernel dislikes. Therefore unset the chain's
|
||||
handle in that case.
|
||||
|
||||
Fixes: 58d7de0181f61 ("xtables: handle concurrent ruleset modifications")
|
||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
||||
(cherry picked from commit dac904bdcd9a18aabafee7275ccf0c2bd53800f3)
|
||||
|
||||
Conflicts:
|
||||
iptables/nft.c
|
||||
-> Upstream changed good/bad return codes of nft_chain_restore()
|
||||
function.
|
||||
|
||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
||||
---
|
||||
iptables/nft.c | 58 ++++++++++---------
|
||||
.../ipt-restore/0016-concurrent-restores_0 | 53 +++++++++++++++++
|
||||
2 files changed, 83 insertions(+), 28 deletions(-)
|
||||
create mode 100755 iptables/tests/shell/testcases/ipt-restore/0016-concurrent-restores_0
|
||||
|
||||
diff --git a/iptables/nft.c b/iptables/nft.c
|
||||
index d661ac2cafda6..dc5490c085364 100644
|
||||
--- a/iptables/nft.c
|
||||
+++ b/iptables/nft.c
|
||||
@@ -283,7 +283,6 @@ struct obj_update {
|
||||
struct list_head head;
|
||||
enum obj_update_type type:8;
|
||||
uint8_t skip:1;
|
||||
- uint8_t implicit:1;
|
||||
unsigned int seq;
|
||||
union {
|
||||
struct nftnl_table *table;
|
||||
@@ -1650,7 +1649,7 @@ int nft_rule_save(struct nft_handle *h, const char *table, unsigned int format)
|
||||
|
||||
static void
|
||||
__nft_rule_flush(struct nft_handle *h, const char *table,
|
||||
- const char *chain, bool verbose, bool implicit)
|
||||
+ const char *chain, bool verbose, bool skip)
|
||||
{
|
||||
struct obj_update *obj;
|
||||
struct nftnl_rule *r;
|
||||
@@ -1672,7 +1671,7 @@ __nft_rule_flush(struct nft_handle *h, const char *table,
|
||||
return;
|
||||
}
|
||||
|
||||
- obj->implicit = implicit;
|
||||
+ obj->skip = skip;
|
||||
}
|
||||
|
||||
int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table,
|
||||
@@ -1768,17 +1767,12 @@ int nft_chain_user_add(struct nft_handle *h, const char *chain, const char *tabl
|
||||
int nft_chain_restore(struct nft_handle *h, const char *chain, const char *table)
|
||||
{
|
||||
struct nftnl_chain_list *list;
|
||||
+ struct obj_update *obj;
|
||||
struct nftnl_chain *c;
|
||||
bool created = false;
|
||||
|
||||
c = nft_chain_find(h, table, chain);
|
||||
- if (c) {
|
||||
- /* Apparently -n still flushes existing user defined
|
||||
- * chains that are redefined.
|
||||
- */
|
||||
- if (h->noflush)
|
||||
- __nft_rule_flush(h, table, chain, false, true);
|
||||
- } else {
|
||||
+ if (!c) {
|
||||
c = nftnl_chain_alloc();
|
||||
if (!c)
|
||||
return -1;
|
||||
@@ -1786,20 +1780,26 @@ int nft_chain_restore(struct nft_handle *h, const char *chain, const char *table
|
||||
nftnl_chain_set_str(c, NFTNL_CHAIN_TABLE, table);
|
||||
nftnl_chain_set_str(c, NFTNL_CHAIN_NAME, chain);
|
||||
created = true;
|
||||
- }
|
||||
|
||||
- if (h->family == NFPROTO_BRIDGE)
|
||||
- nftnl_chain_set_u32(c, NFTNL_CHAIN_POLICY, NF_ACCEPT);
|
||||
+ list = nft_chain_list_get(h, table, chain);
|
||||
+ if (list)
|
||||
+ nftnl_chain_list_add(c, list);
|
||||
+ } else {
|
||||
+ /* If the chain should vanish meanwhile, kernel genid changes
|
||||
+ * and the transaction is refreshed enabling the chain add
|
||||
+ * object. With the handle still set, kernel interprets it as a
|
||||
+ * chain replace job and errors since it is not found anymore.
|
||||
+ */
|
||||
+ nftnl_chain_unset(c, NFTNL_CHAIN_HANDLE);
|
||||
+ }
|
||||
|
||||
- if (!created)
|
||||
- return 0;
|
||||
+ __nft_rule_flush(h, table, chain, false, created);
|
||||
|
||||
- if (!batch_chain_add(h, NFT_COMPAT_CHAIN_USER_ADD, c))
|
||||
+ obj = batch_chain_add(h, NFT_COMPAT_CHAIN_USER_ADD, c);
|
||||
+ if (!obj)
|
||||
return -1;
|
||||
|
||||
- list = nft_chain_list_get(h, table, chain);
|
||||
- if (list)
|
||||
- nftnl_chain_list_add(c, list);
|
||||
+ obj->skip = !created;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -2693,11 +2693,6 @@ static void nft_refresh_transaction(struct nft_handle *h)
|
||||
h->error.lineno = 0;
|
||||
|
||||
list_for_each_entry_safe(n, tmp, &h->obj_list, head) {
|
||||
- if (n->implicit) {
|
||||
- batch_obj_del(h, n);
|
||||
- continue;
|
||||
- }
|
||||
-
|
||||
switch (n->type) {
|
||||
case NFT_COMPAT_TABLE_FLUSH:
|
||||
tablename = nftnl_table_get_str(n->table, NFTNL_TABLE_NAME);
|
||||
@@ -2723,14 +2718,22 @@ static void nft_refresh_transaction(struct nft_handle *h)
|
||||
|
||||
c = nft_chain_find(h, tablename, chainname);
|
||||
if (c) {
|
||||
- /* -restore -n flushes existing rules from redefined user-chain */
|
||||
- __nft_rule_flush(h, tablename,
|
||||
- chainname, false, true);
|
||||
n->skip = 1;
|
||||
} else if (!c) {
|
||||
n->skip = 0;
|
||||
}
|
||||
break;
|
||||
+ case NFT_COMPAT_RULE_FLUSH:
|
||||
+ tablename = nftnl_rule_get_str(n->rule, NFTNL_RULE_TABLE);
|
||||
+ if (!tablename)
|
||||
+ continue;
|
||||
+
|
||||
+ chainname = nftnl_rule_get_str(n->rule, NFTNL_RULE_CHAIN);
|
||||
+ if (!chainname)
|
||||
+ continue;
|
||||
+
|
||||
+ n->skip = !nft_chain_find(h, tablename, chainname);
|
||||
+ break;
|
||||
case NFT_COMPAT_TABLE_ADD:
|
||||
case NFT_COMPAT_CHAIN_ADD:
|
||||
case NFT_COMPAT_CHAIN_ZERO:
|
||||
@@ -2742,7 +2745,6 @@ static void nft_refresh_transaction(struct nft_handle *h)
|
||||
case NFT_COMPAT_RULE_INSERT:
|
||||
case NFT_COMPAT_RULE_REPLACE:
|
||||
case NFT_COMPAT_RULE_DELETE:
|
||||
- case NFT_COMPAT_RULE_FLUSH:
|
||||
case NFT_COMPAT_SET_ADD:
|
||||
break;
|
||||
}
|
||||
diff --git a/iptables/tests/shell/testcases/ipt-restore/0016-concurrent-restores_0 b/iptables/tests/shell/testcases/ipt-restore/0016-concurrent-restores_0
|
||||
new file mode 100755
|
||||
index 0000000000000..53ec12fa368af
|
||||
--- /dev/null
|
||||
+++ b/iptables/tests/shell/testcases/ipt-restore/0016-concurrent-restores_0
|
||||
@@ -0,0 +1,53 @@
|
||||
+#!/bin/bash
|
||||
+
|
||||
+set -e
|
||||
+
|
||||
+RS="*filter
|
||||
+:INPUT ACCEPT [12024:3123388]
|
||||
+:FORWARD ACCEPT [0:0]
|
||||
+:OUTPUT ACCEPT [12840:2144421]
|
||||
+:FOO - [0:0]
|
||||
+:BAR0 - [0:0]
|
||||
+:BAR1 - [0:0]
|
||||
+:BAR2 - [0:0]
|
||||
+:BAR3 - [0:0]
|
||||
+:BAR4 - [0:0]
|
||||
+:BAR5 - [0:0]
|
||||
+:BAR6 - [0:0]
|
||||
+:BAR7 - [0:0]
|
||||
+:BAR8 - [0:0]
|
||||
+:BAR9 - [0:0]
|
||||
+"
|
||||
+
|
||||
+RS1="$RS
|
||||
+-X BAR3
|
||||
+-X BAR6
|
||||
+-X BAR9
|
||||
+-A FOO -s 9.9.0.1/32 -j BAR1
|
||||
+-A FOO -s 9.9.0.2/32 -j BAR2
|
||||
+-A FOO -s 9.9.0.4/32 -j BAR4
|
||||
+-A FOO -s 9.9.0.5/32 -j BAR5
|
||||
+-A FOO -s 9.9.0.7/32 -j BAR7
|
||||
+-A FOO -s 9.9.0.8/32 -j BAR8
|
||||
+COMMIT
|
||||
+"
|
||||
+
|
||||
+RS2="$RS
|
||||
+-X BAR2
|
||||
+-X BAR5
|
||||
+-X BAR7
|
||||
+-A FOO -s 9.9.0.1/32 -j BAR1
|
||||
+-A FOO -s 9.9.0.3/32 -j BAR3
|
||||
+-A FOO -s 9.9.0.4/32 -j BAR4
|
||||
+-A FOO -s 9.9.0.6/32 -j BAR6
|
||||
+-A FOO -s 9.9.0.8/32 -j BAR8
|
||||
+-A FOO -s 9.9.0.9/32 -j BAR9
|
||||
+COMMIT
|
||||
+"
|
||||
+
|
||||
+for n in $(seq 1 10); do
|
||||
+ $XT_MULTI iptables-restore --noflush -w <<< "$RS1" &
|
||||
+ $XT_MULTI iptables-restore --noflush -w <<< "$RS2" &
|
||||
+ wait -n
|
||||
+ wait -n
|
||||
+done
|
||||
--
|
||||
2.28.0
|
||||
|
@ -0,0 +1,55 @@
|
||||
From 674cce10a34e90f2791a3d58789793eef29e8f8b Mon Sep 17 00:00:00 2001
|
||||
From: Phil Sutter <phil@nwl.cc>
|
||||
Date: Mon, 26 Oct 2020 17:25:03 +0100
|
||||
Subject: [PATCH] tests: shell: Improve concurrent noflush restore test a bit
|
||||
|
||||
The described issue happens only if chain FOO does not exist at program
|
||||
start so flush the ruleset after each iteration to make sure this is the
|
||||
case. Sadly the bug is still not 100% reproducible on my testing VM.
|
||||
|
||||
While being at it, add a paragraph describing what exact situation the
|
||||
test is trying to provoke.
|
||||
|
||||
Fixes: dac904bdcd9a1 ("nft: Fix for concurrent noflush restore calls")
|
||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
||||
(cherry picked from commit ed8c8b9316451a4499eeb592d2cf7d782bbe4e9a)
|
||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
||||
---
|
||||
.../ipt-restore/0016-concurrent-restores_0 | 14 ++++++++++++++
|
||||
1 file changed, 14 insertions(+)
|
||||
|
||||
diff --git a/iptables/tests/shell/testcases/ipt-restore/0016-concurrent-restores_0 b/iptables/tests/shell/testcases/ipt-restore/0016-concurrent-restores_0
|
||||
index 53ec12fa368af..aa746ab458a3c 100755
|
||||
--- a/iptables/tests/shell/testcases/ipt-restore/0016-concurrent-restores_0
|
||||
+++ b/iptables/tests/shell/testcases/ipt-restore/0016-concurrent-restores_0
|
||||
@@ -1,5 +1,14 @@
|
||||
#!/bin/bash
|
||||
|
||||
+# test for iptables-restore --noflush skipping an explicitly requested chain
|
||||
+# flush because the chain did not exist when cache was fetched. In order to
|
||||
+# expect for that chain to appear when refreshing the transaction (due to a
|
||||
+# concurrent ruleset change), the chain flush job has to be present in batch
|
||||
+# job list (although disabled at first).
|
||||
+# The input line requesting chain flush is ':FOO - [0:0]'. RS1 and RS2 contents
|
||||
+# are crafted to cause EBUSY when deleting the BAR* chains if FOO is not
|
||||
+# flushed in the same transaction.
|
||||
+
|
||||
set -e
|
||||
|
||||
RS="*filter
|
||||
@@ -45,7 +54,12 @@ RS2="$RS
|
||||
COMMIT
|
||||
"
|
||||
|
||||
+NORS="*filter
|
||||
+COMMIT
|
||||
+"
|
||||
+
|
||||
for n in $(seq 1 10); do
|
||||
+ $XT_MULTI iptables-restore <<< "$NORS"
|
||||
$XT_MULTI iptables-restore --noflush -w <<< "$RS1" &
|
||||
$XT_MULTI iptables-restore --noflush -w <<< "$RS2" &
|
||||
wait -n
|
||||
--
|
||||
2.28.0
|
||||
|
@ -0,0 +1,60 @@
|
||||
From 53cc2b467618f35cadd337066ceae2fd6bcb5fe1 Mon Sep 17 00:00:00 2001
|
||||
From: Phil Sutter <phil@nwl.cc>
|
||||
Date: Mon, 28 Sep 2020 18:57:18 +0200
|
||||
Subject: [PATCH] nft: Fix for broken address mask match detection
|
||||
|
||||
Trying to decide whether a bitwise expression is needed to match parts
|
||||
of a source or destination address only, add_addr() checks if all bytes
|
||||
in 'mask' are 0xff or not. The check is apparently broken though as each
|
||||
byte in 'mask' is cast to a signed char before comparing against 0xff,
|
||||
therefore the bitwise is always added:
|
||||
|
||||
| # ./bad/iptables-nft -A foo -s 10.0.0.1 -j ACCEPT
|
||||
| # ./good/iptables-nft -A foo -s 10.0.0.2 -j ACCEPT
|
||||
| # nft --debug=netlink list chain ip filter foo
|
||||
| ip filter foo 5
|
||||
| [ payload load 4b @ network header + 12 => reg 1 ]
|
||||
| [ bitwise reg 1 = (reg=1 & 0xffffffff ) ^ 0x00000000 ]
|
||||
| [ cmp eq reg 1 0x0100000a ]
|
||||
| [ counter pkts 0 bytes 0 ]
|
||||
| [ immediate reg 0 accept ]
|
||||
|
|
||||
| ip filter foo 6 5
|
||||
| [ payload load 4b @ network header + 12 => reg 1 ]
|
||||
| [ cmp eq reg 1 0x0200000a ]
|
||||
| [ counter pkts 0 bytes 0 ]
|
||||
| [ immediate reg 0 accept ]
|
||||
|
|
||||
| table ip filter {
|
||||
| chain foo {
|
||||
| ip saddr 10.0.0.1 counter packets 0 bytes 0 accept
|
||||
| ip saddr 10.0.0.2 counter packets 0 bytes 0 accept
|
||||
| }
|
||||
| }
|
||||
|
||||
Fix the cast, safe an extra op and gain 100% performance in ideal cases.
|
||||
|
||||
Fixes: 56859380eb328 ("xtables-compat: avoid unneeded bitwise ops")
|
||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
||||
(cherry picked from commit 72ed608bf1ea550ac13b5b880afc7ad3ffa0afd0)
|
||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
||||
---
|
||||
iptables/nft-shared.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c
|
||||
index 78e422781723f..f60f5df97fb86 100644
|
||||
--- a/iptables/nft-shared.c
|
||||
+++ b/iptables/nft-shared.c
|
||||
@@ -165,7 +165,7 @@ void add_outiface(struct nftnl_rule *r, char *iface, uint32_t op)
|
||||
void add_addr(struct nftnl_rule *r, int offset,
|
||||
void *data, void *mask, size_t len, uint32_t op)
|
||||
{
|
||||
- const char *m = mask;
|
||||
+ const unsigned char *m = mask;
|
||||
int i;
|
||||
|
||||
add_payload(r, offset, len, NFT_PAYLOAD_NETWORK_HEADER);
|
||||
--
|
||||
2.28.0
|
||||
|
150
SOURCES/0031-nft-Optimize-class-based-IP-prefix-matches.patch
Normal file
150
SOURCES/0031-nft-Optimize-class-based-IP-prefix-matches.patch
Normal file
@ -0,0 +1,150 @@
|
||||
From 0fbb274e7ab043cf7d967852dbf0d4e6e4ea6449 Mon Sep 17 00:00:00 2001
|
||||
From: Phil Sutter <phil@nwl.cc>
|
||||
Date: Fri, 2 Oct 2020 09:44:38 +0200
|
||||
Subject: [PATCH] nft: Optimize class-based IP prefix matches
|
||||
|
||||
Payload expression works on byte-boundaries, leverage this with suitable
|
||||
prefix lengths.
|
||||
|
||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
||||
(cherry picked from commit 323259001d617ae359430a03ee3d3e7f107684e0)
|
||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
||||
---
|
||||
iptables/nft-arp.c | 11 ++++++++---
|
||||
iptables/nft-ipv4.c | 6 ++++--
|
||||
iptables/nft-ipv6.c | 6 ++++--
|
||||
iptables/nft-shared.c | 14 ++++++++++----
|
||||
iptables/nft-shared.h | 4 ++++
|
||||
5 files changed, 30 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/iptables/nft-arp.c b/iptables/nft-arp.c
|
||||
index d4a86610ec217..ac400e484a4fa 100644
|
||||
--- a/iptables/nft-arp.c
|
||||
+++ b/iptables/nft-arp.c
|
||||
@@ -303,7 +303,8 @@ static bool nft_arp_parse_devaddr(struct nft_xt_ctx *ctx,
|
||||
memcpy(info->mask, ctx->bitwise.mask, ETH_ALEN);
|
||||
ctx->flags &= ~NFT_XT_CTX_BITWISE;
|
||||
} else {
|
||||
- memset(info->mask, 0xff, ETH_ALEN);
|
||||
+ memset(info->mask, 0xff,
|
||||
+ min(ctx->payload.len, ETH_ALEN));
|
||||
}
|
||||
|
||||
return inv;
|
||||
@@ -360,7 +361,9 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx,
|
||||
parse_mask_ipv4(ctx, &fw->arp.smsk);
|
||||
ctx->flags &= ~NFT_XT_CTX_BITWISE;
|
||||
} else {
|
||||
- fw->arp.smsk.s_addr = 0xffffffff;
|
||||
+ memset(&fw->arp.smsk, 0xff,
|
||||
+ min(ctx->payload.len,
|
||||
+ sizeof(struct in_addr)));
|
||||
}
|
||||
|
||||
if (inv)
|
||||
@@ -380,7 +383,9 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx,
|
||||
parse_mask_ipv4(ctx, &fw->arp.tmsk);
|
||||
ctx->flags &= ~NFT_XT_CTX_BITWISE;
|
||||
} else {
|
||||
- fw->arp.tmsk.s_addr = 0xffffffff;
|
||||
+ memset(&fw->arp.tmsk, 0xff,
|
||||
+ min(ctx->payload.len,
|
||||
+ sizeof(struct in_addr)));
|
||||
}
|
||||
|
||||
if (inv)
|
||||
diff --git a/iptables/nft-ipv4.c b/iptables/nft-ipv4.c
|
||||
index 70634f8fad84d..c84af2df90da7 100644
|
||||
--- a/iptables/nft-ipv4.c
|
||||
+++ b/iptables/nft-ipv4.c
|
||||
@@ -199,7 +199,8 @@ static void nft_ipv4_parse_payload(struct nft_xt_ctx *ctx,
|
||||
parse_mask_ipv4(ctx, &cs->fw.ip.smsk);
|
||||
ctx->flags &= ~NFT_XT_CTX_BITWISE;
|
||||
} else {
|
||||
- cs->fw.ip.smsk.s_addr = 0xffffffff;
|
||||
+ memset(&cs->fw.ip.smsk, 0xff,
|
||||
+ min(ctx->payload.len, sizeof(struct in_addr)));
|
||||
}
|
||||
|
||||
if (inv)
|
||||
@@ -212,7 +213,8 @@ static void nft_ipv4_parse_payload(struct nft_xt_ctx *ctx,
|
||||
parse_mask_ipv4(ctx, &cs->fw.ip.dmsk);
|
||||
ctx->flags &= ~NFT_XT_CTX_BITWISE;
|
||||
} else {
|
||||
- cs->fw.ip.dmsk.s_addr = 0xffffffff;
|
||||
+ memset(&cs->fw.ip.dmsk, 0xff,
|
||||
+ min(ctx->payload.len, sizeof(struct in_addr)));
|
||||
}
|
||||
|
||||
if (inv)
|
||||
diff --git a/iptables/nft-ipv6.c b/iptables/nft-ipv6.c
|
||||
index d01491bfdb689..cfced245a781c 100644
|
||||
--- a/iptables/nft-ipv6.c
|
||||
+++ b/iptables/nft-ipv6.c
|
||||
@@ -146,7 +146,8 @@ static void nft_ipv6_parse_payload(struct nft_xt_ctx *ctx,
|
||||
parse_mask_ipv6(ctx, &cs->fw6.ipv6.smsk);
|
||||
ctx->flags &= ~NFT_XT_CTX_BITWISE;
|
||||
} else {
|
||||
- memset(&cs->fw6.ipv6.smsk, 0xff, sizeof(struct in6_addr));
|
||||
+ memset(&cs->fw6.ipv6.smsk, 0xff,
|
||||
+ min(ctx->payload.len, sizeof(struct in6_addr)));
|
||||
}
|
||||
|
||||
if (inv)
|
||||
@@ -159,7 +160,8 @@ static void nft_ipv6_parse_payload(struct nft_xt_ctx *ctx,
|
||||
parse_mask_ipv6(ctx, &cs->fw6.ipv6.dmsk);
|
||||
ctx->flags &= ~NFT_XT_CTX_BITWISE;
|
||||
} else {
|
||||
- memset(&cs->fw6.ipv6.dmsk, 0xff, sizeof(struct in6_addr));
|
||||
+ memset(&cs->fw6.ipv6.dmsk, 0xff,
|
||||
+ min(ctx->payload.len, sizeof(struct in6_addr)));
|
||||
}
|
||||
|
||||
if (inv)
|
||||
diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c
|
||||
index f60f5df97fb86..b1237049d0a34 100644
|
||||
--- a/iptables/nft-shared.c
|
||||
+++ b/iptables/nft-shared.c
|
||||
@@ -166,16 +166,22 @@ void add_addr(struct nftnl_rule *r, int offset,
|
||||
void *data, void *mask, size_t len, uint32_t op)
|
||||
{
|
||||
const unsigned char *m = mask;
|
||||
+ bool bitwise = false;
|
||||
int i;
|
||||
|
||||
- add_payload(r, offset, len, NFT_PAYLOAD_NETWORK_HEADER);
|
||||
-
|
||||
for (i = 0; i < len; i++) {
|
||||
- if (m[i] != 0xff)
|
||||
+ if (m[i] != 0xff) {
|
||||
+ bitwise = m[i] != 0;
|
||||
break;
|
||||
+ }
|
||||
}
|
||||
|
||||
- if (i != len)
|
||||
+ if (!bitwise)
|
||||
+ len = i;
|
||||
+
|
||||
+ add_payload(r, offset, len, NFT_PAYLOAD_NETWORK_HEADER);
|
||||
+
|
||||
+ if (bitwise)
|
||||
add_bitwise(r, mask, len);
|
||||
|
||||
add_cmp_ptr(r, op, data, len);
|
||||
diff --git a/iptables/nft-shared.h b/iptables/nft-shared.h
|
||||
index bee99a7dd0c93..c7f1e366b75ee 100644
|
||||
--- a/iptables/nft-shared.h
|
||||
+++ b/iptables/nft-shared.h
|
||||
@@ -252,4 +252,8 @@ void xtables_restore_parse(struct nft_handle *h,
|
||||
const struct nft_xt_restore_parse *p);
|
||||
|
||||
void nft_check_xt_legacy(int family, bool is_ipt_save);
|
||||
+
|
||||
+#define min(x, y) ((x) < (y) ? (x) : (y))
|
||||
+#define max(x, y) ((x) > (y) ? (x) : (y))
|
||||
+
|
||||
#endif
|
||||
--
|
||||
2.28.0
|
||||
|
218
SOURCES/0032-ebtables-Optimize-masked-MAC-address-matches.patch
Normal file
218
SOURCES/0032-ebtables-Optimize-masked-MAC-address-matches.patch
Normal file
@ -0,0 +1,218 @@
|
||||
From 3e25174a3e3f4757b471bb238d50f213baac50b9 Mon Sep 17 00:00:00 2001
|
||||
From: Phil Sutter <phil@nwl.cc>
|
||||
Date: Fri, 30 Oct 2020 14:08:33 +0100
|
||||
Subject: [PATCH] ebtables: Optimize masked MAC address matches
|
||||
|
||||
Just like with class-based prefix matches in iptables-nft, optimize
|
||||
masked MAC address matches if the mask is on a byte-boundary.
|
||||
|
||||
To reuse the logic in add_addr(), extend it to accept the payload base
|
||||
value via parameter.
|
||||
|
||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
||||
(cherry picked from commit 274cb05edc58d6fa982a34c84b2f4cf6acc3e335)
|
||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
||||
---
|
||||
iptables/nft-arp.c | 12 ++++++++----
|
||||
iptables/nft-bridge.c | 22 ++++++++++------------
|
||||
iptables/nft-ipv4.c | 6 ++++--
|
||||
iptables/nft-ipv6.c | 6 ++++--
|
||||
iptables/nft-shared.c | 5 ++---
|
||||
iptables/nft-shared.h | 3 ++-
|
||||
6 files changed, 30 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/iptables/nft-arp.c b/iptables/nft-arp.c
|
||||
index ac400e484a4fa..776b55949472b 100644
|
||||
--- a/iptables/nft-arp.c
|
||||
+++ b/iptables/nft-arp.c
|
||||
@@ -178,7 +178,8 @@ static int nft_arp_add(struct nft_handle *h, struct nftnl_rule *r, void *data)
|
||||
|
||||
if (need_devaddr(&fw->arp.src_devaddr)) {
|
||||
op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_SRCDEVADDR);
|
||||
- add_addr(r, sizeof(struct arphdr),
|
||||
+ add_addr(r, NFT_PAYLOAD_NETWORK_HEADER,
|
||||
+ sizeof(struct arphdr),
|
||||
&fw->arp.src_devaddr.addr,
|
||||
&fw->arp.src_devaddr.mask,
|
||||
fw->arp.arhln, op);
|
||||
@@ -189,7 +190,8 @@ static int nft_arp_add(struct nft_handle *h, struct nftnl_rule *r, void *data)
|
||||
fw->arp.smsk.s_addr != 0 ||
|
||||
fw->arp.invflags & ARPT_INV_SRCIP) {
|
||||
op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_SRCIP);
|
||||
- add_addr(r, sizeof(struct arphdr) + fw->arp.arhln,
|
||||
+ add_addr(r, NFT_PAYLOAD_NETWORK_HEADER,
|
||||
+ sizeof(struct arphdr) + fw->arp.arhln,
|
||||
&fw->arp.src.s_addr, &fw->arp.smsk.s_addr,
|
||||
sizeof(struct in_addr), op);
|
||||
}
|
||||
@@ -197,7 +199,8 @@ static int nft_arp_add(struct nft_handle *h, struct nftnl_rule *r, void *data)
|
||||
|
||||
if (need_devaddr(&fw->arp.tgt_devaddr)) {
|
||||
op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_TGTDEVADDR);
|
||||
- add_addr(r, sizeof(struct arphdr) + fw->arp.arhln + sizeof(struct in_addr),
|
||||
+ add_addr(r, NFT_PAYLOAD_NETWORK_HEADER,
|
||||
+ sizeof(struct arphdr) + fw->arp.arhln + sizeof(struct in_addr),
|
||||
&fw->arp.tgt_devaddr.addr,
|
||||
&fw->arp.tgt_devaddr.mask,
|
||||
fw->arp.arhln, op);
|
||||
@@ -207,7 +210,8 @@ static int nft_arp_add(struct nft_handle *h, struct nftnl_rule *r, void *data)
|
||||
fw->arp.tmsk.s_addr != 0 ||
|
||||
fw->arp.invflags & ARPT_INV_TGTIP) {
|
||||
op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_TGTIP);
|
||||
- add_addr(r, sizeof(struct arphdr) + fw->arp.arhln + sizeof(struct in_addr) + fw->arp.arhln,
|
||||
+ add_addr(r, NFT_PAYLOAD_NETWORK_HEADER,
|
||||
+ sizeof(struct arphdr) + fw->arp.arhln + sizeof(struct in_addr) + fw->arp.arhln,
|
||||
&fw->arp.tgt.s_addr, &fw->arp.tmsk.s_addr,
|
||||
sizeof(struct in_addr), op);
|
||||
}
|
||||
diff --git a/iptables/nft-bridge.c b/iptables/nft-bridge.c
|
||||
index 3f85cbbf5e4cf..2aa15e2d1e69d 100644
|
||||
--- a/iptables/nft-bridge.c
|
||||
+++ b/iptables/nft-bridge.c
|
||||
@@ -159,20 +159,16 @@ static int nft_bridge_add(struct nft_handle *h,
|
||||
|
||||
if (fw->bitmask & EBT_ISOURCE) {
|
||||
op = nft_invflags2cmp(fw->invflags, EBT_ISOURCE);
|
||||
- add_payload(r, offsetof(struct ethhdr, h_source), 6,
|
||||
- NFT_PAYLOAD_LL_HEADER);
|
||||
- if (!mac_all_ones(fw->sourcemsk))
|
||||
- add_bitwise(r, fw->sourcemsk, 6);
|
||||
- add_cmp_ptr(r, op, fw->sourcemac, 6);
|
||||
+ add_addr(r, NFT_PAYLOAD_LL_HEADER,
|
||||
+ offsetof(struct ethhdr, h_source),
|
||||
+ fw->sourcemac, fw->sourcemsk, ETH_ALEN, op);
|
||||
}
|
||||
|
||||
if (fw->bitmask & EBT_IDEST) {
|
||||
op = nft_invflags2cmp(fw->invflags, EBT_IDEST);
|
||||
- add_payload(r, offsetof(struct ethhdr, h_dest), 6,
|
||||
- NFT_PAYLOAD_LL_HEADER);
|
||||
- if (!mac_all_ones(fw->destmsk))
|
||||
- add_bitwise(r, fw->destmsk, 6);
|
||||
- add_cmp_ptr(r, op, fw->destmac, 6);
|
||||
+ add_addr(r, NFT_PAYLOAD_LL_HEADER,
|
||||
+ offsetof(struct ethhdr, h_dest),
|
||||
+ fw->destmac, fw->destmsk, ETH_ALEN, op);
|
||||
}
|
||||
|
||||
if ((fw->bitmask & EBT_NOPROTO) == 0) {
|
||||
@@ -258,7 +254,8 @@ static void nft_bridge_parse_payload(struct nft_xt_ctx *ctx,
|
||||
memcpy(fw->destmsk, ctx->bitwise.mask, ETH_ALEN);
|
||||
ctx->flags &= ~NFT_XT_CTX_BITWISE;
|
||||
} else {
|
||||
- memset(&fw->destmsk, 0xff, ETH_ALEN);
|
||||
+ memset(&fw->destmsk, 0xff,
|
||||
+ min(ctx->payload.len, ETH_ALEN));
|
||||
}
|
||||
fw->bitmask |= EBT_IDEST;
|
||||
break;
|
||||
@@ -272,7 +269,8 @@ static void nft_bridge_parse_payload(struct nft_xt_ctx *ctx,
|
||||
memcpy(fw->sourcemsk, ctx->bitwise.mask, ETH_ALEN);
|
||||
ctx->flags &= ~NFT_XT_CTX_BITWISE;
|
||||
} else {
|
||||
- memset(&fw->sourcemsk, 0xff, ETH_ALEN);
|
||||
+ memset(&fw->sourcemsk, 0xff,
|
||||
+ min(ctx->payload.len, ETH_ALEN));
|
||||
}
|
||||
fw->bitmask |= EBT_ISOURCE;
|
||||
break;
|
||||
diff --git a/iptables/nft-ipv4.c b/iptables/nft-ipv4.c
|
||||
index c84af2df90da7..5bd0710781533 100644
|
||||
--- a/iptables/nft-ipv4.c
|
||||
+++ b/iptables/nft-ipv4.c
|
||||
@@ -50,13 +50,15 @@ static int nft_ipv4_add(struct nft_handle *h, struct nftnl_rule *r, void *data)
|
||||
|
||||
if (cs->fw.ip.src.s_addr || cs->fw.ip.smsk.s_addr || cs->fw.ip.invflags & IPT_INV_SRCIP) {
|
||||
op = nft_invflags2cmp(cs->fw.ip.invflags, IPT_INV_SRCIP);
|
||||
- add_addr(r, offsetof(struct iphdr, saddr),
|
||||
+ add_addr(r, NFT_PAYLOAD_NETWORK_HEADER,
|
||||
+ offsetof(struct iphdr, saddr),
|
||||
&cs->fw.ip.src.s_addr, &cs->fw.ip.smsk.s_addr,
|
||||
sizeof(struct in_addr), op);
|
||||
}
|
||||
if (cs->fw.ip.dst.s_addr || cs->fw.ip.dmsk.s_addr || cs->fw.ip.invflags & IPT_INV_DSTIP) {
|
||||
op = nft_invflags2cmp(cs->fw.ip.invflags, IPT_INV_DSTIP);
|
||||
- add_addr(r, offsetof(struct iphdr, daddr),
|
||||
+ add_addr(r, NFT_PAYLOAD_NETWORK_HEADER,
|
||||
+ offsetof(struct iphdr, daddr),
|
||||
&cs->fw.ip.dst.s_addr, &cs->fw.ip.dmsk.s_addr,
|
||||
sizeof(struct in_addr), op);
|
||||
}
|
||||
diff --git a/iptables/nft-ipv6.c b/iptables/nft-ipv6.c
|
||||
index cfced245a781c..6ece631d85f59 100644
|
||||
--- a/iptables/nft-ipv6.c
|
||||
+++ b/iptables/nft-ipv6.c
|
||||
@@ -51,7 +51,8 @@ static int nft_ipv6_add(struct nft_handle *h, struct nftnl_rule *r, void *data)
|
||||
!IN6_IS_ADDR_UNSPECIFIED(&cs->fw6.ipv6.smsk) ||
|
||||
(cs->fw6.ipv6.invflags & IPT_INV_SRCIP)) {
|
||||
op = nft_invflags2cmp(cs->fw6.ipv6.invflags, IPT_INV_SRCIP);
|
||||
- add_addr(r, offsetof(struct ip6_hdr, ip6_src),
|
||||
+ add_addr(r, NFT_PAYLOAD_NETWORK_HEADER,
|
||||
+ offsetof(struct ip6_hdr, ip6_src),
|
||||
&cs->fw6.ipv6.src, &cs->fw6.ipv6.smsk,
|
||||
sizeof(struct in6_addr), op);
|
||||
}
|
||||
@@ -59,7 +60,8 @@ static int nft_ipv6_add(struct nft_handle *h, struct nftnl_rule *r, void *data)
|
||||
!IN6_IS_ADDR_UNSPECIFIED(&cs->fw6.ipv6.dmsk) ||
|
||||
(cs->fw6.ipv6.invflags & IPT_INV_DSTIP)) {
|
||||
op = nft_invflags2cmp(cs->fw6.ipv6.invflags, IPT_INV_DSTIP);
|
||||
- add_addr(r, offsetof(struct ip6_hdr, ip6_dst),
|
||||
+ add_addr(r, NFT_PAYLOAD_NETWORK_HEADER,
|
||||
+ offsetof(struct ip6_hdr, ip6_dst),
|
||||
&cs->fw6.ipv6.dst, &cs->fw6.ipv6.dmsk,
|
||||
sizeof(struct in6_addr), op);
|
||||
}
|
||||
diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c
|
||||
index b1237049d0a34..2aae0a3a49dfe 100644
|
||||
--- a/iptables/nft-shared.c
|
||||
+++ b/iptables/nft-shared.c
|
||||
@@ -20,7 +20,6 @@
|
||||
|
||||
#include <xtables.h>
|
||||
|
||||
-#include <linux/netfilter/nf_tables.h>
|
||||
#include <linux/netfilter/xt_comment.h>
|
||||
#include <linux/netfilter/xt_limit.h>
|
||||
|
||||
@@ -162,7 +161,7 @@ void add_outiface(struct nftnl_rule *r, char *iface, uint32_t op)
|
||||
add_cmp_ptr(r, op, iface, iface_len + 1);
|
||||
}
|
||||
|
||||
-void add_addr(struct nftnl_rule *r, int offset,
|
||||
+void add_addr(struct nftnl_rule *r, enum nft_payload_bases base, int offset,
|
||||
void *data, void *mask, size_t len, uint32_t op)
|
||||
{
|
||||
const unsigned char *m = mask;
|
||||
@@ -179,7 +178,7 @@ void add_addr(struct nftnl_rule *r, int offset,
|
||||
if (!bitwise)
|
||||
len = i;
|
||||
|
||||
- add_payload(r, offset, len, NFT_PAYLOAD_NETWORK_HEADER);
|
||||
+ add_payload(r, offset, len, base);
|
||||
|
||||
if (bitwise)
|
||||
add_bitwise(r, mask, len);
|
||||
diff --git a/iptables/nft-shared.h b/iptables/nft-shared.h
|
||||
index c7f1e366b75ee..520a296fb530c 100644
|
||||
--- a/iptables/nft-shared.h
|
||||
+++ b/iptables/nft-shared.h
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <libnftnl/chain.h>
|
||||
|
||||
#include <linux/netfilter_arp/arp_tables.h>
|
||||
+#include <linux/netfilter/nf_tables.h>
|
||||
|
||||
#include "xshared.h"
|
||||
|
||||
@@ -124,7 +125,7 @@ void add_cmp_u16(struct nftnl_rule *r, uint16_t val, uint32_t op);
|
||||
void add_cmp_u32(struct nftnl_rule *r, uint32_t val, uint32_t op);
|
||||
void add_iniface(struct nftnl_rule *r, char *iface, uint32_t op);
|
||||
void add_outiface(struct nftnl_rule *r, char *iface, uint32_t op);
|
||||
-void add_addr(struct nftnl_rule *r, int offset,
|
||||
+void add_addr(struct nftnl_rule *r, enum nft_payload_bases base, int offset,
|
||||
void *data, void *mask, size_t len, uint32_t op);
|
||||
void add_proto(struct nftnl_rule *r, int offset, size_t len,
|
||||
uint8_t proto, uint32_t op);
|
||||
--
|
||||
2.28.0
|
||||
|
@ -0,0 +1,366 @@
|
||||
From 485916fc4cda691818bad9e0c63d6166eb8cadb8 Mon Sep 17 00:00:00 2001
|
||||
From: Phil Sutter <phil@nwl.cc>
|
||||
Date: Tue, 10 Nov 2020 14:50:46 +0100
|
||||
Subject: [PATCH] tests/shell: Add test for bitwise avoidance fixes
|
||||
|
||||
Masked address matching was recently improved to avoid bitwise
|
||||
expression if the given mask covers full bytes. Make use of nft netlink
|
||||
debug output to assert iptables-nft generates the right bytecode for
|
||||
each situation.
|
||||
|
||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
||||
(cherry picked from commit 81a2e128512837b53e5b9ea501b6c8dc64eeca78)
|
||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
||||
---
|
||||
.../nft-only/0009-needless-bitwise_0 | 339 ++++++++++++++++++
|
||||
1 file changed, 339 insertions(+)
|
||||
create mode 100755 iptables/tests/shell/testcases/nft-only/0009-needless-bitwise_0
|
||||
|
||||
diff --git a/iptables/tests/shell/testcases/nft-only/0009-needless-bitwise_0 b/iptables/tests/shell/testcases/nft-only/0009-needless-bitwise_0
|
||||
new file mode 100755
|
||||
index 0000000000000..c5c6e706a1029
|
||||
--- /dev/null
|
||||
+++ b/iptables/tests/shell/testcases/nft-only/0009-needless-bitwise_0
|
||||
@@ -0,0 +1,339 @@
|
||||
+#!/bin/bash -x
|
||||
+
|
||||
+[[ $XT_MULTI == *xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; }
|
||||
+set -e
|
||||
+
|
||||
+nft flush ruleset
|
||||
+
|
||||
+(
|
||||
+ echo "*filter"
|
||||
+ for plen in "" 32 30 24 16 8 0; do
|
||||
+ addr="10.1.2.3${plen:+/}$plen"
|
||||
+ echo "-A OUTPUT -d $addr"
|
||||
+ done
|
||||
+ echo "COMMIT"
|
||||
+) | $XT_MULTI iptables-restore
|
||||
+
|
||||
+(
|
||||
+ echo "*filter"
|
||||
+ for plen in "" 128 124 120 112 88 80 64 48 16 8 0; do
|
||||
+ addr="feed:c0ff:ee00:0102:0304:0506:0708:090A${plen:+/}$plen"
|
||||
+ echo "-A OUTPUT -d $addr"
|
||||
+ done
|
||||
+ echo "COMMIT"
|
||||
+) | $XT_MULTI ip6tables-restore
|
||||
+
|
||||
+masks="
|
||||
+ff:ff:ff:ff:ff:ff
|
||||
+ff:ff:ff:ff:ff:f0
|
||||
+ff:ff:ff:ff:ff:00
|
||||
+ff:ff:ff:ff:00:00
|
||||
+ff:ff:ff:00:00:00
|
||||
+ff:ff:00:00:00:00
|
||||
+ff:00:00:00:00:00
|
||||
+"
|
||||
+(
|
||||
+ echo "*filter"
|
||||
+ for plen in "" 32 30 24 16 8 0; do
|
||||
+ addr="10.1.2.3${plen:+/}$plen"
|
||||
+ echo "-A OUTPUT -d $addr"
|
||||
+ done
|
||||
+ for mask in $masks; do
|
||||
+ echo "-A OUTPUT --destination-mac fe:ed:00:c0:ff:ee/$mask"
|
||||
+ done
|
||||
+ echo "COMMIT"
|
||||
+) | $XT_MULTI arptables-restore
|
||||
+
|
||||
+(
|
||||
+ echo "*filter"
|
||||
+ for mask in $masks; do
|
||||
+ echo "-A OUTPUT -d fe:ed:00:c0:ff:ee/$mask"
|
||||
+ done
|
||||
+ echo "COMMIT"
|
||||
+) | $XT_MULTI ebtables-restore
|
||||
+
|
||||
+EXPECT="ip filter OUTPUT 4
|
||||
+ [ payload load 4b @ network header + 16 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x0302010a ]
|
||||
+ [ counter pkts 0 bytes 0 ]
|
||||
+
|
||||
+ip filter OUTPUT 5 4
|
||||
+ [ payload load 4b @ network header + 16 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x0302010a ]
|
||||
+ [ counter pkts 0 bytes 0 ]
|
||||
+
|
||||
+ip filter OUTPUT 6 5
|
||||
+ [ payload load 4b @ network header + 16 => reg 1 ]
|
||||
+ [ bitwise reg 1 = (reg=1 & 0xfcffffff ) ^ 0x00000000 ]
|
||||
+ [ cmp eq reg 1 0x0002010a ]
|
||||
+ [ counter pkts 0 bytes 0 ]
|
||||
+
|
||||
+ip filter OUTPUT 7 6
|
||||
+ [ payload load 3b @ network header + 16 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x0002010a ]
|
||||
+ [ counter pkts 0 bytes 0 ]
|
||||
+
|
||||
+ip filter OUTPUT 8 7
|
||||
+ [ payload load 2b @ network header + 16 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x0000010a ]
|
||||
+ [ counter pkts 0 bytes 0 ]
|
||||
+
|
||||
+ip filter OUTPUT 9 8
|
||||
+ [ payload load 1b @ network header + 16 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x0000000a ]
|
||||
+ [ counter pkts 0 bytes 0 ]
|
||||
+
|
||||
+ip filter OUTPUT 10 9
|
||||
+ [ counter pkts 0 bytes 0 ]
|
||||
+
|
||||
+ip6 filter OUTPUT 4
|
||||
+ [ payload load 16b @ network header + 24 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0xffc0edfe 0x020100ee 0x06050403 0x0a090807 ]
|
||||
+ [ counter pkts 0 bytes 0 ]
|
||||
+
|
||||
+ip6 filter OUTPUT 5 4
|
||||
+ [ payload load 16b @ network header + 24 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0xffc0edfe 0x020100ee 0x06050403 0x0a090807 ]
|
||||
+ [ counter pkts 0 bytes 0 ]
|
||||
+
|
||||
+ip6 filter OUTPUT 6 5
|
||||
+ [ payload load 16b @ network header + 24 => reg 1 ]
|
||||
+ [ bitwise reg 1 = (reg=1 & 0xffffffff 0xffffffff 0xffffffff 0xf0ffffff ) ^ 0x00000000 0x00000000 0x00000000 0x00000000 ]
|
||||
+ [ cmp eq reg 1 0xffc0edfe 0x020100ee 0x06050403 0x00090807 ]
|
||||
+ [ counter pkts 0 bytes 0 ]
|
||||
+
|
||||
+ip6 filter OUTPUT 7 6
|
||||
+ [ payload load 15b @ network header + 24 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0xffc0edfe 0x020100ee 0x06050403 0x00090807 ]
|
||||
+ [ counter pkts 0 bytes 0 ]
|
||||
+
|
||||
+ip6 filter OUTPUT 8 7
|
||||
+ [ payload load 14b @ network header + 24 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0xffc0edfe 0x020100ee 0x06050403 0x00000807 ]
|
||||
+ [ counter pkts 0 bytes 0 ]
|
||||
+
|
||||
+ip6 filter OUTPUT 9 8
|
||||
+ [ payload load 11b @ network header + 24 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0xffc0edfe 0x020100ee 0x00050403 ]
|
||||
+ [ counter pkts 0 bytes 0 ]
|
||||
+
|
||||
+ip6 filter OUTPUT 10 9
|
||||
+ [ payload load 10b @ network header + 24 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0xffc0edfe 0x020100ee 0x00000403 ]
|
||||
+ [ counter pkts 0 bytes 0 ]
|
||||
+
|
||||
+ip6 filter OUTPUT 11 10
|
||||
+ [ payload load 8b @ network header + 24 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0xffc0edfe 0x020100ee ]
|
||||
+ [ counter pkts 0 bytes 0 ]
|
||||
+
|
||||
+ip6 filter OUTPUT 12 11
|
||||
+ [ payload load 6b @ network header + 24 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0xffc0edfe 0x000000ee ]
|
||||
+ [ counter pkts 0 bytes 0 ]
|
||||
+
|
||||
+ip6 filter OUTPUT 13 12
|
||||
+ [ payload load 2b @ network header + 24 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x0000edfe ]
|
||||
+ [ counter pkts 0 bytes 0 ]
|
||||
+
|
||||
+ip6 filter OUTPUT 14 13
|
||||
+ [ payload load 1b @ network header + 24 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x000000fe ]
|
||||
+ [ counter pkts 0 bytes 0 ]
|
||||
+
|
||||
+ip6 filter OUTPUT 15 14
|
||||
+ [ counter pkts 0 bytes 0 ]
|
||||
+
|
||||
+arp filter OUTPUT 3
|
||||
+ [ payload load 2b @ network header + 0 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x00000100 ]
|
||||
+ [ payload load 1b @ network header + 4 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x00000006 ]
|
||||
+ [ payload load 1b @ network header + 5 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x00000004 ]
|
||||
+ [ payload load 4b @ network header + 24 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x0302010a ]
|
||||
+ [ counter pkts 0 bytes 0 ]
|
||||
+
|
||||
+arp filter OUTPUT 4 3
|
||||
+ [ payload load 2b @ network header + 0 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x00000100 ]
|
||||
+ [ payload load 1b @ network header + 4 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x00000006 ]
|
||||
+ [ payload load 1b @ network header + 5 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x00000004 ]
|
||||
+ [ payload load 4b @ network header + 24 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x0302010a ]
|
||||
+ [ counter pkts 0 bytes 0 ]
|
||||
+
|
||||
+arp filter OUTPUT 5 4
|
||||
+ [ payload load 2b @ network header + 0 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x00000100 ]
|
||||
+ [ payload load 1b @ network header + 4 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x00000006 ]
|
||||
+ [ payload load 1b @ network header + 5 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x00000004 ]
|
||||
+ [ payload load 4b @ network header + 24 => reg 1 ]
|
||||
+ [ bitwise reg 1 = (reg=1 & 0xfcffffff ) ^ 0x00000000 ]
|
||||
+ [ cmp eq reg 1 0x0002010a ]
|
||||
+ [ counter pkts 0 bytes 0 ]
|
||||
+
|
||||
+arp filter OUTPUT 6 5
|
||||
+ [ payload load 2b @ network header + 0 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x00000100 ]
|
||||
+ [ payload load 1b @ network header + 4 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x00000006 ]
|
||||
+ [ payload load 1b @ network header + 5 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x00000004 ]
|
||||
+ [ payload load 3b @ network header + 24 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x0002010a ]
|
||||
+ [ counter pkts 0 bytes 0 ]
|
||||
+
|
||||
+arp filter OUTPUT 7 6
|
||||
+ [ payload load 2b @ network header + 0 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x00000100 ]
|
||||
+ [ payload load 1b @ network header + 4 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x00000006 ]
|
||||
+ [ payload load 1b @ network header + 5 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x00000004 ]
|
||||
+ [ payload load 2b @ network header + 24 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x0000010a ]
|
||||
+ [ counter pkts 0 bytes 0 ]
|
||||
+
|
||||
+arp filter OUTPUT 8 7
|
||||
+ [ payload load 2b @ network header + 0 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x00000100 ]
|
||||
+ [ payload load 1b @ network header + 4 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x00000006 ]
|
||||
+ [ payload load 1b @ network header + 5 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x00000004 ]
|
||||
+ [ payload load 1b @ network header + 24 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x0000000a ]
|
||||
+ [ counter pkts 0 bytes 0 ]
|
||||
+
|
||||
+arp filter OUTPUT 9 8
|
||||
+ [ payload load 2b @ network header + 0 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x00000100 ]
|
||||
+ [ payload load 1b @ network header + 4 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x00000006 ]
|
||||
+ [ payload load 1b @ network header + 5 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x00000004 ]
|
||||
+ [ counter pkts 0 bytes 0 ]
|
||||
+
|
||||
+arp filter OUTPUT 10 9
|
||||
+ [ payload load 2b @ network header + 0 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x00000100 ]
|
||||
+ [ payload load 1b @ network header + 4 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x00000006 ]
|
||||
+ [ payload load 1b @ network header + 5 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x00000004 ]
|
||||
+ [ payload load 6b @ network header + 18 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0xc000edfe 0x0000eeff ]
|
||||
+ [ counter pkts 0 bytes 0 ]
|
||||
+
|
||||
+arp filter OUTPUT 11 10
|
||||
+ [ payload load 2b @ network header + 0 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x00000100 ]
|
||||
+ [ payload load 1b @ network header + 4 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x00000006 ]
|
||||
+ [ payload load 1b @ network header + 5 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x00000004 ]
|
||||
+ [ payload load 6b @ network header + 18 => reg 1 ]
|
||||
+ [ bitwise reg 1 = (reg=1 & 0xffffffff 0x0000f0ff ) ^ 0x00000000 0x00000000 ]
|
||||
+ [ cmp eq reg 1 0xc000edfe 0x0000e0ff ]
|
||||
+ [ counter pkts 0 bytes 0 ]
|
||||
+
|
||||
+arp filter OUTPUT 12 11
|
||||
+ [ payload load 2b @ network header + 0 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x00000100 ]
|
||||
+ [ payload load 1b @ network header + 4 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x00000006 ]
|
||||
+ [ payload load 1b @ network header + 5 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x00000004 ]
|
||||
+ [ payload load 5b @ network header + 18 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0xc000edfe 0x000000ff ]
|
||||
+ [ counter pkts 0 bytes 0 ]
|
||||
+
|
||||
+arp filter OUTPUT 13 12
|
||||
+ [ payload load 2b @ network header + 0 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x00000100 ]
|
||||
+ [ payload load 1b @ network header + 4 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x00000006 ]
|
||||
+ [ payload load 1b @ network header + 5 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x00000004 ]
|
||||
+ [ payload load 4b @ network header + 18 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0xc000edfe ]
|
||||
+ [ counter pkts 0 bytes 0 ]
|
||||
+
|
||||
+arp filter OUTPUT 14 13
|
||||
+ [ payload load 2b @ network header + 0 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x00000100 ]
|
||||
+ [ payload load 1b @ network header + 4 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x00000006 ]
|
||||
+ [ payload load 1b @ network header + 5 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x00000004 ]
|
||||
+ [ payload load 3b @ network header + 18 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x0000edfe ]
|
||||
+ [ counter pkts 0 bytes 0 ]
|
||||
+
|
||||
+arp filter OUTPUT 15 14
|
||||
+ [ payload load 2b @ network header + 0 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x00000100 ]
|
||||
+ [ payload load 1b @ network header + 4 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x00000006 ]
|
||||
+ [ payload load 1b @ network header + 5 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x00000004 ]
|
||||
+ [ payload load 2b @ network header + 18 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x0000edfe ]
|
||||
+ [ counter pkts 0 bytes 0 ]
|
||||
+
|
||||
+arp filter OUTPUT 16 15
|
||||
+ [ payload load 2b @ network header + 0 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x00000100 ]
|
||||
+ [ payload load 1b @ network header + 4 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x00000006 ]
|
||||
+ [ payload load 1b @ network header + 5 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x00000004 ]
|
||||
+ [ payload load 1b @ network header + 18 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x000000fe ]
|
||||
+ [ counter pkts 0 bytes 0 ]
|
||||
+
|
||||
+bridge filter OUTPUT 4
|
||||
+ [ payload load 6b @ link header + 0 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0xc000edfe 0x0000eeff ]
|
||||
+ [ counter pkts 0 bytes 0 ]
|
||||
+
|
||||
+bridge filter OUTPUT 5 4
|
||||
+ [ payload load 6b @ link header + 0 => reg 1 ]
|
||||
+ [ bitwise reg 1 = (reg=1 & 0xffffffff 0x0000f0ff ) ^ 0x00000000 0x00000000 ]
|
||||
+ [ cmp eq reg 1 0xc000edfe 0x0000e0ff ]
|
||||
+ [ counter pkts 0 bytes 0 ]
|
||||
+
|
||||
+bridge filter OUTPUT 6 5
|
||||
+ [ payload load 5b @ link header + 0 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0xc000edfe 0x000000ff ]
|
||||
+ [ counter pkts 0 bytes 0 ]
|
||||
+
|
||||
+bridge filter OUTPUT 7 6
|
||||
+ [ payload load 4b @ link header + 0 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0xc000edfe ]
|
||||
+ [ counter pkts 0 bytes 0 ]
|
||||
+
|
||||
+bridge filter OUTPUT 8 7
|
||||
+ [ payload load 3b @ link header + 0 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x0000edfe ]
|
||||
+ [ counter pkts 0 bytes 0 ]
|
||||
+
|
||||
+bridge filter OUTPUT 9 8
|
||||
+ [ payload load 2b @ link header + 0 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x0000edfe ]
|
||||
+ [ counter pkts 0 bytes 0 ]
|
||||
+
|
||||
+bridge filter OUTPUT 10 9
|
||||
+ [ payload load 1b @ link header + 0 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x000000fe ]
|
||||
+ [ counter pkts 0 bytes 0 ]
|
||||
+"
|
||||
+
|
||||
+diff -u -Z <(echo "$EXPECT") <(nft --debug=netlink list ruleset | awk '/^table/{exit} {print}')
|
||||
--
|
||||
2.28.0
|
||||
|
@ -0,0 +1,80 @@
|
||||
From b38c6a7e467380f7938a125cfd2f3a2902a4dad4 Mon Sep 17 00:00:00 2001
|
||||
From: Phil Sutter <phil@nwl.cc>
|
||||
Date: Sat, 29 Feb 2020 02:08:26 +0100
|
||||
Subject: [PATCH] nft: cache: Make nft_rebuild_cache() respect fake cache
|
||||
|
||||
If transaction needed a refresh in nft_action(), restore with flush
|
||||
would fetch a full cache instead of merely refreshing table list
|
||||
contained in "fake" cache.
|
||||
|
||||
To fix this, nft_rebuild_cache() must distinguish between fake cache and
|
||||
full rule cache. Therefore introduce NFT_CL_FAKE to be distinguished
|
||||
from NFT_CL_RULES.
|
||||
|
||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
||||
(cherry picked from commit 40ad7793d1884f28767cf58c96e9d76ae0a18db1)
|
||||
|
||||
RHEL-only fix: Make nft_rebuild_cache() check 'level' instead of
|
||||
'h->cache_level' as the latter may be reset by __nft_flush_cache().
|
||||
|
||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
||||
---
|
||||
iptables/nft-cache.c | 13 +++++++++----
|
||||
iptables/nft.h | 3 ++-
|
||||
2 files changed, 11 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/iptables/nft-cache.c b/iptables/nft-cache.c
|
||||
index bc6e7f7eaebfb..9623b463f0dd5 100644
|
||||
--- a/iptables/nft-cache.c
|
||||
+++ b/iptables/nft-cache.c
|
||||
@@ -480,6 +480,7 @@ __nft_build_cache(struct nft_handle *h, enum nft_cache_level level,
|
||||
break;
|
||||
/* fall through */
|
||||
case NFT_CL_RULES:
|
||||
+ case NFT_CL_FAKE:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -516,7 +517,7 @@ void nft_fake_cache(struct nft_handle *h)
|
||||
|
||||
h->cache->table[type].chains = nftnl_chain_list_alloc();
|
||||
}
|
||||
- h->cache_level = NFT_CL_RULES;
|
||||
+ h->cache_level = NFT_CL_FAKE;
|
||||
mnl_genid_get(h, &h->nft_genid);
|
||||
}
|
||||
|
||||
@@ -629,9 +630,13 @@ void nft_rebuild_cache(struct nft_handle *h)
|
||||
if (h->cache_level)
|
||||
__nft_flush_cache(h);
|
||||
|
||||
- h->nft_genid = 0;
|
||||
- h->cache_level = NFT_CL_NONE;
|
||||
- __nft_build_cache(h, level, NULL, NULL, NULL);
|
||||
+ if (level == NFT_CL_FAKE) {
|
||||
+ nft_fake_cache(h);
|
||||
+ } else {
|
||||
+ h->nft_genid = 0;
|
||||
+ h->cache_level = NFT_CL_NONE;
|
||||
+ __nft_build_cache(h, level, NULL, NULL, NULL);
|
||||
+ }
|
||||
}
|
||||
|
||||
void nft_release_cache(struct nft_handle *h)
|
||||
diff --git a/iptables/nft.h b/iptables/nft.h
|
||||
index 5cf260a6d2cd3..2094b01455194 100644
|
||||
--- a/iptables/nft.h
|
||||
+++ b/iptables/nft.h
|
||||
@@ -32,7 +32,8 @@ enum nft_cache_level {
|
||||
NFT_CL_TABLES,
|
||||
NFT_CL_CHAINS,
|
||||
NFT_CL_SETS,
|
||||
- NFT_CL_RULES
|
||||
+ NFT_CL_RULES,
|
||||
+ NFT_CL_FAKE /* must be last entry */
|
||||
};
|
||||
|
||||
struct nft_cache {
|
||||
--
|
||||
2.28.0
|
||||
|
@ -17,7 +17,7 @@ Name: iptables
|
||||
Summary: Tools for managing Linux kernel packet filtering capabilities
|
||||
URL: http://www.netfilter.org/projects/iptables
|
||||
Version: 1.8.4
|
||||
Release: 15%{?dist}
|
||||
Release: 15%{?dist}.3
|
||||
Source: %{url}/files/%{name}-%{version}.tar.bz2
|
||||
Source1: iptables.init
|
||||
Source2: iptables-config
|
||||
@ -59,6 +59,15 @@ Patch22: 0022-nfnl_osf-Improve-error-handling.patch
|
||||
Patch23: 0023-nft-cache-Reset-genid-when-rebuilding-cache.patch
|
||||
Patch24: 0024-nft-Fix-for-F-in-iptables-dumps.patch
|
||||
Patch25: 0025-tests-shell-Test-F-in-dump-files.patch
|
||||
Patch26: 0026-nft-Make-batch_add_chain-return-the-added-batch-obje.patch
|
||||
Patch27: 0027-nft-Fix-error-reporting-for-refreshed-transactions.patch
|
||||
Patch28: 0028-nft-Fix-for-concurrent-noflush-restore-calls.patch
|
||||
Patch29: 0029-tests-shell-Improve-concurrent-noflush-restore-test-.patch
|
||||
Patch30: 0030-nft-Fix-for-broken-address-mask-match-detection.patch
|
||||
Patch31: 0031-nft-Optimize-class-based-IP-prefix-matches.patch
|
||||
Patch32: 0032-ebtables-Optimize-masked-MAC-address-matches.patch
|
||||
Patch33: 0033-tests-shell-Add-test-for-bitwise-avoidance-fixes.patch
|
||||
Patch34: 0034-nft-cache-Make-nft_rebuild_cache-respect-fake-cache.patch
|
||||
|
||||
# pf.os: ISC license
|
||||
# iptables-apply: Artistic Licence 2.0
|
||||
@ -467,6 +476,21 @@ done
|
||||
%doc %{_mandir}/man8/ebtables*.8*
|
||||
|
||||
%changelog
|
||||
* Tue Nov 10 2020 Phil Sutter <psutter@redhat.com> - 1.8.4-15.3
|
||||
- nft: cache: Make nft_rebuild_cache() respect fake cache
|
||||
|
||||
* Thu Nov 05 2020 Phil Sutter <psutter@redhat.com> - 1.8.4-15.2
|
||||
- tests/shell: Add test for bitwise avoidance fixes
|
||||
- ebtables: Optimize masked MAC address matches
|
||||
- nft: Optimize class-based IP prefix matches
|
||||
- nft: Fix for broken address mask match detection
|
||||
|
||||
* Wed Oct 28 2020 Phil Sutter <psutter@redhat.com> - 1.8.4-15.1
|
||||
- tests: shell: Improve concurrent noflush restore test a bit
|
||||
- nft: Fix for concurrent noflush restore calls
|
||||
- nft: Fix error reporting for refreshed transactions
|
||||
- nft: Make batch_add_chain() return the added batch object
|
||||
|
||||
* Sat Aug 15 2020 Phil Sutter <psutter@redhat.com> - 1.8.4-15
|
||||
- Ignore sysctl files not suffixed '.conf'
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user