penguin/monok8s

k8s image for Mono Gateway Dev Kit

patches/ask/kernel/0115-net__ipv6__output_core.c.patch

raw ยท 1318 bytes

diff --git a/net/ipv6/output_core.c b/net/ipv6/output_core.c
index 1c9b283..5682505 100644
--- a/net/ipv6/output_core.c
+++ b/net/ipv6/output_core.c
@@ -130,7 +130,19 @@ int __ip6_local_out(struct net *net, struct sock *sk, struct sk_buff *skb)
 	len = skb->len - sizeof(struct ipv6hdr);
 	if (len > IPV6_MAXPLEN)
 		len = 0;
+
+#if defined(CONFIG_INET6_IPSEC_OFFLOAD)
+	/*
+	 * Since tunnel header is not added in slow path and route cache entry
+	 * lookup is changed to perform lookup on tunnel header, dst_output()
+	 * may reach IPv6 output for IPv4-over-IPv6 IPsec tunnel packets. Only
+	 * update the IPv6 payload length when the skb really carries IPv6 here.
+	 */
+	if (ipv6_hdr(skb)->version == 6)
+		ipv6_hdr(skb)->payload_len = htons(len);
+#else
 	ipv6_hdr(skb)->payload_len = htons(len);
+#endif
 	IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr);
 
 	/* if egress device is enslaved to an L3 master device pass the
@@ -142,6 +154,13 @@ int __ip6_local_out(struct net *net, struct sock *sk, struct sk_buff *skb)
 
 	skb->protocol = htons(ETH_P_IPV6);
 
+#if defined(CONFIG_INET6_IPSEC_OFFLOAD)
+	if (skb->ipsec_offload) {
+		dst_output(net, sk, skb);
+		return 0;
+	}
+#endif
+
 	return nf_hook(NFPROTO_IPV6, NF_INET_LOCAL_OUT,
 		       net, sk, skb, NULL, skb_dst_dev(skb),
 		       dst_output);