aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/Kconfig2
-rw-r--r--net/ipv6/Makefile2
-rw-r--r--net/ipv6/addrconf.c208
-rw-r--r--net/ipv6/addrlabel.c12
-rw-r--r--net/ipv6/af_inet6.c7
-rw-r--r--net/ipv6/datagram.c20
-rw-r--r--net/ipv6/icmp.c41
-rw-r--r--net/ipv6/inet6_connection_sock.c10
-rw-r--r--net/ipv6/ip6_flowlabel.c11
-rw-r--r--net/ipv6/ip6_gre.c62
-rw-r--r--net/ipv6/ip6_icmp.c47
-rw-r--r--net/ipv6/ip6_offload.c4
-rw-r--r--net/ipv6/ip6_output.c7
-rw-r--r--net/ipv6/ip6_tunnel.c16
-rw-r--r--net/ipv6/ip6mr.c10
-rw-r--r--net/ipv6/ndisc.c2
-rw-r--r--net/ipv6/netfilter.c12
-rw-r--r--net/ipv6/netfilter/Kconfig2
-rw-r--r--net/ipv6/netfilter/ip6_tables.c4
-rw-r--r--net/ipv6/netfilter/ip6t_NPT.c11
-rw-r--r--net/ipv6/netfilter/ip6t_REJECT.c2
-rw-r--r--net/ipv6/netfilter/ip6table_mangle.c9
-rw-r--r--net/ipv6/netfilter/ip6table_nat.c23
-rw-r--r--net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c8
-rw-r--r--net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c7
-rw-r--r--net/ipv6/netfilter/nf_conntrack_reasm.c22
-rw-r--r--net/ipv6/proc.c9
-rw-r--r--net/ipv6/raw.c9
-rw-r--r--net/ipv6/reassembly.c23
-rw-r--r--net/ipv6/route.c6
-rw-r--r--net/ipv6/sit.c41
-rw-r--r--net/ipv6/syncookies.c3
-rw-r--r--net/ipv6/tcp_ipv6.c75
-rw-r--r--net/ipv6/udp.c34
-rw-r--r--net/ipv6/udp_offload.c8
-rw-r--r--net/ipv6/xfrm6_mode_tunnel.c7
36 files changed, 468 insertions, 308 deletions
diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig
index ed0b9e2e797a..11b13ea69db4 100644
--- a/net/ipv6/Kconfig
+++ b/net/ipv6/Kconfig
@@ -156,6 +156,7 @@ config INET6_XFRM_MODE_ROUTEOPTIMIZATION
156config IPV6_SIT 156config IPV6_SIT
157 tristate "IPv6: IPv6-in-IPv4 tunnel (SIT driver)" 157 tristate "IPv6: IPv6-in-IPv4 tunnel (SIT driver)"
158 select INET_TUNNEL 158 select INET_TUNNEL
159 select NET_IP_TUNNEL
159 select IPV6_NDISC_NODETYPE 160 select IPV6_NDISC_NODETYPE
160 default y 161 default y
161 ---help--- 162 ---help---
@@ -201,6 +202,7 @@ config IPV6_TUNNEL
201config IPV6_GRE 202config IPV6_GRE
202 tristate "IPv6: GRE tunnel" 203 tristate "IPv6: GRE tunnel"
203 select IPV6_TUNNEL 204 select IPV6_TUNNEL
205 select NET_IP_TUNNEL
204 ---help--- 206 ---help---
205 Tunneling means encapsulating data of one protocol type within 207 Tunneling means encapsulating data of one protocol type within
206 another protocol and sending it over a channel that understands the 208 another protocol and sending it over a channel that understands the
diff --git a/net/ipv6/Makefile b/net/ipv6/Makefile
index 309af19a0a0a..9af088d2cdaa 100644
--- a/net/ipv6/Makefile
+++ b/net/ipv6/Makefile
@@ -40,7 +40,7 @@ obj-$(CONFIG_IPV6_SIT) += sit.o
40obj-$(CONFIG_IPV6_TUNNEL) += ip6_tunnel.o 40obj-$(CONFIG_IPV6_TUNNEL) += ip6_tunnel.o
41obj-$(CONFIG_IPV6_GRE) += ip6_gre.o 41obj-$(CONFIG_IPV6_GRE) += ip6_gre.o
42 42
43obj-y += addrconf_core.o exthdrs_core.o ip6_checksum.o 43obj-y += addrconf_core.o exthdrs_core.o ip6_checksum.o ip6_icmp.o
44obj-$(CONFIG_INET) += output_core.o protocol.o $(ipv6-offload) 44obj-$(CONFIG_INET) += output_core.o protocol.o $(ipv6-offload)
45 45
46obj-$(subst m,y,$(CONFIG_IPV6)) += inet6_hashtables.o 46obj-$(subst m,y,$(CONFIG_IPV6)) += inet6_hashtables.o
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index dae802c0af7c..d1ab6ab29a55 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -70,6 +70,7 @@
70#include <net/snmp.h> 70#include <net/snmp.h>
71 71
72#include <net/af_ieee802154.h> 72#include <net/af_ieee802154.h>
73#include <net/firewire.h>
73#include <net/ipv6.h> 74#include <net/ipv6.h>
74#include <net/protocol.h> 75#include <net/protocol.h>
75#include <net/ndisc.h> 76#include <net/ndisc.h>
@@ -419,6 +420,7 @@ static struct inet6_dev *ipv6_add_dev(struct net_device *dev)
419 ipv6_regen_rndid((unsigned long) ndev); 420 ipv6_regen_rndid((unsigned long) ndev);
420 } 421 }
421#endif 422#endif
423 ndev->token = in6addr_any;
422 424
423 if (netif_running(dev) && addrconf_qdisc_ok(dev)) 425 if (netif_running(dev) && addrconf_qdisc_ok(dev))
424 ndev->if_flags |= IF_READY; 426 ndev->if_flags |= IF_READY;
@@ -542,8 +544,7 @@ static const struct nla_policy devconf_ipv6_policy[NETCONFA_MAX+1] = {
542}; 544};
543 545
544static int inet6_netconf_get_devconf(struct sk_buff *in_skb, 546static int inet6_netconf_get_devconf(struct sk_buff *in_skb,
545 struct nlmsghdr *nlh, 547 struct nlmsghdr *nlh)
546 void *arg)
547{ 548{
548 struct net *net = sock_net(in_skb->sk); 549 struct net *net = sock_net(in_skb->sk);
549 struct nlattr *tb[NETCONFA_MAX+1]; 550 struct nlattr *tb[NETCONFA_MAX+1];
@@ -603,6 +604,77 @@ errout:
603 return err; 604 return err;
604} 605}
605 606
607static int inet6_netconf_dump_devconf(struct sk_buff *skb,
608 struct netlink_callback *cb)
609{
610 struct net *net = sock_net(skb->sk);
611 int h, s_h;
612 int idx, s_idx;
613 struct net_device *dev;
614 struct inet6_dev *idev;
615 struct hlist_head *head;
616
617 s_h = cb->args[0];
618 s_idx = idx = cb->args[1];
619
620 for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
621 idx = 0;
622 head = &net->dev_index_head[h];
623 rcu_read_lock();
624 cb->seq = atomic_read(&net->ipv6.dev_addr_genid) ^
625 net->dev_base_seq;
626 hlist_for_each_entry_rcu(dev, head, index_hlist) {
627 if (idx < s_idx)
628 goto cont;
629 idev = __in6_dev_get(dev);
630 if (!idev)
631 goto cont;
632
633 if (inet6_netconf_fill_devconf(skb, dev->ifindex,
634 &idev->cnf,
635 NETLINK_CB(cb->skb).portid,
636 cb->nlh->nlmsg_seq,
637 RTM_NEWNETCONF,
638 NLM_F_MULTI,
639 -1) <= 0) {
640 rcu_read_unlock();
641 goto done;
642 }
643 nl_dump_check_consistent(cb, nlmsg_hdr(skb));
644cont:
645 idx++;
646 }
647 rcu_read_unlock();
648 }
649 if (h == NETDEV_HASHENTRIES) {
650 if (inet6_netconf_fill_devconf(skb, NETCONFA_IFINDEX_ALL,
651 net->ipv6.devconf_all,
652 NETLINK_CB(cb->skb).portid,
653 cb->nlh->nlmsg_seq,
654 RTM_NEWNETCONF, NLM_F_MULTI,
655 -1) <= 0)
656 goto done;
657 else
658 h++;
659 }
660 if (h == NETDEV_HASHENTRIES + 1) {
661 if (inet6_netconf_fill_devconf(skb, NETCONFA_IFINDEX_DEFAULT,
662 net->ipv6.devconf_dflt,
663 NETLINK_CB(cb->skb).portid,
664 cb->nlh->nlmsg_seq,
665 RTM_NEWNETCONF, NLM_F_MULTI,
666 -1) <= 0)
667 goto done;
668 else
669 h++;
670 }
671done:
672 cb->args[0] = h;
673 cb->args[1] = idx;
674
675 return skb->len;
676}
677
606#ifdef CONFIG_SYSCTL 678#ifdef CONFIG_SYSCTL
607static void dev_forward_change(struct inet6_dev *idev) 679static void dev_forward_change(struct inet6_dev *idev)
608{ 680{
@@ -804,6 +876,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen,
804 ifa->prefix_len = pfxlen; 876 ifa->prefix_len = pfxlen;
805 ifa->flags = flags | IFA_F_TENTATIVE; 877 ifa->flags = flags | IFA_F_TENTATIVE;
806 ifa->cstamp = ifa->tstamp = jiffies; 878 ifa->cstamp = ifa->tstamp = jiffies;
879 ifa->tokenized = false;
807 880
808 ifa->rt = rt; 881 ifa->rt = rt;
809 882
@@ -1666,6 +1739,20 @@ static int addrconf_ifid_eui64(u8 *eui, struct net_device *dev)
1666 return 0; 1739 return 0;
1667} 1740}
1668 1741
1742static int addrconf_ifid_ieee1394(u8 *eui, struct net_device *dev)
1743{
1744 union fwnet_hwaddr *ha;
1745
1746 if (dev->addr_len != FWNET_ALEN)
1747 return -1;
1748
1749 ha = (union fwnet_hwaddr *)dev->dev_addr;
1750
1751 memcpy(eui, &ha->uc.uniq_id, sizeof(ha->uc.uniq_id));
1752 eui[0] ^= 2;
1753 return 0;
1754}
1755
1669static int addrconf_ifid_arcnet(u8 *eui, struct net_device *dev) 1756static int addrconf_ifid_arcnet(u8 *eui, struct net_device *dev)
1670{ 1757{
1671 /* XXX: inherit EUI-64 from other interface -- yoshfuji */ 1758 /* XXX: inherit EUI-64 from other interface -- yoshfuji */
@@ -1730,6 +1817,8 @@ static int ipv6_generate_eui64(u8 *eui, struct net_device *dev)
1730 return addrconf_ifid_gre(eui, dev); 1817 return addrconf_ifid_gre(eui, dev);
1731 case ARPHRD_IEEE802154: 1818 case ARPHRD_IEEE802154:
1732 return addrconf_ifid_eui64(eui, dev); 1819 return addrconf_ifid_eui64(eui, dev);
1820 case ARPHRD_IEEE1394:
1821 return addrconf_ifid_ieee1394(eui, dev);
1733 } 1822 }
1734 return -1; 1823 return -1;
1735} 1824}
@@ -2044,11 +2133,19 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao)
2044 struct inet6_ifaddr *ifp; 2133 struct inet6_ifaddr *ifp;
2045 struct in6_addr addr; 2134 struct in6_addr addr;
2046 int create = 0, update_lft = 0; 2135 int create = 0, update_lft = 0;
2136 bool tokenized = false;
2047 2137
2048 if (pinfo->prefix_len == 64) { 2138 if (pinfo->prefix_len == 64) {
2049 memcpy(&addr, &pinfo->prefix, 8); 2139 memcpy(&addr, &pinfo->prefix, 8);
2050 if (ipv6_generate_eui64(addr.s6_addr + 8, dev) && 2140
2051 ipv6_inherit_eui64(addr.s6_addr + 8, in6_dev)) { 2141 if (!ipv6_addr_any(&in6_dev->token)) {
2142 read_lock_bh(&in6_dev->lock);
2143 memcpy(addr.s6_addr + 8,
2144 in6_dev->token.s6_addr + 8, 8);
2145 read_unlock_bh(&in6_dev->lock);
2146 tokenized = true;
2147 } else if (ipv6_generate_eui64(addr.s6_addr + 8, dev) &&
2148 ipv6_inherit_eui64(addr.s6_addr + 8, in6_dev)) {
2052 in6_dev_put(in6_dev); 2149 in6_dev_put(in6_dev);
2053 return; 2150 return;
2054 } 2151 }
@@ -2089,6 +2186,7 @@ ok:
2089 2186
2090 update_lft = create = 1; 2187 update_lft = create = 1;
2091 ifp->cstamp = jiffies; 2188 ifp->cstamp = jiffies;
2189 ifp->tokenized = tokenized;
2092 addrconf_dad_start(ifp); 2190 addrconf_dad_start(ifp);
2093 } 2191 }
2094 2192
@@ -2598,7 +2696,8 @@ static void addrconf_dev_config(struct net_device *dev)
2598 (dev->type != ARPHRD_FDDI) && 2696 (dev->type != ARPHRD_FDDI) &&
2599 (dev->type != ARPHRD_ARCNET) && 2697 (dev->type != ARPHRD_ARCNET) &&
2600 (dev->type != ARPHRD_INFINIBAND) && 2698 (dev->type != ARPHRD_INFINIBAND) &&
2601 (dev->type != ARPHRD_IEEE802154)) { 2699 (dev->type != ARPHRD_IEEE802154) &&
2700 (dev->type != ARPHRD_IEEE1394)) {
2602 /* Alas, we support only Ethernet autoconfiguration. */ 2701 /* Alas, we support only Ethernet autoconfiguration. */
2603 return; 2702 return;
2604 } 2703 }
@@ -3535,7 +3634,7 @@ static const struct nla_policy ifa_ipv6_policy[IFA_MAX+1] = {
3535}; 3634};
3536 3635
3537static int 3636static int
3538inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) 3637inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh)
3539{ 3638{
3540 struct net *net = sock_net(skb->sk); 3639 struct net *net = sock_net(skb->sk);
3541 struct ifaddrmsg *ifm; 3640 struct ifaddrmsg *ifm;
@@ -3601,7 +3700,7 @@ static int inet6_addr_modify(struct inet6_ifaddr *ifp, u8 ifa_flags,
3601} 3700}
3602 3701
3603static int 3702static int
3604inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) 3703inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh)
3605{ 3704{
3606 struct net *net = sock_net(skb->sk); 3705 struct net *net = sock_net(skb->sk);
3607 struct ifaddrmsg *ifm; 3706 struct ifaddrmsg *ifm;
@@ -3832,6 +3931,7 @@ static int in6_dump_addrs(struct inet6_dev *idev, struct sk_buff *skb,
3832 NLM_F_MULTI); 3931 NLM_F_MULTI);
3833 if (err <= 0) 3932 if (err <= 0)
3834 break; 3933 break;
3934 nl_dump_check_consistent(cb, nlmsg_hdr(skb));
3835 } 3935 }
3836 break; 3936 break;
3837 } 3937 }
@@ -3889,6 +3989,7 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
3889 s_ip_idx = ip_idx = cb->args[2]; 3989 s_ip_idx = ip_idx = cb->args[2];
3890 3990
3891 rcu_read_lock(); 3991 rcu_read_lock();
3992 cb->seq = atomic_read(&net->ipv6.dev_addr_genid) ^ net->dev_base_seq;
3892 for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) { 3993 for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
3893 idx = 0; 3994 idx = 0;
3894 head = &net->dev_index_head[h]; 3995 head = &net->dev_index_head[h];
@@ -3940,8 +4041,7 @@ static int inet6_dump_ifacaddr(struct sk_buff *skb, struct netlink_callback *cb)
3940 return inet6_dump_addr(skb, cb, type); 4041 return inet6_dump_addr(skb, cb, type);
3941} 4042}
3942 4043
3943static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr *nlh, 4044static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr *nlh)
3944 void *arg)
3945{ 4045{
3946 struct net *net = sock_net(in_skb->sk); 4046 struct net *net = sock_net(in_skb->sk);
3947 struct ifaddrmsg *ifm; 4047 struct ifaddrmsg *ifm;
@@ -4074,7 +4174,8 @@ static inline size_t inet6_ifla6_size(void)
4074 + nla_total_size(sizeof(struct ifla_cacheinfo)) 4174 + nla_total_size(sizeof(struct ifla_cacheinfo))
4075 + nla_total_size(DEVCONF_MAX * 4) /* IFLA_INET6_CONF */ 4175 + nla_total_size(DEVCONF_MAX * 4) /* IFLA_INET6_CONF */
4076 + nla_total_size(IPSTATS_MIB_MAX * 8) /* IFLA_INET6_STATS */ 4176 + nla_total_size(IPSTATS_MIB_MAX * 8) /* IFLA_INET6_STATS */
4077 + nla_total_size(ICMP6_MIB_MAX * 8); /* IFLA_INET6_ICMP6STATS */ 4177 + nla_total_size(ICMP6_MIB_MAX * 8) /* IFLA_INET6_ICMP6STATS */
4178 + nla_total_size(sizeof(struct in6_addr)); /* IFLA_INET6_TOKEN */
4078} 4179}
4079 4180
4080static inline size_t inet6_if_nlmsg_size(void) 4181static inline size_t inet6_if_nlmsg_size(void)
@@ -4161,6 +4262,13 @@ static int inet6_fill_ifla6_attrs(struct sk_buff *skb, struct inet6_dev *idev)
4161 goto nla_put_failure; 4262 goto nla_put_failure;
4162 snmp6_fill_stats(nla_data(nla), idev, IFLA_INET6_ICMP6STATS, nla_len(nla)); 4263 snmp6_fill_stats(nla_data(nla), idev, IFLA_INET6_ICMP6STATS, nla_len(nla));
4163 4264
4265 nla = nla_reserve(skb, IFLA_INET6_TOKEN, sizeof(struct in6_addr));
4266 if (nla == NULL)
4267 goto nla_put_failure;
4268 read_lock_bh(&idev->lock);
4269 memcpy(nla_data(nla), idev->token.s6_addr, nla_len(nla));
4270 read_unlock_bh(&idev->lock);
4271
4164 return 0; 4272 return 0;
4165 4273
4166nla_put_failure: 4274nla_put_failure:
@@ -4188,6 +4296,80 @@ static int inet6_fill_link_af(struct sk_buff *skb, const struct net_device *dev)
4188 return 0; 4296 return 0;
4189} 4297}
4190 4298
4299static int inet6_set_iftoken(struct inet6_dev *idev, struct in6_addr *token)
4300{
4301 struct inet6_ifaddr *ifp;
4302 struct net_device *dev = idev->dev;
4303 bool update_rs = false;
4304
4305 if (token == NULL)
4306 return -EINVAL;
4307 if (ipv6_addr_any(token))
4308 return -EINVAL;
4309 if (dev->flags & (IFF_LOOPBACK | IFF_NOARP))
4310 return -EINVAL;
4311 if (!ipv6_accept_ra(idev))
4312 return -EINVAL;
4313 if (idev->cnf.rtr_solicits <= 0)
4314 return -EINVAL;
4315
4316 write_lock_bh(&idev->lock);
4317
4318 BUILD_BUG_ON(sizeof(token->s6_addr) != 16);
4319 memcpy(idev->token.s6_addr + 8, token->s6_addr + 8, 8);
4320
4321 write_unlock_bh(&idev->lock);
4322
4323 if (!idev->dead && (idev->if_flags & IF_READY)) {
4324 struct in6_addr ll_addr;
4325
4326 ipv6_get_lladdr(dev, &ll_addr, IFA_F_TENTATIVE |
4327 IFA_F_OPTIMISTIC);
4328
4329 /* If we're not ready, then normal ifup will take care
4330 * of this. Otherwise, we need to request our rs here.
4331 */
4332 ndisc_send_rs(dev, &ll_addr, &in6addr_linklocal_allrouters);
4333 update_rs = true;
4334 }
4335
4336 write_lock_bh(&idev->lock);
4337
4338 if (update_rs)
4339 idev->if_flags |= IF_RS_SENT;
4340
4341 /* Well, that's kinda nasty ... */
4342 list_for_each_entry(ifp, &idev->addr_list, if_list) {
4343 spin_lock(&ifp->lock);
4344 if (ifp->tokenized) {
4345 ifp->valid_lft = 0;
4346 ifp->prefered_lft = 0;
4347 }
4348 spin_unlock(&ifp->lock);
4349 }
4350
4351 write_unlock_bh(&idev->lock);
4352 return 0;
4353}
4354
4355static int inet6_set_link_af(struct net_device *dev, const struct nlattr *nla)
4356{
4357 int err = -EINVAL;
4358 struct inet6_dev *idev = __in6_dev_get(dev);
4359 struct nlattr *tb[IFLA_INET6_MAX + 1];
4360
4361 if (!idev)
4362 return -EAFNOSUPPORT;
4363
4364 if (nla_parse_nested(tb, IFLA_INET6_MAX, nla, NULL) < 0)
4365 BUG();
4366
4367 if (tb[IFLA_INET6_TOKEN])
4368 err = inet6_set_iftoken(idev, nla_data(tb[IFLA_INET6_TOKEN]));
4369
4370 return err;
4371}
4372
4191static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev, 4373static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev,
4192 u32 portid, u32 seq, int event, unsigned int flags) 4374 u32 portid, u32 seq, int event, unsigned int flags)
4193{ 4375{
@@ -4366,6 +4548,8 @@ errout:
4366 4548
4367static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) 4549static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
4368{ 4550{
4551 struct net *net = dev_net(ifp->idev->dev);
4552
4369 inet6_ifa_notify(event ? : RTM_NEWADDR, ifp); 4553 inet6_ifa_notify(event ? : RTM_NEWADDR, ifp);
4370 4554
4371 switch (event) { 4555 switch (event) {
@@ -4391,6 +4575,7 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
4391 dst_free(&ifp->rt->dst); 4575 dst_free(&ifp->rt->dst);
4392 break; 4576 break;
4393 } 4577 }
4578 atomic_inc(&net->ipv6.dev_addr_genid);
4394} 4579}
4395 4580
4396static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) 4581static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
@@ -4871,6 +5056,7 @@ static struct rtnl_af_ops inet6_ops = {
4871 .family = AF_INET6, 5056 .family = AF_INET6,
4872 .fill_link_af = inet6_fill_link_af, 5057 .fill_link_af = inet6_fill_link_af,
4873 .get_link_af_size = inet6_get_link_af_size, 5058 .get_link_af_size = inet6_get_link_af_size,
5059 .set_link_af = inet6_set_link_af,
4874}; 5060};
4875 5061
4876/* 5062/*
@@ -4943,7 +5129,7 @@ int __init addrconf_init(void)
4943 __rtnl_register(PF_INET6, RTM_GETANYCAST, NULL, 5129 __rtnl_register(PF_INET6, RTM_GETANYCAST, NULL,
4944 inet6_dump_ifacaddr, NULL); 5130 inet6_dump_ifacaddr, NULL);
4945 __rtnl_register(PF_INET6, RTM_GETNETCONF, inet6_netconf_get_devconf, 5131 __rtnl_register(PF_INET6, RTM_GETNETCONF, inet6_netconf_get_devconf,
4946 NULL, NULL); 5132 inet6_netconf_dump_devconf, NULL);
4947 5133
4948 ipv6_addr_label_rtnl_register(); 5134 ipv6_addr_label_rtnl_register();
4949 5135
diff --git a/net/ipv6/addrlabel.c b/net/ipv6/addrlabel.c
index aad64352cb60..f083a583a05c 100644
--- a/net/ipv6/addrlabel.c
+++ b/net/ipv6/addrlabel.c
@@ -414,8 +414,7 @@ static const struct nla_policy ifal_policy[IFAL_MAX+1] = {
414 [IFAL_LABEL] = { .len = sizeof(u32), }, 414 [IFAL_LABEL] = { .len = sizeof(u32), },
415}; 415};
416 416
417static int ip6addrlbl_newdel(struct sk_buff *skb, struct nlmsghdr *nlh, 417static int ip6addrlbl_newdel(struct sk_buff *skb, struct nlmsghdr *nlh)
418 void *arg)
419{ 418{
420 struct net *net = sock_net(skb->sk); 419 struct net *net = sock_net(skb->sk);
421 struct ifaddrlblmsg *ifal; 420 struct ifaddrlblmsg *ifal;
@@ -436,10 +435,7 @@ static int ip6addrlbl_newdel(struct sk_buff *skb, struct nlmsghdr *nlh,
436 435
437 if (!tb[IFAL_ADDRESS]) 436 if (!tb[IFAL_ADDRESS])
438 return -EINVAL; 437 return -EINVAL;
439
440 pfx = nla_data(tb[IFAL_ADDRESS]); 438 pfx = nla_data(tb[IFAL_ADDRESS]);
441 if (!pfx)
442 return -EINVAL;
443 439
444 if (!tb[IFAL_LABEL]) 440 if (!tb[IFAL_LABEL])
445 return -EINVAL; 441 return -EINVAL;
@@ -533,8 +529,7 @@ static inline int ip6addrlbl_msgsize(void)
533 + nla_total_size(4); /* IFAL_LABEL */ 529 + nla_total_size(4); /* IFAL_LABEL */
534} 530}
535 531
536static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr* nlh, 532static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr* nlh)
537 void *arg)
538{ 533{
539 struct net *net = sock_net(in_skb->sk); 534 struct net *net = sock_net(in_skb->sk);
540 struct ifaddrlblmsg *ifal; 535 struct ifaddrlblmsg *ifal;
@@ -561,10 +556,7 @@ static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr* nlh,
561 556
562 if (!tb[IFAL_ADDRESS]) 557 if (!tb[IFAL_ADDRESS])
563 return -EINVAL; 558 return -EINVAL;
564
565 addr = nla_data(tb[IFAL_ADDRESS]); 559 addr = nla_data(tb[IFAL_ADDRESS]);
566 if (!addr)
567 return -EINVAL;
568 560
569 rcu_read_lock(); 561 rcu_read_lock();
570 p = __ipv6_addr_label(net, addr, ipv6_addr_type(addr), ifal->ifal_index); 562 p = __ipv6_addr_label(net, addr, ipv6_addr_type(addr), ifal->ifal_index);
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 6b793bfc0e10..ab5c7ad482cd 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -49,7 +49,6 @@
49#include <net/udp.h> 49#include <net/udp.h>
50#include <net/udplite.h> 50#include <net/udplite.h>
51#include <net/tcp.h> 51#include <net/tcp.h>
52#include <net/ipip.h>
53#include <net/protocol.h> 52#include <net/protocol.h>
54#include <net/inet_common.h> 53#include <net/inet_common.h>
55#include <net/route.h> 54#include <net/route.h>
@@ -323,7 +322,7 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
323 struct net_device *dev = NULL; 322 struct net_device *dev = NULL;
324 323
325 rcu_read_lock(); 324 rcu_read_lock();
326 if (addr_type & IPV6_ADDR_LINKLOCAL) { 325 if (__ipv6_addr_needs_scope_id(addr_type)) {
327 if (addr_len >= sizeof(struct sockaddr_in6) && 326 if (addr_len >= sizeof(struct sockaddr_in6) &&
328 addr->sin6_scope_id) { 327 addr->sin6_scope_id) {
329 /* Override any existing binding, if another one 328 /* Override any existing binding, if another one
@@ -471,8 +470,8 @@ int inet6_getname(struct socket *sock, struct sockaddr *uaddr,
471 470
472 sin->sin6_port = inet->inet_sport; 471 sin->sin6_port = inet->inet_sport;
473 } 472 }
474 if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL) 473 sin->sin6_scope_id = ipv6_iface_scope_id(&sin->sin6_addr,
475 sin->sin6_scope_id = sk->sk_bound_dev_if; 474 sk->sk_bound_dev_if);
476 *uaddr_len = sizeof(*sin); 475 *uaddr_len = sizeof(*sin);
477 return 0; 476 return 0;
478} 477}
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index f5a54782a340..4b56cbbc7890 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -124,7 +124,7 @@ ipv4_connected:
124 goto out; 124 goto out;
125 } 125 }
126 126
127 if (addr_type&IPV6_ADDR_LINKLOCAL) { 127 if (__ipv6_addr_needs_scope_id(addr_type)) {
128 if (addr_len >= sizeof(struct sockaddr_in6) && 128 if (addr_len >= sizeof(struct sockaddr_in6) &&
129 usin->sin6_scope_id) { 129 usin->sin6_scope_id) {
130 if (sk->sk_bound_dev_if && 130 if (sk->sk_bound_dev_if &&
@@ -355,18 +355,19 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
355 sin->sin6_family = AF_INET6; 355 sin->sin6_family = AF_INET6;
356 sin->sin6_flowinfo = 0; 356 sin->sin6_flowinfo = 0;
357 sin->sin6_port = serr->port; 357 sin->sin6_port = serr->port;
358 sin->sin6_scope_id = 0;
359 if (skb->protocol == htons(ETH_P_IPV6)) { 358 if (skb->protocol == htons(ETH_P_IPV6)) {
360 const struct ipv6hdr *ip6h = container_of((struct in6_addr *)(nh + serr->addr_offset), 359 const struct ipv6hdr *ip6h = container_of((struct in6_addr *)(nh + serr->addr_offset),
361 struct ipv6hdr, daddr); 360 struct ipv6hdr, daddr);
362 sin->sin6_addr = ip6h->daddr; 361 sin->sin6_addr = ip6h->daddr;
363 if (np->sndflow) 362 if (np->sndflow)
364 sin->sin6_flowinfo = ip6_flowinfo(ip6h); 363 sin->sin6_flowinfo = ip6_flowinfo(ip6h);
365 if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL) 364 sin->sin6_scope_id =
366 sin->sin6_scope_id = IP6CB(skb)->iif; 365 ipv6_iface_scope_id(&sin->sin6_addr,
366 IP6CB(skb)->iif);
367 } else { 367 } else {
368 ipv6_addr_set_v4mapped(*(__be32 *)(nh + serr->addr_offset), 368 ipv6_addr_set_v4mapped(*(__be32 *)(nh + serr->addr_offset),
369 &sin->sin6_addr); 369 &sin->sin6_addr);
370 sin->sin6_scope_id = 0;
370 } 371 }
371 } 372 }
372 373
@@ -376,18 +377,19 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
376 if (serr->ee.ee_origin != SO_EE_ORIGIN_LOCAL) { 377 if (serr->ee.ee_origin != SO_EE_ORIGIN_LOCAL) {
377 sin->sin6_family = AF_INET6; 378 sin->sin6_family = AF_INET6;
378 sin->sin6_flowinfo = 0; 379 sin->sin6_flowinfo = 0;
379 sin->sin6_scope_id = 0;
380 if (skb->protocol == htons(ETH_P_IPV6)) { 380 if (skb->protocol == htons(ETH_P_IPV6)) {
381 sin->sin6_addr = ipv6_hdr(skb)->saddr; 381 sin->sin6_addr = ipv6_hdr(skb)->saddr;
382 if (np->rxopt.all) 382 if (np->rxopt.all)
383 ip6_datagram_recv_ctl(sk, msg, skb); 383 ip6_datagram_recv_ctl(sk, msg, skb);
384 if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL) 384 sin->sin6_scope_id =
385 sin->sin6_scope_id = IP6CB(skb)->iif; 385 ipv6_iface_scope_id(&sin->sin6_addr,
386 IP6CB(skb)->iif);
386 } else { 387 } else {
387 struct inet_sock *inet = inet_sk(sk); 388 struct inet_sock *inet = inet_sk(sk);
388 389
389 ipv6_addr_set_v4mapped(ip_hdr(skb)->saddr, 390 ipv6_addr_set_v4mapped(ip_hdr(skb)->saddr,
390 &sin->sin6_addr); 391 &sin->sin6_addr);
392 sin->sin6_scope_id = 0;
391 if (inet->cmsg_flags) 393 if (inet->cmsg_flags)
392 ip_cmsg_recv(msg, skb); 394 ip_cmsg_recv(msg, skb);
393 } 395 }
@@ -592,7 +594,9 @@ int ip6_datagram_recv_ctl(struct sock *sk, struct msghdr *msg,
592 sin6.sin6_addr = ipv6_hdr(skb)->daddr; 594 sin6.sin6_addr = ipv6_hdr(skb)->daddr;
593 sin6.sin6_port = ports[1]; 595 sin6.sin6_port = ports[1];
594 sin6.sin6_flowinfo = 0; 596 sin6.sin6_flowinfo = 0;
595 sin6.sin6_scope_id = 0; 597 sin6.sin6_scope_id =
598 ipv6_iface_scope_id(&ipv6_hdr(skb)->daddr,
599 opt->iif);
596 600
597 put_cmsg(msg, SOL_IPV6, IPV6_ORIGDSTADDR, sizeof(sin6), &sin6); 601 put_cmsg(msg, SOL_IPV6, IPV6_ORIGDSTADDR, sizeof(sin6), &sin6);
598 } 602 }
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index fff5bdd8b680..b4ff0a42b8c7 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -124,15 +124,6 @@ static __inline__ void icmpv6_xmit_unlock(struct sock *sk)
124} 124}
125 125
126/* 126/*
127 * Slightly more convenient version of icmpv6_send.
128 */
129void icmpv6_param_prob(struct sk_buff *skb, u8 code, int pos)
130{
131 icmpv6_send(skb, ICMPV6_PARAMPROB, code, pos);
132 kfree_skb(skb);
133}
134
135/*
136 * Figure out, may we reply to this packet with icmp error. 127 * Figure out, may we reply to this packet with icmp error.
137 * 128 *
138 * We do not reply, if: 129 * We do not reply, if:
@@ -332,7 +323,7 @@ static struct dst_entry *icmpv6_route_lookup(struct net *net, struct sk_buff *sk
332 * anycast. 323 * anycast.
333 */ 324 */
334 if (((struct rt6_info *)dst)->rt6i_flags & RTF_ANYCAST) { 325 if (((struct rt6_info *)dst)->rt6i_flags & RTF_ANYCAST) {
335 LIMIT_NETDEBUG(KERN_DEBUG "icmpv6_send: acast source\n"); 326 LIMIT_NETDEBUG(KERN_DEBUG "icmp6_send: acast source\n");
336 dst_release(dst); 327 dst_release(dst);
337 return ERR_PTR(-EINVAL); 328 return ERR_PTR(-EINVAL);
338 } 329 }
@@ -381,7 +372,7 @@ relookup_failed:
381/* 372/*
382 * Send an ICMP message in response to a packet in error 373 * Send an ICMP message in response to a packet in error
383 */ 374 */
384void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info) 375static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
385{ 376{
386 struct net *net = dev_net(skb->dev); 377 struct net *net = dev_net(skb->dev);
387 struct inet6_dev *idev = NULL; 378 struct inet6_dev *idev = NULL;
@@ -406,7 +397,7 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
406 /* 397 /*
407 * Make sure we respect the rules 398 * Make sure we respect the rules
408 * i.e. RFC 1885 2.4(e) 399 * i.e. RFC 1885 2.4(e)
409 * Rule (e.1) is enforced by not using icmpv6_send 400 * Rule (e.1) is enforced by not using icmp6_send
410 * in any code that processes icmp errors. 401 * in any code that processes icmp errors.
411 */ 402 */
412 addr_type = ipv6_addr_type(&hdr->daddr); 403 addr_type = ipv6_addr_type(&hdr->daddr);
@@ -434,7 +425,7 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
434 * Source addr check 425 * Source addr check
435 */ 426 */
436 427
437 if (addr_type & IPV6_ADDR_LINKLOCAL) 428 if (__ipv6_addr_needs_scope_id(addr_type))
438 iif = skb->dev->ifindex; 429 iif = skb->dev->ifindex;
439 430
440 /* 431 /*
@@ -444,7 +435,7 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
444 * and anycast addresses will be checked later. 435 * and anycast addresses will be checked later.
445 */ 436 */
446 if ((addr_type == IPV6_ADDR_ANY) || (addr_type & IPV6_ADDR_MULTICAST)) { 437 if ((addr_type == IPV6_ADDR_ANY) || (addr_type & IPV6_ADDR_MULTICAST)) {
447 LIMIT_NETDEBUG(KERN_DEBUG "icmpv6_send: addr_any/mcast source\n"); 438 LIMIT_NETDEBUG(KERN_DEBUG "icmp6_send: addr_any/mcast source\n");
448 return; 439 return;
449 } 440 }
450 441
@@ -452,7 +443,7 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
452 * Never answer to a ICMP packet. 443 * Never answer to a ICMP packet.
453 */ 444 */
454 if (is_ineligible(skb)) { 445 if (is_ineligible(skb)) {
455 LIMIT_NETDEBUG(KERN_DEBUG "icmpv6_send: no reply to icmp error\n"); 446 LIMIT_NETDEBUG(KERN_DEBUG "icmp6_send: no reply to icmp error\n");
456 return; 447 return;
457 } 448 }
458 449
@@ -529,7 +520,14 @@ out_dst_release:
529out: 520out:
530 icmpv6_xmit_unlock(sk); 521 icmpv6_xmit_unlock(sk);
531} 522}
532EXPORT_SYMBOL(icmpv6_send); 523
524/* Slightly more convenient version of icmp6_send.
525 */
526void icmpv6_param_prob(struct sk_buff *skb, u8 code, int pos)
527{
528 icmp6_send(skb, ICMPV6_PARAMPROB, code, pos);
529 kfree_skb(skb);
530}
533 531
534static void icmpv6_echo_reply(struct sk_buff *skb) 532static void icmpv6_echo_reply(struct sk_buff *skb)
535{ 533{
@@ -701,7 +699,7 @@ static int icmpv6_rcv(struct sk_buff *skb)
701 if (__skb_checksum_complete(skb)) { 699 if (__skb_checksum_complete(skb)) {
702 LIMIT_NETDEBUG(KERN_DEBUG "ICMPv6 checksum failed [%pI6 > %pI6]\n", 700 LIMIT_NETDEBUG(KERN_DEBUG "ICMPv6 checksum failed [%pI6 > %pI6]\n",
703 saddr, daddr); 701 saddr, daddr);
704 goto discard_it; 702 goto csum_error;
705 } 703 }
706 } 704 }
707 705
@@ -787,6 +785,8 @@ static int icmpv6_rcv(struct sk_buff *skb)
787 kfree_skb(skb); 785 kfree_skb(skb);
788 return 0; 786 return 0;
789 787
788csum_error:
789 ICMP6_INC_STATS_BH(dev_net(dev), idev, ICMP6_MIB_CSUMERRORS);
790discard_it: 790discard_it:
791 ICMP6_INC_STATS_BH(dev_net(dev), idev, ICMP6_MIB_INERRORS); 791 ICMP6_INC_STATS_BH(dev_net(dev), idev, ICMP6_MIB_INERRORS);
792drop_no_count: 792drop_no_count:
@@ -885,8 +885,14 @@ int __init icmpv6_init(void)
885 err = -EAGAIN; 885 err = -EAGAIN;
886 if (inet6_add_protocol(&icmpv6_protocol, IPPROTO_ICMPV6) < 0) 886 if (inet6_add_protocol(&icmpv6_protocol, IPPROTO_ICMPV6) < 0)
887 goto fail; 887 goto fail;
888
889 err = inet6_register_icmp_sender(icmp6_send);
890 if (err)
891 goto sender_reg_err;
888 return 0; 892 return 0;
889 893
894sender_reg_err:
895 inet6_del_protocol(&icmpv6_protocol, IPPROTO_ICMPV6);
890fail: 896fail:
891 pr_err("Failed to register ICMP6 protocol\n"); 897 pr_err("Failed to register ICMP6 protocol\n");
892 unregister_pernet_subsys(&icmpv6_sk_ops); 898 unregister_pernet_subsys(&icmpv6_sk_ops);
@@ -895,6 +901,7 @@ fail:
895 901
896void icmpv6_cleanup(void) 902void icmpv6_cleanup(void)
897{ 903{
904 inet6_unregister_icmp_sender(icmp6_send);
898 unregister_pernet_subsys(&icmpv6_sk_ops); 905 unregister_pernet_subsys(&icmpv6_sk_ops);
899 inet6_del_protocol(&icmpv6_protocol, IPPROTO_ICMPV6); 906 inet6_del_protocol(&icmpv6_protocol, IPPROTO_ICMPV6);
900} 907}
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c
index 9bfab19ff3c0..e4311cbc8b4e 100644
--- a/net/ipv6/inet6_connection_sock.c
+++ b/net/ipv6/inet6_connection_sock.c
@@ -54,6 +54,10 @@ int inet6_csk_bind_conflict(const struct sock *sk,
54 if (ipv6_rcv_saddr_equal(sk, sk2)) 54 if (ipv6_rcv_saddr_equal(sk, sk2))
55 break; 55 break;
56 } 56 }
57 if (!relax && reuse && sk2->sk_reuse &&
58 sk2->sk_state != TCP_LISTEN &&
59 ipv6_rcv_saddr_equal(sk, sk2))
60 break;
57 } 61 }
58 } 62 }
59 63
@@ -169,10 +173,8 @@ void inet6_csk_addr2sockaddr(struct sock *sk, struct sockaddr * uaddr)
169 sin6->sin6_port = inet_sk(sk)->inet_dport; 173 sin6->sin6_port = inet_sk(sk)->inet_dport;
170 /* We do not store received flowlabel for TCP */ 174 /* We do not store received flowlabel for TCP */
171 sin6->sin6_flowinfo = 0; 175 sin6->sin6_flowinfo = 0;
172 sin6->sin6_scope_id = 0; 176 sin6->sin6_scope_id = ipv6_iface_scope_id(&sin6->sin6_addr,
173 if (sk->sk_bound_dev_if && 177 sk->sk_bound_dev_if);
174 ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL)
175 sin6->sin6_scope_id = sk->sk_bound_dev_if;
176} 178}
177 179
178EXPORT_SYMBOL_GPL(inet6_csk_addr2sockaddr); 180EXPORT_SYMBOL_GPL(inet6_csk_addr2sockaddr);
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index b973ed3d06cf..46e88433ec7d 100644
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -144,7 +144,9 @@ static void ip6_fl_gc(unsigned long dummy)
144 spin_lock(&ip6_fl_lock); 144 spin_lock(&ip6_fl_lock);
145 145
146 for (i=0; i<=FL_HASH_MASK; i++) { 146 for (i=0; i<=FL_HASH_MASK; i++) {
147 struct ip6_flowlabel *fl, **flp; 147 struct ip6_flowlabel *fl;
148 struct ip6_flowlabel __rcu **flp;
149
148 flp = &fl_ht[i]; 150 flp = &fl_ht[i];
149 while ((fl = rcu_dereference_protected(*flp, 151 while ((fl = rcu_dereference_protected(*flp,
150 lockdep_is_held(&ip6_fl_lock))) != NULL) { 152 lockdep_is_held(&ip6_fl_lock))) != NULL) {
@@ -179,7 +181,9 @@ static void __net_exit ip6_fl_purge(struct net *net)
179 181
180 spin_lock(&ip6_fl_lock); 182 spin_lock(&ip6_fl_lock);
181 for (i = 0; i <= FL_HASH_MASK; i++) { 183 for (i = 0; i <= FL_HASH_MASK; i++) {
182 struct ip6_flowlabel *fl, **flp; 184 struct ip6_flowlabel *fl;
185 struct ip6_flowlabel __rcu **flp;
186
183 flp = &fl_ht[i]; 187 flp = &fl_ht[i];
184 while ((fl = rcu_dereference_protected(*flp, 188 while ((fl = rcu_dereference_protected(*flp,
185 lockdep_is_held(&ip6_fl_lock))) != NULL) { 189 lockdep_is_held(&ip6_fl_lock))) != NULL) {
@@ -506,7 +510,8 @@ int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen)
506 struct ipv6_pinfo *np = inet6_sk(sk); 510 struct ipv6_pinfo *np = inet6_sk(sk);
507 struct in6_flowlabel_req freq; 511 struct in6_flowlabel_req freq;
508 struct ipv6_fl_socklist *sfl1=NULL; 512 struct ipv6_fl_socklist *sfl1=NULL;
509 struct ipv6_fl_socklist *sfl, **sflp; 513 struct ipv6_fl_socklist *sfl;
514 struct ipv6_fl_socklist __rcu **sflp;
510 struct ip6_flowlabel *fl, *fl1 = NULL; 515 struct ip6_flowlabel *fl, *fl1 = NULL;
511 516
512 517
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index e4efffe2522e..d3ddd8400354 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -38,6 +38,7 @@
38 38
39#include <net/sock.h> 39#include <net/sock.h>
40#include <net/ip.h> 40#include <net/ip.h>
41#include <net/ip_tunnels.h>
41#include <net/icmp.h> 42#include <net/icmp.h>
42#include <net/protocol.h> 43#include <net/protocol.h>
43#include <net/addrconf.h> 44#include <net/addrconf.h>
@@ -110,46 +111,6 @@ static u32 HASH_ADDR(const struct in6_addr *addr)
110#define tunnels_l tunnels[1] 111#define tunnels_l tunnels[1]
111#define tunnels_wc tunnels[0] 112#define tunnels_wc tunnels[0]
112 113
113static struct rtnl_link_stats64 *ip6gre_get_stats64(struct net_device *dev,
114 struct rtnl_link_stats64 *tot)
115{
116 int i;
117
118 for_each_possible_cpu(i) {
119 const struct pcpu_tstats *tstats = per_cpu_ptr(dev->tstats, i);
120 u64 rx_packets, rx_bytes, tx_packets, tx_bytes;
121 unsigned int start;
122
123 do {
124 start = u64_stats_fetch_begin_bh(&tstats->syncp);
125 rx_packets = tstats->rx_packets;
126 tx_packets = tstats->tx_packets;
127 rx_bytes = tstats->rx_bytes;
128 tx_bytes = tstats->tx_bytes;
129 } while (u64_stats_fetch_retry_bh(&tstats->syncp, start));
130
131 tot->rx_packets += rx_packets;
132 tot->tx_packets += tx_packets;
133 tot->rx_bytes += rx_bytes;
134 tot->tx_bytes += tx_bytes;
135 }
136
137 tot->multicast = dev->stats.multicast;
138 tot->rx_crc_errors = dev->stats.rx_crc_errors;
139 tot->rx_fifo_errors = dev->stats.rx_fifo_errors;
140 tot->rx_length_errors = dev->stats.rx_length_errors;
141 tot->rx_frame_errors = dev->stats.rx_frame_errors;
142 tot->rx_errors = dev->stats.rx_errors;
143
144 tot->tx_fifo_errors = dev->stats.tx_fifo_errors;
145 tot->tx_carrier_errors = dev->stats.tx_carrier_errors;
146 tot->tx_dropped = dev->stats.tx_dropped;
147 tot->tx_aborted_errors = dev->stats.tx_aborted_errors;
148 tot->tx_errors = dev->stats.tx_errors;
149
150 return tot;
151}
152
153/* Given src, dst and key, find appropriate for input tunnel. */ 114/* Given src, dst and key, find appropriate for input tunnel. */
154 115
155static struct ip6_tnl *ip6gre_tunnel_lookup(struct net_device *dev, 116static struct ip6_tnl *ip6gre_tunnel_lookup(struct net_device *dev,
@@ -667,7 +628,6 @@ static netdev_tx_t ip6gre_xmit2(struct sk_buff *skb,
667 struct net_device_stats *stats = &tunnel->dev->stats; 628 struct net_device_stats *stats = &tunnel->dev->stats;
668 int err = -1; 629 int err = -1;
669 u8 proto; 630 u8 proto;
670 int pkt_len;
671 struct sk_buff *new_skb; 631 struct sk_buff *new_skb;
672 632
673 if (dev->type == ARPHRD_ETHER) 633 if (dev->type == ARPHRD_ETHER)
@@ -801,23 +761,9 @@ static netdev_tx_t ip6gre_xmit2(struct sk_buff *skb,
801 } 761 }
802 } 762 }
803 763
804 nf_reset(skb); 764 ip6tunnel_xmit(skb, dev);
805 pkt_len = skb->len;
806 err = ip6_local_out(skb);
807
808 if (net_xmit_eval(err) == 0) {
809 struct pcpu_tstats *tstats = this_cpu_ptr(tunnel->dev->tstats);
810
811 tstats->tx_bytes += pkt_len;
812 tstats->tx_packets++;
813 } else {
814 stats->tx_errors++;
815 stats->tx_aborted_errors++;
816 }
817
818 if (ndst) 765 if (ndst)
819 ip6_tnl_dst_store(tunnel, ndst); 766 ip6_tnl_dst_store(tunnel, ndst);
820
821 return 0; 767 return 0;
822tx_err_link_failure: 768tx_err_link_failure:
823 stats->tx_carrier_errors++; 769 stats->tx_carrier_errors++;
@@ -1271,7 +1217,7 @@ static const struct net_device_ops ip6gre_netdev_ops = {
1271 .ndo_start_xmit = ip6gre_tunnel_xmit, 1217 .ndo_start_xmit = ip6gre_tunnel_xmit,
1272 .ndo_do_ioctl = ip6gre_tunnel_ioctl, 1218 .ndo_do_ioctl = ip6gre_tunnel_ioctl,
1273 .ndo_change_mtu = ip6gre_tunnel_change_mtu, 1219 .ndo_change_mtu = ip6gre_tunnel_change_mtu,
1274 .ndo_get_stats64 = ip6gre_get_stats64, 1220 .ndo_get_stats64 = ip_tunnel_get_stats64,
1275}; 1221};
1276 1222
1277static void ip6gre_dev_free(struct net_device *dev) 1223static void ip6gre_dev_free(struct net_device *dev)
@@ -1520,7 +1466,7 @@ static const struct net_device_ops ip6gre_tap_netdev_ops = {
1520 .ndo_set_mac_address = eth_mac_addr, 1466 .ndo_set_mac_address = eth_mac_addr,
1521 .ndo_validate_addr = eth_validate_addr, 1467 .ndo_validate_addr = eth_validate_addr,
1522 .ndo_change_mtu = ip6gre_tunnel_change_mtu, 1468 .ndo_change_mtu = ip6gre_tunnel_change_mtu,
1523 .ndo_get_stats64 = ip6gre_get_stats64, 1469 .ndo_get_stats64 = ip_tunnel_get_stats64,
1524}; 1470};
1525 1471
1526static void ip6gre_tap_setup(struct net_device *dev) 1472static void ip6gre_tap_setup(struct net_device *dev)
diff --git a/net/ipv6/ip6_icmp.c b/net/ipv6/ip6_icmp.c
new file mode 100644
index 000000000000..4578e23834f7
--- /dev/null
+++ b/net/ipv6/ip6_icmp.c
@@ -0,0 +1,47 @@
1#include <linux/export.h>
2#include <linux/icmpv6.h>
3#include <linux/mutex.h>
4#include <linux/netdevice.h>
5#include <linux/spinlock.h>
6
7#include <net/ipv6.h>
8
9#if IS_ENABLED(CONFIG_IPV6)
10
11static ip6_icmp_send_t __rcu *ip6_icmp_send;
12
13int inet6_register_icmp_sender(ip6_icmp_send_t *fn)
14{
15 return (cmpxchg((ip6_icmp_send_t **)&ip6_icmp_send, NULL, fn) == NULL) ?
16 0 : -EBUSY;
17}
18EXPORT_SYMBOL(inet6_register_icmp_sender);
19
20int inet6_unregister_icmp_sender(ip6_icmp_send_t *fn)
21{
22 int ret;
23
24 ret = (cmpxchg((ip6_icmp_send_t **)&ip6_icmp_send, fn, NULL) == fn) ?
25 0 : -EINVAL;
26
27 synchronize_net();
28
29 return ret;
30}
31EXPORT_SYMBOL(inet6_unregister_icmp_sender);
32
33void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
34{
35 ip6_icmp_send_t *send;
36
37 rcu_read_lock();
38 send = rcu_dereference(ip6_icmp_send);
39
40 if (!send)
41 goto out;
42 send(skb, type, code, info);
43out:
44 rcu_read_unlock();
45}
46EXPORT_SYMBOL(icmpv6_send);
47#endif
diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c
index 8234c1dcdf72..71b766ee821d 100644
--- a/net/ipv6/ip6_offload.c
+++ b/net/ipv6/ip6_offload.c
@@ -92,14 +92,12 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb,
92 u8 *prevhdr; 92 u8 *prevhdr;
93 int offset = 0; 93 int offset = 0;
94 94
95 if (!(features & NETIF_F_V6_CSUM))
96 features &= ~NETIF_F_SG;
97
98 if (unlikely(skb_shinfo(skb)->gso_type & 95 if (unlikely(skb_shinfo(skb)->gso_type &
99 ~(SKB_GSO_UDP | 96 ~(SKB_GSO_UDP |
100 SKB_GSO_DODGY | 97 SKB_GSO_DODGY |
101 SKB_GSO_TCP_ECN | 98 SKB_GSO_TCP_ECN |
102 SKB_GSO_GRE | 99 SKB_GSO_GRE |
100 SKB_GSO_UDP_TUNNEL |
103 SKB_GSO_TCPV6 | 101 SKB_GSO_TCPV6 |
104 0))) 102 0)))
105 goto out; 103 goto out;
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 155eccfa7760..d2eedf192330 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1224,11 +1224,8 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
1224 } 1224 }
1225 1225
1226 /* For UDP, check if TX timestamp is enabled */ 1226 /* For UDP, check if TX timestamp is enabled */
1227 if (sk->sk_type == SOCK_DGRAM) { 1227 if (sk->sk_type == SOCK_DGRAM)
1228 err = sock_tx_timestamp(sk, &tx_flags); 1228 sock_tx_timestamp(sk, &tx_flags);
1229 if (err)
1230 goto error;
1231 }
1232 1229
1233 /* 1230 /*
1234 * Let's try using as much space as possible. 1231 * Let's try using as much space as possible.
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index fff83cbc197f..1e55866cead7 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -47,6 +47,7 @@
47 47
48#include <net/icmp.h> 48#include <net/icmp.h>
49#include <net/ip.h> 49#include <net/ip.h>
50#include <net/ip_tunnels.h>
50#include <net/ipv6.h> 51#include <net/ipv6.h>
51#include <net/ip6_route.h> 52#include <net/ip6_route.h>
52#include <net/addrconf.h> 53#include <net/addrconf.h>
@@ -955,7 +956,6 @@ static int ip6_tnl_xmit2(struct sk_buff *skb,
955 unsigned int max_headroom = sizeof(struct ipv6hdr); 956 unsigned int max_headroom = sizeof(struct ipv6hdr);
956 u8 proto; 957 u8 proto;
957 int err = -1; 958 int err = -1;
958 int pkt_len;
959 959
960 if (!fl6->flowi6_mark) 960 if (!fl6->flowi6_mark)
961 dst = ip6_tnl_dst_check(t); 961 dst = ip6_tnl_dst_check(t);
@@ -1035,19 +1035,7 @@ static int ip6_tnl_xmit2(struct sk_buff *skb,
1035 ipv6h->nexthdr = proto; 1035 ipv6h->nexthdr = proto;
1036 ipv6h->saddr = fl6->saddr; 1036 ipv6h->saddr = fl6->saddr;
1037 ipv6h->daddr = fl6->daddr; 1037 ipv6h->daddr = fl6->daddr;
1038 nf_reset(skb); 1038 ip6tunnel_xmit(skb, dev);
1039 pkt_len = skb->len;
1040 err = ip6_local_out(skb);
1041
1042 if (net_xmit_eval(err) == 0) {
1043 struct pcpu_tstats *tstats = this_cpu_ptr(t->dev->tstats);
1044
1045 tstats->tx_bytes += pkt_len;
1046 tstats->tx_packets++;
1047 } else {
1048 stats->tx_errors++;
1049 stats->tx_aborted_errors++;
1050 }
1051 if (ndst) 1039 if (ndst)
1052 ip6_tnl_dst_store(t, ndst); 1040 ip6_tnl_dst_store(t, ndst);
1053 return 0; 1041 return 0;
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index 96bfb4e4b820..241fb8ad9fcf 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -842,9 +842,9 @@ static void ip6mr_destroy_unres(struct mr6_table *mrt, struct mfc6_cache *c)
842 if (ipv6_hdr(skb)->version == 0) { 842 if (ipv6_hdr(skb)->version == 0) {
843 struct nlmsghdr *nlh = (struct nlmsghdr *)skb_pull(skb, sizeof(struct ipv6hdr)); 843 struct nlmsghdr *nlh = (struct nlmsghdr *)skb_pull(skb, sizeof(struct ipv6hdr));
844 nlh->nlmsg_type = NLMSG_ERROR; 844 nlh->nlmsg_type = NLMSG_ERROR;
845 nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr)); 845 nlh->nlmsg_len = nlmsg_msg_size(sizeof(struct nlmsgerr));
846 skb_trim(skb, nlh->nlmsg_len); 846 skb_trim(skb, nlh->nlmsg_len);
847 ((struct nlmsgerr *)NLMSG_DATA(nlh))->error = -ETIMEDOUT; 847 ((struct nlmsgerr *)nlmsg_data(nlh))->error = -ETIMEDOUT;
848 rtnl_unicast(skb, net, NETLINK_CB(skb).portid); 848 rtnl_unicast(skb, net, NETLINK_CB(skb).portid);
849 } else 849 } else
850 kfree_skb(skb); 850 kfree_skb(skb);
@@ -1100,13 +1100,13 @@ static void ip6mr_cache_resolve(struct net *net, struct mr6_table *mrt,
1100 if (ipv6_hdr(skb)->version == 0) { 1100 if (ipv6_hdr(skb)->version == 0) {
1101 struct nlmsghdr *nlh = (struct nlmsghdr *)skb_pull(skb, sizeof(struct ipv6hdr)); 1101 struct nlmsghdr *nlh = (struct nlmsghdr *)skb_pull(skb, sizeof(struct ipv6hdr));
1102 1102
1103 if (__ip6mr_fill_mroute(mrt, skb, c, NLMSG_DATA(nlh)) > 0) { 1103 if (__ip6mr_fill_mroute(mrt, skb, c, nlmsg_data(nlh)) > 0) {
1104 nlh->nlmsg_len = skb_tail_pointer(skb) - (u8 *)nlh; 1104 nlh->nlmsg_len = skb_tail_pointer(skb) - (u8 *)nlh;
1105 } else { 1105 } else {
1106 nlh->nlmsg_type = NLMSG_ERROR; 1106 nlh->nlmsg_type = NLMSG_ERROR;
1107 nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr)); 1107 nlh->nlmsg_len = nlmsg_msg_size(sizeof(struct nlmsgerr));
1108 skb_trim(skb, nlh->nlmsg_len); 1108 skb_trim(skb, nlh->nlmsg_len);
1109 ((struct nlmsgerr *)NLMSG_DATA(nlh))->error = -EMSGSIZE; 1109 ((struct nlmsgerr *)nlmsg_data(nlh))->error = -EMSGSIZE;
1110 } 1110 }
1111 rtnl_unicast(skb, net, NETLINK_CB(skb).portid); 1111 rtnl_unicast(skb, net, NETLINK_CB(skb).portid);
1112 } else 1112 } else
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 76ef4353d518..2712ab22a174 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -610,8 +610,6 @@ void ndisc_send_rs(struct net_device *dev, const struct in6_addr *saddr,
610 } 610 }
611 } 611 }
612#endif 612#endif
613 if (!dev->addr_len)
614 send_sllao = 0;
615 if (send_sllao) 613 if (send_sllao)
616 optlen += ndisc_opt_addr_space(dev); 614 optlen += ndisc_opt_addr_space(dev);
617 615
diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c
index 429089cb073d..72836f40b730 100644
--- a/net/ipv6/netfilter.c
+++ b/net/ipv6/netfilter.c
@@ -1,3 +1,9 @@
1/*
2 * IPv6 specific functions of netfilter core
3 *
4 * Rusty Russell (C) 2000 -- This code is GPL.
5 * Patrick McHardy (C) 2006-2012
6 */
1#include <linux/kernel.h> 7#include <linux/kernel.h>
2#include <linux/init.h> 8#include <linux/init.h>
3#include <linux/ipv6.h> 9#include <linux/ipv6.h>
@@ -29,7 +35,7 @@ int ip6_route_me_harder(struct sk_buff *skb)
29 IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES); 35 IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES);
30 LIMIT_NETDEBUG(KERN_DEBUG "ip6_route_me_harder: No more route.\n"); 36 LIMIT_NETDEBUG(KERN_DEBUG "ip6_route_me_harder: No more route.\n");
31 dst_release(dst); 37 dst_release(dst);
32 return -EINVAL; 38 return dst->error;
33 } 39 }
34 40
35 /* Drop old route. */ 41 /* Drop old route. */
@@ -43,7 +49,7 @@ int ip6_route_me_harder(struct sk_buff *skb)
43 skb_dst_set(skb, NULL); 49 skb_dst_set(skb, NULL);
44 dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), skb->sk, 0); 50 dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), skb->sk, 0);
45 if (IS_ERR(dst)) 51 if (IS_ERR(dst))
46 return -1; 52 return PTR_ERR(dst);
47 skb_dst_set(skb, dst); 53 skb_dst_set(skb, dst);
48 } 54 }
49#endif 55#endif
@@ -53,7 +59,7 @@ int ip6_route_me_harder(struct sk_buff *skb)
53 if (skb_headroom(skb) < hh_len && 59 if (skb_headroom(skb) < hh_len &&
54 pskb_expand_head(skb, HH_DATA_ALIGN(hh_len - skb_headroom(skb)), 60 pskb_expand_head(skb, HH_DATA_ALIGN(hh_len - skb_headroom(skb)),
55 0, GFP_ATOMIC)) 61 0, GFP_ATOMIC))
56 return -1; 62 return -ENOMEM;
57 63
58 return 0; 64 return 0;
59} 65}
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
index c72532a60d88..4433ab40e7de 100644
--- a/net/ipv6/netfilter/Kconfig
+++ b/net/ipv6/netfilter/Kconfig
@@ -105,7 +105,7 @@ config IP6_NF_MATCH_MH
105 105
106config IP6_NF_MATCH_RPFILTER 106config IP6_NF_MATCH_RPFILTER
107 tristate '"rpfilter" reverse path filter match support' 107 tristate '"rpfilter" reverse path filter match support'
108 depends on NETFILTER_ADVANCED 108 depends on NETFILTER_ADVANCED && (IP6_NF_MANGLE || IP6_NF_RAW)
109 ---help--- 109 ---help---
110 This option allows you to match packets whose replies would 110 This option allows you to match packets whose replies would
111 go out via the interface the packet came in. 111 go out via the interface the packet came in.
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 341b54ade72c..44400c216dc6 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -3,6 +3,7 @@
3 * 3 *
4 * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling 4 * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling
5 * Copyright (C) 2000-2005 Netfilter Core Team <coreteam@netfilter.org> 5 * Copyright (C) 2000-2005 Netfilter Core Team <coreteam@netfilter.org>
6 * Copyright (c) 2006-2010 Patrick McHardy <kaber@trash.net>
6 * 7 *
7 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
@@ -284,6 +285,7 @@ static void trace_packet(const struct sk_buff *skb,
284 const char *hookname, *chainname, *comment; 285 const char *hookname, *chainname, *comment;
285 const struct ip6t_entry *iter; 286 const struct ip6t_entry *iter;
286 unsigned int rulenum = 0; 287 unsigned int rulenum = 0;
288 struct net *net = dev_net(in ? in : out);
287 289
288 table_base = private->entries[smp_processor_id()]; 290 table_base = private->entries[smp_processor_id()];
289 root = get_entry(table_base, private->hook_entry[hook]); 291 root = get_entry(table_base, private->hook_entry[hook]);
@@ -296,7 +298,7 @@ static void trace_packet(const struct sk_buff *skb,
296 &chainname, &comment, &rulenum) != 0) 298 &chainname, &comment, &rulenum) != 0)
297 break; 299 break;
298 300
299 nf_log_packet(AF_INET6, hook, skb, in, out, &trace_loginfo, 301 nf_log_packet(net, AF_INET6, hook, skb, in, out, &trace_loginfo,
300 "TRACE: %s:%s:%s:%u ", 302 "TRACE: %s:%s:%s:%u ",
301 tablename, chainname, comment, rulenum); 303 tablename, chainname, comment, rulenum);
302} 304}
diff --git a/net/ipv6/netfilter/ip6t_NPT.c b/net/ipv6/netfilter/ip6t_NPT.c
index cb631143721c..590f767db5d4 100644
--- a/net/ipv6/netfilter/ip6t_NPT.c
+++ b/net/ipv6/netfilter/ip6t_NPT.c
@@ -18,9 +18,8 @@
18static int ip6t_npt_checkentry(const struct xt_tgchk_param *par) 18static int ip6t_npt_checkentry(const struct xt_tgchk_param *par)
19{ 19{
20 struct ip6t_npt_tginfo *npt = par->targinfo; 20 struct ip6t_npt_tginfo *npt = par->targinfo;
21 __wsum src_sum = 0, dst_sum = 0;
22 struct in6_addr pfx; 21 struct in6_addr pfx;
23 unsigned int i; 22 __wsum src_sum, dst_sum;
24 23
25 if (npt->src_pfx_len > 64 || npt->dst_pfx_len > 64) 24 if (npt->src_pfx_len > 64 || npt->dst_pfx_len > 64)
26 return -EINVAL; 25 return -EINVAL;
@@ -33,12 +32,8 @@ static int ip6t_npt_checkentry(const struct xt_tgchk_param *par)
33 if (!ipv6_addr_equal(&pfx, &npt->dst_pfx.in6)) 32 if (!ipv6_addr_equal(&pfx, &npt->dst_pfx.in6))
34 return -EINVAL; 33 return -EINVAL;
35 34
36 for (i = 0; i < ARRAY_SIZE(npt->src_pfx.in6.s6_addr16); i++) { 35 src_sum = csum_partial(&npt->src_pfx.in6, sizeof(npt->src_pfx.in6), 0);
37 src_sum = csum_add(src_sum, 36 dst_sum = csum_partial(&npt->dst_pfx.in6, sizeof(npt->dst_pfx.in6), 0);
38 (__force __wsum)npt->src_pfx.in6.s6_addr16[i]);
39 dst_sum = csum_add(dst_sum,
40 (__force __wsum)npt->dst_pfx.in6.s6_addr16[i]);
41 }
42 37
43 npt->adjustment = ~csum_fold(csum_sub(src_sum, dst_sum)); 38 npt->adjustment = ~csum_fold(csum_sub(src_sum, dst_sum));
44 return 0; 39 return 0;
diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c
index ed3b427b2841..70f9abc0efe9 100644
--- a/net/ipv6/netfilter/ip6t_REJECT.c
+++ b/net/ipv6/netfilter/ip6t_REJECT.c
@@ -7,6 +7,8 @@
7 * Authors: 7 * Authors:
8 * Yasuyuki Kozakai <yasuyuki.kozakai@toshiba.co.jp> 8 * Yasuyuki Kozakai <yasuyuki.kozakai@toshiba.co.jp>
9 * 9 *
10 * Copyright (c) 2005-2007 Patrick McHardy <kaber@trash.net>
11 *
10 * Based on net/ipv4/netfilter/ipt_REJECT.c 12 * Based on net/ipv4/netfilter/ipt_REJECT.c
11 * 13 *
12 * This program is free software; you can redistribute it and/or 14 * This program is free software; you can redistribute it and/or
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c
index 6134a1ebfb1b..e075399d8b72 100644
--- a/net/ipv6/netfilter/ip6table_mangle.c
+++ b/net/ipv6/netfilter/ip6table_mangle.c
@@ -38,7 +38,7 @@ ip6t_mangle_out(struct sk_buff *skb, const struct net_device *out)
38 struct in6_addr saddr, daddr; 38 struct in6_addr saddr, daddr;
39 u_int8_t hop_limit; 39 u_int8_t hop_limit;
40 u_int32_t flowlabel, mark; 40 u_int32_t flowlabel, mark;
41 41 int err;
42#if 0 42#if 0
43 /* root is playing with raw sockets. */ 43 /* root is playing with raw sockets. */
44 if (skb->len < sizeof(struct iphdr) || 44 if (skb->len < sizeof(struct iphdr) ||
@@ -65,8 +65,11 @@ ip6t_mangle_out(struct sk_buff *skb, const struct net_device *out)
65 !ipv6_addr_equal(&ipv6_hdr(skb)->daddr, &daddr) || 65 !ipv6_addr_equal(&ipv6_hdr(skb)->daddr, &daddr) ||
66 skb->mark != mark || 66 skb->mark != mark ||
67 ipv6_hdr(skb)->hop_limit != hop_limit || 67 ipv6_hdr(skb)->hop_limit != hop_limit ||
68 flowlabel != *((u_int32_t *)ipv6_hdr(skb)))) 68 flowlabel != *((u_int32_t *)ipv6_hdr(skb)))) {
69 return ip6_route_me_harder(skb) == 0 ? ret : NF_DROP; 69 err = ip6_route_me_harder(skb);
70 if (err < 0)
71 ret = NF_DROP_ERR(err);
72 }
70 73
71 return ret; 74 return ret;
72} 75}
diff --git a/net/ipv6/netfilter/ip6table_nat.c b/net/ipv6/netfilter/ip6table_nat.c
index e0e788d25b14..6383f90efda8 100644
--- a/net/ipv6/netfilter/ip6table_nat.c
+++ b/net/ipv6/netfilter/ip6table_nat.c
@@ -179,6 +179,7 @@ nf_nat_ipv6_out(unsigned int hooknum,
179#ifdef CONFIG_XFRM 179#ifdef CONFIG_XFRM
180 const struct nf_conn *ct; 180 const struct nf_conn *ct;
181 enum ip_conntrack_info ctinfo; 181 enum ip_conntrack_info ctinfo;
182 int err;
182#endif 183#endif
183 unsigned int ret; 184 unsigned int ret;
184 185
@@ -197,9 +198,11 @@ nf_nat_ipv6_out(unsigned int hooknum,
197 &ct->tuplehash[!dir].tuple.dst.u3) || 198 &ct->tuplehash[!dir].tuple.dst.u3) ||
198 (ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMPV6 && 199 (ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMPV6 &&
199 ct->tuplehash[dir].tuple.src.u.all != 200 ct->tuplehash[dir].tuple.src.u.all !=
200 ct->tuplehash[!dir].tuple.dst.u.all)) 201 ct->tuplehash[!dir].tuple.dst.u.all)) {
201 if (nf_xfrm_me_harder(skb, AF_INET6) < 0) 202 err = nf_xfrm_me_harder(skb, AF_INET6);
202 ret = NF_DROP; 203 if (err < 0)
204 ret = NF_DROP_ERR(err);
205 }
203 } 206 }
204#endif 207#endif
205 return ret; 208 return ret;
@@ -215,6 +218,7 @@ nf_nat_ipv6_local_fn(unsigned int hooknum,
215 const struct nf_conn *ct; 218 const struct nf_conn *ct;
216 enum ip_conntrack_info ctinfo; 219 enum ip_conntrack_info ctinfo;
217 unsigned int ret; 220 unsigned int ret;
221 int err;
218 222
219 /* root is playing with raw sockets. */ 223 /* root is playing with raw sockets. */
220 if (skb->len < sizeof(struct ipv6hdr)) 224 if (skb->len < sizeof(struct ipv6hdr))
@@ -227,16 +231,19 @@ nf_nat_ipv6_local_fn(unsigned int hooknum,
227 231
228 if (!nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.dst.u3, 232 if (!nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.dst.u3,
229 &ct->tuplehash[!dir].tuple.src.u3)) { 233 &ct->tuplehash[!dir].tuple.src.u3)) {
230 if (ip6_route_me_harder(skb)) 234 err = ip6_route_me_harder(skb);
231 ret = NF_DROP; 235 if (err < 0)
236 ret = NF_DROP_ERR(err);
232 } 237 }
233#ifdef CONFIG_XFRM 238#ifdef CONFIG_XFRM
234 else if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) && 239 else if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) &&
235 ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMPV6 && 240 ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMPV6 &&
236 ct->tuplehash[dir].tuple.dst.u.all != 241 ct->tuplehash[dir].tuple.dst.u.all !=
237 ct->tuplehash[!dir].tuple.src.u.all) 242 ct->tuplehash[!dir].tuple.src.u.all) {
238 if (nf_xfrm_me_harder(skb, AF_INET6)) 243 err = nf_xfrm_me_harder(skb, AF_INET6);
239 ret = NF_DROP; 244 if (err < 0)
245 ret = NF_DROP_ERR(err);
246 }
240#endif 247#endif
241 } 248 }
242 return ret; 249 return ret;
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index 2b6c226f5198..97bcf2bae857 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -330,12 +330,8 @@ ipv6_getorigdst(struct sock *sk, int optval, void __user *user, int *len)
330 sizeof(sin6.sin6_addr)); 330 sizeof(sin6.sin6_addr));
331 331
332 nf_ct_put(ct); 332 nf_ct_put(ct);
333 333 sin6.sin6_scope_id = ipv6_iface_scope_id(&sin6.sin6_addr,
334 if (ipv6_addr_type(&sin6.sin6_addr) & IPV6_ADDR_LINKLOCAL) 334 sk->sk_bound_dev_if);
335 sin6.sin6_scope_id = sk->sk_bound_dev_if;
336 else
337 sin6.sin6_scope_id = 0;
338
339 return copy_to_user(user, &sin6, sizeof(sin6)) ? -EFAULT : 0; 335 return copy_to_user(user, &sin6, sizeof(sin6)) ? -EFAULT : 0;
340} 336}
341 337
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
index 24df3dde0076..b3807c5cb888 100644
--- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
@@ -131,7 +131,8 @@ static bool icmpv6_new(struct nf_conn *ct, const struct sk_buff *skb,
131 type + 128); 131 type + 128);
132 nf_ct_dump_tuple_ipv6(&ct->tuplehash[0].tuple); 132 nf_ct_dump_tuple_ipv6(&ct->tuplehash[0].tuple);
133 if (LOG_INVALID(nf_ct_net(ct), IPPROTO_ICMPV6)) 133 if (LOG_INVALID(nf_ct_net(ct), IPPROTO_ICMPV6))
134 nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL, 134 nf_log_packet(nf_ct_net(ct), PF_INET6, 0, skb, NULL,
135 NULL, NULL,
135 "nf_ct_icmpv6: invalid new with type %d ", 136 "nf_ct_icmpv6: invalid new with type %d ",
136 type + 128); 137 type + 128);
137 return false; 138 return false;
@@ -203,7 +204,7 @@ icmpv6_error(struct net *net, struct nf_conn *tmpl,
203 icmp6h = skb_header_pointer(skb, dataoff, sizeof(_ih), &_ih); 204 icmp6h = skb_header_pointer(skb, dataoff, sizeof(_ih), &_ih);
204 if (icmp6h == NULL) { 205 if (icmp6h == NULL) {
205 if (LOG_INVALID(net, IPPROTO_ICMPV6)) 206 if (LOG_INVALID(net, IPPROTO_ICMPV6))
206 nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL, 207 nf_log_packet(net, PF_INET6, 0, skb, NULL, NULL, NULL,
207 "nf_ct_icmpv6: short packet "); 208 "nf_ct_icmpv6: short packet ");
208 return -NF_ACCEPT; 209 return -NF_ACCEPT;
209 } 210 }
@@ -211,7 +212,7 @@ icmpv6_error(struct net *net, struct nf_conn *tmpl,
211 if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING && 212 if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING &&
212 nf_ip6_checksum(skb, hooknum, dataoff, IPPROTO_ICMPV6)) { 213 nf_ip6_checksum(skb, hooknum, dataoff, IPPROTO_ICMPV6)) {
213 if (LOG_INVALID(net, IPPROTO_ICMPV6)) 214 if (LOG_INVALID(net, IPPROTO_ICMPV6))
214 nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL, 215 nf_log_packet(net, PF_INET6, 0, skb, NULL, NULL, NULL,
215 "nf_ct_icmpv6: ICMPv6 checksum failed "); 216 "nf_ct_icmpv6: ICMPv6 checksum failed ");
216 return -NF_ACCEPT; 217 return -NF_ACCEPT;
217 } 218 }
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index 6700069949dd..dffdc1a389c5 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -41,6 +41,7 @@
41#include <net/rawv6.h> 41#include <net/rawv6.h>
42#include <net/ndisc.h> 42#include <net/ndisc.h>
43#include <net/addrconf.h> 43#include <net/addrconf.h>
44#include <net/inet_ecn.h>
44#include <net/netfilter/ipv6/nf_conntrack_ipv6.h> 45#include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
45#include <linux/sysctl.h> 46#include <linux/sysctl.h>
46#include <linux/netfilter.h> 47#include <linux/netfilter.h>
@@ -138,6 +139,11 @@ static void __net_exit nf_ct_frags6_sysctl_unregister(struct net *net)
138} 139}
139#endif 140#endif
140 141
142static inline u8 ip6_frag_ecn(const struct ipv6hdr *ipv6h)
143{
144 return 1 << (ipv6_get_dsfield(ipv6h) & INET_ECN_MASK);
145}
146
141static unsigned int nf_hashfn(struct inet_frag_queue *q) 147static unsigned int nf_hashfn(struct inet_frag_queue *q)
142{ 148{
143 const struct frag_queue *nq; 149 const struct frag_queue *nq;
@@ -166,7 +172,7 @@ static void nf_ct_frag6_expire(unsigned long data)
166/* Creation primitives. */ 172/* Creation primitives. */
167static inline struct frag_queue *fq_find(struct net *net, __be32 id, 173static inline struct frag_queue *fq_find(struct net *net, __be32 id,
168 u32 user, struct in6_addr *src, 174 u32 user, struct in6_addr *src,
169 struct in6_addr *dst) 175 struct in6_addr *dst, u8 ecn)
170{ 176{
171 struct inet_frag_queue *q; 177 struct inet_frag_queue *q;
172 struct ip6_create_arg arg; 178 struct ip6_create_arg arg;
@@ -176,6 +182,7 @@ static inline struct frag_queue *fq_find(struct net *net, __be32 id,
176 arg.user = user; 182 arg.user = user;
177 arg.src = src; 183 arg.src = src;
178 arg.dst = dst; 184 arg.dst = dst;
185 arg.ecn = ecn;
179 186
180 read_lock_bh(&nf_frags.lock); 187 read_lock_bh(&nf_frags.lock);
181 hash = inet6_hash_frag(id, src, dst, nf_frags.rnd); 188 hash = inet6_hash_frag(id, src, dst, nf_frags.rnd);
@@ -196,6 +203,7 @@ static int nf_ct_frag6_queue(struct frag_queue *fq, struct sk_buff *skb,
196 struct sk_buff *prev, *next; 203 struct sk_buff *prev, *next;
197 unsigned int payload_len; 204 unsigned int payload_len;
198 int offset, end; 205 int offset, end;
206 u8 ecn;
199 207
200 if (fq->q.last_in & INET_FRAG_COMPLETE) { 208 if (fq->q.last_in & INET_FRAG_COMPLETE) {
201 pr_debug("Already completed\n"); 209 pr_debug("Already completed\n");
@@ -213,6 +221,8 @@ static int nf_ct_frag6_queue(struct frag_queue *fq, struct sk_buff *skb,
213 return -1; 221 return -1;
214 } 222 }
215 223
224 ecn = ip6_frag_ecn(ipv6_hdr(skb));
225
216 if (skb->ip_summed == CHECKSUM_COMPLETE) { 226 if (skb->ip_summed == CHECKSUM_COMPLETE) {
217 const unsigned char *nh = skb_network_header(skb); 227 const unsigned char *nh = skb_network_header(skb);
218 skb->csum = csum_sub(skb->csum, 228 skb->csum = csum_sub(skb->csum,
@@ -317,6 +327,7 @@ found:
317 } 327 }
318 fq->q.stamp = skb->tstamp; 328 fq->q.stamp = skb->tstamp;
319 fq->q.meat += skb->len; 329 fq->q.meat += skb->len;
330 fq->ecn |= ecn;
320 if (payload_len > fq->q.max_size) 331 if (payload_len > fq->q.max_size)
321 fq->q.max_size = payload_len; 332 fq->q.max_size = payload_len;
322 add_frag_mem_limit(&fq->q, skb->truesize); 333 add_frag_mem_limit(&fq->q, skb->truesize);
@@ -352,12 +363,17 @@ nf_ct_frag6_reasm(struct frag_queue *fq, struct net_device *dev)
352{ 363{
353 struct sk_buff *fp, *op, *head = fq->q.fragments; 364 struct sk_buff *fp, *op, *head = fq->q.fragments;
354 int payload_len; 365 int payload_len;
366 u8 ecn;
355 367
356 inet_frag_kill(&fq->q, &nf_frags); 368 inet_frag_kill(&fq->q, &nf_frags);
357 369
358 WARN_ON(head == NULL); 370 WARN_ON(head == NULL);
359 WARN_ON(NFCT_FRAG6_CB(head)->offset != 0); 371 WARN_ON(NFCT_FRAG6_CB(head)->offset != 0);
360 372
373 ecn = ip_frag_ecn_table[fq->ecn];
374 if (unlikely(ecn == 0xff))
375 goto out_fail;
376
361 /* Unfragmented part is taken from the first segment. */ 377 /* Unfragmented part is taken from the first segment. */
362 payload_len = ((head->data - skb_network_header(head)) - 378 payload_len = ((head->data - skb_network_header(head)) -
363 sizeof(struct ipv6hdr) + fq->q.len - 379 sizeof(struct ipv6hdr) + fq->q.len -
@@ -428,6 +444,7 @@ nf_ct_frag6_reasm(struct frag_queue *fq, struct net_device *dev)
428 head->dev = dev; 444 head->dev = dev;
429 head->tstamp = fq->q.stamp; 445 head->tstamp = fq->q.stamp;
430 ipv6_hdr(head)->payload_len = htons(payload_len); 446 ipv6_hdr(head)->payload_len = htons(payload_len);
447 ipv6_change_dsfield(ipv6_hdr(head), 0xff, ecn);
431 IP6CB(head)->frag_max_size = sizeof(struct ipv6hdr) + fq->q.max_size; 448 IP6CB(head)->frag_max_size = sizeof(struct ipv6hdr) + fq->q.max_size;
432 449
433 /* Yes, and fold redundant checksum back. 8) */ 450 /* Yes, and fold redundant checksum back. 8) */
@@ -572,7 +589,8 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user)
572 inet_frag_evictor(&net->nf_frag.frags, &nf_frags, false); 589 inet_frag_evictor(&net->nf_frag.frags, &nf_frags, false);
573 local_bh_enable(); 590 local_bh_enable();
574 591
575 fq = fq_find(net, fhdr->identification, user, &hdr->saddr, &hdr->daddr); 592 fq = fq_find(net, fhdr->identification, user, &hdr->saddr, &hdr->daddr,
593 ip6_frag_ecn(hdr));
576 if (fq == NULL) { 594 if (fq == NULL) {
577 pr_debug("Can't find and can't create new queue\n"); 595 pr_debug("Can't find and can't create new queue\n");
578 goto ret_orig; 596 goto ret_orig;
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c
index bbbe53a99b57..f3c1ff4357ff 100644
--- a/net/ipv6/proc.c
+++ b/net/ipv6/proc.c
@@ -90,6 +90,7 @@ static const struct snmp_mib snmp6_ipstats_list[] = {
90 SNMP_MIB_ITEM("Ip6OutMcastOctets", IPSTATS_MIB_OUTMCASTOCTETS), 90 SNMP_MIB_ITEM("Ip6OutMcastOctets", IPSTATS_MIB_OUTMCASTOCTETS),
91 SNMP_MIB_ITEM("Ip6InBcastOctets", IPSTATS_MIB_INBCASTOCTETS), 91 SNMP_MIB_ITEM("Ip6InBcastOctets", IPSTATS_MIB_INBCASTOCTETS),
92 SNMP_MIB_ITEM("Ip6OutBcastOctets", IPSTATS_MIB_OUTBCASTOCTETS), 92 SNMP_MIB_ITEM("Ip6OutBcastOctets", IPSTATS_MIB_OUTBCASTOCTETS),
93 SNMP_MIB_ITEM("InCsumErrors", IPSTATS_MIB_CSUMERRORS),
93 SNMP_MIB_SENTINEL 94 SNMP_MIB_SENTINEL
94}; 95};
95 96
@@ -99,6 +100,7 @@ static const struct snmp_mib snmp6_icmp6_list[] = {
99 SNMP_MIB_ITEM("Icmp6InErrors", ICMP6_MIB_INERRORS), 100 SNMP_MIB_ITEM("Icmp6InErrors", ICMP6_MIB_INERRORS),
100 SNMP_MIB_ITEM("Icmp6OutMsgs", ICMP6_MIB_OUTMSGS), 101 SNMP_MIB_ITEM("Icmp6OutMsgs", ICMP6_MIB_OUTMSGS),
101 SNMP_MIB_ITEM("Icmp6OutErrors", ICMP6_MIB_OUTERRORS), 102 SNMP_MIB_ITEM("Icmp6OutErrors", ICMP6_MIB_OUTERRORS),
103 SNMP_MIB_ITEM("Icmp6InCsumErrors", ICMP6_MIB_CSUMERRORS),
102 SNMP_MIB_SENTINEL 104 SNMP_MIB_SENTINEL
103}; 105};
104 106
@@ -129,6 +131,7 @@ static const struct snmp_mib snmp6_udp6_list[] = {
129 SNMP_MIB_ITEM("Udp6OutDatagrams", UDP_MIB_OUTDATAGRAMS), 131 SNMP_MIB_ITEM("Udp6OutDatagrams", UDP_MIB_OUTDATAGRAMS),
130 SNMP_MIB_ITEM("Udp6RcvbufErrors", UDP_MIB_RCVBUFERRORS), 132 SNMP_MIB_ITEM("Udp6RcvbufErrors", UDP_MIB_RCVBUFERRORS),
131 SNMP_MIB_ITEM("Udp6SndbufErrors", UDP_MIB_SNDBUFERRORS), 133 SNMP_MIB_ITEM("Udp6SndbufErrors", UDP_MIB_SNDBUFERRORS),
134 SNMP_MIB_ITEM("Udp6InCsumErrors", UDP_MIB_CSUMERRORS),
132 SNMP_MIB_SENTINEL 135 SNMP_MIB_SENTINEL
133}; 136};
134 137
@@ -139,6 +142,7 @@ static const struct snmp_mib snmp6_udplite6_list[] = {
139 SNMP_MIB_ITEM("UdpLite6OutDatagrams", UDP_MIB_OUTDATAGRAMS), 142 SNMP_MIB_ITEM("UdpLite6OutDatagrams", UDP_MIB_OUTDATAGRAMS),
140 SNMP_MIB_ITEM("UdpLite6RcvbufErrors", UDP_MIB_RCVBUFERRORS), 143 SNMP_MIB_ITEM("UdpLite6RcvbufErrors", UDP_MIB_RCVBUFERRORS),
141 SNMP_MIB_ITEM("UdpLite6SndbufErrors", UDP_MIB_SNDBUFERRORS), 144 SNMP_MIB_ITEM("UdpLite6SndbufErrors", UDP_MIB_SNDBUFERRORS),
145 SNMP_MIB_ITEM("UdpLite6InCsumErrors", UDP_MIB_CSUMERRORS),
142 SNMP_MIB_SENTINEL 146 SNMP_MIB_SENTINEL
143}; 147};
144 148
@@ -247,7 +251,7 @@ static int snmp6_dev_seq_show(struct seq_file *seq, void *v)
247 251
248static int snmp6_dev_seq_open(struct inode *inode, struct file *file) 252static int snmp6_dev_seq_open(struct inode *inode, struct file *file)
249{ 253{
250 return single_open(file, snmp6_dev_seq_show, PDE(inode)->data); 254 return single_open(file, snmp6_dev_seq_show, PDE_DATA(inode));
251} 255}
252 256
253static const struct file_operations snmp6_dev_seq_fops = { 257static const struct file_operations snmp6_dev_seq_fops = {
@@ -287,8 +291,7 @@ int snmp6_unregister_dev(struct inet6_dev *idev)
287 return -ENOENT; 291 return -ENOENT;
288 if (!idev->stats.proc_dir_entry) 292 if (!idev->stats.proc_dir_entry)
289 return -EINVAL; 293 return -EINVAL;
290 remove_proc_entry(idev->stats.proc_dir_entry->name, 294 proc_remove(idev->stats.proc_dir_entry);
291 net->mib.proc_net_devsnmp6);
292 idev->stats.proc_dir_entry = NULL; 295 idev->stats.proc_dir_entry = NULL;
293 return 0; 296 return 0;
294} 297}
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 330b5e7b7df6..eedff8ccded5 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -263,7 +263,7 @@ static int rawv6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
263 if (addr_type != IPV6_ADDR_ANY) { 263 if (addr_type != IPV6_ADDR_ANY) {
264 struct net_device *dev = NULL; 264 struct net_device *dev = NULL;
265 265
266 if (addr_type & IPV6_ADDR_LINKLOCAL) { 266 if (__ipv6_addr_needs_scope_id(addr_type)) {
267 if (addr_len >= sizeof(struct sockaddr_in6) && 267 if (addr_len >= sizeof(struct sockaddr_in6) &&
268 addr->sin6_scope_id) { 268 addr->sin6_scope_id) {
269 /* Override any existing binding, if another 269 /* Override any existing binding, if another
@@ -498,9 +498,8 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk,
498 sin6->sin6_port = 0; 498 sin6->sin6_port = 0;
499 sin6->sin6_addr = ipv6_hdr(skb)->saddr; 499 sin6->sin6_addr = ipv6_hdr(skb)->saddr;
500 sin6->sin6_flowinfo = 0; 500 sin6->sin6_flowinfo = 0;
501 sin6->sin6_scope_id = 0; 501 sin6->sin6_scope_id = ipv6_iface_scope_id(&sin6->sin6_addr,
502 if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) 502 IP6CB(skb)->iif);
503 sin6->sin6_scope_id = IP6CB(skb)->iif;
504 } 503 }
505 504
506 sock_recv_ts_and_drops(msg, sk, skb); 505 sock_recv_ts_and_drops(msg, sk, skb);
@@ -802,7 +801,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
802 801
803 if (addr_len >= sizeof(struct sockaddr_in6) && 802 if (addr_len >= sizeof(struct sockaddr_in6) &&
804 sin6->sin6_scope_id && 803 sin6->sin6_scope_id &&
805 ipv6_addr_type(daddr)&IPV6_ADDR_LINKLOCAL) 804 __ipv6_addr_needs_scope_id(__ipv6_addr_type(daddr)))
806 fl6.flowi6_oif = sin6->sin6_scope_id; 805 fl6.flowi6_oif = sin6->sin6_scope_id;
807 } else { 806 } else {
808 if (sk->sk_state != TCP_ESTABLISHED) 807 if (sk->sk_state != TCP_ESTABLISHED)
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 0ba10e53a629..790d9f4b8b0b 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -58,6 +58,7 @@
58#include <net/ndisc.h> 58#include <net/ndisc.h>
59#include <net/addrconf.h> 59#include <net/addrconf.h>
60#include <net/inet_frag.h> 60#include <net/inet_frag.h>
61#include <net/inet_ecn.h>
61 62
62struct ip6frag_skb_cb 63struct ip6frag_skb_cb
63{ 64{
@@ -67,6 +68,10 @@ struct ip6frag_skb_cb
67 68
68#define FRAG6_CB(skb) ((struct ip6frag_skb_cb*)((skb)->cb)) 69#define FRAG6_CB(skb) ((struct ip6frag_skb_cb*)((skb)->cb))
69 70
71static inline u8 ip6_frag_ecn(const struct ipv6hdr *ipv6h)
72{
73 return 1 << (ipv6_get_dsfield(ipv6h) & INET_ECN_MASK);
74}
70 75
71static struct inet_frags ip6_frags; 76static struct inet_frags ip6_frags;
72 77
@@ -119,6 +124,7 @@ void ip6_frag_init(struct inet_frag_queue *q, void *a)
119 fq->user = arg->user; 124 fq->user = arg->user;
120 fq->saddr = *arg->src; 125 fq->saddr = *arg->src;
121 fq->daddr = *arg->dst; 126 fq->daddr = *arg->dst;
127 fq->ecn = arg->ecn;
122} 128}
123EXPORT_SYMBOL(ip6_frag_init); 129EXPORT_SYMBOL(ip6_frag_init);
124 130
@@ -173,7 +179,8 @@ static void ip6_frag_expire(unsigned long data)
173} 179}
174 180
175static __inline__ struct frag_queue * 181static __inline__ struct frag_queue *
176fq_find(struct net *net, __be32 id, const struct in6_addr *src, const struct in6_addr *dst) 182fq_find(struct net *net, __be32 id, const struct in6_addr *src,
183 const struct in6_addr *dst, u8 ecn)
177{ 184{
178 struct inet_frag_queue *q; 185 struct inet_frag_queue *q;
179 struct ip6_create_arg arg; 186 struct ip6_create_arg arg;
@@ -183,6 +190,7 @@ fq_find(struct net *net, __be32 id, const struct in6_addr *src, const struct in6
183 arg.user = IP6_DEFRAG_LOCAL_DELIVER; 190 arg.user = IP6_DEFRAG_LOCAL_DELIVER;
184 arg.src = src; 191 arg.src = src;
185 arg.dst = dst; 192 arg.dst = dst;
193 arg.ecn = ecn;
186 194
187 read_lock(&ip6_frags.lock); 195 read_lock(&ip6_frags.lock);
188 hash = inet6_hash_frag(id, src, dst, ip6_frags.rnd); 196 hash = inet6_hash_frag(id, src, dst, ip6_frags.rnd);
@@ -202,6 +210,7 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
202 struct net_device *dev; 210 struct net_device *dev;
203 int offset, end; 211 int offset, end;
204 struct net *net = dev_net(skb_dst(skb)->dev); 212 struct net *net = dev_net(skb_dst(skb)->dev);
213 u8 ecn;
205 214
206 if (fq->q.last_in & INET_FRAG_COMPLETE) 215 if (fq->q.last_in & INET_FRAG_COMPLETE)
207 goto err; 216 goto err;
@@ -219,6 +228,8 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
219 return -1; 228 return -1;
220 } 229 }
221 230
231 ecn = ip6_frag_ecn(ipv6_hdr(skb));
232
222 if (skb->ip_summed == CHECKSUM_COMPLETE) { 233 if (skb->ip_summed == CHECKSUM_COMPLETE) {
223 const unsigned char *nh = skb_network_header(skb); 234 const unsigned char *nh = skb_network_header(skb);
224 skb->csum = csum_sub(skb->csum, 235 skb->csum = csum_sub(skb->csum,
@@ -319,6 +330,7 @@ found:
319 } 330 }
320 fq->q.stamp = skb->tstamp; 331 fq->q.stamp = skb->tstamp;
321 fq->q.meat += skb->len; 332 fq->q.meat += skb->len;
333 fq->ecn |= ecn;
322 add_frag_mem_limit(&fq->q, skb->truesize); 334 add_frag_mem_limit(&fq->q, skb->truesize);
323 335
324 /* The first fragment. 336 /* The first fragment.
@@ -370,9 +382,14 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev,
370 int payload_len; 382 int payload_len;
371 unsigned int nhoff; 383 unsigned int nhoff;
372 int sum_truesize; 384 int sum_truesize;
385 u8 ecn;
373 386
374 inet_frag_kill(&fq->q, &ip6_frags); 387 inet_frag_kill(&fq->q, &ip6_frags);
375 388
389 ecn = ip_frag_ecn_table[fq->ecn];
390 if (unlikely(ecn == 0xff))
391 goto out_fail;
392
376 /* Make the one we just received the head. */ 393 /* Make the one we just received the head. */
377 if (prev) { 394 if (prev) {
378 head = prev->next; 395 head = prev->next;
@@ -471,6 +488,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev,
471 head->dev = dev; 488 head->dev = dev;
472 head->tstamp = fq->q.stamp; 489 head->tstamp = fq->q.stamp;
473 ipv6_hdr(head)->payload_len = htons(payload_len); 490 ipv6_hdr(head)->payload_len = htons(payload_len);
491 ipv6_change_dsfield(ipv6_hdr(head), 0xff, ecn);
474 IP6CB(head)->nhoff = nhoff; 492 IP6CB(head)->nhoff = nhoff;
475 493
476 /* Yes, and fold redundant checksum back. 8) */ 494 /* Yes, and fold redundant checksum back. 8) */
@@ -534,7 +552,8 @@ static int ipv6_frag_rcv(struct sk_buff *skb)
534 IP6_ADD_STATS_BH(net, ip6_dst_idev(skb_dst(skb)), 552 IP6_ADD_STATS_BH(net, ip6_dst_idev(skb_dst(skb)),
535 IPSTATS_MIB_REASMFAILS, evicted); 553 IPSTATS_MIB_REASMFAILS, evicted);
536 554
537 fq = fq_find(net, fhdr->identification, &hdr->saddr, &hdr->daddr); 555 fq = fq_find(net, fhdr->identification, &hdr->saddr, &hdr->daddr,
556 ip6_frag_ecn(hdr));
538 if (fq != NULL) { 557 if (fq != NULL) {
539 int ret; 558 int ret;
540 559
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index e5fe0041adfa..ad0aa6b0b86a 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -2355,7 +2355,7 @@ beginning:
2355 return last_err; 2355 return last_err;
2356} 2356}
2357 2357
2358static int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) 2358static int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh)
2359{ 2359{
2360 struct fib6_config cfg; 2360 struct fib6_config cfg;
2361 int err; 2361 int err;
@@ -2370,7 +2370,7 @@ static int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *a
2370 return ip6_route_del(&cfg); 2370 return ip6_route_del(&cfg);
2371} 2371}
2372 2372
2373static int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) 2373static int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh)
2374{ 2374{
2375 struct fib6_config cfg; 2375 struct fib6_config cfg;
2376 int err; 2376 int err;
@@ -2562,7 +2562,7 @@ int rt6_dump_route(struct rt6_info *rt, void *p_arg)
2562 prefix, 0, NLM_F_MULTI); 2562 prefix, 0, NLM_F_MULTI);
2563} 2563}
2564 2564
2565static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg) 2565static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh)
2566{ 2566{
2567 struct net *net = sock_net(in_skb->sk); 2567 struct net *net = sock_net(in_skb->sk);
2568 struct nlattr *tb[RTA_MAX+1]; 2568 struct nlattr *tb[RTA_MAX+1];
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 02f96dcbcf02..335363478bbf 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -49,7 +49,7 @@
49#include <net/ip.h> 49#include <net/ip.h>
50#include <net/udp.h> 50#include <net/udp.h>
51#include <net/icmp.h> 51#include <net/icmp.h>
52#include <net/ipip.h> 52#include <net/ip_tunnels.h>
53#include <net/inet_ecn.h> 53#include <net/inet_ecn.h>
54#include <net/xfrm.h> 54#include <net/xfrm.h>
55#include <net/dsfield.h> 55#include <net/dsfield.h>
@@ -87,41 +87,6 @@ struct sit_net {
87 struct net_device *fb_tunnel_dev; 87 struct net_device *fb_tunnel_dev;
88}; 88};
89 89
90static struct rtnl_link_stats64 *ipip6_get_stats64(struct net_device *dev,
91 struct rtnl_link_stats64 *tot)
92{
93 int i;
94
95 for_each_possible_cpu(i) {
96 const struct pcpu_tstats *tstats = per_cpu_ptr(dev->tstats, i);
97 u64 rx_packets, rx_bytes, tx_packets, tx_bytes;
98 unsigned int start;
99
100 do {
101 start = u64_stats_fetch_begin_bh(&tstats->syncp);
102 rx_packets = tstats->rx_packets;
103 tx_packets = tstats->tx_packets;
104 rx_bytes = tstats->rx_bytes;
105 tx_bytes = tstats->tx_bytes;
106 } while (u64_stats_fetch_retry_bh(&tstats->syncp, start));
107
108 tot->rx_packets += rx_packets;
109 tot->tx_packets += tx_packets;
110 tot->rx_bytes += rx_bytes;
111 tot->tx_bytes += tx_bytes;
112 }
113
114 tot->rx_errors = dev->stats.rx_errors;
115 tot->rx_frame_errors = dev->stats.rx_frame_errors;
116 tot->tx_fifo_errors = dev->stats.tx_fifo_errors;
117 tot->tx_carrier_errors = dev->stats.tx_carrier_errors;
118 tot->tx_dropped = dev->stats.tx_dropped;
119 tot->tx_aborted_errors = dev->stats.tx_aborted_errors;
120 tot->tx_errors = dev->stats.tx_errors;
121
122 return tot;
123}
124
125/* 90/*
126 * Must be invoked with rcu_read_lock 91 * Must be invoked with rcu_read_lock
127 */ 92 */
@@ -899,6 +864,8 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
899 if ((iph->ttl = tiph->ttl) == 0) 864 if ((iph->ttl = tiph->ttl) == 0)
900 iph->ttl = iph6->hop_limit; 865 iph->ttl = iph6->hop_limit;
901 866
867 skb->ip_summed = CHECKSUM_NONE;
868 ip_select_ident(iph, skb_dst(skb), NULL);
902 iptunnel_xmit(skb, dev); 869 iptunnel_xmit(skb, dev);
903 return NETDEV_TX_OK; 870 return NETDEV_TX_OK;
904 871
@@ -1200,7 +1167,7 @@ static const struct net_device_ops ipip6_netdev_ops = {
1200 .ndo_start_xmit = ipip6_tunnel_xmit, 1167 .ndo_start_xmit = ipip6_tunnel_xmit,
1201 .ndo_do_ioctl = ipip6_tunnel_ioctl, 1168 .ndo_do_ioctl = ipip6_tunnel_ioctl,
1202 .ndo_change_mtu = ipip6_tunnel_change_mtu, 1169 .ndo_change_mtu = ipip6_tunnel_change_mtu,
1203 .ndo_get_stats64= ipip6_get_stats64, 1170 .ndo_get_stats64 = ip_tunnel_get_stats64,
1204}; 1171};
1205 1172
1206static void ipip6_dev_free(struct net_device *dev) 1173static void ipip6_dev_free(struct net_device *dev)
diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c
index 8a0848b60b35..d5dda20bd717 100644
--- a/net/ipv6/syncookies.c
+++ b/net/ipv6/syncookies.c
@@ -149,7 +149,6 @@ static inline int cookie_check(const struct sk_buff *skb, __u32 cookie)
149struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) 149struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
150{ 150{
151 struct tcp_options_received tcp_opt; 151 struct tcp_options_received tcp_opt;
152 const u8 *hash_location;
153 struct inet_request_sock *ireq; 152 struct inet_request_sock *ireq;
154 struct inet6_request_sock *ireq6; 153 struct inet6_request_sock *ireq6;
155 struct tcp_request_sock *treq; 154 struct tcp_request_sock *treq;
@@ -177,7 +176,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
177 176
178 /* check for timestamp cookie support */ 177 /* check for timestamp cookie support */
179 memset(&tcp_opt, 0, sizeof(tcp_opt)); 178 memset(&tcp_opt, 0, sizeof(tcp_opt));
180 tcp_parse_options(skb, &tcp_opt, &hash_location, 0, NULL); 179 tcp_parse_options(skb, &tcp_opt, 0, NULL);
181 180
182 if (!cookie_check_timestamp(&tcp_opt, sock_net(sk), &ecn_ok)) 181 if (!cookie_check_timestamp(&tcp_opt, sock_net(sk), &ecn_ok))
183 goto out; 182 goto out;
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 46a5be85be87..71167069b394 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -462,7 +462,6 @@ out:
462static int tcp_v6_send_synack(struct sock *sk, struct dst_entry *dst, 462static int tcp_v6_send_synack(struct sock *sk, struct dst_entry *dst,
463 struct flowi6 *fl6, 463 struct flowi6 *fl6,
464 struct request_sock *req, 464 struct request_sock *req,
465 struct request_values *rvp,
466 u16 queue_mapping) 465 u16 queue_mapping)
467{ 466{
468 struct inet6_request_sock *treq = inet6_rsk(req); 467 struct inet6_request_sock *treq = inet6_rsk(req);
@@ -474,7 +473,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct dst_entry *dst,
474 if (!dst && (dst = inet6_csk_route_req(sk, fl6, req)) == NULL) 473 if (!dst && (dst = inet6_csk_route_req(sk, fl6, req)) == NULL)
475 goto done; 474 goto done;
476 475
477 skb = tcp_make_synack(sk, dst, req, rvp, NULL); 476 skb = tcp_make_synack(sk, dst, req, NULL);
478 477
479 if (skb) { 478 if (skb) {
480 __tcp_v6_send_check(skb, &treq->loc_addr, &treq->rmt_addr); 479 __tcp_v6_send_check(skb, &treq->loc_addr, &treq->rmt_addr);
@@ -489,13 +488,12 @@ done:
489 return err; 488 return err;
490} 489}
491 490
492static int tcp_v6_rtx_synack(struct sock *sk, struct request_sock *req, 491static int tcp_v6_rtx_synack(struct sock *sk, struct request_sock *req)
493 struct request_values *rvp)
494{ 492{
495 struct flowi6 fl6; 493 struct flowi6 fl6;
496 int res; 494 int res;
497 495
498 res = tcp_v6_send_synack(sk, NULL, &fl6, req, rvp, 0); 496 res = tcp_v6_send_synack(sk, NULL, &fl6, req, 0);
499 if (!res) 497 if (!res)
500 TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS); 498 TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS);
501 return res; 499 return res;
@@ -948,9 +946,7 @@ static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
948 */ 946 */
949static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) 947static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
950{ 948{
951 struct tcp_extend_values tmp_ext;
952 struct tcp_options_received tmp_opt; 949 struct tcp_options_received tmp_opt;
953 const u8 *hash_location;
954 struct request_sock *req; 950 struct request_sock *req;
955 struct inet6_request_sock *treq; 951 struct inet6_request_sock *treq;
956 struct ipv6_pinfo *np = inet6_sk(sk); 952 struct ipv6_pinfo *np = inet6_sk(sk);
@@ -988,50 +984,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
988 tcp_clear_options(&tmp_opt); 984 tcp_clear_options(&tmp_opt);
989 tmp_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr); 985 tmp_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr);
990 tmp_opt.user_mss = tp->rx_opt.user_mss; 986 tmp_opt.user_mss = tp->rx_opt.user_mss;
991 tcp_parse_options(skb, &tmp_opt, &hash_location, 0, NULL); 987 tcp_parse_options(skb, &tmp_opt, 0, NULL);
992
993 if (tmp_opt.cookie_plus > 0 &&
994 tmp_opt.saw_tstamp &&
995 !tp->rx_opt.cookie_out_never &&
996 (sysctl_tcp_cookie_size > 0 ||
997 (tp->cookie_values != NULL &&
998 tp->cookie_values->cookie_desired > 0))) {
999 u8 *c;
1000 u32 *d;
1001 u32 *mess = &tmp_ext.cookie_bakery[COOKIE_DIGEST_WORDS];
1002 int l = tmp_opt.cookie_plus - TCPOLEN_COOKIE_BASE;
1003
1004 if (tcp_cookie_generator(&tmp_ext.cookie_bakery[0]) != 0)
1005 goto drop_and_free;
1006
1007 /* Secret recipe starts with IP addresses */
1008 d = (__force u32 *)&ipv6_hdr(skb)->daddr.s6_addr32[0];
1009 *mess++ ^= *d++;
1010 *mess++ ^= *d++;
1011 *mess++ ^= *d++;
1012 *mess++ ^= *d++;
1013 d = (__force u32 *)&ipv6_hdr(skb)->saddr.s6_addr32[0];
1014 *mess++ ^= *d++;
1015 *mess++ ^= *d++;
1016 *mess++ ^= *d++;
1017 *mess++ ^= *d++;
1018
1019 /* plus variable length Initiator Cookie */
1020 c = (u8 *)mess;
1021 while (l-- > 0)
1022 *c++ ^= *hash_location++;
1023
1024 want_cookie = false; /* not our kind of cookie */
1025 tmp_ext.cookie_out_never = 0; /* false */
1026 tmp_ext.cookie_plus = tmp_opt.cookie_plus;
1027 } else if (!tp->rx_opt.cookie_in_always) {
1028 /* redundant indications, but ensure initialization. */
1029 tmp_ext.cookie_out_never = 1; /* true */
1030 tmp_ext.cookie_plus = 0;
1031 } else {
1032 goto drop_and_free;
1033 }
1034 tmp_ext.cookie_in_always = tp->rx_opt.cookie_in_always;
1035 988
1036 if (want_cookie && !tmp_opt.saw_tstamp) 989 if (want_cookie && !tmp_opt.saw_tstamp)
1037 tcp_clear_options(&tmp_opt); 990 tcp_clear_options(&tmp_opt);
@@ -1109,7 +1062,6 @@ have_isn:
1109 goto drop_and_release; 1062 goto drop_and_release;
1110 1063
1111 if (tcp_v6_send_synack(sk, dst, &fl6, req, 1064 if (tcp_v6_send_synack(sk, dst, &fl6, req,
1112 (struct request_values *)&tmp_ext,
1113 skb_get_queue_mapping(skb)) || 1065 skb_get_queue_mapping(skb)) ||
1114 want_cookie) 1066 want_cookie)
1115 goto drop_and_free; 1067 goto drop_and_free;
@@ -1453,6 +1405,7 @@ discard:
1453 kfree_skb(skb); 1405 kfree_skb(skb);
1454 return 0; 1406 return 0;
1455csum_err: 1407csum_err:
1408 TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_CSUMERRORS);
1456 TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_INERRS); 1409 TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_INERRS);
1457 goto discard; 1410 goto discard;
1458 1411
@@ -1514,7 +1467,7 @@ static int tcp_v6_rcv(struct sk_buff *skb)
1514 goto discard_it; 1467 goto discard_it;
1515 1468
1516 if (!skb_csum_unnecessary(skb) && tcp_v6_checksum_init(skb)) 1469 if (!skb_csum_unnecessary(skb) && tcp_v6_checksum_init(skb))
1517 goto bad_packet; 1470 goto csum_error;
1518 1471
1519 th = tcp_hdr(skb); 1472 th = tcp_hdr(skb);
1520 hdr = ipv6_hdr(skb); 1473 hdr = ipv6_hdr(skb);
@@ -1578,6 +1531,8 @@ no_tcp_socket:
1578 goto discard_it; 1531 goto discard_it;
1579 1532
1580 if (skb->len < (th->doff<<2) || tcp_checksum_complete(skb)) { 1533 if (skb->len < (th->doff<<2) || tcp_checksum_complete(skb)) {
1534csum_error:
1535 TCP_INC_STATS_BH(net, TCP_MIB_CSUMERRORS);
1581bad_packet: 1536bad_packet:
1582 TCP_INC_STATS_BH(net, TCP_MIB_INERRS); 1537 TCP_INC_STATS_BH(net, TCP_MIB_INERRS);
1583 } else { 1538 } else {
@@ -1585,11 +1540,6 @@ bad_packet:
1585 } 1540 }
1586 1541
1587discard_it: 1542discard_it:
1588
1589 /*
1590 * Discard frame
1591 */
1592
1593 kfree_skb(skb); 1543 kfree_skb(skb);
1594 return 0; 1544 return 0;
1595 1545
@@ -1603,10 +1553,13 @@ do_time_wait:
1603 goto discard_it; 1553 goto discard_it;
1604 } 1554 }
1605 1555
1606 if (skb->len < (th->doff<<2) || tcp_checksum_complete(skb)) { 1556 if (skb->len < (th->doff<<2)) {
1607 TCP_INC_STATS_BH(net, TCP_MIB_INERRS);
1608 inet_twsk_put(inet_twsk(sk)); 1557 inet_twsk_put(inet_twsk(sk));
1609 goto discard_it; 1558 goto bad_packet;
1559 }
1560 if (tcp_checksum_complete(skb)) {
1561 inet_twsk_put(inet_twsk(sk));
1562 goto csum_error;
1610 } 1563 }
1611 1564
1612 switch (tcp_timewait_state_process(inet_twsk(sk), skb, th)) { 1565 switch (tcp_timewait_state_process(inet_twsk(sk), skb, th)) {
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index d8e5e852fc7a..d4defdd44937 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -450,15 +450,16 @@ try_again:
450 sin6->sin6_family = AF_INET6; 450 sin6->sin6_family = AF_INET6;
451 sin6->sin6_port = udp_hdr(skb)->source; 451 sin6->sin6_port = udp_hdr(skb)->source;
452 sin6->sin6_flowinfo = 0; 452 sin6->sin6_flowinfo = 0;
453 sin6->sin6_scope_id = 0;
454 453
455 if (is_udp4) 454 if (is_udp4) {
456 ipv6_addr_set_v4mapped(ip_hdr(skb)->saddr, 455 ipv6_addr_set_v4mapped(ip_hdr(skb)->saddr,
457 &sin6->sin6_addr); 456 &sin6->sin6_addr);
458 else { 457 sin6->sin6_scope_id = 0;
458 } else {
459 sin6->sin6_addr = ipv6_hdr(skb)->saddr; 459 sin6->sin6_addr = ipv6_hdr(skb)->saddr;
460 if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) 460 sin6->sin6_scope_id =
461 sin6->sin6_scope_id = IP6CB(skb)->iif; 461 ipv6_iface_scope_id(&sin6->sin6_addr,
462 IP6CB(skb)->iif);
462 } 463 }
463 464
464 } 465 }
@@ -482,12 +483,17 @@ out:
482csum_copy_err: 483csum_copy_err:
483 slow = lock_sock_fast(sk); 484 slow = lock_sock_fast(sk);
484 if (!skb_kill_datagram(sk, skb, flags)) { 485 if (!skb_kill_datagram(sk, skb, flags)) {
485 if (is_udp4) 486 if (is_udp4) {
487 UDP_INC_STATS_USER(sock_net(sk),
488 UDP_MIB_CSUMERRORS, is_udplite);
486 UDP_INC_STATS_USER(sock_net(sk), 489 UDP_INC_STATS_USER(sock_net(sk),
487 UDP_MIB_INERRORS, is_udplite); 490 UDP_MIB_INERRORS, is_udplite);
488 else 491 } else {
492 UDP6_INC_STATS_USER(sock_net(sk),
493 UDP_MIB_CSUMERRORS, is_udplite);
489 UDP6_INC_STATS_USER(sock_net(sk), 494 UDP6_INC_STATS_USER(sock_net(sk),
490 UDP_MIB_INERRORS, is_udplite); 495 UDP_MIB_INERRORS, is_udplite);
496 }
491 } 497 }
492 unlock_sock_fast(sk, slow); 498 unlock_sock_fast(sk, slow);
493 499
@@ -636,7 +642,7 @@ int udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
636 642
637 if (rcu_access_pointer(sk->sk_filter)) { 643 if (rcu_access_pointer(sk->sk_filter)) {
638 if (udp_lib_checksum_complete(skb)) 644 if (udp_lib_checksum_complete(skb))
639 goto drop; 645 goto csum_error;
640 } 646 }
641 647
642 if (sk_rcvqueues_full(sk, skb, sk->sk_rcvbuf)) 648 if (sk_rcvqueues_full(sk, skb, sk->sk_rcvbuf))
@@ -655,6 +661,8 @@ int udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
655 bh_unlock_sock(sk); 661 bh_unlock_sock(sk);
656 662
657 return rc; 663 return rc;
664csum_error:
665 UDP6_INC_STATS_BH(sock_net(sk), UDP_MIB_CSUMERRORS, is_udplite);
658drop: 666drop:
659 UDP6_INC_STATS_BH(sock_net(sk), UDP_MIB_INERRORS, is_udplite); 667 UDP6_INC_STATS_BH(sock_net(sk), UDP_MIB_INERRORS, is_udplite);
660 atomic_inc(&sk->sk_drops); 668 atomic_inc(&sk->sk_drops);
@@ -816,7 +824,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
816 } 824 }
817 825
818 if (udp6_csum_init(skb, uh, proto)) 826 if (udp6_csum_init(skb, uh, proto))
819 goto discard; 827 goto csum_error;
820 828
821 /* 829 /*
822 * Multicast receive code 830 * Multicast receive code
@@ -849,7 +857,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
849 goto discard; 857 goto discard;
850 858
851 if (udp_lib_checksum_complete(skb)) 859 if (udp_lib_checksum_complete(skb))
852 goto discard; 860 goto csum_error;
853 861
854 UDP6_INC_STATS_BH(net, UDP_MIB_NOPORTS, proto == IPPROTO_UDPLITE); 862 UDP6_INC_STATS_BH(net, UDP_MIB_NOPORTS, proto == IPPROTO_UDPLITE);
855 icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0); 863 icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0);
@@ -866,7 +874,9 @@ short_packet:
866 skb->len, 874 skb->len,
867 daddr, 875 daddr,
868 ntohs(uh->dest)); 876 ntohs(uh->dest));
869 877 goto discard;
878csum_error:
879 UDP6_INC_STATS_BH(net, UDP_MIB_CSUMERRORS, proto == IPPROTO_UDPLITE);
870discard: 880discard:
871 UDP6_INC_STATS_BH(net, UDP_MIB_INERRORS, proto == IPPROTO_UDPLITE); 881 UDP6_INC_STATS_BH(net, UDP_MIB_INERRORS, proto == IPPROTO_UDPLITE);
872 kfree_skb(skb); 882 kfree_skb(skb);
@@ -1118,7 +1128,7 @@ do_udp_sendmsg:
1118 1128
1119 if (addr_len >= sizeof(struct sockaddr_in6) && 1129 if (addr_len >= sizeof(struct sockaddr_in6) &&
1120 sin6->sin6_scope_id && 1130 sin6->sin6_scope_id &&
1121 ipv6_addr_type(daddr)&IPV6_ADDR_LINKLOCAL) 1131 __ipv6_addr_needs_scope_id(__ipv6_addr_type(daddr)))
1122 fl6.flowi6_oif = sin6->sin6_scope_id; 1132 fl6.flowi6_oif = sin6->sin6_scope_id;
1123 } else { 1133 } else {
1124 if (sk->sk_state != TCP_ESTABLISHED) 1134 if (sk->sk_state != TCP_ESTABLISHED)
diff --git a/net/ipv6/udp_offload.c b/net/ipv6/udp_offload.c
index cf05cf073c51..3bb3a891a424 100644
--- a/net/ipv6/udp_offload.c
+++ b/net/ipv6/udp_offload.c
@@ -21,6 +21,10 @@ static int udp6_ufo_send_check(struct sk_buff *skb)
21 const struct ipv6hdr *ipv6h; 21 const struct ipv6hdr *ipv6h;
22 struct udphdr *uh; 22 struct udphdr *uh;
23 23
24 /* UDP Tunnel offload on ipv6 is not yet supported. */
25 if (skb->encapsulation)
26 return -EINVAL;
27
24 if (!pskb_may_pull(skb, sizeof(*uh))) 28 if (!pskb_may_pull(skb, sizeof(*uh)))
25 return -EINVAL; 29 return -EINVAL;
26 30
@@ -56,7 +60,9 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb,
56 /* Packet is from an untrusted source, reset gso_segs. */ 60 /* Packet is from an untrusted source, reset gso_segs. */
57 int type = skb_shinfo(skb)->gso_type; 61 int type = skb_shinfo(skb)->gso_type;
58 62
59 if (unlikely(type & ~(SKB_GSO_UDP | SKB_GSO_DODGY | 63 if (unlikely(type & ~(SKB_GSO_UDP |
64 SKB_GSO_DODGY |
65 SKB_GSO_UDP_TUNNEL |
60 SKB_GSO_GRE) || 66 SKB_GSO_GRE) ||
61 !(type & (SKB_GSO_UDP)))) 67 !(type & (SKB_GSO_UDP))))
62 goto out; 68 goto out;
diff --git a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c
index 9bf6a74a71d2..4770d515c2c8 100644
--- a/net/ipv6/xfrm6_mode_tunnel.c
+++ b/net/ipv6/xfrm6_mode_tunnel.c
@@ -49,8 +49,11 @@ static int xfrm6_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
49 sizeof(top_iph->flow_lbl)); 49 sizeof(top_iph->flow_lbl));
50 top_iph->nexthdr = xfrm_af2proto(skb_dst(skb)->ops->family); 50 top_iph->nexthdr = xfrm_af2proto(skb_dst(skb)->ops->family);
51 51
52 dsfield = XFRM_MODE_SKB_CB(skb)->tos; 52 if (x->props.extra_flags & XFRM_SA_XFLAG_DONT_ENCAP_DSCP)
53 dsfield = INET_ECN_encapsulate(dsfield, dsfield); 53 dsfield = 0;
54 else
55 dsfield = XFRM_MODE_SKB_CB(skb)->tos;
56 dsfield = INET_ECN_encapsulate(dsfield, XFRM_MODE_SKB_CB(skb)->tos);
54 if (x->props.flags & XFRM_STATE_NOECN) 57 if (x->props.flags & XFRM_STATE_NOECN)
55 dsfield &= ~INET_ECN_MASK; 58 dsfield &= ~INET_ECN_MASK;
56 ipv6_change_dsfield(top_iph, 0, dsfield); 59 ipv6_change_dsfield(top_iph, 0, dsfield);