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