From 5705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Mon, 19 Nov 2012 15:32:18 +0100 Subject: xtables-restore: add support for dormant tables This patch adds support for dormant tables for xtables-restore. Signed-off-by: Pablo Neira Ayuso --- iptables/nft.c | 55 +++++++++++++++++++++++++++++++++++++++++++--- iptables/nft.h | 2 ++ iptables/xtables-restore.c | 8 ++++++- 3 files changed, 61 insertions(+), 4 deletions(-) (limited to 'iptables') diff --git a/iptables/nft.c b/iptables/nft.c index 24301200..1f5ecb70 100644 --- a/iptables/nft.c +++ b/iptables/nft.c @@ -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 && ichains[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) { diff --git a/iptables/nft.h b/iptables/nft.h index aa458f8c..aed2498b 100644 --- a/iptables/nft.h +++ b/iptables/nft.h @@ -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. diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c index 09922a0c..30ea813c 100644 --- a/iptables/xtables-restore.c +++ b/iptables/xtables-restore.c @@ -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); -- cgit v1.2.3