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