diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2016-09-01 12:33:46 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2016-09-01 12:33:46 -0400 |
commit | 0cb7bf61b1e9f05027de58c80f9b46a714d24e35 (patch) | |
tree | 41fb55cf62d07b425122f9a8b96412c0d8eb99c5 /net/ipv6 | |
parent | aa877175e7a9982233ed8f10cb4bfddd78d82741 (diff) | |
parent | 3eab887a55424fc2c27553b7bfe32330df83f7b8 (diff) |
Merge branch 'linus' into smp/hotplug
Apply upstream changes to avoid conflicts with pending patches.
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/addrconf.c | 4 | ||||
-rw-r--r-- | net/ipv6/calipso.c | 4 | ||||
-rw-r--r-- | net/ipv6/ip6_gre.c | 2 | ||||
-rw-r--r-- | net/ipv6/ping.c | 33 |
4 files changed, 22 insertions, 21 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index ab3e796596b1..df8425fcbc2c 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -3543,7 +3543,7 @@ static int addrconf_ifdown(struct net_device *dev, int how) | |||
3543 | /* combine the user config with event to determine if permanent | 3543 | /* combine the user config with event to determine if permanent |
3544 | * addresses are to be removed from address hash table | 3544 | * addresses are to be removed from address hash table |
3545 | */ | 3545 | */ |
3546 | keep_addr = !(how || _keep_addr <= 0); | 3546 | keep_addr = !(how || _keep_addr <= 0 || idev->cnf.disable_ipv6); |
3547 | 3547 | ||
3548 | /* Step 2: clear hash table */ | 3548 | /* Step 2: clear hash table */ |
3549 | for (i = 0; i < IN6_ADDR_HSIZE; i++) { | 3549 | for (i = 0; i < IN6_ADDR_HSIZE; i++) { |
@@ -3599,7 +3599,7 @@ restart: | |||
3599 | /* re-combine the user config with event to determine if permanent | 3599 | /* re-combine the user config with event to determine if permanent |
3600 | * addresses are to be removed from the interface list | 3600 | * addresses are to be removed from the interface list |
3601 | */ | 3601 | */ |
3602 | keep_addr = (!how && _keep_addr > 0); | 3602 | keep_addr = (!how && _keep_addr > 0 && !idev->cnf.disable_ipv6); |
3603 | 3603 | ||
3604 | INIT_LIST_HEAD(&del_list); | 3604 | INIT_LIST_HEAD(&del_list); |
3605 | list_for_each_entry_safe(ifa, tmp, &idev->addr_list, if_list) { | 3605 | list_for_each_entry_safe(ifa, tmp, &idev->addr_list, if_list) { |
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 | ||