aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2010-02-16 14:15:13 -0500
committerDavid S. Miller <davem@davemloft.net>2010-02-16 14:15:13 -0500
commit749f621e20ab0db35a15ff730088922603c809ba (patch)
tree2684d12199b58f2b9e0c5b7e6cc0ea3f002e611a /net/ipv6
parent339c6e99853d2ef1f02ad8a313e079050a300427 (diff)
parent3e5e524ffb5fcf2447eb5dd9f8e54ad22dd9baa7 (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/ip6_tables.c158
-rw-r--r--net/ipv6/netfilter/ip6table_filter.c113
-rw-r--r--net/ipv6/netfilter/ip6table_mangle.c141
-rw-r--r--net/ipv6/netfilter/ip6table_raw.c86
-rw-r--r--net/ipv6/netfilter/ip6table_security.c109
-rw-r--r--net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c14
-rw-r--r--net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c11
-rw-r--r--net/ipv6/netfilter/nf_conntrack_reasm.c7
-rw-r--r--net/ipv6/reassembly.c4
9 files changed, 208 insertions, 435 deletions
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 8a7e0f52e177..4185099c2943 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -29,6 +29,7 @@
29#include <linux/netfilter_ipv6/ip6_tables.h> 29#include <linux/netfilter_ipv6/ip6_tables.h>
30#include <linux/netfilter/x_tables.h> 30#include <linux/netfilter/x_tables.h>
31#include <net/netfilter/nf_log.h> 31#include <net/netfilter/nf_log.h>
32#include "../../netfilter/xt_repldata.h"
32 33
33MODULE_LICENSE("GPL"); 34MODULE_LICENSE("GPL");
34MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); 35MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
@@ -67,6 +68,12 @@ do { \
67#define inline 68#define inline
68#endif 69#endif
69 70
71void *ip6t_alloc_initial_table(const struct xt_table *info)
72{
73 return xt_alloc_initial_table(ip6t, IP6T);
74}
75EXPORT_SYMBOL_GPL(ip6t_alloc_initial_table);
76
70/* 77/*
71 We keep a set of rules for each CPU, so we can avoid write-locking 78 We keep a set of rules for each CPU, so we can avoid write-locking
72 them in the softirq when updating the counters and therefore 79 them in the softirq when updating the counters and therefore
@@ -201,7 +208,7 @@ ip6t_error(struct sk_buff *skb, const struct xt_target_param *par)
201 208
202/* Performance critical - called for every packet */ 209/* Performance critical - called for every packet */
203static inline bool 210static inline bool
204do_match(struct ip6t_entry_match *m, const struct sk_buff *skb, 211do_match(const struct ip6t_entry_match *m, const struct sk_buff *skb,
205 struct xt_match_param *par) 212 struct xt_match_param *par)
206{ 213{
207 par->match = m->u.kernel.match; 214 par->match = m->u.kernel.match;
@@ -215,7 +222,7 @@ do_match(struct ip6t_entry_match *m, const struct sk_buff *skb,
215} 222}
216 223
217static inline struct ip6t_entry * 224static inline struct ip6t_entry *
218get_entry(void *base, unsigned int offset) 225get_entry(const void *base, unsigned int offset)
219{ 226{
220 return (struct ip6t_entry *)(base + offset); 227 return (struct ip6t_entry *)(base + offset);
221} 228}
@@ -229,6 +236,12 @@ static inline bool unconditional(const struct ip6t_ip6 *ipv6)
229 return memcmp(ipv6, &uncond, sizeof(uncond)) == 0; 236 return memcmp(ipv6, &uncond, sizeof(uncond)) == 0;
230} 237}
231 238
239static inline const struct ip6t_entry_target *
240ip6t_get_target_c(const struct ip6t_entry *e)
241{
242 return ip6t_get_target((struct ip6t_entry *)e);
243}
244
232#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \ 245#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
233 defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE) 246 defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
234/* This cries for unification! */ 247/* This cries for unification! */
@@ -264,11 +277,11 @@ static struct nf_loginfo trace_loginfo = {
264 277
265/* Mildly perf critical (only if packet tracing is on) */ 278/* Mildly perf critical (only if packet tracing is on) */
266static inline int 279static inline int
267get_chainname_rulenum(struct ip6t_entry *s, struct ip6t_entry *e, 280get_chainname_rulenum(const struct ip6t_entry *s, const struct ip6t_entry *e,
268 const char *hookname, const char **chainname, 281 const char *hookname, const char **chainname,
269 const char **comment, unsigned int *rulenum) 282 const char **comment, unsigned int *rulenum)
270{ 283{
271 struct ip6t_standard_target *t = (void *)ip6t_get_target(s); 284 const struct ip6t_standard_target *t = (void *)ip6t_get_target_c(s);
272 285
273 if (strcmp(t->target.u.kernel.target->name, IP6T_ERROR_TARGET) == 0) { 286 if (strcmp(t->target.u.kernel.target->name, IP6T_ERROR_TARGET) == 0) {
274 /* Head of user chain: ERROR target with chainname */ 287 /* Head of user chain: ERROR target with chainname */
@@ -294,15 +307,15 @@ get_chainname_rulenum(struct ip6t_entry *s, struct ip6t_entry *e,
294 return 0; 307 return 0;
295} 308}
296 309
297static void trace_packet(struct sk_buff *skb, 310static void trace_packet(const struct sk_buff *skb,
298 unsigned int hook, 311 unsigned int hook,
299 const struct net_device *in, 312 const struct net_device *in,
300 const struct net_device *out, 313 const struct net_device *out,
301 const char *tablename, 314 const char *tablename,
302 struct xt_table_info *private, 315 const struct xt_table_info *private,
303 struct ip6t_entry *e) 316 const struct ip6t_entry *e)
304{ 317{
305 void *table_base; 318 const void *table_base;
306 const struct ip6t_entry *root; 319 const struct ip6t_entry *root;
307 const char *hookname, *chainname, *comment; 320 const char *hookname, *chainname, *comment;
308 unsigned int rulenum = 0; 321 unsigned int rulenum = 0;
@@ -345,9 +358,9 @@ ip6t_do_table(struct sk_buff *skb,
345 /* Initializing verdict to NF_DROP keeps gcc happy. */ 358 /* Initializing verdict to NF_DROP keeps gcc happy. */
346 unsigned int verdict = NF_DROP; 359 unsigned int verdict = NF_DROP;
347 const char *indev, *outdev; 360 const char *indev, *outdev;
348 void *table_base; 361 const void *table_base;
349 struct ip6t_entry *e, *back; 362 struct ip6t_entry *e, *back;
350 struct xt_table_info *private; 363 const struct xt_table_info *private;
351 struct xt_match_param mtpar; 364 struct xt_match_param mtpar;
352 struct xt_target_param tgpar; 365 struct xt_target_param tgpar;
353 366
@@ -378,7 +391,7 @@ ip6t_do_table(struct sk_buff *skb,
378 back = get_entry(table_base, private->underflow[hook]); 391 back = get_entry(table_base, private->underflow[hook]);
379 392
380 do { 393 do {
381 struct ip6t_entry_target *t; 394 const struct ip6t_entry_target *t;
382 395
383 IP_NF_ASSERT(e); 396 IP_NF_ASSERT(e);
384 IP_NF_ASSERT(back); 397 IP_NF_ASSERT(back);
@@ -393,7 +406,7 @@ ip6t_do_table(struct sk_buff *skb,
393 ntohs(ipv6_hdr(skb)->payload_len) + 406 ntohs(ipv6_hdr(skb)->payload_len) +
394 sizeof(struct ipv6hdr), 1); 407 sizeof(struct ipv6hdr), 1);
395 408
396 t = ip6t_get_target(e); 409 t = ip6t_get_target_c(e);
397 IP_NF_ASSERT(t->u.kernel.target); 410 IP_NF_ASSERT(t->u.kernel.target);
398 411
399#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \ 412#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
@@ -475,7 +488,7 @@ ip6t_do_table(struct sk_buff *skb,
475/* Figures out from what hook each rule can be called: returns 0 if 488/* Figures out from what hook each rule can be called: returns 0 if
476 there are loops. Puts hook bitmask in comefrom. */ 489 there are loops. Puts hook bitmask in comefrom. */
477static int 490static int
478mark_source_chains(struct xt_table_info *newinfo, 491mark_source_chains(const struct xt_table_info *newinfo,
479 unsigned int valid_hooks, void *entry0) 492 unsigned int valid_hooks, void *entry0)
480{ 493{
481 unsigned int hook; 494 unsigned int hook;
@@ -493,8 +506,8 @@ mark_source_chains(struct xt_table_info *newinfo,
493 e->counters.pcnt = pos; 506 e->counters.pcnt = pos;
494 507
495 for (;;) { 508 for (;;) {
496 struct ip6t_standard_target *t 509 const struct ip6t_standard_target *t
497 = (void *)ip6t_get_target(e); 510 = (void *)ip6t_get_target_c(e);
498 int visited = e->comefrom & (1 << hook); 511 int visited = e->comefrom & (1 << hook);
499 512
500 if (e->comefrom & (1 << NF_INET_NUMHOOKS)) { 513 if (e->comefrom & (1 << NF_INET_NUMHOOKS)) {
@@ -585,13 +598,14 @@ mark_source_chains(struct xt_table_info *newinfo,
585} 598}
586 599
587static int 600static int
588cleanup_match(struct ip6t_entry_match *m, unsigned int *i) 601cleanup_match(struct ip6t_entry_match *m, struct net *net, unsigned int *i)
589{ 602{
590 struct xt_mtdtor_param par; 603 struct xt_mtdtor_param par;
591 604
592 if (i && (*i)-- == 0) 605 if (i && (*i)-- == 0)
593 return 1; 606 return 1;
594 607
608 par.net = net;
595 par.match = m->u.kernel.match; 609 par.match = m->u.kernel.match;
596 par.matchinfo = m->data; 610 par.matchinfo = m->data;
597 par.family = NFPROTO_IPV6; 611 par.family = NFPROTO_IPV6;
@@ -602,9 +616,9 @@ cleanup_match(struct ip6t_entry_match *m, unsigned int *i)
602} 616}
603 617
604static int 618static int
605check_entry(struct ip6t_entry *e, const char *name) 619check_entry(const struct ip6t_entry *e, const char *name)
606{ 620{
607 struct ip6t_entry_target *t; 621 const struct ip6t_entry_target *t;
608 622
609 if (!ip6_checkentry(&e->ipv6)) { 623 if (!ip6_checkentry(&e->ipv6)) {
610 duprintf("ip_tables: ip check failed %p %s.\n", e, name); 624 duprintf("ip_tables: ip check failed %p %s.\n", e, name);
@@ -615,7 +629,7 @@ check_entry(struct ip6t_entry *e, const char *name)
615 e->next_offset) 629 e->next_offset)
616 return -EINVAL; 630 return -EINVAL;
617 631
618 t = ip6t_get_target(e); 632 t = ip6t_get_target_c(e);
619 if (e->target_offset + t->u.target_size > e->next_offset) 633 if (e->target_offset + t->u.target_size > e->next_offset)
620 return -EINVAL; 634 return -EINVAL;
621 635
@@ -668,10 +682,11 @@ err:
668 return ret; 682 return ret;
669} 683}
670 684
671static int check_target(struct ip6t_entry *e, const char *name) 685static int check_target(struct ip6t_entry *e, struct net *net, const char *name)
672{ 686{
673 struct ip6t_entry_target *t = ip6t_get_target(e); 687 struct ip6t_entry_target *t = ip6t_get_target(e);
674 struct xt_tgchk_param par = { 688 struct xt_tgchk_param par = {
689 .net = net,
675 .table = name, 690 .table = name,
676 .entryinfo = e, 691 .entryinfo = e,
677 .target = t->u.kernel.target, 692 .target = t->u.kernel.target,
@@ -693,8 +708,8 @@ static int check_target(struct ip6t_entry *e, const char *name)
693} 708}
694 709
695static int 710static int
696find_check_entry(struct ip6t_entry *e, const char *name, unsigned int size, 711find_check_entry(struct ip6t_entry *e, struct net *net, const char *name,
697 unsigned int *i) 712 unsigned int size, unsigned int *i)
698{ 713{
699 struct ip6t_entry_target *t; 714 struct ip6t_entry_target *t;
700 struct xt_target *target; 715 struct xt_target *target;
@@ -707,6 +722,7 @@ find_check_entry(struct ip6t_entry *e, const char *name, unsigned int size,
707 return ret; 722 return ret;
708 723
709 j = 0; 724 j = 0;
725 mtpar.net = net;
710 mtpar.table = name; 726 mtpar.table = name;
711 mtpar.entryinfo = &e->ipv6; 727 mtpar.entryinfo = &e->ipv6;
712 mtpar.hook_mask = e->comefrom; 728 mtpar.hook_mask = e->comefrom;
@@ -727,7 +743,7 @@ find_check_entry(struct ip6t_entry *e, const char *name, unsigned int size,
727 } 743 }
728 t->u.kernel.target = target; 744 t->u.kernel.target = target;
729 745
730 ret = check_target(e, name); 746 ret = check_target(e, net, name);
731 if (ret) 747 if (ret)
732 goto err; 748 goto err;
733 749
@@ -736,18 +752,18 @@ find_check_entry(struct ip6t_entry *e, const char *name, unsigned int size,
736 err: 752 err:
737 module_put(t->u.kernel.target->me); 753 module_put(t->u.kernel.target->me);
738 cleanup_matches: 754 cleanup_matches:
739 IP6T_MATCH_ITERATE(e, cleanup_match, &j); 755 IP6T_MATCH_ITERATE(e, cleanup_match, net, &j);
740 return ret; 756 return ret;
741} 757}
742 758
743static bool check_underflow(struct ip6t_entry *e) 759static bool check_underflow(const struct ip6t_entry *e)
744{ 760{
745 const struct ip6t_entry_target *t; 761 const struct ip6t_entry_target *t;
746 unsigned int verdict; 762 unsigned int verdict;
747 763
748 if (!unconditional(&e->ipv6)) 764 if (!unconditional(&e->ipv6))
749 return false; 765 return false;
750 t = ip6t_get_target(e); 766 t = ip6t_get_target_c(e);
751 if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0) 767 if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0)
752 return false; 768 return false;
753 verdict = ((struct ip6t_standard_target *)t)->verdict; 769 verdict = ((struct ip6t_standard_target *)t)->verdict;
@@ -758,8 +774,8 @@ static bool check_underflow(struct ip6t_entry *e)
758static int 774static int
759check_entry_size_and_hooks(struct ip6t_entry *e, 775check_entry_size_and_hooks(struct ip6t_entry *e,
760 struct xt_table_info *newinfo, 776 struct xt_table_info *newinfo,
761 unsigned char *base, 777 const unsigned char *base,
762 unsigned char *limit, 778 const unsigned char *limit,
763 const unsigned int *hook_entries, 779 const unsigned int *hook_entries,
764 const unsigned int *underflows, 780 const unsigned int *underflows,
765 unsigned int valid_hooks, 781 unsigned int valid_hooks,
@@ -806,7 +822,7 @@ check_entry_size_and_hooks(struct ip6t_entry *e,
806} 822}
807 823
808static int 824static int
809cleanup_entry(struct ip6t_entry *e, unsigned int *i) 825cleanup_entry(struct ip6t_entry *e, struct net *net, unsigned int *i)
810{ 826{
811 struct xt_tgdtor_param par; 827 struct xt_tgdtor_param par;
812 struct ip6t_entry_target *t; 828 struct ip6t_entry_target *t;
@@ -815,9 +831,10 @@ cleanup_entry(struct ip6t_entry *e, unsigned int *i)
815 return 1; 831 return 1;
816 832
817 /* Cleanup all matches */ 833 /* Cleanup all matches */
818 IP6T_MATCH_ITERATE(e, cleanup_match, NULL); 834 IP6T_MATCH_ITERATE(e, cleanup_match, net, NULL);
819 t = ip6t_get_target(e); 835 t = ip6t_get_target(e);
820 836
837 par.net = net;
821 par.target = t->u.kernel.target; 838 par.target = t->u.kernel.target;
822 par.targinfo = t->data; 839 par.targinfo = t->data;
823 par.family = NFPROTO_IPV6; 840 par.family = NFPROTO_IPV6;
@@ -830,7 +847,8 @@ cleanup_entry(struct ip6t_entry *e, unsigned int *i)
830/* Checks and translates the user-supplied table segment (held in 847/* Checks and translates the user-supplied table segment (held in
831 newinfo) */ 848 newinfo) */
832static int 849static int
833translate_table(const char *name, 850translate_table(struct net *net,
851 const char *name,
834 unsigned int valid_hooks, 852 unsigned int valid_hooks,
835 struct xt_table_info *newinfo, 853 struct xt_table_info *newinfo,
836 void *entry0, 854 void *entry0,
@@ -892,11 +910,11 @@ translate_table(const char *name,
892 /* Finally, each sanity check must pass */ 910 /* Finally, each sanity check must pass */
893 i = 0; 911 i = 0;
894 ret = IP6T_ENTRY_ITERATE(entry0, newinfo->size, 912 ret = IP6T_ENTRY_ITERATE(entry0, newinfo->size,
895 find_check_entry, name, size, &i); 913 find_check_entry, net, name, size, &i);
896 914
897 if (ret != 0) { 915 if (ret != 0) {
898 IP6T_ENTRY_ITERATE(entry0, newinfo->size, 916 IP6T_ENTRY_ITERATE(entry0, newinfo->size,
899 cleanup_entry, &i); 917 cleanup_entry, net, &i);
900 return ret; 918 return ret;
901 } 919 }
902 920
@@ -972,11 +990,11 @@ get_counters(const struct xt_table_info *t,
972 local_bh_enable(); 990 local_bh_enable();
973} 991}
974 992
975static struct xt_counters *alloc_counters(struct xt_table *table) 993static struct xt_counters *alloc_counters(const struct xt_table *table)
976{ 994{
977 unsigned int countersize; 995 unsigned int countersize;
978 struct xt_counters *counters; 996 struct xt_counters *counters;
979 struct xt_table_info *private = table->private; 997 const struct xt_table_info *private = table->private;
980 998
981 /* We need atomic snapshot of counters: rest doesn't change 999 /* We need atomic snapshot of counters: rest doesn't change
982 (other than comefrom, which userspace doesn't care 1000 (other than comefrom, which userspace doesn't care
@@ -994,11 +1012,11 @@ static struct xt_counters *alloc_counters(struct xt_table *table)
994 1012
995static int 1013static int
996copy_entries_to_user(unsigned int total_size, 1014copy_entries_to_user(unsigned int total_size,
997 struct xt_table *table, 1015 const struct xt_table *table,
998 void __user *userptr) 1016 void __user *userptr)
999{ 1017{
1000 unsigned int off, num; 1018 unsigned int off, num;
1001 struct ip6t_entry *e; 1019 const struct ip6t_entry *e;
1002 struct xt_counters *counters; 1020 struct xt_counters *counters;
1003 const struct xt_table_info *private = table->private; 1021 const struct xt_table_info *private = table->private;
1004 int ret = 0; 1022 int ret = 0;
@@ -1050,7 +1068,7 @@ copy_entries_to_user(unsigned int total_size,
1050 } 1068 }
1051 } 1069 }
1052 1070
1053 t = ip6t_get_target(e); 1071 t = ip6t_get_target_c(e);
1054 if (copy_to_user(userptr + off + e->target_offset 1072 if (copy_to_user(userptr + off + e->target_offset
1055 + offsetof(struct ip6t_entry_target, 1073 + offsetof(struct ip6t_entry_target,
1056 u.user.name), 1074 u.user.name),
@@ -1067,7 +1085,7 @@ copy_entries_to_user(unsigned int total_size,
1067} 1085}
1068 1086
1069#ifdef CONFIG_COMPAT 1087#ifdef CONFIG_COMPAT
1070static void compat_standard_from_user(void *dst, void *src) 1088static void compat_standard_from_user(void *dst, const void *src)
1071{ 1089{
1072 int v = *(compat_int_t *)src; 1090 int v = *(compat_int_t *)src;
1073 1091
@@ -1076,7 +1094,7 @@ static void compat_standard_from_user(void *dst, void *src)
1076 memcpy(dst, &v, sizeof(v)); 1094 memcpy(dst, &v, sizeof(v));
1077} 1095}
1078 1096
1079static int compat_standard_to_user(void __user *dst, void *src) 1097static int compat_standard_to_user(void __user *dst, const void *src)
1080{ 1098{
1081 compat_int_t cv = *(int *)src; 1099 compat_int_t cv = *(int *)src;
1082 1100
@@ -1086,24 +1104,24 @@ static int compat_standard_to_user(void __user *dst, void *src)
1086} 1104}
1087 1105
1088static inline int 1106static inline int
1089compat_calc_match(struct ip6t_entry_match *m, int *size) 1107compat_calc_match(const struct ip6t_entry_match *m, int *size)
1090{ 1108{
1091 *size += xt_compat_match_offset(m->u.kernel.match); 1109 *size += xt_compat_match_offset(m->u.kernel.match);
1092 return 0; 1110 return 0;
1093} 1111}
1094 1112
1095static int compat_calc_entry(struct ip6t_entry *e, 1113static int compat_calc_entry(const struct ip6t_entry *e,
1096 const struct xt_table_info *info, 1114 const struct xt_table_info *info,
1097 void *base, struct xt_table_info *newinfo) 1115 const void *base, struct xt_table_info *newinfo)
1098{ 1116{
1099 struct ip6t_entry_target *t; 1117 const struct ip6t_entry_target *t;
1100 unsigned int entry_offset; 1118 unsigned int entry_offset;
1101 int off, i, ret; 1119 int off, i, ret;
1102 1120
1103 off = sizeof(struct ip6t_entry) - sizeof(struct compat_ip6t_entry); 1121 off = sizeof(struct ip6t_entry) - sizeof(struct compat_ip6t_entry);
1104 entry_offset = (void *)e - base; 1122 entry_offset = (void *)e - base;
1105 IP6T_MATCH_ITERATE(e, compat_calc_match, &off); 1123 IP6T_MATCH_ITERATE(e, compat_calc_match, &off);
1106 t = ip6t_get_target(e); 1124 t = ip6t_get_target_c(e);
1107 off += xt_compat_target_offset(t->u.kernel.target); 1125 off += xt_compat_target_offset(t->u.kernel.target);
1108 newinfo->size -= off; 1126 newinfo->size -= off;
1109 ret = xt_compat_add_offset(AF_INET6, entry_offset, off); 1127 ret = xt_compat_add_offset(AF_INET6, entry_offset, off);
@@ -1139,7 +1157,8 @@ static int compat_table_info(const struct xt_table_info *info,
1139} 1157}
1140#endif 1158#endif
1141 1159
1142static int get_info(struct net *net, void __user *user, int *len, int compat) 1160static int get_info(struct net *net, void __user *user,
1161 const int *len, int compat)
1143{ 1162{
1144 char name[IP6T_TABLE_MAXNAMELEN]; 1163 char name[IP6T_TABLE_MAXNAMELEN];
1145 struct xt_table *t; 1164 struct xt_table *t;
@@ -1199,7 +1218,8 @@ static int get_info(struct net *net, void __user *user, int *len, int compat)
1199} 1218}
1200 1219
1201static int 1220static int
1202get_entries(struct net *net, struct ip6t_get_entries __user *uptr, int *len) 1221get_entries(struct net *net, struct ip6t_get_entries __user *uptr,
1222 const int *len)
1203{ 1223{
1204 int ret; 1224 int ret;
1205 struct ip6t_get_entries get; 1225 struct ip6t_get_entries get;
@@ -1291,7 +1311,7 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks,
1291 /* Decrease module usage counts and free resource */ 1311 /* Decrease module usage counts and free resource */
1292 loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()]; 1312 loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()];
1293 IP6T_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry, 1313 IP6T_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,
1294 NULL); 1314 net, NULL);
1295 xt_free_table_info(oldinfo); 1315 xt_free_table_info(oldinfo);
1296 if (copy_to_user(counters_ptr, counters, 1316 if (copy_to_user(counters_ptr, counters,
1297 sizeof(struct xt_counters) * num_counters) != 0) 1317 sizeof(struct xt_counters) * num_counters) != 0)
@@ -1310,7 +1330,7 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks,
1310} 1330}
1311 1331
1312static int 1332static int
1313do_replace(struct net *net, void __user *user, unsigned int len) 1333do_replace(struct net *net, const void __user *user, unsigned int len)
1314{ 1334{
1315 int ret; 1335 int ret;
1316 struct ip6t_replace tmp; 1336 struct ip6t_replace tmp;
@@ -1336,7 +1356,7 @@ do_replace(struct net *net, void __user *user, unsigned int len)
1336 goto free_newinfo; 1356 goto free_newinfo;
1337 } 1357 }
1338 1358
1339 ret = translate_table(tmp.name, tmp.valid_hooks, 1359 ret = translate_table(net, tmp.name, tmp.valid_hooks,
1340 newinfo, loc_cpu_entry, tmp.size, tmp.num_entries, 1360 newinfo, loc_cpu_entry, tmp.size, tmp.num_entries,
1341 tmp.hook_entry, tmp.underflow); 1361 tmp.hook_entry, tmp.underflow);
1342 if (ret != 0) 1362 if (ret != 0)
@@ -1351,7 +1371,7 @@ do_replace(struct net *net, void __user *user, unsigned int len)
1351 return 0; 1371 return 0;
1352 1372
1353 free_newinfo_untrans: 1373 free_newinfo_untrans:
1354 IP6T_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, NULL); 1374 IP6T_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, net, NULL);
1355 free_newinfo: 1375 free_newinfo:
1356 xt_free_table_info(newinfo); 1376 xt_free_table_info(newinfo);
1357 return ret; 1377 return ret;
@@ -1371,7 +1391,7 @@ add_counter_to_entry(struct ip6t_entry *e,
1371} 1391}
1372 1392
1373static int 1393static int
1374do_add_counters(struct net *net, void __user *user, unsigned int len, 1394do_add_counters(struct net *net, const void __user *user, unsigned int len,
1375 int compat) 1395 int compat)
1376{ 1396{
1377 unsigned int i, curcpu; 1397 unsigned int i, curcpu;
@@ -1570,10 +1590,10 @@ static int
1570check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e, 1590check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e,
1571 struct xt_table_info *newinfo, 1591 struct xt_table_info *newinfo,
1572 unsigned int *size, 1592 unsigned int *size,
1573 unsigned char *base, 1593 const unsigned char *base,
1574 unsigned char *limit, 1594 const unsigned char *limit,
1575 unsigned int *hook_entries, 1595 const unsigned int *hook_entries,
1576 unsigned int *underflows, 1596 const unsigned int *underflows,
1577 unsigned int *i, 1597 unsigned int *i,
1578 const char *name) 1598 const char *name)
1579{ 1599{
@@ -1690,14 +1710,15 @@ compat_copy_entry_from_user(struct compat_ip6t_entry *e, void **dstptr,
1690 return ret; 1710 return ret;
1691} 1711}
1692 1712
1693static int compat_check_entry(struct ip6t_entry *e, const char *name, 1713static int compat_check_entry(struct ip6t_entry *e, struct net *net,
1694 unsigned int *i) 1714 const char *name, unsigned int *i)
1695{ 1715{
1696 unsigned int j; 1716 unsigned int j;
1697 int ret; 1717 int ret;
1698 struct xt_mtchk_param mtpar; 1718 struct xt_mtchk_param mtpar;
1699 1719
1700 j = 0; 1720 j = 0;
1721 mtpar.net = net;
1701 mtpar.table = name; 1722 mtpar.table = name;
1702 mtpar.entryinfo = &e->ipv6; 1723 mtpar.entryinfo = &e->ipv6;
1703 mtpar.hook_mask = e->comefrom; 1724 mtpar.hook_mask = e->comefrom;
@@ -1706,7 +1727,7 @@ static int compat_check_entry(struct ip6t_entry *e, const char *name,
1706 if (ret) 1727 if (ret)
1707 goto cleanup_matches; 1728 goto cleanup_matches;
1708 1729
1709 ret = check_target(e, name); 1730 ret = check_target(e, net, name);
1710 if (ret) 1731 if (ret)
1711 goto cleanup_matches; 1732 goto cleanup_matches;
1712 1733
@@ -1714,12 +1735,13 @@ static int compat_check_entry(struct ip6t_entry *e, const char *name,
1714 return 0; 1735 return 0;
1715 1736
1716 cleanup_matches: 1737 cleanup_matches:
1717 IP6T_MATCH_ITERATE(e, cleanup_match, &j); 1738 IP6T_MATCH_ITERATE(e, cleanup_match, net, &j);
1718 return ret; 1739 return ret;
1719} 1740}
1720 1741
1721static int 1742static int
1722translate_compat_table(const char *name, 1743translate_compat_table(struct net *net,
1744 const char *name,
1723 unsigned int valid_hooks, 1745 unsigned int valid_hooks,
1724 struct xt_table_info **pinfo, 1746 struct xt_table_info **pinfo,
1725 void **pentry0, 1747 void **pentry0,
@@ -1808,12 +1830,12 @@ translate_compat_table(const char *name,
1808 1830
1809 i = 0; 1831 i = 0;
1810 ret = IP6T_ENTRY_ITERATE(entry1, newinfo->size, compat_check_entry, 1832 ret = IP6T_ENTRY_ITERATE(entry1, newinfo->size, compat_check_entry,
1811 name, &i); 1833 net, name, &i);
1812 if (ret) { 1834 if (ret) {
1813 j -= i; 1835 j -= i;
1814 COMPAT_IP6T_ENTRY_ITERATE_CONTINUE(entry0, newinfo->size, i, 1836 COMPAT_IP6T_ENTRY_ITERATE_CONTINUE(entry0, newinfo->size, i,
1815 compat_release_entry, &j); 1837 compat_release_entry, &j);
1816 IP6T_ENTRY_ITERATE(entry1, newinfo->size, cleanup_entry, &i); 1838 IP6T_ENTRY_ITERATE(entry1, newinfo->size, cleanup_entry, net, &i);
1817 xt_free_table_info(newinfo); 1839 xt_free_table_info(newinfo);
1818 return ret; 1840 return ret;
1819 } 1841 }
@@ -1868,7 +1890,7 @@ compat_do_replace(struct net *net, void __user *user, unsigned int len)
1868 goto free_newinfo; 1890 goto free_newinfo;
1869 } 1891 }
1870 1892
1871 ret = translate_compat_table(tmp.name, tmp.valid_hooks, 1893 ret = translate_compat_table(net, tmp.name, tmp.valid_hooks,
1872 &newinfo, &loc_cpu_entry, tmp.size, 1894 &newinfo, &loc_cpu_entry, tmp.size,
1873 tmp.num_entries, tmp.hook_entry, 1895 tmp.num_entries, tmp.hook_entry,
1874 tmp.underflow); 1896 tmp.underflow);
@@ -1884,7 +1906,7 @@ compat_do_replace(struct net *net, void __user *user, unsigned int len)
1884 return 0; 1906 return 0;
1885 1907
1886 free_newinfo_untrans: 1908 free_newinfo_untrans:
1887 IP6T_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, NULL); 1909 IP6T_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, net, NULL);
1888 free_newinfo: 1910 free_newinfo:
1889 xt_free_table_info(newinfo); 1911 xt_free_table_info(newinfo);
1890 return ret; 1912 return ret;
@@ -2121,7 +2143,7 @@ struct xt_table *ip6t_register_table(struct net *net,
2121 loc_cpu_entry = newinfo->entries[raw_smp_processor_id()]; 2143 loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
2122 memcpy(loc_cpu_entry, repl->entries, repl->size); 2144 memcpy(loc_cpu_entry, repl->entries, repl->size);
2123 2145
2124 ret = translate_table(table->name, table->valid_hooks, 2146 ret = translate_table(net, table->name, table->valid_hooks,
2125 newinfo, loc_cpu_entry, repl->size, 2147 newinfo, loc_cpu_entry, repl->size,
2126 repl->num_entries, 2148 repl->num_entries,
2127 repl->hook_entry, 2149 repl->hook_entry,
@@ -2142,7 +2164,7 @@ out:
2142 return ERR_PTR(ret); 2164 return ERR_PTR(ret);
2143} 2165}
2144 2166
2145void ip6t_unregister_table(struct xt_table *table) 2167void ip6t_unregister_table(struct net *net, struct xt_table *table)
2146{ 2168{
2147 struct xt_table_info *private; 2169 struct xt_table_info *private;
2148 void *loc_cpu_entry; 2170 void *loc_cpu_entry;
@@ -2152,7 +2174,7 @@ void ip6t_unregister_table(struct xt_table *table)
2152 2174
2153 /* Decrease module usage counts and free resources */ 2175 /* Decrease module usage counts and free resources */
2154 loc_cpu_entry = private->entries[raw_smp_processor_id()]; 2176 loc_cpu_entry = private->entries[raw_smp_processor_id()];
2155 IP6T_ENTRY_ITERATE(loc_cpu_entry, private->size, cleanup_entry, NULL); 2177 IP6T_ENTRY_ITERATE(loc_cpu_entry, private->size, cleanup_entry, net, NULL);
2156 if (private->number > private->initial_entries) 2178 if (private->number > private->initial_entries)
2157 module_put(table_owner); 2179 module_put(table_owner);
2158 xt_free_table_info(private); 2180 xt_free_table_info(private);
diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c
index ad378efd0eb8..36b72cafc227 100644
--- a/net/ipv6/netfilter/ip6table_filter.c
+++ b/net/ipv6/netfilter/ip6table_filter.c
@@ -21,99 +21,26 @@ MODULE_DESCRIPTION("ip6tables filter table");
21 (1 << NF_INET_FORWARD) | \ 21 (1 << NF_INET_FORWARD) | \
22 (1 << NF_INET_LOCAL_OUT)) 22 (1 << NF_INET_LOCAL_OUT))
23 23
24static struct
25{
26 struct ip6t_replace repl;
27 struct ip6t_standard entries[3];
28 struct ip6t_error term;
29} initial_table __net_initdata = {
30 .repl = {
31 .name = "filter",
32 .valid_hooks = FILTER_VALID_HOOKS,
33 .num_entries = 4,
34 .size = sizeof(struct ip6t_standard) * 3 + sizeof(struct ip6t_error),
35 .hook_entry = {
36 [NF_INET_LOCAL_IN] = 0,
37 [NF_INET_FORWARD] = sizeof(struct ip6t_standard),
38 [NF_INET_LOCAL_OUT] = sizeof(struct ip6t_standard) * 2
39 },
40 .underflow = {
41 [NF_INET_LOCAL_IN] = 0,
42 [NF_INET_FORWARD] = sizeof(struct ip6t_standard),
43 [NF_INET_LOCAL_OUT] = sizeof(struct ip6t_standard) * 2
44 },
45 },
46 .entries = {
47 IP6T_STANDARD_INIT(NF_ACCEPT), /* LOCAL_IN */
48 IP6T_STANDARD_INIT(NF_ACCEPT), /* FORWARD */
49 IP6T_STANDARD_INIT(NF_ACCEPT), /* LOCAL_OUT */
50 },
51 .term = IP6T_ERROR_INIT, /* ERROR */
52};
53
54static const struct xt_table packet_filter = { 24static const struct xt_table packet_filter = {
55 .name = "filter", 25 .name = "filter",
56 .valid_hooks = FILTER_VALID_HOOKS, 26 .valid_hooks = FILTER_VALID_HOOKS,
57 .me = THIS_MODULE, 27 .me = THIS_MODULE,
58 .af = NFPROTO_IPV6, 28 .af = NFPROTO_IPV6,
29 .priority = NF_IP6_PRI_FILTER,
59}; 30};
60 31
61/* The work comes in here from netfilter.c. */ 32/* The work comes in here from netfilter.c. */
62static unsigned int 33static unsigned int
63ip6t_in_hook(unsigned int hook, 34ip6table_filter_hook(unsigned int hook, struct sk_buff *skb,
64 struct sk_buff *skb, 35 const struct net_device *in, const struct net_device *out,
65 const struct net_device *in, 36 int (*okfn)(struct sk_buff *))
66 const struct net_device *out,
67 int (*okfn)(struct sk_buff *))
68{
69 return ip6t_do_table(skb, hook, in, out,
70 dev_net(in)->ipv6.ip6table_filter);
71}
72
73static unsigned int
74ip6t_local_out_hook(unsigned int hook,
75 struct sk_buff *skb,
76 const struct net_device *in,
77 const struct net_device *out,
78 int (*okfn)(struct sk_buff *))
79{ 37{
80#if 0 38 const struct net *net = dev_net((in != NULL) ? in : out);
81 /* root is playing with raw sockets. */
82 if (skb->len < sizeof(struct iphdr) ||
83 ip_hdrlen(skb) < sizeof(struct iphdr)) {
84 if (net_ratelimit())
85 printk("ip6t_hook: happy cracking.\n");
86 return NF_ACCEPT;
87 }
88#endif
89 39
90 return ip6t_do_table(skb, hook, in, out, 40 return ip6t_do_table(skb, hook, in, out, net->ipv6.ip6table_filter);
91 dev_net(out)->ipv6.ip6table_filter);
92} 41}
93 42
94static struct nf_hook_ops ip6t_ops[] __read_mostly = { 43static struct nf_hook_ops *filter_ops __read_mostly;
95 {
96 .hook = ip6t_in_hook,
97 .owner = THIS_MODULE,
98 .pf = NFPROTO_IPV6,
99 .hooknum = NF_INET_LOCAL_IN,
100 .priority = NF_IP6_PRI_FILTER,
101 },
102 {
103 .hook = ip6t_in_hook,
104 .owner = THIS_MODULE,
105 .pf = NFPROTO_IPV6,
106 .hooknum = NF_INET_FORWARD,
107 .priority = NF_IP6_PRI_FILTER,
108 },
109 {
110 .hook = ip6t_local_out_hook,
111 .owner = THIS_MODULE,
112 .pf = NFPROTO_IPV6,
113 .hooknum = NF_INET_LOCAL_OUT,
114 .priority = NF_IP6_PRI_FILTER,
115 },
116};
117 44
118/* Default to forward because I got too much mail already. */ 45/* Default to forward because I got too much mail already. */
119static int forward = NF_ACCEPT; 46static int forward = NF_ACCEPT;
@@ -121,9 +48,18 @@ module_param(forward, bool, 0000);
121 48
122static int __net_init ip6table_filter_net_init(struct net *net) 49static int __net_init ip6table_filter_net_init(struct net *net)
123{ 50{
124 /* Register table */ 51 struct ip6t_replace *repl;
52
53 repl = ip6t_alloc_initial_table(&packet_filter);
54 if (repl == NULL)
55 return -ENOMEM;
56 /* Entry 1 is the FORWARD hook */
57 ((struct ip6t_standard *)repl->entries)[1].target.verdict =
58 -forward - 1;
59
125 net->ipv6.ip6table_filter = 60 net->ipv6.ip6table_filter =
126 ip6t_register_table(net, &packet_filter, &initial_table.repl); 61 ip6t_register_table(net, &packet_filter, repl);
62 kfree(repl);
127 if (IS_ERR(net->ipv6.ip6table_filter)) 63 if (IS_ERR(net->ipv6.ip6table_filter))
128 return PTR_ERR(net->ipv6.ip6table_filter); 64 return PTR_ERR(net->ipv6.ip6table_filter);
129 return 0; 65 return 0;
@@ -131,7 +67,7 @@ static int __net_init ip6table_filter_net_init(struct net *net)
131 67
132static void __net_exit ip6table_filter_net_exit(struct net *net) 68static void __net_exit ip6table_filter_net_exit(struct net *net)
133{ 69{
134 ip6t_unregister_table(net->ipv6.ip6table_filter); 70 ip6t_unregister_table(net, net->ipv6.ip6table_filter);
135} 71}
136 72
137static struct pernet_operations ip6table_filter_net_ops = { 73static struct pernet_operations ip6table_filter_net_ops = {
@@ -148,17 +84,16 @@ static int __init ip6table_filter_init(void)
148 return -EINVAL; 84 return -EINVAL;
149 } 85 }
150 86
151 /* Entry 1 is the FORWARD hook */
152 initial_table.entries[1].target.verdict = -forward - 1;
153
154 ret = register_pernet_subsys(&ip6table_filter_net_ops); 87 ret = register_pernet_subsys(&ip6table_filter_net_ops);
155 if (ret < 0) 88 if (ret < 0)
156 return ret; 89 return ret;
157 90
158 /* Register hooks */ 91 /* Register hooks */
159 ret = nf_register_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); 92 filter_ops = xt_hook_link(&packet_filter, ip6table_filter_hook);
160 if (ret < 0) 93 if (IS_ERR(filter_ops)) {
94 ret = PTR_ERR(filter_ops);
161 goto cleanup_table; 95 goto cleanup_table;
96 }
162 97
163 return ret; 98 return ret;
164 99
@@ -169,7 +104,7 @@ static int __init ip6table_filter_init(void)
169 104
170static void __exit ip6table_filter_fini(void) 105static void __exit ip6table_filter_fini(void)
171{ 106{
172 nf_unregister_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); 107 xt_hook_unlink(&packet_filter, filter_ops);
173 unregister_pernet_subsys(&ip6table_filter_net_ops); 108 unregister_pernet_subsys(&ip6table_filter_net_ops);
174} 109}
175 110
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c
index a929c19d30e3..7844e557c0ec 100644
--- a/net/ipv6/netfilter/ip6table_mangle.c
+++ b/net/ipv6/netfilter/ip6table_mangle.c
@@ -21,80 +21,17 @@ MODULE_DESCRIPTION("ip6tables mangle table");
21 (1 << NF_INET_LOCAL_OUT) | \ 21 (1 << NF_INET_LOCAL_OUT) | \
22 (1 << NF_INET_POST_ROUTING)) 22 (1 << NF_INET_POST_ROUTING))
23 23
24static const struct
25{
26 struct ip6t_replace repl;
27 struct ip6t_standard entries[5];
28 struct ip6t_error term;
29} initial_table __net_initdata = {
30 .repl = {
31 .name = "mangle",
32 .valid_hooks = MANGLE_VALID_HOOKS,
33 .num_entries = 6,
34 .size = sizeof(struct ip6t_standard) * 5 + sizeof(struct ip6t_error),
35 .hook_entry = {
36 [NF_INET_PRE_ROUTING] = 0,
37 [NF_INET_LOCAL_IN] = sizeof(struct ip6t_standard),
38 [NF_INET_FORWARD] = sizeof(struct ip6t_standard) * 2,
39 [NF_INET_LOCAL_OUT] = sizeof(struct ip6t_standard) * 3,
40 [NF_INET_POST_ROUTING] = sizeof(struct ip6t_standard) * 4,
41 },
42 .underflow = {
43 [NF_INET_PRE_ROUTING] = 0,
44 [NF_INET_LOCAL_IN] = sizeof(struct ip6t_standard),
45 [NF_INET_FORWARD] = sizeof(struct ip6t_standard) * 2,
46 [NF_INET_LOCAL_OUT] = sizeof(struct ip6t_standard) * 3,
47 [NF_INET_POST_ROUTING] = sizeof(struct ip6t_standard) * 4,
48 },
49 },
50 .entries = {
51 IP6T_STANDARD_INIT(NF_ACCEPT), /* PRE_ROUTING */
52 IP6T_STANDARD_INIT(NF_ACCEPT), /* LOCAL_IN */
53 IP6T_STANDARD_INIT(NF_ACCEPT), /* FORWARD */
54 IP6T_STANDARD_INIT(NF_ACCEPT), /* LOCAL_OUT */
55 IP6T_STANDARD_INIT(NF_ACCEPT), /* POST_ROUTING */
56 },
57 .term = IP6T_ERROR_INIT, /* ERROR */
58};
59
60static const struct xt_table packet_mangler = { 24static const struct xt_table packet_mangler = {
61 .name = "mangle", 25 .name = "mangle",
62 .valid_hooks = MANGLE_VALID_HOOKS, 26 .valid_hooks = MANGLE_VALID_HOOKS,
63 .me = THIS_MODULE, 27 .me = THIS_MODULE,
64 .af = NFPROTO_IPV6, 28 .af = NFPROTO_IPV6,
29 .priority = NF_IP6_PRI_MANGLE,
65}; 30};
66 31
67/* The work comes in here from netfilter.c. */
68static unsigned int
69ip6t_in_hook(unsigned int hook,
70 struct sk_buff *skb,
71 const struct net_device *in,
72 const struct net_device *out,
73 int (*okfn)(struct sk_buff *))
74{
75 return ip6t_do_table(skb, hook, in, out,
76 dev_net(in)->ipv6.ip6table_mangle);
77}
78
79static unsigned int
80ip6t_post_routing_hook(unsigned int hook,
81 struct sk_buff *skb,
82 const struct net_device *in,
83 const struct net_device *out,
84 int (*okfn)(struct sk_buff *))
85{
86 return ip6t_do_table(skb, hook, in, out,
87 dev_net(out)->ipv6.ip6table_mangle);
88}
89
90static unsigned int 32static unsigned int
91ip6t_local_out_hook(unsigned int hook, 33ip6t_mangle_out(struct sk_buff *skb, const struct net_device *out)
92 struct sk_buff *skb,
93 const struct net_device *in,
94 const struct net_device *out,
95 int (*okfn)(struct sk_buff *))
96{ 34{
97
98 unsigned int ret; 35 unsigned int ret;
99 struct in6_addr saddr, daddr; 36 struct in6_addr saddr, daddr;
100 u_int8_t hop_limit; 37 u_int8_t hop_limit;
@@ -119,7 +56,7 @@ ip6t_local_out_hook(unsigned int hook,
119 /* flowlabel and prio (includes version, which shouldn't change either */ 56 /* flowlabel and prio (includes version, which shouldn't change either */
120 flowlabel = *((u_int32_t *)ipv6_hdr(skb)); 57 flowlabel = *((u_int32_t *)ipv6_hdr(skb));
121 58
122 ret = ip6t_do_table(skb, hook, in, out, 59 ret = ip6t_do_table(skb, NF_INET_LOCAL_OUT, NULL, out,
123 dev_net(out)->ipv6.ip6table_mangle); 60 dev_net(out)->ipv6.ip6table_mangle);
124 61
125 if (ret != NF_DROP && ret != NF_STOLEN && 62 if (ret != NF_DROP && ret != NF_STOLEN &&
@@ -132,49 +69,33 @@ ip6t_local_out_hook(unsigned int hook,
132 return ret; 69 return ret;
133} 70}
134 71
135static struct nf_hook_ops ip6t_ops[] __read_mostly = { 72/* The work comes in here from netfilter.c. */
136 { 73static unsigned int
137 .hook = ip6t_in_hook, 74ip6table_mangle_hook(unsigned int hook, struct sk_buff *skb,
138 .owner = THIS_MODULE, 75 const struct net_device *in, const struct net_device *out,
139 .pf = NFPROTO_IPV6, 76 int (*okfn)(struct sk_buff *))
140 .hooknum = NF_INET_PRE_ROUTING, 77{
141 .priority = NF_IP6_PRI_MANGLE, 78 if (hook == NF_INET_LOCAL_OUT)
142 }, 79 return ip6t_mangle_out(skb, out);
143 { 80 if (hook == NF_INET_POST_ROUTING)
144 .hook = ip6t_in_hook, 81 return ip6t_do_table(skb, hook, in, out,
145 .owner = THIS_MODULE, 82 dev_net(out)->ipv6.ip6table_mangle);
146 .pf = NFPROTO_IPV6, 83 /* INPUT/FORWARD */
147 .hooknum = NF_INET_LOCAL_IN, 84 return ip6t_do_table(skb, hook, in, out,
148 .priority = NF_IP6_PRI_MANGLE, 85 dev_net(in)->ipv6.ip6table_mangle);
149 }, 86}
150 {
151 .hook = ip6t_in_hook,
152 .owner = THIS_MODULE,
153 .pf = NFPROTO_IPV6,
154 .hooknum = NF_INET_FORWARD,
155 .priority = NF_IP6_PRI_MANGLE,
156 },
157 {
158 .hook = ip6t_local_out_hook,
159 .owner = THIS_MODULE,
160 .pf = NFPROTO_IPV6,
161 .hooknum = NF_INET_LOCAL_OUT,
162 .priority = NF_IP6_PRI_MANGLE,
163 },
164 {
165 .hook = ip6t_post_routing_hook,
166 .owner = THIS_MODULE,
167 .pf = NFPROTO_IPV6,
168 .hooknum = NF_INET_POST_ROUTING,
169 .priority = NF_IP6_PRI_MANGLE,
170 },
171};
172 87
88static struct nf_hook_ops *mangle_ops __read_mostly;
173static int __net_init ip6table_mangle_net_init(struct net *net) 89static int __net_init ip6table_mangle_net_init(struct net *net)
174{ 90{
175 /* Register table */ 91 struct ip6t_replace *repl;
92
93 repl = ip6t_alloc_initial_table(&packet_mangler);
94 if (repl == NULL)
95 return -ENOMEM;
176 net->ipv6.ip6table_mangle = 96 net->ipv6.ip6table_mangle =
177 ip6t_register_table(net, &packet_mangler, &initial_table.repl); 97 ip6t_register_table(net, &packet_mangler, repl);
98 kfree(repl);
178 if (IS_ERR(net->ipv6.ip6table_mangle)) 99 if (IS_ERR(net->ipv6.ip6table_mangle))
179 return PTR_ERR(net->ipv6.ip6table_mangle); 100 return PTR_ERR(net->ipv6.ip6table_mangle);
180 return 0; 101 return 0;
@@ -182,7 +103,7 @@ static int __net_init ip6table_mangle_net_init(struct net *net)
182 103
183static void __net_exit ip6table_mangle_net_exit(struct net *net) 104static void __net_exit ip6table_mangle_net_exit(struct net *net)
184{ 105{
185 ip6t_unregister_table(net->ipv6.ip6table_mangle); 106 ip6t_unregister_table(net, net->ipv6.ip6table_mangle);
186} 107}
187 108
188static struct pernet_operations ip6table_mangle_net_ops = { 109static struct pernet_operations ip6table_mangle_net_ops = {
@@ -199,9 +120,11 @@ static int __init ip6table_mangle_init(void)
199 return ret; 120 return ret;
200 121
201 /* Register hooks */ 122 /* Register hooks */
202 ret = nf_register_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); 123 mangle_ops = xt_hook_link(&packet_mangler, ip6table_mangle_hook);
203 if (ret < 0) 124 if (IS_ERR(mangle_ops)) {
125 ret = PTR_ERR(mangle_ops);
204 goto cleanup_table; 126 goto cleanup_table;
127 }
205 128
206 return ret; 129 return ret;
207 130
@@ -212,7 +135,7 @@ static int __init ip6table_mangle_init(void)
212 135
213static void __exit ip6table_mangle_fini(void) 136static void __exit ip6table_mangle_fini(void)
214{ 137{
215 nf_unregister_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); 138 xt_hook_unlink(&packet_mangler, mangle_ops);
216 unregister_pernet_subsys(&ip6table_mangle_net_ops); 139 unregister_pernet_subsys(&ip6table_mangle_net_ops);
217} 140}
218 141
diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c
index ed1a1180f3b3..aef31a29de9e 100644
--- a/net/ipv6/netfilter/ip6table_raw.c
+++ b/net/ipv6/netfilter/ip6table_raw.c
@@ -8,85 +8,37 @@
8 8
9#define RAW_VALID_HOOKS ((1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_OUT)) 9#define RAW_VALID_HOOKS ((1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_OUT))
10 10
11static const struct
12{
13 struct ip6t_replace repl;
14 struct ip6t_standard entries[2];
15 struct ip6t_error term;
16} initial_table __net_initdata = {
17 .repl = {
18 .name = "raw",
19 .valid_hooks = RAW_VALID_HOOKS,
20 .num_entries = 3,
21 .size = sizeof(struct ip6t_standard) * 2 + sizeof(struct ip6t_error),
22 .hook_entry = {
23 [NF_INET_PRE_ROUTING] = 0,
24 [NF_INET_LOCAL_OUT] = sizeof(struct ip6t_standard)
25 },
26 .underflow = {
27 [NF_INET_PRE_ROUTING] = 0,
28 [NF_INET_LOCAL_OUT] = sizeof(struct ip6t_standard)
29 },
30 },
31 .entries = {
32 IP6T_STANDARD_INIT(NF_ACCEPT), /* PRE_ROUTING */
33 IP6T_STANDARD_INIT(NF_ACCEPT), /* LOCAL_OUT */
34 },
35 .term = IP6T_ERROR_INIT, /* ERROR */
36};
37
38static const struct xt_table packet_raw = { 11static const struct xt_table packet_raw = {
39 .name = "raw", 12 .name = "raw",
40 .valid_hooks = RAW_VALID_HOOKS, 13 .valid_hooks = RAW_VALID_HOOKS,
41 .me = THIS_MODULE, 14 .me = THIS_MODULE,
42 .af = NFPROTO_IPV6, 15 .af = NFPROTO_IPV6,
16 .priority = NF_IP6_PRI_FIRST,
43}; 17};
44 18
45/* The work comes in here from netfilter.c. */ 19/* The work comes in here from netfilter.c. */
46static unsigned int 20static unsigned int
47ip6t_pre_routing_hook(unsigned int hook, 21ip6table_raw_hook(unsigned int hook, struct sk_buff *skb,
48 struct sk_buff *skb, 22 const struct net_device *in, const struct net_device *out,
49 const struct net_device *in, 23 int (*okfn)(struct sk_buff *))
50 const struct net_device *out,
51 int (*okfn)(struct sk_buff *))
52{ 24{
53 return ip6t_do_table(skb, hook, in, out, 25 const struct net *net = dev_net((in != NULL) ? in : out);
54 dev_net(in)->ipv6.ip6table_raw);
55}
56 26
57static unsigned int 27 return ip6t_do_table(skb, hook, in, out, net->ipv6.ip6table_raw);
58ip6t_local_out_hook(unsigned int hook,
59 struct sk_buff *skb,
60 const struct net_device *in,
61 const struct net_device *out,
62 int (*okfn)(struct sk_buff *))
63{
64 return ip6t_do_table(skb, hook, in, out,
65 dev_net(out)->ipv6.ip6table_raw);
66} 28}
67 29
68static struct nf_hook_ops ip6t_ops[] __read_mostly = { 30static struct nf_hook_ops *rawtable_ops __read_mostly;
69 {
70 .hook = ip6t_pre_routing_hook,
71 .pf = NFPROTO_IPV6,
72 .hooknum = NF_INET_PRE_ROUTING,
73 .priority = NF_IP6_PRI_FIRST,
74 .owner = THIS_MODULE,
75 },
76 {
77 .hook = ip6t_local_out_hook,
78 .pf = NFPROTO_IPV6,
79 .hooknum = NF_INET_LOCAL_OUT,
80 .priority = NF_IP6_PRI_FIRST,
81 .owner = THIS_MODULE,
82 },
83};
84 31
85static int __net_init ip6table_raw_net_init(struct net *net) 32static int __net_init ip6table_raw_net_init(struct net *net)
86{ 33{
87 /* Register table */ 34 struct ip6t_replace *repl;
35
36 repl = ip6t_alloc_initial_table(&packet_raw);
37 if (repl == NULL)
38 return -ENOMEM;
88 net->ipv6.ip6table_raw = 39 net->ipv6.ip6table_raw =
89 ip6t_register_table(net, &packet_raw, &initial_table.repl); 40 ip6t_register_table(net, &packet_raw, repl);
41 kfree(repl);
90 if (IS_ERR(net->ipv6.ip6table_raw)) 42 if (IS_ERR(net->ipv6.ip6table_raw))
91 return PTR_ERR(net->ipv6.ip6table_raw); 43 return PTR_ERR(net->ipv6.ip6table_raw);
92 return 0; 44 return 0;
@@ -94,7 +46,7 @@ static int __net_init ip6table_raw_net_init(struct net *net)
94 46
95static void __net_exit ip6table_raw_net_exit(struct net *net) 47static void __net_exit ip6table_raw_net_exit(struct net *net)
96{ 48{
97 ip6t_unregister_table(net->ipv6.ip6table_raw); 49 ip6t_unregister_table(net, net->ipv6.ip6table_raw);
98} 50}
99 51
100static struct pernet_operations ip6table_raw_net_ops = { 52static struct pernet_operations ip6table_raw_net_ops = {
@@ -111,9 +63,11 @@ static int __init ip6table_raw_init(void)
111 return ret; 63 return ret;
112 64
113 /* Register hooks */ 65 /* Register hooks */
114 ret = nf_register_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); 66 rawtable_ops = xt_hook_link(&packet_raw, ip6table_raw_hook);
115 if (ret < 0) 67 if (IS_ERR(rawtable_ops)) {
68 ret = PTR_ERR(rawtable_ops);
116 goto cleanup_table; 69 goto cleanup_table;
70 }
117 71
118 return ret; 72 return ret;
119 73
@@ -124,7 +78,7 @@ static int __init ip6table_raw_init(void)
124 78
125static void __exit ip6table_raw_fini(void) 79static void __exit ip6table_raw_fini(void)
126{ 80{
127 nf_unregister_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); 81 xt_hook_unlink(&packet_raw, rawtable_ops);
128 unregister_pernet_subsys(&ip6table_raw_net_ops); 82 unregister_pernet_subsys(&ip6table_raw_net_ops);
129} 83}
130 84
diff --git a/net/ipv6/netfilter/ip6table_security.c b/net/ipv6/netfilter/ip6table_security.c
index 41b444c60934..0824d865aa9b 100644
--- a/net/ipv6/netfilter/ip6table_security.c
+++ b/net/ipv6/netfilter/ip6table_security.c
@@ -26,106 +26,37 @@ MODULE_DESCRIPTION("ip6tables security table, for MAC rules");
26 (1 << NF_INET_FORWARD) | \ 26 (1 << NF_INET_FORWARD) | \
27 (1 << NF_INET_LOCAL_OUT) 27 (1 << NF_INET_LOCAL_OUT)
28 28
29static const struct
30{
31 struct ip6t_replace repl;
32 struct ip6t_standard entries[3];
33 struct ip6t_error term;
34} initial_table __net_initdata = {
35 .repl = {
36 .name = "security",
37 .valid_hooks = SECURITY_VALID_HOOKS,
38 .num_entries = 4,
39 .size = sizeof(struct ip6t_standard) * 3 + sizeof(struct ip6t_error),
40 .hook_entry = {
41 [NF_INET_LOCAL_IN] = 0,
42 [NF_INET_FORWARD] = sizeof(struct ip6t_standard),
43 [NF_INET_LOCAL_OUT] = sizeof(struct ip6t_standard) * 2,
44 },
45 .underflow = {
46 [NF_INET_LOCAL_IN] = 0,
47 [NF_INET_FORWARD] = sizeof(struct ip6t_standard),
48 [NF_INET_LOCAL_OUT] = sizeof(struct ip6t_standard) * 2,
49 },
50 },
51 .entries = {
52 IP6T_STANDARD_INIT(NF_ACCEPT), /* LOCAL_IN */
53 IP6T_STANDARD_INIT(NF_ACCEPT), /* FORWARD */
54 IP6T_STANDARD_INIT(NF_ACCEPT), /* LOCAL_OUT */
55 },
56 .term = IP6T_ERROR_INIT, /* ERROR */
57};
58
59static const struct xt_table security_table = { 29static const struct xt_table security_table = {
60 .name = "security", 30 .name = "security",
61 .valid_hooks = SECURITY_VALID_HOOKS, 31 .valid_hooks = SECURITY_VALID_HOOKS,
62 .me = THIS_MODULE, 32 .me = THIS_MODULE,
63 .af = NFPROTO_IPV6, 33 .af = NFPROTO_IPV6,
34 .priority = NF_IP6_PRI_SECURITY,
64}; 35};
65 36
66static unsigned int 37static unsigned int
67ip6t_local_in_hook(unsigned int hook, 38ip6table_security_hook(unsigned int hook, struct sk_buff *skb,
68 struct sk_buff *skb, 39 const struct net_device *in,
69 const struct net_device *in, 40 const struct net_device *out,
70 const struct net_device *out, 41 int (*okfn)(struct sk_buff *))
71 int (*okfn)(struct sk_buff *))
72{
73 return ip6t_do_table(skb, hook, in, out,
74 dev_net(in)->ipv6.ip6table_security);
75}
76
77static unsigned int
78ip6t_forward_hook(unsigned int hook,
79 struct sk_buff *skb,
80 const struct net_device *in,
81 const struct net_device *out,
82 int (*okfn)(struct sk_buff *))
83{ 42{
84 return ip6t_do_table(skb, hook, in, out, 43 const struct net *net = dev_net((in != NULL) ? in : out);
85 dev_net(in)->ipv6.ip6table_security);
86}
87 44
88static unsigned int 45 return ip6t_do_table(skb, hook, in, out, net->ipv6.ip6table_security);
89ip6t_local_out_hook(unsigned int hook,
90 struct sk_buff *skb,
91 const struct net_device *in,
92 const struct net_device *out,
93 int (*okfn)(struct sk_buff *))
94{
95 /* TBD: handle short packets via raw socket */
96 return ip6t_do_table(skb, hook, in, out,
97 dev_net(out)->ipv6.ip6table_security);
98} 46}
99 47
100static struct nf_hook_ops ip6t_ops[] __read_mostly = { 48static struct nf_hook_ops *sectbl_ops __read_mostly;
101 {
102 .hook = ip6t_local_in_hook,
103 .owner = THIS_MODULE,
104 .pf = NFPROTO_IPV6,
105 .hooknum = NF_INET_LOCAL_IN,
106 .priority = NF_IP6_PRI_SECURITY,
107 },
108 {
109 .hook = ip6t_forward_hook,
110 .owner = THIS_MODULE,
111 .pf = NFPROTO_IPV6,
112 .hooknum = NF_INET_FORWARD,
113 .priority = NF_IP6_PRI_SECURITY,
114 },
115 {
116 .hook = ip6t_local_out_hook,
117 .owner = THIS_MODULE,
118 .pf = NFPROTO_IPV6,
119 .hooknum = NF_INET_LOCAL_OUT,
120 .priority = NF_IP6_PRI_SECURITY,
121 },
122};
123 49
124static int __net_init ip6table_security_net_init(struct net *net) 50static int __net_init ip6table_security_net_init(struct net *net)
125{ 51{
126 net->ipv6.ip6table_security = 52 struct ip6t_replace *repl;
127 ip6t_register_table(net, &security_table, &initial_table.repl);
128 53
54 repl = ip6t_alloc_initial_table(&security_table);
55 if (repl == NULL)
56 return -ENOMEM;
57 net->ipv6.ip6table_security =
58 ip6t_register_table(net, &security_table, repl);
59 kfree(repl);
129 if (IS_ERR(net->ipv6.ip6table_security)) 60 if (IS_ERR(net->ipv6.ip6table_security))
130 return PTR_ERR(net->ipv6.ip6table_security); 61 return PTR_ERR(net->ipv6.ip6table_security);
131 62
@@ -134,7 +65,7 @@ static int __net_init ip6table_security_net_init(struct net *net)
134 65
135static void __net_exit ip6table_security_net_exit(struct net *net) 66static void __net_exit ip6table_security_net_exit(struct net *net)
136{ 67{
137 ip6t_unregister_table(net->ipv6.ip6table_security); 68 ip6t_unregister_table(net, net->ipv6.ip6table_security);
138} 69}
139 70
140static struct pernet_operations ip6table_security_net_ops = { 71static struct pernet_operations ip6table_security_net_ops = {
@@ -150,9 +81,11 @@ static int __init ip6table_security_init(void)
150 if (ret < 0) 81 if (ret < 0)
151 return ret; 82 return ret;
152 83
153 ret = nf_register_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); 84 sectbl_ops = xt_hook_link(&security_table, ip6table_security_hook);
154 if (ret < 0) 85 if (IS_ERR(sectbl_ops)) {
86 ret = PTR_ERR(sectbl_ops);
155 goto cleanup_table; 87 goto cleanup_table;
88 }
156 89
157 return ret; 90 return ret;
158 91
@@ -163,7 +96,7 @@ cleanup_table:
163 96
164static void __exit ip6table_security_fini(void) 97static void __exit ip6table_security_fini(void)
165{ 98{
166 nf_unregister_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); 99 xt_hook_unlink(&security_table, sectbl_ops);
167 unregister_pernet_subsys(&ip6table_security_net_ops); 100 unregister_pernet_subsys(&ip6table_security_net_ops);
168} 101}
169 102
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index 0956ebabbff2..996c3f41fecd 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -27,6 +27,7 @@
27#include <net/netfilter/nf_conntrack_l4proto.h> 27#include <net/netfilter/nf_conntrack_l4proto.h>
28#include <net/netfilter/nf_conntrack_l3proto.h> 28#include <net/netfilter/nf_conntrack_l3proto.h>
29#include <net/netfilter/nf_conntrack_core.h> 29#include <net/netfilter/nf_conntrack_core.h>
30#include <net/netfilter/nf_conntrack_zones.h>
30#include <net/netfilter/ipv6/nf_conntrack_ipv6.h> 31#include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
31#include <net/netfilter/nf_log.h> 32#include <net/netfilter/nf_log.h>
32 33
@@ -191,15 +192,20 @@ out:
191static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum, 192static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum,
192 struct sk_buff *skb) 193 struct sk_buff *skb)
193{ 194{
195 u16 zone = NF_CT_DEFAULT_ZONE;
196
197 if (skb->nfct)
198 zone = nf_ct_zone((struct nf_conn *)skb->nfct);
199
194#ifdef CONFIG_BRIDGE_NETFILTER 200#ifdef CONFIG_BRIDGE_NETFILTER
195 if (skb->nf_bridge && 201 if (skb->nf_bridge &&
196 skb->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING) 202 skb->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING)
197 return IP6_DEFRAG_CONNTRACK_BRIDGE_IN; 203 return IP6_DEFRAG_CONNTRACK_BRIDGE_IN + zone;
198#endif 204#endif
199 if (hooknum == NF_INET_PRE_ROUTING) 205 if (hooknum == NF_INET_PRE_ROUTING)
200 return IP6_DEFRAG_CONNTRACK_IN; 206 return IP6_DEFRAG_CONNTRACK_IN + zone;
201 else 207 else
202 return IP6_DEFRAG_CONNTRACK_OUT; 208 return IP6_DEFRAG_CONNTRACK_OUT + zone;
203 209
204} 210}
205 211
@@ -212,7 +218,7 @@ static unsigned int ipv6_defrag(unsigned int hooknum,
212 struct sk_buff *reasm; 218 struct sk_buff *reasm;
213 219
214 /* Previously seen (loopback)? */ 220 /* Previously seen (loopback)? */
215 if (skb->nfct) 221 if (skb->nfct && !nf_ct_is_template((struct nf_conn *)skb->nfct))
216 return NF_ACCEPT; 222 return NF_ACCEPT;
217 223
218 reasm = nf_ct_frag6_gather(skb, nf_ct6_defrag_user(hooknum, skb)); 224 reasm = nf_ct_frag6_gather(skb, nf_ct6_defrag_user(hooknum, skb));
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
index c7b8bd1d7984..9be81776415e 100644
--- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
@@ -23,6 +23,7 @@
23#include <net/netfilter/nf_conntrack_tuple.h> 23#include <net/netfilter/nf_conntrack_tuple.h>
24#include <net/netfilter/nf_conntrack_l4proto.h> 24#include <net/netfilter/nf_conntrack_l4proto.h>
25#include <net/netfilter/nf_conntrack_core.h> 25#include <net/netfilter/nf_conntrack_core.h>
26#include <net/netfilter/nf_conntrack_zones.h>
26#include <net/netfilter/ipv6/nf_conntrack_icmpv6.h> 27#include <net/netfilter/ipv6/nf_conntrack_icmpv6.h>
27#include <net/netfilter/nf_log.h> 28#include <net/netfilter/nf_log.h>
28 29
@@ -128,7 +129,7 @@ static bool icmpv6_new(struct nf_conn *ct, const struct sk_buff *skb,
128} 129}
129 130
130static int 131static int
131icmpv6_error_message(struct net *net, 132icmpv6_error_message(struct net *net, struct nf_conn *tmpl,
132 struct sk_buff *skb, 133 struct sk_buff *skb,
133 unsigned int icmp6off, 134 unsigned int icmp6off,
134 enum ip_conntrack_info *ctinfo, 135 enum ip_conntrack_info *ctinfo,
@@ -137,6 +138,7 @@ icmpv6_error_message(struct net *net,
137 struct nf_conntrack_tuple intuple, origtuple; 138 struct nf_conntrack_tuple intuple, origtuple;
138 const struct nf_conntrack_tuple_hash *h; 139 const struct nf_conntrack_tuple_hash *h;
139 const struct nf_conntrack_l4proto *inproto; 140 const struct nf_conntrack_l4proto *inproto;
141 u16 zone = tmpl ? nf_ct_zone(tmpl) : NF_CT_DEFAULT_ZONE;
140 142
141 NF_CT_ASSERT(skb->nfct == NULL); 143 NF_CT_ASSERT(skb->nfct == NULL);
142 144
@@ -163,7 +165,7 @@ icmpv6_error_message(struct net *net,
163 165
164 *ctinfo = IP_CT_RELATED; 166 *ctinfo = IP_CT_RELATED;
165 167
166 h = nf_conntrack_find_get(net, &intuple); 168 h = nf_conntrack_find_get(net, zone, &intuple);
167 if (!h) { 169 if (!h) {
168 pr_debug("icmpv6_error: no match\n"); 170 pr_debug("icmpv6_error: no match\n");
169 return -NF_ACCEPT; 171 return -NF_ACCEPT;
@@ -179,7 +181,8 @@ icmpv6_error_message(struct net *net,
179} 181}
180 182
181static int 183static int
182icmpv6_error(struct net *net, struct sk_buff *skb, unsigned int dataoff, 184icmpv6_error(struct net *net, struct nf_conn *tmpl,
185 struct sk_buff *skb, unsigned int dataoff,
183 enum ip_conntrack_info *ctinfo, u_int8_t pf, unsigned int hooknum) 186 enum ip_conntrack_info *ctinfo, u_int8_t pf, unsigned int hooknum)
184{ 187{
185 const struct icmp6hdr *icmp6h; 188 const struct icmp6hdr *icmp6h;
@@ -215,7 +218,7 @@ icmpv6_error(struct net *net, struct sk_buff *skb, unsigned int dataoff,
215 if (icmp6h->icmp6_type >= 128) 218 if (icmp6h->icmp6_type >= 128)
216 return NF_ACCEPT; 219 return NF_ACCEPT;
217 220
218 return icmpv6_error_message(net, skb, dataoff, ctinfo, hooknum); 221 return icmpv6_error_message(net, tmpl, skb, dataoff, ctinfo, hooknum);
219} 222}
220 223
221#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) 224#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index 624a54832a7c..ad1fcda6898b 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -45,9 +45,6 @@
45#include <linux/kernel.h> 45#include <linux/kernel.h>
46#include <linux/module.h> 46#include <linux/module.h>
47 47
48#define NF_CT_FRAG6_HIGH_THRESH 262144 /* == 256*1024 */
49#define NF_CT_FRAG6_LOW_THRESH 196608 /* == 192*1024 */
50#define NF_CT_FRAG6_TIMEOUT IPV6_FRAG_TIMEOUT
51 48
52struct nf_ct_frag6_skb_cb 49struct nf_ct_frag6_skb_cb
53{ 50{
@@ -670,8 +667,8 @@ int nf_ct_frag6_init(void)
670 nf_frags.frag_expire = nf_ct_frag6_expire; 667 nf_frags.frag_expire = nf_ct_frag6_expire;
671 nf_frags.secret_interval = 10 * 60 * HZ; 668 nf_frags.secret_interval = 10 * 60 * HZ;
672 nf_init_frags.timeout = IPV6_FRAG_TIMEOUT; 669 nf_init_frags.timeout = IPV6_FRAG_TIMEOUT;
673 nf_init_frags.high_thresh = 256 * 1024; 670 nf_init_frags.high_thresh = IPV6_FRAG_HIGH_THRESH;
674 nf_init_frags.low_thresh = 192 * 1024; 671 nf_init_frags.low_thresh = IPV6_FRAG_LOW_THRESH;
675 inet_frags_init_net(&nf_init_frags); 672 inet_frags_init_net(&nf_init_frags);
676 inet_frags_init(&nf_frags); 673 inet_frags_init(&nf_frags);
677 674
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index fe27eb4264d6..b2847ed6a7d9 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -742,8 +742,8 @@ static inline void ip6_frags_sysctl_unregister(void)
742 742
743static int __net_init ipv6_frags_init_net(struct net *net) 743static int __net_init ipv6_frags_init_net(struct net *net)
744{ 744{
745 net->ipv6.frags.high_thresh = 256 * 1024; 745 net->ipv6.frags.high_thresh = IPV6_FRAG_HIGH_THRESH;
746 net->ipv6.frags.low_thresh = 192 * 1024; 746 net->ipv6.frags.low_thresh = IPV6_FRAG_LOW_THRESH;
747 net->ipv6.frags.timeout = IPV6_FRAG_TIMEOUT; 747 net->ipv6.frags.timeout = IPV6_FRAG_TIMEOUT;
748 748
749 inet_frags_init_net(&net->ipv6.frags); 749 inet_frags_init_net(&net->ipv6.frags);