diff mbox series

[iptables,2/3] xtables: Fix position of replaced rules in cache

Message ID 20190115222305.2576-3-phil@nwl.cc
State Accepted
Delegated to: Pablo Neira
Headers show
Series xtables: Fix for inserting rule at wrong position | expand

Commit Message

Phil Sutter Jan. 15, 2019, 10:23 p.m. UTC
When replacing a rule, the replacement was simply appended to the
chain's rule list. Instead, insert it where the rule it replaces was.

This also fixes for zero counters command to remove the old rule from
cache.

Signed-off-by: Phil Sutter <phil@nwl.cc>
---
 iptables/nft.c         | 34 +++++++++++++++++-----------------
 iptables/nft.h         |  2 +-
 iptables/xtables-arp.c |  2 +-
 iptables/xtables-eb.c  |  2 +-
 iptables/xtables.c     |  4 ++--
 5 files changed, 22 insertions(+), 22 deletions(-)

Comments

Pablo Neira Ayuso Jan. 18, 2019, 1:46 a.m. UTC | #1
On Tue, Jan 15, 2019 at 11:23:04PM +0100, Phil Sutter wrote:
> When replacing a rule, the replacement was simply appended to the
> chain's rule list. Instead, insert it where the rule it replaces was.
> 
> This also fixes for zero counters command to remove the old rule from
> cache.

Also applied, thanks.
diff mbox series

Patch

diff --git a/iptables/nft.c b/iptables/nft.c
index 73a99e5d8813e..ee3d142b25247 100644
--- a/iptables/nft.c
+++ b/iptables/nft.c
@@ -1186,7 +1186,7 @@  nft_chain_find(struct nft_handle *h, const char *table, const char *chain);
 
 int
 nft_rule_append(struct nft_handle *h, const char *chain, const char *table,
-		void *data, uint64_t handle, bool verbose)
+		void *data, struct nftnl_rule *ref, bool verbose)
 {
 	struct nftnl_chain *c;
 	struct nftnl_rule *r;
@@ -1202,8 +1202,9 @@  nft_rule_append(struct nft_handle *h, const char *chain, const char *table,
 	if (r == NULL)
 		return 0;
 
-	if (handle > 0) {
-		nftnl_rule_set(r, NFTNL_RULE_HANDLE, &handle);
+	if (ref) {
+		nftnl_rule_set_u64(r, NFTNL_RULE_HANDLE,
+				   nftnl_rule_get_u64(ref, NFTNL_RULE_HANDLE));
 		type = NFT_COMPAT_RULE_REPLACE;
 	} else
 		type = NFT_COMPAT_RULE_APPEND;
@@ -1216,12 +1217,17 @@  nft_rule_append(struct nft_handle *h, const char *chain, const char *table,
 	if (verbose)
 		h->ops->print_rule(r, 0, FMT_PRINT_RULE);
 
-	c = nft_chain_find(h, table, chain);
-	if (!c) {
-		errno = ENOENT;
-		return 0;
+	if (ref) {
+		nftnl_chain_rule_insert_at(r, ref);
+		nftnl_chain_rule_del(r);
+	} else {
+		c = nft_chain_find(h, table, chain);
+		if (!c) {
+			errno = ENOENT;
+			return 0;
+		}
+		nftnl_chain_rule_add_tail(r, c);
 	}
-	nftnl_chain_rule_add_tail(r, c);
 
 	return 1;
 }
@@ -2107,7 +2113,7 @@  int nft_rule_insert(struct nft_handle *h, const char *chain,
 			r = nft_rule_find(h, c, data, rulenum - 1);
 			if (r != NULL)
 				return nft_rule_append(h, chain, table, data,
-						       0, verbose);
+						       NULL, verbose);
 
 			errno = ENOENT;
 			goto err;
@@ -2179,11 +2185,7 @@  int nft_rule_replace(struct nft_handle *h, const char *chain,
 			(unsigned long long)
 			nftnl_rule_get_u64(r, NFTNL_RULE_HANDLE));
 
-		nftnl_rule_list_del(r);
-
-		ret = nft_rule_append(h, chain, table, data,
-				      nftnl_rule_get_u64(r, NFTNL_RULE_HANDLE),
-				      verbose);
+		ret = nft_rule_append(h, chain, table, data, r, verbose);
 	} else
 		errno = ENOENT;
 
@@ -2459,9 +2461,7 @@  int nft_rule_zero_counters(struct nft_handle *h, const char *chain,
 
 	cs.counters.pcnt = cs.counters.bcnt = 0;
 
-	ret =  nft_rule_append(h, chain, table, &cs,
-			       nftnl_rule_get_u64(r, NFTNL_RULE_HANDLE),
-			       false);
+	ret =  nft_rule_append(h, chain, table, &cs, r, false);
 
 error:
 	return ret;
diff --git a/iptables/nft.h b/iptables/nft.h
index dfdffd69342db..97d73c8b534be 100644
--- a/iptables/nft.h
+++ b/iptables/nft.h
@@ -98,7 +98,7 @@  bool nft_chain_exists(struct nft_handle *h, const char *table, const char *chain
  */
 struct nftnl_rule;
 
-int nft_rule_append(struct nft_handle *h, const char *chain, const char *table, void *data, uint64_t handle, bool verbose);
+int nft_rule_append(struct nft_handle *h, const char *chain, const char *table, void *data, struct nftnl_rule *ref, bool verbose);
 int nft_rule_insert(struct nft_handle *h, const char *chain, const char *table, void *data, int rulenum, bool verbose);
 int nft_rule_check(struct nft_handle *h, const char *chain, const char *table, void *data, bool verbose);
 int nft_rule_delete(struct nft_handle *h, const char *chain, const char *table, void *data, bool verbose);
diff --git a/iptables/xtables-arp.c b/iptables/xtables-arp.c
index 2f369d9aadb01..57e717fa901a1 100644
--- a/iptables/xtables-arp.c
+++ b/iptables/xtables-arp.c
@@ -826,7 +826,7 @@  append_entry(struct nft_handle *h,
 		for (j = 0; j < ndaddrs; j++) {
 			cs->arp.arp.tgt.s_addr = daddrs[j].s_addr;
 			if (append) {
-				ret = nft_rule_append(h, chain, table, cs, 0,
+				ret = nft_rule_append(h, chain, table, cs, NULL,
 						      verbose);
 			} else {
 				ret = nft_rule_insert(h, chain, table, cs,
diff --git a/iptables/xtables-eb.c b/iptables/xtables-eb.c
index 16d874120c0bb..b9d98a055e432 100644
--- a/iptables/xtables-eb.c
+++ b/iptables/xtables-eb.c
@@ -171,7 +171,7 @@  append_entry(struct nft_handle *h,
 	int ret = 1;
 
 	if (append)
-		ret = nft_rule_append(h, chain, table, cs, 0, verbose);
+		ret = nft_rule_append(h, chain, table, cs, NULL, verbose);
 	else
 		ret = nft_rule_insert(h, chain, table, cs, rule_nr, verbose);
 
diff --git a/iptables/xtables.c b/iptables/xtables.c
index da11e8cc159a0..d0167e6396975 100644
--- a/iptables/xtables.c
+++ b/iptables/xtables.c
@@ -406,7 +406,7 @@  add_entry(const char *chain,
 
 				if (append) {
 					ret = nft_rule_append(h, chain, table,
-							      cs, 0,
+							      cs, NULL,
 							      verbose);
 				} else {
 					ret = nft_rule_insert(h, chain, table,
@@ -426,7 +426,7 @@  add_entry(const char *chain,
 				       &d.mask.v6[j], sizeof(struct in6_addr));
 				if (append) {
 					ret = nft_rule_append(h, chain, table,
-							      cs, 0,
+							      cs, NULL,
 							      verbose);
 				} else {
 					ret = nft_rule_insert(h, chain, table,