diff options
Diffstat (limited to 'net/ipv6/xfrm6_input.c')
-rw-r--r-- | net/ipv6/xfrm6_input.c | 14 |
1 files changed, 6 insertions, 8 deletions
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c index 02f69e544f6f..515783707e86 100644 --- a/net/ipv6/xfrm6_input.c +++ b/net/ipv6/xfrm6_input.c | |||
@@ -16,7 +16,7 @@ | |||
16 | #include <net/ipv6.h> | 16 | #include <net/ipv6.h> |
17 | #include <net/xfrm.h> | 17 | #include <net/xfrm.h> |
18 | 18 | ||
19 | int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi) | 19 | int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi) |
20 | { | 20 | { |
21 | int err; | 21 | int err; |
22 | __be32 seq; | 22 | __be32 seq; |
@@ -24,11 +24,9 @@ int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi) | |||
24 | struct xfrm_state *x; | 24 | struct xfrm_state *x; |
25 | int xfrm_nr = 0; | 25 | int xfrm_nr = 0; |
26 | int decaps = 0; | 26 | int decaps = 0; |
27 | int nexthdr; | ||
28 | unsigned int nhoff; | 27 | unsigned int nhoff; |
29 | 28 | ||
30 | nhoff = IP6CB(skb)->nhoff; | 29 | nhoff = IP6CB(skb)->nhoff; |
31 | nexthdr = skb_network_header(skb)[nhoff]; | ||
32 | 30 | ||
33 | seq = 0; | 31 | seq = 0; |
34 | if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0) | 32 | if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0) |
@@ -41,7 +39,7 @@ int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi) | |||
41 | goto drop; | 39 | goto drop; |
42 | 40 | ||
43 | x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi, | 41 | x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi, |
44 | nexthdr != IPPROTO_IPIP ? nexthdr : IPPROTO_IPV6, AF_INET6); | 42 | nexthdr, AF_INET6); |
45 | if (x == NULL) | 43 | if (x == NULL) |
46 | goto drop; | 44 | goto drop; |
47 | spin_lock(&x->lock); | 45 | spin_lock(&x->lock); |
@@ -70,10 +68,10 @@ int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi) | |||
70 | 68 | ||
71 | xfrm_vec[xfrm_nr++] = x; | 69 | xfrm_vec[xfrm_nr++] = x; |
72 | 70 | ||
73 | if (x->mode->input(x, skb)) | 71 | if (x->outer_mode->input(x, skb)) |
74 | goto drop; | 72 | goto drop; |
75 | 73 | ||
76 | if (x->props.mode == XFRM_MODE_TUNNEL) { /* XXX */ | 74 | if (x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) { |
77 | decaps = 1; | 75 | decaps = 1; |
78 | break; | 76 | break; |
79 | } | 77 | } |
@@ -99,7 +97,6 @@ int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi) | |||
99 | memcpy(skb->sp->xvec + skb->sp->len, xfrm_vec, | 97 | memcpy(skb->sp->xvec + skb->sp->len, xfrm_vec, |
100 | xfrm_nr * sizeof(xfrm_vec[0])); | 98 | xfrm_nr * sizeof(xfrm_vec[0])); |
101 | skb->sp->len += xfrm_nr; | 99 | skb->sp->len += xfrm_nr; |
102 | skb->ip_summed = CHECKSUM_NONE; | ||
103 | 100 | ||
104 | nf_reset(skb); | 101 | nf_reset(skb); |
105 | 102 | ||
@@ -135,7 +132,8 @@ EXPORT_SYMBOL(xfrm6_rcv_spi); | |||
135 | 132 | ||
136 | int xfrm6_rcv(struct sk_buff *skb) | 133 | int xfrm6_rcv(struct sk_buff *skb) |
137 | { | 134 | { |
138 | return xfrm6_rcv_spi(skb, 0); | 135 | return xfrm6_rcv_spi(skb, skb_network_header(skb)[IP6CB(skb)->nhoff], |
136 | 0); | ||
139 | } | 137 | } |
140 | 138 | ||
141 | EXPORT_SYMBOL(xfrm6_rcv); | 139 | EXPORT_SYMBOL(xfrm6_rcv); |