diff options
Diffstat (limited to 'net/ipv6/esp6.c')
-rw-r--r-- | net/ipv6/esp6.c | 20 |
1 files changed, 4 insertions, 16 deletions
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c index 22f046079037..a15a6f320f70 100644 --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c | |||
@@ -142,25 +142,17 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb) | |||
142 | 142 | ||
143 | int hdr_len = skb->h.raw - skb->nh.raw; | 143 | int hdr_len = skb->h.raw - skb->nh.raw; |
144 | int nfrags; | 144 | int nfrags; |
145 | unsigned char *tmp_hdr = NULL; | ||
146 | int ret = 0; | 145 | int ret = 0; |
147 | 146 | ||
148 | if (!pskb_may_pull(skb, sizeof(struct ipv6_esp_hdr))) { | 147 | if (!pskb_may_pull(skb, sizeof(struct ipv6_esp_hdr))) { |
149 | ret = -EINVAL; | 148 | ret = -EINVAL; |
150 | goto out_nofree; | 149 | goto out; |
151 | } | 150 | } |
152 | 151 | ||
153 | if (elen <= 0 || (elen & (blksize-1))) { | 152 | if (elen <= 0 || (elen & (blksize-1))) { |
154 | ret = -EINVAL; | 153 | ret = -EINVAL; |
155 | goto out_nofree; | 154 | goto out; |
156 | } | ||
157 | |||
158 | tmp_hdr = kmalloc(hdr_len, GFP_ATOMIC); | ||
159 | if (!tmp_hdr) { | ||
160 | ret = -ENOMEM; | ||
161 | goto out_nofree; | ||
162 | } | 155 | } |
163 | memcpy(tmp_hdr, skb->nh.raw, hdr_len); | ||
164 | 156 | ||
165 | /* If integrity check is required, do this. */ | 157 | /* If integrity check is required, do this. */ |
166 | if (esp->auth.icv_full_len) { | 158 | if (esp->auth.icv_full_len) { |
@@ -222,16 +214,12 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb) | |||
222 | /* ... check padding bits here. Silly. :-) */ | 214 | /* ... check padding bits here. Silly. :-) */ |
223 | 215 | ||
224 | pskb_trim(skb, skb->len - alen - padlen - 2); | 216 | pskb_trim(skb, skb->len - alen - padlen - 2); |
225 | skb->h.raw = skb_pull(skb, sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen); | ||
226 | skb->nh.raw += sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen; | ||
227 | memcpy(skb->nh.raw, tmp_hdr, hdr_len); | ||
228 | skb->nh.ipv6h->payload_len = htons(skb->len - sizeof(struct ipv6hdr)); | ||
229 | ret = nexthdr[1]; | 217 | ret = nexthdr[1]; |
230 | } | 218 | } |
231 | 219 | ||
220 | skb->h.raw = __skb_pull(skb, sizeof(*esph) + esp->conf.ivlen) - hdr_len; | ||
221 | |||
232 | out: | 222 | out: |
233 | kfree(tmp_hdr); | ||
234 | out_nofree: | ||
235 | return ret; | 223 | return ret; |
236 | } | 224 | } |
237 | 225 | ||