aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-03-22 20:36:04 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-03-22 20:36:04 -0500
commit80576fd86b350a90c5be329de1e382d31121a8d0 (patch)
tree077b2ae2c7db8d3e370c0c491253caa4926f24c1
parent9d8f057acbd38d8177cf2ffd5e151d52c2477372 (diff)
parent1a55d57b107c3e06935763905dc0fb235214569d (diff)
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
-rw-r--r--include/linux/netfilter/x_tables.h64
-rw-r--r--include/linux/netfilter_arp/arp_tables.h37
-rw-r--r--include/linux/netfilter_ipv4/ip_tables.h70
-rw-r--r--include/linux/netfilter_ipv6/ip6_tables.h69
-rw-r--r--include/net/netfilter/nf_conntrack.h4
-rw-r--r--include/net/tc_act/tc_ipt.h4
-rw-r--r--net/ipv4/ip_output.c6
-rw-r--r--net/ipv4/netfilter/arp_tables.c6
-rw-r--r--net/ipv4/netfilter/ip_conntrack_core.c4
-rw-r--r--net/ipv4/netfilter/ip_conntrack_helper_h323.c4
-rw-r--r--net/ipv4/netfilter/ip_conntrack_netlink.c72
-rw-r--r--net/ipv4/netfilter/ip_tables.c15
-rw-r--r--net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c1
-rw-r--r--net/ipv6/ipv6_sockglue.c4
-rw-r--r--net/ipv6/netfilter/ip6_tables.c15
-rw-r--r--net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c1
-rw-r--r--net/netfilter/Kconfig6
-rw-r--r--net/netfilter/nf_conntrack_core.c35
-rw-r--r--net/netfilter/nf_conntrack_netlink.c84
-rw-r--r--net/netfilter/nf_conntrack_standalone.c2
-rw-r--r--net/netfilter/nfnetlink_queue.c19
-rw-r--r--net/netfilter/x_tables.c16
-rw-r--r--net/netfilter/xt_CLASSIFY.c12
-rw-r--r--net/netfilter/xt_CONNMARK.c12
-rw-r--r--net/netfilter/xt_MARK.c21
-rw-r--r--net/netfilter/xt_NFQUEUE.c19
-rw-r--r--net/netfilter/xt_NOTRACK.c12
-rw-r--r--net/netfilter/xt_comment.c12
-rw-r--r--net/netfilter/xt_connbytes.c12
-rw-r--r--net/netfilter/xt_connmark.c29
-rw-r--r--net/netfilter/xt_conntrack.c33
-rw-r--r--net/netfilter/xt_dccp.c12
-rw-r--r--net/netfilter/xt_helper.c29
-rw-r--r--net/netfilter/xt_length.c12
-rw-r--r--net/netfilter/xt_limit.c12
-rw-r--r--net/netfilter/xt_mac.c12
-rw-r--r--net/netfilter/xt_mark.c12
-rw-r--r--net/netfilter/xt_physdev.c12
-rw-r--r--net/netfilter/xt_pkttype.c12
-rw-r--r--net/netfilter/xt_policy.c18
-rw-r--r--net/netfilter/xt_realm.c5
-rw-r--r--net/netfilter/xt_sctp.c12
-rw-r--r--net/netfilter/xt_state.c41
-rw-r--r--net/netfilter/xt_string.c12
-rw-r--r--net/netfilter/xt_tcpmss.c12
-rw-r--r--net/netfilter/xt_tcpudp.c26
46 files changed, 571 insertions, 368 deletions
diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
index 46a0f974f87c..1350e47b0234 100644
--- a/include/linux/netfilter/x_tables.h
+++ b/include/linux/netfilter/x_tables.h
@@ -4,6 +4,62 @@
4#define XT_FUNCTION_MAXNAMELEN 30 4#define XT_FUNCTION_MAXNAMELEN 30
5#define XT_TABLE_MAXNAMELEN 32 5#define XT_TABLE_MAXNAMELEN 32
6 6
7struct xt_entry_match
8{
9 union {
10 struct {
11 u_int16_t match_size;
12
13 /* Used by userspace */
14 char name[XT_FUNCTION_MAXNAMELEN-1];
15
16 u_int8_t revision;
17 } user;
18 struct {
19 u_int16_t match_size;
20
21 /* Used inside the kernel */
22 struct xt_match *match;
23 } kernel;
24
25 /* Total length */
26 u_int16_t match_size;
27 } u;
28
29 unsigned char data[0];
30};
31
32struct xt_entry_target
33{
34 union {
35 struct {
36 u_int16_t target_size;
37
38 /* Used by userspace */
39 char name[XT_FUNCTION_MAXNAMELEN-1];
40
41 u_int8_t revision;
42 } user;
43 struct {
44 u_int16_t target_size;
45
46 /* Used inside the kernel */
47 struct xt_target *target;
48 } kernel;
49
50 /* Total length */
51 u_int16_t target_size;
52 } u;
53
54 unsigned char data[0];
55};
56
57struct xt_standard_target
58{
59 struct xt_entry_target target;
60 int verdict;
61};
62
7/* The argument to IPT_SO_GET_REVISION_*. Returns highest revision 63/* The argument to IPT_SO_GET_REVISION_*. Returns highest revision
8 * kernel supports, if >= revision. */ 64 * kernel supports, if >= revision. */
9struct xt_get_revision 65struct xt_get_revision
@@ -220,10 +276,10 @@ struct xt_table_info
220 char *entries[NR_CPUS]; 276 char *entries[NR_CPUS];
221}; 277};
222 278
223extern int xt_register_target(int af, struct xt_target *target); 279extern int xt_register_target(struct xt_target *target);
224extern void xt_unregister_target(int af, struct xt_target *target); 280extern void xt_unregister_target(struct xt_target *target);
225extern int xt_register_match(int af, struct xt_match *target); 281extern int xt_register_match(struct xt_match *target);
226extern void xt_unregister_match(int af, struct xt_match *target); 282extern void xt_unregister_match(struct xt_match *target);
227 283
228extern int xt_check_match(const struct xt_match *match, unsigned short family, 284extern int xt_check_match(const struct xt_match *match, unsigned short family,
229 unsigned int size, const char *table, unsigned int hook, 285 unsigned int size, const char *table, unsigned int hook,
diff --git a/include/linux/netfilter_arp/arp_tables.h b/include/linux/netfilter_arp/arp_tables.h
index fd21796e5131..62cc27daca4e 100644
--- a/include/linux/netfilter_arp/arp_tables.h
+++ b/include/linux/netfilter_arp/arp_tables.h
@@ -65,35 +65,8 @@ struct arpt_arp {
65 u_int16_t invflags; 65 u_int16_t invflags;
66}; 66};
67 67
68struct arpt_entry_target 68#define arpt_entry_target xt_entry_target
69{ 69#define arpt_standard_target xt_standard_target
70 union {
71 struct {
72 u_int16_t target_size;
73
74 /* Used by userspace */
75 char name[ARPT_FUNCTION_MAXNAMELEN-1];
76 u_int8_t revision;
77 } user;
78 struct {
79 u_int16_t target_size;
80
81 /* Used inside the kernel */
82 struct arpt_target *target;
83 } kernel;
84
85 /* Total length */
86 u_int16_t target_size;
87 } u;
88
89 unsigned char data[0];
90};
91
92struct arpt_standard_target
93{
94 struct arpt_entry_target target;
95 int verdict;
96};
97 70
98/* Values for "flag" field in struct arpt_ip (general arp structure). 71/* Values for "flag" field in struct arpt_ip (general arp structure).
99 * No flags defined yet. 72 * No flags defined yet.
@@ -263,8 +236,10 @@ static __inline__ struct arpt_entry_target *arpt_get_target(struct arpt_entry *e
263 */ 236 */
264#ifdef __KERNEL__ 237#ifdef __KERNEL__
265 238
266#define arpt_register_target(tgt) xt_register_target(NF_ARP, tgt) 239#define arpt_register_target(tgt) \
267#define arpt_unregister_target(tgt) xt_unregister_target(NF_ARP, tgt) 240({ (tgt)->family = NF_ARP; \
241 xt_register_target(tgt); })
242#define arpt_unregister_target(tgt) xt_unregister_target(tgt)
268 243
269extern int arpt_register_table(struct arpt_table *table, 244extern int arpt_register_table(struct arpt_table *table,
270 const struct arpt_replace *repl); 245 const struct arpt_replace *repl);
diff --git a/include/linux/netfilter_ipv4/ip_tables.h b/include/linux/netfilter_ipv4/ip_tables.h
index 76ba24b68515..d5b8c0d6a12b 100644
--- a/include/linux/netfilter_ipv4/ip_tables.h
+++ b/include/linux/netfilter_ipv4/ip_tables.h
@@ -52,61 +52,9 @@ struct ipt_ip {
52 u_int8_t invflags; 52 u_int8_t invflags;
53}; 53};
54 54
55struct ipt_entry_match 55#define ipt_entry_match xt_entry_match
56{ 56#define ipt_entry_target xt_entry_target
57 union { 57#define ipt_standard_target xt_standard_target
58 struct {
59 u_int16_t match_size;
60
61 /* Used by userspace */
62 char name[IPT_FUNCTION_MAXNAMELEN-1];
63
64 u_int8_t revision;
65 } user;
66 struct {
67 u_int16_t match_size;
68
69 /* Used inside the kernel */
70 struct ipt_match *match;
71 } kernel;
72
73 /* Total length */
74 u_int16_t match_size;
75 } u;
76
77 unsigned char data[0];
78};
79
80struct ipt_entry_target
81{
82 union {
83 struct {
84 u_int16_t target_size;
85
86 /* Used by userspace */
87 char name[IPT_FUNCTION_MAXNAMELEN-1];
88
89 u_int8_t revision;
90 } user;
91 struct {
92 u_int16_t target_size;
93
94 /* Used inside the kernel */
95 struct ipt_target *target;
96 } kernel;
97
98 /* Total length */
99 u_int16_t target_size;
100 } u;
101
102 unsigned char data[0];
103};
104
105struct ipt_standard_target
106{
107 struct ipt_entry_target target;
108 int verdict;
109};
110 58
111#define ipt_counters xt_counters 59#define ipt_counters xt_counters
112 60
@@ -321,11 +269,15 @@ ipt_get_target(struct ipt_entry *e)
321#include <linux/init.h> 269#include <linux/init.h>
322extern void ipt_init(void) __init; 270extern void ipt_init(void) __init;
323 271
324#define ipt_register_target(tgt) xt_register_target(AF_INET, tgt) 272#define ipt_register_target(tgt) \
325#define ipt_unregister_target(tgt) xt_unregister_target(AF_INET, tgt) 273({ (tgt)->family = AF_INET; \
274 xt_register_target(tgt); })
275#define ipt_unregister_target(tgt) xt_unregister_target(tgt)
326 276
327#define ipt_register_match(mtch) xt_register_match(AF_INET, mtch) 277#define ipt_register_match(mtch) \
328#define ipt_unregister_match(mtch) xt_unregister_match(AF_INET, mtch) 278({ (mtch)->family = AF_INET; \
279 xt_register_match(mtch); })
280#define ipt_unregister_match(mtch) xt_unregister_match(mtch)
329 281
330//#define ipt_register_table(tbl, repl) xt_register_table(AF_INET, tbl, repl) 282//#define ipt_register_table(tbl, repl) xt_register_table(AF_INET, tbl, repl)
331//#define ipt_unregister_table(tbl) xt_unregister_table(AF_INET, tbl) 283//#define ipt_unregister_table(tbl) xt_unregister_table(AF_INET, tbl)
diff --git a/include/linux/netfilter_ipv6/ip6_tables.h b/include/linux/netfilter_ipv6/ip6_tables.h
index f249b574f0fa..d0d5d1ee4be3 100644
--- a/include/linux/netfilter_ipv6/ip6_tables.h
+++ b/include/linux/netfilter_ipv6/ip6_tables.h
@@ -56,60 +56,9 @@ struct ip6t_ip6 {
56 u_int8_t invflags; 56 u_int8_t invflags;
57}; 57};
58 58
59/* FIXME: If alignment in kernel different from userspace? --RR */ 59#define ip6t_entry_match xt_entry_match
60struct ip6t_entry_match 60#define ip6t_entry_target xt_entry_target
61{ 61#define ip6t_standard_target xt_standard_target
62 union {
63 struct {
64 u_int16_t match_size;
65
66 /* Used by userspace */
67 char name[IP6T_FUNCTION_MAXNAMELEN-1];
68 u_int8_t revision;
69 } user;
70 struct {
71 u_int16_t match_size;
72
73 /* Used inside the kernel */
74 struct ip6t_match *match;
75 } kernel;
76
77 /* Total length */
78 u_int16_t match_size;
79 } u;
80
81 unsigned char data[0];
82};
83
84struct ip6t_entry_target
85{
86 union {
87 struct {
88 u_int16_t target_size;
89
90 /* Used by userspace */
91 char name[IP6T_FUNCTION_MAXNAMELEN-1];
92 u_int8_t revision;
93 } user;
94 struct {
95 u_int16_t target_size;
96
97 /* Used inside the kernel */
98 struct ip6t_target *target;
99 } kernel;
100
101 /* Total length */
102 u_int16_t target_size;
103 } u;
104
105 unsigned char data[0];
106};
107
108struct ip6t_standard_target
109{
110 struct ip6t_entry_target target;
111 int verdict;
112};
113 62
114#define ip6t_counters xt_counters 63#define ip6t_counters xt_counters
115 64
@@ -334,11 +283,15 @@ ip6t_get_target(struct ip6t_entry *e)
334#include <linux/init.h> 283#include <linux/init.h>
335extern void ip6t_init(void) __init; 284extern void ip6t_init(void) __init;
336 285
337#define ip6t_register_target(tgt) xt_register_target(AF_INET6, tgt) 286#define ip6t_register_target(tgt) \
338#define ip6t_unregister_target(tgt) xt_unregister_target(AF_INET6, tgt) 287({ (tgt)->family = AF_INET6; \
288 xt_register_target(tgt); })
289#define ip6t_unregister_target(tgt) xt_unregister_target(tgt)
339 290
340#define ip6t_register_match(match) xt_register_match(AF_INET6, match) 291#define ip6t_register_match(match) \
341#define ip6t_unregister_match(match) xt_unregister_match(AF_INET6, match) 292({ (match)->family = AF_INET6; \
293 xt_register_match(match); })
294#define ip6t_unregister_match(match) xt_unregister_match(match)
342 295
343extern int ip6t_register_table(struct ip6t_table *table, 296extern int ip6t_register_table(struct ip6t_table *table,
344 const struct ip6t_replace *repl); 297 const struct ip6t_replace *repl);
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
index 2743c156caa0..b6f0905a4ee2 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_conn *ct)
195 nf_conntrack_put(&ct->ct_general); 195 nf_conntrack_put(&ct->ct_general);
196} 196}
197 197
198/* Protocol module loading */
199extern int nf_ct_l3proto_try_module_get(unsigned short l3proto);
200extern void nf_ct_l3proto_module_put(unsigned short l3proto);
201
198extern struct nf_conntrack_tuple_hash * 202extern struct nf_conntrack_tuple_hash *
199__nf_conntrack_find(const struct nf_conntrack_tuple *tuple, 203__nf_conntrack_find(const struct nf_conntrack_tuple *tuple,
200 const struct nf_conn *ignored_conntrack); 204 const struct nf_conn *ignored_conntrack);
diff --git a/include/net/tc_act/tc_ipt.h b/include/net/tc_act/tc_ipt.h
index 02eccebd55ae..cb37ad08427f 100644
--- a/include/net/tc_act/tc_ipt.h
+++ b/include/net/tc_act/tc_ipt.h
@@ -3,14 +3,14 @@
3 3
4#include <net/act_api.h> 4#include <net/act_api.h>
5 5
6struct ipt_entry_target; 6struct xt_entry_target;
7 7
8struct tcf_ipt 8struct tcf_ipt
9{ 9{
10 tca_gen(ipt); 10 tca_gen(ipt);
11 u32 hook; 11 u32 hook;
12 char *tname; 12 char *tname;
13 struct ipt_entry_target *t; 13 struct xt_entry_target *t;
14}; 14};
15 15
16#endif 16#endif
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 8ee4d016740d..f75ff1d96551 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -1249,11 +1249,7 @@ int ip_push_pending_frames(struct sock *sk)
1249 iph->tos = inet->tos; 1249 iph->tos = inet->tos;
1250 iph->tot_len = htons(skb->len); 1250 iph->tot_len = htons(skb->len);
1251 iph->frag_off = df; 1251 iph->frag_off = df;
1252 if (!df) { 1252 ip_select_ident(iph, &rt->u.dst, sk);
1253 __ip_select_ident(iph, &rt->u.dst, 0);
1254 } else {
1255 iph->id = htons(inet->id++);
1256 }
1257 iph->ttl = ttl; 1253 iph->ttl = ttl;
1258 iph->protocol = sk->sk_protocol; 1254 iph->protocol = sk->sk_protocol;
1259 iph->saddr = rt->rt_src; 1255 iph->saddr = rt->rt_src;
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index f7efb3f27bf5..ff0c594a4198 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -1146,12 +1146,14 @@ void arpt_unregister_table(struct arpt_table *table)
1146static struct arpt_target arpt_standard_target = { 1146static struct arpt_target arpt_standard_target = {
1147 .name = ARPT_STANDARD_TARGET, 1147 .name = ARPT_STANDARD_TARGET,
1148 .targetsize = sizeof(int), 1148 .targetsize = sizeof(int),
1149 .family = NF_ARP,
1149}; 1150};
1150 1151
1151static struct arpt_target arpt_error_target = { 1152static struct arpt_target arpt_error_target = {
1152 .name = ARPT_ERROR_TARGET, 1153 .name = ARPT_ERROR_TARGET,
1153 .target = arpt_error, 1154 .target = arpt_error,
1154 .targetsize = ARPT_FUNCTION_MAXNAMELEN, 1155 .targetsize = ARPT_FUNCTION_MAXNAMELEN,
1156 .family = NF_ARP,
1155}; 1157};
1156 1158
1157static struct nf_sockopt_ops arpt_sockopts = { 1159static struct nf_sockopt_ops arpt_sockopts = {
@@ -1171,8 +1173,8 @@ static int __init init(void)
1171 xt_proto_init(NF_ARP); 1173 xt_proto_init(NF_ARP);
1172 1174
1173 /* Noone else will be downing sem now, so we won't sleep */ 1175 /* Noone else will be downing sem now, so we won't sleep */
1174 xt_register_target(NF_ARP, &arpt_standard_target); 1176 xt_register_target(&arpt_standard_target);
1175 xt_register_target(NF_ARP, &arpt_error_target); 1177 xt_register_target(&arpt_error_target);
1176 1178
1177 /* Register setsockopt */ 1179 /* Register setsockopt */
1178 ret = nf_register_sockopt(&arpt_sockopts); 1180 ret = nf_register_sockopt(&arpt_sockopts);
diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c
index 84c66dbfedaf..9e34034729a6 100644
--- a/net/ipv4/netfilter/ip_conntrack_core.c
+++ b/net/ipv4/netfilter/ip_conntrack_core.c
@@ -77,8 +77,8 @@ unsigned int ip_ct_log_invalid;
77static LIST_HEAD(unconfirmed); 77static LIST_HEAD(unconfirmed);
78static int ip_conntrack_vmalloc; 78static int ip_conntrack_vmalloc;
79 79
80static unsigned int ip_conntrack_next_id = 1; 80static unsigned int ip_conntrack_next_id;
81static unsigned int ip_conntrack_expect_next_id = 1; 81static unsigned int ip_conntrack_expect_next_id;
82#ifdef CONFIG_IP_NF_CONNTRACK_EVENTS 82#ifdef CONFIG_IP_NF_CONNTRACK_EVENTS
83struct notifier_block *ip_conntrack_chain; 83struct notifier_block *ip_conntrack_chain;
84struct notifier_block *ip_conntrack_expect_chain; 84struct notifier_block *ip_conntrack_expect_chain;
diff --git a/net/ipv4/netfilter/ip_conntrack_helper_h323.c b/net/ipv4/netfilter/ip_conntrack_helper_h323.c
index 20da6730b860..daeb1395faa4 100644
--- a/net/ipv4/netfilter/ip_conntrack_helper_h323.c
+++ b/net/ipv4/netfilter/ip_conntrack_helper_h323.c
@@ -639,8 +639,8 @@ void ip_conntrack_h245_expect(struct ip_conntrack *new,
639} 639}
640 640
641/****************************************************************************/ 641/****************************************************************************/
642static int get_h225_addr(unsigned char *data, TransportAddress * addr, 642int get_h225_addr(unsigned char *data, TransportAddress * addr,
643 u_int32_t * ip, u_int16_t * port) 643 u_int32_t * ip, u_int16_t * port)
644{ 644{
645 unsigned char *p; 645 unsigned char *p;
646 646
diff --git a/net/ipv4/netfilter/ip_conntrack_netlink.c b/net/ipv4/netfilter/ip_conntrack_netlink.c
index 5ce2e3fc2c7f..9b6e19bae90f 100644
--- a/net/ipv4/netfilter/ip_conntrack_netlink.c
+++ b/net/ipv4/netfilter/ip_conntrack_netlink.c
@@ -4,7 +4,7 @@
4 * (C) 2001 by Jay Schulist <jschlst@samba.org> 4 * (C) 2001 by Jay Schulist <jschlst@samba.org>
5 * (C) 2002-2005 by Harald Welte <laforge@gnumonks.org> 5 * (C) 2002-2005 by Harald Welte <laforge@gnumonks.org>
6 * (C) 2003 by Patrick Mchardy <kaber@trash.net> 6 * (C) 2003 by Patrick Mchardy <kaber@trash.net>
7 * (C) 2005 by Pablo Neira Ayuso <pablo@eurodev.net> 7 * (C) 2005-2006 by Pablo Neira Ayuso <pablo@eurodev.net>
8 * 8 *
9 * I've reworked this stuff to use attributes instead of conntrack 9 * I've reworked this stuff to use attributes instead of conntrack
10 * structures. 5.44 am. I need more tea. --pablo 05/07/11. 10 * structures. 5.44 am. I need more tea. --pablo 05/07/11.
@@ -53,20 +53,18 @@ static char __initdata version[] = "0.90";
53 53
54static inline int 54static inline int
55ctnetlink_dump_tuples_proto(struct sk_buff *skb, 55ctnetlink_dump_tuples_proto(struct sk_buff *skb,
56 const struct ip_conntrack_tuple *tuple) 56 const struct ip_conntrack_tuple *tuple,
57 struct ip_conntrack_protocol *proto)
57{ 58{
58 struct ip_conntrack_protocol *proto;
59 int ret = 0; 59 int ret = 0;
60 struct nfattr *nest_parms = NFA_NEST(skb, CTA_TUPLE_PROTO);
60 61
61 NFA_PUT(skb, CTA_PROTO_NUM, sizeof(u_int8_t), &tuple->dst.protonum); 62 NFA_PUT(skb, CTA_PROTO_NUM, sizeof(u_int8_t), &tuple->dst.protonum);
62 63
63 /* If no protocol helper is found, this function will return the
64 * generic protocol helper, so proto won't *ever* be NULL */
65 proto = ip_conntrack_proto_find_get(tuple->dst.protonum);
66 if (likely(proto->tuple_to_nfattr)) 64 if (likely(proto->tuple_to_nfattr))
67 ret = proto->tuple_to_nfattr(skb, tuple); 65 ret = proto->tuple_to_nfattr(skb, tuple);
68 66
69 ip_conntrack_proto_put(proto); 67 NFA_NEST_END(skb, nest_parms);
70 68
71 return ret; 69 return ret;
72 70
@@ -75,28 +73,41 @@ nfattr_failure:
75} 73}
76 74
77static inline int 75static inline int
78ctnetlink_dump_tuples(struct sk_buff *skb, 76ctnetlink_dump_tuples_ip(struct sk_buff *skb,
79 const struct ip_conntrack_tuple *tuple) 77 const struct ip_conntrack_tuple *tuple)
80{ 78{
81 struct nfattr *nest_parms; 79 struct nfattr *nest_parms = NFA_NEST(skb, CTA_TUPLE_IP);
82 int ret;
83 80
84 nest_parms = NFA_NEST(skb, CTA_TUPLE_IP);
85 NFA_PUT(skb, CTA_IP_V4_SRC, sizeof(u_int32_t), &tuple->src.ip); 81 NFA_PUT(skb, CTA_IP_V4_SRC, sizeof(u_int32_t), &tuple->src.ip);
86 NFA_PUT(skb, CTA_IP_V4_DST, sizeof(u_int32_t), &tuple->dst.ip); 82 NFA_PUT(skb, CTA_IP_V4_DST, sizeof(u_int32_t), &tuple->dst.ip);
87 NFA_NEST_END(skb, nest_parms);
88 83
89 nest_parms = NFA_NEST(skb, CTA_TUPLE_PROTO);
90 ret = ctnetlink_dump_tuples_proto(skb, tuple);
91 NFA_NEST_END(skb, nest_parms); 84 NFA_NEST_END(skb, nest_parms);
92 85
93 return ret; 86 return 0;
94 87
95nfattr_failure: 88nfattr_failure:
96 return -1; 89 return -1;
97} 90}
98 91
99static inline int 92static inline int
93ctnetlink_dump_tuples(struct sk_buff *skb,
94 const struct ip_conntrack_tuple *tuple)
95{
96 int ret;
97 struct ip_conntrack_protocol *proto;
98
99 ret = ctnetlink_dump_tuples_ip(skb, tuple);
100 if (unlikely(ret < 0))
101 return ret;
102
103 proto = ip_conntrack_proto_find_get(tuple->dst.protonum);
104 ret = ctnetlink_dump_tuples_proto(skb, tuple, proto);
105 ip_conntrack_proto_put(proto);
106
107 return ret;
108}
109
110static inline int
100ctnetlink_dump_status(struct sk_buff *skb, const struct ip_conntrack *ct) 111ctnetlink_dump_status(struct sk_buff *skb, const struct ip_conntrack *ct)
101{ 112{
102 u_int32_t status = htonl((u_int32_t) ct->status); 113 u_int32_t status = htonl((u_int32_t) ct->status);
@@ -1135,6 +1146,33 @@ nfattr_failure:
1135} 1146}
1136 1147
1137static inline int 1148static inline int
1149ctnetlink_exp_dump_mask(struct sk_buff *skb,
1150 const struct ip_conntrack_tuple *tuple,
1151 const struct ip_conntrack_tuple *mask)
1152{
1153 int ret;
1154 struct ip_conntrack_protocol *proto;
1155 struct nfattr *nest_parms = NFA_NEST(skb, CTA_EXPECT_MASK);
1156
1157 ret = ctnetlink_dump_tuples_ip(skb, mask);
1158 if (unlikely(ret < 0))
1159 goto nfattr_failure;
1160
1161 proto = ip_conntrack_proto_find_get(tuple->dst.protonum);
1162 ret = ctnetlink_dump_tuples_proto(skb, mask, proto);
1163 ip_conntrack_proto_put(proto);
1164 if (unlikely(ret < 0))
1165 goto nfattr_failure;
1166
1167 NFA_NEST_END(skb, nest_parms);
1168
1169 return 0;
1170
1171nfattr_failure:
1172 return -1;
1173}
1174
1175static inline int
1138ctnetlink_exp_dump_expect(struct sk_buff *skb, 1176ctnetlink_exp_dump_expect(struct sk_buff *skb,
1139 const struct ip_conntrack_expect *exp) 1177 const struct ip_conntrack_expect *exp)
1140{ 1178{
@@ -1144,7 +1182,7 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb,
1144 1182
1145 if (ctnetlink_exp_dump_tuple(skb, &exp->tuple, CTA_EXPECT_TUPLE) < 0) 1183 if (ctnetlink_exp_dump_tuple(skb, &exp->tuple, CTA_EXPECT_TUPLE) < 0)
1146 goto nfattr_failure; 1184 goto nfattr_failure;
1147 if (ctnetlink_exp_dump_tuple(skb, &exp->mask, CTA_EXPECT_MASK) < 0) 1185 if (ctnetlink_exp_dump_mask(skb, &exp->tuple, &exp->mask) < 0)
1148 goto nfattr_failure; 1186 goto nfattr_failure;
1149 if (ctnetlink_exp_dump_tuple(skb, 1187 if (ctnetlink_exp_dump_tuple(skb,
1150 &master->tuplehash[IP_CT_DIR_ORIGINAL].tuple, 1188 &master->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 39705f9bc154..a7b194c4d79d 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -1335,12 +1335,14 @@ icmp_checkentry(const char *tablename,
1335static struct ipt_target ipt_standard_target = { 1335static struct ipt_target ipt_standard_target = {
1336 .name = IPT_STANDARD_TARGET, 1336 .name = IPT_STANDARD_TARGET,
1337 .targetsize = sizeof(int), 1337 .targetsize = sizeof(int),
1338 .family = AF_INET,
1338}; 1339};
1339 1340
1340static struct ipt_target ipt_error_target = { 1341static struct ipt_target ipt_error_target = {
1341 .name = IPT_ERROR_TARGET, 1342 .name = IPT_ERROR_TARGET,
1342 .target = ipt_error, 1343 .target = ipt_error,
1343 .targetsize = IPT_FUNCTION_MAXNAMELEN, 1344 .targetsize = IPT_FUNCTION_MAXNAMELEN,
1345 .family = AF_INET,
1344}; 1346};
1345 1347
1346static struct nf_sockopt_ops ipt_sockopts = { 1348static struct nf_sockopt_ops ipt_sockopts = {
@@ -1358,6 +1360,7 @@ static struct ipt_match icmp_matchstruct = {
1358 .match = icmp_match, 1360 .match = icmp_match,
1359 .matchsize = sizeof(struct ipt_icmp), 1361 .matchsize = sizeof(struct ipt_icmp),
1360 .proto = IPPROTO_ICMP, 1362 .proto = IPPROTO_ICMP,
1363 .family = AF_INET,
1361 .checkentry = icmp_checkentry, 1364 .checkentry = icmp_checkentry,
1362}; 1365};
1363 1366
@@ -1368,9 +1371,9 @@ static int __init init(void)
1368 xt_proto_init(AF_INET); 1371 xt_proto_init(AF_INET);
1369 1372
1370 /* Noone else will be downing sem now, so we won't sleep */ 1373 /* Noone else will be downing sem now, so we won't sleep */
1371 xt_register_target(AF_INET, &ipt_standard_target); 1374 xt_register_target(&ipt_standard_target);
1372 xt_register_target(AF_INET, &ipt_error_target); 1375 xt_register_target(&ipt_error_target);
1373 xt_register_match(AF_INET, &icmp_matchstruct); 1376 xt_register_match(&icmp_matchstruct);
1374 1377
1375 /* Register setsockopt */ 1378 /* Register setsockopt */
1376 ret = nf_register_sockopt(&ipt_sockopts); 1379 ret = nf_register_sockopt(&ipt_sockopts);
@@ -1387,9 +1390,9 @@ static void __exit fini(void)
1387{ 1390{
1388 nf_unregister_sockopt(&ipt_sockopts); 1391 nf_unregister_sockopt(&ipt_sockopts);
1389 1392
1390 xt_unregister_match(AF_INET, &icmp_matchstruct); 1393 xt_unregister_match(&icmp_matchstruct);
1391 xt_unregister_target(AF_INET, &ipt_error_target); 1394 xt_unregister_target(&ipt_error_target);
1392 xt_unregister_target(AF_INET, &ipt_standard_target); 1395 xt_unregister_target(&ipt_standard_target);
1393 1396
1394 xt_proto_fini(AF_INET); 1397 xt_proto_fini(AF_INET);
1395} 1398}
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index cb9c661f3f33..c8abc9d859b9 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)
568 return ret; 568 return ret;
569} 569}
570 570
571MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET));
571MODULE_LICENSE("GPL"); 572MODULE_LICENSE("GPL");
572 573
573static int __init init(void) 574static int __init init(void)
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 602feec47738..4c20eeb3d568 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -907,7 +907,7 @@ int ipv6_getsockopt(struct sock *sk, int level, int optname,
907 err = do_ipv6_getsockopt(sk, level, optname, optval, optlen); 907 err = do_ipv6_getsockopt(sk, level, optname, optval, optlen);
908#ifdef CONFIG_NETFILTER 908#ifdef CONFIG_NETFILTER
909 /* we need to exclude all possible EINVALs except default case */ 909 /* we need to exclude all possible EINVALs except default case */
910 if (err == -ENOPROTOOPT && optname != IPV6_ADDRFORM && 910 if (err == -EINVAL && optname != IPV6_ADDRFORM &&
911 optname != MCAST_MSFILTER) { 911 optname != MCAST_MSFILTER) {
912 int len; 912 int len;
913 913
@@ -944,7 +944,7 @@ int compat_ipv6_getsockopt(struct sock *sk, int level, int optname,
944 err = do_ipv6_getsockopt(sk, level, optname, optval, optlen); 944 err = do_ipv6_getsockopt(sk, level, optname, optval, optlen);
945#ifdef CONFIG_NETFILTER 945#ifdef CONFIG_NETFILTER
946 /* we need to exclude all possible EINVALs except default case */ 946 /* we need to exclude all possible EINVALs except default case */
947 if (err == -ENOPROTOOPT && optname != IPV6_ADDRFORM && 947 if (err == -EINVAL && optname != IPV6_ADDRFORM &&
948 optname != MCAST_MSFILTER) { 948 optname != MCAST_MSFILTER) {
949 int len; 949 int len;
950 950
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 5a2063bda676..db3c9ae98e95 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -1377,12 +1377,14 @@ icmp6_checkentry(const char *tablename,
1377static struct ip6t_target ip6t_standard_target = { 1377static struct ip6t_target ip6t_standard_target = {
1378 .name = IP6T_STANDARD_TARGET, 1378 .name = IP6T_STANDARD_TARGET,
1379 .targetsize = sizeof(int), 1379 .targetsize = sizeof(int),
1380 .family = AF_INET6,
1380}; 1381};
1381 1382
1382static struct ip6t_target ip6t_error_target = { 1383static struct ip6t_target ip6t_error_target = {
1383 .name = IP6T_ERROR_TARGET, 1384 .name = IP6T_ERROR_TARGET,
1384 .target = ip6t_error, 1385 .target = ip6t_error,
1385 .targetsize = IP6T_FUNCTION_MAXNAMELEN, 1386 .targetsize = IP6T_FUNCTION_MAXNAMELEN,
1387 .family = AF_INET6,
1386}; 1388};
1387 1389
1388static struct nf_sockopt_ops ip6t_sockopts = { 1390static struct nf_sockopt_ops ip6t_sockopts = {
@@ -1401,6 +1403,7 @@ static struct ip6t_match icmp6_matchstruct = {
1401 .matchsize = sizeof(struct ip6t_icmp), 1403 .matchsize = sizeof(struct ip6t_icmp),
1402 .checkentry = icmp6_checkentry, 1404 .checkentry = icmp6_checkentry,
1403 .proto = IPPROTO_ICMPV6, 1405 .proto = IPPROTO_ICMPV6,
1406 .family = AF_INET6,
1404}; 1407};
1405 1408
1406static int __init init(void) 1409static int __init init(void)
@@ -1410,9 +1413,9 @@ static int __init init(void)
1410 xt_proto_init(AF_INET6); 1413 xt_proto_init(AF_INET6);
1411 1414
1412 /* Noone else will be downing sem now, so we won't sleep */ 1415 /* Noone else will be downing sem now, so we won't sleep */
1413 xt_register_target(AF_INET6, &ip6t_standard_target); 1416 xt_register_target(&ip6t_standard_target);
1414 xt_register_target(AF_INET6, &ip6t_error_target); 1417 xt_register_target(&ip6t_error_target);
1415 xt_register_match(AF_INET6, &icmp6_matchstruct); 1418 xt_register_match(&icmp6_matchstruct);
1416 1419
1417 /* Register setsockopt */ 1420 /* Register setsockopt */
1418 ret = nf_register_sockopt(&ip6t_sockopts); 1421 ret = nf_register_sockopt(&ip6t_sockopts);
@@ -1429,9 +1432,9 @@ static int __init init(void)
1429static void __exit fini(void) 1432static void __exit fini(void)
1430{ 1433{
1431 nf_unregister_sockopt(&ip6t_sockopts); 1434 nf_unregister_sockopt(&ip6t_sockopts);
1432 xt_unregister_match(AF_INET6, &icmp6_matchstruct); 1435 xt_unregister_match(&icmp6_matchstruct);
1433 xt_unregister_target(AF_INET6, &ip6t_error_target); 1436 xt_unregister_target(&ip6t_error_target);
1434 xt_unregister_target(AF_INET6, &ip6t_standard_target); 1437 xt_unregister_target(&ip6t_standard_target);
1435 xt_proto_fini(AF_INET6); 1438 xt_proto_fini(AF_INET6);
1436} 1439}
1437 1440
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index ac35f9526368..c16f62934bd9 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)
584 return ret; 584 return ret;
585} 585}
586 586
587MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET6));
587MODULE_LICENSE("GPL"); 588MODULE_LICENSE("GPL");
588MODULE_AUTHOR("Yasuyuki KOZAKAI @USAGI <yasuyuki.kozakai@toshiba.co.jp>"); 589MODULE_AUTHOR("Yasuyuki KOZAKAI @USAGI <yasuyuki.kozakai@toshiba.co.jp>");
589 590
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 174027809148..332acb37b385 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -11,7 +11,7 @@ config NETFILTER_NETLINK_QUEUE
11 tristate "Netfilter NFQUEUE over NFNETLINK interface" 11 tristate "Netfilter NFQUEUE over NFNETLINK interface"
12 depends on NETFILTER_NETLINK 12 depends on NETFILTER_NETLINK
13 help 13 help
14 If this option isenabled, the kernel will include support 14 If this option is enabled, the kernel will include support
15 for queueing packets via NFNETLINK. 15 for queueing packets via NFNETLINK.
16 16
17config NETFILTER_NETLINK_LOG 17config NETFILTER_NETLINK_LOG
@@ -66,7 +66,7 @@ config NF_CONNTRACK_EVENTS
66 help 66 help
67 If this option is enabled, the connection tracking code will 67 If this option is enabled, the connection tracking code will
68 provide a notifier chain that can be used by other kernel code 68 provide a notifier chain that can be used by other kernel code
69 to get notified aboutchanges in the connection tracking state. 69 to get notified about changes in the connection tracking state.
70 70
71 If unsure, say `N'. 71 If unsure, say `N'.
72 72
@@ -153,7 +153,7 @@ config NETFILTER_XT_TARGET_NFQUEUE
153 tristate '"NFQUEUE" target Support' 153 tristate '"NFQUEUE" target Support'
154 depends on NETFILTER_XTABLES 154 depends on NETFILTER_XTABLES
155 help 155 help
156 This Target replaced the old obsolete QUEUE target. 156 This target replaced the old obsolete QUEUE target.
157 157
158 As opposed to QUEUE, it supports 65535 different queues, 158 As opposed to QUEUE, it supports 65535 different queues,
159 not just one. 159 not just one.
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index f6498234e264..0ae281d9bfc3 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -23,6 +23,8 @@
23 * 26 Jan 2006: Harald Welte <laforge@netfilter.org> 23 * 26 Jan 2006: Harald Welte <laforge@netfilter.org>
24 * - restructure nf_conn (introduce nf_conn_help) 24 * - restructure nf_conn (introduce nf_conn_help)
25 * - redesign 'features' how they were originally intended 25 * - redesign 'features' how they were originally intended
26 * 26 Feb 2006: Pablo Neira Ayuso <pablo@eurodev.net>
27 * - add support for L3 protocol module load on demand.
26 * 28 *
27 * Derived from net/ipv4/netfilter/ip_conntrack_core.c 29 * Derived from net/ipv4/netfilter/ip_conntrack_core.c
28 */ 30 */
@@ -85,8 +87,8 @@ unsigned int nf_ct_log_invalid;
85static LIST_HEAD(unconfirmed); 87static LIST_HEAD(unconfirmed);
86static int nf_conntrack_vmalloc; 88static int nf_conntrack_vmalloc;
87 89
88static unsigned int nf_conntrack_next_id = 1; 90static unsigned int nf_conntrack_next_id;
89static unsigned int nf_conntrack_expect_next_id = 1; 91static unsigned int nf_conntrack_expect_next_id;
90#ifdef CONFIG_NF_CONNTRACK_EVENTS 92#ifdef CONFIG_NF_CONNTRACK_EVENTS
91struct notifier_block *nf_conntrack_chain; 93struct notifier_block *nf_conntrack_chain;
92struct notifier_block *nf_conntrack_expect_chain; 94struct notifier_block *nf_conntrack_expect_chain;
@@ -241,6 +243,35 @@ void nf_ct_l3proto_put(struct nf_conntrack_l3proto *p)
241 module_put(p->me); 243 module_put(p->me);
242} 244}
243 245
246int
247nf_ct_l3proto_try_module_get(unsigned short l3proto)
248{
249 int ret;
250 struct nf_conntrack_l3proto *p;
251
252retry: p = nf_ct_l3proto_find_get(l3proto);
253 if (p == &nf_conntrack_generic_l3proto) {
254 ret = request_module("nf_conntrack-%d", l3proto);
255 if (!ret)
256 goto retry;
257
258 return -EPROTOTYPE;
259 }
260
261 return 0;
262}
263
264void nf_ct_l3proto_module_put(unsigned short l3proto)
265{
266 struct nf_conntrack_l3proto *p;
267
268 preempt_disable();
269 p = __nf_ct_l3proto_find(l3proto);
270 preempt_enable();
271
272 module_put(p->me);
273}
274
244static int nf_conntrack_hash_rnd_initted; 275static int nf_conntrack_hash_rnd_initted;
245static unsigned int nf_conntrack_hash_rnd; 276static unsigned int nf_conntrack_hash_rnd;
246 277
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 5eadf009bb15..0e0e9d7b34c8 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -4,7 +4,7 @@
4 * (C) 2001 by Jay Schulist <jschlst@samba.org> 4 * (C) 2001 by Jay Schulist <jschlst@samba.org>
5 * (C) 2002-2006 by Harald Welte <laforge@gnumonks.org> 5 * (C) 2002-2006 by Harald Welte <laforge@gnumonks.org>
6 * (C) 2003 by Patrick Mchardy <kaber@trash.net> 6 * (C) 2003 by Patrick Mchardy <kaber@trash.net>
7 * (C) 2005 by Pablo Neira Ayuso <pablo@eurodev.net> 7 * (C) 2005-2006 by Pablo Neira Ayuso <pablo@eurodev.net>
8 * 8 *
9 * I've reworked this stuff to use attributes instead of conntrack 9 * I've reworked this stuff to use attributes instead of conntrack
10 * structures. 5.44 am. I need more tea. --pablo 05/07/11. 10 * structures. 5.44 am. I need more tea. --pablo 05/07/11.
@@ -55,20 +55,18 @@ static char __initdata version[] = "0.93";
55 55
56static inline int 56static inline int
57ctnetlink_dump_tuples_proto(struct sk_buff *skb, 57ctnetlink_dump_tuples_proto(struct sk_buff *skb,
58 const struct nf_conntrack_tuple *tuple) 58 const struct nf_conntrack_tuple *tuple,
59 struct nf_conntrack_protocol *proto)
59{ 60{
60 struct nf_conntrack_protocol *proto;
61 int ret = 0; 61 int ret = 0;
62 struct nfattr *nest_parms = NFA_NEST(skb, CTA_TUPLE_PROTO);
62 63
63 NFA_PUT(skb, CTA_PROTO_NUM, sizeof(u_int8_t), &tuple->dst.protonum); 64 NFA_PUT(skb, CTA_PROTO_NUM, sizeof(u_int8_t), &tuple->dst.protonum);
64 65
65 /* If no protocol helper is found, this function will return the
66 * generic protocol helper, so proto won't *ever* be NULL */
67 proto = nf_ct_proto_find_get(tuple->src.l3num, tuple->dst.protonum);
68 if (likely(proto->tuple_to_nfattr)) 66 if (likely(proto->tuple_to_nfattr))
69 ret = proto->tuple_to_nfattr(skb, tuple); 67 ret = proto->tuple_to_nfattr(skb, tuple);
70 68
71 nf_ct_proto_put(proto); 69 NFA_NEST_END(skb, nest_parms);
72 70
73 return ret; 71 return ret;
74 72
@@ -77,33 +75,44 @@ nfattr_failure:
77} 75}
78 76
79static inline int 77static inline int
80ctnetlink_dump_tuples(struct sk_buff *skb, 78ctnetlink_dump_tuples_ip(struct sk_buff *skb,
81 const struct nf_conntrack_tuple *tuple) 79 const struct nf_conntrack_tuple *tuple,
80 struct nf_conntrack_l3proto *l3proto)
82{ 81{
83 struct nfattr *nest_parms;
84 struct nf_conntrack_l3proto *l3proto;
85 int ret = 0; 82 int ret = 0;
86 83 struct nfattr *nest_parms = NFA_NEST(skb, CTA_TUPLE_IP);
87 l3proto = nf_ct_l3proto_find_get(tuple->src.l3num); 84
88
89 nest_parms = NFA_NEST(skb, CTA_TUPLE_IP);
90 if (likely(l3proto->tuple_to_nfattr)) 85 if (likely(l3proto->tuple_to_nfattr))
91 ret = l3proto->tuple_to_nfattr(skb, tuple); 86 ret = l3proto->tuple_to_nfattr(skb, tuple);
87
92 NFA_NEST_END(skb, nest_parms); 88 NFA_NEST_END(skb, nest_parms);
93 89
90 return ret;
91
92nfattr_failure:
93 return -1;
94}
95
96static inline int
97ctnetlink_dump_tuples(struct sk_buff *skb,
98 const struct nf_conntrack_tuple *tuple)
99{
100 int ret;
101 struct nf_conntrack_l3proto *l3proto;
102 struct nf_conntrack_protocol *proto;
103
104 l3proto = nf_ct_l3proto_find_get(tuple->src.l3num);
105 ret = ctnetlink_dump_tuples_ip(skb, tuple, l3proto);
94 nf_ct_l3proto_put(l3proto); 106 nf_ct_l3proto_put(l3proto);
95 107
96 if (unlikely(ret < 0)) 108 if (unlikely(ret < 0))
97 return ret; 109 return ret;
98 110
99 nest_parms = NFA_NEST(skb, CTA_TUPLE_PROTO); 111 proto = nf_ct_proto_find_get(tuple->src.l3num, tuple->dst.protonum);
100 ret = ctnetlink_dump_tuples_proto(skb, tuple); 112 ret = ctnetlink_dump_tuples_proto(skb, tuple, proto);
101 NFA_NEST_END(skb, nest_parms); 113 nf_ct_proto_put(proto);
102 114
103 return ret; 115 return ret;
104
105nfattr_failure:
106 return -1;
107} 116}
108 117
109static inline int 118static inline int
@@ -1153,6 +1162,37 @@ nfattr_failure:
1153} 1162}
1154 1163
1155static inline int 1164static inline int
1165ctnetlink_exp_dump_mask(struct sk_buff *skb,
1166 const struct nf_conntrack_tuple *tuple,
1167 const struct nf_conntrack_tuple *mask)
1168{
1169 int ret;
1170 struct nf_conntrack_l3proto *l3proto;
1171 struct nf_conntrack_protocol *proto;
1172 struct nfattr *nest_parms = NFA_NEST(skb, CTA_EXPECT_MASK);
1173
1174 l3proto = nf_ct_l3proto_find_get(tuple->src.l3num);
1175 ret = ctnetlink_dump_tuples_ip(skb, mask, l3proto);
1176 nf_ct_l3proto_put(l3proto);
1177
1178 if (unlikely(ret < 0))
1179 goto nfattr_failure;
1180
1181 proto = nf_ct_proto_find_get(tuple->src.l3num, tuple->dst.protonum);
1182 ret = ctnetlink_dump_tuples_proto(skb, mask, proto);
1183 nf_ct_proto_put(proto);
1184 if (unlikely(ret < 0))
1185 goto nfattr_failure;
1186
1187 NFA_NEST_END(skb, nest_parms);
1188
1189 return 0;
1190
1191nfattr_failure:
1192 return -1;
1193}
1194
1195static inline int
1156ctnetlink_exp_dump_expect(struct sk_buff *skb, 1196ctnetlink_exp_dump_expect(struct sk_buff *skb,
1157 const struct nf_conntrack_expect *exp) 1197 const struct nf_conntrack_expect *exp)
1158{ 1198{
@@ -1162,7 +1202,7 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb,
1162 1202
1163 if (ctnetlink_exp_dump_tuple(skb, &exp->tuple, CTA_EXPECT_TUPLE) < 0) 1203 if (ctnetlink_exp_dump_tuple(skb, &exp->tuple, CTA_EXPECT_TUPLE) < 0)
1164 goto nfattr_failure; 1204 goto nfattr_failure;
1165 if (ctnetlink_exp_dump_tuple(skb, &exp->mask, CTA_EXPECT_MASK) < 0) 1205 if (ctnetlink_exp_dump_mask(skb, &exp->tuple, &exp->mask) < 0)
1166 goto nfattr_failure; 1206 goto nfattr_failure;
1167 if (ctnetlink_exp_dump_tuple(skb, 1207 if (ctnetlink_exp_dump_tuple(skb,
1168 &master->tuplehash[IP_CT_DIR_ORIGINAL].tuple, 1208 &master->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
index 290d5a0c559b..75577e175b35 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_init);
834EXPORT_PER_CPU_SYMBOL_GPL(nf_conntrack_ecache); 834EXPORT_PER_CPU_SYMBOL_GPL(nf_conntrack_ecache);
835EXPORT_SYMBOL_GPL(nf_ct_deliver_cached_events); 835EXPORT_SYMBOL_GPL(nf_ct_deliver_cached_events);
836#endif 836#endif
837EXPORT_SYMBOL(nf_ct_l3proto_try_module_get);
838EXPORT_SYMBOL(nf_ct_l3proto_module_put);
837EXPORT_SYMBOL(nf_conntrack_l3proto_register); 839EXPORT_SYMBOL(nf_conntrack_l3proto_register);
838EXPORT_SYMBOL(nf_conntrack_l3proto_unregister); 840EXPORT_SYMBOL(nf_conntrack_l3proto_unregister);
839EXPORT_SYMBOL(nf_conntrack_protocol_register); 841EXPORT_SYMBOL(nf_conntrack_protocol_register);
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index 2cf5fb8322c4..b5701662182e 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -354,16 +354,17 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
354 QDEBUG("entered\n"); 354 QDEBUG("entered\n");
355 355
356 /* all macros expand to constant values at compile time */ 356 /* all macros expand to constant values at compile time */
357 size = NLMSG_SPACE(sizeof(struct nfqnl_msg_packet_hdr)) 357 size = NLMSG_SPACE(sizeof(struct nfgenmsg)) +
358 + NLMSG_SPACE(sizeof(u_int32_t)) /* ifindex */ 358 + NFA_SPACE(sizeof(struct nfqnl_msg_packet_hdr))
359 + NLMSG_SPACE(sizeof(u_int32_t)) /* ifindex */ 359 + NFA_SPACE(sizeof(u_int32_t)) /* ifindex */
360 + NFA_SPACE(sizeof(u_int32_t)) /* ifindex */
360#ifdef CONFIG_BRIDGE_NETFILTER 361#ifdef CONFIG_BRIDGE_NETFILTER
361 + NLMSG_SPACE(sizeof(u_int32_t)) /* ifindex */ 362 + NFA_SPACE(sizeof(u_int32_t)) /* ifindex */
362 + NLMSG_SPACE(sizeof(u_int32_t)) /* ifindex */ 363 + NFA_SPACE(sizeof(u_int32_t)) /* ifindex */
363#endif 364#endif
364 + NLMSG_SPACE(sizeof(u_int32_t)) /* mark */ 365 + NFA_SPACE(sizeof(u_int32_t)) /* mark */
365 + NLMSG_SPACE(sizeof(struct nfqnl_msg_packet_hw)) 366 + NFA_SPACE(sizeof(struct nfqnl_msg_packet_hw))
366 + NLMSG_SPACE(sizeof(struct nfqnl_msg_packet_timestamp)); 367 + NFA_SPACE(sizeof(struct nfqnl_msg_packet_timestamp));
367 368
368 outdev = entinf->outdev; 369 outdev = entinf->outdev;
369 370
@@ -388,7 +389,7 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
388 else 389 else
389 data_len = queue->copy_range; 390 data_len = queue->copy_range;
390 391
391 size += NLMSG_SPACE(data_len); 392 size += NFA_SPACE(data_len);
392 break; 393 break;
393 394
394 default: 395 default:
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index 750b92829766..0a29a24d9a72 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -60,9 +60,9 @@ static const char *xt_prefix[NPROTO] = {
60 60
61/* Registration hooks for targets. */ 61/* Registration hooks for targets. */
62int 62int
63xt_register_target(int af, struct xt_target *target) 63xt_register_target(struct xt_target *target)
64{ 64{
65 int ret; 65 int ret, af = target->family;
66 66
67 ret = down_interruptible(&xt[af].mutex); 67 ret = down_interruptible(&xt[af].mutex);
68 if (ret != 0) 68 if (ret != 0)
@@ -74,8 +74,10 @@ xt_register_target(int af, struct xt_target *target)
74EXPORT_SYMBOL(xt_register_target); 74EXPORT_SYMBOL(xt_register_target);
75 75
76void 76void
77xt_unregister_target(int af, struct xt_target *target) 77xt_unregister_target(struct xt_target *target)
78{ 78{
79 int af = target->family;
80
79 down(&xt[af].mutex); 81 down(&xt[af].mutex);
80 LIST_DELETE(&xt[af].target, target); 82 LIST_DELETE(&xt[af].target, target);
81 up(&xt[af].mutex); 83 up(&xt[af].mutex);
@@ -83,9 +85,9 @@ xt_unregister_target(int af, struct xt_target *target)
83EXPORT_SYMBOL(xt_unregister_target); 85EXPORT_SYMBOL(xt_unregister_target);
84 86
85int 87int
86xt_register_match(int af, struct xt_match *match) 88xt_register_match(struct xt_match *match)
87{ 89{
88 int ret; 90 int ret, af = match->family;
89 91
90 ret = down_interruptible(&xt[af].mutex); 92 ret = down_interruptible(&xt[af].mutex);
91 if (ret != 0) 93 if (ret != 0)
@@ -99,8 +101,10 @@ xt_register_match(int af, struct xt_match *match)
99EXPORT_SYMBOL(xt_register_match); 101EXPORT_SYMBOL(xt_register_match);
100 102
101void 103void
102xt_unregister_match(int af, struct xt_match *match) 104xt_unregister_match(struct xt_match *match)
103{ 105{
106 int af = match->family;
107
104 down(&xt[af].mutex); 108 down(&xt[af].mutex);
105 LIST_DELETE(&xt[af].match, match); 109 LIST_DELETE(&xt[af].match, match);
106 up(&xt[af].mutex); 110 up(&xt[af].mutex);
diff --git a/net/netfilter/xt_CLASSIFY.c b/net/netfilter/xt_CLASSIFY.c
index 3224ed87d4c7..3cd2ac90a25b 100644
--- a/net/netfilter/xt_CLASSIFY.c
+++ b/net/netfilter/xt_CLASSIFY.c
@@ -47,6 +47,7 @@ static struct xt_target classify_reg = {
47 .table = "mangle", 47 .table = "mangle",
48 .hooks = (1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_FORWARD) | 48 .hooks = (1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_FORWARD) |
49 (1 << NF_IP_POST_ROUTING), 49 (1 << NF_IP_POST_ROUTING),
50 .family = AF_INET,
50 .me = THIS_MODULE, 51 .me = THIS_MODULE,
51}; 52};
52static struct xt_target classify6_reg = { 53static struct xt_target classify6_reg = {
@@ -56,6 +57,7 @@ static struct xt_target classify6_reg = {
56 .table = "mangle", 57 .table = "mangle",
57 .hooks = (1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_FORWARD) | 58 .hooks = (1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_FORWARD) |
58 (1 << NF_IP_POST_ROUTING), 59 (1 << NF_IP_POST_ROUTING),
60 .family = AF_INET6,
59 .me = THIS_MODULE, 61 .me = THIS_MODULE,
60}; 62};
61 63
@@ -64,21 +66,21 @@ static int __init init(void)
64{ 66{
65 int ret; 67 int ret;
66 68
67 ret = xt_register_target(AF_INET, &classify_reg); 69 ret = xt_register_target(&classify_reg);
68 if (ret) 70 if (ret)
69 return ret; 71 return ret;
70 72
71 ret = xt_register_target(AF_INET6, &classify6_reg); 73 ret = xt_register_target(&classify6_reg);
72 if (ret) 74 if (ret)
73 xt_unregister_target(AF_INET, &classify_reg); 75 xt_unregister_target(&classify_reg);
74 76
75 return ret; 77 return ret;
76} 78}
77 79
78static void __exit fini(void) 80static void __exit fini(void)
79{ 81{
80 xt_unregister_target(AF_INET, &classify_reg); 82 xt_unregister_target(&classify_reg);
81 xt_unregister_target(AF_INET6, &classify6_reg); 83 xt_unregister_target(&classify6_reg);
82} 84}
83 85
84module_init(init); 86module_init(init);
diff --git a/net/netfilter/xt_CONNMARK.c b/net/netfilter/xt_CONNMARK.c
index df2486a3efd5..35448b8e6883 100644
--- a/net/netfilter/xt_CONNMARK.c
+++ b/net/netfilter/xt_CONNMARK.c
@@ -102,6 +102,7 @@ static struct xt_target connmark_reg = {
102 .target = target, 102 .target = target,
103 .targetsize = sizeof(struct xt_connmark_target_info), 103 .targetsize = sizeof(struct xt_connmark_target_info),
104 .checkentry = checkentry, 104 .checkentry = checkentry,
105 .family = AF_INET,
105 .me = THIS_MODULE 106 .me = THIS_MODULE
106}; 107};
107 108
@@ -110,6 +111,7 @@ static struct xt_target connmark6_reg = {
110 .target = target, 111 .target = target,
111 .targetsize = sizeof(struct xt_connmark_target_info), 112 .targetsize = sizeof(struct xt_connmark_target_info),
112 .checkentry = checkentry, 113 .checkentry = checkentry,
114 .family = AF_INET6,
113 .me = THIS_MODULE 115 .me = THIS_MODULE
114}; 116};
115 117
@@ -119,21 +121,21 @@ static int __init init(void)
119 121
120 need_conntrack(); 122 need_conntrack();
121 123
122 ret = xt_register_target(AF_INET, &connmark_reg); 124 ret = xt_register_target(&connmark_reg);
123 if (ret) 125 if (ret)
124 return ret; 126 return ret;
125 127
126 ret = xt_register_target(AF_INET6, &connmark6_reg); 128 ret = xt_register_target(&connmark6_reg);
127 if (ret) 129 if (ret)
128 xt_unregister_target(AF_INET, &connmark_reg); 130 xt_unregister_target(&connmark_reg);
129 131
130 return ret; 132 return ret;
131} 133}
132 134
133static void __exit fini(void) 135static void __exit fini(void)
134{ 136{
135 xt_unregister_target(AF_INET, &connmark_reg); 137 xt_unregister_target(&connmark_reg);
136 xt_unregister_target(AF_INET6, &connmark6_reg); 138 xt_unregister_target(&connmark6_reg);
137} 139}
138 140
139module_init(init); 141module_init(init);
diff --git a/net/netfilter/xt_MARK.c b/net/netfilter/xt_MARK.c
index dcb5266efae0..73bdd5c80e17 100644
--- a/net/netfilter/xt_MARK.c
+++ b/net/netfilter/xt_MARK.c
@@ -119,6 +119,7 @@ static struct xt_target ipt_mark_reg_v0 = {
119 .table = "mangle", 119 .table = "mangle",
120 .checkentry = checkentry_v0, 120 .checkentry = checkentry_v0,
121 .me = THIS_MODULE, 121 .me = THIS_MODULE,
122 .family = AF_INET,
122 .revision = 0, 123 .revision = 0,
123}; 124};
124 125
@@ -129,6 +130,7 @@ static struct xt_target ipt_mark_reg_v1 = {
129 .table = "mangle", 130 .table = "mangle",
130 .checkentry = checkentry_v1, 131 .checkentry = checkentry_v1,
131 .me = THIS_MODULE, 132 .me = THIS_MODULE,
133 .family = AF_INET,
132 .revision = 1, 134 .revision = 1,
133}; 135};
134 136
@@ -139,6 +141,7 @@ static struct xt_target ip6t_mark_reg_v0 = {
139 .table = "mangle", 141 .table = "mangle",
140 .checkentry = checkentry_v0, 142 .checkentry = checkentry_v0,
141 .me = THIS_MODULE, 143 .me = THIS_MODULE,
144 .family = AF_INET6,
142 .revision = 0, 145 .revision = 0,
143}; 146};
144 147
@@ -146,18 +149,18 @@ static int __init init(void)
146{ 149{
147 int err; 150 int err;
148 151
149 err = xt_register_target(AF_INET, &ipt_mark_reg_v0); 152 err = xt_register_target(&ipt_mark_reg_v0);
150 if (err) 153 if (err)
151 return err; 154 return err;
152 155
153 err = xt_register_target(AF_INET, &ipt_mark_reg_v1); 156 err = xt_register_target(&ipt_mark_reg_v1);
154 if (err) 157 if (err)
155 xt_unregister_target(AF_INET, &ipt_mark_reg_v0); 158 xt_unregister_target(&ipt_mark_reg_v0);
156 159
157 err = xt_register_target(AF_INET6, &ip6t_mark_reg_v0); 160 err = xt_register_target(&ip6t_mark_reg_v0);
158 if (err) { 161 if (err) {
159 xt_unregister_target(AF_INET, &ipt_mark_reg_v0); 162 xt_unregister_target(&ipt_mark_reg_v0);
160 xt_unregister_target(AF_INET, &ipt_mark_reg_v1); 163 xt_unregister_target(&ipt_mark_reg_v1);
161 } 164 }
162 165
163 return err; 166 return err;
@@ -165,9 +168,9 @@ static int __init init(void)
165 168
166static void __exit fini(void) 169static void __exit fini(void)
167{ 170{
168 xt_unregister_target(AF_INET, &ipt_mark_reg_v0); 171 xt_unregister_target(&ipt_mark_reg_v0);
169 xt_unregister_target(AF_INET, &ipt_mark_reg_v1); 172 xt_unregister_target(&ipt_mark_reg_v1);
170 xt_unregister_target(AF_INET6, &ip6t_mark_reg_v0); 173 xt_unregister_target(&ip6t_mark_reg_v0);
171} 174}
172 175
173module_init(init); 176module_init(init);
diff --git a/net/netfilter/xt_NFQUEUE.c b/net/netfilter/xt_NFQUEUE.c
index 39a963edf16b..2873e1c60f68 100644
--- a/net/netfilter/xt_NFQUEUE.c
+++ b/net/netfilter/xt_NFQUEUE.c
@@ -41,6 +41,7 @@ static struct xt_target ipt_NFQ_reg = {
41 .name = "NFQUEUE", 41 .name = "NFQUEUE",
42 .target = target, 42 .target = target,
43 .targetsize = sizeof(struct xt_NFQ_info), 43 .targetsize = sizeof(struct xt_NFQ_info),
44 .family = AF_INET,
44 .me = THIS_MODULE, 45 .me = THIS_MODULE,
45}; 46};
46 47
@@ -48,6 +49,7 @@ static struct xt_target ip6t_NFQ_reg = {
48 .name = "NFQUEUE", 49 .name = "NFQUEUE",
49 .target = target, 50 .target = target,
50 .targetsize = sizeof(struct xt_NFQ_info), 51 .targetsize = sizeof(struct xt_NFQ_info),
52 .family = AF_INET6,
51 .me = THIS_MODULE, 53 .me = THIS_MODULE,
52}; 54};
53 55
@@ -55,36 +57,37 @@ static struct xt_target arpt_NFQ_reg = {
55 .name = "NFQUEUE", 57 .name = "NFQUEUE",
56 .target = target, 58 .target = target,
57 .targetsize = sizeof(struct xt_NFQ_info), 59 .targetsize = sizeof(struct xt_NFQ_info),
60 .family = NF_ARP,
58 .me = THIS_MODULE, 61 .me = THIS_MODULE,
59}; 62};
60 63
61static int __init init(void) 64static int __init init(void)
62{ 65{
63 int ret; 66 int ret;
64 ret = xt_register_target(AF_INET, &ipt_NFQ_reg); 67 ret = xt_register_target(&ipt_NFQ_reg);
65 if (ret) 68 if (ret)
66 return ret; 69 return ret;
67 ret = xt_register_target(AF_INET6, &ip6t_NFQ_reg); 70 ret = xt_register_target(&ip6t_NFQ_reg);
68 if (ret) 71 if (ret)
69 goto out_ip; 72 goto out_ip;
70 ret = xt_register_target(NF_ARP, &arpt_NFQ_reg); 73 ret = xt_register_target(&arpt_NFQ_reg);
71 if (ret) 74 if (ret)
72 goto out_ip6; 75 goto out_ip6;
73 76
74 return ret; 77 return ret;
75out_ip6: 78out_ip6:
76 xt_unregister_target(AF_INET6, &ip6t_NFQ_reg); 79 xt_unregister_target(&ip6t_NFQ_reg);
77out_ip: 80out_ip:
78 xt_unregister_target(AF_INET, &ipt_NFQ_reg); 81 xt_unregister_target(&ipt_NFQ_reg);
79 82
80 return ret; 83 return ret;
81} 84}
82 85
83static void __exit fini(void) 86static void __exit fini(void)
84{ 87{
85 xt_unregister_target(NF_ARP, &arpt_NFQ_reg); 88 xt_unregister_target(&arpt_NFQ_reg);
86 xt_unregister_target(AF_INET6, &ip6t_NFQ_reg); 89 xt_unregister_target(&ip6t_NFQ_reg);
87 xt_unregister_target(AF_INET, &ipt_NFQ_reg); 90 xt_unregister_target(&ipt_NFQ_reg);
88} 91}
89 92
90module_init(init); 93module_init(init);
diff --git a/net/netfilter/xt_NOTRACK.c b/net/netfilter/xt_NOTRACK.c
index b8634e3f6169..cf2ebd76fd6f 100644
--- a/net/netfilter/xt_NOTRACK.c
+++ b/net/netfilter/xt_NOTRACK.c
@@ -39,6 +39,7 @@ static struct xt_target notrack_reg = {
39 .target = target, 39 .target = target,
40 .targetsize = 0, 40 .targetsize = 0,
41 .table = "raw", 41 .table = "raw",
42 .family = AF_INET,
42 .me = THIS_MODULE, 43 .me = THIS_MODULE,
43}; 44};
44 45
@@ -47,6 +48,7 @@ static struct xt_target notrack6_reg = {
47 .target = target, 48 .target = target,
48 .targetsize = 0, 49 .targetsize = 0,
49 .table = "raw", 50 .table = "raw",
51 .family = AF_INET6,
50 .me = THIS_MODULE, 52 .me = THIS_MODULE,
51}; 53};
52 54
@@ -54,21 +56,21 @@ static int __init init(void)
54{ 56{
55 int ret; 57 int ret;
56 58
57 ret = xt_register_target(AF_INET, &notrack_reg); 59 ret = xt_register_target(&notrack_reg);
58 if (ret) 60 if (ret)
59 return ret; 61 return ret;
60 62
61 ret = xt_register_target(AF_INET6, &notrack6_reg); 63 ret = xt_register_target(&notrack6_reg);
62 if (ret) 64 if (ret)
63 xt_unregister_target(AF_INET, &notrack_reg); 65 xt_unregister_target(&notrack_reg);
64 66
65 return ret; 67 return ret;
66} 68}
67 69
68static void __exit fini(void) 70static void __exit fini(void)
69{ 71{
70 xt_unregister_target(AF_INET6, &notrack6_reg); 72 xt_unregister_target(&notrack6_reg);
71 xt_unregister_target(AF_INET, &notrack_reg); 73 xt_unregister_target(&notrack_reg);
72} 74}
73 75
74module_init(init); 76module_init(init);
diff --git a/net/netfilter/xt_comment.c b/net/netfilter/xt_comment.c
index 03d9d741231c..2637724b498d 100644
--- a/net/netfilter/xt_comment.c
+++ b/net/netfilter/xt_comment.c
@@ -33,6 +33,7 @@ static struct xt_match comment_match = {
33 .name = "comment", 33 .name = "comment",
34 .match = match, 34 .match = match,
35 .matchsize = sizeof(struct xt_comment_info), 35 .matchsize = sizeof(struct xt_comment_info),
36 .family = AF_INET,
36 .me = THIS_MODULE 37 .me = THIS_MODULE
37}; 38};
38 39
@@ -40,6 +41,7 @@ static struct xt_match comment6_match = {
40 .name = "comment", 41 .name = "comment",
41 .match = match, 42 .match = match,
42 .matchsize = sizeof(struct xt_comment_info), 43 .matchsize = sizeof(struct xt_comment_info),
44 .family = AF_INET6,
43 .me = THIS_MODULE 45 .me = THIS_MODULE
44}; 46};
45 47
@@ -47,21 +49,21 @@ static int __init init(void)
47{ 49{
48 int ret; 50 int ret;
49 51
50 ret = xt_register_match(AF_INET, &comment_match); 52 ret = xt_register_match(&comment_match);
51 if (ret) 53 if (ret)
52 return ret; 54 return ret;
53 55
54 ret = xt_register_match(AF_INET6, &comment6_match); 56 ret = xt_register_match(&comment6_match);
55 if (ret) 57 if (ret)
56 xt_unregister_match(AF_INET, &comment_match); 58 xt_unregister_match(&comment_match);
57 59
58 return ret; 60 return ret;
59} 61}
60 62
61static void __exit fini(void) 63static void __exit fini(void)
62{ 64{
63 xt_unregister_match(AF_INET, &comment_match); 65 xt_unregister_match(&comment_match);
64 xt_unregister_match(AF_INET6, &comment6_match); 66 xt_unregister_match(&comment6_match);
65} 67}
66 68
67module_init(init); 69module_init(init);
diff --git a/net/netfilter/xt_connbytes.c b/net/netfilter/xt_connbytes.c
index f34ecb9485c7..4985f5ec58ca 100644
--- a/net/netfilter/xt_connbytes.c
+++ b/net/netfilter/xt_connbytes.c
@@ -148,6 +148,7 @@ static struct xt_match connbytes_match = {
148 .match = match, 148 .match = match,
149 .checkentry = check, 149 .checkentry = check,
150 .matchsize = sizeof(struct xt_connbytes_info), 150 .matchsize = sizeof(struct xt_connbytes_info),
151 .family = AF_INET,
151 .me = THIS_MODULE 152 .me = THIS_MODULE
152}; 153};
153static struct xt_match connbytes6_match = { 154static struct xt_match connbytes6_match = {
@@ -155,26 +156,27 @@ static struct xt_match connbytes6_match = {
155 .match = match, 156 .match = match,
156 .checkentry = check, 157 .checkentry = check,
157 .matchsize = sizeof(struct xt_connbytes_info), 158 .matchsize = sizeof(struct xt_connbytes_info),
159 .family = AF_INET6,
158 .me = THIS_MODULE 160 .me = THIS_MODULE
159}; 161};
160 162
161static int __init init(void) 163static int __init init(void)
162{ 164{
163 int ret; 165 int ret;
164 ret = xt_register_match(AF_INET, &connbytes_match); 166 ret = xt_register_match(&connbytes_match);
165 if (ret) 167 if (ret)
166 return ret; 168 return ret;
167 169
168 ret = xt_register_match(AF_INET6, &connbytes6_match); 170 ret = xt_register_match(&connbytes6_match);
169 if (ret) 171 if (ret)
170 xt_unregister_match(AF_INET, &connbytes_match); 172 xt_unregister_match(&connbytes_match);
171 return ret; 173 return ret;
172} 174}
173 175
174static void __exit fini(void) 176static void __exit fini(void)
175{ 177{
176 xt_unregister_match(AF_INET, &connbytes_match); 178 xt_unregister_match(&connbytes_match);
177 xt_unregister_match(AF_INET6, &connbytes6_match); 179 xt_unregister_match(&connbytes6_match);
178} 180}
179 181
180module_init(init); 182module_init(init);
diff --git a/net/netfilter/xt_connmark.c b/net/netfilter/xt_connmark.c
index 51822471e919..7b16f1ee16b4 100644
--- a/net/netfilter/xt_connmark.c
+++ b/net/netfilter/xt_connmark.c
@@ -64,14 +64,31 @@ checkentry(const char *tablename,
64 printk(KERN_WARNING "connmark: only support 32bit mark\n"); 64 printk(KERN_WARNING "connmark: only support 32bit mark\n");
65 return 0; 65 return 0;
66 } 66 }
67#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
68 if (nf_ct_l3proto_try_module_get(match->family) < 0) {
69 printk(KERN_WARNING "can't load nf_conntrack support for "
70 "proto=%d\n", match->family);
71 return 0;
72 }
73#endif
67 return 1; 74 return 1;
68} 75}
69 76
77static void
78destroy(const struct xt_match *match, void *matchinfo, unsigned int matchsize)
79{
80#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
81 nf_ct_l3proto_module_put(match->family);
82#endif
83}
84
70static struct xt_match connmark_match = { 85static struct xt_match connmark_match = {
71 .name = "connmark", 86 .name = "connmark",
72 .match = match, 87 .match = match,
73 .matchsize = sizeof(struct xt_connmark_info), 88 .matchsize = sizeof(struct xt_connmark_info),
74 .checkentry = checkentry, 89 .checkentry = checkentry,
90 .destroy = destroy,
91 .family = AF_INET,
75 .me = THIS_MODULE 92 .me = THIS_MODULE
76}; 93};
77 94
@@ -80,6 +97,8 @@ static struct xt_match connmark6_match = {
80 .match = match, 97 .match = match,
81 .matchsize = sizeof(struct xt_connmark_info), 98 .matchsize = sizeof(struct xt_connmark_info),
82 .checkentry = checkentry, 99 .checkentry = checkentry,
100 .destroy = destroy,
101 .family = AF_INET6,
83 .me = THIS_MODULE 102 .me = THIS_MODULE
84}; 103};
85 104
@@ -89,20 +108,20 @@ static int __init init(void)
89 108
90 need_conntrack(); 109 need_conntrack();
91 110
92 ret = xt_register_match(AF_INET, &connmark_match); 111 ret = xt_register_match(&connmark_match);
93 if (ret) 112 if (ret)
94 return ret; 113 return ret;
95 114
96 ret = xt_register_match(AF_INET6, &connmark6_match); 115 ret = xt_register_match(&connmark6_match);
97 if (ret) 116 if (ret)
98 xt_unregister_match(AF_INET, &connmark_match); 117 xt_unregister_match(&connmark_match);
99 return ret; 118 return ret;
100} 119}
101 120
102static void __exit fini(void) 121static void __exit fini(void)
103{ 122{
104 xt_unregister_match(AF_INET6, &connmark6_match); 123 xt_unregister_match(&connmark6_match);
105 xt_unregister_match(AF_INET, &connmark_match); 124 xt_unregister_match(&connmark_match);
106} 125}
107 126
108module_init(init); 127module_init(init);
diff --git a/net/netfilter/xt_conntrack.c b/net/netfilter/xt_conntrack.c
index 39fc29496e00..65a84809fd30 100644
--- a/net/netfilter/xt_conntrack.c
+++ b/net/netfilter/xt_conntrack.c
@@ -203,10 +203,39 @@ match(const struct sk_buff *skb,
203 203
204#endif /* CONFIG_NF_IP_CONNTRACK */ 204#endif /* CONFIG_NF_IP_CONNTRACK */
205 205
206static int
207checkentry(const char *tablename,
208 const void *ip,
209 const struct xt_match *match,
210 void *matchinfo,
211 unsigned int matchsize,
212 unsigned int hook_mask)
213{
214#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
215 if (nf_ct_l3proto_try_module_get(match->family) < 0) {
216 printk(KERN_WARNING "can't load nf_conntrack support for "
217 "proto=%d\n", match->family);
218 return 0;
219 }
220#endif
221 return 1;
222}
223
224static void
225destroy(const struct xt_match *match, void *matchinfo, unsigned int matchsize)
226{
227#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
228 nf_ct_l3proto_module_put(match->family);
229#endif
230}
231
206static struct xt_match conntrack_match = { 232static struct xt_match conntrack_match = {
207 .name = "conntrack", 233 .name = "conntrack",
208 .match = match, 234 .match = match,
235 .checkentry = checkentry,
236 .destroy = destroy,
209 .matchsize = sizeof(struct xt_conntrack_info), 237 .matchsize = sizeof(struct xt_conntrack_info),
238 .family = AF_INET,
210 .me = THIS_MODULE, 239 .me = THIS_MODULE,
211}; 240};
212 241
@@ -214,14 +243,14 @@ static int __init init(void)
214{ 243{
215 int ret; 244 int ret;
216 need_conntrack(); 245 need_conntrack();
217 ret = xt_register_match(AF_INET, &conntrack_match); 246 ret = xt_register_match(&conntrack_match);
218 247
219 return ret; 248 return ret;
220} 249}
221 250
222static void __exit fini(void) 251static void __exit fini(void)
223{ 252{
224 xt_unregister_match(AF_INET, &conntrack_match); 253 xt_unregister_match(&conntrack_match);
225} 254}
226 255
227module_init(init); 256module_init(init);
diff --git a/net/netfilter/xt_dccp.c b/net/netfilter/xt_dccp.c
index db6b70cdc770..2f331decd151 100644
--- a/net/netfilter/xt_dccp.c
+++ b/net/netfilter/xt_dccp.c
@@ -149,6 +149,7 @@ static struct xt_match dccp_match =
149 .matchsize = sizeof(struct xt_dccp_info), 149 .matchsize = sizeof(struct xt_dccp_info),
150 .proto = IPPROTO_DCCP, 150 .proto = IPPROTO_DCCP,
151 .checkentry = checkentry, 151 .checkentry = checkentry,
152 .family = AF_INET,
152 .me = THIS_MODULE, 153 .me = THIS_MODULE,
153}; 154};
154static struct xt_match dccp6_match = 155static struct xt_match dccp6_match =
@@ -158,6 +159,7 @@ static struct xt_match dccp6_match =
158 .matchsize = sizeof(struct xt_dccp_info), 159 .matchsize = sizeof(struct xt_dccp_info),
159 .proto = IPPROTO_DCCP, 160 .proto = IPPROTO_DCCP,
160 .checkentry = checkentry, 161 .checkentry = checkentry,
162 .family = AF_INET6,
161 .me = THIS_MODULE, 163 .me = THIS_MODULE,
162}; 164};
163 165
@@ -172,17 +174,17 @@ static int __init init(void)
172 dccp_optbuf = kmalloc(256 * 4, GFP_KERNEL); 174 dccp_optbuf = kmalloc(256 * 4, GFP_KERNEL);
173 if (!dccp_optbuf) 175 if (!dccp_optbuf)
174 return -ENOMEM; 176 return -ENOMEM;
175 ret = xt_register_match(AF_INET, &dccp_match); 177 ret = xt_register_match(&dccp_match);
176 if (ret) 178 if (ret)
177 goto out_kfree; 179 goto out_kfree;
178 ret = xt_register_match(AF_INET6, &dccp6_match); 180 ret = xt_register_match(&dccp6_match);
179 if (ret) 181 if (ret)
180 goto out_unreg; 182 goto out_unreg;
181 183
182 return ret; 184 return ret;
183 185
184out_unreg: 186out_unreg:
185 xt_unregister_match(AF_INET, &dccp_match); 187 xt_unregister_match(&dccp_match);
186out_kfree: 188out_kfree:
187 kfree(dccp_optbuf); 189 kfree(dccp_optbuf);
188 190
@@ -191,8 +193,8 @@ out_kfree:
191 193
192static void __exit fini(void) 194static void __exit fini(void)
193{ 195{
194 xt_unregister_match(AF_INET6, &dccp6_match); 196 xt_unregister_match(&dccp6_match);
195 xt_unregister_match(AF_INET, &dccp_match); 197 xt_unregister_match(&dccp_match);
196 kfree(dccp_optbuf); 198 kfree(dccp_optbuf);
197} 199}
198 200
diff --git a/net/netfilter/xt_helper.c b/net/netfilter/xt_helper.c
index ef8e54d40c92..101f0005e987 100644
--- a/net/netfilter/xt_helper.c
+++ b/net/netfilter/xt_helper.c
@@ -144,15 +144,32 @@ static int check(const char *tablename,
144{ 144{
145 struct xt_helper_info *info = matchinfo; 145 struct xt_helper_info *info = matchinfo;
146 146
147#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
148 if (nf_ct_l3proto_try_module_get(match->family) < 0) {
149 printk(KERN_WARNING "can't load nf_conntrack support for "
150 "proto=%d\n", match->family);
151 return 0;
152 }
153#endif
147 info->name[29] = '\0'; 154 info->name[29] = '\0';
148 return 1; 155 return 1;
149} 156}
150 157
158static void
159destroy(const struct xt_match *match, void *matchinfo, unsigned int matchsize)
160{
161#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
162 nf_ct_l3proto_module_put(match->family);
163#endif
164}
165
151static struct xt_match helper_match = { 166static struct xt_match helper_match = {
152 .name = "helper", 167 .name = "helper",
153 .match = match, 168 .match = match,
154 .matchsize = sizeof(struct xt_helper_info), 169 .matchsize = sizeof(struct xt_helper_info),
155 .checkentry = check, 170 .checkentry = check,
171 .destroy = destroy,
172 .family = AF_INET,
156 .me = THIS_MODULE, 173 .me = THIS_MODULE,
157}; 174};
158static struct xt_match helper6_match = { 175static struct xt_match helper6_match = {
@@ -160,6 +177,8 @@ static struct xt_match helper6_match = {
160 .match = match, 177 .match = match,
161 .matchsize = sizeof(struct xt_helper_info), 178 .matchsize = sizeof(struct xt_helper_info),
162 .checkentry = check, 179 .checkentry = check,
180 .destroy = destroy,
181 .family = AF_INET6,
163 .me = THIS_MODULE, 182 .me = THIS_MODULE,
164}; 183};
165 184
@@ -168,21 +187,21 @@ static int __init init(void)
168 int ret; 187 int ret;
169 need_conntrack(); 188 need_conntrack();
170 189
171 ret = xt_register_match(AF_INET, &helper_match); 190 ret = xt_register_match(&helper_match);
172 if (ret < 0) 191 if (ret < 0)
173 return ret; 192 return ret;
174 193
175 ret = xt_register_match(AF_INET6, &helper6_match); 194 ret = xt_register_match(&helper6_match);
176 if (ret < 0) 195 if (ret < 0)
177 xt_unregister_match(AF_INET, &helper_match); 196 xt_unregister_match(&helper_match);
178 197
179 return ret; 198 return ret;
180} 199}
181 200
182static void __exit fini(void) 201static void __exit fini(void)
183{ 202{
184 xt_unregister_match(AF_INET, &helper_match); 203 xt_unregister_match(&helper_match);
185 xt_unregister_match(AF_INET6, &helper6_match); 204 xt_unregister_match(&helper6_match);
186} 205}
187 206
188module_init(init); 207module_init(init);
diff --git a/net/netfilter/xt_length.c b/net/netfilter/xt_length.c
index b9e60f041a64..38560caef757 100644
--- a/net/netfilter/xt_length.c
+++ b/net/netfilter/xt_length.c
@@ -56,6 +56,7 @@ static struct xt_match length_match = {
56 .name = "length", 56 .name = "length",
57 .match = match, 57 .match = match,
58 .matchsize = sizeof(struct xt_length_info), 58 .matchsize = sizeof(struct xt_length_info),
59 .family = AF_INET,
59 .me = THIS_MODULE, 60 .me = THIS_MODULE,
60}; 61};
61 62
@@ -63,26 +64,27 @@ static struct xt_match length6_match = {
63 .name = "length", 64 .name = "length",
64 .match = match6, 65 .match = match6,
65 .matchsize = sizeof(struct xt_length_info), 66 .matchsize = sizeof(struct xt_length_info),
67 .family = AF_INET6,
66 .me = THIS_MODULE, 68 .me = THIS_MODULE,
67}; 69};
68 70
69static int __init init(void) 71static int __init init(void)
70{ 72{
71 int ret; 73 int ret;
72 ret = xt_register_match(AF_INET, &length_match); 74 ret = xt_register_match(&length_match);
73 if (ret) 75 if (ret)
74 return ret; 76 return ret;
75 ret = xt_register_match(AF_INET6, &length6_match); 77 ret = xt_register_match(&length6_match);
76 if (ret) 78 if (ret)
77 xt_unregister_match(AF_INET, &length_match); 79 xt_unregister_match(&length_match);
78 80
79 return ret; 81 return ret;
80} 82}
81 83
82static void __exit fini(void) 84static void __exit fini(void)
83{ 85{
84 xt_unregister_match(AF_INET, &length_match); 86 xt_unregister_match(&length_match);
85 xt_unregister_match(AF_INET6, &length6_match); 87 xt_unregister_match(&length6_match);
86} 88}
87 89
88module_init(init); 90module_init(init);
diff --git a/net/netfilter/xt_limit.c b/net/netfilter/xt_limit.c
index 3049e6f8889e..e91c1a444e77 100644
--- a/net/netfilter/xt_limit.c
+++ b/net/netfilter/xt_limit.c
@@ -141,6 +141,7 @@ static struct xt_match ipt_limit_reg = {
141 .match = ipt_limit_match, 141 .match = ipt_limit_match,
142 .matchsize = sizeof(struct xt_rateinfo), 142 .matchsize = sizeof(struct xt_rateinfo),
143 .checkentry = ipt_limit_checkentry, 143 .checkentry = ipt_limit_checkentry,
144 .family = AF_INET,
144 .me = THIS_MODULE, 145 .me = THIS_MODULE,
145}; 146};
146static struct xt_match limit6_reg = { 147static struct xt_match limit6_reg = {
@@ -148,6 +149,7 @@ static struct xt_match limit6_reg = {
148 .match = ipt_limit_match, 149 .match = ipt_limit_match,
149 .matchsize = sizeof(struct xt_rateinfo), 150 .matchsize = sizeof(struct xt_rateinfo),
150 .checkentry = ipt_limit_checkentry, 151 .checkentry = ipt_limit_checkentry,
152 .family = AF_INET6,
151 .me = THIS_MODULE, 153 .me = THIS_MODULE,
152}; 154};
153 155
@@ -155,21 +157,21 @@ static int __init init(void)
155{ 157{
156 int ret; 158 int ret;
157 159
158 ret = xt_register_match(AF_INET, &ipt_limit_reg); 160 ret = xt_register_match(&ipt_limit_reg);
159 if (ret) 161 if (ret)
160 return ret; 162 return ret;
161 163
162 ret = xt_register_match(AF_INET6, &limit6_reg); 164 ret = xt_register_match(&limit6_reg);
163 if (ret) 165 if (ret)
164 xt_unregister_match(AF_INET, &ipt_limit_reg); 166 xt_unregister_match(&ipt_limit_reg);
165 167
166 return ret; 168 return ret;
167} 169}
168 170
169static void __exit fini(void) 171static void __exit fini(void)
170{ 172{
171 xt_unregister_match(AF_INET, &ipt_limit_reg); 173 xt_unregister_match(&ipt_limit_reg);
172 xt_unregister_match(AF_INET6, &limit6_reg); 174 xt_unregister_match(&limit6_reg);
173} 175}
174 176
175module_init(init); 177module_init(init);
diff --git a/net/netfilter/xt_mac.c b/net/netfilter/xt_mac.c
index b4559a46dce8..f4defa28a6ec 100644
--- a/net/netfilter/xt_mac.c
+++ b/net/netfilter/xt_mac.c
@@ -49,6 +49,7 @@ static struct xt_match mac_match = {
49 .matchsize = sizeof(struct xt_mac_info), 49 .matchsize = sizeof(struct xt_mac_info),
50 .hooks = (1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_IN) | 50 .hooks = (1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_IN) |
51 (1 << NF_IP_FORWARD), 51 (1 << NF_IP_FORWARD),
52 .family = AF_INET,
52 .me = THIS_MODULE, 53 .me = THIS_MODULE,
53}; 54};
54static struct xt_match mac6_match = { 55static struct xt_match mac6_match = {
@@ -57,27 +58,28 @@ static struct xt_match mac6_match = {
57 .matchsize = sizeof(struct xt_mac_info), 58 .matchsize = sizeof(struct xt_mac_info),
58 .hooks = (1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_IN) | 59 .hooks = (1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_IN) |
59 (1 << NF_IP_FORWARD), 60 (1 << NF_IP_FORWARD),
61 .family = AF_INET6,
60 .me = THIS_MODULE, 62 .me = THIS_MODULE,
61}; 63};
62 64
63static int __init init(void) 65static int __init init(void)
64{ 66{
65 int ret; 67 int ret;
66 ret = xt_register_match(AF_INET, &mac_match); 68 ret = xt_register_match(&mac_match);
67 if (ret) 69 if (ret)
68 return ret; 70 return ret;
69 71
70 ret = xt_register_match(AF_INET6, &mac6_match); 72 ret = xt_register_match(&mac6_match);
71 if (ret) 73 if (ret)
72 xt_unregister_match(AF_INET, &mac_match); 74 xt_unregister_match(&mac_match);
73 75
74 return ret; 76 return ret;
75} 77}
76 78
77static void __exit fini(void) 79static void __exit fini(void)
78{ 80{
79 xt_unregister_match(AF_INET, &mac_match); 81 xt_unregister_match(&mac_match);
80 xt_unregister_match(AF_INET6, &mac6_match); 82 xt_unregister_match(&mac6_match);
81} 83}
82 84
83module_init(init); 85module_init(init);
diff --git a/net/netfilter/xt_mark.c b/net/netfilter/xt_mark.c
index c1a8f0f587f0..ce0badfeef9a 100644
--- a/net/netfilter/xt_mark.c
+++ b/net/netfilter/xt_mark.c
@@ -56,6 +56,7 @@ static struct xt_match mark_match = {
56 .match = match, 56 .match = match,
57 .matchsize = sizeof(struct xt_mark_info), 57 .matchsize = sizeof(struct xt_mark_info),
58 .checkentry = checkentry, 58 .checkentry = checkentry,
59 .family = AF_INET,
59 .me = THIS_MODULE, 60 .me = THIS_MODULE,
60}; 61};
61 62
@@ -64,27 +65,28 @@ static struct xt_match mark6_match = {
64 .match = match, 65 .match = match,
65 .matchsize = sizeof(struct xt_mark_info), 66 .matchsize = sizeof(struct xt_mark_info),
66 .checkentry = checkentry, 67 .checkentry = checkentry,
68 .family = AF_INET6,
67 .me = THIS_MODULE, 69 .me = THIS_MODULE,
68}; 70};
69 71
70static int __init init(void) 72static int __init init(void)
71{ 73{
72 int ret; 74 int ret;
73 ret = xt_register_match(AF_INET, &mark_match); 75 ret = xt_register_match(&mark_match);
74 if (ret) 76 if (ret)
75 return ret; 77 return ret;
76 78
77 ret = xt_register_match(AF_INET6, &mark6_match); 79 ret = xt_register_match(&mark6_match);
78 if (ret) 80 if (ret)
79 xt_unregister_match(AF_INET, &mark_match); 81 xt_unregister_match(&mark_match);
80 82
81 return ret; 83 return ret;
82} 84}
83 85
84static void __exit fini(void) 86static void __exit fini(void)
85{ 87{
86 xt_unregister_match(AF_INET, &mark_match); 88 xt_unregister_match(&mark_match);
87 xt_unregister_match(AF_INET6, &mark6_match); 89 xt_unregister_match(&mark6_match);
88} 90}
89 91
90module_init(init); 92module_init(init);
diff --git a/net/netfilter/xt_physdev.c b/net/netfilter/xt_physdev.c
index f788e8e76254..089f4f7e8636 100644
--- a/net/netfilter/xt_physdev.c
+++ b/net/netfilter/xt_physdev.c
@@ -121,6 +121,7 @@ static struct xt_match physdev_match = {
121 .match = match, 121 .match = match,
122 .matchsize = sizeof(struct xt_physdev_info), 122 .matchsize = sizeof(struct xt_physdev_info),
123 .checkentry = checkentry, 123 .checkentry = checkentry,
124 .family = AF_INET,
124 .me = THIS_MODULE, 125 .me = THIS_MODULE,
125}; 126};
126 127
@@ -129,6 +130,7 @@ static struct xt_match physdev6_match = {
129 .match = match, 130 .match = match,
130 .matchsize = sizeof(struct xt_physdev_info), 131 .matchsize = sizeof(struct xt_physdev_info),
131 .checkentry = checkentry, 132 .checkentry = checkentry,
133 .family = AF_INET6,
132 .me = THIS_MODULE, 134 .me = THIS_MODULE,
133}; 135};
134 136
@@ -136,21 +138,21 @@ static int __init init(void)
136{ 138{
137 int ret; 139 int ret;
138 140
139 ret = xt_register_match(AF_INET, &physdev_match); 141 ret = xt_register_match(&physdev_match);
140 if (ret < 0) 142 if (ret < 0)
141 return ret; 143 return ret;
142 144
143 ret = xt_register_match(AF_INET6, &physdev6_match); 145 ret = xt_register_match(&physdev6_match);
144 if (ret < 0) 146 if (ret < 0)
145 xt_unregister_match(AF_INET, &physdev_match); 147 xt_unregister_match(&physdev_match);
146 148
147 return ret; 149 return ret;
148} 150}
149 151
150static void __exit fini(void) 152static void __exit fini(void)
151{ 153{
152 xt_unregister_match(AF_INET, &physdev_match); 154 xt_unregister_match(&physdev_match);
153 xt_unregister_match(AF_INET6, &physdev6_match); 155 xt_unregister_match(&physdev6_match);
154} 156}
155 157
156module_init(init); 158module_init(init);
diff --git a/net/netfilter/xt_pkttype.c b/net/netfilter/xt_pkttype.c
index f38638dfd139..8b8bca988ac6 100644
--- a/net/netfilter/xt_pkttype.c
+++ b/net/netfilter/xt_pkttype.c
@@ -37,6 +37,7 @@ static struct xt_match pkttype_match = {
37 .name = "pkttype", 37 .name = "pkttype",
38 .match = match, 38 .match = match,
39 .matchsize = sizeof(struct xt_pkttype_info), 39 .matchsize = sizeof(struct xt_pkttype_info),
40 .family = AF_INET,
40 .me = THIS_MODULE, 41 .me = THIS_MODULE,
41}; 42};
42 43
@@ -44,27 +45,28 @@ static struct xt_match pkttype6_match = {
44 .name = "pkttype", 45 .name = "pkttype",
45 .match = match, 46 .match = match,
46 .matchsize = sizeof(struct xt_pkttype_info), 47 .matchsize = sizeof(struct xt_pkttype_info),
48 .family = AF_INET6,
47 .me = THIS_MODULE, 49 .me = THIS_MODULE,
48}; 50};
49 51
50static int __init init(void) 52static int __init init(void)
51{ 53{
52 int ret; 54 int ret;
53 ret = xt_register_match(AF_INET, &pkttype_match); 55 ret = xt_register_match(&pkttype_match);
54 if (ret) 56 if (ret)
55 return ret; 57 return ret;
56 58
57 ret = xt_register_match(AF_INET6, &pkttype6_match); 59 ret = xt_register_match(&pkttype6_match);
58 if (ret) 60 if (ret)
59 xt_unregister_match(AF_INET, &pkttype_match); 61 xt_unregister_match(&pkttype_match);
60 62
61 return ret; 63 return ret;
62} 64}
63 65
64static void __exit fini(void) 66static void __exit fini(void)
65{ 67{
66 xt_unregister_match(AF_INET, &pkttype_match); 68 xt_unregister_match(&pkttype_match);
67 xt_unregister_match(AF_INET6, &pkttype6_match); 69 xt_unregister_match(&pkttype6_match);
68} 70}
69 71
70module_init(init); 72module_init(init);
diff --git a/net/netfilter/xt_policy.c b/net/netfilter/xt_policy.c
index 1ec22082f04d..1099cb005fcc 100644
--- a/net/netfilter/xt_policy.c
+++ b/net/netfilter/xt_policy.c
@@ -27,9 +27,9 @@ xt_addr_cmp(const union xt_policy_addr *a1, const union xt_policy_addr *m,
27{ 27{
28 switch (family) { 28 switch (family) {
29 case AF_INET: 29 case AF_INET:
30 return (a1->a4.s_addr ^ a2->a4.s_addr) & m->a4.s_addr; 30 return !((a1->a4.s_addr ^ a2->a4.s_addr) & m->a4.s_addr);
31 case AF_INET6: 31 case AF_INET6:
32 return ipv6_masked_addr_cmp(&a1->a6, &m->a6, &a2->a6); 32 return !ipv6_masked_addr_cmp(&a1->a6, &m->a6, &a2->a6);
33 } 33 }
34 return 0; 34 return 0;
35} 35}
@@ -44,7 +44,7 @@ match_xfrm_state(struct xfrm_state *x, const struct xt_policy_elem *e,
44#define MATCH(x,y) (!e->match.x || ((e->x == (y)) ^ e->invert.x)) 44#define MATCH(x,y) (!e->match.x || ((e->x == (y)) ^ e->invert.x))
45 45
46 return MATCH_ADDR(saddr, smask, (union xt_policy_addr *)&x->props.saddr) && 46 return MATCH_ADDR(saddr, smask, (union xt_policy_addr *)&x->props.saddr) &&
47 MATCH_ADDR(daddr, dmask, (union xt_policy_addr *)&x->id.daddr.a4) && 47 MATCH_ADDR(daddr, dmask, (union xt_policy_addr *)&x->id.daddr) &&
48 MATCH(proto, x->id.proto) && 48 MATCH(proto, x->id.proto) &&
49 MATCH(mode, x->props.mode) && 49 MATCH(mode, x->props.mode) &&
50 MATCH(spi, x->id.spi) && 50 MATCH(spi, x->id.spi) &&
@@ -172,6 +172,7 @@ static struct xt_match policy_match = {
172 .match = match, 172 .match = match,
173 .matchsize = sizeof(struct xt_policy_info), 173 .matchsize = sizeof(struct xt_policy_info),
174 .checkentry = checkentry, 174 .checkentry = checkentry,
175 .family = AF_INET,
175 .me = THIS_MODULE, 176 .me = THIS_MODULE,
176}; 177};
177 178
@@ -181,6 +182,7 @@ static struct xt_match policy6_match = {
181 .match = match, 182 .match = match,
182 .matchsize = sizeof(struct xt_policy_info), 183 .matchsize = sizeof(struct xt_policy_info),
183 .checkentry = checkentry, 184 .checkentry = checkentry,
185 .family = AF_INET6,
184 .me = THIS_MODULE, 186 .me = THIS_MODULE,
185}; 187};
186 188
@@ -188,19 +190,19 @@ static int __init init(void)
188{ 190{
189 int ret; 191 int ret;
190 192
191 ret = xt_register_match(AF_INET, &policy_match); 193 ret = xt_register_match(&policy_match);
192 if (ret) 194 if (ret)
193 return ret; 195 return ret;
194 ret = xt_register_match(AF_INET6, &policy6_match); 196 ret = xt_register_match(&policy6_match);
195 if (ret) 197 if (ret)
196 xt_unregister_match(AF_INET, &policy_match); 198 xt_unregister_match(&policy_match);
197 return ret; 199 return ret;
198} 200}
199 201
200static void __exit fini(void) 202static void __exit fini(void)
201{ 203{
202 xt_unregister_match(AF_INET6, &policy6_match); 204 xt_unregister_match(&policy6_match);
203 xt_unregister_match(AF_INET, &policy_match); 205 xt_unregister_match(&policy_match);
204} 206}
205 207
206module_init(init); 208module_init(init);
diff --git a/net/netfilter/xt_realm.c b/net/netfilter/xt_realm.c
index 57815a07db67..5e31a4a835bf 100644
--- a/net/netfilter/xt_realm.c
+++ b/net/netfilter/xt_realm.c
@@ -45,17 +45,18 @@ static struct xt_match realm_match = {
45 .matchsize = sizeof(struct xt_realm_info), 45 .matchsize = sizeof(struct xt_realm_info),
46 .hooks = (1 << NF_IP_POST_ROUTING) | (1 << NF_IP_FORWARD) | 46 .hooks = (1 << NF_IP_POST_ROUTING) | (1 << NF_IP_FORWARD) |
47 (1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_LOCAL_IN), 47 (1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_LOCAL_IN),
48 .family = AF_INET,
48 .me = THIS_MODULE 49 .me = THIS_MODULE
49}; 50};
50 51
51static int __init init(void) 52static int __init init(void)
52{ 53{
53 return xt_register_match(AF_INET, &realm_match); 54 return xt_register_match(&realm_match);
54} 55}
55 56
56static void __exit fini(void) 57static void __exit fini(void)
57{ 58{
58 xt_unregister_match(AF_INET, &realm_match); 59 xt_unregister_match(&realm_match);
59} 60}
60 61
61module_init(init); 62module_init(init);
diff --git a/net/netfilter/xt_sctp.c b/net/netfilter/xt_sctp.c
index f5d698ba03ca..c6eb24a2fe13 100644
--- a/net/netfilter/xt_sctp.c
+++ b/net/netfilter/xt_sctp.c
@@ -186,6 +186,7 @@ static struct xt_match sctp_match = {
186 .matchsize = sizeof(struct xt_sctp_info), 186 .matchsize = sizeof(struct xt_sctp_info),
187 .proto = IPPROTO_SCTP, 187 .proto = IPPROTO_SCTP,
188 .checkentry = checkentry, 188 .checkentry = checkentry,
189 .family = AF_INET,
189 .me = THIS_MODULE 190 .me = THIS_MODULE
190}; 191};
191 192
@@ -195,27 +196,28 @@ static struct xt_match sctp6_match = {
195 .matchsize = sizeof(struct xt_sctp_info), 196 .matchsize = sizeof(struct xt_sctp_info),
196 .proto = IPPROTO_SCTP, 197 .proto = IPPROTO_SCTP,
197 .checkentry = checkentry, 198 .checkentry = checkentry,
199 .family = AF_INET6,
198 .me = THIS_MODULE 200 .me = THIS_MODULE
199}; 201};
200 202
201static int __init init(void) 203static int __init init(void)
202{ 204{
203 int ret; 205 int ret;
204 ret = xt_register_match(AF_INET, &sctp_match); 206 ret = xt_register_match(&sctp_match);
205 if (ret) 207 if (ret)
206 return ret; 208 return ret;
207 209
208 ret = xt_register_match(AF_INET6, &sctp6_match); 210 ret = xt_register_match(&sctp6_match);
209 if (ret) 211 if (ret)
210 xt_unregister_match(AF_INET, &sctp_match); 212 xt_unregister_match(&sctp_match);
211 213
212 return ret; 214 return ret;
213} 215}
214 216
215static void __exit fini(void) 217static void __exit fini(void)
216{ 218{
217 xt_unregister_match(AF_INET6, &sctp6_match); 219 xt_unregister_match(&sctp6_match);
218 xt_unregister_match(AF_INET, &sctp_match); 220 xt_unregister_match(&sctp_match);
219} 221}
220 222
221module_init(init); 223module_init(init);
diff --git a/net/netfilter/xt_state.c b/net/netfilter/xt_state.c
index b8ec00cd51fc..e6c0be9d94d2 100644
--- a/net/netfilter/xt_state.c
+++ b/net/netfilter/xt_state.c
@@ -44,17 +44,48 @@ match(const struct sk_buff *skb,
44 return (sinfo->statemask & statebit); 44 return (sinfo->statemask & statebit);
45} 45}
46 46
47static int check(const char *tablename,
48 const void *inf,
49 const struct xt_match *match,
50 void *matchinfo,
51 unsigned int matchsize,
52 unsigned int hook_mask)
53{
54#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
55 if (nf_ct_l3proto_try_module_get(match->family) < 0) {
56 printk(KERN_WARNING "can't load nf_conntrack support for "
57 "proto=%d\n", match->family);
58 return 0;
59 }
60#endif
61 return 1;
62}
63
64static void
65destroy(const struct xt_match *match, void *matchinfo, unsigned int matchsize)
66{
67#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
68 nf_ct_l3proto_module_put(match->family);
69#endif
70}
71
47static struct xt_match state_match = { 72static struct xt_match state_match = {
48 .name = "state", 73 .name = "state",
49 .match = match, 74 .match = match,
75 .checkentry = check,
76 .destroy = destroy,
50 .matchsize = sizeof(struct xt_state_info), 77 .matchsize = sizeof(struct xt_state_info),
78 .family = AF_INET,
51 .me = THIS_MODULE, 79 .me = THIS_MODULE,
52}; 80};
53 81
54static struct xt_match state6_match = { 82static struct xt_match state6_match = {
55 .name = "state", 83 .name = "state",
56 .match = match, 84 .match = match,
85 .checkentry = check,
86 .destroy = destroy,
57 .matchsize = sizeof(struct xt_state_info), 87 .matchsize = sizeof(struct xt_state_info),
88 .family = AF_INET6,
58 .me = THIS_MODULE, 89 .me = THIS_MODULE,
59}; 90};
60 91
@@ -64,21 +95,21 @@ static int __init init(void)
64 95
65 need_conntrack(); 96 need_conntrack();
66 97
67 ret = xt_register_match(AF_INET, &state_match); 98 ret = xt_register_match(&state_match);
68 if (ret < 0) 99 if (ret < 0)
69 return ret; 100 return ret;
70 101
71 ret = xt_register_match(AF_INET6, &state6_match); 102 ret = xt_register_match(&state6_match);
72 if (ret < 0) 103 if (ret < 0)
73 xt_unregister_match(AF_INET,&state_match); 104 xt_unregister_match(&state_match);
74 105
75 return ret; 106 return ret;
76} 107}
77 108
78static void __exit fini(void) 109static void __exit fini(void)
79{ 110{
80 xt_unregister_match(AF_INET, &state_match); 111 xt_unregister_match(&state_match);
81 xt_unregister_match(AF_INET6, &state6_match); 112 xt_unregister_match(&state6_match);
82} 113}
83 114
84module_init(init); 115module_init(init);
diff --git a/net/netfilter/xt_string.c b/net/netfilter/xt_string.c
index fccbad6a7f40..703d80fccacf 100644
--- a/net/netfilter/xt_string.c
+++ b/net/netfilter/xt_string.c
@@ -78,6 +78,7 @@ static struct xt_match string_match = {
78 .matchsize = sizeof(struct xt_string_info), 78 .matchsize = sizeof(struct xt_string_info),
79 .checkentry = checkentry, 79 .checkentry = checkentry,
80 .destroy = destroy, 80 .destroy = destroy,
81 .family = AF_INET,
81 .me = THIS_MODULE 82 .me = THIS_MODULE
82}; 83};
83static struct xt_match string6_match = { 84static struct xt_match string6_match = {
@@ -86,6 +87,7 @@ static struct xt_match string6_match = {
86 .matchsize = sizeof(struct xt_string_info), 87 .matchsize = sizeof(struct xt_string_info),
87 .checkentry = checkentry, 88 .checkentry = checkentry,
88 .destroy = destroy, 89 .destroy = destroy,
90 .family = AF_INET6,
89 .me = THIS_MODULE 91 .me = THIS_MODULE
90}; 92};
91 93
@@ -93,20 +95,20 @@ static int __init init(void)
93{ 95{
94 int ret; 96 int ret;
95 97
96 ret = xt_register_match(AF_INET, &string_match); 98 ret = xt_register_match(&string_match);
97 if (ret) 99 if (ret)
98 return ret; 100 return ret;
99 ret = xt_register_match(AF_INET6, &string6_match); 101 ret = xt_register_match(&string6_match);
100 if (ret) 102 if (ret)
101 xt_unregister_match(AF_INET, &string_match); 103 xt_unregister_match(&string_match);
102 104
103 return ret; 105 return ret;
104} 106}
105 107
106static void __exit fini(void) 108static void __exit fini(void)
107{ 109{
108 xt_unregister_match(AF_INET, &string_match); 110 xt_unregister_match(&string_match);
109 xt_unregister_match(AF_INET6, &string6_match); 111 xt_unregister_match(&string6_match);
110} 112}
111 113
112module_init(init); 114module_init(init);
diff --git a/net/netfilter/xt_tcpmss.c b/net/netfilter/xt_tcpmss.c
index 4925fc98f4ae..70a8858ae3f1 100644
--- a/net/netfilter/xt_tcpmss.c
+++ b/net/netfilter/xt_tcpmss.c
@@ -98,6 +98,7 @@ static struct xt_match tcpmss_match = {
98 .match = match, 98 .match = match,
99 .matchsize = sizeof(struct xt_tcpmss_match_info), 99 .matchsize = sizeof(struct xt_tcpmss_match_info),
100 .proto = IPPROTO_TCP, 100 .proto = IPPROTO_TCP,
101 .family = AF_INET,
101 .me = THIS_MODULE, 102 .me = THIS_MODULE,
102}; 103};
103 104
@@ -106,6 +107,7 @@ static struct xt_match tcpmss6_match = {
106 .match = match, 107 .match = match,
107 .matchsize = sizeof(struct xt_tcpmss_match_info), 108 .matchsize = sizeof(struct xt_tcpmss_match_info),
108 .proto = IPPROTO_TCP, 109 .proto = IPPROTO_TCP,
110 .family = AF_INET6,
109 .me = THIS_MODULE, 111 .me = THIS_MODULE,
110}; 112};
111 113
@@ -113,21 +115,21 @@ static struct xt_match tcpmss6_match = {
113static int __init init(void) 115static int __init init(void)
114{ 116{
115 int ret; 117 int ret;
116 ret = xt_register_match(AF_INET, &tcpmss_match); 118 ret = xt_register_match(&tcpmss_match);
117 if (ret) 119 if (ret)
118 return ret; 120 return ret;
119 121
120 ret = xt_register_match(AF_INET6, &tcpmss6_match); 122 ret = xt_register_match(&tcpmss6_match);
121 if (ret) 123 if (ret)
122 xt_unregister_match(AF_INET, &tcpmss_match); 124 xt_unregister_match(&tcpmss_match);
123 125
124 return ret; 126 return ret;
125} 127}
126 128
127static void __exit fini(void) 129static void __exit fini(void)
128{ 130{
129 xt_unregister_match(AF_INET6, &tcpmss6_match); 131 xt_unregister_match(&tcpmss6_match);
130 xt_unregister_match(AF_INET, &tcpmss_match); 132 xt_unregister_match(&tcpmss_match);
131} 133}
132 134
133module_init(init); 135module_init(init);
diff --git a/net/netfilter/xt_tcpudp.c b/net/netfilter/xt_tcpudp.c
index b5cd0dd4e41f..14a990eb666a 100644
--- a/net/netfilter/xt_tcpudp.c
+++ b/net/netfilter/xt_tcpudp.c
@@ -204,6 +204,7 @@ static struct xt_match tcp_matchstruct = {
204 .match = tcp_match, 204 .match = tcp_match,
205 .matchsize = sizeof(struct xt_tcp), 205 .matchsize = sizeof(struct xt_tcp),
206 .proto = IPPROTO_TCP, 206 .proto = IPPROTO_TCP,
207 .family = AF_INET,
207 .checkentry = tcp_checkentry, 208 .checkentry = tcp_checkentry,
208 .me = THIS_MODULE, 209 .me = THIS_MODULE,
209}; 210};
@@ -213,6 +214,7 @@ static struct xt_match tcp6_matchstruct = {
213 .match = tcp_match, 214 .match = tcp_match,
214 .matchsize = sizeof(struct xt_tcp), 215 .matchsize = sizeof(struct xt_tcp),
215 .proto = IPPROTO_TCP, 216 .proto = IPPROTO_TCP,
217 .family = AF_INET6,
216 .checkentry = tcp_checkentry, 218 .checkentry = tcp_checkentry,
217 .me = THIS_MODULE, 219 .me = THIS_MODULE,
218}; 220};
@@ -222,6 +224,7 @@ static struct xt_match udp_matchstruct = {
222 .match = udp_match, 224 .match = udp_match,
223 .matchsize = sizeof(struct xt_udp), 225 .matchsize = sizeof(struct xt_udp),
224 .proto = IPPROTO_UDP, 226 .proto = IPPROTO_UDP,
227 .family = AF_INET,
225 .checkentry = udp_checkentry, 228 .checkentry = udp_checkentry,
226 .me = THIS_MODULE, 229 .me = THIS_MODULE,
227}; 230};
@@ -230,6 +233,7 @@ static struct xt_match udp6_matchstruct = {
230 .match = udp_match, 233 .match = udp_match,
231 .matchsize = sizeof(struct xt_udp), 234 .matchsize = sizeof(struct xt_udp),
232 .proto = IPPROTO_UDP, 235 .proto = IPPROTO_UDP,
236 .family = AF_INET6,
233 .checkentry = udp_checkentry, 237 .checkentry = udp_checkentry,
234 .me = THIS_MODULE, 238 .me = THIS_MODULE,
235}; 239};
@@ -237,39 +241,39 @@ static struct xt_match udp6_matchstruct = {
237static int __init init(void) 241static int __init init(void)
238{ 242{
239 int ret; 243 int ret;
240 ret = xt_register_match(AF_INET, &tcp_matchstruct); 244 ret = xt_register_match(&tcp_matchstruct);
241 if (ret) 245 if (ret)
242 return ret; 246 return ret;
243 247
244 ret = xt_register_match(AF_INET6, &tcp6_matchstruct); 248 ret = xt_register_match(&tcp6_matchstruct);
245 if (ret) 249 if (ret)
246 goto out_unreg_tcp; 250 goto out_unreg_tcp;
247 251
248 ret = xt_register_match(AF_INET, &udp_matchstruct); 252 ret = xt_register_match(&udp_matchstruct);
249 if (ret) 253 if (ret)
250 goto out_unreg_tcp6; 254 goto out_unreg_tcp6;
251 255
252 ret = xt_register_match(AF_INET6, &udp6_matchstruct); 256 ret = xt_register_match(&udp6_matchstruct);
253 if (ret) 257 if (ret)
254 goto out_unreg_udp; 258 goto out_unreg_udp;
255 259
256 return ret; 260 return ret;
257 261
258out_unreg_udp: 262out_unreg_udp:
259 xt_unregister_match(AF_INET, &tcp_matchstruct); 263 xt_unregister_match(&tcp_matchstruct);
260out_unreg_tcp6: 264out_unreg_tcp6:
261 xt_unregister_match(AF_INET6, &tcp6_matchstruct); 265 xt_unregister_match(&tcp6_matchstruct);
262out_unreg_tcp: 266out_unreg_tcp:
263 xt_unregister_match(AF_INET, &tcp_matchstruct); 267 xt_unregister_match(&tcp_matchstruct);
264 return ret; 268 return ret;
265} 269}
266 270
267static void __exit fini(void) 271static void __exit fini(void)
268{ 272{
269 xt_unregister_match(AF_INET6, &udp6_matchstruct); 273 xt_unregister_match(&udp6_matchstruct);
270 xt_unregister_match(AF_INET, &udp_matchstruct); 274 xt_unregister_match(&udp_matchstruct);
271 xt_unregister_match(AF_INET6, &tcp6_matchstruct); 275 xt_unregister_match(&tcp6_matchstruct);
272 xt_unregister_match(AF_INET, &tcp_matchstruct); 276 xt_unregister_match(&tcp_matchstruct);
273} 277}
274 278
275module_init(init); 279module_init(init);