diff options
Diffstat (limited to 'net/ipv6/esp6.c')
-rw-r--r-- | net/ipv6/esp6.c | 52 |
1 files changed, 26 insertions, 26 deletions
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c index 363e63ffecca..7107bb7e2e62 100644 --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c | |||
@@ -42,21 +42,19 @@ | |||
42 | static int esp6_output(struct xfrm_state *x, struct sk_buff *skb) | 42 | static int esp6_output(struct xfrm_state *x, struct sk_buff *skb) |
43 | { | 43 | { |
44 | int err; | 44 | int err; |
45 | int hdr_len; | ||
46 | struct ipv6hdr *top_iph; | 45 | struct ipv6hdr *top_iph; |
47 | struct ipv6_esp_hdr *esph; | 46 | struct ipv6_esp_hdr *esph; |
48 | struct crypto_blkcipher *tfm; | 47 | struct crypto_blkcipher *tfm; |
49 | struct blkcipher_desc desc; | 48 | struct blkcipher_desc desc; |
50 | struct esp_data *esp; | ||
51 | struct sk_buff *trailer; | 49 | struct sk_buff *trailer; |
52 | int blksize; | 50 | int blksize; |
53 | int clen; | 51 | int clen; |
54 | int alen; | 52 | int alen; |
55 | int nfrags; | 53 | int nfrags; |
56 | 54 | u8 *tail; | |
57 | esp = x->data; | 55 | struct esp_data *esp = x->data; |
58 | hdr_len = skb->h.raw - skb->data + | 56 | int hdr_len = (skb_transport_offset(skb) + |
59 | sizeof(*esph) + esp->conf.ivlen; | 57 | sizeof(*esph) + esp->conf.ivlen); |
60 | 58 | ||
61 | /* Strip IP+ESP header. */ | 59 | /* Strip IP+ESP header. */ |
62 | __skb_pull(skb, hdr_len); | 60 | __skb_pull(skb, hdr_len); |
@@ -81,19 +79,20 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb) | |||
81 | } | 79 | } |
82 | 80 | ||
83 | /* Fill padding... */ | 81 | /* Fill padding... */ |
82 | tail = skb_tail_pointer(trailer); | ||
84 | do { | 83 | do { |
85 | int i; | 84 | int i; |
86 | for (i=0; i<clen-skb->len - 2; i++) | 85 | for (i=0; i<clen-skb->len - 2; i++) |
87 | *(u8*)(trailer->tail + i) = i+1; | 86 | tail[i] = i + 1; |
88 | } while (0); | 87 | } while (0); |
89 | *(u8*)(trailer->tail + clen-skb->len - 2) = (clen - skb->len)-2; | 88 | tail[clen-skb->len - 2] = (clen - skb->len) - 2; |
90 | pskb_put(skb, trailer, clen - skb->len); | 89 | pskb_put(skb, trailer, clen - skb->len); |
91 | 90 | ||
92 | top_iph = (struct ipv6hdr *)__skb_push(skb, hdr_len); | 91 | top_iph = (struct ipv6hdr *)__skb_push(skb, hdr_len); |
93 | esph = (struct ipv6_esp_hdr *)skb->h.raw; | 92 | esph = (struct ipv6_esp_hdr *)skb_transport_header(skb); |
94 | top_iph->payload_len = htons(skb->len + alen - sizeof(*top_iph)); | 93 | top_iph->payload_len = htons(skb->len + alen - sizeof(*top_iph)); |
95 | *(u8*)(trailer->tail - 1) = *skb->nh.raw; | 94 | *(skb_tail_pointer(trailer) - 1) = *skb_network_header(skb); |
96 | *skb->nh.raw = IPPROTO_ESP; | 95 | *skb_network_header(skb) = IPPROTO_ESP; |
97 | 96 | ||
98 | esph->spi = x->id.spi; | 97 | esph->spi = x->id.spi; |
99 | esph->seq_no = htonl(++x->replay.oseq); | 98 | esph->seq_no = htonl(++x->replay.oseq); |
@@ -150,8 +149,7 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb) | |||
150 | int blksize = ALIGN(crypto_blkcipher_blocksize(tfm), 4); | 149 | int blksize = ALIGN(crypto_blkcipher_blocksize(tfm), 4); |
151 | int alen = esp->auth.icv_trunc_len; | 150 | int alen = esp->auth.icv_trunc_len; |
152 | int elen = skb->len - sizeof(struct ipv6_esp_hdr) - esp->conf.ivlen - alen; | 151 | int elen = skb->len - sizeof(struct ipv6_esp_hdr) - esp->conf.ivlen - alen; |
153 | 152 | int hdr_len = skb_network_header_len(skb); | |
154 | int hdr_len = skb->h.raw - skb->nh.raw; | ||
155 | int nfrags; | 153 | int nfrags; |
156 | int ret = 0; | 154 | int ret = 0; |
157 | 155 | ||
@@ -191,7 +189,7 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb) | |||
191 | skb->ip_summed = CHECKSUM_NONE; | 189 | skb->ip_summed = CHECKSUM_NONE; |
192 | 190 | ||
193 | esph = (struct ipv6_esp_hdr*)skb->data; | 191 | esph = (struct ipv6_esp_hdr*)skb->data; |
194 | iph = skb->nh.ipv6h; | 192 | iph = ipv6_hdr(skb); |
195 | 193 | ||
196 | /* Get ivec. This can be wrong, check against another impls. */ | 194 | /* Get ivec. This can be wrong, check against another impls. */ |
197 | if (esp->conf.ivlen) | 195 | if (esp->conf.ivlen) |
@@ -231,28 +229,30 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb) | |||
231 | ret = nexthdr[1]; | 229 | ret = nexthdr[1]; |
232 | } | 230 | } |
233 | 231 | ||
234 | skb->h.raw = __skb_pull(skb, sizeof(*esph) + esp->conf.ivlen) - hdr_len; | 232 | __skb_pull(skb, sizeof(*esph) + esp->conf.ivlen); |
235 | 233 | skb_set_transport_header(skb, -hdr_len); | |
236 | out: | 234 | out: |
237 | return ret; | 235 | return ret; |
238 | } | 236 | } |
239 | 237 | ||
240 | static u32 esp6_get_max_size(struct xfrm_state *x, int mtu) | 238 | static u32 esp6_get_mtu(struct xfrm_state *x, int mtu) |
241 | { | 239 | { |
242 | struct esp_data *esp = x->data; | 240 | struct esp_data *esp = x->data; |
243 | u32 blksize = ALIGN(crypto_blkcipher_blocksize(esp->conf.tfm), 4); | 241 | u32 blksize = ALIGN(crypto_blkcipher_blocksize(esp->conf.tfm), 4); |
242 | u32 align = max_t(u32, blksize, esp->conf.padlen); | ||
243 | u32 rem; | ||
244 | |||
245 | mtu -= x->props.header_len + esp->auth.icv_trunc_len; | ||
246 | rem = mtu & (align - 1); | ||
247 | mtu &= ~(align - 1); | ||
244 | 248 | ||
245 | if (x->props.mode == XFRM_MODE_TUNNEL) { | 249 | if (x->props.mode != XFRM_MODE_TUNNEL) { |
246 | mtu = ALIGN(mtu + 2, blksize); | ||
247 | } else { | ||
248 | /* The worst case. */ | ||
249 | u32 padsize = ((blksize - 1) & 7) + 1; | 250 | u32 padsize = ((blksize - 1) & 7) + 1; |
250 | mtu = ALIGN(mtu + 2, padsize) + blksize - padsize; | 251 | mtu -= blksize - padsize; |
252 | mtu += min_t(u32, blksize - padsize, rem); | ||
251 | } | 253 | } |
252 | if (esp->conf.padlen) | ||
253 | mtu = ALIGN(mtu, esp->conf.padlen); | ||
254 | 254 | ||
255 | return mtu + x->props.header_len + esp->auth.icv_trunc_len; | 255 | return mtu - 2; |
256 | } | 256 | } |
257 | 257 | ||
258 | static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | 258 | static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, |
@@ -382,7 +382,7 @@ static struct xfrm_type esp6_type = | |||
382 | .proto = IPPROTO_ESP, | 382 | .proto = IPPROTO_ESP, |
383 | .init_state = esp6_init_state, | 383 | .init_state = esp6_init_state, |
384 | .destructor = esp6_destroy, | 384 | .destructor = esp6_destroy, |
385 | .get_max_size = esp6_get_max_size, | 385 | .get_mtu = esp6_get_mtu, |
386 | .input = esp6_input, | 386 | .input = esp6_input, |
387 | .output = esp6_output, | 387 | .output = esp6_output, |
388 | .hdr_offset = xfrm6_find_1stfragopt, | 388 | .hdr_offset = xfrm6_find_1stfragopt, |