aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorReece R. Pollack2015-02-04 16:40:56 -0600
committerReece R. Pollack2015-02-04 17:36:11 -0600
commit251e0840063b3eafb3905e5d4f6db4b6da84ceb5 (patch)
tree3f38f7c5eeef61be82245ae93239dea3c1bec413
parent8931ad85747fb375811f4ad43c32b879e54202b7 (diff)
downloadlinux-251e0840063b3eafb3905e5d4f6db4b6da84ceb5.tar.gz
linux-251e0840063b3eafb3905e5d4f6db4b6da84ceb5.tar.xz
linux-251e0840063b3eafb3905e5d4f6db4b6da84ceb5.zip
net: Fix skb->protocol setting for mixed IPsec tunnels
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>
-rw-r--r--net/ipv4/xfrm4_output.c9
-rw-r--r--net/ipv6/xfrm6_output.c9
2 files changed, 16 insertions, 2 deletions
diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c
index 327a617d594..080633655a3 100644
--- a/net/ipv4/xfrm4_output.c
+++ b/net/ipv4/xfrm4_output.c
@@ -76,6 +76,8 @@ EXPORT_SYMBOL(xfrm4_prepare_output);
76 76
77int xfrm4_output_finish(struct sk_buff *skb) 77int xfrm4_output_finish(struct sk_buff *skb)
78{ 78{
79 const struct iphdr *iph;
80
79#ifdef CONFIG_NETFILTER 81#ifdef CONFIG_NETFILTER
80 if (!skb_dst(skb)->xfrm) { 82 if (!skb_dst(skb)->xfrm) {
81 IPCB(skb)->flags |= IPSKB_REROUTED; 83 IPCB(skb)->flags |= IPSKB_REROUTED;
@@ -85,7 +87,12 @@ int xfrm4_output_finish(struct sk_buff *skb)
85 IPCB(skb)->flags |= IPSKB_XFRM_TRANSFORMED; 87 IPCB(skb)->flags |= IPSKB_XFRM_TRANSFORMED;
86#endif 88#endif
87 89
88 skb->protocol = htons(ETH_P_IP); 90 iph = ip_hdr(skb);
91 if (iph->version == 6)
92 skb->protocol = htons(ETH_P_IPV6);
93 else
94 skb->protocol = htons(ETH_P_IP);
95
89 return xfrm_output(skb); 96 return xfrm_output(skb);
90} 97}
91 98
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c
index 8755a3079d0..2916d0165b9 100644
--- a/net/ipv6/xfrm6_output.c
+++ b/net/ipv6/xfrm6_output.c
@@ -124,11 +124,18 @@ EXPORT_SYMBOL(xfrm6_prepare_output);
124 124
125int xfrm6_output_finish(struct sk_buff *skb) 125int xfrm6_output_finish(struct sk_buff *skb)
126{ 126{
127 const struct ipv6hdr *iphv6;
128
127#ifdef CONFIG_NETFILTER 129#ifdef CONFIG_NETFILTER
128 IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED; 130 IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED;
129#endif 131#endif
130 132
131 skb->protocol = htons(ETH_P_IPV6); 133 iphv6 = ipv6_hdr(skb);
134 if (iphv6->version == IPVERSION)
135 skb->protocol = htons(ETH_P_IP);
136 else
137 skb->protocol = htons(ETH_P_IPV6);
138
132 return xfrm_output(skb); 139 return xfrm_output(skb);
133} 140}
134 141