Commit ca673235 authored by David S. Miller's avatar David S. Miller

Merge branch 'udp-Fix-reuseport-selection-with-connected-sockets'

Kuniyuki Iwashima says:

====================
udp: Fix reuseport selection with connected sockets.

This patch set addresses two issues which happen when both connected and
unconnected sockets are in the same UDP reuseport group.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 6ef9dcb7 efc6b6f6
......@@ -101,6 +101,7 @@ static struct sock_reuseport *reuseport_grow(struct sock_reuseport *reuse)
more_reuse->prog = reuse->prog;
more_reuse->reuseport_id = reuse->reuseport_id;
more_reuse->bind_inany = reuse->bind_inany;
more_reuse->has_conns = reuse->has_conns;
memcpy(more_reuse->socks, reuse->socks,
reuse->num_socks * sizeof(struct sock *));
......
......@@ -416,7 +416,7 @@ static struct sock *udp4_lib_lookup2(struct net *net,
struct udp_hslot *hslot2,
struct sk_buff *skb)
{
struct sock *sk, *result;
struct sock *sk, *result, *reuseport_result;
int score, badness;
u32 hash = 0;
......@@ -426,17 +426,20 @@ static struct sock *udp4_lib_lookup2(struct net *net,
score = compute_score(sk, net, saddr, sport,
daddr, hnum, dif, sdif);
if (score > badness) {
reuseport_result = NULL;
if (sk->sk_reuseport &&
sk->sk_state != TCP_ESTABLISHED) {
hash = udp_ehashfn(net, daddr, hnum,
saddr, sport);
result = reuseport_select_sock(sk, hash, skb,
sizeof(struct udphdr));
if (result && !reuseport_has_conns(sk, false))
return result;
reuseport_result = reuseport_select_sock(sk, hash, skb,
sizeof(struct udphdr));
if (reuseport_result && !reuseport_has_conns(sk, false))
return reuseport_result;
}
result = reuseport_result ? : sk;
badness = score;
result = sk;
}
}
return result;
......
......@@ -148,7 +148,7 @@ static struct sock *udp6_lib_lookup2(struct net *net,
int dif, int sdif, struct udp_hslot *hslot2,
struct sk_buff *skb)
{
struct sock *sk, *result;
struct sock *sk, *result, *reuseport_result;
int score, badness;
u32 hash = 0;
......@@ -158,17 +158,20 @@ static struct sock *udp6_lib_lookup2(struct net *net,
score = compute_score(sk, net, saddr, sport,
daddr, hnum, dif, sdif);
if (score > badness) {
reuseport_result = NULL;
if (sk->sk_reuseport &&
sk->sk_state != TCP_ESTABLISHED) {
hash = udp6_ehashfn(net, daddr, hnum,
saddr, sport);
result = reuseport_select_sock(sk, hash, skb,
sizeof(struct udphdr));
if (result && !reuseport_has_conns(sk, false))
return result;
reuseport_result = reuseport_select_sock(sk, hash, skb,
sizeof(struct udphdr));
if (reuseport_result && !reuseport_has_conns(sk, false))
return reuseport_result;
}
result = sk;
result = reuseport_result ? : sk;
badness = score;
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment