All of lore.kernel.org
 help / color / mirror / Atom feed
From: Patrick McHardy <kaber@trash.net>
To: davem@davemloft.net
Cc: netfilter-devel@lists.netfilter.org, Patrick McHardy <kaber@trash.net>
Subject: [NETFILTER 06/09]: nf_conntrack: support for layer 3 protocol load on demand
Date: Tue, 21 Mar 2006 02:55:57 +0100 (MET)	[thread overview]
Message-ID: <20060321015557.11977.67226.sendpatchset@localhost.localdomain> (raw)
In-Reply-To: <20060321015549.11977.45799.sendpatchset@localhost.localdomain>

[NETFILTER]: nf_conntrack: support for layer 3 protocol load on demand

x_tables matches and targets that require nf_conntrack_ipv[4|6] to work
don't have enough information to load on demand these modules. This
patch introduces the following changes to solve this issue:

o nf_ct_l3proto_try_module_get: try to load the layer 3 connection
tracker module and increases the refcount.
o nf_ct_l3proto_module put: drop the refcount of the module.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Patrick McHardy <kaber@trash.net>

---
commit 9f037d96029cc5aad5c61969eeb52ebcb71957d5
tree 6ae0f776c82ee652c4046e2d38cfda90565f8517
parent b90f0dbdce18ac0ce97a09f428c05b9852a5e248
author Pablo Neira Ayuso <pablo@netfilter.org> Mon, 20 Mar 2006 14:06:21 +0100
committer Patrick McHardy <kaber@trash.net> Mon, 20 Mar 2006 14:06:21 +0100

 include/net/netfilter/nf_conntrack.h           |    4 +++
 net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c |    1 +
 net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c |    1 +
 net/netfilter/nf_conntrack_core.c              |   31 ++++++++++++++++++++++++
 net/netfilter/nf_conntrack_standalone.c        |    2 ++
 net/netfilter/xt_connmark.c                    |   17 +++++++++++++
 net/netfilter/xt_conntrack.c                   |   28 ++++++++++++++++++++++
 net/netfilter/xt_helper.c                      |   17 +++++++++++++
 net/netfilter/xt_state.c                       |   29 ++++++++++++++++++++++
 9 files changed, 130 insertions(+), 0 deletions(-)

diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
index 9d1f0e6..d1cb88b 100644
--- a/include/net/netfilter/nf_conntrack.h
+++ b/include/net/netfilter/nf_conntrack.h
@@ -195,6 +195,10 @@ static inline void nf_ct_put(struct nf_c
 	nf_conntrack_put(&ct->ct_general);
 }
 
+/* Protocol module loading */
+extern int nf_ct_l3proto_try_module_get(unsigned short l3proto);
+extern void nf_ct_l3proto_module_put(unsigned short l3proto);
+
 extern struct nf_conntrack_tuple_hash *
 __nf_conntrack_find(const struct nf_conntrack_tuple *tuple,
 		    const struct nf_conn *ignored_conntrack);
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index cb9c661..c8abc9d 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -568,6 +568,7 @@ static int init_or_cleanup(int init)
 	return ret;
 }
 
+MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET));
 MODULE_LICENSE("GPL");
 
 static int __init init(void)
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index ac35f95..c16f629 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -584,6 +584,7 @@ static int init_or_cleanup(int init)
 	return ret;
 }
 
+MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET6));
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Yasuyuki KOZAKAI @USAGI <yasuyuki.kozakai@toshiba.co.jp>");
 
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 8dbca5d..de0e3af 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -23,6 +23,8 @@
  * 26 Jan 2006: Harald Welte <laforge@netfilter.org>
  * 	- restructure nf_conn (introduce nf_conn_help)
  * 	- redesign 'features' how they were originally intended
+ * 26 Feb 2006: Pablo Neira Ayuso <pablo@eurodev.net>
+ * 	- add support for L3 protocol module load on demand.
  *
  * Derived from net/ipv4/netfilter/ip_conntrack_core.c
  */
@@ -241,6 +243,35 @@ void nf_ct_l3proto_put(struct nf_conntra
 	module_put(p->me);
 }
 
+int
+nf_ct_l3proto_try_module_get(unsigned short l3proto)
+{
+	int ret;
+	struct nf_conntrack_l3proto *p;
+
+retry:	p = nf_ct_l3proto_find_get(l3proto);
+	if (p == &nf_conntrack_generic_l3proto) {
+		ret = request_module("nf_conntrack-%d", l3proto);
+		if (!ret)
+			goto retry;
+
+		return -EPROTOTYPE;
+	}
+
+	return 0;
+}
+
+void nf_ct_l3proto_module_put(unsigned short l3proto)
+{
+	struct nf_conntrack_l3proto *p;
+
+	preempt_disable();
+	p = __nf_ct_l3proto_find(l3proto);
+	preempt_enable();
+
+	module_put(p->me);
+}
+
 static int nf_conntrack_hash_rnd_initted;
 static unsigned int nf_conntrack_hash_rnd;
 
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
index 290d5a0..75577e1 100644
--- a/net/netfilter/nf_conntrack_standalone.c
+++ b/net/netfilter/nf_conntrack_standalone.c
@@ -834,6 +834,8 @@ EXPORT_SYMBOL_GPL(__nf_ct_event_cache_in
 EXPORT_PER_CPU_SYMBOL_GPL(nf_conntrack_ecache);
 EXPORT_SYMBOL_GPL(nf_ct_deliver_cached_events);
 #endif
+EXPORT_SYMBOL(nf_ct_l3proto_try_module_get);
+EXPORT_SYMBOL(nf_ct_l3proto_module_put);
 EXPORT_SYMBOL(nf_conntrack_l3proto_register);
 EXPORT_SYMBOL(nf_conntrack_l3proto_unregister);
 EXPORT_SYMBOL(nf_conntrack_protocol_register);
diff --git a/net/netfilter/xt_connmark.c b/net/netfilter/xt_connmark.c
index e810600..7b16f1e 100644
--- a/net/netfilter/xt_connmark.c
+++ b/net/netfilter/xt_connmark.c
@@ -64,14 +64,30 @@ checkentry(const char *tablename,
 		printk(KERN_WARNING "connmark: only support 32bit mark\n");
 		return 0;
 	}
+#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
+	if (nf_ct_l3proto_try_module_get(match->family) < 0) {
+		printk(KERN_WARNING "can't load nf_conntrack support for "
+				    "proto=%d\n", match->family);
+		return 0;
+	}
+#endif
 	return 1;
 }
 
+static void
+destroy(const struct xt_match *match, void *matchinfo, unsigned int matchsize)
+{
+#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
+	nf_ct_l3proto_module_put(match->family);
+#endif
+}
+
 static struct xt_match connmark_match = {
 	.name		= "connmark",
 	.match		= match,
 	.matchsize	= sizeof(struct xt_connmark_info),
 	.checkentry	= checkentry,
+	.destroy	= destroy,
 	.family		= AF_INET,
 	.me		= THIS_MODULE
 };
@@ -81,6 +97,7 @@ static struct xt_match connmark6_match =
 	.match		= match,
 	.matchsize	= sizeof(struct xt_connmark_info),
 	.checkentry	= checkentry,
+	.destroy	= destroy,
 	.family		= AF_INET6,
 	.me		= THIS_MODULE
 };
diff --git a/net/netfilter/xt_conntrack.c b/net/netfilter/xt_conntrack.c
index 7d20caa..a6c7e93 100644
--- a/net/netfilter/xt_conntrack.c
+++ b/net/netfilter/xt_conntrack.c
@@ -203,9 +203,37 @@ match(const struct sk_buff *skb,
 
 #endif /* CONFIG_NF_IP_CONNTRACK */
 
+static int
+checkentry(const char *tablename,
+	   const void *ip,
+	   const struct xt_match *match,
+	   void *matchinfo,
+	   unsigned int matchsize,
+	   unsigned int hook_mask)
+{
+#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
+	if (nf_ct_l3proto_try_module_get(match->family) < 0) {
+		printk(KERN_WARNING "can't load nf_conntrack support for "
+				    "proto=%d\n", match->family);
+		return 0;
+	}
+#endif
+	return 1;
+}
+
+static void
+destroy(const struct xt_match *match, void *matchinfo, unsigned int matchsize)
+{
+#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
+	nf_ct_l3proto_module_put(match->family);
+#endif
+}
+
 static struct xt_match conntrack_match = {
 	.name		= "conntrack",
 	.match		= match,
+	.checkentry	= checkentry,
+	.destroy	= destroy,
 	.matchsize	= sizeof(struct xt_conntrack_info),
 	.family		= AF_INET,
 	.me		= THIS_MODULE,
diff --git a/net/netfilter/xt_helper.c b/net/netfilter/xt_helper.c
index af549bd..18f524e 100644
--- a/net/netfilter/xt_helper.c
+++ b/net/netfilter/xt_helper.c
@@ -144,15 +144,31 @@ static int check(const char *tablename,
 {
 	struct xt_helper_info *info = matchinfo;
 
+#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
+	if (nf_ct_l3proto_try_module_get(match->family) < 0) {
+		printk(KERN_WARNING "can't load nf_conntrack support for "
+				    "proto=%d\n", match->family);
+		return 0;
+	}
+#endif
 	info->name[29] = '\0';
 	return 1;
 }
 
+static void
+destroy(const struct xt_match *match, void *matchinfo, unsigned int matchsize)
+{
+#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
+	nf_ct_l3proto_module_put(match->family);
+#endif
+}
+
 static struct xt_match helper_match = {
 	.name		= "helper",
 	.match		= match,
 	.matchsize	= sizeof(struct xt_helper_info),
 	.checkentry	= check,
+	.destroy	= destroy,
 	.family		= AF_INET,
 	.me		= THIS_MODULE,
 };
@@ -161,6 +177,7 @@ static struct xt_match helper6_match = {
 	.match		= match,
 	.matchsize	= sizeof(struct xt_helper_info),
 	.checkentry	= check,
+	.destroy	= destroy,
 	.family		= AF_INET6,
 	.me		= THIS_MODULE,
 };
diff --git a/net/netfilter/xt_state.c b/net/netfilter/xt_state.c
index 7cd557c..e6c0be9 100644
--- a/net/netfilter/xt_state.c
+++ b/net/netfilter/xt_state.c
@@ -44,9 +44,36 @@ match(const struct sk_buff *skb,
 	return (sinfo->statemask & statebit);
 }
 
+static int check(const char *tablename,
+		 const void *inf,
+		 const struct xt_match *match,
+		 void *matchinfo,
+		 unsigned int matchsize,
+		 unsigned int hook_mask)
+{
+#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
+	if (nf_ct_l3proto_try_module_get(match->family) < 0) {
+		printk(KERN_WARNING "can't load nf_conntrack support for "
+				    "proto=%d\n", match->family);
+		return 0;
+	}
+#endif
+	return 1;
+}
+
+static void
+destroy(const struct xt_match *match, void *matchinfo, unsigned int matchsize)
+{
+#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
+	nf_ct_l3proto_module_put(match->family);
+#endif
+}
+
 static struct xt_match state_match = {
 	.name		= "state",
 	.match		= match,
+	.checkentry	= check,
+	.destroy	= destroy,
 	.matchsize	= sizeof(struct xt_state_info),
 	.family		= AF_INET,
 	.me		= THIS_MODULE,
@@ -55,6 +82,8 @@ static struct xt_match state_match = {
 static struct xt_match state6_match = {
 	.name		= "state",
 	.match		= match,
+	.checkentry	= check,
+	.destroy	= destroy,
 	.matchsize	= sizeof(struct xt_state_info),
 	.family		= AF_INET6,
 	.me		= THIS_MODULE,

  parent reply	other threads:[~2006-03-21  1:55 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-03-21  1:55 [NETFILTER 00/09]: Netfilter update Patrick McHardy
2006-03-21  1:55 ` [NETFILTER 01/09]: Fix Kconfig typos Patrick McHardy
2006-03-21  1:55 ` [NETFILTER 02/09]: ctnetlink: Fix expectaction mask dumping Patrick McHardy
2006-03-21  1:55 ` [NETFILTER 03/09]: nfnetlink_queue: fix nfnetlink message size Patrick McHardy
2006-03-21  1:55 ` [NETFILTER 04/09]: conntrack: cleanup the conntrack ID initialization Patrick McHardy
2006-03-21  1:55 ` [NETFILTER 05/09]: x_tables: set the protocol family in x_tables targets/matches Patrick McHardy
2006-03-21  1:55 ` Patrick McHardy [this message]
2006-03-21  1:55 ` [NETFILTER 07/09]: Fix xt_policy address matching Patrick McHardy
2006-03-21  1:56 ` [NETFILTER 08/09]: Add H.323 conntrack/NAT helper Patrick McHardy
2006-03-21  2:03   ` Patrick McHardy
2006-03-21  1:56 ` [NETFILTER 09/09]: futher {ip,ip6,arp}_tables unification Patrick McHardy
2006-03-21  2:11   ` Patrick McHardy
     [not found]     ` <200603211056.02339.dim@sw.ru>
2006-03-21  8:59       ` Patrick McHardy
2006-03-21  9:21         ` Dmitry Mishin
2006-03-21 13:12           ` Patrick McHardy
2006-03-21  2:18 ` [NETFILTER 00/09]: Netfilter update Patrick McHardy
2006-03-21  7:42   ` David S. Miller
2006-03-21  8:56     ` Patrick McHardy

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=20060321015557.11977.67226.sendpatchset@localhost.localdomain \
    --to=kaber@trash.net \
    --cc=davem@davemloft.net \
    --cc=netfilter-devel@lists.netfilter.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.