From 53422c35d925973702e043ac69119f87e08399e0 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Tue, 15 Jan 2019 23:23:04 +0100 Subject: [PATCH] xtables: Fix position of replaced rules in cache 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 Signed-off-by: Pablo Neira Ayuso (cherry picked from commit 5ca9acf51adf9dcc8e0d82cd8f5b9b2514f900ee) Signed-off-by: Phil Sutter --- 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(-) diff --git a/iptables/nft.c b/iptables/nft.c index c2af1a6fd0985..76764fde4e9fb 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; } @@ -2109,7 +2115,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; @@ -2181,11 +2187,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; @@ -2461,9 +2463,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 2dce1a52f16fd..18cdced627c55 100644 --- a/iptables/xtables-arp.c +++ b/iptables/xtables-arp.c @@ -825,7 +825,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 871891442e431..4c52c29aa4817 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, -- 2.20.1