Deleted Added
full compact
key.c (181330) key.c (181803)
1/* $FreeBSD: head/sys/netipsec/key.c 181330 2008-08-05 15:36:50Z vanhu $ */
1/* $FreeBSD: head/sys/netipsec/key.c 181803 2008-08-17 23:27:27Z bz $ */
2/* $KAME: key.c,v 1.191 2001/06/27 10:46:49 sakane Exp $ */
3
4/*-
5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions

--- 81 unchanged lines hidden (view full) ---

91#endif
92
93#include <netipsec/xform.h>
94
95#include <machine/stdarg.h>
96
97/* randomness */
98#include <sys/random.h>
2/* $KAME: key.c,v 1.191 2001/06/27 10:46:49 sakane Exp $ */
3
4/*-
5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions

--- 81 unchanged lines hidden (view full) ---

91#endif
92
93#include <netipsec/xform.h>
94
95#include <machine/stdarg.h>
96
97/* randomness */
98#include <sys/random.h>
99#include <sys/vimage.h>
99
100#define FULLMASK 0xff
101#define _BITS(bytes) ((bytes) << 3)
102
103/*
104 * Note on SA reference counting:
105 * - SAs that are not in DEAD state will have (total external reference + 1)
106 * following value in reference count field. they cannot be freed and are

--- 442 unchanged lines hidden (view full) ---

549 * Return 0 when there are known to be no SP's for the specified
550 * direction. Otherwise return 1. This is used by IPsec code
551 * to optimize performance.
552 */
553int
554key_havesp(u_int dir)
555{
556 return (dir == IPSEC_DIR_INBOUND || dir == IPSEC_DIR_OUTBOUND ?
100
101#define FULLMASK 0xff
102#define _BITS(bytes) ((bytes) << 3)
103
104/*
105 * Note on SA reference counting:
106 * - SAs that are not in DEAD state will have (total external reference + 1)
107 * following value in reference count field. they cannot be freed and are

--- 442 unchanged lines hidden (view full) ---

550 * Return 0 when there are known to be no SP's for the specified
551 * direction. Otherwise return 1. This is used by IPsec code
552 * to optimize performance.
553 */
554int
555key_havesp(u_int dir)
556{
557 return (dir == IPSEC_DIR_INBOUND || dir == IPSEC_DIR_OUTBOUND ?
557 LIST_FIRST(&sptree[dir]) != NULL : 1);
558 LIST_FIRST(&V_sptree[dir]) != NULL : 1);
558}
559
560/* %%% IPsec policy management */
561/*
562 * allocating a SP for OUTBOUND or INBOUND packet.
563 * Must call key_freesp() later.
564 * OUT: NULL: not found
565 * others: found and return the pointer.

--- 11 unchanged lines hidden (view full) ---

577 printf("DP %s from %s:%u\n", __func__, where, tag));
578
579 /* get a SP entry */
580 KEYDEBUG(KEYDEBUG_IPSEC_DATA,
581 printf("*** objects\n");
582 kdebug_secpolicyindex(spidx));
583
584 SPTREE_LOCK();
559}
560
561/* %%% IPsec policy management */
562/*
563 * allocating a SP for OUTBOUND or INBOUND packet.
564 * Must call key_freesp() later.
565 * OUT: NULL: not found
566 * others: found and return the pointer.

--- 11 unchanged lines hidden (view full) ---

578 printf("DP %s from %s:%u\n", __func__, where, tag));
579
580 /* get a SP entry */
581 KEYDEBUG(KEYDEBUG_IPSEC_DATA,
582 printf("*** objects\n");
583 kdebug_secpolicyindex(spidx));
584
585 SPTREE_LOCK();
585 LIST_FOREACH(sp, &sptree[dir], chain) {
586 LIST_FOREACH(sp, &V_sptree[dir], chain) {
586 KEYDEBUG(KEYDEBUG_IPSEC_DATA,
587 printf("*** in SPD\n");
588 kdebug_secpolicyindex(&sp->spidx));
589
590 if (sp->state == IPSEC_SPSTATE_DEAD)
591 continue;
592 if (key_cmpspidx_withmask(&sp->spidx, spidx))
593 goto found;

--- 40 unchanged lines hidden (view full) ---

634
635 /* get a SP entry */
636 KEYDEBUG(KEYDEBUG_IPSEC_DATA,
637 printf("*** objects\n");
638 printf("spi %u proto %u dir %u\n", spi, proto, dir);
639 kdebug_sockaddr(&dst->sa));
640
641 SPTREE_LOCK();
587 KEYDEBUG(KEYDEBUG_IPSEC_DATA,
588 printf("*** in SPD\n");
589 kdebug_secpolicyindex(&sp->spidx));
590
591 if (sp->state == IPSEC_SPSTATE_DEAD)
592 continue;
593 if (key_cmpspidx_withmask(&sp->spidx, spidx))
594 goto found;

--- 40 unchanged lines hidden (view full) ---

635
636 /* get a SP entry */
637 KEYDEBUG(KEYDEBUG_IPSEC_DATA,
638 printf("*** objects\n");
639 printf("spi %u proto %u dir %u\n", spi, proto, dir);
640 kdebug_sockaddr(&dst->sa));
641
642 SPTREE_LOCK();
642 LIST_FOREACH(sp, &sptree[dir], chain) {
643 LIST_FOREACH(sp, &V_sptree[dir], chain) {
643 KEYDEBUG(KEYDEBUG_IPSEC_DATA,
644 printf("*** in SPD\n");
645 kdebug_secpolicyindex(&sp->spidx));
646
647 if (sp->state == IPSEC_SPSTATE_DEAD)
648 continue;
649 /* compare simple values, then dst address */
650 if (sp->spidx.ul_proto != proto)

--- 44 unchanged lines hidden (view full) ---

695 if (isrc->sa_family != idst->sa_family) {
696 ipseclog((LOG_ERR, "%s: protocol family mismatched %d != %d\n.",
697 __func__, isrc->sa_family, idst->sa_family));
698 sp = NULL;
699 goto done;
700 }
701
702 SPTREE_LOCK();
644 KEYDEBUG(KEYDEBUG_IPSEC_DATA,
645 printf("*** in SPD\n");
646 kdebug_secpolicyindex(&sp->spidx));
647
648 if (sp->state == IPSEC_SPSTATE_DEAD)
649 continue;
650 /* compare simple values, then dst address */
651 if (sp->spidx.ul_proto != proto)

--- 44 unchanged lines hidden (view full) ---

696 if (isrc->sa_family != idst->sa_family) {
697 ipseclog((LOG_ERR, "%s: protocol family mismatched %d != %d\n.",
698 __func__, isrc->sa_family, idst->sa_family));
699 sp = NULL;
700 goto done;
701 }
702
703 SPTREE_LOCK();
703 LIST_FOREACH(sp, &sptree[dir], chain) {
704 LIST_FOREACH(sp, &V_sptree[dir], chain) {
704 if (sp->state == IPSEC_SPSTATE_DEAD)
705 continue;
706
707 r1 = r2 = NULL;
708 for (p = sp->req; p; p = p->next) {
709 if (p->saidx.mode != IPSEC_MODE_TUNNEL)
710 continue;
711

--- 142 unchanged lines hidden (view full) ---

854{
855#define N(a) _ARRAYLEN(a)
856 struct secashead *sah;
857 struct secasvar *sav;
858 u_int stateidx, arraysize;
859 const u_int *state_valid;
860
861 SAHTREE_LOCK();
705 if (sp->state == IPSEC_SPSTATE_DEAD)
706 continue;
707
708 r1 = r2 = NULL;
709 for (p = sp->req; p; p = p->next) {
710 if (p->saidx.mode != IPSEC_MODE_TUNNEL)
711 continue;
712

--- 142 unchanged lines hidden (view full) ---

855{
856#define N(a) _ARRAYLEN(a)
857 struct secashead *sah;
858 struct secasvar *sav;
859 u_int stateidx, arraysize;
860 const u_int *state_valid;
861
862 SAHTREE_LOCK();
862 LIST_FOREACH(sah, &sahtree, chain) {
863 LIST_FOREACH(sah, &V_sahtree, chain) {
863 if (sah->state == SADB_SASTATE_DEAD)
864 continue;
865 if (key_cmpsaidx(&sah->saidx, saidx, CMP_MODE_REQID)) {
864 if (sah->state == SADB_SASTATE_DEAD)
865 continue;
866 if (key_cmpsaidx(&sah->saidx, saidx, CMP_MODE_REQID)) {
866 if (key_preferred_oldsa) {
867 if (V_key_preferred_oldsa) {
867 state_valid = saorder_state_valid_prefer_old;
868 arraysize = N(saorder_state_valid_prefer_old);
869 } else {
870 state_valid = saorder_state_valid_prefer_new;
871 arraysize = N(saorder_state_valid_prefer_new);
872 }
873 SAHTREE_UNLOCK();
874 goto found;

--- 48 unchanged lines hidden (view full) ---

923
924 /* Which SA is the better ? */
925
926 IPSEC_ASSERT(candidate->lft_c != NULL,
927 ("null candidate lifetime"));
928 IPSEC_ASSERT(sav->lft_c != NULL, ("null sav lifetime"));
929
930 /* What the best method is to compare ? */
868 state_valid = saorder_state_valid_prefer_old;
869 arraysize = N(saorder_state_valid_prefer_old);
870 } else {
871 state_valid = saorder_state_valid_prefer_new;
872 arraysize = N(saorder_state_valid_prefer_new);
873 }
874 SAHTREE_UNLOCK();
875 goto found;

--- 48 unchanged lines hidden (view full) ---

924
925 /* Which SA is the better ? */
926
927 IPSEC_ASSERT(candidate->lft_c != NULL,
928 ("null candidate lifetime"));
929 IPSEC_ASSERT(sav->lft_c != NULL, ("null sav lifetime"));
930
931 /* What the best method is to compare ? */
931 if (key_preferred_oldsa) {
932 if (V_key_preferred_oldsa) {
932 if (candidate->lft_c->addtime >
933 sav->lft_c->addtime) {
934 candidate = sav;
935 }
936 continue;
937 /*NOTREACHED*/
938 }
939

--- 117 unchanged lines hidden (view full) ---

1057
1058 /*
1059 * searching SAD.
1060 * XXX: to be checked internal IP header somewhere. Also when
1061 * IPsec tunnel packet is received. But ESP tunnel mode is
1062 * encrypted so we can't check internal IP header.
1063 */
1064 SAHTREE_LOCK();
933 if (candidate->lft_c->addtime >
934 sav->lft_c->addtime) {
935 candidate = sav;
936 }
937 continue;
938 /*NOTREACHED*/
939 }
940

--- 117 unchanged lines hidden (view full) ---

1058
1059 /*
1060 * searching SAD.
1061 * XXX: to be checked internal IP header somewhere. Also when
1062 * IPsec tunnel packet is received. But ESP tunnel mode is
1063 * encrypted so we can't check internal IP header.
1064 */
1065 SAHTREE_LOCK();
1065 if (key_preferred_oldsa) {
1066 if (V_key_preferred_oldsa) {
1066 saorder_state_valid = saorder_state_valid_prefer_old;
1067 arraysize = _ARRAYLEN(saorder_state_valid_prefer_old);
1068 } else {
1069 saorder_state_valid = saorder_state_valid_prefer_new;
1070 arraysize = _ARRAYLEN(saorder_state_valid_prefer_new);
1071 }
1067 saorder_state_valid = saorder_state_valid_prefer_old;
1068 arraysize = _ARRAYLEN(saorder_state_valid_prefer_old);
1069 } else {
1070 saorder_state_valid = saorder_state_valid_prefer_new;
1071 arraysize = _ARRAYLEN(saorder_state_valid_prefer_new);
1072 }
1072 LIST_FOREACH(sah, &sahtree, chain) {
1073 LIST_FOREACH(sah, &V_sahtree, chain) {
1073 /* search valid state */
1074 for (stateidx = 0; stateidx < arraysize; stateidx++) {
1075 state = saorder_state_valid[stateidx];
1076 LIST_FOREACH(sav, &sah->savtree[state], chain) {
1077 /* sanity check */
1078 KEY_CHKSASTATE(sav->state, state, __func__);
1079 /* do not return entries w/ unusable state */
1080 if (sav->state != SADB_SASTATE_MATURE &&

--- 184 unchanged lines hidden (view full) ---

1265static struct secpolicy *
1266key_getsp(struct secpolicyindex *spidx)
1267{
1268 struct secpolicy *sp;
1269
1270 IPSEC_ASSERT(spidx != NULL, ("null spidx"));
1271
1272 SPTREE_LOCK();
1074 /* search valid state */
1075 for (stateidx = 0; stateidx < arraysize; stateidx++) {
1076 state = saorder_state_valid[stateidx];
1077 LIST_FOREACH(sav, &sah->savtree[state], chain) {
1078 /* sanity check */
1079 KEY_CHKSASTATE(sav->state, state, __func__);
1080 /* do not return entries w/ unusable state */
1081 if (sav->state != SADB_SASTATE_MATURE &&

--- 184 unchanged lines hidden (view full) ---

1266static struct secpolicy *
1267key_getsp(struct secpolicyindex *spidx)
1268{
1269 struct secpolicy *sp;
1270
1271 IPSEC_ASSERT(spidx != NULL, ("null spidx"));
1272
1273 SPTREE_LOCK();
1273 LIST_FOREACH(sp, &sptree[spidx->dir], chain) {
1274 LIST_FOREACH(sp, &V_sptree[spidx->dir], chain) {
1274 if (sp->state == IPSEC_SPSTATE_DEAD)
1275 continue;
1276 if (key_cmpspidx_exactly(spidx, &sp->spidx)) {
1277 SP_ADDREF(sp);
1278 break;
1279 }
1280 }
1281 SPTREE_UNLOCK();

--- 7 unchanged lines hidden (view full) ---

1289 * others : found, pointer to a SP.
1290 */
1291static struct secpolicy *
1292key_getspbyid(u_int32_t id)
1293{
1294 struct secpolicy *sp;
1295
1296 SPTREE_LOCK();
1275 if (sp->state == IPSEC_SPSTATE_DEAD)
1276 continue;
1277 if (key_cmpspidx_exactly(spidx, &sp->spidx)) {
1278 SP_ADDREF(sp);
1279 break;
1280 }
1281 }
1282 SPTREE_UNLOCK();

--- 7 unchanged lines hidden (view full) ---

1290 * others : found, pointer to a SP.
1291 */
1292static struct secpolicy *
1293key_getspbyid(u_int32_t id)
1294{
1295 struct secpolicy *sp;
1296
1297 SPTREE_LOCK();
1297 LIST_FOREACH(sp, &sptree[IPSEC_DIR_INBOUND], chain) {
1298 LIST_FOREACH(sp, &V_sptree[IPSEC_DIR_INBOUND], chain) {
1298 if (sp->state == IPSEC_SPSTATE_DEAD)
1299 continue;
1300 if (sp->id == id) {
1301 SP_ADDREF(sp);
1302 goto done;
1303 }
1304 }
1305
1299 if (sp->state == IPSEC_SPSTATE_DEAD)
1300 continue;
1301 if (sp->id == id) {
1302 SP_ADDREF(sp);
1303 goto done;
1304 }
1305 }
1306
1306 LIST_FOREACH(sp, &sptree[IPSEC_DIR_OUTBOUND], chain) {
1307 LIST_FOREACH(sp, &V_sptree[IPSEC_DIR_OUTBOUND], chain) {
1307 if (sp->state == IPSEC_SPSTATE_DEAD)
1308 continue;
1309 if (sp->id == id) {
1310 SP_ADDREF(sp);
1311 goto done;
1312 }
1313 }
1314done:

--- 585 unchanged lines hidden (view full) ---

1900
1901 newsp->created = time_second;
1902 newsp->lastused = newsp->created;
1903 newsp->lifetime = lft ? lft->sadb_lifetime_addtime : 0;
1904 newsp->validtime = lft ? lft->sadb_lifetime_usetime : 0;
1905
1906 newsp->refcnt = 1; /* do not reclaim until I say I do */
1907 newsp->state = IPSEC_SPSTATE_ALIVE;
1308 if (sp->state == IPSEC_SPSTATE_DEAD)
1309 continue;
1310 if (sp->id == id) {
1311 SP_ADDREF(sp);
1312 goto done;
1313 }
1314 }
1315done:

--- 585 unchanged lines hidden (view full) ---

1901
1902 newsp->created = time_second;
1903 newsp->lastused = newsp->created;
1904 newsp->lifetime = lft ? lft->sadb_lifetime_addtime : 0;
1905 newsp->validtime = lft ? lft->sadb_lifetime_usetime : 0;
1906
1907 newsp->refcnt = 1; /* do not reclaim until I say I do */
1908 newsp->state = IPSEC_SPSTATE_ALIVE;
1908 LIST_INSERT_TAIL(&sptree[newsp->spidx.dir], newsp, secpolicy, chain);
1909 LIST_INSERT_TAIL(&V_sptree[newsp->spidx.dir], newsp, secpolicy, chain);
1909
1910 /* delete the entry in spacqtree */
1911 if (mhp->msg->sadb_msg_type == SADB_X_SPDUPDATE) {
1912 struct secspacq *spacq = key_getspacq(&spidx);
1913 if (spacq != NULL) {
1914 /* reset counter in order to deletion by timehandler. */
1915 spacq->created = time_second;
1916 spacq->count = 0;

--- 52 unchanged lines hidden (view full) ---

1969 * OUT:
1970 * 0: failure.
1971 * others: success.
1972 */
1973static u_int32_t
1974key_getnewspid()
1975{
1976 u_int32_t newid = 0;
1910
1911 /* delete the entry in spacqtree */
1912 if (mhp->msg->sadb_msg_type == SADB_X_SPDUPDATE) {
1913 struct secspacq *spacq = key_getspacq(&spidx);
1914 if (spacq != NULL) {
1915 /* reset counter in order to deletion by timehandler. */
1916 spacq->created = time_second;
1917 spacq->count = 0;

--- 52 unchanged lines hidden (view full) ---

1970 * OUT:
1971 * 0: failure.
1972 * others: success.
1973 */
1974static u_int32_t
1975key_getnewspid()
1976{
1977 u_int32_t newid = 0;
1977 int count = key_spi_trycnt; /* XXX */
1978 int count = V_key_spi_trycnt; /* XXX */
1978 struct secpolicy *sp;
1979
1980 /* when requesting to allocate spi ranged */
1981 while (count--) {
1979 struct secpolicy *sp;
1980
1981 /* when requesting to allocate spi ranged */
1982 while (count--) {
1982 newid = (policy_id = (policy_id == ~0 ? 1 : policy_id + 1));
1983 newid = (V_policy_id = (V_policy_id == ~0 ? 1 : V_policy_id + 1));
1983
1984 if ((sp = key_getspbyid(newid)) == NULL)
1985 break;
1986
1987 KEY_FREESP(&sp);
1988 }
1989
1990 if (count == 0 || newid == 0) {

--- 270 unchanged lines hidden (view full) ---

2261 IPSEC_ASSERT(sp != NULL, ("null secpolicy"));
2262 IPSEC_ASSERT(sp->req == NULL, ("policy exists"));
2263 IPSEC_ASSERT(sp->policy == IPSEC_POLICY_IPSEC,
2264 ("policy not IPSEC %u", sp->policy));
2265
2266 /* Get an entry to check whether sent message or not. */
2267 newspacq = key_getspacq(&sp->spidx);
2268 if (newspacq != NULL) {
1984
1985 if ((sp = key_getspbyid(newid)) == NULL)
1986 break;
1987
1988 KEY_FREESP(&sp);
1989 }
1990
1991 if (count == 0 || newid == 0) {

--- 270 unchanged lines hidden (view full) ---

2262 IPSEC_ASSERT(sp != NULL, ("null secpolicy"));
2263 IPSEC_ASSERT(sp->req == NULL, ("policy exists"));
2264 IPSEC_ASSERT(sp->policy == IPSEC_POLICY_IPSEC,
2265 ("policy not IPSEC %u", sp->policy));
2266
2267 /* Get an entry to check whether sent message or not. */
2268 newspacq = key_getspacq(&sp->spidx);
2269 if (newspacq != NULL) {
2269 if (key_blockacq_count < newspacq->count) {
2270 if (V_key_blockacq_count < newspacq->count) {
2270 /* reset counter and do send message. */
2271 newspacq->count = 0;
2272 } else {
2273 /* increment counter and do nothing. */
2274 newspacq->count++;
2275 return 0;
2276 }
2277 SPACQ_UNLOCK();

--- 48 unchanged lines hidden (view full) ---

2326 IPSEC_ASSERT(mhp != NULL, ("null msghdr"));
2327 IPSEC_ASSERT(mhp->msg != NULL, ("null msg"));
2328
2329 if (m->m_len != PFKEY_ALIGN8(sizeof(struct sadb_msg)))
2330 return key_senderror(so, m, EINVAL);
2331
2332 for (dir = 0; dir < IPSEC_DIR_MAX; dir++) {
2333 SPTREE_LOCK();
2271 /* reset counter and do send message. */
2272 newspacq->count = 0;
2273 } else {
2274 /* increment counter and do nothing. */
2275 newspacq->count++;
2276 return 0;
2277 }
2278 SPACQ_UNLOCK();

--- 48 unchanged lines hidden (view full) ---

2327 IPSEC_ASSERT(mhp != NULL, ("null msghdr"));
2328 IPSEC_ASSERT(mhp->msg != NULL, ("null msg"));
2329
2330 if (m->m_len != PFKEY_ALIGN8(sizeof(struct sadb_msg)))
2331 return key_senderror(so, m, EINVAL);
2332
2333 for (dir = 0; dir < IPSEC_DIR_MAX; dir++) {
2334 SPTREE_LOCK();
2334 LIST_FOREACH(sp, &sptree[dir], chain)
2335 LIST_FOREACH(sp, &V_sptree[dir], chain)
2335 sp->state = IPSEC_SPSTATE_DEAD;
2336 SPTREE_UNLOCK();
2337 }
2338
2339 if (sizeof(struct sadb_msg) > m->m_len + M_TRAILINGSPACE(m)) {
2340 ipseclog((LOG_DEBUG, "%s: No more memory.\n", __func__));
2341 return key_senderror(so, m, ENOBUFS);
2342 }

--- 34 unchanged lines hidden (view full) ---

2377 IPSEC_ASSERT(so != NULL, ("null socket"));
2378 IPSEC_ASSERT(m != NULL, ("null mbuf"));
2379 IPSEC_ASSERT(mhp != NULL, ("null msghdr"));
2380 IPSEC_ASSERT(mhp->msg != NULL, ("null msg"));
2381
2382 /* search SPD entry and get buffer size. */
2383 cnt = 0;
2384 for (dir = 0; dir < IPSEC_DIR_MAX; dir++) {
2336 sp->state = IPSEC_SPSTATE_DEAD;
2337 SPTREE_UNLOCK();
2338 }
2339
2340 if (sizeof(struct sadb_msg) > m->m_len + M_TRAILINGSPACE(m)) {
2341 ipseclog((LOG_DEBUG, "%s: No more memory.\n", __func__));
2342 return key_senderror(so, m, ENOBUFS);
2343 }

--- 34 unchanged lines hidden (view full) ---

2378 IPSEC_ASSERT(so != NULL, ("null socket"));
2379 IPSEC_ASSERT(m != NULL, ("null mbuf"));
2380 IPSEC_ASSERT(mhp != NULL, ("null msghdr"));
2381 IPSEC_ASSERT(mhp->msg != NULL, ("null msg"));
2382
2383 /* search SPD entry and get buffer size. */
2384 cnt = 0;
2385 for (dir = 0; dir < IPSEC_DIR_MAX; dir++) {
2385 LIST_FOREACH(sp, &sptree[dir], chain) {
2386 LIST_FOREACH(sp, &V_sptree[dir], chain) {
2386 cnt++;
2387 }
2388 }
2389
2390 if (cnt == 0)
2391 return key_senderror(so, m, ENOENT);
2392
2393 for (dir = 0; dir < IPSEC_DIR_MAX; dir++) {
2387 cnt++;
2388 }
2389 }
2390
2391 if (cnt == 0)
2392 return key_senderror(so, m, ENOENT);
2393
2394 for (dir = 0; dir < IPSEC_DIR_MAX; dir++) {
2394 LIST_FOREACH(sp, &sptree[dir], chain) {
2395 LIST_FOREACH(sp, &V_sptree[dir], chain) {
2395 --cnt;
2396 n = key_setdumpsp(sp, SADB_X_SPDDUMP, cnt,
2397 mhp->msg->sadb_msg_pid);
2398
2399 if (n)
2400 key_sendup_mbuf(so, n, KEY_SENDUP_ONE);
2401 }
2402 }

--- 238 unchanged lines hidden (view full) ---

2641 for (i = 0; i < sizeof(newsah->savtree)/sizeof(newsah->savtree[0]); i++)
2642 LIST_INIT(&newsah->savtree[i]);
2643 newsah->saidx = *saidx;
2644
2645 /* add to saidxtree */
2646 newsah->state = SADB_SASTATE_MATURE;
2647
2648 SAHTREE_LOCK();
2396 --cnt;
2397 n = key_setdumpsp(sp, SADB_X_SPDDUMP, cnt,
2398 mhp->msg->sadb_msg_pid);
2399
2400 if (n)
2401 key_sendup_mbuf(so, n, KEY_SENDUP_ONE);
2402 }
2403 }

--- 238 unchanged lines hidden (view full) ---

2642 for (i = 0; i < sizeof(newsah->savtree)/sizeof(newsah->savtree[0]); i++)
2643 LIST_INIT(&newsah->savtree[i]);
2644 newsah->saidx = *saidx;
2645
2646 /* add to saidxtree */
2647 newsah->state = SADB_SASTATE_MATURE;
2648
2649 SAHTREE_LOCK();
2649 LIST_INSERT_HEAD(&sahtree, newsah, chain);
2650 LIST_INSERT_HEAD(&V_sahtree, newsah, chain);
2650 SAHTREE_UNLOCK();
2651 }
2652 return(newsah);
2653}
2654
2655/*
2656 * delete SA index and all SA registerd.
2657 */

--- 5 unchanged lines hidden (view full) ---

2663 u_int stateidx;
2664 int zombie = 0;
2665
2666 IPSEC_ASSERT(sah != NULL, ("NULL sah"));
2667 SAHTREE_LOCK_ASSERT();
2668
2669 /* searching all SA registerd in the secindex. */
2670 for (stateidx = 0;
2651 SAHTREE_UNLOCK();
2652 }
2653 return(newsah);
2654}
2655
2656/*
2657 * delete SA index and all SA registerd.
2658 */

--- 5 unchanged lines hidden (view full) ---

2664 u_int stateidx;
2665 int zombie = 0;
2666
2667 IPSEC_ASSERT(sah != NULL, ("NULL sah"));
2668 SAHTREE_LOCK_ASSERT();
2669
2670 /* searching all SA registerd in the secindex. */
2671 for (stateidx = 0;
2671 stateidx < _ARRAYLEN(saorder_state_any);
2672 stateidx < _ARRAYLEN(V_saorder_state_any);
2672 stateidx++) {
2673 stateidx++) {
2673 u_int state = saorder_state_any[stateidx];
2674 u_int state = V_saorder_state_any[stateidx];
2674 LIST_FOREACH_SAFE(sav, &sah->savtree[state], chain, nextsav) {
2675 if (sav->refcnt == 0) {
2676 /* sanity check */
2677 KEY_CHKSASTATE(state, sav->state, __func__);
2678 KEY_FREESAV(&sav);
2679 } else {
2680 /* give up to delete this sa */
2681 zombie++;

--- 51 unchanged lines hidden (view full) ---

2733 switch (mhp->msg->sadb_msg_type) {
2734 case SADB_GETSPI:
2735 newsav->spi = 0;
2736
2737#ifdef IPSEC_DOSEQCHECK
2738 /* sync sequence number */
2739 if (mhp->msg->sadb_msg_seq == 0)
2740 newsav->seq =
2675 LIST_FOREACH_SAFE(sav, &sah->savtree[state], chain, nextsav) {
2676 if (sav->refcnt == 0) {
2677 /* sanity check */
2678 KEY_CHKSASTATE(state, sav->state, __func__);
2679 KEY_FREESAV(&sav);
2680 } else {
2681 /* give up to delete this sa */
2682 zombie++;

--- 51 unchanged lines hidden (view full) ---

2734 switch (mhp->msg->sadb_msg_type) {
2735 case SADB_GETSPI:
2736 newsav->spi = 0;
2737
2738#ifdef IPSEC_DOSEQCHECK
2739 /* sync sequence number */
2740 if (mhp->msg->sadb_msg_seq == 0)
2741 newsav->seq =
2741 (acq_seq = (acq_seq == ~0 ? 1 : ++acq_seq));
2742 (V_acq_seq = (V_acq_seq == ~0 ? 1 : ++V_acq_seq));
2742 else
2743#endif
2744 newsav->seq = mhp->msg->sadb_msg_seq;
2745 break;
2746
2747 case SADB_ADD:
2748 /* sanity check */
2749 if (mhp->ext[SADB_EXT_SA] == NULL) {

--- 129 unchanged lines hidden (view full) ---

2879 */
2880static struct secashead *
2881key_getsah(saidx)
2882 struct secasindex *saidx;
2883{
2884 struct secashead *sah;
2885
2886 SAHTREE_LOCK();
2743 else
2744#endif
2745 newsav->seq = mhp->msg->sadb_msg_seq;
2746 break;
2747
2748 case SADB_ADD:
2749 /* sanity check */
2750 if (mhp->ext[SADB_EXT_SA] == NULL) {

--- 129 unchanged lines hidden (view full) ---

2880 */
2881static struct secashead *
2882key_getsah(saidx)
2883 struct secasindex *saidx;
2884{
2885 struct secashead *sah;
2886
2887 SAHTREE_LOCK();
2887 LIST_FOREACH(sah, &sahtree, chain) {
2888 LIST_FOREACH(sah, &V_sahtree, chain) {
2888 if (sah->state == SADB_SASTATE_DEAD)
2889 continue;
2890 if (key_cmpsaidx(&sah->saidx, saidx, CMP_REQID))
2891 break;
2892 }
2893 SAHTREE_UNLOCK();
2894
2895 return sah;

--- 19 unchanged lines hidden (view full) ---

2915 ipseclog((LOG_DEBUG, "%s: address family mismatched.\n",
2916 __func__));
2917 return NULL;
2918 }
2919
2920 sav = NULL;
2921 /* check all SAD */
2922 SAHTREE_LOCK();
2889 if (sah->state == SADB_SASTATE_DEAD)
2890 continue;
2891 if (key_cmpsaidx(&sah->saidx, saidx, CMP_REQID))
2892 break;
2893 }
2894 SAHTREE_UNLOCK();
2895
2896 return sah;

--- 19 unchanged lines hidden (view full) ---

2916 ipseclog((LOG_DEBUG, "%s: address family mismatched.\n",
2917 __func__));
2918 return NULL;
2919 }
2920
2921 sav = NULL;
2922 /* check all SAD */
2923 SAHTREE_LOCK();
2923 LIST_FOREACH(sah, &sahtree, chain) {
2924 LIST_FOREACH(sah, &V_sahtree, chain) {
2924 if (!key_ismyaddr((struct sockaddr *)&sah->saidx.dst))
2925 continue;
2926 sav = key_getsavbyspi(sah, spi);
2927 if (sav != NULL)
2928 break;
2929 }
2930 SAHTREE_UNLOCK();
2931

--- 13 unchanged lines hidden (view full) ---

2945{
2946 struct secasvar *sav;
2947 u_int stateidx, state;
2948
2949 sav = NULL;
2950 SAHTREE_LOCK_ASSERT();
2951 /* search all status */
2952 for (stateidx = 0;
2925 if (!key_ismyaddr((struct sockaddr *)&sah->saidx.dst))
2926 continue;
2927 sav = key_getsavbyspi(sah, spi);
2928 if (sav != NULL)
2929 break;
2930 }
2931 SAHTREE_UNLOCK();
2932

--- 13 unchanged lines hidden (view full) ---

2946{
2947 struct secasvar *sav;
2948 u_int stateidx, state;
2949
2950 sav = NULL;
2951 SAHTREE_LOCK_ASSERT();
2952 /* search all status */
2953 for (stateidx = 0;
2953 stateidx < _ARRAYLEN(saorder_state_alive);
2954 stateidx < _ARRAYLEN(V_saorder_state_alive);
2954 stateidx++) {
2955
2955 stateidx++) {
2956
2956 state = saorder_state_alive[stateidx];
2957 state = V_saorder_state_alive[stateidx];
2957 LIST_FOREACH(sav, &sah->savtree[state], chain) {
2958
2959 /* sanity check */
2960 if (sav->state != state) {
2961 ipseclog((LOG_DEBUG, "%s: "
2962 "invalid sav->state (queue: %d SA: %d)\n",
2963 __func__, state, sav->state));
2964 continue;

--- 746 unchanged lines hidden (view full) ---

3711#endif
3712
3713 IPSEC_ASSERT(sa != NULL, ("null sockaddr"));
3714
3715 switch (sa->sa_family) {
3716#ifdef INET
3717 case AF_INET:
3718 sin = (struct sockaddr_in *)sa;
2958 LIST_FOREACH(sav, &sah->savtree[state], chain) {
2959
2960 /* sanity check */
2961 if (sav->state != state) {
2962 ipseclog((LOG_DEBUG, "%s: "
2963 "invalid sav->state (queue: %d SA: %d)\n",
2964 __func__, state, sav->state));
2965 continue;

--- 746 unchanged lines hidden (view full) ---

3712#endif
3713
3714 IPSEC_ASSERT(sa != NULL, ("null sockaddr"));
3715
3716 switch (sa->sa_family) {
3717#ifdef INET
3718 case AF_INET:
3719 sin = (struct sockaddr_in *)sa;
3719 for (ia = in_ifaddrhead.tqh_first; ia;
3720 for (ia = V_in_ifaddrhead.tqh_first; ia;
3720 ia = ia->ia_link.tqe_next)
3721 {
3722 if (sin->sin_family == ia->ia_addr.sin_family &&
3723 sin->sin_len == ia->ia_addr.sin_len &&
3724 sin->sin_addr.s_addr == ia->ia_addr.sin_addr.s_addr)
3725 {
3726 return 1;
3727 }

--- 20 unchanged lines hidden (view full) ---

3748
3749static int
3750key_ismyaddr6(sin6)
3751 struct sockaddr_in6 *sin6;
3752{
3753 struct in6_ifaddr *ia;
3754 struct in6_multi *in6m;
3755
3721 ia = ia->ia_link.tqe_next)
3722 {
3723 if (sin->sin_family == ia->ia_addr.sin_family &&
3724 sin->sin_len == ia->ia_addr.sin_len &&
3725 sin->sin_addr.s_addr == ia->ia_addr.sin_addr.s_addr)
3726 {
3727 return 1;
3728 }

--- 20 unchanged lines hidden (view full) ---

3749
3750static int
3751key_ismyaddr6(sin6)
3752 struct sockaddr_in6 *sin6;
3753{
3754 struct in6_ifaddr *ia;
3755 struct in6_multi *in6m;
3756
3756 for (ia = in6_ifaddr; ia; ia = ia->ia_next) {
3757 for (ia = V_in6_ifaddr; ia; ia = ia->ia_next) {
3757 if (key_sockaddrcmp((struct sockaddr *)&sin6,
3758 (struct sockaddr *)&ia->ia_addr, 0) == 0)
3759 return 1;
3760
3761 /*
3762 * XXX Multicast
3763 * XXX why do we care about multlicast here while we don't care
3764 * about IPv4 multicast??

--- 310 unchanged lines hidden (view full) ---

4075 u_int16_t gen = sptree_scangen++;
4076 struct secpolicy *sp;
4077 u_int dir;
4078
4079 /* SPD */
4080 for (dir = 0; dir < IPSEC_DIR_MAX; dir++) {
4081restart:
4082 SPTREE_LOCK();
3758 if (key_sockaddrcmp((struct sockaddr *)&sin6,
3759 (struct sockaddr *)&ia->ia_addr, 0) == 0)
3760 return 1;
3761
3762 /*
3763 * XXX Multicast
3764 * XXX why do we care about multlicast here while we don't care
3765 * about IPv4 multicast??

--- 310 unchanged lines hidden (view full) ---

4076 u_int16_t gen = sptree_scangen++;
4077 struct secpolicy *sp;
4078 u_int dir;
4079
4080 /* SPD */
4081 for (dir = 0; dir < IPSEC_DIR_MAX; dir++) {
4082restart:
4083 SPTREE_LOCK();
4083 LIST_FOREACH(sp, &sptree[dir], chain) {
4084 LIST_FOREACH(sp, &V_sptree[dir], chain) {
4084 if (sp->scangen == gen) /* previously handled */
4085 continue;
4086 sp->scangen = gen;
4087 if (sp->state == IPSEC_SPSTATE_DEAD) {
4088 /* NB: clean entries created by key_spdflush */
4089 SPTREE_UNLOCK();
4090 KEY_FREESP(&sp);
4091 goto restart;

--- 16 unchanged lines hidden (view full) ---

4108static void
4109key_flush_sad(time_t now)
4110{
4111 struct secashead *sah, *nextsah;
4112 struct secasvar *sav, *nextsav;
4113
4114 /* SAD */
4115 SAHTREE_LOCK();
4085 if (sp->scangen == gen) /* previously handled */
4086 continue;
4087 sp->scangen = gen;
4088 if (sp->state == IPSEC_SPSTATE_DEAD) {
4089 /* NB: clean entries created by key_spdflush */
4090 SPTREE_UNLOCK();
4091 KEY_FREESP(&sp);
4092 goto restart;

--- 16 unchanged lines hidden (view full) ---

4109static void
4110key_flush_sad(time_t now)
4111{
4112 struct secashead *sah, *nextsah;
4113 struct secasvar *sav, *nextsav;
4114
4115 /* SAD */
4116 SAHTREE_LOCK();
4116 LIST_FOREACH_SAFE(sah, &sahtree, chain, nextsah) {
4117 LIST_FOREACH_SAFE(sah, &V_sahtree, chain, nextsah) {
4117 /* if sah has been dead, then delete it and process next sah. */
4118 if (sah->state == SADB_SASTATE_DEAD) {
4119 key_delsah(sah);
4120 continue;
4121 }
4122
4123 /* if LARVAL entry doesn't become MATURE, delete it. */
4124 LIST_FOREACH_SAFE(sav, &sah->savtree[SADB_SASTATE_LARVAL], chain, nextsav) {
4118 /* if sah has been dead, then delete it and process next sah. */
4119 if (sah->state == SADB_SASTATE_DEAD) {
4120 key_delsah(sah);
4121 continue;
4122 }
4123
4124 /* if LARVAL entry doesn't become MATURE, delete it. */
4125 LIST_FOREACH_SAFE(sav, &sah->savtree[SADB_SASTATE_LARVAL], chain, nextsav) {
4125 if (now - sav->created > key_larval_lifetime)
4126 if (now - sav->created > V_key_larval_lifetime)
4126 KEY_FREESAV(&sav);
4127 }
4128
4129 /*
4130 * check MATURE entry to start to send expire message
4131 * whether or not.
4132 */
4133 LIST_FOREACH_SAFE(sav, &sah->savtree[SADB_SASTATE_MATURE], chain, nextsav) {

--- 111 unchanged lines hidden (view full) ---

4245
4246static void
4247key_flush_acq(time_t now)
4248{
4249 struct secacq *acq, *nextacq;
4250
4251 /* ACQ tree */
4252 ACQ_LOCK();
4127 KEY_FREESAV(&sav);
4128 }
4129
4130 /*
4131 * check MATURE entry to start to send expire message
4132 * whether or not.
4133 */
4134 LIST_FOREACH_SAFE(sav, &sah->savtree[SADB_SASTATE_MATURE], chain, nextsav) {

--- 111 unchanged lines hidden (view full) ---

4246
4247static void
4248key_flush_acq(time_t now)
4249{
4250 struct secacq *acq, *nextacq;
4251
4252 /* ACQ tree */
4253 ACQ_LOCK();
4253 for (acq = LIST_FIRST(&acqtree); acq != NULL; acq = nextacq) {
4254 for (acq = LIST_FIRST(&V_acqtree); acq != NULL; acq = nextacq) {
4254 nextacq = LIST_NEXT(acq, chain);
4255 nextacq = LIST_NEXT(acq, chain);
4255 if (now - acq->created > key_blockacq_lifetime
4256 if (now - acq->created > V_key_blockacq_lifetime
4256 && __LIST_CHAINED(acq)) {
4257 LIST_REMOVE(acq, chain);
4258 free(acq, M_IPSEC_SAQ);
4259 }
4260 }
4261 ACQ_UNLOCK();
4262}
4263
4264static void
4265key_flush_spacq(time_t now)
4266{
4267 struct secspacq *acq, *nextacq;
4268
4269 /* SP ACQ tree */
4270 SPACQ_LOCK();
4257 && __LIST_CHAINED(acq)) {
4258 LIST_REMOVE(acq, chain);
4259 free(acq, M_IPSEC_SAQ);
4260 }
4261 }
4262 ACQ_UNLOCK();
4263}
4264
4265static void
4266key_flush_spacq(time_t now)
4267{
4268 struct secspacq *acq, *nextacq;
4269
4270 /* SP ACQ tree */
4271 SPACQ_LOCK();
4271 for (acq = LIST_FIRST(&spacqtree); acq != NULL; acq = nextacq) {
4272 for (acq = LIST_FIRST(&V_spacqtree); acq != NULL; acq = nextacq) {
4272 nextacq = LIST_NEXT(acq, chain);
4273 nextacq = LIST_NEXT(acq, chain);
4273 if (now - acq->created > key_blockacq_lifetime
4274 if (now - acq->created > V_key_blockacq_lifetime
4274 && __LIST_CHAINED(acq)) {
4275 LIST_REMOVE(acq, chain);
4276 free(acq, M_IPSEC_SAQ);
4277 }
4278 }
4279 SPACQ_UNLOCK();
4280}
4281

--- 315 unchanged lines hidden (view full) ---

4597 */
4598static u_int32_t
4599key_do_getnewspi(spirange, saidx)
4600 struct sadb_spirange *spirange;
4601 struct secasindex *saidx;
4602{
4603 u_int32_t newspi;
4604 u_int32_t min, max;
4275 && __LIST_CHAINED(acq)) {
4276 LIST_REMOVE(acq, chain);
4277 free(acq, M_IPSEC_SAQ);
4278 }
4279 }
4280 SPACQ_UNLOCK();
4281}
4282

--- 315 unchanged lines hidden (view full) ---

4598 */
4599static u_int32_t
4600key_do_getnewspi(spirange, saidx)
4601 struct sadb_spirange *spirange;
4602 struct secasindex *saidx;
4603{
4604 u_int32_t newspi;
4605 u_int32_t min, max;
4605 int count = key_spi_trycnt;
4606 int count = V_key_spi_trycnt;
4606
4607 /* set spi range to allocate */
4608 if (spirange != NULL) {
4609 min = spirange->sadb_spirange_min;
4610 max = spirange->sadb_spirange_max;
4611 } else {
4607
4608 /* set spi range to allocate */
4609 if (spirange != NULL) {
4610 min = spirange->sadb_spirange_min;
4611 max = spirange->sadb_spirange_max;
4612 } else {
4612 min = key_spi_minval;
4613 max = key_spi_maxval;
4613 min = V_key_spi_minval;
4614 max = V_key_spi_maxval;
4614 }
4615 /* IPCOMP needs 2-byte SPI */
4616 if (saidx->proto == IPPROTO_IPCOMP) {
4617 u_int32_t t;
4618 if (min >= 0x10000)
4619 min = 0xffff;
4620 if (max >= 0x10000)
4621 max = 0xffff;

--- 30 unchanged lines hidden (view full) ---

4652 ipseclog((LOG_DEBUG, "%s: to allocate spi is failed.\n",
4653 __func__));
4654 return 0;
4655 }
4656 }
4657
4658 /* statistics */
4659 keystat.getspi_count =
4615 }
4616 /* IPCOMP needs 2-byte SPI */
4617 if (saidx->proto == IPPROTO_IPCOMP) {
4618 u_int32_t t;
4619 if (min >= 0x10000)
4620 min = 0xffff;
4621 if (max >= 0x10000)
4622 max = 0xffff;

--- 30 unchanged lines hidden (view full) ---

4653 ipseclog((LOG_DEBUG, "%s: to allocate spi is failed.\n",
4654 __func__));
4655 return 0;
4656 }
4657 }
4658
4659 /* statistics */
4660 keystat.getspi_count =
4660 (keystat.getspi_count + key_spi_trycnt - count) / 2;
4661 (keystat.getspi_count + V_key_spi_trycnt - count) / 2;
4661
4662 return newspi;
4663}
4664
4665/*
4666 * SADB_UPDATE processing
4667 * receive
4668 * <base, SA, (SA2), (lifetime(HSC),) address(SD), (address(P),)

--- 506 unchanged lines hidden (view full) ---

5175 src0 = (struct sadb_address *)(mhp->ext[SADB_EXT_ADDRESS_SRC]);
5176 dst0 = (struct sadb_address *)(mhp->ext[SADB_EXT_ADDRESS_DST]);
5177
5178 /* XXX boundary check against sa_len */
5179 KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx);
5180
5181 /* get a SA header */
5182 SAHTREE_LOCK();
4662
4663 return newspi;
4664}
4665
4666/*
4667 * SADB_UPDATE processing
4668 * receive
4669 * <base, SA, (SA2), (lifetime(HSC),) address(SD), (address(P),)

--- 506 unchanged lines hidden (view full) ---

5176 src0 = (struct sadb_address *)(mhp->ext[SADB_EXT_ADDRESS_SRC]);
5177 dst0 = (struct sadb_address *)(mhp->ext[SADB_EXT_ADDRESS_DST]);
5178
5179 /* XXX boundary check against sa_len */
5180 KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx);
5181
5182 /* get a SA header */
5183 SAHTREE_LOCK();
5183 LIST_FOREACH(sah, &sahtree, chain) {
5184 LIST_FOREACH(sah, &V_sahtree, chain) {
5184 if (sah->state == SADB_SASTATE_DEAD)
5185 continue;
5186 if (key_cmpsaidx(&sah->saidx, &saidx, CMP_HEAD) == 0)
5187 continue;
5188
5189 /* get a SA with SPI. */
5190 sav = key_getsavbyspi(sah, sa0->sadb_sa_spi);
5191 if (sav)

--- 51 unchanged lines hidden (view full) ---

5243
5244 src0 = (struct sadb_address *)(mhp->ext[SADB_EXT_ADDRESS_SRC]);
5245 dst0 = (struct sadb_address *)(mhp->ext[SADB_EXT_ADDRESS_DST]);
5246
5247 /* XXX boundary check against sa_len */
5248 KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx);
5249
5250 SAHTREE_LOCK();
5185 if (sah->state == SADB_SASTATE_DEAD)
5186 continue;
5187 if (key_cmpsaidx(&sah->saidx, &saidx, CMP_HEAD) == 0)
5188 continue;
5189
5190 /* get a SA with SPI. */
5191 sav = key_getsavbyspi(sah, sa0->sadb_sa_spi);
5192 if (sav)

--- 51 unchanged lines hidden (view full) ---

5244
5245 src0 = (struct sadb_address *)(mhp->ext[SADB_EXT_ADDRESS_SRC]);
5246 dst0 = (struct sadb_address *)(mhp->ext[SADB_EXT_ADDRESS_DST]);
5247
5248 /* XXX boundary check against sa_len */
5249 KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx);
5250
5251 SAHTREE_LOCK();
5251 LIST_FOREACH(sah, &sahtree, chain) {
5252 LIST_FOREACH(sah, &V_sahtree, chain) {
5252 if (sah->state == SADB_SASTATE_DEAD)
5253 continue;
5254 if (key_cmpsaidx(&sah->saidx, &saidx, CMP_HEAD) == 0)
5255 continue;
5256
5257 /* Delete all non-LARVAL SAs. */
5258 for (stateidx = 0;
5253 if (sah->state == SADB_SASTATE_DEAD)
5254 continue;
5255 if (key_cmpsaidx(&sah->saidx, &saidx, CMP_HEAD) == 0)
5256 continue;
5257
5258 /* Delete all non-LARVAL SAs. */
5259 for (stateidx = 0;
5259 stateidx < _ARRAYLEN(saorder_state_alive);
5260 stateidx < _ARRAYLEN(V_saorder_state_alive);
5260 stateidx++) {
5261 stateidx++) {
5261 state = saorder_state_alive[stateidx];
5262 state = V_saorder_state_alive[stateidx];
5262 if (state == SADB_SASTATE_LARVAL)
5263 continue;
5264 for (sav = LIST_FIRST(&sah->savtree[state]);
5265 sav != NULL; sav = nextsav) {
5266 nextsav = LIST_NEXT(sav, chain);
5267 /* sanity check */
5268 if (sav->state != state) {
5269 ipseclog((LOG_DEBUG, "%s: invalid "

--- 88 unchanged lines hidden (view full) ---

5358 src0 = (struct sadb_address *)mhp->ext[SADB_EXT_ADDRESS_SRC];
5359 dst0 = (struct sadb_address *)mhp->ext[SADB_EXT_ADDRESS_DST];
5360
5361 /* XXX boundary check against sa_len */
5362 KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx);
5363
5364 /* get a SA header */
5365 SAHTREE_LOCK();
5263 if (state == SADB_SASTATE_LARVAL)
5264 continue;
5265 for (sav = LIST_FIRST(&sah->savtree[state]);
5266 sav != NULL; sav = nextsav) {
5267 nextsav = LIST_NEXT(sav, chain);
5268 /* sanity check */
5269 if (sav->state != state) {
5270 ipseclog((LOG_DEBUG, "%s: invalid "

--- 88 unchanged lines hidden (view full) ---

5359 src0 = (struct sadb_address *)mhp->ext[SADB_EXT_ADDRESS_SRC];
5360 dst0 = (struct sadb_address *)mhp->ext[SADB_EXT_ADDRESS_DST];
5361
5362 /* XXX boundary check against sa_len */
5363 KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx);
5364
5365 /* get a SA header */
5366 SAHTREE_LOCK();
5366 LIST_FOREACH(sah, &sahtree, chain) {
5367 LIST_FOREACH(sah, &V_sahtree, chain) {
5367 if (sah->state == SADB_SASTATE_DEAD)
5368 continue;
5369 if (key_cmpsaidx(&sah->saidx, &saidx, CMP_HEAD) == 0)
5370 continue;
5371
5372 /* get a SA with SPI. */
5373 sav = key_getsavbyspi(sah, sa0->sadb_sa_spi);
5374 if (sav)

--- 60 unchanged lines hidden (view full) ---

5435
5436 m = NULL;
5437 for (i = 1; i <= SADB_EALG_MAX; i++) {
5438 algo = esp_algorithm_lookup(i);
5439 if (algo == NULL)
5440 continue;
5441
5442 /* discard algorithms with key size smaller than system min */
5368 if (sah->state == SADB_SASTATE_DEAD)
5369 continue;
5370 if (key_cmpsaidx(&sah->saidx, &saidx, CMP_HEAD) == 0)
5371 continue;
5372
5373 /* get a SA with SPI. */
5374 sav = key_getsavbyspi(sah, sa0->sadb_sa_spi);
5375 if (sav)

--- 60 unchanged lines hidden (view full) ---

5436
5437 m = NULL;
5438 for (i = 1; i <= SADB_EALG_MAX; i++) {
5439 algo = esp_algorithm_lookup(i);
5440 if (algo == NULL)
5441 continue;
5442
5443 /* discard algorithms with key size smaller than system min */
5443 if (_BITS(algo->maxkey) < ipsec_esp_keymin)
5444 if (_BITS(algo->maxkey) < V_ipsec_esp_keymin)
5444 continue;
5445 continue;
5445 if (_BITS(algo->minkey) < ipsec_esp_keymin)
5446 encmin = ipsec_esp_keymin;
5446 if (_BITS(algo->minkey) < V_ipsec_esp_keymin)
5447 encmin = V_ipsec_esp_keymin;
5447 else
5448 encmin = _BITS(algo->minkey);
5449
5448 else
5449 encmin = _BITS(algo->minkey);
5450
5450 if (ipsec_esp_auth)
5451 if (V_ipsec_esp_auth)
5451 m = key_getcomb_ah();
5452 else {
5453 IPSEC_ASSERT(l <= MLEN,
5454 ("l=%u > MLEN=%lu", l, (u_long) MLEN));
5455 MGET(m, M_DONTWAIT, MT_DATA);
5456 if (m) {
5457 M_ALIGN(m, l);
5458 m->m_len = l;

--- 82 unchanged lines hidden (view full) ---

5541 if (i != SADB_AALG_SHA1HMAC && i != SADB_AALG_MD5HMAC)
5542 continue;
5543#endif
5544 algo = ah_algorithm_lookup(i);
5545 if (!algo)
5546 continue;
5547 key_getsizes_ah(algo, i, &minkeysize, &maxkeysize);
5548 /* discard algorithms with key size smaller than system min */
5452 m = key_getcomb_ah();
5453 else {
5454 IPSEC_ASSERT(l <= MLEN,
5455 ("l=%u > MLEN=%lu", l, (u_long) MLEN));
5456 MGET(m, M_DONTWAIT, MT_DATA);
5457 if (m) {
5458 M_ALIGN(m, l);
5459 m->m_len = l;

--- 82 unchanged lines hidden (view full) ---

5542 if (i != SADB_AALG_SHA1HMAC && i != SADB_AALG_MD5HMAC)
5543 continue;
5544#endif
5545 algo = ah_algorithm_lookup(i);
5546 if (!algo)
5547 continue;
5548 key_getsizes_ah(algo, i, &minkeysize, &maxkeysize);
5549 /* discard algorithms with key size smaller than system min */
5549 if (_BITS(minkeysize) < ipsec_ah_keymin)
5550 if (_BITS(minkeysize) < V_ipsec_ah_keymin)
5550 continue;
5551
5552 if (!m) {
5553 IPSEC_ASSERT(l <= MLEN,
5554 ("l=%u > MLEN=%lu", l, (u_long) MLEN));
5555 MGET(m, M_DONTWAIT, MT_DATA);
5556 if (m) {
5557 M_ALIGN(m, l);

--- 142 unchanged lines hidden (view full) ---

5700 /*
5701 * We never do anything about acquirng SA. There is anather
5702 * solution that kernel blocks to send SADB_ACQUIRE message until
5703 * getting something message from IKEd. In later case, to be
5704 * managed with ACQUIRING list.
5705 */
5706 /* Get an entry to check whether sending message or not. */
5707 if ((newacq = key_getacq(saidx)) != NULL) {
5551 continue;
5552
5553 if (!m) {
5554 IPSEC_ASSERT(l <= MLEN,
5555 ("l=%u > MLEN=%lu", l, (u_long) MLEN));
5556 MGET(m, M_DONTWAIT, MT_DATA);
5557 if (m) {
5558 M_ALIGN(m, l);

--- 142 unchanged lines hidden (view full) ---

5701 /*
5702 * We never do anything about acquirng SA. There is anather
5703 * solution that kernel blocks to send SADB_ACQUIRE message until
5704 * getting something message from IKEd. In later case, to be
5705 * managed with ACQUIRING list.
5706 */
5707 /* Get an entry to check whether sending message or not. */
5708 if ((newacq = key_getacq(saidx)) != NULL) {
5708 if (key_blockacq_count < newacq->count) {
5709 if (V_key_blockacq_count < newacq->count) {
5709 /* reset counter and do send message. */
5710 newacq->count = 0;
5711 } else {
5712 /* increment counter and do nothing. */
5713 newacq->count++;
5714 return 0;
5715 }
5716 } else {

--- 141 unchanged lines hidden (view full) ---

5858 newacq = malloc(sizeof(struct secacq), M_IPSEC_SAQ, M_NOWAIT|M_ZERO);
5859 if (newacq == NULL) {
5860 ipseclog((LOG_DEBUG, "%s: No more memory.\n", __func__));
5861 return NULL;
5862 }
5863
5864 /* copy secindex */
5865 bcopy(saidx, &newacq->saidx, sizeof(newacq->saidx));
5710 /* reset counter and do send message. */
5711 newacq->count = 0;
5712 } else {
5713 /* increment counter and do nothing. */
5714 newacq->count++;
5715 return 0;
5716 }
5717 } else {

--- 141 unchanged lines hidden (view full) ---

5859 newacq = malloc(sizeof(struct secacq), M_IPSEC_SAQ, M_NOWAIT|M_ZERO);
5860 if (newacq == NULL) {
5861 ipseclog((LOG_DEBUG, "%s: No more memory.\n", __func__));
5862 return NULL;
5863 }
5864
5865 /* copy secindex */
5866 bcopy(saidx, &newacq->saidx, sizeof(newacq->saidx));
5866 newacq->seq = (acq_seq == ~0 ? 1 : ++acq_seq);
5867 newacq->seq = (V_acq_seq == ~0 ? 1 : ++V_acq_seq);
5867 newacq->created = time_second;
5868 newacq->count = 0;
5869
5870 /* add to acqtree */
5871 ACQ_LOCK();
5868 newacq->created = time_second;
5869 newacq->count = 0;
5870
5871 /* add to acqtree */
5872 ACQ_LOCK();
5872 LIST_INSERT_HEAD(&acqtree, newacq, chain);
5873 LIST_INSERT_HEAD(&V_acqtree, newacq, chain);
5873 ACQ_UNLOCK();
5874
5875 return newacq;
5876}
5877
5878static struct secacq *
5879key_getacq(const struct secasindex *saidx)
5880{
5881 struct secacq *acq;
5882
5883 ACQ_LOCK();
5874 ACQ_UNLOCK();
5875
5876 return newacq;
5877}
5878
5879static struct secacq *
5880key_getacq(const struct secasindex *saidx)
5881{
5882 struct secacq *acq;
5883
5884 ACQ_LOCK();
5884 LIST_FOREACH(acq, &acqtree, chain) {
5885 LIST_FOREACH(acq, &V_acqtree, chain) {
5885 if (key_cmpsaidx(saidx, &acq->saidx, CMP_EXACTLY))
5886 break;
5887 }
5888 ACQ_UNLOCK();
5889
5890 return acq;
5891}
5892
5893static struct secacq *
5894key_getacqbyseq(seq)
5895 u_int32_t seq;
5896{
5897 struct secacq *acq;
5898
5899 ACQ_LOCK();
5886 if (key_cmpsaidx(saidx, &acq->saidx, CMP_EXACTLY))
5887 break;
5888 }
5889 ACQ_UNLOCK();
5890
5891 return acq;
5892}
5893
5894static struct secacq *
5895key_getacqbyseq(seq)
5896 u_int32_t seq;
5897{
5898 struct secacq *acq;
5899
5900 ACQ_LOCK();
5900 LIST_FOREACH(acq, &acqtree, chain) {
5901 LIST_FOREACH(acq, &V_acqtree, chain) {
5901 if (acq->seq == seq)
5902 break;
5903 }
5904 ACQ_UNLOCK();
5905
5906 return acq;
5907}
5908

--- 12 unchanged lines hidden (view full) ---

5921
5922 /* copy secindex */
5923 bcopy(spidx, &acq->spidx, sizeof(acq->spidx));
5924 acq->created = time_second;
5925 acq->count = 0;
5926
5927 /* add to spacqtree */
5928 SPACQ_LOCK();
5902 if (acq->seq == seq)
5903 break;
5904 }
5905 ACQ_UNLOCK();
5906
5907 return acq;
5908}
5909

--- 12 unchanged lines hidden (view full) ---

5922
5923 /* copy secindex */
5924 bcopy(spidx, &acq->spidx, sizeof(acq->spidx));
5925 acq->created = time_second;
5926 acq->count = 0;
5927
5928 /* add to spacqtree */
5929 SPACQ_LOCK();
5929 LIST_INSERT_HEAD(&spacqtree, acq, chain);
5930 LIST_INSERT_HEAD(&V_spacqtree, acq, chain);
5930 SPACQ_UNLOCK();
5931
5932 return acq;
5933}
5934
5935static struct secspacq *
5936key_getspacq(spidx)
5937 struct secpolicyindex *spidx;
5938{
5939 struct secspacq *acq;
5940
5941 SPACQ_LOCK();
5931 SPACQ_UNLOCK();
5932
5933 return acq;
5934}
5935
5936static struct secspacq *
5937key_getspacq(spidx)
5938 struct secpolicyindex *spidx;
5939{
5940 struct secspacq *acq;
5941
5942 SPACQ_LOCK();
5942 LIST_FOREACH(acq, &spacqtree, chain) {
5943 LIST_FOREACH(acq, &V_spacqtree, chain) {
5943 if (key_cmpspidx_exactly(spidx, &acq->spidx)) {
5944 /* NB: return holding spacq_lock */
5945 return acq;
5946 }
5947 }
5948 SPACQ_UNLOCK();
5949
5950 return NULL;

--- 94 unchanged lines hidden (view full) ---

6045 src0 = (struct sadb_address *)mhp->ext[SADB_EXT_ADDRESS_SRC];
6046 dst0 = (struct sadb_address *)mhp->ext[SADB_EXT_ADDRESS_DST];
6047
6048 /* XXX boundary check against sa_len */
6049 KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx);
6050
6051 /* get a SA index */
6052 SAHTREE_LOCK();
5944 if (key_cmpspidx_exactly(spidx, &acq->spidx)) {
5945 /* NB: return holding spacq_lock */
5946 return acq;
5947 }
5948 }
5949 SPACQ_UNLOCK();
5950
5951 return NULL;

--- 94 unchanged lines hidden (view full) ---

6046 src0 = (struct sadb_address *)mhp->ext[SADB_EXT_ADDRESS_SRC];
6047 dst0 = (struct sadb_address *)mhp->ext[SADB_EXT_ADDRESS_DST];
6048
6049 /* XXX boundary check against sa_len */
6050 KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx);
6051
6052 /* get a SA index */
6053 SAHTREE_LOCK();
6053 LIST_FOREACH(sah, &sahtree, chain) {
6054 LIST_FOREACH(sah, &V_sahtree, chain) {
6054 if (sah->state == SADB_SASTATE_DEAD)
6055 continue;
6056 if (key_cmpsaidx(&sah->saidx, &saidx, CMP_MODE_REQID))
6057 break;
6058 }
6059 SAHTREE_UNLOCK();
6060 if (sah != NULL) {
6061 ipseclog((LOG_DEBUG, "%s: a SA exists already.\n", __func__));

--- 32 unchanged lines hidden (view full) ---

6094 struct secreg *reg, *newreg = 0;
6095
6096 IPSEC_ASSERT(so != NULL, ("null socket"));
6097 IPSEC_ASSERT(m != NULL, ("null mbuf"));
6098 IPSEC_ASSERT(mhp != NULL, ("null msghdr"));
6099 IPSEC_ASSERT(mhp->msg != NULL, ("null msg"));
6100
6101 /* check for invalid register message */
6055 if (sah->state == SADB_SASTATE_DEAD)
6056 continue;
6057 if (key_cmpsaidx(&sah->saidx, &saidx, CMP_MODE_REQID))
6058 break;
6059 }
6060 SAHTREE_UNLOCK();
6061 if (sah != NULL) {
6062 ipseclog((LOG_DEBUG, "%s: a SA exists already.\n", __func__));

--- 32 unchanged lines hidden (view full) ---

6095 struct secreg *reg, *newreg = 0;
6096
6097 IPSEC_ASSERT(so != NULL, ("null socket"));
6098 IPSEC_ASSERT(m != NULL, ("null mbuf"));
6099 IPSEC_ASSERT(mhp != NULL, ("null msghdr"));
6100 IPSEC_ASSERT(mhp->msg != NULL, ("null msg"));
6101
6102 /* check for invalid register message */
6102 if (mhp->msg->sadb_msg_satype >= sizeof(regtree)/sizeof(regtree[0]))
6103 if (mhp->msg->sadb_msg_satype >= sizeof(V_regtree)/sizeof(V_regtree[0]))
6103 return key_senderror(so, m, EINVAL);
6104
6105 /* When SATYPE_UNSPEC is specified, only return sabd_supported. */
6106 if (mhp->msg->sadb_msg_satype == SADB_SATYPE_UNSPEC)
6107 goto setmsg;
6108
6109 /* check whether existing or not */
6110 REGTREE_LOCK();
6104 return key_senderror(so, m, EINVAL);
6105
6106 /* When SATYPE_UNSPEC is specified, only return sabd_supported. */
6107 if (mhp->msg->sadb_msg_satype == SADB_SATYPE_UNSPEC)
6108 goto setmsg;
6109
6110 /* check whether existing or not */
6111 REGTREE_LOCK();
6111 LIST_FOREACH(reg, ®tree[mhp->msg->sadb_msg_satype], chain) {
6112 LIST_FOREACH(reg, &V_regtree[mhp->msg->sadb_msg_satype], chain) {
6112 if (reg->so == so) {
6113 REGTREE_UNLOCK();
6114 ipseclog((LOG_DEBUG, "%s: socket exists already.\n",
6115 __func__));
6116 return key_senderror(so, m, EEXIST);
6117 }
6118 }
6119

--- 4 unchanged lines hidden (view full) ---

6124 ipseclog((LOG_DEBUG, "%s: No more memory.\n", __func__));
6125 return key_senderror(so, m, ENOBUFS);
6126 }
6127
6128 newreg->so = so;
6129 ((struct keycb *)sotorawcb(so))->kp_registered++;
6130
6131 /* add regnode to regtree. */
6113 if (reg->so == so) {
6114 REGTREE_UNLOCK();
6115 ipseclog((LOG_DEBUG, "%s: socket exists already.\n",
6116 __func__));
6117 return key_senderror(so, m, EEXIST);
6118 }
6119 }
6120

--- 4 unchanged lines hidden (view full) ---

6125 ipseclog((LOG_DEBUG, "%s: No more memory.\n", __func__));
6126 return key_senderror(so, m, ENOBUFS);
6127 }
6128
6129 newreg->so = so;
6130 ((struct keycb *)sotorawcb(so))->kp_registered++;
6131
6132 /* add regnode to regtree. */
6132 LIST_INSERT_HEAD(®tree[mhp->msg->sadb_msg_satype], newreg, chain);
6133 LIST_INSERT_HEAD(&V_regtree[mhp->msg->sadb_msg_satype], newreg, chain);
6133 REGTREE_UNLOCK();
6134
6135 setmsg:
6136 {
6137 struct mbuf *n;
6138 struct sadb_msg *newmsg;
6139 struct sadb_supported *sup;
6140 u_int len, alen, elen;

--- 111 unchanged lines hidden (view full) ---

6252
6253 /*
6254 * check whether existing or not.
6255 * check all type of SA, because there is a potential that
6256 * one socket is registered to multiple type of SA.
6257 */
6258 REGTREE_LOCK();
6259 for (i = 0; i <= SADB_SATYPE_MAX; i++) {
6134 REGTREE_UNLOCK();
6135
6136 setmsg:
6137 {
6138 struct mbuf *n;
6139 struct sadb_msg *newmsg;
6140 struct sadb_supported *sup;
6141 u_int len, alen, elen;

--- 111 unchanged lines hidden (view full) ---

6253
6254 /*
6255 * check whether existing or not.
6256 * check all type of SA, because there is a potential that
6257 * one socket is registered to multiple type of SA.
6258 */
6259 REGTREE_LOCK();
6260 for (i = 0; i <= SADB_SATYPE_MAX; i++) {
6260 LIST_FOREACH(reg, ®tree[i], chain) {
6261 LIST_FOREACH(reg, &V_regtree[i], chain) {
6261 if (reg->so == so && __LIST_CHAINED(reg)) {
6262 LIST_REMOVE(reg, chain);
6263 free(reg, M_IPSEC_SAR);
6264 break;
6265 }
6266 }
6267 }
6268 REGTREE_UNLOCK();

--- 162 unchanged lines hidden (view full) ---

6431 if ((proto = key_satype2proto(mhp->msg->sadb_msg_satype)) == 0) {
6432 ipseclog((LOG_DEBUG, "%s: invalid satype is passed.\n",
6433 __func__));
6434 return key_senderror(so, m, EINVAL);
6435 }
6436
6437 /* no SATYPE specified, i.e. flushing all SA. */
6438 SAHTREE_LOCK();
6262 if (reg->so == so && __LIST_CHAINED(reg)) {
6263 LIST_REMOVE(reg, chain);
6264 free(reg, M_IPSEC_SAR);
6265 break;
6266 }
6267 }
6268 }
6269 REGTREE_UNLOCK();

--- 162 unchanged lines hidden (view full) ---

6432 if ((proto = key_satype2proto(mhp->msg->sadb_msg_satype)) == 0) {
6433 ipseclog((LOG_DEBUG, "%s: invalid satype is passed.\n",
6434 __func__));
6435 return key_senderror(so, m, EINVAL);
6436 }
6437
6438 /* no SATYPE specified, i.e. flushing all SA. */
6439 SAHTREE_LOCK();
6439 for (sah = LIST_FIRST(&sahtree);
6440 for (sah = LIST_FIRST(&V_sahtree);
6440 sah != NULL;
6441 sah = nextsah) {
6442 nextsah = LIST_NEXT(sah, chain);
6443
6444 if (mhp->msg->sadb_msg_satype != SADB_SATYPE_UNSPEC
6445 && proto != sah->saidx.proto)
6446 continue;
6447
6448 for (stateidx = 0;
6441 sah != NULL;
6442 sah = nextsah) {
6443 nextsah = LIST_NEXT(sah, chain);
6444
6445 if (mhp->msg->sadb_msg_satype != SADB_SATYPE_UNSPEC
6446 && proto != sah->saidx.proto)
6447 continue;
6448
6449 for (stateidx = 0;
6449 stateidx < _ARRAYLEN(saorder_state_alive);
6450 stateidx < _ARRAYLEN(V_saorder_state_alive);
6450 stateidx++) {
6451 stateidx++) {
6451 state = saorder_state_any[stateidx];
6452 state = V_saorder_state_any[stateidx];
6452 for (sav = LIST_FIRST(&sah->savtree[state]);
6453 sav != NULL;
6454 sav = nextsav) {
6455
6456 nextsav = LIST_NEXT(sav, chain);
6457
6458 key_sa_chgstate(sav, SADB_SASTATE_DEAD);
6459 KEY_FREESAV(&sav);

--- 59 unchanged lines hidden (view full) ---

6519 ipseclog((LOG_DEBUG, "%s: invalid satype is passed.\n",
6520 __func__));
6521 return key_senderror(so, m, EINVAL);
6522 }
6523
6524 /* count sav entries to be sent to the userland. */
6525 cnt = 0;
6526 SAHTREE_LOCK();
6453 for (sav = LIST_FIRST(&sah->savtree[state]);
6454 sav != NULL;
6455 sav = nextsav) {
6456
6457 nextsav = LIST_NEXT(sav, chain);
6458
6459 key_sa_chgstate(sav, SADB_SASTATE_DEAD);
6460 KEY_FREESAV(&sav);

--- 59 unchanged lines hidden (view full) ---

6520 ipseclog((LOG_DEBUG, "%s: invalid satype is passed.\n",
6521 __func__));
6522 return key_senderror(so, m, EINVAL);
6523 }
6524
6525 /* count sav entries to be sent to the userland. */
6526 cnt = 0;
6527 SAHTREE_LOCK();
6527 LIST_FOREACH(sah, &sahtree, chain) {
6528 LIST_FOREACH(sah, &V_sahtree, chain) {
6528 if (mhp->msg->sadb_msg_satype != SADB_SATYPE_UNSPEC
6529 && proto != sah->saidx.proto)
6530 continue;
6531
6532 for (stateidx = 0;
6529 if (mhp->msg->sadb_msg_satype != SADB_SATYPE_UNSPEC
6530 && proto != sah->saidx.proto)
6531 continue;
6532
6533 for (stateidx = 0;
6533 stateidx < _ARRAYLEN(saorder_state_any);
6534 stateidx < _ARRAYLEN(V_saorder_state_any);
6534 stateidx++) {
6535 stateidx++) {
6535 state = saorder_state_any[stateidx];
6536 state = V_saorder_state_any[stateidx];
6536 LIST_FOREACH(sav, &sah->savtree[state], chain) {
6537 cnt++;
6538 }
6539 }
6540 }
6541
6542 if (cnt == 0) {
6543 SAHTREE_UNLOCK();
6544 return key_senderror(so, m, ENOENT);
6545 }
6546
6547 /* send this to the userland, one at a time. */
6548 newmsg = NULL;
6537 LIST_FOREACH(sav, &sah->savtree[state], chain) {
6538 cnt++;
6539 }
6540 }
6541 }
6542
6543 if (cnt == 0) {
6544 SAHTREE_UNLOCK();
6545 return key_senderror(so, m, ENOENT);
6546 }
6547
6548 /* send this to the userland, one at a time. */
6549 newmsg = NULL;
6549 LIST_FOREACH(sah, &sahtree, chain) {
6550 LIST_FOREACH(sah, &V_sahtree, chain) {
6550 if (mhp->msg->sadb_msg_satype != SADB_SATYPE_UNSPEC
6551 && proto != sah->saidx.proto)
6552 continue;
6553
6554 /* map proto to satype */
6555 if ((satype = key_proto2satype(sah->saidx.proto)) == 0) {
6556 SAHTREE_UNLOCK();
6557 ipseclog((LOG_DEBUG, "%s: there was invalid proto in "
6558 "SAD.\n", __func__));
6559 return key_senderror(so, m, EINVAL);
6560 }
6561
6562 for (stateidx = 0;
6551 if (mhp->msg->sadb_msg_satype != SADB_SATYPE_UNSPEC
6552 && proto != sah->saidx.proto)
6553 continue;
6554
6555 /* map proto to satype */
6556 if ((satype = key_proto2satype(sah->saidx.proto)) == 0) {
6557 SAHTREE_UNLOCK();
6558 ipseclog((LOG_DEBUG, "%s: there was invalid proto in "
6559 "SAD.\n", __func__));
6560 return key_senderror(so, m, EINVAL);
6561 }
6562
6563 for (stateidx = 0;
6563 stateidx < _ARRAYLEN(saorder_state_any);
6564 stateidx < _ARRAYLEN(V_saorder_state_any);
6564 stateidx++) {
6565 stateidx++) {
6565 state = saorder_state_any[stateidx];
6566 state = V_saorder_state_any[stateidx];
6566 LIST_FOREACH(sav, &sah->savtree[state], chain) {
6567 n = key_setdumpsa(sav, SADB_DUMP, satype,
6568 --cnt, mhp->msg->sadb_msg_pid);
6569 if (!n) {
6570 SAHTREE_UNLOCK();
6571 return key_senderror(so, m, ENOBUFS);
6572 }
6573 key_sendup_mbuf(so, n, KEY_SENDUP_ONE);

--- 127 unchanged lines hidden (view full) ---

6701 }
6702 msg = mtod(m, struct sadb_msg *);
6703 orglen = PFKEY_UNUNIT64(msg->sadb_msg_len);
6704 target = KEY_SENDUP_ONE;
6705
6706 if ((m->m_flags & M_PKTHDR) == 0 ||
6707 m->m_pkthdr.len != m->m_pkthdr.len) {
6708 ipseclog((LOG_DEBUG, "%s: invalid message length.\n",__func__));
6567 LIST_FOREACH(sav, &sah->savtree[state], chain) {
6568 n = key_setdumpsa(sav, SADB_DUMP, satype,
6569 --cnt, mhp->msg->sadb_msg_pid);
6570 if (!n) {
6571 SAHTREE_UNLOCK();
6572 return key_senderror(so, m, ENOBUFS);
6573 }
6574 key_sendup_mbuf(so, n, KEY_SENDUP_ONE);

--- 127 unchanged lines hidden (view full) ---

6702 }
6703 msg = mtod(m, struct sadb_msg *);
6704 orglen = PFKEY_UNUNIT64(msg->sadb_msg_len);
6705 target = KEY_SENDUP_ONE;
6706
6707 if ((m->m_flags & M_PKTHDR) == 0 ||
6708 m->m_pkthdr.len != m->m_pkthdr.len) {
6709 ipseclog((LOG_DEBUG, "%s: invalid message length.\n",__func__));
6709 pfkeystat.out_invlen++;
6710 V_pfkeystat.out_invlen++;
6710 error = EINVAL;
6711 goto senderror;
6712 }
6713
6714 if (msg->sadb_msg_version != PF_KEY_V2) {
6715 ipseclog((LOG_DEBUG, "%s: PF_KEY version %u is mismatched.\n",
6716 __func__, msg->sadb_msg_version));
6711 error = EINVAL;
6712 goto senderror;
6713 }
6714
6715 if (msg->sadb_msg_version != PF_KEY_V2) {
6716 ipseclog((LOG_DEBUG, "%s: PF_KEY version %u is mismatched.\n",
6717 __func__, msg->sadb_msg_version));
6717 pfkeystat.out_invver++;
6718 V_pfkeystat.out_invver++;
6718 error = EINVAL;
6719 goto senderror;
6720 }
6721
6722 if (msg->sadb_msg_type > SADB_MAX) {
6723 ipseclog((LOG_DEBUG, "%s: invalid type %u is passed.\n",
6724 __func__, msg->sadb_msg_type));
6719 error = EINVAL;
6720 goto senderror;
6721 }
6722
6723 if (msg->sadb_msg_type > SADB_MAX) {
6724 ipseclog((LOG_DEBUG, "%s: invalid type %u is passed.\n",
6725 __func__, msg->sadb_msg_type));
6725 pfkeystat.out_invmsgtype++;
6726 V_pfkeystat.out_invmsgtype++;
6726 error = EINVAL;
6727 goto senderror;
6728 }
6729
6730 /* for old-fashioned code - should be nuked */
6731 if (m->m_pkthdr.len > MCLBYTES) {
6732 m_freem(m);
6733 return ENOBUFS;

--- 36 unchanged lines hidden (view full) ---

6770 case SADB_ADD:
6771 case SADB_DELETE:
6772 case SADB_GET:
6773 case SADB_ACQUIRE:
6774 case SADB_EXPIRE:
6775 ipseclog((LOG_DEBUG, "%s: must specify satype "
6776 "when msg type=%u.\n", __func__,
6777 msg->sadb_msg_type));
6727 error = EINVAL;
6728 goto senderror;
6729 }
6730
6731 /* for old-fashioned code - should be nuked */
6732 if (m->m_pkthdr.len > MCLBYTES) {
6733 m_freem(m);
6734 return ENOBUFS;

--- 36 unchanged lines hidden (view full) ---

6771 case SADB_ADD:
6772 case SADB_DELETE:
6773 case SADB_GET:
6774 case SADB_ACQUIRE:
6775 case SADB_EXPIRE:
6776 ipseclog((LOG_DEBUG, "%s: must specify satype "
6777 "when msg type=%u.\n", __func__,
6778 msg->sadb_msg_type));
6778 pfkeystat.out_invsatype++;
6779 V_pfkeystat.out_invsatype++;
6779 error = EINVAL;
6780 goto senderror;
6781 }
6782 break;
6783 case SADB_SATYPE_AH:
6784 case SADB_SATYPE_ESP:
6785 case SADB_X_SATYPE_IPCOMP:
6786 case SADB_X_SATYPE_TCPSIGNATURE:
6787 switch (msg->sadb_msg_type) {
6788 case SADB_X_SPDADD:
6789 case SADB_X_SPDDELETE:
6790 case SADB_X_SPDGET:
6791 case SADB_X_SPDDUMP:
6792 case SADB_X_SPDFLUSH:
6793 case SADB_X_SPDSETIDX:
6794 case SADB_X_SPDUPDATE:
6795 case SADB_X_SPDDELETE2:
6796 ipseclog((LOG_DEBUG, "%s: illegal satype=%u\n",
6797 __func__, msg->sadb_msg_type));
6780 error = EINVAL;
6781 goto senderror;
6782 }
6783 break;
6784 case SADB_SATYPE_AH:
6785 case SADB_SATYPE_ESP:
6786 case SADB_X_SATYPE_IPCOMP:
6787 case SADB_X_SATYPE_TCPSIGNATURE:
6788 switch (msg->sadb_msg_type) {
6789 case SADB_X_SPDADD:
6790 case SADB_X_SPDDELETE:
6791 case SADB_X_SPDGET:
6792 case SADB_X_SPDDUMP:
6793 case SADB_X_SPDFLUSH:
6794 case SADB_X_SPDSETIDX:
6795 case SADB_X_SPDUPDATE:
6796 case SADB_X_SPDDELETE2:
6797 ipseclog((LOG_DEBUG, "%s: illegal satype=%u\n",
6798 __func__, msg->sadb_msg_type));
6798 pfkeystat.out_invsatype++;
6799 V_pfkeystat.out_invsatype++;
6799 error = EINVAL;
6800 goto senderror;
6801 }
6802 break;
6803 case SADB_SATYPE_RSVP:
6804 case SADB_SATYPE_OSPFV2:
6805 case SADB_SATYPE_RIPV2:
6806 case SADB_SATYPE_MIP:
6807 ipseclog((LOG_DEBUG, "%s: type %u isn't supported.\n",
6808 __func__, msg->sadb_msg_satype));
6800 error = EINVAL;
6801 goto senderror;
6802 }
6803 break;
6804 case SADB_SATYPE_RSVP:
6805 case SADB_SATYPE_OSPFV2:
6806 case SADB_SATYPE_RIPV2:
6807 case SADB_SATYPE_MIP:
6808 ipseclog((LOG_DEBUG, "%s: type %u isn't supported.\n",
6809 __func__, msg->sadb_msg_satype));
6809 pfkeystat.out_invsatype++;
6810 V_pfkeystat.out_invsatype++;
6810 error = EOPNOTSUPP;
6811 goto senderror;
6812 case 1: /* XXX: What does it do? */
6813 if (msg->sadb_msg_type == SADB_X_PROMISC)
6814 break;
6815 /*FALLTHROUGH*/
6816 default:
6817 ipseclog((LOG_DEBUG, "%s: invalid type %u is passed.\n",
6818 __func__, msg->sadb_msg_satype));
6811 error = EOPNOTSUPP;
6812 goto senderror;
6813 case 1: /* XXX: What does it do? */
6814 if (msg->sadb_msg_type == SADB_X_PROMISC)
6815 break;
6816 /*FALLTHROUGH*/
6817 default:
6818 ipseclog((LOG_DEBUG, "%s: invalid type %u is passed.\n",
6819 __func__, msg->sadb_msg_satype));
6819 pfkeystat.out_invsatype++;
6820 V_pfkeystat.out_invsatype++;
6820 error = EINVAL;
6821 goto senderror;
6822 }
6823
6824 /* check field of upper layer protocol and address family */
6825 if (mh.ext[SADB_EXT_ADDRESS_SRC] != NULL
6826 && mh.ext[SADB_EXT_ADDRESS_DST] != NULL) {
6827 struct sadb_address *src0, *dst0;
6828 u_int plen;
6829
6830 src0 = (struct sadb_address *)(mh.ext[SADB_EXT_ADDRESS_SRC]);
6831 dst0 = (struct sadb_address *)(mh.ext[SADB_EXT_ADDRESS_DST]);
6832
6833 /* check upper layer protocol */
6834 if (src0->sadb_address_proto != dst0->sadb_address_proto) {
6835 ipseclog((LOG_DEBUG, "%s: upper layer protocol "
6836 "mismatched.\n", __func__));
6821 error = EINVAL;
6822 goto senderror;
6823 }
6824
6825 /* check field of upper layer protocol and address family */
6826 if (mh.ext[SADB_EXT_ADDRESS_SRC] != NULL
6827 && mh.ext[SADB_EXT_ADDRESS_DST] != NULL) {
6828 struct sadb_address *src0, *dst0;
6829 u_int plen;
6830
6831 src0 = (struct sadb_address *)(mh.ext[SADB_EXT_ADDRESS_SRC]);
6832 dst0 = (struct sadb_address *)(mh.ext[SADB_EXT_ADDRESS_DST]);
6833
6834 /* check upper layer protocol */
6835 if (src0->sadb_address_proto != dst0->sadb_address_proto) {
6836 ipseclog((LOG_DEBUG, "%s: upper layer protocol "
6837 "mismatched.\n", __func__));
6837 pfkeystat.out_invaddr++;
6838 V_pfkeystat.out_invaddr++;
6838 error = EINVAL;
6839 goto senderror;
6840 }
6841
6842 /* check family */
6843 if (PFKEY_ADDR_SADDR(src0)->sa_family !=
6844 PFKEY_ADDR_SADDR(dst0)->sa_family) {
6845 ipseclog((LOG_DEBUG, "%s: address family mismatched.\n",
6846 __func__));
6839 error = EINVAL;
6840 goto senderror;
6841 }
6842
6843 /* check family */
6844 if (PFKEY_ADDR_SADDR(src0)->sa_family !=
6845 PFKEY_ADDR_SADDR(dst0)->sa_family) {
6846 ipseclog((LOG_DEBUG, "%s: address family mismatched.\n",
6847 __func__));
6847 pfkeystat.out_invaddr++;
6848 V_pfkeystat.out_invaddr++;
6848 error = EINVAL;
6849 goto senderror;
6850 }
6851 if (PFKEY_ADDR_SADDR(src0)->sa_len !=
6852 PFKEY_ADDR_SADDR(dst0)->sa_len) {
6853 ipseclog((LOG_DEBUG, "%s: address struct size "
6854 "mismatched.\n", __func__));
6849 error = EINVAL;
6850 goto senderror;
6851 }
6852 if (PFKEY_ADDR_SADDR(src0)->sa_len !=
6853 PFKEY_ADDR_SADDR(dst0)->sa_len) {
6854 ipseclog((LOG_DEBUG, "%s: address struct size "
6855 "mismatched.\n", __func__));
6855 pfkeystat.out_invaddr++;
6856 V_pfkeystat.out_invaddr++;
6856 error = EINVAL;
6857 goto senderror;
6858 }
6859
6860 switch (PFKEY_ADDR_SADDR(src0)->sa_family) {
6861 case AF_INET:
6862 if (PFKEY_ADDR_SADDR(src0)->sa_len !=
6863 sizeof(struct sockaddr_in)) {
6857 error = EINVAL;
6858 goto senderror;
6859 }
6860
6861 switch (PFKEY_ADDR_SADDR(src0)->sa_family) {
6862 case AF_INET:
6863 if (PFKEY_ADDR_SADDR(src0)->sa_len !=
6864 sizeof(struct sockaddr_in)) {
6864 pfkeystat.out_invaddr++;
6865 V_pfkeystat.out_invaddr++;
6865 error = EINVAL;
6866 goto senderror;
6867 }
6868 break;
6869 case AF_INET6:
6870 if (PFKEY_ADDR_SADDR(src0)->sa_len !=
6871 sizeof(struct sockaddr_in6)) {
6866 error = EINVAL;
6867 goto senderror;
6868 }
6869 break;
6870 case AF_INET6:
6871 if (PFKEY_ADDR_SADDR(src0)->sa_len !=
6872 sizeof(struct sockaddr_in6)) {
6872 pfkeystat.out_invaddr++;
6873 V_pfkeystat.out_invaddr++;
6873 error = EINVAL;
6874 goto senderror;
6875 }
6876 break;
6877 default:
6878 ipseclog((LOG_DEBUG, "%s: unsupported address family\n",
6879 __func__));
6874 error = EINVAL;
6875 goto senderror;
6876 }
6877 break;
6878 default:
6879 ipseclog((LOG_DEBUG, "%s: unsupported address family\n",
6880 __func__));
6880 pfkeystat.out_invaddr++;
6881 V_pfkeystat.out_invaddr++;
6881 error = EAFNOSUPPORT;
6882 goto senderror;
6883 }
6884
6885 switch (PFKEY_ADDR_SADDR(src0)->sa_family) {
6886 case AF_INET:
6887 plen = sizeof(struct in_addr) << 3;
6888 break;

--- 5 unchanged lines hidden (view full) ---

6894 break;
6895 }
6896
6897 /* check max prefix length */
6898 if (src0->sadb_address_prefixlen > plen ||
6899 dst0->sadb_address_prefixlen > plen) {
6900 ipseclog((LOG_DEBUG, "%s: illegal prefixlen.\n",
6901 __func__));
6882 error = EAFNOSUPPORT;
6883 goto senderror;
6884 }
6885
6886 switch (PFKEY_ADDR_SADDR(src0)->sa_family) {
6887 case AF_INET:
6888 plen = sizeof(struct in_addr) << 3;
6889 break;

--- 5 unchanged lines hidden (view full) ---

6895 break;
6896 }
6897
6898 /* check max prefix length */
6899 if (src0->sadb_address_prefixlen > plen ||
6900 dst0->sadb_address_prefixlen > plen) {
6901 ipseclog((LOG_DEBUG, "%s: illegal prefixlen.\n",
6902 __func__));
6902 pfkeystat.out_invaddr++;
6903 V_pfkeystat.out_invaddr++;
6903 error = EINVAL;
6904 goto senderror;
6905 }
6906
6907 /*
6908 * prefixlen == 0 is valid because there can be a case when
6909 * all addresses are matched.
6910 */
6911 }
6912
6913 if (msg->sadb_msg_type >= sizeof(key_typesw)/sizeof(key_typesw[0]) ||
6914 key_typesw[msg->sadb_msg_type] == NULL) {
6904 error = EINVAL;
6905 goto senderror;
6906 }
6907
6908 /*
6909 * prefixlen == 0 is valid because there can be a case when
6910 * all addresses are matched.
6911 */
6912 }
6913
6914 if (msg->sadb_msg_type >= sizeof(key_typesw)/sizeof(key_typesw[0]) ||
6915 key_typesw[msg->sadb_msg_type] == NULL) {
6915 pfkeystat.out_invmsgtype++;
6916 V_pfkeystat.out_invmsgtype++;
6916 error = EINVAL;
6917 goto senderror;
6918 }
6919
6920 return (*key_typesw[msg->sadb_msg_type])(so, m, &mh);
6921
6922senderror:
6923 msg->sadb_msg_errno = error;

--- 77 unchanged lines hidden (view full) ---

7001 /*
7002 * XXX Are there duplication payloads of either
7003 * KEY_AUTH or KEY_ENCRYPT ?
7004 */
7005 if (mhp->ext[ext->sadb_ext_type] != NULL) {
7006 ipseclog((LOG_DEBUG, "%s: duplicate ext_type "
7007 "%u\n", __func__, ext->sadb_ext_type));
7008 m_freem(m);
6917 error = EINVAL;
6918 goto senderror;
6919 }
6920
6921 return (*key_typesw[msg->sadb_msg_type])(so, m, &mh);
6922
6923senderror:
6924 msg->sadb_msg_errno = error;

--- 77 unchanged lines hidden (view full) ---

7002 /*
7003 * XXX Are there duplication payloads of either
7004 * KEY_AUTH or KEY_ENCRYPT ?
7005 */
7006 if (mhp->ext[ext->sadb_ext_type] != NULL) {
7007 ipseclog((LOG_DEBUG, "%s: duplicate ext_type "
7008 "%u\n", __func__, ext->sadb_ext_type));
7009 m_freem(m);
7009 pfkeystat.out_dupext++;
7010 V_pfkeystat.out_dupext++;
7010 return EINVAL;
7011 }
7012 break;
7013 default:
7014 ipseclog((LOG_DEBUG, "%s: invalid ext_type %u\n",
7015 __func__, ext->sadb_ext_type));
7016 m_freem(m);
7011 return EINVAL;
7012 }
7013 break;
7014 default:
7015 ipseclog((LOG_DEBUG, "%s: invalid ext_type %u\n",
7016 __func__, ext->sadb_ext_type));
7017 m_freem(m);
7017 pfkeystat.out_invexttype++;
7018 V_pfkeystat.out_invexttype++;
7018 return EINVAL;
7019 }
7020
7021 extlen = PFKEY_UNUNIT64(ext->sadb_ext_len);
7022
7023 if (key_validate_ext(ext, extlen)) {
7024 m_freem(m);
7019 return EINVAL;
7020 }
7021
7022 extlen = PFKEY_UNUNIT64(ext->sadb_ext_len);
7023
7024 if (key_validate_ext(ext, extlen)) {
7025 m_freem(m);
7025 pfkeystat.out_invlen++;
7026 V_pfkeystat.out_invlen++;
7026 return EINVAL;
7027 }
7028
7029 n = m_pulldown(m, off, extlen, &toff);
7030 if (!n) {
7031 /* m is already freed */
7032 return ENOBUFS;
7033 }
7034 ext = (struct sadb_ext *)(mtod(n, caddr_t) + toff);
7035
7036 mhp->ext[ext->sadb_ext_type] = ext;
7037 mhp->extoff[ext->sadb_ext_type] = off;
7038 mhp->extlen[ext->sadb_ext_type] = extlen;
7039 }
7040
7041 if (off != end) {
7042 m_freem(m);
7027 return EINVAL;
7028 }
7029
7030 n = m_pulldown(m, off, extlen, &toff);
7031 if (!n) {
7032 /* m is already freed */
7033 return ENOBUFS;
7034 }
7035 ext = (struct sadb_ext *)(mtod(n, caddr_t) + toff);
7036
7037 mhp->ext[ext->sadb_ext_type] = ext;
7038 mhp->extoff[ext->sadb_ext_type] = off;
7039 mhp->extlen[ext->sadb_ext_type] = extlen;
7040 }
7041
7042 if (off != end) {
7043 m_freem(m);
7043 pfkeystat.out_invlen++;
7044 V_pfkeystat.out_invlen++;
7044 return EINVAL;
7045 }
7046
7047 return 0;
7048}
7049
7050static int
7051key_validate_ext(ext, len)

--- 61 unchanged lines hidden (view full) ---

7113
7114 SPTREE_LOCK_INIT();
7115 REGTREE_LOCK_INIT();
7116 SAHTREE_LOCK_INIT();
7117 ACQ_LOCK_INIT();
7118 SPACQ_LOCK_INIT();
7119
7120 for (i = 0; i < IPSEC_DIR_MAX; i++)
7045 return EINVAL;
7046 }
7047
7048 return 0;
7049}
7050
7051static int
7052key_validate_ext(ext, len)

--- 61 unchanged lines hidden (view full) ---

7114
7115 SPTREE_LOCK_INIT();
7116 REGTREE_LOCK_INIT();
7117 SAHTREE_LOCK_INIT();
7118 ACQ_LOCK_INIT();
7119 SPACQ_LOCK_INIT();
7120
7121 for (i = 0; i < IPSEC_DIR_MAX; i++)
7121 LIST_INIT(&sptree[i]);
7122 LIST_INIT(&V_sptree[i]);
7122
7123
7123 LIST_INIT(&sahtree);
7124 LIST_INIT(&V_sahtree);
7124
7125 for (i = 0; i <= SADB_SATYPE_MAX; i++)
7125
7126 for (i = 0; i <= SADB_SATYPE_MAX; i++)
7126 LIST_INIT(®tree[i]);
7127 LIST_INIT(&V_regtree[i]);
7127
7128
7128 LIST_INIT(&acqtree);
7129 LIST_INIT(&spacqtree);
7129 LIST_INIT(&V_acqtree);
7130 LIST_INIT(&V_spacqtree);
7130
7131 /* system default */
7131
7132 /* system default */
7132 ip4_def_policy.policy = IPSEC_POLICY_NONE;
7133 ip4_def_policy.refcnt++; /*never reclaim this*/
7133 V_ip4_def_policy.policy = IPSEC_POLICY_NONE;
7134 V_ip4_def_policy.refcnt++; /*never reclaim this*/
7134
7135#ifndef IPSEC_DEBUG2
7136 timeout((void *)key_timehandler, (void *)0, hz);
7137#endif /*IPSEC_DEBUG2*/
7138
7139 /* initialize key statistics */
7140 keystat.getspi_count = 1;
7141

--- 71 unchanged lines hidden (view full) ---

7213void
7214key_sa_routechange(dst)
7215 struct sockaddr *dst;
7216{
7217 struct secashead *sah;
7218 struct route *ro;
7219
7220 SAHTREE_LOCK();
7135
7136#ifndef IPSEC_DEBUG2
7137 timeout((void *)key_timehandler, (void *)0, hz);
7138#endif /*IPSEC_DEBUG2*/
7139
7140 /* initialize key statistics */
7141 keystat.getspi_count = 1;
7142

--- 71 unchanged lines hidden (view full) ---

7214void
7215key_sa_routechange(dst)
7216 struct sockaddr *dst;
7217{
7218 struct secashead *sah;
7219 struct route *ro;
7220
7221 SAHTREE_LOCK();
7221 LIST_FOREACH(sah, &sahtree, chain) {
7222 LIST_FOREACH(sah, &V_sahtree, chain) {
7222 ro = &sah->sa_route;
7223 if (ro->ro_rt && dst->sa_len == ro->ro_dst.sa_len
7224 && bcmp(dst, &ro->ro_dst, dst->sa_len) == 0) {
7225 RTFREE(ro->ro_rt);
7226 ro->ro_rt = (struct rtentry *)NULL;
7227 }
7228 }
7229 SAHTREE_UNLOCK();

--- 143 unchanged lines hidden ---
7223 ro = &sah->sa_route;
7224 if (ro->ro_rt && dst->sa_len == ro->ro_dst.sa_len
7225 && bcmp(dst, &ro->ro_dst, dst->sa_len) == 0) {
7226 RTFREE(ro->ro_rt);
7227 ro->ro_rt = (struct rtentry *)NULL;
7228 }
7229 }
7230 SAHTREE_UNLOCK();

--- 143 unchanged lines hidden ---