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);