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  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
  23  */
  24 
  25 #include <sys/types.h>
  26 #include <sys/systm.h>
  27 #include <sys/stream.h>
  28 #include <sys/cmn_err.h>
  29 #include <sys/ddi.h>
  30 #include <sys/sunddi.h>
  31 #include <sys/kmem.h>
  32 #include <sys/socket.h>
  33 #include <sys/sysmacros.h>
  34 #include <sys/list.h>
  35 
  36 #include <netinet/in.h>
  37 #include <netinet/ip6.h>
  38 #include <netinet/sctp.h>
  39 
  40 #include <inet/common.h>
  41 #include <inet/ip.h>
  42 #include <inet/ip6.h>
  43 #include <inet/ip_ire.h>
  44 #include <inet/ip_if.h>
  45 #include <inet/ipclassifier.h>
  46 #include <inet/sctp_ip.h>
  47 #include "sctp_impl.h"
  48 #include "sctp_addr.h"
  49 
  50 static void             sctp_ipif_inactive(sctp_ipif_t *);
  51 static sctp_ipif_t      *sctp_lookup_ipif_addr(in6_addr_t *, boolean_t,
  52                             zoneid_t, boolean_t, uint_t, uint_t, boolean_t,
  53                             sctp_stack_t *);
  54 static int              sctp_get_all_ipifs(sctp_t *, int);
  55 static int              sctp_ipif_hash_insert(sctp_t *, sctp_ipif_t *, int,
  56                             boolean_t, boolean_t);
  57 static void             sctp_ipif_hash_remove(sctp_t *, sctp_ipif_t *,
  58                             boolean_t);
  59 static void             sctp_fix_saddr(sctp_t *, in6_addr_t *);
  60 static int              sctp_compare_ipif_list(sctp_ipif_hash_t *,
  61                             sctp_ipif_hash_t *);
  62 static int              sctp_copy_ipifs(sctp_ipif_hash_t *, sctp_t *, int);
  63 
  64 #define SCTP_ADDR4_HASH(addr)   \
  65         (((addr) ^ ((addr) >> 8) ^ ((addr) >> 16) ^ ((addr) >> 24)) &     \
  66         (SCTP_IPIF_HASH - 1))
  67 
  68 #define SCTP_ADDR6_HASH(addr)   \
  69         (((addr).s6_addr32[3] ^                                         \
  70         (((addr).s6_addr32[3] ^ (addr).s6_addr32[2]) >> 12)) &                \
  71         (SCTP_IPIF_HASH - 1))
  72 
  73 #define SCTP_IPIF_ADDR_HASH(addr, isv6)                                 \
  74         ((isv6) ? SCTP_ADDR6_HASH((addr)) :                             \
  75         SCTP_ADDR4_HASH((addr)._S6_un._S6_u32[3]))
  76 
  77 #define SCTP_IPIF_USABLE(sctp_ipif_state)       \
  78         ((sctp_ipif_state) == SCTP_IPIFS_UP ||  \
  79         (sctp_ipif_state) ==  SCTP_IPIFS_DOWN)
  80 
  81 #define SCTP_IPIF_DISCARD(sctp_ipif_flags)      \
  82         ((sctp_ipif_flags) & (IPIF_PRIVATE | IPIF_DEPRECATED))
  83 
  84 #define SCTP_IS_IPIF_LOOPBACK(ipif)             \
  85         ((ipif)->sctp_ipif_ill->sctp_ill_flags & PHYI_LOOPBACK)
  86 
  87 #define SCTP_IS_IPIF_LINKLOCAL(ipif)            \
  88         ((ipif)->sctp_ipif_isv6 &&           \
  89         IN6_IS_ADDR_LINKLOCAL(&(ipif)->sctp_ipif_saddr))
  90 
  91 #define SCTP_UNSUPP_AF(ipif, supp_af)   \
  92         ((!(ipif)->sctp_ipif_isv6 && !((supp_af) & PARM_SUPP_V4)) ||     \
  93         ((ipif)->sctp_ipif_isv6 && !((supp_af) & PARM_SUPP_V6)))
  94 
  95 #define SCTP_IPIF_ZONE_MATCH(sctp, ipif)                                \
  96         IPCL_ZONE_MATCH((sctp)->sctp_connp, (ipif)->sctp_ipif_zoneid)
  97 
  98 #define SCTP_ILL_HASH_FN(index)         ((index) % SCTP_ILL_HASH)
  99 #define SCTP_ILL_TO_PHYINDEX(ill)       ((ill)->ill_phyint->phyint_ifindex)
 100 
 101 /*
 102  * SCTP Interface list manipulation functions, locking used.
 103  */
 104 
 105 /*
 106  * Delete an SCTP IPIF from the list if the refcount goes to 0 and it is
 107  * marked as condemned. Also, check if the ILL needs to go away.
 108  */
 109 static void
 110 sctp_ipif_inactive(sctp_ipif_t *sctp_ipif)
 111 {
 112         sctp_ill_t      *sctp_ill;
 113         uint_t          hindex;
 114         uint_t          ill_index;
 115         sctp_stack_t    *sctps = sctp_ipif->sctp_ipif_ill->
 116             sctp_ill_netstack->netstack_sctp;
 117 
 118         rw_enter(&sctps->sctps_g_ills_lock, RW_READER);
 119         rw_enter(&sctps->sctps_g_ipifs_lock, RW_WRITER);
 120 
 121         hindex = SCTP_IPIF_ADDR_HASH(sctp_ipif->sctp_ipif_saddr,
 122             sctp_ipif->sctp_ipif_isv6);
 123 
 124         sctp_ill = sctp_ipif->sctp_ipif_ill;
 125         ASSERT(sctp_ill != NULL);
 126         ill_index = SCTP_ILL_HASH_FN(sctp_ill->sctp_ill_index);
 127         if (sctp_ipif->sctp_ipif_state != SCTP_IPIFS_CONDEMNED ||
 128             sctp_ipif->sctp_ipif_refcnt != 0) {
 129                 rw_exit(&sctps->sctps_g_ipifs_lock);
 130                 rw_exit(&sctps->sctps_g_ills_lock);
 131                 return;
 132         }
 133         list_remove(&sctps->sctps_g_ipifs[hindex].sctp_ipif_list,
 134             sctp_ipif);
 135         sctps->sctps_g_ipifs[hindex].ipif_count--;
 136         sctps->sctps_g_ipifs_count--;
 137         rw_destroy(&sctp_ipif->sctp_ipif_lock);
 138         kmem_free(sctp_ipif, sizeof (sctp_ipif_t));
 139 
 140         (void) atomic_dec_32_nv(&sctp_ill->sctp_ill_ipifcnt);
 141         if (rw_tryupgrade(&sctps->sctps_g_ills_lock) != 0) {
 142                 rw_downgrade(&sctps->sctps_g_ipifs_lock);
 143                 if (sctp_ill->sctp_ill_ipifcnt == 0 &&
 144                     sctp_ill->sctp_ill_state == SCTP_ILLS_CONDEMNED) {
 145                         list_remove(&sctps->sctps_g_ills[ill_index].
 146                             sctp_ill_list, (void *)sctp_ill);
 147                         sctps->sctps_g_ills[ill_index].ill_count--;
 148                         sctps->sctps_ills_count--;
 149                         kmem_free(sctp_ill->sctp_ill_name,
 150                             sctp_ill->sctp_ill_name_length);
 151                         kmem_free(sctp_ill, sizeof (sctp_ill_t));
 152                 }
 153         }
 154         rw_exit(&sctps->sctps_g_ipifs_lock);
 155         rw_exit(&sctps->sctps_g_ills_lock);
 156 }
 157 
 158 /*
 159  * Lookup an SCTP IPIF given an IP address. Increments sctp_ipif refcnt.
 160  * We are either looking for a IPIF with the given address before
 161  * inserting it into the global list or looking for an IPIF for an
 162  * address given an SCTP. In the former case we always check the zoneid,
 163  * but for the latter case, check_zid could be B_FALSE if the connp
 164  * for the sctp has conn_all_zones set. When looking for an address we
 165  * give preference to one that is up, so even though we may find one that
 166  * is not up we keep looking if there is one up, we hold the down addr
 167  * in backup_ipif in case we don't find one that is up - i.e. we return
 168  * the backup_ipif in that case. Note that if we are looking for. If we
 169  * are specifically looking for an up address, then usable will be set
 170  * to true.
 171  */
 172 static sctp_ipif_t *
 173 sctp_lookup_ipif_addr(in6_addr_t *addr, boolean_t refhold, zoneid_t zoneid,
 174     boolean_t check_zid, uint_t ifindex, uint_t seqid, boolean_t usable,
 175     sctp_stack_t *sctps)
 176 {
 177         int             j;
 178         sctp_ipif_t     *sctp_ipif;
 179         sctp_ipif_t     *backup_ipif = NULL;
 180         int             hindex;
 181 
 182         hindex = SCTP_IPIF_ADDR_HASH(*addr, !IN6_IS_ADDR_V4MAPPED(addr));
 183 
 184         rw_enter(&sctps->sctps_g_ipifs_lock, RW_READER);
 185         if (sctps->sctps_g_ipifs[hindex].ipif_count == 0) {
 186                 rw_exit(&sctps->sctps_g_ipifs_lock);
 187                 return (NULL);
 188         }
 189         sctp_ipif = list_head(&sctps->sctps_g_ipifs[hindex].sctp_ipif_list);
 190         for (j = 0; j < sctps->sctps_g_ipifs[hindex].ipif_count; j++) {
 191                 rw_enter(&sctp_ipif->sctp_ipif_lock, RW_READER);
 192                 if ((!check_zid ||
 193                     (sctp_ipif->sctp_ipif_zoneid == ALL_ZONES ||
 194                     zoneid == sctp_ipif->sctp_ipif_zoneid)) &&
 195                     (ifindex == 0 || ifindex ==
 196                     sctp_ipif->sctp_ipif_ill->sctp_ill_index) &&
 197                     ((seqid != 0 && seqid == sctp_ipif->sctp_ipif_id) ||
 198                     (IN6_ARE_ADDR_EQUAL(&sctp_ipif->sctp_ipif_saddr,
 199                     addr)))) {
 200                         if (!usable || sctp_ipif->sctp_ipif_state ==
 201                             SCTP_IPIFS_UP) {
 202                                 rw_exit(&sctp_ipif->sctp_ipif_lock);
 203                                 if (refhold)
 204                                         SCTP_IPIF_REFHOLD(sctp_ipif);
 205                                 rw_exit(&sctps->sctps_g_ipifs_lock);
 206                                 return (sctp_ipif);
 207                         } else if (sctp_ipif->sctp_ipif_state ==
 208                             SCTP_IPIFS_DOWN && backup_ipif == NULL) {
 209                                 backup_ipif = sctp_ipif;
 210                         }
 211                 }
 212                 rw_exit(&sctp_ipif->sctp_ipif_lock);
 213                 sctp_ipif = list_next(
 214                     &sctps->sctps_g_ipifs[hindex].sctp_ipif_list, sctp_ipif);
 215         }
 216         if (backup_ipif != NULL) {
 217                 if (refhold)
 218                         SCTP_IPIF_REFHOLD(backup_ipif);
 219                 rw_exit(&sctps->sctps_g_ipifs_lock);
 220                 return (backup_ipif);
 221         }
 222         rw_exit(&sctps->sctps_g_ipifs_lock);
 223         return (NULL);
 224 }
 225 
 226 /*
 227  * Populate the list with all the SCTP ipifs for a given ipversion.
 228  * Increments sctp_ipif refcnt.
 229  * Called with no locks held.
 230  */
 231 static int
 232 sctp_get_all_ipifs(sctp_t *sctp, int sleep)
 233 {
 234         sctp_ipif_t             *sctp_ipif;
 235         int                     i;
 236         int                     j;
 237         int                     error = 0;
 238         sctp_stack_t            *sctps = sctp->sctp_sctps;
 239         boolean_t               isv6;
 240         conn_t                  *connp = sctp->sctp_connp;
 241 
 242         rw_enter(&sctps->sctps_g_ipifs_lock, RW_READER);
 243         for (i = 0; i < SCTP_IPIF_HASH; i++) {
 244                 if (sctps->sctps_g_ipifs[i].ipif_count == 0)
 245                         continue;
 246                 sctp_ipif = list_head(&sctps->sctps_g_ipifs[i].sctp_ipif_list);
 247                 for (j = 0; j < sctps->sctps_g_ipifs[i].ipif_count; j++) {
 248                         rw_enter(&sctp_ipif->sctp_ipif_lock, RW_READER);
 249                         isv6 = sctp_ipif->sctp_ipif_isv6;
 250                         if (SCTP_IPIF_DISCARD(sctp_ipif->sctp_ipif_flags) ||
 251                             !SCTP_IPIF_USABLE(sctp_ipif->sctp_ipif_state) ||
 252                             !SCTP_IPIF_ZONE_MATCH(sctp, sctp_ipif) ||
 253                             SCTP_IS_ADDR_UNSPEC(!isv6,
 254                             sctp_ipif->sctp_ipif_saddr) ||
 255                             (connp->conn_family == AF_INET && isv6) ||
 256                             (connp->conn_ipv6_v6only && !isv6)) {
 257                                 rw_exit(&sctp_ipif->sctp_ipif_lock);
 258                                 sctp_ipif = list_next(
 259                                     &sctps->sctps_g_ipifs[i].sctp_ipif_list,
 260                                     sctp_ipif);
 261                                 continue;
 262                         }
 263                         rw_exit(&sctp_ipif->sctp_ipif_lock);
 264                         SCTP_IPIF_REFHOLD(sctp_ipif);
 265                         error = sctp_ipif_hash_insert(sctp, sctp_ipif, sleep,
 266                             B_FALSE, B_FALSE);
 267                         if (error != 0 && error != EALREADY)
 268                                 goto free_stuff;
 269                         sctp_ipif = list_next(
 270                             &sctps->sctps_g_ipifs[i].sctp_ipif_list,
 271                             sctp_ipif);
 272                 }
 273         }
 274         rw_exit(&sctps->sctps_g_ipifs_lock);
 275         return (0);
 276 free_stuff:
 277         rw_exit(&sctps->sctps_g_ipifs_lock);
 278         sctp_free_saddrs(sctp);
 279         return (ENOMEM);
 280 }
 281 
 282 /*
 283  * Given a list of address, fills in the list of SCTP ipifs if all the addresses
 284  * are present in the SCTP interface list, return number of addresses filled
 285  * or error. If the caller wants the list of addresses, it sends a pre-allocated
 286  * buffer - list. Currently, this list is only used on a clustered node when
 287  * the SCTP is in the listen state (from sctp_bind_add()). When called on a
 288  * clustered node, the input is always a list of addresses (even if the
 289  * original bind() was to INADDR_ANY).
 290  * Called with no locks held.
 291  */
 292 int
 293 sctp_valid_addr_list(sctp_t *sctp, const void *addrs, uint32_t addrcnt,
 294     uchar_t *list, size_t lsize)
 295 {
 296         struct sockaddr_in      *sin4;
 297         struct sockaddr_in6     *sin6;
 298         struct in_addr          *addr4;
 299         in6_addr_t              addr;
 300         int                     cnt;
 301         int                     err = 0;
 302         int                     saddr_cnt = 0;
 303         sctp_ipif_t             *ipif;
 304         boolean_t               bind_to_all = B_FALSE;
 305         boolean_t               check_addrs = B_FALSE;
 306         boolean_t               check_lport = B_FALSE;
 307         uchar_t                 *p = list;
 308         conn_t                  *connp = sctp->sctp_connp;
 309 
 310         /*
 311          * Need to check for port and address depending on the state.
 312          * After a socket is bound, we need to make sure that subsequent
 313          * bindx() has correct port.  After an association is established,
 314          * we need to check for changing the bound address to invalid
 315          * addresses.
 316          */
 317         if (sctp->sctp_state >= SCTPS_BOUND) {
 318                 check_lport = B_TRUE;
 319                 if (sctp->sctp_state > SCTPS_LISTEN)
 320                         check_addrs = B_TRUE;
 321         }
 322 
 323         if (sctp->sctp_conn_tfp != NULL)
 324                 mutex_enter(&sctp->sctp_conn_tfp->tf_lock);
 325         if (sctp->sctp_listen_tfp != NULL)
 326                 mutex_enter(&sctp->sctp_listen_tfp->tf_lock);
 327         for (cnt = 0; cnt < addrcnt; cnt++) {
 328                 boolean_t       lookup_saddr = B_TRUE;
 329                 uint_t          ifindex = 0;
 330 
 331                 switch (connp->conn_family) {
 332                 case AF_INET:
 333                         sin4 = (struct sockaddr_in *)addrs + cnt;
 334                         if (sin4->sin_family != AF_INET || (check_lport &&
 335                             sin4->sin_port != connp->conn_lport)) {
 336                                 err = EINVAL;
 337                                 goto free_ret;
 338                         }
 339                         addr4 = &sin4->sin_addr;
 340                         if (check_addrs &&
 341                             (addr4->s_addr == INADDR_ANY ||
 342                             addr4->s_addr == INADDR_BROADCAST ||
 343                             CLASSD(addr4->s_addr))) {
 344                                 err = EINVAL;
 345                                 goto free_ret;
 346                         }
 347                         IN6_INADDR_TO_V4MAPPED(addr4, &addr);
 348                         if (!check_addrs && addr4->s_addr == INADDR_ANY) {
 349                                 lookup_saddr = B_FALSE;
 350                                 bind_to_all = B_TRUE;
 351                         }
 352 
 353                         break;
 354                 case AF_INET6:
 355                         sin6 = (struct sockaddr_in6 *)addrs + cnt;
 356                         if (sin6->sin6_family != AF_INET6 || (check_lport &&
 357                             sin6->sin6_port != connp->conn_lport)) {
 358                                 err = EINVAL;
 359                                 goto free_ret;
 360                         }
 361                         addr = sin6->sin6_addr;
 362                         /* Contains the interface index */
 363                         ifindex = sin6->sin6_scope_id;
 364                         if (connp->conn_ipv6_v6only &&
 365                             IN6_IS_ADDR_V4MAPPED(&addr)) {
 366                                 err = EAFNOSUPPORT;
 367                                 goto free_ret;
 368                         }
 369                         if (check_addrs &&
 370                             (IN6_IS_ADDR_LINKLOCAL(&addr) ||
 371                             IN6_IS_ADDR_MULTICAST(&addr) ||
 372                             IN6_IS_ADDR_UNSPECIFIED(&addr))) {
 373                                 err = EINVAL;
 374                                 goto free_ret;
 375                         }
 376                         if (!check_addrs && IN6_IS_ADDR_UNSPECIFIED(&addr)) {
 377                                 lookup_saddr = B_FALSE;
 378                                 bind_to_all = B_TRUE;
 379                         }
 380 
 381                         break;
 382                 default:
 383                         err = EAFNOSUPPORT;
 384                         goto free_ret;
 385                 }
 386                 if (lookup_saddr) {
 387                         ipif = sctp_lookup_ipif_addr(&addr, B_TRUE,
 388                             IPCL_ZONEID(connp), !connp->conn_allzones,
 389                             ifindex, 0, B_TRUE, sctp->sctp_sctps);
 390                         if (ipif == NULL) {
 391                                 /* Address not in the list */
 392                                 err = EINVAL;
 393                                 goto free_ret;
 394                         } else if (check_addrs && SCTP_IS_IPIF_LOOPBACK(ipif) &&
 395                             cl_sctp_check_addrs == NULL) {
 396                                 SCTP_IPIF_REFRELE(ipif);
 397                                 err = EINVAL;
 398                                 goto free_ret;
 399                         }
 400                 }
 401                 if (!bind_to_all) {
 402                         /*
 403                          * If an address is added after association setup,
 404                          * we need to wait for the peer to send us an ASCONF
 405                          * ACK before we can start using it.
 406                          * saddr_ipif_dontsrc will be reset (to 0) when we
 407                          * get the ASCONF ACK for this address.
 408                          */
 409                         err = sctp_ipif_hash_insert(sctp, ipif, KM_SLEEP,
 410                             check_addrs ? B_TRUE : B_FALSE, B_FALSE);
 411                         if (err != 0) {
 412                                 SCTP_IPIF_REFRELE(ipif);
 413                                 if (check_addrs && err == EALREADY)
 414                                         err = EADDRINUSE;
 415                                 goto free_ret;
 416                         }
 417                         saddr_cnt++;
 418                         if (lsize >= sizeof (addr)) {
 419                                 bcopy(&addr, p, sizeof (addr));
 420                                 p += sizeof (addr);
 421                                 lsize -= sizeof (addr);
 422                         }
 423                 }
 424         }
 425         if (bind_to_all) {
 426                 /*
 427                  * Free whatever we might have added before encountering
 428                  * inaddr_any.
 429                  */
 430                 if (sctp->sctp_nsaddrs > 0) {
 431                         sctp_free_saddrs(sctp);
 432                         ASSERT(sctp->sctp_nsaddrs == 0);
 433                 }
 434                 err = sctp_get_all_ipifs(sctp, KM_SLEEP);
 435                 if (err != 0)
 436                         return (err);
 437                 sctp->sctp_bound_to_all = 1;
 438         }
 439         if (sctp->sctp_listen_tfp != NULL)
 440                 mutex_exit(&sctp->sctp_listen_tfp->tf_lock);
 441         if (sctp->sctp_conn_tfp != NULL)
 442                 mutex_exit(&sctp->sctp_conn_tfp->tf_lock);
 443         return (0);
 444 free_ret:
 445         if (saddr_cnt != 0)
 446                 sctp_del_saddr_list(sctp, addrs, saddr_cnt, B_TRUE);
 447         if (sctp->sctp_listen_tfp != NULL)
 448                 mutex_exit(&sctp->sctp_listen_tfp->tf_lock);
 449         if (sctp->sctp_conn_tfp != NULL)
 450                 mutex_exit(&sctp->sctp_conn_tfp->tf_lock);
 451         return (err);
 452 }
 453 
 454 static int
 455 sctp_ipif_hash_insert(sctp_t *sctp, sctp_ipif_t *ipif, int sleep,
 456     boolean_t dontsrc, boolean_t allow_dup)
 457 {
 458         int                     cnt;
 459         sctp_saddr_ipif_t       *ipif_obj;
 460         int                     hindex;
 461 
 462         hindex = SCTP_IPIF_ADDR_HASH(ipif->sctp_ipif_saddr,
 463             ipif->sctp_ipif_isv6);
 464         rw_enter(&sctp->sctp_saddrs[hindex].ipif_hash_lock, RW_WRITER);
 465         ipif_obj = list_head(&sctp->sctp_saddrs[hindex].sctp_ipif_list);
 466         for (cnt = 0; cnt < sctp->sctp_saddrs[hindex].ipif_count; cnt++) {
 467                 if (IN6_ARE_ADDR_EQUAL(&ipif_obj->saddr_ipifp->sctp_ipif_saddr,
 468                     &ipif->sctp_ipif_saddr)) {
 469                         if (ipif->sctp_ipif_id !=
 470                             ipif_obj->saddr_ipifp->sctp_ipif_id &&
 471                             ipif_obj->saddr_ipifp->sctp_ipif_state ==
 472                             SCTP_IPIFS_DOWN && ipif->sctp_ipif_state ==
 473                             SCTP_IPIFS_UP) {
 474                                 SCTP_IPIF_REFRELE(ipif_obj->saddr_ipifp);
 475                                 ipif_obj->saddr_ipifp = ipif;
 476                                 ipif_obj->saddr_ipif_dontsrc = dontsrc ? 1 : 0;
 477                                 rw_exit(
 478                                     &sctp->sctp_saddrs[hindex].ipif_hash_lock);
 479                                 return (0);
 480                         } else if (!allow_dup || ipif->sctp_ipif_id ==
 481                             ipif_obj->saddr_ipifp->sctp_ipif_id) {
 482                                 rw_exit(
 483                                     &sctp->sctp_saddrs[hindex].ipif_hash_lock);
 484                                 return (EALREADY);
 485                         }
 486                 }
 487                 ipif_obj = list_next(&sctp->sctp_saddrs[hindex].sctp_ipif_list,
 488                     ipif_obj);
 489         }
 490         ipif_obj = kmem_zalloc(sizeof (sctp_saddr_ipif_t), sleep);
 491         if (ipif_obj == NULL) {
 492                 rw_exit(&sctp->sctp_saddrs[hindex].ipif_hash_lock);
 493                 /* Need to do something */
 494                 return (ENOMEM);
 495         }
 496         ipif_obj->saddr_ipifp = ipif;
 497         ipif_obj->saddr_ipif_dontsrc = dontsrc ? 1 : 0;
 498         list_insert_tail(&sctp->sctp_saddrs[hindex].sctp_ipif_list, ipif_obj);
 499         sctp->sctp_saddrs[hindex].ipif_count++;
 500         sctp->sctp_nsaddrs++;
 501         rw_exit(&sctp->sctp_saddrs[hindex].ipif_hash_lock);
 502         return (0);
 503 }
 504 
 505 /*
 506  * Given a source address, walk through the peer address list to see
 507  * if the source address is being used.  If it is, reset that.
 508  * A cleared saddr will then make sctp_make_mp lookup the destination again
 509  * and as part of that look for a new source.
 510  */
 511 static void
 512 sctp_fix_saddr(sctp_t *sctp, in6_addr_t *saddr)
 513 {
 514         sctp_faddr_t    *fp;
 515 
 516         for (fp = sctp->sctp_faddrs; fp != NULL; fp = fp->sf_next) {
 517                 if (!IN6_ARE_ADDR_EQUAL(&fp->sf_saddr, saddr))
 518                         continue;
 519                 V6_SET_ZERO(fp->sf_saddr);
 520         }
 521 }
 522 
 523 static void
 524 sctp_ipif_hash_remove(sctp_t *sctp, sctp_ipif_t *ipif, boolean_t locked)
 525 {
 526         int                     cnt;
 527         sctp_saddr_ipif_t       *ipif_obj;
 528         int                     hindex;
 529 
 530         hindex = SCTP_IPIF_ADDR_HASH(ipif->sctp_ipif_saddr,
 531             ipif->sctp_ipif_isv6);
 532         if (!locked)
 533                 rw_enter(&sctp->sctp_saddrs[hindex].ipif_hash_lock, RW_WRITER);
 534         ipif_obj = list_head(&sctp->sctp_saddrs[hindex].sctp_ipif_list);
 535         for (cnt = 0; cnt < sctp->sctp_saddrs[hindex].ipif_count; cnt++) {
 536                 if (IN6_ARE_ADDR_EQUAL(&ipif_obj->saddr_ipifp->sctp_ipif_saddr,
 537                     &ipif->sctp_ipif_saddr)) {
 538                         list_remove(&sctp->sctp_saddrs[hindex].sctp_ipif_list,
 539                             ipif_obj);
 540                         sctp->sctp_saddrs[hindex].ipif_count--;
 541                         sctp->sctp_nsaddrs--;
 542                         sctp_fix_saddr(sctp, &ipif->sctp_ipif_saddr);
 543                         SCTP_IPIF_REFRELE(ipif_obj->saddr_ipifp);
 544                         kmem_free(ipif_obj, sizeof (sctp_saddr_ipif_t));
 545                         break;
 546                 }
 547                 ipif_obj = list_next(&sctp->sctp_saddrs[hindex].sctp_ipif_list,
 548                     ipif_obj);
 549         }
 550         if (!locked)
 551                 rw_exit(&sctp->sctp_saddrs[hindex].ipif_hash_lock);
 552 }
 553 
 554 static int
 555 sctp_compare_ipif_list(sctp_ipif_hash_t *list1, sctp_ipif_hash_t *list2)
 556 {
 557         int                     i;
 558         int                     j;
 559         sctp_saddr_ipif_t       *obj1;
 560         sctp_saddr_ipif_t       *obj2;
 561         int                     overlap = 0;
 562 
 563         rw_enter(&list1->ipif_hash_lock, RW_READER);
 564         rw_enter(&list2->ipif_hash_lock, RW_READER);
 565         obj1 = list_head(&list1->sctp_ipif_list);
 566         for (i = 0; i < list1->ipif_count; i++) {
 567                 obj2 = list_head(&list2->sctp_ipif_list);
 568                 for (j = 0; j < list2->ipif_count; j++) {
 569                         if (IN6_ARE_ADDR_EQUAL(
 570                             &obj1->saddr_ipifp->sctp_ipif_saddr,
 571                             &obj2->saddr_ipifp->sctp_ipif_saddr)) {
 572                                 overlap++;
 573                                 break;
 574                         }
 575                         obj2 = list_next(&list2->sctp_ipif_list,
 576                             obj2);
 577                 }
 578                 obj1 = list_next(&list1->sctp_ipif_list, obj1);
 579         }
 580         rw_exit(&list1->ipif_hash_lock);
 581         rw_exit(&list2->ipif_hash_lock);
 582         return (overlap);
 583 }
 584 
 585 int
 586 sctp_compare_saddrs(sctp_t *sctp1, sctp_t *sctp2)
 587 {
 588         int             i;
 589         int             overlap = 0;
 590 
 591         for (i = 0; i < SCTP_IPIF_HASH; i++) {
 592                 overlap += sctp_compare_ipif_list(&sctp1->sctp_saddrs[i],
 593                     &sctp2->sctp_saddrs[i]);
 594         }
 595 
 596         if (sctp1->sctp_nsaddrs == sctp2->sctp_nsaddrs &&
 597             overlap == sctp1->sctp_nsaddrs) {
 598                 return (SCTP_ADDR_EQUAL);
 599         }
 600 
 601         if (overlap == sctp1->sctp_nsaddrs)
 602                 return (SCTP_ADDR_SUBSET);
 603 
 604         if (overlap > 0)
 605                 return (SCTP_ADDR_OVERLAP);
 606 
 607         return (SCTP_ADDR_DISJOINT);
 608 }
 609 
 610 static int
 611 sctp_copy_ipifs(sctp_ipif_hash_t *list1, sctp_t *sctp2, int sleep)
 612 {
 613         int                     i;
 614         sctp_saddr_ipif_t       *obj;
 615         int                     error = 0;
 616 
 617         rw_enter(&list1->ipif_hash_lock, RW_READER);
 618         obj = list_head(&list1->sctp_ipif_list);
 619         for (i = 0; i < list1->ipif_count; i++) {
 620                 SCTP_IPIF_REFHOLD(obj->saddr_ipifp);
 621                 error = sctp_ipif_hash_insert(sctp2, obj->saddr_ipifp, sleep,
 622                     B_FALSE, B_FALSE);
 623                 ASSERT(error != EALREADY);
 624                 if (error != 0) {
 625                         rw_exit(&list1->ipif_hash_lock);
 626                         return (error);
 627                 }
 628                 obj = list_next(&list1->sctp_ipif_list, obj);
 629         }
 630         rw_exit(&list1->ipif_hash_lock);
 631         return (error);
 632 }
 633 
 634 int
 635 sctp_dup_saddrs(sctp_t *sctp1, sctp_t *sctp2, int sleep)
 636 {
 637         int     error = 0;
 638         int     i;
 639 
 640         if (sctp1 == NULL || sctp1->sctp_bound_to_all == 1)
 641                 return (sctp_get_all_ipifs(sctp2, sleep));
 642 
 643         for (i = 0; i < SCTP_IPIF_HASH; i++) {
 644                 rw_enter(&sctp1->sctp_saddrs[i].ipif_hash_lock, RW_READER);
 645                 if (sctp1->sctp_saddrs[i].ipif_count == 0) {
 646                         rw_exit(&sctp1->sctp_saddrs[i].ipif_hash_lock);
 647                         continue;
 648                 }
 649                 error = sctp_copy_ipifs(&sctp1->sctp_saddrs[i], sctp2, sleep);
 650                 if (error != 0) {
 651                         rw_exit(&sctp1->sctp_saddrs[i].ipif_hash_lock);
 652                         sctp_free_saddrs(sctp2);
 653                         return (error);
 654                 }
 655                 rw_exit(&sctp1->sctp_saddrs[i].ipif_hash_lock);
 656         }
 657         return (0);
 658 }
 659 
 660 void
 661 sctp_free_saddrs(sctp_t *sctp)
 662 {
 663         int                     i;
 664         int                     l;
 665         sctp_saddr_ipif_t       *obj;
 666 
 667         if (sctp->sctp_nsaddrs == 0)
 668                 return;
 669         for (i = 0; i < SCTP_IPIF_HASH; i++) {
 670                 rw_enter(&sctp->sctp_saddrs[i].ipif_hash_lock, RW_WRITER);
 671                 if (sctp->sctp_saddrs[i].ipif_count == 0) {
 672                         rw_exit(&sctp->sctp_saddrs[i].ipif_hash_lock);
 673                         continue;
 674                 }
 675                 obj = list_tail(&sctp->sctp_saddrs[i].sctp_ipif_list);
 676                 for (l = 0; l < sctp->sctp_saddrs[i].ipif_count; l++) {
 677                         list_remove(&sctp->sctp_saddrs[i].sctp_ipif_list, obj);
 678                         SCTP_IPIF_REFRELE(obj->saddr_ipifp);
 679                         sctp->sctp_nsaddrs--;
 680                         kmem_free(obj, sizeof (sctp_saddr_ipif_t));
 681                         obj = list_tail(&sctp->sctp_saddrs[i].sctp_ipif_list);
 682                 }
 683                 sctp->sctp_saddrs[i].ipif_count = 0;
 684                 rw_exit(&sctp->sctp_saddrs[i].ipif_hash_lock);
 685         }
 686         if (sctp->sctp_bound_to_all == 1)
 687                 sctp->sctp_bound_to_all = 0;
 688         ASSERT(sctp->sctp_nsaddrs == 0);
 689 }
 690 
 691 /*
 692  * Add/Delete the given ILL from the SCTP ILL list. Called with no locks
 693  * held.
 694  */
 695 void
 696 sctp_update_ill(ill_t *ill, int op)
 697 {
 698         int             i;
 699         sctp_ill_t      *sctp_ill = NULL;
 700         uint_t          index;
 701         netstack_t      *ns = ill->ill_ipst->ips_netstack;
 702         sctp_stack_t    *sctps = ns->netstack_sctp;
 703 
 704         rw_enter(&sctps->sctps_g_ills_lock, RW_WRITER);
 705 
 706         index = SCTP_ILL_HASH_FN(SCTP_ILL_TO_PHYINDEX(ill));
 707         sctp_ill = list_head(&sctps->sctps_g_ills[index].sctp_ill_list);
 708         for (i = 0; i < sctps->sctps_g_ills[index].ill_count; i++) {
 709                 if ((sctp_ill->sctp_ill_index == SCTP_ILL_TO_PHYINDEX(ill)) &&
 710                     (sctp_ill->sctp_ill_isv6 == ill->ill_isv6)) {
 711                         break;
 712                 }
 713                 sctp_ill = list_next(&sctps->sctps_g_ills[index].sctp_ill_list,
 714                     sctp_ill);
 715         }
 716 
 717         switch (op) {
 718         case SCTP_ILL_INSERT:
 719                 if (sctp_ill != NULL) {
 720                         /* Unmark it if it is condemned */
 721                         if (sctp_ill->sctp_ill_state == SCTP_ILLS_CONDEMNED)
 722                                 sctp_ill->sctp_ill_state = 0;
 723                         rw_exit(&sctps->sctps_g_ills_lock);
 724                         return;
 725                 }
 726                 sctp_ill = kmem_zalloc(sizeof (sctp_ill_t), KM_NOSLEEP);
 727                 /* Need to re-try? */
 728                 if (sctp_ill == NULL) {
 729                         cmn_err(CE_WARN, "sctp_update_ill: error adding "
 730                             "ILL %p to SCTP's ILL list", (void *)ill);
 731                         rw_exit(&sctps->sctps_g_ills_lock);
 732                         return;
 733                 }
 734                 sctp_ill->sctp_ill_name = kmem_zalloc(ill->ill_name_length,
 735                     KM_NOSLEEP);
 736                 if (sctp_ill->sctp_ill_name == NULL) {
 737                         cmn_err(CE_WARN, "sctp_update_ill: error adding "
 738                             "ILL %p to SCTP's ILL list", (void *)ill);
 739                         kmem_free(sctp_ill, sizeof (sctp_ill_t));
 740                         rw_exit(&sctps->sctps_g_ills_lock);
 741                         return;
 742                 }
 743                 bcopy(ill->ill_name, sctp_ill->sctp_ill_name,
 744                     ill->ill_name_length);
 745                 sctp_ill->sctp_ill_name_length = ill->ill_name_length;
 746                 sctp_ill->sctp_ill_index = SCTP_ILL_TO_PHYINDEX(ill);
 747                 sctp_ill->sctp_ill_flags = ill->ill_phyint->phyint_flags;
 748                 sctp_ill->sctp_ill_netstack = ns;    /* No netstack_hold */
 749                 sctp_ill->sctp_ill_isv6 = ill->ill_isv6;
 750                 list_insert_tail(&sctps->sctps_g_ills[index].sctp_ill_list,
 751                     (void *)sctp_ill);
 752                 sctps->sctps_g_ills[index].ill_count++;
 753                 sctps->sctps_ills_count++;
 754 
 755                 break;
 756 
 757         case SCTP_ILL_REMOVE:
 758 
 759                 if (sctp_ill == NULL) {
 760                         rw_exit(&sctps->sctps_g_ills_lock);
 761                         return;
 762                 }
 763                 if (sctp_ill->sctp_ill_ipifcnt == 0) {
 764                         list_remove(&sctps->sctps_g_ills[index].sctp_ill_list,
 765                             (void *)sctp_ill);
 766                         sctps->sctps_g_ills[index].ill_count--;
 767                         sctps->sctps_ills_count--;
 768                         kmem_free(sctp_ill->sctp_ill_name,
 769                             ill->ill_name_length);
 770                         kmem_free(sctp_ill, sizeof (sctp_ill_t));
 771                 } else {
 772                         sctp_ill->sctp_ill_state = SCTP_ILLS_CONDEMNED;
 773                 }
 774 
 775                 break;
 776         }
 777         rw_exit(&sctps->sctps_g_ills_lock);
 778 }
 779 
 780 /*
 781  * The ILL's index is being changed, just remove it from the old list,
 782  * change the SCTP ILL's index and re-insert using the new index.
 783  */
 784 void
 785 sctp_ill_reindex(ill_t *ill, uint_t orig_ill_index)
 786 {
 787         sctp_ill_t      *sctp_ill = NULL;
 788         sctp_ill_t      *nxt_sill;
 789         uint_t          indx;
 790         uint_t          nindx;
 791         boolean_t       once = B_FALSE;
 792         netstack_t      *ns = ill->ill_ipst->ips_netstack;
 793         sctp_stack_t    *sctps = ns->netstack_sctp;
 794 
 795         rw_enter(&sctps->sctps_g_ills_lock, RW_WRITER);
 796 
 797         indx = SCTP_ILL_HASH_FN(orig_ill_index);
 798         nindx = SCTP_ILL_HASH_FN(SCTP_ILL_TO_PHYINDEX(ill));
 799         sctp_ill = list_head(&sctps->sctps_g_ills[indx].sctp_ill_list);
 800         while (sctp_ill != NULL) {
 801                 nxt_sill = list_next(&sctps->sctps_g_ills[indx].sctp_ill_list,
 802                     sctp_ill);
 803                 if (sctp_ill->sctp_ill_index == orig_ill_index) {
 804                         sctp_ill->sctp_ill_index = SCTP_ILL_TO_PHYINDEX(ill);
 805                         /*
 806                          * if the new index hashes to the same value, all's
 807                          * done.
 808                          */
 809                         if (nindx != indx) {
 810                                 list_remove(
 811                                     &sctps->sctps_g_ills[indx].sctp_ill_list,
 812                                     (void *)sctp_ill);
 813                                 sctps->sctps_g_ills[indx].ill_count--;
 814                                 list_insert_tail(
 815                                     &sctps->sctps_g_ills[nindx].sctp_ill_list,
 816                                     (void *)sctp_ill);
 817                                 sctps->sctps_g_ills[nindx].ill_count++;
 818                         }
 819                         if (once)
 820                                 break;
 821                         /* We might have one for v4 and for v6 */
 822                         once = B_TRUE;
 823                 }
 824                 sctp_ill = nxt_sill;
 825         }
 826         rw_exit(&sctps->sctps_g_ills_lock);
 827 }
 828 
 829 /* move ipif from f_ill to t_ill */
 830 void
 831 sctp_move_ipif(ipif_t *ipif, ill_t *f_ill, ill_t *t_ill)
 832 {
 833         sctp_ill_t      *fsctp_ill = NULL;
 834         sctp_ill_t      *tsctp_ill = NULL;
 835         sctp_ipif_t     *sctp_ipif;
 836         uint_t          hindex;
 837         int             i;
 838         netstack_t      *ns = ipif->ipif_ill->ill_ipst->ips_netstack;
 839         sctp_stack_t    *sctps = ns->netstack_sctp;
 840 
 841         rw_enter(&sctps->sctps_g_ills_lock, RW_READER);
 842         rw_enter(&sctps->sctps_g_ipifs_lock, RW_READER);
 843 
 844         hindex = SCTP_ILL_HASH_FN(SCTP_ILL_TO_PHYINDEX(f_ill));
 845         fsctp_ill = list_head(&sctps->sctps_g_ills[hindex].sctp_ill_list);
 846         for (i = 0; i < sctps->sctps_g_ills[hindex].ill_count; i++) {
 847                 if (fsctp_ill->sctp_ill_index == SCTP_ILL_TO_PHYINDEX(f_ill) &&
 848                     fsctp_ill->sctp_ill_isv6 == f_ill->ill_isv6) {
 849                         break;
 850                 }
 851                 fsctp_ill = list_next(
 852                     &sctps->sctps_g_ills[hindex].sctp_ill_list, fsctp_ill);
 853         }
 854 
 855         hindex = SCTP_ILL_HASH_FN(SCTP_ILL_TO_PHYINDEX(t_ill));
 856         tsctp_ill = list_head(&sctps->sctps_g_ills[hindex].sctp_ill_list);
 857         for (i = 0; i < sctps->sctps_g_ills[hindex].ill_count; i++) {
 858                 if (tsctp_ill->sctp_ill_index == SCTP_ILL_TO_PHYINDEX(t_ill) &&
 859                     tsctp_ill->sctp_ill_isv6 == t_ill->ill_isv6) {
 860                         break;
 861                 }
 862                 tsctp_ill = list_next(
 863                     &sctps->sctps_g_ills[hindex].sctp_ill_list, tsctp_ill);
 864         }
 865 
 866         hindex = SCTP_IPIF_ADDR_HASH(ipif->ipif_v6lcl_addr,
 867             ipif->ipif_ill->ill_isv6);
 868         sctp_ipif = list_head(&sctps->sctps_g_ipifs[hindex].sctp_ipif_list);
 869         for (i = 0; i < sctps->sctps_g_ipifs[hindex].ipif_count; i++) {
 870                 if (sctp_ipif->sctp_ipif_id == ipif->ipif_seqid)
 871                         break;
 872                 sctp_ipif = list_next(
 873                     &sctps->sctps_g_ipifs[hindex].sctp_ipif_list, sctp_ipif);
 874         }
 875         /* Should be an ASSERT? */
 876         if (fsctp_ill == NULL || tsctp_ill == NULL || sctp_ipif == NULL) {
 877                 ip1dbg(("sctp_move_ipif: error moving ipif %p from %p to %p\n",
 878                     (void *)ipif, (void *)f_ill, (void *)t_ill));
 879                 rw_exit(&sctps->sctps_g_ipifs_lock);
 880                 rw_exit(&sctps->sctps_g_ills_lock);
 881                 return;
 882         }
 883         rw_enter(&sctp_ipif->sctp_ipif_lock, RW_WRITER);
 884         ASSERT(sctp_ipif->sctp_ipif_ill == fsctp_ill);
 885         sctp_ipif->sctp_ipif_ill = tsctp_ill;
 886         rw_exit(&sctp_ipif->sctp_ipif_lock);
 887         (void) atomic_dec_32_nv(&fsctp_ill->sctp_ill_ipifcnt);
 888         atomic_inc_32(&tsctp_ill->sctp_ill_ipifcnt);
 889         rw_exit(&sctps->sctps_g_ipifs_lock);
 890         rw_exit(&sctps->sctps_g_ills_lock);
 891 }
 892 
 893 /*
 894  * Walk the list of SCTPs and find each that has oipif in it's saddr list, and
 895  * if so replace it with nipif.
 896  */
 897 void
 898 sctp_update_saddrs(sctp_ipif_t *oipif, sctp_ipif_t *nipif, int idx,
 899     sctp_stack_t *sctps)
 900 {
 901         sctp_t                  *sctp;
 902         sctp_t                  *sctp_prev = NULL;
 903         sctp_saddr_ipif_t       *sobj;
 904         int                     count;
 905 
 906         mutex_enter(&sctps->sctps_g_lock);
 907         sctp = list_head(&sctps->sctps_g_list);
 908         while (sctp != NULL && oipif->sctp_ipif_refcnt > 0) {
 909                 mutex_enter(&sctp->sctp_reflock);
 910                 if (sctp->sctp_condemned ||
 911                     sctp->sctp_saddrs[idx].ipif_count <= 0) {
 912                         mutex_exit(&sctp->sctp_reflock);
 913                         sctp = list_next(&sctps->sctps_g_list, sctp);
 914                         continue;
 915                 }
 916                 sctp->sctp_refcnt++;
 917                 mutex_exit(&sctp->sctp_reflock);
 918                 mutex_exit(&sctps->sctps_g_lock);
 919                 if (sctp_prev != NULL)
 920                         SCTP_REFRELE(sctp_prev);
 921 
 922                 RUN_SCTP(sctp);
 923                 sobj = list_head(&sctp->sctp_saddrs[idx].sctp_ipif_list);
 924                 for (count = 0; count <
 925                     sctp->sctp_saddrs[idx].ipif_count; count++) {
 926                         if (sobj->saddr_ipifp == oipif) {
 927                                 SCTP_IPIF_REFHOLD(nipif);
 928                                 sobj->saddr_ipifp = nipif;
 929                                 ASSERT(oipif->sctp_ipif_refcnt > 0);
 930                                 /* We have the writer lock */
 931                                 oipif->sctp_ipif_refcnt--;
 932                                 /*
 933                                  * Can't have more than one referring
 934                                  * to the same sctp_ipif.
 935                                  */
 936                                 break;
 937                         }
 938                         sobj = list_next(&sctp->sctp_saddrs[idx].sctp_ipif_list,
 939                             sobj);
 940                 }
 941                 WAKE_SCTP(sctp);
 942                 sctp_prev = sctp;
 943                 mutex_enter(&sctps->sctps_g_lock);
 944                 sctp = list_next(&sctps->sctps_g_list, sctp);
 945         }
 946         mutex_exit(&sctps->sctps_g_lock);
 947         if (sctp_prev != NULL)
 948                 SCTP_REFRELE(sctp_prev);
 949 }
 950 
 951 /*
 952  * Given an ipif, walk the hash list in the global ipif table and for
 953  * any other SCTP ipif with the same address and non-zero reference, walk
 954  * the SCTP list and update the saddr list, if required, to point to the
 955  * new SCTP ipif. If it is a loopback interface, then there could be
 956  * multiple interfaces with 127.0.0.1 if there are zones configured, so
 957  * check the zoneid in addition to the address.
 958  */
 959 void
 960 sctp_chk_and_updt_saddr(int hindex, sctp_ipif_t *ipif, sctp_stack_t *sctps)
 961 {
 962         int             cnt;
 963         sctp_ipif_t     *sipif;
 964 
 965         ASSERT(sctps->sctps_g_ipifs[hindex].ipif_count > 0);
 966         ASSERT(ipif->sctp_ipif_state == SCTP_IPIFS_UP);
 967 
 968         sipif = list_head(&sctps->sctps_g_ipifs[hindex].sctp_ipif_list);
 969         for (cnt = 0; cnt < sctps->sctps_g_ipifs[hindex].ipif_count; cnt++) {
 970                 rw_enter(&sipif->sctp_ipif_lock, RW_WRITER);
 971                 if (sipif->sctp_ipif_id != ipif->sctp_ipif_id &&
 972                     IN6_ARE_ADDR_EQUAL(&sipif->sctp_ipif_saddr,
 973                     &ipif->sctp_ipif_saddr) && sipif->sctp_ipif_refcnt > 0 &&
 974                     (!SCTP_IS_IPIF_LOOPBACK(ipif) || ipif->sctp_ipif_zoneid ==
 975                     sipif->sctp_ipif_zoneid)) {
 976                         /*
 977                          * There can only be one address up at any time
 978                          * and we are here because ipif has been brought
 979                          * up.
 980                          */
 981                         ASSERT(sipif->sctp_ipif_state != SCTP_IPIFS_UP);
 982                         /*
 983                          * Someone has a reference to this we need to update to
 984                          * point to the new sipif.
 985                          */
 986                         sctp_update_saddrs(sipif, ipif, hindex, sctps);
 987                 }
 988                 rw_exit(&sipif->sctp_ipif_lock);
 989                 sipif = list_next(&sctps->sctps_g_ipifs[hindex].sctp_ipif_list,
 990                     sipif);
 991         }
 992 }
 993 
 994 /*
 995  * Insert a new SCTP ipif using 'ipif'. v6addr is the address that existed
 996  * prior to the current address in 'ipif'. Only when an existing address
 997  * is changed on an IPIF, will v6addr be specified. If the IPIF already
 998  * exists in the global SCTP ipif table, then we either removed it, if
 999  * it doesn't have any existing reference, or mark it condemned otherwise.
1000  * If an address is being brought up (IPIF_UP), then we need to scan
1001  * the SCTP list to check if there is any SCTP that points to the *same*
1002  * address on a different SCTP ipif and update in that case.
1003  */
1004 void
1005 sctp_update_ipif_addr(ipif_t *ipif, in6_addr_t v6addr)
1006 {
1007         ill_t           *ill = ipif->ipif_ill;
1008         int             i;
1009         sctp_ill_t      *sctp_ill;
1010         sctp_ill_t      *osctp_ill;
1011         sctp_ipif_t     *sctp_ipif = NULL;
1012         sctp_ipif_t     *osctp_ipif = NULL;
1013         uint_t          ill_index;
1014         int             hindex;
1015         sctp_stack_t    *sctps;
1016 
1017         sctps = ipif->ipif_ill->ill_ipst->ips_netstack->netstack_sctp;
1018 
1019         /* Index for new address */
1020         hindex = SCTP_IPIF_ADDR_HASH(ipif->ipif_v6lcl_addr, ill->ill_isv6);
1021 
1022         /*
1023          * The address on this IPIF is changing, we need to look for
1024          * this old address and mark it condemned, before creating
1025          * one for the new address.
1026          */
1027         osctp_ipif = sctp_lookup_ipif_addr(&v6addr, B_FALSE,
1028             ipif->ipif_zoneid, B_TRUE, SCTP_ILL_TO_PHYINDEX(ill),
1029             ipif->ipif_seqid, B_FALSE, sctps);
1030 
1031         rw_enter(&sctps->sctps_g_ills_lock, RW_READER);
1032         rw_enter(&sctps->sctps_g_ipifs_lock, RW_WRITER);
1033 
1034         ill_index = SCTP_ILL_HASH_FN(SCTP_ILL_TO_PHYINDEX(ill));
1035         sctp_ill = list_head(&sctps->sctps_g_ills[ill_index].sctp_ill_list);
1036         for (i = 0; i < sctps->sctps_g_ills[ill_index].ill_count; i++) {
1037                 if (sctp_ill->sctp_ill_index == SCTP_ILL_TO_PHYINDEX(ill) &&
1038                     sctp_ill->sctp_ill_isv6 == ill->ill_isv6) {
1039                         break;
1040                 }
1041                 sctp_ill = list_next(
1042                     &sctps->sctps_g_ills[ill_index].sctp_ill_list, sctp_ill);
1043         }
1044 
1045         if (sctp_ill == NULL) {
1046                 ip1dbg(("sctp_update_ipif_addr: ill not found ..\n"));
1047                 rw_exit(&sctps->sctps_g_ipifs_lock);
1048                 rw_exit(&sctps->sctps_g_ills_lock);
1049                 return;
1050         }
1051 
1052         if (osctp_ipif != NULL) {
1053 
1054                 /* The address is the same? */
1055                 if (IN6_ARE_ADDR_EQUAL(&ipif->ipif_v6lcl_addr, &v6addr)) {
1056                         boolean_t       chk_n_updt = B_FALSE;
1057 
1058                         rw_downgrade(&sctps->sctps_g_ipifs_lock);
1059                         rw_enter(&osctp_ipif->sctp_ipif_lock, RW_WRITER);
1060                         if (ipif->ipif_flags & IPIF_UP &&
1061                             osctp_ipif->sctp_ipif_state != SCTP_IPIFS_UP) {
1062                                 osctp_ipif->sctp_ipif_state = SCTP_IPIFS_UP;
1063                                 chk_n_updt = B_TRUE;
1064                         } else {
1065                                 osctp_ipif->sctp_ipif_state = SCTP_IPIFS_DOWN;
1066                         }
1067                         osctp_ipif->sctp_ipif_flags = ipif->ipif_flags;
1068                         rw_exit(&osctp_ipif->sctp_ipif_lock);
1069                         if (chk_n_updt) {
1070                                 sctp_chk_and_updt_saddr(hindex, osctp_ipif,
1071                                     sctps);
1072                         }
1073                         rw_exit(&sctps->sctps_g_ipifs_lock);
1074                         rw_exit(&sctps->sctps_g_ills_lock);
1075                         return;
1076                 }
1077                 /*
1078                  * We are effectively removing this address from the ILL.
1079                  */
1080                 if (osctp_ipif->sctp_ipif_refcnt != 0) {
1081                         osctp_ipif->sctp_ipif_state = SCTP_IPIFS_CONDEMNED;
1082                 } else {
1083                         list_t          *ipif_list;
1084                         int             ohindex;
1085 
1086                         osctp_ill = osctp_ipif->sctp_ipif_ill;
1087                         /* hash index for the old one */
1088                         ohindex = SCTP_IPIF_ADDR_HASH(
1089                             osctp_ipif->sctp_ipif_saddr,
1090                             osctp_ipif->sctp_ipif_isv6);
1091 
1092                         ipif_list =
1093                             &sctps->sctps_g_ipifs[ohindex].sctp_ipif_list;
1094 
1095                         list_remove(ipif_list, (void *)osctp_ipif);
1096                         sctps->sctps_g_ipifs[ohindex].ipif_count--;
1097                         sctps->sctps_g_ipifs_count--;
1098                         rw_destroy(&osctp_ipif->sctp_ipif_lock);
1099                         kmem_free(osctp_ipif, sizeof (sctp_ipif_t));
1100                         (void) atomic_dec_32_nv(&osctp_ill->sctp_ill_ipifcnt);
1101                 }
1102         }
1103 
1104         sctp_ipif = kmem_zalloc(sizeof (sctp_ipif_t), KM_NOSLEEP);
1105         /* Try again? */
1106         if (sctp_ipif == NULL) {
1107                 cmn_err(CE_WARN, "sctp_update_ipif_addr: error adding "
1108                     "IPIF %p to SCTP's IPIF list", (void *)ipif);
1109                 rw_exit(&sctps->sctps_g_ipifs_lock);
1110                 rw_exit(&sctps->sctps_g_ills_lock);
1111                 return;
1112         }
1113         sctps->sctps_g_ipifs_count++;
1114         rw_init(&sctp_ipif->sctp_ipif_lock, NULL, RW_DEFAULT, NULL);
1115         sctp_ipif->sctp_ipif_saddr = ipif->ipif_v6lcl_addr;
1116         sctp_ipif->sctp_ipif_ill = sctp_ill;
1117         sctp_ipif->sctp_ipif_isv6 = ill->ill_isv6;
1118         sctp_ipif->sctp_ipif_zoneid = ipif->ipif_zoneid;
1119         sctp_ipif->sctp_ipif_id = ipif->ipif_seqid;
1120         if (ipif->ipif_flags & IPIF_UP)
1121                 sctp_ipif->sctp_ipif_state = SCTP_IPIFS_UP;
1122         else
1123                 sctp_ipif->sctp_ipif_state = SCTP_IPIFS_DOWN;
1124         sctp_ipif->sctp_ipif_flags = ipif->ipif_flags;
1125         /*
1126          * We add it to the head so that it is quicker to find good/recent
1127          * additions.
1128          */
1129         list_insert_head(&sctps->sctps_g_ipifs[hindex].sctp_ipif_list,
1130             (void *)sctp_ipif);
1131         sctps->sctps_g_ipifs[hindex].ipif_count++;
1132         atomic_inc_32(&sctp_ill->sctp_ill_ipifcnt);
1133         if (sctp_ipif->sctp_ipif_state == SCTP_IPIFS_UP)
1134                 sctp_chk_and_updt_saddr(hindex, sctp_ipif, sctps);
1135         rw_exit(&sctps->sctps_g_ipifs_lock);
1136         rw_exit(&sctps->sctps_g_ills_lock);
1137 }
1138 
1139 /* Insert, Remove,  Mark up or Mark down the ipif */
1140 void
1141 sctp_update_ipif(ipif_t *ipif, int op)
1142 {
1143         ill_t           *ill = ipif->ipif_ill;
1144         int             i;
1145         sctp_ill_t      *sctp_ill;
1146         sctp_ipif_t     *sctp_ipif;
1147         uint_t          ill_index;
1148         uint_t          hindex;
1149         netstack_t      *ns = ipif->ipif_ill->ill_ipst->ips_netstack;
1150         sctp_stack_t    *sctps = ns->netstack_sctp;
1151 
1152         ip2dbg(("sctp_update_ipif: %s %d\n", ill->ill_name, ipif->ipif_seqid));
1153 
1154         rw_enter(&sctps->sctps_g_ills_lock, RW_READER);
1155         rw_enter(&sctps->sctps_g_ipifs_lock, RW_WRITER);
1156 
1157         ill_index = SCTP_ILL_HASH_FN(SCTP_ILL_TO_PHYINDEX(ill));
1158         sctp_ill = list_head(&sctps->sctps_g_ills[ill_index].sctp_ill_list);
1159         for (i = 0; i < sctps->sctps_g_ills[ill_index].ill_count; i++) {
1160                 if (sctp_ill->sctp_ill_index == SCTP_ILL_TO_PHYINDEX(ill) &&
1161                     sctp_ill->sctp_ill_isv6 == ill->ill_isv6) {
1162                         break;
1163                 }
1164                 sctp_ill = list_next(
1165                     &sctps->sctps_g_ills[ill_index].sctp_ill_list, sctp_ill);
1166         }
1167         if (sctp_ill == NULL) {
1168                 rw_exit(&sctps->sctps_g_ipifs_lock);
1169                 rw_exit(&sctps->sctps_g_ills_lock);
1170                 return;
1171         }
1172 
1173         hindex = SCTP_IPIF_ADDR_HASH(ipif->ipif_v6lcl_addr,
1174             ipif->ipif_ill->ill_isv6);
1175         sctp_ipif = list_head(&sctps->sctps_g_ipifs[hindex].sctp_ipif_list);
1176         for (i = 0; i < sctps->sctps_g_ipifs[hindex].ipif_count; i++) {
1177                 if (sctp_ipif->sctp_ipif_id == ipif->ipif_seqid) {
1178                         ASSERT(IN6_ARE_ADDR_EQUAL(&sctp_ipif->sctp_ipif_saddr,
1179                             &ipif->ipif_v6lcl_addr));
1180                         break;
1181                 }
1182                 sctp_ipif = list_next(
1183                     &sctps->sctps_g_ipifs[hindex].sctp_ipif_list,
1184                     sctp_ipif);
1185         }
1186         if (sctp_ipif == NULL) {
1187                 ip1dbg(("sctp_update_ipif: null sctp_ipif for %d\n", op));
1188                 rw_exit(&sctps->sctps_g_ipifs_lock);
1189                 rw_exit(&sctps->sctps_g_ills_lock);
1190                 return;
1191         }
1192         ASSERT(sctp_ill == sctp_ipif->sctp_ipif_ill);
1193         switch (op) {
1194         case SCTP_IPIF_REMOVE:
1195         {
1196                 list_t          *ipif_list;
1197                 list_t          *ill_list;
1198 
1199                 ill_list = &sctps->sctps_g_ills[ill_index].sctp_ill_list;
1200                 ipif_list = &sctps->sctps_g_ipifs[hindex].sctp_ipif_list;
1201                 if (sctp_ipif->sctp_ipif_refcnt != 0) {
1202                         sctp_ipif->sctp_ipif_state = SCTP_IPIFS_CONDEMNED;
1203                         rw_exit(&sctps->sctps_g_ipifs_lock);
1204                         rw_exit(&sctps->sctps_g_ills_lock);
1205                         return;
1206                 }
1207                 list_remove(ipif_list, (void *)sctp_ipif);
1208                 sctps->sctps_g_ipifs[hindex].ipif_count--;
1209                 sctps->sctps_g_ipifs_count--;
1210                 rw_destroy(&sctp_ipif->sctp_ipif_lock);
1211                 kmem_free(sctp_ipif, sizeof (sctp_ipif_t));
1212                 (void) atomic_dec_32_nv(&sctp_ill->sctp_ill_ipifcnt);
1213                 if (rw_tryupgrade(&sctps->sctps_g_ills_lock) != 0) {
1214                         rw_downgrade(&sctps->sctps_g_ipifs_lock);
1215                         if (sctp_ill->sctp_ill_ipifcnt == 0 &&
1216                             sctp_ill->sctp_ill_state == SCTP_ILLS_CONDEMNED) {
1217                                 list_remove(ill_list, (void *)sctp_ill);
1218                                 sctps->sctps_ills_count--;
1219                                 sctps->sctps_g_ills[ill_index].ill_count--;
1220                                 kmem_free(sctp_ill->sctp_ill_name,
1221                                     sctp_ill->sctp_ill_name_length);
1222                                 kmem_free(sctp_ill, sizeof (sctp_ill_t));
1223                         }
1224                 }
1225                 break;
1226         }
1227 
1228         case SCTP_IPIF_UP:
1229 
1230                 rw_downgrade(&sctps->sctps_g_ipifs_lock);
1231                 rw_enter(&sctp_ipif->sctp_ipif_lock, RW_WRITER);
1232                 sctp_ipif->sctp_ipif_state = SCTP_IPIFS_UP;
1233                 sctp_ipif->sctp_ipif_flags = ipif->ipif_flags;
1234                 rw_exit(&sctp_ipif->sctp_ipif_lock);
1235                 sctp_chk_and_updt_saddr(hindex, sctp_ipif,
1236                     ipif->ipif_ill->ill_ipst->ips_netstack->netstack_sctp);
1237 
1238                 break;
1239 
1240         case SCTP_IPIF_UPDATE:
1241 
1242                 rw_downgrade(&sctps->sctps_g_ipifs_lock);
1243                 rw_enter(&sctp_ipif->sctp_ipif_lock, RW_WRITER);
1244                 sctp_ipif->sctp_ipif_zoneid = ipif->ipif_zoneid;
1245                 sctp_ipif->sctp_ipif_flags = ipif->ipif_flags;
1246                 rw_exit(&sctp_ipif->sctp_ipif_lock);
1247 
1248                 break;
1249 
1250         case SCTP_IPIF_DOWN:
1251 
1252                 rw_downgrade(&sctps->sctps_g_ipifs_lock);
1253                 rw_enter(&sctp_ipif->sctp_ipif_lock, RW_WRITER);
1254                 sctp_ipif->sctp_ipif_state = SCTP_IPIFS_DOWN;
1255                 sctp_ipif->sctp_ipif_flags = ipif->ipif_flags;
1256                 rw_exit(&sctp_ipif->sctp_ipif_lock);
1257 
1258                 break;
1259         }
1260         rw_exit(&sctps->sctps_g_ipifs_lock);
1261         rw_exit(&sctps->sctps_g_ills_lock);
1262 }
1263 
1264 /*
1265  * SCTP source address list manipulaton, locking not used (except for
1266  * sctp locking by the caller.
1267  */
1268 
1269 /* Remove a specific saddr from the list */
1270 void
1271 sctp_del_saddr(sctp_t *sctp, sctp_saddr_ipif_t *sp)
1272 {
1273         if (sctp->sctp_conn_tfp != NULL)
1274                 mutex_enter(&sctp->sctp_conn_tfp->tf_lock);
1275 
1276         if (sctp->sctp_listen_tfp != NULL)
1277                 mutex_enter(&sctp->sctp_listen_tfp->tf_lock);
1278 
1279         sctp_ipif_hash_remove(sctp, sp->saddr_ipifp, B_FALSE);
1280 
1281         if (sctp->sctp_bound_to_all == 1)
1282                 sctp->sctp_bound_to_all = 0;
1283 
1284         if (sctp->sctp_conn_tfp != NULL)
1285                 mutex_exit(&sctp->sctp_conn_tfp->tf_lock);
1286 
1287         if (sctp->sctp_listen_tfp != NULL)
1288                 mutex_exit(&sctp->sctp_listen_tfp->tf_lock);
1289 }
1290 
1291 /*
1292  * Delete source address from the existing list. No error checking done here
1293  * Called with no locks held.
1294  */
1295 void
1296 sctp_del_saddr_list(sctp_t *sctp, const void *addrs, int addcnt,
1297     boolean_t fanout_locked)
1298 {
1299         struct sockaddr_in      *sin4;
1300         struct sockaddr_in6     *sin6;
1301         int                     cnt;
1302         in6_addr_t              addr;
1303         sctp_ipif_t             *sctp_ipif;
1304         int                     ifindex = 0;
1305         conn_t                  *connp = sctp->sctp_connp;
1306 
1307         ASSERT(sctp->sctp_nsaddrs >= addcnt);
1308 
1309         if (!fanout_locked) {
1310                 if (sctp->sctp_conn_tfp != NULL)
1311                         mutex_enter(&sctp->sctp_conn_tfp->tf_lock);
1312                 if (sctp->sctp_listen_tfp != NULL)
1313                         mutex_enter(&sctp->sctp_listen_tfp->tf_lock);
1314         }
1315 
1316         for (cnt = 0; cnt < addcnt; cnt++) {
1317                 switch (connp->conn_family) {
1318                 case AF_INET:
1319                         sin4 = (struct sockaddr_in *)addrs + cnt;
1320                         IN6_INADDR_TO_V4MAPPED(&sin4->sin_addr, &addr);
1321                         break;
1322 
1323                 case AF_INET6:
1324                         sin6 = (struct sockaddr_in6 *)addrs + cnt;
1325                         addr = sin6->sin6_addr;
1326                         ifindex = sin6->sin6_scope_id;
1327                         break;
1328                 }
1329                 sctp_ipif = sctp_lookup_ipif_addr(&addr, B_FALSE,
1330                     IPCL_ZONEID(connp), !connp->conn_allzones,
1331                     ifindex, 0, B_TRUE, sctp->sctp_sctps);
1332                 ASSERT(sctp_ipif != NULL);
1333                 sctp_ipif_hash_remove(sctp, sctp_ipif, B_FALSE);
1334         }
1335         if (sctp->sctp_bound_to_all == 1)
1336                 sctp->sctp_bound_to_all = 0;
1337 
1338         if (!fanout_locked) {
1339                 if (sctp->sctp_conn_tfp != NULL)
1340                         mutex_exit(&sctp->sctp_conn_tfp->tf_lock);
1341                 if (sctp->sctp_listen_tfp != NULL)
1342                         mutex_exit(&sctp->sctp_listen_tfp->tf_lock);
1343         }
1344 }
1345 
1346 /*
1347  * Given an address get the corresponding entry from the list
1348  * Called with no locks held.
1349  */
1350 sctp_saddr_ipif_t *
1351 sctp_saddr_lookup(sctp_t *sctp, in6_addr_t *addr, uint_t ifindex)
1352 {
1353         int                     cnt;
1354         sctp_saddr_ipif_t       *ipif_obj;
1355         int                     hindex;
1356         sctp_ipif_t             *sctp_ipif;
1357 
1358         hindex = SCTP_IPIF_ADDR_HASH(*addr, !IN6_IS_ADDR_V4MAPPED(addr));
1359         rw_enter(&sctp->sctp_saddrs[hindex].ipif_hash_lock, RW_READER);
1360         if (sctp->sctp_saddrs[hindex].ipif_count == 0) {
1361                 rw_exit(&sctp->sctp_saddrs[hindex].ipif_hash_lock);
1362                 return (NULL);
1363         }
1364 
1365         ipif_obj = list_head(&sctp->sctp_saddrs[hindex].sctp_ipif_list);
1366         for (cnt = 0; cnt < sctp->sctp_saddrs[hindex].ipif_count; cnt++) {
1367                 sctp_ipif = ipif_obj->saddr_ipifp;
1368                 /*
1369                  * Zone check shouldn't be needed.
1370                  */
1371                 if (IN6_ARE_ADDR_EQUAL(addr, &sctp_ipif->sctp_ipif_saddr) &&
1372                     (ifindex == 0 ||
1373                     ifindex == sctp_ipif->sctp_ipif_ill->sctp_ill_index) &&
1374                     SCTP_IPIF_USABLE(sctp_ipif->sctp_ipif_state)) {
1375                         rw_exit(&sctp->sctp_saddrs[hindex].ipif_hash_lock);
1376                         return (ipif_obj);
1377                 }
1378                 ipif_obj = list_next(&sctp->sctp_saddrs[hindex].sctp_ipif_list,
1379                     ipif_obj);
1380         }
1381         rw_exit(&sctp->sctp_saddrs[hindex].ipif_hash_lock);
1382         return (NULL);
1383 }
1384 
1385 /* Given an address, add it to the source address list */
1386 int
1387 sctp_saddr_add_addr(sctp_t *sctp, in6_addr_t *addr, uint_t ifindex)
1388 {
1389         sctp_ipif_t             *sctp_ipif;
1390         conn_t                  *connp = sctp->sctp_connp;
1391 
1392         sctp_ipif = sctp_lookup_ipif_addr(addr, B_TRUE, IPCL_ZONEID(connp),
1393             !connp->conn_allzones, ifindex, 0, B_TRUE, sctp->sctp_sctps);
1394         if (sctp_ipif == NULL)
1395                 return (EINVAL);
1396 
1397         if (sctp_ipif_hash_insert(sctp, sctp_ipif, KM_NOSLEEP, B_FALSE,
1398             B_FALSE) != 0) {
1399                 SCTP_IPIF_REFRELE(sctp_ipif);
1400                 return (EINVAL);
1401         }
1402         return (0);
1403 }
1404 
1405 /*
1406  * Remove or mark as dontsrc addresses that are currently not part of the
1407  * association. One would delete addresses when processing an INIT and
1408  * mark as dontsrc when processing an INIT-ACK.
1409  */
1410 void
1411 sctp_check_saddr(sctp_t *sctp, int supp_af, boolean_t delete,
1412     in6_addr_t *no_del_addr)
1413 {
1414         int                     i;
1415         int                     l;
1416         sctp_saddr_ipif_t       *obj;
1417         int                     scanned = 0;
1418         int                     naddr;
1419         int                     nsaddr;
1420         conn_t                  *connp = sctp->sctp_connp;
1421 
1422         ASSERT(!sctp->sctp_loopback && !sctp->sctp_linklocal && supp_af != 0);
1423 
1424         /*
1425          * Irregardless of the supported address in the INIT, v4
1426          * must be supported.
1427          */
1428         if (connp->conn_family == AF_INET)
1429                 supp_af = PARM_SUPP_V4;
1430 
1431         nsaddr = sctp->sctp_nsaddrs;
1432         for (i = 0; i < SCTP_IPIF_HASH; i++) {
1433                 rw_enter(&sctp->sctp_saddrs[i].ipif_hash_lock, RW_WRITER);
1434                 if (sctp->sctp_saddrs[i].ipif_count == 0) {
1435                         rw_exit(&sctp->sctp_saddrs[i].ipif_hash_lock);
1436                         continue;
1437                 }
1438                 obj = list_head(&sctp->sctp_saddrs[i].sctp_ipif_list);
1439                 naddr = sctp->sctp_saddrs[i].ipif_count;
1440                 for (l = 0; l < naddr; l++) {
1441                         sctp_ipif_t     *ipif;
1442 
1443                         ipif = obj->saddr_ipifp;
1444                         scanned++;
1445 
1446                         if (IN6_ARE_ADDR_EQUAL(&ipif->sctp_ipif_saddr,
1447                             no_del_addr)) {
1448                                 goto next_obj;
1449                         }
1450 
1451                         /*
1452                          * Delete/mark dontsrc loopback/linklocal addresses and
1453                          * unsupported address.
1454                          * On a clustered node, we trust the clustering module
1455                          * to do the right thing w.r.t loopback addresses, so
1456                          * we ignore loopback addresses in this check.
1457                          */
1458                         if ((SCTP_IS_IPIF_LOOPBACK(ipif) &&
1459                             cl_sctp_check_addrs == NULL) ||
1460                             SCTP_IS_IPIF_LINKLOCAL(ipif) ||
1461                             SCTP_UNSUPP_AF(ipif, supp_af)) {
1462                                 if (!delete) {
1463                                         obj->saddr_ipif_unconfirmed = 1;
1464                                         goto next_obj;
1465                                 }
1466                                 if (sctp->sctp_bound_to_all == 1)
1467                                         sctp->sctp_bound_to_all = 0;
1468                                 if (scanned < nsaddr) {
1469                                         obj = list_next(&sctp->sctp_saddrs[i].
1470                                             sctp_ipif_list, obj);
1471                                         sctp_ipif_hash_remove(sctp, ipif,
1472                                             B_TRUE);
1473                                         continue;
1474                                 }
1475                                 sctp_ipif_hash_remove(sctp, ipif, B_TRUE);
1476                         }
1477         next_obj:
1478                         if (scanned >= nsaddr) {
1479                                 rw_exit(&sctp->sctp_saddrs[i].ipif_hash_lock);
1480                                 return;
1481                         }
1482                         obj = list_next(&sctp->sctp_saddrs[i].sctp_ipif_list,
1483                             obj);
1484                 }
1485                 rw_exit(&sctp->sctp_saddrs[i].ipif_hash_lock);
1486         }
1487 }
1488 
1489 
1490 /* Get the first valid address from the list. Called with no locks held */
1491 in6_addr_t
1492 sctp_get_valid_addr(sctp_t *sctp, boolean_t isv6, boolean_t *addr_set)
1493 {
1494         int                     i;
1495         int                     l;
1496         sctp_saddr_ipif_t       *obj;
1497         int                     scanned = 0;
1498         in6_addr_t              addr;
1499 
1500         for (i = 0; i < SCTP_IPIF_HASH; i++) {
1501                 rw_enter(&sctp->sctp_saddrs[i].ipif_hash_lock, RW_READER);
1502                 if (sctp->sctp_saddrs[i].ipif_count == 0) {
1503                         rw_exit(&sctp->sctp_saddrs[i].ipif_hash_lock);
1504                         continue;
1505                 }
1506                 obj = list_head(&sctp->sctp_saddrs[i].sctp_ipif_list);
1507                 for (l = 0; l < sctp->sctp_saddrs[i].ipif_count; l++) {
1508                         sctp_ipif_t     *ipif;
1509 
1510                         ipif = obj->saddr_ipifp;
1511                         if (!SCTP_DONT_SRC(obj) &&
1512                             ipif->sctp_ipif_isv6 == isv6 &&
1513                             ipif->sctp_ipif_state == SCTP_IPIFS_UP) {
1514                                 *addr_set = B_TRUE;
1515                                 rw_exit(&sctp->sctp_saddrs[i].ipif_hash_lock);
1516                                 return (ipif->sctp_ipif_saddr);
1517                         }
1518                         scanned++;
1519                         if (scanned >= sctp->sctp_nsaddrs) {
1520                                 rw_exit(&sctp->sctp_saddrs[i].ipif_hash_lock);
1521                                 goto got_none;
1522                         }
1523                         obj = list_next(&sctp->sctp_saddrs[i].sctp_ipif_list,
1524                             obj);
1525                 }
1526                 rw_exit(&sctp->sctp_saddrs[i].ipif_hash_lock);
1527         }
1528 got_none:
1529         /* Need to double check this */
1530         if (isv6 == B_TRUE)
1531                 addr =  ipv6_all_zeros;
1532         else
1533                 IN6_IPADDR_TO_V4MAPPED(0, &addr);
1534         *addr_set = B_FALSE;
1535         return (addr);
1536 }
1537 
1538 /*
1539  * Return the list of local addresses of an association.  The parameter
1540  * myaddrs is supposed to be either (struct sockaddr_in *) or (struct
1541  * sockaddr_in6 *) depending on the address family.
1542  */
1543 int
1544 sctp_getmyaddrs(void *conn, void *myaddrs, int *addrcnt)
1545 {
1546         int                     i;
1547         int                     l;
1548         sctp_saddr_ipif_t       *obj;
1549         sctp_t                  *sctp = (sctp_t *)conn;
1550         conn_t                  *connp = sctp->sctp_connp;
1551         int                     family = connp->conn_family;
1552         int                     max = *addrcnt;
1553         size_t                  added = 0;
1554         struct sockaddr_in6     *sin6;
1555         struct sockaddr_in      *sin4;
1556         int                     scanned = 0;
1557         boolean_t               skip_lback = B_FALSE;
1558         ip_xmit_attr_t          *ixa = connp->conn_ixa;
1559 
1560         if (sctp->sctp_nsaddrs == 0)
1561                 return (EINVAL);
1562 
1563         /*
1564          * Skip loopback addresses for non-loopback assoc., ignore
1565          * this on a clustered node.
1566          */
1567         if (sctp->sctp_state >= SCTPS_ESTABLISHED && !sctp->sctp_loopback &&
1568             (cl_sctp_check_addrs == NULL)) {
1569                 skip_lback = B_TRUE;
1570         }
1571 
1572         for (i = 0; i < SCTP_IPIF_HASH; i++) {
1573                 rw_enter(&sctp->sctp_saddrs[i].ipif_hash_lock, RW_READER);
1574                 if (sctp->sctp_saddrs[i].ipif_count == 0) {
1575                         rw_exit(&sctp->sctp_saddrs[i].ipif_hash_lock);
1576                         continue;
1577                 }
1578                 obj = list_head(&sctp->sctp_saddrs[i].sctp_ipif_list);
1579                 for (l = 0; l < sctp->sctp_saddrs[i].ipif_count; l++) {
1580                         sctp_ipif_t     *ipif = obj->saddr_ipifp;
1581                         in6_addr_t      addr = ipif->sctp_ipif_saddr;
1582 
1583                         scanned++;
1584                         if ((ipif->sctp_ipif_state == SCTP_IPIFS_CONDEMNED) ||
1585                             SCTP_DONT_SRC(obj) ||
1586                             (SCTP_IS_IPIF_LOOPBACK(ipif) && skip_lback)) {
1587                                 if (scanned >= sctp->sctp_nsaddrs) {
1588                                         rw_exit(&sctp->
1589                                             sctp_saddrs[i].ipif_hash_lock);
1590                                         goto done;
1591                                 }
1592                                 obj = list_next(&sctp->sctp_saddrs[i].
1593                                     sctp_ipif_list, obj);
1594                                 continue;
1595                         }
1596                         switch (family) {
1597                         case AF_INET:
1598                                 sin4 = (struct sockaddr_in *)myaddrs + added;
1599                                 sin4->sin_family = AF_INET;
1600                                 sin4->sin_port = connp->conn_lport;
1601                                 IN6_V4MAPPED_TO_INADDR(&addr, &sin4->sin_addr);
1602                                 break;
1603 
1604                         case AF_INET6:
1605                                 sin6 = (struct sockaddr_in6 *)myaddrs + added;
1606                                 sin6->sin6_family = AF_INET6;
1607                                 sin6->sin6_port = connp->conn_lport;
1608                                 sin6->sin6_addr = addr;
1609                                 /*
1610                                  * Note that flowinfo is only returned for
1611                                  * getpeername just like for TCP and UDP.
1612                                  */
1613                                 sin6->sin6_flowinfo = 0;
1614 
1615                                 if (IN6_IS_ADDR_LINKSCOPE(&sin6->sin6_addr) &&
1616                                     (ixa->ixa_flags & IXAF_SCOPEID_SET))
1617                                         sin6->sin6_scope_id = ixa->ixa_scopeid;
1618                                 else
1619                                         sin6->sin6_scope_id = 0;
1620                                 sin6->__sin6_src_id = 0;
1621                                 break;
1622                         }
1623                         added++;
1624                         if (added >= max || scanned >= sctp->sctp_nsaddrs) {
1625                                 rw_exit(&sctp->sctp_saddrs[i].ipif_hash_lock);
1626                                 goto done;
1627                         }
1628                         obj = list_next(&sctp->sctp_saddrs[i].sctp_ipif_list,
1629                             obj);
1630                 }
1631                 rw_exit(&sctp->sctp_saddrs[i].ipif_hash_lock);
1632         }
1633 done:
1634         *addrcnt = added;
1635         return (0);
1636 }
1637 
1638 /*
1639  * Given the supported address family, walk through the source address list
1640  * and return the total length of the available addresses. If 'p' is not
1641  * null, construct the parameter list for the addresses in 'p'.
1642  * 'modify' will only be set when we want the source address list to
1643  * be modified. The source address list will be modified only when
1644  * generating an INIT chunk. For generating an INIT-ACK 'modify' will
1645  * be false since the 'sctp' will be that of the listener.
1646  */
1647 size_t
1648 sctp_saddr_info(sctp_t *sctp, int supp_af, uchar_t *p, boolean_t modify)
1649 {
1650         int                     i;
1651         int                     l;
1652         sctp_saddr_ipif_t       *obj;
1653         size_t                  paramlen = 0;
1654         sctp_parm_hdr_t         *hdr;
1655         int                     scanned = 0;
1656         int                     naddr;
1657         int                     nsaddr;
1658         boolean_t               del_ll = B_FALSE;
1659         boolean_t               del_lb = B_FALSE;
1660 
1661 
1662         /*
1663          * On a clustered node don't bother changing anything
1664          * on the loopback interface.
1665          */
1666         if (modify && !sctp->sctp_loopback && (cl_sctp_check_addrs == NULL))
1667                 del_lb = B_TRUE;
1668 
1669         if (modify && !sctp->sctp_linklocal)
1670                 del_ll = B_TRUE;
1671 
1672         nsaddr = sctp->sctp_nsaddrs;
1673         for (i = 0; i < SCTP_IPIF_HASH; i++) {
1674                 rw_enter(&sctp->sctp_saddrs[i].ipif_hash_lock, RW_WRITER);
1675                 if (sctp->sctp_saddrs[i].ipif_count == 0) {
1676                         rw_exit(&sctp->sctp_saddrs[i].ipif_hash_lock);
1677                         continue;
1678                 }
1679                 obj = list_head(&sctp->sctp_saddrs[i].sctp_ipif_list);
1680                 naddr = sctp->sctp_saddrs[i].ipif_count;
1681                 for (l = 0; l < naddr; l++) {
1682                         in6_addr_t      addr;
1683                         sctp_ipif_t     *ipif;
1684                         boolean_t       ipif_lb;
1685                         boolean_t       ipif_ll;
1686                         boolean_t       unsupp_af;
1687 
1688                         ipif = obj->saddr_ipifp;
1689                         scanned++;
1690 
1691                         ipif_lb = SCTP_IS_IPIF_LOOPBACK(ipif);
1692                         ipif_ll = SCTP_IS_IPIF_LINKLOCAL(ipif);
1693                         unsupp_af = SCTP_UNSUPP_AF(ipif, supp_af);
1694                         /*
1695                          * We need to either delete or skip loopback/linklocal
1696                          * or unsupported addresses, if required.
1697                          */
1698                         if ((ipif_ll && del_ll) || (ipif_lb && del_lb) ||
1699                             (unsupp_af && modify)) {
1700                                 if (sctp->sctp_bound_to_all == 1)
1701                                         sctp->sctp_bound_to_all = 0;
1702                                 if (scanned < nsaddr) {
1703                                         obj = list_next(&sctp->sctp_saddrs[i].
1704                                             sctp_ipif_list, obj);
1705                                         sctp_ipif_hash_remove(sctp, ipif,
1706                                             B_TRUE);
1707                                         continue;
1708                                 }
1709                                 sctp_ipif_hash_remove(sctp, ipif, B_TRUE);
1710 
1711                                 goto next_addr;
1712                         } else if (ipif_ll || unsupp_af ||
1713                             (ipif_lb && (cl_sctp_check_addrs == NULL))) {
1714                                 goto next_addr;
1715                         }
1716 
1717                         if (!SCTP_IPIF_USABLE(ipif->sctp_ipif_state))
1718                                 goto next_addr;
1719                         if (p != NULL)
1720                                 hdr = (sctp_parm_hdr_t *)(p + paramlen);
1721                         addr = ipif->sctp_ipif_saddr;
1722                         if (!ipif->sctp_ipif_isv6) {
1723                                 struct in_addr  *v4;
1724 
1725                                 if (p != NULL) {
1726                                         hdr->sph_type = htons(PARM_ADDR4);
1727                                         hdr->sph_len = htons(PARM_ADDR4_LEN);
1728                                         v4 = (struct in_addr *)(hdr + 1);
1729                                         IN6_V4MAPPED_TO_INADDR(&addr, v4);
1730                                 }
1731                                 paramlen += PARM_ADDR4_LEN;
1732                         } else {
1733                                 if (p != NULL) {
1734                                         hdr->sph_type = htons(PARM_ADDR6);
1735                                         hdr->sph_len = htons(PARM_ADDR6_LEN);
1736                                         bcopy(&addr, hdr + 1, sizeof (addr));
1737                                 }
1738                                 paramlen += PARM_ADDR6_LEN;
1739                         }
1740 next_addr:
1741                         if (scanned >= nsaddr) {
1742                                 rw_exit(&sctp->sctp_saddrs[i].ipif_hash_lock);
1743                                 return (paramlen);
1744                         }
1745                         obj = list_next(&sctp->sctp_saddrs[i].sctp_ipif_list,
1746                             obj);
1747                 }
1748                 rw_exit(&sctp->sctp_saddrs[i].ipif_hash_lock);
1749         }
1750         return (paramlen);
1751 }
1752 
1753 /*
1754  * This is used on a clustered node to obtain a list of addresses, the list
1755  * consists of sockaddr_in structs for v4 and sockaddr_in6 for v6. The list
1756  * is then passed onto the clustering module which sends back the correct
1757  * list based on the port info. Regardless of the input, i.e INADDR_ANY
1758  * or specific address(es), we create the list since it could be modified by
1759  * the clustering module. When given a list of addresses, we simply
1760  * create the list of sockaddr_in or sockaddr_in6 structs using those
1761  * addresses. If there is an INADDR_ANY in the input list, or if the
1762  * input is INADDR_ANY, we create a list of sockaddr_in or sockaddr_in6
1763  * structs consisting all the addresses in the global interface list
1764  * except those that are hosted on the loopback interface. We create
1765  * a list of sockaddr_in[6] structs just so that it can be directly input
1766  * to sctp_valid_addr_list() once the clustering module has processed it.
1767  */
1768 int
1769 sctp_get_addrlist(sctp_t *sctp, const void *addrs, uint32_t *addrcnt,
1770     uchar_t **addrlist, int *uspec, size_t *size)
1771 {
1772         int                     cnt;
1773         int                     icnt;
1774         sctp_ipif_t             *sctp_ipif;
1775         struct sockaddr_in      *s4;
1776         struct sockaddr_in6     *s6;
1777         uchar_t                 *p;
1778         int                     err = 0;
1779         sctp_stack_t            *sctps = sctp->sctp_sctps;
1780         conn_t                  *connp = sctp->sctp_connp;
1781 
1782         *addrlist = NULL;
1783         *size = 0;
1784 
1785         /*
1786          * Create a list of sockaddr_in[6] structs using the input list.
1787          */
1788         if (connp->conn_family == AF_INET) {
1789                 *size = sizeof (struct sockaddr_in) * *addrcnt;
1790                 *addrlist = kmem_zalloc(*size,  KM_SLEEP);
1791                 p = *addrlist;
1792                 for (cnt = 0; cnt < *addrcnt; cnt++) {
1793                         s4 = (struct sockaddr_in *)addrs + cnt;
1794                         /*
1795                          * We need to create a list of all the available
1796                          * addresses if there is an INADDR_ANY. However,
1797                          * if we are beyond LISTEN, then this is invalid
1798                          * (see sctp_valid_addr_list(). So, we just fail
1799                          * it here rather than wait till it fails in
1800                          * sctp_valid_addr_list().
1801                          */
1802                         if (s4->sin_addr.s_addr == INADDR_ANY) {
1803                                 kmem_free(*addrlist, *size);
1804                                 *addrlist = NULL;
1805                                 *size = 0;
1806                                 if (sctp->sctp_state > SCTPS_LISTEN) {
1807                                         *addrcnt = 0;
1808                                         return (EINVAL);
1809                                 }
1810                                 if (uspec != NULL)
1811                                         *uspec = 1;
1812                                 goto get_all_addrs;
1813                         } else {
1814                                 bcopy(s4, p, sizeof (*s4));
1815                                 p += sizeof (*s4);
1816                         }
1817                 }
1818         } else {
1819                 *size = sizeof (struct sockaddr_in6) * *addrcnt;
1820                 *addrlist = kmem_zalloc(*size, KM_SLEEP);
1821                 p = *addrlist;
1822                 for (cnt = 0; cnt < *addrcnt; cnt++) {
1823                         s6 = (struct sockaddr_in6 *)addrs + cnt;
1824                         /*
1825                          * Comments for INADDR_ANY, above, apply here too.
1826                          */
1827                         if (IN6_IS_ADDR_UNSPECIFIED(&s6->sin6_addr)) {
1828                                 kmem_free(*addrlist, *size);
1829                                 *size = 0;
1830                                 *addrlist = NULL;
1831                                 if (sctp->sctp_state > SCTPS_LISTEN) {
1832                                         *addrcnt = 0;
1833                                         return (EINVAL);
1834                                 }
1835                                 if (uspec != NULL)
1836                                         *uspec = 1;
1837                                 goto get_all_addrs;
1838                         } else {
1839                                 bcopy(addrs, p, sizeof (*s6));
1840                                 p += sizeof (*s6);
1841                         }
1842                 }
1843         }
1844         return (err);
1845 get_all_addrs:
1846 
1847         /*
1848          * Allocate max possible size. We allocate the max. size here because
1849          * the clustering module could end up adding addresses to the list.
1850          * We allocate upfront so that the clustering module need to bother
1851          * re-sizing the list.
1852          */
1853         if (connp->conn_family == AF_INET) {
1854                 *size = sizeof (struct sockaddr_in) *
1855                     sctps->sctps_g_ipifs_count;
1856         } else {
1857                 *size = sizeof (struct sockaddr_in6) *
1858                     sctps->sctps_g_ipifs_count;
1859         }
1860         *addrlist = kmem_zalloc(*size, KM_SLEEP);
1861         *addrcnt = 0;
1862         p = *addrlist;
1863         rw_enter(&sctps->sctps_g_ipifs_lock, RW_READER);
1864 
1865         /*
1866          * Walk through the global interface list and add all addresses,
1867          * except those that are hosted on loopback interfaces.
1868          */
1869         for (cnt = 0; cnt <  SCTP_IPIF_HASH; cnt++) {
1870                 if (sctps->sctps_g_ipifs[cnt].ipif_count == 0)
1871                         continue;
1872                 sctp_ipif = list_head(
1873                     &sctps->sctps_g_ipifs[cnt].sctp_ipif_list);
1874                 for (icnt = 0;
1875                     icnt < sctps->sctps_g_ipifs[cnt].ipif_count;
1876                     icnt++) {
1877                         in6_addr_t      addr;
1878 
1879                         rw_enter(&sctp_ipif->sctp_ipif_lock, RW_READER);
1880                         addr = sctp_ipif->sctp_ipif_saddr;
1881                         if (SCTP_IPIF_DISCARD(sctp_ipif->sctp_ipif_flags) ||
1882                             !SCTP_IPIF_USABLE(sctp_ipif->sctp_ipif_state) ||
1883                             SCTP_IS_IPIF_LOOPBACK(sctp_ipif) ||
1884                             SCTP_IS_IPIF_LINKLOCAL(sctp_ipif) ||
1885                             !SCTP_IPIF_ZONE_MATCH(sctp, sctp_ipif) ||
1886                             (connp->conn_family == AF_INET &&
1887                             sctp_ipif->sctp_ipif_isv6) ||
1888                             (sctp->sctp_connp->conn_ipv6_v6only &&
1889                             !sctp_ipif->sctp_ipif_isv6)) {
1890                                 rw_exit(&sctp_ipif->sctp_ipif_lock);
1891                                 sctp_ipif = list_next(
1892                                     &sctps->sctps_g_ipifs[cnt].sctp_ipif_list,
1893                                     sctp_ipif);
1894                                 continue;
1895                         }
1896                         rw_exit(&sctp_ipif->sctp_ipif_lock);
1897                         if (connp->conn_family == AF_INET) {
1898                                 s4 = (struct sockaddr_in *)p;
1899                                 IN6_V4MAPPED_TO_INADDR(&addr, &s4->sin_addr);
1900                                 s4->sin_family = AF_INET;
1901                                 p += sizeof (*s4);
1902                         } else {
1903                                 s6 = (struct sockaddr_in6 *)p;
1904                                 s6->sin6_addr = addr;
1905                                 s6->sin6_family = AF_INET6;
1906                                 s6->sin6_scope_id =
1907                                     sctp_ipif->sctp_ipif_ill->sctp_ill_index;
1908                                 p += sizeof (*s6);
1909                         }
1910                         (*addrcnt)++;
1911                         sctp_ipif = list_next(
1912                             &sctps->sctps_g_ipifs[cnt].sctp_ipif_list,
1913                             sctp_ipif);
1914                 }
1915         }
1916         rw_exit(&sctps->sctps_g_ipifs_lock);
1917         return (err);
1918 }
1919 
1920 /*
1921  * Get a list of addresses from the source address list. The  caller is
1922  * responsible for allocating sufficient buffer for this.
1923  */
1924 void
1925 sctp_get_saddr_list(sctp_t *sctp, uchar_t *p, size_t psize)
1926 {
1927         int                     cnt;
1928         int                     icnt;
1929         sctp_saddr_ipif_t       *obj;
1930         int                     naddr;
1931         int                     scanned = 0;
1932 
1933         for (cnt = 0; cnt < SCTP_IPIF_HASH; cnt++) {
1934                 rw_enter(&sctp->sctp_saddrs[cnt].ipif_hash_lock, RW_READER);
1935                 if (sctp->sctp_saddrs[cnt].ipif_count == 0) {
1936                         rw_exit(&sctp->sctp_saddrs[cnt].ipif_hash_lock);
1937                         continue;
1938                 }
1939                 obj = list_head(&sctp->sctp_saddrs[cnt].sctp_ipif_list);
1940                 naddr = sctp->sctp_saddrs[cnt].ipif_count;
1941                 for (icnt = 0; icnt < naddr; icnt++) {
1942                         sctp_ipif_t     *ipif;
1943 
1944                         if (psize < sizeof (ipif->sctp_ipif_saddr)) {
1945                                 rw_exit(&sctp->sctp_saddrs[cnt].ipif_hash_lock);
1946                                 return;
1947                         }
1948 
1949                         scanned++;
1950                         ipif = obj->saddr_ipifp;
1951                         bcopy(&ipif->sctp_ipif_saddr, p,
1952                             sizeof (ipif->sctp_ipif_saddr));
1953                         p += sizeof (ipif->sctp_ipif_saddr);
1954                         psize -= sizeof (ipif->sctp_ipif_saddr);
1955                         if (scanned >= sctp->sctp_nsaddrs) {
1956                                 rw_exit(&sctp->sctp_saddrs[cnt].ipif_hash_lock);
1957                                 return;
1958                         }
1959                         obj = list_next(
1960                             &sctp->sctp_saddrs[icnt].sctp_ipif_list,
1961                             obj);
1962                 }
1963                 rw_exit(&sctp->sctp_saddrs[cnt].ipif_hash_lock);
1964         }
1965 }
1966 
1967 /*
1968  * Get a list of addresses from the remote address list. The  caller is
1969  * responsible for allocating sufficient buffer for this.
1970  */
1971 void
1972 sctp_get_faddr_list(sctp_t *sctp, uchar_t *p, size_t psize)
1973 {
1974         sctp_faddr_t    *fp;
1975 
1976         for (fp = sctp->sctp_faddrs; fp != NULL; fp = fp->sf_next) {
1977                 if (psize < sizeof (fp->sf_faddr))
1978                         return;
1979                 bcopy(&fp->sf_faddr, p, sizeof (fp->sf_faddr));
1980                 p += sizeof (fp->sf_faddr);
1981                 psize -= sizeof (fp->sf_faddr);
1982         }
1983 }
1984 
1985 static void
1986 sctp_free_ills(sctp_stack_t *sctps)
1987 {
1988         int                     i;
1989         int                     l;
1990         sctp_ill_t      *sctp_ill;
1991 
1992         if (sctps->sctps_ills_count == 0)
1993                 return;
1994 
1995         for (i = 0; i < SCTP_ILL_HASH; i++) {
1996                 sctp_ill = list_tail(&sctps->sctps_g_ills[i].sctp_ill_list);
1997                 for (l = 0; l < sctps->sctps_g_ills[i].ill_count; l++) {
1998                         ASSERT(sctp_ill->sctp_ill_ipifcnt == 0);
1999                         list_remove(&sctps->sctps_g_ills[i].sctp_ill_list,
2000                             sctp_ill);
2001                         sctps->sctps_ills_count--;
2002                         kmem_free(sctp_ill->sctp_ill_name,
2003                             sctp_ill->sctp_ill_name_length);
2004                         kmem_free(sctp_ill, sizeof (sctp_ill_t));
2005                         sctp_ill =
2006                             list_tail(&sctps->sctps_g_ills[i].sctp_ill_list);
2007                 }
2008                 sctps->sctps_g_ills[i].ill_count = 0;
2009         }
2010         ASSERT(sctps->sctps_ills_count == 0);
2011 }
2012 
2013 static void
2014 sctp_free_ipifs(sctp_stack_t *sctps)
2015 {
2016         int                     i;
2017         int                     l;
2018         sctp_ipif_t     *sctp_ipif;
2019         sctp_ill_t      *sctp_ill;
2020 
2021         if (sctps->sctps_g_ipifs_count == 0)
2022                 return;
2023 
2024         for (i = 0; i < SCTP_IPIF_HASH; i++) {
2025                 sctp_ipif = list_tail(&sctps->sctps_g_ipifs[i].sctp_ipif_list);
2026                 for (l = 0; l < sctps->sctps_g_ipifs[i].ipif_count; l++) {
2027                         sctp_ill = sctp_ipif->sctp_ipif_ill;
2028 
2029                         list_remove(&sctps->sctps_g_ipifs[i].sctp_ipif_list,
2030                             sctp_ipif);
2031                         sctps->sctps_g_ipifs_count--;
2032                         (void) atomic_dec_32_nv(&sctp_ill->sctp_ill_ipifcnt);
2033                         kmem_free(sctp_ipif, sizeof (sctp_ipif_t));
2034                         sctp_ipif =
2035                             list_tail(&sctps->sctps_g_ipifs[i].sctp_ipif_list);
2036                 }
2037                 sctps->sctps_g_ipifs[i].ipif_count = 0;
2038         }
2039         ASSERT(sctps->sctps_g_ipifs_count == 0);
2040 }
2041 
2042 
2043 /* Initialize the SCTP ILL list and lock */
2044 void
2045 sctp_saddr_init(sctp_stack_t *sctps)
2046 {
2047         int     i;
2048 
2049         sctps->sctps_g_ills = kmem_zalloc(sizeof (sctp_ill_hash_t) *
2050             SCTP_ILL_HASH, KM_SLEEP);
2051         sctps->sctps_g_ipifs = kmem_zalloc(sizeof (sctp_ipif_hash_t) *
2052             SCTP_IPIF_HASH, KM_SLEEP);
2053 
2054         rw_init(&sctps->sctps_g_ills_lock, NULL, RW_DEFAULT, NULL);
2055         rw_init(&sctps->sctps_g_ipifs_lock, NULL, RW_DEFAULT, NULL);
2056 
2057         for (i = 0; i < SCTP_ILL_HASH; i++) {
2058                 sctps->sctps_g_ills[i].ill_count = 0;
2059                 list_create(&sctps->sctps_g_ills[i].sctp_ill_list,
2060                     sizeof (sctp_ill_t),
2061                     offsetof(sctp_ill_t, sctp_ills));
2062         }
2063         for (i = 0; i < SCTP_IPIF_HASH; i++) {
2064                 sctps->sctps_g_ipifs[i].ipif_count = 0;
2065                 list_create(&sctps->sctps_g_ipifs[i].sctp_ipif_list,
2066                     sizeof (sctp_ipif_t), offsetof(sctp_ipif_t, sctp_ipifs));
2067         }
2068 }
2069 
2070 void
2071 sctp_saddr_fini(sctp_stack_t *sctps)
2072 {
2073         int     i;
2074 
2075         sctp_free_ipifs(sctps);
2076         sctp_free_ills(sctps);
2077 
2078         for (i = 0; i < SCTP_ILL_HASH; i++)
2079                 list_destroy(&sctps->sctps_g_ills[i].sctp_ill_list);
2080         for (i = 0; i < SCTP_IPIF_HASH; i++)
2081                 list_destroy(&sctps->sctps_g_ipifs[i].sctp_ipif_list);
2082 
2083         ASSERT(sctps->sctps_ills_count == 0 && sctps->sctps_g_ipifs_count == 0);
2084         kmem_free(sctps->sctps_g_ills, sizeof (sctp_ill_hash_t) *
2085             SCTP_ILL_HASH);
2086         sctps->sctps_g_ills = NULL;
2087         kmem_free(sctps->sctps_g_ipifs, sizeof (sctp_ipif_hash_t) *
2088             SCTP_IPIF_HASH);
2089         sctps->sctps_g_ipifs = NULL;
2090         rw_destroy(&sctps->sctps_g_ills_lock);
2091         rw_destroy(&sctps->sctps_g_ipifs_lock);
2092 }