Commit 9caffe92 authored by Arturo Borrero Gonzalez's avatar Arturo Borrero Gonzalez
Browse files

New upstream version 1.8.6

parent eb1d7c5f
......@@ -225,7 +225,8 @@ struct nft_xt_restore_cb {
int (*chain_restore)(struct nft_handle *h, const char *chain,
const char *table);
int (*table_flush)(struct nft_handle *h, const char *table);
int (*table_flush)(struct nft_handle *h, const char *table,
bool verbose);
int (*do_command)(struct nft_handle *h, int argc, char *argv[],
char **table, bool restore);
......
......@@ -265,7 +265,6 @@ struct obj_update {
struct list_head head;
enum obj_update_type type:8;
uint8_t skip:1;
uint8_t implicit:1;
unsigned int seq;
union {
struct nftnl_table *table;
......@@ -350,7 +349,6 @@ static int mnl_append_error(const struct nft_handle *h,
case NFT_COMPAT_RULE_SAVE:
case NFT_COMPAT_RULE_ZERO:
case NFT_COMPAT_BRIDGE_USER_CHAIN_UPDATE:
case NFT_COMPAT_TABLE_NEW:
assert(0);
break;
}
......@@ -389,10 +387,11 @@ batch_set_add(struct nft_handle *h, enum obj_update_type type,
return batch_add(h, type, s);
}
static int batch_chain_add(struct nft_handle *h, enum obj_update_type type,
static struct obj_update *
batch_chain_add(struct nft_handle *h, enum obj_update_type type,
struct nftnl_chain *c)
{
return batch_add(h, type, c) ? 0 : -1;
return batch_add(h, type, c);
}
static struct obj_update *
......@@ -645,19 +644,13 @@ const struct builtin_table xtables_bridge[NFT_TABLE_MAX] = {
},
};
static bool nft_table_initialized(const struct nft_handle *h,
enum nft_table_type type)
{
return h->cache->table[type].initialized;
}
static int nft_table_builtin_add(struct nft_handle *h,
const struct builtin_table *_t)
{
struct nftnl_table *t;
int ret;
if (nft_table_initialized(h, _t->type))
if (h->cache->table[_t->type].exists)
return 0;
t = nftnl_table_alloc();
......@@ -685,7 +678,9 @@ nft_chain_builtin_alloc(const struct builtin_table *table,
nftnl_chain_set_str(c, NFTNL_CHAIN_NAME, chain->name);
nftnl_chain_set_u32(c, NFTNL_CHAIN_HOOKNUM, chain->hook);
nftnl_chain_set_u32(c, NFTNL_CHAIN_PRIO, chain->prio);
nftnl_chain_set_u32(c, NFTNL_CHAIN_POLICY, policy);
if (policy >= 0)
nftnl_chain_set_u32(c, NFTNL_CHAIN_POLICY, policy);
nftnl_chain_set_str(c, NFTNL_CHAIN_TYPE, chain->type);
return c;
......@@ -743,22 +738,17 @@ 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)
{
struct nftnl_chain_list *list;
struct nftnl_chain *c;
int i;
/* Initialize built-in chains if they don't exist yet */
for (i=0; i < NF_INET_NUMHOOKS && table->chains[i].name != NULL; i++) {
list = nft_chain_list_get(h, table->name,
table->chains[i].name);
if (!list)
continue;
c = nftnl_chain_list_lookup_byname(list, table->chains[i].name);
if (c != NULL)
if (nft_chain_find(h, table->name, table->chains[i].name))
continue;
nft_chain_builtin_add(h, table, &table->chains[i]);
......@@ -776,9 +766,6 @@ static int nft_xt_builtin_init(struct nft_handle *h, const char *table)
if (t == NULL)
return -1;
if (nft_table_initialized(h, t->type))
return 0;
if (nft_table_builtin_add(h, t) < 0)
return -1;
......@@ -787,8 +774,6 @@ static int nft_xt_builtin_init(struct nft_handle *h, const char *table)
nft_chain_builtin_init(h, t);
h->cache->table[t->type].initialized = true;
return 0;
}
......@@ -892,7 +877,7 @@ static struct nftnl_chain *nft_chain_new(struct nft_handle *h,
}
/* if this built-in table does not exists, create it */
nft_table_builtin_add(h, _t);
nft_xt_builtin_init(h, table);
_c = nft_chain_builtin_find(_t, chain);
if (_c != NULL) {
......@@ -920,7 +905,6 @@ int nft_chain_set(struct nft_handle *h, const char *table,
const struct xt_counters *counters)
{
struct nftnl_chain *c = NULL;
int ret;
nft_fn = nft_chain_set;
......@@ -928,16 +912,19 @@ int nft_chain_set(struct nft_handle *h, const char *table,
c = nft_chain_new(h, table, chain, NF_DROP, counters);
else if (strcmp(policy, "ACCEPT") == 0)
c = nft_chain_new(h, table, chain, NF_ACCEPT, counters);
else if (strcmp(policy, "-") == 0)
c = nft_chain_new(h, table, chain, -1, counters);
else
errno = EINVAL;
if (c == NULL)
return 0;
ret = batch_chain_add(h, NFT_COMPAT_CHAIN_UPDATE, c);
if (!batch_chain_add(h, NFT_COMPAT_CHAIN_UPDATE, c))
return 0;
/* the core expects 1 for success and 0 for error */
return ret == 0 ? 1 : 0;
return 1;
}
static int __add_match(struct nftnl_expr *e, struct xt_entry_match *m)
......@@ -1400,9 +1387,6 @@ err:
return NULL;
}
static struct nftnl_chain *
nft_chain_find(struct nft_handle *h, const char *table, const char *chain);
int
nft_rule_append(struct nft_handle *h, const char *chain, const char *table,
struct nftnl_rule *r, struct nftnl_rule *ref, bool verbose)
......@@ -1559,51 +1543,33 @@ static const char *policy_name[NF_ACCEPT+1] = {
[NF_ACCEPT] = "ACCEPT",
};
int nft_chain_save(struct nft_handle *h, struct nftnl_chain_list *list)
int nft_chain_save(struct nftnl_chain *c, void *data)
{
struct nft_family_ops *ops = h->ops;
struct nftnl_chain_list_iter *iter;
struct nftnl_chain *c;
iter = nftnl_chain_list_iter_create(list);
if (iter == NULL)
return 0;
c = nftnl_chain_list_iter_next(iter);
while (c != NULL) {
const char *policy = NULL;
if (nft_chain_builtin(c)) {
uint32_t pol = NF_ACCEPT;
if (nftnl_chain_get(c, NFTNL_CHAIN_POLICY))
pol = nftnl_chain_get_u32(c, NFTNL_CHAIN_POLICY);
policy = policy_name[pol];
} else if (h->family == NFPROTO_BRIDGE) {
if (nftnl_chain_is_set(c, NFTNL_CHAIN_POLICY)) {
uint32_t pol;
pol = nftnl_chain_get_u32(c, NFTNL_CHAIN_POLICY);
policy = policy_name[pol];
} else {
policy = "RETURN";
}
}
if (ops->save_chain)
ops->save_chain(c, policy);
struct nft_handle *h = data;
const char *policy = NULL;
c = nftnl_chain_list_iter_next(iter);
if (nftnl_chain_is_set(c, NFTNL_CHAIN_POLICY)) {
policy = policy_name[nftnl_chain_get_u32(c, NFTNL_CHAIN_POLICY)];
} else if (nft_chain_builtin(c)) {
policy = "ACCEPT";
} else if (h->family == NFPROTO_BRIDGE) {
policy = "RETURN";
}
nftnl_chain_list_iter_destroy(iter);
if (h->ops->save_chain)
h->ops->save_chain(c, policy);
return 1;
return 0;
}
static int nft_chain_save_rules(struct nft_handle *h,
struct nftnl_chain *c, unsigned int format)
struct nft_rule_save_data {
struct nft_handle *h;
unsigned int format;
};
static int nft_rule_save_cb(struct nftnl_chain *c, void *data)
{
struct nft_rule_save_data *d = data;
struct nftnl_rule_iter *iter;
struct nftnl_rule *r;
......@@ -1613,7 +1579,7 @@ static int nft_chain_save_rules(struct nft_handle *h,
r = nftnl_rule_iter_next(iter);
while (r != NULL) {
nft_rule_print_save(h, r, NFT_RULE_APPEND, format);
nft_rule_print_save(d->h, r, NFT_RULE_APPEND, d->format);
r = nftnl_rule_iter_next(iter);
}
......@@ -1623,29 +1589,18 @@ static int nft_chain_save_rules(struct nft_handle *h,
int nft_rule_save(struct nft_handle *h, const char *table, unsigned int format)
{
struct nftnl_chain_list_iter *iter;
struct nft_rule_save_data d = {
.h = h,
.format = format,
};
struct nftnl_chain_list *list;
struct nftnl_chain *c;
int ret = 0;
int ret;
list = nft_chain_list_get(h, table, NULL);
if (!list)
return 0;
iter = nftnl_chain_list_iter_create(list);
if (!iter)
return 0;
c = nftnl_chain_list_iter_next(iter);
while (c) {
ret = nft_chain_save_rules(h, c, format);
if (ret != 0)
break;
c = nftnl_chain_list_iter_next(iter);
}
nftnl_chain_list_iter_destroy(iter);
ret = nftnl_chain_list_foreach(list, nft_rule_save_cb, &d);
/* the core expects 1 for success and 0 for error */
return ret == 0 ? 1 : 0;
......@@ -1667,7 +1622,7 @@ struct nftnl_set *nft_set_batch_lookup_byid(struct nft_handle *h,
static void
__nft_rule_flush(struct nft_handle *h, const char *table,
const char *chain, bool verbose, bool implicit)
const char *chain, bool verbose, bool skip)
{
struct obj_update *obj;
struct nftnl_rule *r;
......@@ -1689,31 +1644,47 @@ __nft_rule_flush(struct nft_handle *h, const char *table,
return;
}
obj->implicit = implicit;
obj->skip = skip;
}
struct nft_rule_flush_data {
struct nft_handle *h;
const char *table;
bool verbose;
};
static int nft_rule_flush_cb(struct nftnl_chain *c, void *data)
{
const char *chain = nftnl_chain_get_str(c, NFTNL_CHAIN_NAME);
struct nft_rule_flush_data *d = data;
batch_chain_flush(d->h, d->table, chain);
__nft_rule_flush(d->h, d->table, chain, d->verbose, false);
flush_rule_cache(d->h, d->table, c);
return 0;
}
int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table,
bool verbose)
{
struct nftnl_chain_list_iter *iter;
struct nft_rule_flush_data d = {
.h = h,
.table = table,
.verbose = verbose,
};
struct nftnl_chain_list *list;
struct nftnl_chain *c = NULL;
int ret = 0;
nft_xt_builtin_init(h, table);
nft_fn = nft_rule_flush;
if (chain || verbose) {
list = nft_chain_list_get(h, table, chain);
if (list == NULL) {
ret = 1;
goto err;
}
}
if (chain || verbose)
nft_xt_builtin_init(h, table);
else if (!nft_table_find(h, table))
return 1;
if (chain) {
c = nftnl_chain_list_lookup_byname(list, chain);
c = nft_chain_find(h, table, chain);
if (!c) {
errno = ENOENT;
return 0;
......@@ -1727,22 +1698,13 @@ int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table,
return 1;
}
iter = nftnl_chain_list_iter_create(list);
if (iter == NULL) {
list = nft_chain_list_get(h, table, chain);
if (list == NULL) {
ret = 1;
goto err;
}
c = nftnl_chain_list_iter_next(iter);
while (c != NULL) {
chain = nftnl_chain_get_str(c, NFTNL_CHAIN_NAME);
batch_chain_flush(h, table, chain);
__nft_rule_flush(h, table, chain, verbose, false);
flush_rule_cache(h, table, c);
c = nftnl_chain_list_iter_next(iter);
}
nftnl_chain_list_iter_destroy(iter);
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;
......@@ -1752,7 +1714,6 @@ int nft_chain_user_add(struct nft_handle *h, const char *chain, const char *tabl
{
struct nftnl_chain_list *list;
struct nftnl_chain *c;
int ret;
nft_fn = nft_chain_user_add;
......@@ -1772,31 +1733,28 @@ int nft_chain_user_add(struct nft_handle *h, const char *chain, const char *tabl
if (h->family == NFPROTO_BRIDGE)
nftnl_chain_set_u32(c, NFTNL_CHAIN_POLICY, NF_ACCEPT);
ret = batch_chain_add(h, NFT_COMPAT_CHAIN_USER_ADD, c);
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);
/* the core expects 1 for success and 0 for error */
return ret == 0 ? 1 : 0;
return 1;
}
int nft_chain_restore(struct nft_handle *h, const char *chain, const char *table)
{
struct nftnl_chain_list *list;
struct obj_update *obj;
struct nftnl_chain *c;
bool created = false;
int ret;
nft_xt_builtin_init(h, table);
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, true);
} else {
if (!c) {
c = nftnl_chain_alloc();
if (!c)
return 0;
......@@ -1804,22 +1762,29 @@ int nft_chain_restore(struct nft_handle *h, const char *chain, const char *table
nftnl_chain_set_str(c, NFTNL_CHAIN_TABLE, table);
nftnl_chain_set_str(c, NFTNL_CHAIN_NAME, chain);
created = true;
}
if (h->family == NFPROTO_BRIDGE)
nftnl_chain_set_u32(c, NFTNL_CHAIN_POLICY, NF_ACCEPT);
list = nft_chain_list_get(h, table, chain);
if (list)
nftnl_chain_list_add(c, list);
} else {
/* 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
* chain replace job and errors since it is not found anymore.
*/
nftnl_chain_unset(c, NFTNL_CHAIN_HANDLE);
}
if (!created)
return 1;
__nft_rule_flush(h, table, chain, false, created);
ret = batch_chain_add(h, NFT_COMPAT_CHAIN_USER_ADD, c);
obj = batch_chain_add(h, NFT_COMPAT_CHAIN_USER_ADD, c);
if (!obj)
return 0;
list = nft_chain_list_get(h, table, chain);
if (list)
nftnl_chain_list_add(c, list);
obj->skip = !created;
/* the core expects 1 for success and 0 for error */
return ret == 0 ? 1 : 0;
return 1;
}
/* From linux/netlink.h */
......@@ -1837,7 +1802,6 @@ static int __nft_chain_user_del(struct nftnl_chain *c, void *data)
{
struct chain_user_del_data *d = data;
struct nft_handle *h = d->handle;
int ret;
/* don't delete built-in chain */
if (nft_chain_builtin(c))
......@@ -1849,8 +1813,7 @@ static int __nft_chain_user_del(struct nftnl_chain *c, void *data)
/* XXX This triggers a fast lookup from the kernel. */
nftnl_chain_unset(c, NFTNL_CHAIN_HANDLE);
ret = batch_chain_add(h, NFT_COMPAT_CHAIN_USER_DEL, c);
if (ret)
if (!batch_chain_add(h, NFT_COMPAT_CHAIN_USER_DEL, c))
return -1;
nftnl_chain_list_del(c);
......@@ -1925,7 +1888,6 @@ int nft_chain_user_rename(struct nft_handle *h,const char *chain,
{
struct nftnl_chain *c;
uint64_t handle;
int ret;
nft_fn = nft_chain_user_rename;
......@@ -1934,8 +1896,6 @@ int nft_chain_user_rename(struct nft_handle *h,const char *chain,
return 0;
}
nft_xt_builtin_init(h, table);
/* Config load changed errno. Ensure genuine info for our callers. */
errno = 0;
......@@ -1956,73 +1916,37 @@ int nft_chain_user_rename(struct nft_handle *h,const char *chain,
nftnl_chain_set_str(c, NFTNL_CHAIN_NAME, newname);
nftnl_chain_set_u64(c, NFTNL_CHAIN_HANDLE, handle);
ret = batch_chain_add(h, NFT_COMPAT_CHAIN_RENAME, c);
if (!batch_chain_add(h, NFT_COMPAT_CHAIN_RENAME, c))
return 0;
/* the core expects 1 for success and 0 for error */
return ret == 0 ? 1 : 0;
return 1;
}
bool nft_table_find(struct nft_handle *h, const char *tablename)
{
struct nftnl_table_list_iter *iter;
struct nftnl_table_list *list;
struct nftnl_table *t;
bool ret = false;
list = nftnl_table_list_get(h);
if (list == NULL)
goto err;
iter = nftnl_table_list_iter_create(list);
if (iter == NULL)
goto err;
t = nftnl_table_list_iter_next(iter);
while (t != NULL) {
const char *this_tablename =
nftnl_table_get(t, NFTNL_TABLE_NAME);
if (strcmp(tablename, this_tablename) == 0) {
ret = true;
break;
}
t = nftnl_table_list_iter_next(iter);
}
nftnl_table_list_iter_destroy(iter);
const struct builtin_table *t;
err:
return ret;
t = nft_table_builtin_find(h, tablename);
return t ? h->cache->table[t->type].exists : false;
}
int nft_for_each_table(struct nft_handle *h,
int (*func)(struct nft_handle *h, const char *tablename, void *data),
void *data)
{
struct nftnl_table_list *list;
struct nftnl_table_list_iter *iter;
struct nftnl_table *t;
list = nftnl_table_list_get(h);
if (list == NULL)
return -1;
iter = nftnl_table_list_iter_create(list);
if (iter == NULL)
return -1;
int i;
t = nftnl_table_list_iter_next(iter);
while (t != NULL) {
const char *tablename =
nftnl_table_get(t, NFTNL_TABLE_NAME);
for (i = 0; i < NFT_TABLE_MAX; i++) {
if (h->tables[i].name == NULL)
continue;
func(h, tablename, data);
if (!h->cache->table[h->tables[i].type].exists)
continue;
t = nftnl_table_list_iter_next(iter);
func(h, h->tables[i].name, data);
}
nftnl_table_list_iter_destroy(iter);
return 0;
}
......@@ -2049,7 +1973,7 @@ static int __nft_table_flush(struct nft_handle *h, const char *table, bool exist
_t = nft_table_builtin_find(h, table);
assert(_t);
h->cache->table[_t->type].initialized = false;
h->cache->table[_t->type].exists = false;
flush_chain_cache(h, table);
......@@ -2058,52 +1982,21 @@ static int __nft_table_flush(struct nft_handle *h, const char *table, bool exist
int nft_table_flush(struct nft_handle *h, const char *table)
{
struct nftnl_table_list_iter *iter;
struct nftnl_table_list *list;
struct nftnl_table *t;
bool exists = false;
const struct builtin_table *t;
int ret = 0;
nft_fn = nft_table_flush;
list = nftnl_table_list_get(h);
if (list == NULL) {
ret = -1;
goto err_out;
}
iter = nftnl_table_list_iter_create(list);
if (iter == NULL) {
ret = -1;
goto err_table_list;
}
t = nftnl_table_list_iter_next(iter);
while (t != NULL) {
const char *table_name =
nftnl_table_get_str(t, NFTNL_TABLE_NAME);
if (strcmp(table_name, table) == 0) {
exists = true;
break;
}
t = nft_table_builtin_find(h, table);
if (!t)
return 0;
t = nftnl_table_list_iter_next(iter);
}
ret = __nft_table_flush(h, table, h->cache->table[t->type].exists);
ret = __nft_table_flush(h, table, exists);
nftnl_table_list_iter_destroy(iter);
err_table_list:
err_out:
/* the core expects 1 for success and 0 for error */
return ret == 0 ? 1 : 0;
}
void nft_table_new(struct nft_handle *h, const char *table)
{
nft_xt_builtin_init(h, table);
}
static int __nft_rule_del(struct nft_handle *h, struct nftnl_rule *r)
{
struct obj_update *obj;
......@@ -2452,55 +2345,69 @@ static void __nft_print_header(struct nft_handle *h,
&ctrs, basechain, refs - entries, entries);
}
struct nft_rule_list_cb_data {
struct nft_handle *h;
unsigned int format;
int rulenum;
bool found;
bool save_fmt;
void (*cb)(struct nft_handle *h, struct nftnl_rule *r,
unsigned int num, unsigned int format);
};
static int nft_rule_list_cb(struct nftnl_chain *c, void *data)
{
struct nft_rule_list_cb_data *d = data;
if (!d->save_fmt) {
if (d->found)
printf("\n");
d->found = true;
__nft_print_header(d->h, c, d->format);
}
return __nft_rule_list(d->h, c, d->rulenum, d->format, d->cb);
}
int nft_rule_list(struct nft_handle *h, const char *chain, const char *table,
int rulenum, unsigned int format)
{
const struct nft_family_ops *ops = h->ops;
struct nft_rule_list_cb_data d = {
.h = h,
.format = format,
.rulenum = rulenum,
.cb = ops->print_rule,
};
struct nftnl_chain_list *list;
struct nftnl_chain_list_iter *iter;
struct nftnl_chain *c;
bool found = false;
nft_xt_builtin_init(h, table);
nft_assert_table_compatible(h, table, chain);
list = nft_chain_list_get(h, table, chain);
if (!list)
return 0;
if (chain) {
c = nftnl_chain_list_lookup_byname(list, chain);
c = nft_chain_find(h, table, chain);
if (!c)
return 0;
if (!rulenum) {
if (ops->print_table_header)
ops->print_table_header(table);
__nft_print_header(h, c, format);
}
__nft_rule_list(h, c, rulenum, format, ops->print_rule);
if (rulenum)
d.save_fmt = true; /* skip header printing */
else if (ops->print_table_header)
ops->print_table_header(table);
nft_rule_list_cb(c, &d);
return 1;
}
iter = nftnl_chain_list_iter_create(list);
if (iter == NULL)
list = nft_chain_list_get(h, table, chain);
if (!list)
return 0;
if (ops->print_table_header)
ops->print_table_header(table);
c = nftnl_chain_list_iter_next(iter);
while (c != NULL) {
if (found)
printf("\n");
__nft_print_header(h, c, format);
__nft_rule_list(h, c, rulenum, format, ops->print_rule);
found = true;
c = nftnl_chain_list_iter_next(iter);
}
nftnl_chain_list_iter_destroy(iter);
nftnl_chain_list_foreach(list, nft_rule_list_cb, &d);
return 1;
}
......@@ -2511,7 +2418,7 @@ list_save(struct nft_handle *h, struct nftnl_rule *r,
nft_rule_print_save(h, r, NFT_RULE_APPEND, format);
}
static int __nftnl_rule_list_chain_save(struct nftnl_chain *c, void *data)
static int nft_rule_list_chain_save(struct nftnl_chain *c, void *data)
{
const char *chain_name = nftnl_chain_get_str(c, NFTNL_CHAIN_NAME);
uint32_t policy = nftnl_chain_get_u32(c, NFTNL_CHAIN_POLICY);
......@@ -2533,31 +2440,16 @@ static int __nftnl_rule_list_chain_save(struct nftnl_chain *c, void *data)
return 0;
}
static int
nftnl_rule_list_chain_save(struct nft_handle *h, const char *chain,
struct nftnl_chain_list *list, int counters)
{
struct nftnl_chain *c;
if (chain) {
c = nftnl_chain_list_lookup_byname(list, chain);
if (!c)
return 0;
__nftnl_rule_list_chain_save(c, &counters);
return 1;
}
nftnl_chain_list_foreach(list, __nftnl_rule_list_chain_save, &counters);
return 1;
}
int nft_rule_list_save(struct nft_handle *h, const char *chain,
const char *table, int rulenum, int counters)
{
struct nft_rule_list_cb_data d = {
.h = h,
.rulenum = rulenum,
.save_fmt = true,
.cb = list_save,
};
struct nftnl_chain_list *list;
struct nftnl_chain_list_iter *iter;
unsigned int format = 0;
struct nftnl_chain *c;
int ret = 0;
......@@ -2568,35 +2460,28 @@ int nft_rule_list_save(struct nft_handle *h, const char *chain,
if (!list)
return 0;
/* Dump policies and custom chains first */
if (!rulenum)
nftnl_rule_list_chain_save(h, chain, list, counters);
if (counters < 0)
format = FMT_C_COUNTS;
d.format = FMT_C_COUNTS;
else if (counters == 0)
format = FMT_NOCOUNTS;
d.format = FMT_NOCOUNTS;
if (chain) {
c = nftnl_chain_list_lookup_byname(list, chain);
if (!c)
return 0;
return __nft_rule_list(h, c, rulenum, format, list_save);
if (!rulenum)
nft_rule_list_chain_save(c, &counters);
return nft_rule_list_cb(c, &d);
}
/* Now dump out rules in this table */
iter = nftnl_chain_list_iter_create(list);
if (iter == NULL)
return 0;
/* Dump policies and custom chains first */
nftnl_chain_list_foreach(list, nft_rule_list_chain_save, &counters);
c = nftnl_chain_list_iter_next(iter);
while (c != NULL) {
ret = __nft_rule_list(h, c, rulenum, format, list_save);
c = nftnl_chain_list_iter_next(iter);
}
nftnl_chain_list_iter_destroy(iter);
return ret;
/* Now dump out rules in this table */
ret = nftnl_chain_list_foreach(list, nft_rule_list_cb, &d);
return ret == 0 ? 1 : 0;
}
int nft_rule_zero_counters(struct nft_handle *h, const char *chain,
......@@ -2735,7 +2620,6 @@ static void batch_obj_del(struct nft_handle *h, struct obj_update *o)
case NFT_COMPAT_RULE_SAVE:
case NFT_COMPAT_RULE_ZERO:
case NFT_COMPAT_BRIDGE_USER_CHAIN_UPDATE:
case NFT_COMPAT_TABLE_NEW:
assert(0);
break;
}
......@@ -2754,11 +2638,6 @@ static void nft_refresh_transaction(struct nft_handle *h)
h->error.lineno = 0;
list_for_each_entry_safe(n, tmp, &h->obj_list, head) {
if (n->implicit) {
batch_obj_del(h, n);
continue;
}
switch (n->type) {
case NFT_COMPAT_TABLE_FLUSH:
tablename = nftnl_table_get_str(n->table, NFTNL_TABLE_NAME);
......@@ -2784,14 +2663,22 @@ static void nft_refresh_transaction(struct nft_handle *h)
c = nft_chain_find(h, tablename, chainname);
if (c) {
/* -restore -n flushes existing rules from redefined user-chain */
__nft_rule_flush(h, tablename,
chainname, false, true);
n->skip = 1;
} else if (!c) {
n->skip = 0;
}
break;
case NFT_COMPAT_RULE_FLUSH:
tablename = nftnl_rule_get_str(n->rule, NFTNL_RULE_TABLE);
if (!tablename)
continue;
chainname = nftnl_rule_get_str(n->rule, NFTNL_RULE_CHAIN);
if (!chainname)
continue;
n->skip = !nft_chain_find(h, tablename, chainname);
break;
case NFT_COMPAT_TABLE_ADD:
case NFT_COMPAT_CHAIN_ADD:
case NFT_COMPAT_CHAIN_ZERO:
......@@ -2803,7 +2690,6 @@ static void nft_refresh_transaction(struct nft_handle *h)
case NFT_COMPAT_RULE_INSERT:
case NFT_COMPAT_RULE_REPLACE:
case NFT_COMPAT_RULE_DELETE:
case NFT_COMPAT_RULE_FLUSH:
case NFT_COMPAT_SET_ADD:
case NFT_COMPAT_RULE_LIST:
case NFT_COMPAT_RULE_CHECK:
......@@ -2811,7 +2697,6 @@ static void nft_refresh_transaction(struct nft_handle *h)
case NFT_COMPAT_RULE_SAVE:
case NFT_COMPAT_RULE_ZERO:
case NFT_COMPAT_BRIDGE_USER_CHAIN_UPDATE:
case NFT_COMPAT_TABLE_NEW:
break;
}
}
......@@ -2835,9 +2720,10 @@ retry:
h->nft_genid++;
list_for_each_entry(n, &h->obj_list, head) {
if (n->skip)
if (n->skip) {
n->seq = 0;
continue;
}
n->seq = seq++;
switch (n->type) {
......@@ -2915,7 +2801,6 @@ retry:
case NFT_COMPAT_RULE_SAVE:
case NFT_COMPAT_RULE_ZERO:
case NFT_COMPAT_BRIDGE_USER_CHAIN_UPDATE:
case NFT_COMPAT_TABLE_NEW:
assert(0);
}
......@@ -3178,10 +3063,6 @@ static int nft_prepare(struct nft_handle *h)
ret = ebt_set_user_chain_policy(h, cmd->table,
cmd->chain, cmd->policy);
break;
case NFT_COMPAT_TABLE_NEW:
nft_xt_builtin_init(h, cmd->table);
ret = 1;
break;
case NFT_COMPAT_SET_ADD:
nft_xt_builtin_init(h, cmd->table);
batch_set_add(h, NFT_COMPAT_SET_ADD, cmd->obj.set);
......@@ -3406,7 +3287,7 @@ static int __nft_chain_zero_counters(struct nftnl_chain *c, void *data)
nftnl_chain_set_u64(c, NFTNL_CHAIN_PACKETS, 0);
nftnl_chain_set_u64(c, NFTNL_CHAIN_BYTES, 0);
nftnl_chain_unset(c, NFTNL_CHAIN_HANDLE);
if (batch_chain_add(h, NFT_COMPAT_CHAIN_ZERO, c))
if (!batch_chain_add(h, NFT_COMPAT_CHAIN_ZERO, c))
return -1;
}
......
......@@ -8,10 +8,10 @@
#include <libiptc/linux_list.h>
enum nft_table_type {
NFT_TABLE_FILTER = 0,
NFT_TABLE_MANGLE,
NFT_TABLE_RAW,
NFT_TABLE_MANGLE = 0,
NFT_TABLE_SECURITY,
NFT_TABLE_RAW,
NFT_TABLE_FILTER,
NFT_TABLE_NAT,
};
#define NFT_TABLE_MAX (NFT_TABLE_NAT + 1)
......@@ -38,11 +38,10 @@ enum nft_cache_level {
};
struct nft_cache {
struct nftnl_table_list *tables;
struct {
struct nftnl_chain_list *chains;
struct nftnl_set_list *sets;
bool initialized;
bool exists;
} table[NFT_TABLE_MAX];
};
......@@ -68,7 +67,6 @@ enum obj_update_type {
NFT_COMPAT_RULE_SAVE,
NFT_COMPAT_RULE_ZERO,
NFT_COMPAT_BRIDGE_USER_CHAIN_UPDATE,
NFT_COMPAT_TABLE_NEW,
};
struct cache_chain {
......@@ -135,7 +133,6 @@ int nft_for_each_table(struct nft_handle *h, int (*func)(struct nft_handle *h, c
bool nft_table_find(struct nft_handle *h, const char *tablename);
int nft_table_purge_chains(struct nft_handle *h, const char *table, struct nftnl_chain_list *list);
int nft_table_flush(struct nft_handle *h, const char *table);
void nft_table_new(struct nft_handle *h, const char *table);
const struct builtin_table *nft_table_builtin_find(struct nft_handle *h, const char *table);
/*
......@@ -144,7 +141,7 @@ const struct builtin_table *nft_table_builtin_find(struct nft_handle *h, const c
struct nftnl_chain;
int nft_chain_set(struct nft_handle *h, const char *table, const char *chain, const char *policy, const struct xt_counters *counters);
int nft_chain_save(struct nft_handle *h, struct nftnl_chain_list *list);
int nft_chain_save(struct nftnl_chain *c, void *data);
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_restore(struct nft_handle *h, const char *chain, const char *table);
......
......@@ -4,6 +4,21 @@
TESTDIR="./$(dirname $0)/"
RETURNCODE_SEPARATOR="_"
usage() {
cat <<EOF
Usage: $(basename $0) [-v|--verbose] [-H|--host] [-V|--valgrind]
[[-l|--legacy]|[-n|--nft]] [testscript ...]
-v | --verbose Enable verbose mode (do not drop testscript output).
-H | --host Run tests against installed binaries in \$PATH,
not those built in this source tree.
-V | --valgrind Enable leak checking via valgrind.
-l | --legacy Test legacy variant only. Conflicts with --nft.
-n | --nft Test nft variant only. Conflicts with --legacy.
testscript Run only specific test(s). Implies --verbose.
EOF
}
msg_error() {
echo "E: $1 ..." >&2
exit 1
......@@ -50,6 +65,10 @@ while [ -n "$1" ]; do
VALGRIND=y
shift
;;
-h|--help)
usage
exit 0
;;
*${RETURNCODE_SEPARATOR}+([0-9]))
SINGLE+=" $1"
VERBOSE=y
......
#!/bin/sh
# make sure error return codes are as expected useful cases
# (e.g. commands to check ruleset state)
global_rc=0
cmd() { # (rc, cmd, [args ...])
rc_exp=$1; shift
$XT_MULTI "$@"
rc=$?
[ $rc -eq $rc_exp ] || {
echo "---> expected $rc_exp, got $rc for command '$@'"
global_rc=1
}
}
# test chain creation
cmd 0 ip6tables -N foo
cmd 1 ip6tables -N foo
# iptables-nft allows this - bug or feature?
#cmd 2 ip6tables -N "invalid name"
# test rule adding
cmd 0 ip6tables -A INPUT -j ACCEPT
cmd 1 ip6tables -A noexist -j ACCEPT
cmd 2 ip6tables -I INPUT -j foobar
# test rule checking
cmd 0 ip6tables -C INPUT -j ACCEPT
cmd 1 ip6tables -C FORWARD -j ACCEPT
cmd 1 ip6tables -C nonexist -j ACCEPT
cmd 2 ip6tables -C INPUT -j foobar
cmd 2 ip6tables -C INPUT -m foobar -j ACCEPT
cmd 3 ip6tables -t foobar -C INPUT -j ACCEPT
exit $global_rc
#!/bin/bash
set -e
DUMP="*filter
:foo - [0:0]
:bar - [0:0]
-A foo -j ACCEPT
COMMIT
*nat
:natfoo - [0:0]
:natbar - [0:0]
-A natfoo -j ACCEPT
COMMIT
*raw
:rawfoo - [0:0]
COMMIT
*mangle
:manglefoo - [0:0]
COMMIT
*security
:secfoo - [0:0]
COMMIT
"
$XT_MULTI iptables-restore <<< "$DUMP"
$XT_MULTI ip6tables-restore <<< "$DUMP"
EXPECT="Flushing chain \`INPUT'
Flushing chain \`FORWARD'
Flushing chain \`OUTPUT'
Flushing chain \`bar'
Flushing chain \`foo'
Deleting chain \`bar'
Deleting chain \`foo'
Flushing chain \`PREROUTING'
Flushing chain \`INPUT'
Flushing chain \`OUTPUT'
Flushing chain \`POSTROUTING'
Flushing chain \`natbar'
Flushing chain \`natfoo'
Deleting chain \`natbar'
Deleting chain \`natfoo'
Flushing chain \`PREROUTING'
Flushing chain \`OUTPUT'
Flushing chain \`rawfoo'
Deleting chain \`rawfoo'
Flushing chain \`PREROUTING'
Flushing chain \`INPUT'
Flushing chain \`FORWARD'
Flushing chain \`OUTPUT'
Flushing chain \`POSTROUTING'
Flushing chain \`manglefoo'
Deleting chain \`manglefoo'
Flushing chain \`INPUT'
Flushing chain \`FORWARD'
Flushing chain \`OUTPUT'
Flushing chain \`secfoo'
Deleting chain \`secfoo'"
for ipt in iptables-restore ip6tables-restore; do
diff -u -Z <(sort <<< "$EXPECT") <($XT_MULTI $ipt -v <<< "$DUMP" | sort)
done
DUMP="*filter
:baz - [0:0]
-F foo
-X bar
-A foo -j ACCEPT
COMMIT
"
EXPECT=""
for ipt in iptables-restore ip6tables-restore; do
diff -u -Z <(echo -ne "$EXPECT") <($XT_MULTI $ipt -v --noflush <<< "$DUMP")
done
#!/bin/bash
# test for iptables-restore --noflush skipping an explicitly requested chain
# flush because the chain did not exist when cache was fetched. In order to
# expect for that chain to appear when refreshing the transaction (due to a
# concurrent ruleset change), the chain flush job has to be present in batch
# job list (although disabled at first).
# The input line requesting chain flush is ':FOO - [0:0]'. RS1 and RS2 contents
# are crafted to cause EBUSY when deleting the BAR* chains if FOO is not
# flushed in the same transaction.
set -e
RS="*filter
:INPUT ACCEPT [12024:3123388]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [12840:2144421]
:FOO - [0:0]
:BAR0 - [0:0]
:BAR1 - [0:0]
:BAR2 - [0:0]
:BAR3 - [0:0]
:BAR4 - [0:0]
:BAR5 - [0:0]
:BAR6 - [0:0]
:BAR7 - [0:0]
:BAR8 - [0:0]
:BAR9 - [0:0]
"
RS1="$RS
-X BAR3
-X BAR6
-X BAR9
-A FOO -s 9.9.0.1/32 -j BAR1
-A FOO -s 9.9.0.2/32 -j BAR2
-A FOO -s 9.9.0.4/32 -j BAR4
-A FOO -s 9.9.0.5/32 -j BAR5
-A FOO -s 9.9.0.7/32 -j BAR7
-A FOO -s 9.9.0.8/32 -j BAR8
COMMIT
"
RS2="$RS
-X BAR2
-X BAR5
-X BAR7
-A FOO -s 9.9.0.1/32 -j BAR1
-A FOO -s 9.9.0.3/32 -j BAR3
-A FOO -s 9.9.0.4/32 -j BAR4
-A FOO -s 9.9.0.6/32 -j BAR6
-A FOO -s 9.9.0.8/32 -j BAR8
-A FOO -s 9.9.0.9/32 -j BAR9
COMMIT
"
NORS="*filter
COMMIT
"
for n in $(seq 1 10); do
$XT_MULTI iptables-restore <<< "$NORS"
$XT_MULTI iptables-restore --noflush -w <<< "$RS1" &
$XT_MULTI iptables-restore --noflush -w <<< "$RS2" &
wait -n
wait -n
done
......@@ -13,75 +13,84 @@ cmd() { # (rc, msg, cmd, [args ...])
msg_exp="$1"; shift
}
msg="$($XT_MULTI "$@" 2>&1 >/dev/null)"
rc=$?
for ipt in iptables ip6tables; do
msg="$($XT_MULTI $ipt "$@" 2>&1 >/dev/null)"
rc=$?
[ $rc -eq $rc_exp ] || {
echo "---> expected return code $rc_exp, got $rc for command '$@'"
global_rc=1
}
[ $rc -eq $rc_exp ] || {
echo "---> expected return code $rc_exp, got $rc for command '$ipt $@'"
global_rc=1
}
[ -n "$msg_exp" ] || return
grep -q "$msg_exp" <<< $msg || {
echo "---> expected error message '$msg_exp', got '$msg' for command '$@'"
global_rc=1
}
[ -n "$msg_exp" ] || continue
msg_exp_full="${ipt}$msg_exp"
grep -q "$msg_exp_full" <<< $msg || {
echo "---> expected error message '$msg_exp_full', got '$msg' for command '$ipt $@'"
global_rc=1
}
done
}
EEXIST_F="File exists."
EEXIST="Chain already exists."
ENOENT="No chain/target/match by that name."
E2BIG_I="Index of insertion too big."
E2BIG_D="Index of deletion too big."
E2BIG_R="Index of replacement too big."
EBADRULE="Bad rule (does a matching rule exist in that chain?)."
ENOTGT="Couldn't load target \`foobar':No such file or directory"
ENOMTH="Couldn't load match \`foobar':No such file or directory"
ENOTBL="can't initialize iptables table \`foobar': Table does not exist"
EEXIST_F=": File exists."
EEXIST=": Chain already exists."
ENOENT=": No chain/target/match by that name."
E2BIG_I=": Index of insertion too big."
E2BIG_D=": Index of deletion too big."
E2BIG_R=": Index of replacement too big."
EBADRULE=": Bad rule (does a matching rule exist in that chain?)."
#ENOTGT=" v[0-9\.]* [^ ]*: Couldn't load target \`foobar':No such file or directory"
ENOMTH=" v[0-9\.]* [^ ]*: Couldn't load match \`foobar':No such file or directory"
ENOTBL=": can't initialize iptables table \`foobar': Table does not exist"
# test chain creation
cmd 0 iptables -N foo
cmd 1 "$EEXIST" iptables -N foo
cmd 0 -N foo
cmd 1 "$EEXIST" -N foo
# iptables-nft allows this - bug or feature?
#cmd 2 iptables -N "invalid name"
#cmd 2 -N "invalid name"
# test chain flushing/zeroing
cmd 0 iptables -F foo
cmd 0 iptables -Z foo
cmd 1 "$ENOENT" iptables -F bar
cmd 1 "$ENOENT" iptables -Z bar
cmd 0 -F foo
cmd 0 -Z foo
cmd 1 "$ENOENT" -F bar
cmd 1 "$ENOENT" -Z bar
# test chain rename
cmd 0 iptables -E foo bar
cmd 1 "$EEXIST_F" iptables -E foo bar
cmd 1 "$ENOENT" iptables -E foo bar2
cmd 0 iptables -N foo2
cmd 1 "$EEXIST_F" iptables -E foo2 bar
cmd 0 -E foo bar
cmd 1 "$EEXIST_F" -E foo bar
cmd 1 "$ENOENT" -E foo bar2
cmd 0 -N foo2
cmd 1 "$EEXIST_F" -E foo2 bar
# test rule adding
cmd 0 iptables -A INPUT -j ACCEPT
cmd 1 "$ENOENT" iptables -A noexist -j ACCEPT
cmd 2 "" iptables -I INPUT -j foobar
cmd 2 "" iptables -R INPUT 1 -j foobar
cmd 2 "" iptables -D INPUT -j foobar
cmd 0 -A INPUT -j ACCEPT
cmd 1 "$ENOENT" -A noexist -j ACCEPT
# next three differ:
# legacy: Couldn't load target `foobar':No such file or directory
# nft: Chain 'foobar' does not exist
cmd 2 "" -I INPUT -j foobar
cmd 2 "" -R INPUT 1 -j foobar
cmd 2 "" -D INPUT -j foobar
cmd 1 "$EBADRULE" -D INPUT -p tcp --dport 22 -j ACCEPT
# test rulenum commands
cmd 1 "$E2BIG_I" iptables -I INPUT 23 -j ACCEPT
cmd 1 "$E2BIG_D" iptables -D INPUT 23
cmd 1 "$E2BIG_R" iptables -R INPUT 23 -j ACCEPT
cmd 1 "$ENOENT" iptables -I nonexist 23 -j ACCEPT
cmd 1 "$ENOENT" iptables -D nonexist 23
cmd 1 "$ENOENT" iptables -R nonexist 23 -j ACCEPT
cmd 1 "$E2BIG_I" -I INPUT 23 -j ACCEPT
cmd 1 "$E2BIG_D" -D INPUT 23
cmd 1 "$E2BIG_R" -R INPUT 23 -j ACCEPT
cmd 1 "$ENOENT" -I nonexist 23 -j ACCEPT
cmd 1 "$ENOENT" -D nonexist 23
cmd 1 "$ENOENT" -R nonexist 23 -j ACCEPT
# test rule checking
cmd 0 iptables -C INPUT -j ACCEPT
cmd 1 "$EBADRULE" iptables -C FORWARD -j ACCEPT
cmd 1 "$BADRULE" iptables -C nonexist -j ACCEPT
cmd 2 "$ENOMTH" iptables -C INPUT -m foobar -j ACCEPT
cmd 0 -C INPUT -j ACCEPT
cmd 1 "$EBADRULE" -C FORWARD -j ACCEPT
cmd 1 "$BADRULE" -C nonexist -j ACCEPT
cmd 2 "$ENOMTH" -C INPUT -m foobar -j ACCEPT
# messages of those don't match, but iptables-nft ones are actually nicer.
#cmd 2 "$ENOTGT" iptables -C INPUT -j foobar
#cmd 3 "$ENOTBL" iptables -t foobar -C INPUT -j ACCEPT
cmd 2 "" iptables -C INPUT -j foobar
cmd 3 "" iptables -t foobar -C INPUT -j ACCEPT
# legacy: Couldn't load target `foobar':No such file or directory
# nft: Chain 'foobar' does not exist
cmd 2 "" -C INPUT -j foobar
# legacy: can't initialize ip6tables table `foobar': Table does not exist (do you need to insmod?)
# nft: table 'foobar' does not exist
cmd 3 "" -t foobar -C INPUT -j ACCEPT
exit $global_rc
#!/bin/bash
[[ $XT_MULTI == *xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; }
nft -v >/dev/null || { echo "skip $XT_MULTI (no nft)"; exit 0; }
coproc $XT_MULTI iptables-restore --noflush
cat >&"${COPROC[1]}" <<EOF
*filter
:foo [0:0]
COMMIT
*filter
:foo [0:0]
EOF
$XT_MULTI iptables-save | grep -q ':foo'
nft flush ruleset
echo "COMMIT" >&"${COPROC[1]}"
sleep 1
[[ -n $COPROC_PID ]] && kill $COPROC_PID
wait
#!/bin/bash
[[ $XT_MULTI == *xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; }
set -e
$XT_MULTI iptables -t raw -P OUTPUT DROP
# make sure iptables-nft-restore can correctly handle basechain policies when
# they aren't set with --noflush
#
$XT_MULTI iptables-restore --noflush <<EOF
*raw
:OUTPUT - [0:0]
:PREROUTING - [0:0]
:neutron-linuxbri-OUTPUT - [0:0]
:neutron-linuxbri-PREROUTING - [0:0]
-I OUTPUT 1 -j neutron-linuxbri-OUTPUT
-I PREROUTING 1 -j neutron-linuxbri-PREROUTING
-I neutron-linuxbri-PREROUTING 1 -m physdev --physdev-in brq7425e328-56 -j CT --zone 4097
-I neutron-linuxbri-PREROUTING 2 -i brq7425e328-56 -j CT --zone 4097
-I neutron-linuxbri-PREROUTING 3 -m physdev --physdev-in tap7f101a28-1d -j CT --zone 4097
COMMIT
EOF
$XT_MULTI iptables-save | grep -C2 raw | grep OUTPUT | grep DROP
if [ $? -ne 0 ]; then
exit 1
fi
......@@ -249,15 +249,20 @@ void xs_init_match(struct xtables_match *match)
static int xtables_lock(int wait, struct timeval *wait_interval)
{
struct timeval time_left, wait_time;
const char *lock_file;
int fd, i = 0;
time_left.tv_sec = wait;
time_left.tv_usec = 0;
fd = open(XT_LOCK_NAME, O_CREAT, 0600);
lock_file = getenv("XTABLES_LOCKFILE");
if (lock_file == NULL || lock_file[0] == '\0')
lock_file = XT_LOCK_NAME;
fd = open(lock_file, O_CREAT, 0600);
if (fd < 0) {
fprintf(stderr, "Fatal: can't open lock file %s: %s\n",
XT_LOCK_NAME, strerror(errno));
lock_file, strerror(errno));
return XT_LOCK_FAILED;
}
......@@ -265,7 +270,7 @@ static int xtables_lock(int wait, struct timeval *wait_interval)
if (flock(fd, LOCK_EX) == 0)
return fd;
fprintf(stderr, "Can't lock %s: %s\n", XT_LOCK_NAME,
fprintf(stderr, "Can't lock %s: %s\n", lock_file,
strerror(errno));
return XT_LOCK_BUSY;
}
......
......@@ -1155,7 +1155,7 @@ print_zero:
/*case 7 :*/ /* atomic-init */
/*case 10:*/ /* atomic-save */
case 11: /* init-table */
nft_cmd_table_flush(h, *table);
nft_cmd_table_flush(h, *table, false);
return 1;
/*
replace->command = c;
......
......@@ -93,6 +93,8 @@ static int rule_cb(const struct nlmsghdr *nlh, void *data)
if (arg->nfproto && arg->nfproto != family)
goto err_free;
arg->h->ops = nft_family_ops_lookup(family);
if (arg->is_event)
printf(" EVENT: ");
switch (family) {
......
......@@ -61,7 +61,6 @@ static void print_usage(const char *name, const char *version)
static const struct nft_xt_restore_cb restore_cb = {
.commit = nft_commit,
.abort = nft_abort,
.table_new = nft_cmd_table_new,
.table_flush = nft_cmd_table_flush,
.do_command = do_commandx,
.chain_set = nft_cmd_chain_set,
......@@ -135,7 +134,7 @@ static void xtables_restore_parse_line(struct nft_handle *h,
if (h->noflush == 0) {
DEBUGP("Cleaning all chains of table '%s'\n", table);
if (cb->table_flush)
cb->table_flush(h, table);
cb->table_flush(h, table, verbose);
}
ret = 1;
......@@ -260,7 +259,7 @@ void xtables_restore_parse(struct nft_handle *h,
struct nft_xt_restore_state state = {};
char buffer[10240] = {};
if (!h->noflush)
if (!verbose && !h->noflush)
nft_cache_level_set(h, NFT_CL_FAKE, NULL);
line = 0;
......@@ -410,7 +409,6 @@ int xtables_ip6_restore_main(int argc, char *argv[])
static const struct nft_xt_restore_cb ebt_restore_cb = {
.commit = nft_bridge_commit,
.table_new = nft_cmd_table_new,
.table_flush = nft_cmd_table_flush,
.do_command = do_commandeb,
.chain_set = nft_cmd_chain_set,
......@@ -456,7 +454,6 @@ int xtables_eb_restore_main(int argc, char *argv[])
static const struct nft_xt_restore_cb arp_restore_cb = {
.commit = nft_commit,
.table_new = nft_cmd_table_new,
.table_flush = nft_cmd_table_flush,
.do_command = do_commandarp,
.chain_set = nft_cmd_chain_set,
......
......@@ -92,7 +92,7 @@ __do_output(struct nft_handle *h, const char *tablename, void *data)
printf("*%s\n", tablename);
/* Dump out chain names first,
* thereby preventing dependency conflicts */
nft_chain_save(h, chain_list);
nftnl_chain_list_foreach(chain_list, nft_chain_save, h);
nft_rule_save(h, tablename, d->format);
if (d->commit)
printf("COMMIT\n");
......
......@@ -75,14 +75,10 @@ xtables_main(int family, const char *progname, int argc, char *argv[])
xtables_fini();
if (!ret) {
if (errno == EINVAL) {
fprintf(stderr, "iptables: %s. "
"Run `dmesg' for more information.\n",
nft_strerror(errno));
} else {
fprintf(stderr, "iptables: %s.\n",
nft_strerror(errno));
}
fprintf(stderr, "%s: %s.%s\n", progname, nft_strerror(errno),
(errno == EINVAL ?
" Run `dmesg' for more information." : ""));
if (errno == EAGAIN)
exit(RESOURCE_PROBLEM);
}
......
......@@ -249,7 +249,7 @@ static int do_command_xlate(struct nft_handle *h, int argc, char *argv[],
cs.restore = restore;
if (!restore)
if (!restore && p.command != CMD_NONE)
printf("nft ");
switch (p.command) {
......@@ -310,13 +310,16 @@ static int do_command_xlate(struct nft_handle *h, int argc, char *argv[],
break;
case CMD_SET_POLICY:
break;
case CMD_NONE:
ret = 1;
break;
default:
/* We should never reach this... */
printf("Unsupported command?\n");
exit(1);
}
xtables_rule_matches_free(&cs.matches);
nft_clear_iptables_command_state(&cs);
if (h->family == AF_INET) {
free(args.s.addr.v4);
......
......@@ -275,6 +275,7 @@ SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
XT_LOCK_NAME = @XT_LOCK_NAME@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
......
......@@ -282,6 +282,7 @@ SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
XT_LOCK_NAME = @XT_LOCK_NAME@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
......
......@@ -1169,7 +1169,7 @@ static int iptcc_compile_chain(struct xtc_handle *h, STRUCT_REPLACE *repl, struc
else
foot->target.verdict = RETURN;
/* set policy-counters */
memcpy(&foot->e.counters, &c->counters, sizeof(STRUCT_COUNTERS));
foot->e.counters = c->counters;
return 0;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment