1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  *
  26  * Copyright 2017 Jason King.
  27  * Copyright 2017 Joyent, Inc.
  28  */
  29 
  30 /*
  31  * Manipulation and storage of IKEv2 Security Associations (SAs).
  32  */
  33 #include <umem.h>
  34 #include <pthread.h>
  35 #include <errno.h>
  36 #include <strings.h>
  37 #include <locale.h>
  38 #include <stddef.h>
  39 #include <sys/types.h>
  40 #include <sys/sysmacros.h>
  41 #include <sys/debug.h>
  42 #include <limits.h>
  43 #include <note.h>
  44 #include <ipsec_util.h>
  45 #include <libuutil.h>
  46 #include "defs.h"
  47 #include "buf.h"
  48 #include "timer.h"
  49 #include "pkcs11.h"
  50 #include "ikev2_pkt.h"
  51 #include "ikev2_sa.h"
  52 #include "random.h"
  53 #include "worker.h"
  54 #include "config.h"
  55 
  56 /* Our hashes */
  57 enum {
  58         LSPI,
  59         RHASH
  60 };
  61 
  62 struct i2sa_bucket {
  63         pthread_mutex_t         lock;   /* bucket lock */
  64         uu_list_t               *chain; /* hash chain of ikev2_sa_t's */
  65 };
  66 
  67 typedef struct i2sa_cmp_arg {
  68         sockaddr_u_t            laddr;
  69         sockaddr_u_t            raddr;
  70         const pkt_t             *init_pkt;
  71         uint64_t                lspi;
  72         uint64_t                rspi;
  73         int                     hash;
  74 } i2sa_cmp_arg_t;
  75 
  76 static const struct {
  77         const char      *name;
  78         offset_t        offset;
  79 } pool_names[] = {
  80         { "ikev2_lspi_chain", offsetof(ikev2_sa_t, lspi_node) },
  81         { "ikev2_rhash_chain", offsetof(ikev2_sa_t, rhash_node) }
  82 };
  83 
  84 static volatile uint_t  half_open;      /* # of larval/half open IKEv2 SAs */
  85 static uint_t           num_buckets;    /* Use same value for all hashes */
  86 static uint32_t         remote_noise;   /* random noise for rhash */
  87 static i2sa_bucket_t    *hash[I2SA_NUM_HASH];
  88 static uu_list_pool_t   *list_pool[I2SA_NUM_HASH];
  89 static umem_cache_t     *i2sa_cache;
  90 
  91 #define I2SA_KEY_LADDR          "laddr"
  92 #define I2SA_KEY_LPORT          "lport"
  93 #define I2SA_KEY_RADDR          "raddr"
  94 #define I2SA_KEY_RPORT          "rport"
  95 #define I2SA_KEY_LSPI           "lspi"
  96 #define I2SA_KEY_RSPI           "rspi"
  97 #define I2SA_KEY_INITIATOR      "initiator"
  98 
  99 #define IKEV2_SA_HASH_SPI(spi) \
 100     P2PHASE_TYPED((spi), num_buckets, uint64_t)
 101 
 102 #define IKEV2_SA_RHASH(ss, spi) \
 103     P2PHASE_TYPED(i2sa_rhash((ss), (spi)), num_buckets, uint64_t)
 104 
 105 static void     i2sa_init(ikev2_sa_t *);
 106 static uint32_t i2sa_rhash(const struct sockaddr_storage *, uint64_t);
 107 
 108 static ikev2_sa_t *i2sa_verify(ikev2_sa_t *restrict, uint64_t,
 109     const struct sockaddr_storage *restrict,
 110     const struct sockaddr_storage *restrict);
 111 static boolean_t i2sa_add_to_hash(int, ikev2_sa_t *);
 112 
 113 static void i2sa_unlink(ikev2_sa_t *);
 114 static void i2sa_expire_cb(te_event_t, void *data);
 115 
 116 static boolean_t i2sa_key_add_addr(ikev2_sa_t *, const char *, const char *,
 117     const struct sockaddr_storage *);
 118 static int i2sa_ctor(void *, void *, int);
 119 static void i2sa_dtor(void *, void *);
 120 
 121 static void inc_half_open(void);
 122 static void dec_half_open(void);
 123 
 124 /*
 125  * Attempt to find an IKEv2 SA that matches the given criteria, or return
 126  * NULL if not found.
 127  */
 128 ikev2_sa_t *
 129 ikev2_sa_get(uint64_t l_spi, uint64_t r_spi,
 130     const struct sockaddr_storage *restrict l_addr,
 131     const struct sockaddr_storage *restrict r_addr,
 132     const pkt_t *restrict init_pkt)
 133 {
 134         i2sa_bucket_t *bucket;
 135         ikev2_sa_t *sa;
 136         i2sa_cmp_arg_t arg = { 0 };
 137 
 138         arg.lspi = l_spi;
 139         arg.rspi = r_spi;
 140         arg.init_pkt = init_pkt;
 141         arg.laddr.sau_ss = (struct sockaddr_storage *)l_addr;
 142         arg.raddr.sau_ss = (struct sockaddr_storage *)r_addr;
 143 
 144         if (l_spi != 0) {
 145                 /*
 146                  * We assign the local SPIs, so if there is one, we should
 147                  * only need that to find it.
 148                  */
 149                 bucket = hash[LSPI] + IKEV2_SA_HASH_SPI(l_spi);
 150                 arg.hash = LSPI;
 151         } else {
 152                 /* Otherwise gotta use the other stuff */
 153                 bucket = hash[RHASH] + IKEV2_SA_RHASH(r_addr, r_spi);
 154                 arg.hash = RHASH;
 155         }
 156 
 157         PTH(pthread_mutex_lock(&bucket->lock));
 158         sa = (ikev2_sa_t *)uu_list_find(bucket->chain, NULL, &arg, NULL);
 159         if (sa != NULL)
 160                 I2SA_REFHOLD(sa);
 161         PTH(pthread_mutex_unlock(&bucket->lock));
 162 
 163         return (i2sa_verify(sa, r_spi, l_addr, r_addr));
 164 }
 165 
 166 /*
 167  * Allocate a larval IKEv2 SA.
 168  *
 169  * Obtains a unique local SPI and assigns it to the SA and adds the SA to
 170  * the local SPI hash.  If the packet used to trigger the creation of the SA
 171  * is given, take over management of it.  Also create an SA expiration timer.
 172  *
 173  * If we initiated the SA creation, the remote SPI will not be known initially.
 174  * Once the protocol has proceeded enough to determine the remote SPI,
 175  * ikev2_sa_set_rspi() should be called.
 176  *
 177  * Parameters:
 178  *      initiator       Was this SA locally initiated
 179  *      init_pkt        The packet that trigged the creation of the SA.
 180  *      laddr,
 181  *      raddr           The local and remote addresses of this SA.
 182  *
 183  * On successful create, the larval IKEv2 SA is returned.
 184  * On failure, NULL is returned.  Caller maintains responsibility for
 185  * init_pkt in this instance.
 186  */
 187 ikev2_sa_t *
 188 ikev2_sa_alloc(boolean_t initiator,
 189     pkt_t *restrict init_pkt,
 190     const struct sockaddr_storage *restrict laddr,
 191     const struct sockaddr_storage *restrict raddr)
 192 {
 193         ikev2_sa_t      *i2sa = NULL;
 194 
 195         if ((i2sa = umem_cache_alloc(i2sa_cache, UMEM_DEFAULT)) == NULL)
 196                 return (NULL);
 197 
 198         if ((bunyan_child(log, &i2sa->i2sa_log) != 0)) {
 199                 umem_cache_free(i2sa_cache, i2sa);
 200                 return (NULL);
 201         }
 202 
 203         /* Keep anyone else out while we initialize */
 204         PTH(pthread_mutex_lock(&i2sa->lock));
 205 
 206         ASSERT((init_pkt == NULL) ||
 207             (init_pkt->hdr.exch_type == IKEV2_EXCHANGE_IKE_SA_INIT));
 208 
 209         i2sa->flags |= (initiator) ? I2SA_INITIATOR : 0;
 210 
 211         (void) memcpy(&i2sa->laddr, laddr, sizeof (i2sa->laddr));
 212         (void) memcpy(&i2sa->raddr, raddr, sizeof (i2sa->raddr));
 213 
 214         /* Get a random number for the local SPI that's currently unusued */
 215         while (1) {
 216                 /*CONSTCOND*/
 217                 uint64_t spi;
 218 
 219                 /* 0 is never valid, exteremely unlikely, but easy to handle */
 220                 if ((spi = random_low_64()) == 0)
 221                         continue;
 222 
 223                 if (initiator)
 224                         i2sa->i_spi = spi;
 225                 else
 226                         i2sa->r_spi = spi;
 227 
 228                 if (i2sa_add_to_hash(LSPI, i2sa)) {
 229                         ASSERT(i2sa->refcnt == 1);
 230 
 231                         /* XXX: refhold i2sa in init_pkt */
 232                         i2sa->init = init_pkt;
 233 
 234                         /* refhold for caller */
 235                         I2SA_REFHOLD(i2sa);
 236                         break;
 237                 }
 238         };
 239 
 240         inc_half_open();
 241 
 242         if (!i2sa_key_add_addr(i2sa, I2SA_KEY_LADDR, I2SA_KEY_LPORT, laddr) ||
 243             !i2sa_key_add_addr(i2sa, I2SA_KEY_RADDR, I2SA_KEY_RPORT, raddr) ||
 244             bunyan_key_add(i2sa->i2sa_log,
 245             BUNYAN_T_UINT64, I2SA_KEY_LSPI, I2SA_LOCAL_SPI(i2sa),
 246             BUNYAN_T_UINT64, I2SA_KEY_RSPI, I2SA_REMOTE_SPI(i2sa),
 247             BUNYAN_T_BOOLEAN, I2SA_KEY_INITIATOR,
 248             (i2sa->flags & I2SA_INITIATOR) ? B_TRUE : B_FALSE,
 249             BUNYAN_T_END) != 0)
 250                 goto fail;
 251 
 252         /*
 253          * Start SA expiration timer.
 254          * XXX: Should this be reset after we've successfully authenticated?
 255          */
 256 
 257         I2SA_REFHOLD(i2sa);     /* for the timer */
 258         if (!schedule_timeout(TE_SA_EXPIRE, i2sa_expire_cb, i2sa,
 259             /* XXX: fixme */ 999 * NANOSEC)) {
 260                 bunyan_warn(i2sa->i2sa_log, "aborting larval IKEv2 SA creation",
 261                     BUNYAN_T_END);
 262 
 263                 /* remove from hashes */
 264                 PTH(pthread_mutex_lock(&i2sa->lock));
 265                 i2sa_unlink(i2sa);
 266                 PTH(pthread_mutex_unlock(&i2sa->lock));
 267 
 268                 /* should be free'd once these references are released */
 269                 ASSERT(i2sa->refcnt == 2);
 270                 I2SA_REFRELE(i2sa); /* timer */
 271                 goto fail;
 272         }
 273 
 274         return (i2sa);
 275 
 276 fail:
 277         ASSERT(i2sa->refcnt == 1);
 278         I2SA_REFRELE(i2sa);
 279         return (NULL);
 280 }
 281 
 282 /*
 283  * Invoked when an SA has expired.  REF from timer is passed to this
 284  * function.
 285  */
 286 static void
 287 i2sa_expire_cb(te_event_t evt, void *data)
 288 {
 289         NOTE(ARGUNUSED(evt))
 290 
 291         ikev2_sa_t *i2sa = (ikev2_sa_t *)data;
 292 
 293         /* XXX: todo */
 294         I2SA_REFRELE(i2sa);
 295 }
 296 
 297 void
 298 ikev2_sa_flush(void)
 299 {
 300         /* TODO: implement me */
 301 }
 302 
 303 void
 304 ikev2_sa_condemn(ikev2_sa_t *i2sa)
 305 {
 306 }
 307 
 308 void
 309 ikev2_sa_free(ikev2_sa_t *i2sa)
 310 {
 311         if (i2sa == NULL)
 312                 return;
 313 
 314         ASSERT(i2sa->refcnt == 0);
 315 
 316         if (i2sa->i2sa_rule != NULL)
 317                 CONFIG_REFRELE(i2sa->i2sa_rule->rule_config);
 318 
 319         /* All unauthenticated IKEv2 SAs are considered larval */
 320         if (!(i2sa->flags & I2SA_AUTHENTICATED))
 321                 dec_half_open();
 322 
 323         /*
 324          * XXX: we have potential circular references here
 325          * as ikev2_pkt_t->sa and i2sa->init,
 326          * i2sa->last_{resp_sent,sent,recvd} reference each other.
 327          *
 328          * We will need to sit and think about the lifecycles of
 329          * these packets to make sure when we want this SA to go
 330          * away for any reason, everything is properly cleaned up.
 331          *
 332          * For now, my thought is to punt until after the
 333          * IKE_SA_INIT and IKE_AUTH exchanges are written, as that
 334          * will likely help identify the best approach to resolving this.
 335          */
 336         pkt_free(i2sa->init);
 337         pkt_free(i2sa->last_resp_sent);
 338         pkt_free(i2sa->last_sent);
 339         pkt_free(i2sa->last_recvd);
 340 
 341 #define DESTROY(x, y) pkcs11_destroy_obj(#y, &(x)->y, i2sa->i2sa_log)
 342         DESTROY(i2sa, dh_pubkey);
 343         DESTROY(i2sa, dh_privkey);
 344         DESTROY(i2sa, dh_key);
 345         DESTROY(i2sa, sk_d);
 346         DESTROY(i2sa, sk_ai);
 347         DESTROY(i2sa, sk_ar);
 348         DESTROY(i2sa, sk_ei);
 349         DESTROY(i2sa, sk_er);
 350         DESTROY(i2sa, sk_pi);
 351         DESTROY(i2sa, sk_pr);
 352 #undef  DESTROY
 353 
 354         /* TODO: free child SAs */
 355 
 356         bunyan_fini(i2sa->i2sa_log);
 357 
 358         i2sa_dtor(i2sa, NULL);
 359         i2sa_ctor(i2sa, NULL, 0);
 360         umem_cache_free(i2sa_cache, i2sa);
 361 }
 362 
 363 void
 364 ikev2_sa_set_hashsize(uint_t numbuckets)
 365 {
 366         i2sa_bucket_t *old[I2SA_NUM_HASH];
 367         int i, hashtbl;
 368         boolean_t startup;
 369 
 370         for (i = 0; i < I2SA_NUM_HASH; i++)
 371                 old[i] = hash[i];
 372 
 373         if (old[LSPI] == NULL)
 374                 startup = B_TRUE;
 375         else
 376                 startup = B_FALSE;
 377 
 378         if (!startup)
 379                 worker_suspend();
 380 
 381         /* round up to a power of two if not already */
 382         if (!ISP2(numbuckets)) {
 383                 ASSERT(sizeof (numbuckets) == 4);
 384                 --numbuckets;
 385                 for (i = 1; i <= 16; i++)
 386                         numbuckets |= (numbuckets >> i);
 387                 ++numbuckets;
 388         }
 389         VERIFY(ISP2(numbuckets));
 390 
 391         for (i = 0; i < I2SA_NUM_HASH; i++)
 392                 hash[i] = NULL;
 393 
 394         /* Allocate new buckets */
 395         for (i = 0; i < I2SA_NUM_HASH; i++) {
 396                 hash[i] = calloc(numbuckets, sizeof (i2sa_bucket_t));
 397                 if (hash[i] == NULL)
 398                         goto nomem;
 399         }
 400 
 401         uint32_t flags = UU_LIST_SORTED;
 402 
 403 #ifdef DEBUG
 404         flags |= UU_LIST_DEBUG;
 405 #endif
 406 
 407         for (hashtbl = 0; hashtbl < I2SA_NUM_HASH; hashtbl++) {
 408                 for (i = 0; i < numbuckets; i++) {
 409                         hash[hashtbl][i].chain =
 410                             uu_list_create(list_pool[hashtbl], NULL, flags);
 411                         if (hash[hashtbl][i].chain == NULL)
 412                                 goto nomem;
 413 
 414                         PTH(pthread_mutex_init(&hash[hashtbl][i].lock, NULL));
 415                 }
 416         }
 417 
 418         /* New tables means a new fudge factor.  Pick one randomly. */
 419         remote_noise = random_low_32();
 420 
 421         i = num_buckets;
 422 
 423         /* Set this so the hash functions work on the new buckets */
 424         num_buckets = numbuckets;
 425 
 426         if (startup)
 427                 return;
 428 
 429         /*
 430          * At this point, we've allocated all the necessary structures, so
 431          * we can just move everything over to the new buckets.  Since the
 432          * only remaining reference to the old number of buckets here is i,
 433          * we work backwards to free each chain, and invert the normal
 434          * inner/outer loop order.
 435          */
 436         while (--i >= 0) {
 437                 for (hashtbl = 0; hashtbl < I2SA_NUM_HASH; hashtbl++) {
 438                         uu_list_t *list;
 439                         ikev2_sa_t *i2sa;
 440                         void *cookie;
 441 
 442                         cookie = NULL;
 443                         list = hash[hashtbl][i].chain;
 444                         for (i2sa = uu_list_teardown(list, &cookie);
 445                             i2sa != NULL;
 446                             i2sa = uu_list_teardown(list, &cookie)) {
 447                                 /*
 448                                  * i2sa_add_to_hash() will create a new
 449                                  * ref, so we cannot transfer the ref from
 450                                  * the old hash into the new one, but must
 451                                  * release it instead.
 452                                  */
 453                                 VERIFY(i2sa_add_to_hash(hashtbl, i2sa));
 454                                 I2SA_REFRELE(i2sa);
 455                         }
 456 
 457                         PTH(pthread_mutex_destroy(&old[hashtbl][i].lock));
 458                         uu_list_destroy(old[hashtbl][i].chain);
 459                 }
 460         }
 461 
 462         for (hashtbl = 0; hashtbl < I2SA_NUM_HASH; hashtbl++)
 463                 free(old[hashtbl]);
 464 
 465         worker_resume();
 466         return;
 467 
 468 nomem:
 469         if (startup)
 470                 errx(EXIT_FAILURE, "out of memory");
 471 
 472         /* This will probably fail too, but worth a shot */
 473         (void) bunyan_error(log, "out of memory", BUNYAN_T_STRING);
 474 
 475         /*
 476          * Free what the new stuff we've constructed so far, and put the
 477          * old buckets back into place
 478          */
 479         for (hashtbl = 0; hashtbl < I2SA_NUM_HASH; hashtbl++) {
 480                 if (hash[hashtbl] == NULL)
 481                         continue;
 482                 for (i = 0; i < numbuckets; i++) {
 483                         if (hash[hashtbl][i].chain != NULL)
 484                                 uu_list_destroy(hash[hashtbl][i].chain);
 485                 }
 486                 free(hash[hashtbl]);
 487                 hash[hashtbl] = old[hashtbl];
 488         }
 489 
 490         worker_resume();
 491 }
 492 
 493 /*
 494  * Set the remote SPI of an IKEv2 SA and add to the rhash
 495  */
 496 void
 497 ikev2_sa_set_rspi(ikev2_sa_t *i2sa, uint64_t r_spi)
 498 {
 499         /* better not be set already */
 500         ASSERT(i2sa->r_spi == 0);
 501 
 502         /* never a valid SPI value */
 503         ASSERT(r_spi != 0);
 504 
 505         /*
 506          * A bit confusing at times, but if we are the initiator of the
 507          * SA, the responder (ikev2_sa_t->r_spi) is the remote spi,
 508          * otherwise we are the responder, so the remote spi is the
 509          * initiator (ikev2_sa_t->i_spi)
 510          */
 511         if (i2sa->flags & I2SA_INITIATOR)
 512                 i2sa->r_spi = r_spi;
 513         else
 514                 i2sa->i_spi = r_spi;
 515 
 516         VERIFY(i2sa_add_to_hash(RHASH, i2sa));
 517 }
 518 
 519 static i2sa_bucket_t *
 520 i2sa_get_bucket(int hashtbl, ikev2_sa_t *i2sa)
 521 {
 522         i2sa_bucket_t *bucket;
 523 
 524         VERIFY3S(hashtbl, <, I2SA_NUM_HASH);
 525 
 526         bucket = hash[hashtbl];
 527         switch (hashtbl) {
 528         case LSPI:
 529                 bucket += IKEV2_SA_HASH_SPI(I2SA_LOCAL_SPI(i2sa));
 530                 break;
 531         case RHASH:
 532                 bucket += IKEV2_SA_RHASH(&i2sa->raddr, I2SA_REMOTE_SPI(i2sa));
 533                 break;
 534         }
 535         return (bucket);
 536 }
 537 
 538 
 539 /*
 540  * Add an IKEv2 SA to the given hash.
 541  *
 542  * Returns:
 543  *      B_TRUE  successfully added, hash holds ref to IKEv2 SA
 544  *      B_FALSE IKEv2 SA already exists in hash, no ref held.
 545  *
 546  */
 547 static boolean_t
 548 i2sa_add_to_hash(int hashtbl, ikev2_sa_t *i2sa)
 549 {
 550         i2sa_bucket_t   *bucket;
 551         void            *node;
 552         i2sa_cmp_arg_t  arg = { 0 };
 553         uu_list_index_t idx;
 554 
 555         VERIFY3S(hashtbl, <, I2SA_NUM_HASH);
 556 
 557         bucket = i2sa_get_bucket(hashtbl, i2sa);
 558         PTH(pthread_mutex_lock(&bucket->lock));
 559 
 560         arg.hash = hashtbl;
 561 
 562         /* Set idx to where the SA should be inserted */
 563         node = uu_list_find(bucket->chain, i2sa, &arg, &idx);
 564         if (node != NULL) {
 565                 /*
 566                  * Found a match, should only happen while choosing
 567                  * a local SPI value and we happen to pick one already
 568                  * in use.
 569                  */
 570 
 571                 VERIFY(node != i2sa);
 572 
 573                 /*
 574                  * XXX: Should we do anything different for an rhash
 575                  * match?
 576                  */
 577                 PTH(pthread_mutex_unlock(&bucket->lock));
 578                 return (B_FALSE);
 579         }
 580 
 581         I2SA_REFHOLD(i2sa);     /* ref for chain */
 582         i2sa->bucket[hashtbl] = bucket;
 583         uu_list_insert(bucket->chain, i2sa, idx);
 584         PTH(pthread_mutex_unlock(&bucket->lock));
 585 
 586         return (B_TRUE);
 587 }
 588 
 589 static ikev2_sa_t *
 590 i2sa_verify(ikev2_sa_t *restrict i2sa, uint64_t rem_spi,
 591     const struct sockaddr_storage *laddr,
 592     const struct sockaddr_storage *raddr)
 593 {
 594         if (i2sa == NULL)
 595                 return (NULL);
 596 
 597         if (rem_spi != 0 && I2SA_REMOTE_SPI(i2sa) != rem_spi) {
 598                 /* XXX: log message */
 599                 goto bad_match;
 600         }
 601 
 602         if (laddr != NULL && !SA_ADDR_EQ(laddr, &i2sa->laddr)) {
 603                 /* XXX: log message */
 604                 goto bad_match;
 605         }
 606 
 607         if (raddr != NULL && !SA_ADDR_EQ(raddr, &i2sa->raddr)) {
 608                 /* XXX: log message */
 609                 goto bad_match;
 610         }
 611 
 612         /*
 613          * XXX KEBE ASKS - if remote port changes, do remap?
 614          * Probably have caller do this after packet is really legit.
 615          */
 616 
 617         /* XXX KEBE SAYS FILL IN OTHER REALITY CHECKS HERE. */
 618 
 619         /* XXX: log full match */
 620         return (i2sa);
 621 
 622 bad_match:
 623         I2SA_REFRELE(i2sa);
 624         return (NULL);
 625 }
 626 
 627 static void
 628 i2sa_hash_remove(int hashtbl, ikev2_sa_t *i2sa)
 629 {
 630         i2sa_bucket_t *bucket;
 631 
 632         VERIFY3S(hashtbl, <, I2SA_NUM_HASH);
 633         ASSERT(MUTEX_HELD(i2sa));
 634 
 635         /* We shouldn't be holding the lock if this is the last reference */
 636         ASSERT(i2sa->refcnt > 1);
 637 
 638         bucket = i2sa_get_bucket(hashtbl, i2sa);
 639         PTH(pthread_mutex_lock(&bucket->lock));
 640         uu_list_remove(bucket->chain, i2sa);
 641         i2sa->bucket[hashtbl] = NULL;
 642         PTH(pthread_mutex_unlock(&bucket->lock));
 643         I2SA_REFRELE(i2sa);
 644 }
 645 
 646 static void
 647 i2sa_unlink(ikev2_sa_t *i2sa)
 648 {
 649         ASSERT(MUTEX_HELD(i2sa));
 650         for (int i = 0; i < I2SA_NUM_HASH; i++)
 651                 i2sa_hash_remove(i, i2sa);
 652 }
 653 
 654 /*
 655  * Generate a hash value for a remote SA based off the
 656  * address and remote SPI.
 657  */
 658 static uint32_t
 659 i2sa_rhash(const struct sockaddr_storage *ss, uint64_t spi)
 660 {
 661         uint32_t rc = remote_noise;
 662         const uint32_t *ptr = (const uint32_t *)&spi;
 663         sockaddr_u_t ssu;
 664 
 665         rc ^= ptr[0];
 666         rc ^= ptr[1];
 667 
 668         ssu.sau_ss = (struct sockaddr_storage *)ss;
 669         if (ss->ss_family == AF_INET6) {
 670                 ptr = (const uint32_t *)&ssu.sau_sin6->sin6_addr;
 671                 rc ^= ptr[0];
 672                 rc ^= ptr[1];
 673                 rc ^= ptr[2];
 674                 rc ^= ptr[3];
 675         } else {
 676                 ASSERT(ss->ss_family == AF_INET);
 677                 rc ^= ssu.sau_sin->sin_addr.s_addr;
 678         }
 679 
 680         return (rc);
 681 }
 682 
 683 /*
 684  * Increase the count of larval SAs.  If we reach our threshold for larval SAs,
 685  * enable the use of cookies.
 686  */
 687 static void
 688 inc_half_open(void)
 689 {
 690         atomic_inc_uint(&half_open);
 691 
 692         /* TODO: cookie check */
 693 }
 694 
 695 /*
 696  * Decrease the count of larval SAs.  Disable cookies if the count falls
 697  * below the threshold
 698  */
 699 static void
 700 dec_half_open(void)
 701 {
 702         atomic_dec_uint(&half_open);
 703 
 704         /*
 705          * TODO: Add cookie check.  Include hystersis to avoid potential
 706          * flopping.
 707          */
 708 }
 709 
 710 static int
 711 i2sa_ctor(void *buf, void *dummy, int flags)
 712 {
 713         _NOTE(ARGUNUSUED(dummy, flags))
 714 
 715         ikev2_sa_t *i2sa = (ikev2_sa_t *)&buf;
 716 
 717         (void) memset(i2sa, 0, sizeof (*i2sa));
 718 
 719         PTH(pthread_mutex_init(&i2sa->lock, NULL));
 720         for (size_t i = 0; i < ARRAY_SIZE(pool_names); i++) {
 721                 uu_list_node_init(buf,
 722                     (uu_list_node_t *)((uchar_t *)buf + pool_names[i].offset),
 723                     list_pool[i]);
 724         }
 725 
 726         i2sa->msgwin = 1;
 727         return (0);
 728 }
 729 
 730 static void
 731 i2sa_dtor(void *buf, void *dummy)
 732 {
 733         _NOTE(ARGUNUSUED(dummy))
 734 
 735         ikev2_sa_t *i2sa = (ikev2_sa_t *)buf;
 736 
 737         PTH(pthread_mutex_destroy(&i2sa->lock));
 738         for (size_t i = 0; i < I2SA_NUM_HASH; i++) {
 739                 uu_list_node_fini(buf,
 740                     (uu_list_node_t *)((uchar_t *)buf + pool_names[i].offset),
 741                     list_pool[i]);
 742         }
 743 }
 744 
 745 static int
 746 sockaddr_compare(const struct sockaddr_storage *restrict l,
 747     const struct sockaddr_storage *restrict r)
 748 {
 749         sockaddr_u_t lu;
 750         sockaddr_u_t ru;
 751         int cmp;
 752 
 753         if (l->ss_family > r->ss_family)
 754                 return (1);
 755         if (l->ss_family < r->ss_family)
 756                 return (-1);
 757 
 758         lu.sau_ss = (struct sockaddr_storage *)l;
 759         ru.sau_ss = (struct sockaddr_storage *)r;
 760 
 761         if (l->ss_family == AF_INET) {
 762                 cmp = memcmp(&lu.sau_sin->sin_addr, &ru.sau_sin->sin_addr,
 763                     sizeof (lu.sau_sin->sin_addr));
 764                 if (cmp > 0)
 765                         return (1);
 766                 if (cmp < 0)
 767                         return (-1);
 768 
 769                 if (lu.sau_sin->sin_port > ru.sau_sin->sin_port)
 770                         return (1);
 771                 if (lu.sau_sin->sin_port < ru.sau_sin->sin_port)
 772                         return (-1);
 773                 return (0);
 774         }
 775 
 776         ASSERT(l->ss_family == AF_INET6);
 777 
 778         cmp = memcmp(&lu.sau_sin6->sin6_addr, &ru.sau_sin6->sin6_addr,
 779             sizeof (lu.sau_sin6->sin6_addr));
 780         if (cmp > 0)
 781                 return (1);
 782         if (cmp < 0)
 783                 return (-1);
 784 
 785         if (lu.sau_sin6->sin6_port > ru.sau_sin6->sin6_port)
 786                 return (1);
 787         if (lu.sau_sin6->sin6_port < ru.sau_sin6->sin6_port)
 788                 return (-1);
 789         return (0);
 790 }
 791 
 792 /*
 793  * This is called by uu_list_find() to find an IKEv2 SA.  Since our
 794  * uu_lists are sorted, it is also used to find the insertion spot
 795  * in a hash chain.  When finding an IKEv2 SA, rarg will be NULL and
 796  * arg will have the information to compare.  When finding an insertion
 797  * spot, rarg will be the IKEv2 SA to insert to determine its location.
 798  */
 799 static int
 800 i2sa_compare(const void *larg, const void *rarg, void *arg)
 801 {
 802         const ikev2_sa_t *l = (const ikev2_sa_t *)larg;
 803         const ikev2_sa_t *r = (const ikev2_sa_t *)rarg;
 804         i2sa_cmp_arg_t *carg = (i2sa_cmp_arg_t *)arg;
 805         const uchar_t *lbuf, *rbuf;
 806         uint64_t spi;
 807         size_t lsz, rsz;
 808         int cmp;
 809 
 810         if (carg->hash == LSPI) {
 811                 ASSERT(MUTEX_HELD(&l->bucket[LSPI]->lock));
 812                 if (r != NULL) {
 813                         ASSERT(l->bucket[LSPI] == r->bucket[LSPI]);
 814                         spi = I2SA_LOCAL_SPI(r);
 815                 } else {
 816                         spi = carg->lspi;
 817                 }
 818 
 819                 ASSERT(spi != 0);
 820 
 821                 /*
 822                  * Since we assign the local SPI, we enforce that
 823                  * they are globally unique
 824                  */
 825                 if (I2SA_LOCAL_SPI(l) > spi)
 826                         return (1);
 827                 if (I2SA_LOCAL_SPI(l) < spi)
 828                         return (-1);
 829                 return (0);
 830         }
 831 
 832         ASSERT(carg->hash == RHASH);
 833         ASSERT(MUTEX_HELD(l->bucket_lock_rhash));
 834 
 835         i2sa_cmp_arg_t cmpdata = { 0 };
 836         if (r != NULL) {
 837                 ASSERT3U(l->bucket_lock_rhash, ==, r->bucket_lock_rhash);
 838                 cmpdata.hash = RHASH;
 839                 cmpdata.rspi = I2SA_REMOTE_SPI(r);
 840                 cmpdata.raddr.sau_ss = (struct sockaddr_storage *)&r->raddr;
 841                 cmpdata.laddr.sau_ss = (struct sockaddr_storage *)&r->laddr;
 842                 cmpdata.init_pkt = r->init;
 843                 carg = &cmpdata;
 844         }
 845 
 846         if (I2SA_REMOTE_SPI(l) > carg->rspi)
 847                 return (1);
 848         if (I2SA_REMOTE_SPI(l) < carg->rspi)
 849                 return (-1);
 850 
 851         /* more likely to be different, so check these first */
 852         cmp = sockaddr_compare(&l->raddr, carg->raddr.sau_ss);
 853         if (cmp > 0)
 854                 return (1);
 855         if (cmp < 0)
 856                 return (-1);
 857 
 858         /* a multihomed system might have different local addresses */
 859         cmp = sockaddr_compare(&l->laddr, carg->laddr.sau_ss);
 860         if (cmp > 0)
 861                 return (1);
 862         if (cmp < 0)
 863                 return (-1);
 864 
 865         /*
 866          * RFC5996 2.1 - We cannot merely rely on the remote SPI and
 867          * address as clients behind NATs might choose the same SPI by chance.
 868          * We must in addition look at the initial packet.  This is only
 869          * an issue for half-opened remotely initiated SAs, as this is the
 870          * only time the local SPI is not yet known.
 871          */
 872         cmp = memcmp(l->init->pkt_raw, carg->init_pkt->pkt_raw,
 873             MIN(pkt_len(l->init), pkt_len(carg->init_pkt)));
 874         if (cmp != 0)
 875                 return ((cmp < 0) ? -1 : 1);
 876         if (pkt_len(l->init) < pkt_len(carg->init_pkt))
 877                 return (-1);
 878         if (pkt_len(l->init) > pkt_len(carg->init_pkt))
 879                 return (1);
 880 
 881         return (0);
 882 }
 883 
 884 static boolean_t
 885 i2sa_key_add_addr(ikev2_sa_t *i2sa, const char *addr_key, const char *port_key,
 886     const struct sockaddr_storage *addr)
 887 {
 888         sockaddr_u_t sau;
 889         sau.sau_ss = (struct sockaddr_storage *)addr;
 890         int rc = 0;
 891 
 892         switch (addr->ss_family) {
 893         case AF_INET:
 894                 rc = bunyan_key_add(i2sa->i2sa_log,
 895                     BUNYAN_T_IP, addr_key, &sau.sau_sin->sin_addr,
 896                     BUNYAN_T_UINT32, port_key, (uint32_t)sau.sau_sin->sin_port,
 897                     BUNYAN_T_END);
 898                 break;
 899         case AF_INET6:
 900                 rc = bunyan_key_add(i2sa->i2sa_log,
 901                     BUNYAN_T_IP6, addr_key, &sau.sau_sin6->sin6_addr,
 902                     BUNYAN_T_UINT32, port_key,
 903                     (uint32_t)sau.sau_sin6->sin6_port,
 904                     BUNYAN_T_END);
 905                 break;
 906         default:
 907                 INVALID("addr->ss_family");
 908         }
 909 
 910         return ((rc == 0) ? B_TRUE : B_FALSE);
 911 }
 912 
 913 void
 914 ikev2_sa_init(void)
 915 {
 916         uint32_t flag = UU_LIST_SORTED;
 917 
 918         if ((i2sa_cache = umem_cache_create("IKEv2 SAs", sizeof (ikev2_sa_t),
 919             0, i2sa_ctor, i2sa_dtor, NULL, NULL, NULL, 0)) == NULL)
 920                 err(EXIT_FAILURE, "Unable to allocate IKEv2 SA cache");
 921 
 922 #ifdef DEBUG
 923         flag |= UU_LIST_POOL_DEBUG;
 924 #endif
 925 
 926         for (int i = 0; i < ARRAY_SIZE(pool_names); i++) {
 927                 list_pool[i] = uu_list_pool_create(pool_names[i].name,
 928                     sizeof (ikev2_sa_t), pool_names[i].offset, i2sa_compare,
 929                     flag);
 930 
 931                 if (list_pool[i] != NULL)
 932                         err(EXIT_FAILURE,
 933                             "Unable to allocate IKEv2 SA hash chains");
 934         }
 935 }
 936 
 937 void
 938 ikev2_sa_fini(void)
 939 {
 940         umem_cache_destroy(i2sa_cache);
 941         for (int i = 0; i < I2SA_NUM_HASH; i++)
 942                 uu_list_pool_destroy(list_pool[i]);
 943 }