aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/Makefile4
-rw-r--r--net/ipv6/addrconf.c17
-rw-r--r--net/ipv6/af_inet6.c20
-rw-r--r--net/ipv6/ah6.c23
-rw-r--r--net/ipv6/anycast.c108
-rw-r--r--net/ipv6/datagram.c23
-rw-r--r--net/ipv6/esp6.c15
-rw-r--r--net/ipv6/exthdrs.c2
-rw-r--r--net/ipv6/icmp.c34
-rw-r--r--net/ipv6/inet6_connection_sock.c6
-rw-r--r--net/ipv6/inet6_hashtables.c7
-rw-r--r--net/ipv6/ip6_fib.c142
-rw-r--r--net/ipv6/ip6_flowlabel.c19
-rw-r--r--net/ipv6/ip6_gre.c10
-rw-r--r--net/ipv6/ip6_icmp.c2
-rw-r--r--net/ipv6/ip6_input.c6
-rw-r--r--net/ipv6/ip6_offload.c34
-rw-r--r--net/ipv6/ip6_output.c27
-rw-r--r--net/ipv6/ip6_tunnel.c34
-rw-r--r--net/ipv6/ip6_udp_tunnel.c107
-rw-r--r--net/ipv6/ip6_vti.c2
-rw-r--r--net/ipv6/ip6mr.c4
-rw-r--r--net/ipv6/ipcomp6.c6
-rw-r--r--net/ipv6/ipv6_sockglue.c26
-rw-r--r--net/ipv6/mcast.c302
-rw-r--r--net/ipv6/mip6.c10
-rw-r--r--net/ipv6/ndisc.c17
-rw-r--r--net/ipv6/netfilter/Kconfig43
-rw-r--r--net/ipv6/netfilter/Makefile5
-rw-r--r--net/ipv6/netfilter/ip6t_MASQUERADE.c76
-rw-r--r--net/ipv6/netfilter/ip6table_nat.c233
-rw-r--r--net/ipv6/netfilter/nf_defrag_ipv6_hooks.c2
-rw-r--r--net/ipv6/netfilter/nf_nat_l3proto_ipv6.c199
-rw-r--r--net/ipv6/netfilter/nf_nat_masquerade_ipv6.c120
-rw-r--r--net/ipv6/netfilter/nf_reject_ipv6.c163
-rw-r--r--net/ipv6/netfilter/nft_chain_nat_ipv6.c165
-rw-r--r--net/ipv6/netfilter/nft_masq_ipv6.c77
-rw-r--r--net/ipv6/output_core.c2
-rw-r--r--net/ipv6/proc.c2
-rw-r--r--net/ipv6/protocol.c1
-rw-r--r--net/ipv6/raw.c8
-rw-r--r--net/ipv6/reassembly.c12
-rw-r--r--net/ipv6/route.c22
-rw-r--r--net/ipv6/sit.c123
-rw-r--r--net/ipv6/syncookies.c4
-rw-r--r--net/ipv6/sysctl_net_ipv6.c10
-rw-r--r--net/ipv6/tcp_ipv6.c32
-rw-r--r--net/ipv6/tcpv6_offload.c69
-rw-r--r--net/ipv6/tunnel6.c4
-rw-r--r--net/ipv6/udp.c26
-rw-r--r--net/ipv6/udp_offload.c92
-rw-r--r--net/ipv6/xfrm6_input.c6
-rw-r--r--net/ipv6/xfrm6_output.c1
-rw-r--r--net/ipv6/xfrm6_policy.c22
-rw-r--r--net/ipv6/xfrm6_state.c14
-rw-r--r--net/ipv6/xfrm6_tunnel.c4
56 files changed, 1504 insertions, 1040 deletions
diff --git a/net/ipv6/Makefile b/net/ipv6/Makefile
index 2fe68364bb20..2e8c06108ab9 100644
--- a/net/ipv6/Makefile
+++ b/net/ipv6/Makefile
@@ -45,3 +45,7 @@ obj-y += addrconf_core.o exthdrs_core.o ip6_checksum.o ip6_icmp.o
45obj-$(CONFIG_INET) += output_core.o protocol.o $(ipv6-offload) 45obj-$(CONFIG_INET) += output_core.o protocol.o $(ipv6-offload)
46 46
47obj-$(subst m,y,$(CONFIG_IPV6)) += inet6_hashtables.o 47obj-$(subst m,y,$(CONFIG_IPV6)) += inet6_hashtables.o
48
49ifneq ($(CONFIG_IPV6),)
50obj-$(CONFIG_NET_UDP_TUNNEL) += ip6_udp_tunnel.o
51endif
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 3e118dfddd02..725c763270a0 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -180,7 +180,7 @@ static struct ipv6_devconf ipv6_devconf __read_mostly = {
180 .rtr_solicits = MAX_RTR_SOLICITATIONS, 180 .rtr_solicits = MAX_RTR_SOLICITATIONS,
181 .rtr_solicit_interval = RTR_SOLICITATION_INTERVAL, 181 .rtr_solicit_interval = RTR_SOLICITATION_INTERVAL,
182 .rtr_solicit_delay = MAX_RTR_SOLICITATION_DELAY, 182 .rtr_solicit_delay = MAX_RTR_SOLICITATION_DELAY,
183 .use_tempaddr = 0, 183 .use_tempaddr = 0,
184 .temp_valid_lft = TEMP_VALID_LIFETIME, 184 .temp_valid_lft = TEMP_VALID_LIFETIME,
185 .temp_prefered_lft = TEMP_PREFERRED_LIFETIME, 185 .temp_prefered_lft = TEMP_PREFERRED_LIFETIME,
186 .regen_max_retry = REGEN_MAX_RETRY, 186 .regen_max_retry = REGEN_MAX_RETRY,
@@ -1105,8 +1105,8 @@ retry:
1105 spin_unlock_bh(&ifp->lock); 1105 spin_unlock_bh(&ifp->lock);
1106 1106
1107 regen_advance = idev->cnf.regen_max_retry * 1107 regen_advance = idev->cnf.regen_max_retry *
1108 idev->cnf.dad_transmits * 1108 idev->cnf.dad_transmits *
1109 NEIGH_VAR(idev->nd_parms, RETRANS_TIME) / HZ; 1109 NEIGH_VAR(idev->nd_parms, RETRANS_TIME) / HZ;
1110 write_unlock_bh(&idev->lock); 1110 write_unlock_bh(&idev->lock);
1111 1111
1112 /* A temporary address is created only if this calculated Preferred 1112 /* A temporary address is created only if this calculated Preferred
@@ -1725,7 +1725,7 @@ static void addrconf_join_anycast(struct inet6_ifaddr *ifp)
1725 ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len); 1725 ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len);
1726 if (ipv6_addr_any(&addr)) 1726 if (ipv6_addr_any(&addr))
1727 return; 1727 return;
1728 ipv6_dev_ac_inc(ifp->idev->dev, &addr); 1728 __ipv6_dev_ac_inc(ifp->idev, &addr);
1729} 1729}
1730 1730
1731/* caller must hold RTNL */ 1731/* caller must hold RTNL */
@@ -2844,6 +2844,9 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
2844 if (dev->flags & IFF_SLAVE) 2844 if (dev->flags & IFF_SLAVE)
2845 break; 2845 break;
2846 2846
2847 if (idev && idev->cnf.disable_ipv6)
2848 break;
2849
2847 if (event == NETDEV_UP) { 2850 if (event == NETDEV_UP) {
2848 if (!addrconf_qdisc_ok(dev)) { 2851 if (!addrconf_qdisc_ok(dev)) {
2849 /* device is not ready yet. */ 2852 /* device is not ready yet. */
@@ -3030,7 +3033,7 @@ static int addrconf_ifdown(struct net_device *dev, int how)
3030 struct hlist_head *h = &inet6_addr_lst[i]; 3033 struct hlist_head *h = &inet6_addr_lst[i];
3031 3034
3032 spin_lock_bh(&addrconf_hash_lock); 3035 spin_lock_bh(&addrconf_hash_lock);
3033 restart: 3036restart:
3034 hlist_for_each_entry_rcu(ifa, h, addr_lst) { 3037 hlist_for_each_entry_rcu(ifa, h, addr_lst) {
3035 if (ifa->idev == idev) { 3038 if (ifa->idev == idev) {
3036 hlist_del_init_rcu(&ifa->addr_lst); 3039 hlist_del_init_rcu(&ifa->addr_lst);
@@ -3544,8 +3547,8 @@ static void __net_exit if6_proc_net_exit(struct net *net)
3544} 3547}
3545 3548
3546static struct pernet_operations if6_proc_net_ops = { 3549static struct pernet_operations if6_proc_net_ops = {
3547 .init = if6_proc_net_init, 3550 .init = if6_proc_net_init,
3548 .exit = if6_proc_net_exit, 3551 .exit = if6_proc_net_exit,
3549}; 3552};
3550 3553
3551int __init if6_proc_init(void) 3554int __init if6_proc_init(void)
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 2daa3a133e49..e8c4400f23e9 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -7,15 +7,15 @@
7 * 7 *
8 * Adapted from linux/net/ipv4/af_inet.c 8 * Adapted from linux/net/ipv4/af_inet.c
9 * 9 *
10 * Fixes: 10 * Fixes:
11 * piggy, Karl Knutson : Socket protocol table 11 * piggy, Karl Knutson : Socket protocol table
12 * Hideaki YOSHIFUJI : sin6_scope_id support 12 * Hideaki YOSHIFUJI : sin6_scope_id support
13 * Arnaldo Melo : check proc_net_create return, cleanups 13 * Arnaldo Melo : check proc_net_create return, cleanups
14 * 14 *
15 * This program is free software; you can redistribute it and/or 15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License 16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 17 * as published by the Free Software Foundation; either version
18 * 2 of the License, or (at your option) any later version. 18 * 2 of the License, or (at your option) any later version.
19 */ 19 */
20 20
21#define pr_fmt(fmt) "IPv6: " fmt 21#define pr_fmt(fmt) "IPv6: " fmt
@@ -302,7 +302,7 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
302 /* Reproduce AF_INET checks to make the bindings consistent */ 302 /* Reproduce AF_INET checks to make the bindings consistent */
303 v4addr = addr->sin6_addr.s6_addr32[3]; 303 v4addr = addr->sin6_addr.s6_addr32[3];
304 chk_addr_ret = inet_addr_type(net, v4addr); 304 chk_addr_ret = inet_addr_type(net, v4addr);
305 if (!sysctl_ip_nonlocal_bind && 305 if (!net->ipv4.sysctl_ip_nonlocal_bind &&
306 !(inet->freebind || inet->transparent) && 306 !(inet->freebind || inet->transparent) &&
307 v4addr != htonl(INADDR_ANY) && 307 v4addr != htonl(INADDR_ANY) &&
308 chk_addr_ret != RTN_LOCAL && 308 chk_addr_ret != RTN_LOCAL &&
@@ -672,10 +672,10 @@ int inet6_sk_rebuild_header(struct sock *sk)
672} 672}
673EXPORT_SYMBOL_GPL(inet6_sk_rebuild_header); 673EXPORT_SYMBOL_GPL(inet6_sk_rebuild_header);
674 674
675bool ipv6_opt_accepted(const struct sock *sk, const struct sk_buff *skb) 675bool ipv6_opt_accepted(const struct sock *sk, const struct sk_buff *skb,
676 const struct inet6_skb_parm *opt)
676{ 677{
677 const struct ipv6_pinfo *np = inet6_sk(sk); 678 const struct ipv6_pinfo *np = inet6_sk(sk);
678 const struct inet6_skb_parm *opt = IP6CB(skb);
679 679
680 if (np->rxopt.all) { 680 if (np->rxopt.all) {
681 if ((opt->hop && (np->rxopt.bits.hopopts || 681 if ((opt->hop && (np->rxopt.bits.hopopts ||
@@ -766,7 +766,7 @@ static int __net_init inet6_net_init(struct net *net)
766 net->ipv6.sysctl.icmpv6_time = 1*HZ; 766 net->ipv6.sysctl.icmpv6_time = 1*HZ;
767 net->ipv6.sysctl.flowlabel_consistency = 1; 767 net->ipv6.sysctl.flowlabel_consistency = 1;
768 net->ipv6.sysctl.auto_flowlabels = 0; 768 net->ipv6.sysctl.auto_flowlabels = 0;
769 atomic_set(&net->ipv6.rt_genid, 0); 769 atomic_set(&net->ipv6.fib6_sernum, 1);
770 770
771 err = ipv6_init_mibs(net); 771 err = ipv6_init_mibs(net);
772 if (err) 772 if (err)
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index 72a4930bdc0a..6d16eb0e0c7f 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -17,10 +17,10 @@
17 * Authors 17 * Authors
18 * 18 *
19 * Mitsuru KANDA @USAGI : IPv6 Support 19 * Mitsuru KANDA @USAGI : IPv6 Support
20 * Kazunori MIYAZAWA @USAGI : 20 * Kazunori MIYAZAWA @USAGI :
21 * Kunihiro Ishiguro <kunihiro@ipinfusion.com> 21 * Kunihiro Ishiguro <kunihiro@ipinfusion.com>
22 * 22 *
23 * This file is derived from net/ipv4/ah.c. 23 * This file is derived from net/ipv4/ah.c.
24 */ 24 */
25 25
26#define pr_fmt(fmt) "IPv6: " fmt 26#define pr_fmt(fmt) "IPv6: " fmt
@@ -284,7 +284,7 @@ static int ipv6_clear_mutable_options(struct ipv6hdr *iph, int len, int dir)
284 ipv6_rearrange_rthdr(iph, exthdr.rth); 284 ipv6_rearrange_rthdr(iph, exthdr.rth);
285 break; 285 break;
286 286
287 default : 287 default:
288 return 0; 288 return 0;
289 } 289 }
290 290
@@ -478,7 +478,7 @@ static void ah6_input_done(struct crypto_async_request *base, int err)
478 auth_data = ah_tmp_auth(work_iph, hdr_len); 478 auth_data = ah_tmp_auth(work_iph, hdr_len);
479 icv = ah_tmp_icv(ahp->ahash, auth_data, ahp->icv_trunc_len); 479 icv = ah_tmp_icv(ahp->ahash, auth_data, ahp->icv_trunc_len);
480 480
481 err = memcmp(icv, auth_data, ahp->icv_trunc_len) ? -EBADMSG: 0; 481 err = memcmp(icv, auth_data, ahp->icv_trunc_len) ? -EBADMSG : 0;
482 if (err) 482 if (err)
483 goto out; 483 goto out;
484 484
@@ -622,7 +622,7 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb)
622 goto out_free; 622 goto out_free;
623 } 623 }
624 624
625 err = memcmp(icv, auth_data, ahp->icv_trunc_len) ? -EBADMSG: 0; 625 err = memcmp(icv, auth_data, ahp->icv_trunc_len) ? -EBADMSG : 0;
626 if (err) 626 if (err)
627 goto out_free; 627 goto out_free;
628 628
@@ -647,8 +647,8 @@ static int ah6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
647 u8 type, u8 code, int offset, __be32 info) 647 u8 type, u8 code, int offset, __be32 info)
648{ 648{
649 struct net *net = dev_net(skb->dev); 649 struct net *net = dev_net(skb->dev);
650 struct ipv6hdr *iph = (struct ipv6hdr*)skb->data; 650 struct ipv6hdr *iph = (struct ipv6hdr *)skb->data;
651 struct ip_auth_hdr *ah = (struct ip_auth_hdr*)(skb->data+offset); 651 struct ip_auth_hdr *ah = (struct ip_auth_hdr *)(skb->data+offset);
652 struct xfrm_state *x; 652 struct xfrm_state *x;
653 653
654 if (type != ICMPV6_PKT_TOOBIG && 654 if (type != ICMPV6_PKT_TOOBIG &&
@@ -713,8 +713,6 @@ static int ah6_init_state(struct xfrm_state *x)
713 ahp->icv_full_len = aalg_desc->uinfo.auth.icv_fullbits/8; 713 ahp->icv_full_len = aalg_desc->uinfo.auth.icv_fullbits/8;
714 ahp->icv_trunc_len = x->aalg->alg_trunc_len/8; 714 ahp->icv_trunc_len = x->aalg->alg_trunc_len/8;
715 715
716 BUG_ON(ahp->icv_trunc_len > MAX_AH_AUTH_LEN);
717
718 x->props.header_len = XFRM_ALIGN8(sizeof(struct ip_auth_hdr) + 716 x->props.header_len = XFRM_ALIGN8(sizeof(struct ip_auth_hdr) +
719 ahp->icv_trunc_len); 717 ahp->icv_trunc_len);
720 switch (x->props.mode) { 718 switch (x->props.mode) {
@@ -755,11 +753,10 @@ static int ah6_rcv_cb(struct sk_buff *skb, int err)
755 return 0; 753 return 0;
756} 754}
757 755
758static const struct xfrm_type ah6_type = 756static const struct xfrm_type ah6_type = {
759{
760 .description = "AH6", 757 .description = "AH6",
761 .owner = THIS_MODULE, 758 .owner = THIS_MODULE,
762 .proto = IPPROTO_AH, 759 .proto = IPPROTO_AH,
763 .flags = XFRM_TYPE_REPLAY_PROT, 760 .flags = XFRM_TYPE_REPLAY_PROT,
764 .init_state = ah6_init_state, 761 .init_state = ah6_init_state,
765 .destructor = ah6_destroy, 762 .destructor = ah6_destroy,
diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c
index 9a386842fd62..f5e319a8d4e2 100644
--- a/net/ipv6/anycast.c
+++ b/net/ipv6/anycast.c
@@ -46,10 +46,6 @@
46 46
47static int ipv6_dev_ac_dec(struct net_device *dev, const struct in6_addr *addr); 47static int ipv6_dev_ac_dec(struct net_device *dev, const struct in6_addr *addr);
48 48
49/* Big ac list lock for all the sockets */
50static DEFINE_SPINLOCK(ipv6_sk_ac_lock);
51
52
53/* 49/*
54 * socket join an anycast group 50 * socket join an anycast group
55 */ 51 */
@@ -78,7 +74,6 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
78 pac->acl_addr = *addr; 74 pac->acl_addr = *addr;
79 75
80 rtnl_lock(); 76 rtnl_lock();
81 rcu_read_lock();
82 if (ifindex == 0) { 77 if (ifindex == 0) {
83 struct rt6_info *rt; 78 struct rt6_info *rt;
84 79
@@ -91,11 +86,11 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
91 goto error; 86 goto error;
92 } else { 87 } else {
93 /* router, no matching interface: just pick one */ 88 /* router, no matching interface: just pick one */
94 dev = dev_get_by_flags_rcu(net, IFF_UP, 89 dev = __dev_get_by_flags(net, IFF_UP,
95 IFF_UP | IFF_LOOPBACK); 90 IFF_UP | IFF_LOOPBACK);
96 } 91 }
97 } else 92 } else
98 dev = dev_get_by_index_rcu(net, ifindex); 93 dev = __dev_get_by_index(net, ifindex);
99 94
100 if (dev == NULL) { 95 if (dev == NULL) {
101 err = -ENODEV; 96 err = -ENODEV;
@@ -127,17 +122,14 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
127 goto error; 122 goto error;
128 } 123 }
129 124
130 err = ipv6_dev_ac_inc(dev, addr); 125 err = __ipv6_dev_ac_inc(idev, addr);
131 if (!err) { 126 if (!err) {
132 spin_lock_bh(&ipv6_sk_ac_lock);
133 pac->acl_next = np->ipv6_ac_list; 127 pac->acl_next = np->ipv6_ac_list;
134 np->ipv6_ac_list = pac; 128 np->ipv6_ac_list = pac;
135 spin_unlock_bh(&ipv6_sk_ac_lock);
136 pac = NULL; 129 pac = NULL;
137 } 130 }
138 131
139error: 132error:
140 rcu_read_unlock();
141 rtnl_unlock(); 133 rtnl_unlock();
142 if (pac) 134 if (pac)
143 sock_kfree_s(sk, pac, sizeof(*pac)); 135 sock_kfree_s(sk, pac, sizeof(*pac));
@@ -154,7 +146,7 @@ int ipv6_sock_ac_drop(struct sock *sk, int ifindex, const struct in6_addr *addr)
154 struct ipv6_ac_socklist *pac, *prev_pac; 146 struct ipv6_ac_socklist *pac, *prev_pac;
155 struct net *net = sock_net(sk); 147 struct net *net = sock_net(sk);
156 148
157 spin_lock_bh(&ipv6_sk_ac_lock); 149 rtnl_lock();
158 prev_pac = NULL; 150 prev_pac = NULL;
159 for (pac = np->ipv6_ac_list; pac; pac = pac->acl_next) { 151 for (pac = np->ipv6_ac_list; pac; pac = pac->acl_next) {
160 if ((ifindex == 0 || pac->acl_ifindex == ifindex) && 152 if ((ifindex == 0 || pac->acl_ifindex == ifindex) &&
@@ -163,7 +155,7 @@ int ipv6_sock_ac_drop(struct sock *sk, int ifindex, const struct in6_addr *addr)
163 prev_pac = pac; 155 prev_pac = pac;
164 } 156 }
165 if (!pac) { 157 if (!pac) {
166 spin_unlock_bh(&ipv6_sk_ac_lock); 158 rtnl_unlock();
167 return -ENOENT; 159 return -ENOENT;
168 } 160 }
169 if (prev_pac) 161 if (prev_pac)
@@ -171,14 +163,9 @@ int ipv6_sock_ac_drop(struct sock *sk, int ifindex, const struct in6_addr *addr)
171 else 163 else
172 np->ipv6_ac_list = pac->acl_next; 164 np->ipv6_ac_list = pac->acl_next;
173 165
174 spin_unlock_bh(&ipv6_sk_ac_lock); 166 dev = __dev_get_by_index(net, pac->acl_ifindex);
175
176 rtnl_lock();
177 rcu_read_lock();
178 dev = dev_get_by_index_rcu(net, pac->acl_ifindex);
179 if (dev) 167 if (dev)
180 ipv6_dev_ac_dec(dev, &pac->acl_addr); 168 ipv6_dev_ac_dec(dev, &pac->acl_addr);
181 rcu_read_unlock();
182 rtnl_unlock(); 169 rtnl_unlock();
183 170
184 sock_kfree_s(sk, pac, sizeof(*pac)); 171 sock_kfree_s(sk, pac, sizeof(*pac));
@@ -196,19 +183,16 @@ void ipv6_sock_ac_close(struct sock *sk)
196 if (!np->ipv6_ac_list) 183 if (!np->ipv6_ac_list)
197 return; 184 return;
198 185
199 spin_lock_bh(&ipv6_sk_ac_lock); 186 rtnl_lock();
200 pac = np->ipv6_ac_list; 187 pac = np->ipv6_ac_list;
201 np->ipv6_ac_list = NULL; 188 np->ipv6_ac_list = NULL;
202 spin_unlock_bh(&ipv6_sk_ac_lock);
203 189
204 prev_index = 0; 190 prev_index = 0;
205 rtnl_lock();
206 rcu_read_lock();
207 while (pac) { 191 while (pac) {
208 struct ipv6_ac_socklist *next = pac->acl_next; 192 struct ipv6_ac_socklist *next = pac->acl_next;
209 193
210 if (pac->acl_ifindex != prev_index) { 194 if (pac->acl_ifindex != prev_index) {
211 dev = dev_get_by_index_rcu(net, pac->acl_ifindex); 195 dev = __dev_get_by_index(net, pac->acl_ifindex);
212 prev_index = pac->acl_ifindex; 196 prev_index = pac->acl_ifindex;
213 } 197 }
214 if (dev) 198 if (dev)
@@ -216,10 +200,14 @@ void ipv6_sock_ac_close(struct sock *sk)
216 sock_kfree_s(sk, pac, sizeof(*pac)); 200 sock_kfree_s(sk, pac, sizeof(*pac));
217 pac = next; 201 pac = next;
218 } 202 }
219 rcu_read_unlock();
220 rtnl_unlock(); 203 rtnl_unlock();
221} 204}
222 205
206static void aca_get(struct ifacaddr6 *aca)
207{
208 atomic_inc(&aca->aca_refcnt);
209}
210
223static void aca_put(struct ifacaddr6 *ac) 211static void aca_put(struct ifacaddr6 *ac)
224{ 212{
225 if (atomic_dec_and_test(&ac->aca_refcnt)) { 213 if (atomic_dec_and_test(&ac->aca_refcnt)) {
@@ -229,23 +217,40 @@ static void aca_put(struct ifacaddr6 *ac)
229 } 217 }
230} 218}
231 219
220static struct ifacaddr6 *aca_alloc(struct rt6_info *rt,
221 const struct in6_addr *addr)
222{
223 struct inet6_dev *idev = rt->rt6i_idev;
224 struct ifacaddr6 *aca;
225
226 aca = kzalloc(sizeof(*aca), GFP_ATOMIC);
227 if (aca == NULL)
228 return NULL;
229
230 aca->aca_addr = *addr;
231 in6_dev_hold(idev);
232 aca->aca_idev = idev;
233 aca->aca_rt = rt;
234 aca->aca_users = 1;
235 /* aca_tstamp should be updated upon changes */
236 aca->aca_cstamp = aca->aca_tstamp = jiffies;
237 atomic_set(&aca->aca_refcnt, 1);
238 spin_lock_init(&aca->aca_lock);
239
240 return aca;
241}
242
232/* 243/*
233 * device anycast group inc (add if not found) 244 * device anycast group inc (add if not found)
234 */ 245 */
235int ipv6_dev_ac_inc(struct net_device *dev, const struct in6_addr *addr) 246int __ipv6_dev_ac_inc(struct inet6_dev *idev, const struct in6_addr *addr)
236{ 247{
237 struct ifacaddr6 *aca; 248 struct ifacaddr6 *aca;
238 struct inet6_dev *idev;
239 struct rt6_info *rt; 249 struct rt6_info *rt;
240 int err; 250 int err;
241 251
242 ASSERT_RTNL(); 252 ASSERT_RTNL();
243 253
244 idev = in6_dev_get(dev);
245
246 if (idev == NULL)
247 return -EINVAL;
248
249 write_lock_bh(&idev->lock); 254 write_lock_bh(&idev->lock);
250 if (idev->dead) { 255 if (idev->dead) {
251 err = -ENODEV; 256 err = -ENODEV;
@@ -260,46 +265,35 @@ int ipv6_dev_ac_inc(struct net_device *dev, const struct in6_addr *addr)
260 } 265 }
261 } 266 }
262 267
263 /*
264 * not found: create a new one.
265 */
266
267 aca = kzalloc(sizeof(struct ifacaddr6), GFP_ATOMIC);
268
269 if (aca == NULL) {
270 err = -ENOMEM;
271 goto out;
272 }
273
274 rt = addrconf_dst_alloc(idev, addr, true); 268 rt = addrconf_dst_alloc(idev, addr, true);
275 if (IS_ERR(rt)) { 269 if (IS_ERR(rt)) {
276 kfree(aca);
277 err = PTR_ERR(rt); 270 err = PTR_ERR(rt);
278 goto out; 271 goto out;
279 } 272 }
280 273 aca = aca_alloc(rt, addr);
281 aca->aca_addr = *addr; 274 if (aca == NULL) {
282 aca->aca_idev = idev; 275 ip6_rt_put(rt);
283 aca->aca_rt = rt; 276 err = -ENOMEM;
284 aca->aca_users = 1; 277 goto out;
285 /* aca_tstamp should be updated upon changes */ 278 }
286 aca->aca_cstamp = aca->aca_tstamp = jiffies;
287 atomic_set(&aca->aca_refcnt, 2);
288 spin_lock_init(&aca->aca_lock);
289 279
290 aca->aca_next = idev->ac_list; 280 aca->aca_next = idev->ac_list;
291 idev->ac_list = aca; 281 idev->ac_list = aca;
282
283 /* Hold this for addrconf_join_solict() below before we unlock,
284 * it is already exposed via idev->ac_list.
285 */
286 aca_get(aca);
292 write_unlock_bh(&idev->lock); 287 write_unlock_bh(&idev->lock);
293 288
294 ip6_ins_rt(rt); 289 ip6_ins_rt(rt);
295 290
296 addrconf_join_solict(dev, &aca->aca_addr); 291 addrconf_join_solict(idev->dev, &aca->aca_addr);
297 292
298 aca_put(aca); 293 aca_put(aca);
299 return 0; 294 return 0;
300out: 295out:
301 write_unlock_bh(&idev->lock); 296 write_unlock_bh(&idev->lock);
302 in6_dev_put(idev);
303 return err; 297 return err;
304} 298}
305 299
@@ -341,7 +335,7 @@ int __ipv6_dev_ac_dec(struct inet6_dev *idev, const struct in6_addr *addr)
341 return 0; 335 return 0;
342} 336}
343 337
344/* called with rcu_read_lock() */ 338/* called with rtnl_lock() */
345static int ipv6_dev_ac_dec(struct net_device *dev, const struct in6_addr *addr) 339static int ipv6_dev_ac_dec(struct net_device *dev, const struct in6_addr *addr)
346{ 340{
347 struct inet6_dev *idev = __in6_dev_get(dev); 341 struct inet6_dev *idev = __in6_dev_get(dev);
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index 2753319524f1..2cdc38338be3 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -43,13 +43,13 @@ static bool ipv6_mapped_addr_any(const struct in6_addr *a)
43int ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) 43int ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
44{ 44{
45 struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr; 45 struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr;
46 struct inet_sock *inet = inet_sk(sk); 46 struct inet_sock *inet = inet_sk(sk);
47 struct ipv6_pinfo *np = inet6_sk(sk); 47 struct ipv6_pinfo *np = inet6_sk(sk);
48 struct in6_addr *daddr, *final_p, final; 48 struct in6_addr *daddr, *final_p, final;
49 struct dst_entry *dst; 49 struct dst_entry *dst;
50 struct flowi6 fl6; 50 struct flowi6 fl6;
51 struct ip6_flowlabel *flowlabel = NULL; 51 struct ip6_flowlabel *flowlabel = NULL;
52 struct ipv6_txoptions *opt; 52 struct ipv6_txoptions *opt;
53 int addr_type; 53 int addr_type;
54 int err; 54 int err;
55 55
@@ -332,7 +332,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
332{ 332{
333 struct ipv6_pinfo *np = inet6_sk(sk); 333 struct ipv6_pinfo *np = inet6_sk(sk);
334 struct sock_exterr_skb *serr; 334 struct sock_exterr_skb *serr;
335 struct sk_buff *skb, *skb2; 335 struct sk_buff *skb;
336 DECLARE_SOCKADDR(struct sockaddr_in6 *, sin, msg->msg_name); 336 DECLARE_SOCKADDR(struct sockaddr_in6 *, sin, msg->msg_name);
337 struct { 337 struct {
338 struct sock_extended_err ee; 338 struct sock_extended_err ee;
@@ -342,7 +342,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
342 int copied; 342 int copied;
343 343
344 err = -EAGAIN; 344 err = -EAGAIN;
345 skb = skb_dequeue(&sk->sk_error_queue); 345 skb = sock_dequeue_err_skb(sk);
346 if (skb == NULL) 346 if (skb == NULL)
347 goto out; 347 goto out;
348 348
@@ -415,17 +415,6 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
415 msg->msg_flags |= MSG_ERRQUEUE; 415 msg->msg_flags |= MSG_ERRQUEUE;
416 err = copied; 416 err = copied;
417 417
418 /* Reset and regenerate socket error */
419 spin_lock_bh(&sk->sk_error_queue.lock);
420 sk->sk_err = 0;
421 if ((skb2 = skb_peek(&sk->sk_error_queue)) != NULL) {
422 sk->sk_err = SKB_EXT_ERR(skb2)->ee.ee_errno;
423 spin_unlock_bh(&sk->sk_error_queue.lock);
424 sk->sk_error_report(sk);
425 } else {
426 spin_unlock_bh(&sk->sk_error_queue.lock);
427 }
428
429out_free_skb: 418out_free_skb:
430 kfree_skb(skb); 419 kfree_skb(skb);
431out: 420out:
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index d15da1377149..83fc3a385a26 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -17,10 +17,10 @@
17 * Authors 17 * Authors
18 * 18 *
19 * Mitsuru KANDA @USAGI : IPv6 Support 19 * Mitsuru KANDA @USAGI : IPv6 Support
20 * Kazunori MIYAZAWA @USAGI : 20 * Kazunori MIYAZAWA @USAGI :
21 * Kunihiro Ishiguro <kunihiro@ipinfusion.com> 21 * Kunihiro Ishiguro <kunihiro@ipinfusion.com>
22 * 22 *
23 * This file is derived from net/ipv4/esp.c 23 * This file is derived from net/ipv4/esp.c
24 */ 24 */
25 25
26#define pr_fmt(fmt) "IPv6: " fmt 26#define pr_fmt(fmt) "IPv6: " fmt
@@ -598,7 +598,7 @@ static int esp6_init_state(struct xfrm_state *x)
598 case XFRM_MODE_BEET: 598 case XFRM_MODE_BEET:
599 if (x->sel.family != AF_INET6) 599 if (x->sel.family != AF_INET6)
600 x->props.header_len += IPV4_BEET_PHMAXLEN + 600 x->props.header_len += IPV4_BEET_PHMAXLEN +
601 (sizeof(struct ipv6hdr) - sizeof(struct iphdr)); 601 (sizeof(struct ipv6hdr) - sizeof(struct iphdr));
602 break; 602 break;
603 case XFRM_MODE_TRANSPORT: 603 case XFRM_MODE_TRANSPORT:
604 break; 604 break;
@@ -621,11 +621,10 @@ static int esp6_rcv_cb(struct sk_buff *skb, int err)
621 return 0; 621 return 0;
622} 622}
623 623
624static const struct xfrm_type esp6_type = 624static const struct xfrm_type esp6_type = {
625{
626 .description = "ESP6", 625 .description = "ESP6",
627 .owner = THIS_MODULE, 626 .owner = THIS_MODULE,
628 .proto = IPPROTO_ESP, 627 .proto = IPPROTO_ESP,
629 .flags = XFRM_TYPE_REPLAY_PROT, 628 .flags = XFRM_TYPE_REPLAY_PROT,
630 .init_state = esp6_init_state, 629 .init_state = esp6_init_state,
631 .destructor = esp6_destroy, 630 .destructor = esp6_destroy,
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 8d67900aa003..bfde361b6134 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -142,7 +142,7 @@ static bool ip6_parse_tlv(const struct tlvtype_proc *procs, struct sk_buff *skb)
142 default: /* Other TLV code so scan list */ 142 default: /* Other TLV code so scan list */
143 if (optlen > len) 143 if (optlen > len)
144 goto bad; 144 goto bad;
145 for (curr=procs; curr->type >= 0; curr++) { 145 for (curr = procs; curr->type >= 0; curr++) {
146 if (curr->type == nh[off]) { 146 if (curr->type == nh[off]) {
147 /* type specific length/alignment 147 /* type specific length/alignment
148 checks will be performed in the 148 checks will be performed in the
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 06ba3e58320b..97ae70077a4f 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -170,11 +170,11 @@ static bool is_ineligible(const struct sk_buff *skb)
170/* 170/*
171 * Check the ICMP output rate limit 171 * Check the ICMP output rate limit
172 */ 172 */
173static inline bool icmpv6_xrlim_allow(struct sock *sk, u8 type, 173static bool icmpv6_xrlim_allow(struct sock *sk, u8 type,
174 struct flowi6 *fl6) 174 struct flowi6 *fl6)
175{ 175{
176 struct dst_entry *dst;
177 struct net *net = sock_net(sk); 176 struct net *net = sock_net(sk);
177 struct dst_entry *dst;
178 bool res = false; 178 bool res = false;
179 179
180 /* Informational messages are not limited. */ 180 /* Informational messages are not limited. */
@@ -199,16 +199,20 @@ static inline bool icmpv6_xrlim_allow(struct sock *sk, u8 type,
199 } else { 199 } else {
200 struct rt6_info *rt = (struct rt6_info *)dst; 200 struct rt6_info *rt = (struct rt6_info *)dst;
201 int tmo = net->ipv6.sysctl.icmpv6_time; 201 int tmo = net->ipv6.sysctl.icmpv6_time;
202 struct inet_peer *peer;
203 202
204 /* Give more bandwidth to wider prefixes. */ 203 /* Give more bandwidth to wider prefixes. */
205 if (rt->rt6i_dst.plen < 128) 204 if (rt->rt6i_dst.plen < 128)
206 tmo >>= ((128 - rt->rt6i_dst.plen)>>5); 205 tmo >>= ((128 - rt->rt6i_dst.plen)>>5);
207 206
208 peer = inet_getpeer_v6(net->ipv6.peers, &rt->rt6i_dst.addr, 1); 207 if (icmp_global_allow()) {
209 res = inet_peer_xrlim_allow(peer, tmo); 208 struct inet_peer *peer;
210 if (peer) 209
211 inet_putpeer(peer); 210 peer = inet_getpeer_v6(net->ipv6.peers,
211 &rt->rt6i_dst.addr, 1);
212 res = inet_peer_xrlim_allow(peer, tmo);
213 if (peer)
214 inet_putpeer(peer);
215 }
212 } 216 }
213 dst_release(dst); 217 dst_release(dst);
214 return res; 218 return res;
@@ -503,7 +507,7 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
503 msg.type = type; 507 msg.type = type;
504 508
505 len = skb->len - msg.offset; 509 len = skb->len - msg.offset;
506 len = min_t(unsigned int, len, IPV6_MIN_MTU - sizeof(struct ipv6hdr) -sizeof(struct icmp6hdr)); 510 len = min_t(unsigned int, len, IPV6_MIN_MTU - sizeof(struct ipv6hdr) - sizeof(struct icmp6hdr));
507 if (len < 0) { 511 if (len < 0) {
508 LIMIT_NETDEBUG(KERN_DEBUG "icmp: len problem\n"); 512 LIMIT_NETDEBUG(KERN_DEBUG "icmp: len problem\n");
509 goto out_dst_release; 513 goto out_dst_release;
@@ -636,7 +640,7 @@ void icmpv6_notify(struct sk_buff *skb, u8 type, u8 code, __be32 info)
636 /* now skip over extension headers */ 640 /* now skip over extension headers */
637 inner_offset = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), 641 inner_offset = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr),
638 &nexthdr, &frag_off); 642 &nexthdr, &frag_off);
639 if (inner_offset<0) 643 if (inner_offset < 0)
640 goto out; 644 goto out;
641 } else { 645 } else {
642 inner_offset = sizeof(struct ipv6hdr); 646 inner_offset = sizeof(struct ipv6hdr);
@@ -773,12 +777,12 @@ static int icmpv6_rcv(struct sk_buff *skb)
773 break; 777 break;
774 778
775 default: 779 default:
776 LIMIT_NETDEBUG(KERN_DEBUG "icmpv6: msg of unknown type\n");
777
778 /* informational */ 780 /* informational */
779 if (type & ICMPV6_INFOMSG_MASK) 781 if (type & ICMPV6_INFOMSG_MASK)
780 break; 782 break;
781 783
784 LIMIT_NETDEBUG(KERN_DEBUG "icmpv6: msg of unknown type\n");
785
782 /* 786 /*
783 * error of unknown type. 787 * error of unknown type.
784 * must pass to upper level 788 * must pass to upper level
@@ -808,7 +812,7 @@ void icmpv6_flow_init(struct sock *sk, struct flowi6 *fl6,
808 memset(fl6, 0, sizeof(*fl6)); 812 memset(fl6, 0, sizeof(*fl6));
809 fl6->saddr = *saddr; 813 fl6->saddr = *saddr;
810 fl6->daddr = *daddr; 814 fl6->daddr = *daddr;
811 fl6->flowi6_proto = IPPROTO_ICMPV6; 815 fl6->flowi6_proto = IPPROTO_ICMPV6;
812 fl6->fl6_icmp_type = type; 816 fl6->fl6_icmp_type = type;
813 fl6->fl6_icmp_code = 0; 817 fl6->fl6_icmp_code = 0;
814 fl6->flowi6_oif = oif; 818 fl6->flowi6_oif = oif;
@@ -875,8 +879,8 @@ static void __net_exit icmpv6_sk_exit(struct net *net)
875} 879}
876 880
877static struct pernet_operations icmpv6_sk_ops = { 881static struct pernet_operations icmpv6_sk_ops = {
878 .init = icmpv6_sk_init, 882 .init = icmpv6_sk_init,
879 .exit = icmpv6_sk_exit, 883 .exit = icmpv6_sk_exit,
880}; 884};
881 885
882int __init icmpv6_init(void) 886int __init icmpv6_init(void)
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c
index a245e5ddffbd..29b32206e494 100644
--- a/net/ipv6/inet6_connection_sock.c
+++ b/net/ipv6/inet6_connection_sock.c
@@ -63,7 +63,6 @@ int inet6_csk_bind_conflict(const struct sock *sk,
63 63
64 return sk2 != NULL; 64 return sk2 != NULL;
65} 65}
66
67EXPORT_SYMBOL_GPL(inet6_csk_bind_conflict); 66EXPORT_SYMBOL_GPL(inet6_csk_bind_conflict);
68 67
69struct dst_entry *inet6_csk_route_req(struct sock *sk, 68struct dst_entry *inet6_csk_route_req(struct sock *sk,
@@ -144,7 +143,6 @@ struct request_sock *inet6_csk_search_req(const struct sock *sk,
144 143
145 return NULL; 144 return NULL;
146} 145}
147
148EXPORT_SYMBOL_GPL(inet6_csk_search_req); 146EXPORT_SYMBOL_GPL(inet6_csk_search_req);
149 147
150void inet6_csk_reqsk_queue_hash_add(struct sock *sk, 148void inet6_csk_reqsk_queue_hash_add(struct sock *sk,
@@ -160,10 +158,9 @@ void inet6_csk_reqsk_queue_hash_add(struct sock *sk,
160 reqsk_queue_hash_req(&icsk->icsk_accept_queue, h, req, timeout); 158 reqsk_queue_hash_req(&icsk->icsk_accept_queue, h, req, timeout);
161 inet_csk_reqsk_queue_added(sk, timeout); 159 inet_csk_reqsk_queue_added(sk, timeout);
162} 160}
163
164EXPORT_SYMBOL_GPL(inet6_csk_reqsk_queue_hash_add); 161EXPORT_SYMBOL_GPL(inet6_csk_reqsk_queue_hash_add);
165 162
166void inet6_csk_addr2sockaddr(struct sock *sk, struct sockaddr * uaddr) 163void inet6_csk_addr2sockaddr(struct sock *sk, struct sockaddr *uaddr)
167{ 164{
168 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) uaddr; 165 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) uaddr;
169 166
@@ -175,7 +172,6 @@ void inet6_csk_addr2sockaddr(struct sock *sk, struct sockaddr * uaddr)
175 sin6->sin6_scope_id = ipv6_iface_scope_id(&sin6->sin6_addr, 172 sin6->sin6_scope_id = ipv6_iface_scope_id(&sin6->sin6_addr,
176 sk->sk_bound_dev_if); 173 sk->sk_bound_dev_if);
177} 174}
178
179EXPORT_SYMBOL_GPL(inet6_csk_addr2sockaddr); 175EXPORT_SYMBOL_GPL(inet6_csk_addr2sockaddr);
180 176
181static inline 177static inline
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
index 262e13c02ec2..051dffb49c90 100644
--- a/net/ipv6/inet6_hashtables.c
+++ b/net/ipv6/inet6_hashtables.c
@@ -6,7 +6,7 @@
6 * Generic INET6 transport hashtables 6 * Generic INET6 transport hashtables
7 * 7 *
8 * Authors: Lotsa people, from code originally in tcp, generalised here 8 * Authors: Lotsa people, from code originally in tcp, generalised here
9 * by Arnaldo Carvalho de Melo <acme@mandriva.com> 9 * by Arnaldo Carvalho de Melo <acme@mandriva.com>
10 * 10 *
11 * This program is free software; you can redistribute it and/or 11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License 12 * modify it under the terms of the GNU General Public License
@@ -198,7 +198,7 @@ begin:
198 } 198 }
199 } else if (score == hiscore && reuseport) { 199 } else if (score == hiscore && reuseport) {
200 matches++; 200 matches++;
201 if (((u64)phash * matches) >> 32 == 0) 201 if (reciprocal_scale(phash, matches) == 0)
202 result = sk; 202 result = sk;
203 phash = next_pseudo_random32(phash); 203 phash = next_pseudo_random32(phash);
204 } 204 }
@@ -222,7 +222,6 @@ begin:
222 rcu_read_unlock(); 222 rcu_read_unlock();
223 return result; 223 return result;
224} 224}
225
226EXPORT_SYMBOL_GPL(inet6_lookup_listener); 225EXPORT_SYMBOL_GPL(inet6_lookup_listener);
227 226
228struct sock *inet6_lookup(struct net *net, struct inet_hashinfo *hashinfo, 227struct sock *inet6_lookup(struct net *net, struct inet_hashinfo *hashinfo,
@@ -238,7 +237,6 @@ struct sock *inet6_lookup(struct net *net, struct inet_hashinfo *hashinfo,
238 237
239 return sk; 238 return sk;
240} 239}
241
242EXPORT_SYMBOL_GPL(inet6_lookup); 240EXPORT_SYMBOL_GPL(inet6_lookup);
243 241
244static int __inet6_check_established(struct inet_timewait_death_row *death_row, 242static int __inet6_check_established(struct inet_timewait_death_row *death_row,
@@ -324,5 +322,4 @@ int inet6_hash_connect(struct inet_timewait_death_row *death_row,
324 return __inet_hash_connect(death_row, sk, inet6_sk_port_offset(sk), 322 return __inet_hash_connect(death_row, sk, inet6_sk_port_offset(sk),
325 __inet6_check_established, __inet6_hash); 323 __inet6_check_established, __inet6_hash);
326} 324}
327
328EXPORT_SYMBOL_GPL(inet6_hash_connect); 325EXPORT_SYMBOL_GPL(inet6_hash_connect);
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 97b9fa8de377..b2d1838897c9 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -46,20 +46,11 @@
46 46
47static struct kmem_cache *fib6_node_kmem __read_mostly; 47static struct kmem_cache *fib6_node_kmem __read_mostly;
48 48
49enum fib_walk_state_t { 49struct fib6_cleaner {
50#ifdef CONFIG_IPV6_SUBTREES 50 struct fib6_walker w;
51 FWS_S,
52#endif
53 FWS_L,
54 FWS_R,
55 FWS_C,
56 FWS_U
57};
58
59struct fib6_cleaner_t {
60 struct fib6_walker_t w;
61 struct net *net; 51 struct net *net;
62 int (*func)(struct rt6_info *, void *arg); 52 int (*func)(struct rt6_info *, void *arg);
53 int sernum;
63 void *arg; 54 void *arg;
64}; 55};
65 56
@@ -74,8 +65,8 @@ static DEFINE_RWLOCK(fib6_walker_lock);
74static void fib6_prune_clones(struct net *net, struct fib6_node *fn); 65static void fib6_prune_clones(struct net *net, struct fib6_node *fn);
75static struct rt6_info *fib6_find_prefix(struct net *net, struct fib6_node *fn); 66static struct rt6_info *fib6_find_prefix(struct net *net, struct fib6_node *fn);
76static struct fib6_node *fib6_repair_tree(struct net *net, struct fib6_node *fn); 67static struct fib6_node *fib6_repair_tree(struct net *net, struct fib6_node *fn);
77static int fib6_walk(struct fib6_walker_t *w); 68static int fib6_walk(struct fib6_walker *w);
78static int fib6_walk_continue(struct fib6_walker_t *w); 69static int fib6_walk_continue(struct fib6_walker *w);
79 70
80/* 71/*
81 * A routing update causes an increase of the serial number on the 72 * A routing update causes an increase of the serial number on the
@@ -84,34 +75,41 @@ static int fib6_walk_continue(struct fib6_walker_t *w);
84 * result of redirects, path MTU changes, etc. 75 * result of redirects, path MTU changes, etc.
85 */ 76 */
86 77
87static __u32 rt_sernum;
88
89static void fib6_gc_timer_cb(unsigned long arg); 78static void fib6_gc_timer_cb(unsigned long arg);
90 79
91static LIST_HEAD(fib6_walkers); 80static LIST_HEAD(fib6_walkers);
92#define FOR_WALKERS(w) list_for_each_entry(w, &fib6_walkers, lh) 81#define FOR_WALKERS(w) list_for_each_entry(w, &fib6_walkers, lh)
93 82
94static inline void fib6_walker_link(struct fib6_walker_t *w) 83static void fib6_walker_link(struct fib6_walker *w)
95{ 84{
96 write_lock_bh(&fib6_walker_lock); 85 write_lock_bh(&fib6_walker_lock);
97 list_add(&w->lh, &fib6_walkers); 86 list_add(&w->lh, &fib6_walkers);
98 write_unlock_bh(&fib6_walker_lock); 87 write_unlock_bh(&fib6_walker_lock);
99} 88}
100 89
101static inline void fib6_walker_unlink(struct fib6_walker_t *w) 90static void fib6_walker_unlink(struct fib6_walker *w)
102{ 91{
103 write_lock_bh(&fib6_walker_lock); 92 write_lock_bh(&fib6_walker_lock);
104 list_del(&w->lh); 93 list_del(&w->lh);
105 write_unlock_bh(&fib6_walker_lock); 94 write_unlock_bh(&fib6_walker_lock);
106} 95}
107static __inline__ u32 fib6_new_sernum(void) 96
97static int fib6_new_sernum(struct net *net)
108{ 98{
109 u32 n = ++rt_sernum; 99 int new, old;
110 if ((__s32)n <= 0) 100
111 rt_sernum = n = 1; 101 do {
112 return n; 102 old = atomic_read(&net->ipv6.fib6_sernum);
103 new = old < INT_MAX ? old + 1 : 1;
104 } while (atomic_cmpxchg(&net->ipv6.fib6_sernum,
105 old, new) != old);
106 return new;
113} 107}
114 108
109enum {
110 FIB6_NO_SERNUM_CHANGE = 0,
111};
112
115/* 113/*
116 * Auxiliary address test functions for the radix tree. 114 * Auxiliary address test functions for the radix tree.
117 * 115 *
@@ -128,7 +126,7 @@ static __inline__ u32 fib6_new_sernum(void)
128# define BITOP_BE32_SWIZZLE 0 126# define BITOP_BE32_SWIZZLE 0
129#endif 127#endif
130 128
131static __inline__ __be32 addr_bit_set(const void *token, int fn_bit) 129static __be32 addr_bit_set(const void *token, int fn_bit)
132{ 130{
133 const __be32 *addr = token; 131 const __be32 *addr = token;
134 /* 132 /*
@@ -142,7 +140,7 @@ static __inline__ __be32 addr_bit_set(const void *token, int fn_bit)
142 addr[fn_bit >> 5]; 140 addr[fn_bit >> 5];
143} 141}
144 142
145static __inline__ struct fib6_node *node_alloc(void) 143static struct fib6_node *node_alloc(void)
146{ 144{
147 struct fib6_node *fn; 145 struct fib6_node *fn;
148 146
@@ -151,12 +149,12 @@ static __inline__ struct fib6_node *node_alloc(void)
151 return fn; 149 return fn;
152} 150}
153 151
154static __inline__ void node_free(struct fib6_node *fn) 152static void node_free(struct fib6_node *fn)
155{ 153{
156 kmem_cache_free(fib6_node_kmem, fn); 154 kmem_cache_free(fib6_node_kmem, fn);
157} 155}
158 156
159static __inline__ void rt6_release(struct rt6_info *rt) 157static void rt6_release(struct rt6_info *rt)
160{ 158{
161 if (atomic_dec_and_test(&rt->rt6i_ref)) 159 if (atomic_dec_and_test(&rt->rt6i_ref))
162 dst_free(&rt->dst); 160 dst_free(&rt->dst);
@@ -267,7 +265,7 @@ static void __net_init fib6_tables_init(struct net *net)
267 265
268#endif 266#endif
269 267
270static int fib6_dump_node(struct fib6_walker_t *w) 268static int fib6_dump_node(struct fib6_walker *w)
271{ 269{
272 int res; 270 int res;
273 struct rt6_info *rt; 271 struct rt6_info *rt;
@@ -287,7 +285,7 @@ static int fib6_dump_node(struct fib6_walker_t *w)
287 285
288static void fib6_dump_end(struct netlink_callback *cb) 286static void fib6_dump_end(struct netlink_callback *cb)
289{ 287{
290 struct fib6_walker_t *w = (void *)cb->args[2]; 288 struct fib6_walker *w = (void *)cb->args[2];
291 289
292 if (w) { 290 if (w) {
293 if (cb->args[4]) { 291 if (cb->args[4]) {
@@ -310,7 +308,7 @@ static int fib6_dump_done(struct netlink_callback *cb)
310static int fib6_dump_table(struct fib6_table *table, struct sk_buff *skb, 308static int fib6_dump_table(struct fib6_table *table, struct sk_buff *skb,
311 struct netlink_callback *cb) 309 struct netlink_callback *cb)
312{ 310{
313 struct fib6_walker_t *w; 311 struct fib6_walker *w;
314 int res; 312 int res;
315 313
316 w = (void *)cb->args[2]; 314 w = (void *)cb->args[2];
@@ -355,7 +353,7 @@ static int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
355 unsigned int h, s_h; 353 unsigned int h, s_h;
356 unsigned int e = 0, s_e; 354 unsigned int e = 0, s_e;
357 struct rt6_rtnl_dump_arg arg; 355 struct rt6_rtnl_dump_arg arg;
358 struct fib6_walker_t *w; 356 struct fib6_walker *w;
359 struct fib6_table *tb; 357 struct fib6_table *tb;
360 struct hlist_head *head; 358 struct hlist_head *head;
361 int res = 0; 359 int res = 0;
@@ -423,14 +421,13 @@ out:
423static struct fib6_node *fib6_add_1(struct fib6_node *root, 421static struct fib6_node *fib6_add_1(struct fib6_node *root,
424 struct in6_addr *addr, int plen, 422 struct in6_addr *addr, int plen,
425 int offset, int allow_create, 423 int offset, int allow_create,
426 int replace_required) 424 int replace_required, int sernum)
427{ 425{
428 struct fib6_node *fn, *in, *ln; 426 struct fib6_node *fn, *in, *ln;
429 struct fib6_node *pn = NULL; 427 struct fib6_node *pn = NULL;
430 struct rt6key *key; 428 struct rt6key *key;
431 int bit; 429 int bit;
432 __be32 dir = 0; 430 __be32 dir = 0;
433 __u32 sernum = fib6_new_sernum();
434 431
435 RT6_TRACE("fib6_add_1\n"); 432 RT6_TRACE("fib6_add_1\n");
436 433
@@ -627,7 +624,7 @@ insert_above:
627 return ln; 624 return ln;
628} 625}
629 626
630static inline bool rt6_qualify_for_ecmp(struct rt6_info *rt) 627static bool rt6_qualify_for_ecmp(struct rt6_info *rt)
631{ 628{
632 return (rt->rt6i_flags & (RTF_GATEWAY|RTF_ADDRCONF|RTF_DYNAMIC)) == 629 return (rt->rt6i_flags & (RTF_GATEWAY|RTF_ADDRCONF|RTF_DYNAMIC)) ==
633 RTF_GATEWAY; 630 RTF_GATEWAY;
@@ -820,7 +817,7 @@ add:
820 return 0; 817 return 0;
821} 818}
822 819
823static __inline__ void fib6_start_gc(struct net *net, struct rt6_info *rt) 820static void fib6_start_gc(struct net *net, struct rt6_info *rt)
824{ 821{
825 if (!timer_pending(&net->ipv6.ip6_fib_timer) && 822 if (!timer_pending(&net->ipv6.ip6_fib_timer) &&
826 (rt->rt6i_flags & (RTF_EXPIRES | RTF_CACHE))) 823 (rt->rt6i_flags & (RTF_EXPIRES | RTF_CACHE)))
@@ -848,6 +845,7 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt, struct nl_info *info,
848 int err = -ENOMEM; 845 int err = -ENOMEM;
849 int allow_create = 1; 846 int allow_create = 1;
850 int replace_required = 0; 847 int replace_required = 0;
848 int sernum = fib6_new_sernum(info->nl_net);
851 849
852 if (info->nlh) { 850 if (info->nlh) {
853 if (!(info->nlh->nlmsg_flags & NLM_F_CREATE)) 851 if (!(info->nlh->nlmsg_flags & NLM_F_CREATE))
@@ -860,7 +858,7 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt, struct nl_info *info,
860 858
861 fn = fib6_add_1(root, &rt->rt6i_dst.addr, rt->rt6i_dst.plen, 859 fn = fib6_add_1(root, &rt->rt6i_dst.addr, rt->rt6i_dst.plen,
862 offsetof(struct rt6_info, rt6i_dst), allow_create, 860 offsetof(struct rt6_info, rt6i_dst), allow_create,
863 replace_required); 861 replace_required, sernum);
864 if (IS_ERR(fn)) { 862 if (IS_ERR(fn)) {
865 err = PTR_ERR(fn); 863 err = PTR_ERR(fn);
866 fn = NULL; 864 fn = NULL;
@@ -894,14 +892,14 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt, struct nl_info *info,
894 sfn->leaf = info->nl_net->ipv6.ip6_null_entry; 892 sfn->leaf = info->nl_net->ipv6.ip6_null_entry;
895 atomic_inc(&info->nl_net->ipv6.ip6_null_entry->rt6i_ref); 893 atomic_inc(&info->nl_net->ipv6.ip6_null_entry->rt6i_ref);
896 sfn->fn_flags = RTN_ROOT; 894 sfn->fn_flags = RTN_ROOT;
897 sfn->fn_sernum = fib6_new_sernum(); 895 sfn->fn_sernum = sernum;
898 896
899 /* Now add the first leaf node to new subtree */ 897 /* Now add the first leaf node to new subtree */
900 898
901 sn = fib6_add_1(sfn, &rt->rt6i_src.addr, 899 sn = fib6_add_1(sfn, &rt->rt6i_src.addr,
902 rt->rt6i_src.plen, 900 rt->rt6i_src.plen,
903 offsetof(struct rt6_info, rt6i_src), 901 offsetof(struct rt6_info, rt6i_src),
904 allow_create, replace_required); 902 allow_create, replace_required, sernum);
905 903
906 if (IS_ERR(sn)) { 904 if (IS_ERR(sn)) {
907 /* If it is failed, discard just allocated 905 /* If it is failed, discard just allocated
@@ -920,7 +918,7 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt, struct nl_info *info,
920 sn = fib6_add_1(fn->subtree, &rt->rt6i_src.addr, 918 sn = fib6_add_1(fn->subtree, &rt->rt6i_src.addr,
921 rt->rt6i_src.plen, 919 rt->rt6i_src.plen,
922 offsetof(struct rt6_info, rt6i_src), 920 offsetof(struct rt6_info, rt6i_src),
923 allow_create, replace_required); 921 allow_create, replace_required, sernum);
924 922
925 if (IS_ERR(sn)) { 923 if (IS_ERR(sn)) {
926 err = PTR_ERR(sn); 924 err = PTR_ERR(sn);
@@ -1174,7 +1172,7 @@ static struct fib6_node *fib6_repair_tree(struct net *net,
1174 int children; 1172 int children;
1175 int nstate; 1173 int nstate;
1176 struct fib6_node *child, *pn; 1174 struct fib6_node *child, *pn;
1177 struct fib6_walker_t *w; 1175 struct fib6_walker *w;
1178 int iter = 0; 1176 int iter = 0;
1179 1177
1180 for (;;) { 1178 for (;;) {
@@ -1276,7 +1274,7 @@ static struct fib6_node *fib6_repair_tree(struct net *net,
1276static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp, 1274static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp,
1277 struct nl_info *info) 1275 struct nl_info *info)
1278{ 1276{
1279 struct fib6_walker_t *w; 1277 struct fib6_walker *w;
1280 struct rt6_info *rt = *rtp; 1278 struct rt6_info *rt = *rtp;
1281 struct net *net = info->nl_net; 1279 struct net *net = info->nl_net;
1282 1280
@@ -1414,7 +1412,7 @@ int fib6_del(struct rt6_info *rt, struct nl_info *info)
1414 * <0 -> walk is terminated by an error. 1412 * <0 -> walk is terminated by an error.
1415 */ 1413 */
1416 1414
1417static int fib6_walk_continue(struct fib6_walker_t *w) 1415static int fib6_walk_continue(struct fib6_walker *w)
1418{ 1416{
1419 struct fib6_node *fn, *pn; 1417 struct fib6_node *fn, *pn;
1420 1418
@@ -1498,7 +1496,7 @@ skip:
1498 } 1496 }
1499} 1497}
1500 1498
1501static int fib6_walk(struct fib6_walker_t *w) 1499static int fib6_walk(struct fib6_walker *w)
1502{ 1500{
1503 int res; 1501 int res;
1504 1502
@@ -1512,15 +1510,25 @@ static int fib6_walk(struct fib6_walker_t *w)
1512 return res; 1510 return res;
1513} 1511}
1514 1512
1515static int fib6_clean_node(struct fib6_walker_t *w) 1513static int fib6_clean_node(struct fib6_walker *w)
1516{ 1514{
1517 int res; 1515 int res;
1518 struct rt6_info *rt; 1516 struct rt6_info *rt;
1519 struct fib6_cleaner_t *c = container_of(w, struct fib6_cleaner_t, w); 1517 struct fib6_cleaner *c = container_of(w, struct fib6_cleaner, w);
1520 struct nl_info info = { 1518 struct nl_info info = {
1521 .nl_net = c->net, 1519 .nl_net = c->net,
1522 }; 1520 };
1523 1521
1522 if (c->sernum != FIB6_NO_SERNUM_CHANGE &&
1523 w->node->fn_sernum != c->sernum)
1524 w->node->fn_sernum = c->sernum;
1525
1526 if (!c->func) {
1527 WARN_ON_ONCE(c->sernum == FIB6_NO_SERNUM_CHANGE);
1528 w->leaf = NULL;
1529 return 0;
1530 }
1531
1524 for (rt = w->leaf; rt; rt = rt->dst.rt6_next) { 1532 for (rt = w->leaf; rt; rt = rt->dst.rt6_next) {
1525 res = c->func(rt, c->arg); 1533 res = c->func(rt, c->arg);
1526 if (res < 0) { 1534 if (res < 0) {
@@ -1554,9 +1562,9 @@ static int fib6_clean_node(struct fib6_walker_t *w)
1554 1562
1555static void fib6_clean_tree(struct net *net, struct fib6_node *root, 1563static void fib6_clean_tree(struct net *net, struct fib6_node *root,
1556 int (*func)(struct rt6_info *, void *arg), 1564 int (*func)(struct rt6_info *, void *arg),
1557 int prune, void *arg) 1565 bool prune, int sernum, void *arg)
1558{ 1566{
1559 struct fib6_cleaner_t c; 1567 struct fib6_cleaner c;
1560 1568
1561 c.w.root = root; 1569 c.w.root = root;
1562 c.w.func = fib6_clean_node; 1570 c.w.func = fib6_clean_node;
@@ -1564,14 +1572,16 @@ static void fib6_clean_tree(struct net *net, struct fib6_node *root,
1564 c.w.count = 0; 1572 c.w.count = 0;
1565 c.w.skip = 0; 1573 c.w.skip = 0;
1566 c.func = func; 1574 c.func = func;
1575 c.sernum = sernum;
1567 c.arg = arg; 1576 c.arg = arg;
1568 c.net = net; 1577 c.net = net;
1569 1578
1570 fib6_walk(&c.w); 1579 fib6_walk(&c.w);
1571} 1580}
1572 1581
1573void fib6_clean_all(struct net *net, int (*func)(struct rt6_info *, void *arg), 1582static void __fib6_clean_all(struct net *net,
1574 void *arg) 1583 int (*func)(struct rt6_info *, void *),
1584 int sernum, void *arg)
1575{ 1585{
1576 struct fib6_table *table; 1586 struct fib6_table *table;
1577 struct hlist_head *head; 1587 struct hlist_head *head;
@@ -1583,13 +1593,19 @@ void fib6_clean_all(struct net *net, int (*func)(struct rt6_info *, void *arg),
1583 hlist_for_each_entry_rcu(table, head, tb6_hlist) { 1593 hlist_for_each_entry_rcu(table, head, tb6_hlist) {
1584 write_lock_bh(&table->tb6_lock); 1594 write_lock_bh(&table->tb6_lock);
1585 fib6_clean_tree(net, &table->tb6_root, 1595 fib6_clean_tree(net, &table->tb6_root,
1586 func, 0, arg); 1596 func, false, sernum, arg);
1587 write_unlock_bh(&table->tb6_lock); 1597 write_unlock_bh(&table->tb6_lock);
1588 } 1598 }
1589 } 1599 }
1590 rcu_read_unlock(); 1600 rcu_read_unlock();
1591} 1601}
1592 1602
1603void fib6_clean_all(struct net *net, int (*func)(struct rt6_info *, void *),
1604 void *arg)
1605{
1606 __fib6_clean_all(net, func, FIB6_NO_SERNUM_CHANGE, arg);
1607}
1608
1593static int fib6_prune_clone(struct rt6_info *rt, void *arg) 1609static int fib6_prune_clone(struct rt6_info *rt, void *arg)
1594{ 1610{
1595 if (rt->rt6i_flags & RTF_CACHE) { 1611 if (rt->rt6i_flags & RTF_CACHE) {
@@ -1602,25 +1618,15 @@ static int fib6_prune_clone(struct rt6_info *rt, void *arg)
1602 1618
1603static void fib6_prune_clones(struct net *net, struct fib6_node *fn) 1619static void fib6_prune_clones(struct net *net, struct fib6_node *fn)
1604{ 1620{
1605 fib6_clean_tree(net, fn, fib6_prune_clone, 1, NULL); 1621 fib6_clean_tree(net, fn, fib6_prune_clone, true,
1606} 1622 FIB6_NO_SERNUM_CHANGE, NULL);
1607
1608static int fib6_update_sernum(struct rt6_info *rt, void *arg)
1609{
1610 __u32 sernum = *(__u32 *)arg;
1611
1612 if (rt->rt6i_node &&
1613 rt->rt6i_node->fn_sernum != sernum)
1614 rt->rt6i_node->fn_sernum = sernum;
1615
1616 return 0;
1617} 1623}
1618 1624
1619static void fib6_flush_trees(struct net *net) 1625static void fib6_flush_trees(struct net *net)
1620{ 1626{
1621 __u32 new_sernum = fib6_new_sernum(); 1627 int new_sernum = fib6_new_sernum(net);
1622 1628
1623 fib6_clean_all(net, fib6_update_sernum, &new_sernum); 1629 __fib6_clean_all(net, NULL, new_sernum, NULL);
1624} 1630}
1625 1631
1626/* 1632/*
@@ -1828,10 +1834,10 @@ void fib6_gc_cleanup(void)
1828 1834
1829struct ipv6_route_iter { 1835struct ipv6_route_iter {
1830 struct seq_net_private p; 1836 struct seq_net_private p;
1831 struct fib6_walker_t w; 1837 struct fib6_walker w;
1832 loff_t skip; 1838 loff_t skip;
1833 struct fib6_table *tbl; 1839 struct fib6_table *tbl;
1834 __u32 sernum; 1840 int sernum;
1835}; 1841};
1836 1842
1837static int ipv6_route_seq_show(struct seq_file *seq, void *v) 1843static int ipv6_route_seq_show(struct seq_file *seq, void *v)
@@ -1859,7 +1865,7 @@ static int ipv6_route_seq_show(struct seq_file *seq, void *v)
1859 return 0; 1865 return 0;
1860} 1866}
1861 1867
1862static int ipv6_route_yield(struct fib6_walker_t *w) 1868static int ipv6_route_yield(struct fib6_walker *w)
1863{ 1869{
1864 struct ipv6_route_iter *iter = w->args; 1870 struct ipv6_route_iter *iter = w->args;
1865 1871
@@ -1980,7 +1986,7 @@ static void *ipv6_route_seq_start(struct seq_file *seq, loff_t *pos)
1980 1986
1981static bool ipv6_route_iter_active(struct ipv6_route_iter *iter) 1987static bool ipv6_route_iter_active(struct ipv6_route_iter *iter)
1982{ 1988{
1983 struct fib6_walker_t *w = &iter->w; 1989 struct fib6_walker *w = &iter->w;
1984 return w->node && !(w->state == FWS_U && w->node == w->root); 1990 return w->node && !(w->state == FWS_U && w->node == w->root);
1985} 1991}
1986 1992
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index 4052694c6f2c..3dd7d4ebd7cd 100644
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -136,7 +136,7 @@ static void ip6_fl_gc(unsigned long dummy)
136 136
137 spin_lock(&ip6_fl_lock); 137 spin_lock(&ip6_fl_lock);
138 138
139 for (i=0; i<=FL_HASH_MASK; i++) { 139 for (i = 0; i <= FL_HASH_MASK; i++) {
140 struct ip6_flowlabel *fl; 140 struct ip6_flowlabel *fl;
141 struct ip6_flowlabel __rcu **flp; 141 struct ip6_flowlabel __rcu **flp;
142 142
@@ -239,7 +239,7 @@ static struct ip6_flowlabel *fl_intern(struct net *net,
239 239
240/* Socket flowlabel lists */ 240/* Socket flowlabel lists */
241 241
242struct ip6_flowlabel * fl6_sock_lookup(struct sock *sk, __be32 label) 242struct ip6_flowlabel *fl6_sock_lookup(struct sock *sk, __be32 label)
243{ 243{
244 struct ipv6_fl_socklist *sfl; 244 struct ipv6_fl_socklist *sfl;
245 struct ipv6_pinfo *np = inet6_sk(sk); 245 struct ipv6_pinfo *np = inet6_sk(sk);
@@ -259,7 +259,6 @@ struct ip6_flowlabel * fl6_sock_lookup(struct sock *sk, __be32 label)
259 rcu_read_unlock_bh(); 259 rcu_read_unlock_bh();
260 return NULL; 260 return NULL;
261} 261}
262
263EXPORT_SYMBOL_GPL(fl6_sock_lookup); 262EXPORT_SYMBOL_GPL(fl6_sock_lookup);
264 263
265void fl6_free_socklist(struct sock *sk) 264void fl6_free_socklist(struct sock *sk)
@@ -293,11 +292,11 @@ void fl6_free_socklist(struct sock *sk)
293 following rthdr. 292 following rthdr.
294 */ 293 */
295 294
296struct ipv6_txoptions *fl6_merge_options(struct ipv6_txoptions * opt_space, 295struct ipv6_txoptions *fl6_merge_options(struct ipv6_txoptions *opt_space,
297 struct ip6_flowlabel * fl, 296 struct ip6_flowlabel *fl,
298 struct ipv6_txoptions * fopt) 297 struct ipv6_txoptions *fopt)
299{ 298{
300 struct ipv6_txoptions * fl_opt = fl->opt; 299 struct ipv6_txoptions *fl_opt = fl->opt;
301 300
302 if (fopt == NULL || fopt->opt_flen == 0) 301 if (fopt == NULL || fopt->opt_flen == 0)
303 return fl_opt; 302 return fl_opt;
@@ -388,7 +387,7 @@ fl_create(struct net *net, struct sock *sk, struct in6_flowlabel_req *freq,
388 goto done; 387 goto done;
389 388
390 msg.msg_controllen = olen; 389 msg.msg_controllen = olen;
391 msg.msg_control = (void*)(fl->opt+1); 390 msg.msg_control = (void *)(fl->opt+1);
392 memset(&flowi6, 0, sizeof(flowi6)); 391 memset(&flowi6, 0, sizeof(flowi6));
393 392
394 err = ip6_datagram_send_ctl(net, sk, &msg, &flowi6, fl->opt, 393 err = ip6_datagram_send_ctl(net, sk, &msg, &flowi6, fl->opt,
@@ -517,7 +516,7 @@ int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen)
517 struct net *net = sock_net(sk); 516 struct net *net = sock_net(sk);
518 struct ipv6_pinfo *np = inet6_sk(sk); 517 struct ipv6_pinfo *np = inet6_sk(sk);
519 struct in6_flowlabel_req freq; 518 struct in6_flowlabel_req freq;
520 struct ipv6_fl_socklist *sfl1=NULL; 519 struct ipv6_fl_socklist *sfl1 = NULL;
521 struct ipv6_fl_socklist *sfl; 520 struct ipv6_fl_socklist *sfl;
522 struct ipv6_fl_socklist __rcu **sflp; 521 struct ipv6_fl_socklist __rcu **sflp;
523 struct ip6_flowlabel *fl, *fl1 = NULL; 522 struct ip6_flowlabel *fl, *fl1 = NULL;
@@ -542,7 +541,7 @@ int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen)
542 } 541 }
543 spin_lock_bh(&ip6_sk_fl_lock); 542 spin_lock_bh(&ip6_sk_fl_lock);
544 for (sflp = &np->ipv6_fl_list; 543 for (sflp = &np->ipv6_fl_list;
545 (sfl = rcu_dereference(*sflp))!=NULL; 544 (sfl = rcu_dereference(*sflp)) != NULL;
546 sflp = &sfl->next) { 545 sflp = &sfl->next) {
547 if (sfl->fl->label == freq.flr_label) { 546 if (sfl->fl->label == freq.flr_label) {
548 if (freq.flr_label == (np->flow_label&IPV6_FLOWLABEL_MASK)) 547 if (freq.flr_label == (np->flow_label&IPV6_FLOWLABEL_MASK))
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index 97299d76c1b0..12c3c8ef3849 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -618,6 +618,7 @@ static netdev_tx_t ip6gre_xmit2(struct sk_buff *skb,
618 int err = -1; 618 int err = -1;
619 u8 proto; 619 u8 proto;
620 struct sk_buff *new_skb; 620 struct sk_buff *new_skb;
621 __be16 protocol;
621 622
622 if (dev->type == ARPHRD_ETHER) 623 if (dev->type == ARPHRD_ETHER)
623 IPCB(skb)->flags = 0; 624 IPCB(skb)->flags = 0;
@@ -734,8 +735,9 @@ static netdev_tx_t ip6gre_xmit2(struct sk_buff *skb,
734 ipv6h->daddr = fl6->daddr; 735 ipv6h->daddr = fl6->daddr;
735 736
736 ((__be16 *)(ipv6h + 1))[0] = tunnel->parms.o_flags; 737 ((__be16 *)(ipv6h + 1))[0] = tunnel->parms.o_flags;
737 ((__be16 *)(ipv6h + 1))[1] = (dev->type == ARPHRD_ETHER) ? 738 protocol = (dev->type == ARPHRD_ETHER) ?
738 htons(ETH_P_TEB) : skb->protocol; 739 htons(ETH_P_TEB) : skb->protocol;
740 ((__be16 *)(ipv6h + 1))[1] = protocol;
739 741
740 if (tunnel->parms.o_flags&(GRE_KEY|GRE_CSUM|GRE_SEQ)) { 742 if (tunnel->parms.o_flags&(GRE_KEY|GRE_CSUM|GRE_SEQ)) {
741 __be32 *ptr = (__be32 *)(((u8 *)ipv6h) + tunnel->hlen - 4); 743 __be32 *ptr = (__be32 *)(((u8 *)ipv6h) + tunnel->hlen - 4);
@@ -756,6 +758,8 @@ static netdev_tx_t ip6gre_xmit2(struct sk_buff *skb,
756 } 758 }
757 } 759 }
758 760
761 skb_set_inner_protocol(skb, protocol);
762
759 ip6tunnel_xmit(skb, dev); 763 ip6tunnel_xmit(skb, dev);
760 if (ndst) 764 if (ndst)
761 ip6_tnl_dst_store(tunnel, ndst); 765 ip6_tnl_dst_store(tunnel, ndst);
@@ -1238,7 +1242,7 @@ static void ip6gre_tunnel_setup(struct net_device *dev)
1238 dev->flags |= IFF_NOARP; 1242 dev->flags |= IFF_NOARP;
1239 dev->iflink = 0; 1243 dev->iflink = 0;
1240 dev->addr_len = sizeof(struct in6_addr); 1244 dev->addr_len = sizeof(struct in6_addr);
1241 dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; 1245 netif_keep_dst(dev);
1242} 1246}
1243 1247
1244static int ip6gre_tunnel_init(struct net_device *dev) 1248static int ip6gre_tunnel_init(struct net_device *dev)
diff --git a/net/ipv6/ip6_icmp.c b/net/ipv6/ip6_icmp.c
index 4578e23834f7..14dacc544c3e 100644
--- a/net/ipv6/ip6_icmp.c
+++ b/net/ipv6/ip6_icmp.c
@@ -13,7 +13,7 @@ static ip6_icmp_send_t __rcu *ip6_icmp_send;
13int inet6_register_icmp_sender(ip6_icmp_send_t *fn) 13int inet6_register_icmp_sender(ip6_icmp_send_t *fn)
14{ 14{
15 return (cmpxchg((ip6_icmp_send_t **)&ip6_icmp_send, NULL, fn) == NULL) ? 15 return (cmpxchg((ip6_icmp_send_t **)&ip6_icmp_send, NULL, fn) == NULL) ?
16 0 : -EBUSY; 16 0 : -EBUSY;
17} 17}
18EXPORT_SYMBOL(inet6_register_icmp_sender); 18EXPORT_SYMBOL(inet6_register_icmp_sender);
19 19
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index 51d54dc376f3..a3084ab5df6c 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -15,8 +15,8 @@
15 */ 15 */
16/* Changes 16/* Changes
17 * 17 *
18 * Mitsuru KANDA @USAGI and 18 * Mitsuru KANDA @USAGI and
19 * YOSHIFUJI Hideaki @USAGI: Remove ipv6_parse_exthdrs(). 19 * YOSHIFUJI Hideaki @USAGI: Remove ipv6_parse_exthdrs().
20 */ 20 */
21 21
22#include <linux/errno.h> 22#include <linux/errno.h>
@@ -65,7 +65,7 @@ int ip6_rcv_finish(struct sk_buff *skb)
65int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev) 65int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev)
66{ 66{
67 const struct ipv6hdr *hdr; 67 const struct ipv6hdr *hdr;
68 u32 pkt_len; 68 u32 pkt_len;
69 struct inet6_dev *idev; 69 struct inet6_dev *idev;
70 struct net *net = dev_net(skb->dev); 70 struct net *net = dev_net(skb->dev);
71 71
diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c
index 65eda2a8af48..9034f76ae013 100644
--- a/net/ipv6/ip6_offload.c
+++ b/net/ipv6/ip6_offload.c
@@ -53,31 +53,6 @@ static int ipv6_gso_pull_exthdrs(struct sk_buff *skb, int proto)
53 return proto; 53 return proto;
54} 54}
55 55
56static int ipv6_gso_send_check(struct sk_buff *skb)
57{
58 const struct ipv6hdr *ipv6h;
59 const struct net_offload *ops;
60 int err = -EINVAL;
61
62 if (unlikely(!pskb_may_pull(skb, sizeof(*ipv6h))))
63 goto out;
64
65 ipv6h = ipv6_hdr(skb);
66 __skb_pull(skb, sizeof(*ipv6h));
67 err = -EPROTONOSUPPORT;
68
69 ops = rcu_dereference(inet6_offloads[
70 ipv6_gso_pull_exthdrs(skb, ipv6h->nexthdr)]);
71
72 if (likely(ops && ops->callbacks.gso_send_check)) {
73 skb_reset_transport_header(skb);
74 err = ops->callbacks.gso_send_check(skb);
75 }
76
77out:
78 return err;
79}
80
81static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, 56static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb,
82 netdev_features_t features) 57 netdev_features_t features)
83{ 58{
@@ -244,7 +219,7 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff **head,
244 continue; 219 continue;
245 220
246 iph2 = (struct ipv6hdr *)(p->data + off); 221 iph2 = (struct ipv6hdr *)(p->data + off);
247 first_word = *(__be32 *)iph ^ *(__be32 *)iph2 ; 222 first_word = *(__be32 *)iph ^ *(__be32 *)iph2;
248 223
249 /* All fields must match except length and Traffic Class. 224 /* All fields must match except length and Traffic Class.
250 * XXX skbs on the gro_list have all been parsed and pulled 225 * XXX skbs on the gro_list have all been parsed and pulled
@@ -261,6 +236,9 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff **head,
261 /* flush if Traffic Class fields are different */ 236 /* flush if Traffic Class fields are different */
262 NAPI_GRO_CB(p)->flush |= !!(first_word & htonl(0x0FF00000)); 237 NAPI_GRO_CB(p)->flush |= !!(first_word & htonl(0x0FF00000));
263 NAPI_GRO_CB(p)->flush |= flush; 238 NAPI_GRO_CB(p)->flush |= flush;
239
240 /* Clear flush_id, there's really no concept of ID in IPv6. */
241 NAPI_GRO_CB(p)->flush_id = 0;
264 } 242 }
265 243
266 NAPI_GRO_CB(skb)->flush |= flush; 244 NAPI_GRO_CB(skb)->flush |= flush;
@@ -303,7 +281,6 @@ out_unlock:
303static struct packet_offload ipv6_packet_offload __read_mostly = { 281static struct packet_offload ipv6_packet_offload __read_mostly = {
304 .type = cpu_to_be16(ETH_P_IPV6), 282 .type = cpu_to_be16(ETH_P_IPV6),
305 .callbacks = { 283 .callbacks = {
306 .gso_send_check = ipv6_gso_send_check,
307 .gso_segment = ipv6_gso_segment, 284 .gso_segment = ipv6_gso_segment,
308 .gro_receive = ipv6_gro_receive, 285 .gro_receive = ipv6_gro_receive,
309 .gro_complete = ipv6_gro_complete, 286 .gro_complete = ipv6_gro_complete,
@@ -312,8 +289,9 @@ static struct packet_offload ipv6_packet_offload __read_mostly = {
312 289
313static const struct net_offload sit_offload = { 290static const struct net_offload sit_offload = {
314 .callbacks = { 291 .callbacks = {
315 .gso_send_check = ipv6_gso_send_check,
316 .gso_segment = ipv6_gso_segment, 292 .gso_segment = ipv6_gso_segment,
293 .gro_receive = ipv6_gro_receive,
294 .gro_complete = ipv6_gro_complete,
317 }, 295 },
318}; 296};
319 297
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 0a3448b2888f..8e950c250ada 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -20,7 +20,7 @@
20 * etc. 20 * etc.
21 * 21 *
22 * H. von Brand : Added missing #include <linux/string.h> 22 * H. von Brand : Added missing #include <linux/string.h>
23 * Imran Patel : frag id should be in NBO 23 * Imran Patel : frag id should be in NBO
24 * Kazunori MIYAZAWA @USAGI 24 * Kazunori MIYAZAWA @USAGI
25 * : add ip6_append_data and related functions 25 * : add ip6_append_data and related functions
26 * for datagram xmit 26 * for datagram xmit
@@ -233,7 +233,6 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6,
233 kfree_skb(skb); 233 kfree_skb(skb);
234 return -EMSGSIZE; 234 return -EMSGSIZE;
235} 235}
236
237EXPORT_SYMBOL(ip6_xmit); 236EXPORT_SYMBOL(ip6_xmit);
238 237
239static int ip6_call_ra_chain(struct sk_buff *skb, int sel) 238static int ip6_call_ra_chain(struct sk_buff *skb, int sel)
@@ -555,14 +554,14 @@ static void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt)
555int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) 554int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
556{ 555{
557 struct sk_buff *frag; 556 struct sk_buff *frag;
558 struct rt6_info *rt = (struct rt6_info*)skb_dst(skb); 557 struct rt6_info *rt = (struct rt6_info *)skb_dst(skb);
559 struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL; 558 struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL;
560 struct ipv6hdr *tmp_hdr; 559 struct ipv6hdr *tmp_hdr;
561 struct frag_hdr *fh; 560 struct frag_hdr *fh;
562 unsigned int mtu, hlen, left, len; 561 unsigned int mtu, hlen, left, len;
563 int hroom, troom; 562 int hroom, troom;
564 __be32 frag_id = 0; 563 __be32 frag_id = 0;
565 int ptr, offset = 0, err=0; 564 int ptr, offset = 0, err = 0;
566 u8 *prevhdr, nexthdr = 0; 565 u8 *prevhdr, nexthdr = 0;
567 struct net *net = dev_net(skb_dst(skb)->dev); 566 struct net *net = dev_net(skb_dst(skb)->dev);
568 567
@@ -637,7 +636,7 @@ int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
637 } 636 }
638 637
639 __skb_pull(skb, hlen); 638 __skb_pull(skb, hlen);
640 fh = (struct frag_hdr*)__skb_push(skb, sizeof(struct frag_hdr)); 639 fh = (struct frag_hdr *)__skb_push(skb, sizeof(struct frag_hdr));
641 __skb_push(skb, hlen); 640 __skb_push(skb, hlen);
642 skb_reset_network_header(skb); 641 skb_reset_network_header(skb);
643 memcpy(skb_network_header(skb), tmp_hdr, hlen); 642 memcpy(skb_network_header(skb), tmp_hdr, hlen);
@@ -662,7 +661,7 @@ int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
662 if (frag) { 661 if (frag) {
663 frag->ip_summed = CHECKSUM_NONE; 662 frag->ip_summed = CHECKSUM_NONE;
664 skb_reset_transport_header(frag); 663 skb_reset_transport_header(frag);
665 fh = (struct frag_hdr*)__skb_push(frag, sizeof(struct frag_hdr)); 664 fh = (struct frag_hdr *)__skb_push(frag, sizeof(struct frag_hdr));
666 __skb_push(frag, hlen); 665 __skb_push(frag, hlen);
667 skb_reset_network_header(frag); 666 skb_reset_network_header(frag);
668 memcpy(skb_network_header(frag), tmp_hdr, 667 memcpy(skb_network_header(frag), tmp_hdr,
@@ -681,7 +680,7 @@ int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
681 } 680 }
682 681
683 err = output(skb); 682 err = output(skb);
684 if(!err) 683 if (!err)
685 IP6_INC_STATS(net, ip6_dst_idev(&rt->dst), 684 IP6_INC_STATS(net, ip6_dst_idev(&rt->dst),
686 IPSTATS_MIB_FRAGCREATES); 685 IPSTATS_MIB_FRAGCREATES);
687 686
@@ -702,11 +701,7 @@ int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
702 return 0; 701 return 0;
703 } 702 }
704 703
705 while (frag) { 704 kfree_skb_list(frag);
706 skb = frag->next;
707 kfree_skb(frag);
708 frag = skb;
709 }
710 705
711 IP6_INC_STATS(net, ip6_dst_idev(&rt->dst), 706 IP6_INC_STATS(net, ip6_dst_idev(&rt->dst),
712 IPSTATS_MIB_FRAGFAILS); 707 IPSTATS_MIB_FRAGFAILS);
@@ -742,7 +737,7 @@ slow_path:
742 /* 737 /*
743 * Keep copying data until we run out. 738 * Keep copying data until we run out.
744 */ 739 */
745 while(left > 0) { 740 while (left > 0) {
746 len = left; 741 len = left;
747 /* IF: it doesn't fit, use 'mtu' - the data space left */ 742 /* IF: it doesn't fit, use 'mtu' - the data space left */
748 if (len > mtu) 743 if (len > mtu)
@@ -865,7 +860,7 @@ static struct dst_entry *ip6_sk_dst_check(struct sock *sk,
865 /* Yes, checking route validity in not connected 860 /* Yes, checking route validity in not connected
866 * case is not very simple. Take into account, 861 * case is not very simple. Take into account,
867 * that we do not support routing by source, TOS, 862 * that we do not support routing by source, TOS,
868 * and MSG_DONTROUTE --ANK (980726) 863 * and MSG_DONTROUTE --ANK (980726)
869 * 864 *
870 * 1. ip6_rt_check(): If route was host route, 865 * 1. ip6_rt_check(): If route was host route,
871 * check that cached destination is current. 866 * check that cached destination is current.
@@ -1049,7 +1044,7 @@ static inline int ip6_ufo_append_data(struct sock *sk,
1049 int getfrag(void *from, char *to, int offset, int len, 1044 int getfrag(void *from, char *to, int offset, int len,
1050 int odd, struct sk_buff *skb), 1045 int odd, struct sk_buff *skb),
1051 void *from, int length, int hh_len, int fragheaderlen, 1046 void *from, int length, int hh_len, int fragheaderlen,
1052 int transhdrlen, int mtu,unsigned int flags, 1047 int transhdrlen, int mtu, unsigned int flags,
1053 struct rt6_info *rt) 1048 struct rt6_info *rt)
1054 1049
1055{ 1050{
@@ -1072,7 +1067,7 @@ static inline int ip6_ufo_append_data(struct sock *sk,
1072 skb_reserve(skb, hh_len); 1067 skb_reserve(skb, hh_len);
1073 1068
1074 /* create space for UDP/IP header */ 1069 /* create space for UDP/IP header */
1075 skb_put(skb,fragheaderlen + transhdrlen); 1070 skb_put(skb, fragheaderlen + transhdrlen);
1076 1071
1077 /* initialize network header pointer */ 1072 /* initialize network header pointer */
1078 skb_reset_network_header(skb); 1073 skb_reset_network_header(skb);
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 69a84b464009..9409887fb664 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -412,12 +412,12 @@ __u16 ip6_tnl_parse_tlv_enc_lim(struct sk_buff *skb, __u8 *raw)
412{ 412{
413 const struct ipv6hdr *ipv6h = (const struct ipv6hdr *) raw; 413 const struct ipv6hdr *ipv6h = (const struct ipv6hdr *) raw;
414 __u8 nexthdr = ipv6h->nexthdr; 414 __u8 nexthdr = ipv6h->nexthdr;
415 __u16 off = sizeof (*ipv6h); 415 __u16 off = sizeof(*ipv6h);
416 416
417 while (ipv6_ext_hdr(nexthdr) && nexthdr != NEXTHDR_NONE) { 417 while (ipv6_ext_hdr(nexthdr) && nexthdr != NEXTHDR_NONE) {
418 __u16 optlen = 0; 418 __u16 optlen = 0;
419 struct ipv6_opt_hdr *hdr; 419 struct ipv6_opt_hdr *hdr;
420 if (raw + off + sizeof (*hdr) > skb->data && 420 if (raw + off + sizeof(*hdr) > skb->data &&
421 !pskb_may_pull(skb, raw - skb->data + off + sizeof (*hdr))) 421 !pskb_may_pull(skb, raw - skb->data + off + sizeof (*hdr)))
422 break; 422 break;
423 423
@@ -534,7 +534,7 @@ ip6_tnl_err(struct sk_buff *skb, __u8 ipproto, struct inet6_skb_parm *opt,
534 mtu = IPV6_MIN_MTU; 534 mtu = IPV6_MIN_MTU;
535 t->dev->mtu = mtu; 535 t->dev->mtu = mtu;
536 536
537 if ((len = sizeof (*ipv6h) + ntohs(ipv6h->payload_len)) > mtu) { 537 if ((len = sizeof(*ipv6h) + ntohs(ipv6h->payload_len)) > mtu) {
538 rel_type = ICMPV6_PKT_TOOBIG; 538 rel_type = ICMPV6_PKT_TOOBIG;
539 rel_code = 0; 539 rel_code = 0;
540 rel_info = mtu; 540 rel_info = mtu;
@@ -995,7 +995,7 @@ static int ip6_tnl_xmit2(struct sk_buff *skb,
995 t->parms.name); 995 t->parms.name);
996 goto tx_err_dst_release; 996 goto tx_err_dst_release;
997 } 997 }
998 mtu = dst_mtu(dst) - sizeof (*ipv6h); 998 mtu = dst_mtu(dst) - sizeof(*ipv6h);
999 if (encap_limit >= 0) { 999 if (encap_limit >= 0) {
1000 max_headroom += 8; 1000 max_headroom += 8;
1001 mtu -= 8; 1001 mtu -= 8;
@@ -1087,7 +1087,7 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
1087 if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT)) 1087 if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
1088 encap_limit = t->parms.encap_limit; 1088 encap_limit = t->parms.encap_limit;
1089 1089
1090 memcpy(&fl6, &t->fl.u.ip6, sizeof (fl6)); 1090 memcpy(&fl6, &t->fl.u.ip6, sizeof(fl6));
1091 fl6.flowi6_proto = IPPROTO_IPIP; 1091 fl6.flowi6_proto = IPPROTO_IPIP;
1092 1092
1093 dsfield = ipv4_get_dsfield(iph); 1093 dsfield = ipv4_get_dsfield(iph);
@@ -1139,7 +1139,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
1139 } else if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT)) 1139 } else if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
1140 encap_limit = t->parms.encap_limit; 1140 encap_limit = t->parms.encap_limit;
1141 1141
1142 memcpy(&fl6, &t->fl.u.ip6, sizeof (fl6)); 1142 memcpy(&fl6, &t->fl.u.ip6, sizeof(fl6));
1143 fl6.flowi6_proto = IPPROTO_IPV6; 1143 fl6.flowi6_proto = IPPROTO_IPV6;
1144 1144
1145 dsfield = ipv6_get_dsfield(ipv6h); 1145 dsfield = ipv6_get_dsfield(ipv6h);
@@ -1233,11 +1233,11 @@ static void ip6_tnl_link_config(struct ip6_tnl *t)
1233 1233
1234 if (rt->dst.dev) { 1234 if (rt->dst.dev) {
1235 dev->hard_header_len = rt->dst.dev->hard_header_len + 1235 dev->hard_header_len = rt->dst.dev->hard_header_len +
1236 sizeof (struct ipv6hdr); 1236 sizeof(struct ipv6hdr);
1237 1237
1238 dev->mtu = rt->dst.dev->mtu - sizeof (struct ipv6hdr); 1238 dev->mtu = rt->dst.dev->mtu - sizeof(struct ipv6hdr);
1239 if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT)) 1239 if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
1240 dev->mtu-=8; 1240 dev->mtu -= 8;
1241 1241
1242 if (dev->mtu < IPV6_MIN_MTU) 1242 if (dev->mtu < IPV6_MIN_MTU)
1243 dev->mtu = IPV6_MIN_MTU; 1243 dev->mtu = IPV6_MIN_MTU;
@@ -1354,7 +1354,7 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1354 switch (cmd) { 1354 switch (cmd) {
1355 case SIOCGETTUNNEL: 1355 case SIOCGETTUNNEL:
1356 if (dev == ip6n->fb_tnl_dev) { 1356 if (dev == ip6n->fb_tnl_dev) {
1357 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof (p))) { 1357 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) {
1358 err = -EFAULT; 1358 err = -EFAULT;
1359 break; 1359 break;
1360 } 1360 }
@@ -1366,7 +1366,7 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1366 memset(&p, 0, sizeof(p)); 1366 memset(&p, 0, sizeof(p));
1367 } 1367 }
1368 ip6_tnl_parm_to_user(&p, &t->parms); 1368 ip6_tnl_parm_to_user(&p, &t->parms);
1369 if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof (p))) { 1369 if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p))) {
1370 err = -EFAULT; 1370 err = -EFAULT;
1371 } 1371 }
1372 break; 1372 break;
@@ -1376,7 +1376,7 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1376 if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) 1376 if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
1377 break; 1377 break;
1378 err = -EFAULT; 1378 err = -EFAULT;
1379 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof (p))) 1379 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p)))
1380 break; 1380 break;
1381 err = -EINVAL; 1381 err = -EINVAL;
1382 if (p.proto != IPPROTO_IPV6 && p.proto != IPPROTO_IPIP && 1382 if (p.proto != IPPROTO_IPV6 && p.proto != IPPROTO_IPIP &&
@@ -1411,7 +1411,7 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1411 1411
1412 if (dev == ip6n->fb_tnl_dev) { 1412 if (dev == ip6n->fb_tnl_dev) {
1413 err = -EFAULT; 1413 err = -EFAULT;
1414 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof (p))) 1414 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p)))
1415 break; 1415 break;
1416 err = -ENOENT; 1416 err = -ENOENT;
1417 ip6_tnl_parm_from_user(&p1, &p); 1417 ip6_tnl_parm_from_user(&p1, &p);
@@ -1486,14 +1486,14 @@ static void ip6_tnl_dev_setup(struct net_device *dev)
1486 dev->destructor = ip6_dev_free; 1486 dev->destructor = ip6_dev_free;
1487 1487
1488 dev->type = ARPHRD_TUNNEL6; 1488 dev->type = ARPHRD_TUNNEL6;
1489 dev->hard_header_len = LL_MAX_HEADER + sizeof (struct ipv6hdr); 1489 dev->hard_header_len = LL_MAX_HEADER + sizeof(struct ipv6hdr);
1490 dev->mtu = ETH_DATA_LEN - sizeof (struct ipv6hdr); 1490 dev->mtu = ETH_DATA_LEN - sizeof(struct ipv6hdr);
1491 t = netdev_priv(dev); 1491 t = netdev_priv(dev);
1492 if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT)) 1492 if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
1493 dev->mtu-=8; 1493 dev->mtu -= 8;
1494 dev->flags |= IFF_NOARP; 1494 dev->flags |= IFF_NOARP;
1495 dev->addr_len = sizeof(struct in6_addr); 1495 dev->addr_len = sizeof(struct in6_addr);
1496 dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; 1496 netif_keep_dst(dev);
1497 /* This perm addr will be used as interface identifier by IPv6 */ 1497 /* This perm addr will be used as interface identifier by IPv6 */
1498 dev->addr_assign_type = NET_ADDR_RANDOM; 1498 dev->addr_assign_type = NET_ADDR_RANDOM;
1499 eth_random_addr(dev->perm_addr); 1499 eth_random_addr(dev->perm_addr);
diff --git a/net/ipv6/ip6_udp_tunnel.c b/net/ipv6/ip6_udp_tunnel.c
new file mode 100644
index 000000000000..b04ed72c4542
--- /dev/null
+++ b/net/ipv6/ip6_udp_tunnel.c
@@ -0,0 +1,107 @@
1#include <linux/module.h>
2#include <linux/errno.h>
3#include <linux/socket.h>
4#include <linux/udp.h>
5#include <linux/types.h>
6#include <linux/kernel.h>
7#include <linux/in6.h>
8#include <net/udp.h>
9#include <net/udp_tunnel.h>
10#include <net/net_namespace.h>
11#include <net/netns/generic.h>
12#include <net/ip6_tunnel.h>
13#include <net/ip6_checksum.h>
14
15int udp_sock_create6(struct net *net, struct udp_port_cfg *cfg,
16 struct socket **sockp)
17{
18 struct sockaddr_in6 udp6_addr;
19 int err;
20 struct socket *sock = NULL;
21
22 err = sock_create_kern(AF_INET6, SOCK_DGRAM, 0, &sock);
23 if (err < 0)
24 goto error;
25
26 sk_change_net(sock->sk, net);
27
28 udp6_addr.sin6_family = AF_INET6;
29 memcpy(&udp6_addr.sin6_addr, &cfg->local_ip6,
30 sizeof(udp6_addr.sin6_addr));
31 udp6_addr.sin6_port = cfg->local_udp_port;
32 err = kernel_bind(sock, (struct sockaddr *)&udp6_addr,
33 sizeof(udp6_addr));
34 if (err < 0)
35 goto error;
36
37 if (cfg->peer_udp_port) {
38 udp6_addr.sin6_family = AF_INET6;
39 memcpy(&udp6_addr.sin6_addr, &cfg->peer_ip6,
40 sizeof(udp6_addr.sin6_addr));
41 udp6_addr.sin6_port = cfg->peer_udp_port;
42 err = kernel_connect(sock,
43 (struct sockaddr *)&udp6_addr,
44 sizeof(udp6_addr), 0);
45 }
46 if (err < 0)
47 goto error;
48
49 udp_set_no_check6_tx(sock->sk, !cfg->use_udp6_tx_checksums);
50 udp_set_no_check6_rx(sock->sk, !cfg->use_udp6_rx_checksums);
51
52 *sockp = sock;
53 return 0;
54
55error:
56 if (sock) {
57 kernel_sock_shutdown(sock, SHUT_RDWR);
58 sk_release_kernel(sock->sk);
59 }
60 *sockp = NULL;
61 return err;
62}
63EXPORT_SYMBOL_GPL(udp_sock_create6);
64
65int udp_tunnel6_xmit_skb(struct socket *sock, struct dst_entry *dst,
66 struct sk_buff *skb, struct net_device *dev,
67 struct in6_addr *saddr, struct in6_addr *daddr,
68 __u8 prio, __u8 ttl, __be16 src_port, __be16 dst_port)
69{
70 struct udphdr *uh;
71 struct ipv6hdr *ip6h;
72 struct sock *sk = sock->sk;
73
74 __skb_push(skb, sizeof(*uh));
75 skb_reset_transport_header(skb);
76 uh = udp_hdr(skb);
77
78 uh->dest = dst_port;
79 uh->source = src_port;
80
81 uh->len = htons(skb->len);
82 uh->check = 0;
83
84 memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
85 IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED
86 | IPSKB_REROUTED);
87 skb_dst_set(skb, dst);
88
89 udp6_set_csum(udp_get_no_check6_tx(sk), skb, &inet6_sk(sk)->saddr,
90 &sk->sk_v6_daddr, skb->len);
91
92 __skb_push(skb, sizeof(*ip6h));
93 skb_reset_network_header(skb);
94 ip6h = ipv6_hdr(skb);
95 ip6_flow_hdr(ip6h, prio, htonl(0));
96 ip6h->payload_len = htons(skb->len);
97 ip6h->nexthdr = IPPROTO_UDP;
98 ip6h->hop_limit = ttl;
99 ip6h->daddr = *daddr;
100 ip6h->saddr = *saddr;
101
102 ip6tunnel_xmit(skb, dev);
103 return 0;
104}
105EXPORT_SYMBOL_GPL(udp_tunnel6_xmit_skb);
106
107MODULE_LICENSE("GPL");
diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c
index 5833a2244467..d440bb585524 100644
--- a/net/ipv6/ip6_vti.c
+++ b/net/ipv6/ip6_vti.c
@@ -807,7 +807,7 @@ static void vti6_dev_setup(struct net_device *dev)
807 dev->mtu = ETH_DATA_LEN; 807 dev->mtu = ETH_DATA_LEN;
808 dev->flags |= IFF_NOARP; 808 dev->flags |= IFF_NOARP;
809 dev->addr_len = sizeof(struct in6_addr); 809 dev->addr_len = sizeof(struct in6_addr);
810 dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; 810 netif_keep_dst(dev);
811} 811}
812 812
813/** 813/**
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index f9a3fd320d1d..0171f08325c3 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -845,7 +845,7 @@ static void ip6mr_destroy_unres(struct mr6_table *mrt, struct mfc6_cache *c)
845 845
846 atomic_dec(&mrt->cache_resolve_queue_len); 846 atomic_dec(&mrt->cache_resolve_queue_len);
847 847
848 while((skb = skb_dequeue(&c->mfc_un.unres.unresolved)) != NULL) { 848 while ((skb = skb_dequeue(&c->mfc_un.unres.unresolved)) != NULL) {
849 if (ipv6_hdr(skb)->version == 0) { 849 if (ipv6_hdr(skb)->version == 0) {
850 struct nlmsghdr *nlh = (struct nlmsghdr *)skb_pull(skb, sizeof(struct ipv6hdr)); 850 struct nlmsghdr *nlh = (struct nlmsghdr *)skb_pull(skb, sizeof(struct ipv6hdr));
851 nlh->nlmsg_type = NLMSG_ERROR; 851 nlh->nlmsg_type = NLMSG_ERROR;
@@ -1103,7 +1103,7 @@ static void ip6mr_cache_resolve(struct net *net, struct mr6_table *mrt,
1103 * Play the pending entries through our router 1103 * Play the pending entries through our router
1104 */ 1104 */
1105 1105
1106 while((skb = __skb_dequeue(&uc->mfc_un.unres.unresolved))) { 1106 while ((skb = __skb_dequeue(&uc->mfc_un.unres.unresolved))) {
1107 if (ipv6_hdr(skb)->version == 0) { 1107 if (ipv6_hdr(skb)->version == 0) {
1108 struct nlmsghdr *nlh = (struct nlmsghdr *)skb_pull(skb, sizeof(struct ipv6hdr)); 1108 struct nlmsghdr *nlh = (struct nlmsghdr *)skb_pull(skb, sizeof(struct ipv6hdr));
1109 1109
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index d1c793cffcb5..1b9316e1386a 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -181,8 +181,7 @@ static int ipcomp6_rcv_cb(struct sk_buff *skb, int err)
181 return 0; 181 return 0;
182} 182}
183 183
184static const struct xfrm_type ipcomp6_type = 184static const struct xfrm_type ipcomp6_type = {
185{
186 .description = "IPCOMP6", 185 .description = "IPCOMP6",
187 .owner = THIS_MODULE, 186 .owner = THIS_MODULE,
188 .proto = IPPROTO_COMP, 187 .proto = IPPROTO_COMP,
@@ -193,8 +192,7 @@ static const struct xfrm_type ipcomp6_type =
193 .hdr_offset = xfrm6_find_1stfragopt, 192 .hdr_offset = xfrm6_find_1stfragopt,
194}; 193};
195 194
196static struct xfrm6_protocol ipcomp6_protocol = 195static struct xfrm6_protocol ipcomp6_protocol = {
197{
198 .handler = xfrm6_rcv, 196 .handler = xfrm6_rcv,
199 .cb_handler = ipcomp6_rcv_cb, 197 .cb_handler = ipcomp6_rcv_cb,
200 .err_handler = ipcomp6_err, 198 .err_handler = ipcomp6_err,
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 0c289982796d..e1a9583bb419 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -66,12 +66,12 @@ int ip6_ra_control(struct sock *sk, int sel)
66 if (sk->sk_type != SOCK_RAW || inet_sk(sk)->inet_num != IPPROTO_RAW) 66 if (sk->sk_type != SOCK_RAW || inet_sk(sk)->inet_num != IPPROTO_RAW)
67 return -ENOPROTOOPT; 67 return -ENOPROTOOPT;
68 68
69 new_ra = (sel>=0) ? kmalloc(sizeof(*new_ra), GFP_KERNEL) : NULL; 69 new_ra = (sel >= 0) ? kmalloc(sizeof(*new_ra), GFP_KERNEL) : NULL;
70 70
71 write_lock_bh(&ip6_ra_lock); 71 write_lock_bh(&ip6_ra_lock);
72 for (rap = &ip6_ra_chain; (ra=*rap) != NULL; rap = &ra->next) { 72 for (rap = &ip6_ra_chain; (ra = *rap) != NULL; rap = &ra->next) {
73 if (ra->sk == sk) { 73 if (ra->sk == sk) {
74 if (sel>=0) { 74 if (sel >= 0) {
75 write_unlock_bh(&ip6_ra_lock); 75 write_unlock_bh(&ip6_ra_lock);
76 kfree(new_ra); 76 kfree(new_ra);
77 return -EADDRINUSE; 77 return -EADDRINUSE;
@@ -130,7 +130,7 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
130 int retv = -ENOPROTOOPT; 130 int retv = -ENOPROTOOPT;
131 131
132 if (optval == NULL) 132 if (optval == NULL)
133 val=0; 133 val = 0;
134 else { 134 else {
135 if (optlen >= sizeof(int)) { 135 if (optlen >= sizeof(int)) {
136 if (get_user(val, (int __user *) optval)) 136 if (get_user(val, (int __user *) optval))
@@ -139,7 +139,7 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
139 val = 0; 139 val = 0;
140 } 140 }
141 141
142 valbool = (val!=0); 142 valbool = (val != 0);
143 143
144 if (ip6_mroute_opt(optname)) 144 if (ip6_mroute_opt(optname))
145 return ip6_mroute_setsockopt(sk, optname, optval, optlen); 145 return ip6_mroute_setsockopt(sk, optname, optval, optlen);
@@ -474,7 +474,7 @@ sticky_done:
474 goto done; 474 goto done;
475 475
476 msg.msg_controllen = optlen; 476 msg.msg_controllen = optlen;
477 msg.msg_control = (void*)(opt+1); 477 msg.msg_control = (void *)(opt+1);
478 478
479 retv = ip6_datagram_send_ctl(net, sk, &msg, &fl6, opt, &junk, 479 retv = ip6_datagram_send_ctl(net, sk, &msg, &fl6, opt, &junk,
480 &junk, &junk); 480 &junk, &junk);
@@ -687,7 +687,7 @@ done:
687 retv = -ENOBUFS; 687 retv = -ENOBUFS;
688 break; 688 break;
689 } 689 }
690 gsf = kmalloc(optlen,GFP_KERNEL); 690 gsf = kmalloc(optlen, GFP_KERNEL);
691 if (!gsf) { 691 if (!gsf) {
692 retv = -ENOBUFS; 692 retv = -ENOBUFS;
693 break; 693 break;
@@ -873,7 +873,6 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname,
873#endif 873#endif
874 return err; 874 return err;
875} 875}
876
877EXPORT_SYMBOL(ipv6_setsockopt); 876EXPORT_SYMBOL(ipv6_setsockopt);
878 877
879#ifdef CONFIG_COMPAT 878#ifdef CONFIG_COMPAT
@@ -909,7 +908,6 @@ int compat_ipv6_setsockopt(struct sock *sk, int level, int optname,
909#endif 908#endif
910 return err; 909 return err;
911} 910}
912
913EXPORT_SYMBOL(compat_ipv6_setsockopt); 911EXPORT_SYMBOL(compat_ipv6_setsockopt);
914#endif 912#endif
915 913
@@ -921,7 +919,7 @@ static int ipv6_getsockopt_sticky(struct sock *sk, struct ipv6_txoptions *opt,
921 if (!opt) 919 if (!opt)
922 return 0; 920 return 0;
923 921
924 switch(optname) { 922 switch (optname) {
925 case IPV6_HOPOPTS: 923 case IPV6_HOPOPTS:
926 hdr = opt->hopopt; 924 hdr = opt->hopopt;
927 break; 925 break;
@@ -1284,9 +1282,9 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
1284 return -ENOPROTOOPT; 1282 return -ENOPROTOOPT;
1285 } 1283 }
1286 len = min_t(unsigned int, sizeof(int), len); 1284 len = min_t(unsigned int, sizeof(int), len);
1287 if(put_user(len, optlen)) 1285 if (put_user(len, optlen))
1288 return -EFAULT; 1286 return -EFAULT;
1289 if(copy_to_user(optval,&val,len)) 1287 if (copy_to_user(optval, &val, len))
1290 return -EFAULT; 1288 return -EFAULT;
1291 return 0; 1289 return 0;
1292} 1290}
@@ -1299,7 +1297,7 @@ int ipv6_getsockopt(struct sock *sk, int level, int optname,
1299 if (level == SOL_IP && sk->sk_type != SOCK_RAW) 1297 if (level == SOL_IP && sk->sk_type != SOCK_RAW)
1300 return udp_prot.getsockopt(sk, level, optname, optval, optlen); 1298 return udp_prot.getsockopt(sk, level, optname, optval, optlen);
1301 1299
1302 if(level != SOL_IPV6) 1300 if (level != SOL_IPV6)
1303 return -ENOPROTOOPT; 1301 return -ENOPROTOOPT;
1304 1302
1305 err = do_ipv6_getsockopt(sk, level, optname, optval, optlen, 0); 1303 err = do_ipv6_getsockopt(sk, level, optname, optval, optlen, 0);
@@ -1321,7 +1319,6 @@ int ipv6_getsockopt(struct sock *sk, int level, int optname,
1321#endif 1319#endif
1322 return err; 1320 return err;
1323} 1321}
1324
1325EXPORT_SYMBOL(ipv6_getsockopt); 1322EXPORT_SYMBOL(ipv6_getsockopt);
1326 1323
1327#ifdef CONFIG_COMPAT 1324#ifdef CONFIG_COMPAT
@@ -1364,7 +1361,6 @@ int compat_ipv6_getsockopt(struct sock *sk, int level, int optname,
1364#endif 1361#endif
1365 return err; 1362 return err;
1366} 1363}
1367
1368EXPORT_SYMBOL(compat_ipv6_getsockopt); 1364EXPORT_SYMBOL(compat_ipv6_getsockopt);
1369#endif 1365#endif
1370 1366
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index a23b655a7627..9648de2b6745 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -64,15 +64,6 @@
64 64
65#include <net/ip6_checksum.h> 65#include <net/ip6_checksum.h>
66 66
67/* Set to 3 to get tracing... */
68#define MCAST_DEBUG 2
69
70#if MCAST_DEBUG >= 3
71#define MDBG(x) printk x
72#else
73#define MDBG(x)
74#endif
75
76/* Ensure that we have struct in6_addr aligned on 32bit word. */ 67/* Ensure that we have struct in6_addr aligned on 32bit word. */
77static void *__mld2_query_bugs[] __attribute__((__unused__)) = { 68static void *__mld2_query_bugs[] __attribute__((__unused__)) = {
78 BUILD_BUG_ON_NULL(offsetof(struct mld2_query, mld2q_srcs) % 4), 69 BUILD_BUG_ON_NULL(offsetof(struct mld2_query, mld2q_srcs) % 4),
@@ -82,9 +73,6 @@ static void *__mld2_query_bugs[] __attribute__((__unused__)) = {
82 73
83static struct in6_addr mld2_all_mcr = MLD2_ALL_MCR_INIT; 74static struct in6_addr mld2_all_mcr = MLD2_ALL_MCR_INIT;
84 75
85/* Big mc list lock for all the sockets */
86static DEFINE_SPINLOCK(ipv6_sk_mc_lock);
87
88static void igmp6_join_group(struct ifmcaddr6 *ma); 76static void igmp6_join_group(struct ifmcaddr6 *ma);
89static void igmp6_leave_group(struct ifmcaddr6 *ma); 77static void igmp6_leave_group(struct ifmcaddr6 *ma);
90static void igmp6_timer_handler(unsigned long data); 78static void igmp6_timer_handler(unsigned long data);
@@ -121,6 +109,7 @@ static int ip6_mc_leave_src(struct sock *sk, struct ipv6_mc_socklist *iml,
121#define IPV6_MLD_MAX_MSF 64 109#define IPV6_MLD_MAX_MSF 64
122 110
123int sysctl_mld_max_msf __read_mostly = IPV6_MLD_MAX_MSF; 111int sysctl_mld_max_msf __read_mostly = IPV6_MLD_MAX_MSF;
112int sysctl_mld_qrv __read_mostly = MLD_QRV_DEFAULT;
124 113
125/* 114/*
126 * socket join on multicast group 115 * socket join on multicast group
@@ -173,7 +162,6 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
173 mc_lst->addr = *addr; 162 mc_lst->addr = *addr;
174 163
175 rtnl_lock(); 164 rtnl_lock();
176 rcu_read_lock();
177 if (ifindex == 0) { 165 if (ifindex == 0) {
178 struct rt6_info *rt; 166 struct rt6_info *rt;
179 rt = rt6_lookup(net, addr, NULL, 0, 0); 167 rt = rt6_lookup(net, addr, NULL, 0, 0);
@@ -182,10 +170,9 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
182 ip6_rt_put(rt); 170 ip6_rt_put(rt);
183 } 171 }
184 } else 172 } else
185 dev = dev_get_by_index_rcu(net, ifindex); 173 dev = __dev_get_by_index(net, ifindex);
186 174
187 if (dev == NULL) { 175 if (dev == NULL) {
188 rcu_read_unlock();
189 rtnl_unlock(); 176 rtnl_unlock();
190 sock_kfree_s(sk, mc_lst, sizeof(*mc_lst)); 177 sock_kfree_s(sk, mc_lst, sizeof(*mc_lst));
191 return -ENODEV; 178 return -ENODEV;
@@ -203,18 +190,14 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
203 err = ipv6_dev_mc_inc(dev, addr); 190 err = ipv6_dev_mc_inc(dev, addr);
204 191
205 if (err) { 192 if (err) {
206 rcu_read_unlock();
207 rtnl_unlock(); 193 rtnl_unlock();
208 sock_kfree_s(sk, mc_lst, sizeof(*mc_lst)); 194 sock_kfree_s(sk, mc_lst, sizeof(*mc_lst));
209 return err; 195 return err;
210 } 196 }
211 197
212 spin_lock(&ipv6_sk_mc_lock);
213 mc_lst->next = np->ipv6_mc_list; 198 mc_lst->next = np->ipv6_mc_list;
214 rcu_assign_pointer(np->ipv6_mc_list, mc_lst); 199 rcu_assign_pointer(np->ipv6_mc_list, mc_lst);
215 spin_unlock(&ipv6_sk_mc_lock);
216 200
217 rcu_read_unlock();
218 rtnl_unlock(); 201 rtnl_unlock();
219 202
220 return 0; 203 return 0;
@@ -234,20 +217,16 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex, const struct in6_addr *addr)
234 return -EINVAL; 217 return -EINVAL;
235 218
236 rtnl_lock(); 219 rtnl_lock();
237 spin_lock(&ipv6_sk_mc_lock);
238 for (lnk = &np->ipv6_mc_list; 220 for (lnk = &np->ipv6_mc_list;
239 (mc_lst = rcu_dereference_protected(*lnk, 221 (mc_lst = rtnl_dereference(*lnk)) != NULL;
240 lockdep_is_held(&ipv6_sk_mc_lock))) !=NULL ;
241 lnk = &mc_lst->next) { 222 lnk = &mc_lst->next) {
242 if ((ifindex == 0 || mc_lst->ifindex == ifindex) && 223 if ((ifindex == 0 || mc_lst->ifindex == ifindex) &&
243 ipv6_addr_equal(&mc_lst->addr, addr)) { 224 ipv6_addr_equal(&mc_lst->addr, addr)) {
244 struct net_device *dev; 225 struct net_device *dev;
245 226
246 *lnk = mc_lst->next; 227 *lnk = mc_lst->next;
247 spin_unlock(&ipv6_sk_mc_lock);
248 228
249 rcu_read_lock(); 229 dev = __dev_get_by_index(net, mc_lst->ifindex);
250 dev = dev_get_by_index_rcu(net, mc_lst->ifindex);
251 if (dev != NULL) { 230 if (dev != NULL) {
252 struct inet6_dev *idev = __in6_dev_get(dev); 231 struct inet6_dev *idev = __in6_dev_get(dev);
253 232
@@ -256,7 +235,6 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex, const struct in6_addr *addr)
256 __ipv6_dev_mc_dec(idev, &mc_lst->addr); 235 __ipv6_dev_mc_dec(idev, &mc_lst->addr);
257 } else 236 } else
258 (void) ip6_mc_leave_src(sk, mc_lst, NULL); 237 (void) ip6_mc_leave_src(sk, mc_lst, NULL);
259 rcu_read_unlock();
260 rtnl_unlock(); 238 rtnl_unlock();
261 239
262 atomic_sub(sizeof(*mc_lst), &sk->sk_omem_alloc); 240 atomic_sub(sizeof(*mc_lst), &sk->sk_omem_alloc);
@@ -264,7 +242,6 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex, const struct in6_addr *addr)
264 return 0; 242 return 0;
265 } 243 }
266 } 244 }
267 spin_unlock(&ipv6_sk_mc_lock);
268 rtnl_unlock(); 245 rtnl_unlock();
269 246
270 return -EADDRNOTAVAIL; 247 return -EADDRNOTAVAIL;
@@ -311,16 +288,12 @@ void ipv6_sock_mc_close(struct sock *sk)
311 return; 288 return;
312 289
313 rtnl_lock(); 290 rtnl_lock();
314 spin_lock(&ipv6_sk_mc_lock); 291 while ((mc_lst = rtnl_dereference(np->ipv6_mc_list)) != NULL) {
315 while ((mc_lst = rcu_dereference_protected(np->ipv6_mc_list,
316 lockdep_is_held(&ipv6_sk_mc_lock))) != NULL) {
317 struct net_device *dev; 292 struct net_device *dev;
318 293
319 np->ipv6_mc_list = mc_lst->next; 294 np->ipv6_mc_list = mc_lst->next;
320 spin_unlock(&ipv6_sk_mc_lock);
321 295
322 rcu_read_lock(); 296 dev = __dev_get_by_index(net, mc_lst->ifindex);
323 dev = dev_get_by_index_rcu(net, mc_lst->ifindex);
324 if (dev) { 297 if (dev) {
325 struct inet6_dev *idev = __in6_dev_get(dev); 298 struct inet6_dev *idev = __in6_dev_get(dev);
326 299
@@ -329,14 +302,11 @@ void ipv6_sock_mc_close(struct sock *sk)
329 __ipv6_dev_mc_dec(idev, &mc_lst->addr); 302 __ipv6_dev_mc_dec(idev, &mc_lst->addr);
330 } else 303 } else
331 (void) ip6_mc_leave_src(sk, mc_lst, NULL); 304 (void) ip6_mc_leave_src(sk, mc_lst, NULL);
332 rcu_read_unlock();
333 305
334 atomic_sub(sizeof(*mc_lst), &sk->sk_omem_alloc); 306 atomic_sub(sizeof(*mc_lst), &sk->sk_omem_alloc);
335 kfree_rcu(mc_lst, rcu); 307 kfree_rcu(mc_lst, rcu);
336 308
337 spin_lock(&ipv6_sk_mc_lock);
338 } 309 }
339 spin_unlock(&ipv6_sk_mc_lock);
340 rtnl_unlock(); 310 rtnl_unlock();
341} 311}
342 312
@@ -400,7 +370,7 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
400 if (!psl) 370 if (!psl)
401 goto done; /* err = -EADDRNOTAVAIL */ 371 goto done; /* err = -EADDRNOTAVAIL */
402 rv = !0; 372 rv = !0;
403 for (i=0; i<psl->sl_count; i++) { 373 for (i = 0; i < psl->sl_count; i++) {
404 rv = !ipv6_addr_equal(&psl->sl_addr[i], source); 374 rv = !ipv6_addr_equal(&psl->sl_addr[i], source);
405 if (rv == 0) 375 if (rv == 0)
406 break; 376 break;
@@ -417,7 +387,7 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
417 /* update the interface filter */ 387 /* update the interface filter */
418 ip6_mc_del_src(idev, group, omode, 1, source, 1); 388 ip6_mc_del_src(idev, group, omode, 1, source, 1);
419 389
420 for (j=i+1; j<psl->sl_count; j++) 390 for (j = i+1; j < psl->sl_count; j++)
421 psl->sl_addr[j-1] = psl->sl_addr[j]; 391 psl->sl_addr[j-1] = psl->sl_addr[j];
422 psl->sl_count--; 392 psl->sl_count--;
423 err = 0; 393 err = 0;
@@ -443,19 +413,19 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
443 newpsl->sl_max = count; 413 newpsl->sl_max = count;
444 newpsl->sl_count = count - IP6_SFBLOCK; 414 newpsl->sl_count = count - IP6_SFBLOCK;
445 if (psl) { 415 if (psl) {
446 for (i=0; i<psl->sl_count; i++) 416 for (i = 0; i < psl->sl_count; i++)
447 newpsl->sl_addr[i] = psl->sl_addr[i]; 417 newpsl->sl_addr[i] = psl->sl_addr[i];
448 sock_kfree_s(sk, psl, IP6_SFLSIZE(psl->sl_max)); 418 sock_kfree_s(sk, psl, IP6_SFLSIZE(psl->sl_max));
449 } 419 }
450 pmc->sflist = psl = newpsl; 420 pmc->sflist = psl = newpsl;
451 } 421 }
452 rv = 1; /* > 0 for insert logic below if sl_count is 0 */ 422 rv = 1; /* > 0 for insert logic below if sl_count is 0 */
453 for (i=0; i<psl->sl_count; i++) { 423 for (i = 0; i < psl->sl_count; i++) {
454 rv = !ipv6_addr_equal(&psl->sl_addr[i], source); 424 rv = !ipv6_addr_equal(&psl->sl_addr[i], source);
455 if (rv == 0) /* There is an error in the address. */ 425 if (rv == 0) /* There is an error in the address. */
456 goto done; 426 goto done;
457 } 427 }
458 for (j=psl->sl_count-1; j>=i; j--) 428 for (j = psl->sl_count-1; j >= i; j--)
459 psl->sl_addr[j+1] = psl->sl_addr[j]; 429 psl->sl_addr[j+1] = psl->sl_addr[j];
460 psl->sl_addr[i] = *source; 430 psl->sl_addr[i] = *source;
461 psl->sl_count++; 431 psl->sl_count++;
@@ -524,7 +494,7 @@ int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf)
524 goto done; 494 goto done;
525 } 495 }
526 newpsl->sl_max = newpsl->sl_count = gsf->gf_numsrc; 496 newpsl->sl_max = newpsl->sl_count = gsf->gf_numsrc;
527 for (i=0; i<newpsl->sl_count; ++i) { 497 for (i = 0; i < newpsl->sl_count; ++i) {
528 struct sockaddr_in6 *psin6; 498 struct sockaddr_in6 *psin6;
529 499
530 psin6 = (struct sockaddr_in6 *)&gsf->gf_slist[i]; 500 psin6 = (struct sockaddr_in6 *)&gsf->gf_slist[i];
@@ -586,9 +556,8 @@ int ip6_mc_msfget(struct sock *sk, struct group_filter *gsf,
586 } 556 }
587 557
588 err = -EADDRNOTAVAIL; 558 err = -EADDRNOTAVAIL;
589 /* 559 /* changes to the ipv6_mc_list require the socket lock and
590 * changes to the ipv6_mc_list require the socket lock and 560 * rtnl lock. We have the socket lock and rcu read lock,
591 * a read lock on ip6_sk_mc_lock. We have the socket lock,
592 * so reading the list is safe. 561 * so reading the list is safe.
593 */ 562 */
594 563
@@ -612,11 +581,10 @@ int ip6_mc_msfget(struct sock *sk, struct group_filter *gsf,
612 copy_to_user(optval, gsf, GROUP_FILTER_SIZE(0))) { 581 copy_to_user(optval, gsf, GROUP_FILTER_SIZE(0))) {
613 return -EFAULT; 582 return -EFAULT;
614 } 583 }
615 /* changes to psl require the socket lock, a read lock on 584 /* changes to psl require the socket lock, and a write lock
616 * on ipv6_sk_mc_lock and a write lock on pmc->sflock. We 585 * on pmc->sflock. We have the socket lock so reading here is safe.
617 * have the socket lock, so reading here is safe.
618 */ 586 */
619 for (i=0; i<copycount; i++) { 587 for (i = 0; i < copycount; i++) {
620 struct sockaddr_in6 *psin6; 588 struct sockaddr_in6 *psin6;
621 struct sockaddr_storage ss; 589 struct sockaddr_storage ss;
622 590
@@ -658,7 +626,7 @@ bool inet6_mc_check(struct sock *sk, const struct in6_addr *mc_addr,
658 } else { 626 } else {
659 int i; 627 int i;
660 628
661 for (i=0; i<psl->sl_count; i++) { 629 for (i = 0; i < psl->sl_count; i++) {
662 if (ipv6_addr_equal(&psl->sl_addr[i], src_addr)) 630 if (ipv6_addr_equal(&psl->sl_addr[i], src_addr))
663 break; 631 break;
664 } 632 }
@@ -673,14 +641,6 @@ bool inet6_mc_check(struct sock *sk, const struct in6_addr *mc_addr,
673 return rv; 641 return rv;
674} 642}
675 643
676static void ma_put(struct ifmcaddr6 *mc)
677{
678 if (atomic_dec_and_test(&mc->mca_refcnt)) {
679 in6_dev_put(mc->idev);
680 kfree(mc);
681 }
682}
683
684static void igmp6_group_added(struct ifmcaddr6 *mc) 644static void igmp6_group_added(struct ifmcaddr6 *mc)
685{ 645{
686 struct net_device *dev = mc->idev->dev; 646 struct net_device *dev = mc->idev->dev;
@@ -772,7 +732,7 @@ static void mld_add_delrec(struct inet6_dev *idev, struct ifmcaddr6 *im)
772 pmc->mca_tomb = im->mca_tomb; 732 pmc->mca_tomb = im->mca_tomb;
773 pmc->mca_sources = im->mca_sources; 733 pmc->mca_sources = im->mca_sources;
774 im->mca_tomb = im->mca_sources = NULL; 734 im->mca_tomb = im->mca_sources = NULL;
775 for (psf=pmc->mca_sources; psf; psf=psf->sf_next) 735 for (psf = pmc->mca_sources; psf; psf = psf->sf_next)
776 psf->sf_crcount = pmc->mca_crcount; 736 psf->sf_crcount = pmc->mca_crcount;
777 } 737 }
778 spin_unlock_bh(&im->mca_lock); 738 spin_unlock_bh(&im->mca_lock);
@@ -790,7 +750,7 @@ static void mld_del_delrec(struct inet6_dev *idev, const struct in6_addr *pmca)
790 750
791 spin_lock_bh(&idev->mc_lock); 751 spin_lock_bh(&idev->mc_lock);
792 pmc_prev = NULL; 752 pmc_prev = NULL;
793 for (pmc=idev->mc_tomb; pmc; pmc=pmc->next) { 753 for (pmc = idev->mc_tomb; pmc; pmc = pmc->next) {
794 if (ipv6_addr_equal(&pmc->mca_addr, pmca)) 754 if (ipv6_addr_equal(&pmc->mca_addr, pmca))
795 break; 755 break;
796 pmc_prev = pmc; 756 pmc_prev = pmc;
@@ -804,7 +764,7 @@ static void mld_del_delrec(struct inet6_dev *idev, const struct in6_addr *pmca)
804 spin_unlock_bh(&idev->mc_lock); 764 spin_unlock_bh(&idev->mc_lock);
805 765
806 if (pmc) { 766 if (pmc) {
807 for (psf=pmc->mca_tomb; psf; psf=psf_next) { 767 for (psf = pmc->mca_tomb; psf; psf = psf_next) {
808 psf_next = psf->sf_next; 768 psf_next = psf->sf_next;
809 kfree(psf); 769 kfree(psf);
810 } 770 }
@@ -831,14 +791,14 @@ static void mld_clear_delrec(struct inet6_dev *idev)
831 791
832 /* clear dead sources, too */ 792 /* clear dead sources, too */
833 read_lock_bh(&idev->lock); 793 read_lock_bh(&idev->lock);
834 for (pmc=idev->mc_list; pmc; pmc=pmc->next) { 794 for (pmc = idev->mc_list; pmc; pmc = pmc->next) {
835 struct ip6_sf_list *psf, *psf_next; 795 struct ip6_sf_list *psf, *psf_next;
836 796
837 spin_lock_bh(&pmc->mca_lock); 797 spin_lock_bh(&pmc->mca_lock);
838 psf = pmc->mca_tomb; 798 psf = pmc->mca_tomb;
839 pmc->mca_tomb = NULL; 799 pmc->mca_tomb = NULL;
840 spin_unlock_bh(&pmc->mca_lock); 800 spin_unlock_bh(&pmc->mca_lock);
841 for (; psf; psf=psf_next) { 801 for (; psf; psf = psf_next) {
842 psf_next = psf->sf_next; 802 psf_next = psf->sf_next;
843 kfree(psf); 803 kfree(psf);
844 } 804 }
@@ -846,6 +806,48 @@ static void mld_clear_delrec(struct inet6_dev *idev)
846 read_unlock_bh(&idev->lock); 806 read_unlock_bh(&idev->lock);
847} 807}
848 808
809static void mca_get(struct ifmcaddr6 *mc)
810{
811 atomic_inc(&mc->mca_refcnt);
812}
813
814static void ma_put(struct ifmcaddr6 *mc)
815{
816 if (atomic_dec_and_test(&mc->mca_refcnt)) {
817 in6_dev_put(mc->idev);
818 kfree(mc);
819 }
820}
821
822static struct ifmcaddr6 *mca_alloc(struct inet6_dev *idev,
823 const struct in6_addr *addr)
824{
825 struct ifmcaddr6 *mc;
826
827 mc = kzalloc(sizeof(*mc), GFP_ATOMIC);
828 if (mc == NULL)
829 return NULL;
830
831 setup_timer(&mc->mca_timer, igmp6_timer_handler, (unsigned long)mc);
832
833 mc->mca_addr = *addr;
834 mc->idev = idev; /* reference taken by caller */
835 mc->mca_users = 1;
836 /* mca_stamp should be updated upon changes */
837 mc->mca_cstamp = mc->mca_tstamp = jiffies;
838 atomic_set(&mc->mca_refcnt, 1);
839 spin_lock_init(&mc->mca_lock);
840
841 /* initial mode is (EX, empty) */
842 mc->mca_sfmode = MCAST_EXCLUDE;
843 mc->mca_sfcount[MCAST_EXCLUDE] = 1;
844
845 if (ipv6_addr_is_ll_all_nodes(&mc->mca_addr) ||
846 IPV6_ADDR_MC_SCOPE(&mc->mca_addr) < IPV6_ADDR_SCOPE_LINKLOCAL)
847 mc->mca_flags |= MAF_NOREPORT;
848
849 return mc;
850}
849 851
850/* 852/*
851 * device multicast group inc (add if not found) 853 * device multicast group inc (add if not found)
@@ -881,38 +883,20 @@ int ipv6_dev_mc_inc(struct net_device *dev, const struct in6_addr *addr)
881 } 883 }
882 } 884 }
883 885
884 /* 886 mc = mca_alloc(idev, addr);
885 * not found: create a new one. 887 if (!mc) {
886 */
887
888 mc = kzalloc(sizeof(struct ifmcaddr6), GFP_ATOMIC);
889
890 if (mc == NULL) {
891 write_unlock_bh(&idev->lock); 888 write_unlock_bh(&idev->lock);
892 in6_dev_put(idev); 889 in6_dev_put(idev);
893 return -ENOMEM; 890 return -ENOMEM;
894 } 891 }
895 892
896 setup_timer(&mc->mca_timer, igmp6_timer_handler, (unsigned long)mc);
897
898 mc->mca_addr = *addr;
899 mc->idev = idev; /* (reference taken) */
900 mc->mca_users = 1;
901 /* mca_stamp should be updated upon changes */
902 mc->mca_cstamp = mc->mca_tstamp = jiffies;
903 atomic_set(&mc->mca_refcnt, 2);
904 spin_lock_init(&mc->mca_lock);
905
906 /* initial mode is (EX, empty) */
907 mc->mca_sfmode = MCAST_EXCLUDE;
908 mc->mca_sfcount[MCAST_EXCLUDE] = 1;
909
910 if (ipv6_addr_is_ll_all_nodes(&mc->mca_addr) ||
911 IPV6_ADDR_MC_SCOPE(&mc->mca_addr) < IPV6_ADDR_SCOPE_LINKLOCAL)
912 mc->mca_flags |= MAF_NOREPORT;
913
914 mc->next = idev->mc_list; 893 mc->next = idev->mc_list;
915 idev->mc_list = mc; 894 idev->mc_list = mc;
895
896 /* Hold this for the code below before we unlock,
897 * it is already exposed via idev->mc_list.
898 */
899 mca_get(mc);
916 write_unlock_bh(&idev->lock); 900 write_unlock_bh(&idev->lock);
917 901
918 mld_del_delrec(idev, &mc->mca_addr); 902 mld_del_delrec(idev, &mc->mca_addr);
@@ -931,7 +915,7 @@ int __ipv6_dev_mc_dec(struct inet6_dev *idev, const struct in6_addr *addr)
931 ASSERT_RTNL(); 915 ASSERT_RTNL();
932 916
933 write_lock_bh(&idev->lock); 917 write_lock_bh(&idev->lock);
934 for (map = &idev->mc_list; (ma=*map) != NULL; map = &ma->next) { 918 for (map = &idev->mc_list; (ma = *map) != NULL; map = &ma->next) {
935 if (ipv6_addr_equal(&ma->mca_addr, addr)) { 919 if (ipv6_addr_equal(&ma->mca_addr, addr)) {
936 if (--ma->mca_users == 0) { 920 if (--ma->mca_users == 0) {
937 *map = ma->next; 921 *map = ma->next;
@@ -956,7 +940,7 @@ int ipv6_dev_mc_dec(struct net_device *dev, const struct in6_addr *addr)
956 struct inet6_dev *idev; 940 struct inet6_dev *idev;
957 int err; 941 int err;
958 942
959 rcu_read_lock(); 943 ASSERT_RTNL();
960 944
961 idev = __in6_dev_get(dev); 945 idev = __in6_dev_get(dev);
962 if (!idev) 946 if (!idev)
@@ -964,7 +948,6 @@ int ipv6_dev_mc_dec(struct net_device *dev, const struct in6_addr *addr)
964 else 948 else
965 err = __ipv6_dev_mc_dec(idev, addr); 949 err = __ipv6_dev_mc_dec(idev, addr);
966 950
967 rcu_read_unlock();
968 return err; 951 return err;
969} 952}
970 953
@@ -982,7 +965,7 @@ bool ipv6_chk_mcast_addr(struct net_device *dev, const struct in6_addr *group,
982 idev = __in6_dev_get(dev); 965 idev = __in6_dev_get(dev);
983 if (idev) { 966 if (idev) {
984 read_lock_bh(&idev->lock); 967 read_lock_bh(&idev->lock);
985 for (mc = idev->mc_list; mc; mc=mc->next) { 968 for (mc = idev->mc_list; mc; mc = mc->next) {
986 if (ipv6_addr_equal(&mc->mca_addr, group)) 969 if (ipv6_addr_equal(&mc->mca_addr, group))
987 break; 970 break;
988 } 971 }
@@ -991,7 +974,7 @@ bool ipv6_chk_mcast_addr(struct net_device *dev, const struct in6_addr *group,
991 struct ip6_sf_list *psf; 974 struct ip6_sf_list *psf;
992 975
993 spin_lock_bh(&mc->mca_lock); 976 spin_lock_bh(&mc->mca_lock);
994 for (psf=mc->mca_sources;psf;psf=psf->sf_next) { 977 for (psf = mc->mca_sources; psf; psf = psf->sf_next) {
995 if (ipv6_addr_equal(&psf->sf_addr, src_addr)) 978 if (ipv6_addr_equal(&psf->sf_addr, src_addr))
996 break; 979 break;
997 } 980 }
@@ -1000,7 +983,7 @@ bool ipv6_chk_mcast_addr(struct net_device *dev, const struct in6_addr *group,
1000 psf->sf_count[MCAST_EXCLUDE] != 983 psf->sf_count[MCAST_EXCLUDE] !=
1001 mc->mca_sfcount[MCAST_EXCLUDE]; 984 mc->mca_sfcount[MCAST_EXCLUDE];
1002 else 985 else
1003 rv = mc->mca_sfcount[MCAST_EXCLUDE] !=0; 986 rv = mc->mca_sfcount[MCAST_EXCLUDE] != 0;
1004 spin_unlock_bh(&mc->mca_lock); 987 spin_unlock_bh(&mc->mca_lock);
1005 } else 988 } else
1006 rv = true; /* don't filter unspecified source */ 989 rv = true; /* don't filter unspecified source */
@@ -1091,10 +1074,10 @@ static bool mld_xmarksources(struct ifmcaddr6 *pmc, int nsrcs,
1091 int i, scount; 1074 int i, scount;
1092 1075
1093 scount = 0; 1076 scount = 0;
1094 for (psf=pmc->mca_sources; psf; psf=psf->sf_next) { 1077 for (psf = pmc->mca_sources; psf; psf = psf->sf_next) {
1095 if (scount == nsrcs) 1078 if (scount == nsrcs)
1096 break; 1079 break;
1097 for (i=0; i<nsrcs; i++) { 1080 for (i = 0; i < nsrcs; i++) {
1098 /* skip inactive filters */ 1081 /* skip inactive filters */
1099 if (psf->sf_count[MCAST_INCLUDE] || 1082 if (psf->sf_count[MCAST_INCLUDE] ||
1100 pmc->mca_sfcount[MCAST_EXCLUDE] != 1083 pmc->mca_sfcount[MCAST_EXCLUDE] !=
@@ -1124,10 +1107,10 @@ static bool mld_marksources(struct ifmcaddr6 *pmc, int nsrcs,
1124 /* mark INCLUDE-mode sources */ 1107 /* mark INCLUDE-mode sources */
1125 1108
1126 scount = 0; 1109 scount = 0;
1127 for (psf=pmc->mca_sources; psf; psf=psf->sf_next) { 1110 for (psf = pmc->mca_sources; psf; psf = psf->sf_next) {
1128 if (scount == nsrcs) 1111 if (scount == nsrcs)
1129 break; 1112 break;
1130 for (i=0; i<nsrcs; i++) { 1113 for (i = 0; i < nsrcs; i++) {
1131 if (ipv6_addr_equal(&srcs[i], &psf->sf_addr)) { 1114 if (ipv6_addr_equal(&srcs[i], &psf->sf_addr)) {
1132 psf->sf_gsresp = 1; 1115 psf->sf_gsresp = 1;
1133 scount++; 1116 scount++;
@@ -1205,15 +1188,16 @@ static void mld_update_qrv(struct inet6_dev *idev,
1205 * and SHOULD NOT be one. Catch this here if we ever run 1188 * and SHOULD NOT be one. Catch this here if we ever run
1206 * into such a case in future. 1189 * into such a case in future.
1207 */ 1190 */
1191 const int min_qrv = min(MLD_QRV_DEFAULT, sysctl_mld_qrv);
1208 WARN_ON(idev->mc_qrv == 0); 1192 WARN_ON(idev->mc_qrv == 0);
1209 1193
1210 if (mlh2->mld2q_qrv > 0) 1194 if (mlh2->mld2q_qrv > 0)
1211 idev->mc_qrv = mlh2->mld2q_qrv; 1195 idev->mc_qrv = mlh2->mld2q_qrv;
1212 1196
1213 if (unlikely(idev->mc_qrv < 2)) { 1197 if (unlikely(idev->mc_qrv < min_qrv)) {
1214 net_warn_ratelimited("IPv6: MLD: clamping QRV from %u to %u!\n", 1198 net_warn_ratelimited("IPv6: MLD: clamping QRV from %u to %u!\n",
1215 idev->mc_qrv, MLD_QRV_DEFAULT); 1199 idev->mc_qrv, min_qrv);
1216 idev->mc_qrv = MLD_QRV_DEFAULT; 1200 idev->mc_qrv = min_qrv;
1217 } 1201 }
1218} 1202}
1219 1203
@@ -1253,7 +1237,7 @@ static void mld_update_qri(struct inet6_dev *idev,
1253} 1237}
1254 1238
1255static int mld_process_v1(struct inet6_dev *idev, struct mld_msg *mld, 1239static int mld_process_v1(struct inet6_dev *idev, struct mld_msg *mld,
1256 unsigned long *max_delay) 1240 unsigned long *max_delay, bool v1_query)
1257{ 1241{
1258 unsigned long mldv1_md; 1242 unsigned long mldv1_md;
1259 1243
@@ -1261,11 +1245,32 @@ static int mld_process_v1(struct inet6_dev *idev, struct mld_msg *mld,
1261 if (mld_in_v2_mode_only(idev)) 1245 if (mld_in_v2_mode_only(idev))
1262 return -EINVAL; 1246 return -EINVAL;
1263 1247
1264 /* MLDv1 router present */
1265 mldv1_md = ntohs(mld->mld_maxdelay); 1248 mldv1_md = ntohs(mld->mld_maxdelay);
1249
1250 /* When in MLDv1 fallback and a MLDv2 router start-up being
1251 * unaware of current MLDv1 operation, the MRC == MRD mapping
1252 * only works when the exponential algorithm is not being
1253 * used (as MLDv1 is unaware of such things).
1254 *
1255 * According to the RFC author, the MLDv2 implementations
1256 * he's aware of all use a MRC < 32768 on start up queries.
1257 *
1258 * Thus, should we *ever* encounter something else larger
1259 * than that, just assume the maximum possible within our
1260 * reach.
1261 */
1262 if (!v1_query)
1263 mldv1_md = min(mldv1_md, MLDV1_MRD_MAX_COMPAT);
1264
1266 *max_delay = max(msecs_to_jiffies(mldv1_md), 1UL); 1265 *max_delay = max(msecs_to_jiffies(mldv1_md), 1UL);
1267 1266
1268 mld_set_v1_mode(idev); 1267 /* MLDv1 router present: we need to go into v1 mode *only*
1268 * when an MLDv1 query is received as per section 9.12. of
1269 * RFC3810! And we know from RFC2710 section 3.7 that MLDv1
1270 * queries MUST be of exactly 24 octets.
1271 */
1272 if (v1_query)
1273 mld_set_v1_mode(idev);
1269 1274
1270 /* cancel MLDv2 report timer */ 1275 /* cancel MLDv2 report timer */
1271 mld_gq_stop_timer(idev); 1276 mld_gq_stop_timer(idev);
@@ -1280,10 +1285,6 @@ static int mld_process_v1(struct inet6_dev *idev, struct mld_msg *mld,
1280static int mld_process_v2(struct inet6_dev *idev, struct mld2_query *mld, 1285static int mld_process_v2(struct inet6_dev *idev, struct mld2_query *mld,
1281 unsigned long *max_delay) 1286 unsigned long *max_delay)
1282{ 1287{
1283 /* hosts need to stay in MLDv1 mode, discard MLDv2 queries */
1284 if (mld_in_v1_mode(idev))
1285 return -EINVAL;
1286
1287 *max_delay = max(msecs_to_jiffies(mldv2_mrc(mld)), 1UL); 1288 *max_delay = max(msecs_to_jiffies(mldv2_mrc(mld)), 1UL);
1288 1289
1289 mld_update_qrv(idev, mld); 1290 mld_update_qrv(idev, mld);
@@ -1340,8 +1341,11 @@ int igmp6_event_query(struct sk_buff *skb)
1340 !(group_type&IPV6_ADDR_MULTICAST)) 1341 !(group_type&IPV6_ADDR_MULTICAST))
1341 return -EINVAL; 1342 return -EINVAL;
1342 1343
1343 if (len == MLD_V1_QUERY_LEN) { 1344 if (len < MLD_V1_QUERY_LEN) {
1344 err = mld_process_v1(idev, mld, &max_delay); 1345 return -EINVAL;
1346 } else if (len == MLD_V1_QUERY_LEN || mld_in_v1_mode(idev)) {
1347 err = mld_process_v1(idev, mld, &max_delay,
1348 len == MLD_V1_QUERY_LEN);
1345 if (err < 0) 1349 if (err < 0)
1346 return err; 1350 return err;
1347 } else if (len >= MLD_V2_QUERY_LEN_MIN) { 1351 } else if (len >= MLD_V2_QUERY_LEN_MIN) {
@@ -1373,18 +1377,19 @@ int igmp6_event_query(struct sk_buff *skb)
1373 mlh2 = (struct mld2_query *)skb_transport_header(skb); 1377 mlh2 = (struct mld2_query *)skb_transport_header(skb);
1374 mark = 1; 1378 mark = 1;
1375 } 1379 }
1376 } else 1380 } else {
1377 return -EINVAL; 1381 return -EINVAL;
1382 }
1378 1383
1379 read_lock_bh(&idev->lock); 1384 read_lock_bh(&idev->lock);
1380 if (group_type == IPV6_ADDR_ANY) { 1385 if (group_type == IPV6_ADDR_ANY) {
1381 for (ma = idev->mc_list; ma; ma=ma->next) { 1386 for (ma = idev->mc_list; ma; ma = ma->next) {
1382 spin_lock_bh(&ma->mca_lock); 1387 spin_lock_bh(&ma->mca_lock);
1383 igmp6_group_queried(ma, max_delay); 1388 igmp6_group_queried(ma, max_delay);
1384 spin_unlock_bh(&ma->mca_lock); 1389 spin_unlock_bh(&ma->mca_lock);
1385 } 1390 }
1386 } else { 1391 } else {
1387 for (ma = idev->mc_list; ma; ma=ma->next) { 1392 for (ma = idev->mc_list; ma; ma = ma->next) {
1388 if (!ipv6_addr_equal(group, &ma->mca_addr)) 1393 if (!ipv6_addr_equal(group, &ma->mca_addr))
1389 continue; 1394 continue;
1390 spin_lock_bh(&ma->mca_lock); 1395 spin_lock_bh(&ma->mca_lock);
@@ -1448,7 +1453,7 @@ int igmp6_event_report(struct sk_buff *skb)
1448 */ 1453 */
1449 1454
1450 read_lock_bh(&idev->lock); 1455 read_lock_bh(&idev->lock);
1451 for (ma = idev->mc_list; ma; ma=ma->next) { 1456 for (ma = idev->mc_list; ma; ma = ma->next) {
1452 if (ipv6_addr_equal(&ma->mca_addr, &mld->mld_mca)) { 1457 if (ipv6_addr_equal(&ma->mca_addr, &mld->mld_mca)) {
1453 spin_lock(&ma->mca_lock); 1458 spin_lock(&ma->mca_lock);
1454 if (del_timer(&ma->mca_timer)) 1459 if (del_timer(&ma->mca_timer))
@@ -1512,7 +1517,7 @@ mld_scount(struct ifmcaddr6 *pmc, int type, int gdeleted, int sdeleted)
1512 struct ip6_sf_list *psf; 1517 struct ip6_sf_list *psf;
1513 int scount = 0; 1518 int scount = 0;
1514 1519
1515 for (psf=pmc->mca_sources; psf; psf=psf->sf_next) { 1520 for (psf = pmc->mca_sources; psf; psf = psf->sf_next) {
1516 if (!is_in(pmc, psf, type, gdeleted, sdeleted)) 1521 if (!is_in(pmc, psf, type, gdeleted, sdeleted))
1517 continue; 1522 continue;
1518 scount++; 1523 scount++;
@@ -1726,7 +1731,7 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc,
1726 } 1731 }
1727 first = 1; 1732 first = 1;
1728 psf_prev = NULL; 1733 psf_prev = NULL;
1729 for (psf=*psf_list; psf; psf=psf_next) { 1734 for (psf = *psf_list; psf; psf = psf_next) {
1730 struct in6_addr *psrc; 1735 struct in6_addr *psrc;
1731 1736
1732 psf_next = psf->sf_next; 1737 psf_next = psf->sf_next;
@@ -1805,7 +1810,7 @@ static void mld_send_report(struct inet6_dev *idev, struct ifmcaddr6 *pmc)
1805 1810
1806 read_lock_bh(&idev->lock); 1811 read_lock_bh(&idev->lock);
1807 if (!pmc) { 1812 if (!pmc) {
1808 for (pmc=idev->mc_list; pmc; pmc=pmc->next) { 1813 for (pmc = idev->mc_list; pmc; pmc = pmc->next) {
1809 if (pmc->mca_flags & MAF_NOREPORT) 1814 if (pmc->mca_flags & MAF_NOREPORT)
1810 continue; 1815 continue;
1811 spin_lock_bh(&pmc->mca_lock); 1816 spin_lock_bh(&pmc->mca_lock);
@@ -1838,7 +1843,7 @@ static void mld_clear_zeros(struct ip6_sf_list **ppsf)
1838 struct ip6_sf_list *psf_prev, *psf_next, *psf; 1843 struct ip6_sf_list *psf_prev, *psf_next, *psf;
1839 1844
1840 psf_prev = NULL; 1845 psf_prev = NULL;
1841 for (psf=*ppsf; psf; psf = psf_next) { 1846 for (psf = *ppsf; psf; psf = psf_next) {
1842 psf_next = psf->sf_next; 1847 psf_next = psf->sf_next;
1843 if (psf->sf_crcount == 0) { 1848 if (psf->sf_crcount == 0) {
1844 if (psf_prev) 1849 if (psf_prev)
@@ -1862,7 +1867,7 @@ static void mld_send_cr(struct inet6_dev *idev)
1862 1867
1863 /* deleted MCA's */ 1868 /* deleted MCA's */
1864 pmc_prev = NULL; 1869 pmc_prev = NULL;
1865 for (pmc=idev->mc_tomb; pmc; pmc=pmc_next) { 1870 for (pmc = idev->mc_tomb; pmc; pmc = pmc_next) {
1866 pmc_next = pmc->next; 1871 pmc_next = pmc->next;
1867 if (pmc->mca_sfmode == MCAST_INCLUDE) { 1872 if (pmc->mca_sfmode == MCAST_INCLUDE) {
1868 type = MLD2_BLOCK_OLD_SOURCES; 1873 type = MLD2_BLOCK_OLD_SOURCES;
@@ -1895,7 +1900,7 @@ static void mld_send_cr(struct inet6_dev *idev)
1895 spin_unlock(&idev->mc_lock); 1900 spin_unlock(&idev->mc_lock);
1896 1901
1897 /* change recs */ 1902 /* change recs */
1898 for (pmc=idev->mc_list; pmc; pmc=pmc->next) { 1903 for (pmc = idev->mc_list; pmc; pmc = pmc->next) {
1899 spin_lock_bh(&pmc->mca_lock); 1904 spin_lock_bh(&pmc->mca_lock);
1900 if (pmc->mca_sfcount[MCAST_EXCLUDE]) { 1905 if (pmc->mca_sfcount[MCAST_EXCLUDE]) {
1901 type = MLD2_BLOCK_OLD_SOURCES; 1906 type = MLD2_BLOCK_OLD_SOURCES;
@@ -2032,7 +2037,7 @@ static void mld_send_initial_cr(struct inet6_dev *idev)
2032 2037
2033 skb = NULL; 2038 skb = NULL;
2034 read_lock_bh(&idev->lock); 2039 read_lock_bh(&idev->lock);
2035 for (pmc=idev->mc_list; pmc; pmc=pmc->next) { 2040 for (pmc = idev->mc_list; pmc; pmc = pmc->next) {
2036 spin_lock_bh(&pmc->mca_lock); 2041 spin_lock_bh(&pmc->mca_lock);
2037 if (pmc->mca_sfcount[MCAST_EXCLUDE]) 2042 if (pmc->mca_sfcount[MCAST_EXCLUDE])
2038 type = MLD2_CHANGE_TO_EXCLUDE; 2043 type = MLD2_CHANGE_TO_EXCLUDE;
@@ -2077,7 +2082,7 @@ static int ip6_mc_del1_src(struct ifmcaddr6 *pmc, int sfmode,
2077 int rv = 0; 2082 int rv = 0;
2078 2083
2079 psf_prev = NULL; 2084 psf_prev = NULL;
2080 for (psf=pmc->mca_sources; psf; psf=psf->sf_next) { 2085 for (psf = pmc->mca_sources; psf; psf = psf->sf_next) {
2081 if (ipv6_addr_equal(&psf->sf_addr, psfsrc)) 2086 if (ipv6_addr_equal(&psf->sf_addr, psfsrc))
2082 break; 2087 break;
2083 psf_prev = psf; 2088 psf_prev = psf;
@@ -2118,7 +2123,7 @@ static int ip6_mc_del_src(struct inet6_dev *idev, const struct in6_addr *pmca,
2118 if (!idev) 2123 if (!idev)
2119 return -ENODEV; 2124 return -ENODEV;
2120 read_lock_bh(&idev->lock); 2125 read_lock_bh(&idev->lock);
2121 for (pmc=idev->mc_list; pmc; pmc=pmc->next) { 2126 for (pmc = idev->mc_list; pmc; pmc = pmc->next) {
2122 if (ipv6_addr_equal(pmca, &pmc->mca_addr)) 2127 if (ipv6_addr_equal(pmca, &pmc->mca_addr))
2123 break; 2128 break;
2124 } 2129 }
@@ -2138,7 +2143,7 @@ static int ip6_mc_del_src(struct inet6_dev *idev, const struct in6_addr *pmca,
2138 pmc->mca_sfcount[sfmode]--; 2143 pmc->mca_sfcount[sfmode]--;
2139 } 2144 }
2140 err = 0; 2145 err = 0;
2141 for (i=0; i<sfcount; i++) { 2146 for (i = 0; i < sfcount; i++) {
2142 int rv = ip6_mc_del1_src(pmc, sfmode, &psfsrc[i]); 2147 int rv = ip6_mc_del1_src(pmc, sfmode, &psfsrc[i]);
2143 2148
2144 changerec |= rv > 0; 2149 changerec |= rv > 0;
@@ -2154,7 +2159,7 @@ static int ip6_mc_del_src(struct inet6_dev *idev, const struct in6_addr *pmca,
2154 pmc->mca_sfmode = MCAST_INCLUDE; 2159 pmc->mca_sfmode = MCAST_INCLUDE;
2155 pmc->mca_crcount = idev->mc_qrv; 2160 pmc->mca_crcount = idev->mc_qrv;
2156 idev->mc_ifc_count = pmc->mca_crcount; 2161 idev->mc_ifc_count = pmc->mca_crcount;
2157 for (psf=pmc->mca_sources; psf; psf = psf->sf_next) 2162 for (psf = pmc->mca_sources; psf; psf = psf->sf_next)
2158 psf->sf_crcount = 0; 2163 psf->sf_crcount = 0;
2159 mld_ifc_event(pmc->idev); 2164 mld_ifc_event(pmc->idev);
2160 } else if (sf_setstate(pmc) || changerec) 2165 } else if (sf_setstate(pmc) || changerec)
@@ -2173,7 +2178,7 @@ static int ip6_mc_add1_src(struct ifmcaddr6 *pmc, int sfmode,
2173 struct ip6_sf_list *psf, *psf_prev; 2178 struct ip6_sf_list *psf, *psf_prev;
2174 2179
2175 psf_prev = NULL; 2180 psf_prev = NULL;
2176 for (psf=pmc->mca_sources; psf; psf=psf->sf_next) { 2181 for (psf = pmc->mca_sources; psf; psf = psf->sf_next) {
2177 if (ipv6_addr_equal(&psf->sf_addr, psfsrc)) 2182 if (ipv6_addr_equal(&psf->sf_addr, psfsrc))
2178 break; 2183 break;
2179 psf_prev = psf; 2184 psf_prev = psf;
@@ -2198,7 +2203,7 @@ static void sf_markstate(struct ifmcaddr6 *pmc)
2198 struct ip6_sf_list *psf; 2203 struct ip6_sf_list *psf;
2199 int mca_xcount = pmc->mca_sfcount[MCAST_EXCLUDE]; 2204 int mca_xcount = pmc->mca_sfcount[MCAST_EXCLUDE];
2200 2205
2201 for (psf=pmc->mca_sources; psf; psf=psf->sf_next) 2206 for (psf = pmc->mca_sources; psf; psf = psf->sf_next)
2202 if (pmc->mca_sfcount[MCAST_EXCLUDE]) { 2207 if (pmc->mca_sfcount[MCAST_EXCLUDE]) {
2203 psf->sf_oldin = mca_xcount == 2208 psf->sf_oldin = mca_xcount ==
2204 psf->sf_count[MCAST_EXCLUDE] && 2209 psf->sf_count[MCAST_EXCLUDE] &&
@@ -2215,7 +2220,7 @@ static int sf_setstate(struct ifmcaddr6 *pmc)
2215 int new_in, rv; 2220 int new_in, rv;
2216 2221
2217 rv = 0; 2222 rv = 0;
2218 for (psf=pmc->mca_sources; psf; psf=psf->sf_next) { 2223 for (psf = pmc->mca_sources; psf; psf = psf->sf_next) {
2219 if (pmc->mca_sfcount[MCAST_EXCLUDE]) { 2224 if (pmc->mca_sfcount[MCAST_EXCLUDE]) {
2220 new_in = mca_xcount == psf->sf_count[MCAST_EXCLUDE] && 2225 new_in = mca_xcount == psf->sf_count[MCAST_EXCLUDE] &&
2221 !psf->sf_count[MCAST_INCLUDE]; 2226 !psf->sf_count[MCAST_INCLUDE];
@@ -2225,8 +2230,8 @@ static int sf_setstate(struct ifmcaddr6 *pmc)
2225 if (!psf->sf_oldin) { 2230 if (!psf->sf_oldin) {
2226 struct ip6_sf_list *prev = NULL; 2231 struct ip6_sf_list *prev = NULL;
2227 2232
2228 for (dpsf=pmc->mca_tomb; dpsf; 2233 for (dpsf = pmc->mca_tomb; dpsf;
2229 dpsf=dpsf->sf_next) { 2234 dpsf = dpsf->sf_next) {
2230 if (ipv6_addr_equal(&dpsf->sf_addr, 2235 if (ipv6_addr_equal(&dpsf->sf_addr,
2231 &psf->sf_addr)) 2236 &psf->sf_addr))
2232 break; 2237 break;
@@ -2248,7 +2253,7 @@ static int sf_setstate(struct ifmcaddr6 *pmc)
2248 * add or update "delete" records if an active filter 2253 * add or update "delete" records if an active filter
2249 * is now inactive 2254 * is now inactive
2250 */ 2255 */
2251 for (dpsf=pmc->mca_tomb; dpsf; dpsf=dpsf->sf_next) 2256 for (dpsf = pmc->mca_tomb; dpsf; dpsf = dpsf->sf_next)
2252 if (ipv6_addr_equal(&dpsf->sf_addr, 2257 if (ipv6_addr_equal(&dpsf->sf_addr,
2253 &psf->sf_addr)) 2258 &psf->sf_addr))
2254 break; 2259 break;
@@ -2282,7 +2287,7 @@ static int ip6_mc_add_src(struct inet6_dev *idev, const struct in6_addr *pmca,
2282 if (!idev) 2287 if (!idev)
2283 return -ENODEV; 2288 return -ENODEV;
2284 read_lock_bh(&idev->lock); 2289 read_lock_bh(&idev->lock);
2285 for (pmc=idev->mc_list; pmc; pmc=pmc->next) { 2290 for (pmc = idev->mc_list; pmc; pmc = pmc->next) {
2286 if (ipv6_addr_equal(pmca, &pmc->mca_addr)) 2291 if (ipv6_addr_equal(pmca, &pmc->mca_addr))
2287 break; 2292 break;
2288 } 2293 }
@@ -2298,7 +2303,7 @@ static int ip6_mc_add_src(struct inet6_dev *idev, const struct in6_addr *pmca,
2298 if (!delta) 2303 if (!delta)
2299 pmc->mca_sfcount[sfmode]++; 2304 pmc->mca_sfcount[sfmode]++;
2300 err = 0; 2305 err = 0;
2301 for (i=0; i<sfcount; i++) { 2306 for (i = 0; i < sfcount; i++) {
2302 err = ip6_mc_add1_src(pmc, sfmode, &psfsrc[i]); 2307 err = ip6_mc_add1_src(pmc, sfmode, &psfsrc[i]);
2303 if (err) 2308 if (err)
2304 break; 2309 break;
@@ -2308,7 +2313,7 @@ static int ip6_mc_add_src(struct inet6_dev *idev, const struct in6_addr *pmca,
2308 2313
2309 if (!delta) 2314 if (!delta)
2310 pmc->mca_sfcount[sfmode]--; 2315 pmc->mca_sfcount[sfmode]--;
2311 for (j=0; j<i; j++) 2316 for (j = 0; j < i; j++)
2312 ip6_mc_del1_src(pmc, sfmode, &psfsrc[j]); 2317 ip6_mc_del1_src(pmc, sfmode, &psfsrc[j]);
2313 } else if (isexclude != (pmc->mca_sfcount[MCAST_EXCLUDE] != 0)) { 2318 } else if (isexclude != (pmc->mca_sfcount[MCAST_EXCLUDE] != 0)) {
2314 struct ip6_sf_list *psf; 2319 struct ip6_sf_list *psf;
@@ -2322,7 +2327,7 @@ static int ip6_mc_add_src(struct inet6_dev *idev, const struct in6_addr *pmca,
2322 2327
2323 pmc->mca_crcount = idev->mc_qrv; 2328 pmc->mca_crcount = idev->mc_qrv;
2324 idev->mc_ifc_count = pmc->mca_crcount; 2329 idev->mc_ifc_count = pmc->mca_crcount;
2325 for (psf=pmc->mca_sources; psf; psf = psf->sf_next) 2330 for (psf = pmc->mca_sources; psf; psf = psf->sf_next)
2326 psf->sf_crcount = 0; 2331 psf->sf_crcount = 0;
2327 mld_ifc_event(idev); 2332 mld_ifc_event(idev);
2328 } else if (sf_setstate(pmc)) 2333 } else if (sf_setstate(pmc))
@@ -2336,12 +2341,12 @@ static void ip6_mc_clear_src(struct ifmcaddr6 *pmc)
2336{ 2341{
2337 struct ip6_sf_list *psf, *nextpsf; 2342 struct ip6_sf_list *psf, *nextpsf;
2338 2343
2339 for (psf=pmc->mca_tomb; psf; psf=nextpsf) { 2344 for (psf = pmc->mca_tomb; psf; psf = nextpsf) {
2340 nextpsf = psf->sf_next; 2345 nextpsf = psf->sf_next;
2341 kfree(psf); 2346 kfree(psf);
2342 } 2347 }
2343 pmc->mca_tomb = NULL; 2348 pmc->mca_tomb = NULL;
2344 for (psf=pmc->mca_sources; psf; psf=nextpsf) { 2349 for (psf = pmc->mca_sources; psf; psf = nextpsf) {
2345 nextpsf = psf->sf_next; 2350 nextpsf = psf->sf_next;
2346 kfree(psf); 2351 kfree(psf);
2347 } 2352 }
@@ -2380,7 +2385,7 @@ static int ip6_mc_leave_src(struct sock *sk, struct ipv6_mc_socklist *iml,
2380{ 2385{
2381 int err; 2386 int err;
2382 2387
2383 /* callers have the socket lock and a write lock on ipv6_sk_mc_lock, 2388 /* callers have the socket lock and rtnl lock
2384 * so no other readers or writers of iml or its sflist 2389 * so no other readers or writers of iml or its sflist
2385 */ 2390 */
2386 if (!iml->sflist) { 2391 if (!iml->sflist) {
@@ -2485,13 +2490,21 @@ void ipv6_mc_down(struct inet6_dev *idev)
2485 mld_gq_stop_timer(idev); 2490 mld_gq_stop_timer(idev);
2486 mld_dad_stop_timer(idev); 2491 mld_dad_stop_timer(idev);
2487 2492
2488 for (i = idev->mc_list; i; i=i->next) 2493 for (i = idev->mc_list; i; i = i->next)
2489 igmp6_group_dropped(i); 2494 igmp6_group_dropped(i);
2490 read_unlock_bh(&idev->lock); 2495 read_unlock_bh(&idev->lock);
2491 2496
2492 mld_clear_delrec(idev); 2497 mld_clear_delrec(idev);
2493} 2498}
2494 2499
2500static void ipv6_mc_reset(struct inet6_dev *idev)
2501{
2502 idev->mc_qrv = sysctl_mld_qrv;
2503 idev->mc_qi = MLD_QI_DEFAULT;
2504 idev->mc_qri = MLD_QRI_DEFAULT;
2505 idev->mc_v1_seen = 0;
2506 idev->mc_maxdelay = unsolicited_report_interval(idev);
2507}
2495 2508
2496/* Device going up */ 2509/* Device going up */
2497 2510
@@ -2502,7 +2515,8 @@ void ipv6_mc_up(struct inet6_dev *idev)
2502 /* Install multicast list, except for all-nodes (already installed) */ 2515 /* Install multicast list, except for all-nodes (already installed) */
2503 2516
2504 read_lock_bh(&idev->lock); 2517 read_lock_bh(&idev->lock);
2505 for (i = idev->mc_list; i; i=i->next) 2518 ipv6_mc_reset(idev);
2519 for (i = idev->mc_list; i; i = i->next)
2506 igmp6_group_added(i); 2520 igmp6_group_added(i);
2507 read_unlock_bh(&idev->lock); 2521 read_unlock_bh(&idev->lock);
2508} 2522}
@@ -2522,13 +2536,7 @@ void ipv6_mc_init_dev(struct inet6_dev *idev)
2522 (unsigned long)idev); 2536 (unsigned long)idev);
2523 setup_timer(&idev->mc_dad_timer, mld_dad_timer_expire, 2537 setup_timer(&idev->mc_dad_timer, mld_dad_timer_expire,
2524 (unsigned long)idev); 2538 (unsigned long)idev);
2525 2539 ipv6_mc_reset(idev);
2526 idev->mc_qrv = MLD_QRV_DEFAULT;
2527 idev->mc_qi = MLD_QI_DEFAULT;
2528 idev->mc_qri = MLD_QRI_DEFAULT;
2529
2530 idev->mc_maxdelay = unsolicited_report_interval(idev);
2531 idev->mc_v1_seen = 0;
2532 write_unlock_bh(&idev->lock); 2540 write_unlock_bh(&idev->lock);
2533} 2541}
2534 2542
diff --git a/net/ipv6/mip6.c b/net/ipv6/mip6.c
index db9b6cbc9db3..f61429d391d3 100644
--- a/net/ipv6/mip6.c
+++ b/net/ipv6/mip6.c
@@ -336,11 +336,10 @@ static void mip6_destopt_destroy(struct xfrm_state *x)
336{ 336{
337} 337}
338 338
339static const struct xfrm_type mip6_destopt_type = 339static const struct xfrm_type mip6_destopt_type = {
340{
341 .description = "MIP6DESTOPT", 340 .description = "MIP6DESTOPT",
342 .owner = THIS_MODULE, 341 .owner = THIS_MODULE,
343 .proto = IPPROTO_DSTOPTS, 342 .proto = IPPROTO_DSTOPTS,
344 .flags = XFRM_TYPE_NON_FRAGMENT | XFRM_TYPE_LOCAL_COADDR, 343 .flags = XFRM_TYPE_NON_FRAGMENT | XFRM_TYPE_LOCAL_COADDR,
345 .init_state = mip6_destopt_init_state, 344 .init_state = mip6_destopt_init_state,
346 .destructor = mip6_destopt_destroy, 345 .destructor = mip6_destopt_destroy,
@@ -469,11 +468,10 @@ static void mip6_rthdr_destroy(struct xfrm_state *x)
469{ 468{
470} 469}
471 470
472static const struct xfrm_type mip6_rthdr_type = 471static const struct xfrm_type mip6_rthdr_type = {
473{
474 .description = "MIP6RT", 472 .description = "MIP6RT",
475 .owner = THIS_MODULE, 473 .owner = THIS_MODULE,
476 .proto = IPPROTO_ROUTING, 474 .proto = IPPROTO_ROUTING,
477 .flags = XFRM_TYPE_NON_FRAGMENT | XFRM_TYPE_REMOTE_COADDR, 475 .flags = XFRM_TYPE_NON_FRAGMENT | XFRM_TYPE_REMOTE_COADDR,
478 .init_state = mip6_rthdr_init_state, 476 .init_state = mip6_rthdr_init_state,
479 .destructor = mip6_rthdr_destroy, 477 .destructor = mip6_rthdr_destroy,
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 339078f95d1b..4cb45c1079a2 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -175,7 +175,7 @@ static struct nd_opt_hdr *ndisc_next_option(struct nd_opt_hdr *cur,
175 type = cur->nd_opt_type; 175 type = cur->nd_opt_type;
176 do { 176 do {
177 cur = ((void *)cur) + (cur->nd_opt_len << 3); 177 cur = ((void *)cur) + (cur->nd_opt_len << 3);
178 } while(cur < end && cur->nd_opt_type != type); 178 } while (cur < end && cur->nd_opt_type != type);
179 return cur <= end && cur->nd_opt_type == type ? cur : NULL; 179 return cur <= end && cur->nd_opt_type == type ? cur : NULL;
180} 180}
181 181
@@ -192,7 +192,7 @@ static struct nd_opt_hdr *ndisc_next_useropt(struct nd_opt_hdr *cur,
192 return NULL; 192 return NULL;
193 do { 193 do {
194 cur = ((void *)cur) + (cur->nd_opt_len << 3); 194 cur = ((void *)cur) + (cur->nd_opt_len << 3);
195 } while(cur < end && !ndisc_is_useropt(cur)); 195 } while (cur < end && !ndisc_is_useropt(cur));
196 return cur <= end && ndisc_is_useropt(cur) ? cur : NULL; 196 return cur <= end && ndisc_is_useropt(cur) ? cur : NULL;
197} 197}
198 198
@@ -284,7 +284,6 @@ int ndisc_mc_map(const struct in6_addr *addr, char *buf, struct net_device *dev,
284 } 284 }
285 return -EINVAL; 285 return -EINVAL;
286} 286}
287
288EXPORT_SYMBOL(ndisc_mc_map); 287EXPORT_SYMBOL(ndisc_mc_map);
289 288
290static u32 ndisc_hash(const void *pkey, 289static u32 ndisc_hash(const void *pkey,
@@ -296,7 +295,7 @@ static u32 ndisc_hash(const void *pkey,
296 295
297static int ndisc_constructor(struct neighbour *neigh) 296static int ndisc_constructor(struct neighbour *neigh)
298{ 297{
299 struct in6_addr *addr = (struct in6_addr*)&neigh->primary_key; 298 struct in6_addr *addr = (struct in6_addr *)&neigh->primary_key;
300 struct net_device *dev = neigh->dev; 299 struct net_device *dev = neigh->dev;
301 struct inet6_dev *in6_dev; 300 struct inet6_dev *in6_dev;
302 struct neigh_parms *parms; 301 struct neigh_parms *parms;
@@ -344,7 +343,7 @@ static int ndisc_constructor(struct neighbour *neigh)
344 343
345static int pndisc_constructor(struct pneigh_entry *n) 344static int pndisc_constructor(struct pneigh_entry *n)
346{ 345{
347 struct in6_addr *addr = (struct in6_addr*)&n->key; 346 struct in6_addr *addr = (struct in6_addr *)&n->key;
348 struct in6_addr maddr; 347 struct in6_addr maddr;
349 struct net_device *dev = n->dev; 348 struct net_device *dev = n->dev;
350 349
@@ -357,7 +356,7 @@ static int pndisc_constructor(struct pneigh_entry *n)
357 356
358static void pndisc_destructor(struct pneigh_entry *n) 357static void pndisc_destructor(struct pneigh_entry *n)
359{ 358{
360 struct in6_addr *addr = (struct in6_addr*)&n->key; 359 struct in6_addr *addr = (struct in6_addr *)&n->key;
361 struct in6_addr maddr; 360 struct in6_addr maddr;
362 struct net_device *dev = n->dev; 361 struct net_device *dev = n->dev;
363 362
@@ -1065,7 +1064,7 @@ static void ndisc_router_discovery(struct sk_buff *skb)
1065 int optlen; 1064 int optlen;
1066 unsigned int pref = 0; 1065 unsigned int pref = 0;
1067 1066
1068 __u8 * opt = (__u8 *)(ra_msg + 1); 1067 __u8 *opt = (__u8 *)(ra_msg + 1);
1069 1068
1070 optlen = (skb_tail_pointer(skb) - skb_transport_header(skb)) - 1069 optlen = (skb_tail_pointer(skb) - skb_transport_header(skb)) -
1071 sizeof(struct ra_msg); 1070 sizeof(struct ra_msg);
@@ -1319,7 +1318,7 @@ skip_linkparms:
1319 continue; 1318 continue;
1320 if (ri->prefix_len > in6_dev->cnf.accept_ra_rt_info_max_plen) 1319 if (ri->prefix_len > in6_dev->cnf.accept_ra_rt_info_max_plen)
1321 continue; 1320 continue;
1322 rt6_route_rcv(skb->dev, (u8*)p, (p->nd_opt_len) << 3, 1321 rt6_route_rcv(skb->dev, (u8 *)p, (p->nd_opt_len) << 3,
1323 &ipv6_hdr(skb)->saddr); 1322 &ipv6_hdr(skb)->saddr);
1324 } 1323 }
1325 } 1324 }
@@ -1352,7 +1351,7 @@ skip_routeinfo:
1352 __be32 n; 1351 __be32 n;
1353 u32 mtu; 1352 u32 mtu;
1354 1353
1355 memcpy(&n, ((u8*)(ndopts.nd_opts_mtu+1))+2, sizeof(mtu)); 1354 memcpy(&n, ((u8 *)(ndopts.nd_opts_mtu+1))+2, sizeof(mtu));
1356 mtu = ntohl(n); 1355 mtu = ntohl(n);
1357 1356
1358 if (mtu < IPV6_MIN_MTU || mtu > skb->dev->mtu) { 1357 if (mtu < IPV6_MIN_MTU || mtu > skb->dev->mtu) {
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
index 2812816aabdc..6af874fc187f 100644
--- a/net/ipv6/netfilter/Kconfig
+++ b/net/ipv6/netfilter/Kconfig
@@ -40,18 +40,13 @@ config NFT_CHAIN_ROUTE_IPV6
40 fields such as the source, destination, flowlabel, hop-limit and 40 fields such as the source, destination, flowlabel, hop-limit and
41 the packet mark. 41 the packet mark.
42 42
43config NFT_CHAIN_NAT_IPV6 43config NF_REJECT_IPV6
44 depends on NF_TABLES_IPV6 44 tristate "IPv6 packet rejection"
45 depends on NF_NAT_IPV6 && NFT_NAT 45 default m if NETFILTER_ADVANCED=n
46 tristate "IPv6 nf_tables nat chain support"
47 help
48 This option enables the "nat" chain for IPv6 in nf_tables. This
49 chain type is used to perform Network Address Translation (NAT)
50 packet transformations such as the source, destination address and
51 source and destination ports.
52 46
53config NFT_REJECT_IPV6 47config NFT_REJECT_IPV6
54 depends on NF_TABLES_IPV6 48 depends on NF_TABLES_IPV6
49 select NF_REJECT_IPV6
55 default NFT_REJECT 50 default NFT_REJECT
56 tristate 51 tristate
57 52
@@ -70,6 +65,34 @@ config NF_NAT_IPV6
70 forms of full Network Address Port Translation. This can be 65 forms of full Network Address Port Translation. This can be
71 controlled by iptables or nft. 66 controlled by iptables or nft.
72 67
68if NF_NAT_IPV6
69
70config NFT_CHAIN_NAT_IPV6
71 depends on NF_TABLES_IPV6
72 tristate "IPv6 nf_tables nat chain support"
73 help
74 This option enables the "nat" chain for IPv6 in nf_tables. This
75 chain type is used to perform Network Address Translation (NAT)
76 packet transformations such as the source, destination address and
77 source and destination ports.
78
79config NF_NAT_MASQUERADE_IPV6
80 tristate "IPv6 masquerade support"
81 help
82 This is the kernel functionality to provide NAT in the masquerade
83 flavour (automatic source address selection) for IPv6.
84
85config NFT_MASQ_IPV6
86 tristate "IPv6 masquerade support for nf_tables"
87 depends on NF_TABLES_IPV6
88 depends on NFT_MASQ
89 select NF_NAT_MASQUERADE_IPV6
90 help
91 This is the expression that provides IPv4 masquerading support for
92 nf_tables.
93
94endif # NF_NAT_IPV6
95
73config IP6_NF_IPTABLES 96config IP6_NF_IPTABLES
74 tristate "IP6 tables support (required for filtering)" 97 tristate "IP6 tables support (required for filtering)"
75 depends on INET && IPV6 98 depends on INET && IPV6
@@ -190,6 +213,7 @@ config IP6_NF_FILTER
190config IP6_NF_TARGET_REJECT 213config IP6_NF_TARGET_REJECT
191 tristate "REJECT target support" 214 tristate "REJECT target support"
192 depends on IP6_NF_FILTER 215 depends on IP6_NF_FILTER
216 select NF_REJECT_IPV6
193 default m if NETFILTER_ADVANCED=n 217 default m if NETFILTER_ADVANCED=n
194 help 218 help
195 The REJECT target allows a filtering rule to specify that an ICMPv6 219 The REJECT target allows a filtering rule to specify that an ICMPv6
@@ -260,6 +284,7 @@ if IP6_NF_NAT
260 284
261config IP6_NF_TARGET_MASQUERADE 285config IP6_NF_TARGET_MASQUERADE
262 tristate "MASQUERADE target support" 286 tristate "MASQUERADE target support"
287 select NF_NAT_MASQUERADE_IPV6
263 help 288 help
264 Masquerading is a special case of NAT: all outgoing connections are 289 Masquerading is a special case of NAT: all outgoing connections are
265 changed to seem to come from a particular interface's address, and 290 changed to seem to come from a particular interface's address, and
diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile
index c3d3286db4bb..fbb25f01143c 100644
--- a/net/ipv6/netfilter/Makefile
+++ b/net/ipv6/netfilter/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_NF_CONNTRACK_IPV6) += nf_conntrack_ipv6.o
18 18
19nf_nat_ipv6-y := nf_nat_l3proto_ipv6.o nf_nat_proto_icmpv6.o 19nf_nat_ipv6-y := nf_nat_l3proto_ipv6.o nf_nat_proto_icmpv6.o
20obj-$(CONFIG_NF_NAT_IPV6) += nf_nat_ipv6.o 20obj-$(CONFIG_NF_NAT_IPV6) += nf_nat_ipv6.o
21obj-$(CONFIG_NF_NAT_MASQUERADE_IPV6) += nf_nat_masquerade_ipv6.o
21 22
22# defrag 23# defrag
23nf_defrag_ipv6-y := nf_defrag_ipv6_hooks.o nf_conntrack_reasm.o 24nf_defrag_ipv6-y := nf_defrag_ipv6_hooks.o nf_conntrack_reasm.o
@@ -26,11 +27,15 @@ obj-$(CONFIG_NF_DEFRAG_IPV6) += nf_defrag_ipv6.o
26# logging 27# logging
27obj-$(CONFIG_NF_LOG_IPV6) += nf_log_ipv6.o 28obj-$(CONFIG_NF_LOG_IPV6) += nf_log_ipv6.o
28 29
30# reject
31obj-$(CONFIG_NF_REJECT_IPV6) += nf_reject_ipv6.o
32
29# nf_tables 33# nf_tables
30obj-$(CONFIG_NF_TABLES_IPV6) += nf_tables_ipv6.o 34obj-$(CONFIG_NF_TABLES_IPV6) += nf_tables_ipv6.o
31obj-$(CONFIG_NFT_CHAIN_ROUTE_IPV6) += nft_chain_route_ipv6.o 35obj-$(CONFIG_NFT_CHAIN_ROUTE_IPV6) += nft_chain_route_ipv6.o
32obj-$(CONFIG_NFT_CHAIN_NAT_IPV6) += nft_chain_nat_ipv6.o 36obj-$(CONFIG_NFT_CHAIN_NAT_IPV6) += nft_chain_nat_ipv6.o
33obj-$(CONFIG_NFT_REJECT_IPV6) += nft_reject_ipv6.o 37obj-$(CONFIG_NFT_REJECT_IPV6) += nft_reject_ipv6.o
38obj-$(CONFIG_NFT_MASQ_IPV6) += nft_masq_ipv6.o
34 39
35# matches 40# matches
36obj-$(CONFIG_IP6_NF_MATCH_AH) += ip6t_ah.o 41obj-$(CONFIG_IP6_NF_MATCH_AH) += ip6t_ah.o
diff --git a/net/ipv6/netfilter/ip6t_MASQUERADE.c b/net/ipv6/netfilter/ip6t_MASQUERADE.c
index 3e4e92d5e157..7f9f45d829d2 100644
--- a/net/ipv6/netfilter/ip6t_MASQUERADE.c
+++ b/net/ipv6/netfilter/ip6t_MASQUERADE.c
@@ -19,33 +19,12 @@
19#include <net/netfilter/nf_nat.h> 19#include <net/netfilter/nf_nat.h>
20#include <net/addrconf.h> 20#include <net/addrconf.h>
21#include <net/ipv6.h> 21#include <net/ipv6.h>
22#include <net/netfilter/ipv6/nf_nat_masquerade.h>
22 23
23static unsigned int 24static unsigned int
24masquerade_tg6(struct sk_buff *skb, const struct xt_action_param *par) 25masquerade_tg6(struct sk_buff *skb, const struct xt_action_param *par)
25{ 26{
26 const struct nf_nat_range *range = par->targinfo; 27 return nf_nat_masquerade_ipv6(skb, par->targinfo, par->out);
27 enum ip_conntrack_info ctinfo;
28 struct in6_addr src;
29 struct nf_conn *ct;
30 struct nf_nat_range newrange;
31
32 ct = nf_ct_get(skb, &ctinfo);
33 NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED ||
34 ctinfo == IP_CT_RELATED_REPLY));
35
36 if (ipv6_dev_get_saddr(dev_net(par->out), par->out,
37 &ipv6_hdr(skb)->daddr, 0, &src) < 0)
38 return NF_DROP;
39
40 nfct_nat(ct)->masq_index = par->out->ifindex;
41
42 newrange.flags = range->flags | NF_NAT_RANGE_MAP_IPS;
43 newrange.min_addr.in6 = src;
44 newrange.max_addr.in6 = src;
45 newrange.min_proto = range->min_proto;
46 newrange.max_proto = range->max_proto;
47
48 return nf_nat_setup_info(ct, &newrange, NF_NAT_MANIP_SRC);
49} 28}
50 29
51static int masquerade_tg6_checkentry(const struct xt_tgchk_param *par) 30static int masquerade_tg6_checkentry(const struct xt_tgchk_param *par)
@@ -57,48 +36,6 @@ static int masquerade_tg6_checkentry(const struct xt_tgchk_param *par)
57 return 0; 36 return 0;
58} 37}
59 38
60static int device_cmp(struct nf_conn *ct, void *ifindex)
61{
62 const struct nf_conn_nat *nat = nfct_nat(ct);
63
64 if (!nat)
65 return 0;
66 if (nf_ct_l3num(ct) != NFPROTO_IPV6)
67 return 0;
68 return nat->masq_index == (int)(long)ifindex;
69}
70
71static int masq_device_event(struct notifier_block *this,
72 unsigned long event, void *ptr)
73{
74 const struct net_device *dev = netdev_notifier_info_to_dev(ptr);
75 struct net *net = dev_net(dev);
76
77 if (event == NETDEV_DOWN)
78 nf_ct_iterate_cleanup(net, device_cmp,
79 (void *)(long)dev->ifindex, 0, 0);
80
81 return NOTIFY_DONE;
82}
83
84static struct notifier_block masq_dev_notifier = {
85 .notifier_call = masq_device_event,
86};
87
88static int masq_inet_event(struct notifier_block *this,
89 unsigned long event, void *ptr)
90{
91 struct inet6_ifaddr *ifa = ptr;
92 struct netdev_notifier_info info;
93
94 netdev_notifier_info_init(&info, ifa->idev->dev);
95 return masq_device_event(this, event, &info);
96}
97
98static struct notifier_block masq_inet_notifier = {
99 .notifier_call = masq_inet_event,
100};
101
102static struct xt_target masquerade_tg6_reg __read_mostly = { 39static struct xt_target masquerade_tg6_reg __read_mostly = {
103 .name = "MASQUERADE", 40 .name = "MASQUERADE",
104 .family = NFPROTO_IPV6, 41 .family = NFPROTO_IPV6,
@@ -115,17 +52,14 @@ static int __init masquerade_tg6_init(void)
115 int err; 52 int err;
116 53
117 err = xt_register_target(&masquerade_tg6_reg); 54 err = xt_register_target(&masquerade_tg6_reg);
118 if (err == 0) { 55 if (err == 0)
119 register_netdevice_notifier(&masq_dev_notifier); 56 nf_nat_masquerade_ipv6_register_notifier();
120 register_inet6addr_notifier(&masq_inet_notifier);
121 }
122 57
123 return err; 58 return err;
124} 59}
125static void __exit masquerade_tg6_exit(void) 60static void __exit masquerade_tg6_exit(void)
126{ 61{
127 unregister_inet6addr_notifier(&masq_inet_notifier); 62 nf_nat_masquerade_ipv6_unregister_notifier();
128 unregister_netdevice_notifier(&masq_dev_notifier);
129 xt_unregister_target(&masquerade_tg6_reg); 63 xt_unregister_target(&masquerade_tg6_reg);
130} 64}
131 65
diff --git a/net/ipv6/netfilter/ip6table_nat.c b/net/ipv6/netfilter/ip6table_nat.c
index 387d8b8fc18d..b0634ac996b7 100644
--- a/net/ipv6/netfilter/ip6table_nat.c
+++ b/net/ipv6/netfilter/ip6table_nat.c
@@ -30,222 +30,57 @@ static const struct xt_table nf_nat_ipv6_table = {
30 .af = NFPROTO_IPV6, 30 .af = NFPROTO_IPV6,
31}; 31};
32 32
33static unsigned int alloc_null_binding(struct nf_conn *ct, unsigned int hooknum) 33static unsigned int ip6table_nat_do_chain(const struct nf_hook_ops *ops,
34{ 34 struct sk_buff *skb,
35 /* Force range to this IP; let proto decide mapping for 35 const struct net_device *in,
36 * per-proto parts (hence not IP_NAT_RANGE_PROTO_SPECIFIED). 36 const struct net_device *out,
37 */ 37 struct nf_conn *ct)
38 struct nf_nat_range range;
39
40 range.flags = 0;
41 pr_debug("Allocating NULL binding for %p (%pI6)\n", ct,
42 HOOK2MANIP(hooknum) == NF_NAT_MANIP_SRC ?
43 &ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip6 :
44 &ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip6);
45
46 return nf_nat_setup_info(ct, &range, HOOK2MANIP(hooknum));
47}
48
49static unsigned int nf_nat_rule_find(struct sk_buff *skb, unsigned int hooknum,
50 const struct net_device *in,
51 const struct net_device *out,
52 struct nf_conn *ct)
53{ 38{
54 struct net *net = nf_ct_net(ct); 39 struct net *net = nf_ct_net(ct);
55 unsigned int ret;
56 40
57 ret = ip6t_do_table(skb, hooknum, in, out, net->ipv6.ip6table_nat); 41 return ip6t_do_table(skb, ops->hooknum, in, out, net->ipv6.ip6table_nat);
58 if (ret == NF_ACCEPT) {
59 if (!nf_nat_initialized(ct, HOOK2MANIP(hooknum)))
60 ret = alloc_null_binding(ct, hooknum);
61 }
62 return ret;
63} 42}
64 43
65static unsigned int 44static unsigned int ip6table_nat_fn(const struct nf_hook_ops *ops,
66nf_nat_ipv6_fn(const struct nf_hook_ops *ops, 45 struct sk_buff *skb,
67 struct sk_buff *skb, 46 const struct net_device *in,
68 const struct net_device *in, 47 const struct net_device *out,
69 const struct net_device *out, 48 int (*okfn)(struct sk_buff *))
70 int (*okfn)(struct sk_buff *))
71{ 49{
72 struct nf_conn *ct; 50 return nf_nat_ipv6_fn(ops, skb, in, out, ip6table_nat_do_chain);
73 enum ip_conntrack_info ctinfo;
74 struct nf_conn_nat *nat;
75 enum nf_nat_manip_type maniptype = HOOK2MANIP(ops->hooknum);
76 __be16 frag_off;
77 int hdrlen;
78 u8 nexthdr;
79
80 ct = nf_ct_get(skb, &ctinfo);
81 /* Can't track? It's not due to stress, or conntrack would
82 * have dropped it. Hence it's the user's responsibilty to
83 * packet filter it out, or implement conntrack/NAT for that
84 * protocol. 8) --RR
85 */
86 if (!ct)
87 return NF_ACCEPT;
88
89 /* Don't try to NAT if this packet is not conntracked */
90 if (nf_ct_is_untracked(ct))
91 return NF_ACCEPT;
92
93 nat = nf_ct_nat_ext_add(ct);
94 if (nat == NULL)
95 return NF_ACCEPT;
96
97 switch (ctinfo) {
98 case IP_CT_RELATED:
99 case IP_CT_RELATED_REPLY:
100 nexthdr = ipv6_hdr(skb)->nexthdr;
101 hdrlen = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr),
102 &nexthdr, &frag_off);
103
104 if (hdrlen >= 0 && nexthdr == IPPROTO_ICMPV6) {
105 if (!nf_nat_icmpv6_reply_translation(skb, ct, ctinfo,
106 ops->hooknum,
107 hdrlen))
108 return NF_DROP;
109 else
110 return NF_ACCEPT;
111 }
112 /* Fall thru... (Only ICMPs can be IP_CT_IS_REPLY) */
113 case IP_CT_NEW:
114 /* Seen it before? This can happen for loopback, retrans,
115 * or local packets.
116 */
117 if (!nf_nat_initialized(ct, maniptype)) {
118 unsigned int ret;
119
120 ret = nf_nat_rule_find(skb, ops->hooknum, in, out, ct);
121 if (ret != NF_ACCEPT)
122 return ret;
123 } else {
124 pr_debug("Already setup manip %s for ct %p\n",
125 maniptype == NF_NAT_MANIP_SRC ? "SRC" : "DST",
126 ct);
127 if (nf_nat_oif_changed(ops->hooknum, ctinfo, nat, out))
128 goto oif_changed;
129 }
130 break;
131
132 default:
133 /* ESTABLISHED */
134 NF_CT_ASSERT(ctinfo == IP_CT_ESTABLISHED ||
135 ctinfo == IP_CT_ESTABLISHED_REPLY);
136 if (nf_nat_oif_changed(ops->hooknum, ctinfo, nat, out))
137 goto oif_changed;
138 }
139
140 return nf_nat_packet(ct, ctinfo, ops->hooknum, skb);
141
142oif_changed:
143 nf_ct_kill_acct(ct, ctinfo, skb);
144 return NF_DROP;
145} 51}
146 52
147static unsigned int 53static unsigned int ip6table_nat_in(const struct nf_hook_ops *ops,
148nf_nat_ipv6_in(const struct nf_hook_ops *ops, 54 struct sk_buff *skb,
149 struct sk_buff *skb, 55 const struct net_device *in,
150 const struct net_device *in, 56 const struct net_device *out,
151 const struct net_device *out, 57 int (*okfn)(struct sk_buff *))
152 int (*okfn)(struct sk_buff *))
153{ 58{
154 unsigned int ret; 59 return nf_nat_ipv6_in(ops, skb, in, out, ip6table_nat_do_chain);
155 struct in6_addr daddr = ipv6_hdr(skb)->daddr;
156
157 ret = nf_nat_ipv6_fn(ops, skb, in, out, okfn);
158 if (ret != NF_DROP && ret != NF_STOLEN &&
159 ipv6_addr_cmp(&daddr, &ipv6_hdr(skb)->daddr))
160 skb_dst_drop(skb);
161
162 return ret;
163} 60}
164 61
165static unsigned int 62static unsigned int ip6table_nat_out(const struct nf_hook_ops *ops,
166nf_nat_ipv6_out(const struct nf_hook_ops *ops, 63 struct sk_buff *skb,
167 struct sk_buff *skb, 64 const struct net_device *in,
168 const struct net_device *in, 65 const struct net_device *out,
169 const struct net_device *out, 66 int (*okfn)(struct sk_buff *))
170 int (*okfn)(struct sk_buff *))
171{ 67{
172#ifdef CONFIG_XFRM 68 return nf_nat_ipv6_out(ops, skb, in, out, ip6table_nat_do_chain);
173 const struct nf_conn *ct;
174 enum ip_conntrack_info ctinfo;
175 int err;
176#endif
177 unsigned int ret;
178
179 /* root is playing with raw sockets. */
180 if (skb->len < sizeof(struct ipv6hdr))
181 return NF_ACCEPT;
182
183 ret = nf_nat_ipv6_fn(ops, skb, in, out, okfn);
184#ifdef CONFIG_XFRM
185 if (ret != NF_DROP && ret != NF_STOLEN &&
186 !(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) &&
187 (ct = nf_ct_get(skb, &ctinfo)) != NULL) {
188 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
189
190 if (!nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.src.u3,
191 &ct->tuplehash[!dir].tuple.dst.u3) ||
192 (ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMPV6 &&
193 ct->tuplehash[dir].tuple.src.u.all !=
194 ct->tuplehash[!dir].tuple.dst.u.all)) {
195 err = nf_xfrm_me_harder(skb, AF_INET6);
196 if (err < 0)
197 ret = NF_DROP_ERR(err);
198 }
199 }
200#endif
201 return ret;
202} 69}
203 70
204static unsigned int 71static unsigned int ip6table_nat_local_fn(const struct nf_hook_ops *ops,
205nf_nat_ipv6_local_fn(const struct nf_hook_ops *ops, 72 struct sk_buff *skb,
206 struct sk_buff *skb, 73 const struct net_device *in,
207 const struct net_device *in, 74 const struct net_device *out,
208 const struct net_device *out, 75 int (*okfn)(struct sk_buff *))
209 int (*okfn)(struct sk_buff *))
210{ 76{
211 const struct nf_conn *ct; 77 return nf_nat_ipv6_local_fn(ops, skb, in, out, ip6table_nat_do_chain);
212 enum ip_conntrack_info ctinfo;
213 unsigned int ret;
214 int err;
215
216 /* root is playing with raw sockets. */
217 if (skb->len < sizeof(struct ipv6hdr))
218 return NF_ACCEPT;
219
220 ret = nf_nat_ipv6_fn(ops, skb, in, out, okfn);
221 if (ret != NF_DROP && ret != NF_STOLEN &&
222 (ct = nf_ct_get(skb, &ctinfo)) != NULL) {
223 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
224
225 if (!nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.dst.u3,
226 &ct->tuplehash[!dir].tuple.src.u3)) {
227 err = ip6_route_me_harder(skb);
228 if (err < 0)
229 ret = NF_DROP_ERR(err);
230 }
231#ifdef CONFIG_XFRM
232 else if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) &&
233 ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMPV6 &&
234 ct->tuplehash[dir].tuple.dst.u.all !=
235 ct->tuplehash[!dir].tuple.src.u.all) {
236 err = nf_xfrm_me_harder(skb, AF_INET6);
237 if (err < 0)
238 ret = NF_DROP_ERR(err);
239 }
240#endif
241 }
242 return ret;
243} 78}
244 79
245static struct nf_hook_ops nf_nat_ipv6_ops[] __read_mostly = { 80static struct nf_hook_ops nf_nat_ipv6_ops[] __read_mostly = {
246 /* Before packet filtering, change destination */ 81 /* Before packet filtering, change destination */
247 { 82 {
248 .hook = nf_nat_ipv6_in, 83 .hook = ip6table_nat_in,
249 .owner = THIS_MODULE, 84 .owner = THIS_MODULE,
250 .pf = NFPROTO_IPV6, 85 .pf = NFPROTO_IPV6,
251 .hooknum = NF_INET_PRE_ROUTING, 86 .hooknum = NF_INET_PRE_ROUTING,
@@ -253,7 +88,7 @@ static struct nf_hook_ops nf_nat_ipv6_ops[] __read_mostly = {
253 }, 88 },
254 /* After packet filtering, change source */ 89 /* After packet filtering, change source */
255 { 90 {
256 .hook = nf_nat_ipv6_out, 91 .hook = ip6table_nat_out,
257 .owner = THIS_MODULE, 92 .owner = THIS_MODULE,
258 .pf = NFPROTO_IPV6, 93 .pf = NFPROTO_IPV6,
259 .hooknum = NF_INET_POST_ROUTING, 94 .hooknum = NF_INET_POST_ROUTING,
@@ -261,7 +96,7 @@ static struct nf_hook_ops nf_nat_ipv6_ops[] __read_mostly = {
261 }, 96 },
262 /* Before packet filtering, change destination */ 97 /* Before packet filtering, change destination */
263 { 98 {
264 .hook = nf_nat_ipv6_local_fn, 99 .hook = ip6table_nat_local_fn,
265 .owner = THIS_MODULE, 100 .owner = THIS_MODULE,
266 .pf = NFPROTO_IPV6, 101 .pf = NFPROTO_IPV6,
267 .hooknum = NF_INET_LOCAL_OUT, 102 .hooknum = NF_INET_LOCAL_OUT,
@@ -269,7 +104,7 @@ static struct nf_hook_ops nf_nat_ipv6_ops[] __read_mostly = {
269 }, 104 },
270 /* After packet filtering, change source */ 105 /* After packet filtering, change source */
271 { 106 {
272 .hook = nf_nat_ipv6_fn, 107 .hook = ip6table_nat_fn,
273 .owner = THIS_MODULE, 108 .owner = THIS_MODULE,
274 .pf = NFPROTO_IPV6, 109 .pf = NFPROTO_IPV6,
275 .hooknum = NF_INET_LOCAL_IN, 110 .hooknum = NF_INET_LOCAL_IN,
diff --git a/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
index 7b9a748c6bac..e70382e4dfb5 100644
--- a/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
+++ b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
@@ -40,7 +40,7 @@ static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum,
40 zone = nf_ct_zone((struct nf_conn *)skb->nfct); 40 zone = nf_ct_zone((struct nf_conn *)skb->nfct);
41#endif 41#endif
42 42
43#ifdef CONFIG_BRIDGE_NETFILTER 43#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
44 if (skb->nf_bridge && 44 if (skb->nf_bridge &&
45 skb->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING) 45 skb->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING)
46 return IP6_DEFRAG_CONNTRACK_BRIDGE_IN + zone; 46 return IP6_DEFRAG_CONNTRACK_BRIDGE_IN + zone;
diff --git a/net/ipv6/netfilter/nf_nat_l3proto_ipv6.c b/net/ipv6/netfilter/nf_nat_l3proto_ipv6.c
index fc8e49b2ff3e..c5812e1c1ffb 100644
--- a/net/ipv6/netfilter/nf_nat_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_nat_l3proto_ipv6.c
@@ -261,6 +261,205 @@ int nf_nat_icmpv6_reply_translation(struct sk_buff *skb,
261} 261}
262EXPORT_SYMBOL_GPL(nf_nat_icmpv6_reply_translation); 262EXPORT_SYMBOL_GPL(nf_nat_icmpv6_reply_translation);
263 263
264unsigned int
265nf_nat_ipv6_fn(const struct nf_hook_ops *ops, struct sk_buff *skb,
266 const struct net_device *in, const struct net_device *out,
267 unsigned int (*do_chain)(const struct nf_hook_ops *ops,
268 struct sk_buff *skb,
269 const struct net_device *in,
270 const struct net_device *out,
271 struct nf_conn *ct))
272{
273 struct nf_conn *ct;
274 enum ip_conntrack_info ctinfo;
275 struct nf_conn_nat *nat;
276 enum nf_nat_manip_type maniptype = HOOK2MANIP(ops->hooknum);
277 __be16 frag_off;
278 int hdrlen;
279 u8 nexthdr;
280
281 ct = nf_ct_get(skb, &ctinfo);
282 /* Can't track? It's not due to stress, or conntrack would
283 * have dropped it. Hence it's the user's responsibilty to
284 * packet filter it out, or implement conntrack/NAT for that
285 * protocol. 8) --RR
286 */
287 if (!ct)
288 return NF_ACCEPT;
289
290 /* Don't try to NAT if this packet is not conntracked */
291 if (nf_ct_is_untracked(ct))
292 return NF_ACCEPT;
293
294 nat = nf_ct_nat_ext_add(ct);
295 if (nat == NULL)
296 return NF_ACCEPT;
297
298 switch (ctinfo) {
299 case IP_CT_RELATED:
300 case IP_CT_RELATED_REPLY:
301 nexthdr = ipv6_hdr(skb)->nexthdr;
302 hdrlen = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr),
303 &nexthdr, &frag_off);
304
305 if (hdrlen >= 0 && nexthdr == IPPROTO_ICMPV6) {
306 if (!nf_nat_icmpv6_reply_translation(skb, ct, ctinfo,
307 ops->hooknum,
308 hdrlen))
309 return NF_DROP;
310 else
311 return NF_ACCEPT;
312 }
313 /* Fall thru... (Only ICMPs can be IP_CT_IS_REPLY) */
314 case IP_CT_NEW:
315 /* Seen it before? This can happen for loopback, retrans,
316 * or local packets.
317 */
318 if (!nf_nat_initialized(ct, maniptype)) {
319 unsigned int ret;
320
321 ret = do_chain(ops, skb, in, out, ct);
322 if (ret != NF_ACCEPT)
323 return ret;
324
325 if (nf_nat_initialized(ct, HOOK2MANIP(ops->hooknum)))
326 break;
327
328 ret = nf_nat_alloc_null_binding(ct, ops->hooknum);
329 if (ret != NF_ACCEPT)
330 return ret;
331 } else {
332 pr_debug("Already setup manip %s for ct %p\n",
333 maniptype == NF_NAT_MANIP_SRC ? "SRC" : "DST",
334 ct);
335 if (nf_nat_oif_changed(ops->hooknum, ctinfo, nat, out))
336 goto oif_changed;
337 }
338 break;
339
340 default:
341 /* ESTABLISHED */
342 NF_CT_ASSERT(ctinfo == IP_CT_ESTABLISHED ||
343 ctinfo == IP_CT_ESTABLISHED_REPLY);
344 if (nf_nat_oif_changed(ops->hooknum, ctinfo, nat, out))
345 goto oif_changed;
346 }
347
348 return nf_nat_packet(ct, ctinfo, ops->hooknum, skb);
349
350oif_changed:
351 nf_ct_kill_acct(ct, ctinfo, skb);
352 return NF_DROP;
353}
354EXPORT_SYMBOL_GPL(nf_nat_ipv6_fn);
355
356unsigned int
357nf_nat_ipv6_in(const struct nf_hook_ops *ops, struct sk_buff *skb,
358 const struct net_device *in, const struct net_device *out,
359 unsigned int (*do_chain)(const struct nf_hook_ops *ops,
360 struct sk_buff *skb,
361 const struct net_device *in,
362 const struct net_device *out,
363 struct nf_conn *ct))
364{
365 unsigned int ret;
366 struct in6_addr daddr = ipv6_hdr(skb)->daddr;
367
368 ret = nf_nat_ipv6_fn(ops, skb, in, out, do_chain);
369 if (ret != NF_DROP && ret != NF_STOLEN &&
370 ipv6_addr_cmp(&daddr, &ipv6_hdr(skb)->daddr))
371 skb_dst_drop(skb);
372
373 return ret;
374}
375EXPORT_SYMBOL_GPL(nf_nat_ipv6_in);
376
377unsigned int
378nf_nat_ipv6_out(const struct nf_hook_ops *ops, struct sk_buff *skb,
379 const struct net_device *in, const struct net_device *out,
380 unsigned int (*do_chain)(const struct nf_hook_ops *ops,
381 struct sk_buff *skb,
382 const struct net_device *in,
383 const struct net_device *out,
384 struct nf_conn *ct))
385{
386#ifdef CONFIG_XFRM
387 const struct nf_conn *ct;
388 enum ip_conntrack_info ctinfo;
389 int err;
390#endif
391 unsigned int ret;
392
393 /* root is playing with raw sockets. */
394 if (skb->len < sizeof(struct ipv6hdr))
395 return NF_ACCEPT;
396
397 ret = nf_nat_ipv6_fn(ops, skb, in, out, do_chain);
398#ifdef CONFIG_XFRM
399 if (ret != NF_DROP && ret != NF_STOLEN &&
400 !(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) &&
401 (ct = nf_ct_get(skb, &ctinfo)) != NULL) {
402 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
403
404 if (!nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.src.u3,
405 &ct->tuplehash[!dir].tuple.dst.u3) ||
406 (ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMPV6 &&
407 ct->tuplehash[dir].tuple.src.u.all !=
408 ct->tuplehash[!dir].tuple.dst.u.all)) {
409 err = nf_xfrm_me_harder(skb, AF_INET6);
410 if (err < 0)
411 ret = NF_DROP_ERR(err);
412 }
413 }
414#endif
415 return ret;
416}
417EXPORT_SYMBOL_GPL(nf_nat_ipv6_out);
418
419unsigned int
420nf_nat_ipv6_local_fn(const struct nf_hook_ops *ops, struct sk_buff *skb,
421 const struct net_device *in, const struct net_device *out,
422 unsigned int (*do_chain)(const struct nf_hook_ops *ops,
423 struct sk_buff *skb,
424 const struct net_device *in,
425 const struct net_device *out,
426 struct nf_conn *ct))
427{
428 const struct nf_conn *ct;
429 enum ip_conntrack_info ctinfo;
430 unsigned int ret;
431 int err;
432
433 /* root is playing with raw sockets. */
434 if (skb->len < sizeof(struct ipv6hdr))
435 return NF_ACCEPT;
436
437 ret = nf_nat_ipv6_fn(ops, skb, in, out, do_chain);
438 if (ret != NF_DROP && ret != NF_STOLEN &&
439 (ct = nf_ct_get(skb, &ctinfo)) != NULL) {
440 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
441
442 if (!nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.dst.u3,
443 &ct->tuplehash[!dir].tuple.src.u3)) {
444 err = ip6_route_me_harder(skb);
445 if (err < 0)
446 ret = NF_DROP_ERR(err);
447 }
448#ifdef CONFIG_XFRM
449 else if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) &&
450 ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMPV6 &&
451 ct->tuplehash[dir].tuple.dst.u.all !=
452 ct->tuplehash[!dir].tuple.src.u.all) {
453 err = nf_xfrm_me_harder(skb, AF_INET6);
454 if (err < 0)
455 ret = NF_DROP_ERR(err);
456 }
457#endif
458 }
459 return ret;
460}
461EXPORT_SYMBOL_GPL(nf_nat_ipv6_local_fn);
462
264static int __init nf_nat_l3proto_ipv6_init(void) 463static int __init nf_nat_l3proto_ipv6_init(void)
265{ 464{
266 int err; 465 int err;
diff --git a/net/ipv6/netfilter/nf_nat_masquerade_ipv6.c b/net/ipv6/netfilter/nf_nat_masquerade_ipv6.c
new file mode 100644
index 000000000000..7745609665cd
--- /dev/null
+++ b/net/ipv6/netfilter/nf_nat_masquerade_ipv6.c
@@ -0,0 +1,120 @@
1/*
2 * Copyright (c) 2011 Patrick McHardy <kaber@trash.net>
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 * Based on Rusty Russell's IPv6 MASQUERADE target. Development of IPv6
9 * NAT funded by Astaro.
10 */
11
12#include <linux/kernel.h>
13#include <linux/module.h>
14#include <linux/atomic.h>
15#include <linux/netdevice.h>
16#include <linux/ipv6.h>
17#include <linux/netfilter.h>
18#include <linux/netfilter_ipv6.h>
19#include <net/netfilter/nf_nat.h>
20#include <net/addrconf.h>
21#include <net/ipv6.h>
22#include <net/netfilter/ipv6/nf_nat_masquerade.h>
23
24unsigned int
25nf_nat_masquerade_ipv6(struct sk_buff *skb, const struct nf_nat_range *range,
26 const struct net_device *out)
27{
28 enum ip_conntrack_info ctinfo;
29 struct in6_addr src;
30 struct nf_conn *ct;
31 struct nf_nat_range newrange;
32
33 ct = nf_ct_get(skb, &ctinfo);
34 NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED ||
35 ctinfo == IP_CT_RELATED_REPLY));
36
37 if (ipv6_dev_get_saddr(dev_net(out), out,
38 &ipv6_hdr(skb)->daddr, 0, &src) < 0)
39 return NF_DROP;
40
41 nfct_nat(ct)->masq_index = out->ifindex;
42
43 newrange.flags = range->flags | NF_NAT_RANGE_MAP_IPS;
44 newrange.min_addr.in6 = src;
45 newrange.max_addr.in6 = src;
46 newrange.min_proto = range->min_proto;
47 newrange.max_proto = range->max_proto;
48
49 return nf_nat_setup_info(ct, &newrange, NF_NAT_MANIP_SRC);
50}
51EXPORT_SYMBOL_GPL(nf_nat_masquerade_ipv6);
52
53static int device_cmp(struct nf_conn *ct, void *ifindex)
54{
55 const struct nf_conn_nat *nat = nfct_nat(ct);
56
57 if (!nat)
58 return 0;
59 if (nf_ct_l3num(ct) != NFPROTO_IPV6)
60 return 0;
61 return nat->masq_index == (int)(long)ifindex;
62}
63
64static int masq_device_event(struct notifier_block *this,
65 unsigned long event, void *ptr)
66{
67 const struct net_device *dev = netdev_notifier_info_to_dev(ptr);
68 struct net *net = dev_net(dev);
69
70 if (event == NETDEV_DOWN)
71 nf_ct_iterate_cleanup(net, device_cmp,
72 (void *)(long)dev->ifindex, 0, 0);
73
74 return NOTIFY_DONE;
75}
76
77static struct notifier_block masq_dev_notifier = {
78 .notifier_call = masq_device_event,
79};
80
81static int masq_inet_event(struct notifier_block *this,
82 unsigned long event, void *ptr)
83{
84 struct inet6_ifaddr *ifa = ptr;
85 struct netdev_notifier_info info;
86
87 netdev_notifier_info_init(&info, ifa->idev->dev);
88 return masq_device_event(this, event, &info);
89}
90
91static struct notifier_block masq_inet_notifier = {
92 .notifier_call = masq_inet_event,
93};
94
95static atomic_t masquerade_notifier_refcount = ATOMIC_INIT(0);
96
97void nf_nat_masquerade_ipv6_register_notifier(void)
98{
99 /* check if the notifier is already set */
100 if (atomic_inc_return(&masquerade_notifier_refcount) > 1)
101 return;
102
103 register_netdevice_notifier(&masq_dev_notifier);
104 register_inet6addr_notifier(&masq_inet_notifier);
105}
106EXPORT_SYMBOL_GPL(nf_nat_masquerade_ipv6_register_notifier);
107
108void nf_nat_masquerade_ipv6_unregister_notifier(void)
109{
110 /* check if the notifier still has clients */
111 if (atomic_dec_return(&masquerade_notifier_refcount) > 0)
112 return;
113
114 unregister_inet6addr_notifier(&masq_inet_notifier);
115 unregister_netdevice_notifier(&masq_dev_notifier);
116}
117EXPORT_SYMBOL_GPL(nf_nat_masquerade_ipv6_unregister_notifier);
118
119MODULE_LICENSE("GPL");
120MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
diff --git a/net/ipv6/netfilter/nf_reject_ipv6.c b/net/ipv6/netfilter/nf_reject_ipv6.c
new file mode 100644
index 000000000000..5f5f0438d74d
--- /dev/null
+++ b/net/ipv6/netfilter/nf_reject_ipv6.c
@@ -0,0 +1,163 @@
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#include <net/ipv6.h>
9#include <net/ip6_route.h>
10#include <net/ip6_fib.h>
11#include <net/ip6_checksum.h>
12#include <linux/netfilter_ipv6.h>
13
14void nf_send_reset6(struct net *net, struct sk_buff *oldskb, int hook)
15{
16 struct sk_buff *nskb;
17 struct tcphdr otcph, *tcph;
18 unsigned int otcplen, hh_len;
19 int tcphoff, needs_ack;
20 const struct ipv6hdr *oip6h = ipv6_hdr(oldskb);
21 struct ipv6hdr *ip6h;
22#define DEFAULT_TOS_VALUE 0x0U
23 const __u8 tclass = DEFAULT_TOS_VALUE;
24 struct dst_entry *dst = NULL;
25 u8 proto;
26 __be16 frag_off;
27 struct flowi6 fl6;
28
29 if ((!(ipv6_addr_type(&oip6h->saddr) & IPV6_ADDR_UNICAST)) ||
30 (!(ipv6_addr_type(&oip6h->daddr) & IPV6_ADDR_UNICAST))) {
31 pr_debug("addr is not unicast.\n");
32 return;
33 }
34
35 proto = oip6h->nexthdr;
36 tcphoff = ipv6_skip_exthdr(oldskb, ((u8*)(oip6h+1) - oldskb->data), &proto, &frag_off);
37
38 if ((tcphoff < 0) || (tcphoff > oldskb->len)) {
39 pr_debug("Cannot get TCP header.\n");
40 return;
41 }
42
43 otcplen = oldskb->len - tcphoff;
44
45 /* IP header checks: fragment, too short. */
46 if (proto != IPPROTO_TCP || otcplen < sizeof(struct tcphdr)) {
47 pr_debug("proto(%d) != IPPROTO_TCP, "
48 "or too short. otcplen = %d\n",
49 proto, otcplen);
50 return;
51 }
52
53 if (skb_copy_bits(oldskb, tcphoff, &otcph, sizeof(struct tcphdr)))
54 BUG();
55
56 /* No RST for RST. */
57 if (otcph.rst) {
58 pr_debug("RST is set\n");
59 return;
60 }
61
62 /* Check checksum. */
63 if (nf_ip6_checksum(oldskb, hook, tcphoff, IPPROTO_TCP)) {
64 pr_debug("TCP checksum is invalid\n");
65 return;
66 }
67
68 memset(&fl6, 0, sizeof(fl6));
69 fl6.flowi6_proto = IPPROTO_TCP;
70 fl6.saddr = oip6h->daddr;
71 fl6.daddr = oip6h->saddr;
72 fl6.fl6_sport = otcph.dest;
73 fl6.fl6_dport = otcph.source;
74 security_skb_classify_flow(oldskb, flowi6_to_flowi(&fl6));
75 dst = ip6_route_output(net, NULL, &fl6);
76 if (dst == NULL || dst->error) {
77 dst_release(dst);
78 return;
79 }
80 dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0);
81 if (IS_ERR(dst))
82 return;
83
84 hh_len = (dst->dev->hard_header_len + 15)&~15;
85 nskb = alloc_skb(hh_len + 15 + dst->header_len + sizeof(struct ipv6hdr)
86 + sizeof(struct tcphdr) + dst->trailer_len,
87 GFP_ATOMIC);
88
89 if (!nskb) {
90 net_dbg_ratelimited("cannot alloc skb\n");
91 dst_release(dst);
92 return;
93 }
94
95 skb_dst_set(nskb, dst);
96
97 skb_reserve(nskb, hh_len + dst->header_len);
98
99 skb_put(nskb, sizeof(struct ipv6hdr));
100 skb_reset_network_header(nskb);
101 ip6h = ipv6_hdr(nskb);
102 ip6_flow_hdr(ip6h, tclass, 0);
103 ip6h->hop_limit = ip6_dst_hoplimit(dst);
104 ip6h->nexthdr = IPPROTO_TCP;
105 ip6h->saddr = oip6h->daddr;
106 ip6h->daddr = oip6h->saddr;
107
108 skb_reset_transport_header(nskb);
109 tcph = (struct tcphdr *)skb_put(nskb, sizeof(struct tcphdr));
110 /* Truncate to length (no data) */
111 tcph->doff = sizeof(struct tcphdr)/4;
112 tcph->source = otcph.dest;
113 tcph->dest = otcph.source;
114
115 if (otcph.ack) {
116 needs_ack = 0;
117 tcph->seq = otcph.ack_seq;
118 tcph->ack_seq = 0;
119 } else {
120 needs_ack = 1;
121 tcph->ack_seq = htonl(ntohl(otcph.seq) + otcph.syn + otcph.fin
122 + otcplen - (otcph.doff<<2));
123 tcph->seq = 0;
124 }
125
126 /* Reset flags */
127 ((u_int8_t *)tcph)[13] = 0;
128 tcph->rst = 1;
129 tcph->ack = needs_ack;
130 tcph->window = 0;
131 tcph->urg_ptr = 0;
132 tcph->check = 0;
133
134 /* Adjust TCP checksum */
135 tcph->check = csum_ipv6_magic(&ipv6_hdr(nskb)->saddr,
136 &ipv6_hdr(nskb)->daddr,
137 sizeof(struct tcphdr), IPPROTO_TCP,
138 csum_partial(tcph,
139 sizeof(struct tcphdr), 0));
140
141 nf_ct_attach(nskb, oldskb);
142
143#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
144 /* If we use ip6_local_out for bridged traffic, the MAC source on
145 * the RST will be ours, instead of the destination's. This confuses
146 * some routers/firewalls, and they drop the packet. So we need to
147 * build the eth header using the original destination's MAC as the
148 * source, and send the RST packet directly.
149 */
150 if (oldskb->nf_bridge) {
151 struct ethhdr *oeth = eth_hdr(oldskb);
152 nskb->dev = oldskb->nf_bridge->physindev;
153 nskb->protocol = htons(ETH_P_IPV6);
154 ip6h->payload_len = htons(sizeof(struct tcphdr));
155 if (dev_hard_header(nskb, nskb->dev, ntohs(nskb->protocol),
156 oeth->h_source, oeth->h_dest, nskb->len) < 0)
157 return;
158 dev_queue_xmit(nskb);
159 } else
160#endif
161 ip6_local_out(nskb);
162}
163EXPORT_SYMBOL_GPL(nf_send_reset6);
diff --git a/net/ipv6/netfilter/nft_chain_nat_ipv6.c b/net/ipv6/netfilter/nft_chain_nat_ipv6.c
index d189fcb437fe..1c4b75dd425b 100644
--- a/net/ipv6/netfilter/nft_chain_nat_ipv6.c
+++ b/net/ipv6/netfilter/nft_chain_nat_ipv6.c
@@ -24,144 +24,53 @@
24#include <net/netfilter/nf_nat_l3proto.h> 24#include <net/netfilter/nf_nat_l3proto.h>
25#include <net/ipv6.h> 25#include <net/ipv6.h>
26 26
27/* 27static unsigned int nft_nat_do_chain(const struct nf_hook_ops *ops,
28 * IPv6 NAT chains 28 struct sk_buff *skb,
29 */ 29 const struct net_device *in,
30 30 const struct net_device *out,
31static unsigned int nf_nat_ipv6_fn(const struct nf_hook_ops *ops, 31 struct nf_conn *ct)
32 struct sk_buff *skb,
33 const struct net_device *in,
34 const struct net_device *out,
35 int (*okfn)(struct sk_buff *))
36{ 32{
37 enum ip_conntrack_info ctinfo;
38 struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
39 struct nf_conn_nat *nat;
40 enum nf_nat_manip_type maniptype = HOOK2MANIP(ops->hooknum);
41 __be16 frag_off;
42 int hdrlen;
43 u8 nexthdr;
44 struct nft_pktinfo pkt; 33 struct nft_pktinfo pkt;
45 unsigned int ret;
46
47 if (ct == NULL || nf_ct_is_untracked(ct))
48 return NF_ACCEPT;
49
50 nat = nf_ct_nat_ext_add(ct);
51 if (nat == NULL)
52 return NF_ACCEPT;
53
54 switch (ctinfo) {
55 case IP_CT_RELATED:
56 case IP_CT_RELATED + IP_CT_IS_REPLY:
57 nexthdr = ipv6_hdr(skb)->nexthdr;
58 hdrlen = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr),
59 &nexthdr, &frag_off);
60
61 if (hdrlen >= 0 && nexthdr == IPPROTO_ICMPV6) {
62 if (!nf_nat_icmpv6_reply_translation(skb, ct, ctinfo,
63 ops->hooknum,
64 hdrlen))
65 return NF_DROP;
66 else
67 return NF_ACCEPT;
68 }
69 /* Fall through */
70 case IP_CT_NEW:
71 if (nf_nat_initialized(ct, maniptype))
72 break;
73
74 nft_set_pktinfo_ipv6(&pkt, ops, skb, in, out);
75 34
76 ret = nft_do_chain(&pkt, ops); 35 nft_set_pktinfo_ipv6(&pkt, ops, skb, in, out);
77 if (ret != NF_ACCEPT)
78 return ret;
79 if (!nf_nat_initialized(ct, maniptype)) {
80 ret = nf_nat_alloc_null_binding(ct, ops->hooknum);
81 if (ret != NF_ACCEPT)
82 return ret;
83 }
84 default:
85 break;
86 }
87 36
88 return nf_nat_packet(ct, ctinfo, ops->hooknum, skb); 37 return nft_do_chain(&pkt, ops);
89} 38}
90 39
91static unsigned int nf_nat_ipv6_prerouting(const struct nf_hook_ops *ops, 40static unsigned int nft_nat_ipv6_fn(const struct nf_hook_ops *ops,
92 struct sk_buff *skb, 41 struct sk_buff *skb,
93 const struct net_device *in, 42 const struct net_device *in,
94 const struct net_device *out, 43 const struct net_device *out,
95 int (*okfn)(struct sk_buff *)) 44 int (*okfn)(struct sk_buff *))
96{ 45{
97 struct in6_addr daddr = ipv6_hdr(skb)->daddr; 46 return nf_nat_ipv6_fn(ops, skb, in, out, nft_nat_do_chain);
98 unsigned int ret;
99
100 ret = nf_nat_ipv6_fn(ops, skb, in, out, okfn);
101 if (ret != NF_DROP && ret != NF_STOLEN &&
102 ipv6_addr_cmp(&daddr, &ipv6_hdr(skb)->daddr))
103 skb_dst_drop(skb);
104
105 return ret;
106} 47}
107 48
108static unsigned int nf_nat_ipv6_postrouting(const struct nf_hook_ops *ops, 49static unsigned int nft_nat_ipv6_in(const struct nf_hook_ops *ops,
109 struct sk_buff *skb, 50 struct sk_buff *skb,
110 const struct net_device *in, 51 const struct net_device *in,
111 const struct net_device *out, 52 const struct net_device *out,
112 int (*okfn)(struct sk_buff *)) 53 int (*okfn)(struct sk_buff *))
113{ 54{
114 enum ip_conntrack_info ctinfo __maybe_unused; 55 return nf_nat_ipv6_in(ops, skb, in, out, nft_nat_do_chain);
115 const struct nf_conn *ct __maybe_unused;
116 unsigned int ret;
117
118 ret = nf_nat_ipv6_fn(ops, skb, in, out, okfn);
119#ifdef CONFIG_XFRM
120 if (ret != NF_DROP && ret != NF_STOLEN &&
121 !(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) &&
122 (ct = nf_ct_get(skb, &ctinfo)) != NULL) {
123 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
124
125 if (!nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.src.u3,
126 &ct->tuplehash[!dir].tuple.dst.u3) ||
127 (ct->tuplehash[dir].tuple.src.u.all !=
128 ct->tuplehash[!dir].tuple.dst.u.all))
129 if (nf_xfrm_me_harder(skb, AF_INET6) < 0)
130 ret = NF_DROP;
131 }
132#endif
133 return ret;
134} 56}
135 57
136static unsigned int nf_nat_ipv6_output(const struct nf_hook_ops *ops, 58static unsigned int nft_nat_ipv6_out(const struct nf_hook_ops *ops,
137 struct sk_buff *skb, 59 struct sk_buff *skb,
138 const struct net_device *in, 60 const struct net_device *in,
139 const struct net_device *out, 61 const struct net_device *out,
140 int (*okfn)(struct sk_buff *)) 62 int (*okfn)(struct sk_buff *))
141{ 63{
142 enum ip_conntrack_info ctinfo; 64 return nf_nat_ipv6_out(ops, skb, in, out, nft_nat_do_chain);
143 const struct nf_conn *ct; 65}
144 unsigned int ret;
145
146 ret = nf_nat_ipv6_fn(ops, skb, in, out, okfn);
147 if (ret != NF_DROP && ret != NF_STOLEN &&
148 (ct = nf_ct_get(skb, &ctinfo)) != NULL) {
149 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
150 66
151 if (!nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.dst.u3, 67static unsigned int nft_nat_ipv6_local_fn(const struct nf_hook_ops *ops,
152 &ct->tuplehash[!dir].tuple.src.u3)) { 68 struct sk_buff *skb,
153 if (ip6_route_me_harder(skb)) 69 const struct net_device *in,
154 ret = NF_DROP; 70 const struct net_device *out,
155 } 71 int (*okfn)(struct sk_buff *))
156#ifdef CONFIG_XFRM 72{
157 else if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) && 73 return nf_nat_ipv6_local_fn(ops, skb, in, out, nft_nat_do_chain);
158 ct->tuplehash[dir].tuple.dst.u.all !=
159 ct->tuplehash[!dir].tuple.src.u.all)
160 if (nf_xfrm_me_harder(skb, AF_INET6))
161 ret = NF_DROP;
162#endif
163 }
164 return ret;
165} 74}
166 75
167static const struct nf_chain_type nft_chain_nat_ipv6 = { 76static const struct nf_chain_type nft_chain_nat_ipv6 = {
@@ -174,10 +83,10 @@ static const struct nf_chain_type nft_chain_nat_ipv6 = {
174 (1 << NF_INET_LOCAL_OUT) | 83 (1 << NF_INET_LOCAL_OUT) |
175 (1 << NF_INET_LOCAL_IN), 84 (1 << NF_INET_LOCAL_IN),
176 .hooks = { 85 .hooks = {
177 [NF_INET_PRE_ROUTING] = nf_nat_ipv6_prerouting, 86 [NF_INET_PRE_ROUTING] = nft_nat_ipv6_in,
178 [NF_INET_POST_ROUTING] = nf_nat_ipv6_postrouting, 87 [NF_INET_POST_ROUTING] = nft_nat_ipv6_out,
179 [NF_INET_LOCAL_OUT] = nf_nat_ipv6_output, 88 [NF_INET_LOCAL_OUT] = nft_nat_ipv6_local_fn,
180 [NF_INET_LOCAL_IN] = nf_nat_ipv6_fn, 89 [NF_INET_LOCAL_IN] = nft_nat_ipv6_fn,
181 }, 90 },
182}; 91};
183 92
diff --git a/net/ipv6/netfilter/nft_masq_ipv6.c b/net/ipv6/netfilter/nft_masq_ipv6.c
new file mode 100644
index 000000000000..556262f40761
--- /dev/null
+++ b/net/ipv6/netfilter/nft_masq_ipv6.c
@@ -0,0 +1,77 @@
1/*
2 * Copyright (c) 2014 Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
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/kernel.h>
10#include <linux/init.h>
11#include <linux/module.h>
12#include <linux/netlink.h>
13#include <linux/netfilter.h>
14#include <linux/netfilter/nf_tables.h>
15#include <net/netfilter/nf_tables.h>
16#include <net/netfilter/nf_nat.h>
17#include <net/netfilter/nft_masq.h>
18#include <net/netfilter/ipv6/nf_nat_masquerade.h>
19
20static void nft_masq_ipv6_eval(const struct nft_expr *expr,
21 struct nft_data data[NFT_REG_MAX + 1],
22 const struct nft_pktinfo *pkt)
23{
24 struct nft_masq *priv = nft_expr_priv(expr);
25 struct nf_nat_range range;
26 unsigned int verdict;
27
28 range.flags = priv->flags;
29
30 verdict = nf_nat_masquerade_ipv6(pkt->skb, &range, pkt->out);
31
32 data[NFT_REG_VERDICT].verdict = verdict;
33}
34
35static struct nft_expr_type nft_masq_ipv6_type;
36static const struct nft_expr_ops nft_masq_ipv6_ops = {
37 .type = &nft_masq_ipv6_type,
38 .size = NFT_EXPR_SIZE(sizeof(struct nft_masq)),
39 .eval = nft_masq_ipv6_eval,
40 .init = nft_masq_init,
41 .dump = nft_masq_dump,
42};
43
44static struct nft_expr_type nft_masq_ipv6_type __read_mostly = {
45 .family = NFPROTO_IPV6,
46 .name = "masq",
47 .ops = &nft_masq_ipv6_ops,
48 .policy = nft_masq_policy,
49 .maxattr = NFTA_MASQ_MAX,
50 .owner = THIS_MODULE,
51};
52
53static int __init nft_masq_ipv6_module_init(void)
54{
55 int ret;
56
57 ret = nft_register_expr(&nft_masq_ipv6_type);
58 if (ret < 0)
59 return ret;
60
61 nf_nat_masquerade_ipv6_register_notifier();
62
63 return ret;
64}
65
66static void __exit nft_masq_ipv6_module_exit(void)
67{
68 nft_unregister_expr(&nft_masq_ipv6_type);
69 nf_nat_masquerade_ipv6_unregister_notifier();
70}
71
72module_init(nft_masq_ipv6_module_init);
73module_exit(nft_masq_ipv6_module_exit);
74
75MODULE_LICENSE("GPL");
76MODULE_AUTHOR("Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>");
77MODULE_ALIAS_NFT_AF_EXPR(AF_INET6, "masq");
diff --git a/net/ipv6/output_core.c b/net/ipv6/output_core.c
index 5ec867e4a8b7..fc24c390af05 100644
--- a/net/ipv6/output_core.c
+++ b/net/ipv6/output_core.c
@@ -35,7 +35,7 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
35 if (found_rhdr) 35 if (found_rhdr)
36 return offset; 36 return offset;
37 break; 37 break;
38 default : 38 default:
39 return offset; 39 return offset;
40 } 40 }
41 41
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c
index 2d6f860e5c1e..1752cd0b4882 100644
--- a/net/ipv6/proc.c
+++ b/net/ipv6/proc.c
@@ -8,7 +8,7 @@
8 * except it reports the sockets in the INET6 address family. 8 * except it reports the sockets in the INET6 address family.
9 * 9 *
10 * Authors: David S. Miller (davem@caip.rutgers.edu) 10 * Authors: David S. Miller (davem@caip.rutgers.edu)
11 * YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> 11 * YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
12 * 12 *
13 * This program is free software; you can redistribute it and/or 13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License 14 * modify it under the terms of the GNU General Public License
diff --git a/net/ipv6/protocol.c b/net/ipv6/protocol.c
index e048cf1bb6a2..e3770abe688a 100644
--- a/net/ipv6/protocol.c
+++ b/net/ipv6/protocol.c
@@ -51,6 +51,7 @@ EXPORT_SYMBOL(inet6_del_protocol);
51#endif 51#endif
52 52
53const struct net_offload __rcu *inet6_offloads[MAX_INET_PROTOS] __read_mostly; 53const struct net_offload __rcu *inet6_offloads[MAX_INET_PROTOS] __read_mostly;
54EXPORT_SYMBOL(inet6_offloads);
54 55
55int inet6_add_offload(const struct net_offload *prot, unsigned char protocol) 56int inet6_add_offload(const struct net_offload *prot, unsigned char protocol)
56{ 57{
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 39d44226e402..896af8807979 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -889,7 +889,7 @@ back_from_confirm:
889 else { 889 else {
890 lock_sock(sk); 890 lock_sock(sk);
891 err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov, 891 err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov,
892 len, 0, hlimit, tclass, opt, &fl6, (struct rt6_info*)dst, 892 len, 0, hlimit, tclass, opt, &fl6, (struct rt6_info *)dst,
893 msg->msg_flags, dontfrag); 893 msg->msg_flags, dontfrag);
894 894
895 if (err) 895 if (err)
@@ -902,7 +902,7 @@ done:
902 dst_release(dst); 902 dst_release(dst);
903out: 903out:
904 fl6_sock_release(flowlabel); 904 fl6_sock_release(flowlabel);
905 return err<0?err:len; 905 return err < 0 ? err : len;
906do_confirm: 906do_confirm:
907 dst_confirm(dst); 907 dst_confirm(dst);
908 if (!(msg->msg_flags & MSG_PROBE) || len) 908 if (!(msg->msg_flags & MSG_PROBE) || len)
@@ -1045,7 +1045,7 @@ static int do_rawv6_getsockopt(struct sock *sk, int level, int optname,
1045 struct raw6_sock *rp = raw6_sk(sk); 1045 struct raw6_sock *rp = raw6_sk(sk);
1046 int val, len; 1046 int val, len;
1047 1047
1048 if (get_user(len,optlen)) 1048 if (get_user(len, optlen))
1049 return -EFAULT; 1049 return -EFAULT;
1050 1050
1051 switch (optname) { 1051 switch (optname) {
@@ -1069,7 +1069,7 @@ static int do_rawv6_getsockopt(struct sock *sk, int level, int optname,
1069 1069
1070 if (put_user(len, optlen)) 1070 if (put_user(len, optlen))
1071 return -EFAULT; 1071 return -EFAULT;
1072 if (copy_to_user(optval,&val,len)) 1072 if (copy_to_user(optval, &val, len))
1073 return -EFAULT; 1073 return -EFAULT;
1074 return 0; 1074 return 0;
1075} 1075}
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index c6557d9f7808..1a157ca2ebc1 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -62,13 +62,12 @@
62 62
63static const char ip6_frag_cache_name[] = "ip6-frags"; 63static const char ip6_frag_cache_name[] = "ip6-frags";
64 64
65struct ip6frag_skb_cb 65struct ip6frag_skb_cb {
66{
67 struct inet6_skb_parm h; 66 struct inet6_skb_parm h;
68 int offset; 67 int offset;
69}; 68};
70 69
71#define FRAG6_CB(skb) ((struct ip6frag_skb_cb*)((skb)->cb)) 70#define FRAG6_CB(skb) ((struct ip6frag_skb_cb *)((skb)->cb))
72 71
73static inline u8 ip6_frag_ecn(const struct ipv6hdr *ipv6h) 72static inline u8 ip6_frag_ecn(const struct ipv6hdr *ipv6h)
74{ 73{
@@ -289,7 +288,7 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
289 goto found; 288 goto found;
290 } 289 }
291 prev = NULL; 290 prev = NULL;
292 for(next = fq->q.fragments; next != NULL; next = next->next) { 291 for (next = fq->q.fragments; next != NULL; next = next->next) {
293 if (FRAG6_CB(next)->offset >= offset) 292 if (FRAG6_CB(next)->offset >= offset)
294 break; /* bingo! */ 293 break; /* bingo! */
295 prev = next; 294 prev = next;
@@ -529,7 +528,7 @@ static int ipv6_frag_rcv(struct sk_buff *skb)
529 IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_REASMREQDS); 528 IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_REASMREQDS);
530 529
531 /* Jumbo payload inhibits frag. header */ 530 /* Jumbo payload inhibits frag. header */
532 if (hdr->payload_len==0) 531 if (hdr->payload_len == 0)
533 goto fail_hdr; 532 goto fail_hdr;
534 533
535 if (!pskb_may_pull(skb, (skb_transport_offset(skb) + 534 if (!pskb_may_pull(skb, (skb_transport_offset(skb) +
@@ -575,8 +574,7 @@ fail_hdr:
575 return -1; 574 return -1;
576} 575}
577 576
578static const struct inet6_protocol frag_protocol = 577static const struct inet6_protocol frag_protocol = {
579{
580 .handler = ipv6_frag_rcv, 578 .handler = ipv6_frag_rcv,
581 .flags = INET6_PROTO_NOPOLICY, 579 .flags = INET6_PROTO_NOPOLICY,
582}; 580};
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index bafde82324c5..a318dd89b6d9 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -812,7 +812,7 @@ out:
812 812
813} 813}
814 814
815struct dst_entry * ip6_route_lookup(struct net *net, struct flowi6 *fl6, 815struct dst_entry *ip6_route_lookup(struct net *net, struct flowi6 *fl6,
816 int flags) 816 int flags)
817{ 817{
818 return fib6_rule_lookup(net, fl6, flags, ip6_pol_route_lookup); 818 return fib6_rule_lookup(net, fl6, flags, ip6_pol_route_lookup);
@@ -842,7 +842,6 @@ struct rt6_info *rt6_lookup(struct net *net, const struct in6_addr *daddr,
842 842
843 return NULL; 843 return NULL;
844} 844}
845
846EXPORT_SYMBOL(rt6_lookup); 845EXPORT_SYMBOL(rt6_lookup);
847 846
848/* ip6_ins_rt is called with FREE table->tb6_lock. 847/* ip6_ins_rt is called with FREE table->tb6_lock.
@@ -1023,7 +1022,7 @@ static struct rt6_info *ip6_pol_route_output(struct net *net, struct fib6_table
1023 return ip6_pol_route(net, table, fl6->flowi6_oif, fl6, flags); 1022 return ip6_pol_route(net, table, fl6->flowi6_oif, fl6, flags);
1024} 1023}
1025 1024
1026struct dst_entry * ip6_route_output(struct net *net, const struct sock *sk, 1025struct dst_entry *ip6_route_output(struct net *net, const struct sock *sk,
1027 struct flowi6 *fl6) 1026 struct flowi6 *fl6)
1028{ 1027{
1029 int flags = 0; 1028 int flags = 0;
@@ -1040,7 +1039,6 @@ struct dst_entry * ip6_route_output(struct net *net, const struct sock *sk,
1040 1039
1041 return fib6_rule_lookup(net, fl6, flags, ip6_pol_route_output); 1040 return fib6_rule_lookup(net, fl6, flags, ip6_pol_route_output);
1042} 1041}
1043
1044EXPORT_SYMBOL(ip6_route_output); 1042EXPORT_SYMBOL(ip6_route_output);
1045 1043
1046struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_orig) 1044struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_orig)
@@ -1145,7 +1143,7 @@ static void ip6_link_failure(struct sk_buff *skb)
1145static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, 1143static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk,
1146 struct sk_buff *skb, u32 mtu) 1144 struct sk_buff *skb, u32 mtu)
1147{ 1145{
1148 struct rt6_info *rt6 = (struct rt6_info*)dst; 1146 struct rt6_info *rt6 = (struct rt6_info *)dst;
1149 1147
1150 dst_confirm(dst); 1148 dst_confirm(dst);
1151 if (mtu < dst_mtu(dst) && rt6->rt6i_dst.plen == 128) { 1149 if (mtu < dst_mtu(dst) && rt6->rt6i_dst.plen == 128) {
@@ -1920,7 +1918,7 @@ static struct rt6_info *rt6_get_route_info(struct net *net,
1920 return NULL; 1918 return NULL;
1921 1919
1922 read_lock_bh(&table->tb6_lock); 1920 read_lock_bh(&table->tb6_lock);
1923 fn = fib6_locate(&table->tb6_root, prefix ,prefixlen, NULL, 0); 1921 fn = fib6_locate(&table->tb6_root, prefix, prefixlen, NULL, 0);
1924 if (!fn) 1922 if (!fn)
1925 goto out; 1923 goto out;
1926 1924
@@ -1979,7 +1977,7 @@ struct rt6_info *rt6_get_dflt_router(const struct in6_addr *addr, struct net_dev
1979 return NULL; 1977 return NULL;
1980 1978
1981 read_lock_bh(&table->tb6_lock); 1979 read_lock_bh(&table->tb6_lock);
1982 for (rt = table->tb6_root.leaf; rt; rt=rt->dst.rt6_next) { 1980 for (rt = table->tb6_root.leaf; rt; rt = rt->dst.rt6_next) {
1983 if (dev == rt->dst.dev && 1981 if (dev == rt->dst.dev &&
1984 ((rt->rt6i_flags & (RTF_ADDRCONF | RTF_DEFAULT)) == (RTF_ADDRCONF | RTF_DEFAULT)) && 1982 ((rt->rt6i_flags & (RTF_ADDRCONF | RTF_DEFAULT)) == (RTF_ADDRCONF | RTF_DEFAULT)) &&
1985 ipv6_addr_equal(&rt->rt6i_gateway, addr)) 1983 ipv6_addr_equal(&rt->rt6i_gateway, addr))
@@ -2064,7 +2062,7 @@ int ipv6_route_ioctl(struct net *net, unsigned int cmd, void __user *arg)
2064 struct in6_rtmsg rtmsg; 2062 struct in6_rtmsg rtmsg;
2065 int err; 2063 int err;
2066 2064
2067 switch(cmd) { 2065 switch (cmd) {
2068 case SIOCADDRT: /* Add a route */ 2066 case SIOCADDRT: /* Add a route */
2069 case SIOCDELRT: /* Delete a route */ 2067 case SIOCDELRT: /* Delete a route */
2070 if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) 2068 if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
@@ -2187,7 +2185,7 @@ int ip6_route_get_saddr(struct net *net,
2187 unsigned int prefs, 2185 unsigned int prefs,
2188 struct in6_addr *saddr) 2186 struct in6_addr *saddr)
2189{ 2187{
2190 struct inet6_dev *idev = ip6_dst_idev((struct dst_entry*)rt); 2188 struct inet6_dev *idev = ip6_dst_idev((struct dst_entry *)rt);
2191 int err = 0; 2189 int err = 0;
2192 if (rt->rt6i_prefsrc.plen) 2190 if (rt->rt6i_prefsrc.plen)
2193 *saddr = rt->rt6i_prefsrc.addr; 2191 *saddr = rt->rt6i_prefsrc.addr;
@@ -2482,7 +2480,7 @@ beginning:
2482 return last_err; 2480 return last_err;
2483} 2481}
2484 2482
2485static int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh) 2483static int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh)
2486{ 2484{
2487 struct fib6_config cfg; 2485 struct fib6_config cfg;
2488 int err; 2486 int err;
@@ -2497,7 +2495,7 @@ static int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh)
2497 return ip6_route_del(&cfg); 2495 return ip6_route_del(&cfg);
2498} 2496}
2499 2497
2500static int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh) 2498static int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh)
2501{ 2499{
2502 struct fib6_config cfg; 2500 struct fib6_config cfg;
2503 int err; 2501 int err;
@@ -2689,7 +2687,7 @@ int rt6_dump_route(struct rt6_info *rt, void *p_arg)
2689 prefix, 0, NLM_F_MULTI); 2687 prefix, 0, NLM_F_MULTI);
2690} 2688}
2691 2689
2692static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh) 2690static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh)
2693{ 2691{
2694 struct net *net = sock_net(in_skb->sk); 2692 struct net *net = sock_net(in_skb->sk);
2695 struct nlattr *tb[RTA_MAX+1]; 2693 struct nlattr *tb[RTA_MAX+1];
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 6163f851dc01..6eab37cf5345 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -812,9 +812,9 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
812 const struct ipv6hdr *iph6 = ipv6_hdr(skb); 812 const struct ipv6hdr *iph6 = ipv6_hdr(skb);
813 u8 tos = tunnel->parms.iph.tos; 813 u8 tos = tunnel->parms.iph.tos;
814 __be16 df = tiph->frag_off; 814 __be16 df = tiph->frag_off;
815 struct rtable *rt; /* Route to the other host */ 815 struct rtable *rt; /* Route to the other host */
816 struct net_device *tdev; /* Device to other host */ 816 struct net_device *tdev; /* Device to other host */
817 unsigned int max_headroom; /* The extra header space needed */ 817 unsigned int max_headroom; /* The extra header space needed */
818 __be32 dst = tiph->daddr; 818 __be32 dst = tiph->daddr;
819 struct flowi4 fl4; 819 struct flowi4 fl4;
820 int mtu; 820 int mtu;
@@ -822,6 +822,8 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
822 int addr_type; 822 int addr_type;
823 u8 ttl; 823 u8 ttl;
824 int err; 824 int err;
825 u8 protocol = IPPROTO_IPV6;
826 int t_hlen = tunnel->hlen + sizeof(struct iphdr);
825 827
826 if (skb->protocol != htons(ETH_P_IPV6)) 828 if (skb->protocol != htons(ETH_P_IPV6))
827 goto tx_error; 829 goto tx_error;
@@ -911,8 +913,14 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
911 goto tx_error; 913 goto tx_error;
912 } 914 }
913 915
916 skb = iptunnel_handle_offloads(skb, false, SKB_GSO_SIT);
917 if (IS_ERR(skb)) {
918 ip_rt_put(rt);
919 goto out;
920 }
921
914 if (df) { 922 if (df) {
915 mtu = dst_mtu(&rt->dst) - sizeof(struct iphdr); 923 mtu = dst_mtu(&rt->dst) - t_hlen;
916 924
917 if (mtu < 68) { 925 if (mtu < 68) {
918 dev->stats.collisions++; 926 dev->stats.collisions++;
@@ -947,7 +955,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
947 /* 955 /*
948 * Okay, now see if we can stuff it in the buffer as-is. 956 * Okay, now see if we can stuff it in the buffer as-is.
949 */ 957 */
950 max_headroom = LL_RESERVED_SPACE(tdev)+sizeof(struct iphdr); 958 max_headroom = LL_RESERVED_SPACE(tdev) + t_hlen;
951 959
952 if (skb_headroom(skb) < max_headroom || skb_shared(skb) || 960 if (skb_headroom(skb) < max_headroom || skb_shared(skb) ||
953 (skb_cloned(skb) && !skb_clone_writable(skb, 0))) { 961 (skb_cloned(skb) && !skb_clone_writable(skb, 0))) {
@@ -969,14 +977,15 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
969 ttl = iph6->hop_limit; 977 ttl = iph6->hop_limit;
970 tos = INET_ECN_encapsulate(tos, ipv6_get_dsfield(iph6)); 978 tos = INET_ECN_encapsulate(tos, ipv6_get_dsfield(iph6));
971 979
972 skb = iptunnel_handle_offloads(skb, false, SKB_GSO_SIT); 980 if (ip_tunnel_encap(skb, tunnel, &protocol, &fl4) < 0) {
973 if (IS_ERR(skb)) {
974 ip_rt_put(rt); 981 ip_rt_put(rt);
975 goto out; 982 goto tx_error;
976 } 983 }
977 984
985 skb_set_inner_ipproto(skb, IPPROTO_IPV6);
986
978 err = iptunnel_xmit(skb->sk, rt, skb, fl4.saddr, fl4.daddr, 987 err = iptunnel_xmit(skb->sk, rt, skb, fl4.saddr, fl4.daddr,
979 IPPROTO_IPV6, tos, ttl, df, 988 protocol, tos, ttl, df,
980 !net_eq(tunnel->net, dev_net(dev))); 989 !net_eq(tunnel->net, dev_net(dev)));
981 iptunnel_xmit_stats(err, &dev->stats, dev->tstats); 990 iptunnel_xmit_stats(err, &dev->stats, dev->tstats);
982 return NETDEV_TX_OK; 991 return NETDEV_TX_OK;
@@ -999,6 +1008,8 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
999 if (IS_ERR(skb)) 1008 if (IS_ERR(skb))
1000 goto out; 1009 goto out;
1001 1010
1011 skb_set_inner_ipproto(skb, IPPROTO_IPIP);
1012
1002 ip_tunnel_xmit(skb, dev, tiph, IPPROTO_IPIP); 1013 ip_tunnel_xmit(skb, dev, tiph, IPPROTO_IPIP);
1003 return NETDEV_TX_OK; 1014 return NETDEV_TX_OK;
1004out: 1015out:
@@ -1059,8 +1070,10 @@ static void ipip6_tunnel_bind_dev(struct net_device *dev)
1059 tdev = __dev_get_by_index(tunnel->net, tunnel->parms.link); 1070 tdev = __dev_get_by_index(tunnel->net, tunnel->parms.link);
1060 1071
1061 if (tdev) { 1072 if (tdev) {
1073 int t_hlen = tunnel->hlen + sizeof(struct iphdr);
1074
1062 dev->hard_header_len = tdev->hard_header_len + sizeof(struct iphdr); 1075 dev->hard_header_len = tdev->hard_header_len + sizeof(struct iphdr);
1063 dev->mtu = tdev->mtu - sizeof(struct iphdr); 1076 dev->mtu = tdev->mtu - t_hlen;
1064 if (dev->mtu < IPV6_MIN_MTU) 1077 if (dev->mtu < IPV6_MIN_MTU)
1065 dev->mtu = IPV6_MIN_MTU; 1078 dev->mtu = IPV6_MIN_MTU;
1066 } 1079 }
@@ -1123,7 +1136,7 @@ static int ipip6_tunnel_update_6rd(struct ip_tunnel *t,
1123#endif 1136#endif
1124 1137
1125static int 1138static int
1126ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) 1139ipip6_tunnel_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1127{ 1140{
1128 int err = 0; 1141 int err = 0;
1129 struct ip_tunnel_parm p; 1142 struct ip_tunnel_parm p;
@@ -1307,7 +1320,10 @@ done:
1307 1320
1308static int ipip6_tunnel_change_mtu(struct net_device *dev, int new_mtu) 1321static int ipip6_tunnel_change_mtu(struct net_device *dev, int new_mtu)
1309{ 1322{
1310 if (new_mtu < IPV6_MIN_MTU || new_mtu > 0xFFF8 - sizeof(struct iphdr)) 1323 struct ip_tunnel *tunnel = netdev_priv(dev);
1324 int t_hlen = tunnel->hlen + sizeof(struct iphdr);
1325
1326 if (new_mtu < IPV6_MIN_MTU || new_mtu > 0xFFF8 - t_hlen)
1311 return -EINVAL; 1327 return -EINVAL;
1312 dev->mtu = new_mtu; 1328 dev->mtu = new_mtu;
1313 return 0; 1329 return 0;
@@ -1338,14 +1354,17 @@ static void ipip6_dev_free(struct net_device *dev)
1338 1354
1339static void ipip6_tunnel_setup(struct net_device *dev) 1355static void ipip6_tunnel_setup(struct net_device *dev)
1340{ 1356{
1357 struct ip_tunnel *tunnel = netdev_priv(dev);
1358 int t_hlen = tunnel->hlen + sizeof(struct iphdr);
1359
1341 dev->netdev_ops = &ipip6_netdev_ops; 1360 dev->netdev_ops = &ipip6_netdev_ops;
1342 dev->destructor = ipip6_dev_free; 1361 dev->destructor = ipip6_dev_free;
1343 1362
1344 dev->type = ARPHRD_SIT; 1363 dev->type = ARPHRD_SIT;
1345 dev->hard_header_len = LL_MAX_HEADER + sizeof(struct iphdr); 1364 dev->hard_header_len = LL_MAX_HEADER + t_hlen;
1346 dev->mtu = ETH_DATA_LEN - sizeof(struct iphdr); 1365 dev->mtu = ETH_DATA_LEN - t_hlen;
1347 dev->flags = IFF_NOARP; 1366 dev->flags = IFF_NOARP;
1348 dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; 1367 netif_keep_dst(dev);
1349 dev->iflink = 0; 1368 dev->iflink = 0;
1350 dev->addr_len = 4; 1369 dev->addr_len = 4;
1351 dev->features |= NETIF_F_LLTX; 1370 dev->features |= NETIF_F_LLTX;
@@ -1466,6 +1485,40 @@ static void ipip6_netlink_parms(struct nlattr *data[],
1466 1485
1467} 1486}
1468 1487
1488/* This function returns true when ENCAP attributes are present in the nl msg */
1489static bool ipip6_netlink_encap_parms(struct nlattr *data[],
1490 struct ip_tunnel_encap *ipencap)
1491{
1492 bool ret = false;
1493
1494 memset(ipencap, 0, sizeof(*ipencap));
1495
1496 if (!data)
1497 return ret;
1498
1499 if (data[IFLA_IPTUN_ENCAP_TYPE]) {
1500 ret = true;
1501 ipencap->type = nla_get_u16(data[IFLA_IPTUN_ENCAP_TYPE]);
1502 }
1503
1504 if (data[IFLA_IPTUN_ENCAP_FLAGS]) {
1505 ret = true;
1506 ipencap->flags = nla_get_u16(data[IFLA_IPTUN_ENCAP_FLAGS]);
1507 }
1508
1509 if (data[IFLA_IPTUN_ENCAP_SPORT]) {
1510 ret = true;
1511 ipencap->sport = nla_get_u16(data[IFLA_IPTUN_ENCAP_SPORT]);
1512 }
1513
1514 if (data[IFLA_IPTUN_ENCAP_DPORT]) {
1515 ret = true;
1516 ipencap->dport = nla_get_u16(data[IFLA_IPTUN_ENCAP_DPORT]);
1517 }
1518
1519 return ret;
1520}
1521
1469#ifdef CONFIG_IPV6_SIT_6RD 1522#ifdef CONFIG_IPV6_SIT_6RD
1470/* This function returns true when 6RD attributes are present in the nl msg */ 1523/* This function returns true when 6RD attributes are present in the nl msg */
1471static bool ipip6_netlink_6rd_parms(struct nlattr *data[], 1524static bool ipip6_netlink_6rd_parms(struct nlattr *data[],
@@ -1509,12 +1562,20 @@ static int ipip6_newlink(struct net *src_net, struct net_device *dev,
1509{ 1562{
1510 struct net *net = dev_net(dev); 1563 struct net *net = dev_net(dev);
1511 struct ip_tunnel *nt; 1564 struct ip_tunnel *nt;
1565 struct ip_tunnel_encap ipencap;
1512#ifdef CONFIG_IPV6_SIT_6RD 1566#ifdef CONFIG_IPV6_SIT_6RD
1513 struct ip_tunnel_6rd ip6rd; 1567 struct ip_tunnel_6rd ip6rd;
1514#endif 1568#endif
1515 int err; 1569 int err;
1516 1570
1517 nt = netdev_priv(dev); 1571 nt = netdev_priv(dev);
1572
1573 if (ipip6_netlink_encap_parms(data, &ipencap)) {
1574 err = ip_tunnel_encap_setup(nt, &ipencap);
1575 if (err < 0)
1576 return err;
1577 }
1578
1518 ipip6_netlink_parms(data, &nt->parms); 1579 ipip6_netlink_parms(data, &nt->parms);
1519 1580
1520 if (ipip6_tunnel_locate(net, &nt->parms, 0)) 1581 if (ipip6_tunnel_locate(net, &nt->parms, 0))
@@ -1537,15 +1598,23 @@ static int ipip6_changelink(struct net_device *dev, struct nlattr *tb[],
1537{ 1598{
1538 struct ip_tunnel *t = netdev_priv(dev); 1599 struct ip_tunnel *t = netdev_priv(dev);
1539 struct ip_tunnel_parm p; 1600 struct ip_tunnel_parm p;
1601 struct ip_tunnel_encap ipencap;
1540 struct net *net = t->net; 1602 struct net *net = t->net;
1541 struct sit_net *sitn = net_generic(net, sit_net_id); 1603 struct sit_net *sitn = net_generic(net, sit_net_id);
1542#ifdef CONFIG_IPV6_SIT_6RD 1604#ifdef CONFIG_IPV6_SIT_6RD
1543 struct ip_tunnel_6rd ip6rd; 1605 struct ip_tunnel_6rd ip6rd;
1544#endif 1606#endif
1607 int err;
1545 1608
1546 if (dev == sitn->fb_tunnel_dev) 1609 if (dev == sitn->fb_tunnel_dev)
1547 return -EINVAL; 1610 return -EINVAL;
1548 1611
1612 if (ipip6_netlink_encap_parms(data, &ipencap)) {
1613 err = ip_tunnel_encap_setup(t, &ipencap);
1614 if (err < 0)
1615 return err;
1616 }
1617
1549 ipip6_netlink_parms(data, &p); 1618 ipip6_netlink_parms(data, &p);
1550 1619
1551 if (((dev->flags & IFF_POINTOPOINT) && !p.iph.daddr) || 1620 if (((dev->flags & IFF_POINTOPOINT) && !p.iph.daddr) ||
@@ -1599,6 +1668,14 @@ static size_t ipip6_get_size(const struct net_device *dev)
1599 /* IFLA_IPTUN_6RD_RELAY_PREFIXLEN */ 1668 /* IFLA_IPTUN_6RD_RELAY_PREFIXLEN */
1600 nla_total_size(2) + 1669 nla_total_size(2) +
1601#endif 1670#endif
1671 /* IFLA_IPTUN_ENCAP_TYPE */
1672 nla_total_size(2) +
1673 /* IFLA_IPTUN_ENCAP_FLAGS */
1674 nla_total_size(2) +
1675 /* IFLA_IPTUN_ENCAP_SPORT */
1676 nla_total_size(2) +
1677 /* IFLA_IPTUN_ENCAP_DPORT */
1678 nla_total_size(2) +
1602 0; 1679 0;
1603} 1680}
1604 1681
@@ -1630,6 +1707,16 @@ static int ipip6_fill_info(struct sk_buff *skb, const struct net_device *dev)
1630 goto nla_put_failure; 1707 goto nla_put_failure;
1631#endif 1708#endif
1632 1709
1710 if (nla_put_u16(skb, IFLA_IPTUN_ENCAP_TYPE,
1711 tunnel->encap.type) ||
1712 nla_put_u16(skb, IFLA_IPTUN_ENCAP_SPORT,
1713 tunnel->encap.sport) ||
1714 nla_put_u16(skb, IFLA_IPTUN_ENCAP_DPORT,
1715 tunnel->encap.dport) ||
1716 nla_put_u16(skb, IFLA_IPTUN_ENCAP_FLAGS,
1717 tunnel->encap.dport))
1718 goto nla_put_failure;
1719
1633 return 0; 1720 return 0;
1634 1721
1635nla_put_failure: 1722nla_put_failure:
@@ -1651,6 +1738,10 @@ static const struct nla_policy ipip6_policy[IFLA_IPTUN_MAX + 1] = {
1651 [IFLA_IPTUN_6RD_PREFIXLEN] = { .type = NLA_U16 }, 1738 [IFLA_IPTUN_6RD_PREFIXLEN] = { .type = NLA_U16 },
1652 [IFLA_IPTUN_6RD_RELAY_PREFIXLEN] = { .type = NLA_U16 }, 1739 [IFLA_IPTUN_6RD_RELAY_PREFIXLEN] = { .type = NLA_U16 },
1653#endif 1740#endif
1741 [IFLA_IPTUN_ENCAP_TYPE] = { .type = NLA_U16 },
1742 [IFLA_IPTUN_ENCAP_FLAGS] = { .type = NLA_U16 },
1743 [IFLA_IPTUN_ENCAP_SPORT] = { .type = NLA_U16 },
1744 [IFLA_IPTUN_ENCAP_DPORT] = { .type = NLA_U16 },
1654}; 1745};
1655 1746
1656static void ipip6_dellink(struct net_device *dev, struct list_head *head) 1747static void ipip6_dellink(struct net_device *dev, struct list_head *head)
diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c
index 83cea1d39466..9a2838e93cc5 100644
--- a/net/ipv6/syncookies.c
+++ b/net/ipv6/syncookies.c
@@ -24,7 +24,7 @@
24#define COOKIEBITS 24 /* Upper bits store count */ 24#define COOKIEBITS 24 /* Upper bits store count */
25#define COOKIEMASK (((__u32)1 << COOKIEBITS) - 1) 25#define COOKIEMASK (((__u32)1 << COOKIEBITS) - 1)
26 26
27static u32 syncookie6_secret[2][16-4+SHA_DIGEST_WORDS]; 27static u32 syncookie6_secret[2][16-4+SHA_DIGEST_WORDS] __read_mostly;
28 28
29/* RFC 2460, Section 8.3: 29/* RFC 2460, Section 8.3:
30 * [ipv6 tcp] MSS must be computed as the maximum packet size minus 60 [..] 30 * [ipv6 tcp] MSS must be computed as the maximum packet size minus 60 [..]
@@ -203,7 +203,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
203 ireq->ir_num = ntohs(th->dest); 203 ireq->ir_num = ntohs(th->dest);
204 ireq->ir_v6_rmt_addr = ipv6_hdr(skb)->saddr; 204 ireq->ir_v6_rmt_addr = ipv6_hdr(skb)->saddr;
205 ireq->ir_v6_loc_addr = ipv6_hdr(skb)->daddr; 205 ireq->ir_v6_loc_addr = ipv6_hdr(skb)->daddr;
206 if (ipv6_opt_accepted(sk, skb) || 206 if (ipv6_opt_accepted(sk, skb, &TCP_SKB_CB(skb)->header.h6) ||
207 np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo || 207 np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo ||
208 np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) { 208 np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) {
209 atomic_inc(&skb->users); 209 atomic_inc(&skb->users);
diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c
index 0c56c93619e0..c5c10fafcfe2 100644
--- a/net/ipv6/sysctl_net_ipv6.c
+++ b/net/ipv6/sysctl_net_ipv6.c
@@ -16,6 +16,8 @@
16#include <net/addrconf.h> 16#include <net/addrconf.h>
17#include <net/inet_frag.h> 17#include <net/inet_frag.h>
18 18
19static int one = 1;
20
19static struct ctl_table ipv6_table_template[] = { 21static struct ctl_table ipv6_table_template[] = {
20 { 22 {
21 .procname = "bindv6only", 23 .procname = "bindv6only",
@@ -63,6 +65,14 @@ static struct ctl_table ipv6_rotable[] = {
63 .mode = 0644, 65 .mode = 0644,
64 .proc_handler = proc_dointvec 66 .proc_handler = proc_dointvec
65 }, 67 },
68 {
69 .procname = "mld_qrv",
70 .data = &sysctl_mld_qrv,
71 .maxlen = sizeof(int),
72 .mode = 0644,
73 .proc_handler = proc_dointvec_minmax,
74 .extra1 = &one
75 },
66 { } 76 { }
67}; 77};
68 78
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 29964c3d363c..132bac137aed 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -93,13 +93,16 @@ static struct tcp_md5sig_key *tcp_v6_md5_do_lookup(struct sock *sk,
93static void inet6_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb) 93static void inet6_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb)
94{ 94{
95 struct dst_entry *dst = skb_dst(skb); 95 struct dst_entry *dst = skb_dst(skb);
96 const struct rt6_info *rt = (const struct rt6_info *)dst;
97 96
98 dst_hold(dst); 97 if (dst) {
99 sk->sk_rx_dst = dst; 98 const struct rt6_info *rt = (const struct rt6_info *)dst;
100 inet_sk(sk)->rx_dst_ifindex = skb->skb_iif; 99
101 if (rt->rt6i_node) 100 dst_hold(dst);
102 inet6_sk(sk)->rx_dst_cookie = rt->rt6i_node->fn_sernum; 101 sk->sk_rx_dst = dst;
102 inet_sk(sk)->rx_dst_ifindex = skb->skb_iif;
103 if (rt->rt6i_node)
104 inet6_sk(sk)->rx_dst_cookie = rt->rt6i_node->fn_sernum;
105 }
103} 106}
104 107
105static void tcp_v6_hash(struct sock *sk) 108static void tcp_v6_hash(struct sock *sk)
@@ -738,8 +741,9 @@ static void tcp_v6_init_req(struct request_sock *req, struct sock *sk,
738 ipv6_addr_type(&ireq->ir_v6_rmt_addr) & IPV6_ADDR_LINKLOCAL) 741 ipv6_addr_type(&ireq->ir_v6_rmt_addr) & IPV6_ADDR_LINKLOCAL)
739 ireq->ir_iif = inet6_iif(skb); 742 ireq->ir_iif = inet6_iif(skb);
740 743
741 if (!TCP_SKB_CB(skb)->when && 744 if (!TCP_SKB_CB(skb)->tcp_tw_isn &&
742 (ipv6_opt_accepted(sk, skb) || np->rxopt.bits.rxinfo || 745 (ipv6_opt_accepted(sk, skb, &TCP_SKB_CB(skb)->header.h6) ||
746 np->rxopt.bits.rxinfo ||
743 np->rxopt.bits.rxoinfo || np->rxopt.bits.rxhlim || 747 np->rxopt.bits.rxoinfo || np->rxopt.bits.rxhlim ||
744 np->rxopt.bits.rxohlim || np->repflow)) { 748 np->rxopt.bits.rxohlim || np->repflow)) {
745 atomic_inc(&skb->users); 749 atomic_inc(&skb->users);
@@ -1364,7 +1368,7 @@ ipv6_pktoptions:
1364 np->rcv_flowinfo = ip6_flowinfo(ipv6_hdr(opt_skb)); 1368 np->rcv_flowinfo = ip6_flowinfo(ipv6_hdr(opt_skb));
1365 if (np->repflow) 1369 if (np->repflow)
1366 np->flow_label = ip6_flowlabel(ipv6_hdr(opt_skb)); 1370 np->flow_label = ip6_flowlabel(ipv6_hdr(opt_skb));
1367 if (ipv6_opt_accepted(sk, opt_skb)) { 1371 if (ipv6_opt_accepted(sk, opt_skb, &TCP_SKB_CB(opt_skb)->header.h6)) {
1368 skb_set_owner_r(opt_skb, sk); 1372 skb_set_owner_r(opt_skb, sk);
1369 opt_skb = xchg(&np->pktoptions, opt_skb); 1373 opt_skb = xchg(&np->pktoptions, opt_skb);
1370 } else { 1374 } else {
@@ -1408,11 +1412,19 @@ static int tcp_v6_rcv(struct sk_buff *skb)
1408 1412
1409 th = tcp_hdr(skb); 1413 th = tcp_hdr(skb);
1410 hdr = ipv6_hdr(skb); 1414 hdr = ipv6_hdr(skb);
1415 /* This is tricky : We move IPCB at its correct location into TCP_SKB_CB()
1416 * barrier() makes sure compiler wont play fool^Waliasing games.
1417 */
1418 memmove(&TCP_SKB_CB(skb)->header.h6, IP6CB(skb),
1419 sizeof(struct inet6_skb_parm));
1420 barrier();
1421
1411 TCP_SKB_CB(skb)->seq = ntohl(th->seq); 1422 TCP_SKB_CB(skb)->seq = ntohl(th->seq);
1412 TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin + 1423 TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin +
1413 skb->len - th->doff*4); 1424 skb->len - th->doff*4);
1414 TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq); 1425 TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq);
1415 TCP_SKB_CB(skb)->when = 0; 1426 TCP_SKB_CB(skb)->tcp_flags = tcp_flag_byte(th);
1427 TCP_SKB_CB(skb)->tcp_tw_isn = 0;
1416 TCP_SKB_CB(skb)->ip_dsfield = ipv6_get_dsfield(hdr); 1428 TCP_SKB_CB(skb)->ip_dsfield = ipv6_get_dsfield(hdr);
1417 TCP_SKB_CB(skb)->sacked = 0; 1429 TCP_SKB_CB(skb)->sacked = 0;
1418 1430
diff --git a/net/ipv6/tcpv6_offload.c b/net/ipv6/tcpv6_offload.c
index 01b0ff9a0c2c..c1ab77105b4c 100644
--- a/net/ipv6/tcpv6_offload.c
+++ b/net/ipv6/tcpv6_offload.c
@@ -15,54 +15,17 @@
15#include <net/ip6_checksum.h> 15#include <net/ip6_checksum.h>
16#include "ip6_offload.h" 16#include "ip6_offload.h"
17 17
18static int tcp_v6_gso_send_check(struct sk_buff *skb)
19{
20 const struct ipv6hdr *ipv6h;
21 struct tcphdr *th;
22
23 if (!pskb_may_pull(skb, sizeof(*th)))
24 return -EINVAL;
25
26 ipv6h = ipv6_hdr(skb);
27 th = tcp_hdr(skb);
28
29 th->check = 0;
30 skb->ip_summed = CHECKSUM_PARTIAL;
31 __tcp_v6_send_check(skb, &ipv6h->saddr, &ipv6h->daddr);
32 return 0;
33}
34
35static struct sk_buff **tcp6_gro_receive(struct sk_buff **head, 18static struct sk_buff **tcp6_gro_receive(struct sk_buff **head,
36 struct sk_buff *skb) 19 struct sk_buff *skb)
37{ 20{
38 const struct ipv6hdr *iph = skb_gro_network_header(skb);
39 __wsum wsum;
40
41 /* Don't bother verifying checksum if we're going to flush anyway. */ 21 /* Don't bother verifying checksum if we're going to flush anyway. */
42 if (NAPI_GRO_CB(skb)->flush) 22 if (!NAPI_GRO_CB(skb)->flush &&
43 goto skip_csum; 23 skb_gro_checksum_validate(skb, IPPROTO_TCP,
44 24 ip6_gro_compute_pseudo)) {
45 wsum = NAPI_GRO_CB(skb)->csum;
46
47 switch (skb->ip_summed) {
48 case CHECKSUM_NONE:
49 wsum = skb_checksum(skb, skb_gro_offset(skb), skb_gro_len(skb),
50 wsum);
51
52 /* fall through */
53
54 case CHECKSUM_COMPLETE:
55 if (!tcp_v6_check(skb_gro_len(skb), &iph->saddr, &iph->daddr,
56 wsum)) {
57 skb->ip_summed = CHECKSUM_UNNECESSARY;
58 break;
59 }
60
61 NAPI_GRO_CB(skb)->flush = 1; 25 NAPI_GRO_CB(skb)->flush = 1;
62 return NULL; 26 return NULL;
63 } 27 }
64 28
65skip_csum:
66 return tcp_gro_receive(head, skb); 29 return tcp_gro_receive(head, skb);
67} 30}
68 31
@@ -78,10 +41,32 @@ static int tcp6_gro_complete(struct sk_buff *skb, int thoff)
78 return tcp_gro_complete(skb); 41 return tcp_gro_complete(skb);
79} 42}
80 43
44struct sk_buff *tcp6_gso_segment(struct sk_buff *skb,
45 netdev_features_t features)
46{
47 struct tcphdr *th;
48
49 if (!pskb_may_pull(skb, sizeof(*th)))
50 return ERR_PTR(-EINVAL);
51
52 if (unlikely(skb->ip_summed != CHECKSUM_PARTIAL)) {
53 const struct ipv6hdr *ipv6h = ipv6_hdr(skb);
54 struct tcphdr *th = tcp_hdr(skb);
55
56 /* Set up pseudo header, usually expect stack to have done
57 * this.
58 */
59
60 th->check = 0;
61 skb->ip_summed = CHECKSUM_PARTIAL;
62 __tcp_v6_send_check(skb, &ipv6h->saddr, &ipv6h->daddr);
63 }
64
65 return tcp_gso_segment(skb, features);
66}
81static const struct net_offload tcpv6_offload = { 67static const struct net_offload tcpv6_offload = {
82 .callbacks = { 68 .callbacks = {
83 .gso_send_check = tcp_v6_gso_send_check, 69 .gso_segment = tcp6_gso_segment,
84 .gso_segment = tcp_gso_segment,
85 .gro_receive = tcp6_gro_receive, 70 .gro_receive = tcp6_gro_receive,
86 .gro_complete = tcp6_gro_complete, 71 .gro_complete = tcp6_gro_complete,
87 }, 72 },
diff --git a/net/ipv6/tunnel6.c b/net/ipv6/tunnel6.c
index 2c4e4c5c7614..3c758007b327 100644
--- a/net/ipv6/tunnel6.c
+++ b/net/ipv6/tunnel6.c
@@ -15,7 +15,7 @@
15 * along with this program; if not, see <http://www.gnu.org/licenses/>. 15 * along with this program; if not, see <http://www.gnu.org/licenses/>.
16 * 16 *
17 * Authors Mitsuru KANDA <mk@linux-ipv6.org> 17 * Authors Mitsuru KANDA <mk@linux-ipv6.org>
18 * YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> 18 * YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
19 */ 19 */
20 20
21#define pr_fmt(fmt) "IPv6: " fmt 21#define pr_fmt(fmt) "IPv6: " fmt
@@ -64,7 +64,6 @@ err:
64 64
65 return ret; 65 return ret;
66} 66}
67
68EXPORT_SYMBOL(xfrm6_tunnel_register); 67EXPORT_SYMBOL(xfrm6_tunnel_register);
69 68
70int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler, unsigned short family) 69int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler, unsigned short family)
@@ -92,7 +91,6 @@ int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler, unsigned short family)
92 91
93 return ret; 92 return ret;
94} 93}
95
96EXPORT_SYMBOL(xfrm6_tunnel_deregister); 94EXPORT_SYMBOL(xfrm6_tunnel_deregister);
97 95
98#define for_each_tunnel_rcu(head, handler) \ 96#define for_each_tunnel_rcu(head, handler) \
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 4836af8f582d..f6ba535b6feb 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -243,7 +243,7 @@ begin:
243 goto exact_match; 243 goto exact_match;
244 } else if (score == badness && reuseport) { 244 } else if (score == badness && reuseport) {
245 matches++; 245 matches++;
246 if (((u64)hash * matches) >> 32 == 0) 246 if (reciprocal_scale(hash, matches) == 0)
247 result = sk; 247 result = sk;
248 hash = next_pseudo_random32(hash); 248 hash = next_pseudo_random32(hash);
249 } 249 }
@@ -323,7 +323,7 @@ begin:
323 } 323 }
324 } else if (score == badness && reuseport) { 324 } else if (score == badness && reuseport) {
325 matches++; 325 matches++;
326 if (((u64)hash * matches) >> 32 == 0) 326 if (reciprocal_scale(hash, matches) == 0)
327 result = sk; 327 result = sk;
328 hash = next_pseudo_random32(hash); 328 hash = next_pseudo_random32(hash);
329 } 329 }
@@ -373,8 +373,8 @@ EXPORT_SYMBOL_GPL(udp6_lib_lookup);
373 373
374 374
375/* 375/*
376 * This should be easy, if there is something there we 376 * This should be easy, if there is something there we
377 * return it, otherwise we block. 377 * return it, otherwise we block.
378 */ 378 */
379 379
380int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk, 380int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk,
@@ -530,7 +530,7 @@ void __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
530 const struct ipv6hdr *hdr = (const struct ipv6hdr *)skb->data; 530 const struct ipv6hdr *hdr = (const struct ipv6hdr *)skb->data;
531 const struct in6_addr *saddr = &hdr->saddr; 531 const struct in6_addr *saddr = &hdr->saddr;
532 const struct in6_addr *daddr = &hdr->daddr; 532 const struct in6_addr *daddr = &hdr->daddr;
533 struct udphdr *uh = (struct udphdr*)(skb->data+offset); 533 struct udphdr *uh = (struct udphdr *)(skb->data+offset);
534 struct sock *sk; 534 struct sock *sk;
535 int err; 535 int err;
536 struct net *net = dev_net(skb->dev); 536 struct net *net = dev_net(skb->dev);
@@ -596,7 +596,7 @@ static int __udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
596 596
597static __inline__ void udpv6_err(struct sk_buff *skb, 597static __inline__ void udpv6_err(struct sk_buff *skb,
598 struct inet6_skb_parm *opt, u8 type, 598 struct inet6_skb_parm *opt, u8 type,
599 u8 code, int offset, __be32 info ) 599 u8 code, int offset, __be32 info)
600{ 600{
601 __udp6_lib_err(skb, opt, type, code, offset, info, &udp_table); 601 __udp6_lib_err(skb, opt, type, code, offset, info, &udp_table);
602} 602}
@@ -891,6 +891,10 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
891 goto csum_error; 891 goto csum_error;
892 } 892 }
893 893
894 if (udp_sk(sk)->convert_csum && uh->check && !IS_UDPLITE(sk))
895 skb_checksum_try_convert(skb, IPPROTO_UDP, uh->check,
896 ip6_compute_pseudo);
897
894 ret = udpv6_queue_rcv_skb(sk, skb); 898 ret = udpv6_queue_rcv_skb(sk, skb);
895 sock_put(sk); 899 sock_put(sk);
896 900
@@ -960,10 +964,10 @@ static void udp_v6_flush_pending_frames(struct sock *sk)
960} 964}
961 965
962/** 966/**
963 * udp6_hwcsum_outgoing - handle outgoing HW checksumming 967 * udp6_hwcsum_outgoing - handle outgoing HW checksumming
964 * @sk: socket we are sending on 968 * @sk: socket we are sending on
965 * @skb: sk_buff containing the filled-in UDP header 969 * @skb: sk_buff containing the filled-in UDP header
966 * (checksum field must be zeroed out) 970 * (checksum field must be zeroed out)
967 */ 971 */
968static void udp6_hwcsum_outgoing(struct sock *sk, struct sk_buff *skb, 972static void udp6_hwcsum_outgoing(struct sock *sk, struct sk_buff *skb,
969 const struct in6_addr *saddr, 973 const struct in6_addr *saddr,
@@ -1294,7 +1298,7 @@ do_append_data:
1294 getfrag = is_udplite ? udplite_getfrag : ip_generic_getfrag; 1298 getfrag = is_udplite ? udplite_getfrag : ip_generic_getfrag;
1295 err = ip6_append_data(sk, getfrag, msg->msg_iov, ulen, 1299 err = ip6_append_data(sk, getfrag, msg->msg_iov, ulen,
1296 sizeof(struct udphdr), hlimit, tclass, opt, &fl6, 1300 sizeof(struct udphdr), hlimit, tclass, opt, &fl6,
1297 (struct rt6_info*)dst, 1301 (struct rt6_info *)dst,
1298 corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags, dontfrag); 1302 corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags, dontfrag);
1299 if (err) 1303 if (err)
1300 udp_v6_flush_pending_frames(sk); 1304 udp_v6_flush_pending_frames(sk);
diff --git a/net/ipv6/udp_offload.c b/net/ipv6/udp_offload.c
index 0ae3d98f83e0..6b8f543f6ac6 100644
--- a/net/ipv6/udp_offload.c
+++ b/net/ipv6/udp_offload.c
@@ -10,34 +10,13 @@
10 * UDPv6 GSO support 10 * UDPv6 GSO support
11 */ 11 */
12#include <linux/skbuff.h> 12#include <linux/skbuff.h>
13#include <linux/netdevice.h>
13#include <net/protocol.h> 14#include <net/protocol.h>
14#include <net/ipv6.h> 15#include <net/ipv6.h>
15#include <net/udp.h> 16#include <net/udp.h>
16#include <net/ip6_checksum.h> 17#include <net/ip6_checksum.h>
17#include "ip6_offload.h" 18#include "ip6_offload.h"
18 19
19static int udp6_ufo_send_check(struct sk_buff *skb)
20{
21 const struct ipv6hdr *ipv6h;
22 struct udphdr *uh;
23
24 if (!pskb_may_pull(skb, sizeof(*uh)))
25 return -EINVAL;
26
27 if (likely(!skb->encapsulation)) {
28 ipv6h = ipv6_hdr(skb);
29 uh = udp_hdr(skb);
30
31 uh->check = ~csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr, skb->len,
32 IPPROTO_UDP, 0);
33 skb->csum_start = skb_transport_header(skb) - skb->head;
34 skb->csum_offset = offsetof(struct udphdr, check);
35 skb->ip_summed = CHECKSUM_PARTIAL;
36 }
37
38 return 0;
39}
40
41static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, 20static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb,
42 netdev_features_t features) 21 netdev_features_t features)
43{ 22{
@@ -48,7 +27,6 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb,
48 u8 *packet_start, *prevhdr; 27 u8 *packet_start, *prevhdr;
49 u8 nexthdr; 28 u8 nexthdr;
50 u8 frag_hdr_sz = sizeof(struct frag_hdr); 29 u8 frag_hdr_sz = sizeof(struct frag_hdr);
51 int offset;
52 __wsum csum; 30 __wsum csum;
53 int tnl_hlen; 31 int tnl_hlen;
54 32
@@ -80,15 +58,29 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb,
80 58
81 if (skb->encapsulation && skb_shinfo(skb)->gso_type & 59 if (skb->encapsulation && skb_shinfo(skb)->gso_type &
82 (SKB_GSO_UDP_TUNNEL|SKB_GSO_UDP_TUNNEL_CSUM)) 60 (SKB_GSO_UDP_TUNNEL|SKB_GSO_UDP_TUNNEL_CSUM))
83 segs = skb_udp_tunnel_segment(skb, features); 61 segs = skb_udp_tunnel_segment(skb, features, true);
84 else { 62 else {
63 const struct ipv6hdr *ipv6h;
64 struct udphdr *uh;
65
66 if (!pskb_may_pull(skb, sizeof(struct udphdr)))
67 goto out;
68
85 /* Do software UFO. Complete and fill in the UDP checksum as HW cannot 69 /* Do software UFO. Complete and fill in the UDP checksum as HW cannot
86 * do checksum of UDP packets sent as multiple IP fragments. 70 * do checksum of UDP packets sent as multiple IP fragments.
87 */ 71 */
88 offset = skb_checksum_start_offset(skb); 72
89 csum = skb_checksum(skb, offset, skb->len - offset, 0); 73 uh = udp_hdr(skb);
90 offset += skb->csum_offset; 74 ipv6h = ipv6_hdr(skb);
91 *(__sum16 *)(skb->data + offset) = csum_fold(csum); 75
76 uh->check = 0;
77 csum = skb_checksum(skb, 0, skb->len, 0);
78 uh->check = udp_v6_check(skb->len, &ipv6h->saddr,
79 &ipv6h->daddr, csum);
80
81 if (uh->check == 0)
82 uh->check = CSUM_MANGLED_0;
83
92 skb->ip_summed = CHECKSUM_NONE; 84 skb->ip_summed = CHECKSUM_NONE;
93 85
94 /* Check if there is enough headroom to insert fragment header. */ 86 /* Check if there is enough headroom to insert fragment header. */
@@ -127,10 +119,52 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb,
127out: 119out:
128 return segs; 120 return segs;
129} 121}
122
123static struct sk_buff **udp6_gro_receive(struct sk_buff **head,
124 struct sk_buff *skb)
125{
126 struct udphdr *uh = udp_gro_udphdr(skb);
127
128 if (unlikely(!uh))
129 goto flush;
130
131 /* Don't bother verifying checksum if we're going to flush anyway. */
132 if (NAPI_GRO_CB(skb)->flush)
133 goto skip;
134
135 if (skb_gro_checksum_validate_zero_check(skb, IPPROTO_UDP, uh->check,
136 ip6_gro_compute_pseudo))
137 goto flush;
138 else if (uh->check)
139 skb_gro_checksum_try_convert(skb, IPPROTO_UDP, uh->check,
140 ip6_gro_compute_pseudo);
141
142skip:
143 NAPI_GRO_CB(skb)->is_ipv6 = 1;
144 return udp_gro_receive(head, skb, uh);
145
146flush:
147 NAPI_GRO_CB(skb)->flush = 1;
148 return NULL;
149}
150
151static int udp6_gro_complete(struct sk_buff *skb, int nhoff)
152{
153 const struct ipv6hdr *ipv6h = ipv6_hdr(skb);
154 struct udphdr *uh = (struct udphdr *)(skb->data + nhoff);
155
156 if (uh->check)
157 uh->check = ~udp_v6_check(skb->len - nhoff, &ipv6h->saddr,
158 &ipv6h->daddr, 0);
159
160 return udp_gro_complete(skb, nhoff);
161}
162
130static const struct net_offload udpv6_offload = { 163static const struct net_offload udpv6_offload = {
131 .callbacks = { 164 .callbacks = {
132 .gso_send_check = udp6_ufo_send_check,
133 .gso_segment = udp6_ufo_fragment, 165 .gso_segment = udp6_ufo_fragment,
166 .gro_receive = udp6_gro_receive,
167 .gro_complete = udp6_gro_complete,
134 }, 168 },
135}; 169};
136 170
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c
index f8c3cf842f53..f48fbe4d16f5 100644
--- a/net/ipv6/xfrm6_input.c
+++ b/net/ipv6/xfrm6_input.c
@@ -3,8 +3,8 @@
3 * 3 *
4 * Authors: 4 * Authors:
5 * Mitsuru KANDA @USAGI 5 * Mitsuru KANDA @USAGI
6 * Kazunori MIYAZAWA @USAGI 6 * Kazunori MIYAZAWA @USAGI
7 * Kunihiro Ishiguro <kunihiro@ipinfusion.com> 7 * Kunihiro Ishiguro <kunihiro@ipinfusion.com>
8 * YOSHIFUJI Hideaki @USAGI 8 * YOSHIFUJI Hideaki @USAGI
9 * IPv6 support 9 * IPv6 support
10 */ 10 */
@@ -52,7 +52,6 @@ int xfrm6_rcv(struct sk_buff *skb)
52 return xfrm6_rcv_spi(skb, skb_network_header(skb)[IP6CB(skb)->nhoff], 52 return xfrm6_rcv_spi(skb, skb_network_header(skb)[IP6CB(skb)->nhoff],
53 0); 53 0);
54} 54}
55
56EXPORT_SYMBOL(xfrm6_rcv); 55EXPORT_SYMBOL(xfrm6_rcv);
57 56
58int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, 57int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
@@ -142,5 +141,4 @@ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
142drop: 141drop:
143 return -1; 142 return -1;
144} 143}
145
146EXPORT_SYMBOL(xfrm6_input_addr); 144EXPORT_SYMBOL(xfrm6_input_addr);
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c
index 433672d07d0b..ca3f29b98ae5 100644
--- a/net/ipv6/xfrm6_output.c
+++ b/net/ipv6/xfrm6_output.c
@@ -25,7 +25,6 @@ int xfrm6_find_1stfragopt(struct xfrm_state *x, struct sk_buff *skb,
25{ 25{
26 return ip6_find_1stfragopt(skb, prevhdr); 26 return ip6_find_1stfragopt(skb, prevhdr);
27} 27}
28
29EXPORT_SYMBOL(xfrm6_find_1stfragopt); 28EXPORT_SYMBOL(xfrm6_find_1stfragopt);
30 29
31static int xfrm6_local_dontfrag(struct sk_buff *skb) 30static int xfrm6_local_dontfrag(struct sk_buff *skb)
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 2a0bbda2c76a..ac49f84fe2c3 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -3,11 +3,11 @@
3 * 3 *
4 * Authors: 4 * Authors:
5 * Mitsuru KANDA @USAGI 5 * Mitsuru KANDA @USAGI
6 * Kazunori MIYAZAWA @USAGI 6 * Kazunori MIYAZAWA @USAGI
7 * Kunihiro Ishiguro <kunihiro@ipinfusion.com> 7 * Kunihiro Ishiguro <kunihiro@ipinfusion.com>
8 * IPv6 support 8 * IPv6 support
9 * YOSHIFUJI Hideaki 9 * YOSHIFUJI Hideaki
10 * Split up af-specific portion 10 * Split up af-specific portion
11 * 11 *
12 */ 12 */
13 13
@@ -84,7 +84,7 @@ static int xfrm6_init_path(struct xfrm_dst *path, struct dst_entry *dst,
84 int nfheader_len) 84 int nfheader_len)
85{ 85{
86 if (dst->ops->family == AF_INET6) { 86 if (dst->ops->family == AF_INET6) {
87 struct rt6_info *rt = (struct rt6_info*)dst; 87 struct rt6_info *rt = (struct rt6_info *)dst;
88 if (rt->rt6i_node) 88 if (rt->rt6i_node)
89 path->path_cookie = rt->rt6i_node->fn_sernum; 89 path->path_cookie = rt->rt6i_node->fn_sernum;
90 } 90 }
@@ -97,7 +97,7 @@ static int xfrm6_init_path(struct xfrm_dst *path, struct dst_entry *dst,
97static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev, 97static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
98 const struct flowi *fl) 98 const struct flowi *fl)
99{ 99{
100 struct rt6_info *rt = (struct rt6_info*)xdst->route; 100 struct rt6_info *rt = (struct rt6_info *)xdst->route;
101 101
102 xdst->u.dst.dev = dev; 102 xdst->u.dst.dev = dev;
103 dev_hold(dev); 103 dev_hold(dev);
@@ -296,7 +296,7 @@ static struct xfrm_policy_afinfo xfrm6_policy_afinfo = {
296 .family = AF_INET6, 296 .family = AF_INET6,
297 .dst_ops = &xfrm6_dst_ops, 297 .dst_ops = &xfrm6_dst_ops,
298 .dst_lookup = xfrm6_dst_lookup, 298 .dst_lookup = xfrm6_dst_lookup,
299 .get_saddr = xfrm6_get_saddr, 299 .get_saddr = xfrm6_get_saddr,
300 .decode_session = _decode_session6, 300 .decode_session = _decode_session6,
301 .get_tos = xfrm6_get_tos, 301 .get_tos = xfrm6_get_tos,
302 .init_dst = xfrm6_init_dst, 302 .init_dst = xfrm6_init_dst,
@@ -319,9 +319,9 @@ static void xfrm6_policy_fini(void)
319static struct ctl_table xfrm6_policy_table[] = { 319static struct ctl_table xfrm6_policy_table[] = {
320 { 320 {
321 .procname = "xfrm6_gc_thresh", 321 .procname = "xfrm6_gc_thresh",
322 .data = &init_net.xfrm.xfrm6_dst_ops.gc_thresh, 322 .data = &init_net.xfrm.xfrm6_dst_ops.gc_thresh,
323 .maxlen = sizeof(int), 323 .maxlen = sizeof(int),
324 .mode = 0644, 324 .mode = 0644,
325 .proc_handler = proc_dointvec, 325 .proc_handler = proc_dointvec,
326 }, 326 },
327 { } 327 { }
diff --git a/net/ipv6/xfrm6_state.c b/net/ipv6/xfrm6_state.c
index 3fc970135fc6..8a1f9c0d2a13 100644
--- a/net/ipv6/xfrm6_state.c
+++ b/net/ipv6/xfrm6_state.c
@@ -3,11 +3,11 @@
3 * 3 *
4 * Authors: 4 * Authors:
5 * Mitsuru KANDA @USAGI 5 * Mitsuru KANDA @USAGI
6 * Kazunori MIYAZAWA @USAGI 6 * Kazunori MIYAZAWA @USAGI
7 * Kunihiro Ishiguro <kunihiro@ipinfusion.com> 7 * Kunihiro Ishiguro <kunihiro@ipinfusion.com>
8 * IPv6 support 8 * IPv6 support
9 * YOSHIFUJI Hideaki @USAGI 9 * YOSHIFUJI Hideaki @USAGI
10 * Split up af-specific portion 10 * Split up af-specific portion
11 * 11 *
12 */ 12 */
13 13
@@ -45,10 +45,10 @@ xfrm6_init_temprop(struct xfrm_state *x, const struct xfrm_tmpl *tmpl,
45 const xfrm_address_t *daddr, const xfrm_address_t *saddr) 45 const xfrm_address_t *daddr, const xfrm_address_t *saddr)
46{ 46{
47 x->id = tmpl->id; 47 x->id = tmpl->id;
48 if (ipv6_addr_any((struct in6_addr*)&x->id.daddr)) 48 if (ipv6_addr_any((struct in6_addr *)&x->id.daddr))
49 memcpy(&x->id.daddr, daddr, sizeof(x->sel.daddr)); 49 memcpy(&x->id.daddr, daddr, sizeof(x->sel.daddr));
50 memcpy(&x->props.saddr, &tmpl->saddr, sizeof(x->props.saddr)); 50 memcpy(&x->props.saddr, &tmpl->saddr, sizeof(x->props.saddr));
51 if (ipv6_addr_any((struct in6_addr*)&x->props.saddr)) 51 if (ipv6_addr_any((struct in6_addr *)&x->props.saddr))
52 memcpy(&x->props.saddr, saddr, sizeof(x->props.saddr)); 52 memcpy(&x->props.saddr, saddr, sizeof(x->props.saddr));
53 x->props.mode = tmpl->mode; 53 x->props.mode = tmpl->mode;
54 x->props.reqid = tmpl->reqid; 54 x->props.reqid = tmpl->reqid;
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
index 1c66465a42dd..5743044cd660 100644
--- a/net/ipv6/xfrm6_tunnel.c
+++ b/net/ipv6/xfrm6_tunnel.c
@@ -15,7 +15,7 @@
15 * along with this program; if not, see <http://www.gnu.org/licenses/>. 15 * along with this program; if not, see <http://www.gnu.org/licenses/>.
16 * 16 *
17 * Authors Mitsuru KANDA <mk@linux-ipv6.org> 17 * Authors Mitsuru KANDA <mk@linux-ipv6.org>
18 * YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> 18 * YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
19 * 19 *
20 * Based on net/ipv4/xfrm4_tunnel.c 20 * Based on net/ipv4/xfrm4_tunnel.c
21 * 21 *
@@ -110,7 +110,6 @@ __be32 xfrm6_tunnel_spi_lookup(struct net *net, const xfrm_address_t *saddr)
110 rcu_read_unlock_bh(); 110 rcu_read_unlock_bh();
111 return htonl(spi); 111 return htonl(spi);
112} 112}
113
114EXPORT_SYMBOL(xfrm6_tunnel_spi_lookup); 113EXPORT_SYMBOL(xfrm6_tunnel_spi_lookup);
115 114
116static int __xfrm6_tunnel_spi_check(struct net *net, u32 spi) 115static int __xfrm6_tunnel_spi_check(struct net *net, u32 spi)
@@ -187,7 +186,6 @@ __be32 xfrm6_tunnel_alloc_spi(struct net *net, xfrm_address_t *saddr)
187 186
188 return htonl(spi); 187 return htonl(spi);
189} 188}
190
191EXPORT_SYMBOL(xfrm6_tunnel_alloc_spi); 189EXPORT_SYMBOL(xfrm6_tunnel_alloc_spi);
192 190
193static void x6spi_destroy_rcu(struct rcu_head *head) 191static void x6spi_destroy_rcu(struct rcu_head *head)