aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2007-10-10 18:45:25 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:55:55 -0400
commit87bdc48d304191313203df9b98d783e1ab5a55ab (patch)
tree32f7bfb3a5fa7fe373f11e0ddadd95b6bcd9bd4f
parent37fedd3aab6517daec628764c5d66dd8761fbe5f (diff)
[IPSEC]: Get rid of ipv6_{auth,esp,comp}_hdr
This patch removes the duplicate ipv6_{auth,esp,comp}_hdr structures since they're identical to the IPv4 versions. Duplicating them would only create problems for ourselves later when we need to add things like extended sequence numbers. I've also added transport header type conversion headers for these types which are now used by the transforms. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
-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)