.. | .. |
---|
54 | 54 | #include <trace/events/skb.h> |
---|
55 | 55 | #include "udp_impl.h" |
---|
56 | 56 | |
---|
| 57 | +static void udpv6_destruct_sock(struct sock *sk) |
---|
| 58 | +{ |
---|
| 59 | + udp_destruct_common(sk); |
---|
| 60 | + inet6_sock_destruct(sk); |
---|
| 61 | +} |
---|
| 62 | + |
---|
| 63 | +int udpv6_init_sock(struct sock *sk) |
---|
| 64 | +{ |
---|
| 65 | + skb_queue_head_init(&udp_sk(sk)->reader_queue); |
---|
| 66 | + sk->sk_destruct = udpv6_destruct_sock; |
---|
| 67 | + return 0; |
---|
| 68 | +} |
---|
| 69 | + |
---|
57 | 70 | static u32 udp6_ehashfn(const struct net *net, |
---|
58 | 71 | const struct in6_addr *laddr, |
---|
59 | 72 | const u16 lport, |
---|
.. | .. |
---|
74 | 87 | fhash = __ipv6_addr_jhash(faddr, udp_ipv6_hash_secret); |
---|
75 | 88 | |
---|
76 | 89 | return __inet6_ehashfn(lhash, lport, fhash, fport, |
---|
77 | | - udp_ipv6_hash_secret + net_hash_mix(net)); |
---|
| 90 | + udp6_ehash_secret + net_hash_mix(net)); |
---|
78 | 91 | } |
---|
79 | 92 | |
---|
80 | 93 | int udp_v6_get_port(struct sock *sk, unsigned short snum) |
---|
.. | .. |
---|
176 | 189 | score = compute_score(sk, net, saddr, sport, |
---|
177 | 190 | daddr, hnum, dif, sdif); |
---|
178 | 191 | if (score > badness) { |
---|
179 | | - result = lookup_reuseport(net, sk, skb, |
---|
180 | | - saddr, sport, daddr, hnum); |
---|
| 192 | + badness = score; |
---|
| 193 | + result = lookup_reuseport(net, sk, skb, saddr, sport, daddr, hnum); |
---|
| 194 | + if (!result) { |
---|
| 195 | + result = sk; |
---|
| 196 | + continue; |
---|
| 197 | + } |
---|
| 198 | + |
---|
181 | 199 | /* Fall back to scoring if group has connections */ |
---|
182 | | - if (result && !reuseport_has_conns(sk)) |
---|
| 200 | + if (!reuseport_has_conns(sk)) |
---|
183 | 201 | return result; |
---|
184 | 202 | |
---|
185 | | - result = result ? : sk; |
---|
186 | | - badness = score; |
---|
| 203 | + /* Reuseport logic returned an error, keep original score. */ |
---|
| 204 | + if (IS_ERR(result)) |
---|
| 205 | + continue; |
---|
| 206 | + |
---|
| 207 | + badness = compute_score(sk, net, saddr, sport, |
---|
| 208 | + daddr, hnum, dif, sdif); |
---|
187 | 209 | } |
---|
188 | 210 | } |
---|
189 | 211 | return result; |
---|
.. | .. |
---|
1340 | 1362 | msg->msg_name = &sin; |
---|
1341 | 1363 | msg->msg_namelen = sizeof(sin); |
---|
1342 | 1364 | do_udp_sendmsg: |
---|
1343 | | - if (__ipv6_only_sock(sk)) |
---|
1344 | | - return -ENETUNREACH; |
---|
1345 | | - return udp_sendmsg(sk, msg, len); |
---|
| 1365 | + err = __ipv6_only_sock(sk) ? |
---|
| 1366 | + -ENETUNREACH : udp_sendmsg(sk, msg, len); |
---|
| 1367 | + msg->msg_name = sin6; |
---|
| 1368 | + msg->msg_namelen = addr_len; |
---|
| 1369 | + return err; |
---|
1346 | 1370 | } |
---|
1347 | 1371 | } |
---|
1348 | 1372 | |
---|
.. | .. |
---|
1615 | 1639 | udp_encap_disable(); |
---|
1616 | 1640 | } |
---|
1617 | 1641 | } |
---|
1618 | | - |
---|
1619 | | - inet6_destroy_sock(sk); |
---|
1620 | 1642 | } |
---|
1621 | 1643 | |
---|
1622 | 1644 | /* |
---|
.. | .. |
---|
1700 | 1722 | .connect = ip6_datagram_connect, |
---|
1701 | 1723 | .disconnect = udp_disconnect, |
---|
1702 | 1724 | .ioctl = udp_ioctl, |
---|
1703 | | - .init = udp_init_sock, |
---|
| 1725 | + .init = udpv6_init_sock, |
---|
1704 | 1726 | .destroy = udpv6_destroy_sock, |
---|
1705 | 1727 | .setsockopt = udpv6_setsockopt, |
---|
1706 | 1728 | .getsockopt = udpv6_getsockopt, |
---|