aboutsummaryrefslogtreecommitdiff
path: root/iptables/nft.c
diff options
context:
space:
mode:
Diffstat (limited to 'iptables/nft.c')
-rw-r--r--iptables/nft.c325
1 files changed, 193 insertions, 132 deletions
diff --git a/iptables/nft.c b/iptables/nft.c
index 39882a44..bde4ca72 100644
--- a/iptables/nft.c
+++ b/iptables/nft.c
@@ -688,7 +688,8 @@ nft_chain_builtin_alloc(const struct builtin_table *table,
static void nft_chain_builtin_add(struct nft_handle *h,
const struct builtin_table *table,
- const struct builtin_chain *chain)
+ const struct builtin_chain *chain,
+ bool fake)
{
struct nftnl_chain *c;
@@ -696,8 +697,9 @@ static void nft_chain_builtin_add(struct nft_handle *h,
if (c == NULL)
return;
- batch_chain_add(h, NFT_COMPAT_CHAIN_ADD, c);
- nftnl_chain_list_add_tail(c, h->cache->table[table->type].chains);
+ if (!fake)
+ batch_chain_add(h, NFT_COMPAT_CHAIN_ADD, c);
+ nft_cache_add_chain(h, table, c);
}
/* find if built-in table already exists */
@@ -738,9 +740,6 @@ nft_chain_builtin_find(const struct builtin_table *t, const char *chain)
return found ? &t->chains[i] : NULL;
}
-static struct nftnl_chain *
-nft_chain_find(struct nft_handle *h, const char *table, const char *chain);
-
static void nft_chain_builtin_init(struct nft_handle *h,
const struct builtin_table *table)
{
@@ -751,29 +750,57 @@ static void nft_chain_builtin_init(struct nft_handle *h,
if (nft_chain_find(h, table->name, table->chains[i].name))
continue;
- nft_chain_builtin_add(h, table, &table->chains[i]);
+ nft_chain_builtin_add(h, table, &table->chains[i], false);
}
}
-static int nft_xt_builtin_init(struct nft_handle *h, const char *table)
+static const struct builtin_table *
+nft_xt_builtin_table_init(struct nft_handle *h, const char *table)
{
const struct builtin_table *t;
if (!h->cache_init)
- return 0;
+ return NULL;
t = nft_table_builtin_find(h, table);
if (t == NULL)
- return -1;
+ return NULL;
if (nft_table_builtin_add(h, t) < 0)
+ return NULL;
+
+ return t;
+}
+
+static int nft_xt_builtin_init(struct nft_handle *h, const char *table,
+ const char *chain)
+{
+ const struct builtin_table *t;
+ const struct builtin_chain *c;
+
+ if (!h->cache_init)
+ return 0;
+
+ t = nft_xt_builtin_table_init(h, table);
+ if (!t)
return -1;
if (h->cache_req.level < NFT_CL_CHAINS)
return 0;
- nft_chain_builtin_init(h, t);
+ if (!chain) {
+ nft_chain_builtin_init(h, t);
+ return 0;
+ }
+
+ c = nft_chain_builtin_find(t, chain);
+ if (!c)
+ return -1;
+
+ if (h->cache->table[t->type].base_chains[c->hook])
+ return 0;
+ nft_chain_builtin_add(h, t, c, false);
return 0;
}
@@ -785,6 +812,40 @@ static bool nft_chain_builtin(struct nftnl_chain *c)
return nftnl_chain_get(c, NFTNL_CHAIN_HOOKNUM) != NULL;
}
+static int __nft_xt_fake_builtin_chains(struct nft_handle *h,
+ const char *table, void *data)
+{
+ const char *chain = data ? *(const char **)data : NULL;
+ const struct builtin_table *t;
+ struct nft_chain **bcp;
+ int i;
+
+ t = nft_table_builtin_find(h, table);
+ if (!t)
+ return -1;
+
+ bcp = h->cache->table[t->type].base_chains;
+ for (i = 0; i < NF_INET_NUMHOOKS && t->chains[i].name; i++) {
+ if (bcp[t->chains[i].hook])
+ continue;
+
+ if (chain && strcmp(chain, t->chains[i].name))
+ continue;
+
+ nft_chain_builtin_add(h, t, &t->chains[i], true);
+ }
+ return 0;
+}
+
+int nft_xt_fake_builtin_chains(struct nft_handle *h,
+ const char *table, const char *chain)
+{
+ if (table)
+ return __nft_xt_fake_builtin_chains(h, table, &chain);
+
+ return nft_for_each_table(h, __nft_xt_fake_builtin_chains, &chain);
+}
+
int nft_restart(struct nft_handle *h)
{
mnl_socket_close(h->nl);
@@ -877,7 +938,7 @@ static struct nftnl_chain *nft_chain_new(struct nft_handle *h,
}
/* if this built-in table does not exists, create it */
- nft_xt_builtin_init(h, table);
+ nft_xt_builtin_init(h, table, chain);
_c = nft_chain_builtin_find(_t, chain);
if (_c != NULL) {
@@ -1391,10 +1452,10 @@ int
nft_rule_append(struct nft_handle *h, const char *chain, const char *table,
struct nftnl_rule *r, struct nftnl_rule *ref, bool verbose)
{
- struct nftnl_chain *c;
+ struct nft_chain *c;
int type;
- nft_xt_builtin_init(h, table);
+ nft_xt_builtin_init(h, table, chain);
nft_fn = nft_rule_append;
@@ -1421,7 +1482,7 @@ nft_rule_append(struct nft_handle *h, const char *chain, const char *table,
errno = ENOENT;
return 0;
}
- nftnl_chain_rule_add_tail(r, c);
+ nftnl_chain_rule_add_tail(r, c->nftnl);
}
return 1;
@@ -1543,8 +1604,9 @@ static const char *policy_name[NF_ACCEPT+1] = {
[NF_ACCEPT] = "ACCEPT",
};
-int nft_chain_save(struct nftnl_chain *c, void *data)
+int nft_chain_save(struct nft_chain *nc, void *data)
{
+ struct nftnl_chain *c = nc->nftnl;
struct nft_handle *h = data;
const char *policy = NULL;
@@ -1567,13 +1629,13 @@ struct nft_rule_save_data {
unsigned int format;
};
-static int nft_rule_save_cb(struct nftnl_chain *c, void *data)
+static int nft_rule_save_cb(struct nft_chain *c, void *data)
{
struct nft_rule_save_data *d = data;
struct nftnl_rule_iter *iter;
struct nftnl_rule *r;
- iter = nftnl_rule_iter_create(c);
+ iter = nftnl_rule_iter_create(c->nftnl);
if (iter == NULL)
return 1;
@@ -1593,14 +1655,9 @@ int nft_rule_save(struct nft_handle *h, const char *table, unsigned int format)
.h = h,
.format = format,
};
- struct nftnl_chain_list *list;
int ret;
- list = nft_chain_list_get(h, table, NULL);
- if (!list)
- return 0;
-
- ret = nftnl_chain_list_foreach(list, nft_rule_save_cb, &d);
+ ret = nft_chain_foreach(h, table, nft_rule_save_cb, &d);
/* the core expects 1 for success and 0 for error */
return ret == 0 ? 1 : 0;
@@ -1653,9 +1710,9 @@ struct nft_rule_flush_data {
bool verbose;
};
-static int nft_rule_flush_cb(struct nftnl_chain *c, void *data)
+static int nft_rule_flush_cb(struct nft_chain *c, void *data)
{
- const char *chain = nftnl_chain_get_str(c, NFTNL_CHAIN_NAME);
+ const char *chain = nftnl_chain_get_str(c->nftnl, NFTNL_CHAIN_NAME);
struct nft_rule_flush_data *d = data;
batch_chain_flush(d->h, d->table, chain);
@@ -1672,14 +1729,13 @@ int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table,
.table = table,
.verbose = verbose,
};
- struct nftnl_chain_list *list;
- struct nftnl_chain *c = NULL;
+ struct nft_chain *c = NULL;
int ret = 0;
nft_fn = nft_rule_flush;
if (chain || verbose)
- nft_xt_builtin_init(h, table);
+ nft_xt_builtin_init(h, table, chain);
else if (!nft_table_find(h, table))
return 1;
@@ -1698,26 +1754,20 @@ int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table,
return 1;
}
- list = nft_chain_list_get(h, table, chain);
- if (list == NULL) {
- ret = 1;
- goto err;
- }
+ ret = nft_chain_foreach(h, table, nft_rule_flush_cb, &d);
- ret = nftnl_chain_list_foreach(list, nft_rule_flush_cb, &d);
-err:
/* the core expects 1 for success and 0 for error */
return ret == 0 ? 1 : 0;
}
int nft_chain_user_add(struct nft_handle *h, const char *chain, const char *table)
{
- struct nftnl_chain_list *list;
+ const struct builtin_table *t;
struct nftnl_chain *c;
nft_fn = nft_chain_user_add;
- nft_xt_builtin_init(h, table);
+ t = nft_xt_builtin_table_init(h, table);
if (nft_chain_exists(h, table, chain)) {
errno = EEXIST;
@@ -1736,9 +1786,7 @@ int nft_chain_user_add(struct nft_handle *h, const char *chain, const char *tabl
if (!batch_chain_add(h, NFT_COMPAT_CHAIN_USER_ADD, c))
return 0;
- list = nft_chain_list_get(h, table, chain);
- if (list)
- nftnl_chain_list_add(c, list);
+ nft_cache_add_chain(h, t, c);
/* the core expects 1 for success and 0 for error */
return 1;
@@ -1746,15 +1794,16 @@ int nft_chain_user_add(struct nft_handle *h, const char *chain, const char *tabl
int nft_chain_restore(struct nft_handle *h, const char *chain, const char *table)
{
- struct nftnl_chain_list *list;
+ const struct builtin_table *t;
struct obj_update *obj;
struct nftnl_chain *c;
+ struct nft_chain *nc;
bool created = false;
- nft_xt_builtin_init(h, table);
+ t = nft_xt_builtin_table_init(h, table);
- c = nft_chain_find(h, table, chain);
- if (!c) {
+ nc = nft_chain_find(h, table, chain);
+ if (!nc) {
c = nftnl_chain_alloc();
if (!c)
return 0;
@@ -1763,10 +1812,10 @@ int nft_chain_restore(struct nft_handle *h, const char *chain, const char *table
nftnl_chain_set_str(c, NFTNL_CHAIN_NAME, chain);
created = true;
- list = nft_chain_list_get(h, table, chain);
- if (list)
- nftnl_chain_list_add(c, list);
+ nft_cache_add_chain(h, t, c);
} else {
+ c = nc->nftnl;
+
/* If the chain should vanish meanwhile, kernel genid changes
* and the transaction is refreshed enabling the chain add
* object. With the handle still set, kernel interprets it as a
@@ -1798,9 +1847,10 @@ struct chain_user_del_data {
int builtin_err;
};
-static int __nft_chain_user_del(struct nftnl_chain *c, void *data)
+static int __nft_chain_user_del(struct nft_chain *nc, void *data)
{
struct chain_user_del_data *d = data;
+ struct nftnl_chain *c = nc->nftnl;
struct nft_handle *h = d->handle;
/* don't delete built-in chain */
@@ -1811,12 +1861,17 @@ static int __nft_chain_user_del(struct nftnl_chain *c, void *data)
fprintf(stdout, "Deleting chain `%s'\n",
nftnl_chain_get_str(c, NFTNL_CHAIN_NAME));
+
/* XXX This triggers a fast lookup from the kernel. */
nftnl_chain_unset(c, NFTNL_CHAIN_HANDLE);
if (!batch_chain_add(h, NFT_COMPAT_CHAIN_USER_DEL, c))
return -1;
- nftnl_chain_list_del(c);
+ /* nftnl_chain is freed when deleting the batch object */
+ nc->nftnl = NULL;
+
+ nft_chain_list_del(nc);
+ nft_chain_free(nc);
return 0;
}
@@ -1827,18 +1882,13 @@ int nft_chain_user_del(struct nft_handle *h, const char *chain,
.handle = h,
.verbose = verbose,
};
- struct nftnl_chain_list *list;
- struct nftnl_chain *c;
+ struct nft_chain *c;
int ret = 0;
nft_fn = nft_chain_user_del;
- list = nft_chain_list_get(h, table, chain);
- if (list == NULL)
- return 0;
-
if (chain) {
- c = nftnl_chain_list_lookup_byname(list, chain);
+ c = nft_chain_find(h, table, chain);
if (!c) {
errno = ENOENT;
return 0;
@@ -1850,24 +1900,12 @@ int nft_chain_user_del(struct nft_handle *h, const char *chain,
goto out;
}
- ret = nftnl_chain_list_foreach(list, __nft_chain_user_del, &d);
+ ret = nft_chain_foreach(h, table, __nft_chain_user_del, &d);
out:
/* the core expects 1 for success and 0 for error */
return ret == 0 ? 1 : 0;
}
-static struct nftnl_chain *
-nft_chain_find(struct nft_handle *h, const char *table, const char *chain)
-{
- struct nftnl_chain_list *list;
-
- list = nft_chain_list_get(h, table, chain);
- if (list == NULL)
- return NULL;
-
- return nftnl_chain_list_lookup_byname(list, chain);
-}
-
bool nft_chain_exists(struct nft_handle *h,
const char *table, const char *chain)
{
@@ -1887,6 +1925,7 @@ int nft_chain_user_rename(struct nft_handle *h,const char *chain,
const char *table, const char *newname)
{
struct nftnl_chain *c;
+ struct nft_chain *nc;
uint64_t handle;
nft_fn = nft_chain_user_rename;
@@ -1896,16 +1935,13 @@ int nft_chain_user_rename(struct nft_handle *h,const char *chain,
return 0;
}
- /* Config load changed errno. Ensure genuine info for our callers. */
- errno = 0;
-
/* Find the old chain to be renamed */
- c = nft_chain_find(h, table, chain);
- if (c == NULL) {
+ nc = nft_chain_find(h, table, chain);
+ if (nc == NULL) {
errno = ENOENT;
return 0;
}
- handle = nftnl_chain_get_u64(c, NFTNL_CHAIN_HANDLE);
+ handle = nftnl_chain_get_u64(nc->nftnl, NFTNL_CHAIN_HANDLE);
/* Now prepare the new name for the chain */
c = nftnl_chain_alloc();
@@ -2054,9 +2090,10 @@ out:
}
static struct nftnl_rule *
-nft_rule_find(struct nft_handle *h, struct nftnl_chain *c,
+nft_rule_find(struct nft_handle *h, struct nft_chain *nc,
struct nftnl_rule *rule, int rulenum)
{
+ struct nftnl_chain *c = nc->nftnl;
struct nftnl_rule *r;
struct nftnl_rule_iter *iter;
bool found = false;
@@ -2085,8 +2122,8 @@ nft_rule_find(struct nft_handle *h, struct nftnl_chain *c,
int nft_rule_check(struct nft_handle *h, const char *chain,
const char *table, struct nftnl_rule *rule, bool verbose)
{
- struct nftnl_chain *c;
struct nftnl_rule *r;
+ struct nft_chain *c;
nft_fn = nft_rule_check;
@@ -2111,8 +2148,8 @@ int nft_rule_delete(struct nft_handle *h, const char *chain,
const char *table, struct nftnl_rule *rule, bool verbose)
{
int ret = 0;
- struct nftnl_chain *c;
struct nftnl_rule *r;
+ struct nft_chain *c;
nft_fn = nft_rule_delete;
@@ -2172,9 +2209,9 @@ int nft_rule_insert(struct nft_handle *h, const char *chain,
bool verbose)
{
struct nftnl_rule *r = NULL;
- struct nftnl_chain *c;
+ struct nft_chain *c;
- nft_xt_builtin_init(h, table);
+ nft_xt_builtin_init(h, table, chain);
nft_fn = nft_rule_insert;
@@ -2207,7 +2244,7 @@ int nft_rule_insert(struct nft_handle *h, const char *chain,
if (r)
nftnl_chain_rule_insert_at(new_rule, r);
else
- nftnl_chain_rule_add(new_rule, c);
+ nftnl_chain_rule_add(new_rule, c->nftnl);
return 1;
err:
@@ -2218,8 +2255,8 @@ int nft_rule_delete_num(struct nft_handle *h, const char *chain,
const char *table, int rulenum, bool verbose)
{
int ret = 0;
- struct nftnl_chain *c;
struct nftnl_rule *r;
+ struct nft_chain *c;
nft_fn = nft_rule_delete_num;
@@ -2246,8 +2283,8 @@ int nft_rule_replace(struct nft_handle *h, const char *chain,
int rulenum, bool verbose)
{
int ret = 0;
- struct nftnl_chain *c;
struct nftnl_rule *r;
+ struct nft_chain *c;
nft_fn = nft_rule_replace;
@@ -2326,8 +2363,9 @@ static int nft_rule_count(struct nft_handle *h, struct nftnl_chain *c)
}
static void __nft_print_header(struct nft_handle *h,
- struct nftnl_chain *c, unsigned int format)
+ struct nft_chain *nc, unsigned int format)
{
+ struct nftnl_chain *c = nc->nftnl;
const char *chain_name = nftnl_chain_get_str(c, NFTNL_CHAIN_NAME);
bool basechain = !!nftnl_chain_get(c, NFTNL_CHAIN_HOOKNUM);
uint32_t refs = nftnl_chain_get_u32(c, NFTNL_CHAIN_USE);
@@ -2355,7 +2393,7 @@ struct nft_rule_list_cb_data {
unsigned int num, unsigned int format);
};
-static int nft_rule_list_cb(struct nftnl_chain *c, void *data)
+static int nft_rule_list_cb(struct nft_chain *c, void *data)
{
struct nft_rule_list_cb_data *d = data;
@@ -2367,7 +2405,7 @@ static int nft_rule_list_cb(struct nftnl_chain *c, void *data)
__nft_print_header(d->h, c, d->format);
}
- return __nft_rule_list(d->h, c, d->rulenum, d->format, d->cb);
+ return __nft_rule_list(d->h, c->nftnl, d->rulenum, d->format, d->cb);
}
int nft_rule_list(struct nft_handle *h, const char *chain, const char *table,
@@ -2380,10 +2418,9 @@ int nft_rule_list(struct nft_handle *h, const char *chain, const char *table,
.rulenum = rulenum,
.cb = ops->print_rule,
};
- struct nftnl_chain_list *list;
- struct nftnl_chain *c;
+ struct nft_chain *c;
- nft_xt_builtin_init(h, table);
+ nft_xt_fake_builtin_chains(h, table, chain);
nft_assert_table_compatible(h, table, chain);
if (chain) {
@@ -2400,14 +2437,10 @@ int nft_rule_list(struct nft_handle *h, const char *chain, const char *table,
return 1;
}
- list = nft_chain_list_get(h, table, chain);
- if (!list)
- return 0;
-
if (ops->print_table_header)
ops->print_table_header(table);
- nftnl_chain_list_foreach(list, nft_rule_list_cb, &d);
+ nft_chain_foreach(h, table, nft_rule_list_cb, &d);
return 1;
}
@@ -2418,8 +2451,44 @@ list_save(struct nft_handle *h, struct nftnl_rule *r,
nft_rule_print_save(h, r, NFT_RULE_APPEND, format);
}
-static int nft_rule_list_chain_save(struct nftnl_chain *c, void *data)
+int nft_chain_foreach(struct nft_handle *h, const char *table,
+ int (*cb)(struct nft_chain *c, void *data),
+ void *data)
{
+ const struct builtin_table *t;
+ struct nft_chain_list *list;
+ struct nft_chain *c, *c_bak;
+ int i, ret;
+
+ t = nft_table_builtin_find(h, table);
+ if (!t)
+ return -1;
+
+ for (i = 0; i < NF_INET_NUMHOOKS; i++) {
+ c = h->cache->table[t->type].base_chains[i];
+ if (!c)
+ continue;
+
+ ret = cb(c, data);
+ if (ret < 0)
+ return ret;
+ }
+
+ list = h->cache->table[t->type].chains;
+ if (!list)
+ return -1;
+
+ list_for_each_entry_safe(c, c_bak, &list->list, head) {
+ ret = cb(c, data);
+ if (ret < 0)
+ return ret;
+ }
+ return 0;
+}
+
+static int nft_rule_list_chain_save(struct nft_chain *nc, void *data)
+{
+ struct nftnl_chain *c = nc->nftnl;
const char *chain_name = nftnl_chain_get_str(c, NFTNL_CHAIN_NAME);
uint32_t policy = nftnl_chain_get_u32(c, NFTNL_CHAIN_POLICY);
int *counters = data;
@@ -2449,24 +2518,19 @@ int nft_rule_list_save(struct nft_handle *h, const char *chain,
.save_fmt = true,
.cb = list_save,
};
- struct nftnl_chain_list *list;
- struct nftnl_chain *c;
+ struct nft_chain *c;
int ret = 0;
- nft_xt_builtin_init(h, table);
+ nft_xt_fake_builtin_chains(h, table, chain);
nft_assert_table_compatible(h, table, chain);
- list = nft_chain_list_get(h, table, chain);
- if (!list)
- return 0;
-
if (counters < 0)
d.format = FMT_C_COUNTS;
else if (counters == 0)
d.format = FMT_NOCOUNTS;
if (chain) {
- c = nftnl_chain_list_lookup_byname(list, chain);
+ c = nft_chain_find(h, table, chain);
if (!c)
return 0;
@@ -2477,10 +2541,10 @@ int nft_rule_list_save(struct nft_handle *h, const char *chain,
}
/* Dump policies and custom chains first */
- nftnl_chain_list_foreach(list, nft_rule_list_chain_save, &counters);
+ nft_chain_foreach(h, table, nft_rule_list_chain_save, &counters);
/* Now dump out rules in this table */
- ret = nftnl_chain_list_foreach(list, nft_rule_list_cb, &d);
+ ret = nft_chain_foreach(h, table, nft_rule_list_cb, &d);
return ret == 0 ? 1 : 0;
}
@@ -2489,7 +2553,7 @@ int nft_rule_zero_counters(struct nft_handle *h, const char *chain,
{
struct iptables_command_state cs = {};
struct nftnl_rule *r, *new_rule;
- struct nftnl_chain *c;
+ struct nft_chain *c;
int ret = 0;
nft_fn = nft_rule_delete;
@@ -2631,7 +2695,7 @@ static void batch_obj_del(struct nft_handle *h, struct obj_update *o)
static void nft_refresh_transaction(struct nft_handle *h)
{
const char *tablename, *chainname;
- const struct nftnl_chain *c;
+ const struct nft_chain *c;
struct obj_update *n, *tmp;
bool exists;
@@ -2928,7 +2992,7 @@ err_free_rule:
int ebt_set_user_chain_policy(struct nft_handle *h, const char *table,
const char *chain, const char *policy)
{
- struct nftnl_chain *c = nft_chain_find(h, table, chain);
+ struct nft_chain *c = nft_chain_find(h, table, chain);
int pval;
if (!c)
@@ -2943,14 +3007,15 @@ int ebt_set_user_chain_policy(struct nft_handle *h, const char *table,
else
return 0;
- nftnl_chain_set_u32(c, NFTNL_CHAIN_POLICY, pval);
+ nftnl_chain_set_u32(c->nftnl, NFTNL_CHAIN_POLICY, pval);
return 1;
}
static void nft_bridge_commit_prepare(struct nft_handle *h)
{
const struct builtin_table *t;
- struct nftnl_chain_list *list;
+ struct nft_chain_list *list;
+ struct nft_chain *c;
int i;
for (i = 0; i < NFT_TABLE_MAX; i++) {
@@ -2963,7 +3028,9 @@ static void nft_bridge_commit_prepare(struct nft_handle *h)
if (!list)
continue;
- nftnl_chain_list_foreach(list, ebt_add_policy_rule, h);
+ list_for_each_entry(c, &list->list, head) {
+ ebt_add_policy_rule(c->nftnl, h);
+ }
}
}
@@ -3064,7 +3131,7 @@ static int nft_prepare(struct nft_handle *h)
cmd->chain, cmd->policy);
break;
case NFT_COMPAT_SET_ADD:
- nft_xt_builtin_init(h, cmd->table);
+ nft_xt_builtin_table_init(h, cmd->table);
batch_set_add(h, NFT_COMPAT_SET_ADD, cmd->obj.set);
ret = 1;
break;
@@ -3271,8 +3338,9 @@ struct chain_zero_data {
bool verbose;
};
-static int __nft_chain_zero_counters(struct nftnl_chain *c, void *data)
+static int __nft_chain_zero_counters(struct nft_chain *nc, void *data)
{
+ struct nftnl_chain *c = nc->nftnl;
struct chain_zero_data *d = data;
struct nft_handle *h = d->handle;
struct nftnl_rule_iter *iter;
@@ -3280,7 +3348,7 @@ static int __nft_chain_zero_counters(struct nftnl_chain *c, void *data)
if (d->verbose)
fprintf(stdout, "Zeroing chain `%s'\n",
- nftnl_chain_get_str(c, NFTNL_CHAIN_NAME));
+ nftnl_chain_get_str(c, NFTNL_CHAIN_NAME));
if (nftnl_chain_is_set(c, NFTNL_CHAIN_HOOKNUM)) {
/* zero base chain counters. */
@@ -3345,20 +3413,15 @@ static int __nft_chain_zero_counters(struct nftnl_chain *c, void *data)
int nft_chain_zero_counters(struct nft_handle *h, const char *chain,
const char *table, bool verbose)
{
- struct nftnl_chain_list *list;
struct chain_zero_data d = {
.handle = h,
.verbose = verbose,
};
- struct nftnl_chain *c;
+ struct nft_chain *c;
int ret = 0;
- list = nft_chain_list_get(h, table, chain);
- if (list == NULL)
- goto err;
-
if (chain) {
- c = nftnl_chain_list_lookup_byname(list, chain);
+ c = nft_chain_find(h, table, chain);
if (!c) {
errno = ENOENT;
return 0;
@@ -3368,7 +3431,7 @@ int nft_chain_zero_counters(struct nft_handle *h, const char *chain,
goto err;
}
- ret = nftnl_chain_list_foreach(list, __nft_chain_zero_counters, &d);
+ ret = nft_chain_foreach(h, table, __nft_chain_zero_counters, &d);
err:
/* the core expects 1 for success and 0 for error */
return ret == 0 ? 1 : 0;
@@ -3418,8 +3481,9 @@ static int nft_is_rule_compatible(struct nftnl_rule *rule, void *data)
return nftnl_expr_foreach(rule, nft_is_expr_compatible, NULL);
}
-static int nft_is_chain_compatible(struct nftnl_chain *c, void *data)
+static int nft_is_chain_compatible(struct nft_chain *nc, void *data)
{
+ struct nftnl_chain *c = nc->nftnl;
const struct builtin_table *table;
const struct builtin_chain *chain;
const char *tname, *cname, *type;
@@ -3457,16 +3521,13 @@ static int nft_is_chain_compatible(struct nftnl_chain *c, void *data)
bool nft_is_table_compatible(struct nft_handle *h,
const char *table, const char *chain)
{
- struct nftnl_chain_list *clist;
-
- clist = nft_chain_list_get(h, table, chain);
- if (clist == NULL)
- return false;
+ if (chain) {
+ struct nft_chain *c = nft_chain_find(h, table, chain);
- if (nftnl_chain_list_foreach(clist, nft_is_chain_compatible, h))
- return false;
+ return c && !nft_is_chain_compatible(c, h);
+ }
- return true;
+ return !nft_chain_foreach(h, table, nft_is_chain_compatible, h);
}
void nft_assert_table_compatible(struct nft_handle *h,