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