]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
nft: load tables and chains based on /etc/xtables.conf
authorPablo Neira Ayuso <pablo@netfilter.org>
Sun, 10 Mar 2013 15:04:39 +0000 (16:04 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Mon, 30 Dec 2013 22:50:27 +0000 (23:50 +0100)
If /etc/xtables.conf is available, use the configuration there to
autoload the xtables built-in table and chain so you can define custom
configurations. Otherwise, rely on default common table/chain
configuration.

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

index 88fd84be864a0e7166e0a797b66459f1a32e7a4c..f39f40716baafbbdcae486116efe407db8540cdc 100644 (file)
@@ -17,6 +17,7 @@
 #include <errno.h>
 #include <netdb.h>     /* getprotobynumber */
 #include <time.h>
+#include <stdarg.h>
 
 #include <xtables.h>
 #include <libiptc/libxtc.h>
@@ -47,6 +48,7 @@
 #include "nft.h"
 #include "xshared.h" /* proto_to_name */
 #include "nft-shared.h"
+#include "xtables-config-parser.h"
 
 static void *nft_fn;
 
@@ -683,7 +685,8 @@ nft_rule_add(struct nft_handle *h, const char *chain, const char *table,
        int ip_flags = 0;
 
        /* If built-in chains don't exist for this table, create them */
-       nft_chain_builtin_init(h, table, chain, NF_ACCEPT);
+       if (nft_xtables_config_load(h, XTABLES_CONFIG_DEFAULT, 0) < 0)
+               nft_chain_builtin_init(h, table, chain, NF_ACCEPT);
 
        nft_fn = nft_rule_add;
 
@@ -1302,7 +1305,8 @@ int nft_chain_user_add(struct nft_handle *h, const char *chain, const char *tabl
        int ret;
 
        /* If built-in chains don't exist for this table, create them */
-       nft_chain_builtin_init(h, table, NULL, NF_ACCEPT);
+       if (nft_xtables_config_load(h, XTABLES_CONFIG_DEFAULT, 0) < 0)
+               nft_chain_builtin_init(h, table, NULL, NF_ACCEPT);
 
        c = nft_chain_alloc();
        if (c == NULL) {
@@ -1469,7 +1473,8 @@ int nft_chain_user_rename(struct nft_handle *h,const char *chain,
        int ret;
 
        /* If built-in chains don't exist for this table, create them */
-       nft_chain_builtin_init(h, table, NULL, NF_ACCEPT);
+       if (nft_xtables_config_load(h, XTABLES_CONFIG_DEFAULT, 0) < 0)
+               nft_chain_builtin_init(h, table, NULL, NF_ACCEPT);
 
        /* Find the old chain to be renamed */
        c = nft_chain_find(h, table, chain);
@@ -2760,3 +2765,88 @@ const char *nft_strerror(int err)
 
        return strerror(err);
 }
+
+static void xtables_config_perror(uint32_t flags, const char *fmt, ...)
+{
+       va_list args;
+
+       va_start(args, fmt);
+
+       if (flags & NFT_LOAD_VERBOSE)
+               vfprintf(stderr, fmt, args);
+
+       va_end(args);
+}
+
+int nft_xtables_config_load(struct nft_handle *h, const char *filename,
+                           uint32_t flags)
+{
+       struct nft_table_list *table_list = nft_table_list_alloc();
+       struct nft_chain_list *chain_list = nft_chain_list_alloc();
+       struct nft_table_list_iter *titer;
+       struct nft_chain_list_iter *citer;
+       struct nft_table *table;
+       struct nft_chain *chain;
+
+       if (xtables_config_parse(filename, table_list, chain_list) < 0) {
+               if (errno == ENOENT) {
+                       xtables_config_perror(flags,
+                               "configuration file `%s' does not exists\n",
+                               filename);
+               } else {
+                       xtables_config_perror(flags,
+                               "Fatal error parsing config file: %s\n",
+                                strerror(errno));
+               }
+               return -1;
+       }
+
+       nft_init(h);
+
+       /* Stage 1) create tables */
+       titer = nft_table_list_iter_create(table_list);
+       while ((table = nft_table_list_iter_next(titer)) != NULL) {
+               if (nft_table_add(h, table) < 0) {
+                       if (errno == EEXIST) {
+                               xtables_config_perror(flags,
+                                       "table `%s' already exists, skipping\n",
+                                       (char *)nft_table_attr_get(table, NFT_TABLE_ATTR_NAME));
+                       } else {
+                               xtables_config_perror(flags,
+                                       "table `%s' cannot be create, reason `%s'. Exitting\n",
+                                       (char *)nft_table_attr_get(table, NFT_TABLE_ATTR_NAME),
+                                       strerror(errno));
+                               return -1;
+                       }
+                       continue;
+               }
+               xtables_config_perror(flags, "table `%s' has been created\n",
+                       (char *)nft_table_attr_get(table, NFT_TABLE_ATTR_NAME));
+       }
+
+       /* Stage 2) create chains */
+       citer = nft_chain_list_iter_create(chain_list);
+       while ((chain = nft_chain_list_iter_next(citer)) != NULL) {
+               if (nft_chain_add(h, chain) < 0) {
+                       if (errno == EEXIST) {
+                               xtables_config_perror(flags,
+                                       "chain `%s' already exists in table `%s', skipping\n",
+                                       (char *)nft_chain_attr_get(chain, NFT_CHAIN_ATTR_NAME),
+                                       (char *)nft_chain_attr_get(chain, NFT_CHAIN_ATTR_TABLE));
+                       } else {
+                               xtables_config_perror(flags,
+                                       "chain `%s' cannot be create, reason `%s'. Exitting\n",
+                                       (char *)nft_chain_attr_get(chain, NFT_CHAIN_ATTR_NAME),
+                                       strerror(errno));
+                               return -1;
+                       }
+                       continue;
+               }
+
+               xtables_config_perror(flags,
+                       "chain `%s' in table `%s' has been created\n",
+                       (char *)nft_chain_attr_get(chain, NFT_CHAIN_ATTR_NAME),
+                       (char *)nft_chain_attr_get(chain, NFT_CHAIN_ATTR_TABLE));
+       }
+       return 0;
+}
index d2a9b928bc018df41f59857acfdd8b4f9061c6f6..8d5881d6d0ee4e0db86762f64775355935ee3dd9 100644 (file)
@@ -84,4 +84,20 @@ const char *nft_strerror(int err);
 /* For xtables.c */
 int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table);
 
+/*
+ * Parse config for tables and chain helper functions
+ */
+#define XTABLES_CONFIG_DEFAULT  "/etc/xtables.conf"
+
+struct nft_table_list;
+struct nft_chain_list;
+
+extern int xtables_config_parse(const char *filename, struct nft_table_list *table_list, struct nft_chain_list *chain_list);
+
+enum {
+       NFT_LOAD_VERBOSE = (1 << 0),
+};
+
+int nft_xtables_config_load(struct nft_handle *h, const char *filename, uint32_t flags);
+
 #endif
index fce03a19451fe2792cee1ab42604039d86e05aae..3ad46e852000be1c5d5eb8dab1eac39944156598 100644 (file)
 #include <string.h>
 #include <errno.h>
 
-#include <libnftables/table.h>
-#include <libnftables/chain.h>
-
 #include "xtables-multi.h"
-#include "xtables-config-parser.h"
-
 #include "nft.h"
 
-extern int xtables_config_parse(const char *filename,
-                               struct nft_table_list *table_list,
-                               struct nft_chain_list *chain_list);
-
-#define XTABLES_CONFIG_DEFAULT "/etc/xtables.conf"
-
 int xtables_config_main(int argc, char *argv[])
 {
-       struct nft_table_list *table_list = nft_table_list_alloc();
-       struct nft_chain_list *chain_list = nft_chain_list_alloc();
-       struct nft_table_list_iter *titer;
-       struct nft_chain_list_iter *citer;
-       struct nft_table *table;
-       struct nft_chain *chain;
-       const char *filename = NULL;
        struct nft_handle h = {
                .family = AF_INET,
        };
+       const char *filename = NULL;
 
        if (argc > 2) {
                fprintf(stderr, "Usage: %s [<config_file>]\n", argv[0]);
@@ -52,58 +35,6 @@ int xtables_config_main(int argc, char *argv[])
        else
                filename = argv[1];
 
-       if (xtables_config_parse(filename, table_list, chain_list) < 0) {
-               if (errno == ENOENT) {
-                       fprintf(stderr, "configuration file `%s' does not "
-                                       "exists\n", filename);
-               } else {
-                       fprintf(stderr, "Fatal error: %s\n", strerror(errno));
-               }
-               return EXIT_FAILURE;
-       }
-
-       nft_init(&h);
-
-       /* Stage 1) create tables */
-       titer = nft_table_list_iter_create(table_list);
-       while ((table = nft_table_list_iter_next(titer)) != NULL) {
-               if (nft_table_add(&h, table) < 0) {
-                       if (errno == EEXIST) {
-                               printf("table `%s' already exists, skipping\n",
-                                       (char *)nft_table_attr_get(table, NFT_TABLE_ATTR_NAME));
-                       } else {
-                               printf("table `%s' cannot be create, reason `%s'. Exitting\n",
-                                       (char *)nft_table_attr_get(table, NFT_TABLE_ATTR_NAME),
-                                       strerror(errno));
-                               return EXIT_FAILURE;
-                       }
-                       continue;
-               }
-               printf("table `%s' has been created\n",
-                       (char *)nft_table_attr_get(table, NFT_TABLE_ATTR_NAME));
-       }
-
-       /* Stage 2) create chains */
-       citer = nft_chain_list_iter_create(chain_list);
-       while ((chain = nft_chain_list_iter_next(citer)) != NULL) {
-               if (nft_chain_add(&h, chain) < 0) {
-                       if (errno == EEXIST) {
-                               printf("chain `%s' already exists in table `%s', skipping\n",
-                                       (char *)nft_chain_attr_get(chain, NFT_CHAIN_ATTR_NAME),
-                                       (char *)nft_chain_attr_get(chain, NFT_CHAIN_ATTR_TABLE));
-                       } else {
-                               printf("chain `%s' cannot be create, reason `%s'. Exitting\n",
-                                       (char *)nft_chain_attr_get(chain, NFT_CHAIN_ATTR_NAME),
-                                       strerror(errno));
-                               return EXIT_FAILURE;
-                       }
-                       continue;
-               }
-
-               printf("chain `%s' in table `%s' has been created\n",
-                       (char *)nft_chain_attr_get(chain, NFT_CHAIN_ATTR_NAME),
-                       (char *)nft_chain_attr_get(chain, NFT_CHAIN_ATTR_TABLE));
-       }
-
-       return EXIT_SUCCESS;
+       return nft_xtables_config_load(&h, filename, NFT_LOAD_VERBOSE) == 0 ?
+                                                   EXIT_SUCCESS : EXIT_FAILURE;
 }