]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
xtables-restore: add support for dormant tables
authorPablo Neira Ayuso <pablo@netfilter.org>
Mon, 19 Nov 2012 14:32:18 +0000 (15:32 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Mon, 30 Dec 2013 22:50:21 +0000 (23:50 +0100)
This patch adds support for dormant tables for xtables-restore.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/linux/netfilter/nf_tables.h
iptables/nft.c
iptables/nft.h
iptables/xtables-restore.c

index 542b6549707b0cbf7a2770818934714ad1fe1885..837bab320fa32071a06b92c465daa64b6362f1a4 100644 (file)
@@ -53,9 +53,19 @@ enum nft_hook_attributes {
 };
 #define NFTA_HOOK_MAX          (__NFTA_HOOK_MAX - 1)
 
+/**
+ * enum nft_table_flags - nf_tables table flags
+ *
+ * @NFT_TABLE_F_DORMANT: this table is not active
+ */
+enum nft_table_flags {
+       NFT_TABLE_F_DORMANT     = 0x1,
+};
+
 enum nft_table_attributes {
        NFTA_TABLE_UNSPEC,
        NFTA_TABLE_NAME,
+       NFTA_TABLE_FLAGS,
        __NFTA_TABLE_MAX
 };
 #define NFTA_TABLE_MAX         (__NFTA_TABLE_MAX - 1)
index 24301200ac69cf3b40e89c7b6ce85fdcf76413c0..1f5ecb70def950f33c3ad3b3d0afdbfd28bda74c 100644 (file)
@@ -229,7 +229,9 @@ static struct builtin_table {
        },
 };
 
-static int nft_table_builtin_add(struct nft_handle *h, struct builtin_table *_t)
+static int
+nft_table_builtin_add(struct nft_handle *h, struct builtin_table *_t,
+                       bool dormant)
 {
        char buf[MNL_SOCKET_BUFFER_SIZE];
        struct nlmsghdr *nlh;
@@ -241,6 +243,10 @@ static int nft_table_builtin_add(struct nft_handle *h, struct builtin_table *_t)
                return -1;
 
        nft_table_attr_set(t, NFT_TABLE_ATTR_NAME, (char *)_t->name);
+       if (dormant) {
+               nft_table_attr_set_u32(t, NFT_TABLE_ATTR_FLAGS,
+                                       NFT_TABLE_F_DORMANT);
+       }
 
        nlh = nft_table_nlmsg_build_hdr(buf, NFT_MSG_NEWTABLE, AF_INET,
                                        NLM_F_ACK|NLM_F_EXCL, h->seq);
@@ -367,7 +373,7 @@ nft_chain_builtin_init(struct nft_handle *h, const char *table,
                ret = -1;
                goto out;
        }
-       if (nft_table_builtin_add(h, t) < 0) {
+       if (nft_table_builtin_add(h, t, false) < 0) {
                /* Built-in table already initialized, skip. */
                if (errno == EEXIST)
                        goto out;
@@ -423,6 +429,49 @@ int nft_chain_add(struct nft_handle *h, const struct nft_chain *c)
        return mnl_talk(h, nlh, NULL, NULL);
 }
 
+int nft_table_set_dormant(struct nft_handle *h, const char *table)
+{
+       int ret = 0, i;
+       struct builtin_table *t;
+
+       t = nft_table_builtin_find(table);
+       if (t == NULL) {
+               ret = -1;
+               goto out;
+       }
+       /* Add this table as dormant */
+       if (nft_table_builtin_add(h, t, true) < 0) {
+               /* Built-in table already initialized, skip. */
+               if (errno == EEXIST)
+                       goto out;
+       }
+       for (i=0; t->chains[i].name != NULL && i<NF_INET_NUMHOOKS; i++)
+               __nft_chain_builtin_init(h, t, t->chains[i].name, NF_ACCEPT);
+out:
+       return ret;
+}
+
+int nft_table_wake_dormant(struct nft_handle *h, const char *table)
+{
+       char buf[MNL_SOCKET_BUFFER_SIZE];
+       struct nlmsghdr *nlh;
+       struct nft_table *t;
+
+       t = nft_table_alloc();
+       if (t == NULL)
+               return -1;
+
+       nft_table_attr_set(t, NFT_TABLE_ATTR_NAME, (char *)table);
+       nft_table_attr_set_u32(t, NFT_TABLE_ATTR_FLAGS, 0);
+
+       nlh = nft_table_nlmsg_build_hdr(buf, NFT_MSG_NEWTABLE, AF_INET,
+                                       NLM_F_ACK, h->seq);
+       nft_table_nlmsg_build_payload(nlh, t);
+       nft_table_free(t);
+
+       return mnl_talk(h, nlh, NULL, NULL);
+}
+
 static void nft_chain_print_debug(struct nft_chain *c, struct nlmsghdr *nlh)
 {
 #ifdef NLDEBUG
@@ -449,7 +498,7 @@ __nft_chain_set(struct nft_handle *h, const char *table,
        _t = nft_table_builtin_find(table);
        /* if this built-in table does not exists, create it */
        if (_t != NULL)
-               nft_table_builtin_add(h, _t);
+               nft_table_builtin_add(h, _t, false);
 
        _c = nft_chain_builtin_find(_t, chain);
        if (_c != NULL) {
index aa458f8cc55905dc52a9558001d0facaf6bf4915..aed2498b7cf0c6bf7fa5fa47d1b9f5c6d956ec6e 100644 (file)
@@ -20,6 +20,8 @@ struct nft_table;
 int nft_table_add(struct nft_handle *h, const struct nft_table *t);
 int nft_for_each_table(struct nft_handle *h, int (*func)(struct nft_handle *h, const char *tablename, bool counters), bool counters);
 bool nft_table_find(struct nft_handle *h, const char *tablename);
+int nft_table_set_dormant(struct nft_handle *h, const char *table);
+int nft_table_wake_dormant(struct nft_handle *h, const char *table);
 
 /*
  * Operations with chains.
index 09922a0c6201fe9a93149e4c39431539e051303d..30ea813c9eba99d994b8960886e0a481152ca807 100644 (file)
@@ -243,11 +243,16 @@ xtables_restore_main(int argc, char *argv[])
                                fputs(buffer, stdout);
                        continue;
                } else if ((strcmp(buffer, "COMMIT\n") == 0) && (in_table)) {
-                       /* FIXME commit/testing operation not supported */
                        if (!testing) {
+                               if (nft_table_wake_dormant(&h, curtable) < 0) {
+                                       fprintf(stderr, "Failed to wake up "
+                                               "dormant table `%s'\n",
+                                               curtable);
+                               }
                                DEBUGP("Calling commit\n");
                                ret = 1;
                        } else {
+                               /* FIXME -t needs to be fixed */
                                DEBUGP("Not calling commit, testing\n");
                                ret = 1;
                        }
@@ -270,6 +275,7 @@ xtables_restore_main(int argc, char *argv[])
                        if (tablename && (strcmp(tablename, table) != 0))
                                continue;
 
+                       nft_table_set_dormant(&h, table);
                        if (noflush == 0) {
                                DEBUGP("Cleaning all chains of table '%s'\n",
                                        table);