[PATCH net 5/6] seg6: account for the MAC header in skb checksum on L2 encapsulation

From: Andrea Mayer

Date: Sat Oct 31 2026 - 18:58:31 EST


In L2ENCAP and L2ENCAP_RED mode, seg6_do_srh() puts the MAC header back
in front of the frame with skb_push(), without adding it to skb->csum.
The encapsulation then calls skb_postpush_rcsum() only for the outer
headers. With CHECKSUM_COMPLETE the MAC header is missing from
skb->csum, which no longer covers the whole packet as required.

For a forwarded packet, ip6_forward() sets ip_summed to CHECKSUM_NONE with
skb_forward_csum(), and End.DX2 does the same before sending the frame.
When the packet is delivered on the same node, a raw socket with
IPV6_CHECKSUM still reads skb->csum. With skb->csum computed by the device,
the kernel can then log a "hw csum failure", as if the device had computed
a wrong skb->csum.

Use skb_push_rcsum(), which also calls skb_postpush_rcsum() for the MAC
header.

Found by manual code inspection of the skb->csum updates in the SRv6 code,
and observed in a VM without kernel changes or error injection: with
skb->csum computed by a tc ct action, a BPF tracing program on
ip6_forward() shows skb->csum missing the MAC header. With this patch,
skb->csum covers it. Also tested against the srv6 selftests, and with a
ConnectX-6 Lx NIC (mlx5) that provides CHECKSUM_COMPLETE.

Fixes: 38ee7f2d4756 ("ipv6: sr: add support for encapsulation of L2 frames")
Signed-off-by: Andrea Mayer <andrea.mayer@xxxxxxxxxxx>
---
net/ipv6/seg6_iptunnel.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/ipv6/seg6_iptunnel.c b/net/ipv6/seg6_iptunnel.c
index 0d39a38a5dd2..3821d8e1409e 100644
--- a/net/ipv6/seg6_iptunnel.c
+++ b/net/ipv6/seg6_iptunnel.c
@@ -456,7 +456,7 @@ static int seg6_do_srh(struct sk_buff *skb, struct dst_entry *cache_dst)
return err;

skb_mac_header_rebuild(skb);
- skb_push(skb, skb->mac_len);
+ skb_push_rcsum(skb, skb->mac_len);

if (tinfo->mode == SEG6_IPTUN_MODE_L2ENCAP)
err = __seg6_do_srh_encap(skb, tinfo->srh,
--
2.43.0