penguin/monok8s

k8s image for Mono Gateway Dev Kit

patches/ask/kernel/0108-net__ipv4__ip_output.c.patch

raw ยท 2328 bytes

diff -uNr a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
--- a/net/ipv4/ip_output.c	2026-05-08 18:06:42.017639432 +0000
+++ b/net/ipv4/ip_output.c	2026-05-08 18:06:42.100831810 +0000
@@ -103,6 +103,17 @@
 {
 	struct iphdr *iph = ip_hdr(skb);
 
+#if defined(CONFIG_INET_IPSEC_OFFLOAD)
+	/*
+	 * The tunnel header is not added in slow path and packet may be ipv6
+	 * (IPv6 traffic and IPv4 IPSec tunnel) in case IPv6 over IPv4 IPsec
+	 * tunnel. When it assumes as IPv4 and accessing IP header from SKB
+	 * causing invalid accesses it leading to kernel panic.
+	 * Avoiding ip header checks.
+	 */
+	if ((skb->ipsec_offload) && (iph->version == 6))
+		goto sendout;
+#endif /* endif for CONFIG_INET_IPSEC_OFFLOAD */
 	IP_INC_STATS(net, IPSTATS_MIB_OUTREQUESTS);
 
 	iph_set_totlen(iph, skb->len);
@@ -115,8 +126,17 @@
 	if (unlikely(!skb))
 		return 0;
 
+#if defined(CONFIG_INET_IPSEC_OFFLOAD)
+sendout:
+#endif
 	skb->protocol = htons(ETH_P_IP);
 
+#if defined(CONFIG_INET_IPSEC_OFFLOAD)
+	if (skb->ipsec_offload) {
+		dst_output(net, sk, skb);
+		return 0;
+	} else
+#endif /* endif for CONFIG_INET_IPSEC_OFFLOAD */
 	return nf_hook(NFPROTO_IPV4, NF_INET_LOCAL_OUT,
 		       net, sk, skb, NULL, skb_dst_dev(skb),
 		       dst_output);
@@ -309,7 +329,11 @@
 	if (skb_is_gso(skb))
 		return ip_finish_output_gso(net, sk, skb, mtu);
 
-	if (skb->len > mtu || IPCB(skb)->frag_max_size)
+	if (
+#if defined(CONFIG_INET_IPSEC_OFFLOAD)
+		(skb->ipsec_offload == 0) &&
+#endif
+		(skb->len > mtu || IPCB(skb)->frag_max_size))
 		return ip_fragment(net, sk, skb, mtu, ip_finish_output2);
 
 	return ip_finish_output2(net, sk, skb);
@@ -435,6 +459,16 @@
 	skb->dev = dev;
 	skb->protocol = htons(ETH_P_IP);
 
+#if defined(CONFIG_INET_IPSEC_OFFLOAD)
+	/* Bypass invoking post routing hooks since the tunnel header and ESP
+	 * processing is not done in slow path for IPSec offloaded cases
+	 */
+	if (skb->ipsec_offload) {
+		ret_val = ip_finish_output(net, sk, skb);
+		rcu_read_unlock();
+		return ret_val;
+	}
+#endif
 	ret_val = NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING,
 				net, sk, skb, indev, dev,
 				ip_finish_output,
@@ -559,6 +593,9 @@
 	skb_dst_copy(to, from);
 	to->dev = from->dev;
 	to->mark = from->mark;
+#if defined(CONFIG_CPE_FAST_PATH)
+	to->qosmark = from->qosmark;
+#endif
 
 	skb_copy_hash(to, from);