netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Pablo Neira Ayuso <pablo@netfilter.org>
To: netfilter-devel@vger.kernel.org
Cc: davem@davemloft.net, netdev@vger.kernel.org
Subject: [PATCH 02/17] netfilter: nf_tables: destroy basechain and rules on netdevice removal
Date: Fri,  8 Jan 2016 15:02:02 +0100	[thread overview]
Message-ID: <1452261737-7475-3-git-send-email-pablo@netfilter.org> (raw)
In-Reply-To: <1452261737-7475-1-git-send-email-pablo@netfilter.org>

If the netdevice is destroyed, the resources that are attached should
be released too as they belong to the device that is now gone.

Suggested-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 include/net/netfilter/nf_tables.h |  5 +----
 net/netfilter/nf_tables_api.c     | 31 +++++++++++++++++++++------
 net/netfilter/nf_tables_netdev.c  | 45 ++++++++++++++++-----------------------
 3 files changed, 44 insertions(+), 37 deletions(-)

diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index a50f139..0191fbb 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -821,10 +821,7 @@ static inline struct nft_base_chain *nft_base_chain(const struct nft_chain *chai
 	return container_of(chain, struct nft_base_chain, chain);
 }
 
-int nft_register_basechain(struct nft_base_chain *basechain,
-			   unsigned int hook_nops);
-void nft_unregister_basechain(struct nft_base_chain *basechain,
-			      unsigned int hook_nops);
+int __nft_release_basechain(struct nft_ctx *ctx);
 
 unsigned int nft_do_chain(struct nft_pktinfo *pkt, void *priv);
 
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 8522731..5729844 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -131,8 +131,8 @@ static void nft_trans_destroy(struct nft_trans *trans)
 	kfree(trans);
 }
 
-int nft_register_basechain(struct nft_base_chain *basechain,
-			   unsigned int hook_nops)
+static int nft_register_basechain(struct nft_base_chain *basechain,
+				  unsigned int hook_nops)
 {
 	struct net *net = read_pnet(&basechain->pnet);
 
@@ -141,10 +141,9 @@ int nft_register_basechain(struct nft_base_chain *basechain,
 
 	return nf_register_net_hooks(net, basechain->ops, hook_nops);
 }
-EXPORT_SYMBOL_GPL(nft_register_basechain);
 
-void nft_unregister_basechain(struct nft_base_chain *basechain,
-			      unsigned int hook_nops)
+static void nft_unregister_basechain(struct nft_base_chain *basechain,
+				     unsigned int hook_nops)
 {
 	struct net *net = read_pnet(&basechain->pnet);
 
@@ -153,7 +152,6 @@ void nft_unregister_basechain(struct nft_base_chain *basechain,
 
 	nf_unregister_net_hooks(net, basechain->ops, hook_nops);
 }
-EXPORT_SYMBOL_GPL(nft_unregister_basechain);
 
 static int nf_tables_register_hooks(const struct nft_table *table,
 				    struct nft_chain *chain,
@@ -4590,6 +4588,27 @@ static int __net_init nf_tables_init_net(struct net *net)
 	return 0;
 }
 
+int __nft_release_basechain(struct nft_ctx *ctx)
+{
+	struct nft_rule *rule, *nr;
+
+	BUG_ON(!(ctx->chain->flags & NFT_BASE_CHAIN));
+
+	nf_tables_unregister_hooks(ctx->chain->table, ctx->chain,
+				   ctx->afi->nops);
+	list_for_each_entry_safe(rule, nr, &ctx->chain->rules, list) {
+		list_del(&rule->list);
+		ctx->chain->use--;
+		nf_tables_rule_destroy(ctx, rule);
+	}
+	list_del(&ctx->chain->list);
+	ctx->table->use--;
+	nf_tables_chain_destroy(ctx->chain);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(__nft_release_basechain);
+
 /* Called by nft_unregister_afinfo() from __net_exit path, nfnl_lock is held. */
 static void __nft_release_afinfo(struct net *net, struct nft_af_info *afi)
 {
diff --git a/net/netfilter/nf_tables_netdev.c b/net/netfilter/nf_tables_netdev.c
index 2bfd1fb..3e9c87b 100644
--- a/net/netfilter/nf_tables_netdev.c
+++ b/net/netfilter/nf_tables_netdev.c
@@ -156,35 +156,17 @@ static const struct nf_chain_type nft_filter_chain_netdev = {
 	.hook_mask	= (1 << NF_NETDEV_INGRESS),
 };
 
-static void nft_netdev_event(unsigned long event, struct nft_af_info *afi,
-			     struct net_device *dev, struct nft_table *table,
-			     struct nft_base_chain *basechain)
+static void nft_netdev_event(unsigned long event, struct net_device *dev,
+			     struct nft_ctx *ctx)
 {
-	switch (event) {
-	case NETDEV_REGISTER:
-		if (strcmp(basechain->dev_name, dev->name) != 0)
-			return;
+	struct nft_base_chain *basechain = nft_base_chain(ctx->chain);
 
-		BUG_ON(!(basechain->flags & NFT_BASECHAIN_DISABLED));
-
-		dev_hold(dev);
-		basechain->ops[0].dev = dev;
-		basechain->flags &= ~NFT_BASECHAIN_DISABLED;
-		if (!(table->flags & NFT_TABLE_F_DORMANT))
-			nft_register_basechain(basechain, afi->nops);
-		break;
+	switch (event) {
 	case NETDEV_UNREGISTER:
 		if (strcmp(basechain->dev_name, dev->name) != 0)
 			return;
 
-		BUG_ON(basechain->flags & NFT_BASECHAIN_DISABLED);
-
-		if (!(table->flags & NFT_TABLE_F_DORMANT))
-			nft_unregister_basechain(basechain, afi->nops);
-
-		dev_put(basechain->ops[0].dev);
-		basechain->ops[0].dev = NULL;
-		basechain->flags |= NFT_BASECHAIN_DISABLED;
+		__nft_release_basechain(ctx);
 		break;
 	case NETDEV_CHANGENAME:
 		if (dev->ifindex != basechain->ops[0].dev->ifindex)
@@ -201,20 +183,29 @@ static int nf_tables_netdev_event(struct notifier_block *this,
 	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
 	struct nft_af_info *afi;
 	struct nft_table *table;
-	struct nft_chain *chain;
+	struct nft_chain *chain, *nr;
+	struct nft_ctx ctx = {
+		.net	= dev_net(dev),
+	};
+
+	if (event != NETDEV_UNREGISTER &&
+	    event != NETDEV_CHANGENAME)
+		return NOTIFY_DONE;
 
 	nfnl_lock(NFNL_SUBSYS_NFTABLES);
 	list_for_each_entry(afi, &dev_net(dev)->nft.af_info, list) {
+		ctx.afi = afi;
 		if (afi->family != NFPROTO_NETDEV)
 			continue;
 
 		list_for_each_entry(table, &afi->tables, list) {
-			list_for_each_entry(chain, &table->chains, list) {
+			ctx.table = table;
+			list_for_each_entry_safe(chain, nr, &table->chains, list) {
 				if (!(chain->flags & NFT_BASE_CHAIN))
 					continue;
 
-				nft_netdev_event(event, afi, dev, table,
-						 nft_base_chain(chain));
+				ctx.chain = chain;
+				nft_netdev_event(event, dev, &ctx);
 			}
 		}
 	}
-- 
2.1.4

  parent reply	other threads:[~2016-01-08 14:02 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-01-08 14:02 [PATCH 00/17] Netfilter updates for net-next Pablo Neira Ayuso
2016-01-08 14:02 ` [PATCH 01/17] netfilter: nf_tables: release objects on netns destruction Pablo Neira Ayuso
2016-01-08 14:02 ` Pablo Neira Ayuso [this message]
2016-01-08 14:02 ` [PATCH 03/17] netfilter: nf_tables: remove check against removal of inactive objects Pablo Neira Ayuso
2016-01-08 14:02 ` [PATCH 04/17] netfilter: nfnetlink: pass down netns pointer to call() and call_rcu() Pablo Neira Ayuso
2016-01-08 14:02 ` [PATCH 05/17] netfilter: nfnetlink: pass down netns pointer to commit() and abort() callbacks Pablo Neira Ayuso
2016-01-08 14:02 ` [PATCH 06/17] netfilter: nft_limit: allow to invert matching criteria Pablo Neira Ayuso
2016-01-08 14:02 ` [PATCH 07/17] netfilter: nf_tables: add packet duplication to the netdev family Pablo Neira Ayuso
2016-01-08 14:02 ` [PATCH 08/17] netfilter: nf_tables: add forward expression " Pablo Neira Ayuso
2016-01-08 14:02 ` [PATCH 09/17] netfilter: nf_ct_helper: define pr_fmt() Pablo Neira Ayuso
2016-01-08 14:02 ` [PATCH 10/17] netfilter: nfnetlink_queue: validate dependencies to avoid breaking atomicity Pablo Neira Ayuso
2016-01-08 14:02 ` [PATCH 11/17] netfilter: nfnetlink_queue: don't handle options after unbind Pablo Neira Ayuso
2016-01-08 14:02 ` [PATCH 12/17] netfilter: nfnetlink_queue: just returns error for unknown command Pablo Neira Ayuso
2016-01-08 14:02 ` [PATCH 13/17] netfilter: nfnetlink_queue: autoload nf_conntrack_netlink module NFQA_CFG_F_CONNTRACK config flag Pablo Neira Ayuso
2016-01-08 14:02 ` [PATCH 14/17] netfilter: nfnetlink_log: just returns error for unknown command Pablo Neira Ayuso
2016-01-08 14:02 ` [PATCH 15/17] netfilter: nf_tables: Add new attributes into nft_set to store user data Pablo Neira Ayuso
2016-01-08 14:02 ` [PATCH 16/17] netfilter: nft_byteorder: provide 64bit le/be conversion Pablo Neira Ayuso
2016-01-08 14:26   ` David Laight
2016-01-08 16:23     ` Florian Westphal
2016-01-08 16:41       ` David Laight
2016-01-08 16:55         ` Florian Westphal
2016-01-08 14:02 ` [PATCH 17/17] netfilter: nft_ct: add byte/packet counter support Pablo Neira Ayuso
2016-01-09  2:24 ` [PATCH 00/17] Netfilter updates for net-next David Miller

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1452261737-7475-3-git-send-email-pablo@netfilter.org \
    --to=pablo@netfilter.org \
    --cc=davem@davemloft.net \
    --cc=netdev@vger.kernel.org \
    --cc=netfilter-devel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).