aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-10-08 12:50:38 -0400
committerDavid S. Miller <davem@davemloft.net>2008-10-08 12:50:38 -0400
commit364ae953a48152be11f1aa424cbfd943b7762b0d (patch)
tree6873b352af1aa2dd6baa223b951eff4d6e74b1ae /net/ipv6
parent075f664689b40217539ebfe856fab73d302a15f1 (diff)
parentf39a9410ed0503278fd5edc559fa019051413039 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-next-2.6
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/netfilter.c2
-rw-r--r--net/ipv6/netfilter/Kconfig77
-rw-r--r--net/ipv6/netfilter/ip6_tables.c173
-rw-r--r--net/ipv6/netfilter/ip6t_HL.c15
-rw-r--r--net/ipv6/netfilter/ip6t_LOG.c22
-rw-r--r--net/ipv6/netfilter/ip6t_REJECT.c39
-rw-r--r--net/ipv6/netfilter/ip6t_ah.c21
-rw-r--r--net/ipv6/netfilter/ip6t_eui64.c11
-rw-r--r--net/ipv6/netfilter/ip6t_frag.c21
-rw-r--r--net/ipv6/netfilter/ip6t_hbh.c25
-rw-r--r--net/ipv6/netfilter/ip6t_hl.c9
-rw-r--r--net/ipv6/netfilter/ip6t_ipv6header.c16
-rw-r--r--net/ipv6/netfilter/ip6t_mh.c25
-rw-r--r--net/ipv6/netfilter/ip6t_rt.c21
-rw-r--r--net/ipv6/netfilter/ip6table_filter.c6
-rw-r--r--net/ipv6/netfilter/ip6table_mangle.c31
-rw-r--r--net/ipv6/netfilter/ip6table_raw.c20
-rw-r--r--net/ipv6/netfilter/ip6table_security.c6
-rw-r--r--net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c24
-rw-r--r--net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c19
20 files changed, 274 insertions, 309 deletions
diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c
index 8c6c5e71f210..4cb4844a3220 100644
--- a/net/ipv6/netfilter.c
+++ b/net/ipv6/netfilter.c
@@ -23,7 +23,7 @@ int ip6_route_me_harder(struct sk_buff *skb)
23 .saddr = iph->saddr, } }, 23 .saddr = iph->saddr, } },
24 }; 24 };
25 25
26 dst = ip6_route_output(&init_net, skb->sk, &fl); 26 dst = ip6_route_output(dev_net(skb->dst->dev), skb->sk, &fl);
27 27
28#ifdef CONFIG_XFRM 28#ifdef CONFIG_XFRM
29 if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) && 29 if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) &&
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
index 0cfcce7b18d8..53ea512c4608 100644
--- a/net/ipv6/netfilter/Kconfig
+++ b/net/ipv6/netfilter/Kconfig
@@ -55,30 +55,29 @@ config IP6_NF_IPTABLES
55 55
56 To compile it as a module, choose M here. If unsure, say N. 56 To compile it as a module, choose M here. If unsure, say N.
57 57
58if IP6_NF_IPTABLES
59
58# The simple matches. 60# The simple matches.
59config IP6_NF_MATCH_RT 61config IP6_NF_MATCH_AH
60 tristate '"rt" Routing header match support' 62 tristate '"ah" match support'
61 depends on IP6_NF_IPTABLES
62 depends on NETFILTER_ADVANCED 63 depends on NETFILTER_ADVANCED
63 help 64 help
64 rt matching allows you to match packets based on the routing 65 This module allows one to match AH packets.
65 header of the packet.
66 66
67 To compile it as a module, choose M here. If unsure, say N. 67 To compile it as a module, choose M here. If unsure, say N.
68 68
69config IP6_NF_MATCH_OPTS 69config IP6_NF_MATCH_EUI64
70 tristate '"hopbyhop" and "dst" opts header match support' 70 tristate '"eui64" address check'
71 depends on IP6_NF_IPTABLES
72 depends on NETFILTER_ADVANCED 71 depends on NETFILTER_ADVANCED
73 help 72 help
74 This allows one to match packets based on the hop-by-hop 73 This module performs checking on the IPv6 source address
75 and destination options headers of a packet. 74 Compares the last 64 bits with the EUI64 (delivered
75 from the MAC address) address
76 76
77 To compile it as a module, choose M here. If unsure, say N. 77 To compile it as a module, choose M here. If unsure, say N.
78 78
79config IP6_NF_MATCH_FRAG 79config IP6_NF_MATCH_FRAG
80 tristate '"frag" Fragmentation header match support' 80 tristate '"frag" Fragmentation header match support'
81 depends on IP6_NF_IPTABLES
82 depends on NETFILTER_ADVANCED 81 depends on NETFILTER_ADVANCED
83 help 82 help
84 frag matching allows you to match packets based on the fragmentation 83 frag matching allows you to match packets based on the fragmentation
@@ -86,9 +85,17 @@ config IP6_NF_MATCH_FRAG
86 85
87 To compile it as a module, choose M here. If unsure, say N. 86 To compile it as a module, choose M here. If unsure, say N.
88 87
88config IP6_NF_MATCH_OPTS
89 tristate '"hbh" hop-by-hop and "dst" opts header match support'
90 depends on NETFILTER_ADVANCED
91 help
92 This allows one to match packets based on the hop-by-hop
93 and destination options headers of a packet.
94
95 To compile it as a module, choose M here. If unsure, say N.
96
89config IP6_NF_MATCH_HL 97config IP6_NF_MATCH_HL
90 tristate '"hl" match support' 98 tristate '"hl" match support'
91 depends on IP6_NF_IPTABLES
92 depends on NETFILTER_ADVANCED 99 depends on NETFILTER_ADVANCED
93 help 100 help
94 HL matching allows you to match packets based on the hop 101 HL matching allows you to match packets based on the hop
@@ -98,7 +105,6 @@ config IP6_NF_MATCH_HL
98 105
99config IP6_NF_MATCH_IPV6HEADER 106config IP6_NF_MATCH_IPV6HEADER
100 tristate '"ipv6header" IPv6 Extension Headers Match' 107 tristate '"ipv6header" IPv6 Extension Headers Match'
101 depends on IP6_NF_IPTABLES
102 default m if NETFILTER_ADVANCED=n 108 default m if NETFILTER_ADVANCED=n
103 help 109 help
104 This module allows one to match packets based upon 110 This module allows one to match packets based upon
@@ -106,54 +112,40 @@ config IP6_NF_MATCH_IPV6HEADER
106 112
107 To compile it as a module, choose M here. If unsure, say N. 113 To compile it as a module, choose M here. If unsure, say N.
108 114
109config IP6_NF_MATCH_AH
110 tristate '"ah" match support'
111 depends on IP6_NF_IPTABLES
112 depends on NETFILTER_ADVANCED
113 help
114 This module allows one to match AH packets.
115
116 To compile it as a module, choose M here. If unsure, say N.
117
118config IP6_NF_MATCH_MH 115config IP6_NF_MATCH_MH
119 tristate '"mh" match support' 116 tristate '"mh" match support'
120 depends on IP6_NF_IPTABLES
121 depends on NETFILTER_ADVANCED 117 depends on NETFILTER_ADVANCED
122 help 118 help
123 This module allows one to match MH packets. 119 This module allows one to match MH packets.
124 120
125 To compile it as a module, choose M here. If unsure, say N. 121 To compile it as a module, choose M here. If unsure, say N.
126 122
127config IP6_NF_MATCH_EUI64 123config IP6_NF_MATCH_RT
128 tristate '"eui64" address check' 124 tristate '"rt" Routing header match support'
129 depends on IP6_NF_IPTABLES
130 depends on NETFILTER_ADVANCED 125 depends on NETFILTER_ADVANCED
131 help 126 help
132 This module performs checking on the IPv6 source address 127 rt matching allows you to match packets based on the routing
133 Compares the last 64 bits with the EUI64 (delivered 128 header of the packet.
134 from the MAC address) address
135 129
136 To compile it as a module, choose M here. If unsure, say N. 130 To compile it as a module, choose M here. If unsure, say N.
137 131
138# The targets 132# The targets
139config IP6_NF_FILTER 133config IP6_NF_TARGET_LOG
140 tristate "Packet filtering" 134 tristate "LOG target support"
141 depends on IP6_NF_IPTABLES
142 default m if NETFILTER_ADVANCED=n 135 default m if NETFILTER_ADVANCED=n
143 help 136 help
144 Packet filtering defines a table `filter', which has a series of 137 This option adds a `LOG' target, which allows you to create rules in
145 rules for simple packet filtering at local input, forwarding and 138 any iptables table which records the packet header to the syslog.
146 local output. See the man page for iptables(8).
147 139
148 To compile it as a module, choose M here. If unsure, say N. 140 To compile it as a module, choose M here. If unsure, say N.
149 141
150config IP6_NF_TARGET_LOG 142config IP6_NF_FILTER
151 tristate "LOG target support" 143 tristate "Packet filtering"
152 depends on IP6_NF_FILTER
153 default m if NETFILTER_ADVANCED=n 144 default m if NETFILTER_ADVANCED=n
154 help 145 help
155 This option adds a `LOG' target, which allows you to create rules in 146 Packet filtering defines a table `filter', which has a series of
156 any iptables table which records the packet header to the syslog. 147 rules for simple packet filtering at local input, forwarding and
148 local output. See the man page for iptables(8).
157 149
158 To compile it as a module, choose M here. If unsure, say N. 150 To compile it as a module, choose M here. If unsure, say N.
159 151
@@ -170,7 +162,6 @@ config IP6_NF_TARGET_REJECT
170 162
171config IP6_NF_MANGLE 163config IP6_NF_MANGLE
172 tristate "Packet mangling" 164 tristate "Packet mangling"
173 depends on IP6_NF_IPTABLES
174 default m if NETFILTER_ADVANCED=n 165 default m if NETFILTER_ADVANCED=n
175 help 166 help
176 This option adds a `mangle' table to iptables: see the man page for 167 This option adds a `mangle' table to iptables: see the man page for
@@ -198,7 +189,6 @@ config IP6_NF_TARGET_HL
198 189
199config IP6_NF_RAW 190config IP6_NF_RAW
200 tristate 'raw table support (required for TRACE)' 191 tristate 'raw table support (required for TRACE)'
201 depends on IP6_NF_IPTABLES
202 depends on NETFILTER_ADVANCED 192 depends on NETFILTER_ADVANCED
203 help 193 help
204 This option adds a `raw' table to ip6tables. This table is the very 194 This option adds a `raw' table to ip6tables. This table is the very
@@ -211,7 +201,6 @@ config IP6_NF_RAW
211# security table for MAC policy 201# security table for MAC policy
212config IP6_NF_SECURITY 202config IP6_NF_SECURITY
213 tristate "Security table" 203 tristate "Security table"
214 depends on IP6_NF_IPTABLES
215 depends on SECURITY 204 depends on SECURITY
216 depends on NETFILTER_ADVANCED 205 depends on NETFILTER_ADVANCED
217 help 206 help
@@ -220,5 +209,7 @@ config IP6_NF_SECURITY
220 209
221 If unsure, say N. 210 If unsure, say N.
222 211
212endif # IP6_NF_IPTABLES
213
223endmenu 214endmenu
224 215
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 0b4557e03431..a33485dc81cb 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -200,32 +200,25 @@ ip6_checkentry(const struct ip6t_ip6 *ipv6)
200} 200}
201 201
202static unsigned int 202static unsigned int
203ip6t_error(struct sk_buff *skb, 203ip6t_error(struct sk_buff *skb, const struct xt_target_param *par)
204 const struct net_device *in,
205 const struct net_device *out,
206 unsigned int hooknum,
207 const struct xt_target *target,
208 const void *targinfo)
209{ 204{
210 if (net_ratelimit()) 205 if (net_ratelimit())
211 printk("ip6_tables: error: `%s'\n", (char *)targinfo); 206 printk("ip6_tables: error: `%s'\n",
207 (const char *)par->targinfo);
212 208
213 return NF_DROP; 209 return NF_DROP;
214} 210}
215 211
216/* Performance critical - called for every packet */ 212/* Performance critical - called for every packet */
217static inline bool 213static inline bool
218do_match(struct ip6t_entry_match *m, 214do_match(struct ip6t_entry_match *m, const struct sk_buff *skb,
219 const struct sk_buff *skb, 215 struct xt_match_param *par)
220 const struct net_device *in,
221 const struct net_device *out,
222 int offset,
223 unsigned int protoff,
224 bool *hotdrop)
225{ 216{
217 par->match = m->u.kernel.match;
218 par->matchinfo = m->data;
219
226 /* Stop iteration if it doesn't match */ 220 /* Stop iteration if it doesn't match */
227 if (!m->u.kernel.match->match(skb, in, out, m->u.kernel.match, m->data, 221 if (!m->u.kernel.match->match(skb, par))
228 offset, protoff, hotdrop))
229 return true; 222 return true;
230 else 223 else
231 return false; 224 return false;
@@ -355,8 +348,6 @@ ip6t_do_table(struct sk_buff *skb,
355 struct xt_table *table) 348 struct xt_table *table)
356{ 349{
357 static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); 350 static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long))));
358 int offset = 0;
359 unsigned int protoff = 0;
360 bool hotdrop = false; 351 bool hotdrop = false;
361 /* Initializing verdict to NF_DROP keeps gcc happy. */ 352 /* Initializing verdict to NF_DROP keeps gcc happy. */
362 unsigned int verdict = NF_DROP; 353 unsigned int verdict = NF_DROP;
@@ -364,6 +355,8 @@ ip6t_do_table(struct sk_buff *skb,
364 void *table_base; 355 void *table_base;
365 struct ip6t_entry *e, *back; 356 struct ip6t_entry *e, *back;
366 struct xt_table_info *private; 357 struct xt_table_info *private;
358 struct xt_match_param mtpar;
359 struct xt_target_param tgpar;
367 360
368 /* Initialization */ 361 /* Initialization */
369 indev = in ? in->name : nulldevname; 362 indev = in ? in->name : nulldevname;
@@ -374,6 +367,11 @@ ip6t_do_table(struct sk_buff *skb,
374 * things we don't know, ie. tcp syn flag or ports). If the 367 * things we don't know, ie. tcp syn flag or ports). If the
375 * rule is also a fragment-specific rule, non-fragments won't 368 * rule is also a fragment-specific rule, non-fragments won't
376 * match it. */ 369 * match it. */
370 mtpar.hotdrop = &hotdrop;
371 mtpar.in = tgpar.in = in;
372 mtpar.out = tgpar.out = out;
373 mtpar.family = tgpar.family = NFPROTO_IPV6;
374 tgpar.hooknum = hook;
377 375
378 read_lock_bh(&table->lock); 376 read_lock_bh(&table->lock);
379 IP_NF_ASSERT(table->valid_hooks & (1 << hook)); 377 IP_NF_ASSERT(table->valid_hooks & (1 << hook));
@@ -388,12 +386,10 @@ ip6t_do_table(struct sk_buff *skb,
388 IP_NF_ASSERT(e); 386 IP_NF_ASSERT(e);
389 IP_NF_ASSERT(back); 387 IP_NF_ASSERT(back);
390 if (ip6_packet_match(skb, indev, outdev, &e->ipv6, 388 if (ip6_packet_match(skb, indev, outdev, &e->ipv6,
391 &protoff, &offset, &hotdrop)) { 389 &mtpar.thoff, &mtpar.fragoff, &hotdrop)) {
392 struct ip6t_entry_target *t; 390 struct ip6t_entry_target *t;
393 391
394 if (IP6T_MATCH_ITERATE(e, do_match, 392 if (IP6T_MATCH_ITERATE(e, do_match, skb, &mtpar) != 0)
395 skb, in, out,
396 offset, protoff, &hotdrop) != 0)
397 goto no_match; 393 goto no_match;
398 394
399 ADD_COUNTER(e->counters, 395 ADD_COUNTER(e->counters,
@@ -441,15 +437,15 @@ ip6t_do_table(struct sk_buff *skb,
441 } else { 437 } else {
442 /* Targets which reenter must return 438 /* Targets which reenter must return
443 abs. verdicts */ 439 abs. verdicts */
440 tgpar.target = t->u.kernel.target;
441 tgpar.targinfo = t->data;
442
444#ifdef CONFIG_NETFILTER_DEBUG 443#ifdef CONFIG_NETFILTER_DEBUG
445 ((struct ip6t_entry *)table_base)->comefrom 444 ((struct ip6t_entry *)table_base)->comefrom
446 = 0xeeeeeeec; 445 = 0xeeeeeeec;
447#endif 446#endif
448 verdict = t->u.kernel.target->target(skb, 447 verdict = t->u.kernel.target->target(skb,
449 in, out, 448 &tgpar);
450 hook,
451 t->u.kernel.target,
452 t->data);
453 449
454#ifdef CONFIG_NETFILTER_DEBUG 450#ifdef CONFIG_NETFILTER_DEBUG
455 if (((struct ip6t_entry *)table_base)->comefrom 451 if (((struct ip6t_entry *)table_base)->comefrom
@@ -602,12 +598,17 @@ mark_source_chains(struct xt_table_info *newinfo,
602static int 598static int
603cleanup_match(struct ip6t_entry_match *m, unsigned int *i) 599cleanup_match(struct ip6t_entry_match *m, unsigned int *i)
604{ 600{
601 struct xt_mtdtor_param par;
602
605 if (i && (*i)-- == 0) 603 if (i && (*i)-- == 0)
606 return 1; 604 return 1;
607 605
608 if (m->u.kernel.match->destroy) 606 par.match = m->u.kernel.match;
609 m->u.kernel.match->destroy(m->u.kernel.match, m->data); 607 par.matchinfo = m->data;
610 module_put(m->u.kernel.match->me); 608 par.family = NFPROTO_IPV6;
609 if (par.match->destroy != NULL)
610 par.match->destroy(&par);
611 module_put(par.match->me);
611 return 0; 612 return 0;
612} 613}
613 614
@@ -632,34 +633,28 @@ check_entry(struct ip6t_entry *e, const char *name)
632 return 0; 633 return 0;
633} 634}
634 635
635static int check_match(struct ip6t_entry_match *m, const char *name, 636static int check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par,
636 const struct ip6t_ip6 *ipv6, 637 unsigned int *i)
637 unsigned int hookmask, unsigned int *i)
638{ 638{
639 struct xt_match *match; 639 const struct ip6t_ip6 *ipv6 = par->entryinfo;
640 int ret; 640 int ret;
641 641
642 match = m->u.kernel.match; 642 par->match = m->u.kernel.match;
643 ret = xt_check_match(match, AF_INET6, m->u.match_size - sizeof(*m), 643 par->matchinfo = m->data;
644 name, hookmask, ipv6->proto, 644
645 ipv6->invflags & IP6T_INV_PROTO); 645 ret = xt_check_match(par, m->u.match_size - sizeof(*m),
646 if (!ret && m->u.kernel.match->checkentry 646 ipv6->proto, ipv6->invflags & IP6T_INV_PROTO);
647 && !m->u.kernel.match->checkentry(name, ipv6, match, m->data, 647 if (ret < 0) {
648 hookmask)) {
649 duprintf("ip_tables: check failed for `%s'.\n", 648 duprintf("ip_tables: check failed for `%s'.\n",
650 m->u.kernel.match->name); 649 par.match->name);
651 ret = -EINVAL; 650 return ret;
652 } 651 }
653 if (!ret) 652 ++*i;
654 (*i)++; 653 return 0;
655 return ret;
656} 654}
657 655
658static int 656static int
659find_check_match(struct ip6t_entry_match *m, 657find_check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par,
660 const char *name,
661 const struct ip6t_ip6 *ipv6,
662 unsigned int hookmask,
663 unsigned int *i) 658 unsigned int *i)
664{ 659{
665 struct xt_match *match; 660 struct xt_match *match;
@@ -674,7 +669,7 @@ find_check_match(struct ip6t_entry_match *m,
674 } 669 }
675 m->u.kernel.match = match; 670 m->u.kernel.match = match;
676 671
677 ret = check_match(m, name, ipv6, hookmask, i); 672 ret = check_match(m, par, i);
678 if (ret) 673 if (ret)
679 goto err; 674 goto err;
680 675
@@ -686,23 +681,26 @@ err:
686 681
687static int check_target(struct ip6t_entry *e, const char *name) 682static int check_target(struct ip6t_entry *e, const char *name)
688{ 683{
689 struct ip6t_entry_target *t; 684 struct ip6t_entry_target *t = ip6t_get_target(e);
690 struct xt_target *target; 685 struct xt_tgchk_param par = {
686 .table = name,
687 .entryinfo = e,
688 .target = t->u.kernel.target,
689 .targinfo = t->data,
690 .hook_mask = e->comefrom,
691 .family = NFPROTO_IPV6,
692 };
691 int ret; 693 int ret;
692 694
693 t = ip6t_get_target(e); 695 t = ip6t_get_target(e);
694 target = t->u.kernel.target; 696 ret = xt_check_target(&par, t->u.target_size - sizeof(*t),
695 ret = xt_check_target(target, AF_INET6, t->u.target_size - sizeof(*t), 697 e->ipv6.proto, e->ipv6.invflags & IP6T_INV_PROTO);
696 name, e->comefrom, e->ipv6.proto, 698 if (ret < 0) {
697 e->ipv6.invflags & IP6T_INV_PROTO);
698 if (!ret && t->u.kernel.target->checkentry
699 && !t->u.kernel.target->checkentry(name, e, target, t->data,
700 e->comefrom)) {
701 duprintf("ip_tables: check failed for `%s'.\n", 699 duprintf("ip_tables: check failed for `%s'.\n",
702 t->u.kernel.target->name); 700 t->u.kernel.target->name);
703 ret = -EINVAL; 701 return ret;
704 } 702 }
705 return ret; 703 return 0;
706} 704}
707 705
708static int 706static int
@@ -713,14 +711,18 @@ find_check_entry(struct ip6t_entry *e, const char *name, unsigned int size,
713 struct xt_target *target; 711 struct xt_target *target;
714 int ret; 712 int ret;
715 unsigned int j; 713 unsigned int j;
714 struct xt_mtchk_param mtpar;
716 715
717 ret = check_entry(e, name); 716 ret = check_entry(e, name);
718 if (ret) 717 if (ret)
719 return ret; 718 return ret;
720 719
721 j = 0; 720 j = 0;
722 ret = IP6T_MATCH_ITERATE(e, find_check_match, name, &e->ipv6, 721 mtpar.table = name;
723 e->comefrom, &j); 722 mtpar.entryinfo = &e->ipv6;
723 mtpar.hook_mask = e->comefrom;
724 mtpar.family = NFPROTO_IPV6;
725 ret = IP6T_MATCH_ITERATE(e, find_check_match, &mtpar, &j);
724 if (ret != 0) 726 if (ret != 0)
725 goto cleanup_matches; 727 goto cleanup_matches;
726 728
@@ -795,6 +797,7 @@ check_entry_size_and_hooks(struct ip6t_entry *e,
795static int 797static int
796cleanup_entry(struct ip6t_entry *e, unsigned int *i) 798cleanup_entry(struct ip6t_entry *e, unsigned int *i)
797{ 799{
800 struct xt_tgdtor_param par;
798 struct ip6t_entry_target *t; 801 struct ip6t_entry_target *t;
799 802
800 if (i && (*i)-- == 0) 803 if (i && (*i)-- == 0)
@@ -803,9 +806,13 @@ cleanup_entry(struct ip6t_entry *e, unsigned int *i)
803 /* Cleanup all matches */ 806 /* Cleanup all matches */
804 IP6T_MATCH_ITERATE(e, cleanup_match, NULL); 807 IP6T_MATCH_ITERATE(e, cleanup_match, NULL);
805 t = ip6t_get_target(e); 808 t = ip6t_get_target(e);
806 if (t->u.kernel.target->destroy) 809
807 t->u.kernel.target->destroy(t->u.kernel.target, t->data); 810 par.target = t->u.kernel.target;
808 module_put(t->u.kernel.target->me); 811 par.targinfo = t->data;
812 par.family = NFPROTO_IPV6;
813 if (par.target->destroy != NULL)
814 par.target->destroy(&par);
815 module_put(par.target->me);
809 return 0; 816 return 0;
810} 817}
811 818
@@ -1677,10 +1684,14 @@ static int compat_check_entry(struct ip6t_entry *e, const char *name,
1677{ 1684{
1678 unsigned int j; 1685 unsigned int j;
1679 int ret; 1686 int ret;
1687 struct xt_mtchk_param mtpar;
1680 1688
1681 j = 0; 1689 j = 0;
1682 ret = IP6T_MATCH_ITERATE(e, check_match, name, &e->ipv6, 1690 mtpar.table = name;
1683 e->comefrom, &j); 1691 mtpar.entryinfo = &e->ipv6;
1692 mtpar.hook_mask = e->comefrom;
1693 mtpar.family = NFPROTO_IPV6;
1694 ret = IP6T_MATCH_ITERATE(e, check_match, &mtpar, &j);
1684 if (ret) 1695 if (ret)
1685 goto cleanup_matches; 1696 goto cleanup_matches;
1686 1697
@@ -2146,30 +2157,23 @@ icmp6_type_code_match(u_int8_t test_type, u_int8_t min_code, u_int8_t max_code,
2146} 2157}
2147 2158
2148static bool 2159static bool
2149icmp6_match(const struct sk_buff *skb, 2160icmp6_match(const struct sk_buff *skb, const struct xt_match_param *par)
2150 const struct net_device *in,
2151 const struct net_device *out,
2152 const struct xt_match *match,
2153 const void *matchinfo,
2154 int offset,
2155 unsigned int protoff,
2156 bool *hotdrop)
2157{ 2161{
2158 const struct icmp6hdr *ic; 2162 const struct icmp6hdr *ic;
2159 struct icmp6hdr _icmph; 2163 struct icmp6hdr _icmph;
2160 const struct ip6t_icmp *icmpinfo = matchinfo; 2164 const struct ip6t_icmp *icmpinfo = par->matchinfo;
2161 2165
2162 /* Must not be a fragment. */ 2166 /* Must not be a fragment. */
2163 if (offset) 2167 if (par->fragoff != 0)
2164 return false; 2168 return false;
2165 2169
2166 ic = skb_header_pointer(skb, protoff, sizeof(_icmph), &_icmph); 2170 ic = skb_header_pointer(skb, par->thoff, sizeof(_icmph), &_icmph);
2167 if (ic == NULL) { 2171 if (ic == NULL) {
2168 /* We've been asked to examine this packet, and we 2172 /* We've been asked to examine this packet, and we
2169 * can't. Hence, no choice but to drop. 2173 * can't. Hence, no choice but to drop.
2170 */ 2174 */
2171 duprintf("Dropping evil ICMP tinygram.\n"); 2175 duprintf("Dropping evil ICMP tinygram.\n");
2172 *hotdrop = true; 2176 *par->hotdrop = true;
2173 return false; 2177 return false;
2174 } 2178 }
2175 2179
@@ -2181,14 +2185,9 @@ icmp6_match(const struct sk_buff *skb,
2181} 2185}
2182 2186
2183/* Called when user tries to insert an entry of this type. */ 2187/* Called when user tries to insert an entry of this type. */
2184static bool 2188static bool icmp6_checkentry(const struct xt_mtchk_param *par)
2185icmp6_checkentry(const char *tablename,
2186 const void *entry,
2187 const struct xt_match *match,
2188 void *matchinfo,
2189 unsigned int hook_mask)
2190{ 2189{
2191 const struct ip6t_icmp *icmpinfo = matchinfo; 2190 const struct ip6t_icmp *icmpinfo = par->matchinfo;
2192 2191
2193 /* Must specify no unknown invflags */ 2192 /* Must specify no unknown invflags */
2194 return !(icmpinfo->invflags & ~IP6T_ICMP_INV); 2193 return !(icmpinfo->invflags & ~IP6T_ICMP_INV);
diff --git a/net/ipv6/netfilter/ip6t_HL.c b/net/ipv6/netfilter/ip6t_HL.c
index d5f8fd5f29d3..27b5adf670a2 100644
--- a/net/ipv6/netfilter/ip6t_HL.c
+++ b/net/ipv6/netfilter/ip6t_HL.c
@@ -19,12 +19,10 @@ MODULE_DESCRIPTION("Xtables: IPv6 Hop Limit field modification target");
19MODULE_LICENSE("GPL"); 19MODULE_LICENSE("GPL");
20 20
21static unsigned int 21static unsigned int
22hl_tg6(struct sk_buff *skb, const struct net_device *in, 22hl_tg6(struct sk_buff *skb, const struct xt_target_param *par)
23 const struct net_device *out, unsigned int hooknum,
24 const struct xt_target *target, const void *targinfo)
25{ 23{
26 struct ipv6hdr *ip6h; 24 struct ipv6hdr *ip6h;
27 const struct ip6t_HL_info *info = targinfo; 25 const struct ip6t_HL_info *info = par->targinfo;
28 int new_hl; 26 int new_hl;
29 27
30 if (!skb_make_writable(skb, skb->len)) 28 if (!skb_make_writable(skb, skb->len))
@@ -56,12 +54,9 @@ hl_tg6(struct sk_buff *skb, const struct net_device *in,
56 return XT_CONTINUE; 54 return XT_CONTINUE;
57} 55}
58 56
59static bool 57static bool hl_tg6_check(const struct xt_tgchk_param *par)
60hl_tg6_check(const char *tablename, const void *entry,
61 const struct xt_target *target, void *targinfo,
62 unsigned int hook_mask)
63{ 58{
64 const struct ip6t_HL_info *info = targinfo; 59 const struct ip6t_HL_info *info = par->targinfo;
65 60
66 if (info->mode > IP6T_HL_MAXMODE) { 61 if (info->mode > IP6T_HL_MAXMODE) {
67 printk(KERN_WARNING "ip6t_HL: invalid or unknown Mode %u\n", 62 printk(KERN_WARNING "ip6t_HL: invalid or unknown Mode %u\n",
@@ -78,7 +73,7 @@ hl_tg6_check(const char *tablename, const void *entry,
78 73
79static struct xt_target hl_tg6_reg __read_mostly = { 74static struct xt_target hl_tg6_reg __read_mostly = {
80 .name = "HL", 75 .name = "HL",
81 .family = AF_INET6, 76 .family = NFPROTO_IPV6,
82 .target = hl_tg6, 77 .target = hl_tg6,
83 .targetsize = sizeof(struct ip6t_HL_info), 78 .targetsize = sizeof(struct ip6t_HL_info),
84 .table = "mangle", 79 .table = "mangle",
diff --git a/net/ipv6/netfilter/ip6t_LOG.c b/net/ipv6/netfilter/ip6t_LOG.c
index 3a2316974f83..caa441d09567 100644
--- a/net/ipv6/netfilter/ip6t_LOG.c
+++ b/net/ipv6/netfilter/ip6t_LOG.c
@@ -385,7 +385,7 @@ static struct nf_loginfo default_loginfo = {
385}; 385};
386 386
387static void 387static void
388ip6t_log_packet(unsigned int pf, 388ip6t_log_packet(u_int8_t pf,
389 unsigned int hooknum, 389 unsigned int hooknum,
390 const struct sk_buff *skb, 390 const struct sk_buff *skb,
391 const struct net_device *in, 391 const struct net_device *in,
@@ -438,28 +438,24 @@ ip6t_log_packet(unsigned int pf,
438} 438}
439 439
440static unsigned int 440static unsigned int
441log_tg6(struct sk_buff *skb, const struct net_device *in, 441log_tg6(struct sk_buff *skb, const struct xt_target_param *par)
442 const struct net_device *out, unsigned int hooknum,
443 const struct xt_target *target, const void *targinfo)
444{ 442{
445 const struct ip6t_log_info *loginfo = targinfo; 443 const struct ip6t_log_info *loginfo = par->targinfo;
446 struct nf_loginfo li; 444 struct nf_loginfo li;
447 445
448 li.type = NF_LOG_TYPE_LOG; 446 li.type = NF_LOG_TYPE_LOG;
449 li.u.log.level = loginfo->level; 447 li.u.log.level = loginfo->level;
450 li.u.log.logflags = loginfo->logflags; 448 li.u.log.logflags = loginfo->logflags;
451 449
452 ip6t_log_packet(PF_INET6, hooknum, skb, in, out, &li, loginfo->prefix); 450 ip6t_log_packet(NFPROTO_IPV6, par->hooknum, skb, par->in, par->out,
451 &li, loginfo->prefix);
453 return XT_CONTINUE; 452 return XT_CONTINUE;
454} 453}
455 454
456 455
457static bool 456static bool log_tg6_check(const struct xt_tgchk_param *par)
458log_tg6_check(const char *tablename, const void *entry,
459 const struct xt_target *target, void *targinfo,
460 unsigned int hook_mask)
461{ 457{
462 const struct ip6t_log_info *loginfo = targinfo; 458 const struct ip6t_log_info *loginfo = par->targinfo;
463 459
464 if (loginfo->level >= 8) { 460 if (loginfo->level >= 8) {
465 pr_debug("LOG: level %u >= 8\n", loginfo->level); 461 pr_debug("LOG: level %u >= 8\n", loginfo->level);
@@ -475,7 +471,7 @@ log_tg6_check(const char *tablename, const void *entry,
475 471
476static struct xt_target log_tg6_reg __read_mostly = { 472static struct xt_target log_tg6_reg __read_mostly = {
477 .name = "LOG", 473 .name = "LOG",
478 .family = AF_INET6, 474 .family = NFPROTO_IPV6,
479 .target = log_tg6, 475 .target = log_tg6,
480 .targetsize = sizeof(struct ip6t_log_info), 476 .targetsize = sizeof(struct ip6t_log_info),
481 .checkentry = log_tg6_check, 477 .checkentry = log_tg6_check,
@@ -495,7 +491,7 @@ static int __init log_tg6_init(void)
495 ret = xt_register_target(&log_tg6_reg); 491 ret = xt_register_target(&log_tg6_reg);
496 if (ret < 0) 492 if (ret < 0)
497 return ret; 493 return ret;
498 nf_log_register(PF_INET6, &ip6t_logger); 494 nf_log_register(NFPROTO_IPV6, &ip6t_logger);
499 return 0; 495 return 0;
500} 496}
501 497
diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c
index 44c8d65a2431..0981b4ccb8b1 100644
--- a/net/ipv6/netfilter/ip6t_REJECT.c
+++ b/net/ipv6/netfilter/ip6t_REJECT.c
@@ -35,7 +35,7 @@ MODULE_DESCRIPTION("Xtables: packet \"rejection\" target for IPv6");
35MODULE_LICENSE("GPL"); 35MODULE_LICENSE("GPL");
36 36
37/* Send RST reply */ 37/* Send RST reply */
38static void send_reset(struct sk_buff *oldskb) 38static void send_reset(struct net *net, struct sk_buff *oldskb)
39{ 39{
40 struct sk_buff *nskb; 40 struct sk_buff *nskb;
41 struct tcphdr otcph, *tcph; 41 struct tcphdr otcph, *tcph;
@@ -94,7 +94,7 @@ static void send_reset(struct sk_buff *oldskb)
94 fl.fl_ip_sport = otcph.dest; 94 fl.fl_ip_sport = otcph.dest;
95 fl.fl_ip_dport = otcph.source; 95 fl.fl_ip_dport = otcph.source;
96 security_skb_classify_flow(oldskb, &fl); 96 security_skb_classify_flow(oldskb, &fl);
97 dst = ip6_route_output(&init_net, NULL, &fl); 97 dst = ip6_route_output(net, NULL, &fl);
98 if (dst == NULL) 98 if (dst == NULL)
99 return; 99 return;
100 if (dst->error || xfrm_lookup(&dst, &fl, NULL, 0)) 100 if (dst->error || xfrm_lookup(&dst, &fl, NULL, 0))
@@ -163,20 +163,20 @@ static void send_reset(struct sk_buff *oldskb)
163} 163}
164 164
165static inline void 165static inline void
166send_unreach(struct sk_buff *skb_in, unsigned char code, unsigned int hooknum) 166send_unreach(struct net *net, struct sk_buff *skb_in, unsigned char code,
167 unsigned int hooknum)
167{ 168{
168 if (hooknum == NF_INET_LOCAL_OUT && skb_in->dev == NULL) 169 if (hooknum == NF_INET_LOCAL_OUT && skb_in->dev == NULL)
169 skb_in->dev = init_net.loopback_dev; 170 skb_in->dev = net->loopback_dev;
170 171
171 icmpv6_send(skb_in, ICMPV6_DEST_UNREACH, code, 0, NULL); 172 icmpv6_send(skb_in, ICMPV6_DEST_UNREACH, code, 0, NULL);
172} 173}
173 174
174static unsigned int 175static unsigned int
175reject_tg6(struct sk_buff *skb, const struct net_device *in, 176reject_tg6(struct sk_buff *skb, const struct xt_target_param *par)
176 const struct net_device *out, unsigned int hooknum,
177 const struct xt_target *target, const void *targinfo)
178{ 177{
179 const struct ip6t_reject_info *reject = targinfo; 178 const struct ip6t_reject_info *reject = par->targinfo;
179 struct net *net = dev_net((par->in != NULL) ? par->in : par->out);
180 180
181 pr_debug("%s: medium point\n", __func__); 181 pr_debug("%s: medium point\n", __func__);
182 /* WARNING: This code causes reentry within ip6tables. 182 /* WARNING: This code causes reentry within ip6tables.
@@ -184,25 +184,25 @@ reject_tg6(struct sk_buff *skb, const struct net_device *in,
184 must return an absolute verdict. --RR */ 184 must return an absolute verdict. --RR */
185 switch (reject->with) { 185 switch (reject->with) {
186 case IP6T_ICMP6_NO_ROUTE: 186 case IP6T_ICMP6_NO_ROUTE:
187 send_unreach(skb, ICMPV6_NOROUTE, hooknum); 187 send_unreach(net, skb, ICMPV6_NOROUTE, par->hooknum);
188 break; 188 break;
189 case IP6T_ICMP6_ADM_PROHIBITED: 189 case IP6T_ICMP6_ADM_PROHIBITED:
190 send_unreach(skb, ICMPV6_ADM_PROHIBITED, hooknum); 190 send_unreach(net, skb, ICMPV6_ADM_PROHIBITED, par->hooknum);
191 break; 191 break;
192 case IP6T_ICMP6_NOT_NEIGHBOUR: 192 case IP6T_ICMP6_NOT_NEIGHBOUR:
193 send_unreach(skb, ICMPV6_NOT_NEIGHBOUR, hooknum); 193 send_unreach(net, skb, ICMPV6_NOT_NEIGHBOUR, par->hooknum);
194 break; 194 break;
195 case IP6T_ICMP6_ADDR_UNREACH: 195 case IP6T_ICMP6_ADDR_UNREACH:
196 send_unreach(skb, ICMPV6_ADDR_UNREACH, hooknum); 196 send_unreach(net, skb, ICMPV6_ADDR_UNREACH, par->hooknum);
197 break; 197 break;
198 case IP6T_ICMP6_PORT_UNREACH: 198 case IP6T_ICMP6_PORT_UNREACH:
199 send_unreach(skb, ICMPV6_PORT_UNREACH, hooknum); 199 send_unreach(net, skb, ICMPV6_PORT_UNREACH, par->hooknum);
200 break; 200 break;
201 case IP6T_ICMP6_ECHOREPLY: 201 case IP6T_ICMP6_ECHOREPLY:
202 /* Do nothing */ 202 /* Do nothing */
203 break; 203 break;
204 case IP6T_TCP_RESET: 204 case IP6T_TCP_RESET:
205 send_reset(skb); 205 send_reset(net, skb);
206 break; 206 break;
207 default: 207 default:
208 if (net_ratelimit()) 208 if (net_ratelimit())
@@ -213,13 +213,10 @@ reject_tg6(struct sk_buff *skb, const struct net_device *in,
213 return NF_DROP; 213 return NF_DROP;
214} 214}
215 215
216static bool 216static bool reject_tg6_check(const struct xt_tgchk_param *par)
217reject_tg6_check(const char *tablename, const void *entry,
218 const struct xt_target *target, void *targinfo,
219 unsigned int hook_mask)
220{ 217{
221 const struct ip6t_reject_info *rejinfo = targinfo; 218 const struct ip6t_reject_info *rejinfo = par->targinfo;
222 const struct ip6t_entry *e = entry; 219 const struct ip6t_entry *e = par->entryinfo;
223 220
224 if (rejinfo->with == IP6T_ICMP6_ECHOREPLY) { 221 if (rejinfo->with == IP6T_ICMP6_ECHOREPLY) {
225 printk("ip6t_REJECT: ECHOREPLY is not supported.\n"); 222 printk("ip6t_REJECT: ECHOREPLY is not supported.\n");
@@ -237,7 +234,7 @@ reject_tg6_check(const char *tablename, const void *entry,
237 234
238static struct xt_target reject_tg6_reg __read_mostly = { 235static struct xt_target reject_tg6_reg __read_mostly = {
239 .name = "REJECT", 236 .name = "REJECT",
240 .family = AF_INET6, 237 .family = NFPROTO_IPV6,
241 .target = reject_tg6, 238 .target = reject_tg6,
242 .targetsize = sizeof(struct ip6t_reject_info), 239 .targetsize = sizeof(struct ip6t_reject_info),
243 .table = "filter", 240 .table = "filter",
diff --git a/net/ipv6/netfilter/ip6t_ah.c b/net/ipv6/netfilter/ip6t_ah.c
index 429629fd63b6..3a82f24746b9 100644
--- a/net/ipv6/netfilter/ip6t_ah.c
+++ b/net/ipv6/netfilter/ip6t_ah.c
@@ -36,14 +36,11 @@ spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, bool invert)
36 return r; 36 return r;
37} 37}
38 38
39static bool 39static bool ah_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
40ah_mt6(const struct sk_buff *skb, const struct net_device *in,
41 const struct net_device *out, const struct xt_match *match,
42 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
43{ 40{
44 struct ip_auth_hdr _ah; 41 struct ip_auth_hdr _ah;
45 const struct ip_auth_hdr *ah; 42 const struct ip_auth_hdr *ah;
46 const struct ip6t_ah *ahinfo = matchinfo; 43 const struct ip6t_ah *ahinfo = par->matchinfo;
47 unsigned int ptr; 44 unsigned int ptr;
48 unsigned int hdrlen = 0; 45 unsigned int hdrlen = 0;
49 int err; 46 int err;
@@ -51,13 +48,13 @@ ah_mt6(const struct sk_buff *skb, const struct net_device *in,
51 err = ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH, NULL); 48 err = ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH, NULL);
52 if (err < 0) { 49 if (err < 0) {
53 if (err != -ENOENT) 50 if (err != -ENOENT)
54 *hotdrop = true; 51 *par->hotdrop = true;
55 return false; 52 return false;
56 } 53 }
57 54
58 ah = skb_header_pointer(skb, ptr, sizeof(_ah), &_ah); 55 ah = skb_header_pointer(skb, ptr, sizeof(_ah), &_ah);
59 if (ah == NULL) { 56 if (ah == NULL) {
60 *hotdrop = true; 57 *par->hotdrop = true;
61 return false; 58 return false;
62 } 59 }
63 60
@@ -93,13 +90,9 @@ ah_mt6(const struct sk_buff *skb, const struct net_device *in,
93 !(ahinfo->hdrres && ah->reserved); 90 !(ahinfo->hdrres && ah->reserved);
94} 91}
95 92
96/* Called when user tries to insert an entry of this type. */ 93static bool ah_mt6_check(const struct xt_mtchk_param *par)
97static bool
98ah_mt6_check(const char *tablename, const void *entry,
99 const struct xt_match *match, void *matchinfo,
100 unsigned int hook_mask)
101{ 94{
102 const struct ip6t_ah *ahinfo = matchinfo; 95 const struct ip6t_ah *ahinfo = par->matchinfo;
103 96
104 if (ahinfo->invflags & ~IP6T_AH_INV_MASK) { 97 if (ahinfo->invflags & ~IP6T_AH_INV_MASK) {
105 pr_debug("ip6t_ah: unknown flags %X\n", ahinfo->invflags); 98 pr_debug("ip6t_ah: unknown flags %X\n", ahinfo->invflags);
@@ -110,7 +103,7 @@ ah_mt6_check(const char *tablename, const void *entry,
110 103
111static struct xt_match ah_mt6_reg __read_mostly = { 104static struct xt_match ah_mt6_reg __read_mostly = {
112 .name = "ah", 105 .name = "ah",
113 .family = AF_INET6, 106 .family = NFPROTO_IPV6,
114 .match = ah_mt6, 107 .match = ah_mt6,
115 .matchsize = sizeof(struct ip6t_ah), 108 .matchsize = sizeof(struct ip6t_ah),
116 .checkentry = ah_mt6_check, 109 .checkentry = ah_mt6_check,
diff --git a/net/ipv6/netfilter/ip6t_eui64.c b/net/ipv6/netfilter/ip6t_eui64.c
index 8f331f12b2ec..db610bacbcce 100644
--- a/net/ipv6/netfilter/ip6t_eui64.c
+++ b/net/ipv6/netfilter/ip6t_eui64.c
@@ -20,18 +20,15 @@ MODULE_LICENSE("GPL");
20MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>"); 20MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
21 21
22static bool 22static bool
23eui64_mt6(const struct sk_buff *skb, const struct net_device *in, 23eui64_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
24 const struct net_device *out, const struct xt_match *match,
25 const void *matchinfo, int offset, unsigned int protoff,
26 bool *hotdrop)
27{ 24{
28 unsigned char eui64[8]; 25 unsigned char eui64[8];
29 int i = 0; 26 int i = 0;
30 27
31 if (!(skb_mac_header(skb) >= skb->head && 28 if (!(skb_mac_header(skb) >= skb->head &&
32 skb_mac_header(skb) + ETH_HLEN <= skb->data) && 29 skb_mac_header(skb) + ETH_HLEN <= skb->data) &&
33 offset != 0) { 30 par->fragoff != 0) {
34 *hotdrop = true; 31 *par->hotdrop = true;
35 return false; 32 return false;
36 } 33 }
37 34
@@ -60,7 +57,7 @@ eui64_mt6(const struct sk_buff *skb, const struct net_device *in,
60 57
61static struct xt_match eui64_mt6_reg __read_mostly = { 58static struct xt_match eui64_mt6_reg __read_mostly = {
62 .name = "eui64", 59 .name = "eui64",
63 .family = AF_INET6, 60 .family = NFPROTO_IPV6,
64 .match = eui64_mt6, 61 .match = eui64_mt6,
65 .matchsize = sizeof(int), 62 .matchsize = sizeof(int),
66 .hooks = (1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_IN) | 63 .hooks = (1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_IN) |
diff --git a/net/ipv6/netfilter/ip6t_frag.c b/net/ipv6/netfilter/ip6t_frag.c
index e2bbc63dba5b..673aa0a5084e 100644
--- a/net/ipv6/netfilter/ip6t_frag.c
+++ b/net/ipv6/netfilter/ip6t_frag.c
@@ -35,27 +35,24 @@ id_match(u_int32_t min, u_int32_t max, u_int32_t id, bool invert)
35} 35}
36 36
37static bool 37static bool
38frag_mt6(const struct sk_buff *skb, const struct net_device *in, 38frag_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
39 const struct net_device *out, const struct xt_match *match,
40 const void *matchinfo, int offset, unsigned int protoff,
41 bool *hotdrop)
42{ 39{
43 struct frag_hdr _frag; 40 struct frag_hdr _frag;
44 const struct frag_hdr *fh; 41 const struct frag_hdr *fh;
45 const struct ip6t_frag *fraginfo = matchinfo; 42 const struct ip6t_frag *fraginfo = par->matchinfo;
46 unsigned int ptr; 43 unsigned int ptr;
47 int err; 44 int err;
48 45
49 err = ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT, NULL); 46 err = ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT, NULL);
50 if (err < 0) { 47 if (err < 0) {
51 if (err != -ENOENT) 48 if (err != -ENOENT)
52 *hotdrop = true; 49 *par->hotdrop = true;
53 return false; 50 return false;
54 } 51 }
55 52
56 fh = skb_header_pointer(skb, ptr, sizeof(_frag), &_frag); 53 fh = skb_header_pointer(skb, ptr, sizeof(_frag), &_frag);
57 if (fh == NULL) { 54 if (fh == NULL) {
58 *hotdrop = true; 55 *par->hotdrop = true;
59 return false; 56 return false;
60 } 57 }
61 58
@@ -110,13 +107,9 @@ frag_mt6(const struct sk_buff *skb, const struct net_device *in,
110 && (ntohs(fh->frag_off) & IP6_MF)); 107 && (ntohs(fh->frag_off) & IP6_MF));
111} 108}
112 109
113/* Called when user tries to insert an entry of this type. */ 110static bool frag_mt6_check(const struct xt_mtchk_param *par)
114static bool
115frag_mt6_check(const char *tablename, const void *ip,
116 const struct xt_match *match, void *matchinfo,
117 unsigned int hook_mask)
118{ 111{
119 const struct ip6t_frag *fraginfo = matchinfo; 112 const struct ip6t_frag *fraginfo = par->matchinfo;
120 113
121 if (fraginfo->invflags & ~IP6T_FRAG_INV_MASK) { 114 if (fraginfo->invflags & ~IP6T_FRAG_INV_MASK) {
122 pr_debug("ip6t_frag: unknown flags %X\n", fraginfo->invflags); 115 pr_debug("ip6t_frag: unknown flags %X\n", fraginfo->invflags);
@@ -127,7 +120,7 @@ frag_mt6_check(const char *tablename, const void *ip,
127 120
128static struct xt_match frag_mt6_reg __read_mostly = { 121static struct xt_match frag_mt6_reg __read_mostly = {
129 .name = "frag", 122 .name = "frag",
130 .family = AF_INET6, 123 .family = NFPROTO_IPV6,
131 .match = frag_mt6, 124 .match = frag_mt6,
132 .matchsize = sizeof(struct ip6t_frag), 125 .matchsize = sizeof(struct ip6t_frag),
133 .checkentry = frag_mt6_check, 126 .checkentry = frag_mt6_check,
diff --git a/net/ipv6/netfilter/ip6t_hbh.c b/net/ipv6/netfilter/ip6t_hbh.c
index 26654b26d7fa..cbe8dec9744b 100644
--- a/net/ipv6/netfilter/ip6t_hbh.c
+++ b/net/ipv6/netfilter/ip6t_hbh.c
@@ -42,14 +42,11 @@ MODULE_ALIAS("ip6t_dst");
42 */ 42 */
43 43
44static bool 44static bool
45hbh_mt6(const struct sk_buff *skb, const struct net_device *in, 45hbh_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
46 const struct net_device *out, const struct xt_match *match,
47 const void *matchinfo, int offset, unsigned int protoff,
48 bool *hotdrop)
49{ 46{
50 struct ipv6_opt_hdr _optsh; 47 struct ipv6_opt_hdr _optsh;
51 const struct ipv6_opt_hdr *oh; 48 const struct ipv6_opt_hdr *oh;
52 const struct ip6t_opts *optinfo = matchinfo; 49 const struct ip6t_opts *optinfo = par->matchinfo;
53 unsigned int temp; 50 unsigned int temp;
54 unsigned int ptr; 51 unsigned int ptr;
55 unsigned int hdrlen = 0; 52 unsigned int hdrlen = 0;
@@ -61,16 +58,16 @@ hbh_mt6(const struct sk_buff *skb, const struct net_device *in,
61 unsigned int optlen; 58 unsigned int optlen;
62 int err; 59 int err;
63 60
64 err = ipv6_find_hdr(skb, &ptr, match->data, NULL); 61 err = ipv6_find_hdr(skb, &ptr, par->match->data, NULL);
65 if (err < 0) { 62 if (err < 0) {
66 if (err != -ENOENT) 63 if (err != -ENOENT)
67 *hotdrop = true; 64 *par->hotdrop = true;
68 return false; 65 return false;
69 } 66 }
70 67
71 oh = skb_header_pointer(skb, ptr, sizeof(_optsh), &_optsh); 68 oh = skb_header_pointer(skb, ptr, sizeof(_optsh), &_optsh);
72 if (oh == NULL) { 69 if (oh == NULL) {
73 *hotdrop = true; 70 *par->hotdrop = true;
74 return false; 71 return false;
75 } 72 }
76 73
@@ -163,13 +160,9 @@ hbh_mt6(const struct sk_buff *skb, const struct net_device *in,
163 return false; 160 return false;
164} 161}
165 162
166/* Called when user tries to insert an entry of this type. */ 163static bool hbh_mt6_check(const struct xt_mtchk_param *par)
167static bool
168hbh_mt6_check(const char *tablename, const void *entry,
169 const struct xt_match *match, void *matchinfo,
170 unsigned int hook_mask)
171{ 164{
172 const struct ip6t_opts *optsinfo = matchinfo; 165 const struct ip6t_opts *optsinfo = par->matchinfo;
173 166
174 if (optsinfo->invflags & ~IP6T_OPTS_INV_MASK) { 167 if (optsinfo->invflags & ~IP6T_OPTS_INV_MASK) {
175 pr_debug("ip6t_opts: unknown flags %X\n", optsinfo->invflags); 168 pr_debug("ip6t_opts: unknown flags %X\n", optsinfo->invflags);
@@ -187,7 +180,7 @@ hbh_mt6_check(const char *tablename, const void *entry,
187static struct xt_match hbh_mt6_reg[] __read_mostly = { 180static struct xt_match hbh_mt6_reg[] __read_mostly = {
188 { 181 {
189 .name = "hbh", 182 .name = "hbh",
190 .family = AF_INET6, 183 .family = NFPROTO_IPV6,
191 .match = hbh_mt6, 184 .match = hbh_mt6,
192 .matchsize = sizeof(struct ip6t_opts), 185 .matchsize = sizeof(struct ip6t_opts),
193 .checkentry = hbh_mt6_check, 186 .checkentry = hbh_mt6_check,
@@ -196,7 +189,7 @@ static struct xt_match hbh_mt6_reg[] __read_mostly = {
196 }, 189 },
197 { 190 {
198 .name = "dst", 191 .name = "dst",
199 .family = AF_INET6, 192 .family = NFPROTO_IPV6,
200 .match = hbh_mt6, 193 .match = hbh_mt6,
201 .matchsize = sizeof(struct ip6t_opts), 194 .matchsize = sizeof(struct ip6t_opts),
202 .checkentry = hbh_mt6_check, 195 .checkentry = hbh_mt6_check,
diff --git a/net/ipv6/netfilter/ip6t_hl.c b/net/ipv6/netfilter/ip6t_hl.c
index 345671673845..c964dca1132d 100644
--- a/net/ipv6/netfilter/ip6t_hl.c
+++ b/net/ipv6/netfilter/ip6t_hl.c
@@ -19,12 +19,9 @@ MODULE_AUTHOR("Maciej Soltysiak <solt@dns.toxicfilms.tv>");
19MODULE_DESCRIPTION("Xtables: IPv6 Hop Limit field match"); 19MODULE_DESCRIPTION("Xtables: IPv6 Hop Limit field match");
20MODULE_LICENSE("GPL"); 20MODULE_LICENSE("GPL");
21 21
22static bool 22static bool hl_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
23hl_mt6(const struct sk_buff *skb, const struct net_device *in,
24 const struct net_device *out, const struct xt_match *match,
25 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
26{ 23{
27 const struct ip6t_hl_info *info = matchinfo; 24 const struct ip6t_hl_info *info = par->matchinfo;
28 const struct ipv6hdr *ip6h = ipv6_hdr(skb); 25 const struct ipv6hdr *ip6h = ipv6_hdr(skb);
29 26
30 switch (info->mode) { 27 switch (info->mode) {
@@ -51,7 +48,7 @@ hl_mt6(const struct sk_buff *skb, const struct net_device *in,
51 48
52static struct xt_match hl_mt6_reg __read_mostly = { 49static struct xt_match hl_mt6_reg __read_mostly = {
53 .name = "hl", 50 .name = "hl",
54 .family = AF_INET6, 51 .family = NFPROTO_IPV6,
55 .match = hl_mt6, 52 .match = hl_mt6,
56 .matchsize = sizeof(struct ip6t_hl_info), 53 .matchsize = sizeof(struct ip6t_hl_info),
57 .me = THIS_MODULE, 54 .me = THIS_MODULE,
diff --git a/net/ipv6/netfilter/ip6t_ipv6header.c b/net/ipv6/netfilter/ip6t_ipv6header.c
index 317a8960a757..14e6724d5672 100644
--- a/net/ipv6/netfilter/ip6t_ipv6header.c
+++ b/net/ipv6/netfilter/ip6t_ipv6header.c
@@ -27,12 +27,9 @@ MODULE_DESCRIPTION("Xtables: IPv6 header types match");
27MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>"); 27MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
28 28
29static bool 29static bool
30ipv6header_mt6(const struct sk_buff *skb, const struct net_device *in, 30ipv6header_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
31 const struct net_device *out, const struct xt_match *match,
32 const void *matchinfo, int offset, unsigned int protoff,
33 bool *hotdrop)
34{ 31{
35 const struct ip6t_ipv6header_info *info = matchinfo; 32 const struct ip6t_ipv6header_info *info = par->matchinfo;
36 unsigned int temp; 33 unsigned int temp;
37 int len; 34 int len;
38 u8 nexthdr; 35 u8 nexthdr;
@@ -121,12 +118,9 @@ ipv6header_mt6(const struct sk_buff *skb, const struct net_device *in,
121 } 118 }
122} 119}
123 120
124static bool 121static bool ipv6header_mt6_check(const struct xt_mtchk_param *par)
125ipv6header_mt6_check(const char *tablename, const void *ip,
126 const struct xt_match *match, void *matchinfo,
127 unsigned int hook_mask)
128{ 122{
129 const struct ip6t_ipv6header_info *info = matchinfo; 123 const struct ip6t_ipv6header_info *info = par->matchinfo;
130 124
131 /* invflags is 0 or 0xff in hard mode */ 125 /* invflags is 0 or 0xff in hard mode */
132 if ((!info->modeflag) && info->invflags != 0x00 && 126 if ((!info->modeflag) && info->invflags != 0x00 &&
@@ -138,7 +132,7 @@ ipv6header_mt6_check(const char *tablename, const void *ip,
138 132
139static struct xt_match ipv6header_mt6_reg __read_mostly = { 133static struct xt_match ipv6header_mt6_reg __read_mostly = {
140 .name = "ipv6header", 134 .name = "ipv6header",
141 .family = AF_INET6, 135 .family = NFPROTO_IPV6,
142 .match = ipv6header_mt6, 136 .match = ipv6header_mt6,
143 .matchsize = sizeof(struct ip6t_ipv6header_info), 137 .matchsize = sizeof(struct ip6t_ipv6header_info),
144 .checkentry = ipv6header_mt6_check, 138 .checkentry = ipv6header_mt6_check,
diff --git a/net/ipv6/netfilter/ip6t_mh.c b/net/ipv6/netfilter/ip6t_mh.c
index e06678d07ec8..aafe4e66577b 100644
--- a/net/ipv6/netfilter/ip6t_mh.c
+++ b/net/ipv6/netfilter/ip6t_mh.c
@@ -37,32 +37,29 @@ type_match(u_int8_t min, u_int8_t max, u_int8_t type, bool invert)
37 return (type >= min && type <= max) ^ invert; 37 return (type >= min && type <= max) ^ invert;
38} 38}
39 39
40static bool 40static bool mh_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
41mh_mt6(const struct sk_buff *skb, const struct net_device *in,
42 const struct net_device *out, const struct xt_match *match,
43 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
44{ 41{
45 struct ip6_mh _mh; 42 struct ip6_mh _mh;
46 const struct ip6_mh *mh; 43 const struct ip6_mh *mh;
47 const struct ip6t_mh *mhinfo = matchinfo; 44 const struct ip6t_mh *mhinfo = par->matchinfo;
48 45
49 /* Must not be a fragment. */ 46 /* Must not be a fragment. */
50 if (offset) 47 if (par->fragoff != 0)
51 return false; 48 return false;
52 49
53 mh = skb_header_pointer(skb, protoff, sizeof(_mh), &_mh); 50 mh = skb_header_pointer(skb, par->thoff, sizeof(_mh), &_mh);
54 if (mh == NULL) { 51 if (mh == NULL) {
55 /* We've been asked to examine this packet, and we 52 /* We've been asked to examine this packet, and we
56 can't. Hence, no choice but to drop. */ 53 can't. Hence, no choice but to drop. */
57 duprintf("Dropping evil MH tinygram.\n"); 54 duprintf("Dropping evil MH tinygram.\n");
58 *hotdrop = true; 55 *par->hotdrop = true;
59 return false; 56 return false;
60 } 57 }
61 58
62 if (mh->ip6mh_proto != IPPROTO_NONE) { 59 if (mh->ip6mh_proto != IPPROTO_NONE) {
63 duprintf("Dropping invalid MH Payload Proto: %u\n", 60 duprintf("Dropping invalid MH Payload Proto: %u\n",
64 mh->ip6mh_proto); 61 mh->ip6mh_proto);
65 *hotdrop = true; 62 *par->hotdrop = true;
66 return false; 63 return false;
67 } 64 }
68 65
@@ -70,13 +67,9 @@ mh_mt6(const struct sk_buff *skb, const struct net_device *in,
70 !!(mhinfo->invflags & IP6T_MH_INV_TYPE)); 67 !!(mhinfo->invflags & IP6T_MH_INV_TYPE));
71} 68}
72 69
73/* Called when user tries to insert an entry of this type. */ 70static bool mh_mt6_check(const struct xt_mtchk_param *par)
74static bool
75mh_mt6_check(const char *tablename, const void *entry,
76 const struct xt_match *match, void *matchinfo,
77 unsigned int hook_mask)
78{ 71{
79 const struct ip6t_mh *mhinfo = matchinfo; 72 const struct ip6t_mh *mhinfo = par->matchinfo;
80 73
81 /* Must specify no unknown invflags */ 74 /* Must specify no unknown invflags */
82 return !(mhinfo->invflags & ~IP6T_MH_INV_MASK); 75 return !(mhinfo->invflags & ~IP6T_MH_INV_MASK);
@@ -84,7 +77,7 @@ mh_mt6_check(const char *tablename, const void *entry,
84 77
85static struct xt_match mh_mt6_reg __read_mostly = { 78static struct xt_match mh_mt6_reg __read_mostly = {
86 .name = "mh", 79 .name = "mh",
87 .family = AF_INET6, 80 .family = NFPROTO_IPV6,
88 .checkentry = mh_mt6_check, 81 .checkentry = mh_mt6_check,
89 .match = mh_mt6, 82 .match = mh_mt6,
90 .matchsize = sizeof(struct ip6t_mh), 83 .matchsize = sizeof(struct ip6t_mh),
diff --git a/net/ipv6/netfilter/ip6t_rt.c b/net/ipv6/netfilter/ip6t_rt.c
index 81aaf7aaaabf..356b8d6f6baa 100644
--- a/net/ipv6/netfilter/ip6t_rt.c
+++ b/net/ipv6/netfilter/ip6t_rt.c
@@ -36,14 +36,11 @@ segsleft_match(u_int32_t min, u_int32_t max, u_int32_t id, bool invert)
36 return r; 36 return r;
37} 37}
38 38
39static bool 39static bool rt_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
40rt_mt6(const struct sk_buff *skb, const struct net_device *in,
41 const struct net_device *out, const struct xt_match *match,
42 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
43{ 40{
44 struct ipv6_rt_hdr _route; 41 struct ipv6_rt_hdr _route;
45 const struct ipv6_rt_hdr *rh; 42 const struct ipv6_rt_hdr *rh;
46 const struct ip6t_rt *rtinfo = matchinfo; 43 const struct ip6t_rt *rtinfo = par->matchinfo;
47 unsigned int temp; 44 unsigned int temp;
48 unsigned int ptr; 45 unsigned int ptr;
49 unsigned int hdrlen = 0; 46 unsigned int hdrlen = 0;
@@ -55,13 +52,13 @@ rt_mt6(const struct sk_buff *skb, const struct net_device *in,
55 err = ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING, NULL); 52 err = ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING, NULL);
56 if (err < 0) { 53 if (err < 0) {
57 if (err != -ENOENT) 54 if (err != -ENOENT)
58 *hotdrop = true; 55 *par->hotdrop = true;
59 return false; 56 return false;
60 } 57 }
61 58
62 rh = skb_header_pointer(skb, ptr, sizeof(_route), &_route); 59 rh = skb_header_pointer(skb, ptr, sizeof(_route), &_route);
63 if (rh == NULL) { 60 if (rh == NULL) {
64 *hotdrop = true; 61 *par->hotdrop = true;
65 return false; 62 return false;
66 } 63 }
67 64
@@ -189,13 +186,9 @@ rt_mt6(const struct sk_buff *skb, const struct net_device *in,
189 return false; 186 return false;
190} 187}
191 188
192/* Called when user tries to insert an entry of this type. */ 189static bool rt_mt6_check(const struct xt_mtchk_param *par)
193static bool
194rt_mt6_check(const char *tablename, const void *entry,
195 const struct xt_match *match, void *matchinfo,
196 unsigned int hook_mask)
197{ 190{
198 const struct ip6t_rt *rtinfo = matchinfo; 191 const struct ip6t_rt *rtinfo = par->matchinfo;
199 192
200 if (rtinfo->invflags & ~IP6T_RT_INV_MASK) { 193 if (rtinfo->invflags & ~IP6T_RT_INV_MASK) {
201 pr_debug("ip6t_rt: unknown flags %X\n", rtinfo->invflags); 194 pr_debug("ip6t_rt: unknown flags %X\n", rtinfo->invflags);
@@ -214,7 +207,7 @@ rt_mt6_check(const char *tablename, const void *entry,
214 207
215static struct xt_match rt_mt6_reg __read_mostly = { 208static struct xt_match rt_mt6_reg __read_mostly = {
216 .name = "rt", 209 .name = "rt",
217 .family = AF_INET6, 210 .family = NFPROTO_IPV6,
218 .match = rt_mt6, 211 .match = rt_mt6,
219 .matchsize = sizeof(struct ip6t_rt), 212 .matchsize = sizeof(struct ip6t_rt),
220 .checkentry = rt_mt6_check, 213 .checkentry = rt_mt6_check,
diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c
index 55a2c290bad4..b110a8a85a14 100644
--- a/net/ipv6/netfilter/ip6table_filter.c
+++ b/net/ipv6/netfilter/ip6table_filter.c
@@ -68,7 +68,7 @@ ip6t_local_in_hook(unsigned int hook,
68 int (*okfn)(struct sk_buff *)) 68 int (*okfn)(struct sk_buff *))
69{ 69{
70 return ip6t_do_table(skb, hook, in, out, 70 return ip6t_do_table(skb, hook, in, out,
71 nf_local_in_net(in, out)->ipv6.ip6table_filter); 71 dev_net(in)->ipv6.ip6table_filter);
72} 72}
73 73
74static unsigned int 74static unsigned int
@@ -79,7 +79,7 @@ ip6t_forward_hook(unsigned int hook,
79 int (*okfn)(struct sk_buff *)) 79 int (*okfn)(struct sk_buff *))
80{ 80{
81 return ip6t_do_table(skb, hook, in, out, 81 return ip6t_do_table(skb, hook, in, out,
82 nf_forward_net(in, out)->ipv6.ip6table_filter); 82 dev_net(in)->ipv6.ip6table_filter);
83} 83}
84 84
85static unsigned int 85static unsigned int
@@ -100,7 +100,7 @@ ip6t_local_out_hook(unsigned int hook,
100#endif 100#endif
101 101
102 return ip6t_do_table(skb, hook, in, out, 102 return ip6t_do_table(skb, hook, in, out,
103 nf_local_out_net(in, out)->ipv6.ip6table_filter); 103 dev_net(out)->ipv6.ip6table_filter);
104} 104}
105 105
106static struct nf_hook_ops ip6t_ops[] __read_mostly = { 106static struct nf_hook_ops ip6t_ops[] __read_mostly = {
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c
index f405cea21a8b..d0b31b259d4d 100644
--- a/net/ipv6/netfilter/ip6table_mangle.c
+++ b/net/ipv6/netfilter/ip6table_mangle.c
@@ -67,17 +67,29 @@ static struct xt_table packet_mangler = {
67 67
68/* The work comes in here from netfilter.c. */ 68/* The work comes in here from netfilter.c. */
69static unsigned int 69static unsigned int
70ip6t_route_hook(unsigned int hook, 70ip6t_in_hook(unsigned int hook,
71 struct sk_buff *skb, 71 struct sk_buff *skb,
72 const struct net_device *in, 72 const struct net_device *in,
73 const struct net_device *out, 73 const struct net_device *out,
74 int (*okfn)(struct sk_buff *)) 74 int (*okfn)(struct sk_buff *))
75{ 75{
76 return ip6t_do_table(skb, hook, in, out, init_net.ipv6.ip6table_mangle); 76 return ip6t_do_table(skb, hook, in, out,
77 dev_net(in)->ipv6.ip6table_mangle);
77} 78}
78 79
79static unsigned int 80static unsigned int
80ip6t_local_hook(unsigned int hook, 81ip6t_post_routing_hook(unsigned int hook,
82 struct sk_buff *skb,
83 const struct net_device *in,
84 const struct net_device *out,
85 int (*okfn)(struct sk_buff *))
86{
87 return ip6t_do_table(skb, hook, in, out,
88 dev_net(out)->ipv6.ip6table_mangle);
89}
90
91static unsigned int
92ip6t_local_out_hook(unsigned int hook,
81 struct sk_buff *skb, 93 struct sk_buff *skb,
82 const struct net_device *in, 94 const struct net_device *in,
83 const struct net_device *out, 95 const struct net_device *out,
@@ -108,7 +120,8 @@ ip6t_local_hook(unsigned int hook,
108 /* flowlabel and prio (includes version, which shouldn't change either */ 120 /* flowlabel and prio (includes version, which shouldn't change either */
109 flowlabel = *((u_int32_t *)ipv6_hdr(skb)); 121 flowlabel = *((u_int32_t *)ipv6_hdr(skb));
110 122
111 ret = ip6t_do_table(skb, hook, in, out, init_net.ipv6.ip6table_mangle); 123 ret = ip6t_do_table(skb, hook, in, out,
124 dev_net(out)->ipv6.ip6table_mangle);
112 125
113 if (ret != NF_DROP && ret != NF_STOLEN 126 if (ret != NF_DROP && ret != NF_STOLEN
114 && (memcmp(&ipv6_hdr(skb)->saddr, &saddr, sizeof(saddr)) 127 && (memcmp(&ipv6_hdr(skb)->saddr, &saddr, sizeof(saddr))
@@ -122,35 +135,35 @@ ip6t_local_hook(unsigned int hook,
122 135
123static struct nf_hook_ops ip6t_ops[] __read_mostly = { 136static struct nf_hook_ops ip6t_ops[] __read_mostly = {
124 { 137 {
125 .hook = ip6t_route_hook, 138 .hook = ip6t_in_hook,
126 .owner = THIS_MODULE, 139 .owner = THIS_MODULE,
127 .pf = PF_INET6, 140 .pf = PF_INET6,
128 .hooknum = NF_INET_PRE_ROUTING, 141 .hooknum = NF_INET_PRE_ROUTING,
129 .priority = NF_IP6_PRI_MANGLE, 142 .priority = NF_IP6_PRI_MANGLE,
130 }, 143 },
131 { 144 {
132 .hook = ip6t_route_hook, 145 .hook = ip6t_in_hook,
133 .owner = THIS_MODULE, 146 .owner = THIS_MODULE,
134 .pf = PF_INET6, 147 .pf = PF_INET6,
135 .hooknum = NF_INET_LOCAL_IN, 148 .hooknum = NF_INET_LOCAL_IN,
136 .priority = NF_IP6_PRI_MANGLE, 149 .priority = NF_IP6_PRI_MANGLE,
137 }, 150 },
138 { 151 {
139 .hook = ip6t_route_hook, 152 .hook = ip6t_in_hook,
140 .owner = THIS_MODULE, 153 .owner = THIS_MODULE,
141 .pf = PF_INET6, 154 .pf = PF_INET6,
142 .hooknum = NF_INET_FORWARD, 155 .hooknum = NF_INET_FORWARD,
143 .priority = NF_IP6_PRI_MANGLE, 156 .priority = NF_IP6_PRI_MANGLE,
144 }, 157 },
145 { 158 {
146 .hook = ip6t_local_hook, 159 .hook = ip6t_local_out_hook,
147 .owner = THIS_MODULE, 160 .owner = THIS_MODULE,
148 .pf = PF_INET6, 161 .pf = PF_INET6,
149 .hooknum = NF_INET_LOCAL_OUT, 162 .hooknum = NF_INET_LOCAL_OUT,
150 .priority = NF_IP6_PRI_MANGLE, 163 .priority = NF_IP6_PRI_MANGLE,
151 }, 164 },
152 { 165 {
153 .hook = ip6t_route_hook, 166 .hook = ip6t_post_routing_hook,
154 .owner = THIS_MODULE, 167 .owner = THIS_MODULE,
155 .pf = PF_INET6, 168 .pf = PF_INET6,
156 .hooknum = NF_INET_POST_ROUTING, 169 .hooknum = NF_INET_POST_ROUTING,
diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c
index 92b91077ac29..109fab6f831a 100644
--- a/net/ipv6/netfilter/ip6table_raw.c
+++ b/net/ipv6/netfilter/ip6table_raw.c
@@ -45,25 +45,37 @@ static struct xt_table packet_raw = {
45 45
46/* The work comes in here from netfilter.c. */ 46/* The work comes in here from netfilter.c. */
47static unsigned int 47static unsigned int
48ip6t_hook(unsigned int hook, 48ip6t_pre_routing_hook(unsigned int hook,
49 struct sk_buff *skb, 49 struct sk_buff *skb,
50 const struct net_device *in, 50 const struct net_device *in,
51 const struct net_device *out, 51 const struct net_device *out,
52 int (*okfn)(struct sk_buff *)) 52 int (*okfn)(struct sk_buff *))
53{ 53{
54 return ip6t_do_table(skb, hook, in, out, init_net.ipv6.ip6table_raw); 54 return ip6t_do_table(skb, hook, in, out,
55 dev_net(in)->ipv6.ip6table_raw);
56}
57
58static unsigned int
59ip6t_local_out_hook(unsigned int hook,
60 struct sk_buff *skb,
61 const struct net_device *in,
62 const struct net_device *out,
63 int (*okfn)(struct sk_buff *))
64{
65 return ip6t_do_table(skb, hook, in, out,
66 dev_net(out)->ipv6.ip6table_raw);
55} 67}
56 68
57static struct nf_hook_ops ip6t_ops[] __read_mostly = { 69static struct nf_hook_ops ip6t_ops[] __read_mostly = {
58 { 70 {
59 .hook = ip6t_hook, 71 .hook = ip6t_pre_routing_hook,
60 .pf = PF_INET6, 72 .pf = PF_INET6,
61 .hooknum = NF_INET_PRE_ROUTING, 73 .hooknum = NF_INET_PRE_ROUTING,
62 .priority = NF_IP6_PRI_FIRST, 74 .priority = NF_IP6_PRI_FIRST,
63 .owner = THIS_MODULE, 75 .owner = THIS_MODULE,
64 }, 76 },
65 { 77 {
66 .hook = ip6t_hook, 78 .hook = ip6t_local_out_hook,
67 .pf = PF_INET6, 79 .pf = PF_INET6,
68 .hooknum = NF_INET_LOCAL_OUT, 80 .hooknum = NF_INET_LOCAL_OUT,
69 .priority = NF_IP6_PRI_FIRST, 81 .priority = NF_IP6_PRI_FIRST,
diff --git a/net/ipv6/netfilter/ip6table_security.c b/net/ipv6/netfilter/ip6table_security.c
index 6e7131036bc6..20bc52f13e43 100644
--- a/net/ipv6/netfilter/ip6table_security.c
+++ b/net/ipv6/netfilter/ip6table_security.c
@@ -72,7 +72,7 @@ ip6t_local_in_hook(unsigned int hook,
72 int (*okfn)(struct sk_buff *)) 72 int (*okfn)(struct sk_buff *))
73{ 73{
74 return ip6t_do_table(skb, hook, in, out, 74 return ip6t_do_table(skb, hook, in, out,
75 nf_local_in_net(in, out)->ipv6.ip6table_security); 75 dev_net(in)->ipv6.ip6table_security);
76} 76}
77 77
78static unsigned int 78static unsigned int
@@ -83,7 +83,7 @@ ip6t_forward_hook(unsigned int hook,
83 int (*okfn)(struct sk_buff *)) 83 int (*okfn)(struct sk_buff *))
84{ 84{
85 return ip6t_do_table(skb, hook, in, out, 85 return ip6t_do_table(skb, hook, in, out,
86 nf_forward_net(in, out)->ipv6.ip6table_security); 86 dev_net(in)->ipv6.ip6table_security);
87} 87}
88 88
89static unsigned int 89static unsigned int
@@ -95,7 +95,7 @@ ip6t_local_out_hook(unsigned int hook,
95{ 95{
96 /* TBD: handle short packets via raw socket */ 96 /* TBD: handle short packets via raw socket */
97 return ip6t_do_table(skb, hook, in, out, 97 return ip6t_do_table(skb, hook, in, out,
98 nf_local_out_net(in, out)->ipv6.ip6table_security); 98 dev_net(out)->ipv6.ip6table_security);
99} 99}
100 100
101static struct nf_hook_ops ip6t_ops[] __read_mostly = { 101static struct nf_hook_ops ip6t_ops[] __read_mostly = {
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index 85050c072abd..e91db16611d9 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -211,11 +211,10 @@ static unsigned int ipv6_defrag(unsigned int hooknum,
211 return NF_STOLEN; 211 return NF_STOLEN;
212} 212}
213 213
214static unsigned int ipv6_conntrack_in(unsigned int hooknum, 214static unsigned int __ipv6_conntrack_in(struct net *net,
215 struct sk_buff *skb, 215 unsigned int hooknum,
216 const struct net_device *in, 216 struct sk_buff *skb,
217 const struct net_device *out, 217 int (*okfn)(struct sk_buff *))
218 int (*okfn)(struct sk_buff *))
219{ 218{
220 struct sk_buff *reasm = skb->nfct_reasm; 219 struct sk_buff *reasm = skb->nfct_reasm;
221 220
@@ -225,7 +224,7 @@ static unsigned int ipv6_conntrack_in(unsigned int hooknum,
225 if (!reasm->nfct) { 224 if (!reasm->nfct) {
226 unsigned int ret; 225 unsigned int ret;
227 226
228 ret = nf_conntrack_in(PF_INET6, hooknum, reasm); 227 ret = nf_conntrack_in(net, PF_INET6, hooknum, reasm);
229 if (ret != NF_ACCEPT) 228 if (ret != NF_ACCEPT)
230 return ret; 229 return ret;
231 } 230 }
@@ -235,7 +234,16 @@ static unsigned int ipv6_conntrack_in(unsigned int hooknum,
235 return NF_ACCEPT; 234 return NF_ACCEPT;
236 } 235 }
237 236
238 return nf_conntrack_in(PF_INET6, hooknum, skb); 237 return nf_conntrack_in(net, PF_INET6, hooknum, skb);
238}
239
240static unsigned int ipv6_conntrack_in(unsigned int hooknum,
241 struct sk_buff *skb,
242 const struct net_device *in,
243 const struct net_device *out,
244 int (*okfn)(struct sk_buff *))
245{
246 return __ipv6_conntrack_in(dev_net(in), hooknum, skb, okfn);
239} 247}
240 248
241static unsigned int ipv6_conntrack_local(unsigned int hooknum, 249static unsigned int ipv6_conntrack_local(unsigned int hooknum,
@@ -250,7 +258,7 @@ static unsigned int ipv6_conntrack_local(unsigned int hooknum,
250 printk("ipv6_conntrack_local: packet too short\n"); 258 printk("ipv6_conntrack_local: packet too short\n");
251 return NF_ACCEPT; 259 return NF_ACCEPT;
252 } 260 }
253 return ipv6_conntrack_in(hooknum, skb, in, out, okfn); 261 return __ipv6_conntrack_in(dev_net(out), hooknum, skb, okfn);
254} 262}
255 263
256static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = { 264static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = {
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
index 14d47d833545..05726177903f 100644
--- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
@@ -81,7 +81,7 @@ static int icmpv6_packet(struct nf_conn *ct,
81 const struct sk_buff *skb, 81 const struct sk_buff *skb,
82 unsigned int dataoff, 82 unsigned int dataoff,
83 enum ip_conntrack_info ctinfo, 83 enum ip_conntrack_info ctinfo,
84 int pf, 84 u_int8_t pf,
85 unsigned int hooknum) 85 unsigned int hooknum)
86{ 86{
87 /* Try to delete connection immediately after all replies: 87 /* Try to delete connection immediately after all replies:
@@ -93,7 +93,7 @@ static int icmpv6_packet(struct nf_conn *ct,
93 nf_ct_kill_acct(ct, ctinfo, skb); 93 nf_ct_kill_acct(ct, ctinfo, skb);
94 } else { 94 } else {
95 atomic_inc(&ct->proto.icmp.count); 95 atomic_inc(&ct->proto.icmp.count);
96 nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, skb); 96 nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, ct);
97 nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_icmpv6_timeout); 97 nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_icmpv6_timeout);
98 } 98 }
99 99
@@ -122,7 +122,8 @@ static bool icmpv6_new(struct nf_conn *ct, const struct sk_buff *skb,
122} 122}
123 123
124static int 124static int
125icmpv6_error_message(struct sk_buff *skb, 125icmpv6_error_message(struct net *net,
126 struct sk_buff *skb,
126 unsigned int icmp6off, 127 unsigned int icmp6off,
127 enum ip_conntrack_info *ctinfo, 128 enum ip_conntrack_info *ctinfo,
128 unsigned int hooknum) 129 unsigned int hooknum)
@@ -156,7 +157,7 @@ icmpv6_error_message(struct sk_buff *skb,
156 157
157 *ctinfo = IP_CT_RELATED; 158 *ctinfo = IP_CT_RELATED;
158 159
159 h = nf_conntrack_find_get(&intuple); 160 h = nf_conntrack_find_get(net, &intuple);
160 if (!h) { 161 if (!h) {
161 pr_debug("icmpv6_error: no match\n"); 162 pr_debug("icmpv6_error: no match\n");
162 return -NF_ACCEPT; 163 return -NF_ACCEPT;
@@ -172,21 +173,21 @@ icmpv6_error_message(struct sk_buff *skb,
172} 173}
173 174
174static int 175static int
175icmpv6_error(struct sk_buff *skb, unsigned int dataoff, 176icmpv6_error(struct net *net, struct sk_buff *skb, unsigned int dataoff,
176 enum ip_conntrack_info *ctinfo, int pf, unsigned int hooknum) 177 enum ip_conntrack_info *ctinfo, u_int8_t pf, unsigned int hooknum)
177{ 178{
178 const struct icmp6hdr *icmp6h; 179 const struct icmp6hdr *icmp6h;
179 struct icmp6hdr _ih; 180 struct icmp6hdr _ih;
180 181
181 icmp6h = skb_header_pointer(skb, dataoff, sizeof(_ih), &_ih); 182 icmp6h = skb_header_pointer(skb, dataoff, sizeof(_ih), &_ih);
182 if (icmp6h == NULL) { 183 if (icmp6h == NULL) {
183 if (LOG_INVALID(IPPROTO_ICMPV6)) 184 if (LOG_INVALID(net, IPPROTO_ICMPV6))
184 nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL, 185 nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL,
185 "nf_ct_icmpv6: short packet "); 186 "nf_ct_icmpv6: short packet ");
186 return -NF_ACCEPT; 187 return -NF_ACCEPT;
187 } 188 }
188 189
189 if (nf_conntrack_checksum && hooknum == NF_INET_PRE_ROUTING && 190 if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING &&
190 nf_ip6_checksum(skb, hooknum, dataoff, IPPROTO_ICMPV6)) { 191 nf_ip6_checksum(skb, hooknum, dataoff, IPPROTO_ICMPV6)) {
191 nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL, 192 nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL,
192 "nf_ct_icmpv6: ICMPv6 checksum failed\n"); 193 "nf_ct_icmpv6: ICMPv6 checksum failed\n");
@@ -197,7 +198,7 @@ icmpv6_error(struct sk_buff *skb, unsigned int dataoff,
197 if (icmp6h->icmp6_type >= 128) 198 if (icmp6h->icmp6_type >= 128)
198 return NF_ACCEPT; 199 return NF_ACCEPT;
199 200
200 return icmpv6_error_message(skb, dataoff, ctinfo, hooknum); 201 return icmpv6_error_message(net, skb, dataoff, ctinfo, hooknum);
201} 202}
202 203
203#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) 204#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)