Commit c26b8c4e authored by Eric Dumazet's avatar Eric Dumazet Committed by Jakub Kicinski
Browse files

net: fix off-by-one in udp_flow_src_port() / psp_write_headers()



udp_flow_src_port() and psp_write_headers() use ip_local_port_range.

ip_local_port_range is inclusive : all ports between min and max
can be used.

Before this patch, if ip_local_port_range was set to 40000-40001
40001 would not be used as a source port.

Use reciprocal_scale() to help code readability.

Not tagged for stable trees, as this change could break user
expectations.

Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Reviewed-by: default avatarWillem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20260302163933.1754393-1-edumazet@google.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 98d95000
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@
#include <linux/seq_file.h>
#include <linux/poll.h>
#include <linux/indirect_call_wrapper.h>
#include <linux/math.h>

/**
 *	struct udp_skb_cb  -  UDP(-Lite) private variables
@@ -376,7 +377,7 @@ static inline __be16 udp_flow_src_port(struct net *net, struct sk_buff *skb,
	 */
	hash ^= hash << 16;

	return htons((((u64) hash * (max - min)) >> 32) + min);
	return htons(reciprocal_scale(hash, max - min + 1) + min);
}

static inline int udp_rqueue_get(struct sock *sk)
+1 −1
Original line number Diff line number Diff line
@@ -202,7 +202,7 @@ static void psp_write_headers(struct net *net, struct sk_buff *skb, __be32 spi,
		 * reciprocal divide.
		 */
		hash ^= hash << 16;
		uh->source = htons((((u64)hash * (max - min)) >> 32) + min);
		uh->source = htons(reciprocal_scale(hash, max - min + 1) + min);
	} else {
		uh->source = udp_flow_src_port(net, skb, 0, 0, false);
	}