diff options
| author | Li Hongjun <hongjun.li@6wind.com> | 2013-08-28 05:54:50 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2013-08-30 17:13:28 -0400 |
| commit | 737e828bdbdaf2f9d7de07f20a0308ac46ce5178 (patch) | |
| tree | ab12496674c4006b6a5cde6c53b7e18407bb1d44 | |
| parent | 2c8d85182348021fc0a1bed193a4be4161dc8364 (diff) | |
ipv4 tunnels: fix an oops when using ipip/sit with IPsec
Since commit 3d7b46cd20e3 (ip_tunnel: push generic protocol handling to
ip_tunnel module.), an Oops is triggered when an xfrm policy is configured on
an IPv4 over IPv4 tunnel.
xfrm4_policy_check() calls __xfrm_policy_check2(), which uses skb_dst(skb). But
this field is NULL because iptunnel_pull_header() calls skb_dst_drop(skb).
Signed-off-by: Li Hongjun <hongjun.li@6wind.com>
Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | net/ipv4/ipip.c | 5 | ||||
| -rw-r--r-- | net/ipv6/sit.c | 6 |
2 files changed, 4 insertions, 7 deletions
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index 51fc2a1dcdd3..b3ac3c3f6219 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c | |||
| @@ -190,15 +190,14 @@ static int ipip_rcv(struct sk_buff *skb) | |||
| 190 | struct ip_tunnel *tunnel; | 190 | struct ip_tunnel *tunnel; |
| 191 | const struct iphdr *iph; | 191 | const struct iphdr *iph; |
| 192 | 192 | ||
| 193 | if (iptunnel_pull_header(skb, 0, tpi.proto)) | ||
| 194 | goto drop; | ||
| 195 | |||
| 196 | iph = ip_hdr(skb); | 193 | iph = ip_hdr(skb); |
| 197 | tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, TUNNEL_NO_KEY, | 194 | tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, TUNNEL_NO_KEY, |
| 198 | iph->saddr, iph->daddr, 0); | 195 | iph->saddr, iph->daddr, 0); |
| 199 | if (tunnel) { | 196 | if (tunnel) { |
| 200 | if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) | 197 | if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) |
| 201 | goto drop; | 198 | goto drop; |
| 199 | if (iptunnel_pull_header(skb, 0, tpi.proto)) | ||
| 200 | goto drop; | ||
| 202 | return ip_tunnel_rcv(tunnel, skb, &tpi, log_ecn_error); | 201 | return ip_tunnel_rcv(tunnel, skb, &tpi, log_ecn_error); |
| 203 | } | 202 | } |
| 204 | 203 | ||
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index fbfc5a83867f..21b25dd8466b 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
| @@ -645,11 +645,7 @@ static int ipip_rcv(struct sk_buff *skb) | |||
| 645 | const struct iphdr *iph; | 645 | const struct iphdr *iph; |
| 646 | struct ip_tunnel *tunnel; | 646 | struct ip_tunnel *tunnel; |
| 647 | 647 | ||
| 648 | if (iptunnel_pull_header(skb, 0, tpi.proto)) | ||
| 649 | goto drop; | ||
| 650 | |||
| 651 | iph = ip_hdr(skb); | 648 | iph = ip_hdr(skb); |
| 652 | |||
| 653 | tunnel = ipip6_tunnel_lookup(dev_net(skb->dev), skb->dev, | 649 | tunnel = ipip6_tunnel_lookup(dev_net(skb->dev), skb->dev, |
| 654 | iph->saddr, iph->daddr); | 650 | iph->saddr, iph->daddr); |
| 655 | if (tunnel != NULL) { | 651 | if (tunnel != NULL) { |
| @@ -659,6 +655,8 @@ static int ipip_rcv(struct sk_buff *skb) | |||
| 659 | 655 | ||
| 660 | if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) | 656 | if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) |
| 661 | goto drop; | 657 | goto drop; |
| 658 | if (iptunnel_pull_header(skb, 0, tpi.proto)) | ||
| 659 | goto drop; | ||
| 662 | return ip_tunnel_rcv(tunnel, skb, &tpi, log_ecn_error); | 660 | return ip_tunnel_rcv(tunnel, skb, &tpi, log_ecn_error); |
| 663 | } | 661 | } |
| 664 | 662 | ||
