From 8b9ea2e3f8d685a6b940691cabf5e82c96254747 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sun, 10 Mar 2013 16:04:39 +0100 Subject: nft: load tables and chains based on /etc/xtables.conf 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 --- iptables/nft.c | 96 +++++++++++++++++++++++++++++++++++++++++++++-- iptables/nft.h | 16 ++++++++ iptables/xtables-config.c | 75 ++---------------------------------- 3 files changed, 112 insertions(+), 75 deletions(-) diff --git a/iptables/nft.c b/iptables/nft.c index 88fd84be..f39f4071 100644 --- a/iptables/nft.c +++ b/iptables/nft.c @@ -17,6 +17,7 @@ #include #include /* getprotobynumber */ #include +#include #include #include @@ -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; +} diff --git a/iptables/nft.h b/iptables/nft.h index d2a9b928..8d5881d6 100644 --- a/iptables/nft.h +++ b/iptables/nft.h @@ -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 diff --git a/iptables/xtables-config.c b/iptables/xtables-config.c index fce03a19..3ad46e85 100644 --- a/iptables/xtables-config.c +++ b/iptables/xtables-config.c @@ -16,32 +16,15 @@ #include #include -#include -#include - #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 []\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; } -- cgit v1.2.3