| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: key.c,v 1.158 2017/05/31 09:52:43 ozaki-r Exp $ */ | | 1 | /* $NetBSD: key.c,v 1.159 2017/05/31 09:53:35 ozaki-r Exp $ */ |
2 | /* $FreeBSD: src/sys/netipsec/key.c,v 1.3.2.3 2004/02/14 22:23:23 bms Exp $ */ | | 2 | /* $FreeBSD: src/sys/netipsec/key.c,v 1.3.2.3 2004/02/14 22:23:23 bms Exp $ */ |
3 | /* $KAME: key.c,v 1.191 2001/06/27 10:46:49 sakane Exp $ */ | | 3 | /* $KAME: key.c,v 1.191 2001/06/27 10:46:49 sakane Exp $ */ |
4 | | | 4 | |
5 | /* | | 5 | /* |
6 | * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. | | 6 | * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. |
7 | * All rights reserved. | | 7 | * All rights reserved. |
8 | * | | 8 | * |
9 | * Redistribution and use in source and binary forms, with or without | | 9 | * Redistribution and use in source and binary forms, with or without |
10 | * modification, are permitted provided that the following conditions | | 10 | * modification, are permitted provided that the following conditions |
11 | * are met: | | 11 | * are met: |
12 | * 1. Redistributions of source code must retain the above copyright | | 12 | * 1. Redistributions of source code must retain the above copyright |
13 | * notice, this list of conditions and the following disclaimer. | | 13 | * notice, this list of conditions and the following disclaimer. |
14 | * 2. Redistributions in binary form must reproduce the above copyright | | 14 | * 2. Redistributions in binary form must reproduce the above copyright |
| @@ -22,27 +22,27 @@ | | | @@ -22,27 +22,27 @@ |
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | | 22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | | 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE | | 24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE |
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | | 25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | | 26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
31 | * SUCH DAMAGE. | | 31 | * SUCH DAMAGE. |
32 | */ | | 32 | */ |
33 | | | 33 | |
34 | #include <sys/cdefs.h> | | 34 | #include <sys/cdefs.h> |
35 | __KERNEL_RCSID(0, "$NetBSD: key.c,v 1.158 2017/05/31 09:52:43 ozaki-r Exp $"); | | 35 | __KERNEL_RCSID(0, "$NetBSD: key.c,v 1.159 2017/05/31 09:53:35 ozaki-r Exp $"); |
36 | | | 36 | |
37 | /* | | 37 | /* |
38 | * This code is referd to RFC 2367 | | 38 | * This code is referd to RFC 2367 |
39 | */ | | 39 | */ |
40 | | | 40 | |
41 | #if defined(_KERNEL_OPT) | | 41 | #if defined(_KERNEL_OPT) |
42 | #include "opt_inet.h" | | 42 | #include "opt_inet.h" |
43 | #include "opt_ipsec.h" | | 43 | #include "opt_ipsec.h" |
44 | #include "opt_gateway.h" | | 44 | #include "opt_gateway.h" |
45 | #endif | | 45 | #endif |
46 | | | 46 | |
47 | #include <sys/types.h> | | 47 | #include <sys/types.h> |
48 | #include <sys/param.h> | | 48 | #include <sys/param.h> |
| @@ -4467,72 +4467,60 @@ key_bb_match_withmask(const void *a1, co | | | @@ -4467,72 +4467,60 @@ key_bb_match_withmask(const void *a1, co |
4467 | if (*p1++ != *p2++) | | 4467 | if (*p1++ != *p2++) |
4468 | return 0; | | 4468 | return 0; |
4469 | bits -= 8; | | 4469 | bits -= 8; |
4470 | } | | 4470 | } |
4471 | | | 4471 | |
4472 | if (bits > 0) { | | 4472 | if (bits > 0) { |
4473 | u_int8_t mask = ~((1<<(8-bits))-1); | | 4473 | u_int8_t mask = ~((1<<(8-bits))-1); |
4474 | if ((*p1 & mask) != (*p2 & mask)) | | 4474 | if ((*p1 & mask) != (*p2 & mask)) |
4475 | return 0; | | 4475 | return 0; |
4476 | } | | 4476 | } |
4477 | return 1; /* Match! */ | | 4477 | return 1; /* Match! */ |
4478 | } | | 4478 | } |
4479 | | | 4479 | |
4480 | /* | | | |
4481 | * time handler. | | | |
4482 | * scanning SPD and SAD to check status for each entries, | | | |
4483 | * and do to remove or to expire. | | | |
4484 | */ | | | |
4485 | static void | | 4480 | static void |
4486 | key_timehandler_work(struct work *wk, void *arg) | | 4481 | key_timehandler_spd(time_t now) |
4487 | { | | 4482 | { |
4488 | u_int dir; | | 4483 | u_int dir; |
4489 | int s; | | | |
4490 | time_t now = time_uptime; | | | |
4491 | | | | |
4492 | s = splsoftnet(); | | | |
4493 | mutex_enter(softnet_lock); | | | |
4494 | | | | |
4495 | /* SPD */ | | | |
4496 | { | | | |
4497 | struct secpolicy *sp, *nextsp; | | 4484 | struct secpolicy *sp, *nextsp; |
4498 | | | 4485 | |
4499 | for (dir = 0; dir < IPSEC_DIR_MAX; dir++) { | | 4486 | for (dir = 0; dir < IPSEC_DIR_MAX; dir++) { |
4500 | LIST_FOREACH_SAFE(sp, &sptree[dir], chain, nextsp) { | | 4487 | LIST_FOREACH_SAFE(sp, &sptree[dir], chain, nextsp) { |
4501 | if (sp->state == IPSEC_SPSTATE_DEAD) { | | 4488 | if (sp->state == IPSEC_SPSTATE_DEAD) { |
4502 | key_sp_unlink(sp); /*XXX*/ | | 4489 | key_sp_unlink(sp); /*XXX*/ |
4503 | | | 4490 | |
4504 | /* 'sp' dead; continue transfers to | | 4491 | /* 'sp' dead; continue transfers to |
4505 | * 'sp = nextsp' | | 4492 | * 'sp = nextsp' |
4506 | */ | | 4493 | */ |
4507 | continue; | | 4494 | continue; |
4508 | } | | 4495 | } |
4509 | | | 4496 | |
4510 | if (sp->lifetime == 0 && sp->validtime == 0) | | 4497 | if (sp->lifetime == 0 && sp->validtime == 0) |
4511 | continue; | | 4498 | continue; |
4512 | | | 4499 | |
4513 | /* the deletion will occur next time */ | | 4500 | /* the deletion will occur next time */ |
4514 | if ((sp->lifetime && now - sp->created > sp->lifetime) || | | 4501 | if ((sp->lifetime && now - sp->created > sp->lifetime) || |
4515 | (sp->validtime && now - sp->lastused > sp->validtime)) { | | 4502 | (sp->validtime && now - sp->lastused > sp->validtime)) { |
4516 | key_sp_dead(sp); | | 4503 | key_sp_dead(sp); |
4517 | key_spdexpire(sp); | | 4504 | key_spdexpire(sp); |
4518 | continue; | | 4505 | continue; |
4519 | } | | 4506 | } |
4520 | } | | 4507 | } |
4521 | } | | 4508 | } |
4522 | } | | 4509 | } |
4523 | | | 4510 | |
4524 | /* SAD */ | | 4511 | static void |
4525 | { | | 4512 | key_timehandler_sad(time_t now) |
| | | 4513 | { |
4526 | struct secashead *sah, *nextsah; | | 4514 | struct secashead *sah, *nextsah; |
4527 | struct secasvar *sav, *nextsav; | | 4515 | struct secasvar *sav, *nextsav; |
4528 | | | 4516 | |
4529 | LIST_FOREACH_SAFE(sah, &sahtree, chain, nextsah) { | | 4517 | LIST_FOREACH_SAFE(sah, &sahtree, chain, nextsah) { |
4530 | /* if sah has been dead, then delete it and process next sah. */ | | 4518 | /* if sah has been dead, then delete it and process next sah. */ |
4531 | if (sah->state == SADB_SASTATE_DEAD) { | | 4519 | if (sah->state == SADB_SASTATE_DEAD) { |
4532 | key_delsah(sah); | | 4520 | key_delsah(sah); |
4533 | continue; | | 4521 | continue; |
4534 | } | | 4522 | } |
4535 | | | 4523 | |
4536 | /* if LARVAL entry doesn't become MATURE, delete it. */ | | 4524 | /* if LARVAL entry doesn't become MATURE, delete it. */ |
4537 | LIST_FOREACH_SAFE(sav, &sah->savtree[SADB_SASTATE_LARVAL], | | 4525 | LIST_FOREACH_SAFE(sav, &sah->savtree[SADB_SASTATE_LARVAL], |
4538 | chain, nextsav) { | | 4526 | chain, nextsav) { |
| @@ -4651,61 +4639,82 @@ key_timehandler_work(struct work *wk, vo | | | @@ -4651,61 +4639,82 @@ key_timehandler_work(struct work *wk, vo |
4651 | "invalid sav->state (queue: %d SA: %d): " | | 4639 | "invalid sav->state (queue: %d SA: %d): " |
4652 | "kill it anyway\n", | | 4640 | "kill it anyway\n", |
4653 | SADB_SASTATE_DEAD, sav->state); | | 4641 | SADB_SASTATE_DEAD, sav->state); |
4654 | } | | 4642 | } |
4655 | | | 4643 | |
4656 | /* | | 4644 | /* |
4657 | * do not call key_freesav() here. | | 4645 | * do not call key_freesav() here. |
4658 | * sav should already be freed, and sav->refcnt | | 4646 | * sav should already be freed, and sav->refcnt |
4659 | * shows other references to sav | | 4647 | * shows other references to sav |
4660 | * (such as from SPD). | | 4648 | * (such as from SPD). |
4661 | */ | | 4649 | */ |
4662 | } | | 4650 | } |
4663 | } | | 4651 | } |
4664 | } | | 4652 | } |
4665 | | | 4653 | |
| | | 4654 | static void |
| | | 4655 | key_timehandler_acq(time_t now) |
| | | 4656 | { |
4666 | #ifndef IPSEC_NONBLOCK_ACQUIRE | | 4657 | #ifndef IPSEC_NONBLOCK_ACQUIRE |
4667 | /* ACQ tree */ | | | |
4668 | { | | | |
4669 | struct secacq *acq, *nextacq; | | 4658 | struct secacq *acq, *nextacq; |
4670 | | | 4659 | |
4671 | restart: | | 4660 | restart: |
4672 | mutex_enter(&key_mtx); | | 4661 | mutex_enter(&key_mtx); |
4673 | LIST_FOREACH_SAFE(acq, &acqtree, chain, nextacq) { | | 4662 | LIST_FOREACH_SAFE(acq, &acqtree, chain, nextacq) { |
4674 | if (now - acq->created > key_blockacq_lifetime) { | | 4663 | if (now - acq->created > key_blockacq_lifetime) { |
4675 | LIST_REMOVE(acq, chain); | | 4664 | LIST_REMOVE(acq, chain); |
4676 | mutex_exit(&key_mtx); | | 4665 | mutex_exit(&key_mtx); |
4677 | kmem_free(acq, sizeof(*acq)); | | 4666 | kmem_free(acq, sizeof(*acq)); |
4678 | goto restart; | | 4667 | goto restart; |
4679 | } | | 4668 | } |
4680 | } | | 4669 | } |
4681 | mutex_exit(&key_mtx); | | 4670 | mutex_exit(&key_mtx); |
4682 | } | | | |
4683 | #endif | | 4671 | #endif |
| | | 4672 | } |
4684 | | | 4673 | |
| | | 4674 | static void |
| | | 4675 | key_timehandler_spacq(time_t now) |
| | | 4676 | { |
4685 | #ifdef notyet | | 4677 | #ifdef notyet |
4686 | /* SP ACQ tree */ | | | |
4687 | { | | | |
4688 | struct secspacq *acq, *nextacq; | | 4678 | struct secspacq *acq, *nextacq; |
4689 | | | 4679 | |
4690 | LIST_FOREACH_SAFE(acq, &spacqtree, chain, nextacq) { | | 4680 | LIST_FOREACH_SAFE(acq, &spacqtree, chain, nextacq) { |
4691 | if (now - acq->created > key_blockacq_lifetime) { | | 4681 | if (now - acq->created > key_blockacq_lifetime) { |
4692 | KASSERT(__LIST_CHAINED(acq)); | | 4682 | KASSERT(__LIST_CHAINED(acq)); |
4693 | LIST_REMOVE(acq, chain); | | 4683 | LIST_REMOVE(acq, chain); |
4694 | kmem_free(acq, sizeof(*acq)); | | 4684 | kmem_free(acq, sizeof(*acq)); |
4695 | } | | 4685 | } |
4696 | } | | 4686 | } |
4697 | } | | | |
4698 | #endif | | 4687 | #endif |
| | | 4688 | } |
| | | 4689 | |
| | | 4690 | /* |
| | | 4691 | * time handler. |
| | | 4692 | * scanning SPD and SAD to check status for each entries, |
| | | 4693 | * and do to remove or to expire. |
| | | 4694 | */ |
| | | 4695 | static void |
| | | 4696 | key_timehandler_work(struct work *wk, void *arg) |
| | | 4697 | { |
| | | 4698 | int s; |
| | | 4699 | time_t now = time_uptime; |
| | | 4700 | |
| | | 4701 | s = splsoftnet(); |
| | | 4702 | mutex_enter(softnet_lock); |
| | | 4703 | |
| | | 4704 | key_timehandler_spd(now); |
| | | 4705 | key_timehandler_sad(now); |
| | | 4706 | key_timehandler_acq(now); |
| | | 4707 | key_timehandler_spacq(now); |
4699 | | | 4708 | |
4700 | /* do exchange to tick time !! */ | | 4709 | /* do exchange to tick time !! */ |
4701 | callout_reset(&key_timehandler_ch, hz, key_timehandler, NULL); | | 4710 | callout_reset(&key_timehandler_ch, hz, key_timehandler, NULL); |
4702 | | | 4711 | |
4703 | mutex_exit(softnet_lock); | | 4712 | mutex_exit(softnet_lock); |
4704 | splx(s); | | 4713 | splx(s); |
4705 | return; | | 4714 | return; |
4706 | } | | 4715 | } |
4707 | | | 4716 | |
4708 | static void | | 4717 | static void |
4709 | key_timehandler(void *arg) | | 4718 | key_timehandler(void *arg) |
4710 | { | | 4719 | { |
4711 | | | 4720 | |