diff options
Diffstat (limited to 'net/ipv6/udp.c')
-rw-r--r-- | net/ipv6/udp.c | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 9cbf363172bd..2596ffdeebea 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -102,7 +102,7 @@ int udp_v6_get_port(struct sock *sk, unsigned short snum) | |||
102 | return udp_lib_get_port(sk, snum, hash2_nulladdr); | 102 | return udp_lib_get_port(sk, snum, hash2_nulladdr); |
103 | } | 103 | } |
104 | 104 | ||
105 | static void udp_v6_rehash(struct sock *sk) | 105 | void udp_v6_rehash(struct sock *sk) |
106 | { | 106 | { |
107 | u16 new_hash = ipv6_portaddr_hash(sock_net(sk), | 107 | u16 new_hash = ipv6_portaddr_hash(sock_net(sk), |
108 | &sk->sk_v6_rcv_saddr, | 108 | &sk->sk_v6_rcv_saddr, |
@@ -1132,15 +1132,23 @@ static int udp_v6_send_skb(struct sk_buff *skb, struct flowi6 *fl6, | |||
1132 | const int hlen = skb_network_header_len(skb) + | 1132 | const int hlen = skb_network_header_len(skb) + |
1133 | sizeof(struct udphdr); | 1133 | sizeof(struct udphdr); |
1134 | 1134 | ||
1135 | if (hlen + cork->gso_size > cork->fragsize) | 1135 | if (hlen + cork->gso_size > cork->fragsize) { |
1136 | kfree_skb(skb); | ||
1136 | return -EINVAL; | 1137 | return -EINVAL; |
1137 | if (skb->len > cork->gso_size * UDP_MAX_SEGMENTS) | 1138 | } |
1139 | if (skb->len > cork->gso_size * UDP_MAX_SEGMENTS) { | ||
1140 | kfree_skb(skb); | ||
1138 | return -EINVAL; | 1141 | return -EINVAL; |
1139 | if (udp_sk(sk)->no_check6_tx) | 1142 | } |
1143 | if (udp_sk(sk)->no_check6_tx) { | ||
1144 | kfree_skb(skb); | ||
1140 | return -EINVAL; | 1145 | return -EINVAL; |
1146 | } | ||
1141 | if (skb->ip_summed != CHECKSUM_PARTIAL || is_udplite || | 1147 | if (skb->ip_summed != CHECKSUM_PARTIAL || is_udplite || |
1142 | dst_xfrm(skb_dst(skb))) | 1148 | dst_xfrm(skb_dst(skb))) { |
1149 | kfree_skb(skb); | ||
1143 | return -EIO; | 1150 | return -EIO; |
1151 | } | ||
1144 | 1152 | ||
1145 | skb_shinfo(skb)->gso_size = cork->gso_size; | 1153 | skb_shinfo(skb)->gso_size = cork->gso_size; |
1146 | skb_shinfo(skb)->gso_type = SKB_GSO_UDP_L4; | 1154 | skb_shinfo(skb)->gso_type = SKB_GSO_UDP_L4; |
@@ -1390,10 +1398,7 @@ do_udp_sendmsg: | |||
1390 | ipc6.opt = opt; | 1398 | ipc6.opt = opt; |
1391 | 1399 | ||
1392 | fl6.flowi6_proto = sk->sk_protocol; | 1400 | fl6.flowi6_proto = sk->sk_protocol; |
1393 | if (!ipv6_addr_any(daddr)) | 1401 | fl6.daddr = *daddr; |
1394 | fl6.daddr = *daddr; | ||
1395 | else | ||
1396 | fl6.daddr.s6_addr[15] = 0x1; /* :: means loopback (BSD'ism) */ | ||
1397 | if (ipv6_addr_any(&fl6.saddr) && !ipv6_addr_any(&np->saddr)) | 1402 | if (ipv6_addr_any(&fl6.saddr) && !ipv6_addr_any(&np->saddr)) |
1398 | fl6.saddr = np->saddr; | 1403 | fl6.saddr = np->saddr; |
1399 | fl6.fl6_sport = inet->inet_sport; | 1404 | fl6.fl6_sport = inet->inet_sport; |
@@ -1421,6 +1426,9 @@ do_udp_sendmsg: | |||
1421 | } | 1426 | } |
1422 | } | 1427 | } |
1423 | 1428 | ||
1429 | if (ipv6_addr_any(&fl6.daddr)) | ||
1430 | fl6.daddr.s6_addr[15] = 0x1; /* :: means loopback (BSD'ism) */ | ||
1431 | |||
1424 | final_p = fl6_update_dst(&fl6, opt, &final); | 1432 | final_p = fl6_update_dst(&fl6, opt, &final); |
1425 | if (final_p) | 1433 | if (final_p) |
1426 | connected = false; | 1434 | connected = false; |