aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2010-12-09 12:17:25 -0500
committerThomas Gleixner <tglx@linutronix.de>2010-12-09 12:17:25 -0500
commitd834a9dcecae834cd6b2bc5e50e1907738d9cf6a (patch)
tree0589d753465d3fe359ba451ba6cb7798df03aaa2 /net/ipv6
parenta38c5380ef9f088be9f49b6e4c5d80af8b1b5cd4 (diff)
parentf658bcfb2607bf0808966a69cf74135ce98e5c2d (diff)
Merge branch 'x86/amd-nb' into x86/apic-cleanups
Reason: apic cleanup series depends on x86/apic, x86/amd-nb x86/platform Conflicts: arch/x86/include/asm/io_apic.h Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/addrconf.c48
-rw-r--r--net/ipv6/addrlabel.c5
-rw-r--r--net/ipv6/af_inet6.c9
-rw-r--r--net/ipv6/datagram.c19
-rw-r--r--net/ipv6/exthdrs_core.c4
-rw-r--r--net/ipv6/fib6_rules.c3
-rw-r--r--net/ipv6/ip6_fib.c9
-rw-r--r--net/ipv6/ip6_output.c6
-rw-r--r--net/ipv6/ip6_tunnel.c159
-rw-r--r--net/ipv6/ip6mr.c1
-rw-r--r--net/ipv6/ipv6_sockglue.c27
-rw-r--r--net/ipv6/ndisc.c36
-rw-r--r--net/ipv6/netfilter/Kconfig9
-rw-r--r--net/ipv6/netfilter/Makefile8
-rw-r--r--net/ipv6/netfilter/ip6_tables.c99
-rw-r--r--net/ipv6/netfilter/ip6t_LOG.c157
-rw-r--r--net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c78
-rw-r--r--net/ipv6/netfilter/nf_conntrack_reasm.c21
-rw-r--r--net/ipv6/netfilter/nf_defrag_ipv6_hooks.c131
-rw-r--r--net/ipv6/proc.c4
-rw-r--r--net/ipv6/protocol.c34
-rw-r--r--net/ipv6/raw.c14
-rw-r--r--net/ipv6/reassembly.c4
-rw-r--r--net/ipv6/route.c58
-rw-r--r--net/ipv6/sit.c166
-rw-r--r--net/ipv6/tcp_ipv6.c14
-rw-r--r--net/ipv6/tunnel6.c37
-rw-r--r--net/ipv6/udp.c18
-rw-r--r--net/ipv6/xfrm6_policy.c10
-rw-r--r--net/ipv6/xfrm6_tunnel.c8
30 files changed, 745 insertions, 451 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 324fac3b6c16..b41ce0f0d514 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -243,7 +243,7 @@ static inline bool addrconf_qdisc_ok(const struct net_device *dev)
243/* Check if a route is valid prefix route */ 243/* Check if a route is valid prefix route */
244static inline int addrconf_is_prefix_route(const struct rt6_info *rt) 244static inline int addrconf_is_prefix_route(const struct rt6_info *rt)
245{ 245{
246 return ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0); 246 return (rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0;
247} 247}
248 248
249static void addrconf_del_timer(struct inet6_ifaddr *ifp) 249static void addrconf_del_timer(struct inet6_ifaddr *ifp)
@@ -836,7 +836,7 @@ static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, struct inet6_ifaddr *i
836{ 836{
837 struct inet6_dev *idev = ifp->idev; 837 struct inet6_dev *idev = ifp->idev;
838 struct in6_addr addr, *tmpaddr; 838 struct in6_addr addr, *tmpaddr;
839 unsigned long tmp_prefered_lft, tmp_valid_lft, tmp_cstamp, tmp_tstamp; 839 unsigned long tmp_prefered_lft, tmp_valid_lft, tmp_cstamp, tmp_tstamp, age;
840 unsigned long regen_advance; 840 unsigned long regen_advance;
841 int tmp_plen; 841 int tmp_plen;
842 int ret = 0; 842 int ret = 0;
@@ -886,12 +886,13 @@ retry:
886 goto out; 886 goto out;
887 } 887 }
888 memcpy(&addr.s6_addr[8], idev->rndid, 8); 888 memcpy(&addr.s6_addr[8], idev->rndid, 8);
889 age = (jiffies - ifp->tstamp) / HZ;
889 tmp_valid_lft = min_t(__u32, 890 tmp_valid_lft = min_t(__u32,
890 ifp->valid_lft, 891 ifp->valid_lft,
891 idev->cnf.temp_valid_lft); 892 idev->cnf.temp_valid_lft + age);
892 tmp_prefered_lft = min_t(__u32, 893 tmp_prefered_lft = min_t(__u32,
893 ifp->prefered_lft, 894 ifp->prefered_lft,
894 idev->cnf.temp_prefered_lft - 895 idev->cnf.temp_prefered_lft + age -
895 idev->cnf.max_desync_factor); 896 idev->cnf.max_desync_factor);
896 tmp_plen = ifp->prefix_len; 897 tmp_plen = ifp->prefix_len;
897 max_addresses = idev->cnf.max_addresses; 898 max_addresses = idev->cnf.max_addresses;
@@ -1426,8 +1427,10 @@ void addrconf_dad_failure(struct inet6_ifaddr *ifp)
1426{ 1427{
1427 struct inet6_dev *idev = ifp->idev; 1428 struct inet6_dev *idev = ifp->idev;
1428 1429
1429 if (addrconf_dad_end(ifp)) 1430 if (addrconf_dad_end(ifp)) {
1431 in6_ifa_put(ifp);
1430 return; 1432 return;
1433 }
1431 1434
1432 if (net_ratelimit()) 1435 if (net_ratelimit())
1433 printk(KERN_INFO "%s: IPv6 duplicate address %pI6c detected!\n", 1436 printk(KERN_INFO "%s: IPv6 duplicate address %pI6c detected!\n",
@@ -1544,7 +1547,7 @@ static int addrconf_ifid_infiniband(u8 *eui, struct net_device *dev)
1544 return 0; 1547 return 0;
1545} 1548}
1546 1549
1547int __ipv6_isatap_ifid(u8 *eui, __be32 addr) 1550static int __ipv6_isatap_ifid(u8 *eui, __be32 addr)
1548{ 1551{
1549 if (addr == 0) 1552 if (addr == 0)
1550 return -1; 1553 return -1;
@@ -1560,7 +1563,6 @@ int __ipv6_isatap_ifid(u8 *eui, __be32 addr)
1560 memcpy(eui + 4, &addr, 4); 1563 memcpy(eui + 4, &addr, 4);
1561 return 0; 1564 return 0;
1562} 1565}
1563EXPORT_SYMBOL(__ipv6_isatap_ifid);
1564 1566
1565static int addrconf_ifid_sit(u8 *eui, struct net_device *dev) 1567static int addrconf_ifid_sit(u8 *eui, struct net_device *dev)
1566{ 1568{
@@ -2022,10 +2024,11 @@ ok:
2022 ipv6_ifa_notify(0, ift); 2024 ipv6_ifa_notify(0, ift);
2023 } 2025 }
2024 2026
2025 if (create && in6_dev->cnf.use_tempaddr > 0) { 2027 if ((create || list_empty(&in6_dev->tempaddr_list)) && in6_dev->cnf.use_tempaddr > 0) {
2026 /* 2028 /*
2027 * When a new public address is created as described in [ADDRCONF], 2029 * When a new public address is created as described in [ADDRCONF],
2028 * also create a new temporary address. 2030 * also create a new temporary address. Also create a temporary
2031 * address if it's enabled but no temporary address currently exists.
2029 */ 2032 */
2030 read_unlock_bh(&in6_dev->lock); 2033 read_unlock_bh(&in6_dev->lock);
2031 ipv6_create_tempaddr(ifp, NULL); 2034 ipv6_create_tempaddr(ifp, NULL);
@@ -2737,10 +2740,6 @@ static int addrconf_ifdown(struct net_device *dev, int how)
2737 /* Flag it for later restoration when link comes up */ 2740 /* Flag it for later restoration when link comes up */
2738 ifa->flags |= IFA_F_TENTATIVE; 2741 ifa->flags |= IFA_F_TENTATIVE;
2739 ifa->state = INET6_IFADDR_STATE_DAD; 2742 ifa->state = INET6_IFADDR_STATE_DAD;
2740
2741 write_unlock_bh(&idev->lock);
2742
2743 in6_ifa_hold(ifa);
2744 } else { 2743 } else {
2745 list_del(&ifa->if_list); 2744 list_del(&ifa->if_list);
2746 2745
@@ -2755,19 +2754,15 @@ static int addrconf_ifdown(struct net_device *dev, int how)
2755 ifa->state = INET6_IFADDR_STATE_DEAD; 2754 ifa->state = INET6_IFADDR_STATE_DEAD;
2756 spin_unlock_bh(&ifa->state_lock); 2755 spin_unlock_bh(&ifa->state_lock);
2757 2756
2758 if (state == INET6_IFADDR_STATE_DEAD) 2757 if (state == INET6_IFADDR_STATE_DEAD) {
2759 goto put_ifa; 2758 in6_ifa_put(ifa);
2759 } else {
2760 __ipv6_ifa_notify(RTM_DELADDR, ifa);
2761 atomic_notifier_call_chain(&inet6addr_chain,
2762 NETDEV_DOWN, ifa);
2763 }
2764 write_lock_bh(&idev->lock);
2760 } 2765 }
2761
2762 __ipv6_ifa_notify(RTM_DELADDR, ifa);
2763 if (ifa->state == INET6_IFADDR_STATE_DEAD)
2764 atomic_notifier_call_chain(&inet6addr_chain,
2765 NETDEV_DOWN, ifa);
2766
2767put_ifa:
2768 in6_ifa_put(ifa);
2769
2770 write_lock_bh(&idev->lock);
2771 } 2766 }
2772 2767
2773 list_splice(&keep_list, &idev->addr_list); 2768 list_splice(&keep_list, &idev->addr_list);
@@ -2964,7 +2959,8 @@ static void addrconf_dad_completed(struct inet6_ifaddr *ifp)
2964 start sending router solicitations. 2959 start sending router solicitations.
2965 */ 2960 */
2966 2961
2967 if (ifp->idev->cnf.forwarding == 0 && 2962 if ((ifp->idev->cnf.forwarding == 0 ||
2963 ifp->idev->cnf.forwarding == 2) &&
2968 ifp->idev->cnf.rtr_solicits > 0 && 2964 ifp->idev->cnf.rtr_solicits > 0 &&
2969 (dev->flags&IFF_LOOPBACK) == 0 && 2965 (dev->flags&IFF_LOOPBACK) == 0 &&
2970 (ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL)) { 2966 (ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL)) {
diff --git a/net/ipv6/addrlabel.c b/net/ipv6/addrlabel.c
index 8175f802651b..c8993e5a337c 100644
--- a/net/ipv6/addrlabel.c
+++ b/net/ipv6/addrlabel.c
@@ -518,10 +518,9 @@ static int ip6addrlbl_dump(struct sk_buff *skb, struct netlink_callback *cb)
518 518
519static inline int ip6addrlbl_msgsize(void) 519static inline int ip6addrlbl_msgsize(void)
520{ 520{
521 return (NLMSG_ALIGN(sizeof(struct ifaddrlblmsg)) 521 return NLMSG_ALIGN(sizeof(struct ifaddrlblmsg))
522 + nla_total_size(16) /* IFAL_ADDRESS */ 522 + nla_total_size(16) /* IFAL_ADDRESS */
523 + nla_total_size(4) /* IFAL_LABEL */ 523 + nla_total_size(4); /* IFAL_LABEL */
524 );
525} 524}
526 525
527static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr* nlh, 526static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr* nlh,
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 56b9bf2516f4..54e8e42f7a88 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -343,7 +343,8 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
343 */ 343 */
344 v4addr = LOOPBACK4_IPV6; 344 v4addr = LOOPBACK4_IPV6;
345 if (!(addr_type & IPV6_ADDR_MULTICAST)) { 345 if (!(addr_type & IPV6_ADDR_MULTICAST)) {
346 if (!ipv6_chk_addr(net, &addr->sin6_addr, 346 if (!inet->transparent &&
347 !ipv6_chk_addr(net, &addr->sin6_addr,
347 dev, 0)) { 348 dev, 0)) {
348 err = -EADDRNOTAVAIL; 349 err = -EADDRNOTAVAIL;
349 goto out_unlock; 350 goto out_unlock;
@@ -467,7 +468,7 @@ int inet6_getname(struct socket *sock, struct sockaddr *uaddr,
467 if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL) 468 if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL)
468 sin->sin6_scope_id = sk->sk_bound_dev_if; 469 sin->sin6_scope_id = sk->sk_bound_dev_if;
469 *uaddr_len = sizeof(*sin); 470 *uaddr_len = sizeof(*sin);
470 return(0); 471 return 0;
471} 472}
472 473
473EXPORT_SYMBOL(inet6_getname); 474EXPORT_SYMBOL(inet6_getname);
@@ -488,7 +489,7 @@ int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
488 case SIOCADDRT: 489 case SIOCADDRT:
489 case SIOCDELRT: 490 case SIOCDELRT:
490 491
491 return(ipv6_route_ioctl(net, cmd, (void __user *)arg)); 492 return ipv6_route_ioctl(net, cmd, (void __user *)arg);
492 493
493 case SIOCSIFADDR: 494 case SIOCSIFADDR:
494 return addrconf_add_ifaddr(net, (void __user *) arg); 495 return addrconf_add_ifaddr(net, (void __user *) arg);
@@ -502,7 +503,7 @@ int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
502 return sk->sk_prot->ioctl(sk, cmd, arg); 503 return sk->sk_prot->ioctl(sk, cmd, arg);
503 } 504 }
504 /*NOTREACHED*/ 505 /*NOTREACHED*/
505 return(0); 506 return 0;
506} 507}
507 508
508EXPORT_SYMBOL(inet6_ioctl); 509EXPORT_SYMBOL(inet6_ioctl);
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index ef371aa01ac5..320bdb877eed 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -577,6 +577,25 @@ int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
577 u8 *ptr = nh + opt->dst1; 577 u8 *ptr = nh + opt->dst1;
578 put_cmsg(msg, SOL_IPV6, IPV6_2292DSTOPTS, (ptr[1]+1)<<3, ptr); 578 put_cmsg(msg, SOL_IPV6, IPV6_2292DSTOPTS, (ptr[1]+1)<<3, ptr);
579 } 579 }
580 if (np->rxopt.bits.rxorigdstaddr) {
581 struct sockaddr_in6 sin6;
582 u16 *ports = (u16 *) skb_transport_header(skb);
583
584 if (skb_transport_offset(skb) + 4 <= skb->len) {
585 /* All current transport protocols have the port numbers in the
586 * first four bytes of the transport header and this function is
587 * written with this assumption in mind.
588 */
589
590 sin6.sin6_family = AF_INET6;
591 ipv6_addr_copy(&sin6.sin6_addr, &ipv6_hdr(skb)->daddr);
592 sin6.sin6_port = ports[1];
593 sin6.sin6_flowinfo = 0;
594 sin6.sin6_scope_id = 0;
595
596 put_cmsg(msg, SOL_IPV6, IPV6_ORIGDSTADDR, sizeof(sin6), &sin6);
597 }
598 }
580 return 0; 599 return 0;
581} 600}
582 601
diff --git a/net/ipv6/exthdrs_core.c b/net/ipv6/exthdrs_core.c
index e1caa5d526c2..14ed0a955b56 100644
--- a/net/ipv6/exthdrs_core.c
+++ b/net/ipv6/exthdrs_core.c
@@ -13,12 +13,12 @@ int ipv6_ext_hdr(u8 nexthdr)
13 /* 13 /*
14 * find out if nexthdr is an extension header or a protocol 14 * find out if nexthdr is an extension header or a protocol
15 */ 15 */
16 return ( (nexthdr == NEXTHDR_HOP) || 16 return (nexthdr == NEXTHDR_HOP) ||
17 (nexthdr == NEXTHDR_ROUTING) || 17 (nexthdr == NEXTHDR_ROUTING) ||
18 (nexthdr == NEXTHDR_FRAGMENT) || 18 (nexthdr == NEXTHDR_FRAGMENT) ||
19 (nexthdr == NEXTHDR_AUTH) || 19 (nexthdr == NEXTHDR_AUTH) ||
20 (nexthdr == NEXTHDR_NONE) || 20 (nexthdr == NEXTHDR_NONE) ||
21 (nexthdr == NEXTHDR_DEST) ); 21 (nexthdr == NEXTHDR_DEST);
22} 22}
23 23
24/* 24/*
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c
index b1108ede18e1..d829874d8946 100644
--- a/net/ipv6/fib6_rules.c
+++ b/net/ipv6/fib6_rules.c
@@ -34,11 +34,10 @@ struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi *fl,
34{ 34{
35 struct fib_lookup_arg arg = { 35 struct fib_lookup_arg arg = {
36 .lookup_ptr = lookup, 36 .lookup_ptr = lookup,
37 .flags = FIB_LOOKUP_NOREF,
37 }; 38 };
38 39
39 fib_rules_lookup(net->ipv6.fib6_rules_ops, fl, flags, &arg); 40 fib_rules_lookup(net->ipv6.fib6_rules_ops, fl, flags, &arg);
40 if (arg.rule)
41 fib_rule_put(arg.rule);
42 41
43 if (arg.result) 42 if (arg.result)
44 return arg.result; 43 return arg.result;
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index b6a585909d35..de382114609b 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -1500,15 +1500,18 @@ static void fib6_gc_timer_cb(unsigned long arg)
1500 1500
1501static int __net_init fib6_net_init(struct net *net) 1501static int __net_init fib6_net_init(struct net *net)
1502{ 1502{
1503 size_t size = sizeof(struct hlist_head) * FIB6_TABLE_HASHSZ;
1504
1503 setup_timer(&net->ipv6.ip6_fib_timer, fib6_gc_timer_cb, (unsigned long)net); 1505 setup_timer(&net->ipv6.ip6_fib_timer, fib6_gc_timer_cb, (unsigned long)net);
1504 1506
1505 net->ipv6.rt6_stats = kzalloc(sizeof(*net->ipv6.rt6_stats), GFP_KERNEL); 1507 net->ipv6.rt6_stats = kzalloc(sizeof(*net->ipv6.rt6_stats), GFP_KERNEL);
1506 if (!net->ipv6.rt6_stats) 1508 if (!net->ipv6.rt6_stats)
1507 goto out_timer; 1509 goto out_timer;
1508 1510
1509 net->ipv6.fib_table_hash = kcalloc(FIB6_TABLE_HASHSZ, 1511 /* Avoid false sharing : Use at least a full cache line */
1510 sizeof(*net->ipv6.fib_table_hash), 1512 size = max_t(size_t, size, L1_CACHE_BYTES);
1511 GFP_KERNEL); 1513
1514 net->ipv6.fib_table_hash = kzalloc(size, GFP_KERNEL);
1512 if (!net->ipv6.fib_table_hash) 1515 if (!net->ipv6.fib_table_hash)
1513 goto out_rt6_stats; 1516 goto out_rt6_stats;
1514 1517
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 980912ed7a38..99157b4cd56e 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -637,7 +637,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
637 } 637 }
638 mtu -= hlen + sizeof(struct frag_hdr); 638 mtu -= hlen + sizeof(struct frag_hdr);
639 639
640 if (skb_has_frags(skb)) { 640 if (skb_has_frag_list(skb)) {
641 int first_len = skb_pagelen(skb); 641 int first_len = skb_pagelen(skb);
642 struct sk_buff *frag2; 642 struct sk_buff *frag2;
643 643
@@ -878,8 +878,8 @@ static inline int ip6_rt_check(struct rt6key *rt_key,
878 struct in6_addr *fl_addr, 878 struct in6_addr *fl_addr,
879 struct in6_addr *addr_cache) 879 struct in6_addr *addr_cache)
880{ 880{
881 return ((rt_key->plen != 128 || !ipv6_addr_equal(fl_addr, &rt_key->addr)) && 881 return (rt_key->plen != 128 || !ipv6_addr_equal(fl_addr, &rt_key->addr)) &&
882 (addr_cache == NULL || !ipv6_addr_equal(fl_addr, addr_cache))); 882 (addr_cache == NULL || !ipv6_addr_equal(fl_addr, addr_cache));
883} 883}
884 884
885static struct dst_entry *ip6_sk_dst_check(struct sock *sk, 885static struct dst_entry *ip6_sk_dst_check(struct sock *sk,
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 0fd027f3f47e..2a59610c2a58 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -75,7 +75,7 @@ MODULE_LICENSE("GPL");
75 (addr)->s6_addr32[2] ^ (addr)->s6_addr32[3]) & \ 75 (addr)->s6_addr32[2] ^ (addr)->s6_addr32[3]) & \
76 (HASH_SIZE - 1)) 76 (HASH_SIZE - 1))
77 77
78static void ip6_tnl_dev_init(struct net_device *dev); 78static int ip6_tnl_dev_init(struct net_device *dev);
79static void ip6_tnl_dev_setup(struct net_device *dev); 79static void ip6_tnl_dev_setup(struct net_device *dev);
80 80
81static int ip6_tnl_net_id __read_mostly; 81static int ip6_tnl_net_id __read_mostly;
@@ -83,15 +83,42 @@ struct ip6_tnl_net {
83 /* the IPv6 tunnel fallback device */ 83 /* the IPv6 tunnel fallback device */
84 struct net_device *fb_tnl_dev; 84 struct net_device *fb_tnl_dev;
85 /* lists for storing tunnels in use */ 85 /* lists for storing tunnels in use */
86 struct ip6_tnl *tnls_r_l[HASH_SIZE]; 86 struct ip6_tnl __rcu *tnls_r_l[HASH_SIZE];
87 struct ip6_tnl *tnls_wc[1]; 87 struct ip6_tnl __rcu *tnls_wc[1];
88 struct ip6_tnl **tnls[2]; 88 struct ip6_tnl __rcu **tnls[2];
89}; 89};
90 90
91/* often modified stats are per cpu, other are shared (netdev->stats) */
92struct pcpu_tstats {
93 unsigned long rx_packets;
94 unsigned long rx_bytes;
95 unsigned long tx_packets;
96 unsigned long tx_bytes;
97};
98
99static struct net_device_stats *ip6_get_stats(struct net_device *dev)
100{
101 struct pcpu_tstats sum = { 0 };
102 int i;
103
104 for_each_possible_cpu(i) {
105 const struct pcpu_tstats *tstats = per_cpu_ptr(dev->tstats, i);
106
107 sum.rx_packets += tstats->rx_packets;
108 sum.rx_bytes += tstats->rx_bytes;
109 sum.tx_packets += tstats->tx_packets;
110 sum.tx_bytes += tstats->tx_bytes;
111 }
112 dev->stats.rx_packets = sum.rx_packets;
113 dev->stats.rx_bytes = sum.rx_bytes;
114 dev->stats.tx_packets = sum.tx_packets;
115 dev->stats.tx_bytes = sum.tx_bytes;
116 return &dev->stats;
117}
118
91/* 119/*
92 * Locking : hash tables are protected by RCU and a spinlock 120 * Locking : hash tables are protected by RCU and RTNL
93 */ 121 */
94static DEFINE_SPINLOCK(ip6_tnl_lock);
95 122
96static inline struct dst_entry *ip6_tnl_dst_check(struct ip6_tnl *t) 123static inline struct dst_entry *ip6_tnl_dst_check(struct ip6_tnl *t)
97{ 124{
@@ -138,8 +165,8 @@ static inline void ip6_tnl_dst_store(struct ip6_tnl *t, struct dst_entry *dst)
138static struct ip6_tnl * 165static struct ip6_tnl *
139ip6_tnl_lookup(struct net *net, struct in6_addr *remote, struct in6_addr *local) 166ip6_tnl_lookup(struct net *net, struct in6_addr *remote, struct in6_addr *local)
140{ 167{
141 unsigned h0 = HASH(remote); 168 unsigned int h0 = HASH(remote);
142 unsigned h1 = HASH(local); 169 unsigned int h1 = HASH(local);
143 struct ip6_tnl *t; 170 struct ip6_tnl *t;
144 struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); 171 struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
145 172
@@ -167,7 +194,7 @@ ip6_tnl_lookup(struct net *net, struct in6_addr *remote, struct in6_addr *local)
167 * Return: head of IPv6 tunnel list 194 * Return: head of IPv6 tunnel list
168 **/ 195 **/
169 196
170static struct ip6_tnl ** 197static struct ip6_tnl __rcu **
171ip6_tnl_bucket(struct ip6_tnl_net *ip6n, struct ip6_tnl_parm *p) 198ip6_tnl_bucket(struct ip6_tnl_net *ip6n, struct ip6_tnl_parm *p)
172{ 199{
173 struct in6_addr *remote = &p->raddr; 200 struct in6_addr *remote = &p->raddr;
@@ -190,12 +217,10 @@ ip6_tnl_bucket(struct ip6_tnl_net *ip6n, struct ip6_tnl_parm *p)
190static void 217static void
191ip6_tnl_link(struct ip6_tnl_net *ip6n, struct ip6_tnl *t) 218ip6_tnl_link(struct ip6_tnl_net *ip6n, struct ip6_tnl *t)
192{ 219{
193 struct ip6_tnl **tp = ip6_tnl_bucket(ip6n, &t->parms); 220 struct ip6_tnl __rcu **tp = ip6_tnl_bucket(ip6n, &t->parms);
194 221
195 spin_lock_bh(&ip6_tnl_lock); 222 rcu_assign_pointer(t->next , rtnl_dereference(*tp));
196 t->next = *tp;
197 rcu_assign_pointer(*tp, t); 223 rcu_assign_pointer(*tp, t);
198 spin_unlock_bh(&ip6_tnl_lock);
199} 224}
200 225
201/** 226/**
@@ -206,18 +231,25 @@ ip6_tnl_link(struct ip6_tnl_net *ip6n, struct ip6_tnl *t)
206static void 231static void
207ip6_tnl_unlink(struct ip6_tnl_net *ip6n, struct ip6_tnl *t) 232ip6_tnl_unlink(struct ip6_tnl_net *ip6n, struct ip6_tnl *t)
208{ 233{
209 struct ip6_tnl **tp; 234 struct ip6_tnl __rcu **tp;
210 235 struct ip6_tnl *iter;
211 for (tp = ip6_tnl_bucket(ip6n, &t->parms); *tp; tp = &(*tp)->next) { 236
212 if (t == *tp) { 237 for (tp = ip6_tnl_bucket(ip6n, &t->parms);
213 spin_lock_bh(&ip6_tnl_lock); 238 (iter = rtnl_dereference(*tp)) != NULL;
214 *tp = t->next; 239 tp = &iter->next) {
215 spin_unlock_bh(&ip6_tnl_lock); 240 if (t == iter) {
241 rcu_assign_pointer(*tp, t->next);
216 break; 242 break;
217 } 243 }
218 } 244 }
219} 245}
220 246
247static void ip6_dev_free(struct net_device *dev)
248{
249 free_percpu(dev->tstats);
250 free_netdev(dev);
251}
252
221/** 253/**
222 * ip6_tnl_create() - create a new tunnel 254 * ip6_tnl_create() - create a new tunnel
223 * @p: tunnel parameters 255 * @p: tunnel parameters
@@ -256,7 +288,9 @@ static struct ip6_tnl *ip6_tnl_create(struct net *net, struct ip6_tnl_parm *p)
256 288
257 t = netdev_priv(dev); 289 t = netdev_priv(dev);
258 t->parms = *p; 290 t->parms = *p;
259 ip6_tnl_dev_init(dev); 291 err = ip6_tnl_dev_init(dev);
292 if (err < 0)
293 goto failed_free;
260 294
261 if ((err = register_netdevice(dev)) < 0) 295 if ((err = register_netdevice(dev)) < 0)
262 goto failed_free; 296 goto failed_free;
@@ -266,7 +300,7 @@ static struct ip6_tnl *ip6_tnl_create(struct net *net, struct ip6_tnl_parm *p)
266 return t; 300 return t;
267 301
268failed_free: 302failed_free:
269 free_netdev(dev); 303 ip6_dev_free(dev);
270failed: 304failed:
271 return NULL; 305 return NULL;
272} 306}
@@ -290,10 +324,13 @@ static struct ip6_tnl *ip6_tnl_locate(struct net *net,
290{ 324{
291 struct in6_addr *remote = &p->raddr; 325 struct in6_addr *remote = &p->raddr;
292 struct in6_addr *local = &p->laddr; 326 struct in6_addr *local = &p->laddr;
327 struct ip6_tnl __rcu **tp;
293 struct ip6_tnl *t; 328 struct ip6_tnl *t;
294 struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); 329 struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
295 330
296 for (t = *ip6_tnl_bucket(ip6n, p); t; t = t->next) { 331 for (tp = ip6_tnl_bucket(ip6n, p);
332 (t = rtnl_dereference(*tp)) != NULL;
333 tp = &t->next) {
297 if (ipv6_addr_equal(local, &t->parms.laddr) && 334 if (ipv6_addr_equal(local, &t->parms.laddr) &&
298 ipv6_addr_equal(remote, &t->parms.raddr)) 335 ipv6_addr_equal(remote, &t->parms.raddr))
299 return t; 336 return t;
@@ -318,13 +355,10 @@ ip6_tnl_dev_uninit(struct net_device *dev)
318 struct net *net = dev_net(dev); 355 struct net *net = dev_net(dev);
319 struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); 356 struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
320 357
321 if (dev == ip6n->fb_tnl_dev) { 358 if (dev == ip6n->fb_tnl_dev)
322 spin_lock_bh(&ip6_tnl_lock); 359 rcu_assign_pointer(ip6n->tnls_wc[0], NULL);
323 ip6n->tnls_wc[0] = NULL; 360 else
324 spin_unlock_bh(&ip6_tnl_lock);
325 } else {
326 ip6_tnl_unlink(ip6n, t); 361 ip6_tnl_unlink(ip6n, t);
327 }
328 ip6_tnl_dst_reset(t); 362 ip6_tnl_dst_reset(t);
329 dev_put(dev); 363 dev_put(dev);
330} 364}
@@ -702,6 +736,8 @@ static int ip6_tnl_rcv(struct sk_buff *skb, __u16 protocol,
702 736
703 if ((t = ip6_tnl_lookup(dev_net(skb->dev), &ipv6h->saddr, 737 if ((t = ip6_tnl_lookup(dev_net(skb->dev), &ipv6h->saddr,
704 &ipv6h->daddr)) != NULL) { 738 &ipv6h->daddr)) != NULL) {
739 struct pcpu_tstats *tstats;
740
705 if (t->parms.proto != ipproto && t->parms.proto != 0) { 741 if (t->parms.proto != ipproto && t->parms.proto != 0) {
706 rcu_read_unlock(); 742 rcu_read_unlock();
707 goto discard; 743 goto discard;
@@ -724,10 +760,16 @@ static int ip6_tnl_rcv(struct sk_buff *skb, __u16 protocol,
724 skb->pkt_type = PACKET_HOST; 760 skb->pkt_type = PACKET_HOST;
725 memset(skb->cb, 0, sizeof(struct inet6_skb_parm)); 761 memset(skb->cb, 0, sizeof(struct inet6_skb_parm));
726 762
727 skb_tunnel_rx(skb, t->dev); 763 tstats = this_cpu_ptr(t->dev->tstats);
764 tstats->rx_packets++;
765 tstats->rx_bytes += skb->len;
766
767 __skb_tunnel_rx(skb, t->dev);
728 768
729 dscp_ecn_decapsulate(t, ipv6h, skb); 769 dscp_ecn_decapsulate(t, ipv6h, skb);
770
730 netif_rx(skb); 771 netif_rx(skb);
772
731 rcu_read_unlock(); 773 rcu_read_unlock();
732 return 0; 774 return 0;
733 } 775 }
@@ -934,8 +976,10 @@ static int ip6_tnl_xmit2(struct sk_buff *skb,
934 err = ip6_local_out(skb); 976 err = ip6_local_out(skb);
935 977
936 if (net_xmit_eval(err) == 0) { 978 if (net_xmit_eval(err) == 0) {
937 stats->tx_bytes += pkt_len; 979 struct pcpu_tstats *tstats = this_cpu_ptr(t->dev->tstats);
938 stats->tx_packets++; 980
981 tstats->tx_bytes += pkt_len;
982 tstats->tx_packets++;
939 } else { 983 } else {
940 stats->tx_errors++; 984 stats->tx_errors++;
941 stats->tx_aborted_errors++; 985 stats->tx_aborted_errors++;
@@ -1240,6 +1284,7 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1240 t = netdev_priv(dev); 1284 t = netdev_priv(dev);
1241 1285
1242 ip6_tnl_unlink(ip6n, t); 1286 ip6_tnl_unlink(ip6n, t);
1287 synchronize_net();
1243 err = ip6_tnl_change(t, &p); 1288 err = ip6_tnl_change(t, &p);
1244 ip6_tnl_link(ip6n, t); 1289 ip6_tnl_link(ip6n, t);
1245 netdev_state_change(dev); 1290 netdev_state_change(dev);
@@ -1300,12 +1345,14 @@ ip6_tnl_change_mtu(struct net_device *dev, int new_mtu)
1300 1345
1301 1346
1302static const struct net_device_ops ip6_tnl_netdev_ops = { 1347static const struct net_device_ops ip6_tnl_netdev_ops = {
1303 .ndo_uninit = ip6_tnl_dev_uninit, 1348 .ndo_uninit = ip6_tnl_dev_uninit,
1304 .ndo_start_xmit = ip6_tnl_xmit, 1349 .ndo_start_xmit = ip6_tnl_xmit,
1305 .ndo_do_ioctl = ip6_tnl_ioctl, 1350 .ndo_do_ioctl = ip6_tnl_ioctl,
1306 .ndo_change_mtu = ip6_tnl_change_mtu, 1351 .ndo_change_mtu = ip6_tnl_change_mtu,
1352 .ndo_get_stats = ip6_get_stats,
1307}; 1353};
1308 1354
1355
1309/** 1356/**
1310 * ip6_tnl_dev_setup - setup virtual tunnel device 1357 * ip6_tnl_dev_setup - setup virtual tunnel device
1311 * @dev: virtual device associated with tunnel 1358 * @dev: virtual device associated with tunnel
@@ -1317,7 +1364,7 @@ static const struct net_device_ops ip6_tnl_netdev_ops = {
1317static void ip6_tnl_dev_setup(struct net_device *dev) 1364static void ip6_tnl_dev_setup(struct net_device *dev)
1318{ 1365{
1319 dev->netdev_ops = &ip6_tnl_netdev_ops; 1366 dev->netdev_ops = &ip6_tnl_netdev_ops;
1320 dev->destructor = free_netdev; 1367 dev->destructor = ip6_dev_free;
1321 1368
1322 dev->type = ARPHRD_TUNNEL6; 1369 dev->type = ARPHRD_TUNNEL6;
1323 dev->hard_header_len = LL_MAX_HEADER + sizeof (struct ipv6hdr); 1370 dev->hard_header_len = LL_MAX_HEADER + sizeof (struct ipv6hdr);
@@ -1325,6 +1372,7 @@ static void ip6_tnl_dev_setup(struct net_device *dev)
1325 dev->flags |= IFF_NOARP; 1372 dev->flags |= IFF_NOARP;
1326 dev->addr_len = sizeof(struct in6_addr); 1373 dev->addr_len = sizeof(struct in6_addr);
1327 dev->features |= NETIF_F_NETNS_LOCAL; 1374 dev->features |= NETIF_F_NETNS_LOCAL;
1375 dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
1328} 1376}
1329 1377
1330 1378
@@ -1333,12 +1381,17 @@ static void ip6_tnl_dev_setup(struct net_device *dev)
1333 * @dev: virtual device associated with tunnel 1381 * @dev: virtual device associated with tunnel
1334 **/ 1382 **/
1335 1383
1336static inline void 1384static inline int
1337ip6_tnl_dev_init_gen(struct net_device *dev) 1385ip6_tnl_dev_init_gen(struct net_device *dev)
1338{ 1386{
1339 struct ip6_tnl *t = netdev_priv(dev); 1387 struct ip6_tnl *t = netdev_priv(dev);
1388
1340 t->dev = dev; 1389 t->dev = dev;
1341 strcpy(t->parms.name, dev->name); 1390 strcpy(t->parms.name, dev->name);
1391 dev->tstats = alloc_percpu(struct pcpu_tstats);
1392 if (!dev->tstats)
1393 return -ENOMEM;
1394 return 0;
1342} 1395}
1343 1396
1344/** 1397/**
@@ -1346,11 +1399,15 @@ ip6_tnl_dev_init_gen(struct net_device *dev)
1346 * @dev: virtual device associated with tunnel 1399 * @dev: virtual device associated with tunnel
1347 **/ 1400 **/
1348 1401
1349static void ip6_tnl_dev_init(struct net_device *dev) 1402static int ip6_tnl_dev_init(struct net_device *dev)
1350{ 1403{
1351 struct ip6_tnl *t = netdev_priv(dev); 1404 struct ip6_tnl *t = netdev_priv(dev);
1352 ip6_tnl_dev_init_gen(dev); 1405 int err = ip6_tnl_dev_init_gen(dev);
1406
1407 if (err)
1408 return err;
1353 ip6_tnl_link_config(t); 1409 ip6_tnl_link_config(t);
1410 return 0;
1354} 1411}
1355 1412
1356/** 1413/**
@@ -1360,25 +1417,29 @@ static void ip6_tnl_dev_init(struct net_device *dev)
1360 * Return: 0 1417 * Return: 0
1361 **/ 1418 **/
1362 1419
1363static void __net_init ip6_fb_tnl_dev_init(struct net_device *dev) 1420static int __net_init ip6_fb_tnl_dev_init(struct net_device *dev)
1364{ 1421{
1365 struct ip6_tnl *t = netdev_priv(dev); 1422 struct ip6_tnl *t = netdev_priv(dev);
1366 struct net *net = dev_net(dev); 1423 struct net *net = dev_net(dev);
1367 struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); 1424 struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
1425 int err = ip6_tnl_dev_init_gen(dev);
1426
1427 if (err)
1428 return err;
1368 1429
1369 ip6_tnl_dev_init_gen(dev);
1370 t->parms.proto = IPPROTO_IPV6; 1430 t->parms.proto = IPPROTO_IPV6;
1371 dev_hold(dev); 1431 dev_hold(dev);
1372 ip6n->tnls_wc[0] = t; 1432 rcu_assign_pointer(ip6n->tnls_wc[0], t);
1433 return 0;
1373} 1434}
1374 1435
1375static struct xfrm6_tunnel ip4ip6_handler = { 1436static struct xfrm6_tunnel ip4ip6_handler __read_mostly = {
1376 .handler = ip4ip6_rcv, 1437 .handler = ip4ip6_rcv,
1377 .err_handler = ip4ip6_err, 1438 .err_handler = ip4ip6_err,
1378 .priority = 1, 1439 .priority = 1,
1379}; 1440};
1380 1441
1381static struct xfrm6_tunnel ip6ip6_handler = { 1442static struct xfrm6_tunnel ip6ip6_handler __read_mostly = {
1382 .handler = ip6ip6_rcv, 1443 .handler = ip6ip6_rcv,
1383 .err_handler = ip6ip6_err, 1444 .err_handler = ip6ip6_err,
1384 .priority = 1, 1445 .priority = 1,
@@ -1391,14 +1452,14 @@ static void __net_exit ip6_tnl_destroy_tunnels(struct ip6_tnl_net *ip6n)
1391 LIST_HEAD(list); 1452 LIST_HEAD(list);
1392 1453
1393 for (h = 0; h < HASH_SIZE; h++) { 1454 for (h = 0; h < HASH_SIZE; h++) {
1394 t = ip6n->tnls_r_l[h]; 1455 t = rtnl_dereference(ip6n->tnls_r_l[h]);
1395 while (t != NULL) { 1456 while (t != NULL) {
1396 unregister_netdevice_queue(t->dev, &list); 1457 unregister_netdevice_queue(t->dev, &list);
1397 t = t->next; 1458 t = rtnl_dereference(t->next);
1398 } 1459 }
1399 } 1460 }
1400 1461
1401 t = ip6n->tnls_wc[0]; 1462 t = rtnl_dereference(ip6n->tnls_wc[0]);
1402 unregister_netdevice_queue(t->dev, &list); 1463 unregister_netdevice_queue(t->dev, &list);
1403 unregister_netdevice_many(&list); 1464 unregister_netdevice_many(&list);
1404} 1465}
@@ -1419,7 +1480,9 @@ static int __net_init ip6_tnl_init_net(struct net *net)
1419 goto err_alloc_dev; 1480 goto err_alloc_dev;
1420 dev_net_set(ip6n->fb_tnl_dev, net); 1481 dev_net_set(ip6n->fb_tnl_dev, net);
1421 1482
1422 ip6_fb_tnl_dev_init(ip6n->fb_tnl_dev); 1483 err = ip6_fb_tnl_dev_init(ip6n->fb_tnl_dev);
1484 if (err < 0)
1485 goto err_register;
1423 1486
1424 err = register_netdev(ip6n->fb_tnl_dev); 1487 err = register_netdev(ip6n->fb_tnl_dev);
1425 if (err < 0) 1488 if (err < 0)
@@ -1427,7 +1490,7 @@ static int __net_init ip6_tnl_init_net(struct net *net)
1427 return 0; 1490 return 0;
1428 1491
1429err_register: 1492err_register:
1430 free_netdev(ip6n->fb_tnl_dev); 1493 ip6_dev_free(ip6n->fb_tnl_dev);
1431err_alloc_dev: 1494err_alloc_dev:
1432 return err; 1495 return err;
1433} 1496}
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index 66078dad7fe8..6f32ffce7022 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -667,6 +667,7 @@ static int pim6_rcv(struct sk_buff *skb)
667 skb_tunnel_rx(skb, reg_dev); 667 skb_tunnel_rx(skb, reg_dev);
668 668
669 netif_rx(skb); 669 netif_rx(skb);
670
670 dev_put(reg_dev); 671 dev_put(reg_dev);
671 return 0; 672 return 0;
672 drop: 673 drop:
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index a7f66bc8f0b0..d1770e061c08 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -342,6 +342,25 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
342 retv = 0; 342 retv = 0;
343 break; 343 break;
344 344
345 case IPV6_TRANSPARENT:
346 if (!capable(CAP_NET_ADMIN)) {
347 retv = -EPERM;
348 break;
349 }
350 if (optlen < sizeof(int))
351 goto e_inval;
352 /* we don't have a separate transparent bit for IPV6 we use the one in the IPv4 socket */
353 inet_sk(sk)->transparent = valbool;
354 retv = 0;
355 break;
356
357 case IPV6_RECVORIGDSTADDR:
358 if (optlen < sizeof(int))
359 goto e_inval;
360 np->rxopt.bits.rxorigdstaddr = valbool;
361 retv = 0;
362 break;
363
345 case IPV6_HOPOPTS: 364 case IPV6_HOPOPTS:
346 case IPV6_RTHDRDSTOPTS: 365 case IPV6_RTHDRDSTOPTS:
347 case IPV6_RTHDR: 366 case IPV6_RTHDR:
@@ -1104,6 +1123,14 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
1104 break; 1123 break;
1105 } 1124 }
1106 1125
1126 case IPV6_TRANSPARENT:
1127 val = inet_sk(sk)->transparent;
1128 break;
1129
1130 case IPV6_RECVORIGDSTADDR:
1131 val = np->rxopt.bits.rxorigdstaddr;
1132 break;
1133
1107 case IPV6_UNICAST_HOPS: 1134 case IPV6_UNICAST_HOPS:
1108 case IPV6_MULTICAST_HOPS: 1135 case IPV6_MULTICAST_HOPS:
1109 { 1136 {
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 58841c4ae947..998d6d27e7cf 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -91,7 +91,9 @@
91#include <linux/netfilter.h> 91#include <linux/netfilter.h>
92#include <linux/netfilter_ipv6.h> 92#include <linux/netfilter_ipv6.h>
93 93
94static u32 ndisc_hash(const void *pkey, const struct net_device *dev); 94static u32 ndisc_hash(const void *pkey,
95 const struct net_device *dev,
96 __u32 rnd);
95static int ndisc_constructor(struct neighbour *neigh); 97static int ndisc_constructor(struct neighbour *neigh);
96static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb); 98static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb);
97static void ndisc_error_report(struct neighbour *neigh, struct sk_buff *skb); 99static void ndisc_error_report(struct neighbour *neigh, struct sk_buff *skb);
@@ -228,12 +230,12 @@ static struct nd_opt_hdr *ndisc_next_option(struct nd_opt_hdr *cur,
228 do { 230 do {
229 cur = ((void *)cur) + (cur->nd_opt_len << 3); 231 cur = ((void *)cur) + (cur->nd_opt_len << 3);
230 } while(cur < end && cur->nd_opt_type != type); 232 } while(cur < end && cur->nd_opt_type != type);
231 return (cur <= end && cur->nd_opt_type == type ? cur : NULL); 233 return cur <= end && cur->nd_opt_type == type ? cur : NULL;
232} 234}
233 235
234static inline int ndisc_is_useropt(struct nd_opt_hdr *opt) 236static inline int ndisc_is_useropt(struct nd_opt_hdr *opt)
235{ 237{
236 return (opt->nd_opt_type == ND_OPT_RDNSS); 238 return opt->nd_opt_type == ND_OPT_RDNSS;
237} 239}
238 240
239static struct nd_opt_hdr *ndisc_next_useropt(struct nd_opt_hdr *cur, 241static struct nd_opt_hdr *ndisc_next_useropt(struct nd_opt_hdr *cur,
@@ -244,7 +246,7 @@ static struct nd_opt_hdr *ndisc_next_useropt(struct nd_opt_hdr *cur,
244 do { 246 do {
245 cur = ((void *)cur) + (cur->nd_opt_len << 3); 247 cur = ((void *)cur) + (cur->nd_opt_len << 3);
246 } while(cur < end && !ndisc_is_useropt(cur)); 248 } while(cur < end && !ndisc_is_useropt(cur));
247 return (cur <= end && ndisc_is_useropt(cur) ? cur : NULL); 249 return cur <= end && ndisc_is_useropt(cur) ? cur : NULL;
248} 250}
249 251
250static struct ndisc_options *ndisc_parse_options(u8 *opt, int opt_len, 252static struct ndisc_options *ndisc_parse_options(u8 *opt, int opt_len,
@@ -319,7 +321,7 @@ static inline u8 *ndisc_opt_addr_data(struct nd_opt_hdr *p,
319 int prepad = ndisc_addr_option_pad(dev->type); 321 int prepad = ndisc_addr_option_pad(dev->type);
320 if (lladdrlen != NDISC_OPT_SPACE(dev->addr_len + prepad)) 322 if (lladdrlen != NDISC_OPT_SPACE(dev->addr_len + prepad))
321 return NULL; 323 return NULL;
322 return (lladdr + prepad); 324 return lladdr + prepad;
323} 325}
324 326
325int ndisc_mc_map(struct in6_addr *addr, char *buf, struct net_device *dev, int dir) 327int ndisc_mc_map(struct in6_addr *addr, char *buf, struct net_device *dev, int dir)
@@ -350,7 +352,9 @@ int ndisc_mc_map(struct in6_addr *addr, char *buf, struct net_device *dev, int d
350 352
351EXPORT_SYMBOL(ndisc_mc_map); 353EXPORT_SYMBOL(ndisc_mc_map);
352 354
353static u32 ndisc_hash(const void *pkey, const struct net_device *dev) 355static u32 ndisc_hash(const void *pkey,
356 const struct net_device *dev,
357 __u32 hash_rnd)
354{ 358{
355 const u32 *p32 = pkey; 359 const u32 *p32 = pkey;
356 u32 addr_hash, i; 360 u32 addr_hash, i;
@@ -359,7 +363,7 @@ static u32 ndisc_hash(const void *pkey, const struct net_device *dev)
359 for (i = 0; i < (sizeof(struct in6_addr) / sizeof(u32)); i++) 363 for (i = 0; i < (sizeof(struct in6_addr) / sizeof(u32)); i++)
360 addr_hash ^= *p32++; 364 addr_hash ^= *p32++;
361 365
362 return jhash_2words(addr_hash, dev->ifindex, nd_tbl.hash_rnd); 366 return jhash_2words(addr_hash, dev->ifindex, hash_rnd);
363} 367}
364 368
365static int ndisc_constructor(struct neighbour *neigh) 369static int ndisc_constructor(struct neighbour *neigh)
@@ -1105,6 +1109,18 @@ errout:
1105 rtnl_set_sk_err(net, RTNLGRP_ND_USEROPT, err); 1109 rtnl_set_sk_err(net, RTNLGRP_ND_USEROPT, err);
1106} 1110}
1107 1111
1112static inline int accept_ra(struct inet6_dev *in6_dev)
1113{
1114 /*
1115 * If forwarding is enabled, RA are not accepted unless the special
1116 * hybrid mode (accept_ra=2) is enabled.
1117 */
1118 if (in6_dev->cnf.forwarding && in6_dev->cnf.accept_ra < 2)
1119 return 0;
1120
1121 return in6_dev->cnf.accept_ra;
1122}
1123
1108static void ndisc_router_discovery(struct sk_buff *skb) 1124static void ndisc_router_discovery(struct sk_buff *skb)
1109{ 1125{
1110 struct ra_msg *ra_msg = (struct ra_msg *)skb_transport_header(skb); 1126 struct ra_msg *ra_msg = (struct ra_msg *)skb_transport_header(skb);
@@ -1158,8 +1174,7 @@ static void ndisc_router_discovery(struct sk_buff *skb)
1158 return; 1174 return;
1159 } 1175 }
1160 1176
1161 /* skip route and link configuration on routers */ 1177 if (!accept_ra(in6_dev))
1162 if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_ra)
1163 goto skip_linkparms; 1178 goto skip_linkparms;
1164 1179
1165#ifdef CONFIG_IPV6_NDISC_NODETYPE 1180#ifdef CONFIG_IPV6_NDISC_NODETYPE
@@ -1309,8 +1324,7 @@ skip_linkparms:
1309 NEIGH_UPDATE_F_ISROUTER); 1324 NEIGH_UPDATE_F_ISROUTER);
1310 } 1325 }
1311 1326
1312 /* skip route and link configuration on routers */ 1327 if (!accept_ra(in6_dev))
1313 if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_ra)
1314 goto out; 1328 goto out;
1315 1329
1316#ifdef CONFIG_IPV6_ROUTE_INFO 1330#ifdef CONFIG_IPV6_ROUTE_INFO
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
index 29d643bcafa4..448464844a25 100644
--- a/net/ipv6/netfilter/Kconfig
+++ b/net/ipv6/netfilter/Kconfig
@@ -5,10 +5,15 @@
5menu "IPv6: Netfilter Configuration" 5menu "IPv6: Netfilter Configuration"
6 depends on INET && IPV6 && NETFILTER 6 depends on INET && IPV6 && NETFILTER
7 7
8config NF_DEFRAG_IPV6
9 tristate
10 default n
11
8config NF_CONNTRACK_IPV6 12config NF_CONNTRACK_IPV6
9 tristate "IPv6 connection tracking support" 13 tristate "IPv6 connection tracking support"
10 depends on INET && IPV6 && NF_CONNTRACK 14 depends on INET && IPV6 && NF_CONNTRACK
11 default m if NETFILTER_ADVANCED=n 15 default m if NETFILTER_ADVANCED=n
16 select NF_DEFRAG_IPV6
12 ---help--- 17 ---help---
13 Connection tracking keeps a record of what packets have passed 18 Connection tracking keeps a record of what packets have passed
14 through your machine, in order to figure out how they are related 19 through your machine, in order to figure out how they are related
@@ -132,10 +137,10 @@ config IP6_NF_MATCH_RT
132# The targets 137# The targets
133config IP6_NF_TARGET_HL 138config IP6_NF_TARGET_HL
134 tristate '"HL" hoplimit target support' 139 tristate '"HL" hoplimit target support'
135 depends on NETFILTER_ADVANCED 140 depends on NETFILTER_ADVANCED && IP6_NF_MANGLE
136 select NETFILTER_XT_TARGET_HL 141 select NETFILTER_XT_TARGET_HL
137 ---help--- 142 ---help---
138 This is a backwards-compat option for the user's convenience 143 This is a backwards-compatible option for the user's convenience
139 (e.g. when running oldconfig). It selects 144 (e.g. when running oldconfig). It selects
140 CONFIG_NETFILTER_XT_TARGET_HL. 145 CONFIG_NETFILTER_XT_TARGET_HL.
141 146
diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile
index aafbba30c899..0a432c9b0795 100644
--- a/net/ipv6/netfilter/Makefile
+++ b/net/ipv6/netfilter/Makefile
@@ -11,10 +11,14 @@ obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o
11obj-$(CONFIG_IP6_NF_SECURITY) += ip6table_security.o 11obj-$(CONFIG_IP6_NF_SECURITY) += ip6table_security.o
12 12
13# objects for l3 independent conntrack 13# objects for l3 independent conntrack
14nf_conntrack_ipv6-objs := nf_conntrack_l3proto_ipv6.o nf_conntrack_proto_icmpv6.o nf_conntrack_reasm.o 14nf_conntrack_ipv6-objs := nf_conntrack_l3proto_ipv6.o nf_conntrack_proto_icmpv6.o
15 15
16# l3 independent conntrack 16# l3 independent conntrack
17obj-$(CONFIG_NF_CONNTRACK_IPV6) += nf_conntrack_ipv6.o 17obj-$(CONFIG_NF_CONNTRACK_IPV6) += nf_conntrack_ipv6.o nf_defrag_ipv6.o
18
19# defrag
20nf_defrag_ipv6-objs := nf_defrag_ipv6_hooks.o nf_conntrack_reasm.o
21obj-$(CONFIG_NF_DEFRAG_IPV6) += nf_defrag_ipv6.o
18 22
19# matches 23# matches
20obj-$(CONFIG_IP6_NF_MATCH_AH) += ip6t_ah.o 24obj-$(CONFIG_IP6_NF_MATCH_AH) += ip6t_ah.o
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 8e754be92c24..455582384ece 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -82,13 +82,13 @@ EXPORT_SYMBOL_GPL(ip6t_alloc_initial_table);
82int 82int
83ip6t_ext_hdr(u8 nexthdr) 83ip6t_ext_hdr(u8 nexthdr)
84{ 84{
85 return ( (nexthdr == IPPROTO_HOPOPTS) || 85 return (nexthdr == IPPROTO_HOPOPTS) ||
86 (nexthdr == IPPROTO_ROUTING) || 86 (nexthdr == IPPROTO_ROUTING) ||
87 (nexthdr == IPPROTO_FRAGMENT) || 87 (nexthdr == IPPROTO_FRAGMENT) ||
88 (nexthdr == IPPROTO_ESP) || 88 (nexthdr == IPPROTO_ESP) ||
89 (nexthdr == IPPROTO_AH) || 89 (nexthdr == IPPROTO_AH) ||
90 (nexthdr == IPPROTO_NONE) || 90 (nexthdr == IPPROTO_NONE) ||
91 (nexthdr == IPPROTO_DSTOPTS) ); 91 (nexthdr == IPPROTO_DSTOPTS);
92} 92}
93 93
94/* Returns whether matches rule or not. */ 94/* Returns whether matches rule or not. */
@@ -215,7 +215,7 @@ static inline bool unconditional(const struct ip6t_ip6 *ipv6)
215 return memcmp(ipv6, &uncond, sizeof(uncond)) == 0; 215 return memcmp(ipv6, &uncond, sizeof(uncond)) == 0;
216} 216}
217 217
218static inline const struct ip6t_entry_target * 218static inline const struct xt_entry_target *
219ip6t_get_target_c(const struct ip6t_entry *e) 219ip6t_get_target_c(const struct ip6t_entry *e)
220{ 220{
221 return ip6t_get_target((struct ip6t_entry *)e); 221 return ip6t_get_target((struct ip6t_entry *)e);
@@ -260,9 +260,9 @@ get_chainname_rulenum(const struct ip6t_entry *s, const struct ip6t_entry *e,
260 const char *hookname, const char **chainname, 260 const char *hookname, const char **chainname,
261 const char **comment, unsigned int *rulenum) 261 const char **comment, unsigned int *rulenum)
262{ 262{
263 const struct ip6t_standard_target *t = (void *)ip6t_get_target_c(s); 263 const struct xt_standard_target *t = (void *)ip6t_get_target_c(s);
264 264
265 if (strcmp(t->target.u.kernel.target->name, IP6T_ERROR_TARGET) == 0) { 265 if (strcmp(t->target.u.kernel.target->name, XT_ERROR_TARGET) == 0) {
266 /* Head of user chain: ERROR target with chainname */ 266 /* Head of user chain: ERROR target with chainname */
267 *chainname = t->target.data; 267 *chainname = t->target.data;
268 (*rulenum) = 0; 268 (*rulenum) = 0;
@@ -271,7 +271,7 @@ get_chainname_rulenum(const struct ip6t_entry *s, const struct ip6t_entry *e,
271 271
272 if (s->target_offset == sizeof(struct ip6t_entry) && 272 if (s->target_offset == sizeof(struct ip6t_entry) &&
273 strcmp(t->target.u.kernel.target->name, 273 strcmp(t->target.u.kernel.target->name,
274 IP6T_STANDARD_TARGET) == 0 && 274 XT_STANDARD_TARGET) == 0 &&
275 t->verdict < 0 && 275 t->verdict < 0 &&
276 unconditional(&s->ipv6)) { 276 unconditional(&s->ipv6)) {
277 /* Tail of chains: STANDARD target (return/policy) */ 277 /* Tail of chains: STANDARD target (return/policy) */
@@ -369,7 +369,7 @@ ip6t_do_table(struct sk_buff *skb,
369 e = get_entry(table_base, private->hook_entry[hook]); 369 e = get_entry(table_base, private->hook_entry[hook]);
370 370
371 do { 371 do {
372 const struct ip6t_entry_target *t; 372 const struct xt_entry_target *t;
373 const struct xt_entry_match *ematch; 373 const struct xt_entry_match *ematch;
374 374
375 IP_NF_ASSERT(e); 375 IP_NF_ASSERT(e);
@@ -403,10 +403,10 @@ ip6t_do_table(struct sk_buff *skb,
403 if (!t->u.kernel.target->target) { 403 if (!t->u.kernel.target->target) {
404 int v; 404 int v;
405 405
406 v = ((struct ip6t_standard_target *)t)->verdict; 406 v = ((struct xt_standard_target *)t)->verdict;
407 if (v < 0) { 407 if (v < 0) {
408 /* Pop from stack? */ 408 /* Pop from stack? */
409 if (v != IP6T_RETURN) { 409 if (v != XT_RETURN) {
410 verdict = (unsigned)(-v) - 1; 410 verdict = (unsigned)(-v) - 1;
411 break; 411 break;
412 } 412 }
@@ -434,7 +434,7 @@ ip6t_do_table(struct sk_buff *skb,
434 acpar.targinfo = t->data; 434 acpar.targinfo = t->data;
435 435
436 verdict = t->u.kernel.target->target(skb, &acpar); 436 verdict = t->u.kernel.target->target(skb, &acpar);
437 if (verdict == IP6T_CONTINUE) 437 if (verdict == XT_CONTINUE)
438 e = ip6t_next_entry(e); 438 e = ip6t_next_entry(e);
439 else 439 else
440 /* Verdict */ 440 /* Verdict */
@@ -474,7 +474,7 @@ mark_source_chains(const struct xt_table_info *newinfo,
474 e->counters.pcnt = pos; 474 e->counters.pcnt = pos;
475 475
476 for (;;) { 476 for (;;) {
477 const struct ip6t_standard_target *t 477 const struct xt_standard_target *t
478 = (void *)ip6t_get_target_c(e); 478 = (void *)ip6t_get_target_c(e);
479 int visited = e->comefrom & (1 << hook); 479 int visited = e->comefrom & (1 << hook);
480 480
@@ -488,13 +488,13 @@ mark_source_chains(const struct xt_table_info *newinfo,
488 /* Unconditional return/END. */ 488 /* Unconditional return/END. */
489 if ((e->target_offset == sizeof(struct ip6t_entry) && 489 if ((e->target_offset == sizeof(struct ip6t_entry) &&
490 (strcmp(t->target.u.user.name, 490 (strcmp(t->target.u.user.name,
491 IP6T_STANDARD_TARGET) == 0) && 491 XT_STANDARD_TARGET) == 0) &&
492 t->verdict < 0 && 492 t->verdict < 0 &&
493 unconditional(&e->ipv6)) || visited) { 493 unconditional(&e->ipv6)) || visited) {
494 unsigned int oldpos, size; 494 unsigned int oldpos, size;
495 495
496 if ((strcmp(t->target.u.user.name, 496 if ((strcmp(t->target.u.user.name,
497 IP6T_STANDARD_TARGET) == 0) && 497 XT_STANDARD_TARGET) == 0) &&
498 t->verdict < -NF_MAX_VERDICT - 1) { 498 t->verdict < -NF_MAX_VERDICT - 1) {
499 duprintf("mark_source_chains: bad " 499 duprintf("mark_source_chains: bad "
500 "negative verdict (%i)\n", 500 "negative verdict (%i)\n",
@@ -537,7 +537,7 @@ mark_source_chains(const struct xt_table_info *newinfo,
537 int newpos = t->verdict; 537 int newpos = t->verdict;
538 538
539 if (strcmp(t->target.u.user.name, 539 if (strcmp(t->target.u.user.name,
540 IP6T_STANDARD_TARGET) == 0 && 540 XT_STANDARD_TARGET) == 0 &&
541 newpos >= 0) { 541 newpos >= 0) {
542 if (newpos > newinfo->size - 542 if (newpos > newinfo->size -
543 sizeof(struct ip6t_entry)) { 543 sizeof(struct ip6t_entry)) {
@@ -565,7 +565,7 @@ mark_source_chains(const struct xt_table_info *newinfo,
565 return 1; 565 return 1;
566} 566}
567 567
568static void cleanup_match(struct ip6t_entry_match *m, struct net *net) 568static void cleanup_match(struct xt_entry_match *m, struct net *net)
569{ 569{
570 struct xt_mtdtor_param par; 570 struct xt_mtdtor_param par;
571 571
@@ -581,14 +581,14 @@ static void cleanup_match(struct ip6t_entry_match *m, struct net *net)
581static int 581static int
582check_entry(const struct ip6t_entry *e, const char *name) 582check_entry(const struct ip6t_entry *e, const char *name)
583{ 583{
584 const struct ip6t_entry_target *t; 584 const struct xt_entry_target *t;
585 585
586 if (!ip6_checkentry(&e->ipv6)) { 586 if (!ip6_checkentry(&e->ipv6)) {
587 duprintf("ip_tables: ip check failed %p %s.\n", e, name); 587 duprintf("ip_tables: ip check failed %p %s.\n", e, name);
588 return -EINVAL; 588 return -EINVAL;
589 } 589 }
590 590
591 if (e->target_offset + sizeof(struct ip6t_entry_target) > 591 if (e->target_offset + sizeof(struct xt_entry_target) >
592 e->next_offset) 592 e->next_offset)
593 return -EINVAL; 593 return -EINVAL;
594 594
@@ -599,7 +599,7 @@ check_entry(const struct ip6t_entry *e, const char *name)
599 return 0; 599 return 0;
600} 600}
601 601
602static int check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par) 602static int check_match(struct xt_entry_match *m, struct xt_mtchk_param *par)
603{ 603{
604 const struct ip6t_ip6 *ipv6 = par->entryinfo; 604 const struct ip6t_ip6 *ipv6 = par->entryinfo;
605 int ret; 605 int ret;
@@ -618,7 +618,7 @@ static int check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par)
618} 618}
619 619
620static int 620static int
621find_check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par) 621find_check_match(struct xt_entry_match *m, struct xt_mtchk_param *par)
622{ 622{
623 struct xt_match *match; 623 struct xt_match *match;
624 int ret; 624 int ret;
@@ -643,7 +643,7 @@ err:
643 643
644static int check_target(struct ip6t_entry *e, struct net *net, const char *name) 644static int check_target(struct ip6t_entry *e, struct net *net, const char *name)
645{ 645{
646 struct ip6t_entry_target *t = ip6t_get_target(e); 646 struct xt_entry_target *t = ip6t_get_target(e);
647 struct xt_tgchk_param par = { 647 struct xt_tgchk_param par = {
648 .net = net, 648 .net = net,
649 .table = name, 649 .table = name,
@@ -670,7 +670,7 @@ static int
670find_check_entry(struct ip6t_entry *e, struct net *net, const char *name, 670find_check_entry(struct ip6t_entry *e, struct net *net, const char *name,
671 unsigned int size) 671 unsigned int size)
672{ 672{
673 struct ip6t_entry_target *t; 673 struct xt_entry_target *t;
674 struct xt_target *target; 674 struct xt_target *target;
675 int ret; 675 int ret;
676 unsigned int j; 676 unsigned int j;
@@ -721,7 +721,7 @@ find_check_entry(struct ip6t_entry *e, struct net *net, const char *name,
721 721
722static bool check_underflow(const struct ip6t_entry *e) 722static bool check_underflow(const struct ip6t_entry *e)
723{ 723{
724 const struct ip6t_entry_target *t; 724 const struct xt_entry_target *t;
725 unsigned int verdict; 725 unsigned int verdict;
726 726
727 if (!unconditional(&e->ipv6)) 727 if (!unconditional(&e->ipv6))
@@ -729,7 +729,7 @@ static bool check_underflow(const struct ip6t_entry *e)
729 t = ip6t_get_target_c(e); 729 t = ip6t_get_target_c(e);
730 if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0) 730 if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0)
731 return false; 731 return false;
732 verdict = ((struct ip6t_standard_target *)t)->verdict; 732 verdict = ((struct xt_standard_target *)t)->verdict;
733 verdict = -verdict - 1; 733 verdict = -verdict - 1;
734 return verdict == NF_DROP || verdict == NF_ACCEPT; 734 return verdict == NF_DROP || verdict == NF_ACCEPT;
735} 735}
@@ -752,7 +752,7 @@ check_entry_size_and_hooks(struct ip6t_entry *e,
752 } 752 }
753 753
754 if (e->next_offset 754 if (e->next_offset
755 < sizeof(struct ip6t_entry) + sizeof(struct ip6t_entry_target)) { 755 < sizeof(struct ip6t_entry) + sizeof(struct xt_entry_target)) {
756 duprintf("checking: element %p size %u\n", 756 duprintf("checking: element %p size %u\n",
757 e, e->next_offset); 757 e, e->next_offset);
758 return -EINVAL; 758 return -EINVAL;
@@ -784,7 +784,7 @@ check_entry_size_and_hooks(struct ip6t_entry *e,
784static void cleanup_entry(struct ip6t_entry *e, struct net *net) 784static void cleanup_entry(struct ip6t_entry *e, struct net *net)
785{ 785{
786 struct xt_tgdtor_param par; 786 struct xt_tgdtor_param par;
787 struct ip6t_entry_target *t; 787 struct xt_entry_target *t;
788 struct xt_entry_match *ematch; 788 struct xt_entry_match *ematch;
789 789
790 /* Cleanup all matches */ 790 /* Cleanup all matches */
@@ -985,8 +985,8 @@ copy_entries_to_user(unsigned int total_size,
985 /* ... then go back and fix counters and names */ 985 /* ... then go back and fix counters and names */
986 for (off = 0, num = 0; off < total_size; off += e->next_offset, num++){ 986 for (off = 0, num = 0; off < total_size; off += e->next_offset, num++){
987 unsigned int i; 987 unsigned int i;
988 const struct ip6t_entry_match *m; 988 const struct xt_entry_match *m;
989 const struct ip6t_entry_target *t; 989 const struct xt_entry_target *t;
990 990
991 e = (struct ip6t_entry *)(loc_cpu_entry + off); 991 e = (struct ip6t_entry *)(loc_cpu_entry + off);
992 if (copy_to_user(userptr + off 992 if (copy_to_user(userptr + off
@@ -1003,7 +1003,7 @@ copy_entries_to_user(unsigned int total_size,
1003 m = (void *)e + i; 1003 m = (void *)e + i;
1004 1004
1005 if (copy_to_user(userptr + off + i 1005 if (copy_to_user(userptr + off + i
1006 + offsetof(struct ip6t_entry_match, 1006 + offsetof(struct xt_entry_match,
1007 u.user.name), 1007 u.user.name),
1008 m->u.kernel.match->name, 1008 m->u.kernel.match->name,
1009 strlen(m->u.kernel.match->name)+1) 1009 strlen(m->u.kernel.match->name)+1)
@@ -1015,7 +1015,7 @@ copy_entries_to_user(unsigned int total_size,
1015 1015
1016 t = ip6t_get_target_c(e); 1016 t = ip6t_get_target_c(e);
1017 if (copy_to_user(userptr + off + e->target_offset 1017 if (copy_to_user(userptr + off + e->target_offset
1018 + offsetof(struct ip6t_entry_target, 1018 + offsetof(struct xt_entry_target,
1019 u.user.name), 1019 u.user.name),
1020 t->u.kernel.target->name, 1020 t->u.kernel.target->name,
1021 strlen(t->u.kernel.target->name)+1) != 0) { 1021 strlen(t->u.kernel.target->name)+1) != 0) {
@@ -1053,7 +1053,7 @@ static int compat_calc_entry(const struct ip6t_entry *e,
1053 const void *base, struct xt_table_info *newinfo) 1053 const void *base, struct xt_table_info *newinfo)
1054{ 1054{
1055 const struct xt_entry_match *ematch; 1055 const struct xt_entry_match *ematch;
1056 const struct ip6t_entry_target *t; 1056 const struct xt_entry_target *t;
1057 unsigned int entry_offset; 1057 unsigned int entry_offset;
1058 int off, i, ret; 1058 int off, i, ret;
1059 1059
@@ -1105,7 +1105,7 @@ static int compat_table_info(const struct xt_table_info *info,
1105static int get_info(struct net *net, void __user *user, 1105static int get_info(struct net *net, void __user *user,
1106 const int *len, int compat) 1106 const int *len, int compat)
1107{ 1107{
1108 char name[IP6T_TABLE_MAXNAMELEN]; 1108 char name[XT_TABLE_MAXNAMELEN];
1109 struct xt_table *t; 1109 struct xt_table *t;
1110 int ret; 1110 int ret;
1111 1111
@@ -1118,7 +1118,7 @@ static int get_info(struct net *net, void __user *user,
1118 if (copy_from_user(name, user, sizeof(name)) != 0) 1118 if (copy_from_user(name, user, sizeof(name)) != 0)
1119 return -EFAULT; 1119 return -EFAULT;
1120 1120
1121 name[IP6T_TABLE_MAXNAMELEN-1] = '\0'; 1121 name[XT_TABLE_MAXNAMELEN-1] = '\0';
1122#ifdef CONFIG_COMPAT 1122#ifdef CONFIG_COMPAT
1123 if (compat) 1123 if (compat)
1124 xt_compat_lock(AF_INET6); 1124 xt_compat_lock(AF_INET6);
@@ -1137,6 +1137,7 @@ static int get_info(struct net *net, void __user *user,
1137 private = &tmp; 1137 private = &tmp;
1138 } 1138 }
1139#endif 1139#endif
1140 memset(&info, 0, sizeof(info));
1140 info.valid_hooks = t->valid_hooks; 1141 info.valid_hooks = t->valid_hooks;
1141 memcpy(info.hook_entry, private->hook_entry, 1142 memcpy(info.hook_entry, private->hook_entry,
1142 sizeof(info.hook_entry)); 1143 sizeof(info.hook_entry));
@@ -1415,14 +1416,14 @@ do_add_counters(struct net *net, const void __user *user, unsigned int len,
1415 1416
1416#ifdef CONFIG_COMPAT 1417#ifdef CONFIG_COMPAT
1417struct compat_ip6t_replace { 1418struct compat_ip6t_replace {
1418 char name[IP6T_TABLE_MAXNAMELEN]; 1419 char name[XT_TABLE_MAXNAMELEN];
1419 u32 valid_hooks; 1420 u32 valid_hooks;
1420 u32 num_entries; 1421 u32 num_entries;
1421 u32 size; 1422 u32 size;
1422 u32 hook_entry[NF_INET_NUMHOOKS]; 1423 u32 hook_entry[NF_INET_NUMHOOKS];
1423 u32 underflow[NF_INET_NUMHOOKS]; 1424 u32 underflow[NF_INET_NUMHOOKS];
1424 u32 num_counters; 1425 u32 num_counters;
1425 compat_uptr_t counters; /* struct ip6t_counters * */ 1426 compat_uptr_t counters; /* struct xt_counters * */
1426 struct compat_ip6t_entry entries[0]; 1427 struct compat_ip6t_entry entries[0];
1427}; 1428};
1428 1429
@@ -1431,7 +1432,7 @@ compat_copy_entry_to_user(struct ip6t_entry *e, void __user **dstptr,
1431 unsigned int *size, struct xt_counters *counters, 1432 unsigned int *size, struct xt_counters *counters,
1432 unsigned int i) 1433 unsigned int i)
1433{ 1434{
1434 struct ip6t_entry_target *t; 1435 struct xt_entry_target *t;
1435 struct compat_ip6t_entry __user *ce; 1436 struct compat_ip6t_entry __user *ce;
1436 u_int16_t target_offset, next_offset; 1437 u_int16_t target_offset, next_offset;
1437 compat_uint_t origsize; 1438 compat_uint_t origsize;
@@ -1466,7 +1467,7 @@ compat_copy_entry_to_user(struct ip6t_entry *e, void __user **dstptr,
1466} 1467}
1467 1468
1468static int 1469static int
1469compat_find_calc_match(struct ip6t_entry_match *m, 1470compat_find_calc_match(struct xt_entry_match *m,
1470 const char *name, 1471 const char *name,
1471 const struct ip6t_ip6 *ipv6, 1472 const struct ip6t_ip6 *ipv6,
1472 unsigned int hookmask, 1473 unsigned int hookmask,
@@ -1488,7 +1489,7 @@ compat_find_calc_match(struct ip6t_entry_match *m,
1488 1489
1489static void compat_release_entry(struct compat_ip6t_entry *e) 1490static void compat_release_entry(struct compat_ip6t_entry *e)
1490{ 1491{
1491 struct ip6t_entry_target *t; 1492 struct xt_entry_target *t;
1492 struct xt_entry_match *ematch; 1493 struct xt_entry_match *ematch;
1493 1494
1494 /* Cleanup all matches */ 1495 /* Cleanup all matches */
@@ -1509,7 +1510,7 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e,
1509 const char *name) 1510 const char *name)
1510{ 1511{
1511 struct xt_entry_match *ematch; 1512 struct xt_entry_match *ematch;
1512 struct ip6t_entry_target *t; 1513 struct xt_entry_target *t;
1513 struct xt_target *target; 1514 struct xt_target *target;
1514 unsigned int entry_offset; 1515 unsigned int entry_offset;
1515 unsigned int j; 1516 unsigned int j;
@@ -1591,7 +1592,7 @@ compat_copy_entry_from_user(struct compat_ip6t_entry *e, void **dstptr,
1591 unsigned int *size, const char *name, 1592 unsigned int *size, const char *name,
1592 struct xt_table_info *newinfo, unsigned char *base) 1593 struct xt_table_info *newinfo, unsigned char *base)
1593{ 1594{
1594 struct ip6t_entry_target *t; 1595 struct xt_entry_target *t;
1595 struct xt_target *target; 1596 struct xt_target *target;
1596 struct ip6t_entry *de; 1597 struct ip6t_entry *de;
1597 unsigned int origsize; 1598 unsigned int origsize;
@@ -1899,7 +1900,7 @@ compat_do_ip6t_set_ctl(struct sock *sk, int cmd, void __user *user,
1899} 1900}
1900 1901
1901struct compat_ip6t_get_entries { 1902struct compat_ip6t_get_entries {
1902 char name[IP6T_TABLE_MAXNAMELEN]; 1903 char name[XT_TABLE_MAXNAMELEN];
1903 compat_uint_t size; 1904 compat_uint_t size;
1904 struct compat_ip6t_entry entrytable[0]; 1905 struct compat_ip6t_entry entrytable[0];
1905}; 1906};
@@ -2054,7 +2055,7 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
2054 2055
2055 case IP6T_SO_GET_REVISION_MATCH: 2056 case IP6T_SO_GET_REVISION_MATCH:
2056 case IP6T_SO_GET_REVISION_TARGET: { 2057 case IP6T_SO_GET_REVISION_TARGET: {
2057 struct ip6t_get_revision rev; 2058 struct xt_get_revision rev;
2058 int target; 2059 int target;
2059 2060
2060 if (*len != sizeof(rev)) { 2061 if (*len != sizeof(rev)) {
@@ -2191,7 +2192,7 @@ static int icmp6_checkentry(const struct xt_mtchk_param *par)
2191/* The built-in targets: standard (NULL) and error. */ 2192/* The built-in targets: standard (NULL) and error. */
2192static struct xt_target ip6t_builtin_tg[] __read_mostly = { 2193static struct xt_target ip6t_builtin_tg[] __read_mostly = {
2193 { 2194 {
2194 .name = IP6T_STANDARD_TARGET, 2195 .name = XT_STANDARD_TARGET,
2195 .targetsize = sizeof(int), 2196 .targetsize = sizeof(int),
2196 .family = NFPROTO_IPV6, 2197 .family = NFPROTO_IPV6,
2197#ifdef CONFIG_COMPAT 2198#ifdef CONFIG_COMPAT
@@ -2201,9 +2202,9 @@ static struct xt_target ip6t_builtin_tg[] __read_mostly = {
2201#endif 2202#endif
2202 }, 2203 },
2203 { 2204 {
2204 .name = IP6T_ERROR_TARGET, 2205 .name = XT_ERROR_TARGET,
2205 .target = ip6t_error, 2206 .target = ip6t_error,
2206 .targetsize = IP6T_FUNCTION_MAXNAMELEN, 2207 .targetsize = XT_FUNCTION_MAXNAMELEN,
2207 .family = NFPROTO_IPV6, 2208 .family = NFPROTO_IPV6,
2208 }, 2209 },
2209}; 2210};
diff --git a/net/ipv6/netfilter/ip6t_LOG.c b/net/ipv6/netfilter/ip6t_LOG.c
index 0a07ae7b933f..09c88891a753 100644
--- a/net/ipv6/netfilter/ip6t_LOG.c
+++ b/net/ipv6/netfilter/ip6t_LOG.c
@@ -23,6 +23,7 @@
23#include <linux/netfilter/x_tables.h> 23#include <linux/netfilter/x_tables.h>
24#include <linux/netfilter_ipv6/ip6_tables.h> 24#include <linux/netfilter_ipv6/ip6_tables.h>
25#include <net/netfilter/nf_log.h> 25#include <net/netfilter/nf_log.h>
26#include <net/netfilter/xt_log.h>
26 27
27MODULE_AUTHOR("Jan Rekorajski <baggins@pld.org.pl>"); 28MODULE_AUTHOR("Jan Rekorajski <baggins@pld.org.pl>");
28MODULE_DESCRIPTION("Xtables: IPv6 packet logging to syslog"); 29MODULE_DESCRIPTION("Xtables: IPv6 packet logging to syslog");
@@ -32,11 +33,9 @@ struct in_device;
32#include <net/route.h> 33#include <net/route.h>
33#include <linux/netfilter_ipv6/ip6t_LOG.h> 34#include <linux/netfilter_ipv6/ip6t_LOG.h>
34 35
35/* Use lock to serialize, so printks don't overlap */
36static DEFINE_SPINLOCK(log_lock);
37
38/* One level of recursion won't kill us */ 36/* One level of recursion won't kill us */
39static void dump_packet(const struct nf_loginfo *info, 37static void dump_packet(struct sbuff *m,
38 const struct nf_loginfo *info,
40 const struct sk_buff *skb, unsigned int ip6hoff, 39 const struct sk_buff *skb, unsigned int ip6hoff,
41 int recurse) 40 int recurse)
42{ 41{
@@ -55,15 +54,15 @@ static void dump_packet(const struct nf_loginfo *info,
55 54
56 ih = skb_header_pointer(skb, ip6hoff, sizeof(_ip6h), &_ip6h); 55 ih = skb_header_pointer(skb, ip6hoff, sizeof(_ip6h), &_ip6h);
57 if (ih == NULL) { 56 if (ih == NULL) {
58 printk("TRUNCATED"); 57 sb_add(m, "TRUNCATED");
59 return; 58 return;
60 } 59 }
61 60
62 /* Max length: 88 "SRC=0000.0000.0000.0000.0000.0000.0000.0000 DST=0000.0000.0000.0000.0000.0000.0000.0000 " */ 61 /* Max length: 88 "SRC=0000.0000.0000.0000.0000.0000.0000.0000 DST=0000.0000.0000.0000.0000.0000.0000.0000 " */
63 printk("SRC=%pI6 DST=%pI6 ", &ih->saddr, &ih->daddr); 62 sb_add(m, "SRC=%pI6 DST=%pI6 ", &ih->saddr, &ih->daddr);
64 63
65 /* Max length: 44 "LEN=65535 TC=255 HOPLIMIT=255 FLOWLBL=FFFFF " */ 64 /* Max length: 44 "LEN=65535 TC=255 HOPLIMIT=255 FLOWLBL=FFFFF " */
66 printk("LEN=%Zu TC=%u HOPLIMIT=%u FLOWLBL=%u ", 65 sb_add(m, "LEN=%Zu TC=%u HOPLIMIT=%u FLOWLBL=%u ",
67 ntohs(ih->payload_len) + sizeof(struct ipv6hdr), 66 ntohs(ih->payload_len) + sizeof(struct ipv6hdr),
68 (ntohl(*(__be32 *)ih) & 0x0ff00000) >> 20, 67 (ntohl(*(__be32 *)ih) & 0x0ff00000) >> 20,
69 ih->hop_limit, 68 ih->hop_limit,
@@ -78,35 +77,35 @@ static void dump_packet(const struct nf_loginfo *info,
78 77
79 hp = skb_header_pointer(skb, ptr, sizeof(_hdr), &_hdr); 78 hp = skb_header_pointer(skb, ptr, sizeof(_hdr), &_hdr);
80 if (hp == NULL) { 79 if (hp == NULL) {
81 printk("TRUNCATED"); 80 sb_add(m, "TRUNCATED");
82 return; 81 return;
83 } 82 }
84 83
85 /* Max length: 48 "OPT (...) " */ 84 /* Max length: 48 "OPT (...) " */
86 if (logflags & IP6T_LOG_IPOPT) 85 if (logflags & IP6T_LOG_IPOPT)
87 printk("OPT ( "); 86 sb_add(m, "OPT ( ");
88 87
89 switch (currenthdr) { 88 switch (currenthdr) {
90 case IPPROTO_FRAGMENT: { 89 case IPPROTO_FRAGMENT: {
91 struct frag_hdr _fhdr; 90 struct frag_hdr _fhdr;
92 const struct frag_hdr *fh; 91 const struct frag_hdr *fh;
93 92
94 printk("FRAG:"); 93 sb_add(m, "FRAG:");
95 fh = skb_header_pointer(skb, ptr, sizeof(_fhdr), 94 fh = skb_header_pointer(skb, ptr, sizeof(_fhdr),
96 &_fhdr); 95 &_fhdr);
97 if (fh == NULL) { 96 if (fh == NULL) {
98 printk("TRUNCATED "); 97 sb_add(m, "TRUNCATED ");
99 return; 98 return;
100 } 99 }
101 100
102 /* Max length: 6 "65535 " */ 101 /* Max length: 6 "65535 " */
103 printk("%u ", ntohs(fh->frag_off) & 0xFFF8); 102 sb_add(m, "%u ", ntohs(fh->frag_off) & 0xFFF8);
104 103
105 /* Max length: 11 "INCOMPLETE " */ 104 /* Max length: 11 "INCOMPLETE " */
106 if (fh->frag_off & htons(0x0001)) 105 if (fh->frag_off & htons(0x0001))
107 printk("INCOMPLETE "); 106 sb_add(m, "INCOMPLETE ");
108 107
109 printk("ID:%08x ", ntohl(fh->identification)); 108 sb_add(m, "ID:%08x ", ntohl(fh->identification));
110 109
111 if (ntohs(fh->frag_off) & 0xFFF8) 110 if (ntohs(fh->frag_off) & 0xFFF8)
112 fragment = 1; 111 fragment = 1;
@@ -120,7 +119,7 @@ static void dump_packet(const struct nf_loginfo *info,
120 case IPPROTO_HOPOPTS: 119 case IPPROTO_HOPOPTS:
121 if (fragment) { 120 if (fragment) {
122 if (logflags & IP6T_LOG_IPOPT) 121 if (logflags & IP6T_LOG_IPOPT)
123 printk(")"); 122 sb_add(m, ")");
124 return; 123 return;
125 } 124 }
126 hdrlen = ipv6_optlen(hp); 125 hdrlen = ipv6_optlen(hp);
@@ -132,10 +131,10 @@ static void dump_packet(const struct nf_loginfo *info,
132 const struct ip_auth_hdr *ah; 131 const struct ip_auth_hdr *ah;
133 132
134 /* Max length: 3 "AH " */ 133 /* Max length: 3 "AH " */
135 printk("AH "); 134 sb_add(m, "AH ");
136 135
137 if (fragment) { 136 if (fragment) {
138 printk(")"); 137 sb_add(m, ")");
139 return; 138 return;
140 } 139 }
141 140
@@ -146,13 +145,13 @@ static void dump_packet(const struct nf_loginfo *info,
146 * Max length: 26 "INCOMPLETE [65535 145 * Max length: 26 "INCOMPLETE [65535
147 * bytes] )" 146 * bytes] )"
148 */ 147 */
149 printk("INCOMPLETE [%u bytes] )", 148 sb_add(m, "INCOMPLETE [%u bytes] )",
150 skb->len - ptr); 149 skb->len - ptr);
151 return; 150 return;
152 } 151 }
153 152
154 /* Length: 15 "SPI=0xF1234567 */ 153 /* Length: 15 "SPI=0xF1234567 */
155 printk("SPI=0x%x ", ntohl(ah->spi)); 154 sb_add(m, "SPI=0x%x ", ntohl(ah->spi));
156 155
157 } 156 }
158 157
@@ -164,10 +163,10 @@ static void dump_packet(const struct nf_loginfo *info,
164 const struct ip_esp_hdr *eh; 163 const struct ip_esp_hdr *eh;
165 164
166 /* Max length: 4 "ESP " */ 165 /* Max length: 4 "ESP " */
167 printk("ESP "); 166 sb_add(m, "ESP ");
168 167
169 if (fragment) { 168 if (fragment) {
170 printk(")"); 169 sb_add(m, ")");
171 return; 170 return;
172 } 171 }
173 172
@@ -177,23 +176,23 @@ static void dump_packet(const struct nf_loginfo *info,
177 eh = skb_header_pointer(skb, ptr, sizeof(_esph), 176 eh = skb_header_pointer(skb, ptr, sizeof(_esph),
178 &_esph); 177 &_esph);
179 if (eh == NULL) { 178 if (eh == NULL) {
180 printk("INCOMPLETE [%u bytes] )", 179 sb_add(m, "INCOMPLETE [%u bytes] )",
181 skb->len - ptr); 180 skb->len - ptr);
182 return; 181 return;
183 } 182 }
184 183
185 /* Length: 16 "SPI=0xF1234567 )" */ 184 /* Length: 16 "SPI=0xF1234567 )" */
186 printk("SPI=0x%x )", ntohl(eh->spi) ); 185 sb_add(m, "SPI=0x%x )", ntohl(eh->spi) );
187 186
188 } 187 }
189 return; 188 return;
190 default: 189 default:
191 /* Max length: 20 "Unknown Ext Hdr 255" */ 190 /* Max length: 20 "Unknown Ext Hdr 255" */
192 printk("Unknown Ext Hdr %u", currenthdr); 191 sb_add(m, "Unknown Ext Hdr %u", currenthdr);
193 return; 192 return;
194 } 193 }
195 if (logflags & IP6T_LOG_IPOPT) 194 if (logflags & IP6T_LOG_IPOPT)
196 printk(") "); 195 sb_add(m, ") ");
197 196
198 currenthdr = hp->nexthdr; 197 currenthdr = hp->nexthdr;
199 ptr += hdrlen; 198 ptr += hdrlen;
@@ -205,7 +204,7 @@ static void dump_packet(const struct nf_loginfo *info,
205 const struct tcphdr *th; 204 const struct tcphdr *th;
206 205
207 /* Max length: 10 "PROTO=TCP " */ 206 /* Max length: 10 "PROTO=TCP " */
208 printk("PROTO=TCP "); 207 sb_add(m, "PROTO=TCP ");
209 208
210 if (fragment) 209 if (fragment)
211 break; 210 break;
@@ -213,40 +212,40 @@ static void dump_packet(const struct nf_loginfo *info,
213 /* Max length: 25 "INCOMPLETE [65535 bytes] " */ 212 /* Max length: 25 "INCOMPLETE [65535 bytes] " */
214 th = skb_header_pointer(skb, ptr, sizeof(_tcph), &_tcph); 213 th = skb_header_pointer(skb, ptr, sizeof(_tcph), &_tcph);
215 if (th == NULL) { 214 if (th == NULL) {
216 printk("INCOMPLETE [%u bytes] ", skb->len - ptr); 215 sb_add(m, "INCOMPLETE [%u bytes] ", skb->len - ptr);
217 return; 216 return;
218 } 217 }
219 218
220 /* Max length: 20 "SPT=65535 DPT=65535 " */ 219 /* Max length: 20 "SPT=65535 DPT=65535 " */
221 printk("SPT=%u DPT=%u ", 220 sb_add(m, "SPT=%u DPT=%u ",
222 ntohs(th->source), ntohs(th->dest)); 221 ntohs(th->source), ntohs(th->dest));
223 /* Max length: 30 "SEQ=4294967295 ACK=4294967295 " */ 222 /* Max length: 30 "SEQ=4294967295 ACK=4294967295 " */
224 if (logflags & IP6T_LOG_TCPSEQ) 223 if (logflags & IP6T_LOG_TCPSEQ)
225 printk("SEQ=%u ACK=%u ", 224 sb_add(m, "SEQ=%u ACK=%u ",
226 ntohl(th->seq), ntohl(th->ack_seq)); 225 ntohl(th->seq), ntohl(th->ack_seq));
227 /* Max length: 13 "WINDOW=65535 " */ 226 /* Max length: 13 "WINDOW=65535 " */
228 printk("WINDOW=%u ", ntohs(th->window)); 227 sb_add(m, "WINDOW=%u ", ntohs(th->window));
229 /* Max length: 9 "RES=0x3C " */ 228 /* Max length: 9 "RES=0x3C " */
230 printk("RES=0x%02x ", (u_int8_t)(ntohl(tcp_flag_word(th) & TCP_RESERVED_BITS) >> 22)); 229 sb_add(m, "RES=0x%02x ", (u_int8_t)(ntohl(tcp_flag_word(th) & TCP_RESERVED_BITS) >> 22));
231 /* Max length: 32 "CWR ECE URG ACK PSH RST SYN FIN " */ 230 /* Max length: 32 "CWR ECE URG ACK PSH RST SYN FIN " */
232 if (th->cwr) 231 if (th->cwr)
233 printk("CWR "); 232 sb_add(m, "CWR ");
234 if (th->ece) 233 if (th->ece)
235 printk("ECE "); 234 sb_add(m, "ECE ");
236 if (th->urg) 235 if (th->urg)
237 printk("URG "); 236 sb_add(m, "URG ");
238 if (th->ack) 237 if (th->ack)
239 printk("ACK "); 238 sb_add(m, "ACK ");
240 if (th->psh) 239 if (th->psh)
241 printk("PSH "); 240 sb_add(m, "PSH ");
242 if (th->rst) 241 if (th->rst)
243 printk("RST "); 242 sb_add(m, "RST ");
244 if (th->syn) 243 if (th->syn)
245 printk("SYN "); 244 sb_add(m, "SYN ");
246 if (th->fin) 245 if (th->fin)
247 printk("FIN "); 246 sb_add(m, "FIN ");
248 /* Max length: 11 "URGP=65535 " */ 247 /* Max length: 11 "URGP=65535 " */
249 printk("URGP=%u ", ntohs(th->urg_ptr)); 248 sb_add(m, "URGP=%u ", ntohs(th->urg_ptr));
250 249
251 if ((logflags & IP6T_LOG_TCPOPT) && 250 if ((logflags & IP6T_LOG_TCPOPT) &&
252 th->doff * 4 > sizeof(struct tcphdr)) { 251 th->doff * 4 > sizeof(struct tcphdr)) {
@@ -260,15 +259,15 @@ static void dump_packet(const struct nf_loginfo *info,
260 ptr + sizeof(struct tcphdr), 259 ptr + sizeof(struct tcphdr),
261 optsize, _opt); 260 optsize, _opt);
262 if (op == NULL) { 261 if (op == NULL) {
263 printk("OPT (TRUNCATED)"); 262 sb_add(m, "OPT (TRUNCATED)");
264 return; 263 return;
265 } 264 }
266 265
267 /* Max length: 127 "OPT (" 15*4*2chars ") " */ 266 /* Max length: 127 "OPT (" 15*4*2chars ") " */
268 printk("OPT ("); 267 sb_add(m, "OPT (");
269 for (i =0; i < optsize; i++) 268 for (i =0; i < optsize; i++)
270 printk("%02X", op[i]); 269 sb_add(m, "%02X", op[i]);
271 printk(") "); 270 sb_add(m, ") ");
272 } 271 }
273 break; 272 break;
274 } 273 }
@@ -279,9 +278,9 @@ static void dump_packet(const struct nf_loginfo *info,
279 278
280 if (currenthdr == IPPROTO_UDP) 279 if (currenthdr == IPPROTO_UDP)
281 /* Max length: 10 "PROTO=UDP " */ 280 /* Max length: 10 "PROTO=UDP " */
282 printk("PROTO=UDP " ); 281 sb_add(m, "PROTO=UDP " );
283 else /* Max length: 14 "PROTO=UDPLITE " */ 282 else /* Max length: 14 "PROTO=UDPLITE " */
284 printk("PROTO=UDPLITE "); 283 sb_add(m, "PROTO=UDPLITE ");
285 284
286 if (fragment) 285 if (fragment)
287 break; 286 break;
@@ -289,12 +288,12 @@ static void dump_packet(const struct nf_loginfo *info,
289 /* Max length: 25 "INCOMPLETE [65535 bytes] " */ 288 /* Max length: 25 "INCOMPLETE [65535 bytes] " */
290 uh = skb_header_pointer(skb, ptr, sizeof(_udph), &_udph); 289 uh = skb_header_pointer(skb, ptr, sizeof(_udph), &_udph);
291 if (uh == NULL) { 290 if (uh == NULL) {
292 printk("INCOMPLETE [%u bytes] ", skb->len - ptr); 291 sb_add(m, "INCOMPLETE [%u bytes] ", skb->len - ptr);
293 return; 292 return;
294 } 293 }
295 294
296 /* Max length: 20 "SPT=65535 DPT=65535 " */ 295 /* Max length: 20 "SPT=65535 DPT=65535 " */
297 printk("SPT=%u DPT=%u LEN=%u ", 296 sb_add(m, "SPT=%u DPT=%u LEN=%u ",
298 ntohs(uh->source), ntohs(uh->dest), 297 ntohs(uh->source), ntohs(uh->dest),
299 ntohs(uh->len)); 298 ntohs(uh->len));
300 break; 299 break;
@@ -304,7 +303,7 @@ static void dump_packet(const struct nf_loginfo *info,
304 const struct icmp6hdr *ic; 303 const struct icmp6hdr *ic;
305 304
306 /* Max length: 13 "PROTO=ICMPv6 " */ 305 /* Max length: 13 "PROTO=ICMPv6 " */
307 printk("PROTO=ICMPv6 "); 306 sb_add(m, "PROTO=ICMPv6 ");
308 307
309 if (fragment) 308 if (fragment)
310 break; 309 break;
@@ -312,18 +311,18 @@ static void dump_packet(const struct nf_loginfo *info,
312 /* Max length: 25 "INCOMPLETE [65535 bytes] " */ 311 /* Max length: 25 "INCOMPLETE [65535 bytes] " */
313 ic = skb_header_pointer(skb, ptr, sizeof(_icmp6h), &_icmp6h); 312 ic = skb_header_pointer(skb, ptr, sizeof(_icmp6h), &_icmp6h);
314 if (ic == NULL) { 313 if (ic == NULL) {
315 printk("INCOMPLETE [%u bytes] ", skb->len - ptr); 314 sb_add(m, "INCOMPLETE [%u bytes] ", skb->len - ptr);
316 return; 315 return;
317 } 316 }
318 317
319 /* Max length: 18 "TYPE=255 CODE=255 " */ 318 /* Max length: 18 "TYPE=255 CODE=255 " */
320 printk("TYPE=%u CODE=%u ", ic->icmp6_type, ic->icmp6_code); 319 sb_add(m, "TYPE=%u CODE=%u ", ic->icmp6_type, ic->icmp6_code);
321 320
322 switch (ic->icmp6_type) { 321 switch (ic->icmp6_type) {
323 case ICMPV6_ECHO_REQUEST: 322 case ICMPV6_ECHO_REQUEST:
324 case ICMPV6_ECHO_REPLY: 323 case ICMPV6_ECHO_REPLY:
325 /* Max length: 19 "ID=65535 SEQ=65535 " */ 324 /* Max length: 19 "ID=65535 SEQ=65535 " */
326 printk("ID=%u SEQ=%u ", 325 sb_add(m, "ID=%u SEQ=%u ",
327 ntohs(ic->icmp6_identifier), 326 ntohs(ic->icmp6_identifier),
328 ntohs(ic->icmp6_sequence)); 327 ntohs(ic->icmp6_sequence));
329 break; 328 break;
@@ -334,35 +333,35 @@ static void dump_packet(const struct nf_loginfo *info,
334 333
335 case ICMPV6_PARAMPROB: 334 case ICMPV6_PARAMPROB:
336 /* Max length: 17 "POINTER=ffffffff " */ 335 /* Max length: 17 "POINTER=ffffffff " */
337 printk("POINTER=%08x ", ntohl(ic->icmp6_pointer)); 336 sb_add(m, "POINTER=%08x ", ntohl(ic->icmp6_pointer));
338 /* Fall through */ 337 /* Fall through */
339 case ICMPV6_DEST_UNREACH: 338 case ICMPV6_DEST_UNREACH:
340 case ICMPV6_PKT_TOOBIG: 339 case ICMPV6_PKT_TOOBIG:
341 case ICMPV6_TIME_EXCEED: 340 case ICMPV6_TIME_EXCEED:
342 /* Max length: 3+maxlen */ 341 /* Max length: 3+maxlen */
343 if (recurse) { 342 if (recurse) {
344 printk("["); 343 sb_add(m, "[");
345 dump_packet(info, skb, ptr + sizeof(_icmp6h), 344 dump_packet(m, info, skb,
346 0); 345 ptr + sizeof(_icmp6h), 0);
347 printk("] "); 346 sb_add(m, "] ");
348 } 347 }
349 348
350 /* Max length: 10 "MTU=65535 " */ 349 /* Max length: 10 "MTU=65535 " */
351 if (ic->icmp6_type == ICMPV6_PKT_TOOBIG) 350 if (ic->icmp6_type == ICMPV6_PKT_TOOBIG)
352 printk("MTU=%u ", ntohl(ic->icmp6_mtu)); 351 sb_add(m, "MTU=%u ", ntohl(ic->icmp6_mtu));
353 } 352 }
354 break; 353 break;
355 } 354 }
356 /* Max length: 10 "PROTO=255 " */ 355 /* Max length: 10 "PROTO=255 " */
357 default: 356 default:
358 printk("PROTO=%u ", currenthdr); 357 sb_add(m, "PROTO=%u ", currenthdr);
359 } 358 }
360 359
361 /* Max length: 15 "UID=4294967295 " */ 360 /* Max length: 15 "UID=4294967295 " */
362 if ((logflags & IP6T_LOG_UID) && recurse && skb->sk) { 361 if ((logflags & IP6T_LOG_UID) && recurse && skb->sk) {
363 read_lock_bh(&skb->sk->sk_callback_lock); 362 read_lock_bh(&skb->sk->sk_callback_lock);
364 if (skb->sk->sk_socket && skb->sk->sk_socket->file) 363 if (skb->sk->sk_socket && skb->sk->sk_socket->file)
365 printk("UID=%u GID=%u ", 364 sb_add(m, "UID=%u GID=%u ",
366 skb->sk->sk_socket->file->f_cred->fsuid, 365 skb->sk->sk_socket->file->f_cred->fsuid,
367 skb->sk->sk_socket->file->f_cred->fsgid); 366 skb->sk->sk_socket->file->f_cred->fsgid);
368 read_unlock_bh(&skb->sk->sk_callback_lock); 367 read_unlock_bh(&skb->sk->sk_callback_lock);
@@ -370,10 +369,11 @@ static void dump_packet(const struct nf_loginfo *info,
370 369
371 /* Max length: 16 "MARK=0xFFFFFFFF " */ 370 /* Max length: 16 "MARK=0xFFFFFFFF " */
372 if (!recurse && skb->mark) 371 if (!recurse && skb->mark)
373 printk("MARK=0x%x ", skb->mark); 372 sb_add(m, "MARK=0x%x ", skb->mark);
374} 373}
375 374
376static void dump_mac_header(const struct nf_loginfo *info, 375static void dump_mac_header(struct sbuff *m,
376 const struct nf_loginfo *info,
377 const struct sk_buff *skb) 377 const struct sk_buff *skb)
378{ 378{
379 struct net_device *dev = skb->dev; 379 struct net_device *dev = skb->dev;
@@ -387,7 +387,7 @@ static void dump_mac_header(const struct nf_loginfo *info,
387 387
388 switch (dev->type) { 388 switch (dev->type) {
389 case ARPHRD_ETHER: 389 case ARPHRD_ETHER:
390 printk("MACSRC=%pM MACDST=%pM MACPROTO=%04x ", 390 sb_add(m, "MACSRC=%pM MACDST=%pM MACPROTO=%04x ",
391 eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest, 391 eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest,
392 ntohs(eth_hdr(skb)->h_proto)); 392 ntohs(eth_hdr(skb)->h_proto));
393 return; 393 return;
@@ -396,7 +396,7 @@ static void dump_mac_header(const struct nf_loginfo *info,
396 } 396 }
397 397
398fallback: 398fallback:
399 printk("MAC="); 399 sb_add(m, "MAC=");
400 if (dev->hard_header_len && 400 if (dev->hard_header_len &&
401 skb->mac_header != skb->network_header) { 401 skb->mac_header != skb->network_header) {
402 const unsigned char *p = skb_mac_header(skb); 402 const unsigned char *p = skb_mac_header(skb);
@@ -408,19 +408,19 @@ fallback:
408 p = NULL; 408 p = NULL;
409 409
410 if (p != NULL) { 410 if (p != NULL) {
411 printk("%02x", *p++); 411 sb_add(m, "%02x", *p++);
412 for (i = 1; i < len; i++) 412 for (i = 1; i < len; i++)
413 printk(":%02x", p[i]); 413 sb_add(m, ":%02x", p[i]);
414 } 414 }
415 printk(" "); 415 sb_add(m, " ");
416 416
417 if (dev->type == ARPHRD_SIT) { 417 if (dev->type == ARPHRD_SIT) {
418 const struct iphdr *iph = 418 const struct iphdr *iph =
419 (struct iphdr *)skb_mac_header(skb); 419 (struct iphdr *)skb_mac_header(skb);
420 printk("TUNNEL=%pI4->%pI4 ", &iph->saddr, &iph->daddr); 420 sb_add(m, "TUNNEL=%pI4->%pI4 ", &iph->saddr, &iph->daddr);
421 } 421 }
422 } else 422 } else
423 printk(" "); 423 sb_add(m, " ");
424} 424}
425 425
426static struct nf_loginfo default_loginfo = { 426static struct nf_loginfo default_loginfo = {
@@ -442,22 +442,23 @@ ip6t_log_packet(u_int8_t pf,
442 const struct nf_loginfo *loginfo, 442 const struct nf_loginfo *loginfo,
443 const char *prefix) 443 const char *prefix)
444{ 444{
445 struct sbuff *m = sb_open();
446
445 if (!loginfo) 447 if (!loginfo)
446 loginfo = &default_loginfo; 448 loginfo = &default_loginfo;
447 449
448 spin_lock_bh(&log_lock); 450 sb_add(m, "<%d>%sIN=%s OUT=%s ", loginfo->u.log.level,
449 printk("<%d>%sIN=%s OUT=%s ", loginfo->u.log.level, 451 prefix,
450 prefix, 452 in ? in->name : "",
451 in ? in->name : "", 453 out ? out->name : "");
452 out ? out->name : "");
453 454
454 /* MAC logging for input path only. */ 455 /* MAC logging for input path only. */
455 if (in && !out) 456 if (in && !out)
456 dump_mac_header(loginfo, skb); 457 dump_mac_header(m, loginfo, skb);
458
459 dump_packet(m, loginfo, skb, skb_network_offset(skb), 1);
457 460
458 dump_packet(loginfo, skb, skb_network_offset(skb), 1); 461 sb_close(m);
459 printk("\n");
460 spin_unlock_bh(&log_lock);
461} 462}
462 463
463static unsigned int 464static unsigned int
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index ff43461704be..c8af58b22562 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -16,7 +16,6 @@
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/skbuff.h> 17#include <linux/skbuff.h>
18#include <linux/icmp.h> 18#include <linux/icmp.h>
19#include <linux/sysctl.h>
20#include <net/ipv6.h> 19#include <net/ipv6.h>
21#include <net/inet_frag.h> 20#include <net/inet_frag.h>
22 21
@@ -29,6 +28,7 @@
29#include <net/netfilter/nf_conntrack_core.h> 28#include <net/netfilter/nf_conntrack_core.h>
30#include <net/netfilter/nf_conntrack_zones.h> 29#include <net/netfilter/nf_conntrack_zones.h>
31#include <net/netfilter/ipv6/nf_conntrack_ipv6.h> 30#include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
31#include <net/netfilter/ipv6/nf_defrag_ipv6.h>
32#include <net/netfilter/nf_log.h> 32#include <net/netfilter/nf_log.h>
33 33
34static bool ipv6_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff, 34static bool ipv6_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
@@ -189,53 +189,6 @@ out:
189 return nf_conntrack_confirm(skb); 189 return nf_conntrack_confirm(skb);
190} 190}
191 191
192static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum,
193 struct sk_buff *skb)
194{
195 u16 zone = NF_CT_DEFAULT_ZONE;
196
197 if (skb->nfct)
198 zone = nf_ct_zone((struct nf_conn *)skb->nfct);
199
200#ifdef CONFIG_BRIDGE_NETFILTER
201 if (skb->nf_bridge &&
202 skb->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING)
203 return IP6_DEFRAG_CONNTRACK_BRIDGE_IN + zone;
204#endif
205 if (hooknum == NF_INET_PRE_ROUTING)
206 return IP6_DEFRAG_CONNTRACK_IN + zone;
207 else
208 return IP6_DEFRAG_CONNTRACK_OUT + zone;
209
210}
211
212static unsigned int ipv6_defrag(unsigned int hooknum,
213 struct sk_buff *skb,
214 const struct net_device *in,
215 const struct net_device *out,
216 int (*okfn)(struct sk_buff *))
217{
218 struct sk_buff *reasm;
219
220 /* Previously seen (loopback)? */
221 if (skb->nfct && !nf_ct_is_template((struct nf_conn *)skb->nfct))
222 return NF_ACCEPT;
223
224 reasm = nf_ct_frag6_gather(skb, nf_ct6_defrag_user(hooknum, skb));
225 /* queued */
226 if (reasm == NULL)
227 return NF_STOLEN;
228
229 /* error occured or not fragmented */
230 if (reasm == skb)
231 return NF_ACCEPT;
232
233 nf_ct_frag6_output(hooknum, reasm, (struct net_device *)in,
234 (struct net_device *)out, okfn);
235
236 return NF_STOLEN;
237}
238
239static unsigned int __ipv6_conntrack_in(struct net *net, 192static unsigned int __ipv6_conntrack_in(struct net *net,
240 unsigned int hooknum, 193 unsigned int hooknum,
241 struct sk_buff *skb, 194 struct sk_buff *skb,
@@ -288,13 +241,6 @@ static unsigned int ipv6_conntrack_local(unsigned int hooknum,
288 241
289static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = { 242static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = {
290 { 243 {
291 .hook = ipv6_defrag,
292 .owner = THIS_MODULE,
293 .pf = NFPROTO_IPV6,
294 .hooknum = NF_INET_PRE_ROUTING,
295 .priority = NF_IP6_PRI_CONNTRACK_DEFRAG,
296 },
297 {
298 .hook = ipv6_conntrack_in, 244 .hook = ipv6_conntrack_in,
299 .owner = THIS_MODULE, 245 .owner = THIS_MODULE,
300 .pf = NFPROTO_IPV6, 246 .pf = NFPROTO_IPV6,
@@ -309,13 +255,6 @@ static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = {
309 .priority = NF_IP6_PRI_CONNTRACK, 255 .priority = NF_IP6_PRI_CONNTRACK,
310 }, 256 },
311 { 257 {
312 .hook = ipv6_defrag,
313 .owner = THIS_MODULE,
314 .pf = NFPROTO_IPV6,
315 .hooknum = NF_INET_LOCAL_OUT,
316 .priority = NF_IP6_PRI_CONNTRACK_DEFRAG,
317 },
318 {
319 .hook = ipv6_confirm, 258 .hook = ipv6_confirm,
320 .owner = THIS_MODULE, 259 .owner = THIS_MODULE,
321 .pf = NFPROTO_IPV6, 260 .pf = NFPROTO_IPV6,
@@ -387,10 +326,6 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6 __read_mostly = {
387 .nlattr_to_tuple = ipv6_nlattr_to_tuple, 326 .nlattr_to_tuple = ipv6_nlattr_to_tuple,
388 .nla_policy = ipv6_nla_policy, 327 .nla_policy = ipv6_nla_policy,
389#endif 328#endif
390#ifdef CONFIG_SYSCTL
391 .ctl_table_path = nf_net_netfilter_sysctl_path,
392 .ctl_table = nf_ct_ipv6_sysctl_table,
393#endif
394 .me = THIS_MODULE, 329 .me = THIS_MODULE,
395}; 330};
396 331
@@ -403,16 +338,12 @@ static int __init nf_conntrack_l3proto_ipv6_init(void)
403 int ret = 0; 338 int ret = 0;
404 339
405 need_conntrack(); 340 need_conntrack();
341 nf_defrag_ipv6_enable();
406 342
407 ret = nf_ct_frag6_init();
408 if (ret < 0) {
409 pr_err("nf_conntrack_ipv6: can't initialize frag6.\n");
410 return ret;
411 }
412 ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_tcp6); 343 ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_tcp6);
413 if (ret < 0) { 344 if (ret < 0) {
414 pr_err("nf_conntrack_ipv6: can't register tcp.\n"); 345 pr_err("nf_conntrack_ipv6: can't register tcp.\n");
415 goto cleanup_frag6; 346 return ret;
416 } 347 }
417 348
418 ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_udp6); 349 ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_udp6);
@@ -450,8 +381,6 @@ static int __init nf_conntrack_l3proto_ipv6_init(void)
450 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp6); 381 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp6);
451 cleanup_tcp: 382 cleanup_tcp:
452 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp6); 383 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp6);
453 cleanup_frag6:
454 nf_ct_frag6_cleanup();
455 return ret; 384 return ret;
456} 385}
457 386
@@ -463,7 +392,6 @@ static void __exit nf_conntrack_l3proto_ipv6_fini(void)
463 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_icmpv6); 392 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_icmpv6);
464 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp6); 393 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp6);
465 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp6); 394 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp6);
466 nf_ct_frag6_cleanup();
467} 395}
468 396
469module_init(nf_conntrack_l3proto_ipv6_init); 397module_init(nf_conntrack_l3proto_ipv6_init);
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index 578f3c1a16db..79d43aa8fa8d 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -73,7 +73,7 @@ static struct inet_frags nf_frags;
73static struct netns_frags nf_init_frags; 73static struct netns_frags nf_init_frags;
74 74
75#ifdef CONFIG_SYSCTL 75#ifdef CONFIG_SYSCTL
76struct ctl_table nf_ct_ipv6_sysctl_table[] = { 76struct ctl_table nf_ct_frag6_sysctl_table[] = {
77 { 77 {
78 .procname = "nf_conntrack_frag6_timeout", 78 .procname = "nf_conntrack_frag6_timeout",
79 .data = &nf_init_frags.timeout, 79 .data = &nf_init_frags.timeout,
@@ -97,6 +97,8 @@ struct ctl_table nf_ct_ipv6_sysctl_table[] = {
97 }, 97 },
98 { } 98 { }
99}; 99};
100
101static struct ctl_table_header *nf_ct_frag6_sysctl_header;
100#endif 102#endif
101 103
102static unsigned int nf_hashfn(struct inet_frag_queue *q) 104static unsigned int nf_hashfn(struct inet_frag_queue *q)
@@ -284,7 +286,7 @@ found:
284 286
285 /* Check for overlap with preceding fragment. */ 287 /* Check for overlap with preceding fragment. */
286 if (prev && 288 if (prev &&
287 (NFCT_FRAG6_CB(prev)->offset + prev->len) - offset > 0) 289 (NFCT_FRAG6_CB(prev)->offset + prev->len) > offset)
288 goto discard_fq; 290 goto discard_fq;
289 291
290 /* Look for overlap with succeeding segment. */ 292 /* Look for overlap with succeeding segment. */
@@ -363,7 +365,7 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)
363 /* If the first fragment is fragmented itself, we split 365 /* If the first fragment is fragmented itself, we split
364 * it to two chunks: the first with data and paged part 366 * it to two chunks: the first with data and paged part
365 * and the second, holding only fragments. */ 367 * and the second, holding only fragments. */
366 if (skb_has_frags(head)) { 368 if (skb_has_frag_list(head)) {
367 struct sk_buff *clone; 369 struct sk_buff *clone;
368 int i, plen = 0; 370 int i, plen = 0;
369 371
@@ -623,11 +625,24 @@ int nf_ct_frag6_init(void)
623 inet_frags_init_net(&nf_init_frags); 625 inet_frags_init_net(&nf_init_frags);
624 inet_frags_init(&nf_frags); 626 inet_frags_init(&nf_frags);
625 627
628#ifdef CONFIG_SYSCTL
629 nf_ct_frag6_sysctl_header = register_sysctl_paths(nf_net_netfilter_sysctl_path,
630 nf_ct_frag6_sysctl_table);
631 if (!nf_ct_frag6_sysctl_header) {
632 inet_frags_fini(&nf_frags);
633 return -ENOMEM;
634 }
635#endif
636
626 return 0; 637 return 0;
627} 638}
628 639
629void nf_ct_frag6_cleanup(void) 640void nf_ct_frag6_cleanup(void)
630{ 641{
642#ifdef CONFIG_SYSCTL
643 unregister_sysctl_table(nf_ct_frag6_sysctl_header);
644 nf_ct_frag6_sysctl_header = NULL;
645#endif
631 inet_frags_fini(&nf_frags); 646 inet_frags_fini(&nf_frags);
632 647
633 nf_init_frags.low_thresh = 0; 648 nf_init_frags.low_thresh = 0;
diff --git a/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
new file mode 100644
index 000000000000..99abfb53bab9
--- /dev/null
+++ b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
@@ -0,0 +1,131 @@
1/* (C) 1999-2001 Paul `Rusty' Russell
2 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include <linux/types.h>
10#include <linux/ipv6.h>
11#include <linux/in6.h>
12#include <linux/netfilter.h>
13#include <linux/module.h>
14#include <linux/skbuff.h>
15#include <linux/icmp.h>
16#include <linux/sysctl.h>
17#include <net/ipv6.h>
18#include <net/inet_frag.h>
19
20#include <linux/netfilter_ipv6.h>
21#include <linux/netfilter_bridge.h>
22#include <net/netfilter/nf_conntrack.h>
23#include <net/netfilter/nf_conntrack_helper.h>
24#include <net/netfilter/nf_conntrack_l4proto.h>
25#include <net/netfilter/nf_conntrack_l3proto.h>
26#include <net/netfilter/nf_conntrack_core.h>
27#include <net/netfilter/nf_conntrack_zones.h>
28#include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
29#include <net/netfilter/ipv6/nf_defrag_ipv6.h>
30
31static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum,
32 struct sk_buff *skb)
33{
34 u16 zone = NF_CT_DEFAULT_ZONE;
35
36 if (skb->nfct)
37 zone = nf_ct_zone((struct nf_conn *)skb->nfct);
38
39#ifdef CONFIG_BRIDGE_NETFILTER
40 if (skb->nf_bridge &&
41 skb->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING)
42 return IP6_DEFRAG_CONNTRACK_BRIDGE_IN + zone;
43#endif
44 if (hooknum == NF_INET_PRE_ROUTING)
45 return IP6_DEFRAG_CONNTRACK_IN + zone;
46 else
47 return IP6_DEFRAG_CONNTRACK_OUT + zone;
48
49}
50
51static unsigned int ipv6_defrag(unsigned int hooknum,
52 struct sk_buff *skb,
53 const struct net_device *in,
54 const struct net_device *out,
55 int (*okfn)(struct sk_buff *))
56{
57 struct sk_buff *reasm;
58
59 /* Previously seen (loopback)? */
60 if (skb->nfct && !nf_ct_is_template((struct nf_conn *)skb->nfct))
61 return NF_ACCEPT;
62
63 reasm = nf_ct_frag6_gather(skb, nf_ct6_defrag_user(hooknum, skb));
64 /* queued */
65 if (reasm == NULL)
66 return NF_STOLEN;
67
68 /* error occured or not fragmented */
69 if (reasm == skb)
70 return NF_ACCEPT;
71
72 nf_ct_frag6_output(hooknum, reasm, (struct net_device *)in,
73 (struct net_device *)out, okfn);
74
75 return NF_STOLEN;
76}
77
78static struct nf_hook_ops ipv6_defrag_ops[] = {
79 {
80 .hook = ipv6_defrag,
81 .owner = THIS_MODULE,
82 .pf = NFPROTO_IPV6,
83 .hooknum = NF_INET_PRE_ROUTING,
84 .priority = NF_IP6_PRI_CONNTRACK_DEFRAG,
85 },
86 {
87 .hook = ipv6_defrag,
88 .owner = THIS_MODULE,
89 .pf = NFPROTO_IPV6,
90 .hooknum = NF_INET_LOCAL_OUT,
91 .priority = NF_IP6_PRI_CONNTRACK_DEFRAG,
92 },
93};
94
95static int __init nf_defrag_init(void)
96{
97 int ret = 0;
98
99 ret = nf_ct_frag6_init();
100 if (ret < 0) {
101 pr_err("nf_defrag_ipv6: can't initialize frag6.\n");
102 return ret;
103 }
104 ret = nf_register_hooks(ipv6_defrag_ops, ARRAY_SIZE(ipv6_defrag_ops));
105 if (ret < 0) {
106 pr_err("nf_defrag_ipv6: can't register hooks\n");
107 goto cleanup_frag6;
108 }
109 return ret;
110
111cleanup_frag6:
112 nf_ct_frag6_cleanup();
113 return ret;
114
115}
116
117static void __exit nf_defrag_fini(void)
118{
119 nf_unregister_hooks(ipv6_defrag_ops, ARRAY_SIZE(ipv6_defrag_ops));
120 nf_ct_frag6_cleanup();
121}
122
123void nf_defrag_ipv6_enable(void)
124{
125}
126EXPORT_SYMBOL_GPL(nf_defrag_ipv6_enable);
127
128module_init(nf_defrag_init);
129module_exit(nf_defrag_fini);
130
131MODULE_LICENSE("GPL");
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c
index d082eaeefa25..24b3558b8e67 100644
--- a/net/ipv6/proc.c
+++ b/net/ipv6/proc.c
@@ -126,6 +126,8 @@ static const struct snmp_mib snmp6_udp6_list[] = {
126 SNMP_MIB_ITEM("Udp6NoPorts", UDP_MIB_NOPORTS), 126 SNMP_MIB_ITEM("Udp6NoPorts", UDP_MIB_NOPORTS),
127 SNMP_MIB_ITEM("Udp6InErrors", UDP_MIB_INERRORS), 127 SNMP_MIB_ITEM("Udp6InErrors", UDP_MIB_INERRORS),
128 SNMP_MIB_ITEM("Udp6OutDatagrams", UDP_MIB_OUTDATAGRAMS), 128 SNMP_MIB_ITEM("Udp6OutDatagrams", UDP_MIB_OUTDATAGRAMS),
129 SNMP_MIB_ITEM("Udp6RcvbufErrors", UDP_MIB_RCVBUFERRORS),
130 SNMP_MIB_ITEM("Udp6SndbufErrors", UDP_MIB_SNDBUFERRORS),
129 SNMP_MIB_SENTINEL 131 SNMP_MIB_SENTINEL
130}; 132};
131 133
@@ -134,6 +136,8 @@ static const struct snmp_mib snmp6_udplite6_list[] = {
134 SNMP_MIB_ITEM("UdpLite6NoPorts", UDP_MIB_NOPORTS), 136 SNMP_MIB_ITEM("UdpLite6NoPorts", UDP_MIB_NOPORTS),
135 SNMP_MIB_ITEM("UdpLite6InErrors", UDP_MIB_INERRORS), 137 SNMP_MIB_ITEM("UdpLite6InErrors", UDP_MIB_INERRORS),
136 SNMP_MIB_ITEM("UdpLite6OutDatagrams", UDP_MIB_OUTDATAGRAMS), 138 SNMP_MIB_ITEM("UdpLite6OutDatagrams", UDP_MIB_OUTDATAGRAMS),
139 SNMP_MIB_ITEM("UdpLite6RcvbufErrors", UDP_MIB_RCVBUFERRORS),
140 SNMP_MIB_ITEM("UdpLite6SndbufErrors", UDP_MIB_SNDBUFERRORS),
137 SNMP_MIB_SENTINEL 141 SNMP_MIB_SENTINEL
138}; 142};
139 143
diff --git a/net/ipv6/protocol.c b/net/ipv6/protocol.c
index 1fa3468f0f32..9a7978fdc02a 100644
--- a/net/ipv6/protocol.c
+++ b/net/ipv6/protocol.c
@@ -25,28 +25,15 @@
25#include <linux/spinlock.h> 25#include <linux/spinlock.h>
26#include <net/protocol.h> 26#include <net/protocol.h>
27 27
28const struct inet6_protocol *inet6_protos[MAX_INET_PROTOS]; 28const struct inet6_protocol __rcu *inet6_protos[MAX_INET_PROTOS] __read_mostly;
29static DEFINE_SPINLOCK(inet6_proto_lock);
30
31 29
32int inet6_add_protocol(const struct inet6_protocol *prot, unsigned char protocol) 30int inet6_add_protocol(const struct inet6_protocol *prot, unsigned char protocol)
33{ 31{
34 int ret, hash = protocol & (MAX_INET_PROTOS - 1); 32 int hash = protocol & (MAX_INET_PROTOS - 1);
35
36 spin_lock_bh(&inet6_proto_lock);
37
38 if (inet6_protos[hash]) {
39 ret = -1;
40 } else {
41 inet6_protos[hash] = prot;
42 ret = 0;
43 }
44
45 spin_unlock_bh(&inet6_proto_lock);
46 33
47 return ret; 34 return !cmpxchg((const struct inet6_protocol **)&inet6_protos[hash],
35 NULL, prot) ? 0 : -1;
48} 36}
49
50EXPORT_SYMBOL(inet6_add_protocol); 37EXPORT_SYMBOL(inet6_add_protocol);
51 38
52/* 39/*
@@ -57,20 +44,11 @@ int inet6_del_protocol(const struct inet6_protocol *prot, unsigned char protocol
57{ 44{
58 int ret, hash = protocol & (MAX_INET_PROTOS - 1); 45 int ret, hash = protocol & (MAX_INET_PROTOS - 1);
59 46
60 spin_lock_bh(&inet6_proto_lock); 47 ret = (cmpxchg((const struct inet6_protocol **)&inet6_protos[hash],
61 48 prot, NULL) == prot) ? 0 : -1;
62 if (inet6_protos[hash] != prot) {
63 ret = -1;
64 } else {
65 inet6_protos[hash] = NULL;
66 ret = 0;
67 }
68
69 spin_unlock_bh(&inet6_proto_lock);
70 49
71 synchronize_net(); 50 synchronize_net();
72 51
73 return ret; 52 return ret;
74} 53}
75
76EXPORT_SYMBOL(inet6_del_protocol); 54EXPORT_SYMBOL(inet6_del_protocol);
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index e677937a07fc..86c39526ba5e 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -373,7 +373,7 @@ void raw6_icmp_error(struct sk_buff *skb, int nexthdr,
373 373
374static inline int rawv6_rcv_skb(struct sock * sk, struct sk_buff * skb) 374static inline int rawv6_rcv_skb(struct sock * sk, struct sk_buff * skb)
375{ 375{
376 if ((raw6_sk(sk)->checksum || sk->sk_filter) && 376 if ((raw6_sk(sk)->checksum || rcu_dereference_raw(sk->sk_filter)) &&
377 skb_checksum_complete(skb)) { 377 skb_checksum_complete(skb)) {
378 atomic_inc(&sk->sk_drops); 378 atomic_inc(&sk->sk_drops);
379 kfree_skb(skb); 379 kfree_skb(skb);
@@ -764,7 +764,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
764 return -EINVAL; 764 return -EINVAL;
765 765
766 if (sin6->sin6_family && sin6->sin6_family != AF_INET6) 766 if (sin6->sin6_family && sin6->sin6_family != AF_INET6)
767 return(-EAFNOSUPPORT); 767 return -EAFNOSUPPORT;
768 768
769 /* port is the proto value [0..255] carried in nexthdr */ 769 /* port is the proto value [0..255] carried in nexthdr */
770 proto = ntohs(sin6->sin6_port); 770 proto = ntohs(sin6->sin6_port);
@@ -772,10 +772,10 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
772 if (!proto) 772 if (!proto)
773 proto = inet->inet_num; 773 proto = inet->inet_num;
774 else if (proto != inet->inet_num) 774 else if (proto != inet->inet_num)
775 return(-EINVAL); 775 return -EINVAL;
776 776
777 if (proto > 255) 777 if (proto > 255)
778 return(-EINVAL); 778 return -EINVAL;
779 779
780 daddr = &sin6->sin6_addr; 780 daddr = &sin6->sin6_addr;
781 if (np->sndflow) { 781 if (np->sndflow) {
@@ -985,7 +985,7 @@ static int do_rawv6_setsockopt(struct sock *sk, int level, int optname,
985 /* You may get strange result with a positive odd offset; 985 /* You may get strange result with a positive odd offset;
986 RFC2292bis agrees with me. */ 986 RFC2292bis agrees with me. */
987 if (val > 0 && (val&1)) 987 if (val > 0 && (val&1))
988 return(-EINVAL); 988 return -EINVAL;
989 if (val < 0) { 989 if (val < 0) {
990 rp->checksum = 0; 990 rp->checksum = 0;
991 } else { 991 } else {
@@ -997,7 +997,7 @@ static int do_rawv6_setsockopt(struct sock *sk, int level, int optname,
997 break; 997 break;
998 998
999 default: 999 default:
1000 return(-ENOPROTOOPT); 1000 return -ENOPROTOOPT;
1001 } 1001 }
1002} 1002}
1003 1003
@@ -1190,7 +1190,7 @@ static int rawv6_init_sk(struct sock *sk)
1190 default: 1190 default:
1191 break; 1191 break;
1192 } 1192 }
1193 return(0); 1193 return 0;
1194} 1194}
1195 1195
1196struct proto rawv6_prot = { 1196struct proto rawv6_prot = {
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 64cfef1b0a4c..0f2766453759 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -349,7 +349,7 @@ found:
349 349
350 /* Check for overlap with preceding fragment. */ 350 /* Check for overlap with preceding fragment. */
351 if (prev && 351 if (prev &&
352 (FRAG6_CB(prev)->offset + prev->len) - offset > 0) 352 (FRAG6_CB(prev)->offset + prev->len) > offset)
353 goto discard_fq; 353 goto discard_fq;
354 354
355 /* Look for overlap with succeeding segment. */ 355 /* Look for overlap with succeeding segment. */
@@ -458,7 +458,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev,
458 /* If the first fragment is fragmented itself, we split 458 /* If the first fragment is fragmented itself, we split
459 * it to two chunks: the first with data and paged part 459 * it to two chunks: the first with data and paged part
460 * and the second, holding only fragments. */ 460 * and the second, holding only fragments. */
461 if (skb_has_frags(head)) { 461 if (skb_has_frag_list(head)) {
462 struct sk_buff *clone; 462 struct sk_buff *clone;
463 int i, plen = 0; 463 int i, plen = 0;
464 464
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index a275c6e1e25c..96455ffb76fb 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -109,7 +109,6 @@ static struct dst_ops ip6_dst_ops_template = {
109 .link_failure = ip6_link_failure, 109 .link_failure = ip6_link_failure,
110 .update_pmtu = ip6_rt_update_pmtu, 110 .update_pmtu = ip6_rt_update_pmtu,
111 .local_out = __ip6_local_out, 111 .local_out = __ip6_local_out,
112 .entries = ATOMIC_INIT(0),
113}; 112};
114 113
115static void ip6_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu) 114static void ip6_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu)
@@ -122,7 +121,6 @@ static struct dst_ops ip6_dst_blackhole_ops = {
122 .destroy = ip6_dst_destroy, 121 .destroy = ip6_dst_destroy,
123 .check = ip6_dst_check, 122 .check = ip6_dst_check,
124 .update_pmtu = ip6_rt_blackhole_update_pmtu, 123 .update_pmtu = ip6_rt_blackhole_update_pmtu,
125 .entries = ATOMIC_INIT(0),
126}; 124};
127 125
128static struct rt6_info ip6_null_entry_template = { 126static struct rt6_info ip6_null_entry_template = {
@@ -217,14 +215,14 @@ static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
217 215
218static __inline__ int rt6_check_expired(const struct rt6_info *rt) 216static __inline__ int rt6_check_expired(const struct rt6_info *rt)
219{ 217{
220 return (rt->rt6i_flags & RTF_EXPIRES && 218 return (rt->rt6i_flags & RTF_EXPIRES) &&
221 time_after(jiffies, rt->rt6i_expires)); 219 time_after(jiffies, rt->rt6i_expires);
222} 220}
223 221
224static inline int rt6_need_strict(struct in6_addr *daddr) 222static inline int rt6_need_strict(struct in6_addr *daddr)
225{ 223{
226 return (ipv6_addr_type(daddr) & 224 return ipv6_addr_type(daddr) &
227 (IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL | IPV6_ADDR_LOOPBACK)); 225 (IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL | IPV6_ADDR_LOOPBACK);
228} 226}
229 227
230/* 228/*
@@ -440,7 +438,7 @@ static struct rt6_info *rt6_select(struct fib6_node *fn, int oif, int strict)
440 __func__, match); 438 __func__, match);
441 439
442 net = dev_net(rt0->rt6i_dev); 440 net = dev_net(rt0->rt6i_dev);
443 return (match ? match : net->ipv6.ip6_null_entry); 441 return match ? match : net->ipv6.ip6_null_entry;
444} 442}
445 443
446#ifdef CONFIG_IPV6_ROUTE_INFO 444#ifdef CONFIG_IPV6_ROUTE_INFO
@@ -859,7 +857,7 @@ int ip6_dst_blackhole(struct sock *sk, struct dst_entry **dstp, struct flowi *fl
859 857
860 dst_release(*dstp); 858 dst_release(*dstp);
861 *dstp = new; 859 *dstp = new;
862 return (new ? 0 : -ENOMEM); 860 return new ? 0 : -ENOMEM;
863} 861}
864EXPORT_SYMBOL_GPL(ip6_dst_blackhole); 862EXPORT_SYMBOL_GPL(ip6_dst_blackhole);
865 863
@@ -1058,19 +1056,22 @@ static int ip6_dst_gc(struct dst_ops *ops)
1058 int rt_elasticity = net->ipv6.sysctl.ip6_rt_gc_elasticity; 1056 int rt_elasticity = net->ipv6.sysctl.ip6_rt_gc_elasticity;
1059 int rt_gc_timeout = net->ipv6.sysctl.ip6_rt_gc_timeout; 1057 int rt_gc_timeout = net->ipv6.sysctl.ip6_rt_gc_timeout;
1060 unsigned long rt_last_gc = net->ipv6.ip6_rt_last_gc; 1058 unsigned long rt_last_gc = net->ipv6.ip6_rt_last_gc;
1059 int entries;
1061 1060
1061 entries = dst_entries_get_fast(ops);
1062 if (time_after(rt_last_gc + rt_min_interval, now) && 1062 if (time_after(rt_last_gc + rt_min_interval, now) &&
1063 atomic_read(&ops->entries) <= rt_max_size) 1063 entries <= rt_max_size)
1064 goto out; 1064 goto out;
1065 1065
1066 net->ipv6.ip6_rt_gc_expire++; 1066 net->ipv6.ip6_rt_gc_expire++;
1067 fib6_run_gc(net->ipv6.ip6_rt_gc_expire, net); 1067 fib6_run_gc(net->ipv6.ip6_rt_gc_expire, net);
1068 net->ipv6.ip6_rt_last_gc = now; 1068 net->ipv6.ip6_rt_last_gc = now;
1069 if (atomic_read(&ops->entries) < ops->gc_thresh) 1069 entries = dst_entries_get_slow(ops);
1070 if (entries < ops->gc_thresh)
1070 net->ipv6.ip6_rt_gc_expire = rt_gc_timeout>>1; 1071 net->ipv6.ip6_rt_gc_expire = rt_gc_timeout>>1;
1071out: 1072out:
1072 net->ipv6.ip6_rt_gc_expire -= net->ipv6.ip6_rt_gc_expire>>rt_elasticity; 1073 net->ipv6.ip6_rt_gc_expire -= net->ipv6.ip6_rt_gc_expire>>rt_elasticity;
1073 return (atomic_read(&ops->entries) > rt_max_size); 1074 return entries > rt_max_size;
1074} 1075}
1075 1076
1076/* Clean host part of a prefix. Not necessary in radix tree, 1077/* Clean host part of a prefix. Not necessary in radix tree,
@@ -1169,6 +1170,8 @@ int ip6_route_add(struct fib6_config *cfg)
1169 1170
1170 if (addr_type & IPV6_ADDR_MULTICAST) 1171 if (addr_type & IPV6_ADDR_MULTICAST)
1171 rt->dst.input = ip6_mc_input; 1172 rt->dst.input = ip6_mc_input;
1173 else if (cfg->fc_flags & RTF_LOCAL)
1174 rt->dst.input = ip6_input;
1172 else 1175 else
1173 rt->dst.input = ip6_forward; 1176 rt->dst.input = ip6_forward;
1174 1177
@@ -1190,7 +1193,8 @@ int ip6_route_add(struct fib6_config *cfg)
1190 they would result in kernel looping; promote them to reject routes 1193 they would result in kernel looping; promote them to reject routes
1191 */ 1194 */
1192 if ((cfg->fc_flags & RTF_REJECT) || 1195 if ((cfg->fc_flags & RTF_REJECT) ||
1193 (dev && (dev->flags&IFF_LOOPBACK) && !(addr_type&IPV6_ADDR_LOOPBACK))) { 1196 (dev && (dev->flags&IFF_LOOPBACK) && !(addr_type&IPV6_ADDR_LOOPBACK)
1197 && !(cfg->fc_flags&RTF_LOCAL))) {
1194 /* hold loopback dev/idev if we haven't done so. */ 1198 /* hold loopback dev/idev if we haven't done so. */
1195 if (dev != net->loopback_dev) { 1199 if (dev != net->loopback_dev) {
1196 if (dev) { 1200 if (dev) {
@@ -1941,8 +1945,12 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
1941 struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops); 1945 struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops);
1942 struct neighbour *neigh; 1946 struct neighbour *neigh;
1943 1947
1944 if (rt == NULL) 1948 if (rt == NULL) {
1949 if (net_ratelimit())
1950 pr_warning("IPv6: Maximum number of routes reached,"
1951 " consider increasing route/max_size.\n");
1945 return ERR_PTR(-ENOMEM); 1952 return ERR_PTR(-ENOMEM);
1953 }
1946 1954
1947 dev_hold(net->loopback_dev); 1955 dev_hold(net->loopback_dev);
1948 in6_dev_hold(idev); 1956 in6_dev_hold(idev);
@@ -2102,6 +2110,9 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh,
2102 if (rtm->rtm_type == RTN_UNREACHABLE) 2110 if (rtm->rtm_type == RTN_UNREACHABLE)
2103 cfg->fc_flags |= RTF_REJECT; 2111 cfg->fc_flags |= RTF_REJECT;
2104 2112
2113 if (rtm->rtm_type == RTN_LOCAL)
2114 cfg->fc_flags |= RTF_LOCAL;
2115
2105 cfg->fc_nlinfo.pid = NETLINK_CB(skb).pid; 2116 cfg->fc_nlinfo.pid = NETLINK_CB(skb).pid;
2106 cfg->fc_nlinfo.nlh = nlh; 2117 cfg->fc_nlinfo.nlh = nlh;
2107 cfg->fc_nlinfo.nl_net = sock_net(skb->sk); 2118 cfg->fc_nlinfo.nl_net = sock_net(skb->sk);
@@ -2222,6 +2233,8 @@ static int rt6_fill_node(struct net *net,
2222 NLA_PUT_U32(skb, RTA_TABLE, table); 2233 NLA_PUT_U32(skb, RTA_TABLE, table);
2223 if (rt->rt6i_flags&RTF_REJECT) 2234 if (rt->rt6i_flags&RTF_REJECT)
2224 rtm->rtm_type = RTN_UNREACHABLE; 2235 rtm->rtm_type = RTN_UNREACHABLE;
2236 else if (rt->rt6i_flags&RTF_LOCAL)
2237 rtm->rtm_type = RTN_LOCAL;
2225 else if (rt->rt6i_dev && (rt->rt6i_dev->flags&IFF_LOOPBACK)) 2238 else if (rt->rt6i_dev && (rt->rt6i_dev->flags&IFF_LOOPBACK))
2226 rtm->rtm_type = RTN_LOCAL; 2239 rtm->rtm_type = RTN_LOCAL;
2227 else 2240 else
@@ -2516,7 +2529,7 @@ static int rt6_stats_seq_show(struct seq_file *seq, void *v)
2516 net->ipv6.rt6_stats->fib_rt_alloc, 2529 net->ipv6.rt6_stats->fib_rt_alloc,
2517 net->ipv6.rt6_stats->fib_rt_entries, 2530 net->ipv6.rt6_stats->fib_rt_entries,
2518 net->ipv6.rt6_stats->fib_rt_cache, 2531 net->ipv6.rt6_stats->fib_rt_cache,
2519 atomic_read(&net->ipv6.ip6_dst_ops.entries), 2532 dst_entries_get_slow(&net->ipv6.ip6_dst_ops),
2520 net->ipv6.rt6_stats->fib_discarded_routes); 2533 net->ipv6.rt6_stats->fib_discarded_routes);
2521 2534
2522 return 0; 2535 return 0;
@@ -2658,11 +2671,14 @@ static int __net_init ip6_route_net_init(struct net *net)
2658 memcpy(&net->ipv6.ip6_dst_ops, &ip6_dst_ops_template, 2671 memcpy(&net->ipv6.ip6_dst_ops, &ip6_dst_ops_template,
2659 sizeof(net->ipv6.ip6_dst_ops)); 2672 sizeof(net->ipv6.ip6_dst_ops));
2660 2673
2674 if (dst_entries_init(&net->ipv6.ip6_dst_ops) < 0)
2675 goto out_ip6_dst_ops;
2676
2661 net->ipv6.ip6_null_entry = kmemdup(&ip6_null_entry_template, 2677 net->ipv6.ip6_null_entry = kmemdup(&ip6_null_entry_template,
2662 sizeof(*net->ipv6.ip6_null_entry), 2678 sizeof(*net->ipv6.ip6_null_entry),
2663 GFP_KERNEL); 2679 GFP_KERNEL);
2664 if (!net->ipv6.ip6_null_entry) 2680 if (!net->ipv6.ip6_null_entry)
2665 goto out_ip6_dst_ops; 2681 goto out_ip6_dst_entries;
2666 net->ipv6.ip6_null_entry->dst.path = 2682 net->ipv6.ip6_null_entry->dst.path =
2667 (struct dst_entry *)net->ipv6.ip6_null_entry; 2683 (struct dst_entry *)net->ipv6.ip6_null_entry;
2668 net->ipv6.ip6_null_entry->dst.ops = &net->ipv6.ip6_dst_ops; 2684 net->ipv6.ip6_null_entry->dst.ops = &net->ipv6.ip6_dst_ops;
@@ -2712,6 +2728,8 @@ out_ip6_prohibit_entry:
2712out_ip6_null_entry: 2728out_ip6_null_entry:
2713 kfree(net->ipv6.ip6_null_entry); 2729 kfree(net->ipv6.ip6_null_entry);
2714#endif 2730#endif
2731out_ip6_dst_entries:
2732 dst_entries_destroy(&net->ipv6.ip6_dst_ops);
2715out_ip6_dst_ops: 2733out_ip6_dst_ops:
2716 goto out; 2734 goto out;
2717} 2735}
@@ -2727,6 +2745,7 @@ static void __net_exit ip6_route_net_exit(struct net *net)
2727 kfree(net->ipv6.ip6_prohibit_entry); 2745 kfree(net->ipv6.ip6_prohibit_entry);
2728 kfree(net->ipv6.ip6_blk_hole_entry); 2746 kfree(net->ipv6.ip6_blk_hole_entry);
2729#endif 2747#endif
2748 dst_entries_destroy(&net->ipv6.ip6_dst_ops);
2730} 2749}
2731 2750
2732static struct pernet_operations ip6_route_net_ops = { 2751static struct pernet_operations ip6_route_net_ops = {
@@ -2750,10 +2769,14 @@ int __init ip6_route_init(void)
2750 if (!ip6_dst_ops_template.kmem_cachep) 2769 if (!ip6_dst_ops_template.kmem_cachep)
2751 goto out; 2770 goto out;
2752 2771
2753 ret = register_pernet_subsys(&ip6_route_net_ops); 2772 ret = dst_entries_init(&ip6_dst_blackhole_ops);
2754 if (ret) 2773 if (ret)
2755 goto out_kmem_cache; 2774 goto out_kmem_cache;
2756 2775
2776 ret = register_pernet_subsys(&ip6_route_net_ops);
2777 if (ret)
2778 goto out_dst_entries;
2779
2757 ip6_dst_blackhole_ops.kmem_cachep = ip6_dst_ops_template.kmem_cachep; 2780 ip6_dst_blackhole_ops.kmem_cachep = ip6_dst_ops_template.kmem_cachep;
2758 2781
2759 /* Registering of the loopback is done before this portion of code, 2782 /* Registering of the loopback is done before this portion of code,
@@ -2800,6 +2823,8 @@ out_fib6_init:
2800 fib6_gc_cleanup(); 2823 fib6_gc_cleanup();
2801out_register_subsys: 2824out_register_subsys:
2802 unregister_pernet_subsys(&ip6_route_net_ops); 2825 unregister_pernet_subsys(&ip6_route_net_ops);
2826out_dst_entries:
2827 dst_entries_destroy(&ip6_dst_blackhole_ops);
2803out_kmem_cache: 2828out_kmem_cache:
2804 kmem_cache_destroy(ip6_dst_ops_template.kmem_cachep); 2829 kmem_cache_destroy(ip6_dst_ops_template.kmem_cachep);
2805 goto out; 2830 goto out;
@@ -2812,5 +2837,6 @@ void ip6_route_cleanup(void)
2812 xfrm6_fini(); 2837 xfrm6_fini();
2813 fib6_gc_cleanup(); 2838 fib6_gc_cleanup();
2814 unregister_pernet_subsys(&ip6_route_net_ops); 2839 unregister_pernet_subsys(&ip6_route_net_ops);
2840 dst_entries_destroy(&ip6_dst_blackhole_ops);
2815 kmem_cache_destroy(ip6_dst_ops_template.kmem_cachep); 2841 kmem_cache_destroy(ip6_dst_ops_template.kmem_cachep);
2816} 2842}
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 4699cd3c3118..d6bfaec3bbbf 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -63,36 +63,63 @@
63#define HASH_SIZE 16 63#define HASH_SIZE 16
64#define HASH(addr) (((__force u32)addr^((__force u32)addr>>4))&0xF) 64#define HASH(addr) (((__force u32)addr^((__force u32)addr>>4))&0xF)
65 65
66static void ipip6_tunnel_init(struct net_device *dev); 66static int ipip6_tunnel_init(struct net_device *dev);
67static void ipip6_tunnel_setup(struct net_device *dev); 67static void ipip6_tunnel_setup(struct net_device *dev);
68static void ipip6_dev_free(struct net_device *dev);
68 69
69static int sit_net_id __read_mostly; 70static int sit_net_id __read_mostly;
70struct sit_net { 71struct sit_net {
71 struct ip_tunnel *tunnels_r_l[HASH_SIZE]; 72 struct ip_tunnel __rcu *tunnels_r_l[HASH_SIZE];
72 struct ip_tunnel *tunnels_r[HASH_SIZE]; 73 struct ip_tunnel __rcu *tunnels_r[HASH_SIZE];
73 struct ip_tunnel *tunnels_l[HASH_SIZE]; 74 struct ip_tunnel __rcu *tunnels_l[HASH_SIZE];
74 struct ip_tunnel *tunnels_wc[1]; 75 struct ip_tunnel __rcu *tunnels_wc[1];
75 struct ip_tunnel **tunnels[4]; 76 struct ip_tunnel __rcu **tunnels[4];
76 77
77 struct net_device *fb_tunnel_dev; 78 struct net_device *fb_tunnel_dev;
78}; 79};
79 80
80/* 81/*
81 * Locking : hash tables are protected by RCU and a spinlock 82 * Locking : hash tables are protected by RCU and RTNL
82 */ 83 */
83static DEFINE_SPINLOCK(ipip6_lock);
84 84
85#define for_each_ip_tunnel_rcu(start) \ 85#define for_each_ip_tunnel_rcu(start) \
86 for (t = rcu_dereference(start); t; t = rcu_dereference(t->next)) 86 for (t = rcu_dereference(start); t; t = rcu_dereference(t->next))
87 87
88/* often modified stats are per cpu, other are shared (netdev->stats) */
89struct pcpu_tstats {
90 unsigned long rx_packets;
91 unsigned long rx_bytes;
92 unsigned long tx_packets;
93 unsigned long tx_bytes;
94};
95
96static struct net_device_stats *ipip6_get_stats(struct net_device *dev)
97{
98 struct pcpu_tstats sum = { 0 };
99 int i;
100
101 for_each_possible_cpu(i) {
102 const struct pcpu_tstats *tstats = per_cpu_ptr(dev->tstats, i);
103
104 sum.rx_packets += tstats->rx_packets;
105 sum.rx_bytes += tstats->rx_bytes;
106 sum.tx_packets += tstats->tx_packets;
107 sum.tx_bytes += tstats->tx_bytes;
108 }
109 dev->stats.rx_packets = sum.rx_packets;
110 dev->stats.rx_bytes = sum.rx_bytes;
111 dev->stats.tx_packets = sum.tx_packets;
112 dev->stats.tx_bytes = sum.tx_bytes;
113 return &dev->stats;
114}
88/* 115/*
89 * Must be invoked with rcu_read_lock 116 * Must be invoked with rcu_read_lock
90 */ 117 */
91static struct ip_tunnel * ipip6_tunnel_lookup(struct net *net, 118static struct ip_tunnel * ipip6_tunnel_lookup(struct net *net,
92 struct net_device *dev, __be32 remote, __be32 local) 119 struct net_device *dev, __be32 remote, __be32 local)
93{ 120{
94 unsigned h0 = HASH(remote); 121 unsigned int h0 = HASH(remote);
95 unsigned h1 = HASH(local); 122 unsigned int h1 = HASH(local);
96 struct ip_tunnel *t; 123 struct ip_tunnel *t;
97 struct sit_net *sitn = net_generic(net, sit_net_id); 124 struct sit_net *sitn = net_generic(net, sit_net_id);
98 125
@@ -121,12 +148,12 @@ static struct ip_tunnel * ipip6_tunnel_lookup(struct net *net,
121 return NULL; 148 return NULL;
122} 149}
123 150
124static struct ip_tunnel **__ipip6_bucket(struct sit_net *sitn, 151static struct ip_tunnel __rcu **__ipip6_bucket(struct sit_net *sitn,
125 struct ip_tunnel_parm *parms) 152 struct ip_tunnel_parm *parms)
126{ 153{
127 __be32 remote = parms->iph.daddr; 154 __be32 remote = parms->iph.daddr;
128 __be32 local = parms->iph.saddr; 155 __be32 local = parms->iph.saddr;
129 unsigned h = 0; 156 unsigned int h = 0;
130 int prio = 0; 157 int prio = 0;
131 158
132 if (remote) { 159 if (remote) {
@@ -140,7 +167,7 @@ static struct ip_tunnel **__ipip6_bucket(struct sit_net *sitn,
140 return &sitn->tunnels[prio][h]; 167 return &sitn->tunnels[prio][h];
141} 168}
142 169
143static inline struct ip_tunnel **ipip6_bucket(struct sit_net *sitn, 170static inline struct ip_tunnel __rcu **ipip6_bucket(struct sit_net *sitn,
144 struct ip_tunnel *t) 171 struct ip_tunnel *t)
145{ 172{
146 return __ipip6_bucket(sitn, &t->parms); 173 return __ipip6_bucket(sitn, &t->parms);
@@ -148,13 +175,14 @@ static inline struct ip_tunnel **ipip6_bucket(struct sit_net *sitn,
148 175
149static void ipip6_tunnel_unlink(struct sit_net *sitn, struct ip_tunnel *t) 176static void ipip6_tunnel_unlink(struct sit_net *sitn, struct ip_tunnel *t)
150{ 177{
151 struct ip_tunnel **tp; 178 struct ip_tunnel __rcu **tp;
152 179 struct ip_tunnel *iter;
153 for (tp = ipip6_bucket(sitn, t); *tp; tp = &(*tp)->next) { 180
154 if (t == *tp) { 181 for (tp = ipip6_bucket(sitn, t);
155 spin_lock_bh(&ipip6_lock); 182 (iter = rtnl_dereference(*tp)) != NULL;
156 *tp = t->next; 183 tp = &iter->next) {
157 spin_unlock_bh(&ipip6_lock); 184 if (t == iter) {
185 rcu_assign_pointer(*tp, t->next);
158 break; 186 break;
159 } 187 }
160 } 188 }
@@ -162,12 +190,10 @@ static void ipip6_tunnel_unlink(struct sit_net *sitn, struct ip_tunnel *t)
162 190
163static void ipip6_tunnel_link(struct sit_net *sitn, struct ip_tunnel *t) 191static void ipip6_tunnel_link(struct sit_net *sitn, struct ip_tunnel *t)
164{ 192{
165 struct ip_tunnel **tp = ipip6_bucket(sitn, t); 193 struct ip_tunnel __rcu **tp = ipip6_bucket(sitn, t);
166 194
167 spin_lock_bh(&ipip6_lock); 195 rcu_assign_pointer(t->next, rtnl_dereference(*tp));
168 t->next = *tp;
169 rcu_assign_pointer(*tp, t); 196 rcu_assign_pointer(*tp, t);
170 spin_unlock_bh(&ipip6_lock);
171} 197}
172 198
173static void ipip6_tunnel_clone_6rd(struct net_device *dev, struct sit_net *sitn) 199static void ipip6_tunnel_clone_6rd(struct net_device *dev, struct sit_net *sitn)
@@ -187,17 +213,20 @@ static void ipip6_tunnel_clone_6rd(struct net_device *dev, struct sit_net *sitn)
187#endif 213#endif
188} 214}
189 215
190static struct ip_tunnel * ipip6_tunnel_locate(struct net *net, 216static struct ip_tunnel *ipip6_tunnel_locate(struct net *net,
191 struct ip_tunnel_parm *parms, int create) 217 struct ip_tunnel_parm *parms, int create)
192{ 218{
193 __be32 remote = parms->iph.daddr; 219 __be32 remote = parms->iph.daddr;
194 __be32 local = parms->iph.saddr; 220 __be32 local = parms->iph.saddr;
195 struct ip_tunnel *t, **tp, *nt; 221 struct ip_tunnel *t, *nt;
222 struct ip_tunnel __rcu **tp;
196 struct net_device *dev; 223 struct net_device *dev;
197 char name[IFNAMSIZ]; 224 char name[IFNAMSIZ];
198 struct sit_net *sitn = net_generic(net, sit_net_id); 225 struct sit_net *sitn = net_generic(net, sit_net_id);
199 226
200 for (tp = __ipip6_bucket(sitn, parms); (t = *tp) != NULL; tp = &t->next) { 227 for (tp = __ipip6_bucket(sitn, parms);
228 (t = rtnl_dereference(*tp)) != NULL;
229 tp = &t->next) {
201 if (local == t->parms.iph.saddr && 230 if (local == t->parms.iph.saddr &&
202 remote == t->parms.iph.daddr && 231 remote == t->parms.iph.daddr &&
203 parms->link == t->parms.link) { 232 parms->link == t->parms.link) {
@@ -213,7 +242,7 @@ static struct ip_tunnel * ipip6_tunnel_locate(struct net *net,
213 if (parms->name[0]) 242 if (parms->name[0])
214 strlcpy(name, parms->name, IFNAMSIZ); 243 strlcpy(name, parms->name, IFNAMSIZ);
215 else 244 else
216 sprintf(name, "sit%%d"); 245 strcpy(name, "sit%d");
217 246
218 dev = alloc_netdev(sizeof(*t), name, ipip6_tunnel_setup); 247 dev = alloc_netdev(sizeof(*t), name, ipip6_tunnel_setup);
219 if (dev == NULL) 248 if (dev == NULL)
@@ -229,7 +258,8 @@ static struct ip_tunnel * ipip6_tunnel_locate(struct net *net,
229 nt = netdev_priv(dev); 258 nt = netdev_priv(dev);
230 259
231 nt->parms = *parms; 260 nt->parms = *parms;
232 ipip6_tunnel_init(dev); 261 if (ipip6_tunnel_init(dev) < 0)
262 goto failed_free;
233 ipip6_tunnel_clone_6rd(dev, sitn); 263 ipip6_tunnel_clone_6rd(dev, sitn);
234 264
235 if (parms->i_flags & SIT_ISATAP) 265 if (parms->i_flags & SIT_ISATAP)
@@ -244,7 +274,7 @@ static struct ip_tunnel * ipip6_tunnel_locate(struct net *net,
244 return nt; 274 return nt;
245 275
246failed_free: 276failed_free:
247 free_netdev(dev); 277 ipip6_dev_free(dev);
248failed: 278failed:
249 return NULL; 279 return NULL;
250} 280}
@@ -340,7 +370,7 @@ ipip6_tunnel_add_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a, int chg)
340 370
341 ASSERT_RTNL(); 371 ASSERT_RTNL();
342 372
343 for (p = t->prl; p; p = p->next) { 373 for (p = rtnl_dereference(t->prl); p; p = rtnl_dereference(p->next)) {
344 if (p->addr == a->addr) { 374 if (p->addr == a->addr) {
345 if (chg) { 375 if (chg) {
346 p->flags = a->flags; 376 p->flags = a->flags;
@@ -451,15 +481,12 @@ static void ipip6_tunnel_uninit(struct net_device *dev)
451 struct sit_net *sitn = net_generic(net, sit_net_id); 481 struct sit_net *sitn = net_generic(net, sit_net_id);
452 482
453 if (dev == sitn->fb_tunnel_dev) { 483 if (dev == sitn->fb_tunnel_dev) {
454 spin_lock_bh(&ipip6_lock); 484 rcu_assign_pointer(sitn->tunnels_wc[0], NULL);
455 sitn->tunnels_wc[0] = NULL;
456 spin_unlock_bh(&ipip6_lock);
457 dev_put(dev);
458 } else { 485 } else {
459 ipip6_tunnel_unlink(sitn, netdev_priv(dev)); 486 ipip6_tunnel_unlink(sitn, netdev_priv(dev));
460 ipip6_tunnel_del_prl(netdev_priv(dev), NULL); 487 ipip6_tunnel_del_prl(netdev_priv(dev), NULL);
461 dev_put(dev);
462 } 488 }
489 dev_put(dev);
463} 490}
464 491
465 492
@@ -548,6 +575,8 @@ static int ipip6_rcv(struct sk_buff *skb)
548 tunnel = ipip6_tunnel_lookup(dev_net(skb->dev), skb->dev, 575 tunnel = ipip6_tunnel_lookup(dev_net(skb->dev), skb->dev,
549 iph->saddr, iph->daddr); 576 iph->saddr, iph->daddr);
550 if (tunnel != NULL) { 577 if (tunnel != NULL) {
578 struct pcpu_tstats *tstats;
579
551 secpath_reset(skb); 580 secpath_reset(skb);
552 skb->mac_header = skb->network_header; 581 skb->mac_header = skb->network_header;
553 skb_reset_network_header(skb); 582 skb_reset_network_header(skb);
@@ -563,10 +592,16 @@ static int ipip6_rcv(struct sk_buff *skb)
563 return 0; 592 return 0;
564 } 593 }
565 594
566 skb_tunnel_rx(skb, tunnel->dev); 595 tstats = this_cpu_ptr(tunnel->dev->tstats);
596 tstats->rx_packets++;
597 tstats->rx_bytes += skb->len;
598
599 __skb_tunnel_rx(skb, tunnel->dev);
567 600
568 ipip6_ecn_decapsulate(iph, skb); 601 ipip6_ecn_decapsulate(iph, skb);
602
569 netif_rx(skb); 603 netif_rx(skb);
604
570 rcu_read_unlock(); 605 rcu_read_unlock();
571 return 0; 606 return 0;
572 } 607 }
@@ -590,7 +625,7 @@ __be32 try_6rd(struct in6_addr *v6dst, struct ip_tunnel *tunnel)
590#ifdef CONFIG_IPV6_SIT_6RD 625#ifdef CONFIG_IPV6_SIT_6RD
591 if (ipv6_prefix_equal(v6dst, &tunnel->ip6rd.prefix, 626 if (ipv6_prefix_equal(v6dst, &tunnel->ip6rd.prefix,
592 tunnel->ip6rd.prefixlen)) { 627 tunnel->ip6rd.prefixlen)) {
593 unsigned pbw0, pbi0; 628 unsigned int pbw0, pbi0;
594 int pbi1; 629 int pbi1;
595 u32 d; 630 u32 d;
596 631
@@ -625,14 +660,13 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
625 struct net_device *dev) 660 struct net_device *dev)
626{ 661{
627 struct ip_tunnel *tunnel = netdev_priv(dev); 662 struct ip_tunnel *tunnel = netdev_priv(dev);
628 struct net_device_stats *stats = &dev->stats; 663 struct pcpu_tstats *tstats;
629 struct netdev_queue *txq = netdev_get_tx_queue(dev, 0);
630 struct iphdr *tiph = &tunnel->parms.iph; 664 struct iphdr *tiph = &tunnel->parms.iph;
631 struct ipv6hdr *iph6 = ipv6_hdr(skb); 665 struct ipv6hdr *iph6 = ipv6_hdr(skb);
632 u8 tos = tunnel->parms.iph.tos; 666 u8 tos = tunnel->parms.iph.tos;
633 __be16 df = tiph->frag_off; 667 __be16 df = tiph->frag_off;
634 struct rtable *rt; /* Route to the other host */ 668 struct rtable *rt; /* Route to the other host */
635 struct net_device *tdev; /* Device to other host */ 669 struct net_device *tdev; /* Device to other host */
636 struct iphdr *iph; /* Our new IP header */ 670 struct iphdr *iph; /* Our new IP header */
637 unsigned int max_headroom; /* The extra header space needed */ 671 unsigned int max_headroom; /* The extra header space needed */
638 __be32 dst = tiph->daddr; 672 __be32 dst = tiph->daddr;
@@ -703,20 +737,20 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
703 .oif = tunnel->parms.link, 737 .oif = tunnel->parms.link,
704 .proto = IPPROTO_IPV6 }; 738 .proto = IPPROTO_IPV6 };
705 if (ip_route_output_key(dev_net(dev), &rt, &fl)) { 739 if (ip_route_output_key(dev_net(dev), &rt, &fl)) {
706 stats->tx_carrier_errors++; 740 dev->stats.tx_carrier_errors++;
707 goto tx_error_icmp; 741 goto tx_error_icmp;
708 } 742 }
709 } 743 }
710 if (rt->rt_type != RTN_UNICAST) { 744 if (rt->rt_type != RTN_UNICAST) {
711 ip_rt_put(rt); 745 ip_rt_put(rt);
712 stats->tx_carrier_errors++; 746 dev->stats.tx_carrier_errors++;
713 goto tx_error_icmp; 747 goto tx_error_icmp;
714 } 748 }
715 tdev = rt->dst.dev; 749 tdev = rt->dst.dev;
716 750
717 if (tdev == dev) { 751 if (tdev == dev) {
718 ip_rt_put(rt); 752 ip_rt_put(rt);
719 stats->collisions++; 753 dev->stats.collisions++;
720 goto tx_error; 754 goto tx_error;
721 } 755 }
722 756
@@ -724,7 +758,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
724 mtu = dst_mtu(&rt->dst) - sizeof(struct iphdr); 758 mtu = dst_mtu(&rt->dst) - sizeof(struct iphdr);
725 759
726 if (mtu < 68) { 760 if (mtu < 68) {
727 stats->collisions++; 761 dev->stats.collisions++;
728 ip_rt_put(rt); 762 ip_rt_put(rt);
729 goto tx_error; 763 goto tx_error;
730 } 764 }
@@ -763,7 +797,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
763 struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom); 797 struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom);
764 if (!new_skb) { 798 if (!new_skb) {
765 ip_rt_put(rt); 799 ip_rt_put(rt);
766 txq->tx_dropped++; 800 dev->stats.tx_dropped++;
767 dev_kfree_skb(skb); 801 dev_kfree_skb(skb);
768 return NETDEV_TX_OK; 802 return NETDEV_TX_OK;
769 } 803 }
@@ -799,14 +833,14 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
799 iph->ttl = iph6->hop_limit; 833 iph->ttl = iph6->hop_limit;
800 834
801 nf_reset(skb); 835 nf_reset(skb);
802 836 tstats = this_cpu_ptr(dev->tstats);
803 IPTUNNEL_XMIT(); 837 __IPTUNNEL_XMIT(tstats, &dev->stats);
804 return NETDEV_TX_OK; 838 return NETDEV_TX_OK;
805 839
806tx_error_icmp: 840tx_error_icmp:
807 dst_link_failure(skb); 841 dst_link_failure(skb);
808tx_error: 842tx_error:
809 stats->tx_errors++; 843 dev->stats.tx_errors++;
810 dev_kfree_skb(skb); 844 dev_kfree_skb(skb);
811 return NETDEV_TX_OK; 845 return NETDEV_TX_OK;
812} 846}
@@ -929,6 +963,7 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
929 } 963 }
930 t = netdev_priv(dev); 964 t = netdev_priv(dev);
931 ipip6_tunnel_unlink(sitn, t); 965 ipip6_tunnel_unlink(sitn, t);
966 synchronize_net();
932 t->parms.iph.saddr = p.iph.saddr; 967 t->parms.iph.saddr = p.iph.saddr;
933 t->parms.iph.daddr = p.iph.daddr; 968 t->parms.iph.daddr = p.iph.daddr;
934 memcpy(dev->dev_addr, &p.iph.saddr, 4); 969 memcpy(dev->dev_addr, &p.iph.saddr, 4);
@@ -1083,12 +1118,19 @@ static const struct net_device_ops ipip6_netdev_ops = {
1083 .ndo_start_xmit = ipip6_tunnel_xmit, 1118 .ndo_start_xmit = ipip6_tunnel_xmit,
1084 .ndo_do_ioctl = ipip6_tunnel_ioctl, 1119 .ndo_do_ioctl = ipip6_tunnel_ioctl,
1085 .ndo_change_mtu = ipip6_tunnel_change_mtu, 1120 .ndo_change_mtu = ipip6_tunnel_change_mtu,
1121 .ndo_get_stats = ipip6_get_stats,
1086}; 1122};
1087 1123
1124static void ipip6_dev_free(struct net_device *dev)
1125{
1126 free_percpu(dev->tstats);
1127 free_netdev(dev);
1128}
1129
1088static void ipip6_tunnel_setup(struct net_device *dev) 1130static void ipip6_tunnel_setup(struct net_device *dev)
1089{ 1131{
1090 dev->netdev_ops = &ipip6_netdev_ops; 1132 dev->netdev_ops = &ipip6_netdev_ops;
1091 dev->destructor = free_netdev; 1133 dev->destructor = ipip6_dev_free;
1092 1134
1093 dev->type = ARPHRD_SIT; 1135 dev->type = ARPHRD_SIT;
1094 dev->hard_header_len = LL_MAX_HEADER + sizeof(struct iphdr); 1136 dev->hard_header_len = LL_MAX_HEADER + sizeof(struct iphdr);
@@ -1098,9 +1140,10 @@ static void ipip6_tunnel_setup(struct net_device *dev)
1098 dev->iflink = 0; 1140 dev->iflink = 0;
1099 dev->addr_len = 4; 1141 dev->addr_len = 4;
1100 dev->features |= NETIF_F_NETNS_LOCAL; 1142 dev->features |= NETIF_F_NETNS_LOCAL;
1143 dev->features |= NETIF_F_LLTX;
1101} 1144}
1102 1145
1103static void ipip6_tunnel_init(struct net_device *dev) 1146static int ipip6_tunnel_init(struct net_device *dev)
1104{ 1147{
1105 struct ip_tunnel *tunnel = netdev_priv(dev); 1148 struct ip_tunnel *tunnel = netdev_priv(dev);
1106 1149
@@ -1111,9 +1154,14 @@ static void ipip6_tunnel_init(struct net_device *dev)
1111 memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4); 1154 memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4);
1112 1155
1113 ipip6_tunnel_bind_dev(dev); 1156 ipip6_tunnel_bind_dev(dev);
1157 dev->tstats = alloc_percpu(struct pcpu_tstats);
1158 if (!dev->tstats)
1159 return -ENOMEM;
1160
1161 return 0;
1114} 1162}
1115 1163
1116static void __net_init ipip6_fb_tunnel_init(struct net_device *dev) 1164static int __net_init ipip6_fb_tunnel_init(struct net_device *dev)
1117{ 1165{
1118 struct ip_tunnel *tunnel = netdev_priv(dev); 1166 struct ip_tunnel *tunnel = netdev_priv(dev);
1119 struct iphdr *iph = &tunnel->parms.iph; 1167 struct iphdr *iph = &tunnel->parms.iph;
@@ -1128,11 +1176,15 @@ static void __net_init ipip6_fb_tunnel_init(struct net_device *dev)
1128 iph->ihl = 5; 1176 iph->ihl = 5;
1129 iph->ttl = 64; 1177 iph->ttl = 64;
1130 1178
1179 dev->tstats = alloc_percpu(struct pcpu_tstats);
1180 if (!dev->tstats)
1181 return -ENOMEM;
1131 dev_hold(dev); 1182 dev_hold(dev);
1132 sitn->tunnels_wc[0] = tunnel; 1183 sitn->tunnels_wc[0] = tunnel;
1184 return 0;
1133} 1185}
1134 1186
1135static struct xfrm_tunnel sit_handler = { 1187static struct xfrm_tunnel sit_handler __read_mostly = {
1136 .handler = ipip6_rcv, 1188 .handler = ipip6_rcv,
1137 .err_handler = ipip6_err, 1189 .err_handler = ipip6_err,
1138 .priority = 1, 1190 .priority = 1,
@@ -1173,7 +1225,10 @@ static int __net_init sit_init_net(struct net *net)
1173 } 1225 }
1174 dev_net_set(sitn->fb_tunnel_dev, net); 1226 dev_net_set(sitn->fb_tunnel_dev, net);
1175 1227
1176 ipip6_fb_tunnel_init(sitn->fb_tunnel_dev); 1228 err = ipip6_fb_tunnel_init(sitn->fb_tunnel_dev);
1229 if (err)
1230 goto err_dev_free;
1231
1177 ipip6_tunnel_clone_6rd(sitn->fb_tunnel_dev, sitn); 1232 ipip6_tunnel_clone_6rd(sitn->fb_tunnel_dev, sitn);
1178 1233
1179 if ((err = register_netdev(sitn->fb_tunnel_dev))) 1234 if ((err = register_netdev(sitn->fb_tunnel_dev)))
@@ -1183,7 +1238,8 @@ static int __net_init sit_init_net(struct net *net)
1183 1238
1184err_reg_dev: 1239err_reg_dev:
1185 dev_put(sitn->fb_tunnel_dev); 1240 dev_put(sitn->fb_tunnel_dev);
1186 free_netdev(sitn->fb_tunnel_dev); 1241err_dev_free:
1242 ipip6_dev_free(sitn->fb_tunnel_dev);
1187err_alloc_dev: 1243err_alloc_dev:
1188 return err; 1244 return err;
1189} 1245}
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index fe6d40418c0b..7e41e2cbb85e 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -139,7 +139,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
139 return -EINVAL; 139 return -EINVAL;
140 140
141 if (usin->sin6_family != AF_INET6) 141 if (usin->sin6_family != AF_INET6)
142 return(-EAFNOSUPPORT); 142 return -EAFNOSUPPORT;
143 143
144 memset(&fl, 0, sizeof(fl)); 144 memset(&fl, 0, sizeof(fl));
145 145
@@ -1409,7 +1409,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1409 1409
1410 newsk = tcp_create_openreq_child(sk, req, skb); 1410 newsk = tcp_create_openreq_child(sk, req, skb);
1411 if (newsk == NULL) 1411 if (newsk == NULL)
1412 goto out; 1412 goto out_nonewsk;
1413 1413
1414 /* 1414 /*
1415 * No need to charge this sock to the relevant IPv6 refcnt debug socks 1415 * No need to charge this sock to the relevant IPv6 refcnt debug socks
@@ -1497,18 +1497,22 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1497 } 1497 }
1498#endif 1498#endif
1499 1499
1500 if (__inet_inherit_port(sk, newsk) < 0) {
1501 sock_put(newsk);
1502 goto out;
1503 }
1500 __inet6_hash(newsk, NULL); 1504 __inet6_hash(newsk, NULL);
1501 __inet_inherit_port(sk, newsk);
1502 1505
1503 return newsk; 1506 return newsk;
1504 1507
1505out_overflow: 1508out_overflow:
1506 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENOVERFLOWS); 1509 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENOVERFLOWS);
1507out: 1510out_nonewsk:
1508 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
1509 if (opt && opt != np->opt) 1511 if (opt && opt != np->opt)
1510 sock_kfree_s(sk, opt, opt->tot_len); 1512 sock_kfree_s(sk, opt, opt->tot_len);
1511 dst_release(dst); 1513 dst_release(dst);
1514out:
1515 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
1512 return NULL; 1516 return NULL;
1513} 1517}
1514 1518
diff --git a/net/ipv6/tunnel6.c b/net/ipv6/tunnel6.c
index fc3c86a47452..4f3cec12aa85 100644
--- a/net/ipv6/tunnel6.c
+++ b/net/ipv6/tunnel6.c
@@ -30,28 +30,31 @@
30#include <net/protocol.h> 30#include <net/protocol.h>
31#include <net/xfrm.h> 31#include <net/xfrm.h>
32 32
33static struct xfrm6_tunnel *tunnel6_handlers; 33static struct xfrm6_tunnel __rcu *tunnel6_handlers __read_mostly;
34static struct xfrm6_tunnel *tunnel46_handlers; 34static struct xfrm6_tunnel __rcu *tunnel46_handlers __read_mostly;
35static DEFINE_MUTEX(tunnel6_mutex); 35static DEFINE_MUTEX(tunnel6_mutex);
36 36
37int xfrm6_tunnel_register(struct xfrm6_tunnel *handler, unsigned short family) 37int xfrm6_tunnel_register(struct xfrm6_tunnel *handler, unsigned short family)
38{ 38{
39 struct xfrm6_tunnel **pprev; 39 struct xfrm6_tunnel __rcu **pprev;
40 struct xfrm6_tunnel *t;
40 int ret = -EEXIST; 41 int ret = -EEXIST;
41 int priority = handler->priority; 42 int priority = handler->priority;
42 43
43 mutex_lock(&tunnel6_mutex); 44 mutex_lock(&tunnel6_mutex);
44 45
45 for (pprev = (family == AF_INET6) ? &tunnel6_handlers : &tunnel46_handlers; 46 for (pprev = (family == AF_INET6) ? &tunnel6_handlers : &tunnel46_handlers;
46 *pprev; pprev = &(*pprev)->next) { 47 (t = rcu_dereference_protected(*pprev,
47 if ((*pprev)->priority > priority) 48 lockdep_is_held(&tunnel6_mutex))) != NULL;
49 pprev = &t->next) {
50 if (t->priority > priority)
48 break; 51 break;
49 if ((*pprev)->priority == priority) 52 if (t->priority == priority)
50 goto err; 53 goto err;
51 } 54 }
52 55
53 handler->next = *pprev; 56 handler->next = *pprev;
54 *pprev = handler; 57 rcu_assign_pointer(*pprev, handler);
55 58
56 ret = 0; 59 ret = 0;
57 60
@@ -65,14 +68,17 @@ EXPORT_SYMBOL(xfrm6_tunnel_register);
65 68
66int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler, unsigned short family) 69int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler, unsigned short family)
67{ 70{
68 struct xfrm6_tunnel **pprev; 71 struct xfrm6_tunnel __rcu **pprev;
72 struct xfrm6_tunnel *t;
69 int ret = -ENOENT; 73 int ret = -ENOENT;
70 74
71 mutex_lock(&tunnel6_mutex); 75 mutex_lock(&tunnel6_mutex);
72 76
73 for (pprev = (family == AF_INET6) ? &tunnel6_handlers : &tunnel46_handlers; 77 for (pprev = (family == AF_INET6) ? &tunnel6_handlers : &tunnel46_handlers;
74 *pprev; pprev = &(*pprev)->next) { 78 (t = rcu_dereference_protected(*pprev,
75 if (*pprev == handler) { 79 lockdep_is_held(&tunnel6_mutex))) != NULL;
80 pprev = &t->next) {
81 if (t == handler) {
76 *pprev = handler->next; 82 *pprev = handler->next;
77 ret = 0; 83 ret = 0;
78 break; 84 break;
@@ -88,6 +94,11 @@ int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler, unsigned short family)
88 94
89EXPORT_SYMBOL(xfrm6_tunnel_deregister); 95EXPORT_SYMBOL(xfrm6_tunnel_deregister);
90 96
97#define for_each_tunnel_rcu(head, handler) \
98 for (handler = rcu_dereference(head); \
99 handler != NULL; \
100 handler = rcu_dereference(handler->next)) \
101
91static int tunnel6_rcv(struct sk_buff *skb) 102static int tunnel6_rcv(struct sk_buff *skb)
92{ 103{
93 struct xfrm6_tunnel *handler; 104 struct xfrm6_tunnel *handler;
@@ -95,7 +106,7 @@ static int tunnel6_rcv(struct sk_buff *skb)
95 if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) 106 if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
96 goto drop; 107 goto drop;
97 108
98 for (handler = tunnel6_handlers; handler; handler = handler->next) 109 for_each_tunnel_rcu(tunnel6_handlers, handler)
99 if (!handler->handler(skb)) 110 if (!handler->handler(skb))
100 return 0; 111 return 0;
101 112
@@ -113,7 +124,7 @@ static int tunnel46_rcv(struct sk_buff *skb)
113 if (!pskb_may_pull(skb, sizeof(struct iphdr))) 124 if (!pskb_may_pull(skb, sizeof(struct iphdr)))
114 goto drop; 125 goto drop;
115 126
116 for (handler = tunnel46_handlers; handler; handler = handler->next) 127 for_each_tunnel_rcu(tunnel46_handlers, handler)
117 if (!handler->handler(skb)) 128 if (!handler->handler(skb))
118 return 0; 129 return 0;
119 130
@@ -129,7 +140,7 @@ static void tunnel6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
129{ 140{
130 struct xfrm6_tunnel *handler; 141 struct xfrm6_tunnel *handler;
131 142
132 for (handler = tunnel6_handlers; handler; handler = handler->next) 143 for_each_tunnel_rcu(tunnel6_handlers, handler)
133 if (!handler->err_handler(skb, opt, type, code, offset, info)) 144 if (!handler->err_handler(skb, opt, type, code, offset, info))
134 break; 145 break;
135} 146}
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 5acb3560ff15..91def93bec85 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -122,8 +122,8 @@ static void udp_v6_rehash(struct sock *sk)
122 122
123static inline int compute_score(struct sock *sk, struct net *net, 123static inline int compute_score(struct sock *sk, struct net *net,
124 unsigned short hnum, 124 unsigned short hnum,
125 struct in6_addr *saddr, __be16 sport, 125 const struct in6_addr *saddr, __be16 sport,
126 struct in6_addr *daddr, __be16 dport, 126 const struct in6_addr *daddr, __be16 dport,
127 int dif) 127 int dif)
128{ 128{
129 int score = -1; 129 int score = -1;
@@ -239,8 +239,8 @@ exact_match:
239} 239}
240 240
241static struct sock *__udp6_lib_lookup(struct net *net, 241static struct sock *__udp6_lib_lookup(struct net *net,
242 struct in6_addr *saddr, __be16 sport, 242 const struct in6_addr *saddr, __be16 sport,
243 struct in6_addr *daddr, __be16 dport, 243 const struct in6_addr *daddr, __be16 dport,
244 int dif, struct udp_table *udptable) 244 int dif, struct udp_table *udptable)
245{ 245{
246 struct sock *sk, *result; 246 struct sock *sk, *result;
@@ -320,6 +320,14 @@ static struct sock *__udp6_lib_lookup_skb(struct sk_buff *skb,
320 udptable); 320 udptable);
321} 321}
322 322
323struct sock *udp6_lib_lookup(struct net *net, const struct in6_addr *saddr, __be16 sport,
324 const struct in6_addr *daddr, __be16 dport, int dif)
325{
326 return __udp6_lib_lookup(net, saddr, sport, daddr, dport, dif, &udp_table);
327}
328EXPORT_SYMBOL_GPL(udp6_lib_lookup);
329
330
323/* 331/*
324 * This should be easy, if there is something there we 332 * This should be easy, if there is something there we
325 * return it, otherwise we block. 333 * return it, otherwise we block.
@@ -519,7 +527,7 @@ int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
519 } 527 }
520 } 528 }
521 529
522 if (sk->sk_filter) { 530 if (rcu_dereference_raw(sk->sk_filter)) {
523 if (udp_lib_checksum_complete(skb)) 531 if (udp_lib_checksum_complete(skb))
524 goto drop; 532 goto drop;
525 } 533 }
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 6baeabbbca82..7e74023ea6e4 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -199,7 +199,7 @@ static inline int xfrm6_garbage_collect(struct dst_ops *ops)
199 struct net *net = container_of(ops, struct net, xfrm.xfrm6_dst_ops); 199 struct net *net = container_of(ops, struct net, xfrm.xfrm6_dst_ops);
200 200
201 xfrm6_policy_afinfo.garbage_collect(net); 201 xfrm6_policy_afinfo.garbage_collect(net);
202 return (atomic_read(&ops->entries) > ops->gc_thresh * 2); 202 return dst_entries_get_fast(ops) > ops->gc_thresh * 2;
203} 203}
204 204
205static void xfrm6_update_pmtu(struct dst_entry *dst, u32 mtu) 205static void xfrm6_update_pmtu(struct dst_entry *dst, u32 mtu)
@@ -255,7 +255,6 @@ static struct dst_ops xfrm6_dst_ops = {
255 .ifdown = xfrm6_dst_ifdown, 255 .ifdown = xfrm6_dst_ifdown,
256 .local_out = __ip6_local_out, 256 .local_out = __ip6_local_out,
257 .gc_thresh = 1024, 257 .gc_thresh = 1024,
258 .entries = ATOMIC_INIT(0),
259}; 258};
260 259
261static struct xfrm_policy_afinfo xfrm6_policy_afinfo = { 260static struct xfrm_policy_afinfo xfrm6_policy_afinfo = {
@@ -312,11 +311,13 @@ int __init xfrm6_init(void)
312 */ 311 */
313 gc_thresh = FIB6_TABLE_HASHSZ * 8; 312 gc_thresh = FIB6_TABLE_HASHSZ * 8;
314 xfrm6_dst_ops.gc_thresh = (gc_thresh < 1024) ? 1024 : gc_thresh; 313 xfrm6_dst_ops.gc_thresh = (gc_thresh < 1024) ? 1024 : gc_thresh;
314 dst_entries_init(&xfrm6_dst_ops);
315 315
316 ret = xfrm6_policy_init(); 316 ret = xfrm6_policy_init();
317 if (ret) 317 if (ret) {
318 dst_entries_destroy(&xfrm6_dst_ops);
318 goto out; 319 goto out;
319 320 }
320 ret = xfrm6_state_init(); 321 ret = xfrm6_state_init();
321 if (ret) 322 if (ret)
322 goto out_policy; 323 goto out_policy;
@@ -341,4 +342,5 @@ void xfrm6_fini(void)
341 //xfrm6_input_fini(); 342 //xfrm6_input_fini();
342 xfrm6_policy_fini(); 343 xfrm6_policy_fini();
343 xfrm6_state_fini(); 344 xfrm6_state_fini();
345 dst_entries_destroy(&xfrm6_dst_ops);
344} 346}
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
index 2ce3a8278f26..2969cad408de 100644
--- a/net/ipv6/xfrm6_tunnel.c
+++ b/net/ipv6/xfrm6_tunnel.c
@@ -199,7 +199,7 @@ static void x6spi_destroy_rcu(struct rcu_head *head)
199 container_of(head, struct xfrm6_tunnel_spi, rcu_head)); 199 container_of(head, struct xfrm6_tunnel_spi, rcu_head));
200} 200}
201 201
202void xfrm6_tunnel_free_spi(struct net *net, xfrm_address_t *saddr) 202static void xfrm6_tunnel_free_spi(struct net *net, xfrm_address_t *saddr)
203{ 203{
204 struct xfrm6_tunnel_net *xfrm6_tn = xfrm6_tunnel_pernet(net); 204 struct xfrm6_tunnel_net *xfrm6_tn = xfrm6_tunnel_pernet(net);
205 struct xfrm6_tunnel_spi *x6spi; 205 struct xfrm6_tunnel_spi *x6spi;
@@ -223,8 +223,6 @@ void xfrm6_tunnel_free_spi(struct net *net, xfrm_address_t *saddr)
223 spin_unlock_bh(&xfrm6_tunnel_spi_lock); 223 spin_unlock_bh(&xfrm6_tunnel_spi_lock);
224} 224}
225 225
226EXPORT_SYMBOL(xfrm6_tunnel_free_spi);
227
228static int xfrm6_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) 226static int xfrm6_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
229{ 227{
230 skb_push(skb, -skb_network_offset(skb)); 228 skb_push(skb, -skb_network_offset(skb));
@@ -317,13 +315,13 @@ static const struct xfrm_type xfrm6_tunnel_type = {
317 .output = xfrm6_tunnel_output, 315 .output = xfrm6_tunnel_output,
318}; 316};
319 317
320static struct xfrm6_tunnel xfrm6_tunnel_handler = { 318static struct xfrm6_tunnel xfrm6_tunnel_handler __read_mostly = {
321 .handler = xfrm6_tunnel_rcv, 319 .handler = xfrm6_tunnel_rcv,
322 .err_handler = xfrm6_tunnel_err, 320 .err_handler = xfrm6_tunnel_err,
323 .priority = 2, 321 .priority = 2,
324}; 322};
325 323
326static struct xfrm6_tunnel xfrm46_tunnel_handler = { 324static struct xfrm6_tunnel xfrm46_tunnel_handler __read_mostly = {
327 .handler = xfrm6_tunnel_rcv, 325 .handler = xfrm6_tunnel_rcv,
328 .err_handler = xfrm6_tunnel_err, 326 .err_handler = xfrm6_tunnel_err,
329 .priority = 2, 327 .priority = 2,