summaryrefslogtreecommitdiffstats
path: root/iptables/nft.c
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2013-03-10 16:04:39 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2013-12-30 23:50:27 +0100
commit8b9ea2e3f8d685a6b940691cabf5e82c96254747 (patch)
tree8e8d56ac5edebbf1f3dec6393abb5198a7501bfc /iptables/nft.c
parentc924c0cd07440aa9ce7465e2ba68fb266f07d7c3 (diff)
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 <pablo@netfilter.org>
Diffstat (limited to 'iptables/nft.c')
-rw-r--r--iptables/nft.c96
1 files changed, 93 insertions, 3 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 <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;
+}