diff options
Diffstat (limited to 'net/ipv4/xfrm4_input.c')
-rw-r--r-- | net/ipv4/xfrm4_input.c | 17 |
1 files changed, 9 insertions, 8 deletions
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c index 850d919591d1..3e174c83bfe7 100644 --- a/net/ipv4/xfrm4_input.c +++ b/net/ipv4/xfrm4_input.c | |||
@@ -37,8 +37,6 @@ static int xfrm4_parse_spi(struct sk_buff *skb, u8 nexthdr, u32 *spi, u32 *seq) | |||
37 | { | 37 | { |
38 | switch (nexthdr) { | 38 | switch (nexthdr) { |
39 | case IPPROTO_IPIP: | 39 | case IPPROTO_IPIP: |
40 | if (!pskb_may_pull(skb, sizeof(struct iphdr))) | ||
41 | return -EINVAL; | ||
42 | *spi = skb->nh.iph->saddr; | 40 | *spi = skb->nh.iph->saddr; |
43 | *seq = 0; | 41 | *seq = 0; |
44 | return 0; | 42 | return 0; |
@@ -68,7 +66,7 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type) | |||
68 | { | 66 | { |
69 | int err; | 67 | int err; |
70 | u32 spi, seq; | 68 | u32 spi, seq; |
71 | struct sec_decap_state xfrm_vec[XFRM_MAX_DEPTH]; | 69 | struct xfrm_state *xfrm_vec[XFRM_MAX_DEPTH]; |
72 | struct xfrm_state *x; | 70 | struct xfrm_state *x; |
73 | int xfrm_nr = 0; | 71 | int xfrm_nr = 0; |
74 | int decaps = 0; | 72 | int decaps = 0; |
@@ -90,14 +88,16 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type) | |||
90 | if (unlikely(x->km.state != XFRM_STATE_VALID)) | 88 | if (unlikely(x->km.state != XFRM_STATE_VALID)) |
91 | goto drop_unlock; | 89 | goto drop_unlock; |
92 | 90 | ||
91 | if ((x->encap ? x->encap->encap_type : 0) != encap_type) | ||
92 | goto drop_unlock; | ||
93 | |||
93 | if (x->props.replay_window && xfrm_replay_check(x, seq)) | 94 | if (x->props.replay_window && xfrm_replay_check(x, seq)) |
94 | goto drop_unlock; | 95 | goto drop_unlock; |
95 | 96 | ||
96 | if (xfrm_state_check_expire(x)) | 97 | if (xfrm_state_check_expire(x)) |
97 | goto drop_unlock; | 98 | goto drop_unlock; |
98 | 99 | ||
99 | xfrm_vec[xfrm_nr].decap.decap_type = encap_type; | 100 | if (x->type->input(x, skb)) |
100 | if (x->type->input(x, &(xfrm_vec[xfrm_nr].decap), skb)) | ||
101 | goto drop_unlock; | 101 | goto drop_unlock; |
102 | 102 | ||
103 | /* only the first xfrm gets the encap type */ | 103 | /* only the first xfrm gets the encap type */ |
@@ -111,7 +111,7 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type) | |||
111 | 111 | ||
112 | spin_unlock(&x->lock); | 112 | spin_unlock(&x->lock); |
113 | 113 | ||
114 | xfrm_vec[xfrm_nr++].xvec = x; | 114 | xfrm_vec[xfrm_nr++] = x; |
115 | 115 | ||
116 | iph = skb->nh.iph; | 116 | iph = skb->nh.iph; |
117 | 117 | ||
@@ -153,7 +153,8 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type) | |||
153 | if (xfrm_nr + skb->sp->len > XFRM_MAX_DEPTH) | 153 | if (xfrm_nr + skb->sp->len > XFRM_MAX_DEPTH) |
154 | goto drop; | 154 | goto drop; |
155 | 155 | ||
156 | memcpy(skb->sp->x+skb->sp->len, xfrm_vec, xfrm_nr*sizeof(struct sec_decap_state)); | 156 | memcpy(skb->sp->xvec + skb->sp->len, xfrm_vec, |
157 | xfrm_nr * sizeof(xfrm_vec[0])); | ||
157 | skb->sp->len += xfrm_nr; | 158 | skb->sp->len += xfrm_nr; |
158 | 159 | ||
159 | nf_reset(skb); | 160 | nf_reset(skb); |
@@ -184,7 +185,7 @@ drop_unlock: | |||
184 | xfrm_state_put(x); | 185 | xfrm_state_put(x); |
185 | drop: | 186 | drop: |
186 | while (--xfrm_nr >= 0) | 187 | while (--xfrm_nr >= 0) |
187 | xfrm_state_put(xfrm_vec[xfrm_nr].xvec); | 188 | xfrm_state_put(xfrm_vec[xfrm_nr]); |
188 | 189 | ||
189 | kfree_skb(skb); | 190 | kfree_skb(skb); |
190 | return 0; | 191 | return 0; |