1 /* $OpenBSD: ip_ipsp.c,v 1.272 2022/07/14 13:52:10 mvs Exp $ */ 2 /* 3 * The authors of this code are John Ioannidis (ji@tla.org), 4 * Angelos D. Keromytis (kermit@csd.uch.gr), 5 * Niels Provos (provos@physnet.uni-hamburg.de) and 6 * Niklas Hallqvist (niklas@appli.se). 7 * 8 * The original version of this code was written by John Ioannidis 9 * for BSD/OS in Athens, Greece, in November 1995. 10 * 11 * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996, 12 * by Angelos D. Keromytis. 13 * 14 * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis 15 * and Niels Provos. 16 * 17 * Additional features in 1999 by Angelos D. Keromytis and Niklas Hallqvist. 18 * 19 * Copyright (c) 1995, 1996, 1997, 1998, 1999 by John Ioannidis, 20 * Angelos D. Keromytis and Niels Provos. 21 * Copyright (c) 1999 Niklas Hallqvist. 22 * Copyright (c) 2001, Angelos D. Keromytis. 23 * 24 * Permission to use, copy, and modify this software with or without fee 25 * is hereby granted, provided that this entire notice is included in 26 * all copies of any software which is or includes a copy or 27 * modification of this software. 28 * You may use this code under the GNU public license if you so wish. Please 29 * contribute changes back to the authors under this freer than GPL license 30 * so that we may further the use of strong encryption without limitations to 31 * all. 32 * 33 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR 34 * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY 35 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE 36 * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR 37 * PURPOSE. 38 */ 39 40 #include "pf.h" 41 #include "pfsync.h" 42 43 #include <sys/param.h> 44 #include <sys/systm.h> 45 #include <sys/mbuf.h> 46 #include <sys/socket.h> 47 #include <sys/kernel.h> 48 #include <sys/timeout.h> 49 #include <sys/pool.h> 50 #include <sys/atomic.h> 51 #include <sys/mutex.h> 52 53 #include <net/if.h> 54 #include <net/route.h> 55 56 #include <netinet/in.h> 57 #include <netinet/ip.h> 58 #include <netinet/in_pcb.h> 59 #include <netinet/ip_var.h> 60 #include <netinet/ip_ipip.h> 61 62 #if NPF > 0 63 #include <net/pfvar.h> 64 #endif 65 66 #if NPFSYNC > 0 67 #include <net/if_pfsync.h> 68 #endif 69 70 #include <netinet/ip_ipsp.h> 71 #include <net/pfkeyv2.h> 72 73 #ifdef DDB 74 #include <ddb/db_output.h> 75 void tdb_hashstats(void); 76 #endif 77 78 #ifdef ENCDEBUG 79 #define DPRINTF(fmt, args...) \ 80 do { \ 81 if (encdebug) \ 82 printf("%s: " fmt "\n", __func__, ## args); \ 83 } while (0) 84 #else 85 #define DPRINTF(fmt, args...) \ 86 do { } while (0) 87 #endif 88 89 /* 90 * Locks used to protect global data and struct members: 91 * D tdb_sadb_mtx 92 * F ipsec_flows_mtx SA database global mutex 93 */ 94 95 struct mutex ipsec_flows_mtx = MUTEX_INITIALIZER(IPL_SOFTNET); 96 97 int tdb_rehash(void); 98 void tdb_timeout(void *); 99 void tdb_firstuse(void *); 100 void tdb_soft_timeout(void *); 101 void tdb_soft_firstuse(void *); 102 int tdb_hash(u_int32_t, union sockaddr_union *, u_int8_t); 103 104 int ipsec_in_use = 0; 105 u_int64_t ipsec_last_added = 0; 106 int ipsec_ids_idle = 100; /* keep free ids for 100s */ 107 108 struct pool tdb_pool; 109 110 /* Protected by the NET_LOCK(). */ 111 u_int32_t ipsec_ids_next_flow = 1; /* [F] may not be zero */ 112 struct ipsec_ids_tree ipsec_ids_tree; /* [F] */ 113 struct ipsec_ids_flows ipsec_ids_flows; /* [F] */ 114 struct ipsec_policy_head ipsec_policy_head = 115 TAILQ_HEAD_INITIALIZER(ipsec_policy_head); 116 117 void ipsp_ids_gc(void *); 118 119 LIST_HEAD(, ipsec_ids) ipsp_ids_gc_list = 120 LIST_HEAD_INITIALIZER(ipsp_ids_gc_list); /* [F] */ 121 struct timeout ipsp_ids_gc_timeout = 122 TIMEOUT_INITIALIZER_FLAGS(ipsp_ids_gc, NULL, TIMEOUT_PROC); 123 124 static inline int ipsp_ids_cmp(const struct ipsec_ids *, 125 const struct ipsec_ids *); 126 static inline int ipsp_ids_flow_cmp(const struct ipsec_ids *, 127 const struct ipsec_ids *); 128 RBT_PROTOTYPE(ipsec_ids_tree, ipsec_ids, id_node_flow, ipsp_ids_cmp); 129 RBT_PROTOTYPE(ipsec_ids_flows, ipsec_ids, id_node_id, ipsp_ids_flow_cmp); 130 RBT_GENERATE(ipsec_ids_tree, ipsec_ids, id_node_flow, ipsp_ids_cmp); 131 RBT_GENERATE(ipsec_ids_flows, ipsec_ids, id_node_id, ipsp_ids_flow_cmp); 132 133 /* 134 * This is the proper place to define the various encapsulation transforms. 135 */ 136 137 const struct xformsw xformsw[] = { 138 #ifdef IPSEC 139 { 140 .xf_type = XF_IP4, 141 .xf_flags = 0, 142 .xf_name = "IPv4 Simple Encapsulation", 143 .xf_attach = ipe4_attach, 144 .xf_init = ipe4_init, 145 .xf_zeroize = ipe4_zeroize, 146 .xf_input = ipe4_input, 147 .xf_output = NULL, 148 }, 149 { 150 .xf_type = XF_AH, 151 .xf_flags = XFT_AUTH, 152 .xf_name = "IPsec AH", 153 .xf_attach = ah_attach, 154 .xf_init = ah_init, 155 .xf_zeroize = ah_zeroize, 156 .xf_input = ah_input, 157 .xf_output = ah_output, 158 }, 159 { 160 .xf_type = XF_ESP, 161 .xf_flags = XFT_CONF|XFT_AUTH, 162 .xf_name = "IPsec ESP", 163 .xf_attach = esp_attach, 164 .xf_init = esp_init, 165 .xf_zeroize = esp_zeroize, 166 .xf_input = esp_input, 167 .xf_output = esp_output, 168 }, 169 { 170 .xf_type = XF_IPCOMP, 171 .xf_flags = XFT_COMP, 172 .xf_name = "IPcomp", 173 .xf_attach = ipcomp_attach, 174 .xf_init = ipcomp_init, 175 .xf_zeroize = ipcomp_zeroize, 176 .xf_input = ipcomp_input, 177 .xf_output = ipcomp_output, 178 }, 179 #endif /* IPSEC */ 180 #ifdef TCP_SIGNATURE 181 { 182 .xf_type = XF_TCPSIGNATURE, 183 .xf_flags = XFT_AUTH, 184 .xf_name = "TCP MD5 Signature Option, RFC 2385", 185 .xf_attach = tcp_signature_tdb_attach, 186 .xf_init = tcp_signature_tdb_init, 187 .xf_zeroize = tcp_signature_tdb_zeroize, 188 .xf_input = tcp_signature_tdb_input, 189 .xf_output = tcp_signature_tdb_output, 190 } 191 #endif /* TCP_SIGNATURE */ 192 }; 193 194 const struct xformsw *const xformswNXFORMSW = &xformsw[nitems(xformsw)]; 195 196 #define TDB_HASHSIZE_INIT 32 197 198 struct mutex tdb_sadb_mtx = MUTEX_INITIALIZER(IPL_SOFTNET); 199 static SIPHASH_KEY tdbkey; /* [D] */ 200 static struct tdb **tdbh; /* [D] */ 201 static struct tdb **tdbdst; /* [D] */ 202 static struct tdb **tdbsrc; /* [D] */ 203 static u_int tdb_hashmask = TDB_HASHSIZE_INIT - 1; /* [D] */ 204 static int tdb_count; /* [D] */ 205 206 void 207 ipsp_init(void) 208 { 209 pool_init(&tdb_pool, sizeof(struct tdb), 0, IPL_SOFTNET, 0, 210 "tdb", NULL); 211 212 arc4random_buf(&tdbkey, sizeof(tdbkey)); 213 tdbh = mallocarray(tdb_hashmask + 1, sizeof(struct tdb *), M_TDB, 214 M_WAITOK | M_ZERO); 215 tdbdst = mallocarray(tdb_hashmask + 1, sizeof(struct tdb *), M_TDB, 216 M_WAITOK | M_ZERO); 217 tdbsrc = mallocarray(tdb_hashmask + 1, sizeof(struct tdb *), M_TDB, 218 M_WAITOK | M_ZERO); 219 } 220 221 /* 222 * Our hashing function needs to stir things with a non-zero random multiplier 223 * so we cannot be DoS-attacked via choosing of the data to hash. 224 */ 225 int 226 tdb_hash(u_int32_t spi, union sockaddr_union *dst, 227 u_int8_t proto) 228 { 229 SIPHASH_CTX ctx; 230 231 MUTEX_ASSERT_LOCKED(&tdb_sadb_mtx); 232 233 SipHash24_Init(&ctx, &tdbkey); 234 SipHash24_Update(&ctx, &spi, sizeof(spi)); 235 SipHash24_Update(&ctx, &proto, sizeof(proto)); 236 SipHash24_Update(&ctx, dst, dst->sa.sa_len); 237 238 return (SipHash24_End(&ctx) & tdb_hashmask); 239 } 240 241 /* 242 * Reserve an SPI; the SA is not valid yet though. We use 0 as 243 * an error return value. 244 */ 245 u_int32_t 246 reserve_spi(u_int rdomain, u_int32_t sspi, u_int32_t tspi, 247 union sockaddr_union *src, union sockaddr_union *dst, 248 u_int8_t sproto, int *errval) 249 { 250 struct tdb *tdbp, *exists; 251 u_int32_t spi; 252 int nums; 253 254 /* Don't accept ranges only encompassing reserved SPIs. */ 255 if (sproto != IPPROTO_IPCOMP && 256 (tspi < sspi || tspi <= SPI_RESERVED_MAX)) { 257 (*errval) = EINVAL; 258 return 0; 259 } 260 if (sproto == IPPROTO_IPCOMP && (tspi < sspi || 261 tspi <= CPI_RESERVED_MAX || 262 tspi >= CPI_PRIVATE_MIN)) { 263 (*errval) = EINVAL; 264 return 0; 265 } 266 267 /* Limit the range to not include reserved areas. */ 268 if (sspi <= SPI_RESERVED_MAX) 269 sspi = SPI_RESERVED_MAX + 1; 270 271 /* For IPCOMP the CPI is only 16 bits long, what a good idea.... */ 272 273 if (sproto == IPPROTO_IPCOMP) { 274 u_int32_t t; 275 if (sspi >= 0x10000) 276 sspi = 0xffff; 277 if (tspi >= 0x10000) 278 tspi = 0xffff; 279 if (sspi > tspi) { 280 t = sspi; sspi = tspi; tspi = t; 281 } 282 } 283 284 if (sspi == tspi) /* Asking for a specific SPI. */ 285 nums = 1; 286 else 287 nums = 100; /* Arbitrarily chosen */ 288 289 /* allocate ahead of time to avoid potential sleeping race in loop */ 290 tdbp = tdb_alloc(rdomain); 291 292 while (nums--) { 293 if (sspi == tspi) /* Specific SPI asked. */ 294 spi = tspi; 295 else /* Range specified */ 296 spi = sspi + arc4random_uniform(tspi - sspi); 297 298 /* Don't allocate reserved SPIs. */ 299 if (spi >= SPI_RESERVED_MIN && spi <= SPI_RESERVED_MAX) 300 continue; 301 else 302 spi = htonl(spi); 303 304 /* Check whether we're using this SPI already. */ 305 exists = gettdb(rdomain, spi, dst, sproto); 306 if (exists != NULL) { 307 tdb_unref(exists); 308 continue; 309 } 310 311 tdbp->tdb_spi = spi; 312 memcpy(&tdbp->tdb_dst.sa, &dst->sa, dst->sa.sa_len); 313 memcpy(&tdbp->tdb_src.sa, &src->sa, src->sa.sa_len); 314 tdbp->tdb_sproto = sproto; 315 tdbp->tdb_flags |= TDBF_INVALID; /* Mark SA invalid for now. */ 316 tdbp->tdb_satype = SADB_SATYPE_UNSPEC; 317 puttdb(tdbp); 318 319 #ifdef IPSEC 320 /* Setup a "silent" expiration (since TDBF_INVALID's set). */ 321 if (ipsec_keep_invalid > 0) { 322 mtx_enter(&tdbp->tdb_mtx); 323 tdbp->tdb_flags |= TDBF_TIMER; 324 tdbp->tdb_exp_timeout = ipsec_keep_invalid; 325 if (timeout_add_sec(&tdbp->tdb_timer_tmo, 326 ipsec_keep_invalid)) 327 tdb_ref(tdbp); 328 mtx_leave(&tdbp->tdb_mtx); 329 } 330 #endif 331 332 return spi; 333 } 334 335 (*errval) = EEXIST; 336 tdb_unref(tdbp); 337 return 0; 338 } 339 340 /* 341 * An IPSP SAID is really the concatenation of the SPI found in the 342 * packet, the destination address of the packet and the IPsec protocol. 343 * When we receive an IPSP packet, we need to look up its tunnel descriptor 344 * block, based on the SPI in the packet and the destination address (which 345 * is really one of our addresses if we received the packet! 346 */ 347 struct tdb * 348 gettdb_dir(u_int rdomain, u_int32_t spi, union sockaddr_union *dst, 349 u_int8_t proto, int reverse) 350 { 351 u_int32_t hashval; 352 struct tdb *tdbp; 353 354 NET_ASSERT_LOCKED(); 355 356 mtx_enter(&tdb_sadb_mtx); 357 hashval = tdb_hash(spi, dst, proto); 358 359 for (tdbp = tdbh[hashval]; tdbp != NULL; tdbp = tdbp->tdb_hnext) 360 if ((tdbp->tdb_spi == spi) && (tdbp->tdb_sproto == proto) && 361 ((!reverse && tdbp->tdb_rdomain == rdomain) || 362 (reverse && tdbp->tdb_rdomain_post == rdomain)) && 363 !memcmp(&tdbp->tdb_dst, dst, dst->sa.sa_len)) 364 break; 365 366 tdb_ref(tdbp); 367 mtx_leave(&tdb_sadb_mtx); 368 return tdbp; 369 } 370 371 /* 372 * Same as gettdb() but compare SRC as well, so we 373 * use the tdbsrc[] hash table. Setting spi to 0 374 * matches all SPIs. 375 */ 376 struct tdb * 377 gettdbbysrcdst_dir(u_int rdomain, u_int32_t spi, union sockaddr_union *src, 378 union sockaddr_union *dst, u_int8_t proto, int reverse) 379 { 380 u_int32_t hashval; 381 struct tdb *tdbp; 382 union sockaddr_union su_null; 383 384 mtx_enter(&tdb_sadb_mtx); 385 hashval = tdb_hash(0, src, proto); 386 387 for (tdbp = tdbsrc[hashval]; tdbp != NULL; tdbp = tdbp->tdb_snext) { 388 if (tdbp->tdb_sproto == proto && 389 (spi == 0 || tdbp->tdb_spi == spi) && 390 ((!reverse && tdbp->tdb_rdomain == rdomain) || 391 (reverse && tdbp->tdb_rdomain_post == rdomain)) && 392 ((tdbp->tdb_flags & TDBF_INVALID) == 0) && 393 (tdbp->tdb_dst.sa.sa_family == AF_UNSPEC || 394 !memcmp(&tdbp->tdb_dst, dst, dst->sa.sa_len)) && 395 !memcmp(&tdbp->tdb_src, src, src->sa.sa_len)) 396 break; 397 } 398 if (tdbp != NULL) { 399 tdb_ref(tdbp); 400 mtx_leave(&tdb_sadb_mtx); 401 return tdbp; 402 } 403 404 memset(&su_null, 0, sizeof(su_null)); 405 su_null.sa.sa_len = sizeof(struct sockaddr); 406 hashval = tdb_hash(0, &su_null, proto); 407 408 for (tdbp = tdbsrc[hashval]; tdbp != NULL; tdbp = tdbp->tdb_snext) { 409 if (tdbp->tdb_sproto == proto && 410 (spi == 0 || tdbp->tdb_spi == spi) && 411 ((!reverse && tdbp->tdb_rdomain == rdomain) || 412 (reverse && tdbp->tdb_rdomain_post == rdomain)) && 413 ((tdbp->tdb_flags & TDBF_INVALID) == 0) && 414 (tdbp->tdb_dst.sa.sa_family == AF_UNSPEC || 415 !memcmp(&tdbp->tdb_dst, dst, dst->sa.sa_len)) && 416 tdbp->tdb_src.sa.sa_family == AF_UNSPEC) 417 break; 418 } 419 tdb_ref(tdbp); 420 mtx_leave(&tdb_sadb_mtx); 421 return tdbp; 422 } 423 424 /* 425 * Check that IDs match. Return true if so. The t* range of 426 * arguments contains information from TDBs; the p* range of 427 * arguments contains information from policies or already 428 * established TDBs. 429 */ 430 int 431 ipsp_aux_match(struct tdb *tdb, 432 struct ipsec_ids *ids, 433 struct sockaddr_encap *pfilter, 434 struct sockaddr_encap *pfiltermask) 435 { 436 if (ids != NULL) 437 if (tdb->tdb_ids == NULL || 438 !ipsp_ids_match(tdb->tdb_ids, ids)) 439 return 0; 440 441 /* Check for filter matches. */ 442 if (pfilter != NULL && pfiltermask != NULL && 443 tdb->tdb_filter.sen_type) { 444 /* 445 * XXX We should really be doing a subnet-check (see 446 * whether the TDB-associated filter is a subset 447 * of the policy's. For now, an exact match will solve 448 * most problems (all this will do is make every 449 * policy get its own SAs). 450 */ 451 if (memcmp(&tdb->tdb_filter, pfilter, 452 sizeof(struct sockaddr_encap)) || 453 memcmp(&tdb->tdb_filtermask, pfiltermask, 454 sizeof(struct sockaddr_encap))) 455 return 0; 456 } 457 458 return 1; 459 } 460 461 /* 462 * Get an SA given the remote address, the security protocol type, and 463 * the desired IDs. 464 */ 465 struct tdb * 466 gettdbbydst(u_int rdomain, union sockaddr_union *dst, u_int8_t sproto, 467 struct ipsec_ids *ids, 468 struct sockaddr_encap *filter, struct sockaddr_encap *filtermask) 469 { 470 u_int32_t hashval; 471 struct tdb *tdbp; 472 473 mtx_enter(&tdb_sadb_mtx); 474 hashval = tdb_hash(0, dst, sproto); 475 476 for (tdbp = tdbdst[hashval]; tdbp != NULL; tdbp = tdbp->tdb_dnext) 477 if ((tdbp->tdb_sproto == sproto) && 478 (tdbp->tdb_rdomain == rdomain) && 479 ((tdbp->tdb_flags & TDBF_INVALID) == 0) && 480 (!memcmp(&tdbp->tdb_dst, dst, dst->sa.sa_len))) { 481 /* Check whether IDs match */ 482 if (!ipsp_aux_match(tdbp, ids, filter, filtermask)) 483 continue; 484 break; 485 } 486 487 tdb_ref(tdbp); 488 mtx_leave(&tdb_sadb_mtx); 489 return tdbp; 490 } 491 492 /* 493 * Get an SA given the source address, the security protocol type, and 494 * the desired IDs. 495 */ 496 struct tdb * 497 gettdbbysrc(u_int rdomain, union sockaddr_union *src, u_int8_t sproto, 498 struct ipsec_ids *ids, 499 struct sockaddr_encap *filter, struct sockaddr_encap *filtermask) 500 { 501 u_int32_t hashval; 502 struct tdb *tdbp; 503 504 mtx_enter(&tdb_sadb_mtx); 505 hashval = tdb_hash(0, src, sproto); 506 507 for (tdbp = tdbsrc[hashval]; tdbp != NULL; tdbp = tdbp->tdb_snext) { 508 if ((tdbp->tdb_sproto == sproto) && 509 (tdbp->tdb_rdomain == rdomain) && 510 ((tdbp->tdb_flags & TDBF_INVALID) == 0) && 511 (!memcmp(&tdbp->tdb_src, src, src->sa.sa_len))) { 512 /* Check whether IDs match */ 513 if (!ipsp_aux_match(tdbp, ids, filter, filtermask)) 514 continue; 515 break; 516 } 517 } 518 tdb_ref(tdbp); 519 mtx_leave(&tdb_sadb_mtx); 520 return tdbp; 521 } 522 523 #ifdef DDB 524 525 #define NBUCKETS 16 526 void 527 tdb_hashstats(void) 528 { 529 int i, cnt, buckets[NBUCKETS]; 530 struct tdb *tdbp; 531 532 if (tdbh == NULL) { 533 db_printf("no tdb hash table\n"); 534 return; 535 } 536 537 memset(buckets, 0, sizeof(buckets)); 538 for (i = 0; i <= tdb_hashmask; i++) { 539 cnt = 0; 540 for (tdbp = tdbh[i]; cnt < NBUCKETS - 1 && tdbp != NULL; 541 tdbp = tdbp->tdb_hnext) 542 cnt++; 543 buckets[cnt]++; 544 } 545 546 db_printf("tdb cnt\t\tbucket cnt\n"); 547 for (i = 0; i < NBUCKETS; i++) 548 if (buckets[i] > 0) 549 db_printf("%d%s\t\t%d\n", i, i == NBUCKETS - 1 ? 550 "+" : "", buckets[i]); 551 } 552 553 #define DUMP(m, f) pr("%18s: " f "\n", #m, tdb->tdb_##m) 554 void 555 tdb_printit(void *addr, int full, int (*pr)(const char *, ...)) 556 { 557 struct tdb *tdb = addr; 558 char buf[INET6_ADDRSTRLEN]; 559 560 if (full) { 561 pr("tdb at %p\n", tdb); 562 DUMP(hnext, "%p"); 563 DUMP(dnext, "%p"); 564 DUMP(snext, "%p"); 565 DUMP(inext, "%p"); 566 DUMP(onext, "%p"); 567 DUMP(xform, "%p"); 568 pr("%18s: %d\n", "refcnt", tdb->tdb_refcnt.r_refs); 569 DUMP(encalgxform, "%p"); 570 DUMP(authalgxform, "%p"); 571 DUMP(compalgxform, "%p"); 572 pr("%18s: %b\n", "flags", tdb->tdb_flags, TDBF_BITS); 573 /* tdb_XXX_tmo */ 574 DUMP(seq, "%d"); 575 DUMP(exp_allocations, "%d"); 576 DUMP(soft_allocations, "%d"); 577 DUMP(cur_allocations, "%d"); 578 DUMP(exp_bytes, "%lld"); 579 DUMP(soft_bytes, "%lld"); 580 DUMP(cur_bytes, "%lld"); 581 DUMP(exp_timeout, "%lld"); 582 DUMP(soft_timeout, "%lld"); 583 DUMP(established, "%lld"); 584 DUMP(first_use, "%lld"); 585 DUMP(soft_first_use, "%lld"); 586 DUMP(exp_first_use, "%lld"); 587 DUMP(last_used, "%lld"); 588 DUMP(last_marked, "%lld"); 589 /* tdb_data */ 590 DUMP(cryptoid, "%lld"); 591 pr("%18s: %08x\n", "tdb_spi", ntohl(tdb->tdb_spi)); 592 DUMP(amxkeylen, "%d"); 593 DUMP(emxkeylen, "%d"); 594 DUMP(ivlen, "%d"); 595 DUMP(sproto, "%d"); 596 DUMP(wnd, "%d"); 597 DUMP(satype, "%d"); 598 DUMP(updates, "%d"); 599 pr("%18s: %s\n", "dst", 600 ipsp_address(&tdb->tdb_dst, buf, sizeof(buf))); 601 pr("%18s: %s\n", "src", 602 ipsp_address(&tdb->tdb_src, buf, sizeof(buf))); 603 DUMP(amxkey, "%p"); 604 DUMP(emxkey, "%p"); 605 DUMP(rpl, "%lld"); 606 /* tdb_seen */ 607 /* tdb_iv */ 608 DUMP(ids, "%p"); 609 DUMP(ids_swapped, "%d"); 610 DUMP(mtu, "%d"); 611 DUMP(mtutimeout, "%lld"); 612 pr("%18s: %d\n", "udpencap_port", 613 ntohs(tdb->tdb_udpencap_port)); 614 DUMP(tag, "%d"); 615 DUMP(tap, "%d"); 616 DUMP(rdomain, "%d"); 617 DUMP(rdomain_post, "%d"); 618 /* tdb_filter */ 619 /* tdb_filtermask */ 620 /* tdb_policy_head */ 621 /* tdb_sync_entry */ 622 } else { 623 pr("%p:", tdb); 624 pr(" %08x", ntohl(tdb->tdb_spi)); 625 pr(" %s", ipsp_address(&tdb->tdb_src, buf, sizeof(buf))); 626 pr("->%s", ipsp_address(&tdb->tdb_dst, buf, sizeof(buf))); 627 pr(":%d", tdb->tdb_sproto); 628 pr(" #%d", tdb->tdb_refcnt.r_refs); 629 pr(" %08x\n", tdb->tdb_flags); 630 } 631 } 632 #undef DUMP 633 #endif /* DDB */ 634 635 int 636 tdb_walk(u_int rdomain, int (*walker)(struct tdb *, void *, int), void *arg) 637 { 638 SIMPLEQ_HEAD(, tdb) tdblist; 639 struct tdb *tdbp; 640 int i, rval; 641 642 /* 643 * The walker may sleep. So we cannot hold the tdb_sadb_mtx while 644 * traversing the tdb_hnext list. Create a new tdb_walk list with 645 * exclusive netlock protection. 646 */ 647 NET_ASSERT_WLOCKED(); 648 SIMPLEQ_INIT(&tdblist); 649 650 mtx_enter(&tdb_sadb_mtx); 651 for (i = 0; i <= tdb_hashmask; i++) { 652 for (tdbp = tdbh[i]; tdbp != NULL; tdbp = tdbp->tdb_hnext) { 653 if (rdomain != tdbp->tdb_rdomain) 654 continue; 655 tdb_ref(tdbp); 656 SIMPLEQ_INSERT_TAIL(&tdblist, tdbp, tdb_walk); 657 } 658 } 659 mtx_leave(&tdb_sadb_mtx); 660 661 rval = 0; 662 while ((tdbp = SIMPLEQ_FIRST(&tdblist)) != NULL) { 663 SIMPLEQ_REMOVE_HEAD(&tdblist, tdb_walk); 664 if (rval == 0) 665 rval = walker(tdbp, arg, SIMPLEQ_EMPTY(&tdblist)); 666 tdb_unref(tdbp); 667 } 668 669 return rval; 670 } 671 672 void 673 tdb_timeout(void *v) 674 { 675 struct tdb *tdb = v; 676 677 NET_LOCK(); 678 if (tdb->tdb_flags & TDBF_TIMER) { 679 /* If it's an "invalid" TDB do a silent expiration. */ 680 if (!(tdb->tdb_flags & TDBF_INVALID)) { 681 #ifdef IPSEC 682 ipsecstat_inc(ipsec_exctdb); 683 #endif /* IPSEC */ 684 pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_HARD); 685 } 686 tdb_delete(tdb); 687 } 688 /* decrement refcount of the timeout argument */ 689 tdb_unref(tdb); 690 NET_UNLOCK(); 691 } 692 693 void 694 tdb_firstuse(void *v) 695 { 696 struct tdb *tdb = v; 697 698 NET_LOCK(); 699 if (tdb->tdb_flags & TDBF_SOFT_FIRSTUSE) { 700 /* If the TDB hasn't been used, don't renew it. */ 701 if (tdb->tdb_first_use != 0) { 702 #ifdef IPSEC 703 ipsecstat_inc(ipsec_exctdb); 704 #endif /* IPSEC */ 705 pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_HARD); 706 } 707 tdb_delete(tdb); 708 } 709 /* decrement refcount of the timeout argument */ 710 tdb_unref(tdb); 711 NET_UNLOCK(); 712 } 713 714 void 715 tdb_soft_timeout(void *v) 716 { 717 struct tdb *tdb = v; 718 719 NET_LOCK(); 720 mtx_enter(&tdb->tdb_mtx); 721 if (tdb->tdb_flags & TDBF_SOFT_TIMER) { 722 tdb->tdb_flags &= ~TDBF_SOFT_TIMER; 723 mtx_leave(&tdb->tdb_mtx); 724 /* Soft expirations. */ 725 pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_SOFT); 726 } else 727 mtx_leave(&tdb->tdb_mtx); 728 /* decrement refcount of the timeout argument */ 729 tdb_unref(tdb); 730 NET_UNLOCK(); 731 } 732 733 void 734 tdb_soft_firstuse(void *v) 735 { 736 struct tdb *tdb = v; 737 738 NET_LOCK(); 739 mtx_enter(&tdb->tdb_mtx); 740 if (tdb->tdb_flags & TDBF_SOFT_FIRSTUSE) { 741 tdb->tdb_flags &= ~TDBF_SOFT_FIRSTUSE; 742 mtx_leave(&tdb->tdb_mtx); 743 /* If the TDB hasn't been used, don't renew it. */ 744 if (tdb->tdb_first_use != 0) 745 pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_SOFT); 746 } else 747 mtx_leave(&tdb->tdb_mtx); 748 /* decrement refcount of the timeout argument */ 749 tdb_unref(tdb); 750 NET_UNLOCK(); 751 } 752 753 int 754 tdb_rehash(void) 755 { 756 struct tdb **new_tdbh, **new_tdbdst, **new_srcaddr, *tdbp, *tdbnp; 757 u_int i, old_hashmask; 758 u_int32_t hashval; 759 760 MUTEX_ASSERT_LOCKED(&tdb_sadb_mtx); 761 762 old_hashmask = tdb_hashmask; 763 tdb_hashmask = (tdb_hashmask << 1) | 1; 764 765 arc4random_buf(&tdbkey, sizeof(tdbkey)); 766 new_tdbh = mallocarray(tdb_hashmask + 1, sizeof(struct tdb *), M_TDB, 767 M_NOWAIT | M_ZERO); 768 new_tdbdst = mallocarray(tdb_hashmask + 1, sizeof(struct tdb *), M_TDB, 769 M_NOWAIT | M_ZERO); 770 new_srcaddr = mallocarray(tdb_hashmask + 1, sizeof(struct tdb *), M_TDB, 771 M_NOWAIT | M_ZERO); 772 if (new_tdbh == NULL || 773 new_tdbdst == NULL || 774 new_srcaddr == NULL) { 775 free(new_tdbh, M_TDB, 0); 776 free(new_tdbdst, M_TDB, 0); 777 free(new_srcaddr, M_TDB, 0); 778 return (ENOMEM); 779 } 780 781 for (i = 0; i <= old_hashmask; i++) { 782 for (tdbp = tdbh[i]; tdbp != NULL; tdbp = tdbnp) { 783 tdbnp = tdbp->tdb_hnext; 784 hashval = tdb_hash(tdbp->tdb_spi, &tdbp->tdb_dst, 785 tdbp->tdb_sproto); 786 tdbp->tdb_hnext = new_tdbh[hashval]; 787 new_tdbh[hashval] = tdbp; 788 } 789 790 for (tdbp = tdbdst[i]; tdbp != NULL; tdbp = tdbnp) { 791 tdbnp = tdbp->tdb_dnext; 792 hashval = tdb_hash(0, &tdbp->tdb_dst, tdbp->tdb_sproto); 793 tdbp->tdb_dnext = new_tdbdst[hashval]; 794 new_tdbdst[hashval] = tdbp; 795 } 796 797 for (tdbp = tdbsrc[i]; tdbp != NULL; tdbp = tdbnp) { 798 tdbnp = tdbp->tdb_snext; 799 hashval = tdb_hash(0, &tdbp->tdb_src, tdbp->tdb_sproto); 800 tdbp->tdb_snext = new_srcaddr[hashval]; 801 new_srcaddr[hashval] = tdbp; 802 } 803 } 804 805 free(tdbh, M_TDB, 0); 806 tdbh = new_tdbh; 807 808 free(tdbdst, M_TDB, 0); 809 tdbdst = new_tdbdst; 810 811 free(tdbsrc, M_TDB, 0); 812 tdbsrc = new_srcaddr; 813 814 return 0; 815 } 816 817 /* 818 * Add TDB in the hash table. 819 */ 820 void 821 puttdb(struct tdb *tdbp) 822 { 823 mtx_enter(&tdb_sadb_mtx); 824 puttdb_locked(tdbp); 825 mtx_leave(&tdb_sadb_mtx); 826 } 827 828 void 829 puttdb_locked(struct tdb *tdbp) 830 { 831 u_int32_t hashval; 832 833 MUTEX_ASSERT_LOCKED(&tdb_sadb_mtx); 834 835 hashval = tdb_hash(tdbp->tdb_spi, &tdbp->tdb_dst, tdbp->tdb_sproto); 836 837 /* 838 * Rehash if this tdb would cause a bucket to have more than 839 * two items and if the number of tdbs exceed 10% of the 840 * bucket count. This number is arbitrarily chosen and is 841 * just a measure to not keep rehashing when adding and 842 * removing tdbs which happens to always end up in the same 843 * bucket, which is not uncommon when doing manual keying. 844 */ 845 if (tdbh[hashval] != NULL && tdbh[hashval]->tdb_hnext != NULL && 846 tdb_count * 10 > tdb_hashmask + 1) { 847 if (tdb_rehash() == 0) 848 hashval = tdb_hash(tdbp->tdb_spi, &tdbp->tdb_dst, 849 tdbp->tdb_sproto); 850 } 851 852 tdbp->tdb_hnext = tdbh[hashval]; 853 tdbh[hashval] = tdbp; 854 855 hashval = tdb_hash(0, &tdbp->tdb_dst, tdbp->tdb_sproto); 856 tdbp->tdb_dnext = tdbdst[hashval]; 857 tdbdst[hashval] = tdbp; 858 859 hashval = tdb_hash(0, &tdbp->tdb_src, tdbp->tdb_sproto); 860 tdbp->tdb_snext = tdbsrc[hashval]; 861 tdbsrc[hashval] = tdbp; 862 863 tdb_count++; 864 #ifdef IPSEC 865 if ((tdbp->tdb_flags & (TDBF_INVALID|TDBF_TUNNELING)) == TDBF_TUNNELING) 866 ipsecstat_inc(ipsec_tunnels); 867 #endif /* IPSEC */ 868 869 ipsec_last_added = getuptime(); 870 } 871 872 void 873 tdb_unlink(struct tdb *tdbp) 874 { 875 mtx_enter(&tdb_sadb_mtx); 876 tdb_unlink_locked(tdbp); 877 mtx_leave(&tdb_sadb_mtx); 878 } 879 880 void 881 tdb_unlink_locked(struct tdb *tdbp) 882 { 883 struct tdb *tdbpp; 884 u_int32_t hashval; 885 886 MUTEX_ASSERT_LOCKED(&tdb_sadb_mtx); 887 888 hashval = tdb_hash(tdbp->tdb_spi, &tdbp->tdb_dst, tdbp->tdb_sproto); 889 890 if (tdbh[hashval] == tdbp) { 891 tdbh[hashval] = tdbp->tdb_hnext; 892 } else { 893 for (tdbpp = tdbh[hashval]; tdbpp != NULL; 894 tdbpp = tdbpp->tdb_hnext) { 895 if (tdbpp->tdb_hnext == tdbp) { 896 tdbpp->tdb_hnext = tdbp->tdb_hnext; 897 break; 898 } 899 } 900 } 901 902 tdbp->tdb_hnext = NULL; 903 904 hashval = tdb_hash(0, &tdbp->tdb_dst, tdbp->tdb_sproto); 905 906 if (tdbdst[hashval] == tdbp) { 907 tdbdst[hashval] = tdbp->tdb_dnext; 908 } else { 909 for (tdbpp = tdbdst[hashval]; tdbpp != NULL; 910 tdbpp = tdbpp->tdb_dnext) { 911 if (tdbpp->tdb_dnext == tdbp) { 912 tdbpp->tdb_dnext = tdbp->tdb_dnext; 913 break; 914 } 915 } 916 } 917 918 tdbp->tdb_dnext = NULL; 919 920 hashval = tdb_hash(0, &tdbp->tdb_src, tdbp->tdb_sproto); 921 922 if (tdbsrc[hashval] == tdbp) { 923 tdbsrc[hashval] = tdbp->tdb_snext; 924 } else { 925 for (tdbpp = tdbsrc[hashval]; tdbpp != NULL; 926 tdbpp = tdbpp->tdb_snext) { 927 if (tdbpp->tdb_snext == tdbp) { 928 tdbpp->tdb_snext = tdbp->tdb_snext; 929 break; 930 } 931 } 932 } 933 934 tdbp->tdb_snext = NULL; 935 tdb_count--; 936 #ifdef IPSEC 937 if ((tdbp->tdb_flags & (TDBF_INVALID|TDBF_TUNNELING)) == 938 TDBF_TUNNELING) { 939 ipsecstat_dec(ipsec_tunnels); 940 ipsecstat_inc(ipsec_prevtunnels); 941 } 942 #endif /* IPSEC */ 943 } 944 945 void 946 tdb_cleanspd(struct tdb *tdbp) 947 { 948 struct ipsec_policy *ipo; 949 950 mtx_enter(&ipo_tdb_mtx); 951 while ((ipo = TAILQ_FIRST(&tdbp->tdb_policy_head)) != NULL) { 952 TAILQ_REMOVE(&tdbp->tdb_policy_head, ipo, ipo_tdb_next); 953 tdb_unref(ipo->ipo_tdb); 954 ipo->ipo_tdb = NULL; 955 ipo->ipo_last_searched = 0; /* Force a re-search. */ 956 } 957 mtx_leave(&ipo_tdb_mtx); 958 } 959 960 void 961 tdb_unbundle(struct tdb *tdbp) 962 { 963 if (tdbp->tdb_onext != NULL) { 964 if (tdbp->tdb_onext->tdb_inext == tdbp) { 965 tdb_unref(tdbp); /* to us */ 966 tdbp->tdb_onext->tdb_inext = NULL; 967 } 968 tdb_unref(tdbp->tdb_onext); /* to other */ 969 tdbp->tdb_onext = NULL; 970 } 971 if (tdbp->tdb_inext != NULL) { 972 if (tdbp->tdb_inext->tdb_onext == tdbp) { 973 tdb_unref(tdbp); /* to us */ 974 tdbp->tdb_inext->tdb_onext = NULL; 975 } 976 tdb_unref(tdbp->tdb_inext); /* to other */ 977 tdbp->tdb_inext = NULL; 978 } 979 } 980 981 void 982 tdb_deltimeouts(struct tdb *tdbp) 983 { 984 mtx_enter(&tdbp->tdb_mtx); 985 tdbp->tdb_flags &= ~(TDBF_FIRSTUSE | TDBF_SOFT_FIRSTUSE | TDBF_TIMER | 986 TDBF_SOFT_TIMER); 987 if (timeout_del(&tdbp->tdb_timer_tmo)) 988 tdb_unref(tdbp); 989 if (timeout_del(&tdbp->tdb_first_tmo)) 990 tdb_unref(tdbp); 991 if (timeout_del(&tdbp->tdb_stimer_tmo)) 992 tdb_unref(tdbp); 993 if (timeout_del(&tdbp->tdb_sfirst_tmo)) 994 tdb_unref(tdbp); 995 mtx_leave(&tdbp->tdb_mtx); 996 } 997 998 struct tdb * 999 tdb_ref(struct tdb *tdb) 1000 { 1001 if (tdb == NULL) 1002 return NULL; 1003 refcnt_take(&tdb->tdb_refcnt); 1004 return tdb; 1005 } 1006 1007 void 1008 tdb_unref(struct tdb *tdb) 1009 { 1010 if (tdb == NULL) 1011 return; 1012 if (refcnt_rele(&tdb->tdb_refcnt) == 0) 1013 return; 1014 tdb_free(tdb); 1015 } 1016 1017 void 1018 tdb_delete(struct tdb *tdbp) 1019 { 1020 NET_ASSERT_LOCKED(); 1021 1022 mtx_enter(&tdbp->tdb_mtx); 1023 if (tdbp->tdb_flags & TDBF_DELETED) { 1024 mtx_leave(&tdbp->tdb_mtx); 1025 return; 1026 } 1027 tdbp->tdb_flags |= TDBF_DELETED; 1028 mtx_leave(&tdbp->tdb_mtx); 1029 tdb_unlink(tdbp); 1030 1031 /* cleanup SPD references */ 1032 tdb_cleanspd(tdbp); 1033 /* release tdb_onext/tdb_inext references */ 1034 tdb_unbundle(tdbp); 1035 /* delete timeouts and release references */ 1036 tdb_deltimeouts(tdbp); 1037 /* release the reference for tdb_unlink() */ 1038 tdb_unref(tdbp); 1039 } 1040 1041 /* 1042 * Allocate a TDB and initialize a few basic fields. 1043 */ 1044 struct tdb * 1045 tdb_alloc(u_int rdomain) 1046 { 1047 struct tdb *tdbp; 1048 1049 tdbp = pool_get(&tdb_pool, PR_WAITOK | PR_ZERO); 1050 1051 refcnt_init_trace(&tdbp->tdb_refcnt, DT_REFCNT_IDX_TDB); 1052 mtx_init(&tdbp->tdb_mtx, IPL_SOFTNET); 1053 TAILQ_INIT(&tdbp->tdb_policy_head); 1054 1055 /* Record establishment time. */ 1056 tdbp->tdb_established = gettime(); 1057 1058 /* Save routing domain */ 1059 tdbp->tdb_rdomain = rdomain; 1060 tdbp->tdb_rdomain_post = rdomain; 1061 1062 /* Initialize counters. */ 1063 tdbp->tdb_counters = counters_alloc(tdb_ncounters); 1064 1065 /* Initialize timeouts. */ 1066 timeout_set_proc(&tdbp->tdb_timer_tmo, tdb_timeout, tdbp); 1067 timeout_set_proc(&tdbp->tdb_first_tmo, tdb_firstuse, tdbp); 1068 timeout_set_proc(&tdbp->tdb_stimer_tmo, tdb_soft_timeout, tdbp); 1069 timeout_set_proc(&tdbp->tdb_sfirst_tmo, tdb_soft_firstuse, tdbp); 1070 1071 return tdbp; 1072 } 1073 1074 void 1075 tdb_free(struct tdb *tdbp) 1076 { 1077 NET_ASSERT_LOCKED(); 1078 1079 if (tdbp->tdb_xform) { 1080 (*(tdbp->tdb_xform->xf_zeroize))(tdbp); 1081 tdbp->tdb_xform = NULL; 1082 } 1083 1084 #if NPFSYNC > 0 1085 /* Cleanup pfsync references */ 1086 pfsync_delete_tdb(tdbp); 1087 #endif 1088 1089 KASSERT(TAILQ_EMPTY(&tdbp->tdb_policy_head)); 1090 1091 if (tdbp->tdb_ids) { 1092 ipsp_ids_free(tdbp->tdb_ids); 1093 tdbp->tdb_ids = NULL; 1094 } 1095 1096 #if NPF > 0 1097 if (tdbp->tdb_tag) { 1098 pf_tag_unref(tdbp->tdb_tag); 1099 tdbp->tdb_tag = 0; 1100 } 1101 #endif 1102 1103 counters_free(tdbp->tdb_counters, tdb_ncounters); 1104 1105 KASSERT(tdbp->tdb_onext == NULL); 1106 KASSERT(tdbp->tdb_inext == NULL); 1107 1108 /* Remove expiration timeouts. */ 1109 KASSERT(timeout_pending(&tdbp->tdb_timer_tmo) == 0); 1110 KASSERT(timeout_pending(&tdbp->tdb_first_tmo) == 0); 1111 KASSERT(timeout_pending(&tdbp->tdb_stimer_tmo) == 0); 1112 KASSERT(timeout_pending(&tdbp->tdb_sfirst_tmo) == 0); 1113 1114 pool_put(&tdb_pool, tdbp); 1115 } 1116 1117 /* 1118 * Do further initializations of a TDB. 1119 */ 1120 int 1121 tdb_init(struct tdb *tdbp, u_int16_t alg, struct ipsecinit *ii) 1122 { 1123 const struct xformsw *xsp; 1124 int err; 1125 #ifdef ENCDEBUG 1126 char buf[INET6_ADDRSTRLEN]; 1127 #endif 1128 1129 for (xsp = xformsw; xsp < xformswNXFORMSW; xsp++) { 1130 if (xsp->xf_type == alg) { 1131 err = (*(xsp->xf_init))(tdbp, xsp, ii); 1132 return err; 1133 } 1134 } 1135 1136 DPRINTF("no alg %d for spi %08x, addr %s, proto %d", 1137 alg, ntohl(tdbp->tdb_spi), 1138 ipsp_address(&tdbp->tdb_dst, buf, sizeof(buf)), 1139 tdbp->tdb_sproto); 1140 1141 return EINVAL; 1142 } 1143 1144 #if defined(DDB) || defined(ENCDEBUG) 1145 /* Return a printable string for the address. */ 1146 const char * 1147 ipsp_address(union sockaddr_union *sa, char *buf, socklen_t size) 1148 { 1149 switch (sa->sa.sa_family) { 1150 case AF_INET: 1151 return inet_ntop(AF_INET, &sa->sin.sin_addr, 1152 buf, (size_t)size); 1153 1154 #ifdef INET6 1155 case AF_INET6: 1156 return inet_ntop(AF_INET6, &sa->sin6.sin6_addr, 1157 buf, (size_t)size); 1158 #endif /* INET6 */ 1159 1160 default: 1161 return "(unknown address family)"; 1162 } 1163 } 1164 #endif /* DDB || ENCDEBUG */ 1165 1166 /* Check whether an IP{4,6} address is unspecified. */ 1167 int 1168 ipsp_is_unspecified(union sockaddr_union addr) 1169 { 1170 switch (addr.sa.sa_family) { 1171 case AF_INET: 1172 if (addr.sin.sin_addr.s_addr == INADDR_ANY) 1173 return 1; 1174 else 1175 return 0; 1176 1177 #ifdef INET6 1178 case AF_INET6: 1179 if (IN6_IS_ADDR_UNSPECIFIED(&addr.sin6.sin6_addr)) 1180 return 1; 1181 else 1182 return 0; 1183 #endif /* INET6 */ 1184 1185 case 0: /* No family set. */ 1186 default: 1187 return 1; 1188 } 1189 } 1190 1191 int 1192 ipsp_ids_match(struct ipsec_ids *a, struct ipsec_ids *b) 1193 { 1194 return a == b; 1195 } 1196 1197 struct ipsec_ids * 1198 ipsp_ids_insert(struct ipsec_ids *ids) 1199 { 1200 struct ipsec_ids *found; 1201 u_int32_t start_flow; 1202 1203 mtx_enter(&ipsec_flows_mtx); 1204 1205 found = RBT_INSERT(ipsec_ids_tree, &ipsec_ids_tree, ids); 1206 if (found) { 1207 /* if refcount was zero, then timeout is running */ 1208 if ((++found->id_refcount) == 1) { 1209 LIST_REMOVE(found, id_gc_list); 1210 1211 if (LIST_EMPTY(&ipsp_ids_gc_list)) 1212 timeout_del(&ipsp_ids_gc_timeout); 1213 } 1214 mtx_leave (&ipsec_flows_mtx); 1215 DPRINTF("ids %p count %d", found, found->id_refcount); 1216 return found; 1217 } 1218 1219 ids->id_refcount = 1; 1220 ids->id_flow = start_flow = ipsec_ids_next_flow; 1221 1222 if (++ipsec_ids_next_flow == 0) 1223 ipsec_ids_next_flow = 1; 1224 while (RBT_INSERT(ipsec_ids_flows, &ipsec_ids_flows, ids) != NULL) { 1225 ids->id_flow = ipsec_ids_next_flow; 1226 if (++ipsec_ids_next_flow == 0) 1227 ipsec_ids_next_flow = 1; 1228 if (ipsec_ids_next_flow == start_flow) { 1229 RBT_REMOVE(ipsec_ids_tree, &ipsec_ids_tree, ids); 1230 mtx_leave(&ipsec_flows_mtx); 1231 DPRINTF("ipsec_ids_next_flow exhausted %u", 1232 start_flow); 1233 return NULL; 1234 } 1235 } 1236 mtx_leave(&ipsec_flows_mtx); 1237 DPRINTF("new ids %p flow %u", ids, ids->id_flow); 1238 return ids; 1239 } 1240 1241 struct ipsec_ids * 1242 ipsp_ids_lookup(u_int32_t ipsecflowinfo) 1243 { 1244 struct ipsec_ids key; 1245 struct ipsec_ids *ids; 1246 1247 key.id_flow = ipsecflowinfo; 1248 1249 mtx_enter(&ipsec_flows_mtx); 1250 ids = RBT_FIND(ipsec_ids_flows, &ipsec_ids_flows, &key); 1251 if (ids != NULL) { 1252 if (ids->id_refcount != 0) 1253 ids->id_refcount++; 1254 else 1255 ids = NULL; 1256 } 1257 mtx_leave(&ipsec_flows_mtx); 1258 1259 return ids; 1260 } 1261 1262 /* free ids only from delayed timeout */ 1263 void 1264 ipsp_ids_gc(void *arg) 1265 { 1266 struct ipsec_ids *ids, *tids; 1267 1268 mtx_enter(&ipsec_flows_mtx); 1269 1270 LIST_FOREACH_SAFE(ids, &ipsp_ids_gc_list, id_gc_list, tids) { 1271 KASSERT(ids->id_refcount == 0); 1272 DPRINTF("ids %p count %d", ids, ids->id_refcount); 1273 1274 if ((--ids->id_gc_ttl) > 0) 1275 continue; 1276 1277 LIST_REMOVE(ids, id_gc_list); 1278 RBT_REMOVE(ipsec_ids_tree, &ipsec_ids_tree, ids); 1279 RBT_REMOVE(ipsec_ids_flows, &ipsec_ids_flows, ids); 1280 free(ids->id_local, M_CREDENTIALS, 0); 1281 free(ids->id_remote, M_CREDENTIALS, 0); 1282 free(ids, M_CREDENTIALS, 0); 1283 } 1284 1285 if (!LIST_EMPTY(&ipsp_ids_gc_list)) 1286 timeout_add_sec(&ipsp_ids_gc_timeout, 1); 1287 1288 mtx_leave(&ipsec_flows_mtx); 1289 } 1290 1291 /* decrements refcount, actual free happens in gc */ 1292 void 1293 ipsp_ids_free(struct ipsec_ids *ids) 1294 { 1295 if (ids == NULL) 1296 return; 1297 1298 mtx_enter(&ipsec_flows_mtx); 1299 1300 /* 1301 * If the refcount becomes zero, then a timeout is started. This 1302 * timeout must be cancelled if refcount is increased from zero. 1303 */ 1304 DPRINTF("ids %p count %d", ids, ids->id_refcount); 1305 KASSERT(ids->id_refcount > 0); 1306 1307 if ((--ids->id_refcount) > 0) { 1308 mtx_leave(&ipsec_flows_mtx); 1309 return; 1310 } 1311 1312 /* 1313 * Add second for the case ipsp_ids_gc() is already running and 1314 * awaits netlock to be released. 1315 */ 1316 ids->id_gc_ttl = ipsec_ids_idle + 1; 1317 1318 if (LIST_EMPTY(&ipsp_ids_gc_list)) 1319 timeout_add_sec(&ipsp_ids_gc_timeout, 1); 1320 LIST_INSERT_HEAD(&ipsp_ids_gc_list, ids, id_gc_list); 1321 1322 mtx_leave(&ipsec_flows_mtx); 1323 } 1324 1325 static int 1326 ipsp_id_cmp(struct ipsec_id *a, struct ipsec_id *b) 1327 { 1328 if (a->type > b->type) 1329 return 1; 1330 if (a->type < b->type) 1331 return -1; 1332 if (a->len > b->len) 1333 return 1; 1334 if (a->len < b->len) 1335 return -1; 1336 return memcmp(a + 1, b + 1, a->len); 1337 } 1338 1339 static inline int 1340 ipsp_ids_cmp(const struct ipsec_ids *a, const struct ipsec_ids *b) 1341 { 1342 int ret; 1343 1344 ret = ipsp_id_cmp(a->id_remote, b->id_remote); 1345 if (ret != 0) 1346 return ret; 1347 return ipsp_id_cmp(a->id_local, b->id_local); 1348 } 1349 1350 static inline int 1351 ipsp_ids_flow_cmp(const struct ipsec_ids *a, const struct ipsec_ids *b) 1352 { 1353 if (a->id_flow > b->id_flow) 1354 return 1; 1355 if (a->id_flow < b->id_flow) 1356 return -1; 1357 return 0; 1358 } 1359