Wed Aug 9 09:48:11 2017 UTC ()
MP-ify SAD (savlist)

localcount(9) is used to protect savlist of sah. The basic design is
similar to MP-ifications of SPD and SAD sahlist. Please read the
locking notes of SAD for more details.


(ozaki-r)
diff -r1.222 -r1.223 src/sys/netipsec/key.c
diff -r1.28 -r1.29 src/sys/netipsec/key.h
diff -r1.19 -r1.20 src/sys/netipsec/keydb.h
diff -r1.71 -r1.72 src/sys/netipsec/xform_ah.c
diff -r1.69 -r1.70 src/sys/netipsec/xform_esp.c
diff -r1.50 -r1.51 src/sys/netipsec/xform_ipcomp.c

cvs diff -r1.222 -r1.223 src/sys/netipsec/key.c (expand / switch to unified diff)

--- src/sys/netipsec/key.c 2017/08/09 08:30:54 1.222
+++ src/sys/netipsec/key.c 2017/08/09 09:48:11 1.223
@@ -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
228static pserialize_t key_spd_psz __read_mostly; 240static pserialize_t key_spd_psz __read_mostly;
229static pserialize_t key_sad_psz __read_mostly; 241static pserialize_t key_sad_psz __read_mostly;
230 242
231/* SPD */ 243/* SPD */
232static struct { 244static 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
633static struct mbuf * key_setspddump_chain (int *errorp, int *lenp, pid_t pid); 645static struct mbuf * key_setspddump_chain (int *errorp, int *lenp, pid_t pid);
634static int key_api_nat_map(struct socket *, struct mbuf *, 646static int key_api_nat_map(struct socket *, struct mbuf *,
635 const struct sadb_msghdr *); 647 const struct sadb_msghdr *);
636static struct mbuf *key_setdumpsp (struct secpolicy *, 648static struct mbuf *key_setdumpsp (struct secpolicy *,
637 u_int8_t, u_int32_t, pid_t); 649 u_int8_t, u_int32_t, pid_t);
638static u_int key_getspreqmsglen (const struct secpolicy *); 650static u_int key_getspreqmsglen (const struct secpolicy *);
639static int key_spdexpire (struct secpolicy *); 651static int key_spdexpire (struct secpolicy *);
640static struct secashead *key_newsah (const struct secasindex *); 652static struct secashead *key_newsah (const struct secasindex *);
641static void key_unlink_sah(struct secashead *); 653static void key_unlink_sah(struct secashead *);
642static void key_destroy_sah(struct secashead *); 654static void key_destroy_sah(struct secashead *);
643static bool key_sah_has_sav(struct secashead *); 655static bool key_sah_has_sav(struct secashead *);
644static void key_sah_ref(struct secashead *); 656static void key_sah_ref(struct secashead *);
645static void key_sah_unref(struct secashead *); 657static void key_sah_unref(struct secashead *);
 658static void key_init_sav(struct secasvar *);
 659static void key_destroy_sav(struct secasvar *);
 660static void key_destroy_sav_with_ref(struct secasvar *);
646static struct secasvar *key_newsav(struct mbuf *, 661static 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__)
650static void key_delsav (struct secasvar *); 665static void key_delsav (struct secasvar *);
651static struct secashead *key_getsah(const struct secasindex *, int); 666static struct secashead *key_getsah(const struct secasindex *, int);
652static struct secashead *key_getsah_ref(const struct secasindex *, int); 667static struct secashead *key_getsah_ref(const struct secasindex *, int);
653static bool key_checkspidup(const struct secasindex *, u_int32_t); 668static bool key_checkspidup(const struct secasindex *, u_int32_t);
654static struct secasvar *key_getsavbyspi (struct secashead *, u_int32_t); 669static struct secasvar *key_getsavbyspi (struct secashead *, u_int32_t);
655static int key_setsaval (struct secasvar *, struct mbuf *, 670static int key_setsaval (struct secasvar *, struct mbuf *,
656 const struct sadb_msghdr *); 671 const struct sadb_msghdr *);
657static void key_freesaval(struct secasvar *); 672static void key_freesaval(struct secasvar *);
658static int key_init_xform(struct secasvar *); 673static 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
766static const char *key_getfqdn (void); 781static const char *key_getfqdn (void);
767static const char *key_getuserfqdn (void); 782static const char *key_getuserfqdn (void);
768#endif 783#endif
769static void key_sa_chgstate (struct secasvar *, u_int8_t); 784static void key_sa_chgstate (struct secasvar *, u_int8_t);
770 785
771static struct mbuf *key_alloc_mbuf (int); 786static struct mbuf *key_alloc_mbuf (int);
772 787
773static void key_timehandler(void *); 788static void key_timehandler(void *);
774static void key_timehandler_work(struct work *, void *); 789static void key_timehandler_work(struct work *, void *);
775static struct callout key_timehandler_ch; 790static struct callout key_timehandler_ch;
776static struct workqueue *key_timehandler_wq; 791static struct workqueue *key_timehandler_wq;
777static struct work key_timehandler_wk; 792static 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 
808u_int 794u_int
809key_sp_refcnt(const struct secpolicy *sp) 795key_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 */
820static void 806static 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 }
1095out: 1081out:
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;
1293done: 1279done:
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
1361void 1347void
1362key_sp_unref(struct secpolicy *sp, const char* where, int tag) 1348key_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
 1360static void
 1361key_init_sav(struct secasvar *sav)
 1362{
 1363
 1364 ASSERT_SLEEPABLE();
 1365
 1366 localcount_init(&sav->localcount);
 1367 SAVLIST_ENTRY_INIT(sav);
 1368}
 1369
1374u_int 1370u_int
1375key_sa_refcnt(const struct secasvar *sav) 1371key_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
1384void 1378void
1385key_sa_ref(struct secasvar *sav, const char* where, int tag) 1379key_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
 1389void
 1390key_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 */
1400static void 1407static void
1401key_freeso(struct socket *so) 1408key_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 */
1475void 1481static void
1476key_freesav(struct secasvar **psav, const char* where, int tag) 1482key_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 */
 1501static void
 1502key_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 */
 1516static void
 1517key_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 */
1503static void 1545static void
1504key_destroy_sp(struct secpolicy *sp) 1546key_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 */
3172static void 3214static void
3173key_delsav(struct secasvar *sav) 3215key_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 */
3191static void 3227static void
3192key_sah_ref(struct secashead *sah) 3228key_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 }
3323out: 3359out:
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
4836static void 4885static void
4837key_timehandler_acq(time_t now) 4886key_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
8239static void 8282static void
8240key_sa_chgstate(struct secasvar *sav, u_int8_t state) 8283key_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 >

cvs diff -r1.28 -r1.29 src/sys/netipsec/key.h (expand / switch to unified diff)

--- src/sys/netipsec/key.h 2017/08/08 08:23:10 1.28
+++ src/sys/netipsec/key.h 2017/08/09 09:48:11 1.29
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: key.h,v 1.28 2017/08/08 08:23:10 ozaki-r Exp $ */ 1/* $NetBSD: key.h,v 1.29 2017/08/09 09:48:11 ozaki-r Exp $ */
2/* $FreeBSD: src/sys/netipsec/key.h,v 1.1.4.1 2003/01/24 05:11:36 sam Exp $ */ 2/* $FreeBSD: src/sys/netipsec/key.h,v 1.1.4.1 2003/01/24 05:11:36 sam Exp $ */
3/* $KAME: key.h,v 1.21 2001/07/27 03:51:30 itojun Exp $ */ 3/* $KAME: key.h,v 1.21 2001/07/27 03:51:30 itojun 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
@@ -51,60 +51,59 @@ int key_havesp(u_int dir); @@ -51,60 +51,59 @@ int key_havesp(u_int dir);
51struct secpolicy *key_lookup_sp_byspidx(const struct secpolicyindex *, u_int, 51struct secpolicy *key_lookup_sp_byspidx(const struct secpolicyindex *, u_int,
52 const char*, int); 52 const char*, int);
53struct secpolicy *key_newsp(const char*, int); 53struct secpolicy *key_newsp(const char*, int);
54struct secpolicy *key_gettunnel(const struct sockaddr *, 54struct secpolicy *key_gettunnel(const struct sockaddr *,
55 const struct sockaddr *, const struct sockaddr *, 55 const struct sockaddr *, const struct sockaddr *,
56 const struct sockaddr *, const char*, int); 56 const struct sockaddr *, const char*, int);
57/* NB: prepend with _ for KAME IPv6 compatbility */ 57/* NB: prepend with _ for KAME IPv6 compatbility */
58void key_init_sp(struct secpolicy *); 58void key_init_sp(struct secpolicy *);
59void key_free_sp(struct secpolicy *); 59void key_free_sp(struct secpolicy *);
60u_int key_sp_refcnt(const struct secpolicy *); 60u_int key_sp_refcnt(const struct secpolicy *);
61void key_sp_ref(struct secpolicy *, const char*, int); 61void key_sp_ref(struct secpolicy *, const char*, int);
62void key_sp_unref(struct secpolicy *, const char*, int); 62void key_sp_unref(struct secpolicy *, const char*, int);
63void key_sa_ref(struct secasvar *, const char*, int); 63void key_sa_ref(struct secasvar *, const char*, int);
 64void key_sa_unref(struct secasvar *, const char*, int);
64u_int key_sa_refcnt(const struct secasvar *); 65u_int key_sa_refcnt(const struct secasvar *);
65 66
66void key_socksplist_add(struct secpolicy *); 67void key_socksplist_add(struct secpolicy *);
67 68
68/* 69/*
69 * Access to the SADB are interlocked with splsoftnet. In particular, 70 * Access to the SADB are interlocked with splsoftnet. In particular,
70 * holders of SA's use this to block accesses by protocol processing 71 * holders of SA's use this to block accesses by protocol processing
71 * that can happen either by network swi's or by continuations that 72 * that can happen either by network swi's or by continuations that
72 * occur on crypto callbacks. Much of this could go away if 73 * occur on crypto callbacks. Much of this could go away if
73 * key_checkrequest were redone. 74 * key_checkrequest were redone.
74 */ 75 */
75#define KEY_LOOKUP_SP_BYSPIDX(spidx, dir) \ 76#define KEY_LOOKUP_SP_BYSPIDX(spidx, dir) \
76 key_lookup_sp_byspidx(spidx, dir, __func__, __LINE__) 77 key_lookup_sp_byspidx(spidx, dir, __func__, __LINE__)
77#define KEY_NEWSP() \ 78#define KEY_NEWSP() \
78 key_newsp(__func__, __LINE__) 79 key_newsp(__func__, __LINE__)
79#define KEY_GETTUNNEL(osrc, odst, isrc, idst) \ 80#define KEY_GETTUNNEL(osrc, odst, isrc, idst) \
80 key_gettunnel(osrc, odst, isrc, idst, __func__, __LINE__) 81 key_gettunnel(osrc, odst, isrc, idst, __func__, __LINE__)
81#define KEY_SP_UNREF(spp) \ 82#define KEY_SP_UNREF(spp) \
82 key_sp_unref(*(spp), __func__, __LINE__) 83 key_sp_unref(*(spp), __func__, __LINE__)
83#define KEY_SP_REF(sp) \ 84#define KEY_SP_REF(sp) \
84 key_sp_ref(sp, __func__, __LINE__) 85 key_sp_ref(sp, __func__, __LINE__)
85#define KEY_SA_REF(sav) \ 86#define KEY_SA_REF(sav) \
86 key_sa_ref(sav, __func__, __LINE__) 87 key_sa_ref(sav, __func__, __LINE__)
87#define KEY_SA_UNREF(psav) \ 88#define KEY_SA_UNREF(psav) \
88 key_freesav(psav, __func__, __LINE__) 89 key_sa_unref(*(psav), __func__, __LINE__)
89 90
90struct secasvar *key_lookup_sa(const union sockaddr_union *, 91struct secasvar *key_lookup_sa(const union sockaddr_union *,
91 u_int, u_int32_t, u_int16_t, u_int16_t, const char*, int); 92 u_int, u_int32_t, u_int16_t, u_int16_t, const char*, int);
92void key_freesav(struct secasvar **, const char*, int); 93void key_freesav(struct secasvar **, const char*, int);
93 94
94#define KEY_LOOKUP_SA(dst, proto, spi, sport, dport) \ 95#define KEY_LOOKUP_SA(dst, proto, spi, sport, dport) \
95 key_lookup_sa(dst, proto, spi, sport, dport, __func__, __LINE__) 96 key_lookup_sa(dst, proto, spi, sport, dport, __func__, __LINE__)
96#define KEY_FREESAV(psav) \ 
97 key_freesav(psav, __func__, __LINE__) 
98 97
99int key_checktunnelsanity (struct secasvar *, u_int, void *, void *); 98int key_checktunnelsanity (struct secasvar *, u_int, void *, void *);
100int key_checkrequest(struct ipsecrequest *, struct secasvar **); 99int key_checkrequest(struct ipsecrequest *, struct secasvar **);
101 100
102struct secpolicy *key_msg2sp (const struct sadb_x_policy *, size_t, int *); 101struct secpolicy *key_msg2sp (const struct sadb_x_policy *, size_t, int *);
103struct mbuf *key_sp2msg (const struct secpolicy *); 102struct mbuf *key_sp2msg (const struct secpolicy *);
104int key_ismyaddr (const struct sockaddr *); 103int key_ismyaddr (const struct sockaddr *);
105int key_spdacquire (const struct secpolicy *); 104int key_spdacquire (const struct secpolicy *);
106u_long key_random (void); 105u_long key_random (void);
107void key_randomfill (void *, size_t); 106void key_randomfill (void *, size_t);
108void key_freereg (struct socket *); 107void key_freereg (struct socket *);
109int key_parse (struct mbuf *, struct socket *); 108int key_parse (struct mbuf *, struct socket *);
110void key_init (void); 109void key_init (void);

cvs diff -r1.19 -r1.20 src/sys/netipsec/keydb.h (expand / switch to unified diff)

--- src/sys/netipsec/keydb.h 2017/08/08 04:17:34 1.19
+++ src/sys/netipsec/keydb.h 2017/08/09 09:48:11 1.20
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: keydb.h,v 1.19 2017/08/08 04:17:34 ozaki-r Exp $ */ 1/* $NetBSD: keydb.h,v 1.20 2017/08/09 09:48:11 ozaki-r Exp $ */
2/* $FreeBSD: src/sys/netipsec/keydb.h,v 1.1.4.1 2003/01/24 05:11:36 sam Exp $ */ 2/* $FreeBSD: src/sys/netipsec/keydb.h,v 1.1.4.1 2003/01/24 05:11:36 sam Exp $ */
3/* $KAME: keydb.h,v 1.14 2000/08/02 17:58:26 sakane Exp $ */ 3/* $KAME: keydb.h,v 1.14 2000/08/02 17:58:26 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
@@ -84,28 +84,28 @@ struct secashead { @@ -84,28 +84,28 @@ struct secashead {
84 /* The first of this list is newer SA */ 84 /* The first of this list is newer SA */
85 85
86 struct route sa_route; /* route cache */ 86 struct route sa_route; /* route cache */
87}; 87};
88 88
89struct xformsw; 89struct xformsw;
90struct enc_xform; 90struct enc_xform;
91struct auth_hash; 91struct auth_hash;
92struct comp_algo; 92struct comp_algo;
93 93
94/* Security Association */ 94/* Security Association */
95struct secasvar { 95struct secasvar {
96 struct pslist_entry pslist_entry; 96 struct pslist_entry pslist_entry;
 97 struct localcount localcount; /* reference count */
97 98
98 u_int refcnt; /* reference count */ 
99 u_int8_t state; /* Status of this Association */ 99 u_int8_t state; /* Status of this Association */
100 100
101 u_int8_t alg_auth; /* Authentication Algorithm Identifier*/ 101 u_int8_t alg_auth; /* Authentication Algorithm Identifier*/
102 u_int8_t alg_enc; /* Cipher Algorithm Identifier */ 102 u_int8_t alg_enc; /* Cipher Algorithm Identifier */
103 u_int8_t alg_comp; /* Compression Algorithm Identifier */ 103 u_int8_t alg_comp; /* Compression Algorithm Identifier */
104 u_int32_t spi; /* SPI Value, network byte order */ 104 u_int32_t spi; /* SPI Value, network byte order */
105 u_int32_t flags; /* holder for SADB_KEY_FLAGS */ 105 u_int32_t flags; /* holder for SADB_KEY_FLAGS */
106 106
107 struct sadb_key *key_auth; /* Key for Authentication */ 107 struct sadb_key *key_auth; /* Key for Authentication */
108 size_t key_auth_len; /* length of key_auth */ 108 size_t key_auth_len; /* length of key_auth */
109 struct sadb_key *key_enc; /* Key for Encryption */ 109 struct sadb_key *key_enc; /* Key for Encryption */
110 size_t key_enc_len; /* length of key_enc */ 110 size_t key_enc_len; /* length of key_enc */
111 u_int ivlen; /* length of IV */ 111 u_int ivlen; /* length of IV */

cvs diff -r1.71 -r1.72 src/sys/netipsec/xform_ah.c (expand / switch to unified diff)

--- src/sys/netipsec/xform_ah.c 2017/08/03 06:32:51 1.71
+++ src/sys/netipsec/xform_ah.c 2017/08/09 09:48:11 1.72
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: xform_ah.c,v 1.71 2017/08/03 06:32:51 ozaki-r Exp $ */ 1/* $NetBSD: xform_ah.c,v 1.72 2017/08/09 09:48:11 ozaki-r Exp $ */
2/* $FreeBSD: src/sys/netipsec/xform_ah.c,v 1.1.4.1 2003/01/24 05:11:36 sam Exp $ */ 2/* $FreeBSD: src/sys/netipsec/xform_ah.c,v 1.1.4.1 2003/01/24 05:11:36 sam Exp $ */
3/* $OpenBSD: ip_ah.c,v 1.63 2001/06/26 06:18:58 angelos Exp $ */ 3/* $OpenBSD: ip_ah.c,v 1.63 2001/06/26 06:18:58 angelos Exp $ */
4/* 4/*
5 * The authors of this code are John Ioannidis (ji@tla.org), 5 * The authors of this code are John Ioannidis (ji@tla.org),
6 * Angelos D. Keromytis (kermit@csd.uch.gr) and 6 * Angelos D. Keromytis (kermit@csd.uch.gr) and
7 * Niels Provos (provos@physnet.uni-hamburg.de). 7 * Niels Provos (provos@physnet.uni-hamburg.de).
8 * 8 *
9 * The original version of this code was written by John Ioannidis 9 * The original version of this code was written by John Ioannidis
10 * for BSD/OS in Athens, Greece, in November 1995. 10 * for BSD/OS in Athens, Greece, in November 1995.
11 * 11 *
12 * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996, 12 * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
13 * by Angelos D. Keromytis. 13 * by Angelos D. Keromytis.
14 * 14 *
@@ -29,27 +29,27 @@ @@ -29,27 +29,27 @@
29 * You may use this code under the GNU public license if you so wish. Please 29 * You may use this code under the GNU public license if you so wish. Please
30 * contribute changes back to the authors under this freer than GPL license 30 * contribute changes back to the authors under this freer than GPL license
31 * so that we may further the use of strong encryption without limitations to 31 * so that we may further the use of strong encryption without limitations to
32 * all. 32 * all.
33 * 33 *
34 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR 34 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
35 * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY 35 * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
36 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE 36 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
37 * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR 37 * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
38 * PURPOSE. 38 * PURPOSE.
39 */ 39 */
40 40
41#include <sys/cdefs.h> 41#include <sys/cdefs.h>
42__KERNEL_RCSID(0, "$NetBSD: xform_ah.c,v 1.71 2017/08/03 06:32:51 ozaki-r Exp $"); 42__KERNEL_RCSID(0, "$NetBSD: xform_ah.c,v 1.72 2017/08/09 09:48:11 ozaki-r Exp $");
43 43
44#if defined(_KERNEL_OPT) 44#if defined(_KERNEL_OPT)
45#include "opt_inet.h" 45#include "opt_inet.h"
46#include "opt_ipsec.h" 46#include "opt_ipsec.h"
47#endif 47#endif
48 48
49#include <sys/param.h> 49#include <sys/param.h>
50#include <sys/systm.h> 50#include <sys/systm.h>
51#include <sys/mbuf.h> 51#include <sys/mbuf.h>
52#include <sys/socket.h> 52#include <sys/socket.h>
53#include <sys/syslog.h> 53#include <sys/syslog.h>
54#include <sys/kernel.h> 54#include <sys/kernel.h>
55#include <sys/sysctl.h> 55#include <sys/sysctl.h>
@@ -723,43 +723,58 @@ ah_input(struct mbuf *m, struct secasvar @@ -723,43 +723,58 @@ ah_input(struct mbuf *m, struct secasvar
723 m_copydata(m, 0, extra, (tc + 1)); 723 m_copydata(m, 0, extra, (tc + 1));
724 /* Zeroize the authenticator on the packet. */ 724 /* Zeroize the authenticator on the packet. */
725 m_copyback(m, skip + rplen, authsize, ipseczeroes); 725 m_copyback(m, skip + rplen, authsize, ipseczeroes);
726 726
727 /* "Massage" the packet headers for crypto processing. */ 727 /* "Massage" the packet headers for crypto processing. */
728 error = ah_massage_headers(&m, sav->sah->saidx.dst.sa.sa_family, 728 error = ah_massage_headers(&m, sav->sah->saidx.dst.sa.sa_family,
729 skip, ahx->type, 0); 729 skip, ahx->type, 0);
730 if (error != 0) { 730 if (error != 0) {
731 /* NB: mbuf is free'd by ah_massage_headers */ 731 /* NB: mbuf is free'd by ah_massage_headers */
732 m = NULL; 732 m = NULL;
733 goto bad; 733 goto bad;
734 } 734 }
735 735
 736 {
 737 int s = pserialize_read_enter();
 738
 739 /*
 740 * Take another reference to the SA for opencrypto callback.
 741 */
 742 if (__predict_false(sav->state == SADB_SASTATE_DEAD)) {
 743 pserialize_read_exit(s);
 744 stat = AH_STAT_NOTDB;
 745 error = ENOENT;
 746 goto bad;
 747 }
 748 KEY_SA_REF(sav);
 749 pserialize_read_exit(s);
 750 }
 751
736 /* Crypto operation descriptor. */ 752 /* Crypto operation descriptor. */
737 crp->crp_ilen = m->m_pkthdr.len; /* Total input length. */ 753 crp->crp_ilen = m->m_pkthdr.len; /* Total input length. */
738 crp->crp_flags = CRYPTO_F_IMBUF; 754 crp->crp_flags = CRYPTO_F_IMBUF;
739 crp->crp_buf = m; 755 crp->crp_buf = m;
740 crp->crp_callback = ah_input_cb; 756 crp->crp_callback = ah_input_cb;
741 crp->crp_sid = sav->tdb_cryptoid; 757 crp->crp_sid = sav->tdb_cryptoid;
742 crp->crp_opaque = tc; 758 crp->crp_opaque = tc;
743 759
744 /* These are passed as-is to the callback. */ 760 /* These are passed as-is to the callback. */
745 tc->tc_spi = sav->spi; 761 tc->tc_spi = sav->spi;
746 tc->tc_dst = sav->sah->saidx.dst; 762 tc->tc_dst = sav->sah->saidx.dst;
747 tc->tc_proto = sav->sah->saidx.proto; 763 tc->tc_proto = sav->sah->saidx.proto;
748 tc->tc_nxt = ah->ah_nxt; 764 tc->tc_nxt = ah->ah_nxt;
749 tc->tc_protoff = protoff; 765 tc->tc_protoff = protoff;
750 tc->tc_skip = skip; 766 tc->tc_skip = skip;
751 tc->tc_sav = sav; 767 tc->tc_sav = sav;
752 KEY_SA_REF(sav); 
753 768
754 DPRINTF(("%s: hash over %d bytes, skip %d: " 769 DPRINTF(("%s: hash over %d bytes, skip %d: "
755 "crda len %d skip %d inject %d\n", __func__, 770 "crda len %d skip %d inject %d\n", __func__,
756 crp->crp_ilen, tc->tc_skip, 771 crp->crp_ilen, tc->tc_skip,
757 crda->crd_len, crda->crd_skip, crda->crd_inject)); 772 crda->crd_len, crda->crd_skip, crda->crd_inject));
758 773
759 return crypto_dispatch(crp); 774 return crypto_dispatch(crp);
760 775
761bad: 776bad:
762 if (tc != NULL) 777 if (tc != NULL)
763 pool_put(&ah_tdb_crypto_pool, tc); 778 pool_put(&ah_tdb_crypto_pool, tc);
764 if (crp != NULL) 779 if (crp != NULL)
765 crypto_freereq(crp); 780 crypto_freereq(crp);
@@ -1134,55 +1149,59 @@ ah_output( @@ -1134,55 +1149,59 @@ ah_output(
1134 /* "Massage" the packet headers for crypto processing. */ 1149 /* "Massage" the packet headers for crypto processing. */
1135 error = ah_massage_headers(&m, sav->sah->saidx.dst.sa.sa_family, 1150 error = ah_massage_headers(&m, sav->sah->saidx.dst.sa.sa_family,
1136 skip, ahx->type, 1); 1151 skip, ahx->type, 1);
1137 if (error != 0) { 1152 if (error != 0) {
1138 m = NULL; /* mbuf was free'd by ah_massage_headers. */ 1153 m = NULL; /* mbuf was free'd by ah_massage_headers. */
1139 pool_put(&ah_tdb_crypto_pool, tc); 1154 pool_put(&ah_tdb_crypto_pool, tc);
1140 crypto_freereq(crp); 1155 crypto_freereq(crp);
1141 goto bad; 1156 goto bad;
1142 } 1157 }
1143 1158
1144 { 1159 {
1145 int s = pserialize_read_enter(); 1160 int s = pserialize_read_enter();
1146 1161
1147 if (__predict_false(isr->sp->state == IPSEC_SPSTATE_DEAD)) { 1162 /*
 1163 * Take another reference to the SP and the SA for opencrypto callback.
 1164 */
 1165 if (__predict_false(isr->sp->state == IPSEC_SPSTATE_DEAD ||
 1166 sav->state == SADB_SASTATE_DEAD)) {
1148 pserialize_read_exit(s); 1167 pserialize_read_exit(s);
1149 pool_put(&ah_tdb_crypto_pool, tc); 1168 pool_put(&ah_tdb_crypto_pool, tc);
1150 crypto_freereq(crp); 1169 crypto_freereq(crp);
1151 AH_STATINC(AH_STAT_NOTDB); 1170 AH_STATINC(AH_STAT_NOTDB);
1152 error = ENOENT; 1171 error = ENOENT;
1153 goto bad; 1172 goto bad;
1154 } 1173 }
1155 KEY_SP_REF(isr->sp); 1174 KEY_SP_REF(isr->sp);
 1175 KEY_SA_REF(sav);
1156 pserialize_read_exit(s); 1176 pserialize_read_exit(s);
1157 } 1177 }
1158 1178
1159 /* Crypto operation descriptor. */ 1179 /* Crypto operation descriptor. */
1160 crp->crp_ilen = m->m_pkthdr.len; /* Total input length. */ 1180 crp->crp_ilen = m->m_pkthdr.len; /* Total input length. */
1161 crp->crp_flags = CRYPTO_F_IMBUF; 1181 crp->crp_flags = CRYPTO_F_IMBUF;
1162 crp->crp_buf = m; 1182 crp->crp_buf = m;
1163 crp->crp_callback = ah_output_cb; 1183 crp->crp_callback = ah_output_cb;
1164 crp->crp_sid = sav->tdb_cryptoid; 1184 crp->crp_sid = sav->tdb_cryptoid;
1165 crp->crp_opaque = tc; 1185 crp->crp_opaque = tc;
1166 1186
1167 /* These are passed as-is to the callback. */ 1187 /* These are passed as-is to the callback. */
1168 tc->tc_isr = isr; 1188 tc->tc_isr = isr;
1169 tc->tc_spi = sav->spi; 1189 tc->tc_spi = sav->spi;
1170 tc->tc_dst = sav->sah->saidx.dst; 1190 tc->tc_dst = sav->sah->saidx.dst;
1171 tc->tc_proto = sav->sah->saidx.proto; 1191 tc->tc_proto = sav->sah->saidx.proto;
1172 tc->tc_skip = skip; 1192 tc->tc_skip = skip;
1173 tc->tc_protoff = protoff; 1193 tc->tc_protoff = protoff;
1174 tc->tc_sav = sav; 1194 tc->tc_sav = sav;
1175 KEY_SA_REF(sav); 
1176 1195
1177 return crypto_dispatch(crp); 1196 return crypto_dispatch(crp);
1178bad: 1197bad:
1179 if (m) 1198 if (m)
1180 m_freem(m); 1199 m_freem(m);
1181 return (error); 1200 return (error);
1182} 1201}
1183 1202
1184/* 1203/*
1185 * AH output callback from the crypto driver. 1204 * AH output callback from the crypto driver.
1186 */ 1205 */
1187static int 1206static int
1188ah_output_cb(struct cryptop *crp) 1207ah_output_cb(struct cryptop *crp)

cvs diff -r1.69 -r1.70 src/sys/netipsec/xform_esp.c (expand / switch to unified diff)

--- src/sys/netipsec/xform_esp.c 2017/08/03 06:32:51 1.69
+++ src/sys/netipsec/xform_esp.c 2017/08/09 09:48:11 1.70
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: xform_esp.c,v 1.69 2017/08/03 06:32:51 ozaki-r Exp $ */ 1/* $NetBSD: xform_esp.c,v 1.70 2017/08/09 09:48:11 ozaki-r Exp $ */
2/* $FreeBSD: src/sys/netipsec/xform_esp.c,v 1.2.2.1 2003/01/24 05:11:36 sam Exp $ */ 2/* $FreeBSD: src/sys/netipsec/xform_esp.c,v 1.2.2.1 2003/01/24 05:11:36 sam Exp $ */
3/* $OpenBSD: ip_esp.c,v 1.69 2001/06/26 06:18:59 angelos Exp $ */ 3/* $OpenBSD: ip_esp.c,v 1.69 2001/06/26 06:18:59 angelos Exp $ */
4 4
5/* 5/*
6 * The authors of this code are John Ioannidis (ji@tla.org), 6 * The authors of this code are John Ioannidis (ji@tla.org),
7 * Angelos D. Keromytis (kermit@csd.uch.gr) and 7 * Angelos D. Keromytis (kermit@csd.uch.gr) and
8 * Niels Provos (provos@physnet.uni-hamburg.de). 8 * Niels Provos (provos@physnet.uni-hamburg.de).
9 * 9 *
10 * The original version of this code was written by John Ioannidis 10 * The original version of this code was written by John Ioannidis
11 * for BSD/OS in Athens, Greece, in November 1995. 11 * for BSD/OS in Athens, Greece, in November 1995.
12 * 12 *
13 * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996, 13 * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
14 * by Angelos D. Keromytis. 14 * by Angelos D. Keromytis.
@@ -29,27 +29,27 @@ @@ -29,27 +29,27 @@
29 * You may use this code under the GNU public license if you so wish. Please 29 * You may use this code under the GNU public license if you so wish. Please
30 * contribute changes back to the authors under this freer than GPL license 30 * contribute changes back to the authors under this freer than GPL license
31 * so that we may further the use of strong encryption without limitations to 31 * so that we may further the use of strong encryption without limitations to
32 * all. 32 * all.
33 * 33 *
34 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR 34 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
35 * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY 35 * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
36 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE 36 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
37 * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR 37 * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
38 * PURPOSE. 38 * PURPOSE.
39 */ 39 */
40 40
41#include <sys/cdefs.h> 41#include <sys/cdefs.h>
42__KERNEL_RCSID(0, "$NetBSD: xform_esp.c,v 1.69 2017/08/03 06:32:51 ozaki-r Exp $"); 42__KERNEL_RCSID(0, "$NetBSD: xform_esp.c,v 1.70 2017/08/09 09:48:11 ozaki-r Exp $");
43 43
44#if defined(_KERNEL_OPT) 44#if defined(_KERNEL_OPT)
45#include "opt_inet.h" 45#include "opt_inet.h"
46#include "opt_ipsec.h" 46#include "opt_ipsec.h"
47#endif 47#endif
48 48
49#include <sys/param.h> 49#include <sys/param.h>
50#include <sys/systm.h> 50#include <sys/systm.h>
51#include <sys/mbuf.h> 51#include <sys/mbuf.h>
52#include <sys/socket.h> 52#include <sys/socket.h>
53#include <sys/syslog.h> 53#include <sys/syslog.h>
54#include <sys/kernel.h> 54#include <sys/kernel.h>
55#include <sys/sysctl.h> 55#include <sys/sysctl.h>
@@ -419,42 +419,58 @@ esp_input(struct mbuf *m, struct secasva @@ -419,42 +419,58 @@ esp_input(struct mbuf *m, struct secasva
419 crda->crd_key = _KEYBUF(sav->key_auth); 419 crda->crd_key = _KEYBUF(sav->key_auth);
420 crda->crd_klen = _KEYBITS(sav->key_auth); 420 crda->crd_klen = _KEYBITS(sav->key_auth);
421 } 421 }
422 422
423 /* Copy the authenticator */ 423 /* Copy the authenticator */
424 m_copydata(m, m->m_pkthdr.len - alen, alen, (tc + 1)); 424 m_copydata(m, m->m_pkthdr.len - alen, alen, (tc + 1));
425 425
426 /* Chain authentication request */ 426 /* Chain authentication request */
427 crde = crda->crd_next; 427 crde = crda->crd_next;
428 } else { 428 } else {
429 crde = crp->crp_desc; 429 crde = crp->crp_desc;
430 } 430 }
431 431
 432 {
 433 int s = pserialize_read_enter();
 434
 435 /*
 436 * Take another reference to the SA for opencrypto callback.
 437 */
 438 if (__predict_false(sav->state == SADB_SASTATE_DEAD)) {
 439 pserialize_read_exit(s);
 440 pool_put(&esp_tdb_crypto_pool, tc);
 441 crypto_freereq(crp);
 442 ESP_STATINC(ESP_STAT_NOTDB);
 443 return ENOENT;
 444 }
 445 KEY_SA_REF(sav);
 446 pserialize_read_exit(s);
 447 }
 448
432 /* Crypto operation descriptor */ 449 /* Crypto operation descriptor */
433 crp->crp_ilen = m->m_pkthdr.len; /* Total input length */ 450 crp->crp_ilen = m->m_pkthdr.len; /* Total input length */
434 crp->crp_flags = CRYPTO_F_IMBUF; 451 crp->crp_flags = CRYPTO_F_IMBUF;
435 crp->crp_buf = m; 452 crp->crp_buf = m;
436 crp->crp_callback = esp_input_cb; 453 crp->crp_callback = esp_input_cb;
437 crp->crp_sid = sav->tdb_cryptoid; 454 crp->crp_sid = sav->tdb_cryptoid;
438 crp->crp_opaque = tc; 455 crp->crp_opaque = tc;
439 456
440 /* These are passed as-is to the callback */ 457 /* These are passed as-is to the callback */
441 tc->tc_spi = sav->spi; 458 tc->tc_spi = sav->spi;
442 tc->tc_dst = sav->sah->saidx.dst; 459 tc->tc_dst = sav->sah->saidx.dst;
443 tc->tc_proto = sav->sah->saidx.proto; 460 tc->tc_proto = sav->sah->saidx.proto;
444 tc->tc_protoff = protoff; 461 tc->tc_protoff = protoff;
445 tc->tc_skip = skip; 462 tc->tc_skip = skip;
446 tc->tc_sav = sav; 463 tc->tc_sav = sav;
447 KEY_SA_REF(sav); 
448 464
449 /* Decryption descriptor */ 465 /* Decryption descriptor */
450 if (espx) { 466 if (espx) {
451 KASSERTMSG(crde != NULL, "null esp crypto descriptor"); 467 KASSERTMSG(crde != NULL, "null esp crypto descriptor");
452 crde->crd_skip = skip + hlen; 468 crde->crd_skip = skip + hlen;
453 if (espx->type == CRYPTO_AES_GMAC) 469 if (espx->type == CRYPTO_AES_GMAC)
454 crde->crd_len = 0; 470 crde->crd_len = 0;
455 else 471 else
456 crde->crd_len = m->m_pkthdr.len - (skip + hlen + alen); 472 crde->crd_len = m->m_pkthdr.len - (skip + hlen + alen);
457 crde->crd_inject = skip + hlen - sav->ivlen; 473 crde->crd_inject = skip + hlen - sav->ivlen;
458 474
459 crde->crd_alg = espx->type; 475 crde->crd_alg = espx->type;
460 crde->crd_key = _KEYBUF(sav->key_enc); 476 crde->crd_key = _KEYBUF(sav->key_enc);
@@ -891,45 +907,49 @@ esp_output( @@ -891,45 +907,49 @@ esp_output(
891 /* IPsec-specific opaque crypto info. */ 907 /* IPsec-specific opaque crypto info. */
892 tc = pool_get(&esp_tdb_crypto_pool, PR_NOWAIT); 908 tc = pool_get(&esp_tdb_crypto_pool, PR_NOWAIT);
893 if (tc == NULL) { 909 if (tc == NULL) {
894 crypto_freereq(crp); 910 crypto_freereq(crp);
895 DPRINTF(("%s: failed to allocate tdb_crypto\n", __func__)); 911 DPRINTF(("%s: failed to allocate tdb_crypto\n", __func__));
896 ESP_STATINC(ESP_STAT_CRYPTO); 912 ESP_STATINC(ESP_STAT_CRYPTO);
897 error = ENOBUFS; 913 error = ENOBUFS;
898 goto bad; 914 goto bad;
899 } 915 }
900 916
901 { 917 {
902 int s = pserialize_read_enter(); 918 int s = pserialize_read_enter();
903 919
904 if (__predict_false(isr->sp->state == IPSEC_SPSTATE_DEAD)) { 920 /*
 921 * Take another reference to the SP and the SA for opencrypto callback.
 922 */
 923 if (__predict_false(isr->sp->state == IPSEC_SPSTATE_DEAD ||
 924 sav->state == SADB_SASTATE_DEAD)) {
905 pserialize_read_exit(s); 925 pserialize_read_exit(s);
906 pool_put(&esp_tdb_crypto_pool, tc); 926 pool_put(&esp_tdb_crypto_pool, tc);
907 crypto_freereq(crp); 927 crypto_freereq(crp);
908 ESP_STATINC(ESP_STAT_NOTDB); 928 ESP_STATINC(ESP_STAT_NOTDB);
909 error = ENOENT; 929 error = ENOENT;
910 goto bad; 930 goto bad;
911 } 931 }
912 KEY_SP_REF(isr->sp); 932 KEY_SP_REF(isr->sp);
 933 KEY_SA_REF(sav);
913 pserialize_read_exit(s); 934 pserialize_read_exit(s);
914 } 935 }
915 936
916 /* Callback parameters */ 937 /* Callback parameters */
917 tc->tc_isr = isr; 938 tc->tc_isr = isr;
918 tc->tc_spi = sav->spi; 939 tc->tc_spi = sav->spi;
919 tc->tc_dst = saidx->dst; 940 tc->tc_dst = saidx->dst;
920 tc->tc_proto = saidx->proto; 941 tc->tc_proto = saidx->proto;
921 tc->tc_sav = sav; 942 tc->tc_sav = sav;
922 KEY_SA_REF(sav); 
923 943
924 /* Crypto operation descriptor. */ 944 /* Crypto operation descriptor. */
925 crp->crp_ilen = m->m_pkthdr.len; /* Total input length. */ 945 crp->crp_ilen = m->m_pkthdr.len; /* Total input length. */
926 crp->crp_flags = CRYPTO_F_IMBUF; 946 crp->crp_flags = CRYPTO_F_IMBUF;
927 crp->crp_buf = m; 947 crp->crp_buf = m;
928 crp->crp_callback = esp_output_cb; 948 crp->crp_callback = esp_output_cb;
929 crp->crp_opaque = tc; 949 crp->crp_opaque = tc;
930 crp->crp_sid = sav->tdb_cryptoid; 950 crp->crp_sid = sav->tdb_cryptoid;
931 951
932 if (esph) { 952 if (esph) {
933 /* Authentication descriptor. */ 953 /* Authentication descriptor. */
934 crda->crd_skip = skip; 954 crda->crd_skip = skip;
935 if (espx && espx->type == CRYPTO_AES_GCM_16) 955 if (espx && espx->type == CRYPTO_AES_GCM_16)

cvs diff -r1.50 -r1.51 src/sys/netipsec/xform_ipcomp.c (expand / switch to unified diff)

--- src/sys/netipsec/xform_ipcomp.c 2017/08/03 06:32:51 1.50
+++ src/sys/netipsec/xform_ipcomp.c 2017/08/09 09:48:11 1.51
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: xform_ipcomp.c,v 1.50 2017/08/03 06:32:51 ozaki-r Exp $ */ 1/* $NetBSD: xform_ipcomp.c,v 1.51 2017/08/09 09:48:11 ozaki-r Exp $ */
2/* $FreeBSD: src/sys/netipsec/xform_ipcomp.c,v 1.1.4.1 2003/01/24 05:11:36 sam Exp $ */ 2/* $FreeBSD: src/sys/netipsec/xform_ipcomp.c,v 1.1.4.1 2003/01/24 05:11:36 sam Exp $ */
3/* $OpenBSD: ip_ipcomp.c,v 1.1 2001/07/05 12:08:52 jjbg Exp $ */ 3/* $OpenBSD: ip_ipcomp.c,v 1.1 2001/07/05 12:08:52 jjbg Exp $ */
4 4
5/* 5/*
6 * Copyright (c) 2001 Jean-Jacques Bernard-Gundol (jj@wabbitt.org) 6 * Copyright (c) 2001 Jean-Jacques Bernard-Gundol (jj@wabbitt.org)
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 11 *
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
@@ -20,27 +20,27 @@ @@ -20,27 +20,27 @@
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33__KERNEL_RCSID(0, "$NetBSD: xform_ipcomp.c,v 1.50 2017/08/03 06:32:51 ozaki-r Exp $"); 33__KERNEL_RCSID(0, "$NetBSD: xform_ipcomp.c,v 1.51 2017/08/09 09:48:11 ozaki-r Exp $");
34 34
35/* IP payload compression protocol (IPComp), see RFC 2393 */ 35/* IP payload compression protocol (IPComp), see RFC 2393 */
36#if defined(_KERNEL_OPT) 36#if defined(_KERNEL_OPT)
37#include "opt_inet.h" 37#include "opt_inet.h"
38#endif 38#endif
39 39
40#include <sys/param.h> 40#include <sys/param.h>
41#include <sys/systm.h> 41#include <sys/systm.h>
42#include <sys/mbuf.h> 42#include <sys/mbuf.h>
43#include <sys/socket.h> 43#include <sys/socket.h>
44#include <sys/kernel.h> 44#include <sys/kernel.h>
45#include <sys/protosw.h> 45#include <sys/protosw.h>
46#include <sys/sysctl.h> 46#include <sys/sysctl.h>
@@ -174,52 +174,68 @@ ipcomp_input(struct mbuf *m, struct seca @@ -174,52 +174,68 @@ ipcomp_input(struct mbuf *m, struct seca
174 return ENOBUFS; 174 return ENOBUFS;
175 } 175 }
176 176
177 error = m_makewritable(&m, 0, m->m_pkthdr.len, M_NOWAIT); 177 error = m_makewritable(&m, 0, m->m_pkthdr.len, M_NOWAIT);
178 if (error) { 178 if (error) {
179 DPRINTF(("%s: m_makewritable failed\n", __func__)); 179 DPRINTF(("%s: m_makewritable failed\n", __func__));
180 m_freem(m); 180 m_freem(m);
181 pool_put(&ipcomp_tdb_crypto_pool, tc); 181 pool_put(&ipcomp_tdb_crypto_pool, tc);
182 crypto_freereq(crp); 182 crypto_freereq(crp);
183 IPCOMP_STATINC(IPCOMP_STAT_CRYPTO); 183 IPCOMP_STATINC(IPCOMP_STAT_CRYPTO);
184 return error; 184 return error;
185 } 185 }
186 186
 187 {
 188 int s = pserialize_read_enter();
 189
 190 /*
 191 * Take another reference to the SA for opencrypto callback.
 192 */
 193 if (__predict_false(sav->state == SADB_SASTATE_DEAD)) {
 194 pserialize_read_exit(s);
 195 pool_put(&ipcomp_tdb_crypto_pool, tc);
 196 crypto_freereq(crp);
 197 IPCOMP_STATINC(IPCOMP_STAT_NOTDB);
 198 return ENOENT;
 199 }
 200 KEY_SA_REF(sav);
 201 pserialize_read_exit(s);
 202 }
 203
187 crdc = crp->crp_desc; 204 crdc = crp->crp_desc;
188 205
189 crdc->crd_skip = skip + hlen; 206 crdc->crd_skip = skip + hlen;
190 crdc->crd_len = m->m_pkthdr.len - (skip + hlen); 207 crdc->crd_len = m->m_pkthdr.len - (skip + hlen);
191 crdc->crd_inject = 0; /* unused */ 208 crdc->crd_inject = 0; /* unused */
192 209
193 /* Decompression operation */ 210 /* Decompression operation */
194 crdc->crd_alg = sav->tdb_compalgxform->type; 211 crdc->crd_alg = sav->tdb_compalgxform->type;
195 212
196 /* Crypto operation descriptor */ 213 /* Crypto operation descriptor */
197 crp->crp_ilen = m->m_pkthdr.len - (skip + hlen); 214 crp->crp_ilen = m->m_pkthdr.len - (skip + hlen);
198 crp->crp_olen = MCLBYTES; /* hint to decompression code */ 215 crp->crp_olen = MCLBYTES; /* hint to decompression code */
199 crp->crp_flags = CRYPTO_F_IMBUF; 216 crp->crp_flags = CRYPTO_F_IMBUF;
200 crp->crp_buf = m; 217 crp->crp_buf = m;
201 crp->crp_callback = ipcomp_input_cb; 218 crp->crp_callback = ipcomp_input_cb;
202 crp->crp_sid = sav->tdb_cryptoid; 219 crp->crp_sid = sav->tdb_cryptoid;
203 crp->crp_opaque = tc; 220 crp->crp_opaque = tc;
204 221
205 /* These are passed as-is to the callback */ 222 /* These are passed as-is to the callback */
206 tc->tc_spi = sav->spi; 223 tc->tc_spi = sav->spi;
207 tc->tc_dst = sav->sah->saidx.dst; 224 tc->tc_dst = sav->sah->saidx.dst;
208 tc->tc_proto = sav->sah->saidx.proto; 225 tc->tc_proto = sav->sah->saidx.proto;
209 tc->tc_protoff = protoff; 226 tc->tc_protoff = protoff;
210 tc->tc_skip = skip; 227 tc->tc_skip = skip;
211 tc->tc_sav = sav; 228 tc->tc_sav = sav;
212 KEY_SA_REF(sav); 
213 229
214 return crypto_dispatch(crp); 230 return crypto_dispatch(crp);
215} 231}
216 232
217#ifdef INET6 233#ifdef INET6
218#define IPSEC_COMMON_INPUT_CB(m, sav, skip, protoff) do { \ 234#define IPSEC_COMMON_INPUT_CB(m, sav, skip, protoff) do { \
219 if (saidx->dst.sa.sa_family == AF_INET6) { \ 235 if (saidx->dst.sa.sa_family == AF_INET6) { \
220 error = ipsec6_common_input_cb(m, sav, skip, protoff); \ 236 error = ipsec6_common_input_cb(m, sav, skip, protoff); \
221 } else { \ 237 } else { \
222 error = ipsec4_common_input_cb(m, sav, skip, protoff); \ 238 error = ipsec4_common_input_cb(m, sav, skip, protoff); \
223 } \ 239 } \
224} while (0) 240} while (0)
225#else 241#else
@@ -473,46 +489,50 @@ ipcomp_output( @@ -473,46 +489,50 @@ ipcomp_output(
473 /* IPsec-specific opaque crypto info */ 489 /* IPsec-specific opaque crypto info */
474 tc = pool_get(&ipcomp_tdb_crypto_pool, PR_NOWAIT); 490 tc = pool_get(&ipcomp_tdb_crypto_pool, PR_NOWAIT);
475 if (tc == NULL) { 491 if (tc == NULL) {
476 IPCOMP_STATINC(IPCOMP_STAT_CRYPTO); 492 IPCOMP_STATINC(IPCOMP_STAT_CRYPTO);
477 DPRINTF(("%s: failed to allocate tdb_crypto\n", __func__)); 493 DPRINTF(("%s: failed to allocate tdb_crypto\n", __func__));
478 crypto_freereq(crp); 494 crypto_freereq(crp);
479 error = ENOBUFS; 495 error = ENOBUFS;
480 goto bad; 496 goto bad;
481 } 497 }
482 498
483 { 499 {
484 int s = pserialize_read_enter(); 500 int s = pserialize_read_enter();
485 501
486 if (__predict_false(isr->sp->state == IPSEC_SPSTATE_DEAD)) { 502 /*
 503 * Take another reference to the SP and the SA for opencrypto callback.
 504 */
 505 if (__predict_false(isr->sp->state == IPSEC_SPSTATE_DEAD ||
 506 sav->state == SADB_SASTATE_DEAD)) {
487 pserialize_read_exit(s); 507 pserialize_read_exit(s);
488 pool_put(&ipcomp_tdb_crypto_pool, tc); 508 pool_put(&ipcomp_tdb_crypto_pool, tc);
489 crypto_freereq(crp); 509 crypto_freereq(crp);
490 IPCOMP_STATINC(IPCOMP_STAT_NOTDB); 510 IPCOMP_STATINC(IPCOMP_STAT_NOTDB);
491 error = ENOENT; 511 error = ENOENT;
492 goto bad; 512 goto bad;
493 } 513 }
494 KEY_SP_REF(isr->sp); 514 KEY_SP_REF(isr->sp);
 515 KEY_SA_REF(sav);
495 pserialize_read_exit(s); 516 pserialize_read_exit(s);
496 } 517 }
497 518
498 tc->tc_isr = isr; 519 tc->tc_isr = isr;
499 tc->tc_spi = sav->spi; 520 tc->tc_spi = sav->spi;
500 tc->tc_dst = sav->sah->saidx.dst; 521 tc->tc_dst = sav->sah->saidx.dst;
501 tc->tc_proto = sav->sah->saidx.proto; 522 tc->tc_proto = sav->sah->saidx.proto;
502 tc->tc_skip = skip; 523 tc->tc_skip = skip;
503 tc->tc_protoff = protoff; 524 tc->tc_protoff = protoff;
504 tc->tc_sav = sav; 525 tc->tc_sav = sav;
505 KEY_SA_REF(sav); 
506 526
507 /* Crypto operation descriptor */ 527 /* Crypto operation descriptor */
508 crp->crp_ilen = m->m_pkthdr.len; /* Total input length */ 528 crp->crp_ilen = m->m_pkthdr.len; /* Total input length */
509 crp->crp_flags = CRYPTO_F_IMBUF; 529 crp->crp_flags = CRYPTO_F_IMBUF;
510 crp->crp_buf = m; 530 crp->crp_buf = m;
511 crp->crp_callback = ipcomp_output_cb; 531 crp->crp_callback = ipcomp_output_cb;
512 crp->crp_opaque = tc; 532 crp->crp_opaque = tc;
513 crp->crp_sid = sav->tdb_cryptoid; 533 crp->crp_sid = sav->tdb_cryptoid;
514 534
515 return crypto_dispatch(crp); 535 return crypto_dispatch(crp);
516bad: 536bad:
517 if (m) 537 if (m)
518 m_freem(m); 538 m_freem(m);