aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/ipv6.h21
-rw-r--r--include/net/ah.h7
-rw-r--r--include/net/esp.h7
-rw-r--r--include/net/ipcomp.h11
-rw-r--r--net/ipv4/ah4.c18
-rw-r--r--net/ipv4/esp4.c10
-rw-r--r--net/ipv4/ipcomp.c2
-rw-r--r--net/ipv6/ah6.c16
-rw-r--r--net/ipv6/esp6.c18
-rw-r--r--net/ipv6/ipcomp6.c17
10 files changed, 64 insertions, 63 deletions
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index 4ca60c3320fb..5d35a4cc3bff 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -96,27 +96,6 @@ struct ipv6_destopt_hao {
96 struct in6_addr addr; 96 struct in6_addr addr;
97} __attribute__ ((__packed__)); 97} __attribute__ ((__packed__));
98 98
99struct ipv6_auth_hdr {
100 __u8 nexthdr;
101 __u8 hdrlen; /* This one is measured in 32 bit units! */
102 __be16 reserved;
103 __be32 spi;
104 __be32 seq_no; /* Sequence number */
105 __u8 auth_data[0]; /* Length variable but >=4. Mind the 64 bit alignment! */
106};
107
108struct ipv6_esp_hdr {
109 __be32 spi;
110 __be32 seq_no; /* Sequence number */
111 __u8 enc_data[0]; /* Length variable but >=8. Mind the 64 bit alignment! */
112};
113
114struct ipv6_comp_hdr {
115 __u8 nexthdr;
116 __u8 flags;
117 __be16 cpi;
118};
119
120/* 99/*
121 * IPv6 fixed header 100 * IPv6 fixed header
122 * 101 *
diff --git a/include/net/ah.h b/include/net/ah.h
index 5e758c2b5dd5..ae1c322f4242 100644
--- a/include/net/ah.h
+++ b/include/net/ah.h
@@ -38,4 +38,11 @@ out:
38 return err; 38 return err;
39} 39}
40 40
41struct ip_auth_hdr;
42
43static inline struct ip_auth_hdr *ip_auth_hdr(const struct sk_buff *skb)
44{
45 return (struct ip_auth_hdr *)skb_transport_header(skb);
46}
47
41#endif 48#endif
diff --git a/include/net/esp.h b/include/net/esp.h
index e793d769430e..c1bc529809da 100644
--- a/include/net/esp.h
+++ b/include/net/esp.h
@@ -53,4 +53,11 @@ static inline int esp_mac_digest(struct esp_data *esp, struct sk_buff *skb,
53 return crypto_hash_final(&desc, esp->auth.work_icv); 53 return crypto_hash_final(&desc, esp->auth.work_icv);
54} 54}
55 55
56struct ip_esp_hdr;
57
58static inline struct ip_esp_hdr *ip_esp_hdr(const struct sk_buff *skb)
59{
60 return (struct ip_esp_hdr *)skb_transport_header(skb);
61}
62
56#endif 63#endif
diff --git a/include/net/ipcomp.h b/include/net/ipcomp.h
index 87c1af3e5e82..330b74e813a9 100644
--- a/include/net/ipcomp.h
+++ b/include/net/ipcomp.h
@@ -1,14 +1,23 @@
1#ifndef _NET_IPCOMP_H 1#ifndef _NET_IPCOMP_H
2#define _NET_IPCOMP_H 2#define _NET_IPCOMP_H
3 3
4#include <linux/crypto.h>
5#include <linux/types.h> 4#include <linux/types.h>
6 5
7#define IPCOMP_SCRATCH_SIZE 65400 6#define IPCOMP_SCRATCH_SIZE 65400
8 7
8struct crypto_comp;
9
9struct ipcomp_data { 10struct ipcomp_data {
10 u16 threshold; 11 u16 threshold;
11 struct crypto_comp **tfms; 12 struct crypto_comp **tfms;
12}; 13};
13 14
15struct ip_comp_hdr;
16struct sk_buff;
17
18static inline struct ip_comp_hdr *ip_comp_hdr(const struct sk_buff *skb)
19{
20 return (struct ip_comp_hdr *)skb_transport_header(skb);
21}
22
14#endif 23#endif
diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c
index e4f7aa39978d..d69706405d58 100644
--- a/net/ipv4/ah4.c
+++ b/net/ipv4/ah4.c
@@ -82,7 +82,7 @@ static int ah_output(struct xfrm_state *x, struct sk_buff *skb)
82 goto error; 82 goto error;
83 } 83 }
84 84
85 ah = (struct ip_auth_hdr *)skb_transport_header(skb); 85 ah = ip_auth_hdr(skb);
86 ah->nexthdr = *skb_mac_header(skb); 86 ah->nexthdr = *skb_mac_header(skb);
87 *skb_mac_header(skb) = IPPROTO_AH; 87 *skb_mac_header(skb) = IPPROTO_AH;
88 88
@@ -93,8 +93,7 @@ static int ah_output(struct xfrm_state *x, struct sk_buff *skb)
93 top_iph->check = 0; 93 top_iph->check = 0;
94 94
95 ahp = x->data; 95 ahp = x->data;
96 ah->hdrlen = (XFRM_ALIGN8(sizeof(struct ip_auth_hdr) + 96 ah->hdrlen = (XFRM_ALIGN8(sizeof(*ah) + ahp->icv_trunc_len) >> 2) - 2;
97 ahp->icv_trunc_len) >> 2) - 2;
98 97
99 ah->reserved = 0; 98 ah->reserved = 0;
100 ah->spi = x->id.spi; 99 ah->spi = x->id.spi;
@@ -134,15 +133,15 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb)
134 struct ah_data *ahp; 133 struct ah_data *ahp;
135 char work_buf[60]; 134 char work_buf[60];
136 135
137 if (!pskb_may_pull(skb, sizeof(struct ip_auth_hdr))) 136 if (!pskb_may_pull(skb, sizeof(*ah)))
138 goto out; 137 goto out;
139 138
140 ah = (struct ip_auth_hdr*)skb->data; 139 ah = (struct ip_auth_hdr *)skb->data;
141 ahp = x->data; 140 ahp = x->data;
142 ah_hlen = (ah->hdrlen + 2) << 2; 141 ah_hlen = (ah->hdrlen + 2) << 2;
143 142
144 if (ah_hlen != XFRM_ALIGN8(sizeof(struct ip_auth_hdr) + ahp->icv_full_len) && 143 if (ah_hlen != XFRM_ALIGN8(sizeof(*ah) + ahp->icv_full_len) &&
145 ah_hlen != XFRM_ALIGN8(sizeof(struct ip_auth_hdr) + ahp->icv_trunc_len)) 144 ah_hlen != XFRM_ALIGN8(sizeof(*ah) + ahp->icv_trunc_len))
146 goto out; 145 goto out;
147 146
148 if (!pskb_may_pull(skb, ah_hlen)) 147 if (!pskb_may_pull(skb, ah_hlen))
@@ -156,7 +155,7 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb)
156 155
157 skb->ip_summed = CHECKSUM_NONE; 156 skb->ip_summed = CHECKSUM_NONE;
158 157
159 ah = (struct ip_auth_hdr*)skb->data; 158 ah = (struct ip_auth_hdr *)skb->data;
160 iph = ip_hdr(skb); 159 iph = ip_hdr(skb);
161 160
162 ihl = skb->data - skb_network_header(skb); 161 ihl = skb->data - skb_network_header(skb);
@@ -266,7 +265,8 @@ static int ah_init_state(struct xfrm_state *x)
266 if (!ahp->work_icv) 265 if (!ahp->work_icv)
267 goto error; 266 goto error;
268 267
269 x->props.header_len = XFRM_ALIGN8(sizeof(struct ip_auth_hdr) + ahp->icv_trunc_len); 268 x->props.header_len = XFRM_ALIGN8(sizeof(struct ip_auth_hdr) +
269 ahp->icv_trunc_len);
270 if (x->props.mode == XFRM_MODE_TUNNEL) 270 if (x->props.mode == XFRM_MODE_TUNNEL)
271 x->props.header_len += sizeof(struct iphdr); 271 x->props.header_len += sizeof(struct iphdr);
272 x->data = ahp; 272 x->data = ahp;
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 93153d105619..66eb4968b910 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -60,7 +60,7 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
60 60
61 skb_push(skb, -skb_network_offset(skb)); 61 skb_push(skb, -skb_network_offset(skb));
62 top_iph = ip_hdr(skb); 62 top_iph = ip_hdr(skb);
63 esph = (struct ip_esp_hdr *)skb_transport_header(skb); 63 esph = ip_esp_hdr(skb);
64 top_iph->tot_len = htons(skb->len + alen); 64 top_iph->tot_len = htons(skb->len + alen);
65 *(skb_tail_pointer(trailer) - 1) = *skb_mac_header(skb); 65 *(skb_tail_pointer(trailer) - 1) = *skb_mac_header(skb);
66 *skb_mac_header(skb) = IPPROTO_ESP; 66 *skb_mac_header(skb) = IPPROTO_ESP;
@@ -157,7 +157,7 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
157 struct sk_buff *trailer; 157 struct sk_buff *trailer;
158 int blksize = ALIGN(crypto_blkcipher_blocksize(tfm), 4); 158 int blksize = ALIGN(crypto_blkcipher_blocksize(tfm), 4);
159 int alen = esp->auth.icv_trunc_len; 159 int alen = esp->auth.icv_trunc_len;
160 int elen = skb->len - sizeof(struct ip_esp_hdr) - esp->conf.ivlen - alen; 160 int elen = skb->len - sizeof(*esph) - esp->conf.ivlen - alen;
161 int nfrags; 161 int nfrags;
162 int ihl; 162 int ihl;
163 u8 nexthdr[2]; 163 u8 nexthdr[2];
@@ -165,7 +165,7 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
165 int padlen; 165 int padlen;
166 int err; 166 int err;
167 167
168 if (!pskb_may_pull(skb, sizeof(struct ip_esp_hdr))) 168 if (!pskb_may_pull(skb, sizeof(*esph)))
169 goto out; 169 goto out;
170 170
171 if (elen <= 0 || (elen & (blksize-1))) 171 if (elen <= 0 || (elen & (blksize-1)))
@@ -193,7 +193,7 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
193 193
194 skb->ip_summed = CHECKSUM_NONE; 194 skb->ip_summed = CHECKSUM_NONE;
195 195
196 esph = (struct ip_esp_hdr*)skb->data; 196 esph = (struct ip_esp_hdr *)skb->data;
197 197
198 /* Get ivec. This can be wrong, check against another impls. */ 198 /* Get ivec. This can be wrong, check against another impls. */
199 if (esp->conf.ivlen) 199 if (esp->conf.ivlen)
@@ -206,7 +206,7 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
206 if (!sg) 206 if (!sg)
207 goto out; 207 goto out;
208 } 208 }
209 skb_to_sgvec(skb, sg, sizeof(struct ip_esp_hdr) + esp->conf.ivlen, elen); 209 skb_to_sgvec(skb, sg, sizeof(*esph) + esp->conf.ivlen, elen);
210 err = crypto_blkcipher_decrypt(&desc, sg, sg, elen); 210 err = crypto_blkcipher_decrypt(&desc, sg, sg, elen);
211 if (unlikely(sg != &esp->sgbuf[0])) 211 if (unlikely(sg != &esp->sgbuf[0]))
212 kfree(sg); 212 kfree(sg);
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c
index bf74f64fe5fb..78d6ddb02d1d 100644
--- a/net/ipv4/ipcomp.c
+++ b/net/ipv4/ipcomp.c
@@ -154,7 +154,7 @@ static int ipcomp_output(struct xfrm_state *x, struct sk_buff *skb)
154 154
155 /* Install ipcomp header, convert into ipcomp datagram. */ 155 /* Install ipcomp header, convert into ipcomp datagram. */
156 iph->tot_len = htons(skb->len); 156 iph->tot_len = htons(skb->len);
157 ipch = (struct ip_comp_hdr *)skb_transport_header(skb); 157 ipch = ip_comp_hdr(skb);
158 ipch->nexthdr = *skb_mac_header(skb); 158 ipch->nexthdr = *skb_mac_header(skb);
159 ipch->flags = 0; 159 ipch->flags = 0;
160 ipch->cpi = htons((u16 )ntohl(x->id.spi)); 160 ipch->cpi = htons((u16 )ntohl(x->id.spi));
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index ac6bae17a13b..f9f689162692 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -270,7 +270,7 @@ static int ah6_output(struct xfrm_state *x, struct sk_buff *skb)
270 goto error_free_iph; 270 goto error_free_iph;
271 } 271 }
272 272
273 ah = (struct ip_auth_hdr *)skb_transport_header(skb); 273 ah = ip_auth_hdr(skb);
274 ah->nexthdr = nexthdr; 274 ah->nexthdr = nexthdr;
275 275
276 top_iph->priority = 0; 276 top_iph->priority = 0;
@@ -280,8 +280,7 @@ static int ah6_output(struct xfrm_state *x, struct sk_buff *skb)
280 top_iph->hop_limit = 0; 280 top_iph->hop_limit = 0;
281 281
282 ahp = x->data; 282 ahp = x->data;
283 ah->hdrlen = (XFRM_ALIGN8(sizeof(struct ipv6_auth_hdr) + 283 ah->hdrlen = (XFRM_ALIGN8(sizeof(*ah) + ahp->icv_trunc_len) >> 2) - 2;
284 ahp->icv_trunc_len) >> 2) - 2;
285 284
286 ah->reserved = 0; 285 ah->reserved = 0;
287 ah->spi = x->id.spi; 286 ah->spi = x->id.spi;
@@ -327,7 +326,7 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb)
327 * There is offset of AH before IPv6 header after the process. 326 * There is offset of AH before IPv6 header after the process.
328 */ 327 */
329 328
330 struct ipv6_auth_hdr *ah; 329 struct ip_auth_hdr *ah;
331 struct ipv6hdr *ip6h; 330 struct ipv6hdr *ip6h;
332 struct ah_data *ahp; 331 struct ah_data *ahp;
333 unsigned char *tmp_hdr = NULL; 332 unsigned char *tmp_hdr = NULL;
@@ -346,13 +345,13 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb)
346 goto out; 345 goto out;
347 346
348 hdr_len = skb->data - skb_network_header(skb); 347 hdr_len = skb->data - skb_network_header(skb);
349 ah = (struct ipv6_auth_hdr*)skb->data; 348 ah = (struct ip_auth_hdr *)skb->data;
350 ahp = x->data; 349 ahp = x->data;
351 nexthdr = ah->nexthdr; 350 nexthdr = ah->nexthdr;
352 ah_hlen = (ah->hdrlen + 2) << 2; 351 ah_hlen = (ah->hdrlen + 2) << 2;
353 352
354 if (ah_hlen != XFRM_ALIGN8(sizeof(struct ipv6_auth_hdr) + ahp->icv_full_len) && 353 if (ah_hlen != XFRM_ALIGN8(sizeof(*ah) + ahp->icv_full_len) &&
355 ah_hlen != XFRM_ALIGN8(sizeof(struct ipv6_auth_hdr) + ahp->icv_trunc_len)) 354 ah_hlen != XFRM_ALIGN8(sizeof(*ah) + ahp->icv_trunc_len))
356 goto out; 355 goto out;
357 356
358 if (!pskb_may_pull(skb, ah_hlen)) 357 if (!pskb_may_pull(skb, ah_hlen))
@@ -474,7 +473,8 @@ static int ah6_init_state(struct xfrm_state *x)
474 if (!ahp->work_icv) 473 if (!ahp->work_icv)
475 goto error; 474 goto error;
476 475
477 x->props.header_len = XFRM_ALIGN8(sizeof(struct ipv6_auth_hdr) + ahp->icv_trunc_len); 476 x->props.header_len = XFRM_ALIGN8(sizeof(struct ip_auth_hdr) +
477 ahp->icv_trunc_len);
478 if (x->props.mode == XFRM_MODE_TUNNEL) 478 if (x->props.mode == XFRM_MODE_TUNNEL)
479 x->props.header_len += sizeof(struct ipv6hdr); 479 x->props.header_len += sizeof(struct ipv6hdr);
480 x->data = ahp; 480 x->data = ahp;
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index 21c93f026dbc..a64295d164ea 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -44,7 +44,7 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
44{ 44{
45 int err; 45 int err;
46 struct ipv6hdr *top_iph; 46 struct ipv6hdr *top_iph;
47 struct ipv6_esp_hdr *esph; 47 struct ip_esp_hdr *esph;
48 struct crypto_blkcipher *tfm; 48 struct crypto_blkcipher *tfm;
49 struct blkcipher_desc desc; 49 struct blkcipher_desc desc;
50 struct sk_buff *trailer; 50 struct sk_buff *trailer;
@@ -86,7 +86,7 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
86 86
87 skb_push(skb, -skb_network_offset(skb)); 87 skb_push(skb, -skb_network_offset(skb));
88 top_iph = ipv6_hdr(skb); 88 top_iph = ipv6_hdr(skb);
89 esph = (struct ipv6_esp_hdr *)skb_transport_header(skb); 89 esph = ip_esp_hdr(skb);
90 top_iph->payload_len = htons(skb->len + alen - sizeof(*top_iph)); 90 top_iph->payload_len = htons(skb->len + alen - sizeof(*top_iph));
91 *(skb_tail_pointer(trailer) - 1) = *skb_mac_header(skb); 91 *(skb_tail_pointer(trailer) - 1) = *skb_mac_header(skb);
92 *skb_mac_header(skb) = IPPROTO_ESP; 92 *skb_mac_header(skb) = IPPROTO_ESP;
@@ -142,19 +142,19 @@ error:
142static int esp6_input(struct xfrm_state *x, struct sk_buff *skb) 142static int esp6_input(struct xfrm_state *x, struct sk_buff *skb)
143{ 143{
144 struct ipv6hdr *iph; 144 struct ipv6hdr *iph;
145 struct ipv6_esp_hdr *esph; 145 struct ip_esp_hdr *esph;
146 struct esp_data *esp = x->data; 146 struct esp_data *esp = x->data;
147 struct crypto_blkcipher *tfm = esp->conf.tfm; 147 struct crypto_blkcipher *tfm = esp->conf.tfm;
148 struct blkcipher_desc desc = { .tfm = tfm }; 148 struct blkcipher_desc desc = { .tfm = tfm };
149 struct sk_buff *trailer; 149 struct sk_buff *trailer;
150 int blksize = ALIGN(crypto_blkcipher_blocksize(tfm), 4); 150 int blksize = ALIGN(crypto_blkcipher_blocksize(tfm), 4);
151 int alen = esp->auth.icv_trunc_len; 151 int alen = esp->auth.icv_trunc_len;
152 int elen = skb->len - sizeof(struct ipv6_esp_hdr) - esp->conf.ivlen - alen; 152 int elen = skb->len - sizeof(*esph) - esp->conf.ivlen - alen;
153 int hdr_len = skb_network_header_len(skb); 153 int hdr_len = skb_network_header_len(skb);
154 int nfrags; 154 int nfrags;
155 int ret = 0; 155 int ret = 0;
156 156
157 if (!pskb_may_pull(skb, sizeof(struct ipv6_esp_hdr))) { 157 if (!pskb_may_pull(skb, sizeof(*esph))) {
158 ret = -EINVAL; 158 ret = -EINVAL;
159 goto out; 159 goto out;
160 } 160 }
@@ -189,7 +189,7 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb)
189 189
190 skb->ip_summed = CHECKSUM_NONE; 190 skb->ip_summed = CHECKSUM_NONE;
191 191
192 esph = (struct ipv6_esp_hdr*)skb->data; 192 esph = (struct ip_esp_hdr *)skb->data;
193 iph = ipv6_hdr(skb); 193 iph = ipv6_hdr(skb);
194 194
195 /* Get ivec. This can be wrong, check against another impls. */ 195 /* Get ivec. This can be wrong, check against another impls. */
@@ -208,7 +208,7 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb)
208 goto out; 208 goto out;
209 } 209 }
210 } 210 }
211 skb_to_sgvec(skb, sg, sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen, elen); 211 skb_to_sgvec(skb, sg, sizeof(*esph) + esp->conf.ivlen, elen);
212 ret = crypto_blkcipher_decrypt(&desc, sg, sg, elen); 212 ret = crypto_blkcipher_decrypt(&desc, sg, sg, elen);
213 if (unlikely(sg != &esp->sgbuf[0])) 213 if (unlikely(sg != &esp->sgbuf[0]))
214 kfree(sg); 214 kfree(sg);
@@ -260,7 +260,7 @@ static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
260 int type, int code, int offset, __be32 info) 260 int type, int code, int offset, __be32 info)
261{ 261{
262 struct ipv6hdr *iph = (struct ipv6hdr*)skb->data; 262 struct ipv6hdr *iph = (struct ipv6hdr*)skb->data;
263 struct ipv6_esp_hdr *esph = (struct ipv6_esp_hdr*)(skb->data+offset); 263 struct ip_esp_hdr *esph = (struct ip_esp_hdr *)(skb->data + offset);
264 struct xfrm_state *x; 264 struct xfrm_state *x;
265 265
266 if (type != ICMPV6_DEST_UNREACH && 266 if (type != ICMPV6_DEST_UNREACH &&
@@ -356,7 +356,7 @@ static int esp6_init_state(struct xfrm_state *x)
356 if (crypto_blkcipher_setkey(tfm, x->ealg->alg_key, 356 if (crypto_blkcipher_setkey(tfm, x->ealg->alg_key,
357 (x->ealg->alg_key_len + 7) / 8)) 357 (x->ealg->alg_key_len + 7) / 8))
358 goto error; 358 goto error;
359 x->props.header_len = sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen; 359 x->props.header_len = sizeof(struct ip_esp_hdr) + esp->conf.ivlen;
360 if (x->props.mode == XFRM_MODE_TUNNEL) 360 if (x->props.mode == XFRM_MODE_TUNNEL)
361 x->props.header_len += sizeof(struct ipv6hdr); 361 x->props.header_len += sizeof(struct ipv6hdr);
362 x->data = esp; 362 x->data = esp;
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index 87e6407ebf97..8f3f32faaf4c 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -65,7 +65,7 @@ static LIST_HEAD(ipcomp6_tfms_list);
65static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb) 65static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb)
66{ 66{
67 int err = -ENOMEM; 67 int err = -ENOMEM;
68 struct ipv6_comp_hdr *ipch; 68 struct ip_comp_hdr *ipch;
69 int plen, dlen; 69 int plen, dlen;
70 struct ipcomp_data *ipcd = x->data; 70 struct ipcomp_data *ipcd = x->data;
71 u8 *start, *scratch; 71 u8 *start, *scratch;
@@ -92,12 +92,10 @@ static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb)
92 tfm = *per_cpu_ptr(ipcd->tfms, cpu); 92 tfm = *per_cpu_ptr(ipcd->tfms, cpu);
93 93
94 err = crypto_comp_decompress(tfm, start, plen, scratch, &dlen); 94 err = crypto_comp_decompress(tfm, start, plen, scratch, &dlen);
95 if (err) { 95 if (err)
96 err = -EINVAL;
97 goto out_put_cpu; 96 goto out_put_cpu;
98 }
99 97
100 if (dlen < (plen + sizeof(struct ipv6_comp_hdr))) { 98 if (dlen < (plen + sizeof(*ipch))) {
101 err = -EINVAL; 99 err = -EINVAL;
102 goto out_put_cpu; 100 goto out_put_cpu;
103 } 101 }
@@ -122,7 +120,7 @@ static int ipcomp6_output(struct xfrm_state *x, struct sk_buff *skb)
122{ 120{
123 int err; 121 int err;
124 struct ipv6hdr *top_iph; 122 struct ipv6hdr *top_iph;
125 struct ipv6_comp_hdr *ipch; 123 struct ip_comp_hdr *ipch;
126 struct ipcomp_data *ipcd = x->data; 124 struct ipcomp_data *ipcd = x->data;
127 int plen, dlen; 125 int plen, dlen;
128 u8 *start, *scratch; 126 u8 *start, *scratch;
@@ -151,7 +149,7 @@ static int ipcomp6_output(struct xfrm_state *x, struct sk_buff *skb)
151 tfm = *per_cpu_ptr(ipcd->tfms, cpu); 149 tfm = *per_cpu_ptr(ipcd->tfms, cpu);
152 150
153 err = crypto_comp_compress(tfm, start, plen, scratch, &dlen); 151 err = crypto_comp_compress(tfm, start, plen, scratch, &dlen);
154 if (err || (dlen + sizeof(struct ipv6_comp_hdr)) >= plen) { 152 if (err || (dlen + sizeof(*ipch)) >= plen) {
155 put_cpu(); 153 put_cpu();
156 goto out_ok; 154 goto out_ok;
157 } 155 }
@@ -164,7 +162,7 @@ static int ipcomp6_output(struct xfrm_state *x, struct sk_buff *skb)
164 162
165 top_iph->payload_len = htons(skb->len - sizeof(struct ipv6hdr)); 163 top_iph->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
166 164
167 ipch = (struct ipv6_comp_hdr *)start; 165 ipch = ip_comp_hdr(skb);
168 ipch->nexthdr = *skb_mac_header(skb); 166 ipch->nexthdr = *skb_mac_header(skb);
169 ipch->flags = 0; 167 ipch->flags = 0;
170 ipch->cpi = htons((u16 )ntohl(x->id.spi)); 168 ipch->cpi = htons((u16 )ntohl(x->id.spi));
@@ -179,7 +177,8 @@ static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
179{ 177{
180 __be32 spi; 178 __be32 spi;
181 struct ipv6hdr *iph = (struct ipv6hdr*)skb->data; 179 struct ipv6hdr *iph = (struct ipv6hdr*)skb->data;
182 struct ipv6_comp_hdr *ipcomph = (struct ipv6_comp_hdr*)(skb->data+offset); 180 struct ip_comp_hdr *ipcomph =
181 (struct ip_comp_hdr *)(skb->data + offset);
183 struct xfrm_state *x; 182 struct xfrm_state *x;
184 183
185 if (type != ICMPV6_DEST_UNREACH && type != ICMPV6_PKT_TOOBIG) 184 if (type != ICMPV6_DEST_UNREACH && type != ICMPV6_PKT_TOOBIG)