]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
xtables-compat-restore: flush table and its content with no -n
authorPablo Neira Ayuso <pablo@netfilter.org>
Tue, 8 May 2018 09:45:59 +0000 (11:45 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Tue, 8 May 2018 10:07:13 +0000 (12:07 +0200)
With no -n, semantics for *filter are to delete filter table and all its
content.

This restores the similar behaviour introduced in ca165845f7ec
("xtables-compat-restore: flush rules and delete user-defined chains").

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
iptables/nft.c

index 37c017f9a47c3aa951f64219bcd07f5a28d27764..5f7e3ab2f97a8b24a23a2cd5c6582106b16e8627 100644 (file)
@@ -252,6 +252,7 @@ static void mnl_nftnl_batch_end(struct mnl_nlmsg_batch *batch, uint32_t seq)
 
 enum obj_update_type {
        NFT_COMPAT_TABLE_ADD,
+       NFT_COMPAT_TABLE_FLUSH,
        NFT_COMPAT_CHAIN_ADD,
        NFT_COMPAT_CHAIN_USER_ADD,
        NFT_COMPAT_CHAIN_USER_DEL,
@@ -1306,62 +1307,6 @@ __nft_rule_flush(struct nft_handle *h, const char *table, const char *chain)
                nftnl_rule_free(r);
 }
 
-struct flush_data {
-       struct nft_handle       *handle;
-       const char              *table;
-};
-
-static int __nft_table_flush(struct nftnl_chain *c, void *data)
-{
-       const char *table_name = nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE);
-       const char *chain_name = nftnl_chain_get_str(c, NFTNL_CHAIN_NAME);
-       struct flush_data *d = data;
-       struct nft_handle *h = d->handle;
-       const char *table = d->table;
-       int ret;
-
-       if (strcmp(table, table_name) != 0)
-               return 0;
-
-       __nft_rule_flush(h, table_name, chain_name);
-
-       if (!nftnl_chain_is_set(c, NFTNL_CHAIN_HOOKNUM)) {
-               ret = batch_chain_add(h, NFT_COMPAT_CHAIN_USER_DEL, c);
-               if (ret < 0)
-                       return ret;
-
-               nftnl_chain_list_del(c);
-       }
-
-       return 0;
-}
-
-int nft_table_flush(struct nft_handle *h, const char *table)
-{
-       struct flush_data d = {
-               .handle = h,
-               .table  = table,
-       };
-       struct nftnl_chain_list *list;
-       int ret = 0;
-
-       nft_fn = nft_table_flush;
-
-       list = nftnl_chain_list_get(h);
-       if (list == NULL) {
-               ret = 0;
-               goto err;
-       }
-
-       nftnl_chain_list_foreach(list, __nft_table_flush, &d);
-       flush_rule_cache(h);
-err:
-       nftnl_chain_list_free(list);
-
-       /* the core expects 1 for success and 0 for error */
-       return ret == 0 ? 1 : 0;
-}
-
 struct chain_user_flush_data {
        struct nft_handle       *handle;
        const char              *table;
@@ -1740,6 +1685,66 @@ int nft_for_each_table(struct nft_handle *h,
        return 0;
 }
 
+static int __nft_table_flush(struct nft_handle *h, const char *table)
+{
+       struct nftnl_table *t;
+
+       t = nftnl_table_alloc();
+       if (t == NULL)
+               return -1;
+
+       nftnl_table_set_str(t, NFTNL_TABLE_NAME, table);
+
+       batch_table_add(h, NFT_COMPAT_TABLE_FLUSH, t);
+
+       return 0;
+}
+
+int nft_table_flush(struct nft_handle *h, const char *table)
+{
+       struct nftnl_table_list_iter *iter;
+       struct nftnl_table_list *list;
+       struct nftnl_table *t;
+       int ret = 0;
+
+       nft_fn = nft_table_flush;
+
+       list = nftnl_table_list_get(h);
+       if (list == NULL) {
+               ret = -1;
+               goto err_out;
+       }
+
+       iter = nftnl_table_list_iter_create(list);
+       if (iter == NULL) {
+               ret = -1;
+               goto err_table_list;
+       }
+
+       t = nftnl_table_list_iter_next(iter);
+       while (t != NULL) {
+               const char *table_name =
+                       nftnl_table_get_str(t, NFTNL_TABLE_NAME);
+
+               if (strcmp(table_name, table) != 0)
+                       goto next;
+
+               ret = __nft_table_flush(h, table);
+               if (ret < 0)
+                       goto err_table_iter;
+next:
+               t = nftnl_table_list_iter_next(iter);
+       }
+
+err_table_iter:
+       nftnl_table_list_iter_destroy(iter);
+err_table_list:
+       nftnl_table_list_free(list);
+err_out:
+       /* the core expects 1 for success and 0 for error */
+       return ret == 0 ? 1 : 0;
+}
+
 static int __nft_rule_del(struct nft_handle *h, struct nftnl_rule_list *list,
                          struct nftnl_rule *r)
 {
@@ -2310,6 +2315,11 @@ static int nft_action(struct nft_handle *h, int action)
                                                   NLM_F_CREATE, seq++,
                                                   n->table);
                        break;
+               case NFT_COMPAT_TABLE_FLUSH:
+                       nft_compat_table_batch_add(h, NFT_MSG_DELTABLE,
+                                                  0,
+                                                  seq++, n->table);
+                       break;
                case NFT_COMPAT_CHAIN_ADD:
                        nft_compat_chain_batch_add(h, NFT_MSG_NEWCHAIN,
                                                   NLM_F_CREATE, seq++,