1 /*- 2 * SPDX-License-Identifier: ISC 3 * 4 * Copyright (C) 2015-2021 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. 5 * Copyright (C) 2019-2021 Matt Dunwoodie <ncon@noconroy.net> 6 * 7 * Permission to use, copy, modify, and distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #include "opt_inet6.h" 21 22 #include <sys/param.h> 23 #include <sys/systm.h> 24 #include <sys/callout.h> 25 #include <sys/kernel.h> 26 #include <sys/lock.h> 27 #include <sys/malloc.h> 28 #include <sys/objcache.h> 29 #include <sys/queue.h> 30 #include <sys/socket.h> 31 #include <sys/time.h> 32 #include <netinet/in.h> 33 34 #include <crypto/chachapoly.h> 35 #include <crypto/blake2/blake2s.h> 36 #include <crypto/siphash/siphash.h> 37 38 #include "wg_cookie.h" 39 40 /* Constants for cookies */ 41 #define COOKIE_KEY_SIZE BLAKE2S_KEY_SIZE 42 #define COOKIE_SECRET_SIZE 32 43 #define COOKIE_MAC1_KEY_LABEL "mac1----" 44 #define COOKIE_COOKIE_KEY_LABEL "cookie--" 45 #define COOKIE_SECRET_MAX_AGE 120 46 #define COOKIE_SECRET_LATENCY 5 47 48 /* Constants for initiation rate limiting */ 49 #define RATELIMIT_SIZE (1 << 13) 50 #define RATELIMIT_MASK (RATELIMIT_SIZE - 1) 51 #define RATELIMIT_SIZE_MAX (RATELIMIT_SIZE * 8) 52 #define NSEC_PER_SEC 1000000000LL 53 #define INITIATIONS_PER_SECOND 20 54 #define INITIATIONS_BURSTABLE 5 55 #define INITIATION_COST (NSEC_PER_SEC / INITIATIONS_PER_SECOND) 56 #define TOKEN_MAX (INITIATION_COST * INITIATIONS_BURSTABLE) 57 #define ELEMENT_TIMEOUT 1 /* second */ 58 #define IPV4_MASK_SIZE 4 /* Use all 4 bytes of IPv4 address */ 59 #define IPV6_MASK_SIZE 8 /* Use top 8 bytes (/64) of IPv6 address */ 60 61 struct cookie_maker { 62 uint8_t cm_mac1_key[COOKIE_KEY_SIZE]; 63 uint8_t cm_cookie_key[COOKIE_KEY_SIZE]; 64 65 struct lock cm_lock; 66 bool cm_cookie_valid; 67 uint8_t cm_cookie[COOKIE_COOKIE_SIZE]; 68 struct timespec cm_cookie_birthdate; /* nanouptime */ 69 bool cm_mac1_sent; 70 uint8_t cm_mac1_last[COOKIE_MAC_SIZE]; 71 }; 72 73 struct cookie_checker { 74 struct lock cc_key_lock; 75 uint8_t cc_mac1_key[COOKIE_KEY_SIZE]; 76 uint8_t cc_cookie_key[COOKIE_KEY_SIZE]; 77 78 struct lock cc_secret_mtx; 79 struct timespec cc_secret_birthdate; /* nanouptime */ 80 uint8_t cc_secret[COOKIE_SECRET_SIZE]; 81 }; 82 83 struct ratelimit_key { 84 uint8_t ip[IPV6_MASK_SIZE]; 85 }; 86 87 struct ratelimit_entry { 88 LIST_ENTRY(ratelimit_entry) r_entry; 89 struct ratelimit_key r_key; 90 struct timespec r_last_time; /* nanouptime */ 91 uint64_t r_tokens; 92 }; 93 94 struct ratelimit { 95 uint8_t rl_secret[SIPHASH_KEY_LENGTH]; 96 struct lock rl_mtx; 97 struct callout rl_gc; 98 LIST_HEAD(, ratelimit_entry) rl_table[RATELIMIT_SIZE]; 99 size_t rl_table_num; 100 bool rl_initialized; 101 }; 102 103 104 static void macs_mac1(struct cookie_macs *, const void *, size_t, 105 const uint8_t[COOKIE_KEY_SIZE]); 106 static void macs_mac2(struct cookie_macs *, const void *, size_t, 107 const uint8_t[COOKIE_COOKIE_SIZE]); 108 static void make_cookie(struct cookie_checker *, 109 uint8_t[COOKIE_COOKIE_SIZE], 110 const struct sockaddr *); 111 static void precompute_key(uint8_t[COOKIE_KEY_SIZE], 112 const uint8_t[COOKIE_INPUT_SIZE], 113 const uint8_t *, size_t); 114 static void ratelimit_init(struct ratelimit *); 115 static void ratelimit_deinit(struct ratelimit *); 116 static void ratelimit_gc_callout(void *); 117 static void ratelimit_gc_schedule(struct ratelimit *); 118 static void ratelimit_gc(struct ratelimit *, bool); 119 static int ratelimit_allow(struct ratelimit *, const struct sockaddr *); 120 121 122 static struct ratelimit ratelimit_v4; 123 #ifdef INET6 124 static struct ratelimit ratelimit_v6; 125 #endif 126 127 static struct objcache *ratelimit_zone; 128 static MALLOC_DEFINE(M_WG_RATELIMIT, "WG ratelimit", "wireguard ratelimit"); 129 static MALLOC_DEFINE(M_WG_COOKIE, "WG cookie", "wireguard cookie"); 130 131 132 static inline uint64_t 133 siphash13(const uint8_t key[SIPHASH_KEY_LENGTH], const void *src, size_t len) 134 { 135 SIPHASH_CTX ctx; 136 return SipHashX(&ctx, 1, 3, key, src, len); 137 } 138 139 static inline bool 140 timer_expired(const struct timespec *birthdate, time_t sec, long nsec) 141 { 142 struct timespec uptime; 143 struct timespec expire = { .tv_sec = sec, .tv_nsec = nsec }; 144 145 if (birthdate->tv_sec == 0 && birthdate->tv_nsec == 0) 146 return (true); 147 148 getnanouptime(&uptime); 149 timespecadd(birthdate, &expire, &expire); 150 return timespeccmp(&uptime, &expire, >); 151 } 152 153 /*----------------------------------------------------------------------------*/ 154 /* Public Functions */ 155 156 int 157 cookie_init(void) 158 { 159 ratelimit_zone = objcache_create_simple( 160 M_WG_RATELIMIT, sizeof(struct ratelimit_entry)); 161 if (ratelimit_zone == NULL) 162 return (ENOMEM); 163 164 ratelimit_init(&ratelimit_v4); 165 #ifdef INET6 166 ratelimit_init(&ratelimit_v6); 167 #endif 168 169 return (0); 170 } 171 172 void 173 cookie_deinit(void) 174 { 175 ratelimit_deinit(&ratelimit_v4); 176 #ifdef INET6 177 ratelimit_deinit(&ratelimit_v6); 178 #endif 179 if (ratelimit_zone != NULL) 180 objcache_destroy(ratelimit_zone); 181 } 182 183 struct cookie_checker * 184 cookie_checker_alloc(void) 185 { 186 struct cookie_checker *cc; 187 188 cc = kmalloc(sizeof(*cc), M_WG_COOKIE, M_WAITOK | M_ZERO); 189 lockinit(&cc->cc_key_lock, "cookie_checker_key", 0, 0); 190 lockinit(&cc->cc_secret_mtx, "cookie_checker_secret", 0, 0); 191 192 return (cc); 193 } 194 195 void 196 cookie_checker_free(struct cookie_checker *cc) 197 { 198 lockuninit(&cc->cc_key_lock); 199 lockuninit(&cc->cc_secret_mtx); 200 explicit_bzero(cc, sizeof(*cc)); 201 kfree(cc, M_WG_COOKIE); 202 } 203 204 void 205 cookie_checker_update(struct cookie_checker *cc, 206 const uint8_t key[COOKIE_INPUT_SIZE]) 207 { 208 lockmgr(&cc->cc_key_lock, LK_EXCLUSIVE); 209 if (key != NULL) { 210 precompute_key(cc->cc_mac1_key, key, COOKIE_MAC1_KEY_LABEL, 211 sizeof(COOKIE_MAC1_KEY_LABEL) - 1); 212 precompute_key(cc->cc_cookie_key, key, COOKIE_COOKIE_KEY_LABEL, 213 sizeof(COOKIE_COOKIE_KEY_LABEL) - 1); 214 } else { 215 bzero(cc->cc_mac1_key, sizeof(cc->cc_mac1_key)); 216 bzero(cc->cc_cookie_key, sizeof(cc->cc_cookie_key)); 217 } 218 lockmgr(&cc->cc_key_lock, LK_RELEASE); 219 } 220 221 void 222 cookie_checker_create_payload(struct cookie_checker *cc, 223 const struct cookie_macs *macs, 224 uint8_t nonce[COOKIE_NONCE_SIZE], 225 uint8_t ecookie[COOKIE_ENCRYPTED_SIZE], 226 const struct sockaddr *sa) 227 { 228 uint8_t cookie[COOKIE_COOKIE_SIZE]; 229 230 make_cookie(cc, cookie, sa); 231 karc4random_buf(nonce, COOKIE_NONCE_SIZE); 232 233 lockmgr(&cc->cc_key_lock, LK_SHARED); 234 xchacha20poly1305_encrypt(ecookie, cookie, COOKIE_COOKIE_SIZE, 235 macs->mac1, COOKIE_MAC_SIZE, nonce, 236 cc->cc_cookie_key); 237 lockmgr(&cc->cc_key_lock, LK_RELEASE); 238 239 explicit_bzero(cookie, sizeof(cookie)); 240 } 241 242 int 243 cookie_checker_validate_macs(struct cookie_checker *cc, 244 const struct cookie_macs *macs, 245 const void *buf, size_t len, bool check_cookie, 246 const struct sockaddr *sa) 247 { 248 struct cookie_macs our_macs; 249 uint8_t cookie[COOKIE_COOKIE_SIZE]; 250 251 /* Validate incoming MACs */ 252 lockmgr(&cc->cc_key_lock, LK_SHARED); 253 macs_mac1(&our_macs, buf, len, cc->cc_mac1_key); 254 lockmgr(&cc->cc_key_lock, LK_RELEASE); 255 256 /* If mac1 is invald, we want to drop the packet */ 257 if (timingsafe_bcmp(our_macs.mac1, macs->mac1, COOKIE_MAC_SIZE) != 0) 258 return (EINVAL); 259 260 if (check_cookie) { 261 make_cookie(cc, cookie, sa); 262 macs_mac2(&our_macs, buf, len, cookie); 263 264 /* If mac2 is invalid, we want to send a cookie response. */ 265 if (timingsafe_bcmp(our_macs.mac2, macs->mac2, COOKIE_MAC_SIZE) 266 != 0) 267 return (EAGAIN); 268 269 /* 270 * If the mac2 is valid, we may want to rate limit the peer. 271 * ratelimit_allow() will return either 0 or ECONNREFUSED, 272 * implying there is no ratelimiting, or we should ratelimit 273 * (refuse), respectively. 274 */ 275 if (sa->sa_family == AF_INET) 276 return ratelimit_allow(&ratelimit_v4, sa); 277 #ifdef INET6 278 else if (sa->sa_family == AF_INET6) 279 return ratelimit_allow(&ratelimit_v6, sa); 280 #endif 281 else 282 return (EAFNOSUPPORT); 283 } 284 285 return (0); 286 } 287 288 struct cookie_maker * 289 cookie_maker_alloc(const uint8_t key[COOKIE_INPUT_SIZE]) 290 { 291 struct cookie_maker *cm; 292 293 cm = kmalloc(sizeof(*cm), M_WG_COOKIE, M_WAITOK | M_ZERO); 294 precompute_key(cm->cm_mac1_key, key, COOKIE_MAC1_KEY_LABEL, 295 sizeof(COOKIE_MAC1_KEY_LABEL) - 1); 296 precompute_key(cm->cm_cookie_key, key, COOKIE_COOKIE_KEY_LABEL, 297 sizeof(COOKIE_COOKIE_KEY_LABEL) - 1); 298 lockinit(&cm->cm_lock, "cookie_maker", 0, 0); 299 300 return (cm); 301 } 302 303 void 304 cookie_maker_free(struct cookie_maker *cm) 305 { 306 lockuninit(&cm->cm_lock); 307 explicit_bzero(cm, sizeof(*cm)); 308 kfree(cm, M_WG_COOKIE); 309 } 310 311 int 312 cookie_maker_consume_payload(struct cookie_maker *cm, 313 const uint8_t nonce[COOKIE_NONCE_SIZE], 314 const uint8_t ecookie[COOKIE_ENCRYPTED_SIZE]) 315 { 316 uint8_t cookie[COOKIE_COOKIE_SIZE]; 317 int ret = 0; 318 319 lockmgr(&cm->cm_lock, LK_SHARED); 320 321 if (!cm->cm_mac1_sent) { 322 ret = ETIMEDOUT; 323 goto out; 324 } 325 326 if (!xchacha20poly1305_decrypt(cookie, ecookie, COOKIE_ENCRYPTED_SIZE, 327 cm->cm_mac1_last, COOKIE_MAC_SIZE, 328 nonce, cm->cm_cookie_key)) { 329 ret = EINVAL; 330 goto out; 331 } 332 333 lockmgr(&cm->cm_lock, LK_RELEASE); 334 lockmgr(&cm->cm_lock, LK_EXCLUSIVE); 335 336 memcpy(cm->cm_cookie, cookie, COOKIE_COOKIE_SIZE); 337 getnanouptime(&cm->cm_cookie_birthdate); 338 cm->cm_cookie_valid = true; 339 cm->cm_mac1_sent = false; 340 341 out: 342 lockmgr(&cm->cm_lock, LK_RELEASE); 343 return (ret); 344 } 345 346 void 347 cookie_maker_mac(struct cookie_maker *cm, struct cookie_macs *macs, 348 const void *buf, size_t len) 349 { 350 lockmgr(&cm->cm_lock, LK_EXCLUSIVE); 351 352 macs_mac1(macs, buf, len, cm->cm_mac1_key); 353 memcpy(cm->cm_mac1_last, macs->mac1, COOKIE_MAC_SIZE); 354 cm->cm_mac1_sent = true; 355 356 if (cm->cm_cookie_valid && 357 !timer_expired(&cm->cm_cookie_birthdate, 358 COOKIE_SECRET_MAX_AGE - COOKIE_SECRET_LATENCY, 0)) { 359 macs_mac2(macs, buf, len, cm->cm_cookie); 360 } else { 361 bzero(macs->mac2, COOKIE_MAC_SIZE); 362 cm->cm_cookie_valid = false; 363 } 364 365 lockmgr(&cm->cm_lock, LK_RELEASE); 366 } 367 368 /*----------------------------------------------------------------------------*/ 369 /* Private functions */ 370 371 static void 372 precompute_key(uint8_t key[COOKIE_KEY_SIZE], 373 const uint8_t input[COOKIE_INPUT_SIZE], 374 const uint8_t *label, size_t label_len) 375 { 376 struct blake2s_state blake; 377 378 blake2s_init(&blake, COOKIE_KEY_SIZE); 379 blake2s_update(&blake, label, label_len); 380 blake2s_update(&blake, input, COOKIE_INPUT_SIZE); 381 blake2s_final(&blake, key); 382 } 383 384 static void 385 macs_mac1(struct cookie_macs *macs, const void *buf, size_t len, 386 const uint8_t key[COOKIE_KEY_SIZE]) 387 { 388 struct blake2s_state state; 389 390 blake2s_init_key(&state, COOKIE_MAC_SIZE, key, COOKIE_KEY_SIZE); 391 blake2s_update(&state, buf, len); 392 blake2s_final(&state, macs->mac1); 393 } 394 395 static void 396 macs_mac2(struct cookie_macs *macs, const void *buf, size_t len, 397 const uint8_t key[COOKIE_COOKIE_SIZE]) 398 { 399 struct blake2s_state state; 400 401 blake2s_init_key(&state, COOKIE_MAC_SIZE, key, COOKIE_COOKIE_SIZE); 402 blake2s_update(&state, buf, len); 403 blake2s_update(&state, macs->mac1, COOKIE_MAC_SIZE); 404 blake2s_final(&state, macs->mac2); 405 } 406 407 static void 408 make_cookie(struct cookie_checker *cc, uint8_t cookie[COOKIE_COOKIE_SIZE], 409 const struct sockaddr *sa) 410 { 411 struct blake2s_state state; 412 413 lockmgr(&cc->cc_secret_mtx, LK_EXCLUSIVE); 414 if (timer_expired(&cc->cc_secret_birthdate, 415 COOKIE_SECRET_MAX_AGE, 0)) { 416 karc4random_buf(cc->cc_secret, COOKIE_SECRET_SIZE); 417 getnanouptime(&cc->cc_secret_birthdate); 418 } 419 blake2s_init_key(&state, COOKIE_COOKIE_SIZE, cc->cc_secret, 420 COOKIE_SECRET_SIZE); 421 lockmgr(&cc->cc_secret_mtx, LK_RELEASE); 422 423 if (sa->sa_family == AF_INET) { 424 const struct sockaddr_in *sin = (const void *)sa; 425 blake2s_update(&state, (const uint8_t *)&sin->sin_addr, 426 sizeof(sin->sin_addr)); 427 blake2s_update(&state, (const uint8_t *)&sin->sin_port, 428 sizeof(sin->sin_port)); 429 blake2s_final(&state, cookie); 430 #ifdef INET6 431 } else if (sa->sa_family == AF_INET6) { 432 const struct sockaddr_in6 *sin6 = (const void *)sa; 433 blake2s_update(&state, (const uint8_t *)&sin6->sin6_addr, 434 sizeof(sin6->sin6_addr)); 435 blake2s_update(&state, (const uint8_t *)&sin6->sin6_port, 436 sizeof(sin6->sin6_port)); 437 blake2s_final(&state, cookie); 438 #endif 439 } else { 440 karc4random_buf(cookie, COOKIE_COOKIE_SIZE); 441 } 442 } 443 444 445 static void 446 ratelimit_init(struct ratelimit *rl) 447 { 448 size_t i; 449 450 bzero(rl, sizeof(*rl)); 451 lockinit(&rl->rl_mtx, "ratelimit_lock", 0, 0); 452 callout_init_lk(&rl->rl_gc, &rl->rl_mtx); 453 karc4random_buf(rl->rl_secret, sizeof(rl->rl_secret)); 454 for (i = 0; i < RATELIMIT_SIZE; i++) 455 LIST_INIT(&rl->rl_table[i]); 456 rl->rl_table_num = 0; 457 458 rl->rl_initialized = true; 459 } 460 461 static void 462 ratelimit_deinit(struct ratelimit *rl) 463 { 464 if (!rl->rl_initialized) 465 return; 466 467 lockmgr(&rl->rl_mtx, LK_EXCLUSIVE); 468 callout_stop(&rl->rl_gc); 469 ratelimit_gc(rl, true); 470 lockmgr(&rl->rl_mtx, LK_RELEASE); 471 lockuninit(&rl->rl_mtx); 472 473 rl->rl_initialized = false; 474 } 475 476 static void 477 ratelimit_gc_callout(void *_rl) 478 { 479 /* callout will lock for us */ 480 ratelimit_gc(_rl, false); 481 } 482 483 static void 484 ratelimit_gc_schedule(struct ratelimit *rl) 485 { 486 /* 487 * Trigger another GC if needed. There is no point calling GC if 488 * there are no entries in the table. We also want to ensure that 489 * GC occurs on a regular interval, so don't override a currently 490 * pending GC. 491 * 492 * In the case of a forced ratelimit_gc(), there will be no entries 493 * left so we will not schedule another GC. 494 */ 495 if (rl->rl_table_num > 0 && !callout_pending(&rl->rl_gc)) 496 callout_reset(&rl->rl_gc, ELEMENT_TIMEOUT * hz, 497 ratelimit_gc_callout, rl); 498 } 499 500 static void 501 ratelimit_gc(struct ratelimit *rl, bool force) 502 { 503 struct ratelimit_entry *r, *tr; 504 struct timespec expiry; 505 size_t i; 506 507 KKASSERT(lockstatus(&rl->rl_mtx, curthread) == LK_EXCLUSIVE); 508 509 if (rl->rl_table_num == 0) 510 return; 511 512 getnanouptime(&expiry); 513 expiry.tv_sec -= ELEMENT_TIMEOUT; 514 515 for (i = 0; i < RATELIMIT_SIZE; i++) { 516 LIST_FOREACH_MUTABLE(r, &rl->rl_table[i], r_entry, tr) { 517 if (force || 518 timespeccmp(&r->r_last_time, &expiry, <)) { 519 rl->rl_table_num--; 520 LIST_REMOVE(r, r_entry); 521 objcache_put(ratelimit_zone, r); 522 } 523 } 524 } 525 526 ratelimit_gc_schedule(rl); 527 } 528 529 static int 530 ratelimit_allow(struct ratelimit *rl, const struct sockaddr *sa) 531 { 532 struct timespec diff; 533 struct ratelimit_entry *r; 534 struct ratelimit_key key = { 0 }; 535 uint64_t bucket, tokens; 536 size_t len; 537 int ret = ECONNREFUSED; 538 539 if (sa->sa_family == AF_INET) { 540 len = IPV4_MASK_SIZE; 541 memcpy(key.ip, &((const struct sockaddr_in *)sa)->sin_addr, 542 len); 543 } 544 #ifdef INET6 545 else if (sa->sa_family == AF_INET6) { 546 len = IPV6_MASK_SIZE; 547 memcpy(key.ip, &((const struct sockaddr_in6 *)sa)->sin6_addr, 548 len); 549 } 550 #endif 551 else { 552 return (ret); 553 } 554 555 bucket = siphash13(rl->rl_secret, &key, len) & RATELIMIT_MASK; 556 lockmgr(&rl->rl_mtx, LK_EXCLUSIVE); 557 558 LIST_FOREACH(r, &rl->rl_table[bucket], r_entry) { 559 if (memcmp(&r->r_key, &key, len) != 0) 560 continue; 561 562 /* 563 * Found an entry for the endpoint. We apply standard token 564 * bucket, by calculating the time lapsed since last_time, 565 * adding that, ensuring that we cap the tokens at TOKEN_MAX. 566 * If the endpoint has no tokens left (i.e., tokens < 567 * INITIATION_COST) then we block the request. Otherwise, we 568 * subtract the INITITIATION_COST and return OK. 569 */ 570 diff = r->r_last_time; 571 getnanouptime(&r->r_last_time); 572 timespecsub(&r->r_last_time, &diff, &diff); 573 574 tokens = r->r_tokens; 575 tokens += diff.tv_sec * NSEC_PER_SEC + diff.tv_nsec; 576 if (tokens > TOKEN_MAX) 577 tokens = TOKEN_MAX; 578 579 if (tokens >= INITIATION_COST) { 580 r->r_tokens = tokens - INITIATION_COST; 581 goto ok; 582 } else { 583 r->r_tokens = tokens; 584 goto error; 585 } 586 } 587 588 /* 589 * Didn't have an entry for the endpoint, so let's add one if we 590 * have space. 591 */ 592 if (rl->rl_table_num >= RATELIMIT_SIZE_MAX) 593 goto error; 594 595 if ((r = objcache_get(ratelimit_zone, M_NOWAIT)) == NULL) 596 goto error; 597 bzero(r, sizeof(*r)); /* objcache_get() doesn't ensure M_ZERO. */ 598 599 rl->rl_table_num++; 600 601 /* Insert the new entry and initialize it. */ 602 LIST_INSERT_HEAD(&rl->rl_table[bucket], r, r_entry); 603 r->r_key = key; 604 r->r_tokens = TOKEN_MAX - INITIATION_COST; 605 getnanouptime(&r->r_last_time); 606 607 /* We've added a new entry; let's trigger GC. */ 608 ratelimit_gc_schedule(rl); 609 610 ok: 611 ret = 0; 612 error: 613 lockmgr(&rl->rl_mtx, LK_RELEASE); 614 return (ret); 615 } 616 617 618 #ifdef WG_SELFTESTS 619 #include "selftest/cookie.c" 620 #endif /* WG_SELFTESTS */ 621