penguin/monok8s

k8s image for Mono Gateway Dev Kit

patches/ask/kernel/0112-net__ipv6__ip6_output.c.patch

raw ยท 2512 bytes

diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index f904739..e26e743 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -80,6 +80,13 @@ static int ip6_finish_output2(struct net *net, struct sock *sk, struct sk_buff *
 
 	hdr = ipv6_hdr(skb);
 	daddr = &hdr->daddr;
+#if defined(CONFIG_INET6_IPSEC_OFFLOAD)
+	/* For IPv4 over IPv6 IPsec tunnel cases, just send the packet out
+	 * since the packet is IPv4
+	 */
+	if((skb->ipsec_offload) && (hdr->version == 4))
+		goto sendout;
+#endif /* endif for CONFIG_INET6_IPSEC_OFFLOAD */
 	if (ipv6_addr_is_multicast(daddr)) {
 		if (!(dev->flags & IFF_LOOPBACK) && sk_mc_loop(sk) &&
 		    ((mroute6_is_socket(net, skb) &&
@@ -111,6 +118,9 @@ static int ip6_finish_output2(struct net *net, struct sock *sk, struct sk_buff *
 		}
 	}
 
+#if defined(CONFIG_INET6_IPSEC_OFFLOAD)
+sendout:
+#endif /* endif for CONFIG_INET6_IPSEC_OFFLOAD */
 	if (lwtunnel_xmit_redirect(dst->lwtstate)) {
 		int res = lwtunnel_xmit(skb);
 
@@ -202,8 +212,15 @@ static int __ip6_finish_output(struct net *net, struct sock *sk, struct sk_buff
 	if (skb_is_gso(skb))
 		return ip6_finish_output_gso(net, sk, skb, mtu);
 
-	if (skb->len > mtu ||
-	    (IP6CB(skb)->frag_max_size && skb->len > IP6CB(skb)->frag_max_size))
+	if (
+#if defined(CONFIG_INET6_IPSEC_OFFLOAD)
+		/* If ipsec offload is there, do not do fragment. So, when IPSec
+		 * offload is enabled it directly calls ip6_finish_output2
+		 */
+		(skb->ipsec_offload == 0) &&
+#endif
+		((skb->len > mtu) ||
+		(IP6CB(skb)->frag_max_size && skb->len > IP6CB(skb)->frag_max_size)))
 		return ip6_fragment(net, sk, skb, ip6_finish_output2);
 
 	return ip6_finish_output2(net, sk, skb);
@@ -244,6 +261,16 @@ int ip6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
 		return 0;
 	}
 
+#if defined(CONFIG_INET6_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 = ip6_finish_output(net, sk, skb);
+		rcu_read_unlock();
+		return ret;
+	}
+#endif
 	ret = NF_HOOK_COND(NFPROTO_IPV6, NF_INET_POST_ROUTING,
 			   net, sk, skb, indev, dev,
 			   ip6_finish_output,
@@ -697,6 +724,9 @@ static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from)
 	skb_dst_set(to, dst_clone(skb_dst(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);