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_add_32_nv(&sctp_ill->sctp_ill_ipifcnt, -1);
 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_add_32_nv(&fsctp_ill->sctp_ill_ipifcnt, -1);
 888         atomic_add_32(&tsctp_ill->sctp_ill_ipifcnt, 1);
 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_add_32_nv(&osctp_ill->sctp_ill_ipifcnt,
1101                             -1);
1102                 }
1103         }
1104 
1105         sctp_ipif = kmem_zalloc(sizeof (sctp_ipif_t), KM_NOSLEEP);
1106         /* Try again? */
1107         if (sctp_ipif == NULL) {
1108                 cmn_err(CE_WARN, "sctp_update_ipif_addr: error adding "
1109                     "IPIF %p to SCTP's IPIF list", (void *)ipif);
1110                 rw_exit(&sctps->sctps_g_ipifs_lock);
1111                 rw_exit(&sctps->sctps_g_ills_lock);
1112                 return;
1113         }
1114         sctps->sctps_g_ipifs_count++;
1115         rw_init(&sctp_ipif->sctp_ipif_lock, NULL, RW_DEFAULT, NULL);
1116         sctp_ipif->sctp_ipif_saddr = ipif->ipif_v6lcl_addr;
1117         sctp_ipif->sctp_ipif_ill = sctp_ill;
1118         sctp_ipif->sctp_ipif_isv6 = ill->ill_isv6;
1119         sctp_ipif->sctp_ipif_zoneid = ipif->ipif_zoneid;
1120         sctp_ipif->sctp_ipif_id = ipif->ipif_seqid;
1121         if (ipif->ipif_flags & IPIF_UP)
1122                 sctp_ipif->sctp_ipif_state = SCTP_IPIFS_UP;
1123         else
1124                 sctp_ipif->sctp_ipif_state = SCTP_IPIFS_DOWN;
1125         sctp_ipif->sctp_ipif_flags = ipif->ipif_flags;
1126         /*
1127          * We add it to the head so that it is quicker to find good/recent
1128          * additions.
1129          */
1130         list_insert_head(&sctps->sctps_g_ipifs[hindex].sctp_ipif_list,
1131             (void *)sctp_ipif);
1132         sctps->sctps_g_ipifs[hindex].ipif_count++;
1133         atomic_add_32(&sctp_ill->sctp_ill_ipifcnt, 1);
1134         if (sctp_ipif->sctp_ipif_state == SCTP_IPIFS_UP)
1135                 sctp_chk_and_updt_saddr(hindex, sctp_ipif, sctps);
1136         rw_exit(&sctps->sctps_g_ipifs_lock);
1137         rw_exit(&sctps->sctps_g_ills_lock);
1138 }
1139 
1140 /* Insert, Remove,  Mark up or Mark down the ipif */
1141 void
1142 sctp_update_ipif(ipif_t *ipif, int op)
1143 {
1144         ill_t           *ill = ipif->ipif_ill;
1145         int             i;
1146         sctp_ill_t      *sctp_ill;
1147         sctp_ipif_t     *sctp_ipif;
1148         uint_t          ill_index;
1149         uint_t          hindex;
1150         netstack_t      *ns = ipif->ipif_ill->ill_ipst->ips_netstack;
1151         sctp_stack_t    *sctps = ns->netstack_sctp;
1152 
1153         ip2dbg(("sctp_update_ipif: %s %d\n", ill->ill_name, ipif->ipif_seqid));
1154 
1155         rw_enter(&sctps->sctps_g_ills_lock, RW_READER);
1156         rw_enter(&sctps->sctps_g_ipifs_lock, RW_WRITER);
1157 
1158         ill_index = SCTP_ILL_HASH_FN(SCTP_ILL_TO_PHYINDEX(ill));
1159         sctp_ill = list_head(&sctps->sctps_g_ills[ill_index].sctp_ill_list);
1160         for (i = 0; i < sctps->sctps_g_ills[ill_index].ill_count; i++) {
1161                 if (sctp_ill->sctp_ill_index == SCTP_ILL_TO_PHYINDEX(ill) &&
1162                     sctp_ill->sctp_ill_isv6 == ill->ill_isv6) {
1163                         break;
1164                 }
1165                 sctp_ill = list_next(
1166                     &sctps->sctps_g_ills[ill_index].sctp_ill_list, sctp_ill);
1167         }
1168         if (sctp_ill == NULL) {
1169                 rw_exit(&sctps->sctps_g_ipifs_lock);
1170                 rw_exit(&sctps->sctps_g_ills_lock);
1171                 return;
1172         }
1173 
1174         hindex = SCTP_IPIF_ADDR_HASH(ipif->ipif_v6lcl_addr,
1175             ipif->ipif_ill->ill_isv6);
1176         sctp_ipif = list_head(&sctps->sctps_g_ipifs[hindex].sctp_ipif_list);
1177         for (i = 0; i < sctps->sctps_g_ipifs[hindex].ipif_count; i++) {
1178                 if (sctp_ipif->sctp_ipif_id == ipif->ipif_seqid) {
1179                         ASSERT(IN6_ARE_ADDR_EQUAL(&sctp_ipif->sctp_ipif_saddr,
1180                             &ipif->ipif_v6lcl_addr));
1181                         break;
1182                 }
1183                 sctp_ipif = list_next(
1184                     &sctps->sctps_g_ipifs[hindex].sctp_ipif_list,
1185                     sctp_ipif);
1186         }
1187         if (sctp_ipif == NULL) {
1188                 ip1dbg(("sctp_update_ipif: null sctp_ipif for %d\n", op));
1189                 rw_exit(&sctps->sctps_g_ipifs_lock);
1190                 rw_exit(&sctps->sctps_g_ills_lock);
1191                 return;
1192         }
1193         ASSERT(sctp_ill == sctp_ipif->sctp_ipif_ill);
1194         switch (op) {
1195         case SCTP_IPIF_REMOVE:
1196         {
1197                 list_t          *ipif_list;
1198                 list_t          *ill_list;
1199 
1200                 ill_list = &sctps->sctps_g_ills[ill_index].sctp_ill_list;
1201                 ipif_list = &sctps->sctps_g_ipifs[hindex].sctp_ipif_list;
1202                 if (sctp_ipif->sctp_ipif_refcnt != 0) {
1203                         sctp_ipif->sctp_ipif_state = SCTP_IPIFS_CONDEMNED;
1204                         rw_exit(&sctps->sctps_g_ipifs_lock);
1205                         rw_exit(&sctps->sctps_g_ills_lock);
1206                         return;
1207                 }
1208                 list_remove(ipif_list, (void *)sctp_ipif);
1209                 sctps->sctps_g_ipifs[hindex].ipif_count--;
1210                 sctps->sctps_g_ipifs_count--;
1211                 rw_destroy(&sctp_ipif->sctp_ipif_lock);
1212                 kmem_free(sctp_ipif, sizeof (sctp_ipif_t));
1213                 (void) atomic_add_32_nv(&sctp_ill->sctp_ill_ipifcnt, -1);
1214                 if (rw_tryupgrade(&sctps->sctps_g_ills_lock) != 0) {
1215                         rw_downgrade(&sctps->sctps_g_ipifs_lock);
1216                         if (sctp_ill->sctp_ill_ipifcnt == 0 &&
1217                             sctp_ill->sctp_ill_state == SCTP_ILLS_CONDEMNED) {
1218                                 list_remove(ill_list, (void *)sctp_ill);
1219                                 sctps->sctps_ills_count--;
1220                                 sctps->sctps_g_ills[ill_index].ill_count--;
1221                                 kmem_free(sctp_ill->sctp_ill_name,
1222                                     sctp_ill->sctp_ill_name_length);
1223                                 kmem_free(sctp_ill, sizeof (sctp_ill_t));
1224                         }
1225                 }
1226                 break;
1227         }
1228 
1229         case SCTP_IPIF_UP:
1230 
1231                 rw_downgrade(&sctps->sctps_g_ipifs_lock);
1232                 rw_enter(&sctp_ipif->sctp_ipif_lock, RW_WRITER);
1233                 sctp_ipif->sctp_ipif_state = SCTP_IPIFS_UP;
1234                 sctp_ipif->sctp_ipif_flags = ipif->ipif_flags;
1235                 rw_exit(&sctp_ipif->sctp_ipif_lock);
1236                 sctp_chk_and_updt_saddr(hindex, sctp_ipif,
1237                     ipif->ipif_ill->ill_ipst->ips_netstack->netstack_sctp);
1238 
1239                 break;
1240 
1241         case SCTP_IPIF_UPDATE:
1242 
1243                 rw_downgrade(&sctps->sctps_g_ipifs_lock);
1244                 rw_enter(&sctp_ipif->sctp_ipif_lock, RW_WRITER);
1245                 sctp_ipif->sctp_ipif_zoneid = ipif->ipif_zoneid;
1246                 sctp_ipif->sctp_ipif_flags = ipif->ipif_flags;
1247                 rw_exit(&sctp_ipif->sctp_ipif_lock);
1248 
1249                 break;
1250 
1251         case SCTP_IPIF_DOWN:
1252 
1253                 rw_downgrade(&sctps->sctps_g_ipifs_lock);
1254                 rw_enter(&sctp_ipif->sctp_ipif_lock, RW_WRITER);
1255                 sctp_ipif->sctp_ipif_state = SCTP_IPIFS_DOWN;
1256                 sctp_ipif->sctp_ipif_flags = ipif->ipif_flags;
1257                 rw_exit(&sctp_ipif->sctp_ipif_lock);
1258 
1259                 break;
1260         }
1261         rw_exit(&sctps->sctps_g_ipifs_lock);
1262         rw_exit(&sctps->sctps_g_ills_lock);
1263 }
1264 
1265 /*
1266  * SCTP source address list manipulaton, locking not used (except for
1267  * sctp locking by the caller.
1268  */
1269 
1270 /* Remove a specific saddr from the list */
1271 void
1272 sctp_del_saddr(sctp_t *sctp, sctp_saddr_ipif_t *sp)
1273 {
1274         if (sctp->sctp_conn_tfp != NULL)
1275                 mutex_enter(&sctp->sctp_conn_tfp->tf_lock);
1276 
1277         if (sctp->sctp_listen_tfp != NULL)
1278                 mutex_enter(&sctp->sctp_listen_tfp->tf_lock);
1279 
1280         sctp_ipif_hash_remove(sctp, sp->saddr_ipifp, B_FALSE);
1281 
1282         if (sctp->sctp_bound_to_all == 1)
1283                 sctp->sctp_bound_to_all = 0;
1284 
1285         if (sctp->sctp_conn_tfp != NULL)
1286                 mutex_exit(&sctp->sctp_conn_tfp->tf_lock);
1287 
1288         if (sctp->sctp_listen_tfp != NULL)
1289                 mutex_exit(&sctp->sctp_listen_tfp->tf_lock);
1290 }
1291 
1292 /*
1293  * Delete source address from the existing list. No error checking done here
1294  * Called with no locks held.
1295  */
1296 void
1297 sctp_del_saddr_list(sctp_t *sctp, const void *addrs, int addcnt,
1298     boolean_t fanout_locked)
1299 {
1300         struct sockaddr_in      *sin4;
1301         struct sockaddr_in6     *sin6;
1302         int                     cnt;
1303         in6_addr_t              addr;
1304         sctp_ipif_t             *sctp_ipif;
1305         int                     ifindex = 0;
1306         conn_t                  *connp = sctp->sctp_connp;
1307 
1308         ASSERT(sctp->sctp_nsaddrs >= addcnt);
1309 
1310         if (!fanout_locked) {
1311                 if (sctp->sctp_conn_tfp != NULL)
1312                         mutex_enter(&sctp->sctp_conn_tfp->tf_lock);
1313                 if (sctp->sctp_listen_tfp != NULL)
1314                         mutex_enter(&sctp->sctp_listen_tfp->tf_lock);
1315         }
1316 
1317         for (cnt = 0; cnt < addcnt; cnt++) {
1318                 switch (connp->conn_family) {
1319                 case AF_INET:
1320                         sin4 = (struct sockaddr_in *)addrs + cnt;
1321                         IN6_INADDR_TO_V4MAPPED(&sin4->sin_addr, &addr);
1322                         break;
1323 
1324                 case AF_INET6:
1325                         sin6 = (struct sockaddr_in6 *)addrs + cnt;
1326                         addr = sin6->sin6_addr;
1327                         ifindex = sin6->sin6_scope_id;
1328                         break;
1329                 }
1330                 sctp_ipif = sctp_lookup_ipif_addr(&addr, B_FALSE,
1331                     IPCL_ZONEID(connp), !connp->conn_allzones,
1332                     ifindex, 0, B_TRUE, sctp->sctp_sctps);
1333                 ASSERT(sctp_ipif != NULL);
1334                 sctp_ipif_hash_remove(sctp, sctp_ipif, B_FALSE);
1335         }
1336         if (sctp->sctp_bound_to_all == 1)
1337                 sctp->sctp_bound_to_all = 0;
1338 
1339         if (!fanout_locked) {
1340                 if (sctp->sctp_conn_tfp != NULL)
1341                         mutex_exit(&sctp->sctp_conn_tfp->tf_lock);
1342                 if (sctp->sctp_listen_tfp != NULL)
1343                         mutex_exit(&sctp->sctp_listen_tfp->tf_lock);
1344         }
1345 }
1346 
1347 /*
1348  * Given an address get the corresponding entry from the list
1349  * Called with no locks held.
1350  */
1351 sctp_saddr_ipif_t *
1352 sctp_saddr_lookup(sctp_t *sctp, in6_addr_t *addr, uint_t ifindex)
1353 {
1354         int                     cnt;
1355         sctp_saddr_ipif_t       *ipif_obj;
1356         int                     hindex;
1357         sctp_ipif_t             *sctp_ipif;
1358 
1359         hindex = SCTP_IPIF_ADDR_HASH(*addr, !IN6_IS_ADDR_V4MAPPED(addr));
1360         rw_enter(&sctp->sctp_saddrs[hindex].ipif_hash_lock, RW_READER);
1361         if (sctp->sctp_saddrs[hindex].ipif_count == 0) {
1362                 rw_exit(&sctp->sctp_saddrs[hindex].ipif_hash_lock);
1363                 return (NULL);
1364         }
1365 
1366         ipif_obj = list_head(&sctp->sctp_saddrs[hindex].sctp_ipif_list);
1367         for (cnt = 0; cnt < sctp->sctp_saddrs[hindex].ipif_count; cnt++) {
1368                 sctp_ipif = ipif_obj->saddr_ipifp;
1369                 /*
1370                  * Zone check shouldn't be needed.
1371                  */
1372                 if (IN6_ARE_ADDR_EQUAL(addr, &sctp_ipif->sctp_ipif_saddr) &&
1373                     (ifindex == 0 ||
1374                     ifindex == sctp_ipif->sctp_ipif_ill->sctp_ill_index) &&
1375                     SCTP_IPIF_USABLE(sctp_ipif->sctp_ipif_state)) {
1376                         rw_exit(&sctp->sctp_saddrs[hindex].ipif_hash_lock);
1377                         return (ipif_obj);
1378                 }
1379                 ipif_obj = list_next(&sctp->sctp_saddrs[hindex].sctp_ipif_list,
1380                     ipif_obj);
1381         }
1382         rw_exit(&sctp->sctp_saddrs[hindex].ipif_hash_lock);
1383         return (NULL);
1384 }
1385 
1386 /* Given an address, add it to the source address list */
1387 int
1388 sctp_saddr_add_addr(sctp_t *sctp, in6_addr_t *addr, uint_t ifindex)
1389 {
1390         sctp_ipif_t             *sctp_ipif;
1391         conn_t                  *connp = sctp->sctp_connp;
1392 
1393         sctp_ipif = sctp_lookup_ipif_addr(addr, B_TRUE, IPCL_ZONEID(connp),
1394             !connp->conn_allzones, ifindex, 0, B_TRUE, sctp->sctp_sctps);
1395         if (sctp_ipif == NULL)
1396                 return (EINVAL);
1397 
1398         if (sctp_ipif_hash_insert(sctp, sctp_ipif, KM_NOSLEEP, B_FALSE,
1399             B_FALSE) != 0) {
1400                 SCTP_IPIF_REFRELE(sctp_ipif);
1401                 return (EINVAL);
1402         }
1403         return (0);
1404 }
1405 
1406 /*
1407  * Remove or mark as dontsrc addresses that are currently not part of the
1408  * association. One would delete addresses when processing an INIT and
1409  * mark as dontsrc when processing an INIT-ACK.
1410  */
1411 void
1412 sctp_check_saddr(sctp_t *sctp, int supp_af, boolean_t delete,
1413     in6_addr_t *no_del_addr)
1414 {
1415         int                     i;
1416         int                     l;
1417         sctp_saddr_ipif_t       *obj;
1418         int                     scanned = 0;
1419         int                     naddr;
1420         int                     nsaddr;
1421         conn_t                  *connp = sctp->sctp_connp;
1422 
1423         ASSERT(!sctp->sctp_loopback && !sctp->sctp_linklocal && supp_af != 0);
1424 
1425         /*
1426          * Irregardless of the supported address in the INIT, v4
1427          * must be supported.
1428          */
1429         if (connp->conn_family == AF_INET)
1430                 supp_af = PARM_SUPP_V4;
1431 
1432         nsaddr = sctp->sctp_nsaddrs;
1433         for (i = 0; i < SCTP_IPIF_HASH; i++) {
1434                 rw_enter(&sctp->sctp_saddrs[i].ipif_hash_lock, RW_WRITER);
1435                 if (sctp->sctp_saddrs[i].ipif_count == 0) {
1436                         rw_exit(&sctp->sctp_saddrs[i].ipif_hash_lock);
1437                         continue;
1438                 }
1439                 obj = list_head(&sctp->sctp_saddrs[i].sctp_ipif_list);
1440                 naddr = sctp->sctp_saddrs[i].ipif_count;
1441                 for (l = 0; l < naddr; l++) {
1442                         sctp_ipif_t     *ipif;
1443 
1444                         ipif = obj->saddr_ipifp;
1445                         scanned++;
1446 
1447                         if (IN6_ARE_ADDR_EQUAL(&ipif->sctp_ipif_saddr,
1448                             no_del_addr)) {
1449                                 goto next_obj;
1450                         }
1451 
1452                         /*
1453                          * Delete/mark dontsrc loopback/linklocal addresses and
1454                          * unsupported address.
1455                          * On a clustered node, we trust the clustering module
1456                          * to do the right thing w.r.t loopback addresses, so
1457                          * we ignore loopback addresses in this check.
1458                          */
1459                         if ((SCTP_IS_IPIF_LOOPBACK(ipif) &&
1460                             cl_sctp_check_addrs == NULL) ||
1461                             SCTP_IS_IPIF_LINKLOCAL(ipif) ||
1462                             SCTP_UNSUPP_AF(ipif, supp_af)) {
1463                                 if (!delete) {
1464                                         obj->saddr_ipif_unconfirmed = 1;
1465                                         goto next_obj;
1466                                 }
1467                                 if (sctp->sctp_bound_to_all == 1)
1468                                         sctp->sctp_bound_to_all = 0;
1469                                 if (scanned < nsaddr) {
1470                                         obj = list_next(&sctp->sctp_saddrs[i].
1471                                             sctp_ipif_list, obj);
1472                                         sctp_ipif_hash_remove(sctp, ipif,
1473                                             B_TRUE);
1474                                         continue;
1475                                 }
1476                                 sctp_ipif_hash_remove(sctp, ipif, B_TRUE);
1477                         }
1478         next_obj:
1479                         if (scanned >= nsaddr) {
1480                                 rw_exit(&sctp->sctp_saddrs[i].ipif_hash_lock);
1481                                 return;
1482                         }
1483                         obj = list_next(&sctp->sctp_saddrs[i].sctp_ipif_list,
1484                             obj);
1485                 }
1486                 rw_exit(&sctp->sctp_saddrs[i].ipif_hash_lock);
1487         }
1488 }
1489 
1490 
1491 /* Get the first valid address from the list. Called with no locks held */
1492 in6_addr_t
1493 sctp_get_valid_addr(sctp_t *sctp, boolean_t isv6, boolean_t *addr_set)
1494 {
1495         int                     i;
1496         int                     l;
1497         sctp_saddr_ipif_t       *obj;
1498         int                     scanned = 0;
1499         in6_addr_t              addr;
1500 
1501         for (i = 0; i < SCTP_IPIF_HASH; i++) {
1502                 rw_enter(&sctp->sctp_saddrs[i].ipif_hash_lock, RW_READER);
1503                 if (sctp->sctp_saddrs[i].ipif_count == 0) {
1504                         rw_exit(&sctp->sctp_saddrs[i].ipif_hash_lock);
1505                         continue;
1506                 }
1507                 obj = list_head(&sctp->sctp_saddrs[i].sctp_ipif_list);
1508                 for (l = 0; l < sctp->sctp_saddrs[i].ipif_count; l++) {
1509                         sctp_ipif_t     *ipif;
1510 
1511                         ipif = obj->saddr_ipifp;
1512                         if (!SCTP_DONT_SRC(obj) &&
1513                             ipif->sctp_ipif_isv6 == isv6 &&
1514                             ipif->sctp_ipif_state == SCTP_IPIFS_UP) {
1515                                 *addr_set = B_TRUE;
1516                                 rw_exit(&sctp->sctp_saddrs[i].ipif_hash_lock);
1517                                 return (ipif->sctp_ipif_saddr);
1518                         }
1519                         scanned++;
1520                         if (scanned >= sctp->sctp_nsaddrs) {
1521                                 rw_exit(&sctp->sctp_saddrs[i].ipif_hash_lock);
1522                                 goto got_none;
1523                         }
1524                         obj = list_next(&sctp->sctp_saddrs[i].sctp_ipif_list,
1525                             obj);
1526                 }
1527                 rw_exit(&sctp->sctp_saddrs[i].ipif_hash_lock);
1528         }
1529 got_none:
1530         /* Need to double check this */
1531         if (isv6 == B_TRUE)
1532                 addr =  ipv6_all_zeros;
1533         else
1534                 IN6_IPADDR_TO_V4MAPPED(0, &addr);
1535         *addr_set = B_FALSE;
1536         return (addr);
1537 }
1538 
1539 /*
1540  * Return the list of local addresses of an association.  The parameter
1541  * myaddrs is supposed to be either (struct sockaddr_in *) or (struct
1542  * sockaddr_in6 *) depending on the address family.
1543  */
1544 int
1545 sctp_getmyaddrs(void *conn, void *myaddrs, int *addrcnt)
1546 {
1547         int                     i;
1548         int                     l;
1549         sctp_saddr_ipif_t       *obj;
1550         sctp_t                  *sctp = (sctp_t *)conn;
1551         conn_t                  *connp = sctp->sctp_connp;
1552         int                     family = connp->conn_family;
1553         int                     max = *addrcnt;
1554         size_t                  added = 0;
1555         struct sockaddr_in6     *sin6;
1556         struct sockaddr_in      *sin4;
1557         int                     scanned = 0;
1558         boolean_t               skip_lback = B_FALSE;
1559         ip_xmit_attr_t          *ixa = connp->conn_ixa;
1560 
1561         if (sctp->sctp_nsaddrs == 0)
1562                 return (EINVAL);
1563 
1564         /*
1565          * Skip loopback addresses for non-loopback assoc., ignore
1566          * this on a clustered node.
1567          */
1568         if (sctp->sctp_state >= SCTPS_ESTABLISHED && !sctp->sctp_loopback &&
1569             (cl_sctp_check_addrs == NULL)) {
1570                 skip_lback = B_TRUE;
1571         }
1572 
1573         for (i = 0; i < SCTP_IPIF_HASH; i++) {
1574                 rw_enter(&sctp->sctp_saddrs[i].ipif_hash_lock, RW_READER);
1575                 if (sctp->sctp_saddrs[i].ipif_count == 0) {
1576                         rw_exit(&sctp->sctp_saddrs[i].ipif_hash_lock);
1577                         continue;
1578                 }
1579                 obj = list_head(&sctp->sctp_saddrs[i].sctp_ipif_list);
1580                 for (l = 0; l < sctp->sctp_saddrs[i].ipif_count; l++) {
1581                         sctp_ipif_t     *ipif = obj->saddr_ipifp;
1582                         in6_addr_t      addr = ipif->sctp_ipif_saddr;
1583 
1584                         scanned++;
1585                         if ((ipif->sctp_ipif_state == SCTP_IPIFS_CONDEMNED) ||
1586                             SCTP_DONT_SRC(obj) ||
1587                             (SCTP_IS_IPIF_LOOPBACK(ipif) && skip_lback)) {
1588                                 if (scanned >= sctp->sctp_nsaddrs) {
1589                                         rw_exit(&sctp->
1590                                             sctp_saddrs[i].ipif_hash_lock);
1591                                         goto done;
1592                                 }
1593                                 obj = list_next(&sctp->sctp_saddrs[i].
1594                                     sctp_ipif_list, obj);
1595                                 continue;
1596                         }
1597                         switch (family) {
1598                         case AF_INET:
1599                                 sin4 = (struct sockaddr_in *)myaddrs + added;
1600                                 sin4->sin_family = AF_INET;
1601                                 sin4->sin_port = connp->conn_lport;
1602                                 IN6_V4MAPPED_TO_INADDR(&addr, &sin4->sin_addr);
1603                                 break;
1604 
1605                         case AF_INET6:
1606                                 sin6 = (struct sockaddr_in6 *)myaddrs + added;
1607                                 sin6->sin6_family = AF_INET6;
1608                                 sin6->sin6_port = connp->conn_lport;
1609                                 sin6->sin6_addr = addr;
1610                                 /*
1611                                  * Note that flowinfo is only returned for
1612                                  * getpeername just like for TCP and UDP.
1613                                  */
1614                                 sin6->sin6_flowinfo = 0;
1615 
1616                                 if (IN6_IS_ADDR_LINKSCOPE(&sin6->sin6_addr) &&
1617                                     (ixa->ixa_flags & IXAF_SCOPEID_SET))
1618                                         sin6->sin6_scope_id = ixa->ixa_scopeid;
1619                                 else
1620                                         sin6->sin6_scope_id = 0;
1621                                 sin6->__sin6_src_id = 0;
1622                                 break;
1623                         }
1624                         added++;
1625                         if (added >= max || scanned >= sctp->sctp_nsaddrs) {
1626                                 rw_exit(&sctp->sctp_saddrs[i].ipif_hash_lock);
1627                                 goto done;
1628                         }
1629                         obj = list_next(&sctp->sctp_saddrs[i].sctp_ipif_list,
1630                             obj);
1631                 }
1632                 rw_exit(&sctp->sctp_saddrs[i].ipif_hash_lock);
1633         }
1634 done:
1635         *addrcnt = added;
1636         return (0);
1637 }
1638 
1639 /*
1640  * Given the supported address family, walk through the source address list
1641  * and return the total length of the available addresses. If 'p' is not
1642  * null, construct the parameter list for the addresses in 'p'.
1643  * 'modify' will only be set when we want the source address list to
1644  * be modified. The source address list will be modified only when
1645  * generating an INIT chunk. For generating an INIT-ACK 'modify' will
1646  * be false since the 'sctp' will be that of the listener.
1647  */
1648 size_t
1649 sctp_saddr_info(sctp_t *sctp, int supp_af, uchar_t *p, boolean_t modify)
1650 {
1651         int                     i;
1652         int                     l;
1653         sctp_saddr_ipif_t       *obj;
1654         size_t                  paramlen = 0;
1655         sctp_parm_hdr_t         *hdr;
1656         int                     scanned = 0;
1657         int                     naddr;
1658         int                     nsaddr;
1659         boolean_t               del_ll = B_FALSE;
1660         boolean_t               del_lb = B_FALSE;
1661 
1662 
1663         /*
1664          * On a clustered node don't bother changing anything
1665          * on the loopback interface.
1666          */
1667         if (modify && !sctp->sctp_loopback && (cl_sctp_check_addrs == NULL))
1668                 del_lb = B_TRUE;
1669 
1670         if (modify && !sctp->sctp_linklocal)
1671                 del_ll = B_TRUE;
1672 
1673         nsaddr = sctp->sctp_nsaddrs;
1674         for (i = 0; i < SCTP_IPIF_HASH; i++) {
1675                 rw_enter(&sctp->sctp_saddrs[i].ipif_hash_lock, RW_WRITER);
1676                 if (sctp->sctp_saddrs[i].ipif_count == 0) {
1677                         rw_exit(&sctp->sctp_saddrs[i].ipif_hash_lock);
1678                         continue;
1679                 }
1680                 obj = list_head(&sctp->sctp_saddrs[i].sctp_ipif_list);
1681                 naddr = sctp->sctp_saddrs[i].ipif_count;
1682                 for (l = 0; l < naddr; l++) {
1683                         in6_addr_t      addr;
1684                         sctp_ipif_t     *ipif;
1685                         boolean_t       ipif_lb;
1686                         boolean_t       ipif_ll;
1687                         boolean_t       unsupp_af;
1688 
1689                         ipif = obj->saddr_ipifp;
1690                         scanned++;
1691 
1692                         ipif_lb = SCTP_IS_IPIF_LOOPBACK(ipif);
1693                         ipif_ll = SCTP_IS_IPIF_LINKLOCAL(ipif);
1694                         unsupp_af = SCTP_UNSUPP_AF(ipif, supp_af);
1695                         /*
1696                          * We need to either delete or skip loopback/linklocal
1697                          * or unsupported addresses, if required.
1698                          */
1699                         if ((ipif_ll && del_ll) || (ipif_lb && del_lb) ||
1700                             (unsupp_af && modify)) {
1701                                 if (sctp->sctp_bound_to_all == 1)
1702                                         sctp->sctp_bound_to_all = 0;
1703                                 if (scanned < nsaddr) {
1704                                         obj = list_next(&sctp->sctp_saddrs[i].
1705                                             sctp_ipif_list, obj);
1706                                         sctp_ipif_hash_remove(sctp, ipif,
1707                                             B_TRUE);
1708                                         continue;
1709                                 }
1710                                 sctp_ipif_hash_remove(sctp, ipif, B_TRUE);
1711 
1712                                 goto next_addr;
1713                         } else if (ipif_ll || unsupp_af ||
1714                             (ipif_lb && (cl_sctp_check_addrs == NULL))) {
1715                                 goto next_addr;
1716                         }
1717 
1718                         if (!SCTP_IPIF_USABLE(ipif->sctp_ipif_state))
1719                                 goto next_addr;
1720                         if (p != NULL)
1721                                 hdr = (sctp_parm_hdr_t *)(p + paramlen);
1722                         addr = ipif->sctp_ipif_saddr;
1723                         if (!ipif->sctp_ipif_isv6) {
1724                                 struct in_addr  *v4;
1725 
1726                                 if (p != NULL) {
1727                                         hdr->sph_type = htons(PARM_ADDR4);
1728                                         hdr->sph_len = htons(PARM_ADDR4_LEN);
1729                                         v4 = (struct in_addr *)(hdr + 1);
1730                                         IN6_V4MAPPED_TO_INADDR(&addr, v4);
1731                                 }
1732                                 paramlen += PARM_ADDR4_LEN;
1733                         } else {
1734                                 if (p != NULL) {
1735                                         hdr->sph_type = htons(PARM_ADDR6);
1736                                         hdr->sph_len = htons(PARM_ADDR6_LEN);
1737                                         bcopy(&addr, hdr + 1, sizeof (addr));
1738                                 }
1739                                 paramlen += PARM_ADDR6_LEN;
1740                         }
1741 next_addr:
1742                         if (scanned >= nsaddr) {
1743                                 rw_exit(&sctp->sctp_saddrs[i].ipif_hash_lock);
1744                                 return (paramlen);
1745                         }
1746                         obj = list_next(&sctp->sctp_saddrs[i].sctp_ipif_list,
1747                             obj);
1748                 }
1749                 rw_exit(&sctp->sctp_saddrs[i].ipif_hash_lock);
1750         }
1751         return (paramlen);
1752 }
1753 
1754 /*
1755  * This is used on a clustered node to obtain a list of addresses, the list
1756  * consists of sockaddr_in structs for v4 and sockaddr_in6 for v6. The list
1757  * is then passed onto the clustering module which sends back the correct
1758  * list based on the port info. Regardless of the input, i.e INADDR_ANY
1759  * or specific address(es), we create the list since it could be modified by
1760  * the clustering module. When given a list of addresses, we simply
1761  * create the list of sockaddr_in or sockaddr_in6 structs using those
1762  * addresses. If there is an INADDR_ANY in the input list, or if the
1763  * input is INADDR_ANY, we create a list of sockaddr_in or sockaddr_in6
1764  * structs consisting all the addresses in the global interface list
1765  * except those that are hosted on the loopback interface. We create
1766  * a list of sockaddr_in[6] structs just so that it can be directly input
1767  * to sctp_valid_addr_list() once the clustering module has processed it.
1768  */
1769 int
1770 sctp_get_addrlist(sctp_t *sctp, const void *addrs, uint32_t *addrcnt,
1771     uchar_t **addrlist, int *uspec, size_t *size)
1772 {
1773         int                     cnt;
1774         int                     icnt;
1775         sctp_ipif_t             *sctp_ipif;
1776         struct sockaddr_in      *s4;
1777         struct sockaddr_in6     *s6;
1778         uchar_t                 *p;
1779         int                     err = 0;
1780         sctp_stack_t            *sctps = sctp->sctp_sctps;
1781         conn_t                  *connp = sctp->sctp_connp;
1782 
1783         *addrlist = NULL;
1784         *size = 0;
1785 
1786         /*
1787          * Create a list of sockaddr_in[6] structs using the input list.
1788          */
1789         if (connp->conn_family == AF_INET) {
1790                 *size = sizeof (struct sockaddr_in) * *addrcnt;
1791                 *addrlist = kmem_zalloc(*size,  KM_SLEEP);
1792                 p = *addrlist;
1793                 for (cnt = 0; cnt < *addrcnt; cnt++) {
1794                         s4 = (struct sockaddr_in *)addrs + cnt;
1795                         /*
1796                          * We need to create a list of all the available
1797                          * addresses if there is an INADDR_ANY. However,
1798                          * if we are beyond LISTEN, then this is invalid
1799                          * (see sctp_valid_addr_list(). So, we just fail
1800                          * it here rather than wait till it fails in
1801                          * sctp_valid_addr_list().
1802                          */
1803                         if (s4->sin_addr.s_addr == INADDR_ANY) {
1804                                 kmem_free(*addrlist, *size);
1805                                 *addrlist = NULL;
1806                                 *size = 0;
1807                                 if (sctp->sctp_state > SCTPS_LISTEN) {
1808                                         *addrcnt = 0;
1809                                         return (EINVAL);
1810                                 }
1811                                 if (uspec != NULL)
1812                                         *uspec = 1;
1813                                 goto get_all_addrs;
1814                         } else {
1815                                 bcopy(s4, p, sizeof (*s4));
1816                                 p += sizeof (*s4);
1817                         }
1818                 }
1819         } else {
1820                 *size = sizeof (struct sockaddr_in6) * *addrcnt;
1821                 *addrlist = kmem_zalloc(*size, KM_SLEEP);
1822                 p = *addrlist;
1823                 for (cnt = 0; cnt < *addrcnt; cnt++) {
1824                         s6 = (struct sockaddr_in6 *)addrs + cnt;
1825                         /*
1826                          * Comments for INADDR_ANY, above, apply here too.
1827                          */
1828                         if (IN6_IS_ADDR_UNSPECIFIED(&s6->sin6_addr)) {
1829                                 kmem_free(*addrlist, *size);
1830                                 *size = 0;
1831                                 *addrlist = NULL;
1832                                 if (sctp->sctp_state > SCTPS_LISTEN) {
1833                                         *addrcnt = 0;
1834                                         return (EINVAL);
1835                                 }
1836                                 if (uspec != NULL)
1837                                         *uspec = 1;
1838                                 goto get_all_addrs;
1839                         } else {
1840                                 bcopy(addrs, p, sizeof (*s6));
1841                                 p += sizeof (*s6);
1842                         }
1843                 }
1844         }
1845         return (err);
1846 get_all_addrs:
1847 
1848         /*
1849          * Allocate max possible size. We allocate the max. size here because
1850          * the clustering module could end up adding addresses to the list.
1851          * We allocate upfront so that the clustering module need to bother
1852          * re-sizing the list.
1853          */
1854         if (connp->conn_family == AF_INET) {
1855                 *size = sizeof (struct sockaddr_in) *
1856                     sctps->sctps_g_ipifs_count;
1857         } else {
1858                 *size = sizeof (struct sockaddr_in6) *
1859                     sctps->sctps_g_ipifs_count;
1860         }
1861         *addrlist = kmem_zalloc(*size, KM_SLEEP);
1862         *addrcnt = 0;
1863         p = *addrlist;
1864         rw_enter(&sctps->sctps_g_ipifs_lock, RW_READER);
1865 
1866         /*
1867          * Walk through the global interface list and add all addresses,
1868          * except those that are hosted on loopback interfaces.
1869          */
1870         for (cnt = 0; cnt <  SCTP_IPIF_HASH; cnt++) {
1871                 if (sctps->sctps_g_ipifs[cnt].ipif_count == 0)
1872                         continue;
1873                 sctp_ipif = list_head(
1874                     &sctps->sctps_g_ipifs[cnt].sctp_ipif_list);
1875                 for (icnt = 0;
1876                     icnt < sctps->sctps_g_ipifs[cnt].ipif_count;
1877                     icnt++) {
1878                         in6_addr_t      addr;
1879 
1880                         rw_enter(&sctp_ipif->sctp_ipif_lock, RW_READER);
1881                         addr = sctp_ipif->sctp_ipif_saddr;
1882                         if (SCTP_IPIF_DISCARD(sctp_ipif->sctp_ipif_flags) ||
1883                             !SCTP_IPIF_USABLE(sctp_ipif->sctp_ipif_state) ||
1884                             SCTP_IS_IPIF_LOOPBACK(sctp_ipif) ||
1885                             SCTP_IS_IPIF_LINKLOCAL(sctp_ipif) ||
1886                             !SCTP_IPIF_ZONE_MATCH(sctp, sctp_ipif) ||
1887                             (connp->conn_family == AF_INET &&
1888                             sctp_ipif->sctp_ipif_isv6) ||
1889                             (sctp->sctp_connp->conn_ipv6_v6only &&
1890                             !sctp_ipif->sctp_ipif_isv6)) {
1891                                 rw_exit(&sctp_ipif->sctp_ipif_lock);
1892                                 sctp_ipif = list_next(
1893                                     &sctps->sctps_g_ipifs[cnt].sctp_ipif_list,
1894                                     sctp_ipif);
1895                                 continue;
1896                         }
1897                         rw_exit(&sctp_ipif->sctp_ipif_lock);
1898                         if (connp->conn_family == AF_INET) {
1899                                 s4 = (struct sockaddr_in *)p;
1900                                 IN6_V4MAPPED_TO_INADDR(&addr, &s4->sin_addr);
1901                                 s4->sin_family = AF_INET;
1902                                 p += sizeof (*s4);
1903                         } else {
1904                                 s6 = (struct sockaddr_in6 *)p;
1905                                 s6->sin6_addr = addr;
1906                                 s6->sin6_family = AF_INET6;
1907                                 s6->sin6_scope_id =
1908                                     sctp_ipif->sctp_ipif_ill->sctp_ill_index;
1909                                 p += sizeof (*s6);
1910                         }
1911                         (*addrcnt)++;
1912                         sctp_ipif = list_next(
1913                             &sctps->sctps_g_ipifs[cnt].sctp_ipif_list,
1914                             sctp_ipif);
1915                 }
1916         }
1917         rw_exit(&sctps->sctps_g_ipifs_lock);
1918         return (err);
1919 }
1920 
1921 /*
1922  * Get a list of addresses from the source address list. The  caller is
1923  * responsible for allocating sufficient buffer for this.
1924  */
1925 void
1926 sctp_get_saddr_list(sctp_t *sctp, uchar_t *p, size_t psize)
1927 {
1928         int                     cnt;
1929         int                     icnt;
1930         sctp_saddr_ipif_t       *obj;
1931         int                     naddr;
1932         int                     scanned = 0;
1933 
1934         for (cnt = 0; cnt < SCTP_IPIF_HASH; cnt++) {
1935                 rw_enter(&sctp->sctp_saddrs[cnt].ipif_hash_lock, RW_READER);
1936                 if (sctp->sctp_saddrs[cnt].ipif_count == 0) {
1937                         rw_exit(&sctp->sctp_saddrs[cnt].ipif_hash_lock);
1938                         continue;
1939                 }
1940                 obj = list_head(&sctp->sctp_saddrs[cnt].sctp_ipif_list);
1941                 naddr = sctp->sctp_saddrs[cnt].ipif_count;
1942                 for (icnt = 0; icnt < naddr; icnt++) {
1943                         sctp_ipif_t     *ipif;
1944 
1945                         if (psize < sizeof (ipif->sctp_ipif_saddr)) {
1946                                 rw_exit(&sctp->sctp_saddrs[cnt].ipif_hash_lock);
1947                                 return;
1948                         }
1949 
1950                         scanned++;
1951                         ipif = obj->saddr_ipifp;
1952                         bcopy(&ipif->sctp_ipif_saddr, p,
1953                             sizeof (ipif->sctp_ipif_saddr));
1954                         p += sizeof (ipif->sctp_ipif_saddr);
1955                         psize -= sizeof (ipif->sctp_ipif_saddr);
1956                         if (scanned >= sctp->sctp_nsaddrs) {
1957                                 rw_exit(&sctp->sctp_saddrs[cnt].ipif_hash_lock);
1958                                 return;
1959                         }
1960                         obj = list_next(
1961                             &sctp->sctp_saddrs[icnt].sctp_ipif_list,
1962                             obj);
1963                 }
1964                 rw_exit(&sctp->sctp_saddrs[cnt].ipif_hash_lock);
1965         }
1966 }
1967 
1968 /*
1969  * Get a list of addresses from the remote address list. The  caller is
1970  * responsible for allocating sufficient buffer for this.
1971  */
1972 void
1973 sctp_get_faddr_list(sctp_t *sctp, uchar_t *p, size_t psize)
1974 {
1975         sctp_faddr_t    *fp;
1976 
1977         for (fp = sctp->sctp_faddrs; fp != NULL; fp = fp->sf_next) {
1978                 if (psize < sizeof (fp->sf_faddr))
1979                         return;
1980                 bcopy(&fp->sf_faddr, p, sizeof (fp->sf_faddr));
1981                 p += sizeof (fp->sf_faddr);
1982                 psize -= sizeof (fp->sf_faddr);
1983         }
1984 }
1985 
1986 static void
1987 sctp_free_ills(sctp_stack_t *sctps)
1988 {
1989         int                     i;
1990         int                     l;
1991         sctp_ill_t      *sctp_ill;
1992 
1993         if (sctps->sctps_ills_count == 0)
1994                 return;
1995 
1996         for (i = 0; i < SCTP_ILL_HASH; i++) {
1997                 sctp_ill = list_tail(&sctps->sctps_g_ills[i].sctp_ill_list);
1998                 for (l = 0; l < sctps->sctps_g_ills[i].ill_count; l++) {
1999                         ASSERT(sctp_ill->sctp_ill_ipifcnt == 0);
2000                         list_remove(&sctps->sctps_g_ills[i].sctp_ill_list,
2001                             sctp_ill);
2002                         sctps->sctps_ills_count--;
2003                         kmem_free(sctp_ill->sctp_ill_name,
2004                             sctp_ill->sctp_ill_name_length);
2005                         kmem_free(sctp_ill, sizeof (sctp_ill_t));
2006                         sctp_ill =
2007                             list_tail(&sctps->sctps_g_ills[i].sctp_ill_list);
2008                 }
2009                 sctps->sctps_g_ills[i].ill_count = 0;
2010         }
2011         ASSERT(sctps->sctps_ills_count == 0);
2012 }
2013 
2014 static void
2015 sctp_free_ipifs(sctp_stack_t *sctps)
2016 {
2017         int                     i;
2018         int                     l;
2019         sctp_ipif_t     *sctp_ipif;
2020         sctp_ill_t      *sctp_ill;
2021 
2022         if (sctps->sctps_g_ipifs_count == 0)
2023                 return;
2024 
2025         for (i = 0; i < SCTP_IPIF_HASH; i++) {
2026                 sctp_ipif = list_tail(&sctps->sctps_g_ipifs[i].sctp_ipif_list);
2027                 for (l = 0; l < sctps->sctps_g_ipifs[i].ipif_count; l++) {
2028                         sctp_ill = sctp_ipif->sctp_ipif_ill;
2029 
2030                         list_remove(&sctps->sctps_g_ipifs[i].sctp_ipif_list,
2031                             sctp_ipif);
2032                         sctps->sctps_g_ipifs_count--;
2033                         (void) atomic_add_32_nv(&sctp_ill->sctp_ill_ipifcnt,
2034                             -1);
2035                         kmem_free(sctp_ipif, sizeof (sctp_ipif_t));
2036                         sctp_ipif =
2037                             list_tail(&sctps->sctps_g_ipifs[i].sctp_ipif_list);
2038                 }
2039                 sctps->sctps_g_ipifs[i].ipif_count = 0;
2040         }
2041         ASSERT(sctps->sctps_g_ipifs_count == 0);
2042 }
2043 
2044 
2045 /* Initialize the SCTP ILL list and lock */
2046 void
2047 sctp_saddr_init(sctp_stack_t *sctps)
2048 {
2049         int     i;
2050 
2051         sctps->sctps_g_ills = kmem_zalloc(sizeof (sctp_ill_hash_t) *
2052             SCTP_ILL_HASH, KM_SLEEP);
2053         sctps->sctps_g_ipifs = kmem_zalloc(sizeof (sctp_ipif_hash_t) *
2054             SCTP_IPIF_HASH, KM_SLEEP);
2055 
2056         rw_init(&sctps->sctps_g_ills_lock, NULL, RW_DEFAULT, NULL);
2057         rw_init(&sctps->sctps_g_ipifs_lock, NULL, RW_DEFAULT, NULL);
2058 
2059         for (i = 0; i < SCTP_ILL_HASH; i++) {
2060                 sctps->sctps_g_ills[i].ill_count = 0;
2061                 list_create(&sctps->sctps_g_ills[i].sctp_ill_list,
2062                     sizeof (sctp_ill_t),
2063                     offsetof(sctp_ill_t, sctp_ills));
2064         }
2065         for (i = 0; i < SCTP_IPIF_HASH; i++) {
2066                 sctps->sctps_g_ipifs[i].ipif_count = 0;
2067                 list_create(&sctps->sctps_g_ipifs[i].sctp_ipif_list,
2068                     sizeof (sctp_ipif_t), offsetof(sctp_ipif_t, sctp_ipifs));
2069         }
2070 }
2071 
2072 void
2073 sctp_saddr_fini(sctp_stack_t *sctps)
2074 {
2075         int     i;
2076 
2077         sctp_free_ipifs(sctps);
2078         sctp_free_ills(sctps);
2079 
2080         for (i = 0; i < SCTP_ILL_HASH; i++)
2081                 list_destroy(&sctps->sctps_g_ills[i].sctp_ill_list);
2082         for (i = 0; i < SCTP_IPIF_HASH; i++)
2083                 list_destroy(&sctps->sctps_g_ipifs[i].sctp_ipif_list);
2084 
2085         ASSERT(sctps->sctps_ills_count == 0 && sctps->sctps_g_ipifs_count == 0);
2086         kmem_free(sctps->sctps_g_ills, sizeof (sctp_ill_hash_t) *
2087             SCTP_ILL_HASH);
2088         sctps->sctps_g_ills = NULL;
2089         kmem_free(sctps->sctps_g_ipifs, sizeof (sctp_ipif_hash_t) *
2090             SCTP_IPIF_HASH);
2091         sctps->sctps_g_ipifs = NULL;
2092         rw_destroy(&sctps->sctps_g_ills_lock);
2093         rw_destroy(&sctps->sctps_g_ipifs_lock);
2094 }