[Openvpn-devel,RFC,net-next,v3,8/9] net: gro: honor skbs consumed by protocol callbacks

Message ID b620b08b5f1c90f64b52c041ed08a3f3d32fd132.1789546917.git.ralf@mandelbit.com
State Superseded
Headers
Series ovpn: preserve GSO and GRO batching |

Commit Message

Ralf Lici Sept. 16, 2026, 8:35 a.m. UTC
  XFRM's ESP GRO callbacks may consume an skb and return
ERR_PTR(-EINPROGRESS) as an ownership marker. dev_gro_receive already
recognizes this marker unconditionally and converts it to GRO_CONSUMED,
so -EINPROGRESS is reserved by the generic GRO callback interface and
cannot represent an ordinary callback error. The nested flush helpers
currently avoid accessing a consumed skb only when XFRM offload is
configured, because XFRM has so far been the sole user of the
convention.

Make the ownership check unconditional so other protocol callbacks can
safely use the existing marker without acquiring an unrelated
CONFIG_XFRM_OFFLOAD dependency. Callbacks which do not return the marker
are unaffected.

Signed-off-by: Ralf Lici <ralf@mandelbit.com>
---
No changes since v2 https://lore.kernel.org/openvpn-devel/3192bff7d69f958114e5fc9efe0dc5039c5be147.1789540779.git.ralf@mandelbit.com/

No changes since v1 https://lore.kernel.org/openvpn-devel/893f6c2b385f9df3e9617a9b7f547734061df195.1789485693.git.ralf@mandelbit.com/

 include/net/gro.h | 19 +++----------------
 1 file changed, 3 insertions(+), 16 deletions(-)
  

Patch

diff --git a/include/net/gro.h b/include/net/gro.h
index 2300b6da05b2..20ddc5488789 100644
--- a/include/net/gro.h
+++ b/include/net/gro.h
@@ -361,9 +361,11 @@  static inline void skb_gro_remcsum_cleanup(struct sk_buff *skb,
 	remcsum_unadjust((__sum16 *)ptr, grc->delta);
 }
 
-#ifdef CONFIG_XFRM_OFFLOAD
 static inline void skb_gro_flush_final(struct sk_buff *skb, struct sk_buff *pp, int flush)
 {
+	/* a GRO callback may consume skb and return this marker to prevent
+	 * accessing the skb while unwinding through the enclosing GRO layers
+	 */
 	if (PTR_ERR(pp) != -EINPROGRESS)
 		NAPI_GRO_CB(skb)->flush |= flush;
 }
@@ -378,21 +380,6 @@  static inline void skb_gro_flush_final_remcsum(struct sk_buff *skb,
 		skb->remcsum_offload = 0;
 	}
 }
-#else
-static inline void skb_gro_flush_final(struct sk_buff *skb, struct sk_buff *pp, int flush)
-{
-	NAPI_GRO_CB(skb)->flush |= flush;
-}
-static inline void skb_gro_flush_final_remcsum(struct sk_buff *skb,
-					       struct sk_buff *pp,
-					       int flush,
-					       struct gro_remcsum *grc)
-{
-	NAPI_GRO_CB(skb)->flush |= flush;
-	skb_gro_remcsum_cleanup(skb, grc);
-	skb->remcsum_offload = 0;
-}
-#endif
 
 INDIRECT_CALLABLE_DECLARE(struct sk_buff *ipv6_gro_receive(struct list_head *,
 							   struct sk_buff *));