summaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--iptables/nft.c96
-rw-r--r--iptables/nft.h16
-rw-r--r--iptables/xtables-config.c75
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 <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;
+}
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 <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;
}