summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--iptables/nft-shared.h7
-rw-r--r--iptables/nft.c82
-rw-r--r--iptables/nft.h4
-rw-r--r--iptables/xtables-restore.c38
-rw-r--r--iptables/xtables-translate.c6
5 files changed, 59 insertions, 78 deletions
diff --git a/iptables/nft-shared.h b/iptables/nft-shared.h
index 019c1f20..de889ead 100644
--- a/iptables/nft-shared.h
+++ b/iptables/nft-shared.h
@@ -245,14 +245,11 @@ struct nft_xt_restore_cb {
void (*table_new)(struct nft_handle *h, const char *table);
struct nftnl_chain_list *(*chain_list)(struct nft_handle *h,
const char *table);
- int (*chain_user_flush)(struct nft_handle *h,
- struct nftnl_chain_list *clist,
- const char *table, const char *chain);
int (*chain_set)(struct nft_handle *h, const char *table,
const char *chain, const char *policy,
const struct xt_counters *counters);
- int (*chain_user_add)(struct nft_handle *h, const char *chain,
- const char *table);
+ int (*chain_restore)(struct nft_handle *h, const char *chain,
+ const char *table);
int (*table_flush)(struct nft_handle *h, const char *table);
diff --git a/iptables/nft.c b/iptables/nft.c
index a297d985..16d7b795 100644
--- a/iptables/nft.c
+++ b/iptables/nft.c
@@ -1621,49 +1621,6 @@ __nft_rule_flush(struct nft_handle *h, const char *table,
nftnl_rule_free(r);
}
-struct chain_user_flush_data {
- struct nft_handle *handle;
- const char *table;
- const char *chain;
-};
-
-static int __nft_chain_user_flush(struct nftnl_chain *c, void *data)
-{
- const char *table_name = nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE);
- const char *chain_name = nftnl_chain_get_str(c, NFTNL_CHAIN_NAME);
- struct chain_user_flush_data *d = data;
- struct nft_handle *h = d->handle;
- const char *table = d->table;
- const char *chain = d->chain;
-
- if (strcmp(table, table_name) != 0)
- return 0;
-
- if (strcmp(chain, chain_name) != 0)
- return 0;
-
- if (!nftnl_chain_is_set(c, NFTNL_CHAIN_HOOKNUM))
- __nft_rule_flush(h, table, chain, false);
-
- return 0;
-}
-
-int nft_chain_user_flush(struct nft_handle *h, struct nftnl_chain_list *list,
- const char *table, const char *chain)
-{
- struct chain_user_flush_data d = {
- .handle = h,
- .table = table,
- .chain = chain,
- };
-
- nft_fn = nft_chain_user_flush;
-
- nftnl_chain_list_foreach(list, __nft_chain_user_flush, &d);
-
- return 1;
-}
-
int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table,
bool verbose)
{
@@ -1750,6 +1707,45 @@ int nft_chain_user_add(struct nft_handle *h, const char *chain, const char *tabl
return ret == 0 ? 1 : 0;
}
+int nft_chain_restore(struct nft_handle *h, const char *chain, const char *table)
+{
+ struct nftnl_chain_list *list;
+ struct nftnl_chain *c;
+ bool created = false;
+ int ret;
+
+ c = nft_chain_find(h, table, chain);
+ if (c) {
+ /* Apparently -n still flushes existing user defined
+ * chains that are redefined.
+ */
+ if (h->noflush)
+ __nft_rule_flush(h, table, chain, false);
+ } else {
+ c = nftnl_chain_alloc();
+ if (!c)
+ return -1;
+
+ nftnl_chain_set(c, NFTNL_CHAIN_TABLE, (char *)table);
+ nftnl_chain_set(c, NFTNL_CHAIN_NAME, (char *)chain);
+ created = true;
+ }
+
+ if (h->family == NFPROTO_BRIDGE)
+ nftnl_chain_set_u32(c, NFTNL_CHAIN_POLICY, NF_ACCEPT);
+
+ if (!created)
+ return 0;
+
+ ret = batch_chain_add(h, NFT_COMPAT_CHAIN_USER_ADD, c);
+
+ list = nft_chain_list_get(h, table);
+ if (list)
+ nftnl_chain_list_add(c, list);
+
+ return ret;
+}
+
/* From linux/netlink.h */
#ifndef NLM_F_NONREC
#define NLM_F_NONREC 0x100 /* Do not delete recursively */
diff --git a/iptables/nft.h b/iptables/nft.h
index 56dc2076..d428287b 100644
--- a/iptables/nft.h
+++ b/iptables/nft.h
@@ -45,6 +45,7 @@ struct nft_handle {
} table[NFT_TABLE_MAX];
bool have_cache;
bool restore;
+ bool noflush;
int8_t config_done;
/* meta data, for error reporting */
@@ -87,8 +88,7 @@ struct nftnl_chain_list *nft_chain_list_get(struct nft_handle *h,
int nft_chain_save(struct nft_handle *h, struct nftnl_chain_list *list);
int nft_chain_user_add(struct nft_handle *h, const char *chain, const char *table);
int nft_chain_user_del(struct nft_handle *h, const char *chain, const char *table, bool verbose);
-int nft_chain_user_flush(struct nft_handle *h, struct nftnl_chain_list *list,
- const char *chain, const char *table);
+int nft_chain_restore(struct nft_handle *h, const char *chain, const char *table);
int nft_chain_user_rename(struct nft_handle *h, const char *chain, const char *table, const char *newname);
int nft_chain_zero_counters(struct nft_handle *h, const char *chain, const char *table, bool verbose);
const struct builtin_chain *nft_chain_builtin_find(const struct builtin_table *t, const char *chain);
diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c
index 6e6daffc..b12ab6a6 100644
--- a/iptables/xtables-restore.c
+++ b/iptables/xtables-restore.c
@@ -19,7 +19,7 @@
#include "nft-bridge.h"
#include <libnftnl/chain.h>
-static int counters, verbose, noflush;
+static int counters, verbose;
/* Keeping track of external matches and targets. */
static const struct option options[] = {
@@ -74,10 +74,9 @@ struct nft_xt_restore_cb restore_cb = {
.abort = nft_abort,
.table_new = nft_table_new,
.table_flush = nft_table_flush,
- .chain_user_flush = nft_chain_user_flush,
.do_command = do_commandx,
.chain_set = nft_chain_set,
- .chain_user_add = nft_chain_user_add,
+ .chain_restore = nft_chain_restore,
};
static const struct xtc_ops xtc_ops = {
@@ -93,7 +92,6 @@ void xtables_restore_parse(struct nft_handle *h,
char buffer[10240];
int in_table = 0;
const struct xtc_ops *ops = &xtc_ops;
- struct nftnl_chain_list *chain_list = NULL;
line = 0;
@@ -147,10 +145,12 @@ void xtables_restore_parse(struct nft_handle *h,
if (p->tablename && (strcmp(p->tablename, table) != 0))
continue;
- if (cb->chain_list)
- chain_list = cb->chain_list(h, table);
+ /* Fixme: Needed to init chain cache.
+ * Should create explicit function to do this.
+ */
+ nft_chain_list_get(h, table);
- if (noflush == 0) {
+ if (h->noflush == 0) {
DEBUGP("Cleaning all chains of table '%s'\n",
table);
if (cb->table_flush)
@@ -214,19 +214,7 @@ void xtables_restore_parse(struct nft_handle *h,
}
DEBUGP("Setting policy of chain %s to %s\n",
chain, policy);
-
- } else if (noflush &&
- nftnl_chain_list_lookup_byname(chain_list, chain)) {
- /* Apparently -n still flushes existing user
- * defined chains that are redefined. Otherwise,
- * leave them as is.
- */
- if (cb->chain_user_flush)
- cb->chain_user_flush(h, chain_list,
- curtable->name, chain);
- } else if (cb->chain_user_add &&
- cb->chain_user_add(h, chain,
- curtable->name) < 0 &&
+ } else if (cb->chain_restore(h, chain, curtable->name) < 0 &&
errno != EEXIST) {
xtables_error(PARAMETER_PROBLEM,
"cannot create chain "
@@ -380,7 +368,7 @@ xtables_restore_main(int family, const char *progname, int argc, char *argv[])
IPTABLES_VERSION);
exit(0);
case 'n':
- noflush = 1;
+ h.noflush = 1;
break;
case 'M':
xtables_modprobe_program = optarg;
@@ -480,10 +468,9 @@ struct nft_xt_restore_cb ebt_restore_cb = {
.commit = nft_commit,
.table_new = nft_table_new,
.table_flush = ebt_table_flush,
- .chain_user_flush = nft_chain_user_flush,
.do_command = do_commandeb,
.chain_set = nft_chain_set,
- .chain_user_add = nft_chain_user_add,
+ .chain_restore = nft_chain_restore,
};
static const struct option ebt_restore_options[] = {
@@ -496,6 +483,7 @@ int xtables_eb_restore_main(int argc, char *argv[])
struct nft_xt_restore_parse p = {
.in = stdin,
};
+ bool noflush = false;
struct nft_handle h;
int c;
@@ -514,6 +502,7 @@ int xtables_eb_restore_main(int argc, char *argv[])
}
nft_init_eb(&h, "ebtables-restore");
+ h.noflush = noflush;
xtables_restore_parse(&h, &p, &ebt_restore_cb, argc, argv);
nft_fini(&h);
@@ -525,10 +514,9 @@ struct nft_xt_restore_cb arp_restore_cb = {
.commit = nft_commit,
.table_new = nft_table_new,
.table_flush = nft_table_flush,
- .chain_user_flush = nft_chain_user_flush,
.do_command = do_commandarp,
.chain_set = nft_chain_set,
- .chain_user_add = nft_chain_user_add,
+ .chain_restore = nft_chain_restore,
};
int xtables_arp_restore_main(int argc, char *argv[])
diff --git a/iptables/xtables-translate.c b/iptables/xtables-translate.c
index e1d2a7d6..eb35890a 100644
--- a/iptables/xtables-translate.c
+++ b/iptables/xtables-translate.c
@@ -329,8 +329,8 @@ static const struct option options[] = {
{ NULL },
};
-static int xlate_chain_user_add(struct nft_handle *h, const char *chain,
- const char *table)
+static int xlate_chain_user_restore(struct nft_handle *h, const char *chain,
+ const char *table)
{
printf("add chain %s %s %s\n", family2str[h->family], table, chain);
return 0;
@@ -416,7 +416,7 @@ static int dummy_compat_rev(const char *name, uint8_t rev, int opt)
static struct nft_xt_restore_cb cb_xlate = {
.table_new = xlate_table_new,
.chain_set = xlate_chain_set,
- .chain_user_add = xlate_chain_user_add,
+ .chain_restore = xlate_chain_user_restore,
.do_command = do_command_xlate,
.commit = commit,
.abort = commit,