aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/addrconf.c38
-rw-r--r--net/ipv6/calipso.c4
-rw-r--r--net/ipv6/ip6_gre.c2
-rw-r--r--net/ipv6/ping.c33
-rw-r--r--net/ipv6/tcp_ipv6.c8
-rw-r--r--net/ipv6/udp.c1
-rw-r--r--net/ipv6/udplite.c1
7 files changed, 50 insertions, 37 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index ab3e796596b1..f418d2eaeddd 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1872,7 +1872,6 @@ static int addrconf_dad_end(struct inet6_ifaddr *ifp)
1872 1872
1873void addrconf_dad_failure(struct inet6_ifaddr *ifp) 1873void addrconf_dad_failure(struct inet6_ifaddr *ifp)
1874{ 1874{
1875 struct in6_addr addr;
1876 struct inet6_dev *idev = ifp->idev; 1875 struct inet6_dev *idev = ifp->idev;
1877 struct net *net = dev_net(ifp->idev->dev); 1876 struct net *net = dev_net(ifp->idev->dev);
1878 1877
@@ -1934,18 +1933,6 @@ void addrconf_dad_failure(struct inet6_ifaddr *ifp)
1934 in6_ifa_put(ifp2); 1933 in6_ifa_put(ifp2);
1935lock_errdad: 1934lock_errdad:
1936 spin_lock_bh(&ifp->lock); 1935 spin_lock_bh(&ifp->lock);
1937 } else if (idev->cnf.accept_dad > 1 && !idev->cnf.disable_ipv6) {
1938 addr.s6_addr32[0] = htonl(0xfe800000);
1939 addr.s6_addr32[1] = 0;
1940
1941 if (!ipv6_generate_eui64(addr.s6_addr + 8, idev->dev) &&
1942 ipv6_addr_equal(&ifp->addr, &addr)) {
1943 /* DAD failed for link-local based on MAC address */
1944 idev->cnf.disable_ipv6 = 1;
1945
1946 pr_info("%s: IPv6 being disabled!\n",
1947 ifp->idev->dev->name);
1948 }
1949 } 1936 }
1950 1937
1951errdad: 1938errdad:
@@ -3543,7 +3530,7 @@ static int addrconf_ifdown(struct net_device *dev, int how)
3543 /* combine the user config with event to determine if permanent 3530 /* combine the user config with event to determine if permanent
3544 * addresses are to be removed from address hash table 3531 * addresses are to be removed from address hash table
3545 */ 3532 */
3546 keep_addr = !(how || _keep_addr <= 0); 3533 keep_addr = !(how || _keep_addr <= 0 || idev->cnf.disable_ipv6);
3547 3534
3548 /* Step 2: clear hash table */ 3535 /* Step 2: clear hash table */
3549 for (i = 0; i < IN6_ADDR_HSIZE; i++) { 3536 for (i = 0; i < IN6_ADDR_HSIZE; i++) {
@@ -3599,7 +3586,7 @@ restart:
3599 /* re-combine the user config with event to determine if permanent 3586 /* re-combine the user config with event to determine if permanent
3600 * addresses are to be removed from the interface list 3587 * addresses are to be removed from the interface list
3601 */ 3588 */
3602 keep_addr = (!how && _keep_addr > 0); 3589 keep_addr = (!how && _keep_addr > 0 && !idev->cnf.disable_ipv6);
3603 3590
3604 INIT_LIST_HEAD(&del_list); 3591 INIT_LIST_HEAD(&del_list);
3605 list_for_each_entry_safe(ifa, tmp, &idev->addr_list, if_list) { 3592 list_for_each_entry_safe(ifa, tmp, &idev->addr_list, if_list) {
@@ -3821,6 +3808,7 @@ static void addrconf_dad_work(struct work_struct *w)
3821 dad_work); 3808 dad_work);
3822 struct inet6_dev *idev = ifp->idev; 3809 struct inet6_dev *idev = ifp->idev;
3823 struct in6_addr mcaddr; 3810 struct in6_addr mcaddr;
3811 bool disable_ipv6 = false;
3824 3812
3825 enum { 3813 enum {
3826 DAD_PROCESS, 3814 DAD_PROCESS,
@@ -3837,6 +3825,24 @@ static void addrconf_dad_work(struct work_struct *w)
3837 } else if (ifp->state == INET6_IFADDR_STATE_ERRDAD) { 3825 } else if (ifp->state == INET6_IFADDR_STATE_ERRDAD) {
3838 action = DAD_ABORT; 3826 action = DAD_ABORT;
3839 ifp->state = INET6_IFADDR_STATE_POSTDAD; 3827 ifp->state = INET6_IFADDR_STATE_POSTDAD;
3828
3829 if (idev->cnf.accept_dad > 1 && !idev->cnf.disable_ipv6 &&
3830 !(ifp->flags & IFA_F_STABLE_PRIVACY)) {
3831 struct in6_addr addr;
3832
3833 addr.s6_addr32[0] = htonl(0xfe800000);
3834 addr.s6_addr32[1] = 0;
3835
3836 if (!ipv6_generate_eui64(addr.s6_addr + 8, idev->dev) &&
3837 ipv6_addr_equal(&ifp->addr, &addr)) {
3838 /* DAD failed for link-local based on MAC */
3839 idev->cnf.disable_ipv6 = 1;
3840
3841 pr_info("%s: IPv6 being disabled!\n",
3842 ifp->idev->dev->name);
3843 disable_ipv6 = true;
3844 }
3845 }
3840 } 3846 }
3841 spin_unlock_bh(&ifp->lock); 3847 spin_unlock_bh(&ifp->lock);
3842 3848
@@ -3845,6 +3851,8 @@ static void addrconf_dad_work(struct work_struct *w)
3845 goto out; 3851 goto out;
3846 } else if (action == DAD_ABORT) { 3852 } else if (action == DAD_ABORT) {
3847 addrconf_dad_stop(ifp, 1); 3853 addrconf_dad_stop(ifp, 1);
3854 if (disable_ipv6)
3855 addrconf_ifdown(idev->dev, 0);
3848 goto out; 3856 goto out;
3849 } 3857 }
3850 3858
diff --git a/net/ipv6/calipso.c b/net/ipv6/calipso.c
index c53b92c617c5..37ac9de713c6 100644
--- a/net/ipv6/calipso.c
+++ b/net/ipv6/calipso.c
@@ -952,8 +952,10 @@ calipso_opt_insert(struct ipv6_opt_hdr *hop,
952 memcpy(new, hop, start); 952 memcpy(new, hop, start);
953 ret_val = calipso_genopt((unsigned char *)new, start, buf_len, doi_def, 953 ret_val = calipso_genopt((unsigned char *)new, start, buf_len, doi_def,
954 secattr); 954 secattr);
955 if (ret_val < 0) 955 if (ret_val < 0) {
956 kfree(new);
956 return ERR_PTR(ret_val); 957 return ERR_PTR(ret_val);
958 }
957 959
958 buf_len = start + ret_val; 960 buf_len = start + ret_val;
959 /* At this point buf_len aligns to 4n, so (buf_len & 4) pads to 8n */ 961 /* At this point buf_len aligns to 4n, so (buf_len & 4) pads to 8n */
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index 776d145113e1..704274cbd495 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -519,8 +519,6 @@ static netdev_tx_t __gre6_xmit(struct sk_buff *skb,
519 gre_build_header(skb, tunnel->tun_hlen, tunnel->parms.o_flags, 519 gre_build_header(skb, tunnel->tun_hlen, tunnel->parms.o_flags,
520 protocol, tunnel->parms.o_key, htonl(tunnel->o_seqno)); 520 protocol, tunnel->parms.o_key, htonl(tunnel->o_seqno));
521 521
522 skb_set_inner_protocol(skb, protocol);
523
524 return ip6_tnl_xmit(skb, dev, dsfield, fl6, encap_limit, pmtu, 522 return ip6_tnl_xmit(skb, dev, dsfield, fl6, encap_limit, pmtu,
525 NEXTHDR_GRE); 523 NEXTHDR_GRE);
526} 524}
diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c
index fed40d1ec29b..0900352c924c 100644
--- a/net/ipv6/ping.c
+++ b/net/ipv6/ping.c
@@ -55,7 +55,7 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
55 struct icmp6hdr user_icmph; 55 struct icmp6hdr user_icmph;
56 int addr_type; 56 int addr_type;
57 struct in6_addr *daddr; 57 struct in6_addr *daddr;
58 int iif = 0; 58 int oif = 0;
59 struct flowi6 fl6; 59 struct flowi6 fl6;
60 int err; 60 int err;
61 struct dst_entry *dst; 61 struct dst_entry *dst;
@@ -78,25 +78,30 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
78 if (u->sin6_family != AF_INET6) { 78 if (u->sin6_family != AF_INET6) {
79 return -EAFNOSUPPORT; 79 return -EAFNOSUPPORT;
80 } 80 }
81 if (sk->sk_bound_dev_if &&
82 sk->sk_bound_dev_if != u->sin6_scope_id) {
83 return -EINVAL;
84 }
85 daddr = &(u->sin6_addr); 81 daddr = &(u->sin6_addr);
86 iif = u->sin6_scope_id; 82 if (__ipv6_addr_needs_scope_id(ipv6_addr_type(daddr)))
83 oif = u->sin6_scope_id;
87 } else { 84 } else {
88 if (sk->sk_state != TCP_ESTABLISHED) 85 if (sk->sk_state != TCP_ESTABLISHED)
89 return -EDESTADDRREQ; 86 return -EDESTADDRREQ;
90 daddr = &sk->sk_v6_daddr; 87 daddr = &sk->sk_v6_daddr;
91 } 88 }
92 89
93 if (!iif) 90 if (!oif)
94 iif = sk->sk_bound_dev_if; 91 oif = sk->sk_bound_dev_if;
92
93 if (!oif)
94 oif = np->sticky_pktinfo.ipi6_ifindex;
95
96 if (!oif && ipv6_addr_is_multicast(daddr))
97 oif = np->mcast_oif;
98 else if (!oif)
99 oif = np->ucast_oif;
95 100
96 addr_type = ipv6_addr_type(daddr); 101 addr_type = ipv6_addr_type(daddr);
97 if (__ipv6_addr_needs_scope_id(addr_type) && !iif) 102 if ((__ipv6_addr_needs_scope_id(addr_type) && !oif) ||
98 return -EINVAL; 103 (addr_type & IPV6_ADDR_MAPPED) ||
99 if (addr_type & IPV6_ADDR_MAPPED) 104 (oif && sk->sk_bound_dev_if && oif != sk->sk_bound_dev_if))
100 return -EINVAL; 105 return -EINVAL;
101 106
102 /* TODO: use ip6_datagram_send_ctl to get options from cmsg */ 107 /* TODO: use ip6_datagram_send_ctl to get options from cmsg */
@@ -106,16 +111,12 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
106 fl6.flowi6_proto = IPPROTO_ICMPV6; 111 fl6.flowi6_proto = IPPROTO_ICMPV6;
107 fl6.saddr = np->saddr; 112 fl6.saddr = np->saddr;
108 fl6.daddr = *daddr; 113 fl6.daddr = *daddr;
114 fl6.flowi6_oif = oif;
109 fl6.flowi6_mark = sk->sk_mark; 115 fl6.flowi6_mark = sk->sk_mark;
110 fl6.fl6_icmp_type = user_icmph.icmp6_type; 116 fl6.fl6_icmp_type = user_icmph.icmp6_type;
111 fl6.fl6_icmp_code = user_icmph.icmp6_code; 117 fl6.fl6_icmp_code = user_icmph.icmp6_code;
112 security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); 118 security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
113 119
114 if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr))
115 fl6.flowi6_oif = np->mcast_oif;
116 else if (!fl6.flowi6_oif)
117 fl6.flowi6_oif = np->ucast_oif;
118
119 ipc6.tclass = np->tclass; 120 ipc6.tclass = np->tclass;
120 fl6.flowlabel = ip6_make_flowinfo(ipc6.tclass, fl6.flowlabel); 121 fl6.flowlabel = ip6_make_flowinfo(ipc6.tclass, fl6.flowlabel);
121 122
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 33df8b8575cc..94f4f89d73e7 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -944,9 +944,15 @@ static void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb,
944 /* sk->sk_state == TCP_LISTEN -> for regular TCP_SYN_RECV 944 /* sk->sk_state == TCP_LISTEN -> for regular TCP_SYN_RECV
945 * sk->sk_state == TCP_SYN_RECV -> for Fast Open. 945 * sk->sk_state == TCP_SYN_RECV -> for Fast Open.
946 */ 946 */
947 /* RFC 7323 2.3
948 * The window field (SEG.WND) of every outgoing segment, with the
949 * exception of <SYN> segments, MUST be right-shifted by
950 * Rcv.Wind.Shift bits:
951 */
947 tcp_v6_send_ack(sk, skb, (sk->sk_state == TCP_LISTEN) ? 952 tcp_v6_send_ack(sk, skb, (sk->sk_state == TCP_LISTEN) ?
948 tcp_rsk(req)->snt_isn + 1 : tcp_sk(sk)->snd_nxt, 953 tcp_rsk(req)->snt_isn + 1 : tcp_sk(sk)->snd_nxt,
949 tcp_rsk(req)->rcv_nxt, req->rsk_rcv_wnd, 954 tcp_rsk(req)->rcv_nxt,
955 req->rsk_rcv_wnd >> inet_rsk(req)->rcv_wscale,
950 tcp_time_stamp, req->ts_recent, sk->sk_bound_dev_if, 956 tcp_time_stamp, req->ts_recent, sk->sk_bound_dev_if,
951 tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->daddr), 957 tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->daddr),
952 0, 0); 958 0, 0);
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 81e2f98b958d..19ac3a1c308d 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -1460,7 +1460,6 @@ struct proto udpv6_prot = {
1460 .sysctl_wmem = &sysctl_udp_wmem_min, 1460 .sysctl_wmem = &sysctl_udp_wmem_min,
1461 .sysctl_rmem = &sysctl_udp_rmem_min, 1461 .sysctl_rmem = &sysctl_udp_rmem_min,
1462 .obj_size = sizeof(struct udp6_sock), 1462 .obj_size = sizeof(struct udp6_sock),
1463 .slab_flags = SLAB_DESTROY_BY_RCU,
1464 .h.udp_table = &udp_table, 1463 .h.udp_table = &udp_table,
1465#ifdef CONFIG_COMPAT 1464#ifdef CONFIG_COMPAT
1466 .compat_setsockopt = compat_udpv6_setsockopt, 1465 .compat_setsockopt = compat_udpv6_setsockopt,
diff --git a/net/ipv6/udplite.c b/net/ipv6/udplite.c
index 9cf097e206e9..fd6ef414899b 100644
--- a/net/ipv6/udplite.c
+++ b/net/ipv6/udplite.c
@@ -50,7 +50,6 @@ struct proto udplitev6_prot = {
50 .unhash = udp_lib_unhash, 50 .unhash = udp_lib_unhash,
51 .get_port = udp_v6_get_port, 51 .get_port = udp_v6_get_port,
52 .obj_size = sizeof(struct udp6_sock), 52 .obj_size = sizeof(struct udp6_sock),
53 .slab_flags = SLAB_DESTROY_BY_RCU,
54 .h.udp_table = &udplite_table, 53 .h.udp_table = &udplite_table,
55#ifdef CONFIG_COMPAT 54#ifdef CONFIG_COMPAT
56 .compat_setsockopt = compat_udpv6_setsockopt, 55 .compat_setsockopt = compat_udpv6_setsockopt,