summaryrefslogtreecommitdiffstats
path: root/net/ipv6/udp.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/udp.c')
-rw-r--r--net/ipv6/udp.c26
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
105static void udp_v6_rehash(struct sock *sk) 105void 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;