]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - keystone-linux/linux.git/commitdiff
net: Fix skb->protocol setting for mixed IPsec tunnels
authorReece R. Pollack <x0183204@ti.com>
Wed, 4 Feb 2015 22:40:56 +0000 (17:40 -0500)
committerReece R. Pollack <x0183204@ti.com>
Wed, 4 Feb 2015 23:36:11 +0000 (18:36 -0500)
When processing fragmented packets in a mixed-protocol tunnel
(i.e. IPv6 inner and IPv4 outer, or IPv4 inner and IPv6 outer),
the skb->protocol field is being set to the wrong value. This
patch sets the skb->protocol value according to the IP header
version of the packet it's carrying.

Signed-off-by: Reece R. Pollack <x0183204@ti.com>
net/ipv4/xfrm4_output.c
net/ipv6/xfrm6_output.c

index 327a617d594cd04929ffa668082ed575b0f54d7f..080633655a3aa90b742a6410157475f79679b646 100644 (file)
@@ -76,6 +76,8 @@ EXPORT_SYMBOL(xfrm4_prepare_output);
 
 int xfrm4_output_finish(struct sk_buff *skb)
 {
+       const struct iphdr *iph;
+
 #ifdef CONFIG_NETFILTER
        if (!skb_dst(skb)->xfrm) {
                IPCB(skb)->flags |= IPSKB_REROUTED;
@@ -85,7 +87,12 @@ int xfrm4_output_finish(struct sk_buff *skb)
        IPCB(skb)->flags |= IPSKB_XFRM_TRANSFORMED;
 #endif
 
-       skb->protocol = htons(ETH_P_IP);
+       iph = ip_hdr(skb);
+       if (iph->version == 6)
+               skb->protocol = htons(ETH_P_IPV6);
+       else
+               skb->protocol = htons(ETH_P_IP);
+
        return xfrm_output(skb);
 }
 
index 8755a3079d0f3279255e54520fbfcdeb19a2006b..2916d0165b924ce3848fd65cf6d55a46e8b7f109 100644 (file)
@@ -124,11 +124,18 @@ EXPORT_SYMBOL(xfrm6_prepare_output);
 
 int xfrm6_output_finish(struct sk_buff *skb)
 {
+       const struct ipv6hdr *iphv6;
+
 #ifdef CONFIG_NETFILTER
        IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED;
 #endif
 
-       skb->protocol = htons(ETH_P_IPV6);
+       iphv6 = ipv6_hdr(skb);
+       if (iphv6->version == IPVERSION)
+               skb->protocol = htons(ETH_P_IP);
+       else
+               skb->protocol = htons(ETH_P_IPV6);
+
        return xfrm_output(skb);
 }