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

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
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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 *));
+9 −6
Original line number Diff line number Diff line
@@ -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,
				reuseport_result = reuseport_select_sock(sk, hash, skb,
									 sizeof(struct udphdr));
				if (result && !reuseport_has_conns(sk, false))
					return result;
				if (reuseport_result && !reuseport_has_conns(sk, false))
					return reuseport_result;
			}

			result = reuseport_result ? : sk;
			badness = score;
			result = sk;
		}
	}
	return result;
+9 −6
Original line number Diff line number Diff line
@@ -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,
				reuseport_result = reuseport_select_sock(sk, hash, skb,
									 sizeof(struct udphdr));
				if (result && !reuseport_has_conns(sk, false))
					return result;
				if (reuseport_result && !reuseport_has_conns(sk, false))
					return reuseport_result;
			}
			result = sk;

			result = reuseport_result ? : sk;
			badness = score;
		}
	}