Blame view
net/ipv6/esp6.c
21.7 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 |
/* * Copyright (C)2002 USAGI/WIDE Project |
1ab1457c4 [NET] IPV6: Fix w... |
3 |
* |
1da177e4c Linux-2.6.12-rc2 |
4 5 6 7 |
* This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. |
1ab1457c4 [NET] IPV6: Fix w... |
8 |
* |
1da177e4c Linux-2.6.12-rc2 |
9 10 11 12 |
* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. |
1ab1457c4 [NET] IPV6: Fix w... |
13 |
* |
1da177e4c Linux-2.6.12-rc2 |
14 |
* You should have received a copy of the GNU General Public License |
a99421d9b ipv4/ipv6: Fix FS... |
15 |
* along with this program; if not, see <http://www.gnu.org/licenses/>. |
1da177e4c Linux-2.6.12-rc2 |
16 17 18 |
* * Authors * |
1ab1457c4 [NET] IPV6: Fix w... |
19 |
* Mitsuru KANDA @USAGI : IPv6 Support |
67ba4152e ipv6: White-space... |
20 21 |
* Kazunori MIYAZAWA @USAGI : * Kunihiro Ishiguro <kunihiro@ipinfusion.com> |
1ab1457c4 [NET] IPV6: Fix w... |
22 |
* |
67ba4152e ipv6: White-space... |
23 |
* This file is derived from net/ipv4/esp.c |
1da177e4c Linux-2.6.12-rc2 |
24 |
*/ |
f32138319 net: ipv6: Standa... |
25 |
#define pr_fmt(fmt) "IPv6: " fmt |
38320c70d [IPSEC]: Use cryp... |
26 27 |
#include <crypto/aead.h> #include <crypto/authenc.h> |
6b7326c84 [IPSEC] ESP: Use ... |
28 |
#include <linux/err.h> |
1da177e4c Linux-2.6.12-rc2 |
29 30 31 32 |
#include <linux/module.h> #include <net/ip.h> #include <net/xfrm.h> #include <net/esp.h> |
72998d8c8 [INET] ESP: Must ... |
33 |
#include <linux/scatterlist.h> |
a02a64223 [IPSEC]: Use ALIG... |
34 |
#include <linux/kernel.h> |
1da177e4c Linux-2.6.12-rc2 |
35 36 |
#include <linux/pfkeyv2.h> #include <linux/random.h> |
38320c70d [IPSEC]: Use cryp... |
37 |
#include <linux/slab.h> |
b7c6538cd [IPSEC]: Move sta... |
38 |
#include <linux/spinlock.h> |
81aded246 ipv6: Handle PMTU... |
39 |
#include <net/ip6_route.h> |
1da177e4c Linux-2.6.12-rc2 |
40 41 |
#include <net/icmp.h> #include <net/ipv6.h> |
14c850212 [INET_SOCK]: Move... |
42 |
#include <net/protocol.h> |
1da177e4c Linux-2.6.12-rc2 |
43 |
#include <linux/icmpv6.h> |
03e2a30f6 esp6: Avoid skb_c... |
44 |
#include <linux/highmem.h> |
38320c70d [IPSEC]: Use cryp... |
45 46 47 48 49 50 |
struct esp_skb_cb { struct xfrm_skb_cb xfrm; void *tmp; }; #define ESP_SKB_CB(__skb) ((struct esp_skb_cb *)&((__skb)->cb[0])) |
040253c93 xfrm: Traffic Flo... |
51 |
static u32 esp6_get_mtu(struct xfrm_state *x, int mtu); |
38320c70d [IPSEC]: Use cryp... |
52 53 54 |
/* * Allocate an AEAD request structure with extra space for SG and IV. * |
d212a4c29 esp6: Add support... |
55 56 57 |
* For alignment considerations the upper 32 bits of the sequence number are * placed at the front, if present. Followed by the IV, the request and finally * the SG list. |
38320c70d [IPSEC]: Use cryp... |
58 59 60 |
* * TODO: Use spare space in skb for this where possible. */ |
d212a4c29 esp6: Add support... |
61 |
static void *esp_alloc_tmp(struct crypto_aead *aead, int nfrags, int seqihlen) |
38320c70d [IPSEC]: Use cryp... |
62 63 |
{ unsigned int len; |
d212a4c29 esp6: Add support... |
64 65 66 |
len = seqihlen; len += crypto_aead_ivsize(aead); |
38320c70d [IPSEC]: Use cryp... |
67 68 69 70 71 |
if (len) { len += crypto_aead_alignmask(aead) & ~(crypto_tfm_ctx_alignment() - 1); len = ALIGN(len, crypto_tfm_ctx_alignment()); } |
000ae7b26 esp6: Switch to n... |
72 |
len += sizeof(struct aead_request) + crypto_aead_reqsize(aead); |
38320c70d [IPSEC]: Use cryp... |
73 74 75 76 77 78 |
len = ALIGN(len, __alignof__(struct scatterlist)); len += sizeof(struct scatterlist) * nfrags; return kmalloc(len, GFP_ATOMIC); } |
d212a4c29 esp6: Add support... |
79 80 81 82 83 84 |
static inline __be32 *esp_tmp_seqhi(void *tmp) { return PTR_ALIGN((__be32 *)tmp, __alignof__(__be32)); } static inline u8 *esp_tmp_iv(struct crypto_aead *aead, void *tmp, int seqhilen) |
38320c70d [IPSEC]: Use cryp... |
85 86 |
{ return crypto_aead_ivsize(aead) ? |
d212a4c29 esp6: Add support... |
87 88 |
PTR_ALIGN((u8 *)tmp + seqhilen, crypto_aead_alignmask(aead) + 1) : tmp + seqhilen; |
38320c70d [IPSEC]: Use cryp... |
89 |
} |
38320c70d [IPSEC]: Use cryp... |
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
static inline struct aead_request *esp_tmp_req(struct crypto_aead *aead, u8 *iv) { struct aead_request *req; req = (void *)PTR_ALIGN(iv + crypto_aead_ivsize(aead), crypto_tfm_ctx_alignment()); aead_request_set_tfm(req, aead); return req; } static inline struct scatterlist *esp_req_sg(struct crypto_aead *aead, struct aead_request *req) { return (void *)ALIGN((unsigned long)(req + 1) + crypto_aead_reqsize(aead), __alignof__(struct scatterlist)); } |
03e2a30f6 esp6: Avoid skb_c... |
107 108 |
static void esp_ssg_unref(struct xfrm_state *x, void *tmp) { |
03e2a30f6 esp6: Avoid skb_c... |
109 110 111 112 113 114 115 116 |
struct crypto_aead *aead = x->data; int seqhilen = 0; u8 *iv; struct aead_request *req; struct scatterlist *sg; if (x->props.flags & XFRM_STATE_ESN) seqhilen += sizeof(__be32); |
03e2a30f6 esp6: Avoid skb_c... |
117 118 119 120 121 122 123 124 125 126 |
iv = esp_tmp_iv(aead, tmp, seqhilen); req = esp_tmp_req(aead, iv); /* Unref skb_frag_pages in the src scatterlist if necessary. * Skip the first sg which comes from skb->data. */ if (req->src != req->dst) for (sg = sg_next(req->src); sg; sg = sg_next(sg)) put_page(sg_page(sg)); } |
38320c70d [IPSEC]: Use cryp... |
127 128 129 |
static void esp_output_done(struct crypto_async_request *base, int err) { struct sk_buff *skb = base->data; |
03e2a30f6 esp6: Avoid skb_c... |
130 131 132 |
void *tmp; struct dst_entry *dst = skb_dst(skb); struct xfrm_state *x = dst->xfrm; |
38320c70d [IPSEC]: Use cryp... |
133 |
|
03e2a30f6 esp6: Avoid skb_c... |
134 135 136 |
tmp = ESP_SKB_CB(skb)->tmp; esp_ssg_unref(x, tmp); kfree(tmp); |
38320c70d [IPSEC]: Use cryp... |
137 138 |
xfrm_output_resume(skb, err); } |
000ae7b26 esp6: Switch to n... |
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
/* Move ESP header back into place. */ static void esp_restore_header(struct sk_buff *skb, unsigned int offset) { struct ip_esp_hdr *esph = (void *)(skb->data + offset); void *tmp = ESP_SKB_CB(skb)->tmp; __be32 *seqhi = esp_tmp_seqhi(tmp); esph->seq_no = esph->spi; esph->spi = *seqhi; } static void esp_output_restore_header(struct sk_buff *skb) { esp_restore_header(skb, skb_transport_offset(skb) - sizeof(__be32)); } |
03e2a30f6 esp6: Avoid skb_c... |
154 |
static struct ip_esp_hdr *esp_output_set_esn(struct sk_buff *skb, |
383d0350f esp6: Reorganize ... |
155 |
struct xfrm_state *x, |
03e2a30f6 esp6: Avoid skb_c... |
156 157 158 |
struct ip_esp_hdr *esph, __be32 *seqhi) { |
03e2a30f6 esp6: Avoid skb_c... |
159 160 161 162 163 |
/* For ESN we move the header forward by 4 bytes to * accomodate the high bits. We will move it back after * encryption. */ if ((x->props.flags & XFRM_STATE_ESN)) { |
7862b4058 esp: Add gso hand... |
164 |
struct xfrm_offload *xo = xfrm_offload(skb); |
03e2a30f6 esp6: Avoid skb_c... |
165 166 |
esph = (void *)(skb_transport_header(skb) - sizeof(__be32)); *seqhi = esph->spi; |
7862b4058 esp: Add gso hand... |
167 168 169 170 |
if (xo) esph->seq_no = htonl(xo->seq.hi); else esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq.output.hi); |
03e2a30f6 esp6: Avoid skb_c... |
171 172 173 174 175 176 |
} esph->spi = x->id.spi; return esph; } |
000ae7b26 esp6: Switch to n... |
177 178 179 180 181 182 183 |
static void esp_output_done_esn(struct crypto_async_request *base, int err) { struct sk_buff *skb = base->data; esp_output_restore_header(skb); esp_output_done(base, err); } |
eb758c886 esp: Introduce a ... |
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 |
static void esp_output_fill_trailer(u8 *tail, int tfclen, int plen, __u8 proto) { /* Fill padding... */ if (tfclen) { memset(tail, 0, tfclen); tail += tfclen; } do { int i; for (i = 0; i < plen - 2; i++) tail[i] = i + 1; } while (0); tail[plen - 2] = plen - 2; tail[plen - 1] = proto; } |
383d0350f esp6: Reorganize ... |
199 |
int esp6_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *esp) |
1da177e4c Linux-2.6.12-rc2 |
200 |
{ |
27a884dc3 [SK_BUFF]: Conver... |
201 |
u8 *tail; |
03e2a30f6 esp6: Avoid skb_c... |
202 |
u8 *vaddr; |
383d0350f esp6: Reorganize ... |
203 204 |
int nfrags; struct page *page; |
383d0350f esp6: Reorganize ... |
205 206 |
struct sk_buff *trailer; int tailen = esp->tailen; |
d212a4c29 esp6: Add support... |
207 |
|
03e2a30f6 esp6: Avoid skb_c... |
208 |
if (!skb_cloned(skb)) { |
54ffd7907 esp: Fix skb tail... |
209 |
if (tailen <= skb_tailroom(skb)) { |
03e2a30f6 esp6: Avoid skb_c... |
210 211 212 213 214 215 216 217 218 219 |
nfrags = 1; trailer = skb; tail = skb_tail_pointer(trailer); goto skip_cow; } else if ((skb_shinfo(skb)->nr_frags < MAX_SKB_FRAGS) && !skb_has_frag_list(skb)) { int allocsize; struct sock *sk = skb->sk; struct page_frag *pfrag = &x->xfrag; |
383d0350f esp6: Reorganize ... |
220 |
esp->inplace = false; |
03e2a30f6 esp6: Avoid skb_c... |
221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 |
allocsize = ALIGN(tailen, L1_CACHE_BYTES); spin_lock_bh(&x->lock); if (unlikely(!skb_page_frag_refill(allocsize, pfrag, GFP_ATOMIC))) { spin_unlock_bh(&x->lock); goto cow; } page = pfrag->page; get_page(page); vaddr = kmap_atomic(page); tail = vaddr + pfrag->offset; |
383d0350f esp6: Reorganize ... |
236 |
esp_output_fill_trailer(tail, esp->tfclen, esp->plen, esp->proto); |
03e2a30f6 esp6: Avoid skb_c... |
237 238 239 240 241 242 243 244 245 246 |
kunmap_atomic(vaddr); nfrags = skb_shinfo(skb)->nr_frags; __skb_fill_page_desc(skb, nfrags, page, pfrag->offset, tailen); skb_shinfo(skb)->nr_frags = ++nfrags; pfrag->offset = pfrag->offset + allocsize; |
36ff0dd39 esp: Fix locking ... |
247 248 |
spin_unlock_bh(&x->lock); |
03e2a30f6 esp6: Avoid skb_c... |
249 250 251 252 253 254 |
nfrags++; skb->len += tailen; skb->data_len += tailen; skb->truesize += tailen; if (sk) |
14afee4b6 net: convert sock... |
255 |
refcount_add(tailen, &sk->sk_wmem_alloc); |
03e2a30f6 esp6: Avoid skb_c... |
256 |
|
383d0350f esp6: Reorganize ... |
257 |
goto out; |
03e2a30f6 esp6: Avoid skb_c... |
258 |
} |
48f125ce1 net: ipv6: fix er... |
259 |
} |
38320c70d [IPSEC]: Use cryp... |
260 |
|
03e2a30f6 esp6: Avoid skb_c... |
261 |
cow: |
383d0350f esp6: Reorganize ... |
262 263 264 |
nfrags = skb_cow_data(skb, tailen, &trailer); if (nfrags < 0) goto out; |
27a884dc3 [SK_BUFF]: Conver... |
265 |
tail = skb_tail_pointer(trailer); |
03e2a30f6 esp6: Avoid skb_c... |
266 267 |
skip_cow: |
383d0350f esp6: Reorganize ... |
268 269 |
esp_output_fill_trailer(tail, esp->tfclen, esp->plen, esp->proto); pskb_put(skb, trailer, tailen); |
1da177e4c Linux-2.6.12-rc2 |
270 |
|
383d0350f esp6: Reorganize ... |
271 272 273 274 |
out: return nfrags; } EXPORT_SYMBOL_GPL(esp6_output_head); |
1da177e4c Linux-2.6.12-rc2 |
275 |
|
383d0350f esp6: Reorganize ... |
276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 |
int esp6_output_tail(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *esp) { u8 *iv; int alen; void *tmp; int ivlen; int assoclen; int seqhilen; __be32 *seqhi; struct page *page; struct ip_esp_hdr *esph; struct aead_request *req; struct crypto_aead *aead; struct scatterlist *sg, *dsg; int err = -ENOMEM; assoclen = sizeof(struct ip_esp_hdr); seqhilen = 0; if (x->props.flags & XFRM_STATE_ESN) { seqhilen += sizeof(__be32); assoclen += sizeof(__be32); } |
1da177e4c Linux-2.6.12-rc2 |
299 |
|
383d0350f esp6: Reorganize ... |
300 301 302 303 304 |
aead = x->data; alen = crypto_aead_authsize(aead); ivlen = crypto_aead_ivsize(aead); tmp = esp_alloc_tmp(aead, esp->nfrags + 2, seqhilen); |
e892d2d40 esp: Fix misplace... |
305 |
if (!tmp) |
03e2a30f6 esp6: Avoid skb_c... |
306 |
goto error; |
000ae7b26 esp6: Switch to n... |
307 |
|
03e2a30f6 esp6: Avoid skb_c... |
308 309 310 311 |
seqhi = esp_tmp_seqhi(tmp); iv = esp_tmp_iv(aead, tmp, seqhilen); req = esp_tmp_req(aead, iv); sg = esp_req_sg(aead, req); |
03e2a30f6 esp6: Avoid skb_c... |
312 |
|
383d0350f esp6: Reorganize ... |
313 314 315 316 317 318 |
if (esp->inplace) dsg = sg; else dsg = &sg[esp->nfrags]; esph = esp_output_set_esn(skb, x, ip_esp_hdr(skb), seqhi); |
000ae7b26 esp6: Switch to n... |
319 |
|
383d0350f esp6: Reorganize ... |
320 |
sg_init_table(sg, esp->nfrags); |
3f2977072 ipsec: check retu... |
321 322 323 324 |
err = skb_to_sgvec(skb, sg, (unsigned char *)esph - skb->data, assoclen + ivlen + esp->clen + alen); if (unlikely(err < 0)) |
e61949232 esp: Fix memleaks... |
325 |
goto error_free; |
383d0350f esp6: Reorganize ... |
326 327 328 329 330 331 332 333 334 335 |
if (!esp->inplace) { int allocsize; struct page_frag *pfrag = &x->xfrag; allocsize = ALIGN(skb->data_len, L1_CACHE_BYTES); spin_lock_bh(&x->lock); if (unlikely(!skb_page_frag_refill(allocsize, pfrag, GFP_ATOMIC))) { spin_unlock_bh(&x->lock); |
e61949232 esp: Fix memleaks... |
336 |
goto error_free; |
383d0350f esp6: Reorganize ... |
337 338 339 340 341 342 343 344 345 346 347 348 |
} skb_shinfo(skb)->nr_frags = 1; page = pfrag->page; get_page(page); /* replace page frags in skb with new page */ __skb_fill_page_desc(skb, 0, page, pfrag->offset, skb->data_len); pfrag->offset = pfrag->offset + allocsize; spin_unlock_bh(&x->lock); sg_init_table(dsg, skb_shinfo(skb)->nr_frags + 1); |
3f2977072 ipsec: check retu... |
349 350 351 352 |
err = skb_to_sgvec(skb, dsg, (unsigned char *)esph - skb->data, assoclen + ivlen + esp->clen + alen); if (unlikely(err < 0)) |
e61949232 esp: Fix memleaks... |
353 |
goto error_free; |
383d0350f esp6: Reorganize ... |
354 |
} |
d212a4c29 esp6: Add support... |
355 |
|
03e2a30f6 esp6: Avoid skb_c... |
356 357 358 359 |
if ((x->props.flags & XFRM_STATE_ESN)) aead_request_set_callback(req, 0, esp_output_done_esn, skb); else aead_request_set_callback(req, 0, esp_output_done, skb); |
383d0350f esp6: Reorganize ... |
360 |
aead_request_set_crypt(req, sg, dsg, ivlen + esp->clen, iv); |
000ae7b26 esp6: Switch to n... |
361 |
aead_request_set_ad(req, assoclen); |
000ae7b26 esp6: Switch to n... |
362 |
memset(iv, 0, ivlen); |
383d0350f esp6: Reorganize ... |
363 |
memcpy(iv + ivlen - min(ivlen, 8), (u8 *)&esp->seqno + 8 - min(ivlen, 8), |
000ae7b26 esp6: Switch to n... |
364 |
min(ivlen, 8)); |
1da177e4c Linux-2.6.12-rc2 |
365 |
|
38320c70d [IPSEC]: Use cryp... |
366 |
ESP_SKB_CB(skb)->tmp = tmp; |
000ae7b26 esp6: Switch to n... |
367 368 369 370 |
err = crypto_aead_encrypt(req); switch (err) { case -EINPROGRESS: |
38320c70d [IPSEC]: Use cryp... |
371 |
goto error; |
1da177e4c Linux-2.6.12-rc2 |
372 |
|
000ae7b26 esp6: Switch to n... |
373 |
case -EBUSY: |
38320c70d [IPSEC]: Use cryp... |
374 |
err = NET_XMIT_DROP; |
000ae7b26 esp6: Switch to n... |
375 376 377 378 379 380 |
break; case 0: if ((x->props.flags & XFRM_STATE_ESN)) esp_output_restore_header(skb); } |
38320c70d [IPSEC]: Use cryp... |
381 |
|
03e2a30f6 esp6: Avoid skb_c... |
382 383 |
if (sg != dsg) esp_ssg_unref(x, tmp); |
38320c70d [IPSEC]: Use cryp... |
384 |
|
e61949232 esp: Fix memleaks... |
385 386 |
error_free: kfree(tmp); |
38320c70d [IPSEC]: Use cryp... |
387 388 389 |
error: return err; } |
383d0350f esp6: Reorganize ... |
390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 |
EXPORT_SYMBOL_GPL(esp6_output_tail); static int esp6_output(struct xfrm_state *x, struct sk_buff *skb) { int alen; int blksize; struct ip_esp_hdr *esph; struct crypto_aead *aead; struct esp_info esp; esp.inplace = true; esp.proto = *skb_mac_header(skb); *skb_mac_header(skb) = IPPROTO_ESP; /* skb is pure payload to encrypt */ aead = x->data; alen = crypto_aead_authsize(aead); esp.tfclen = 0; if (x->tfcpad) { struct xfrm_dst *dst = (struct xfrm_dst *)skb_dst(skb); u32 padto; padto = min(x->tfcpad, esp6_get_mtu(x, dst->child_mtu_cached)); if (skb->len < padto) esp.tfclen = padto - skb->len; } blksize = ALIGN(crypto_aead_blocksize(aead), 4); esp.clen = ALIGN(skb->len + 2 + esp.tfclen, blksize); esp.plen = esp.clen - skb->len - esp.tfclen; esp.tailen = esp.tfclen + esp.plen + alen; esp.nfrags = esp6_output_head(x, skb, &esp); if (esp.nfrags < 0) return esp.nfrags; esph = ip_esp_hdr(skb); esph->spi = x->id.spi; esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq.output.low); esp.seqno = cpu_to_be64(XFRM_SKB_CB(skb)->seq.output.low + ((u64)XFRM_SKB_CB(skb)->seq.output.hi << 32)); skb_push(skb, -skb_network_offset(skb)); return esp6_output_tail(x, skb, &esp); } |
38320c70d [IPSEC]: Use cryp... |
439 |
|
47ebcc0bb xfrm: Add support... |
440 |
static inline int esp_remove_trailer(struct sk_buff *skb) |
38320c70d [IPSEC]: Use cryp... |
441 442 |
{ struct xfrm_state *x = xfrm_input_state(skb); |
d77e38e61 xfrm: Add an IPse... |
443 |
struct xfrm_offload *xo = xfrm_offload(skb); |
1c5ad13f7 net: esp{4,6}: ge... |
444 |
struct crypto_aead *aead = x->data; |
47ebcc0bb xfrm: Add support... |
445 |
int alen, hlen, elen; |
e51a64727 esp6: Support RX ... |
446 447 |
int padlen, trimlen; __wsum csumdiff; |
38320c70d [IPSEC]: Use cryp... |
448 |
u8 nexthdr[2]; |
47ebcc0bb xfrm: Add support... |
449 |
int ret; |
38320c70d [IPSEC]: Use cryp... |
450 |
|
47ebcc0bb xfrm: Add support... |
451 452 453 |
alen = crypto_aead_authsize(aead); hlen = sizeof(struct ip_esp_hdr) + crypto_aead_ivsize(aead); elen = skb->len - hlen; |
1da177e4c Linux-2.6.12-rc2 |
454 |
|
47ebcc0bb xfrm: Add support... |
455 456 |
if (xo && (xo->flags & XFRM_ESP_NO_TRAILER)) { ret = xo->proto; |
38320c70d [IPSEC]: Use cryp... |
457 |
goto out; |
47ebcc0bb xfrm: Add support... |
458 |
} |
6b7326c84 [IPSEC] ESP: Use ... |
459 |
|
38320c70d [IPSEC]: Use cryp... |
460 461 |
if (skb_copy_bits(skb, skb->len - alen - 2, nexthdr, 2)) BUG(); |
1da177e4c Linux-2.6.12-rc2 |
462 |
|
47ebcc0bb xfrm: Add support... |
463 |
ret = -EINVAL; |
38320c70d [IPSEC]: Use cryp... |
464 465 |
padlen = nexthdr[0]; if (padlen + 2 + alen >= elen) { |
ba7a46f16 net: Convert LIMI... |
466 467 468 |
net_dbg_ratelimited("ipsec esp packet is garbage padlen=%d, elen=%d ", padlen + 2, elen - alen); |
38320c70d [IPSEC]: Use cryp... |
469 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
470 |
} |
e51a64727 esp6: Support RX ... |
471 472 473 474 475 476 477 |
trimlen = alen + padlen + 2; if (skb->ip_summed == CHECKSUM_COMPLETE) { csumdiff = skb_checksum(skb, skb->len - trimlen, trimlen, 0); skb->csum = csum_block_sub(skb->csum, csumdiff, skb->len - trimlen); } pskb_trim(skb, skb->len - trimlen); |
47ebcc0bb xfrm: Add support... |
478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 |
ret = nexthdr[1]; out: return ret; } int esp6_input_done2(struct sk_buff *skb, int err) { struct xfrm_state *x = xfrm_input_state(skb); struct xfrm_offload *xo = xfrm_offload(skb); struct crypto_aead *aead = x->data; int hlen = sizeof(struct ip_esp_hdr) + crypto_aead_ivsize(aead); int hdr_len = skb_network_header_len(skb); if (!xo || (xo && !(xo->flags & CRYPTO_DONE))) kfree(ESP_SKB_CB(skb)->tmp); if (unlikely(err)) goto out; err = esp_remove_trailer(skb); if (unlikely(err < 0)) goto out; skb_postpull_rcsum(skb, skb_network_header(skb), skb_network_header_len(skb)); |
e51a64727 esp6: Support RX ... |
504 |
skb_pull_rcsum(skb, hlen); |
a9403f8ae ah6/esp6: set tra... |
505 506 507 508 |
if (x->props.mode == XFRM_MODE_TUNNEL) skb_reset_transport_header(skb); else skb_set_transport_header(skb, -hdr_len); |
38320c70d [IPSEC]: Use cryp... |
509 |
|
38320c70d [IPSEC]: Use cryp... |
510 511 512 513 514 |
/* RFC4303: Drop dummy packets without any error */ if (err == IPPROTO_NONE) err = -EINVAL; out: |
1da177e4c Linux-2.6.12-rc2 |
515 516 |
return err; } |
383d0350f esp6: Reorganize ... |
517 |
EXPORT_SYMBOL_GPL(esp6_input_done2); |
1da177e4c Linux-2.6.12-rc2 |
518 |
|
38320c70d [IPSEC]: Use cryp... |
519 520 521 |
static void esp_input_done(struct crypto_async_request *base, int err) { struct sk_buff *skb = base->data; |
f1fbed0e8 esp6: Remame esp_... |
522 |
xfrm_input_resume(skb, esp6_input_done2(skb, err)); |
38320c70d [IPSEC]: Use cryp... |
523 |
} |
000ae7b26 esp6: Switch to n... |
524 525 526 527 528 |
static void esp_input_restore_header(struct sk_buff *skb) { esp_restore_header(skb, 0); __skb_pull(skb, 4); } |
03e2a30f6 esp6: Avoid skb_c... |
529 530 531 532 533 534 535 536 537 538 |
static void esp_input_set_header(struct sk_buff *skb, __be32 *seqhi) { struct xfrm_state *x = xfrm_input_state(skb); struct ip_esp_hdr *esph = (struct ip_esp_hdr *)skb->data; /* For ESN we move the header forward by 4 bytes to * accomodate the high bits. We will move it back after * decryption. */ if ((x->props.flags & XFRM_STATE_ESN)) { |
d58ff3512 networking: make ... |
539 |
esph = skb_push(skb, 4); |
03e2a30f6 esp6: Avoid skb_c... |
540 541 542 543 544 |
*seqhi = esph->spi; esph->spi = esph->seq_no; esph->seq_no = XFRM_SKB_CB(skb)->seq.input.hi; } } |
000ae7b26 esp6: Switch to n... |
545 546 547 548 549 550 551 |
static void esp_input_done_esn(struct crypto_async_request *base, int err) { struct sk_buff *skb = base->data; esp_input_restore_header(skb); esp_input_done(base, err); } |
e695633e2 [IPSEC]: Kill unu... |
552 |
static int esp6_input(struct xfrm_state *x, struct sk_buff *skb) |
1da177e4c Linux-2.6.12-rc2 |
553 |
{ |
87bdc48d3 [IPSEC]: Get rid ... |
554 |
struct ip_esp_hdr *esph; |
1c5ad13f7 net: esp{4,6}: ge... |
555 |
struct crypto_aead *aead = x->data; |
38320c70d [IPSEC]: Use cryp... |
556 |
struct aead_request *req; |
1da177e4c Linux-2.6.12-rc2 |
557 |
struct sk_buff *trailer; |
000ae7b26 esp6: Switch to n... |
558 559 |
int ivlen = crypto_aead_ivsize(aead); int elen = skb->len - sizeof(*esph) - ivlen; |
1da177e4c Linux-2.6.12-rc2 |
560 |
int nfrags; |
d212a4c29 esp6: Add support... |
561 |
int assoclen; |
d212a4c29 esp6: Add support... |
562 |
int seqhilen; |
1da177e4c Linux-2.6.12-rc2 |
563 |
int ret = 0; |
38320c70d [IPSEC]: Use cryp... |
564 |
void *tmp; |
d212a4c29 esp6: Add support... |
565 |
__be32 *seqhi; |
38320c70d [IPSEC]: Use cryp... |
566 567 |
u8 *iv; struct scatterlist *sg; |
1da177e4c Linux-2.6.12-rc2 |
568 |
|
000ae7b26 esp6: Switch to n... |
569 |
if (!pskb_may_pull(skb, sizeof(*esph) + ivlen)) { |
1da177e4c Linux-2.6.12-rc2 |
570 |
ret = -EINVAL; |
31a4ab930 [IPSEC] proto: Mo... |
571 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
572 |
} |
38320c70d [IPSEC]: Use cryp... |
573 |
if (elen <= 0) { |
1da177e4c Linux-2.6.12-rc2 |
574 |
ret = -EINVAL; |
31a4ab930 [IPSEC] proto: Mo... |
575 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
576 |
} |
1da177e4c Linux-2.6.12-rc2 |
577 |
|
d212a4c29 esp6: Add support... |
578 |
assoclen = sizeof(*esph); |
d212a4c29 esp6: Add support... |
579 580 581 |
seqhilen = 0; if (x->props.flags & XFRM_STATE_ESN) { |
d212a4c29 esp6: Add support... |
582 583 584 |
seqhilen += sizeof(__be32); assoclen += seqhilen; } |
03e2a30f6 esp6: Avoid skb_c... |
585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 |
if (!skb_cloned(skb)) { if (!skb_is_nonlinear(skb)) { nfrags = 1; goto skip_cow; } else if (!skb_has_frag_list(skb)) { nfrags = skb_shinfo(skb)->nr_frags; nfrags++; goto skip_cow; } } nfrags = skb_cow_data(skb, 0, &trailer); if (nfrags < 0) { ret = -EINVAL; goto out; } skip_cow: ret = -ENOMEM; |
000ae7b26 esp6: Switch to n... |
606 |
tmp = esp_alloc_tmp(aead, nfrags, seqhilen); |
38320c70d [IPSEC]: Use cryp... |
607 608 |
if (!tmp) goto out; |
1da177e4c Linux-2.6.12-rc2 |
609 |
|
38320c70d [IPSEC]: Use cryp... |
610 |
ESP_SKB_CB(skb)->tmp = tmp; |
d212a4c29 esp6: Add support... |
611 612 |
seqhi = esp_tmp_seqhi(tmp); iv = esp_tmp_iv(aead, tmp, seqhilen); |
38320c70d [IPSEC]: Use cryp... |
613 |
req = esp_tmp_req(aead, iv); |
000ae7b26 esp6: Switch to n... |
614 |
sg = esp_req_sg(aead, req); |
1da177e4c Linux-2.6.12-rc2 |
615 |
|
03e2a30f6 esp6: Avoid skb_c... |
616 |
esp_input_set_header(skb, seqhi); |
1da177e4c Linux-2.6.12-rc2 |
617 |
|
03e2a30f6 esp6: Avoid skb_c... |
618 |
sg_init_table(sg, nfrags); |
3f2977072 ipsec: check retu... |
619 |
ret = skb_to_sgvec(skb, sg, 0, skb->len); |
b6f147a2d esp6: fix memleak... |
620 621 |
if (unlikely(ret < 0)) { kfree(tmp); |
3f2977072 ipsec: check retu... |
622 |
goto out; |
b6f147a2d esp6: fix memleak... |
623 |
} |
1da177e4c Linux-2.6.12-rc2 |
624 |
|
03e2a30f6 esp6: Avoid skb_c... |
625 |
skb->ip_summed = CHECKSUM_NONE; |
d212a4c29 esp6: Add support... |
626 |
|
03e2a30f6 esp6: Avoid skb_c... |
627 |
if ((x->props.flags & XFRM_STATE_ESN)) |
000ae7b26 esp6: Switch to n... |
628 |
aead_request_set_callback(req, 0, esp_input_done_esn, skb); |
03e2a30f6 esp6: Avoid skb_c... |
629 630 |
else aead_request_set_callback(req, 0, esp_input_done, skb); |
000ae7b26 esp6: Switch to n... |
631 632 633 |
aead_request_set_crypt(req, sg, sg, elen + ivlen, iv); aead_request_set_ad(req, assoclen); |
1da177e4c Linux-2.6.12-rc2 |
634 |
|
38320c70d [IPSEC]: Use cryp... |
635 636 637 |
ret = crypto_aead_decrypt(req); if (ret == -EINPROGRESS) goto out; |
95a02cfd4 [IPv6] ESP: Disca... |
638 |
|
000ae7b26 esp6: Switch to n... |
639 640 |
if ((x->props.flags & XFRM_STATE_ESN)) esp_input_restore_header(skb); |
f1fbed0e8 esp6: Remame esp_... |
641 |
ret = esp6_input_done2(skb, ret); |
1da177e4c Linux-2.6.12-rc2 |
642 643 |
out: |
1da177e4c Linux-2.6.12-rc2 |
644 645 |
return ret; } |
c5c252389 [XFRM]: Optimize ... |
646 |
static u32 esp6_get_mtu(struct xfrm_state *x, int mtu) |
1da177e4c Linux-2.6.12-rc2 |
647 |
{ |
1c5ad13f7 net: esp{4,6}: ge... |
648 649 |
struct crypto_aead *aead = x->data; u32 blksize = ALIGN(crypto_aead_blocksize(aead), 4); |
91657eafb xfrm: take net hd... |
650 |
unsigned int net_adj; |
1da177e4c Linux-2.6.12-rc2 |
651 |
|
91657eafb xfrm: take net hd... |
652 653 654 655 |
if (x->props.mode != XFRM_MODE_TUNNEL) net_adj = sizeof(struct ipv6hdr); else net_adj = 0; |
c5c252389 [XFRM]: Optimize ... |
656 |
|
1c5ad13f7 net: esp{4,6}: ge... |
657 |
return ((mtu - x->props.header_len - crypto_aead_authsize(aead) - |
123b0d1ba net: esp{4,6}: re... |
658 |
net_adj) & ~(blksize - 1)) + net_adj - 2; |
1da177e4c Linux-2.6.12-rc2 |
659 |
} |
d5860c5cc esp6: Use the IPs... |
660 661 |
static int esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, u8 type, u8 code, int offset, __be32 info) |
1da177e4c Linux-2.6.12-rc2 |
662 |
{ |
4fb236bac netns xfrm: AH/ES... |
663 |
struct net *net = dev_net(skb->dev); |
b71d1d426 inet: constify ip... |
664 |
const struct ipv6hdr *iph = (const struct ipv6hdr *)skb->data; |
87bdc48d3 [IPSEC]: Get rid ... |
665 |
struct ip_esp_hdr *esph = (struct ip_esp_hdr *)(skb->data + offset); |
1da177e4c Linux-2.6.12-rc2 |
666 |
struct xfrm_state *x; |
b3b2b9e19 ipsec: Don't upda... |
667 |
if (type != ICMPV6_PKT_TOOBIG && |
ec18d9a26 ipv6: Add redirec... |
668 |
type != NDISC_REDIRECT) |
d5860c5cc esp6: Use the IPs... |
669 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
670 |
|
b71d1d426 inet: constify ip... |
671 672 |
x = xfrm_state_lookup(net, skb->mark, (const xfrm_address_t *)&iph->daddr, esph->spi, IPPROTO_ESP, AF_INET6); |
1da177e4c Linux-2.6.12-rc2 |
673 |
if (!x) |
d5860c5cc esp6: Use the IPs... |
674 |
return 0; |
ec18d9a26 ipv6: Add redirec... |
675 676 |
if (type == NDISC_REDIRECT) |
e2d118a1c net: inet: Suppor... |
677 678 |
ip6_redirect(skb, net, skb->dev->ifindex, 0, sock_net_uid(net, NULL)); |
ec18d9a26 ipv6: Add redirec... |
679 |
else |
e2d118a1c net: inet: Suppor... |
680 |
ip6_update_pmtu(skb, net, info, 0, 0, sock_net_uid(net, NULL)); |
1da177e4c Linux-2.6.12-rc2 |
681 |
xfrm_state_put(x); |
d5860c5cc esp6: Use the IPs... |
682 683 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
684 685 686 687 |
} static void esp6_destroy(struct xfrm_state *x) { |
1c5ad13f7 net: esp{4,6}: ge... |
688 |
struct crypto_aead *aead = x->data; |
1da177e4c Linux-2.6.12-rc2 |
689 |
|
1c5ad13f7 net: esp{4,6}: ge... |
690 |
if (!aead) |
1da177e4c Linux-2.6.12-rc2 |
691 |
return; |
1c5ad13f7 net: esp{4,6}: ge... |
692 |
crypto_free_aead(aead); |
1da177e4c Linux-2.6.12-rc2 |
693 |
} |
1a6509d99 [IPSEC]: Add supp... |
694 695 |
static int esp_init_aead(struct xfrm_state *x) { |
000ae7b26 esp6: Switch to n... |
696 |
char aead_name[CRYPTO_MAX_ALG_NAME]; |
1a6509d99 [IPSEC]: Add supp... |
697 698 |
struct crypto_aead *aead; int err; |
b3859c8eb esp: Use a synchr... |
699 |
u32 mask = 0; |
1a6509d99 [IPSEC]: Add supp... |
700 |
|
000ae7b26 esp6: Switch to n... |
701 702 703 704 |
err = -ENAMETOOLONG; if (snprintf(aead_name, CRYPTO_MAX_ALG_NAME, "%s(%s)", x->geniv, x->aead->alg_name) >= CRYPTO_MAX_ALG_NAME) goto error; |
b3859c8eb esp: Use a synchr... |
705 706 707 708 |
if (x->xso.offload_handle) mask |= CRYPTO_ALG_ASYNC; aead = crypto_alloc_aead(aead_name, 0, mask); |
1a6509d99 [IPSEC]: Add supp... |
709 710 711 |
err = PTR_ERR(aead); if (IS_ERR(aead)) goto error; |
1c5ad13f7 net: esp{4,6}: ge... |
712 |
x->data = aead; |
1a6509d99 [IPSEC]: Add supp... |
713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 |
err = crypto_aead_setkey(aead, x->aead->alg_key, (x->aead->alg_key_len + 7) / 8); if (err) goto error; err = crypto_aead_setauthsize(aead, x->aead->alg_icv_len / 8); if (err) goto error; error: return err; } static int esp_init_authenc(struct xfrm_state *x) |
1da177e4c Linux-2.6.12-rc2 |
728 |
{ |
38320c70d [IPSEC]: Use cryp... |
729 730 731 732 733 734 |
struct crypto_aead *aead; struct crypto_authenc_key_param *param; struct rtattr *rta; char *key; char *p; char authenc_name[CRYPTO_MAX_ALG_NAME]; |
38320c70d [IPSEC]: Use cryp... |
735 736 |
unsigned int keylen; int err; |
b3859c8eb esp: Use a synchr... |
737 |
u32 mask = 0; |
1da177e4c Linux-2.6.12-rc2 |
738 |
|
1a6509d99 [IPSEC]: Add supp... |
739 |
err = -EINVAL; |
63159f29b ipv6: coding styl... |
740 |
if (!x->ealg) |
1a6509d99 [IPSEC]: Add supp... |
741 |
goto error; |
38320c70d [IPSEC]: Use cryp... |
742 |
|
1a6509d99 [IPSEC]: Add supp... |
743 |
err = -ENAMETOOLONG; |
d212a4c29 esp6: Add support... |
744 745 746 |
if ((x->props.flags & XFRM_STATE_ESN)) { if (snprintf(authenc_name, CRYPTO_MAX_ALG_NAME, |
000ae7b26 esp6: Switch to n... |
747 748 |
"%s%sauthencesn(%s,%s)%s", x->geniv ?: "", x->geniv ? "(" : "", |
d212a4c29 esp6: Add support... |
749 |
x->aalg ? x->aalg->alg_name : "digest_null", |
000ae7b26 esp6: Switch to n... |
750 751 |
x->ealg->alg_name, x->geniv ? ")" : "") >= CRYPTO_MAX_ALG_NAME) |
d212a4c29 esp6: Add support... |
752 753 754 |
goto error; } else { if (snprintf(authenc_name, CRYPTO_MAX_ALG_NAME, |
000ae7b26 esp6: Switch to n... |
755 756 |
"%s%sauthenc(%s,%s)%s", x->geniv ?: "", x->geniv ? "(" : "", |
d212a4c29 esp6: Add support... |
757 |
x->aalg ? x->aalg->alg_name : "digest_null", |
000ae7b26 esp6: Switch to n... |
758 759 |
x->ealg->alg_name, x->geniv ? ")" : "") >= CRYPTO_MAX_ALG_NAME) |
d212a4c29 esp6: Add support... |
760 761 |
goto error; } |
38320c70d [IPSEC]: Use cryp... |
762 |
|
b3859c8eb esp: Use a synchr... |
763 764 765 766 |
if (x->xso.offload_handle) mask |= CRYPTO_ALG_ASYNC; aead = crypto_alloc_aead(authenc_name, 0, mask); |
38320c70d [IPSEC]: Use cryp... |
767 768 769 |
err = PTR_ERR(aead); if (IS_ERR(aead)) goto error; |
1c5ad13f7 net: esp{4,6}: ge... |
770 |
x->data = aead; |
38320c70d [IPSEC]: Use cryp... |
771 772 773 774 775 776 777 778 779 780 781 782 783 784 |
keylen = (x->aalg ? (x->aalg->alg_key_len + 7) / 8 : 0) + (x->ealg->alg_key_len + 7) / 8 + RTA_SPACE(sizeof(*param)); err = -ENOMEM; key = kmalloc(keylen, GFP_KERNEL); if (!key) goto error; p = key; rta = (void *)p; rta->rta_type = CRYPTO_AUTHENC_KEYA_PARAM; rta->rta_len = RTA_LENGTH(sizeof(*param)); param = RTA_DATA(rta); p += RTA_SPACE(sizeof(*param)); |
1da177e4c Linux-2.6.12-rc2 |
785 786 |
if (x->aalg) { struct xfrm_algo_desc *aalg_desc; |
38320c70d [IPSEC]: Use cryp... |
787 788 |
memcpy(p, x->aalg->alg_key, (x->aalg->alg_key_len + 7) / 8); p += (x->aalg->alg_key_len + 7) / 8; |
1ab1457c4 [NET] IPV6: Fix w... |
789 |
|
1da177e4c Linux-2.6.12-rc2 |
790 791 |
aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name, 0); BUG_ON(!aalg_desc); |
1ab1457c4 [NET] IPV6: Fix w... |
792 |
|
38320c70d [IPSEC]: Use cryp... |
793 |
err = -EINVAL; |
450834977 net: esp: Convert... |
794 |
if (aalg_desc->uinfo.auth.icv_fullbits / 8 != |
38320c70d [IPSEC]: Use cryp... |
795 |
crypto_aead_authsize(aead)) { |
450834977 net: esp: Convert... |
796 797 798 799 800 |
pr_info("ESP: %s digestsize %u != %hu ", x->aalg->alg_name, crypto_aead_authsize(aead), aalg_desc->uinfo.auth.icv_fullbits / 8); |
38320c70d [IPSEC]: Use cryp... |
801 |
goto free_key; |
1da177e4c Linux-2.6.12-rc2 |
802 |
} |
1ab1457c4 [NET] IPV6: Fix w... |
803 |
|
38320c70d [IPSEC]: Use cryp... |
804 |
err = crypto_aead_setauthsize( |
8f8a088c2 xfrm: Use the use... |
805 |
aead, x->aalg->alg_trunc_len / 8); |
38320c70d [IPSEC]: Use cryp... |
806 807 |
if (err) goto free_key; |
1da177e4c Linux-2.6.12-rc2 |
808 |
} |
38320c70d [IPSEC]: Use cryp... |
809 |
|
38320c70d [IPSEC]: Use cryp... |
810 811 812 813 814 815 816 |
param->enckeylen = cpu_to_be32((x->ealg->alg_key_len + 7) / 8); memcpy(p, x->ealg->alg_key, (x->ealg->alg_key_len + 7) / 8); err = crypto_aead_setkey(aead, key, keylen); free_key: kfree(key); |
1a6509d99 [IPSEC]: Add supp... |
817 818 819 820 821 822 |
error: return err; } static int esp6_init_state(struct xfrm_state *x) { |
1a6509d99 [IPSEC]: Add supp... |
823 824 825 826 827 828 |
struct crypto_aead *aead; u32 align; int err; if (x->encap) return -EINVAL; |
1c5ad13f7 net: esp{4,6}: ge... |
829 |
x->data = NULL; |
1a6509d99 [IPSEC]: Add supp... |
830 831 832 833 834 |
if (x->aead) err = esp_init_aead(x); else err = esp_init_authenc(x); |
38320c70d [IPSEC]: Use cryp... |
835 |
if (err) |
1da177e4c Linux-2.6.12-rc2 |
836 |
goto error; |
38320c70d [IPSEC]: Use cryp... |
837 |
|
1c5ad13f7 net: esp{4,6}: ge... |
838 |
aead = x->data; |
1a6509d99 [IPSEC]: Add supp... |
839 |
|
38320c70d [IPSEC]: Use cryp... |
840 841 |
x->props.header_len = sizeof(struct ip_esp_hdr) + crypto_aead_ivsize(aead); |
ca68145f1 [IPSEC]: Disallow... |
842 843 |
switch (x->props.mode) { case XFRM_MODE_BEET: |
abf5cdb89 ipsec: Interfamil... |
844 845 |
if (x->sel.family != AF_INET6) x->props.header_len += IPV4_BEET_PHMAXLEN + |
67ba4152e ipv6: White-space... |
846 |
(sizeof(struct ipv6hdr) - sizeof(struct iphdr)); |
abf5cdb89 ipsec: Interfamil... |
847 |
break; |
ca68145f1 [IPSEC]: Disallow... |
848 849 850 |
case XFRM_MODE_TRANSPORT: break; case XFRM_MODE_TUNNEL: |
1da177e4c Linux-2.6.12-rc2 |
851 |
x->props.header_len += sizeof(struct ipv6hdr); |
ea2c47b42 [IPSEC] IPV6: Fix... |
852 |
break; |
ca68145f1 [IPSEC]: Disallow... |
853 854 855 |
default: goto error; } |
38320c70d [IPSEC]: Use cryp... |
856 857 |
align = ALIGN(crypto_aead_blocksize(aead), 4); |
1c5ad13f7 net: esp{4,6}: ge... |
858 |
x->props.trailer_len = align + 1 + crypto_aead_authsize(aead); |
1da177e4c Linux-2.6.12-rc2 |
859 860 |
error: |
38320c70d [IPSEC]: Use cryp... |
861 |
return err; |
1da177e4c Linux-2.6.12-rc2 |
862 |
} |
d5860c5cc esp6: Use the IPs... |
863 864 865 866 |
static int esp6_rcv_cb(struct sk_buff *skb, int err) { return 0; } |
cc24becae ipv6: White-space... |
867 |
static const struct xfrm_type esp6_type = { |
1da177e4c Linux-2.6.12-rc2 |
868 |
.description = "ESP6", |
cc24becae ipv6: White-space... |
869 870 |
.owner = THIS_MODULE, .proto = IPPROTO_ESP, |
436a0a402 [IPSEC]: Move out... |
871 |
.flags = XFRM_TYPE_REPLAY_PROT, |
1da177e4c Linux-2.6.12-rc2 |
872 873 |
.init_state = esp6_init_state, .destructor = esp6_destroy, |
c5c252389 [XFRM]: Optimize ... |
874 |
.get_mtu = esp6_get_mtu, |
1da177e4c Linux-2.6.12-rc2 |
875 |
.input = esp6_input, |
aee5adb43 [XFRM] STATE: Add... |
876 877 |
.output = esp6_output, .hdr_offset = xfrm6_find_1stfragopt, |
1da177e4c Linux-2.6.12-rc2 |
878 |
}; |
d5860c5cc esp6: Use the IPs... |
879 880 881 |
static struct xfrm6_protocol esp6_protocol = { .handler = xfrm6_rcv, .cb_handler = esp6_rcv_cb, |
1da177e4c Linux-2.6.12-rc2 |
882 |
.err_handler = esp6_err, |
d5860c5cc esp6: Use the IPs... |
883 |
.priority = 0, |
1da177e4c Linux-2.6.12-rc2 |
884 885 886 887 888 |
}; static int __init esp6_init(void) { if (xfrm_register_type(&esp6_type, AF_INET6) < 0) { |
f32138319 net: ipv6: Standa... |
889 890 |
pr_info("%s: can't add xfrm type ", __func__); |
1da177e4c Linux-2.6.12-rc2 |
891 892 |
return -EAGAIN; } |
d5860c5cc esp6: Use the IPs... |
893 |
if (xfrm6_protocol_register(&esp6_protocol, IPPROTO_ESP) < 0) { |
f32138319 net: ipv6: Standa... |
894 895 |
pr_info("%s: can't add protocol ", __func__); |
1da177e4c Linux-2.6.12-rc2 |
896 897 898 899 900 901 902 903 904 |
xfrm_unregister_type(&esp6_type, AF_INET6); return -EAGAIN; } return 0; } static void __exit esp6_fini(void) { |
d5860c5cc esp6: Use the IPs... |
905 |
if (xfrm6_protocol_deregister(&esp6_protocol, IPPROTO_ESP) < 0) |
f32138319 net: ipv6: Standa... |
906 907 |
pr_info("%s: can't remove protocol ", __func__); |
1da177e4c Linux-2.6.12-rc2 |
908 |
if (xfrm_unregister_type(&esp6_type, AF_INET6) < 0) |
f32138319 net: ipv6: Standa... |
909 910 |
pr_info("%s: can't remove xfrm type ", __func__); |
1da177e4c Linux-2.6.12-rc2 |
911 912 913 914 915 916 |
} module_init(esp6_init); module_exit(esp6_fini); MODULE_LICENSE("GPL"); |
d3d6dd3ad [XFRM]: Add modul... |
917 |
MODULE_ALIAS_XFRM_TYPE(AF_INET6, XFRM_PROTO_ESP); |