diff options
Diffstat (limited to 'net/ipv4/udp.c')
-rw-r--r-- | net/ipv4/udp.c | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index dc45b538e237..be0b21852b13 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -499,6 +499,7 @@ static struct sock *udp4_lib_lookup2(struct net *net, | |||
499 | struct sock *sk, *result; | 499 | struct sock *sk, *result; |
500 | struct hlist_nulls_node *node; | 500 | struct hlist_nulls_node *node; |
501 | int score, badness, matches = 0, reuseport = 0; | 501 | int score, badness, matches = 0, reuseport = 0; |
502 | bool select_ok = true; | ||
502 | u32 hash = 0; | 503 | u32 hash = 0; |
503 | 504 | ||
504 | begin: | 505 | begin: |
@@ -512,14 +513,18 @@ begin: | |||
512 | badness = score; | 513 | badness = score; |
513 | reuseport = sk->sk_reuseport; | 514 | reuseport = sk->sk_reuseport; |
514 | if (reuseport) { | 515 | if (reuseport) { |
515 | struct sock *sk2; | ||
516 | hash = udp_ehashfn(net, daddr, hnum, | 516 | hash = udp_ehashfn(net, daddr, hnum, |
517 | saddr, sport); | 517 | saddr, sport); |
518 | sk2 = reuseport_select_sock(sk, hash, skb, | 518 | if (select_ok) { |
519 | sizeof(struct udphdr)); | 519 | struct sock *sk2; |
520 | if (sk2) { | 520 | |
521 | result = sk2; | 521 | sk2 = reuseport_select_sock(sk, hash, skb, |
522 | goto found; | 522 | sizeof(struct udphdr)); |
523 | if (sk2) { | ||
524 | result = sk2; | ||
525 | select_ok = false; | ||
526 | goto found; | ||
527 | } | ||
523 | } | 528 | } |
524 | matches = 1; | 529 | matches = 1; |
525 | } | 530 | } |
@@ -563,6 +568,7 @@ struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr, | |||
563 | unsigned int hash2, slot2, slot = udp_hashfn(net, hnum, udptable->mask); | 568 | unsigned int hash2, slot2, slot = udp_hashfn(net, hnum, udptable->mask); |
564 | struct udp_hslot *hslot2, *hslot = &udptable->hash[slot]; | 569 | struct udp_hslot *hslot2, *hslot = &udptable->hash[slot]; |
565 | int score, badness, matches = 0, reuseport = 0; | 570 | int score, badness, matches = 0, reuseport = 0; |
571 | bool select_ok = true; | ||
566 | u32 hash = 0; | 572 | u32 hash = 0; |
567 | 573 | ||
568 | rcu_read_lock(); | 574 | rcu_read_lock(); |
@@ -601,14 +607,18 @@ begin: | |||
601 | badness = score; | 607 | badness = score; |
602 | reuseport = sk->sk_reuseport; | 608 | reuseport = sk->sk_reuseport; |
603 | if (reuseport) { | 609 | if (reuseport) { |
604 | struct sock *sk2; | ||
605 | hash = udp_ehashfn(net, daddr, hnum, | 610 | hash = udp_ehashfn(net, daddr, hnum, |
606 | saddr, sport); | 611 | saddr, sport); |
607 | sk2 = reuseport_select_sock(sk, hash, skb, | 612 | if (select_ok) { |
613 | struct sock *sk2; | ||
614 | |||
615 | sk2 = reuseport_select_sock(sk, hash, skb, | ||
608 | sizeof(struct udphdr)); | 616 | sizeof(struct udphdr)); |
609 | if (sk2) { | 617 | if (sk2) { |
610 | result = sk2; | 618 | result = sk2; |
611 | goto found; | 619 | select_ok = false; |
620 | goto found; | ||
621 | } | ||
612 | } | 622 | } |
613 | matches = 1; | 623 | matches = 1; |
614 | } | 624 | } |