From: Julius Bairaktaris <julius@bairaktaris.de>
To: netdev@vger.kernel.org
Cc: davem@davemloft.net, edumazet@kernel.org, kuba@kernel.org,
pabeni@redhat.com, horms@kernel.org, dsahern@kernel.org,
idosch@nvidia.com, willemb@google.com,
steffen.klassert@secunet.com, jiayuan.chen@linux.dev,
mfleming@cloudflare.com, almasrymina@google.com,
bigeasy@linutronix.de, richardbgobert@gmail.com,
ecree.xilinx@gmail.com, bsdhenrymartin@gmail.com,
linux-kernel@vger.kernel.org
Subject: [PATCH net v5 0/4] ipmr: forward GSO multicast packets
Date: Sat, 14 Nov 2026 19:26:56 +0100 [thread overview]
Message-ID: <cover.1794151759.git.julius@bairaktaris.de> (raw)
With fraglist GRO or UDP GRO forwarding on, a routed IPv4 multicast
stream arrives as GSO packets. ipmr_prepare_xmit() drops every DF
aggregate larger than the MTU, and ip_encap() sets no tunnel GSO state,
so a GSO packet sent to a VIFF_TUNNEL vif is dropped during
segmentation. With that state set, a fraglist aggregate reaches
skb_segment_list() with tunnel headers, which can write before the head
of a frag_list member; this also happens today when such a packet is
routed into a tunnel device. Checking the segment length instead of
skb->len relies on skb_gso_transport_seglen(), which counts the inner
UDP header of an encapsulated UDP GSO packet 8 bytes short.
Patch 1 makes room for the tunnel headers in skb_segment_list().
Patch 2 counts the inner UDP header of encapsulated UDP GSO packets.
Patch 3 sets up IPXIP4 GSO state, outer IP IDs and length in ip_encap().
Patch 4 lets DF GSO packets pass when their segments fit the MTU.
Tested in QEMU (KVM, KASAN and lockdep) on veth, 3 runs each on net
(30c71476d842) and with this series: an MFC entry to a plain vif and a
tunnel vif, 40 x 1316-byte datagrams per GSO packet, 4000 datagrams per
arm, UDP_SEGMENT, fraglist GRO and UDP GRO forwarding, DF set and clear,
software and device segmentation on egress:
- net: every DF aggregate dropped on both vifs (FragFails 2 per
aggregate), and with software segmentation nothing arrives over the
tunnel vif; fraglist GRO routed into VXLAN reports a KASAN
slab-out-of-bounds write in skb_segment_list(), then panics.
- this series, all 12 arms: 4000 of 4000 datagrams on the plain vif,
FragFails 0; on the tunnel vif 4000 of 4000 IPIP packets with unique
outer IDs with software segmentation, and the 100 GSO packets of 52688
bytes whole with device segmentation.
- VXLAN with DF, 1404-byte outer segments, route MTU 1400: net forwards
all 1000 segments at 1404 bytes through ip_forward(); with this series
none leave, through ip_forward() or the MFC entry, and FragFails
counts them.
- a GRE GSO packet (skb->encapsulation set) multicast-routed to both
vifs, 50 packets: all 1000 segments on the plain vif; none on the
tunnel vif, whose pkt_out stays at 0 (v4 counted 50).
- fraglist GRO routed into VXLAN and IPIP with software segmentation:
every segment reaches the peer, no KASAN report.
Changes in v5:
- Patch 3: drop an already encapsulated GSO packet in
ipmr_prepare_xmit() before the route lookup, so the vif does not count
it, and call iptunnel_handle_offloads() without error handling, since
skb_cow() leaves no header to unclone (Eric Dumazet, Sashiko). Simon's
Reviewed-by stays, as this is the change Eric asked for.
- Outer tot_len 0 (Eric): 50 x 1310-byte datagrams merged by UDP GRO
forwarding make a 65528-byte packet, so the outer header gets tot_len
0 from iph_set_totlen(); before, htons() truncated it to 12. In 3 runs
nft ip forward chains still match it with meta l4proto 4 and
ip protocol 4 (100 of 100), while a netdev egress chain on the output
device does not match meta l4proto 4 (0 of 100), as
nft_set_pktinfo_ipv4_validate() takes the length from iph_totlen().
All 5000 segments reach the peer, with software and device
segmentation.
- skb_gso_transport_seglen() also leaves out the inner SCTP header of
an encapsulated SCTP GSO packet (Sashiko on patch 2). That predates
this series, and multicast routing does not see such packets:
sctp_v4_addr_valid() and sctp_v4_available() reject multicast
addresses.
- Rebase onto net.
- v4: https://lore.kernel.org/netdev/cover.1792838740.git.julius@bairaktaris.de/
Changes in v4:
- Add patch 2 (Sashiko).
- Patch 3: drop GSO packets that are already encapsulated, and set the
outer length with iph_set_totlen() (Sashiko).
- Drop v3 patch 2 (TCP fixed-ID flag on encapsulation): multicast
routing does not carry TCP, and the flag also needs the decap and
GRE/UDP segmentation paths, which go to a separate series (Sashiko).
- Rebase onto net.
- v3: https://lore.kernel.org/netdev/cover.1792293419.git.julius@bairaktaris.de/
Changes in v3:
- Patch 1: name the VXLAN out-of-bounds write (Sashiko).
- Add patch 2 (Sashiko).
- Patch 3: reserve one outer IP ID per segment (Sashiko).
- v2: https://lore.kernel.org/netdev/20261011162957.1328474-1-julius@bairaktaris.de/
Changes in v2:
- Add patches 1 and 3; v1 let DF GSO packets reach ip_encap() on tunnel
vifs, where they were dropped during segmentation (Sashiko).
- Keep the additive MTU comparison and check mtu > encap before
subtracting, so a route MTU below 20 cannot wrap (Sashiko).
- v1: https://lore.kernel.org/netdev/20261010131842.2157365-1-julius@bairaktaris.de/
I used Claude (Anthropic) to help write these patches.
Julius Bairaktaris (4):
net: make room for the tunnel header in skb_segment_list()
net: gso: count the inner UDP header of encapsulated UDP GSO packets
ipmr: set up GSO state for tunnel vifs
ipmr: do not drop GSO packets that fit the MTU after segmentation
net/core/gso.c | 2 ++
net/core/skbuff.c | 4 ++++
net/ipv4/ipmr.c | 17 ++++++++++++++---
3 files changed, 20 insertions(+), 3 deletions(-)
base-commit: 30c71476d842b094651bd7712f6c8ee8716147d0
--
2.53.0
next reply other threads:[~2026-11-14 18:27 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-14 18:26 Julius Bairaktaris [this message]
2026-11-14 18:26 ` [PATCH net v5 1/4] net: make room for the tunnel header in skb_segment_list() Julius Bairaktaris
2026-11-14 18:26 ` [PATCH net v5 2/4] net: gso: count the inner UDP header of encapsulated UDP GSO packets Julius Bairaktaris
2026-11-14 18:26 ` [PATCH net v5 3/4] ipmr: set up GSO state for tunnel vifs Julius Bairaktaris
2026-11-14 18:27 ` [PATCH net v5 4/4] ipmr: do not drop GSO packets that fit the MTU after segmentation Julius Bairaktaris
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=cover.1794151759.git.julius@bairaktaris.de \
--to=julius@bairaktaris.de \
--cc=almasrymina@google.com \
--cc=bigeasy@linutronix.de \
--cc=bsdhenrymartin@gmail.com \
--cc=davem@davemloft.net \
--cc=dsahern@kernel.org \
--cc=ecree.xilinx@gmail.com \
--cc=edumazet@kernel.org \
--cc=horms@kernel.org \
--cc=idosch@nvidia.com \
--cc=jiayuan.chen@linux.dev \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mfleming@cloudflare.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=richardbgobert@gmail.com \
--cc=steffen.klassert@secunet.com \
--cc=willemb@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.