diff mbox series

[nf-next,2/6] net: netfilter: nf_flow_table: set inner protocol when popping tunnel header

Message ID 20260901-nf-flowtable-sw-accel-ip6ip-sit-preliminary-v1-2-72e49be8c31f@oss.qualcomm.com
State New
Headers show
Series net: netfilter: preliminary support for IPv4 over IPv6 and SIT flowtable offload | expand

Commit Message

Lorenzo Bianconi Sept. 1, 2026, 4:32 p.m. UTC
Pop the outer tunnel header and set skb->protocol to the inner protocol
derived from ctx->tun.inner_proto in nf_flow_ip_tunnel_pop(), instead of
bailing out unless the tunnel carries IP-in-IP or IPv6-in-IPv6.
While at it, key nf_flow_encap_pop() off ctx->tun.inner_proto rather than
skb->protocol to decide whether the tunnel header needs to be popped, as
the skb protocol may not be updated yet at that point.
This is a preliminary patch to support IPv4 over IPv6 and SIT tunnel
flowtable offload.

Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
---
 net/netfilter/nf_flow_table_ip.c | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)
diff mbox series

Patch

diff --git a/net/netfilter/nf_flow_table_ip.c b/net/netfilter/nf_flow_table_ip.c
index 42e8de696474..8af3d98ef4b2 100644
--- a/net/netfilter/nf_flow_table_ip.c
+++ b/net/netfilter/nf_flow_table_ip.c
@@ -158,6 +158,12 @@  struct nf_flowtable_ctx {
 	} tun;
 };
 
+static bool nf_flow_is_tunnel_ip(struct nf_flowtable_ctx *ctx)
+{
+	return ctx->tun.inner_proto == IPPROTO_IPIP ||
+	       ctx->tun.inner_proto == IPPROTO_IPV6;
+}
+
 static void nf_flow_tuple_encap(struct nf_flowtable_ctx *ctx,
 				struct sk_buff *skb,
 				struct flow_offload_tuple *tuple)
@@ -366,12 +372,13 @@  static bool nf_flow_ip6_tunnel_proto(struct nf_flowtable_ctx *ctx,
 static void nf_flow_ip_tunnel_pop(struct nf_flowtable_ctx *ctx,
 				  struct sk_buff *skb)
 {
-	if (ctx->tun.inner_proto != IPPROTO_IPIP &&
-	    ctx->tun.inner_proto != IPPROTO_IPV6)
-		return;
-
 	skb_pull(skb, ctx->tun.hdr_size);
 	skb_reset_network_header(skb);
+
+	if (ctx->tun.inner_proto == IPPROTO_IPIP)
+		skb->protocol = htons(ETH_P_IP);
+	else
+		skb->protocol = htons(ETH_P_IPV6);
 }
 
 static bool nf_flow_skb_encap_protocol(struct nf_flowtable_ctx *ctx,
@@ -448,8 +455,7 @@  static void nf_flow_encap_pop(struct nf_flowtable_ctx *ctx,
 		}
 	}
 
-	if (skb->protocol == htons(ETH_P_IP) ||
-	    skb->protocol == htons(ETH_P_IPV6))
+	if (unlikely(nf_flow_is_tunnel_ip(ctx)))
 		nf_flow_ip_tunnel_pop(ctx, skb);
 }