netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Florian Westphal <fw@strlen.de>
To: <netfilter-devel@vger.kernel.org>
Cc: Florian Westphal <fw@strlen.de>
Subject: [PATCH v3 nf-next 12/12] netfilter: inform ctnetlink about new l3 protocol trackers
Date: Thu,  3 Dec 2015 10:49:45 +0100	[thread overview]
Message-ID: <1449136185-4165-13-git-send-email-fw@strlen.de> (raw)
In-Reply-To: <1449136185-4165-1-git-send-email-fw@strlen.de>

Previous patch made 'conntrack -E' (or other ctnetlink event tools)
register netfilter hooks of already-loaded conntrack l3 protocols, but this
fails when a new l3 protocol is loaded at a later point in time.

This informs ctnetlink about new module and also registers their hooks
if needed.

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 not part of v2.
 This is a seperate patch to ease review.

 include/linux/netfilter.h            |  1 +
 net/netfilter/nf_conntrack_netlink.c | 37 +++++++++++++++++++++++++++++++++++-
 net/netfilter/nf_conntrack_proto.c   |  6 ++++++
 3 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index c3cf796..663832d 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -397,6 +397,7 @@ struct nfnl_ct_hook {
 	void (*seq_adjust)(struct sk_buff *skb, struct nf_conn *ct,
 			   enum ip_conntrack_info ctinfo, s32 off);
 	int (*register_hooks)(struct net *);
+	void (*newproto)(void);
 };
 extern struct nfnl_ct_hook __rcu *nfnl_ct_hook;
 
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 0a9b1e9..1350a28 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -61,6 +61,7 @@ static int ctnetlink_net_id __read_mostly;
 
 struct ctnl_net {
 	DECLARE_BITMAP(enabled, NFPROTO_NUMPROTO);
+	bool active;
 };
 
 static inline int
@@ -2138,7 +2139,7 @@ ctnetlink_alloc_expect(const struct nlattr *const cda[], struct nf_conn *ct,
 		       struct nf_conntrack_tuple *tuple,
 		       struct nf_conntrack_tuple *mask);
 
-static int ctnl_bind(struct net *net)
+static void __ctnl_bind(struct net *net)
 {
 	struct ctnl_net *ctnet = net_generic(net, ctnetlink_net_id);
 	int i;
@@ -2178,11 +2179,43 @@ static int ctnl_bind(struct net *net)
 	}
 
 	rcu_read_unlock();
+}
+
+static int ctnl_bind(struct net *net)
+{
+	struct ctnl_net *ctnet = net_generic(net, ctnetlink_net_id);
+
+	__ctnl_bind(net);
+
+	if (!ctnet->active)
+		ctnet->active = true;
 
 	return 0;
 }
 
 #ifdef CONFIG_NETFILTER_NETLINK_GLUE_CT
+/* called with RCU read lock held */
+static void ctnl_newproto(void)
+{
+	struct ctnl_net *ctnet;
+	struct net *net;
+
+	if (!try_module_get(THIS_MODULE))
+		return;
+
+	rcu_read_unlock();
+	rtnl_lock();
+	for_each_net(net) {
+		ctnet = net_generic(net, ctnetlink_net_id);
+		if (ctnet->active)
+			__ctnl_bind(net);
+	}
+	rtnl_unlock();
+	rcu_read_lock();
+
+	module_put(THIS_MODULE);
+}
+
 static size_t
 ctnetlink_glue_build_size(const struct nf_conn *ct)
 {
@@ -2452,6 +2485,7 @@ static struct nfnl_ct_hook ctnetlink_glue_hook = {
 	.attach_expect	= ctnetlink_glue_attach_expect,
 	.seq_adjust	= ctnetlink_glue_seqadj,
 	.register_hooks = ctnl_bind,
+	.newproto	= ctnl_newproto,
 };
 #endif /* CONFIG_NETFILTER_NETLINK_GLUE_CT */
 
@@ -3434,6 +3468,7 @@ static void ctnetlink_net_exit(struct net *net)
 		rcu_read_lock();
 	}
 
+	ctnet->active = false;
 	rcu_read_unlock();
 }
 
diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c
index 1fb11b6..20d51e4 100644
--- a/net/netfilter/nf_conntrack_proto.c
+++ b/net/netfilter/nf_conntrack_proto.c
@@ -259,6 +259,7 @@ int nf_ct_l3proto_register(struct nf_conntrack_l3proto *proto)
 {
 	int ret = 0;
 	struct nf_conntrack_l3proto *old;
+	struct nfnl_ct_hook *nfnl_ct;
 
 	if (proto->l3proto >= AF_MAX)
 		return -EBUSY;
@@ -279,6 +280,11 @@ int nf_ct_l3proto_register(struct nf_conntrack_l3proto *proto)
 
 	rcu_assign_pointer(nf_ct_l3protos[proto->l3proto], proto);
 
+	rcu_read_lock();
+	nfnl_ct = rcu_dereference(nfnl_ct_hook);
+	if (nfnl_ct)
+		nfnl_ct->newproto();
+	rcu_read_unlock();
 out_unlock:
 	mutex_unlock(&nf_ct_proto_mutex);
 	return ret;
-- 
2.4.10


  parent reply	other threads:[~2015-12-03  9:50 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-12-03  9:49 [PATCH v3 nf-next 0/12] netfilter: don't copy init ns hooks to new namespaces Florian Westphal
2015-12-03  9:49 ` [PATCH v3 nf-next 01/12] netfilter: add and use nf_ct_netns_get/put Florian Westphal
2015-12-03  9:49 ` [PATCH v3 nf-next 02/12] netfilter: conntrack: register hooks in netns when needed by ruleset Florian Westphal
2015-12-03  9:49 ` [PATCH v3 nf-next 03/12] netfilter: xtables: don't register table hooks in namespace at init time Florian Westphal
2015-12-03  9:49 ` [PATCH v3 nf-next 04/12] netfilter: defrag: only register defrag functionality if needed Florian Westphal
2015-12-03  9:49 ` [PATCH v3 nf-next 05/12] netfilter: nat: add dependencies on conntrack module Florian Westphal
2015-12-03  9:49 ` [PATCH v3 nf-next 06/12] netfilter: bridge: register hooks only when bridge interface is added Florian Westphal
2015-12-03  9:49 ` [PATCH v3 nf-next 07/12] netfilter: don't call nf_hook_state_init/_hook_slow unless needed Florian Westphal
2015-12-03  9:49 ` [PATCH v3 nf-next 08/12] nftables: add conntrack dependencies for nat/masq/redir expressions Florian Westphal
2015-12-03  9:49 ` [PATCH v3 nf-next 09/12] nfnetlink: add nfnl_dereference_protected helper Florian Westphal
2015-12-18 10:39   ` Pablo Neira Ayuso
2015-12-03  9:49 ` [PATCH v3 nf-next 10/12] netfilter: ctnetlink: make ctnetlink bind register conntrack hooks Florian Westphal
2015-12-03  9:49 ` [PATCH v3 nf-next 11/12] netfilter: hook up nfnetlink log/queue to " Florian Westphal
2015-12-03  9:49 ` Florian Westphal [this message]
2015-12-18 11:42 ` [PATCH v3 nf-next 0/12] netfilter: don't copy init ns hooks to new namespaces Pablo Neira Ayuso
2015-12-20 21:01   ` Florian Westphal

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=1449136185-4165-13-git-send-email-fw@strlen.de \
    --to=fw@strlen.de \
    --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).