Re: [PATCH net 5/6] seg6: account for the MAC header in skb checksum on L2 encapsulation
From: Hangbin Liu
Date: Mon Nov 02 2026 - 21:39:16 EST
Hi Andrea,
On Sat, Oct 31, 2026 at 11:50:32PM +0100, Andrea Mayer wrote:
> 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
>
Should we put the skb_push_rcsum() inside of __seg6_do_srh_encap() and
seg6_do_srh_encap_red()? They all do skb_mac_header_rebuild() again.
Thanks
Hangbin