The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/netinet/ip_ipsp.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $OpenBSD: ip_ipsp.c,v 1.275 2022/11/11 18:09:58 cheloha 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, KCLOCK_NONE, 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_LOCKED_EXCLUSIVE();
  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 && defined(IPSEC)
 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 }

Cache object: aa55b6db39a9de432d039cd21bbea67a


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.