瀏覽代碼

Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6

* master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6:
  [TCP]: Do not use inet->id of global tcp_socket when sending RST.
  [NETFILTER]: Fix undefined references to get_h225_addr
  [NETFILTER]: futher {ip,ip6,arp}_tables unification
  [NETFILTER]: Fix xt_policy address matching
  [NETFILTER]: nf_conntrack: support for layer 3 protocol load on demand
  [NETFILTER]: x_tables: set the protocol family in x_tables targets/matches
  [NETFILTER]: conntrack: cleanup the conntrack ID initialization
  [NETFILTER]: nfnetlink_queue: fix nfnetlink message size
  [NETFILTER]: ctnetlink: Fix expectaction mask dumping
  [NETFILTER]: Fix Kconfig typos
  [NETFILTER]: Fix ip6tables breakage from {get,set}sockopt compat layer
Linus Torvalds 19 年之前
父節點
當前提交
80576fd86b
共有 46 個文件被更改,包括 571 次插入368 次删除
  1. 60 4
      include/linux/netfilter/x_tables.h
  2. 6 31
      include/linux/netfilter_arp/arp_tables.h
  3. 11 59
      include/linux/netfilter_ipv4/ip_tables.h
  4. 11 58
      include/linux/netfilter_ipv6/ip6_tables.h
  5. 4 0
      include/net/netfilter/nf_conntrack.h
  6. 2 2
      include/net/tc_act/tc_ipt.h
  7. 1 5
      net/ipv4/ip_output.c
  8. 4 2
      net/ipv4/netfilter/arp_tables.c
  9. 2 2
      net/ipv4/netfilter/ip_conntrack_core.c
  10. 2 2
      net/ipv4/netfilter/ip_conntrack_helper_h323.c
  11. 55 17
      net/ipv4/netfilter/ip_conntrack_netlink.c
  12. 9 6
      net/ipv4/netfilter/ip_tables.c
  13. 1 0
      net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
  14. 2 2
      net/ipv6/ipv6_sockglue.c
  15. 9 6
      net/ipv6/netfilter/ip6_tables.c
  16. 1 0
      net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
  17. 3 3
      net/netfilter/Kconfig
  18. 33 2
      net/netfilter/nf_conntrack_core.c
  19. 62 22
      net/netfilter/nf_conntrack_netlink.c
  20. 2 0
      net/netfilter/nf_conntrack_standalone.c
  21. 10 9
      net/netfilter/nfnetlink_queue.c
  22. 10 6
      net/netfilter/x_tables.c
  23. 7 5
      net/netfilter/xt_CLASSIFY.c
  24. 7 5
      net/netfilter/xt_CONNMARK.c
  25. 12 9
      net/netfilter/xt_MARK.c
  26. 11 8
      net/netfilter/xt_NFQUEUE.c
  27. 7 5
      net/netfilter/xt_NOTRACK.c
  28. 7 5
      net/netfilter/xt_comment.c
  29. 7 5
      net/netfilter/xt_connbytes.c
  30. 24 5
      net/netfilter/xt_connmark.c
  31. 31 2
      net/netfilter/xt_conntrack.c
  32. 7 5
      net/netfilter/xt_dccp.c
  33. 24 5
      net/netfilter/xt_helper.c
  34. 7 5
      net/netfilter/xt_length.c
  35. 7 5
      net/netfilter/xt_limit.c
  36. 7 5
      net/netfilter/xt_mac.c
  37. 7 5
      net/netfilter/xt_mark.c
  38. 7 5
      net/netfilter/xt_physdev.c
  39. 7 5
      net/netfilter/xt_pkttype.c
  40. 10 8
      net/netfilter/xt_policy.c
  41. 3 2
      net/netfilter/xt_realm.c
  42. 7 5
      net/netfilter/xt_sctp.c
  43. 36 5
      net/netfilter/xt_state.c
  44. 7 5
      net/netfilter/xt_string.c
  45. 7 5
      net/netfilter/xt_tcpmss.c
  46. 15 11
      net/netfilter/xt_tcpudp.c

+ 60 - 4
include/linux/netfilter/x_tables.h

@@ -4,6 +4,62 @@
 #define XT_FUNCTION_MAXNAMELEN 30
 #define XT_FUNCTION_MAXNAMELEN 30
 #define XT_TABLE_MAXNAMELEN 32
 #define XT_TABLE_MAXNAMELEN 32
 
 
+struct xt_entry_match
+{
+	union {
+		struct {
+			u_int16_t match_size;
+
+			/* Used by userspace */
+			char name[XT_FUNCTION_MAXNAMELEN-1];
+
+			u_int8_t revision;
+		} user;
+		struct {
+			u_int16_t match_size;
+
+			/* Used inside the kernel */
+			struct xt_match *match;
+		} kernel;
+
+		/* Total length */
+		u_int16_t match_size;
+	} u;
+
+	unsigned char data[0];
+};
+
+struct xt_entry_target
+{
+	union {
+		struct {
+			u_int16_t target_size;
+
+			/* Used by userspace */
+			char name[XT_FUNCTION_MAXNAMELEN-1];
+
+			u_int8_t revision;
+		} user;
+		struct {
+			u_int16_t target_size;
+
+			/* Used inside the kernel */
+			struct xt_target *target;
+		} kernel;
+
+		/* Total length */
+		u_int16_t target_size;
+	} u;
+
+	unsigned char data[0];
+};
+
+struct xt_standard_target
+{
+	struct xt_entry_target target;
+	int verdict;
+};
+
 /* The argument to IPT_SO_GET_REVISION_*.  Returns highest revision
 /* The argument to IPT_SO_GET_REVISION_*.  Returns highest revision
  * kernel supports, if >= revision. */
  * kernel supports, if >= revision. */
 struct xt_get_revision
 struct xt_get_revision
@@ -220,10 +276,10 @@ struct xt_table_info
 	char *entries[NR_CPUS];
 	char *entries[NR_CPUS];
 };
 };
 
 
-extern int xt_register_target(int af, struct xt_target *target);
-extern void xt_unregister_target(int af, struct xt_target *target);
-extern int xt_register_match(int af, struct xt_match *target);
-extern void xt_unregister_match(int af, struct xt_match *target);
+extern int xt_register_target(struct xt_target *target);
+extern void xt_unregister_target(struct xt_target *target);
+extern int xt_register_match(struct xt_match *target);
+extern void xt_unregister_match(struct xt_match *target);
 
 
 extern int xt_check_match(const struct xt_match *match, unsigned short family,
 extern int xt_check_match(const struct xt_match *match, unsigned short family,
 			  unsigned int size, const char *table, unsigned int hook,
 			  unsigned int size, const char *table, unsigned int hook,

+ 6 - 31
include/linux/netfilter_arp/arp_tables.h

@@ -65,35 +65,8 @@ struct arpt_arp {
 	u_int16_t invflags;
 	u_int16_t invflags;
 };
 };
 
 
-struct arpt_entry_target
-{
-	union {
-		struct {
-			u_int16_t target_size;
-
-			/* Used by userspace */
-			char name[ARPT_FUNCTION_MAXNAMELEN-1];
-			u_int8_t revision;
-		} user;
-		struct {
-			u_int16_t target_size;
-
-			/* Used inside the kernel */
-			struct arpt_target *target;
-		} kernel;
-
-		/* Total length */
-		u_int16_t target_size;
-	} u;
-
-	unsigned char data[0];
-};
-
-struct arpt_standard_target
-{
-	struct arpt_entry_target target;
-	int verdict;
-};
+#define arpt_entry_target xt_entry_target
+#define arpt_standard_target xt_standard_target
 
 
 /* Values for "flag" field in struct arpt_ip (general arp structure).
 /* Values for "flag" field in struct arpt_ip (general arp structure).
  * No flags defined yet.
  * No flags defined yet.
@@ -263,8 +236,10 @@ static __inline__ struct arpt_entry_target *arpt_get_target(struct arpt_entry *e
  */
  */
 #ifdef __KERNEL__
 #ifdef __KERNEL__
 
 
-#define arpt_register_target(tgt) xt_register_target(NF_ARP, tgt)
-#define arpt_unregister_target(tgt) xt_unregister_target(NF_ARP, tgt)
+#define arpt_register_target(tgt) 	\
+({	(tgt)->family = NF_ARP;		\
+ 	xt_register_target(tgt); })
+#define arpt_unregister_target(tgt) xt_unregister_target(tgt)
 
 
 extern int arpt_register_table(struct arpt_table *table,
 extern int arpt_register_table(struct arpt_table *table,
 			       const struct arpt_replace *repl);
 			       const struct arpt_replace *repl);

+ 11 - 59
include/linux/netfilter_ipv4/ip_tables.h

@@ -52,61 +52,9 @@ struct ipt_ip {
 	u_int8_t invflags;
 	u_int8_t invflags;
 };
 };
 
 
-struct ipt_entry_match
-{
-	union {
-		struct {
-			u_int16_t match_size;
-
-			/* Used by userspace */
-			char name[IPT_FUNCTION_MAXNAMELEN-1];
-
-			u_int8_t revision;
-		} user;
-		struct {
-			u_int16_t match_size;
-
-			/* Used inside the kernel */
-			struct ipt_match *match;
-		} kernel;
-
-		/* Total length */
-		u_int16_t match_size;
-	} u;
-
-	unsigned char data[0];
-};
-
-struct ipt_entry_target
-{
-	union {
-		struct {
-			u_int16_t target_size;
-
-			/* Used by userspace */
-			char name[IPT_FUNCTION_MAXNAMELEN-1];
-
-			u_int8_t revision;
-		} user;
-		struct {
-			u_int16_t target_size;
-
-			/* Used inside the kernel */
-			struct ipt_target *target;
-		} kernel;
-
-		/* Total length */
-		u_int16_t target_size;
-	} u;
-
-	unsigned char data[0];
-};
-
-struct ipt_standard_target
-{
-	struct ipt_entry_target target;
-	int verdict;
-};
+#define ipt_entry_match xt_entry_match
+#define ipt_entry_target xt_entry_target
+#define ipt_standard_target xt_standard_target
 
 
 #define ipt_counters xt_counters
 #define ipt_counters xt_counters
 
 
@@ -321,11 +269,15 @@ ipt_get_target(struct ipt_entry *e)
 #include <linux/init.h>
 #include <linux/init.h>
 extern void ipt_init(void) __init;
 extern void ipt_init(void) __init;
 
 
-#define ipt_register_target(tgt) xt_register_target(AF_INET, tgt)
-#define ipt_unregister_target(tgt) xt_unregister_target(AF_INET, tgt)
+#define ipt_register_target(tgt) 	\
+({	(tgt)->family = AF_INET;	\
+ 	xt_register_target(tgt); })
+#define ipt_unregister_target(tgt) xt_unregister_target(tgt)
 
 
-#define ipt_register_match(mtch) xt_register_match(AF_INET, mtch)
-#define ipt_unregister_match(mtch) xt_unregister_match(AF_INET, mtch)
+#define ipt_register_match(mtch) 	\
+({	(mtch)->family = AF_INET;	\
+	xt_register_match(mtch); })
+#define ipt_unregister_match(mtch) xt_unregister_match(mtch)
 
 
 //#define ipt_register_table(tbl, repl) xt_register_table(AF_INET, tbl, repl)
 //#define ipt_register_table(tbl, repl) xt_register_table(AF_INET, tbl, repl)
 //#define ipt_unregister_table(tbl) xt_unregister_table(AF_INET, tbl)
 //#define ipt_unregister_table(tbl) xt_unregister_table(AF_INET, tbl)

+ 11 - 58
include/linux/netfilter_ipv6/ip6_tables.h

@@ -56,60 +56,9 @@ struct ip6t_ip6 {
 	u_int8_t invflags;
 	u_int8_t invflags;
 };
 };
 
 
-/* FIXME: If alignment in kernel different from userspace? --RR */
-struct ip6t_entry_match
-{
-	union {
-		struct {
-			u_int16_t match_size;
-
-			/* Used by userspace */
-			char name[IP6T_FUNCTION_MAXNAMELEN-1];
-			u_int8_t revision;
-		} user;
-		struct {
-			u_int16_t match_size;
-
-			/* Used inside the kernel */
-			struct ip6t_match *match;
-		} kernel;
-
-		/* Total length */
-		u_int16_t match_size;
-	} u;
-
-	unsigned char data[0];
-};
-
-struct ip6t_entry_target
-{
-	union {
-		struct {
-			u_int16_t target_size;
-
-			/* Used by userspace */
-			char name[IP6T_FUNCTION_MAXNAMELEN-1];
-			u_int8_t revision;
-		} user;
-		struct {
-			u_int16_t target_size;
-
-			/* Used inside the kernel */
-			struct ip6t_target *target;
-		} kernel;
-
-		/* Total length */
-		u_int16_t target_size;
-	} u;
-
-	unsigned char data[0];
-};
-
-struct ip6t_standard_target
-{
-	struct ip6t_entry_target target;
-	int verdict;
-};
+#define ip6t_entry_match xt_entry_match
+#define ip6t_entry_target xt_entry_target
+#define ip6t_standard_target xt_standard_target
 
 
 #define ip6t_counters	xt_counters
 #define ip6t_counters	xt_counters
 
 
@@ -334,11 +283,15 @@ ip6t_get_target(struct ip6t_entry *e)
 #include <linux/init.h>
 #include <linux/init.h>
 extern void ip6t_init(void) __init;
 extern void ip6t_init(void) __init;
 
 
-#define ip6t_register_target(tgt) xt_register_target(AF_INET6, tgt)
-#define ip6t_unregister_target(tgt) xt_unregister_target(AF_INET6, tgt)
+#define ip6t_register_target(tgt) 		\
+({	(tgt)->family = AF_INET6;		\
+ 	xt_register_target(tgt); })
+#define ip6t_unregister_target(tgt) xt_unregister_target(tgt)
 
 
-#define ip6t_register_match(match) xt_register_match(AF_INET6, match)
-#define ip6t_unregister_match(match) xt_unregister_match(AF_INET6, match)
+#define ip6t_register_match(match)		\
+({	(match)->family = AF_INET6;		\
+	xt_register_match(match); })
+#define ip6t_unregister_match(match) xt_unregister_match(match)
 
 
 extern int ip6t_register_table(struct ip6t_table *table,
 extern int ip6t_register_table(struct ip6t_table *table,
 			       const struct ip6t_replace *repl);
 			       const struct ip6t_replace *repl);

+ 4 - 0
include/net/netfilter/nf_conntrack.h

@@ -195,6 +195,10 @@ static inline void nf_ct_put(struct nf_conn *ct)
 	nf_conntrack_put(&ct->ct_general);
 	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 *
 extern struct nf_conntrack_tuple_hash *
 __nf_conntrack_find(const struct nf_conntrack_tuple *tuple,
 __nf_conntrack_find(const struct nf_conntrack_tuple *tuple,
 		    const struct nf_conn *ignored_conntrack);
 		    const struct nf_conn *ignored_conntrack);

+ 2 - 2
include/net/tc_act/tc_ipt.h

@@ -3,14 +3,14 @@
 
 
 #include <net/act_api.h>
 #include <net/act_api.h>
 
 
-struct ipt_entry_target;
+struct xt_entry_target;
 
 
 struct tcf_ipt
 struct tcf_ipt
 {
 {
 	tca_gen(ipt);
 	tca_gen(ipt);
 	u32 hook;
 	u32 hook;
 	char *tname;
 	char *tname;
-	struct ipt_entry_target *t;
+	struct xt_entry_target *t;
 };
 };
 
 
 #endif
 #endif

+ 1 - 5
net/ipv4/ip_output.c

@@ -1249,11 +1249,7 @@ int ip_push_pending_frames(struct sock *sk)
 	iph->tos = inet->tos;
 	iph->tos = inet->tos;
 	iph->tot_len = htons(skb->len);
 	iph->tot_len = htons(skb->len);
 	iph->frag_off = df;
 	iph->frag_off = df;
-	if (!df) {
-		__ip_select_ident(iph, &rt->u.dst, 0);
-	} else {
-		iph->id = htons(inet->id++);
-	}
+	ip_select_ident(iph, &rt->u.dst, sk);
 	iph->ttl = ttl;
 	iph->ttl = ttl;
 	iph->protocol = sk->sk_protocol;
 	iph->protocol = sk->sk_protocol;
 	iph->saddr = rt->rt_src;
 	iph->saddr = rt->rt_src;

+ 4 - 2
net/ipv4/netfilter/arp_tables.c

@@ -1146,12 +1146,14 @@ void arpt_unregister_table(struct arpt_table *table)
 static struct arpt_target arpt_standard_target = {
 static struct arpt_target arpt_standard_target = {
 	.name		= ARPT_STANDARD_TARGET,
 	.name		= ARPT_STANDARD_TARGET,
 	.targetsize	= sizeof(int),
 	.targetsize	= sizeof(int),
+	.family		= NF_ARP,
 };
 };
 
 
 static struct arpt_target arpt_error_target = {
 static struct arpt_target arpt_error_target = {
 	.name		= ARPT_ERROR_TARGET,
 	.name		= ARPT_ERROR_TARGET,
 	.target		= arpt_error,
 	.target		= arpt_error,
 	.targetsize	= ARPT_FUNCTION_MAXNAMELEN,
 	.targetsize	= ARPT_FUNCTION_MAXNAMELEN,
+	.family		= NF_ARP,
 };
 };
 
 
 static struct nf_sockopt_ops arpt_sockopts = {
 static struct nf_sockopt_ops arpt_sockopts = {
@@ -1171,8 +1173,8 @@ static int __init init(void)
 	xt_proto_init(NF_ARP);
 	xt_proto_init(NF_ARP);
 
 
 	/* Noone else will be downing sem now, so we won't sleep */
 	/* Noone else will be downing sem now, so we won't sleep */
-	xt_register_target(NF_ARP, &arpt_standard_target);
-	xt_register_target(NF_ARP, &arpt_error_target);
+	xt_register_target(&arpt_standard_target);
+	xt_register_target(&arpt_error_target);
 
 
 	/* Register setsockopt */
 	/* Register setsockopt */
 	ret = nf_register_sockopt(&arpt_sockopts);
 	ret = nf_register_sockopt(&arpt_sockopts);

+ 2 - 2
net/ipv4/netfilter/ip_conntrack_core.c

@@ -77,8 +77,8 @@ unsigned int ip_ct_log_invalid;
 static LIST_HEAD(unconfirmed);
 static LIST_HEAD(unconfirmed);
 static int ip_conntrack_vmalloc;
 static int ip_conntrack_vmalloc;
 
 
-static unsigned int ip_conntrack_next_id = 1;
-static unsigned int ip_conntrack_expect_next_id = 1;
+static unsigned int ip_conntrack_next_id;
+static unsigned int ip_conntrack_expect_next_id;
 #ifdef CONFIG_IP_NF_CONNTRACK_EVENTS
 #ifdef CONFIG_IP_NF_CONNTRACK_EVENTS
 struct notifier_block *ip_conntrack_chain;
 struct notifier_block *ip_conntrack_chain;
 struct notifier_block *ip_conntrack_expect_chain;
 struct notifier_block *ip_conntrack_expect_chain;

+ 2 - 2
net/ipv4/netfilter/ip_conntrack_helper_h323.c

@@ -639,8 +639,8 @@ void ip_conntrack_h245_expect(struct ip_conntrack *new,
 }
 }
 
 
 /****************************************************************************/
 /****************************************************************************/
-static int get_h225_addr(unsigned char *data, TransportAddress * addr,
-			 u_int32_t * ip, u_int16_t * port)
+int get_h225_addr(unsigned char *data, TransportAddress * addr,
+		  u_int32_t * ip, u_int16_t * port)
 {
 {
 	unsigned char *p;
 	unsigned char *p;
 
 

+ 55 - 17
net/ipv4/netfilter/ip_conntrack_netlink.c

@@ -4,7 +4,7 @@
  * (C) 2001 by Jay Schulist <jschlst@samba.org>
  * (C) 2001 by Jay Schulist <jschlst@samba.org>
  * (C) 2002-2005 by Harald Welte <laforge@gnumonks.org>
  * (C) 2002-2005 by Harald Welte <laforge@gnumonks.org>
  * (C) 2003 by Patrick Mchardy <kaber@trash.net>
  * (C) 2003 by Patrick Mchardy <kaber@trash.net>
- * (C) 2005 by Pablo Neira Ayuso <pablo@eurodev.net>
+ * (C) 2005-2006 by Pablo Neira Ayuso <pablo@eurodev.net>
  *
  *
  * I've reworked this stuff to use attributes instead of conntrack 
  * I've reworked this stuff to use attributes instead of conntrack 
  * structures. 5.44 am. I need more tea. --pablo 05/07/11.
  * structures. 5.44 am. I need more tea. --pablo 05/07/11.
@@ -53,20 +53,18 @@ static char __initdata version[] = "0.90";
 
 
 static inline int
 static inline int
 ctnetlink_dump_tuples_proto(struct sk_buff *skb, 
 ctnetlink_dump_tuples_proto(struct sk_buff *skb, 
-			    const struct ip_conntrack_tuple *tuple)
+			    const struct ip_conntrack_tuple *tuple,
+			    struct ip_conntrack_protocol *proto)
 {
 {
-	struct ip_conntrack_protocol *proto;
 	int ret = 0;
 	int ret = 0;
+	struct nfattr *nest_parms = NFA_NEST(skb, CTA_TUPLE_PROTO);
 
 
 	NFA_PUT(skb, CTA_PROTO_NUM, sizeof(u_int8_t), &tuple->dst.protonum);
 	NFA_PUT(skb, CTA_PROTO_NUM, sizeof(u_int8_t), &tuple->dst.protonum);
 
 
-	/* If no protocol helper is found, this function will return the
-	 * generic protocol helper, so proto won't *ever* be NULL */
-	proto = ip_conntrack_proto_find_get(tuple->dst.protonum);
 	if (likely(proto->tuple_to_nfattr))
 	if (likely(proto->tuple_to_nfattr))
 		ret = proto->tuple_to_nfattr(skb, tuple);
 		ret = proto->tuple_to_nfattr(skb, tuple);
 	
 	
-	ip_conntrack_proto_put(proto);
+	NFA_NEST_END(skb, nest_parms);
 
 
 	return ret;
 	return ret;
 
 
@@ -75,27 +73,40 @@ nfattr_failure:
 }
 }
 
 
 static inline int
 static inline int
-ctnetlink_dump_tuples(struct sk_buff *skb, 
-		      const struct ip_conntrack_tuple *tuple)
+ctnetlink_dump_tuples_ip(struct sk_buff *skb,
+			 const struct ip_conntrack_tuple *tuple)
 {
 {
-	struct nfattr *nest_parms;
-	int ret;
+	struct nfattr *nest_parms = NFA_NEST(skb, CTA_TUPLE_IP);
 	
 	
-	nest_parms = NFA_NEST(skb, CTA_TUPLE_IP);
 	NFA_PUT(skb, CTA_IP_V4_SRC, sizeof(u_int32_t), &tuple->src.ip);
 	NFA_PUT(skb, CTA_IP_V4_SRC, sizeof(u_int32_t), &tuple->src.ip);
 	NFA_PUT(skb, CTA_IP_V4_DST, sizeof(u_int32_t), &tuple->dst.ip);
 	NFA_PUT(skb, CTA_IP_V4_DST, sizeof(u_int32_t), &tuple->dst.ip);
-	NFA_NEST_END(skb, nest_parms);
 
 
-	nest_parms = NFA_NEST(skb, CTA_TUPLE_PROTO);
-	ret = ctnetlink_dump_tuples_proto(skb, tuple);
 	NFA_NEST_END(skb, nest_parms);
 	NFA_NEST_END(skb, nest_parms);
 
 
-	return ret;
+	return 0;
 
 
 nfattr_failure:
 nfattr_failure:
 	return -1;
 	return -1;
 }
 }
 
 
+static inline int
+ctnetlink_dump_tuples(struct sk_buff *skb,
+		      const struct ip_conntrack_tuple *tuple)
+{
+	int ret;
+	struct ip_conntrack_protocol *proto;
+
+	ret = ctnetlink_dump_tuples_ip(skb, tuple);
+	if (unlikely(ret < 0))
+		return ret;
+
+	proto = ip_conntrack_proto_find_get(tuple->dst.protonum);
+	ret = ctnetlink_dump_tuples_proto(skb, tuple, proto);
+	ip_conntrack_proto_put(proto);
+
+	return ret;
+}
+
 static inline int
 static inline int
 ctnetlink_dump_status(struct sk_buff *skb, const struct ip_conntrack *ct)
 ctnetlink_dump_status(struct sk_buff *skb, const struct ip_conntrack *ct)
 {
 {
@@ -1134,6 +1145,33 @@ nfattr_failure:
 	return -1;
 	return -1;
 }			
 }			
 
 
+static inline int
+ctnetlink_exp_dump_mask(struct sk_buff *skb,
+			const struct ip_conntrack_tuple *tuple,
+			const struct ip_conntrack_tuple *mask)
+{
+	int ret;
+	struct ip_conntrack_protocol *proto;
+	struct nfattr *nest_parms = NFA_NEST(skb, CTA_EXPECT_MASK);
+
+	ret = ctnetlink_dump_tuples_ip(skb, mask);
+	if (unlikely(ret < 0))
+		goto nfattr_failure;
+
+	proto = ip_conntrack_proto_find_get(tuple->dst.protonum);
+	ret = ctnetlink_dump_tuples_proto(skb, mask, proto);
+	ip_conntrack_proto_put(proto);
+	if (unlikely(ret < 0))
+		goto nfattr_failure;
+
+	NFA_NEST_END(skb, nest_parms);
+
+	return 0;
+
+nfattr_failure:
+	return -1;
+}
+
 static inline int
 static inline int
 ctnetlink_exp_dump_expect(struct sk_buff *skb,
 ctnetlink_exp_dump_expect(struct sk_buff *skb,
                           const struct ip_conntrack_expect *exp)
                           const struct ip_conntrack_expect *exp)
@@ -1144,7 +1182,7 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb,
 
 
 	if (ctnetlink_exp_dump_tuple(skb, &exp->tuple, CTA_EXPECT_TUPLE) < 0)
 	if (ctnetlink_exp_dump_tuple(skb, &exp->tuple, CTA_EXPECT_TUPLE) < 0)
 		goto nfattr_failure;
 		goto nfattr_failure;
-	if (ctnetlink_exp_dump_tuple(skb, &exp->mask, CTA_EXPECT_MASK) < 0)
+	if (ctnetlink_exp_dump_mask(skb, &exp->tuple, &exp->mask) < 0)
 		goto nfattr_failure;
 		goto nfattr_failure;
 	if (ctnetlink_exp_dump_tuple(skb,
 	if (ctnetlink_exp_dump_tuple(skb,
 				 &master->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
 				 &master->tuplehash[IP_CT_DIR_ORIGINAL].tuple,

+ 9 - 6
net/ipv4/netfilter/ip_tables.c

@@ -1335,12 +1335,14 @@ icmp_checkentry(const char *tablename,
 static struct ipt_target ipt_standard_target = {
 static struct ipt_target ipt_standard_target = {
 	.name		= IPT_STANDARD_TARGET,
 	.name		= IPT_STANDARD_TARGET,
 	.targetsize	= sizeof(int),
 	.targetsize	= sizeof(int),
+	.family		= AF_INET,
 };
 };
 
 
 static struct ipt_target ipt_error_target = {
 static struct ipt_target ipt_error_target = {
 	.name		= IPT_ERROR_TARGET,
 	.name		= IPT_ERROR_TARGET,
 	.target		= ipt_error,
 	.target		= ipt_error,
 	.targetsize	= IPT_FUNCTION_MAXNAMELEN,
 	.targetsize	= IPT_FUNCTION_MAXNAMELEN,
+	.family		= AF_INET,
 };
 };
 
 
 static struct nf_sockopt_ops ipt_sockopts = {
 static struct nf_sockopt_ops ipt_sockopts = {
@@ -1358,6 +1360,7 @@ static struct ipt_match icmp_matchstruct = {
 	.match		= icmp_match,
 	.match		= icmp_match,
 	.matchsize	= sizeof(struct ipt_icmp),
 	.matchsize	= sizeof(struct ipt_icmp),
 	.proto		= IPPROTO_ICMP,
 	.proto		= IPPROTO_ICMP,
+	.family		= AF_INET,
 	.checkentry	= icmp_checkentry,
 	.checkentry	= icmp_checkentry,
 };
 };
 
 
@@ -1368,9 +1371,9 @@ static int __init init(void)
 	xt_proto_init(AF_INET);
 	xt_proto_init(AF_INET);
 
 
 	/* Noone else will be downing sem now, so we won't sleep */
 	/* Noone else will be downing sem now, so we won't sleep */
-	xt_register_target(AF_INET, &ipt_standard_target);
-	xt_register_target(AF_INET, &ipt_error_target);
-	xt_register_match(AF_INET, &icmp_matchstruct);
+	xt_register_target(&ipt_standard_target);
+	xt_register_target(&ipt_error_target);
+	xt_register_match(&icmp_matchstruct);
 
 
 	/* Register setsockopt */
 	/* Register setsockopt */
 	ret = nf_register_sockopt(&ipt_sockopts);
 	ret = nf_register_sockopt(&ipt_sockopts);
@@ -1387,9 +1390,9 @@ static void __exit fini(void)
 {
 {
 	nf_unregister_sockopt(&ipt_sockopts);
 	nf_unregister_sockopt(&ipt_sockopts);
 
 
-	xt_unregister_match(AF_INET, &icmp_matchstruct);
-	xt_unregister_target(AF_INET, &ipt_error_target);
-	xt_unregister_target(AF_INET, &ipt_standard_target);
+	xt_unregister_match(&icmp_matchstruct);
+	xt_unregister_target(&ipt_error_target);
+	xt_unregister_target(&ipt_standard_target);
 
 
 	xt_proto_fini(AF_INET);
 	xt_proto_fini(AF_INET);
 }
 }

+ 1 - 0
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c

@@ -568,6 +568,7 @@ static int init_or_cleanup(int init)
 	return ret;
 	return ret;
 }
 }
 
 
+MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET));
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
 
 
 static int __init init(void)
 static int __init init(void)

+ 2 - 2
net/ipv6/ipv6_sockglue.c

@@ -907,7 +907,7 @@ int ipv6_getsockopt(struct sock *sk, int level, int optname,
 	err = do_ipv6_getsockopt(sk, level, optname, optval, optlen);
 	err = do_ipv6_getsockopt(sk, level, optname, optval, optlen);
 #ifdef CONFIG_NETFILTER
 #ifdef CONFIG_NETFILTER
 	/* we need to exclude all possible EINVALs except default case */
 	/* we need to exclude all possible EINVALs except default case */
-	if (err == -ENOPROTOOPT && optname != IPV6_ADDRFORM &&
+	if (err == -EINVAL && optname != IPV6_ADDRFORM &&
 			optname != MCAST_MSFILTER) {
 			optname != MCAST_MSFILTER) {
 		int len;
 		int len;
 
 
@@ -944,7 +944,7 @@ int compat_ipv6_getsockopt(struct sock *sk, int level, int optname,
 	err = do_ipv6_getsockopt(sk, level, optname, optval, optlen);
 	err = do_ipv6_getsockopt(sk, level, optname, optval, optlen);
 #ifdef CONFIG_NETFILTER
 #ifdef CONFIG_NETFILTER
 	/* we need to exclude all possible EINVALs except default case */
 	/* we need to exclude all possible EINVALs except default case */
-	if (err == -ENOPROTOOPT && optname != IPV6_ADDRFORM &&
+	if (err == -EINVAL && optname != IPV6_ADDRFORM &&
 			optname != MCAST_MSFILTER) {
 			optname != MCAST_MSFILTER) {
 		int len;
 		int len;
 
 

+ 9 - 6
net/ipv6/netfilter/ip6_tables.c

@@ -1377,12 +1377,14 @@ icmp6_checkentry(const char *tablename,
 static struct ip6t_target ip6t_standard_target = {
 static struct ip6t_target ip6t_standard_target = {
 	.name		= IP6T_STANDARD_TARGET,
 	.name		= IP6T_STANDARD_TARGET,
 	.targetsize	= sizeof(int),
 	.targetsize	= sizeof(int),
+	.family		= AF_INET6,
 };
 };
 
 
 static struct ip6t_target ip6t_error_target = {
 static struct ip6t_target ip6t_error_target = {
 	.name		= IP6T_ERROR_TARGET,
 	.name		= IP6T_ERROR_TARGET,
 	.target		= ip6t_error,
 	.target		= ip6t_error,
 	.targetsize	= IP6T_FUNCTION_MAXNAMELEN,
 	.targetsize	= IP6T_FUNCTION_MAXNAMELEN,
+	.family		= AF_INET6,
 };
 };
 
 
 static struct nf_sockopt_ops ip6t_sockopts = {
 static struct nf_sockopt_ops ip6t_sockopts = {
@@ -1401,6 +1403,7 @@ static struct ip6t_match icmp6_matchstruct = {
 	.matchsize	= sizeof(struct ip6t_icmp),
 	.matchsize	= sizeof(struct ip6t_icmp),
 	.checkentry	= icmp6_checkentry,
 	.checkentry	= icmp6_checkentry,
 	.proto		= IPPROTO_ICMPV6,
 	.proto		= IPPROTO_ICMPV6,
+	.family		= AF_INET6,
 };
 };
 
 
 static int __init init(void)
 static int __init init(void)
@@ -1410,9 +1413,9 @@ static int __init init(void)
 	xt_proto_init(AF_INET6);
 	xt_proto_init(AF_INET6);
 
 
 	/* Noone else will be downing sem now, so we won't sleep */
 	/* Noone else will be downing sem now, so we won't sleep */
-	xt_register_target(AF_INET6, &ip6t_standard_target);
-	xt_register_target(AF_INET6, &ip6t_error_target);
-	xt_register_match(AF_INET6, &icmp6_matchstruct);
+	xt_register_target(&ip6t_standard_target);
+	xt_register_target(&ip6t_error_target);
+	xt_register_match(&icmp6_matchstruct);
 
 
 	/* Register setsockopt */
 	/* Register setsockopt */
 	ret = nf_register_sockopt(&ip6t_sockopts);
 	ret = nf_register_sockopt(&ip6t_sockopts);
@@ -1429,9 +1432,9 @@ static int __init init(void)
 static void __exit fini(void)
 static void __exit fini(void)
 {
 {
 	nf_unregister_sockopt(&ip6t_sockopts);
 	nf_unregister_sockopt(&ip6t_sockopts);
-	xt_unregister_match(AF_INET6, &icmp6_matchstruct);
-	xt_unregister_target(AF_INET6, &ip6t_error_target);
-	xt_unregister_target(AF_INET6, &ip6t_standard_target);
+	xt_unregister_match(&icmp6_matchstruct);
+	xt_unregister_target(&ip6t_error_target);
+	xt_unregister_target(&ip6t_standard_target);
 	xt_proto_fini(AF_INET6);
 	xt_proto_fini(AF_INET6);
 }
 }
 
 

+ 1 - 0
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c

@@ -584,6 +584,7 @@ static int init_or_cleanup(int init)
 	return ret;
 	return ret;
 }
 }
 
 
+MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET6));
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Yasuyuki KOZAKAI @USAGI <yasuyuki.kozakai@toshiba.co.jp>");
 MODULE_AUTHOR("Yasuyuki KOZAKAI @USAGI <yasuyuki.kozakai@toshiba.co.jp>");
 
 

+ 3 - 3
net/netfilter/Kconfig

@@ -11,7 +11,7 @@ config NETFILTER_NETLINK_QUEUE
 	tristate "Netfilter NFQUEUE over NFNETLINK interface"
 	tristate "Netfilter NFQUEUE over NFNETLINK interface"
 	depends on NETFILTER_NETLINK
 	depends on NETFILTER_NETLINK
 	help
 	help
-	  If this option isenabled, the kernel will include support
+	  If this option is enabled, the kernel will include support
 	  for queueing packets via NFNETLINK.
 	  for queueing packets via NFNETLINK.
 	  
 	  
 config NETFILTER_NETLINK_LOG
 config NETFILTER_NETLINK_LOG
@@ -66,7 +66,7 @@ config NF_CONNTRACK_EVENTS
 	help
 	help
 	  If this option is enabled, the connection tracking code will
 	  If this option is enabled, the connection tracking code will
 	  provide a notifier chain that can be used by other kernel code
 	  provide a notifier chain that can be used by other kernel code
-	  to get notified aboutchanges in the connection tracking state.
+	  to get notified about changes in the connection tracking state.
 
 
 	  If unsure, say `N'.
 	  If unsure, say `N'.
 
 
@@ -153,7 +153,7 @@ config NETFILTER_XT_TARGET_NFQUEUE
 	tristate '"NFQUEUE" target Support'
 	tristate '"NFQUEUE" target Support'
 	depends on NETFILTER_XTABLES
 	depends on NETFILTER_XTABLES
 	help
 	help
-	  This Target replaced the old obsolete QUEUE target.
+	  This target replaced the old obsolete QUEUE target.
 
 
 	  As opposed to QUEUE, it supports 65535 different queues,
 	  As opposed to QUEUE, it supports 65535 different queues,
 	  not just one.
 	  not just one.

+ 33 - 2
net/netfilter/nf_conntrack_core.c

@@ -23,6 +23,8 @@
  * 26 Jan 2006: Harald Welte <laforge@netfilter.org>
  * 26 Jan 2006: Harald Welte <laforge@netfilter.org>
  * 	- restructure nf_conn (introduce nf_conn_help)
  * 	- restructure nf_conn (introduce nf_conn_help)
  * 	- redesign 'features' how they were originally intended
  * 	- 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
  * Derived from net/ipv4/netfilter/ip_conntrack_core.c
  */
  */
@@ -85,8 +87,8 @@ unsigned int nf_ct_log_invalid;
 static LIST_HEAD(unconfirmed);
 static LIST_HEAD(unconfirmed);
 static int nf_conntrack_vmalloc;
 static int nf_conntrack_vmalloc;
 
 
-static unsigned int nf_conntrack_next_id = 1;
-static unsigned int nf_conntrack_expect_next_id = 1;
+static unsigned int nf_conntrack_next_id;
+static unsigned int nf_conntrack_expect_next_id;
 #ifdef CONFIG_NF_CONNTRACK_EVENTS
 #ifdef CONFIG_NF_CONNTRACK_EVENTS
 struct notifier_block *nf_conntrack_chain;
 struct notifier_block *nf_conntrack_chain;
 struct notifier_block *nf_conntrack_expect_chain;
 struct notifier_block *nf_conntrack_expect_chain;
@@ -241,6 +243,35 @@ void nf_ct_l3proto_put(struct nf_conntrack_l3proto *p)
 	module_put(p->me);
 	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 int nf_conntrack_hash_rnd_initted;
 static unsigned int nf_conntrack_hash_rnd;
 static unsigned int nf_conntrack_hash_rnd;
 
 

+ 62 - 22
net/netfilter/nf_conntrack_netlink.c

@@ -4,7 +4,7 @@
  * (C) 2001 by Jay Schulist <jschlst@samba.org>
  * (C) 2001 by Jay Schulist <jschlst@samba.org>
  * (C) 2002-2006 by Harald Welte <laforge@gnumonks.org>
  * (C) 2002-2006 by Harald Welte <laforge@gnumonks.org>
  * (C) 2003 by Patrick Mchardy <kaber@trash.net>
  * (C) 2003 by Patrick Mchardy <kaber@trash.net>
- * (C) 2005 by Pablo Neira Ayuso <pablo@eurodev.net>
+ * (C) 2005-2006 by Pablo Neira Ayuso <pablo@eurodev.net>
  *
  *
  * I've reworked this stuff to use attributes instead of conntrack 
  * I've reworked this stuff to use attributes instead of conntrack 
  * structures. 5.44 am. I need more tea. --pablo 05/07/11.
  * structures. 5.44 am. I need more tea. --pablo 05/07/11.
@@ -55,20 +55,18 @@ static char __initdata version[] = "0.93";
 
 
 static inline int
 static inline int
 ctnetlink_dump_tuples_proto(struct sk_buff *skb, 
 ctnetlink_dump_tuples_proto(struct sk_buff *skb, 
-			    const struct nf_conntrack_tuple *tuple)
+			    const struct nf_conntrack_tuple *tuple,
+			    struct nf_conntrack_protocol *proto)
 {
 {
-	struct nf_conntrack_protocol *proto;
 	int ret = 0;
 	int ret = 0;
+	struct nfattr *nest_parms = NFA_NEST(skb, CTA_TUPLE_PROTO);
 
 
 	NFA_PUT(skb, CTA_PROTO_NUM, sizeof(u_int8_t), &tuple->dst.protonum);
 	NFA_PUT(skb, CTA_PROTO_NUM, sizeof(u_int8_t), &tuple->dst.protonum);
 
 
-	/* If no protocol helper is found, this function will return the
-	 * generic protocol helper, so proto won't *ever* be NULL */
-	proto = nf_ct_proto_find_get(tuple->src.l3num, tuple->dst.protonum);
 	if (likely(proto->tuple_to_nfattr))
 	if (likely(proto->tuple_to_nfattr))
 		ret = proto->tuple_to_nfattr(skb, tuple);
 		ret = proto->tuple_to_nfattr(skb, tuple);
 	
 	
-	nf_ct_proto_put(proto);
+	NFA_NEST_END(skb, nest_parms);
 
 
 	return ret;
 	return ret;
 
 
@@ -77,33 +75,44 @@ nfattr_failure:
 }
 }
 
 
 static inline int
 static inline int
-ctnetlink_dump_tuples(struct sk_buff *skb, 
-		      const struct nf_conntrack_tuple *tuple)
+ctnetlink_dump_tuples_ip(struct sk_buff *skb,
+			 const struct nf_conntrack_tuple *tuple,
+			 struct nf_conntrack_l3proto *l3proto)
 {
 {
-	struct nfattr *nest_parms;
-	struct nf_conntrack_l3proto *l3proto;
 	int ret = 0;
 	int ret = 0;
-	
-	l3proto = nf_ct_l3proto_find_get(tuple->src.l3num);
-	
-	nest_parms = NFA_NEST(skb, CTA_TUPLE_IP);
+	struct nfattr *nest_parms = NFA_NEST(skb, CTA_TUPLE_IP);
+
 	if (likely(l3proto->tuple_to_nfattr))
 	if (likely(l3proto->tuple_to_nfattr))
 		ret = l3proto->tuple_to_nfattr(skb, tuple);
 		ret = l3proto->tuple_to_nfattr(skb, tuple);
+
 	NFA_NEST_END(skb, nest_parms);
 	NFA_NEST_END(skb, nest_parms);
 
 
+	return ret;
+
+nfattr_failure:
+	return -1;
+}
+
+static inline int
+ctnetlink_dump_tuples(struct sk_buff *skb,
+		      const struct nf_conntrack_tuple *tuple)
+{
+	int ret;
+	struct nf_conntrack_l3proto *l3proto;
+	struct nf_conntrack_protocol *proto;
+
+	l3proto = nf_ct_l3proto_find_get(tuple->src.l3num);
+	ret = ctnetlink_dump_tuples_ip(skb, tuple, l3proto);
 	nf_ct_l3proto_put(l3proto);
 	nf_ct_l3proto_put(l3proto);
 
 
 	if (unlikely(ret < 0))
 	if (unlikely(ret < 0))
 		return ret;
 		return ret;
 
 
-	nest_parms = NFA_NEST(skb, CTA_TUPLE_PROTO);
-	ret = ctnetlink_dump_tuples_proto(skb, tuple);
-	NFA_NEST_END(skb, nest_parms);
+	proto = nf_ct_proto_find_get(tuple->src.l3num, tuple->dst.protonum);
+	ret = ctnetlink_dump_tuples_proto(skb, tuple, proto);
+	nf_ct_proto_put(proto);
 
 
 	return ret;
 	return ret;
-
-nfattr_failure:
-	return -1;
 }
 }
 
 
 static inline int
 static inline int
@@ -1152,6 +1161,37 @@ nfattr_failure:
 	return -1;
 	return -1;
 }			
 }			
 
 
+static inline int
+ctnetlink_exp_dump_mask(struct sk_buff *skb,
+			const struct nf_conntrack_tuple *tuple,
+			const struct nf_conntrack_tuple *mask)
+{
+	int ret;
+	struct nf_conntrack_l3proto *l3proto;
+	struct nf_conntrack_protocol *proto;
+	struct nfattr *nest_parms = NFA_NEST(skb, CTA_EXPECT_MASK);
+
+	l3proto = nf_ct_l3proto_find_get(tuple->src.l3num);
+	ret = ctnetlink_dump_tuples_ip(skb, mask, l3proto);
+	nf_ct_l3proto_put(l3proto);
+
+	if (unlikely(ret < 0))
+		goto nfattr_failure;
+
+	proto = nf_ct_proto_find_get(tuple->src.l3num, tuple->dst.protonum);
+	ret = ctnetlink_dump_tuples_proto(skb, mask, proto);
+	nf_ct_proto_put(proto);
+	if (unlikely(ret < 0))
+		goto nfattr_failure;
+
+	NFA_NEST_END(skb, nest_parms);
+
+	return 0;
+
+nfattr_failure:
+	return -1;
+}
+
 static inline int
 static inline int
 ctnetlink_exp_dump_expect(struct sk_buff *skb,
 ctnetlink_exp_dump_expect(struct sk_buff *skb,
                           const struct nf_conntrack_expect *exp)
                           const struct nf_conntrack_expect *exp)
@@ -1162,7 +1202,7 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb,
 
 
 	if (ctnetlink_exp_dump_tuple(skb, &exp->tuple, CTA_EXPECT_TUPLE) < 0)
 	if (ctnetlink_exp_dump_tuple(skb, &exp->tuple, CTA_EXPECT_TUPLE) < 0)
 		goto nfattr_failure;
 		goto nfattr_failure;
-	if (ctnetlink_exp_dump_tuple(skb, &exp->mask, CTA_EXPECT_MASK) < 0)
+	if (ctnetlink_exp_dump_mask(skb, &exp->tuple, &exp->mask) < 0)
 		goto nfattr_failure;
 		goto nfattr_failure;
 	if (ctnetlink_exp_dump_tuple(skb,
 	if (ctnetlink_exp_dump_tuple(skb,
 				 &master->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
 				 &master->tuplehash[IP_CT_DIR_ORIGINAL].tuple,

+ 2 - 0
net/netfilter/nf_conntrack_standalone.c

@@ -834,6 +834,8 @@ EXPORT_SYMBOL_GPL(__nf_ct_event_cache_init);
 EXPORT_PER_CPU_SYMBOL_GPL(nf_conntrack_ecache);
 EXPORT_PER_CPU_SYMBOL_GPL(nf_conntrack_ecache);
 EXPORT_SYMBOL_GPL(nf_ct_deliver_cached_events);
 EXPORT_SYMBOL_GPL(nf_ct_deliver_cached_events);
 #endif
 #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_register);
 EXPORT_SYMBOL(nf_conntrack_l3proto_unregister);
 EXPORT_SYMBOL(nf_conntrack_l3proto_unregister);
 EXPORT_SYMBOL(nf_conntrack_protocol_register);
 EXPORT_SYMBOL(nf_conntrack_protocol_register);

+ 10 - 9
net/netfilter/nfnetlink_queue.c

@@ -354,16 +354,17 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
 	QDEBUG("entered\n");
 	QDEBUG("entered\n");
 
 
 	/* all macros expand to constant values at compile time */
 	/* all macros expand to constant values at compile time */
-	size =    NLMSG_SPACE(sizeof(struct nfqnl_msg_packet_hdr))
-		+ NLMSG_SPACE(sizeof(u_int32_t))	/* ifindex */
-		+ NLMSG_SPACE(sizeof(u_int32_t))	/* ifindex */
+	size =    NLMSG_SPACE(sizeof(struct nfgenmsg)) +
+		+ NFA_SPACE(sizeof(struct nfqnl_msg_packet_hdr))
+		+ NFA_SPACE(sizeof(u_int32_t))	/* ifindex */
+		+ NFA_SPACE(sizeof(u_int32_t))	/* ifindex */
 #ifdef CONFIG_BRIDGE_NETFILTER
 #ifdef CONFIG_BRIDGE_NETFILTER
-		+ NLMSG_SPACE(sizeof(u_int32_t))	/* ifindex */
-		+ NLMSG_SPACE(sizeof(u_int32_t))	/* ifindex */
+		+ NFA_SPACE(sizeof(u_int32_t))	/* ifindex */
+		+ NFA_SPACE(sizeof(u_int32_t))	/* ifindex */
 #endif
 #endif
-		+ NLMSG_SPACE(sizeof(u_int32_t))	/* mark */
-		+ NLMSG_SPACE(sizeof(struct nfqnl_msg_packet_hw))
-		+ NLMSG_SPACE(sizeof(struct nfqnl_msg_packet_timestamp));
+		+ NFA_SPACE(sizeof(u_int32_t))	/* mark */
+		+ NFA_SPACE(sizeof(struct nfqnl_msg_packet_hw))
+		+ NFA_SPACE(sizeof(struct nfqnl_msg_packet_timestamp));
 
 
 	outdev = entinf->outdev;
 	outdev = entinf->outdev;
 
 
@@ -388,7 +389,7 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
 		else
 		else
 			data_len = queue->copy_range;
 			data_len = queue->copy_range;
 		
 		
-		size += NLMSG_SPACE(data_len);
+		size += NFA_SPACE(data_len);
 		break;
 		break;
 	
 	
 	default:
 	default:

+ 10 - 6
net/netfilter/x_tables.c

@@ -60,9 +60,9 @@ static const char *xt_prefix[NPROTO] = {
 
 
 /* Registration hooks for targets. */
 /* Registration hooks for targets. */
 int
 int
-xt_register_target(int af, struct xt_target *target)
+xt_register_target(struct xt_target *target)
 {
 {
-	int ret;
+	int ret, af = target->family;
 
 
 	ret = down_interruptible(&xt[af].mutex);
 	ret = down_interruptible(&xt[af].mutex);
 	if (ret != 0)
 	if (ret != 0)
@@ -74,8 +74,10 @@ xt_register_target(int af, struct xt_target *target)
 EXPORT_SYMBOL(xt_register_target);
 EXPORT_SYMBOL(xt_register_target);
 
 
 void
 void
-xt_unregister_target(int af, struct xt_target *target)
+xt_unregister_target(struct xt_target *target)
 {
 {
+	int af = target->family;
+
 	down(&xt[af].mutex);
 	down(&xt[af].mutex);
 	LIST_DELETE(&xt[af].target, target);
 	LIST_DELETE(&xt[af].target, target);
 	up(&xt[af].mutex);
 	up(&xt[af].mutex);
@@ -83,9 +85,9 @@ xt_unregister_target(int af, struct xt_target *target)
 EXPORT_SYMBOL(xt_unregister_target);
 EXPORT_SYMBOL(xt_unregister_target);
 
 
 int
 int
-xt_register_match(int af, struct xt_match *match)
+xt_register_match(struct xt_match *match)
 {
 {
-	int ret;
+	int ret, af = match->family;
 
 
 	ret = down_interruptible(&xt[af].mutex);
 	ret = down_interruptible(&xt[af].mutex);
 	if (ret != 0)
 	if (ret != 0)
@@ -99,8 +101,10 @@ xt_register_match(int af, struct xt_match *match)
 EXPORT_SYMBOL(xt_register_match);
 EXPORT_SYMBOL(xt_register_match);
 
 
 void
 void
-xt_unregister_match(int af, struct xt_match *match)
+xt_unregister_match(struct xt_match *match)
 {
 {
+	int af =  match->family;
+
 	down(&xt[af].mutex);
 	down(&xt[af].mutex);
 	LIST_DELETE(&xt[af].match, match);
 	LIST_DELETE(&xt[af].match, match);
 	up(&xt[af].mutex);
 	up(&xt[af].mutex);

+ 7 - 5
net/netfilter/xt_CLASSIFY.c

@@ -47,6 +47,7 @@ static struct xt_target classify_reg = {
 	.table		= "mangle",
 	.table		= "mangle",
 	.hooks		= (1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_FORWARD) |
 	.hooks		= (1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_FORWARD) |
 		          (1 << NF_IP_POST_ROUTING),
 		          (1 << NF_IP_POST_ROUTING),
+	.family		= AF_INET,
 	.me 		= THIS_MODULE,
 	.me 		= THIS_MODULE,
 };
 };
 static struct xt_target classify6_reg = { 
 static struct xt_target classify6_reg = { 
@@ -56,6 +57,7 @@ static struct xt_target classify6_reg = {
 	.table		= "mangle",
 	.table		= "mangle",
 	.hooks		= (1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_FORWARD) |
 	.hooks		= (1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_FORWARD) |
 		          (1 << NF_IP_POST_ROUTING),
 		          (1 << NF_IP_POST_ROUTING),
+	.family		= AF_INET6,
 	.me 		= THIS_MODULE,
 	.me 		= THIS_MODULE,
 };
 };
 
 
@@ -64,21 +66,21 @@ static int __init init(void)
 {
 {
 	int ret;
 	int ret;
 
 
-	ret = xt_register_target(AF_INET, &classify_reg);
+	ret = xt_register_target(&classify_reg);
 	if (ret)
 	if (ret)
 		return ret;
 		return ret;
 
 
-	ret = xt_register_target(AF_INET6, &classify6_reg);
+	ret = xt_register_target(&classify6_reg);
 	if (ret)
 	if (ret)
-		xt_unregister_target(AF_INET, &classify_reg);
+		xt_unregister_target(&classify_reg);
 
 
 	return ret;
 	return ret;
 }
 }
 
 
 static void __exit fini(void)
 static void __exit fini(void)
 {
 {
-	xt_unregister_target(AF_INET, &classify_reg);
-	xt_unregister_target(AF_INET6, &classify6_reg);
+	xt_unregister_target(&classify_reg);
+	xt_unregister_target(&classify6_reg);
 }
 }
 
 
 module_init(init);
 module_init(init);

+ 7 - 5
net/netfilter/xt_CONNMARK.c

@@ -102,6 +102,7 @@ static struct xt_target connmark_reg = {
 	.target		= target,
 	.target		= target,
 	.targetsize	= sizeof(struct xt_connmark_target_info),
 	.targetsize	= sizeof(struct xt_connmark_target_info),
 	.checkentry	= checkentry,
 	.checkentry	= checkentry,
+	.family		= AF_INET,
 	.me		= THIS_MODULE
 	.me		= THIS_MODULE
 };
 };
 
 
@@ -110,6 +111,7 @@ static struct xt_target connmark6_reg = {
 	.target		= target,
 	.target		= target,
 	.targetsize	= sizeof(struct xt_connmark_target_info),
 	.targetsize	= sizeof(struct xt_connmark_target_info),
 	.checkentry	= checkentry,
 	.checkentry	= checkentry,
+	.family		= AF_INET6,
 	.me		= THIS_MODULE
 	.me		= THIS_MODULE
 };
 };
 
 
@@ -119,21 +121,21 @@ static int __init init(void)
 
 
 	need_conntrack();
 	need_conntrack();
 
 
-	ret = xt_register_target(AF_INET, &connmark_reg);
+	ret = xt_register_target(&connmark_reg);
 	if (ret)
 	if (ret)
 		return ret;
 		return ret;
 
 
-	ret = xt_register_target(AF_INET6, &connmark6_reg);
+	ret = xt_register_target(&connmark6_reg);
 	if (ret)
 	if (ret)
-		xt_unregister_target(AF_INET, &connmark_reg);
+		xt_unregister_target(&connmark_reg);
 
 
 	return ret;
 	return ret;
 }
 }
 
 
 static void __exit fini(void)
 static void __exit fini(void)
 {
 {
-	xt_unregister_target(AF_INET, &connmark_reg);
-	xt_unregister_target(AF_INET6, &connmark6_reg);
+	xt_unregister_target(&connmark_reg);
+	xt_unregister_target(&connmark6_reg);
 }
 }
 
 
 module_init(init);
 module_init(init);

+ 12 - 9
net/netfilter/xt_MARK.c

@@ -119,6 +119,7 @@ static struct xt_target ipt_mark_reg_v0 = {
 	.table		= "mangle",
 	.table		= "mangle",
 	.checkentry	= checkentry_v0,
 	.checkentry	= checkentry_v0,
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
+	.family		= AF_INET,
 	.revision	= 0,
 	.revision	= 0,
 };
 };
 
 
@@ -129,6 +130,7 @@ static struct xt_target ipt_mark_reg_v1 = {
 	.table		= "mangle",
 	.table		= "mangle",
 	.checkentry	= checkentry_v1,
 	.checkentry	= checkentry_v1,
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
+	.family		= AF_INET,
 	.revision	= 1,
 	.revision	= 1,
 };
 };
 
 
@@ -139,6 +141,7 @@ static struct xt_target ip6t_mark_reg_v0 = {
 	.table		= "mangle",
 	.table		= "mangle",
 	.checkentry	= checkentry_v0,
 	.checkentry	= checkentry_v0,
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
+	.family		= AF_INET6,
 	.revision	= 0,
 	.revision	= 0,
 };
 };
 
 
@@ -146,18 +149,18 @@ static int __init init(void)
 {
 {
 	int err;
 	int err;
 
 
-	err = xt_register_target(AF_INET, &ipt_mark_reg_v0);
+	err = xt_register_target(&ipt_mark_reg_v0);
 	if (err)
 	if (err)
 		return err;
 		return err;
 
 
-	err = xt_register_target(AF_INET, &ipt_mark_reg_v1);
+	err = xt_register_target(&ipt_mark_reg_v1);
 	if (err)
 	if (err)
-		xt_unregister_target(AF_INET, &ipt_mark_reg_v0);
+		xt_unregister_target(&ipt_mark_reg_v0);
 
 
-	err = xt_register_target(AF_INET6, &ip6t_mark_reg_v0);
+	err = xt_register_target(&ip6t_mark_reg_v0);
 	if (err) {
 	if (err) {
-		xt_unregister_target(AF_INET, &ipt_mark_reg_v0);
-		xt_unregister_target(AF_INET, &ipt_mark_reg_v1);
+		xt_unregister_target(&ipt_mark_reg_v0);
+		xt_unregister_target(&ipt_mark_reg_v1);
 	}
 	}
 
 
 	return err;
 	return err;
@@ -165,9 +168,9 @@ static int __init init(void)
 
 
 static void __exit fini(void)
 static void __exit fini(void)
 {
 {
-	xt_unregister_target(AF_INET, &ipt_mark_reg_v0);
-	xt_unregister_target(AF_INET, &ipt_mark_reg_v1);
-	xt_unregister_target(AF_INET6, &ip6t_mark_reg_v0);
+	xt_unregister_target(&ipt_mark_reg_v0);
+	xt_unregister_target(&ipt_mark_reg_v1);
+	xt_unregister_target(&ip6t_mark_reg_v0);
 }
 }
 
 
 module_init(init);
 module_init(init);

+ 11 - 8
net/netfilter/xt_NFQUEUE.c

@@ -41,6 +41,7 @@ static struct xt_target ipt_NFQ_reg = {
 	.name		= "NFQUEUE",
 	.name		= "NFQUEUE",
 	.target		= target,
 	.target		= target,
 	.targetsize	= sizeof(struct xt_NFQ_info),
 	.targetsize	= sizeof(struct xt_NFQ_info),
+	.family		= AF_INET,
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
 
 
@@ -48,6 +49,7 @@ static struct xt_target ip6t_NFQ_reg = {
 	.name		= "NFQUEUE",
 	.name		= "NFQUEUE",
 	.target		= target,
 	.target		= target,
 	.targetsize	= sizeof(struct xt_NFQ_info),
 	.targetsize	= sizeof(struct xt_NFQ_info),
+	.family		= AF_INET6,
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
 
 
@@ -55,36 +57,37 @@ static struct xt_target arpt_NFQ_reg = {
 	.name		= "NFQUEUE",
 	.name		= "NFQUEUE",
 	.target		= target,
 	.target		= target,
 	.targetsize	= sizeof(struct xt_NFQ_info),
 	.targetsize	= sizeof(struct xt_NFQ_info),
+	.family		= NF_ARP,
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
 
 
 static int __init init(void)
 static int __init init(void)
 {
 {
 	int ret;
 	int ret;
-	ret = xt_register_target(AF_INET, &ipt_NFQ_reg);
+	ret = xt_register_target(&ipt_NFQ_reg);
 	if (ret)
 	if (ret)
 		return ret;
 		return ret;
-	ret = xt_register_target(AF_INET6, &ip6t_NFQ_reg);
+	ret = xt_register_target(&ip6t_NFQ_reg);
 	if (ret)
 	if (ret)
 		goto out_ip;
 		goto out_ip;
-	ret = xt_register_target(NF_ARP, &arpt_NFQ_reg);
+	ret = xt_register_target(&arpt_NFQ_reg);
 	if (ret)
 	if (ret)
 		goto out_ip6;
 		goto out_ip6;
 
 
 	return ret;
 	return ret;
 out_ip6:
 out_ip6:
-	xt_unregister_target(AF_INET6, &ip6t_NFQ_reg);
+	xt_unregister_target(&ip6t_NFQ_reg);
 out_ip:
 out_ip:
-	xt_unregister_target(AF_INET, &ipt_NFQ_reg);
+	xt_unregister_target(&ipt_NFQ_reg);
 
 
 	return ret;
 	return ret;
 }
 }
 
 
 static void __exit fini(void)
 static void __exit fini(void)
 {
 {
-	xt_unregister_target(NF_ARP, &arpt_NFQ_reg);
-	xt_unregister_target(AF_INET6, &ip6t_NFQ_reg);
-	xt_unregister_target(AF_INET, &ipt_NFQ_reg);
+	xt_unregister_target(&arpt_NFQ_reg);
+	xt_unregister_target(&ip6t_NFQ_reg);
+	xt_unregister_target(&ipt_NFQ_reg);
 }
 }
 
 
 module_init(init);
 module_init(init);

+ 7 - 5
net/netfilter/xt_NOTRACK.c

@@ -39,6 +39,7 @@ static struct xt_target notrack_reg = {
 	.target		= target,
 	.target		= target,
 	.targetsize	= 0,
 	.targetsize	= 0,
 	.table		= "raw",
 	.table		= "raw",
+	.family		= AF_INET,
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
 
 
@@ -47,6 +48,7 @@ static struct xt_target notrack6_reg = {
 	.target		= target,
 	.target		= target,
 	.targetsize	= 0,
 	.targetsize	= 0,
 	.table		= "raw",
 	.table		= "raw",
+	.family		= AF_INET6,
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
 
 
@@ -54,21 +56,21 @@ static int __init init(void)
 {
 {
 	int ret;
 	int ret;
 
 
-	ret = xt_register_target(AF_INET, &notrack_reg);
+	ret = xt_register_target(&notrack_reg);
 	if (ret)
 	if (ret)
 		return ret;
 		return ret;
 
 
-	ret = xt_register_target(AF_INET6, &notrack6_reg);
+	ret = xt_register_target(&notrack6_reg);
 	if (ret)
 	if (ret)
-		xt_unregister_target(AF_INET, &notrack_reg);
+		xt_unregister_target(&notrack_reg);
 
 
 	return ret;
 	return ret;
 }
 }
 
 
 static void __exit fini(void)
 static void __exit fini(void)
 {
 {
-	xt_unregister_target(AF_INET6, &notrack6_reg);
-	xt_unregister_target(AF_INET, &notrack_reg);
+	xt_unregister_target(&notrack6_reg);
+	xt_unregister_target(&notrack_reg);
 }
 }
 
 
 module_init(init);
 module_init(init);

+ 7 - 5
net/netfilter/xt_comment.c

@@ -33,6 +33,7 @@ static struct xt_match comment_match = {
 	.name		= "comment",
 	.name		= "comment",
 	.match		= match,
 	.match		= match,
 	.matchsize	= sizeof(struct xt_comment_info),
 	.matchsize	= sizeof(struct xt_comment_info),
+	.family		= AF_INET,
 	.me		= THIS_MODULE
 	.me		= THIS_MODULE
 };
 };
 
 
@@ -40,6 +41,7 @@ static struct xt_match comment6_match = {
 	.name		= "comment",
 	.name		= "comment",
 	.match		= match,
 	.match		= match,
 	.matchsize	= sizeof(struct xt_comment_info),
 	.matchsize	= sizeof(struct xt_comment_info),
+	.family		= AF_INET6,
 	.me		= THIS_MODULE
 	.me		= THIS_MODULE
 };
 };
 
 
@@ -47,21 +49,21 @@ static int __init init(void)
 {
 {
 	int ret;
 	int ret;
 
 
-	ret = xt_register_match(AF_INET, &comment_match);
+	ret = xt_register_match(&comment_match);
 	if (ret)
 	if (ret)
 		return ret;
 		return ret;
 
 
-	ret = xt_register_match(AF_INET6, &comment6_match);
+	ret = xt_register_match(&comment6_match);
 	if (ret)
 	if (ret)
-		xt_unregister_match(AF_INET, &comment_match);
+		xt_unregister_match(&comment_match);
 
 
 	return ret;
 	return ret;
 }
 }
 
 
 static void __exit fini(void)
 static void __exit fini(void)
 {
 {
-	xt_unregister_match(AF_INET, &comment_match);
-	xt_unregister_match(AF_INET6, &comment6_match);
+	xt_unregister_match(&comment_match);
+	xt_unregister_match(&comment6_match);
 }
 }
 
 
 module_init(init);
 module_init(init);

+ 7 - 5
net/netfilter/xt_connbytes.c

@@ -148,6 +148,7 @@ static struct xt_match connbytes_match = {
 	.match		= match,
 	.match		= match,
 	.checkentry	= check,
 	.checkentry	= check,
 	.matchsize	= sizeof(struct xt_connbytes_info),
 	.matchsize	= sizeof(struct xt_connbytes_info),
+	.family		= AF_INET,
 	.me		= THIS_MODULE
 	.me		= THIS_MODULE
 };
 };
 static struct xt_match connbytes6_match = {
 static struct xt_match connbytes6_match = {
@@ -155,26 +156,27 @@ static struct xt_match connbytes6_match = {
 	.match		= match,
 	.match		= match,
 	.checkentry	= check,
 	.checkentry	= check,
 	.matchsize	= sizeof(struct xt_connbytes_info),
 	.matchsize	= sizeof(struct xt_connbytes_info),
+	.family		= AF_INET6,
 	.me		= THIS_MODULE
 	.me		= THIS_MODULE
 };
 };
 
 
 static int __init init(void)
 static int __init init(void)
 {
 {
 	int ret;
 	int ret;
-	ret = xt_register_match(AF_INET, &connbytes_match);
+	ret = xt_register_match(&connbytes_match);
 	if (ret)
 	if (ret)
 		return ret;
 		return ret;
 
 
-	ret = xt_register_match(AF_INET6, &connbytes6_match);
+	ret = xt_register_match(&connbytes6_match);
 	if (ret)
 	if (ret)
-		xt_unregister_match(AF_INET, &connbytes_match);
+		xt_unregister_match(&connbytes_match);
 	return ret;
 	return ret;
 }
 }
 
 
 static void __exit fini(void)
 static void __exit fini(void)
 {
 {
-	xt_unregister_match(AF_INET, &connbytes_match);
-	xt_unregister_match(AF_INET6, &connbytes6_match);
+	xt_unregister_match(&connbytes_match);
+	xt_unregister_match(&connbytes6_match);
 }
 }
 
 
 module_init(init);
 module_init(init);

+ 24 - 5
net/netfilter/xt_connmark.c

@@ -64,14 +64,31 @@ checkentry(const char *tablename,
 		printk(KERN_WARNING "connmark: only support 32bit mark\n");
 		printk(KERN_WARNING "connmark: only support 32bit mark\n");
 		return 0;
 		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;
 	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 = {
 static struct xt_match connmark_match = {
 	.name		= "connmark",
 	.name		= "connmark",
 	.match		= match,
 	.match		= match,
 	.matchsize	= sizeof(struct xt_connmark_info),
 	.matchsize	= sizeof(struct xt_connmark_info),
 	.checkentry	= checkentry,
 	.checkentry	= checkentry,
+	.destroy	= destroy,
+	.family		= AF_INET,
 	.me		= THIS_MODULE
 	.me		= THIS_MODULE
 };
 };
 
 
@@ -80,6 +97,8 @@ static struct xt_match connmark6_match = {
 	.match		= match,
 	.match		= match,
 	.matchsize	= sizeof(struct xt_connmark_info),
 	.matchsize	= sizeof(struct xt_connmark_info),
 	.checkentry	= checkentry,
 	.checkentry	= checkentry,
+	.destroy	= destroy,
+	.family		= AF_INET6,
 	.me		= THIS_MODULE
 	.me		= THIS_MODULE
 };
 };
 
 
@@ -89,20 +108,20 @@ static int __init init(void)
 
 
 	need_conntrack();
 	need_conntrack();
 
 
-	ret = xt_register_match(AF_INET, &connmark_match);
+	ret = xt_register_match(&connmark_match);
 	if (ret)
 	if (ret)
 		return ret;
 		return ret;
 
 
-	ret = xt_register_match(AF_INET6, &connmark6_match);
+	ret = xt_register_match(&connmark6_match);
 	if (ret)
 	if (ret)
-		xt_unregister_match(AF_INET, &connmark_match);
+		xt_unregister_match(&connmark_match);
 	return ret;
 	return ret;
 }
 }
 
 
 static void __exit fini(void)
 static void __exit fini(void)
 {
 {
-	xt_unregister_match(AF_INET6, &connmark6_match);
-	xt_unregister_match(AF_INET, &connmark_match);
+	xt_unregister_match(&connmark6_match);
+	xt_unregister_match(&connmark_match);
 }
 }
 
 
 module_init(init);
 module_init(init);

+ 31 - 2
net/netfilter/xt_conntrack.c

@@ -203,10 +203,39 @@ match(const struct sk_buff *skb,
 
 
 #endif /* CONFIG_NF_IP_CONNTRACK */
 #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 = {
 static struct xt_match conntrack_match = {
 	.name		= "conntrack",
 	.name		= "conntrack",
 	.match		= match,
 	.match		= match,
+	.checkentry	= checkentry,
+	.destroy	= destroy,
 	.matchsize	= sizeof(struct xt_conntrack_info),
 	.matchsize	= sizeof(struct xt_conntrack_info),
+	.family		= AF_INET,
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
 
 
@@ -214,14 +243,14 @@ static int __init init(void)
 {
 {
 	int ret;
 	int ret;
 	need_conntrack();
 	need_conntrack();
-	ret = xt_register_match(AF_INET, &conntrack_match);
+	ret = xt_register_match(&conntrack_match);
 
 
 	return ret;
 	return ret;
 }
 }
 
 
 static void __exit fini(void)
 static void __exit fini(void)
 {
 {
-	xt_unregister_match(AF_INET, &conntrack_match);
+	xt_unregister_match(&conntrack_match);
 }
 }
 
 
 module_init(init);
 module_init(init);

+ 7 - 5
net/netfilter/xt_dccp.c

@@ -149,6 +149,7 @@ static struct xt_match dccp_match =
 	.matchsize	= sizeof(struct xt_dccp_info),
 	.matchsize	= sizeof(struct xt_dccp_info),
 	.proto		= IPPROTO_DCCP,
 	.proto		= IPPROTO_DCCP,
 	.checkentry	= checkentry,
 	.checkentry	= checkentry,
+	.family		= AF_INET,
 	.me 		= THIS_MODULE,
 	.me 		= THIS_MODULE,
 };
 };
 static struct xt_match dccp6_match = 
 static struct xt_match dccp6_match = 
@@ -158,6 +159,7 @@ static struct xt_match dccp6_match =
 	.matchsize	= sizeof(struct xt_dccp_info),
 	.matchsize	= sizeof(struct xt_dccp_info),
 	.proto		= IPPROTO_DCCP,
 	.proto		= IPPROTO_DCCP,
 	.checkentry	= checkentry,
 	.checkentry	= checkentry,
+	.family		= AF_INET6,
 	.me 		= THIS_MODULE,
 	.me 		= THIS_MODULE,
 };
 };
 
 
@@ -172,17 +174,17 @@ static int __init init(void)
 	dccp_optbuf = kmalloc(256 * 4, GFP_KERNEL);
 	dccp_optbuf = kmalloc(256 * 4, GFP_KERNEL);
 	if (!dccp_optbuf)
 	if (!dccp_optbuf)
 		return -ENOMEM;
 		return -ENOMEM;
-	ret = xt_register_match(AF_INET, &dccp_match);
+	ret = xt_register_match(&dccp_match);
 	if (ret)
 	if (ret)
 		goto out_kfree;
 		goto out_kfree;
-	ret = xt_register_match(AF_INET6, &dccp6_match);
+	ret = xt_register_match(&dccp6_match);
 	if (ret)
 	if (ret)
 		goto out_unreg;
 		goto out_unreg;
 
 
 	return ret;
 	return ret;
 
 
 out_unreg:
 out_unreg:
-	xt_unregister_match(AF_INET, &dccp_match);
+	xt_unregister_match(&dccp_match);
 out_kfree:
 out_kfree:
 	kfree(dccp_optbuf);
 	kfree(dccp_optbuf);
 
 
@@ -191,8 +193,8 @@ out_kfree:
 
 
 static void __exit fini(void)
 static void __exit fini(void)
 {
 {
-	xt_unregister_match(AF_INET6, &dccp6_match);
-	xt_unregister_match(AF_INET, &dccp_match);
+	xt_unregister_match(&dccp6_match);
+	xt_unregister_match(&dccp_match);
 	kfree(dccp_optbuf);
 	kfree(dccp_optbuf);
 }
 }
 
 

+ 24 - 5
net/netfilter/xt_helper.c

@@ -144,15 +144,32 @@ static int check(const char *tablename,
 {
 {
 	struct xt_helper_info *info = matchinfo;
 	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';
 	info->name[29] = '\0';
 	return 1;
 	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 = {
 static struct xt_match helper_match = {
 	.name		= "helper",
 	.name		= "helper",
 	.match		= match,
 	.match		= match,
 	.matchsize	= sizeof(struct xt_helper_info),
 	.matchsize	= sizeof(struct xt_helper_info),
 	.checkentry	= check,
 	.checkentry	= check,
+	.destroy	= destroy,
+	.family		= AF_INET,
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
 static struct xt_match helper6_match = {
 static struct xt_match helper6_match = {
@@ -160,6 +177,8 @@ static struct xt_match helper6_match = {
 	.match		= match,
 	.match		= match,
 	.matchsize	= sizeof(struct xt_helper_info),
 	.matchsize	= sizeof(struct xt_helper_info),
 	.checkentry	= check,
 	.checkentry	= check,
+	.destroy	= destroy,
+	.family		= AF_INET6,
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
 
 
@@ -168,21 +187,21 @@ static int __init init(void)
 	int ret;
 	int ret;
 	need_conntrack();
 	need_conntrack();
 
 
-	ret = xt_register_match(AF_INET, &helper_match);
+	ret = xt_register_match(&helper_match);
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;
 
 
-	ret = xt_register_match(AF_INET6, &helper6_match);
+	ret = xt_register_match(&helper6_match);
 	if (ret < 0)
 	if (ret < 0)
-		xt_unregister_match(AF_INET, &helper_match);
+		xt_unregister_match(&helper_match);
 
 
 	return ret;
 	return ret;
 }
 }
 
 
 static void __exit fini(void)
 static void __exit fini(void)
 {
 {
-	xt_unregister_match(AF_INET, &helper_match);
-	xt_unregister_match(AF_INET6, &helper6_match);
+	xt_unregister_match(&helper_match);
+	xt_unregister_match(&helper6_match);
 }
 }
 
 
 module_init(init);
 module_init(init);

+ 7 - 5
net/netfilter/xt_length.c

@@ -56,6 +56,7 @@ static struct xt_match length_match = {
 	.name		= "length",
 	.name		= "length",
 	.match		= match,
 	.match		= match,
 	.matchsize	= sizeof(struct xt_length_info),
 	.matchsize	= sizeof(struct xt_length_info),
+	.family		= AF_INET,
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
 
 
@@ -63,26 +64,27 @@ static struct xt_match length6_match = {
 	.name		= "length",
 	.name		= "length",
 	.match		= match6,
 	.match		= match6,
 	.matchsize	= sizeof(struct xt_length_info),
 	.matchsize	= sizeof(struct xt_length_info),
+	.family		= AF_INET6,
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
 
 
 static int __init init(void)
 static int __init init(void)
 {
 {
 	int ret;
 	int ret;
-	ret = xt_register_match(AF_INET, &length_match);
+	ret = xt_register_match(&length_match);
 	if (ret)
 	if (ret)
 		return ret;
 		return ret;
-	ret = xt_register_match(AF_INET6, &length6_match);
+	ret = xt_register_match(&length6_match);
 	if (ret)
 	if (ret)
-		xt_unregister_match(AF_INET, &length_match);
+		xt_unregister_match(&length_match);
 
 
 	return ret;
 	return ret;
 }
 }
 
 
 static void __exit fini(void)
 static void __exit fini(void)
 {
 {
-	xt_unregister_match(AF_INET, &length_match);
-	xt_unregister_match(AF_INET6, &length6_match);
+	xt_unregister_match(&length_match);
+	xt_unregister_match(&length6_match);
 }
 }
 
 
 module_init(init);
 module_init(init);

+ 7 - 5
net/netfilter/xt_limit.c

@@ -141,6 +141,7 @@ static struct xt_match ipt_limit_reg = {
 	.match		= ipt_limit_match,
 	.match		= ipt_limit_match,
 	.matchsize	= sizeof(struct xt_rateinfo),
 	.matchsize	= sizeof(struct xt_rateinfo),
 	.checkentry	= ipt_limit_checkentry,
 	.checkentry	= ipt_limit_checkentry,
+	.family		= AF_INET,
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
 static struct xt_match limit6_reg = {
 static struct xt_match limit6_reg = {
@@ -148,6 +149,7 @@ static struct xt_match limit6_reg = {
 	.match		= ipt_limit_match,
 	.match		= ipt_limit_match,
 	.matchsize	= sizeof(struct xt_rateinfo),
 	.matchsize	= sizeof(struct xt_rateinfo),
 	.checkentry	= ipt_limit_checkentry,
 	.checkentry	= ipt_limit_checkentry,
+	.family		= AF_INET6,
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
 
 
@@ -155,21 +157,21 @@ static int __init init(void)
 {
 {
 	int ret;
 	int ret;
 	
 	
-	ret = xt_register_match(AF_INET, &ipt_limit_reg);
+	ret = xt_register_match(&ipt_limit_reg);
 	if (ret)
 	if (ret)
 		return ret;
 		return ret;
 	
 	
-	ret = xt_register_match(AF_INET6, &limit6_reg);
+	ret = xt_register_match(&limit6_reg);
 	if (ret)
 	if (ret)
-		xt_unregister_match(AF_INET, &ipt_limit_reg);
+		xt_unregister_match(&ipt_limit_reg);
 
 
 	return ret;
 	return ret;
 }
 }
 
 
 static void __exit fini(void)
 static void __exit fini(void)
 {
 {
-	xt_unregister_match(AF_INET, &ipt_limit_reg);
-	xt_unregister_match(AF_INET6, &limit6_reg);
+	xt_unregister_match(&ipt_limit_reg);
+	xt_unregister_match(&limit6_reg);
 }
 }
 
 
 module_init(init);
 module_init(init);

+ 7 - 5
net/netfilter/xt_mac.c

@@ -49,6 +49,7 @@ static struct xt_match mac_match = {
 	.matchsize	= sizeof(struct xt_mac_info),
 	.matchsize	= sizeof(struct xt_mac_info),
 	.hooks		= (1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_IN) |
 	.hooks		= (1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_IN) |
 			  (1 << NF_IP_FORWARD),
 			  (1 << NF_IP_FORWARD),
+	.family		= AF_INET,
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
 static struct xt_match mac6_match = {
 static struct xt_match mac6_match = {
@@ -57,27 +58,28 @@ static struct xt_match mac6_match = {
 	.matchsize	= sizeof(struct xt_mac_info),
 	.matchsize	= sizeof(struct xt_mac_info),
 	.hooks		= (1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_IN) |
 	.hooks		= (1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_IN) |
 			  (1 << NF_IP_FORWARD),
 			  (1 << NF_IP_FORWARD),
+	.family		= AF_INET6,
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
 
 
 static int __init init(void)
 static int __init init(void)
 {
 {
 	int ret;
 	int ret;
-	ret = xt_register_match(AF_INET, &mac_match);
+	ret = xt_register_match(&mac_match);
 	if (ret)
 	if (ret)
 		return ret;
 		return ret;
 
 
-	ret = xt_register_match(AF_INET6, &mac6_match);
+	ret = xt_register_match(&mac6_match);
 	if (ret)
 	if (ret)
-		xt_unregister_match(AF_INET, &mac_match);
+		xt_unregister_match(&mac_match);
 
 
 	return ret;
 	return ret;
 }
 }
 
 
 static void __exit fini(void)
 static void __exit fini(void)
 {
 {
-	xt_unregister_match(AF_INET, &mac_match);
-	xt_unregister_match(AF_INET6, &mac6_match);
+	xt_unregister_match(&mac_match);
+	xt_unregister_match(&mac6_match);
 }
 }
 
 
 module_init(init);
 module_init(init);

+ 7 - 5
net/netfilter/xt_mark.c

@@ -56,6 +56,7 @@ static struct xt_match mark_match = {
 	.match		= match,
 	.match		= match,
 	.matchsize	= sizeof(struct xt_mark_info),
 	.matchsize	= sizeof(struct xt_mark_info),
 	.checkentry	= checkentry,
 	.checkentry	= checkentry,
+	.family		= AF_INET,
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
 
 
@@ -64,27 +65,28 @@ static struct xt_match mark6_match = {
 	.match		= match,
 	.match		= match,
 	.matchsize	= sizeof(struct xt_mark_info),
 	.matchsize	= sizeof(struct xt_mark_info),
 	.checkentry	= checkentry,
 	.checkentry	= checkentry,
+	.family		= AF_INET6,
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
 
 
 static int __init init(void)
 static int __init init(void)
 {
 {
 	int ret;
 	int ret;
-	ret = xt_register_match(AF_INET, &mark_match);
+	ret = xt_register_match(&mark_match);
 	if (ret)
 	if (ret)
 		return ret;
 		return ret;
 
 
-	ret = xt_register_match(AF_INET6, &mark6_match);
+	ret = xt_register_match(&mark6_match);
 	if (ret)
 	if (ret)
-		xt_unregister_match(AF_INET, &mark_match);
+		xt_unregister_match(&mark_match);
 
 
 	return ret;
 	return ret;
 }
 }
 
 
 static void __exit fini(void)
 static void __exit fini(void)
 {
 {
-	xt_unregister_match(AF_INET, &mark_match);
-	xt_unregister_match(AF_INET6, &mark6_match);
+	xt_unregister_match(&mark_match);
+	xt_unregister_match(&mark6_match);
 }
 }
 
 
 module_init(init);
 module_init(init);

+ 7 - 5
net/netfilter/xt_physdev.c

@@ -121,6 +121,7 @@ static struct xt_match physdev_match = {
 	.match		= match,
 	.match		= match,
 	.matchsize	= sizeof(struct xt_physdev_info),
 	.matchsize	= sizeof(struct xt_physdev_info),
 	.checkentry	= checkentry,
 	.checkentry	= checkentry,
+	.family		= AF_INET,
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
 
 
@@ -129,6 +130,7 @@ static struct xt_match physdev6_match = {
 	.match		= match,
 	.match		= match,
 	.matchsize	= sizeof(struct xt_physdev_info),
 	.matchsize	= sizeof(struct xt_physdev_info),
 	.checkentry	= checkentry,
 	.checkentry	= checkentry,
+	.family		= AF_INET6,
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
 
 
@@ -136,21 +138,21 @@ static int __init init(void)
 {
 {
 	int ret;
 	int ret;
 
 
-	ret = xt_register_match(AF_INET, &physdev_match);
+	ret = xt_register_match(&physdev_match);
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;
 
 
-	ret = xt_register_match(AF_INET6, &physdev6_match);
+	ret = xt_register_match(&physdev6_match);
 	if (ret < 0)
 	if (ret < 0)
-		xt_unregister_match(AF_INET, &physdev_match);
+		xt_unregister_match(&physdev_match);
 
 
 	return ret;
 	return ret;
 }
 }
 
 
 static void __exit fini(void)
 static void __exit fini(void)
 {
 {
-	xt_unregister_match(AF_INET, &physdev_match);
-	xt_unregister_match(AF_INET6, &physdev6_match);
+	xt_unregister_match(&physdev_match);
+	xt_unregister_match(&physdev6_match);
 }
 }
 
 
 module_init(init);
 module_init(init);

+ 7 - 5
net/netfilter/xt_pkttype.c

@@ -37,6 +37,7 @@ static struct xt_match pkttype_match = {
 	.name		= "pkttype",
 	.name		= "pkttype",
 	.match		= match,
 	.match		= match,
 	.matchsize	= sizeof(struct xt_pkttype_info),
 	.matchsize	= sizeof(struct xt_pkttype_info),
+	.family		= AF_INET,
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
 
 
@@ -44,27 +45,28 @@ static struct xt_match pkttype6_match = {
 	.name		= "pkttype",
 	.name		= "pkttype",
 	.match		= match,
 	.match		= match,
 	.matchsize	= sizeof(struct xt_pkttype_info),
 	.matchsize	= sizeof(struct xt_pkttype_info),
+	.family		= AF_INET6,
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
 
 
 static int __init init(void)
 static int __init init(void)
 {
 {
 	int ret;
 	int ret;
-	ret = xt_register_match(AF_INET, &pkttype_match);
+	ret = xt_register_match(&pkttype_match);
 	if (ret)
 	if (ret)
 		return ret;
 		return ret;
 
 
-	ret = xt_register_match(AF_INET6, &pkttype6_match);
+	ret = xt_register_match(&pkttype6_match);
 	if (ret)
 	if (ret)
-		xt_unregister_match(AF_INET, &pkttype_match);
+		xt_unregister_match(&pkttype_match);
 
 
 	return ret;
 	return ret;
 }
 }
 
 
 static void __exit fini(void)
 static void __exit fini(void)
 {
 {
-	xt_unregister_match(AF_INET, &pkttype_match);
-	xt_unregister_match(AF_INET6, &pkttype6_match);
+	xt_unregister_match(&pkttype_match);
+	xt_unregister_match(&pkttype6_match);
 }
 }
 
 
 module_init(init);
 module_init(init);

+ 10 - 8
net/netfilter/xt_policy.c

@@ -27,9 +27,9 @@ xt_addr_cmp(const union xt_policy_addr *a1, const union xt_policy_addr *m,
 {
 {
 	switch (family) {
 	switch (family) {
 	case AF_INET:
 	case AF_INET:
-		return (a1->a4.s_addr ^ a2->a4.s_addr) & m->a4.s_addr;
+		return !((a1->a4.s_addr ^ a2->a4.s_addr) & m->a4.s_addr);
 	case AF_INET6:
 	case AF_INET6:
-		return ipv6_masked_addr_cmp(&a1->a6, &m->a6, &a2->a6);
+		return !ipv6_masked_addr_cmp(&a1->a6, &m->a6, &a2->a6);
 	}
 	}
 	return 0;
 	return 0;
 }
 }
@@ -44,7 +44,7 @@ match_xfrm_state(struct xfrm_state *x, const struct xt_policy_elem *e,
 #define MATCH(x,y)		(!e->match.x || ((e->x == (y)) ^ e->invert.x))
 #define MATCH(x,y)		(!e->match.x || ((e->x == (y)) ^ e->invert.x))
 
 
 	return MATCH_ADDR(saddr, smask, (union xt_policy_addr *)&x->props.saddr) &&
 	return MATCH_ADDR(saddr, smask, (union xt_policy_addr *)&x->props.saddr) &&
-	       MATCH_ADDR(daddr, dmask, (union xt_policy_addr *)&x->id.daddr.a4) &&
+	       MATCH_ADDR(daddr, dmask, (union xt_policy_addr *)&x->id.daddr) &&
 	       MATCH(proto, x->id.proto) &&
 	       MATCH(proto, x->id.proto) &&
 	       MATCH(mode, x->props.mode) &&
 	       MATCH(mode, x->props.mode) &&
 	       MATCH(spi, x->id.spi) &&
 	       MATCH(spi, x->id.spi) &&
@@ -172,6 +172,7 @@ static struct xt_match policy_match = {
 	.match		= match,
 	.match		= match,
 	.matchsize	= sizeof(struct xt_policy_info),
 	.matchsize	= sizeof(struct xt_policy_info),
 	.checkentry 	= checkentry,
 	.checkentry 	= checkentry,
+	.family		= AF_INET,
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
 
 
@@ -181,6 +182,7 @@ static struct xt_match policy6_match = {
 	.match		= match,
 	.match		= match,
 	.matchsize	= sizeof(struct xt_policy_info),
 	.matchsize	= sizeof(struct xt_policy_info),
 	.checkentry	= checkentry,
 	.checkentry	= checkentry,
+	.family		= AF_INET6,
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
 
 
@@ -188,19 +190,19 @@ static int __init init(void)
 {
 {
 	int ret;
 	int ret;
 
 
-	ret = xt_register_match(AF_INET, &policy_match);
+	ret = xt_register_match(&policy_match);
 	if (ret)
 	if (ret)
 		return ret;
 		return ret;
-	ret = xt_register_match(AF_INET6, &policy6_match);
+	ret = xt_register_match(&policy6_match);
 	if (ret)
 	if (ret)
-		xt_unregister_match(AF_INET, &policy_match);
+		xt_unregister_match(&policy_match);
 	return ret;
 	return ret;
 }
 }
 
 
 static void __exit fini(void)
 static void __exit fini(void)
 {
 {
-	xt_unregister_match(AF_INET6, &policy6_match);
-	xt_unregister_match(AF_INET, &policy_match);
+	xt_unregister_match(&policy6_match);
+	xt_unregister_match(&policy_match);
 }
 }
 
 
 module_init(init);
 module_init(init);

+ 3 - 2
net/netfilter/xt_realm.c

@@ -45,17 +45,18 @@ static struct xt_match realm_match = {
 	.matchsize	= sizeof(struct xt_realm_info),
 	.matchsize	= sizeof(struct xt_realm_info),
 	.hooks		= (1 << NF_IP_POST_ROUTING) | (1 << NF_IP_FORWARD) |
 	.hooks		= (1 << NF_IP_POST_ROUTING) | (1 << NF_IP_FORWARD) |
 			  (1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_LOCAL_IN),
 			  (1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_LOCAL_IN),
+	.family		= AF_INET,
 	.me		= THIS_MODULE
 	.me		= THIS_MODULE
 };
 };
 
 
 static int __init init(void)
 static int __init init(void)
 {
 {
-	return xt_register_match(AF_INET, &realm_match);
+	return xt_register_match(&realm_match);
 }
 }
 
 
 static void __exit fini(void)
 static void __exit fini(void)
 {
 {
-	xt_unregister_match(AF_INET, &realm_match);
+	xt_unregister_match(&realm_match);
 }
 }
 
 
 module_init(init);
 module_init(init);

+ 7 - 5
net/netfilter/xt_sctp.c

@@ -186,6 +186,7 @@ static struct xt_match sctp_match = {
 	.matchsize	= sizeof(struct xt_sctp_info),
 	.matchsize	= sizeof(struct xt_sctp_info),
 	.proto		= IPPROTO_SCTP,
 	.proto		= IPPROTO_SCTP,
 	.checkentry	= checkentry,
 	.checkentry	= checkentry,
+	.family		= AF_INET,
 	.me		= THIS_MODULE
 	.me		= THIS_MODULE
 };
 };
 
 
@@ -195,27 +196,28 @@ static struct xt_match sctp6_match = {
 	.matchsize	= sizeof(struct xt_sctp_info),
 	.matchsize	= sizeof(struct xt_sctp_info),
 	.proto		= IPPROTO_SCTP,
 	.proto		= IPPROTO_SCTP,
 	.checkentry	= checkentry,
 	.checkentry	= checkentry,
+	.family		= AF_INET6,
 	.me		= THIS_MODULE
 	.me		= THIS_MODULE
 };
 };
 
 
 static int __init init(void)
 static int __init init(void)
 {
 {
 	int ret;
 	int ret;
-	ret = xt_register_match(AF_INET, &sctp_match);
+	ret = xt_register_match(&sctp_match);
 	if (ret)
 	if (ret)
 		return ret;
 		return ret;
 
 
-	ret = xt_register_match(AF_INET6, &sctp6_match);
+	ret = xt_register_match(&sctp6_match);
 	if (ret)
 	if (ret)
-		xt_unregister_match(AF_INET, &sctp_match);
+		xt_unregister_match(&sctp_match);
 
 
 	return ret;
 	return ret;
 }
 }
 
 
 static void __exit fini(void)
 static void __exit fini(void)
 {
 {
-	xt_unregister_match(AF_INET6, &sctp6_match);
-	xt_unregister_match(AF_INET, &sctp_match);
+	xt_unregister_match(&sctp6_match);
+	xt_unregister_match(&sctp_match);
 }
 }
 
 
 module_init(init);
 module_init(init);

+ 36 - 5
net/netfilter/xt_state.c

@@ -44,17 +44,48 @@ match(const struct sk_buff *skb,
 	return (sinfo->statemask & statebit);
 	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 = {
 static struct xt_match state_match = {
 	.name		= "state",
 	.name		= "state",
 	.match		= match,
 	.match		= match,
+	.checkentry	= check,
+	.destroy	= destroy,
 	.matchsize	= sizeof(struct xt_state_info),
 	.matchsize	= sizeof(struct xt_state_info),
+	.family		= AF_INET,
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
 
 
 static struct xt_match state6_match = {
 static struct xt_match state6_match = {
 	.name		= "state",
 	.name		= "state",
 	.match		= match,
 	.match		= match,
+	.checkentry	= check,
+	.destroy	= destroy,
 	.matchsize	= sizeof(struct xt_state_info),
 	.matchsize	= sizeof(struct xt_state_info),
+	.family		= AF_INET6,
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
 
 
@@ -64,21 +95,21 @@ static int __init init(void)
 
 
 	need_conntrack();
 	need_conntrack();
 
 
-	ret = xt_register_match(AF_INET, &state_match);
+	ret = xt_register_match(&state_match);
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;
 
 
-	ret = xt_register_match(AF_INET6, &state6_match);
+	ret = xt_register_match(&state6_match);
 	if (ret < 0)
 	if (ret < 0)
-		xt_unregister_match(AF_INET,&state_match);
+		xt_unregister_match(&state_match);
 
 
 	return ret;
 	return ret;
 }
 }
 
 
 static void __exit fini(void)
 static void __exit fini(void)
 {
 {
-	xt_unregister_match(AF_INET, &state_match);
-	xt_unregister_match(AF_INET6, &state6_match);
+	xt_unregister_match(&state_match);
+	xt_unregister_match(&state6_match);
 }
 }
 
 
 module_init(init);
 module_init(init);

+ 7 - 5
net/netfilter/xt_string.c

@@ -78,6 +78,7 @@ static struct xt_match string_match = {
 	.matchsize	= sizeof(struct xt_string_info),
 	.matchsize	= sizeof(struct xt_string_info),
 	.checkentry	= checkentry,
 	.checkentry	= checkentry,
 	.destroy 	= destroy,
 	.destroy 	= destroy,
+	.family		= AF_INET,
 	.me 		= THIS_MODULE
 	.me 		= THIS_MODULE
 };
 };
 static struct xt_match string6_match = {
 static struct xt_match string6_match = {
@@ -86,6 +87,7 @@ static struct xt_match string6_match = {
 	.matchsize	= sizeof(struct xt_string_info),
 	.matchsize	= sizeof(struct xt_string_info),
 	.checkentry	= checkentry,
 	.checkentry	= checkentry,
 	.destroy 	= destroy,
 	.destroy 	= destroy,
+	.family		= AF_INET6,
 	.me 		= THIS_MODULE
 	.me 		= THIS_MODULE
 };
 };
 
 
@@ -93,20 +95,20 @@ static int __init init(void)
 {
 {
 	int ret;
 	int ret;
 
 
-	ret = xt_register_match(AF_INET, &string_match);
+	ret = xt_register_match(&string_match);
 	if (ret)
 	if (ret)
 		return ret;
 		return ret;
-	ret = xt_register_match(AF_INET6, &string6_match);
+	ret = xt_register_match(&string6_match);
 	if (ret)
 	if (ret)
-		xt_unregister_match(AF_INET, &string_match);
+		xt_unregister_match(&string_match);
 
 
 	return ret;
 	return ret;
 }
 }
 
 
 static void __exit fini(void)
 static void __exit fini(void)
 {
 {
-	xt_unregister_match(AF_INET, &string_match);
-	xt_unregister_match(AF_INET6, &string6_match);
+	xt_unregister_match(&string_match);
+	xt_unregister_match(&string6_match);
 }
 }
 
 
 module_init(init);
 module_init(init);

+ 7 - 5
net/netfilter/xt_tcpmss.c

@@ -98,6 +98,7 @@ static struct xt_match tcpmss_match = {
 	.match		= match,
 	.match		= match,
 	.matchsize	= sizeof(struct xt_tcpmss_match_info),
 	.matchsize	= sizeof(struct xt_tcpmss_match_info),
 	.proto		= IPPROTO_TCP,
 	.proto		= IPPROTO_TCP,
+	.family		= AF_INET,
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
 
 
@@ -106,6 +107,7 @@ static struct xt_match tcpmss6_match = {
 	.match		= match,
 	.match		= match,
 	.matchsize	= sizeof(struct xt_tcpmss_match_info),
 	.matchsize	= sizeof(struct xt_tcpmss_match_info),
 	.proto		= IPPROTO_TCP,
 	.proto		= IPPROTO_TCP,
+	.family		= AF_INET6,
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
 
 
@@ -113,21 +115,21 @@ static struct xt_match tcpmss6_match = {
 static int __init init(void)
 static int __init init(void)
 {
 {
 	int ret;
 	int ret;
-	ret = xt_register_match(AF_INET, &tcpmss_match);
+	ret = xt_register_match(&tcpmss_match);
 	if (ret)
 	if (ret)
 		return ret;
 		return ret;
 
 
-	ret = xt_register_match(AF_INET6, &tcpmss6_match);
+	ret = xt_register_match(&tcpmss6_match);
 	if (ret)
 	if (ret)
-		xt_unregister_match(AF_INET, &tcpmss_match);
+		xt_unregister_match(&tcpmss_match);
 
 
 	return ret;
 	return ret;
 }
 }
 
 
 static void __exit fini(void)
 static void __exit fini(void)
 {
 {
-	xt_unregister_match(AF_INET6, &tcpmss6_match);
-	xt_unregister_match(AF_INET, &tcpmss_match);
+	xt_unregister_match(&tcpmss6_match);
+	xt_unregister_match(&tcpmss_match);
 }
 }
 
 
 module_init(init);
 module_init(init);

+ 15 - 11
net/netfilter/xt_tcpudp.c

@@ -204,6 +204,7 @@ static struct xt_match tcp_matchstruct = {
 	.match		= tcp_match,
 	.match		= tcp_match,
 	.matchsize	= sizeof(struct xt_tcp),
 	.matchsize	= sizeof(struct xt_tcp),
 	.proto		= IPPROTO_TCP,
 	.proto		= IPPROTO_TCP,
+	.family		= AF_INET,
 	.checkentry	= tcp_checkentry,
 	.checkentry	= tcp_checkentry,
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
@@ -213,6 +214,7 @@ static struct xt_match tcp6_matchstruct = {
 	.match		= tcp_match,
 	.match		= tcp_match,
 	.matchsize	= sizeof(struct xt_tcp),
 	.matchsize	= sizeof(struct xt_tcp),
 	.proto		= IPPROTO_TCP,
 	.proto		= IPPROTO_TCP,
+	.family		= AF_INET6,
 	.checkentry	= tcp_checkentry,
 	.checkentry	= tcp_checkentry,
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
@@ -222,6 +224,7 @@ static struct xt_match udp_matchstruct = {
 	.match		= udp_match,
 	.match		= udp_match,
 	.matchsize	= sizeof(struct xt_udp),
 	.matchsize	= sizeof(struct xt_udp),
 	.proto		= IPPROTO_UDP,
 	.proto		= IPPROTO_UDP,
+	.family		= AF_INET,
 	.checkentry	= udp_checkentry,
 	.checkentry	= udp_checkentry,
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
@@ -230,6 +233,7 @@ static struct xt_match udp6_matchstruct = {
 	.match		= udp_match,
 	.match		= udp_match,
 	.matchsize	= sizeof(struct xt_udp),
 	.matchsize	= sizeof(struct xt_udp),
 	.proto		= IPPROTO_UDP,
 	.proto		= IPPROTO_UDP,
+	.family		= AF_INET6,
 	.checkentry	= udp_checkentry,
 	.checkentry	= udp_checkentry,
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
@@ -237,39 +241,39 @@ static struct xt_match udp6_matchstruct = {
 static int __init init(void)
 static int __init init(void)
 {
 {
 	int ret;
 	int ret;
-	ret = xt_register_match(AF_INET, &tcp_matchstruct);
+	ret = xt_register_match(&tcp_matchstruct);
 	if (ret)
 	if (ret)
 		return ret;
 		return ret;
 
 
-	ret = xt_register_match(AF_INET6, &tcp6_matchstruct);
+	ret = xt_register_match(&tcp6_matchstruct);
 	if (ret)
 	if (ret)
 		goto out_unreg_tcp;
 		goto out_unreg_tcp;
 
 
-	ret = xt_register_match(AF_INET, &udp_matchstruct);
+	ret = xt_register_match(&udp_matchstruct);
 	if (ret)
 	if (ret)
 		goto out_unreg_tcp6;
 		goto out_unreg_tcp6;
 	
 	
-	ret = xt_register_match(AF_INET6, &udp6_matchstruct);
+	ret = xt_register_match(&udp6_matchstruct);
 	if (ret)
 	if (ret)
 		goto out_unreg_udp;
 		goto out_unreg_udp;
 
 
 	return ret;
 	return ret;
 
 
 out_unreg_udp:
 out_unreg_udp:
-	xt_unregister_match(AF_INET, &tcp_matchstruct);
+	xt_unregister_match(&tcp_matchstruct);
 out_unreg_tcp6:
 out_unreg_tcp6:
-	xt_unregister_match(AF_INET6, &tcp6_matchstruct);
+	xt_unregister_match(&tcp6_matchstruct);
 out_unreg_tcp:
 out_unreg_tcp:
-	xt_unregister_match(AF_INET, &tcp_matchstruct);
+	xt_unregister_match(&tcp_matchstruct);
 	return ret;
 	return ret;
 }
 }
 
 
 static void __exit fini(void)
 static void __exit fini(void)
 {
 {
-	xt_unregister_match(AF_INET6, &udp6_matchstruct);
-	xt_unregister_match(AF_INET, &udp_matchstruct);
-	xt_unregister_match(AF_INET6, &tcp6_matchstruct);
-	xt_unregister_match(AF_INET, &tcp_matchstruct);
+	xt_unregister_match(&udp6_matchstruct);
+	xt_unregister_match(&udp_matchstruct);
+	xt_unregister_match(&tcp6_matchstruct);
+	xt_unregister_match(&tcp_matchstruct);
 }
 }
 
 
 module_init(init);
 module_init(init);