| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: key.c,v 1.222 2017/08/09 08:30:54 ozaki-r Exp $ */ | | 1 | /* $NetBSD: key.c,v 1.223 2017/08/09 09:48:11 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.222 2017/08/09 08:30:54 ozaki-r Exp $"); | | 35 | __KERNEL_RCSID(0, "$NetBSD: key.c,v 1.223 2017/08/09 09:48:11 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 | #include "opt_net_mpsafe.h" | | 45 | #include "opt_net_mpsafe.h" |
46 | #endif | | 46 | #endif |
47 | | | 47 | |
48 | #include <sys/types.h> | | 48 | #include <sys/types.h> |
| @@ -192,42 +192,54 @@ static u_int32_t acq_seq = 0; | | | @@ -192,42 +192,54 @@ static u_int32_t acq_seq = 0; |
192 | * setsockopt(IP_IPSEC_POLICY) | | 192 | * setsockopt(IP_IPSEC_POLICY) |
193 | * - Such policies (SPs) are set to a socket (PCB) and also inserted to | | 193 | * - Such policies (SPs) are set to a socket (PCB) and also inserted to |
194 | * the key_spd.socksplist list (not the key_spd.splist) | | 194 | * the key_spd.socksplist list (not the key_spd.splist) |
195 | * - Such a policy is destroyed when a corresponding socket is destroed, | | 195 | * - Such a policy is destroyed when a corresponding socket is destroed, |
196 | * however, a socket can be destroyed in softint so we cannot destroy | | 196 | * however, a socket can be destroyed in softint so we cannot destroy |
197 | * it directly instead we just mark it DEAD and delay the destruction | | 197 | * it directly instead we just mark it DEAD and delay the destruction |
198 | * until GC by the timer | | 198 | * until GC by the timer |
199 | */ | | 199 | */ |
200 | /* | | 200 | /* |
201 | * Locking notes on SAD: | | 201 | * Locking notes on SAD: |
202 | * - Data structures | | 202 | * - Data structures |
203 | * - SAs are managed by the list called key_sad.sahlist and sav lists of sah | | 203 | * - SAs are managed by the list called key_sad.sahlist and sav lists of sah |
204 | * entries | | 204 | * entries |
| | | 205 | * - An sav is supposed to be an SA from a viewpoint of users |
205 | * - A sah has sav lists for each SA state | | 206 | * - A sah has sav lists for each SA state |
206 | * - Multiple sahs with the same saidx can exist | | 207 | * - Multiple sahs with the same saidx can exist |
207 | * - Only one entry has MATURE state and others should be DEAD | | 208 | * - Only one entry has MATURE state and others should be DEAD |
208 | * - DEAD entries are just ignored from searching | | 209 | * - DEAD entries are just ignored from searching |
209 | * - Modifications to the key_sad.sahlist must be done with holding key_sad.lock | | 210 | * - Modifications to the key_sad.sahlist and sah.savlist must be done with |
210 | * which is a adaptive mutex | | 211 | * holding key_sad.lock which is a adaptive mutex |
211 | * - Read accesses to the key_sad.sahlist must be in pserialize(9) read sections | | 212 | * - Read accesses to the key_sad.sahlist and sah.savlist must be in |
| | | 213 | * pserialize(9) read sections |
212 | * - sah's lifetime is managed by localcount(9) | | 214 | * - sah's lifetime is managed by localcount(9) |
213 | * - Getting an sah entry | | 215 | * - Getting an sah entry |
214 | * - We get an sah from the key_sad.sahlist | | 216 | * - We get an sah from the key_sad.sahlist |
215 | * - Must iterate the list and increment the reference count of a found sah | | 217 | * - Must iterate the list and increment the reference count of a found sah |
216 | * (by key_sah_ref) in a pserialize read section | | 218 | * (by key_sah_ref) in a pserialize read section |
217 | * - A gotten sah must be released after use by key_sah_unref | | 219 | * - A gotten sah must be released after use by key_sah_unref |
218 | * - An sah is destroyed when its state become DEAD and no sav is | | 220 | * - An sah is destroyed when its state become DEAD and no sav is |
219 | * listed to the sah | | 221 | * listed to the sah |
220 | * - The destruction is done only in the timer (see key_timehandler_sad) | | 222 | * - The destruction is done only in the timer (see key_timehandler_sad) |
| | | 223 | * - sav's lifetime is managed by localcount(9) |
| | | 224 | * - Getting an sav entry |
| | | 225 | * - First get an sah by saidx and get an sav from either of sah's savlists |
| | | 226 | * - Must iterate the list and increment the reference count of a found sav |
| | | 227 | * (by key_sa_ref) in a pserialize read section |
| | | 228 | * - We can gain another reference from a held SA only if we check its state |
| | | 229 | * and take its reference in a pserialize read section |
| | | 230 | * (see esp_output for example) |
| | | 231 | * - A gotten sav must be released after use by key_sa_unref |
| | | 232 | * - An sav is destroyed when its state become DEAD |
221 | */ | | 233 | */ |
222 | /* | | 234 | /* |
223 | * Locking notes on misc data: | | 235 | * Locking notes on misc data: |
224 | * - All lists of key_misc are protected by key_misc.lock | | 236 | * - All lists of key_misc are protected by key_misc.lock |
225 | * - key_misc.lock must be held even for read accesses | | 237 | * - key_misc.lock must be held even for read accesses |
226 | */ | | 238 | */ |
227 | | | 239 | |
228 | static pserialize_t key_spd_psz __read_mostly; | | 240 | static pserialize_t key_spd_psz __read_mostly; |
229 | static pserialize_t key_sad_psz __read_mostly; | | 241 | static pserialize_t key_sad_psz __read_mostly; |
230 | | | 242 | |
231 | /* SPD */ | | 243 | /* SPD */ |
232 | static struct { | | 244 | static struct { |
233 | kmutex_t lock; | | 245 | kmutex_t lock; |
| @@ -633,26 +645,29 @@ static struct mbuf * key_setspddump (int | | | @@ -633,26 +645,29 @@ static struct mbuf * key_setspddump (int |
633 | static struct mbuf * key_setspddump_chain (int *errorp, int *lenp, pid_t pid); | | 645 | static struct mbuf * key_setspddump_chain (int *errorp, int *lenp, pid_t pid); |
634 | static int key_api_nat_map(struct socket *, struct mbuf *, | | 646 | static int key_api_nat_map(struct socket *, struct mbuf *, |
635 | const struct sadb_msghdr *); | | 647 | const struct sadb_msghdr *); |
636 | static struct mbuf *key_setdumpsp (struct secpolicy *, | | 648 | static struct mbuf *key_setdumpsp (struct secpolicy *, |
637 | u_int8_t, u_int32_t, pid_t); | | 649 | u_int8_t, u_int32_t, pid_t); |
638 | static u_int key_getspreqmsglen (const struct secpolicy *); | | 650 | static u_int key_getspreqmsglen (const struct secpolicy *); |
639 | static int key_spdexpire (struct secpolicy *); | | 651 | static int key_spdexpire (struct secpolicy *); |
640 | static struct secashead *key_newsah (const struct secasindex *); | | 652 | static struct secashead *key_newsah (const struct secasindex *); |
641 | static void key_unlink_sah(struct secashead *); | | 653 | static void key_unlink_sah(struct secashead *); |
642 | static void key_destroy_sah(struct secashead *); | | 654 | static void key_destroy_sah(struct secashead *); |
643 | static bool key_sah_has_sav(struct secashead *); | | 655 | static bool key_sah_has_sav(struct secashead *); |
644 | static void key_sah_ref(struct secashead *); | | 656 | static void key_sah_ref(struct secashead *); |
645 | static void key_sah_unref(struct secashead *); | | 657 | static void key_sah_unref(struct secashead *); |
| | | 658 | static void key_init_sav(struct secasvar *); |
| | | 659 | static void key_destroy_sav(struct secasvar *); |
| | | 660 | static void key_destroy_sav_with_ref(struct secasvar *); |
646 | static struct secasvar *key_newsav(struct mbuf *, | | 661 | static struct secasvar *key_newsav(struct mbuf *, |
647 | const struct sadb_msghdr *, int *, const char*, int); | | 662 | const struct sadb_msghdr *, int *, const char*, int); |
648 | #define KEY_NEWSAV(m, sadb, e) \ | | 663 | #define KEY_NEWSAV(m, sadb, e) \ |
649 | key_newsav(m, sadb, e, __func__, __LINE__) | | 664 | key_newsav(m, sadb, e, __func__, __LINE__) |
650 | static void key_delsav (struct secasvar *); | | 665 | static void key_delsav (struct secasvar *); |
651 | static struct secashead *key_getsah(const struct secasindex *, int); | | 666 | static struct secashead *key_getsah(const struct secasindex *, int); |
652 | static struct secashead *key_getsah_ref(const struct secasindex *, int); | | 667 | static struct secashead *key_getsah_ref(const struct secasindex *, int); |
653 | static bool key_checkspidup(const struct secasindex *, u_int32_t); | | 668 | static bool key_checkspidup(const struct secasindex *, u_int32_t); |
654 | static struct secasvar *key_getsavbyspi (struct secashead *, u_int32_t); | | 669 | static struct secasvar *key_getsavbyspi (struct secashead *, u_int32_t); |
655 | static int key_setsaval (struct secasvar *, struct mbuf *, | | 670 | static int key_setsaval (struct secasvar *, struct mbuf *, |
656 | const struct sadb_msghdr *); | | 671 | const struct sadb_msghdr *); |
657 | static void key_freesaval(struct secasvar *); | | 672 | static void key_freesaval(struct secasvar *); |
658 | static int key_init_xform(struct secasvar *); | | 673 | static int key_init_xform(struct secasvar *); |
| @@ -766,55 +781,26 @@ static int key_align (struct mbuf *, str | | | @@ -766,55 +781,26 @@ static int key_align (struct mbuf *, str |
766 | static const char *key_getfqdn (void); | | 781 | static const char *key_getfqdn (void); |
767 | static const char *key_getuserfqdn (void); | | 782 | static const char *key_getuserfqdn (void); |
768 | #endif | | 783 | #endif |
769 | static void key_sa_chgstate (struct secasvar *, u_int8_t); | | 784 | static void key_sa_chgstate (struct secasvar *, u_int8_t); |
770 | | | 785 | |
771 | static struct mbuf *key_alloc_mbuf (int); | | 786 | static struct mbuf *key_alloc_mbuf (int); |
772 | | | 787 | |
773 | static void key_timehandler(void *); | | 788 | static void key_timehandler(void *); |
774 | static void key_timehandler_work(struct work *, void *); | | 789 | static void key_timehandler_work(struct work *, void *); |
775 | static struct callout key_timehandler_ch; | | 790 | static struct callout key_timehandler_ch; |
776 | static struct workqueue *key_timehandler_wq; | | 791 | static struct workqueue *key_timehandler_wq; |
777 | static struct work key_timehandler_wk; | | 792 | static struct work key_timehandler_wk; |
778 | | | 793 | |
779 | #ifdef IPSEC_REF_DEBUG | | | |
780 | #define REFLOG(label, p, where, tag) \ | | | |
781 | log(LOG_DEBUG, "%s:%d: " label " : refcnt=%d (%p)\n.", \ | | | |
782 | (where), (tag), (p)->refcnt, (p)) | | | |
783 | #else | | | |
784 | #define REFLOG(label, p, where, tag) do {} while (0) | | | |
785 | #endif | | | |
786 | | | | |
787 | #define SA_ADDREF(p) do { \ | | | |
788 | atomic_inc_uint(&(p)->refcnt); \ | | | |
789 | REFLOG("SA_ADDREF", (p), __func__, __LINE__); \ | | | |
790 | KASSERTMSG((p)->refcnt != 0, "SA refcnt overflow"); \ | | | |
791 | } while (0) | | | |
792 | #define SA_ADDREF2(p, where, tag) do { \ | | | |
793 | atomic_inc_uint(&(p)->refcnt); \ | | | |
794 | REFLOG("SA_ADDREF", (p), (where), (tag)); \ | | | |
795 | KASSERTMSG((p)->refcnt != 0, "SA refcnt overflow"); \ | | | |
796 | } while (0) | | | |
797 | #define SA_DELREF(p) do { \ | | | |
798 | KASSERTMSG((p)->refcnt > 0, "SA refcnt underflow"); \ | | | |
799 | atomic_dec_uint(&(p)->refcnt); \ | | | |
800 | REFLOG("SA_DELREF", (p), __func__, __LINE__); \ | | | |
801 | } while (0) | | | |
802 | #define SA_DELREF2(p, nv, where, tag) do { \ | | | |
803 | KASSERTMSG((p)->refcnt > 0, "SA refcnt underflow"); \ | | | |
804 | nv = atomic_dec_uint_nv(&(p)->refcnt); \ | | | |
805 | REFLOG("SA_DELREF", (p), (where), (tag)); \ | | | |
806 | } while (0) | | | |
807 | | | | |
808 | u_int | | 794 | u_int |
809 | key_sp_refcnt(const struct secpolicy *sp) | | 795 | key_sp_refcnt(const struct secpolicy *sp) |
810 | { | | 796 | { |
811 | | | 797 | |
812 | /* FIXME */ | | 798 | /* FIXME */ |
813 | return 0; | | 799 | return 0; |
814 | } | | 800 | } |
815 | | | 801 | |
816 | /* | | 802 | /* |
817 | * Remove the sp from the key_spd.splist and wait for references to the sp | | 803 | * Remove the sp from the key_spd.splist and wait for references to the sp |
818 | * to be released. key_spd.lock must be held. | | 804 | * to be released. key_spd.lock must be held. |
819 | */ | | 805 | */ |
820 | static void | | 806 | static void |
| @@ -1075,27 +1061,27 @@ key_lookup_sa_bysaidx(const struct secas | | | @@ -1075,27 +1061,27 @@ key_lookup_sa_bysaidx(const struct secas |
1075 | state = saorder_state_valid[stateidx]; | | 1061 | state = saorder_state_valid[stateidx]; |
1076 | | | 1062 | |
1077 | if (key_prefered_oldsa) | | 1063 | if (key_prefered_oldsa) |
1078 | sav = SAVLIST_READER_FIRST(sah, state); | | 1064 | sav = SAVLIST_READER_FIRST(sah, state); |
1079 | else { | | 1065 | else { |
1080 | /* XXX need O(1) lookup */ | | 1066 | /* XXX need O(1) lookup */ |
1081 | struct secasvar *last = NULL; | | 1067 | struct secasvar *last = NULL; |
1082 | | | 1068 | |
1083 | SAVLIST_READER_FOREACH(sav, sah, state) | | 1069 | SAVLIST_READER_FOREACH(sav, sah, state) |
1084 | last = sav; | | 1070 | last = sav; |
1085 | sav = last; | | 1071 | sav = last; |
1086 | } | | 1072 | } |
1087 | if (sav != NULL) { | | 1073 | if (sav != NULL) { |
1088 | SA_ADDREF(sav); | | 1074 | KEY_SA_REF(sav); |
1089 | KEYDEBUG_PRINTF(KEYDEBUG_IPSEC_STAMP, | | 1075 | KEYDEBUG_PRINTF(KEYDEBUG_IPSEC_STAMP, |
1090 | "DP cause refcnt++:%d SA:%p\n", | | 1076 | "DP cause refcnt++:%d SA:%p\n", |
1091 | key_sa_refcnt(sav), sav); | | 1077 | key_sa_refcnt(sav), sav); |
1092 | break; | | 1078 | break; |
1093 | } | | 1079 | } |
1094 | } | | 1080 | } |
1095 | out: | | 1081 | out: |
1096 | pserialize_read_exit(s); | | 1082 | pserialize_read_exit(s); |
1097 | | | 1083 | |
1098 | return sav; | | 1084 | return sav; |
1099 | } | | 1085 | } |
1100 | | | 1086 | |
1101 | #if 0 | | 1087 | #if 0 |
| @@ -1274,27 +1260,27 @@ key_lookup_sa( | | | @@ -1274,27 +1260,27 @@ key_lookup_sa( |
1274 | | | 1260 | |
1275 | #if 0 /* don't check src */ | | 1261 | #if 0 /* don't check src */ |
1276 | /* Fix port in src->sa */ | | 1262 | /* Fix port in src->sa */ |
1277 | | | 1263 | |
1278 | /* check src address */ | | 1264 | /* check src address */ |
1279 | if (!key_sockaddr_match(&src->sa, &sav->sah->saidx.src.sa, PORT_NONE)) | | 1265 | if (!key_sockaddr_match(&src->sa, &sav->sah->saidx.src.sa, PORT_NONE)) |
1280 | continue; | | 1266 | continue; |
1281 | #endif | | 1267 | #endif |
1282 | /* fix port of dst address XXX*/ | | 1268 | /* fix port of dst address XXX*/ |
1283 | key_porttosaddr(__UNCONST(dst), dport); | | 1269 | key_porttosaddr(__UNCONST(dst), dport); |
1284 | /* check dst address */ | | 1270 | /* check dst address */ |
1285 | if (!key_sockaddr_match(&dst->sa, &sav->sah->saidx.dst.sa, chkport)) | | 1271 | if (!key_sockaddr_match(&dst->sa, &sav->sah->saidx.dst.sa, chkport)) |
1286 | continue; | | 1272 | continue; |
1287 | SA_ADDREF2(sav, where, tag); | | 1273 | key_sa_ref(sav, where, tag); |
1288 | goto done; | | 1274 | goto done; |
1289 | } | | 1275 | } |
1290 | } | | 1276 | } |
1291 | } | | 1277 | } |
1292 | sav = NULL; | | 1278 | sav = NULL; |
1293 | done: | | 1279 | done: |
1294 | pserialize_read_exit(s); | | 1280 | pserialize_read_exit(s); |
1295 | | | 1281 | |
1296 | KEYDEBUG_PRINTF(KEYDEBUG_IPSEC_STAMP, | | 1282 | KEYDEBUG_PRINTF(KEYDEBUG_IPSEC_STAMP, |
1297 | "DP return SA:%p; refcnt %u\n", sav, key_sa_refcnt(sav)); | | 1283 | "DP return SA:%p; refcnt %u\n", sav, key_sa_refcnt(sav)); |
1298 | return sav; | | 1284 | return sav; |
1299 | } | | 1285 | } |
1300 | | | 1286 | |
| @@ -1361,45 +1347,66 @@ key_sp_ref(struct secpolicy *sp, const c | | | @@ -1361,45 +1347,66 @@ key_sp_ref(struct secpolicy *sp, const c |
1361 | void | | 1347 | void |
1362 | key_sp_unref(struct secpolicy *sp, const char* where, int tag) | | 1348 | key_sp_unref(struct secpolicy *sp, const char* where, int tag) |
1363 | { | | 1349 | { |
1364 | | | 1350 | |
1365 | KDASSERT(mutex_ownable(&key_spd.lock)); | | 1351 | KDASSERT(mutex_ownable(&key_spd.lock)); |
1366 | | | 1352 | |
1367 | KEYDEBUG_PRINTF(KEYDEBUG_IPSEC_STAMP, | | 1353 | KEYDEBUG_PRINTF(KEYDEBUG_IPSEC_STAMP, |
1368 | "DP SP:%p (ID=%u) from %s:%u; refcnt-- now %u\n", | | 1354 | "DP SP:%p (ID=%u) from %s:%u; refcnt-- now %u\n", |
1369 | sp, sp->id, where, tag, key_sp_refcnt(sp)); | | 1355 | sp, sp->id, where, tag, key_sp_refcnt(sp)); |
1370 | | | 1356 | |
1371 | localcount_release(&sp->localcount, &key_spd.cv, &key_spd.lock); | | 1357 | localcount_release(&sp->localcount, &key_spd.cv, &key_spd.lock); |
1372 | } | | 1358 | } |
1373 | | | 1359 | |
| | | 1360 | static void |
| | | 1361 | key_init_sav(struct secasvar *sav) |
| | | 1362 | { |
| | | 1363 | |
| | | 1364 | ASSERT_SLEEPABLE(); |
| | | 1365 | |
| | | 1366 | localcount_init(&sav->localcount); |
| | | 1367 | SAVLIST_ENTRY_INIT(sav); |
| | | 1368 | } |
| | | 1369 | |
1374 | u_int | | 1370 | u_int |
1375 | key_sa_refcnt(const struct secasvar *sav) | | 1371 | key_sa_refcnt(const struct secasvar *sav) |
1376 | { | | 1372 | { |
1377 | | | 1373 | |
1378 | if (sav == NULL) | | 1374 | /* FIXME */ |
1379 | return 0; | | 1375 | return 0; |
1380 | | | | |
1381 | return sav->refcnt; | | | |
1382 | } | | 1376 | } |
1383 | | | 1377 | |
1384 | void | | 1378 | void |
1385 | key_sa_ref(struct secasvar *sav, const char* where, int tag) | | 1379 | key_sa_ref(struct secasvar *sav, const char* where, int tag) |
1386 | { | | 1380 | { |
1387 | | | 1381 | |
1388 | SA_ADDREF2(sav, where, tag); | | 1382 | localcount_acquire(&sav->localcount); |
1389 | | | 1383 | |
1390 | KEYDEBUG_PRINTF(KEYDEBUG_IPSEC_STAMP, | | 1384 | KEYDEBUG_PRINTF(KEYDEBUG_IPSEC_STAMP, |
1391 | "DP cause refcnt++:%d SA:%p from %s:%u\n", | | 1385 | "DP cause refcnt++: SA:%p from %s:%u\n", |
1392 | sav->refcnt, sav, where, tag); | | 1386 | sav, where, tag); |
| | | 1387 | } |
| | | 1388 | |
| | | 1389 | void |
| | | 1390 | key_sa_unref(struct secasvar *sav, const char* where, int tag) |
| | | 1391 | { |
| | | 1392 | |
| | | 1393 | KDASSERT(mutex_ownable(&key_sad.lock)); |
| | | 1394 | |
| | | 1395 | KEYDEBUG_PRINTF(KEYDEBUG_IPSEC_STAMP, |
| | | 1396 | "DP cause refcnt--: SA:%p from %s:%u\n", |
| | | 1397 | sav, where, tag); |
| | | 1398 | |
| | | 1399 | localcount_release(&sav->localcount, &key_sad.cv, &key_sad.lock); |
1393 | } | | 1400 | } |
1394 | | | 1401 | |
1395 | #if 0 | | 1402 | #if 0 |
1396 | /* | | 1403 | /* |
1397 | * Must be called after calling key_lookup_sp*(). | | 1404 | * Must be called after calling key_lookup_sp*(). |
1398 | * For the packet with socket. | | 1405 | * For the packet with socket. |
1399 | */ | | 1406 | */ |
1400 | static void | | 1407 | static void |
1401 | key_freeso(struct socket *so) | | 1408 | key_freeso(struct socket *so) |
1402 | { | | 1409 | { |
1403 | /* sanity check */ | | 1410 | /* sanity check */ |
1404 | KASSERT(so != NULL); | | 1411 | KASSERT(so != NULL); |
1405 | | | 1412 | |
| @@ -1458,52 +1465,87 @@ key_freesp_so(struct secpolicy **sp) | | | @@ -1458,52 +1465,87 @@ key_freesp_so(struct secpolicy **sp) |
1458 | KASSERT(*sp != NULL); | | 1465 | KASSERT(*sp != NULL); |
1459 | | | 1466 | |
1460 | if ((*sp)->policy == IPSEC_POLICY_ENTRUST || | | 1467 | if ((*sp)->policy == IPSEC_POLICY_ENTRUST || |
1461 | (*sp)->policy == IPSEC_POLICY_BYPASS) | | 1468 | (*sp)->policy == IPSEC_POLICY_BYPASS) |
1462 | return; | | 1469 | return; |
1463 | | | 1470 | |
1464 | KASSERTMSG((*sp)->policy == IPSEC_POLICY_IPSEC, | | 1471 | KASSERTMSG((*sp)->policy == IPSEC_POLICY_IPSEC, |
1465 | "invalid policy %u", (*sp)->policy); | | 1472 | "invalid policy %u", (*sp)->policy); |
1466 | KEY_SP_UNREF(&sp); | | 1473 | KEY_SP_UNREF(&sp); |
1467 | } | | 1474 | } |
1468 | #endif | | 1475 | #endif |
1469 | | | 1476 | |
1470 | /* | | 1477 | /* |
1471 | * Must be called after calling key_lookup_sa(). | | 1478 | * Remove the sav from the savlist of its sah and wait for references to the sav |
1472 | * This function is called by key_freesp() to free some SA allocated | | 1479 | * to be released. key_sad.lock must be held. |
1473 | * for a policy. | | | |
1474 | */ | | 1480 | */ |
1475 | void | | 1481 | static void |
1476 | key_freesav(struct secasvar **psav, const char* where, int tag) | | 1482 | key_unlink_sav(struct secasvar *sav) |
1477 | { | | 1483 | { |
1478 | struct secasvar *sav = *psav; | | | |
1479 | unsigned int nv; | | | |
1480 | | | 1484 | |
1481 | KASSERT(sav != NULL); | | 1485 | KASSERT(mutex_owned(&key_sad.lock)); |
1482 | | | 1486 | |
1483 | SA_DELREF2(sav, nv, where, tag); | | 1487 | SAVLIST_WRITER_REMOVE(sav); |
1484 | | | 1488 | |
1485 | KEYDEBUG_PRINTF(KEYDEBUG_IPSEC_STAMP, | | 1489 | #ifdef NET_MPSAFE |
1486 | "DP SA:%p (SPI %lu) from %s:%u; refcnt now %u\n", | | 1490 | KASSERT(mutex_ownable(softnet_lock)); |
1487 | sav, (u_long)ntohl(sav->spi), where, tag, nv); | | 1491 | pserialize_perform(key_sad_psz); |
| | | 1492 | #endif |
1488 | | | 1493 | |
1489 | if (nv == 0) { | | 1494 | localcount_drain(&sav->localcount, &key_sad.cv, &key_sad.lock); |
1490 | *psav = NULL; | | 1495 | } |
1491 | | | 1496 | |
1492 | /* remove from SA header */ | | 1497 | /* |
1493 | SAVLIST_WRITER_REMOVE(sav); | | 1498 | * Destroy an sav where the sav must be unlinked from an sah |
| | | 1499 | * by say key_unlink_sav. |
| | | 1500 | */ |
| | | 1501 | static void |
| | | 1502 | key_destroy_sav(struct secasvar *sav) |
| | | 1503 | { |
1494 | | | 1504 | |
1495 | key_delsav(sav); | | 1505 | ASSERT_SLEEPABLE(); |
1496 | } | | 1506 | |
| | | 1507 | localcount_fini(&sav->localcount); |
| | | 1508 | SAVLIST_ENTRY_DESTROY(sav); |
| | | 1509 | |
| | | 1510 | key_delsav(sav); |
| | | 1511 | } |
| | | 1512 | |
| | | 1513 | /* |
| | | 1514 | * Destroy sav with holding its reference. |
| | | 1515 | */ |
| | | 1516 | static void |
| | | 1517 | key_destroy_sav_with_ref(struct secasvar *sav) |
| | | 1518 | { |
| | | 1519 | |
| | | 1520 | ASSERT_SLEEPABLE(); |
| | | 1521 | |
| | | 1522 | mutex_enter(&key_sad.lock); |
| | | 1523 | sav->state = SADB_SASTATE_DEAD; |
| | | 1524 | SAVLIST_WRITER_REMOVE(sav); |
| | | 1525 | mutex_exit(&key_sad.lock); |
| | | 1526 | |
| | | 1527 | /* We cannot unref with holding key_sad.lock */ |
| | | 1528 | KEY_SA_UNREF(&sav); |
| | | 1529 | |
| | | 1530 | mutex_enter(&key_sad.lock); |
| | | 1531 | #ifdef NET_MPSAFE |
| | | 1532 | KASSERT(mutex_ownable(softnet_lock)); |
| | | 1533 | pserialize_perform(key_sad_psz); |
| | | 1534 | #endif |
| | | 1535 | localcount_drain(&sav->localcount, &key_sad.cv, &key_sad.lock); |
| | | 1536 | mutex_exit(&key_sad.lock); |
| | | 1537 | |
| | | 1538 | key_destroy_sav(sav); |
1497 | } | | 1539 | } |
1498 | | | 1540 | |
1499 | /* %%% SPD management */ | | 1541 | /* %%% SPD management */ |
1500 | /* | | 1542 | /* |
1501 | * free security policy entry. | | 1543 | * free security policy entry. |
1502 | */ | | 1544 | */ |
1503 | static void | | 1545 | static void |
1504 | key_destroy_sp(struct secpolicy *sp) | | 1546 | key_destroy_sp(struct secpolicy *sp) |
1505 | { | | 1547 | { |
1506 | | | 1548 | |
1507 | SPLIST_ENTRY_DESTROY(sp); | | 1549 | SPLIST_ENTRY_DESTROY(sp); |
1508 | localcount_fini(&sp->localcount); | | 1550 | localcount_fini(&sp->localcount); |
1509 | | | 1551 | |
| @@ -3163,35 +3205,29 @@ key_clear_xform(struct secasvar *sav) | | | @@ -3163,35 +3205,29 @@ key_clear_xform(struct secasvar *sav) |
3163 | if (sav->key_enc != NULL) | | 3205 | if (sav->key_enc != NULL) |
3164 | explicit_memset(_KEYBUF(sav->key_enc), 0, | | 3206 | explicit_memset(_KEYBUF(sav->key_enc), 0, |
3165 | _KEYLEN(sav->key_enc)); | | 3207 | _KEYLEN(sav->key_enc)); |
3166 | } | | 3208 | } |
3167 | } | | 3209 | } |
3168 | | | 3210 | |
3169 | /* | | 3211 | /* |
3170 | * free() SA variable entry. | | 3212 | * free() SA variable entry. |
3171 | */ | | 3213 | */ |
3172 | static void | | 3214 | static void |
3173 | key_delsav(struct secasvar *sav) | | 3215 | key_delsav(struct secasvar *sav) |
3174 | { | | 3216 | { |
3175 | | | 3217 | |
3176 | KASSERT(sav != NULL); | | | |
3177 | KASSERTMSG(sav->refcnt == 0, "reference count %u > 0", sav->refcnt); | | | |
3178 | | | | |
3179 | key_clear_xform(sav); | | 3218 | key_clear_xform(sav); |
3180 | key_freesaval(sav); | | 3219 | key_freesaval(sav); |
3181 | SAVLIST_ENTRY_DESTROY(sav); | | 3220 | kmem_free(sav, sizeof(*sav)); |
3182 | kmem_intr_free(sav, sizeof(*sav)); | | | |
3183 | | | | |
3184 | return; | | | |
3185 | } | | 3221 | } |
3186 | | | 3222 | |
3187 | /* | | 3223 | /* |
3188 | * Must be called in a pserialize read section. A held sah | | 3224 | * Must be called in a pserialize read section. A held sah |
3189 | * must be released by key_sah_unref after use. | | 3225 | * must be released by key_sah_unref after use. |
3190 | */ | | 3226 | */ |
3191 | static void | | 3227 | static void |
3192 | key_sah_ref(struct secashead *sah) | | 3228 | key_sah_ref(struct secashead *sah) |
3193 | { | | 3229 | { |
3194 | | | 3230 | |
3195 | localcount_acquire(&sah->localcount); | | 3231 | localcount_acquire(&sah->localcount); |
3196 | } | | 3232 | } |
3197 | | | 3233 | |
| @@ -3305,27 +3341,27 @@ key_getsavbyspi(struct secashead *sah, u | | | @@ -3305,27 +3341,27 @@ key_getsavbyspi(struct secashead *sah, u |
3305 | /* search all status */ | | 3341 | /* search all status */ |
3306 | s = pserialize_read_enter(); | | 3342 | s = pserialize_read_enter(); |
3307 | SASTATE_ALIVE_FOREACH(state) { | | 3343 | SASTATE_ALIVE_FOREACH(state) { |
3308 | SAVLIST_READER_FOREACH(sav, sah, state) { | | 3344 | SAVLIST_READER_FOREACH(sav, sah, state) { |
3309 | /* sanity check */ | | 3345 | /* sanity check */ |
3310 | if (sav->state != state) { | | 3346 | if (sav->state != state) { |
3311 | IPSECLOG(LOG_DEBUG, | | 3347 | IPSECLOG(LOG_DEBUG, |
3312 | "invalid sav->state (queue: %d SA: %d)\n", | | 3348 | "invalid sav->state (queue: %d SA: %d)\n", |
3313 | state, sav->state); | | 3349 | state, sav->state); |
3314 | continue; | | 3350 | continue; |
3315 | } | | 3351 | } |
3316 | | | 3352 | |
3317 | if (sav->spi == spi) { | | 3353 | if (sav->spi == spi) { |
3318 | SA_ADDREF(sav); | | 3354 | KEY_SA_REF(sav); |
3319 | goto out; | | 3355 | goto out; |
3320 | } | | 3356 | } |
3321 | } | | 3357 | } |
3322 | } | | 3358 | } |
3323 | out: | | 3359 | out: |
3324 | pserialize_read_exit(s); | | 3360 | pserialize_read_exit(s); |
3325 | | | 3361 | |
3326 | return sav; | | 3362 | return sav; |
3327 | } | | 3363 | } |
3328 | | | 3364 | |
3329 | /* | | 3365 | /* |
3330 | * Free allocated data to member variables of sav: | | 3366 | * Free allocated data to member variables of sav: |
3331 | * sav->replay, sav->key_* and sav->lft_*. | | 3367 | * sav->replay, sav->key_* and sav->lft_*. |
| @@ -4708,91 +4744,99 @@ restart: | | | @@ -4708,91 +4744,99 @@ restart: |
4708 | goto restart; | | 4744 | goto restart; |
4709 | } | | 4745 | } |
4710 | } | | 4746 | } |
4711 | mutex_exit(&key_sad.lock); | | 4747 | mutex_exit(&key_sad.lock); |
4712 | | | 4748 | |
4713 | s = pserialize_read_enter(); | | 4749 | s = pserialize_read_enter(); |
4714 | SAHLIST_READER_FOREACH(sah) { | | 4750 | SAHLIST_READER_FOREACH(sah) { |
4715 | struct secasvar *sav; | | 4751 | struct secasvar *sav; |
4716 | | | 4752 | |
4717 | key_sah_ref(sah); | | 4753 | key_sah_ref(sah); |
4718 | pserialize_read_exit(s); | | 4754 | pserialize_read_exit(s); |
4719 | | | 4755 | |
4720 | /* if LARVAL entry doesn't become MATURE, delete it. */ | | 4756 | /* if LARVAL entry doesn't become MATURE, delete it. */ |
| | | 4757 | mutex_enter(&key_sad.lock); |
4721 | restart_sav_LARVAL: | | 4758 | restart_sav_LARVAL: |
4722 | SAVLIST_READER_FOREACH(sav, sah, SADB_SASTATE_LARVAL) { | | 4759 | SAVLIST_WRITER_FOREACH(sav, sah, SADB_SASTATE_LARVAL) { |
4723 | if (now - sav->created > key_larval_lifetime) { | | 4760 | if (now - sav->created > key_larval_lifetime) { |
4724 | key_sa_chgstate(sav, SADB_SASTATE_DEAD); | | 4761 | key_sa_chgstate(sav, SADB_SASTATE_DEAD); |
4725 | goto restart_sav_LARVAL; | | 4762 | goto restart_sav_LARVAL; |
4726 | } | | 4763 | } |
4727 | } | | 4764 | } |
| | | 4765 | mutex_exit(&key_sad.lock); |
4728 | | | 4766 | |
4729 | /* | | 4767 | /* |
4730 | * check MATURE entry to start to send expire message | | 4768 | * check MATURE entry to start to send expire message |
4731 | * whether or not. | | 4769 | * whether or not. |
4732 | */ | | 4770 | */ |
4733 | restart_sav_MATURE: | | 4771 | restart_sav_MATURE: |
4734 | SAVLIST_READER_FOREACH(sav, sah, SADB_SASTATE_MATURE) { | | 4772 | mutex_enter(&key_sad.lock); |
| | | 4773 | SAVLIST_WRITER_FOREACH(sav, sah, SADB_SASTATE_MATURE) { |
4735 | /* we don't need to check. */ | | 4774 | /* we don't need to check. */ |
4736 | if (sav->lft_s == NULL) | | 4775 | if (sav->lft_s == NULL) |
4737 | continue; | | 4776 | continue; |
4738 | | | 4777 | |
4739 | /* sanity check */ | | 4778 | /* sanity check */ |
4740 | KASSERT(sav->lft_c != NULL); | | 4779 | KASSERT(sav->lft_c != NULL); |
4741 | | | 4780 | |
4742 | /* check SOFT lifetime */ | | 4781 | /* check SOFT lifetime */ |
4743 | if (sav->lft_s->sadb_lifetime_addtime != 0 && | | 4782 | if (sav->lft_s->sadb_lifetime_addtime != 0 && |
4744 | now - sav->created > sav->lft_s->sadb_lifetime_addtime) { | | 4783 | now - sav->created > sav->lft_s->sadb_lifetime_addtime) { |
4745 | /* | | 4784 | /* |
4746 | * check SA to be used whether or not. | | 4785 | * check SA to be used whether or not. |
4747 | * when SA hasn't been used, delete it. | | 4786 | * when SA hasn't been used, delete it. |
4748 | */ | | 4787 | */ |
4749 | if (sav->lft_c->sadb_lifetime_usetime == 0) { | | 4788 | if (sav->lft_c->sadb_lifetime_usetime == 0) { |
4750 | key_sa_chgstate(sav, SADB_SASTATE_DEAD); | | 4789 | key_sa_chgstate(sav, SADB_SASTATE_DEAD); |
| | | 4790 | mutex_exit(&key_sad.lock); |
4751 | } else { | | 4791 | } else { |
4752 | key_sa_chgstate(sav, SADB_SASTATE_DYING); | | 4792 | key_sa_chgstate(sav, SADB_SASTATE_DYING); |
| | | 4793 | mutex_exit(&key_sad.lock); |
4753 | /* | | 4794 | /* |
4754 | * XXX If we keep to send expire | | 4795 | * XXX If we keep to send expire |
4755 | * message in the status of | | 4796 | * message in the status of |
4756 | * DYING. Do remove below code. | | 4797 | * DYING. Do remove below code. |
4757 | */ | | 4798 | */ |
4758 | key_expire(sav); | | 4799 | key_expire(sav); |
4759 | } | | 4800 | } |
4760 | goto restart_sav_MATURE; | | 4801 | goto restart_sav_MATURE; |
4761 | } | | 4802 | } |
4762 | /* check SOFT lifetime by bytes */ | | 4803 | /* check SOFT lifetime by bytes */ |
4763 | /* | | 4804 | /* |
4764 | * XXX I don't know the way to delete this SA | | 4805 | * XXX I don't know the way to delete this SA |
4765 | * when new SA is installed. Caution when it's | | 4806 | * when new SA is installed. Caution when it's |
4766 | * installed too big lifetime by time. | | 4807 | * installed too big lifetime by time. |
4767 | */ | | 4808 | */ |
4768 | else if (sav->lft_s->sadb_lifetime_bytes != 0 && | | 4809 | else if (sav->lft_s->sadb_lifetime_bytes != 0 && |
4769 | sav->lft_s->sadb_lifetime_bytes < | | 4810 | sav->lft_s->sadb_lifetime_bytes < |
4770 | sav->lft_c->sadb_lifetime_bytes) { | | 4811 | sav->lft_c->sadb_lifetime_bytes) { |
4771 | | | 4812 | |
4772 | key_sa_chgstate(sav, SADB_SASTATE_DYING); | | 4813 | key_sa_chgstate(sav, SADB_SASTATE_DYING); |
| | | 4814 | mutex_exit(&key_sad.lock); |
4773 | /* | | 4815 | /* |
4774 | * XXX If we keep to send expire | | 4816 | * XXX If we keep to send expire |
4775 | * message in the status of | | 4817 | * message in the status of |
4776 | * DYING. Do remove below code. | | 4818 | * DYING. Do remove below code. |
4777 | */ | | 4819 | */ |
4778 | key_expire(sav); | | 4820 | key_expire(sav); |
4779 | goto restart_sav_MATURE; | | 4821 | goto restart_sav_MATURE; |
4780 | } | | 4822 | } |
4781 | } | | 4823 | } |
| | | 4824 | mutex_exit(&key_sad.lock); |
4782 | | | 4825 | |
4783 | /* check DYING entry to change status to DEAD. */ | | 4826 | /* check DYING entry to change status to DEAD. */ |
| | | 4827 | mutex_enter(&key_sad.lock); |
4784 | restart_sav_DYING: | | 4828 | restart_sav_DYING: |
4785 | SAVLIST_READER_FOREACH(sav, sah, SADB_SASTATE_DYING) { | | 4829 | SAVLIST_WRITER_FOREACH(sav, sah, SADB_SASTATE_DYING) { |
4786 | /* we don't need to check. */ | | 4830 | /* we don't need to check. */ |
4787 | if (sav->lft_h == NULL) | | 4831 | if (sav->lft_h == NULL) |
4788 | continue; | | 4832 | continue; |
4789 | | | 4833 | |
4790 | /* sanity check */ | | 4834 | /* sanity check */ |
4791 | KASSERT(sav->lft_c != NULL); | | 4835 | KASSERT(sav->lft_c != NULL); |
4792 | | | 4836 | |
4793 | if (sav->lft_h->sadb_lifetime_addtime != 0 && | | 4837 | if (sav->lft_h->sadb_lifetime_addtime != 0 && |
4794 | now - sav->created > sav->lft_h->sadb_lifetime_addtime) { | | 4838 | now - sav->created > sav->lft_h->sadb_lifetime_addtime) { |
4795 | key_sa_chgstate(sav, SADB_SASTATE_DEAD); | | 4839 | key_sa_chgstate(sav, SADB_SASTATE_DEAD); |
4796 | goto restart_sav_DYING; | | 4840 | goto restart_sav_DYING; |
4797 | } | | 4841 | } |
4798 | #if 0 /* XXX Should we keep to send expire message until HARD lifetime ? */ | | 4842 | #if 0 /* XXX Should we keep to send expire message until HARD lifetime ? */ |
| @@ -4809,33 +4853,38 @@ restart: | | | @@ -4809,33 +4853,38 @@ restart: |
4809 | * expire message. | | 4853 | * expire message. |
4810 | */ | | 4854 | */ |
4811 | key_expire(sav); | | 4855 | key_expire(sav); |
4812 | } | | 4856 | } |
4813 | #endif | | 4857 | #endif |
4814 | /* check HARD lifetime by bytes */ | | 4858 | /* check HARD lifetime by bytes */ |
4815 | else if (sav->lft_h->sadb_lifetime_bytes != 0 && | | 4859 | else if (sav->lft_h->sadb_lifetime_bytes != 0 && |
4816 | sav->lft_h->sadb_lifetime_bytes < | | 4860 | sav->lft_h->sadb_lifetime_bytes < |
4817 | sav->lft_c->sadb_lifetime_bytes) { | | 4861 | sav->lft_c->sadb_lifetime_bytes) { |
4818 | key_sa_chgstate(sav, SADB_SASTATE_DEAD); | | 4862 | key_sa_chgstate(sav, SADB_SASTATE_DEAD); |
4819 | goto restart_sav_DYING; | | 4863 | goto restart_sav_DYING; |
4820 | } | | 4864 | } |
4821 | } | | 4865 | } |
| | | 4866 | mutex_exit(&key_sad.lock); |
4822 | | | 4867 | |
4823 | /* delete entry in DEAD */ | | 4868 | /* delete entry in DEAD */ |
4824 | restart_sav_DEAD: | | 4869 | restart_sav_DEAD: |
4825 | SAVLIST_READER_FOREACH(sav, sah, SADB_SASTATE_DEAD) { | | 4870 | mutex_enter(&key_sad.lock); |
4826 | KEY_FREESAV(&sav); | | 4871 | SAVLIST_WRITER_FOREACH(sav, sah, SADB_SASTATE_DEAD) { |
| | | 4872 | key_unlink_sav(sav); |
| | | 4873 | mutex_exit(&key_sad.lock); |
| | | 4874 | key_destroy_sav(sav); |
4827 | goto restart_sav_DEAD; | | 4875 | goto restart_sav_DEAD; |
4828 | } | | 4876 | } |
| | | 4877 | mutex_exit(&key_sad.lock); |
4829 | | | 4878 | |
4830 | s = pserialize_read_enter(); | | 4879 | s = pserialize_read_enter(); |
4831 | key_sah_unref(sah); | | 4880 | key_sah_unref(sah); |
4832 | } | | 4881 | } |
4833 | pserialize_read_exit(s); | | 4882 | pserialize_read_exit(s); |
4834 | } | | 4883 | } |
4835 | | | 4884 | |
4836 | static void | | 4885 | static void |
4837 | key_timehandler_acq(time_t now) | | 4886 | key_timehandler_acq(time_t now) |
4838 | { | | 4887 | { |
4839 | #ifndef IPSEC_NONBLOCK_ACQUIRE | | 4888 | #ifndef IPSEC_NONBLOCK_ACQUIRE |
4840 | struct secacq *acq, *nextacq; | | 4889 | struct secacq *acq, *nextacq; |
4841 | | | 4890 | |
| @@ -5110,31 +5159,30 @@ key_api_getspi(struct socket *so, struct | | | @@ -5110,31 +5159,30 @@ key_api_getspi(struct socket *so, struct |
5110 | | | 5159 | |
5111 | /* get a new SA */ | | 5160 | /* get a new SA */ |
5112 | /* XXX rewrite */ | | 5161 | /* XXX rewrite */ |
5113 | newsav = KEY_NEWSAV(m, mhp, &error); | | 5162 | newsav = KEY_NEWSAV(m, mhp, &error); |
5114 | if (newsav == NULL) { | | 5163 | if (newsav == NULL) { |
5115 | key_sah_unref(sah); | | 5164 | key_sah_unref(sah); |
5116 | /* XXX don't free new SA index allocated in above. */ | | 5165 | /* XXX don't free new SA index allocated in above. */ |
5117 | return key_senderror(so, m, error); | | 5166 | return key_senderror(so, m, error); |
5118 | } | | 5167 | } |
5119 | | | 5168 | |
5120 | /* set spi */ | | 5169 | /* set spi */ |
5121 | newsav->spi = htonl(spi); | | 5170 | newsav->spi = htonl(spi); |
5122 | | | 5171 | |
5123 | /* add to satree */ | | 5172 | /* Add to sah#savlist */ |
5124 | newsav->refcnt = 1; | | 5173 | key_init_sav(newsav); |
5125 | newsav->sah = sah; | | 5174 | newsav->sah = sah; |
5126 | newsav->state = SADB_SASTATE_LARVAL; | | 5175 | newsav->state = SADB_SASTATE_LARVAL; |
5127 | SAVLIST_ENTRY_INIT(newsav); | | | |
5128 | mutex_enter(&key_sad.lock); | | 5176 | mutex_enter(&key_sad.lock); |
5129 | SAVLIST_WRITER_INSERT_TAIL(sah, SADB_SASTATE_LARVAL, newsav); | | 5177 | SAVLIST_WRITER_INSERT_TAIL(sah, SADB_SASTATE_LARVAL, newsav); |
5130 | mutex_exit(&key_sad.lock); | | 5178 | mutex_exit(&key_sad.lock); |
5131 | key_validate_savlist(sah, SADB_SASTATE_LARVAL); | | 5179 | key_validate_savlist(sah, SADB_SASTATE_LARVAL); |
5132 | | | 5180 | |
5133 | key_sah_unref(sah); | | 5181 | key_sah_unref(sah); |
5134 | | | 5182 | |
5135 | #ifndef IPSEC_NONBLOCK_ACQUIRE | | 5183 | #ifndef IPSEC_NONBLOCK_ACQUIRE |
5136 | /* delete the entry in key_misc.acqlist */ | | 5184 | /* delete the entry in key_misc.acqlist */ |
5137 | if (mhp->msg->sadb_msg_seq != 0) { | | 5185 | if (mhp->msg->sadb_msg_seq != 0) { |
5138 | struct secacq *acq; | | 5186 | struct secacq *acq; |
5139 | mutex_enter(&key_misc.lock); | | 5187 | mutex_enter(&key_misc.lock); |
5140 | acq = key_getacqbyseq(mhp->msg->sadb_msg_seq); | | 5188 | acq = key_getacqbyseq(mhp->msg->sadb_msg_seq); |
| @@ -5557,42 +5605,40 @@ key_api_update(struct socket *so, struct | | | @@ -5557,42 +5605,40 @@ key_api_update(struct socket *so, struct |
5557 | | | 5605 | |
5558 | error = key_handle_natt_info(newsav, mhp); | | 5606 | error = key_handle_natt_info(newsav, mhp); |
5559 | if (error != 0) { | | 5607 | if (error != 0) { |
5560 | key_delsav(newsav); | | 5608 | key_delsav(newsav); |
5561 | goto error; | | 5609 | goto error; |
5562 | } | | 5610 | } |
5563 | | | 5611 | |
5564 | error = key_init_xform(newsav); | | 5612 | error = key_init_xform(newsav); |
5565 | if (error != 0) { | | 5613 | if (error != 0) { |
5566 | key_delsav(newsav); | | 5614 | key_delsav(newsav); |
5567 | goto error; | | 5615 | goto error; |
5568 | } | | 5616 | } |
5569 | | | 5617 | |
5570 | /* add to satree */ | | 5618 | /* Add to sah#savlist */ |
5571 | newsav->refcnt = 1; | | 5619 | key_init_sav(newsav); |
5572 | newsav->state = SADB_SASTATE_MATURE; | | 5620 | newsav->state = SADB_SASTATE_MATURE; |
5573 | SAVLIST_ENTRY_INIT(newsav); | | | |
5574 | mutex_enter(&key_sad.lock); | | 5621 | mutex_enter(&key_sad.lock); |
5575 | SAVLIST_WRITER_INSERT_TAIL(sah, SADB_SASTATE_MATURE, newsav); | | 5622 | SAVLIST_WRITER_INSERT_TAIL(sah, SADB_SASTATE_MATURE, newsav); |
5576 | mutex_exit(&key_sad.lock); | | 5623 | mutex_exit(&key_sad.lock); |
5577 | key_validate_savlist(sah, SADB_SASTATE_MATURE); | | 5624 | key_validate_savlist(sah, SADB_SASTATE_MATURE); |
5578 | | | 5625 | |
5579 | key_sa_chgstate(sav, SADB_SASTATE_DEAD); | | | |
5580 | KEY_FREESAV(&sav); | | | |
5581 | KEY_FREESAV(&sav); | | | |
5582 | | | | |
5583 | key_sah_unref(sah); | | 5626 | key_sah_unref(sah); |
5584 | sah = NULL; | | 5627 | sah = NULL; |
5585 | | | 5628 | |
| | | 5629 | key_destroy_sav_with_ref(sav); |
| | | 5630 | sav = NULL; |
| | | 5631 | |
5586 | { | | 5632 | { |
5587 | struct mbuf *n; | | 5633 | struct mbuf *n; |
5588 | | | 5634 | |
5589 | /* set msg buf from mhp */ | | 5635 | /* set msg buf from mhp */ |
5590 | n = key_getmsgbuf_x1(m, mhp); | | 5636 | n = key_getmsgbuf_x1(m, mhp); |
5591 | if (n == NULL) { | | 5637 | if (n == NULL) { |
5592 | IPSECLOG(LOG_DEBUG, "No more memory.\n"); | | 5638 | IPSECLOG(LOG_DEBUG, "No more memory.\n"); |
5593 | return key_senderror(so, m, ENOBUFS); | | 5639 | return key_senderror(so, m, ENOBUFS); |
5594 | } | | 5640 | } |
5595 | | | 5641 | |
5596 | m_freem(m); | | 5642 | m_freem(m); |
5597 | return key_sendup_mbuf(so, n, KEY_SENDUP_ALL); | | 5643 | return key_sendup_mbuf(so, n, KEY_SENDUP_ALL); |
5598 | } | | 5644 | } |
| @@ -5755,30 +5801,29 @@ key_api_add(struct socket *so, struct mb | | | @@ -5755,30 +5801,29 @@ key_api_add(struct socket *so, struct mb |
5755 | error = key_handle_natt_info(newsav, mhp); | | 5801 | error = key_handle_natt_info(newsav, mhp); |
5756 | if (error != 0) { | | 5802 | if (error != 0) { |
5757 | key_delsav(newsav); | | 5803 | key_delsav(newsav); |
5758 | error = EINVAL; | | 5804 | error = EINVAL; |
5759 | goto error; | | 5805 | goto error; |
5760 | } | | 5806 | } |
5761 | | | 5807 | |
5762 | error = key_init_xform(newsav); | | 5808 | error = key_init_xform(newsav); |
5763 | if (error != 0) { | | 5809 | if (error != 0) { |
5764 | key_delsav(newsav); | | 5810 | key_delsav(newsav); |
5765 | goto error; | | 5811 | goto error; |
5766 | } | | 5812 | } |
5767 | | | 5813 | |
5768 | /* add to satree */ | | 5814 | /* Add to sah#savlist */ |
5769 | newsav->refcnt = 1; | | 5815 | key_init_sav(newsav); |
5770 | newsav->state = SADB_SASTATE_MATURE; | | 5816 | newsav->state = SADB_SASTATE_MATURE; |
5771 | SAVLIST_ENTRY_INIT(newsav); | | | |
5772 | mutex_enter(&key_sad.lock); | | 5817 | mutex_enter(&key_sad.lock); |
5773 | SAVLIST_WRITER_INSERT_TAIL(sah, SADB_SASTATE_MATURE, newsav); | | 5818 | SAVLIST_WRITER_INSERT_TAIL(sah, SADB_SASTATE_MATURE, newsav); |
5774 | mutex_exit(&key_sad.lock); | | 5819 | mutex_exit(&key_sad.lock); |
5775 | key_validate_savlist(sah, SADB_SASTATE_MATURE); | | 5820 | key_validate_savlist(sah, SADB_SASTATE_MATURE); |
5776 | | | 5821 | |
5777 | key_sah_unref(sah); | | 5822 | key_sah_unref(sah); |
5778 | sah = NULL; | | 5823 | sah = NULL; |
5779 | | | 5824 | |
5780 | /* | | 5825 | /* |
5781 | * don't call key_freesav() here, as we would like to keep the SA | | 5826 | * don't call key_freesav() here, as we would like to keep the SA |
5782 | * in the database on success. | | 5827 | * in the database on success. |
5783 | */ | | 5828 | */ |
5784 | | | 5829 | |
| @@ -5985,29 +6030,28 @@ key_api_delete(struct socket *so, struct | | | @@ -5985,29 +6030,28 @@ key_api_delete(struct socket *so, struct |
5985 | /* get a SA header */ | | 6030 | /* get a SA header */ |
5986 | sah = key_getsah_ref(&saidx, CMP_HEAD); | | 6031 | sah = key_getsah_ref(&saidx, CMP_HEAD); |
5987 | if (sah != NULL) { | | 6032 | if (sah != NULL) { |
5988 | /* get a SA with SPI. */ | | 6033 | /* get a SA with SPI. */ |
5989 | sav = key_getsavbyspi(sah, sa0->sadb_sa_spi); | | 6034 | sav = key_getsavbyspi(sah, sa0->sadb_sa_spi); |
5990 | key_sah_unref(sah); | | 6035 | key_sah_unref(sah); |
5991 | } | | 6036 | } |
5992 | | | 6037 | |
5993 | if (sav == NULL) { | | 6038 | if (sav == NULL) { |
5994 | IPSECLOG(LOG_DEBUG, "no SA found.\n"); | | 6039 | IPSECLOG(LOG_DEBUG, "no SA found.\n"); |
5995 | return key_senderror(so, m, ENOENT); | | 6040 | return key_senderror(so, m, ENOENT); |
5996 | } | | 6041 | } |
5997 | | | 6042 | |
5998 | key_sa_chgstate(sav, SADB_SASTATE_DEAD); | | 6043 | key_destroy_sav_with_ref(sav); |
5999 | KEY_FREESAV(&sav); | | 6044 | sav = NULL; |
6000 | KEY_FREESAV(&sav); | | | |
6001 | | | 6045 | |
6002 | { | | 6046 | { |
6003 | struct mbuf *n; | | 6047 | struct mbuf *n; |
6004 | | | 6048 | |
6005 | /* create new sadb_msg to reply. */ | | 6049 | /* create new sadb_msg to reply. */ |
6006 | n = key_gather_mbuf(m, mhp, 1, 4, SADB_EXT_RESERVED, | | 6050 | n = key_gather_mbuf(m, mhp, 1, 4, SADB_EXT_RESERVED, |
6007 | SADB_EXT_SA, SADB_EXT_ADDRESS_SRC, SADB_EXT_ADDRESS_DST); | | 6051 | SADB_EXT_SA, SADB_EXT_ADDRESS_SRC, SADB_EXT_ADDRESS_DST); |
6008 | if (!n) | | 6052 | if (!n) |
6009 | return key_senderror(so, m, ENOBUFS); | | 6053 | return key_senderror(so, m, ENOBUFS); |
6010 | | | 6054 | |
6011 | n = key_fill_replymsg(n, 0); | | 6055 | n = key_fill_replymsg(n, 0); |
6012 | if (n == NULL) | | 6056 | if (n == NULL) |
6013 | return key_senderror(so, m, ENOBUFS); | | 6057 | return key_senderror(so, m, ENOBUFS); |
| @@ -6039,40 +6083,35 @@ key_delete_all(struct socket *so, struct | | | @@ -6039,40 +6083,35 @@ key_delete_all(struct socket *so, struct |
6039 | return key_senderror(so, m, EINVAL); | | 6083 | return key_senderror(so, m, EINVAL); |
6040 | | | 6084 | |
6041 | error = key_set_natt_ports(&saidx.src, &saidx.dst, mhp); | | 6085 | error = key_set_natt_ports(&saidx.src, &saidx.dst, mhp); |
6042 | if (error != 0) | | 6086 | if (error != 0) |
6043 | return key_senderror(so, m, EINVAL); | | 6087 | return key_senderror(so, m, EINVAL); |
6044 | | | 6088 | |
6045 | sah = key_getsah_ref(&saidx, CMP_HEAD); | | 6089 | sah = key_getsah_ref(&saidx, CMP_HEAD); |
6046 | if (sah != NULL) { | | 6090 | if (sah != NULL) { |
6047 | /* Delete all non-LARVAL SAs. */ | | 6091 | /* Delete all non-LARVAL SAs. */ |
6048 | SASTATE_ALIVE_FOREACH(state) { | | 6092 | SASTATE_ALIVE_FOREACH(state) { |
6049 | if (state == SADB_SASTATE_LARVAL) | | 6093 | if (state == SADB_SASTATE_LARVAL) |
6050 | continue; | | 6094 | continue; |
6051 | restart: | | 6095 | restart: |
| | | 6096 | mutex_enter(&key_sad.lock); |
6052 | SAVLIST_WRITER_FOREACH(sav, sah, state) { | | 6097 | SAVLIST_WRITER_FOREACH(sav, sah, state) { |
6053 | /* sanity check */ | | 6098 | sav->state = SADB_SASTATE_DEAD; |
6054 | if (sav->state != state) { | | 6099 | key_unlink_sav(sav); |
6055 | IPSECLOG(LOG_DEBUG, | | 6100 | mutex_exit(&key_sad.lock); |
6056 | "invalid sav->state " | | 6101 | key_destroy_sav(sav); |
6057 | "(queue: %d SA: %d)\n", | | | |
6058 | state, sav->state); | | | |
6059 | continue; | | | |
6060 | } | | | |
6061 | | | | |
6062 | key_sa_chgstate(sav, SADB_SASTATE_DEAD); | | | |
6063 | KEY_FREESAV(&sav); | | | |
6064 | goto restart; | | 6102 | goto restart; |
6065 | } | | 6103 | } |
| | | 6104 | mutex_exit(&key_sad.lock); |
6066 | } | | 6105 | } |
6067 | key_sah_unref(sah); | | 6106 | key_sah_unref(sah); |
6068 | } | | 6107 | } |
6069 | { | | 6108 | { |
6070 | struct mbuf *n; | | 6109 | struct mbuf *n; |
6071 | | | 6110 | |
6072 | /* create new sadb_msg to reply. */ | | 6111 | /* create new sadb_msg to reply. */ |
6073 | n = key_gather_mbuf(m, mhp, 1, 3, SADB_EXT_RESERVED, | | 6112 | n = key_gather_mbuf(m, mhp, 1, 3, SADB_EXT_RESERVED, |
6074 | SADB_EXT_ADDRESS_SRC, SADB_EXT_ADDRESS_DST); | | 6113 | SADB_EXT_ADDRESS_SRC, SADB_EXT_ADDRESS_DST); |
6075 | if (!n) | | 6114 | if (!n) |
6076 | return key_senderror(so, m, ENOBUFS); | | 6115 | return key_senderror(so, m, ENOBUFS); |
6077 | | | 6116 | |
6078 | n = key_fill_replymsg(n, 0); | | 6117 | n = key_fill_replymsg(n, 0); |
| @@ -7282,31 +7321,35 @@ key_api_flush(struct socket *so, struct | | | @@ -7282,31 +7321,35 @@ key_api_flush(struct socket *so, struct |
7282 | | | 7321 | |
7283 | /* no SATYPE specified, i.e. flushing all SA. */ | | 7322 | /* no SATYPE specified, i.e. flushing all SA. */ |
7284 | s = pserialize_read_enter(); | | 7323 | s = pserialize_read_enter(); |
7285 | SAHLIST_READER_FOREACH(sah) { | | 7324 | SAHLIST_READER_FOREACH(sah) { |
7286 | if (mhp->msg->sadb_msg_satype != SADB_SATYPE_UNSPEC && | | 7325 | if (mhp->msg->sadb_msg_satype != SADB_SATYPE_UNSPEC && |
7287 | proto != sah->saidx.proto) | | 7326 | proto != sah->saidx.proto) |
7288 | continue; | | 7327 | continue; |
7289 | | | 7328 | |
7290 | key_sah_ref(sah); | | 7329 | key_sah_ref(sah); |
7291 | pserialize_read_exit(s); | | 7330 | pserialize_read_exit(s); |
7292 | | | 7331 | |
7293 | SASTATE_ALIVE_FOREACH(state) { | | 7332 | SASTATE_ALIVE_FOREACH(state) { |
7294 | restart: | | 7333 | restart: |
| | | 7334 | mutex_enter(&key_sad.lock); |
7295 | SAVLIST_WRITER_FOREACH(sav, sah, state) { | | 7335 | SAVLIST_WRITER_FOREACH(sav, sah, state) { |
7296 | key_sa_chgstate(sav, SADB_SASTATE_DEAD); | | 7336 | sav->state = SADB_SASTATE_DEAD; |
7297 | KEY_FREESAV(&sav); | | 7337 | key_unlink_sav(sav); |
| | | 7338 | mutex_exit(&key_sad.lock); |
| | | 7339 | key_destroy_sav(sav); |
7298 | goto restart; | | 7340 | goto restart; |
7299 | } | | 7341 | } |
| | | 7342 | mutex_exit(&key_sad.lock); |
7300 | } | | 7343 | } |
7301 | | | 7344 | |
7302 | s = pserialize_read_enter(); | | 7345 | s = pserialize_read_enter(); |
7303 | sah->state = SADB_SASTATE_DEAD; | | 7346 | sah->state = SADB_SASTATE_DEAD; |
7304 | key_sah_unref(sah); | | 7347 | key_sah_unref(sah); |
7305 | } | | 7348 | } |
7306 | pserialize_read_exit(s); | | 7349 | pserialize_read_exit(s); |
7307 | | | 7350 | |
7308 | if (m->m_len < sizeof(struct sadb_msg) || | | 7351 | if (m->m_len < sizeof(struct sadb_msg) || |
7309 | sizeof(struct sadb_msg) > m->m_len + M_TRAILINGSPACE(m)) { | | 7352 | sizeof(struct sadb_msg) > m->m_len + M_TRAILINGSPACE(m)) { |
7310 | IPSECLOG(LOG_DEBUG, "No more memory.\n"); | | 7353 | IPSECLOG(LOG_DEBUG, "No more memory.\n"); |
7311 | return key_senderror(so, m, ENOBUFS); | | 7354 | return key_senderror(so, m, ENOBUFS); |
7312 | } | | 7355 | } |
| @@ -8231,34 +8274,35 @@ key_sa_routechange(struct sockaddr *dst) | | | @@ -8231,34 +8274,35 @@ key_sa_routechange(struct sockaddr *dst) |
8231 | s = pserialize_read_enter(); | | 8274 | s = pserialize_read_enter(); |
8232 | key_sah_unref(sah); | | 8275 | key_sah_unref(sah); |
8233 | } | | 8276 | } |
8234 | pserialize_read_exit(s); | | 8277 | pserialize_read_exit(s); |
8235 | | | 8278 | |
8236 | return; | | 8279 | return; |
8237 | } | | 8280 | } |
8238 | | | 8281 | |
8239 | static void | | 8282 | static void |
8240 | key_sa_chgstate(struct secasvar *sav, u_int8_t state) | | 8283 | key_sa_chgstate(struct secasvar *sav, u_int8_t state) |
8241 | { | | 8284 | { |
8242 | struct secasvar *_sav; | | 8285 | struct secasvar *_sav; |
8243 | | | 8286 | |
8244 | KASSERT(sav != NULL); | | 8287 | ASSERT_SLEEPABLE(); |
| | | 8288 | KASSERT(mutex_owned(&key_sad.lock)); |
8245 | | | 8289 | |
8246 | if (sav->state == state) | | 8290 | if (sav->state == state) |
8247 | return; | | 8291 | return; |
8248 | | | 8292 | |
8249 | SAVLIST_WRITER_REMOVE(sav); | | 8293 | key_unlink_sav(sav); |
8250 | SAVLIST_ENTRY_DESTROY(sav); | | 8294 | SAVLIST_ENTRY_DESTROY(sav); |
8251 | SAVLIST_ENTRY_INIT(sav); | | 8295 | key_init_sav(sav); |
8252 | | | 8296 | |
8253 | sav->state = state; | | 8297 | sav->state = state; |
8254 | if (!SADB_SASTATE_USABLE_P(sav)) { | | 8298 | if (!SADB_SASTATE_USABLE_P(sav)) { |
8255 | /* We don't need to care about the order */ | | 8299 | /* We don't need to care about the order */ |
8256 | SAVLIST_WRITER_INSERT_HEAD(sav->sah, state, sav); | | 8300 | SAVLIST_WRITER_INSERT_HEAD(sav->sah, state, sav); |
8257 | return; | | 8301 | return; |
8258 | } | | 8302 | } |
8259 | /* | | 8303 | /* |
8260 | * Sort the list by lft_c->sadb_lifetime_addtime | | 8304 | * Sort the list by lft_c->sadb_lifetime_addtime |
8261 | * in ascending order. | | 8305 | * in ascending order. |
8262 | */ | | 8306 | */ |
8263 | SAVLIST_READER_FOREACH(_sav, sav->sah, state) { | | 8307 | SAVLIST_READER_FOREACH(_sav, sav->sah, state) { |
8264 | if (_sav->lft_c->sadb_lifetime_addtime > | | 8308 | if (_sav->lft_c->sadb_lifetime_addtime > |