* [nf_tables PATCH v2 0/5] Series short description
@ 2014-08-26 14:11 Arturo Borrero Gonzalez
2014-08-26 14:12 ` [nf_tables PATCH v2 1/5] netfilter: nf_tables: refactor rule deletion helper Arturo Borrero Gonzalez
` (4 more replies)
0 siblings, 5 replies; 7+ messages in thread
From: Arturo Borrero Gonzalez @ 2014-08-26 14:11 UTC (permalink / raw)
To: netfilter-devel; +Cc: kaber, pablo
The following series implements some changes to the NFT_MSG_DELTABLE
API call.
The main change is the ability to flush the entire ruleset (also per AF).
We are no longer returning EBUSY.
This way, clients of the API can wipe the ruleset and add a new one in just
one transaction/batch.
In the first patches, there are a lot of code factorization and renaming.
The last patch is the change to NFT_MSG_DELTABLE itself.
Changes in this v2 are:
* rebase on top of git.kernel.org/cgit/linux/kernel/git/pablo/nftables.git
* address comments by Pablo. Now, support AF_UNSPEC and specified table.
Comments are welcome.
---
Arturo Borrero Gonzalez (5):
netfilter: nf_tables: refactor rule deletion helper
netfilter: nf_tables: add helper to unregister chain hooks
netfilter: nf_tables: rename nf_table_delrule_by_chain()
netfilter: nf_tables: add helpers to schedule objects deletion
netfilter: nf_tables: extend NFT_MSG_DELTABLE to support flushing the ruleset
net/netfilter/nf_tables_api.c | 454 +++++++++++++++++++++++++----------------
1 file changed, 281 insertions(+), 173 deletions(-)
--
Arturo Borrero Gonzalez
^ permalink raw reply [flat|nested] 7+ messages in thread
* [nf_tables PATCH v2 1/5] netfilter: nf_tables: refactor rule deletion helper
2014-08-26 14:11 [nf_tables PATCH v2 0/5] Series short description Arturo Borrero Gonzalez
@ 2014-08-26 14:12 ` Arturo Borrero Gonzalez
2014-08-26 14:40 ` Patrick McHardy
2014-08-26 14:12 ` [nf_tables PATCH v2 2/5] netfilter: nf_tables: add helper to unregister chain hooks Arturo Borrero Gonzalez
` (3 subsequent siblings)
4 siblings, 1 reply; 7+ messages in thread
From: Arturo Borrero Gonzalez @ 2014-08-26 14:12 UTC (permalink / raw)
To: netfilter-devel; +Cc: kaber, pablo
This helper function always schedule the rule to be removed in the following
transaction.
In follow-up patches, it is interesting to handle separately the logic of rule
activation/disactivation from the transaction mechanism.
So, this patch simply splits the original nf_tables_delrule_one() in two
functions, allowing further control.
While at it, for the sake of homigeneize the function naming scheme, let's
rename nf_tables_delrule_one() to nft_delrule().
Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
---
v2: no changes, resending the series.
net/netfilter/nf_tables_api.c | 26 +++++++++++++++++++++-----
1 file changed, 21 insertions(+), 5 deletions(-)
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index deeb95f..d1535d8 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -1868,12 +1868,10 @@ err1:
}
static int
-nf_tables_delrule_one(struct nft_ctx *ctx, struct nft_rule *rule)
+nf_tables_delrule_disactivate(struct nft_ctx *ctx, struct nft_rule *rule)
{
/* You cannot delete the same rule twice */
if (nft_rule_is_active_next(ctx->net, rule)) {
- if (nft_trans_rule_add(ctx, NFT_MSG_DELRULE, rule) == NULL)
- return -ENOMEM;
nft_rule_disactivate_next(ctx->net, rule);
ctx->chain->use--;
return 0;
@@ -1881,13 +1879,31 @@ nf_tables_delrule_one(struct nft_ctx *ctx, struct nft_rule *rule)
return -ENOENT;
}
+static int nft_delrule(struct nft_ctx *ctx, struct nft_rule *rule)
+{
+ struct nft_trans *trans;
+ int err;
+
+ trans = nft_trans_rule_add(ctx, NFT_MSG_DELRULE, rule);
+ if (trans == NULL)
+ return -ENOMEM;
+
+ err = nf_tables_delrule_disactivate(ctx, rule);
+ if (err < 0) {
+ nft_trans_destroy(trans);
+ return err;
+ }
+
+ return 0;
+}
+
static int nf_table_delrule_by_chain(struct nft_ctx *ctx)
{
struct nft_rule *rule;
int err;
list_for_each_entry(rule, &ctx->chain->rules, list) {
- err = nf_tables_delrule_one(ctx, rule);
+ err = nft_delrule(ctx, rule);
if (err < 0)
return err;
}
@@ -1932,7 +1948,7 @@ static int nf_tables_delrule(struct sock *nlsk, struct sk_buff *skb,
if (IS_ERR(rule))
return PTR_ERR(rule);
- err = nf_tables_delrule_one(&ctx, rule);
+ err = nft_delrule(&ctx, rule);
} else {
err = nf_table_delrule_by_chain(&ctx);
}
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [nf_tables PATCH v2 2/5] netfilter: nf_tables: add helper to unregister chain hooks
2014-08-26 14:11 [nf_tables PATCH v2 0/5] Series short description Arturo Borrero Gonzalez
2014-08-26 14:12 ` [nf_tables PATCH v2 1/5] netfilter: nf_tables: refactor rule deletion helper Arturo Borrero Gonzalez
@ 2014-08-26 14:12 ` Arturo Borrero Gonzalez
2014-08-26 14:13 ` [nf_tables PATCH v2 3/5] netfilter: nf_tables: rename nf_table_delrule_by_chain() Arturo Borrero Gonzalez
` (2 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: Arturo Borrero Gonzalez @ 2014-08-26 14:12 UTC (permalink / raw)
To: netfilter-devel; +Cc: kaber, pablo
This patch adds a helper function to unregister chain hooks in the chain
deletion path. Basically, a code factorization.
The new function is useful in follow-up patches.
Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
---
v2: rebased.
net/netfilter/nf_tables_api.c | 31 ++++++++++++++++---------------
1 file changed, 16 insertions(+), 15 deletions(-)
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index d1535d8..0b35f52 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -127,6 +127,15 @@ static void nft_trans_destroy(struct nft_trans *trans)
kfree(trans);
}
+static void nf_tables_unregister_hooks(const struct nft_table *table,
+ const struct nft_chain *chain,
+ unsigned int hook_nops)
+{
+ if (!(table->flags & NFT_TABLE_F_DORMANT) &&
+ chain->flags & NFT_BASE_CHAIN)
+ nf_unregister_hooks(nft_base_chain(chain)->ops, hook_nops);
+}
+
/*
* Tables
*/
@@ -1157,11 +1166,7 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
list_add_tail_rcu(&chain->list, &table->chains);
return 0;
err2:
- if (!(table->flags & NFT_TABLE_F_DORMANT) &&
- chain->flags & NFT_BASE_CHAIN) {
- nf_unregister_hooks(nft_base_chain(chain)->ops,
- afi->nops);
- }
+ nf_tables_unregister_hooks(table, chain, afi->nops);
err1:
nf_tables_chain_destroy(chain);
return err;
@@ -3368,11 +3373,9 @@ static int nf_tables_commit(struct sk_buff *skb)
break;
case NFT_MSG_DELCHAIN:
nf_tables_chain_notify(&trans->ctx, NFT_MSG_DELCHAIN);
- if (!(trans->ctx.table->flags & NFT_TABLE_F_DORMANT) &&
- trans->ctx.chain->flags & NFT_BASE_CHAIN) {
- nf_unregister_hooks(nft_base_chain(trans->ctx.chain)->ops,
- trans->ctx.afi->nops);
- }
+ nf_tables_unregister_hooks(trans->ctx.table,
+ trans->ctx.chain,
+ trans->ctx.afi->nops);
break;
case NFT_MSG_NEWRULE:
nft_rule_clear(trans->ctx.net, nft_trans_rule(trans));
@@ -3495,11 +3498,9 @@ static int nf_tables_abort(struct sk_buff *skb)
} else {
trans->ctx.table->use--;
list_del_rcu(&trans->ctx.chain->list);
- if (!(trans->ctx.table->flags & NFT_TABLE_F_DORMANT) &&
- trans->ctx.chain->flags & NFT_BASE_CHAIN) {
- nf_unregister_hooks(nft_base_chain(trans->ctx.chain)->ops,
- trans->ctx.afi->nops);
- }
+ nf_tables_unregister_hooks(trans->ctx.table,
+ trans->ctx.chain,
+ trans->ctx.afi->nops);
}
break;
case NFT_MSG_DELCHAIN:
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [nf_tables PATCH v2 3/5] netfilter: nf_tables: rename nf_table_delrule_by_chain()
2014-08-26 14:11 [nf_tables PATCH v2 0/5] Series short description Arturo Borrero Gonzalez
2014-08-26 14:12 ` [nf_tables PATCH v2 1/5] netfilter: nf_tables: refactor rule deletion helper Arturo Borrero Gonzalez
2014-08-26 14:12 ` [nf_tables PATCH v2 2/5] netfilter: nf_tables: add helper to unregister chain hooks Arturo Borrero Gonzalez
@ 2014-08-26 14:13 ` Arturo Borrero Gonzalez
2014-08-26 14:14 ` [nf_tables PATCH v2 4/5] netfilter: nf_tables: add helpers to schedule objects deletion Arturo Borrero Gonzalez
2014-08-26 14:15 ` [nf_tables PATCH v2 5/5] netfilter: nf_tables: extend NFT_MSG_DELTABLE to support flushing the ruleset Arturo Borrero Gonzalez
4 siblings, 0 replies; 7+ messages in thread
From: Arturo Borrero Gonzalez @ 2014-08-26 14:13 UTC (permalink / raw)
To: netfilter-devel; +Cc: kaber, pablo
For the sake of homogenize the function naming scheme, let's rename
nf_table_delrule_by_chain() to nft_delrule_by_chain().
Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
---
v2: no changes, resending the series.
net/netfilter/nf_tables_api.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 0b35f52..2b71fe1 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -1902,7 +1902,7 @@ static int nft_delrule(struct nft_ctx *ctx, struct nft_rule *rule)
return 0;
}
-static int nf_table_delrule_by_chain(struct nft_ctx *ctx)
+static int nft_delrule_by_chain(struct nft_ctx *ctx)
{
struct nft_rule *rule;
int err;
@@ -1955,12 +1955,12 @@ static int nf_tables_delrule(struct sock *nlsk, struct sk_buff *skb,
err = nft_delrule(&ctx, rule);
} else {
- err = nf_table_delrule_by_chain(&ctx);
+ err = nft_delrule_by_chain(&ctx);
}
} else {
list_for_each_entry(chain, &table->chains, list) {
ctx.chain = chain;
- err = nf_table_delrule_by_chain(&ctx);
+ err = nft_delrule_by_chain(&ctx);
if (err < 0)
break;
}
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [nf_tables PATCH v2 4/5] netfilter: nf_tables: add helpers to schedule objects deletion
2014-08-26 14:11 [nf_tables PATCH v2 0/5] Series short description Arturo Borrero Gonzalez
` (2 preceding siblings ...)
2014-08-26 14:13 ` [nf_tables PATCH v2 3/5] netfilter: nf_tables: rename nf_table_delrule_by_chain() Arturo Borrero Gonzalez
@ 2014-08-26 14:14 ` Arturo Borrero Gonzalez
2014-08-26 14:15 ` [nf_tables PATCH v2 5/5] netfilter: nf_tables: extend NFT_MSG_DELTABLE to support flushing the ruleset Arturo Borrero Gonzalez
4 siblings, 0 replies; 7+ messages in thread
From: Arturo Borrero Gonzalez @ 2014-08-26 14:14 UTC (permalink / raw)
To: netfilter-devel; +Cc: kaber, pablo
This patch refactor the code to schedule objects deletion.
They are useful in follow-up patches.
In order to be able to use these new helper functions in all the code,
they are placed in the top of the file, with all the dependant functions
and symbols.
Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
---
v2: rebased: now, nft_del*() functions use list_del_rcu().
net/netfilter/nf_tables_api.c | 361 ++++++++++++++++++++++-------------------
1 file changed, 193 insertions(+), 168 deletions(-)
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 2b71fe1..806ad7e 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -136,6 +136,195 @@ static void nf_tables_unregister_hooks(const struct nft_table *table,
nf_unregister_hooks(nft_base_chain(chain)->ops, hook_nops);
}
+/* Internal table flags */
+#define NFT_TABLE_INACTIVE (1 << 15)
+
+static int nft_trans_table_add(struct nft_ctx *ctx, int msg_type)
+{
+ struct nft_trans *trans;
+
+ trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_table));
+ if (trans == NULL)
+ return -ENOMEM;
+
+ if (msg_type == NFT_MSG_NEWTABLE)
+ ctx->table->flags |= NFT_TABLE_INACTIVE;
+
+ list_add_tail(&trans->list, &ctx->net->nft.commit_list);
+ return 0;
+}
+
+static int nft_deltable(struct nft_ctx *ctx)
+{
+ int err;
+
+ err = nft_trans_table_add(ctx, NFT_MSG_DELTABLE);
+ if (err < 0)
+ return err;
+
+ list_del_rcu(&ctx->table->list);
+ return err;
+}
+
+static int nft_trans_chain_add(struct nft_ctx *ctx, int msg_type)
+{
+ struct nft_trans *trans;
+
+ trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_chain));
+ if (trans == NULL)
+ return -ENOMEM;
+
+ if (msg_type == NFT_MSG_NEWCHAIN)
+ ctx->chain->flags |= NFT_CHAIN_INACTIVE;
+
+ list_add_tail(&trans->list, &ctx->net->nft.commit_list);
+ return 0;
+}
+
+static int nft_delchain(struct nft_ctx *ctx)
+{
+ int err;
+
+ err = nft_trans_chain_add(ctx, NFT_MSG_DELCHAIN);
+ if (err < 0)
+ return err;
+
+ ctx->table->use--;
+ list_del_rcu(&ctx->chain->list);
+
+ return err;
+}
+
+static inline bool
+nft_rule_is_active(struct net *net, const struct nft_rule *rule)
+{
+ return (rule->genmask & (1 << net->nft.gencursor)) == 0;
+}
+
+static inline int gencursor_next(struct net *net)
+{
+ return net->nft.gencursor+1 == 1 ? 1 : 0;
+}
+
+static inline int
+nft_rule_is_active_next(struct net *net, const struct nft_rule *rule)
+{
+ return (rule->genmask & (1 << gencursor_next(net))) == 0;
+}
+
+static inline void
+nft_rule_activate_next(struct net *net, struct nft_rule *rule)
+{
+ /* Now inactive, will be active in the future */
+ rule->genmask = (1 << net->nft.gencursor);
+}
+
+static inline void
+nft_rule_disactivate_next(struct net *net, struct nft_rule *rule)
+{
+ rule->genmask = (1 << gencursor_next(net));
+}
+
+static inline void nft_rule_clear(struct net *net, struct nft_rule *rule)
+{
+ rule->genmask = 0;
+}
+
+static int
+nf_tables_delrule_disactivate(struct nft_ctx *ctx, struct nft_rule *rule)
+{
+ /* You cannot delete the same rule twice */
+ if (nft_rule_is_active_next(ctx->net, rule)) {
+ nft_rule_disactivate_next(ctx->net, rule);
+ ctx->chain->use--;
+ return 0;
+ }
+ return -ENOENT;
+}
+
+static struct nft_trans *nft_trans_rule_add(struct nft_ctx *ctx, int msg_type,
+ struct nft_rule *rule)
+{
+ struct nft_trans *trans;
+
+ trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_rule));
+ if (trans == NULL)
+ return NULL;
+
+ nft_trans_rule(trans) = rule;
+ list_add_tail(&trans->list, &ctx->net->nft.commit_list);
+
+ return trans;
+}
+
+static int nft_delrule(struct nft_ctx *ctx, struct nft_rule *rule)
+{
+ struct nft_trans *trans;
+ int err;
+
+ trans = nft_trans_rule_add(ctx, NFT_MSG_DELRULE, rule);
+ if (trans == NULL)
+ return -ENOMEM;
+
+ err = nf_tables_delrule_disactivate(ctx, rule);
+ if (err < 0) {
+ nft_trans_destroy(trans);
+ return err;
+ }
+
+ return 0;
+}
+
+static int nft_delrule_by_chain(struct nft_ctx *ctx)
+{
+ struct nft_rule *rule;
+ int err;
+
+ list_for_each_entry(rule, &ctx->chain->rules, list) {
+ err = nft_delrule(ctx, rule);
+ if (err < 0)
+ return err;
+ }
+ return 0;
+}
+
+/* Internal set flag */
+#define NFT_SET_INACTIVE (1 << 15)
+
+static int nft_trans_set_add(struct nft_ctx *ctx, int msg_type,
+ struct nft_set *set)
+{
+ struct nft_trans *trans;
+
+ trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_set));
+ if (trans == NULL)
+ return -ENOMEM;
+
+ if (msg_type == NFT_MSG_NEWSET && ctx->nla[NFTA_SET_ID] != NULL) {
+ nft_trans_set_id(trans) =
+ ntohl(nla_get_be32(ctx->nla[NFTA_SET_ID]));
+ set->flags |= NFT_SET_INACTIVE;
+ }
+ nft_trans_set(trans) = set;
+ list_add_tail(&trans->list, &ctx->net->nft.commit_list);
+
+ return 0;
+}
+
+static int nft_delset(struct nft_ctx *ctx, struct nft_set *set)
+{
+ int err;
+
+ err = nft_trans_set_add(ctx, NFT_MSG_DELSET, set);
+ if (err < 0)
+ return err;
+
+ list_del_rcu(&set->list);
+ ctx->table->use--;
+
+ return err;
+}
+
/*
* Tables
*/
@@ -318,9 +507,6 @@ done:
return skb->len;
}
-/* Internal table flags */
-#define NFT_TABLE_INACTIVE (1 << 15)
-
static int nf_tables_gettable(struct sock *nlsk, struct sk_buff *skb,
const struct nlmsghdr *nlh,
const struct nlattr * const nla[])
@@ -452,21 +638,6 @@ err:
return ret;
}
-static int nft_trans_table_add(struct nft_ctx *ctx, int msg_type)
-{
- struct nft_trans *trans;
-
- trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_table));
- if (trans == NULL)
- return -ENOMEM;
-
- if (msg_type == NFT_MSG_NEWTABLE)
- ctx->table->flags |= NFT_TABLE_INACTIVE;
-
- list_add_tail(&trans->list, &ctx->net->nft.commit_list);
- return 0;
-}
-
static int nf_tables_newtable(struct sock *nlsk, struct sk_buff *skb,
const struct nlmsghdr *nlh,
const struct nlattr * const nla[])
@@ -544,7 +715,7 @@ static int nf_tables_deltable(struct sock *nlsk, struct sk_buff *skb,
struct nft_af_info *afi;
struct nft_table *table;
struct net *net = sock_net(skb->sk);
- int family = nfmsg->nfgen_family, err;
+ int family = nfmsg->nfgen_family;
struct nft_ctx ctx;
afi = nf_tables_afinfo_lookup(net, family, false);
@@ -560,12 +731,8 @@ static int nf_tables_deltable(struct sock *nlsk, struct sk_buff *skb,
return -EBUSY;
nft_ctx_init(&ctx, skb, nlh, afi, table, NULL, nla);
- err = nft_trans_table_add(&ctx, NFT_MSG_DELTABLE);
- if (err < 0)
- return err;
- list_del_rcu(&table->list);
- return 0;
+ return nft_deltable(&ctx);
}
static void nf_tables_table_destroy(struct nft_ctx *ctx)
@@ -922,21 +1089,6 @@ static void nft_chain_stats_replace(struct nft_base_chain *chain,
rcu_assign_pointer(chain->stats, newstats);
}
-static int nft_trans_chain_add(struct nft_ctx *ctx, int msg_type)
-{
- struct nft_trans *trans;
-
- trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_chain));
- if (trans == NULL)
- return -ENOMEM;
-
- if (msg_type == NFT_MSG_NEWCHAIN)
- ctx->chain->flags |= NFT_CHAIN_INACTIVE;
-
- list_add_tail(&trans->list, &ctx->net->nft.commit_list);
- return 0;
-}
-
static void nf_tables_chain_destroy(struct nft_chain *chain)
{
BUG_ON(chain->use > 0);
@@ -1183,7 +1335,6 @@ static int nf_tables_delchain(struct sock *nlsk, struct sk_buff *skb,
struct net *net = sock_net(skb->sk);
int family = nfmsg->nfgen_family;
struct nft_ctx ctx;
- int err;
afi = nf_tables_afinfo_lookup(net, family, false);
if (IS_ERR(afi))
@@ -1204,13 +1355,8 @@ static int nf_tables_delchain(struct sock *nlsk, struct sk_buff *skb,
return -EBUSY;
nft_ctx_init(&ctx, skb, nlh, afi, table, chain, nla);
- err = nft_trans_chain_add(&ctx, NFT_MSG_DELCHAIN);
- if (err < 0)
- return err;
- table->use--;
- list_del_rcu(&chain->list);
- return 0;
+ return nft_delchain(&ctx);
}
/*
@@ -1532,41 +1678,6 @@ err:
return err;
}
-static inline bool
-nft_rule_is_active(struct net *net, const struct nft_rule *rule)
-{
- return (rule->genmask & (1 << net->nft.gencursor)) == 0;
-}
-
-static inline int gencursor_next(struct net *net)
-{
- return net->nft.gencursor+1 == 1 ? 1 : 0;
-}
-
-static inline int
-nft_rule_is_active_next(struct net *net, const struct nft_rule *rule)
-{
- return (rule->genmask & (1 << gencursor_next(net))) == 0;
-}
-
-static inline void
-nft_rule_activate_next(struct net *net, struct nft_rule *rule)
-{
- /* Now inactive, will be active in the future */
- rule->genmask = (1 << net->nft.gencursor);
-}
-
-static inline void
-nft_rule_disactivate_next(struct net *net, struct nft_rule *rule)
-{
- rule->genmask = (1 << gencursor_next(net));
-}
-
-static inline void nft_rule_clear(struct net *net, struct nft_rule *rule)
-{
- rule->genmask = 0;
-}
-
static int nf_tables_dump_rules(struct sk_buff *skb,
struct netlink_callback *cb)
{
@@ -1692,21 +1803,6 @@ static void nf_tables_rule_destroy(const struct nft_ctx *ctx,
kfree(rule);
}
-static struct nft_trans *nft_trans_rule_add(struct nft_ctx *ctx, int msg_type,
- struct nft_rule *rule)
-{
- struct nft_trans *trans;
-
- trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_rule));
- if (trans == NULL)
- return NULL;
-
- nft_trans_rule(trans) = rule;
- list_add_tail(&trans->list, &ctx->net->nft.commit_list);
-
- return trans;
-}
-
#define NFT_RULE_MAXEXPRS 128
static struct nft_expr_info *info;
@@ -1872,49 +1968,6 @@ err1:
return err;
}
-static int
-nf_tables_delrule_disactivate(struct nft_ctx *ctx, struct nft_rule *rule)
-{
- /* You cannot delete the same rule twice */
- if (nft_rule_is_active_next(ctx->net, rule)) {
- nft_rule_disactivate_next(ctx->net, rule);
- ctx->chain->use--;
- return 0;
- }
- return -ENOENT;
-}
-
-static int nft_delrule(struct nft_ctx *ctx, struct nft_rule *rule)
-{
- struct nft_trans *trans;
- int err;
-
- trans = nft_trans_rule_add(ctx, NFT_MSG_DELRULE, rule);
- if (trans == NULL)
- return -ENOMEM;
-
- err = nf_tables_delrule_disactivate(ctx, rule);
- if (err < 0) {
- nft_trans_destroy(trans);
- return err;
- }
-
- return 0;
-}
-
-static int nft_delrule_by_chain(struct nft_ctx *ctx)
-{
- struct nft_rule *rule;
- int err;
-
- list_for_each_entry(rule, &ctx->chain->rules, list) {
- err = nft_delrule(ctx, rule);
- if (err < 0)
- return err;
- }
- return 0;
-}
-
static int nf_tables_delrule(struct sock *nlsk, struct sk_buff *skb,
const struct nlmsghdr *nlh,
const struct nlattr * const nla[])
@@ -2343,8 +2396,6 @@ static int nf_tables_dump_sets_done(struct netlink_callback *cb)
return 0;
}
-#define NFT_SET_INACTIVE (1 << 15) /* Internal set flag */
-
static int nf_tables_getset(struct sock *nlsk, struct sk_buff *skb,
const struct nlmsghdr *nlh,
const struct nlattr * const nla[])
@@ -2419,26 +2470,6 @@ static int nf_tables_set_desc_parse(const struct nft_ctx *ctx,
return 0;
}
-static int nft_trans_set_add(struct nft_ctx *ctx, int msg_type,
- struct nft_set *set)
-{
- struct nft_trans *trans;
-
- trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_set));
- if (trans == NULL)
- return -ENOMEM;
-
- if (msg_type == NFT_MSG_NEWSET && ctx->nla[NFTA_SET_ID] != NULL) {
- nft_trans_set_id(trans) =
- ntohl(nla_get_be32(ctx->nla[NFTA_SET_ID]));
- set->flags |= NFT_SET_INACTIVE;
- }
- nft_trans_set(trans) = set;
- list_add_tail(&trans->list, &ctx->net->nft.commit_list);
-
- return 0;
-}
-
static int nf_tables_newset(struct sock *nlsk, struct sk_buff *skb,
const struct nlmsghdr *nlh,
const struct nlattr * const nla[])
@@ -2632,13 +2663,7 @@ static int nf_tables_delset(struct sock *nlsk, struct sk_buff *skb,
if (!list_empty(&set->bindings))
return -EBUSY;
- err = nft_trans_set_add(&ctx, NFT_MSG_DELSET, set);
- if (err < 0)
- return err;
-
- list_del_rcu(&set->list);
- ctx.table->use--;
- return 0;
+ return nft_delset(&ctx, set);
}
static int nf_tables_bind_check_setelem(const struct nft_ctx *ctx,
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [nf_tables PATCH v2 5/5] netfilter: nf_tables: extend NFT_MSG_DELTABLE to support flushing the ruleset
2014-08-26 14:11 [nf_tables PATCH v2 0/5] Series short description Arturo Borrero Gonzalez
` (3 preceding siblings ...)
2014-08-26 14:14 ` [nf_tables PATCH v2 4/5] netfilter: nf_tables: add helpers to schedule objects deletion Arturo Borrero Gonzalez
@ 2014-08-26 14:15 ` Arturo Borrero Gonzalez
4 siblings, 0 replies; 7+ messages in thread
From: Arturo Borrero Gonzalez @ 2014-08-26 14:15 UTC (permalink / raw)
To: netfilter-devel; +Cc: kaber, pablo
This patch extend the NFT_MSG_DELTABLE call to support flushing the entire
ruleset.
The options now are:
* No family speficied, no table specified: flush all the ruleset.
* Family specified, no table specified: flush all tables in the AF.
* Family specified, table specified: flush the given table.
Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
---
v2: address comments by Pablo:
* don't return EINVAL if called with AF_UNSPEC and a concrete table.
* A more generic function, nft_flush()
net/netfilter/nf_tables_api.c | 74 +++++++++++++++++++++++++++++++++++++++--
1 file changed, 70 insertions(+), 4 deletions(-)
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 806ad7e..b3963cf 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -707,6 +707,68 @@ static int nf_tables_newtable(struct sock *nlsk, struct sk_buff *skb,
return 0;
}
+static int nft_flush_table(struct nft_ctx *ctx)
+{
+ int err;
+ struct nft_chain *chain, *nc;
+ struct nft_set *set, *ns;
+
+ list_for_each_entry_safe(chain, nc, &ctx->table->chains, list) {
+ ctx->chain = chain;
+
+ err = nft_delrule_by_chain(ctx);
+ if (err < 0)
+ goto out;
+
+ err = nft_delchain(ctx);
+ if (err < 0)
+ goto out;
+ }
+
+ list_for_each_entry_safe(set, ns, &ctx->table->sets, list) {
+ if (set->flags & NFT_SET_ANONYMOUS)
+ continue;
+
+ err = nft_delset(ctx, set);
+ if (err < 0)
+ goto out;
+ }
+
+ err = nft_deltable(ctx);
+out:
+ return err;
+}
+
+static int nft_flush(struct nft_ctx *ctx, int family)
+{
+ struct nft_af_info *afi;
+ struct nft_table *table, *nt;
+ const struct nlattr * const *nla = ctx->nla;
+ int err = 0;
+
+ list_for_each_entry(afi, &ctx->net->nft.af_info, list) {
+ if (family != AF_UNSPEC && afi->family != family)
+ continue;
+
+ ctx->afi = afi;
+
+ list_for_each_entry_safe(table, nt, &afi->tables, list) {
+ if (nla[NFTA_TABLE_NAME] &&
+ nla_strcmp(nla[NFTA_TABLE_NAME], table->name) != 0)
+ continue;
+
+ ctx->table = table;
+
+ err = nft_flush_table(ctx);
+ if (err < 0)
+ goto out;
+ }
+ }
+
+out:
+ return err;
+}
+
static int nf_tables_deltable(struct sock *nlsk, struct sk_buff *skb,
const struct nlmsghdr *nlh,
const struct nlattr * const nla[])
@@ -718,6 +780,11 @@ static int nf_tables_deltable(struct sock *nlsk, struct sk_buff *skb,
int family = nfmsg->nfgen_family;
struct nft_ctx ctx;
+ nft_ctx_init(&ctx, skb, nlh, NULL, NULL, NULL, nla);
+ if (family == AF_UNSPEC || nla[NFTA_TABLE_NAME] == NULL)
+ return nft_flush(&ctx, family);
+
+
afi = nf_tables_afinfo_lookup(net, family, false);
if (IS_ERR(afi))
return PTR_ERR(afi);
@@ -727,12 +794,11 @@ static int nf_tables_deltable(struct sock *nlsk, struct sk_buff *skb,
return PTR_ERR(table);
if (table->flags & NFT_TABLE_INACTIVE)
return -ENOENT;
- if (table->use > 0)
- return -EBUSY;
- nft_ctx_init(&ctx, skb, nlh, afi, table, NULL, nla);
+ ctx.afi = afi;
+ ctx.table = table;
- return nft_deltable(&ctx);
+ return nft_flush_table(&ctx);
}
static void nf_tables_table_destroy(struct nft_ctx *ctx)
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [nf_tables PATCH v2 1/5] netfilter: nf_tables: refactor rule deletion helper
2014-08-26 14:12 ` [nf_tables PATCH v2 1/5] netfilter: nf_tables: refactor rule deletion helper Arturo Borrero Gonzalez
@ 2014-08-26 14:40 ` Patrick McHardy
0 siblings, 0 replies; 7+ messages in thread
From: Patrick McHardy @ 2014-08-26 14:40 UTC (permalink / raw)
To: Arturo Borrero Gonzalez; +Cc: netfilter-devel, pablo
On Tue, Aug 26, 2014 at 04:12:22PM +0200, Arturo Borrero Gonzalez wrote:
> This helper function always schedule the rule to be removed in the following
> transaction.
> In follow-up patches, it is interesting to handle separately the logic of rule
> activation/disactivation from the transaction mechanism.
>
> So, this patch simply splits the original nf_tables_delrule_one() in two
> functions, allowing further control.
>
> While at it, for the sake of homigeneize the function naming scheme, let's
> rename nf_tables_delrule_one() to nft_delrule().
>
> Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
> ---
> v2: no changes, resending the series.
>
> net/netfilter/nf_tables_api.c | 26 +++++++++++++++++++++-----
> 1 file changed, 21 insertions(+), 5 deletions(-)
>
> diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
> index deeb95f..d1535d8 100644
> --- a/net/netfilter/nf_tables_api.c
> +++ b/net/netfilter/nf_tables_api.c
> @@ -1868,12 +1868,10 @@ err1:
> }
>
> static int
> -nf_tables_delrule_one(struct nft_ctx *ctx, struct nft_rule *rule)
> +nf_tables_delrule_disactivate(struct nft_ctx *ctx, struct nft_rule *rule)
Without any further review so far, this grammatical error has disturbed me for
a while now :) Please don't spread it further, its called deactivate.
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2014-08-26 14:40 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-08-26 14:11 [nf_tables PATCH v2 0/5] Series short description Arturo Borrero Gonzalez
2014-08-26 14:12 ` [nf_tables PATCH v2 1/5] netfilter: nf_tables: refactor rule deletion helper Arturo Borrero Gonzalez
2014-08-26 14:40 ` Patrick McHardy
2014-08-26 14:12 ` [nf_tables PATCH v2 2/5] netfilter: nf_tables: add helper to unregister chain hooks Arturo Borrero Gonzalez
2014-08-26 14:13 ` [nf_tables PATCH v2 3/5] netfilter: nf_tables: rename nf_table_delrule_by_chain() Arturo Borrero Gonzalez
2014-08-26 14:14 ` [nf_tables PATCH v2 4/5] netfilter: nf_tables: add helpers to schedule objects deletion Arturo Borrero Gonzalez
2014-08-26 14:15 ` [nf_tables PATCH v2 5/5] netfilter: nf_tables: extend NFT_MSG_DELTABLE to support flushing the ruleset Arturo Borrero Gonzalez
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).