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: Eric Dumazet <edumazet@google.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20260302163933.1754393-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Eric Dumazet
2026-03-02 16:39:33 +00:00
committed by Jakub Kicinski
parent 98d95000bb
commit c26b8c4e29
2 changed files with 3 additions and 2 deletions

View File

@@ -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)

View File

@@ -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);
}