80 lines
2.3 KiB
Diff
80 lines
2.3 KiB
Diff
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);
|
|
|