Skip to content

Commit d84d5ac

Browse files
committed
bpf: clear decap state on skb_adjust_room shrink path
commit-author Nick Hudson <nhudson@akamai.com> commit - commit-source https://lore.kernel.org/netdev/20260504101759.3319427-6-nhudson@akamai.com/ On shrink in bpf_skb_adjust_room(), apply decapsulation state updates according to BPF_F_ADJ_ROOM_DECAP_* flags. For GSO skbs, clear only the tunnel gso_type bits that correspond to the requested decap layer: - DECAP_L4_UDP: SKB_GSO_UDP_TUNNEL{,_CSUM} - DECAP_L4_GRE: SKB_GSO_GRE{,_CSUM} - DECAP_IPXIP4: SKB_GSO_IPXIP4 - DECAP_IPXIP6: SKB_GSO_IPXIP6 Then clear skb->encapsulation only if no tunnel GSO bits remain, keeping encapsulation set for cases such as ESP-in-UDP where tunnel state remains. For non-GSO skbs, there are no tunnel GSO bits to consult, so clear skb->encapsulation directly when DECAP_L4_* or DECAP_IPXIP_* flags are set. This keeps decap state handling consistent between GSO and non-GSO packets. Co-developed-by: Max Tottenham <mtottenh@akamai.com> Signed-off-by: Max Tottenham <mtottenh@akamai.com> Co-developed-by: Anna Glasgall <aglasgal@akamai.com> Signed-off-by: Anna Glasgall <aglasgal@akamai.com> Signed-off-by: Nick Hudson <nhudson@akamai.com> Signed-off-by: Brett Mastbergen <bmastbergen@ciq.com>
1 parent 4687d1c commit d84d5ac

1 file changed

Lines changed: 39 additions & 0 deletions

File tree

net/core/filter.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3596,9 +3596,48 @@ static int bpf_skb_net_shrink(struct sk_buff *skb, u32 off, u32 len_diff,
35963596
if (!(flags & BPF_F_ADJ_ROOM_FIXED_GSO))
35973597
skb_increase_gso_size(shinfo, len_diff);
35983598

3599+
/* Selective GSO flag clearing based on decap type.
3600+
* Only clear the flags for the tunnel layer being removed.
3601+
*/
3602+
if ((flags & BPF_F_ADJ_ROOM_DECAP_L4_UDP) &&
3603+
(shinfo->gso_type & (SKB_GSO_UDP_TUNNEL |
3604+
SKB_GSO_UDP_TUNNEL_CSUM)))
3605+
shinfo->gso_type &= ~(SKB_GSO_UDP_TUNNEL |
3606+
SKB_GSO_UDP_TUNNEL_CSUM);
3607+
if ((flags & BPF_F_ADJ_ROOM_DECAP_L4_GRE) &&
3608+
(shinfo->gso_type & (SKB_GSO_GRE | SKB_GSO_GRE_CSUM)))
3609+
shinfo->gso_type &= ~(SKB_GSO_GRE |
3610+
SKB_GSO_GRE_CSUM);
3611+
if ((flags & BPF_F_ADJ_ROOM_DECAP_IPXIP4) &&
3612+
(shinfo->gso_type & SKB_GSO_IPXIP4))
3613+
shinfo->gso_type &= ~SKB_GSO_IPXIP4;
3614+
if ((flags & BPF_F_ADJ_ROOM_DECAP_IPXIP6) &&
3615+
(shinfo->gso_type & SKB_GSO_IPXIP6))
3616+
shinfo->gso_type &= ~SKB_GSO_IPXIP6;
3617+
3618+
/* Clear encapsulation flag only when no tunnel GSO flags remain */
3619+
if (flags & (BPF_F_ADJ_ROOM_DECAP_L4_MASK |
3620+
BPF_F_ADJ_ROOM_DECAP_IPXIP_MASK)) {
3621+
if (!(shinfo->gso_type & (SKB_GSO_UDP_TUNNEL |
3622+
SKB_GSO_UDP_TUNNEL_CSUM |
3623+
SKB_GSO_GRE |
3624+
SKB_GSO_GRE_CSUM |
3625+
SKB_GSO_IPXIP4 |
3626+
SKB_GSO_IPXIP6 |
3627+
SKB_GSO_ESP)))
3628+
if (skb->encapsulation)
3629+
skb->encapsulation = 0;
3630+
}
3631+
35993632
/* Header must be checked, and gso_segs recomputed. */
36003633
shinfo->gso_type |= SKB_GSO_DODGY;
36013634
shinfo->gso_segs = 0;
3635+
} else {
3636+
/* For non-GSO packets, clear encapsulation if decap flags are set */
3637+
if ((flags & (BPF_F_ADJ_ROOM_DECAP_L4_MASK |
3638+
BPF_F_ADJ_ROOM_DECAP_IPXIP_MASK)) &&
3639+
skb->encapsulation)
3640+
skb->encapsulation = 0;
36023641
}
36033642

36043643
return 0;

0 commit comments

Comments
 (0)