]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
xtables: Fix position of replaced rules in cache
authorPhil Sutter <phil@nwl.cc>
Tue, 15 Jan 2019 22:23:04 +0000 (23:23 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Fri, 18 Jan 2019 01:42:08 +0000 (02:42 +0100)
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>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
iptables/nft.c
iptables/nft.h
iptables/xtables-arp.c
iptables/xtables-eb.c
iptables/xtables.c

index 73a99e5d8813e50762cd7461709e200af18282cb..ee3d142b25247e74b4991496cc5d3fea0b916aef 100644 (file)
@@ -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;
index dfdffd69342dbdb544bc8114514ea103d49bed57..97d73c8b534be95c28d7ca9bfae266b6c8ac0e6d 100644 (file)
@@ -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);
index 2f369d9aadb01188978b37921c9fab139a67cfe9..57e717fa901a1187bd9ec6b154e2999b96e7b408 100644 (file)
@@ -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,
index 16d874120c0bb647b44c5c3764c9f1304144fb8f..b9d98a055e43200dfab2451d941ccf4f8225c590 100644 (file)
@@ -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);
 
index da11e8cc159a04aa1d59ca2f2fae05073c75e902..d0167e63969754bfdb3e187c252118e1eb95a4b2 100644 (file)
@@ -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,