diff options
Diffstat (limited to 'net/ipv6/udp.c')
-rw-r--r-- | net/ipv6/udp.c | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 5d2c2afffe7b..22e28a44e3c8 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -257,6 +257,7 @@ static struct sock *udp6_lib_lookup2(struct net *net, | |||
257 | struct sock *sk, *result; | 257 | struct sock *sk, *result; |
258 | struct hlist_nulls_node *node; | 258 | struct hlist_nulls_node *node; |
259 | int score, badness, matches = 0, reuseport = 0; | 259 | int score, badness, matches = 0, reuseport = 0; |
260 | bool select_ok = true; | ||
260 | u32 hash = 0; | 261 | u32 hash = 0; |
261 | 262 | ||
262 | begin: | 263 | begin: |
@@ -270,14 +271,18 @@ begin: | |||
270 | badness = score; | 271 | badness = score; |
271 | reuseport = sk->sk_reuseport; | 272 | reuseport = sk->sk_reuseport; |
272 | if (reuseport) { | 273 | if (reuseport) { |
273 | struct sock *sk2; | ||
274 | hash = udp6_ehashfn(net, daddr, hnum, | 274 | hash = udp6_ehashfn(net, daddr, hnum, |
275 | saddr, sport); | 275 | saddr, sport); |
276 | sk2 = reuseport_select_sock(sk, hash, skb, | 276 | if (select_ok) { |
277 | sizeof(struct udphdr)); | 277 | struct sock *sk2; |
278 | if (sk2) { | 278 | |
279 | result = sk2; | 279 | sk2 = reuseport_select_sock(sk, hash, skb, |
280 | goto found; | 280 | sizeof(struct udphdr)); |
281 | if (sk2) { | ||
282 | result = sk2; | ||
283 | select_ok = false; | ||
284 | goto found; | ||
285 | } | ||
281 | } | 286 | } |
282 | matches = 1; | 287 | matches = 1; |
283 | } | 288 | } |
@@ -321,6 +326,7 @@ struct sock *__udp6_lib_lookup(struct net *net, | |||
321 | unsigned int hash2, slot2, slot = udp_hashfn(net, hnum, udptable->mask); | 326 | unsigned int hash2, slot2, slot = udp_hashfn(net, hnum, udptable->mask); |
322 | struct udp_hslot *hslot2, *hslot = &udptable->hash[slot]; | 327 | struct udp_hslot *hslot2, *hslot = &udptable->hash[slot]; |
323 | int score, badness, matches = 0, reuseport = 0; | 328 | int score, badness, matches = 0, reuseport = 0; |
329 | bool select_ok = true; | ||
324 | u32 hash = 0; | 330 | u32 hash = 0; |
325 | 331 | ||
326 | rcu_read_lock(); | 332 | rcu_read_lock(); |
@@ -358,14 +364,18 @@ begin: | |||
358 | badness = score; | 364 | badness = score; |
359 | reuseport = sk->sk_reuseport; | 365 | reuseport = sk->sk_reuseport; |
360 | if (reuseport) { | 366 | if (reuseport) { |
361 | struct sock *sk2; | ||
362 | hash = udp6_ehashfn(net, daddr, hnum, | 367 | hash = udp6_ehashfn(net, daddr, hnum, |
363 | saddr, sport); | 368 | saddr, sport); |
364 | sk2 = reuseport_select_sock(sk, hash, skb, | 369 | if (select_ok) { |
370 | struct sock *sk2; | ||
371 | |||
372 | sk2 = reuseport_select_sock(sk, hash, skb, | ||
365 | sizeof(struct udphdr)); | 373 | sizeof(struct udphdr)); |
366 | if (sk2) { | 374 | if (sk2) { |
367 | result = sk2; | 375 | result = sk2; |
368 | goto found; | 376 | select_ok = false; |
377 | goto found; | ||
378 | } | ||
369 | } | 379 | } |
370 | matches = 1; | 380 | matches = 1; |
371 | } | 381 | } |