diff options
| author | Alice Mikityanska <alice@isovalent.com> | 2026-07-10 16:42:34 +0300 |
|---|---|---|
| committer | Paolo Abeni <pabeni@redhat.com> | 2026-07-22 13:47:02 +0200 |
| commit | 5329647dad1bdb512e36905d0ae6a817b64f7f52 (patch) | |
| tree | d23f47ba2fac4f94676c910732a1d0688aeb1029 /include/linux | |
| parent | ba520084dc3b7f8b0bca534bd272266b764427f2 (diff) | |
net: Use helpers to get/set UDP len tree-wide
Since BIG TCP for UDP tunnels will start using len=0 in the UDP header
as an indicator of a GSO packet bigger than 65535 bytes, this commit
introduces the following getter and setters to use tree-wide, in order
to explicitly mark places where len=0 may be expected, and handle them
properly:
1. udp_set_len() sets uh->len to its real value if it's not bigger than
65535, and to 0 otherwise: to be used in GSO context with aggregated
packets.
2. udp_set_len_short() is to be used when the length is known to fit 16
bits. It WARNs when the caller tries to assign a bigger value if
CONFIG_DEBUG_NET=y.
3. udp_get_len_short() returns len in host byte order: to be used on the
RX side to deal with non-aggregated packets, or to access the raw value
of the len field.
4. udp_get_len() decodes uh->len set by udp_set_len(). It checks whether
the packet is GSO to guard from malformed packets.
At the moment udp_set_len() is not used, a following commit will start
using it after enabling len>65535 for GSO.
Raw uh->len (in network byte order) is still accessed in a few places
for checksum calculation purposes, and to decode len=0 in udpv6_rcv for
jumbograms. udp_rcv and udpv6_rcv will be addressed by the commit that
starts using udp_set_len() to set UDP len=0 for BIG TCP packets in UDP
tunnels.
Signed-off-by: Alice Mikityanska <alice@isovalent.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Acked-by: Jason A. Donenfeld <Jason@zx2c4.com>
Link: https://patch.msgid.link/20260710134242.216538-2-alice.kernel@fastmail.im
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/udp.h | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/include/linux/udp.h b/include/linux/udp.h index ce56ebcee5cb..998906ec3b32 100644 --- a/include/linux/udp.h +++ b/include/linux/udp.h @@ -23,6 +23,33 @@ static inline struct udphdr *udp_hdr(const struct sk_buff *skb) return (struct udphdr *)skb_transport_header(skb); } +static inline unsigned int udp_get_len(const struct sk_buff *skb, + const struct udphdr *uh, + unsigned int dataoff) +{ + if (uh->len) + return ntohs(uh->len); + if (skb_is_gso(skb)) /* BIG TCP */ + return skb->len - dataoff; + return 0; +} + +static inline unsigned int udp_get_len_short(const struct udphdr *uh) +{ + return ntohs(uh->len); +} + +static inline void udp_set_len(struct udphdr *uh, unsigned int len) +{ + uh->len = len < GRO_LEGACY_MAX_SIZE ? htons(len) : 0; +} + +static inline void udp_set_len_short(struct udphdr *uh, unsigned int len) +{ + DEBUG_NET_WARN_ON_ONCE(len >= GRO_LEGACY_MAX_SIZE); + uh->len = htons(len); +} + #define UDP_HTABLE_SIZE_MIN_PERNET 128 #define UDP_HTABLE_SIZE_MIN (IS_ENABLED(CONFIG_BASE_SMALL) ? 128 : 256) #define UDP_HTABLE_SIZE_MAX 65536 |
