diff options
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/Kconfig | 2 | ||||
-rw-r--r-- | net/ipv6/addrconf.c | 108 | ||||
-rw-r--r-- | net/ipv6/addrlabel.c | 12 | ||||
-rw-r--r-- | net/ipv6/af_inet6.c | 7 | ||||
-rw-r--r-- | net/ipv6/datagram.c | 20 | ||||
-rw-r--r-- | net/ipv6/icmp.c | 2 | ||||
-rw-r--r-- | net/ipv6/inet6_connection_sock.c | 10 | ||||
-rw-r--r-- | net/ipv6/ip6_flowlabel.c | 11 | ||||
-rw-r--r-- | net/ipv6/ip6_gre.c | 62 | ||||
-rw-r--r-- | net/ipv6/ip6_offload.c | 4 | ||||
-rw-r--r-- | net/ipv6/ip6_tunnel.c | 16 | ||||
-rw-r--r-- | net/ipv6/ip6mr.c | 10 | ||||
-rw-r--r-- | net/ipv6/ndisc.c | 2 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6t_NPT.c | 11 | ||||
-rw-r--r-- | net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 8 | ||||
-rw-r--r-- | net/ipv6/raw.c | 9 | ||||
-rw-r--r-- | net/ipv6/reassembly.c | 23 | ||||
-rw-r--r-- | net/ipv6/route.c | 6 | ||||
-rw-r--r-- | net/ipv6/sit.c | 41 | ||||
-rw-r--r-- | net/ipv6/syncookies.c | 3 | ||||
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 56 | ||||
-rw-r--r-- | net/ipv6/udp.c | 13 | ||||
-rw-r--r-- | net/ipv6/udp_offload.c | 8 |
23 files changed, 202 insertions, 242 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 | |||
156 | config IPV6_SIT | 156 | config 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 | |||
201 | config IPV6_GRE | 202 | config 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/addrconf.c b/net/ipv6/addrconf.c index a459c4f5b769..a33b157d9ccf 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> |
@@ -544,8 +545,7 @@ static const struct nla_policy devconf_ipv6_policy[NETCONFA_MAX+1] = { | |||
544 | }; | 545 | }; |
545 | 546 | ||
546 | static int inet6_netconf_get_devconf(struct sk_buff *in_skb, | 547 | static int inet6_netconf_get_devconf(struct sk_buff *in_skb, |
547 | struct nlmsghdr *nlh, | 548 | struct nlmsghdr *nlh) |
548 | void *arg) | ||
549 | { | 549 | { |
550 | struct net *net = sock_net(in_skb->sk); | 550 | struct net *net = sock_net(in_skb->sk); |
551 | struct nlattr *tb[NETCONFA_MAX+1]; | 551 | struct nlattr *tb[NETCONFA_MAX+1]; |
@@ -605,6 +605,77 @@ errout: | |||
605 | return err; | 605 | return err; |
606 | } | 606 | } |
607 | 607 | ||
608 | static int inet6_netconf_dump_devconf(struct sk_buff *skb, | ||
609 | struct netlink_callback *cb) | ||
610 | { | ||
611 | struct net *net = sock_net(skb->sk); | ||
612 | int h, s_h; | ||
613 | int idx, s_idx; | ||
614 | struct net_device *dev; | ||
615 | struct inet6_dev *idev; | ||
616 | struct hlist_head *head; | ||
617 | |||
618 | s_h = cb->args[0]; | ||
619 | s_idx = idx = cb->args[1]; | ||
620 | |||
621 | for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) { | ||
622 | idx = 0; | ||
623 | head = &net->dev_index_head[h]; | ||
624 | rcu_read_lock(); | ||
625 | cb->seq = atomic_read(&net->ipv6.dev_addr_genid) ^ | ||
626 | net->dev_base_seq; | ||
627 | hlist_for_each_entry_rcu(dev, head, index_hlist) { | ||
628 | if (idx < s_idx) | ||
629 | goto cont; | ||
630 | idev = __in6_dev_get(dev); | ||
631 | if (!idev) | ||
632 | goto cont; | ||
633 | |||
634 | if (inet6_netconf_fill_devconf(skb, dev->ifindex, | ||
635 | &idev->cnf, | ||
636 | NETLINK_CB(cb->skb).portid, | ||
637 | cb->nlh->nlmsg_seq, | ||
638 | RTM_NEWNETCONF, | ||
639 | NLM_F_MULTI, | ||
640 | -1) <= 0) { | ||
641 | rcu_read_unlock(); | ||
642 | goto done; | ||
643 | } | ||
644 | nl_dump_check_consistent(cb, nlmsg_hdr(skb)); | ||
645 | cont: | ||
646 | idx++; | ||
647 | } | ||
648 | rcu_read_unlock(); | ||
649 | } | ||
650 | if (h == NETDEV_HASHENTRIES) { | ||
651 | if (inet6_netconf_fill_devconf(skb, NETCONFA_IFINDEX_ALL, | ||
652 | net->ipv6.devconf_all, | ||
653 | NETLINK_CB(cb->skb).portid, | ||
654 | cb->nlh->nlmsg_seq, | ||
655 | RTM_NEWNETCONF, NLM_F_MULTI, | ||
656 | -1) <= 0) | ||
657 | goto done; | ||
658 | else | ||
659 | h++; | ||
660 | } | ||
661 | if (h == NETDEV_HASHENTRIES + 1) { | ||
662 | if (inet6_netconf_fill_devconf(skb, NETCONFA_IFINDEX_DEFAULT, | ||
663 | net->ipv6.devconf_dflt, | ||
664 | NETLINK_CB(cb->skb).portid, | ||
665 | cb->nlh->nlmsg_seq, | ||
666 | RTM_NEWNETCONF, NLM_F_MULTI, | ||
667 | -1) <= 0) | ||
668 | goto done; | ||
669 | else | ||
670 | h++; | ||
671 | } | ||
672 | done: | ||
673 | cb->args[0] = h; | ||
674 | cb->args[1] = idx; | ||
675 | |||
676 | return skb->len; | ||
677 | } | ||
678 | |||
608 | #ifdef CONFIG_SYSCTL | 679 | #ifdef CONFIG_SYSCTL |
609 | static void dev_forward_change(struct inet6_dev *idev) | 680 | static void dev_forward_change(struct inet6_dev *idev) |
610 | { | 681 | { |
@@ -1668,6 +1739,20 @@ static int addrconf_ifid_eui64(u8 *eui, struct net_device *dev) | |||
1668 | return 0; | 1739 | return 0; |
1669 | } | 1740 | } |
1670 | 1741 | ||
1742 | static 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 | |||
1671 | static int addrconf_ifid_arcnet(u8 *eui, struct net_device *dev) | 1756 | static int addrconf_ifid_arcnet(u8 *eui, struct net_device *dev) |
1672 | { | 1757 | { |
1673 | /* XXX: inherit EUI-64 from other interface -- yoshfuji */ | 1758 | /* XXX: inherit EUI-64 from other interface -- yoshfuji */ |
@@ -1732,6 +1817,8 @@ static int ipv6_generate_eui64(u8 *eui, struct net_device *dev) | |||
1732 | return addrconf_ifid_gre(eui, dev); | 1817 | return addrconf_ifid_gre(eui, dev); |
1733 | case ARPHRD_IEEE802154: | 1818 | case ARPHRD_IEEE802154: |
1734 | return addrconf_ifid_eui64(eui, dev); | 1819 | return addrconf_ifid_eui64(eui, dev); |
1820 | case ARPHRD_IEEE1394: | ||
1821 | return addrconf_ifid_ieee1394(eui, dev); | ||
1735 | } | 1822 | } |
1736 | return -1; | 1823 | return -1; |
1737 | } | 1824 | } |
@@ -2600,7 +2687,8 @@ static void addrconf_dev_config(struct net_device *dev) | |||
2600 | (dev->type != ARPHRD_FDDI) && | 2687 | (dev->type != ARPHRD_FDDI) && |
2601 | (dev->type != ARPHRD_ARCNET) && | 2688 | (dev->type != ARPHRD_ARCNET) && |
2602 | (dev->type != ARPHRD_INFINIBAND) && | 2689 | (dev->type != ARPHRD_INFINIBAND) && |
2603 | (dev->type != ARPHRD_IEEE802154)) { | 2690 | (dev->type != ARPHRD_IEEE802154) && |
2691 | (dev->type != ARPHRD_IEEE1394)) { | ||
2604 | /* Alas, we support only Ethernet autoconfiguration. */ | 2692 | /* Alas, we support only Ethernet autoconfiguration. */ |
2605 | return; | 2693 | return; |
2606 | } | 2694 | } |
@@ -3537,7 +3625,7 @@ static const struct nla_policy ifa_ipv6_policy[IFA_MAX+1] = { | |||
3537 | }; | 3625 | }; |
3538 | 3626 | ||
3539 | static int | 3627 | static int |
3540 | inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | 3628 | inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh) |
3541 | { | 3629 | { |
3542 | struct net *net = sock_net(skb->sk); | 3630 | struct net *net = sock_net(skb->sk); |
3543 | struct ifaddrmsg *ifm; | 3631 | struct ifaddrmsg *ifm; |
@@ -3603,7 +3691,7 @@ static int inet6_addr_modify(struct inet6_ifaddr *ifp, u8 ifa_flags, | |||
3603 | } | 3691 | } |
3604 | 3692 | ||
3605 | static int | 3693 | static int |
3606 | inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | 3694 | inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh) |
3607 | { | 3695 | { |
3608 | struct net *net = sock_net(skb->sk); | 3696 | struct net *net = sock_net(skb->sk); |
3609 | struct ifaddrmsg *ifm; | 3697 | struct ifaddrmsg *ifm; |
@@ -3834,6 +3922,7 @@ static int in6_dump_addrs(struct inet6_dev *idev, struct sk_buff *skb, | |||
3834 | NLM_F_MULTI); | 3922 | NLM_F_MULTI); |
3835 | if (err <= 0) | 3923 | if (err <= 0) |
3836 | break; | 3924 | break; |
3925 | nl_dump_check_consistent(cb, nlmsg_hdr(skb)); | ||
3837 | } | 3926 | } |
3838 | break; | 3927 | break; |
3839 | } | 3928 | } |
@@ -3891,6 +3980,7 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb, | |||
3891 | s_ip_idx = ip_idx = cb->args[2]; | 3980 | s_ip_idx = ip_idx = cb->args[2]; |
3892 | 3981 | ||
3893 | rcu_read_lock(); | 3982 | rcu_read_lock(); |
3983 | cb->seq = atomic_read(&net->ipv6.dev_addr_genid) ^ net->dev_base_seq; | ||
3894 | for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) { | 3984 | for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) { |
3895 | idx = 0; | 3985 | idx = 0; |
3896 | head = &net->dev_index_head[h]; | 3986 | head = &net->dev_index_head[h]; |
@@ -3942,8 +4032,7 @@ static int inet6_dump_ifacaddr(struct sk_buff *skb, struct netlink_callback *cb) | |||
3942 | return inet6_dump_addr(skb, cb, type); | 4032 | return inet6_dump_addr(skb, cb, type); |
3943 | } | 4033 | } |
3944 | 4034 | ||
3945 | static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr *nlh, | 4035 | static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr *nlh) |
3946 | void *arg) | ||
3947 | { | 4036 | { |
3948 | struct net *net = sock_net(in_skb->sk); | 4037 | struct net *net = sock_net(in_skb->sk); |
3949 | struct ifaddrmsg *ifm; | 4038 | struct ifaddrmsg *ifm; |
@@ -4368,6 +4457,8 @@ errout: | |||
4368 | 4457 | ||
4369 | static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) | 4458 | static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) |
4370 | { | 4459 | { |
4460 | struct net *net = dev_net(ifp->idev->dev); | ||
4461 | |||
4371 | inet6_ifa_notify(event ? : RTM_NEWADDR, ifp); | 4462 | inet6_ifa_notify(event ? : RTM_NEWADDR, ifp); |
4372 | 4463 | ||
4373 | switch (event) { | 4464 | switch (event) { |
@@ -4393,6 +4484,7 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) | |||
4393 | dst_free(&ifp->rt->dst); | 4484 | dst_free(&ifp->rt->dst); |
4394 | break; | 4485 | break; |
4395 | } | 4486 | } |
4487 | atomic_inc(&net->ipv6.dev_addr_genid); | ||
4396 | } | 4488 | } |
4397 | 4489 | ||
4398 | static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) | 4490 | static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) |
@@ -4961,7 +5053,7 @@ int __init addrconf_init(void) | |||
4961 | __rtnl_register(PF_INET6, RTM_GETANYCAST, NULL, | 5053 | __rtnl_register(PF_INET6, RTM_GETANYCAST, NULL, |
4962 | inet6_dump_ifacaddr, NULL); | 5054 | inet6_dump_ifacaddr, NULL); |
4963 | __rtnl_register(PF_INET6, RTM_GETNETCONF, inet6_netconf_get_devconf, | 5055 | __rtnl_register(PF_INET6, RTM_GETNETCONF, inet6_netconf_get_devconf, |
4964 | NULL, NULL); | 5056 | inet6_netconf_dump_devconf, NULL); |
4965 | 5057 | ||
4966 | ipv6_addr_label_rtnl_register(); | 5058 | ipv6_addr_label_rtnl_register(); |
4967 | 5059 | ||
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 | ||
417 | static int ip6addrlbl_newdel(struct sk_buff *skb, struct nlmsghdr *nlh, | 417 | static 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 | ||
536 | static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr* nlh, | 532 | static 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..71b900c3f4ff 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c | |||
@@ -434,7 +434,7 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info) | |||
434 | * Source addr check | 434 | * Source addr check |
435 | */ | 435 | */ |
436 | 436 | ||
437 | if (addr_type & IPV6_ADDR_LINKLOCAL) | 437 | if (__ipv6_addr_needs_scope_id(addr_type)) |
438 | iif = skb->dev->ifindex; | 438 | iif = skb->dev->ifindex; |
439 | 439 | ||
440 | /* | 440 | /* |
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 | ||
178 | EXPORT_SYMBOL_GPL(inet6_csk_addr2sockaddr); | 180 | EXPORT_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 | ||
113 | static 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 | ||
155 | static struct ip6_tnl *ip6gre_tunnel_lookup(struct net_device *dev, | 116 | static 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; |
822 | tx_err_link_failure: | 768 | tx_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 | ||
1277 | static void ip6gre_dev_free(struct net_device *dev) | 1223 | static 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 | ||
1526 | static void ip6gre_tap_setup(struct net_device *dev) | 1472 | static void ip6gre_tap_setup(struct net_device *dev) |
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_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/ip6t_NPT.c b/net/ipv6/netfilter/ip6t_NPT.c index 33608c610276..938e0b7ea1bd 100644 --- a/net/ipv6/netfilter/ip6t_NPT.c +++ b/net/ipv6/netfilter/ip6t_NPT.c | |||
@@ -18,9 +18,8 @@ | |||
18 | static int ip6t_npt_checkentry(const struct xt_tgchk_param *par) | 18 | static 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/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/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 196ab9347ad1..e6e44cef8db2 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 | ||
62 | struct ip6frag_skb_cb | 63 | struct 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 | ||
71 | static inline u8 ip6_frag_ecn(const struct ipv6hdr *ipv6h) | ||
72 | { | ||
73 | return 1 << (ipv6_get_dsfield(ipv6h) & INET_ECN_MASK); | ||
74 | } | ||
70 | 75 | ||
71 | static struct inet_frags ip6_frags; | 76 | static 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 | } |
123 | EXPORT_SYMBOL(ip6_frag_init); | 129 | EXPORT_SYMBOL(ip6_frag_init); |
124 | 130 | ||
@@ -173,7 +179,8 @@ static void ip6_frag_expire(unsigned long data) | |||
173 | } | 179 | } |
174 | 180 | ||
175 | static __inline__ struct frag_queue * | 181 | static __inline__ struct frag_queue * |
176 | fq_find(struct net *net, __be32 id, const struct in6_addr *src, const struct in6_addr *dst) | 182 | fq_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. |
@@ -362,9 +374,14 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev, | |||
362 | int payload_len; | 374 | int payload_len; |
363 | unsigned int nhoff; | 375 | unsigned int nhoff; |
364 | int sum_truesize; | 376 | int sum_truesize; |
377 | u8 ecn; | ||
365 | 378 | ||
366 | inet_frag_kill(&fq->q, &ip6_frags); | 379 | inet_frag_kill(&fq->q, &ip6_frags); |
367 | 380 | ||
381 | ecn = ip_frag_ecn_table[fq->ecn]; | ||
382 | if (unlikely(ecn == 0xff)) | ||
383 | goto out_fail; | ||
384 | |||
368 | /* Make the one we just received the head. */ | 385 | /* Make the one we just received the head. */ |
369 | if (prev) { | 386 | if (prev) { |
370 | head = prev->next; | 387 | head = prev->next; |
@@ -463,6 +480,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev, | |||
463 | head->dev = dev; | 480 | head->dev = dev; |
464 | head->tstamp = fq->q.stamp; | 481 | head->tstamp = fq->q.stamp; |
465 | ipv6_hdr(head)->payload_len = htons(payload_len); | 482 | ipv6_hdr(head)->payload_len = htons(payload_len); |
483 | ipv6_change_dsfield(ipv6_hdr(head), 0xff, ecn); | ||
466 | IP6CB(head)->nhoff = nhoff; | 484 | IP6CB(head)->nhoff = nhoff; |
467 | 485 | ||
468 | /* Yes, and fold redundant checksum back. 8) */ | 486 | /* Yes, and fold redundant checksum back. 8) */ |
@@ -526,7 +544,8 @@ static int ipv6_frag_rcv(struct sk_buff *skb) | |||
526 | IP6_ADD_STATS_BH(net, ip6_dst_idev(skb_dst(skb)), | 544 | IP6_ADD_STATS_BH(net, ip6_dst_idev(skb_dst(skb)), |
527 | IPSTATS_MIB_REASMFAILS, evicted); | 545 | IPSTATS_MIB_REASMFAILS, evicted); |
528 | 546 | ||
529 | fq = fq_find(net, fhdr->identification, &hdr->saddr, &hdr->daddr); | 547 | fq = fq_find(net, fhdr->identification, &hdr->saddr, &hdr->daddr, |
548 | ip6_frag_ecn(hdr)); | ||
530 | if (fq != NULL) { | 549 | if (fq != NULL) { |
531 | int ret; | 550 | int ret; |
532 | 551 | ||
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 | ||
2358 | static int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | 2358 | static 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 | ||
2373 | static int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | 2373 | static 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 | ||
2565 | static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg) | 2565 | static 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 | ||
90 | static 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 | ||
1206 | static void ipip6_dev_free(struct net_device *dev) | 1173 | static 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) | |||
149 | struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) | 149 | struct 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 f6d629fd6aee..1033d2b1d81e 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -461,7 +461,6 @@ out: | |||
461 | static int tcp_v6_send_synack(struct sock *sk, struct dst_entry *dst, | 461 | static int tcp_v6_send_synack(struct sock *sk, struct dst_entry *dst, |
462 | struct flowi6 *fl6, | 462 | struct flowi6 *fl6, |
463 | struct request_sock *req, | 463 | struct request_sock *req, |
464 | struct request_values *rvp, | ||
465 | u16 queue_mapping) | 464 | u16 queue_mapping) |
466 | { | 465 | { |
467 | struct inet6_request_sock *treq = inet6_rsk(req); | 466 | struct inet6_request_sock *treq = inet6_rsk(req); |
@@ -473,7 +472,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct dst_entry *dst, | |||
473 | if (!dst && (dst = inet6_csk_route_req(sk, fl6, req)) == NULL) | 472 | if (!dst && (dst = inet6_csk_route_req(sk, fl6, req)) == NULL) |
474 | goto done; | 473 | goto done; |
475 | 474 | ||
476 | skb = tcp_make_synack(sk, dst, req, rvp, NULL); | 475 | skb = tcp_make_synack(sk, dst, req, NULL); |
477 | 476 | ||
478 | if (skb) { | 477 | if (skb) { |
479 | __tcp_v6_send_check(skb, &treq->loc_addr, &treq->rmt_addr); | 478 | __tcp_v6_send_check(skb, &treq->loc_addr, &treq->rmt_addr); |
@@ -488,13 +487,12 @@ done: | |||
488 | return err; | 487 | return err; |
489 | } | 488 | } |
490 | 489 | ||
491 | static int tcp_v6_rtx_synack(struct sock *sk, struct request_sock *req, | 490 | static int tcp_v6_rtx_synack(struct sock *sk, struct request_sock *req) |
492 | struct request_values *rvp) | ||
493 | { | 491 | { |
494 | struct flowi6 fl6; | 492 | struct flowi6 fl6; |
495 | int res; | 493 | int res; |
496 | 494 | ||
497 | res = tcp_v6_send_synack(sk, NULL, &fl6, req, rvp, 0); | 495 | res = tcp_v6_send_synack(sk, NULL, &fl6, req, 0); |
498 | if (!res) | 496 | if (!res) |
499 | TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS); | 497 | TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS); |
500 | return res; | 498 | return res; |
@@ -947,9 +945,7 @@ static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb) | |||
947 | */ | 945 | */ |
948 | static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) | 946 | static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) |
949 | { | 947 | { |
950 | struct tcp_extend_values tmp_ext; | ||
951 | struct tcp_options_received tmp_opt; | 948 | struct tcp_options_received tmp_opt; |
952 | const u8 *hash_location; | ||
953 | struct request_sock *req; | 949 | struct request_sock *req; |
954 | struct inet6_request_sock *treq; | 950 | struct inet6_request_sock *treq; |
955 | struct ipv6_pinfo *np = inet6_sk(sk); | 951 | struct ipv6_pinfo *np = inet6_sk(sk); |
@@ -987,50 +983,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) | |||
987 | tcp_clear_options(&tmp_opt); | 983 | tcp_clear_options(&tmp_opt); |
988 | tmp_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr); | 984 | tmp_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr); |
989 | tmp_opt.user_mss = tp->rx_opt.user_mss; | 985 | tmp_opt.user_mss = tp->rx_opt.user_mss; |
990 | tcp_parse_options(skb, &tmp_opt, &hash_location, 0, NULL); | 986 | tcp_parse_options(skb, &tmp_opt, 0, NULL); |
991 | |||
992 | if (tmp_opt.cookie_plus > 0 && | ||
993 | tmp_opt.saw_tstamp && | ||
994 | !tp->rx_opt.cookie_out_never && | ||
995 | (sysctl_tcp_cookie_size > 0 || | ||
996 | (tp->cookie_values != NULL && | ||
997 | tp->cookie_values->cookie_desired > 0))) { | ||
998 | u8 *c; | ||
999 | u32 *d; | ||
1000 | u32 *mess = &tmp_ext.cookie_bakery[COOKIE_DIGEST_WORDS]; | ||
1001 | int l = tmp_opt.cookie_plus - TCPOLEN_COOKIE_BASE; | ||
1002 | |||
1003 | if (tcp_cookie_generator(&tmp_ext.cookie_bakery[0]) != 0) | ||
1004 | goto drop_and_free; | ||
1005 | |||
1006 | /* Secret recipe starts with IP addresses */ | ||
1007 | d = (__force u32 *)&ipv6_hdr(skb)->daddr.s6_addr32[0]; | ||
1008 | *mess++ ^= *d++; | ||
1009 | *mess++ ^= *d++; | ||
1010 | *mess++ ^= *d++; | ||
1011 | *mess++ ^= *d++; | ||
1012 | d = (__force u32 *)&ipv6_hdr(skb)->saddr.s6_addr32[0]; | ||
1013 | *mess++ ^= *d++; | ||
1014 | *mess++ ^= *d++; | ||
1015 | *mess++ ^= *d++; | ||
1016 | *mess++ ^= *d++; | ||
1017 | |||
1018 | /* plus variable length Initiator Cookie */ | ||
1019 | c = (u8 *)mess; | ||
1020 | while (l-- > 0) | ||
1021 | *c++ ^= *hash_location++; | ||
1022 | |||
1023 | want_cookie = false; /* not our kind of cookie */ | ||
1024 | tmp_ext.cookie_out_never = 0; /* false */ | ||
1025 | tmp_ext.cookie_plus = tmp_opt.cookie_plus; | ||
1026 | } else if (!tp->rx_opt.cookie_in_always) { | ||
1027 | /* redundant indications, but ensure initialization. */ | ||
1028 | tmp_ext.cookie_out_never = 1; /* true */ | ||
1029 | tmp_ext.cookie_plus = 0; | ||
1030 | } else { | ||
1031 | goto drop_and_free; | ||
1032 | } | ||
1033 | tmp_ext.cookie_in_always = tp->rx_opt.cookie_in_always; | ||
1034 | 987 | ||
1035 | if (want_cookie && !tmp_opt.saw_tstamp) | 988 | if (want_cookie && !tmp_opt.saw_tstamp) |
1036 | tcp_clear_options(&tmp_opt); | 989 | tcp_clear_options(&tmp_opt); |
@@ -1108,7 +1061,6 @@ have_isn: | |||
1108 | goto drop_and_release; | 1061 | goto drop_and_release; |
1109 | 1062 | ||
1110 | if (tcp_v6_send_synack(sk, dst, &fl6, req, | 1063 | if (tcp_v6_send_synack(sk, dst, &fl6, req, |
1111 | (struct request_values *)&tmp_ext, | ||
1112 | skb_get_queue_mapping(skb)) || | 1064 | skb_get_queue_mapping(skb)) || |
1113 | want_cookie) | 1065 | want_cookie) |
1114 | goto drop_and_free; | 1066 | goto drop_and_free; |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index d8e5e852fc7a..da6019b63730 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 | } |
@@ -1118,7 +1119,7 @@ do_udp_sendmsg: | |||
1118 | 1119 | ||
1119 | if (addr_len >= sizeof(struct sockaddr_in6) && | 1120 | if (addr_len >= sizeof(struct sockaddr_in6) && |
1120 | sin6->sin6_scope_id && | 1121 | sin6->sin6_scope_id && |
1121 | ipv6_addr_type(daddr)&IPV6_ADDR_LINKLOCAL) | 1122 | __ipv6_addr_needs_scope_id(__ipv6_addr_type(daddr))) |
1122 | fl6.flowi6_oif = sin6->sin6_scope_id; | 1123 | fl6.flowi6_oif = sin6->sin6_scope_id; |
1123 | } else { | 1124 | } else { |
1124 | if (sk->sk_state != TCP_ESTABLISHED) | 1125 | 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; |