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_ire.h>
     45 #include <inet/ip_if.h>
     46 #include <inet/ipclassifier.h>
     47 #include <inet/sctp_ip.h>
     48 #include "sctp_impl.h"
     49 #include "sctp_addr.h"
     50 
     51 static void		sctp_ipif_inactive(sctp_ipif_t *);
     52 static sctp_ipif_t	*sctp_lookup_ipif_addr(in6_addr_t *, boolean_t,
     53 			    zoneid_t, boolean_t, uint_t, uint_t, boolean_t,
     54 			    sctp_stack_t *);
     55 static int		sctp_get_all_ipifs(sctp_t *, int);
     56 static int		sctp_ipif_hash_insert(sctp_t *, sctp_ipif_t *, int,
     57 			    boolean_t, boolean_t);
     58 static void		sctp_ipif_hash_remove(sctp_t *, sctp_ipif_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 	ipif_obj = list_head(&sctp->sctp_saddrs[hindex].sctp_ipif_list);
    465 	for (cnt = 0; cnt < sctp->sctp_saddrs[hindex].ipif_count; cnt++) {
    466 		if (IN6_ARE_ADDR_EQUAL(&ipif_obj->saddr_ipifp->sctp_ipif_saddr,
    467 		    &ipif->sctp_ipif_saddr)) {
    468 			if (ipif->sctp_ipif_id !=
    469 			    ipif_obj->saddr_ipifp->sctp_ipif_id &&
    470 			    ipif_obj->saddr_ipifp->sctp_ipif_state ==
    471 			    SCTP_IPIFS_DOWN && ipif->sctp_ipif_state ==
    472 			    SCTP_IPIFS_UP) {
    473 				SCTP_IPIF_REFRELE(ipif_obj->saddr_ipifp);
    474 				ipif_obj->saddr_ipifp = ipif;
    475 				ipif_obj->saddr_ipif_dontsrc = dontsrc ? 1 : 0;
    476 				return (0);
    477 			} else if (!allow_dup || ipif->sctp_ipif_id ==
    478 			    ipif_obj->saddr_ipifp->sctp_ipif_id) {
    479 				return (EALREADY);
    480 			}
    481 		}
    482 		ipif_obj = list_next(&sctp->sctp_saddrs[hindex].sctp_ipif_list,
    483 		    ipif_obj);
    484 	}
    485 	ipif_obj = kmem_zalloc(sizeof (sctp_saddr_ipif_t), sleep);
    486 	if (ipif_obj == NULL) {
    487 		/* Need to do something */
    488 		return (ENOMEM);
    489 	}
    490 	ipif_obj->saddr_ipifp = ipif;
    491 	ipif_obj->saddr_ipif_dontsrc = dontsrc ? 1 : 0;
    492 	list_insert_tail(&sctp->sctp_saddrs[hindex].sctp_ipif_list, ipif_obj);
    493 	sctp->sctp_saddrs[hindex].ipif_count++;
    494 	sctp->sctp_nsaddrs++;
    495 	return (0);
    496 }
    497 
    498 /*
    499  * Given a source address, walk through the peer address list to see
    500  * if the source address is being used.  If it is, reset that.
    501  * A cleared saddr will then make sctp_make_mp lookup the destination again
    502  * and as part of that look for a new source.
    503  */
    504 static void
    505 sctp_fix_saddr(sctp_t *sctp, in6_addr_t *saddr)
    506 {
    507 	sctp_faddr_t	*fp;
    508 
    509 	for (fp = sctp->sctp_faddrs; fp != NULL; fp = fp->next) {
    510 		if (!IN6_ARE_ADDR_EQUAL(&fp->saddr, saddr))
    511 			continue;
    512 		V6_SET_ZERO(fp->saddr);
    513 	}
    514 }
    515 
    516 static void
    517 sctp_ipif_hash_remove(sctp_t *sctp, sctp_ipif_t *ipif)
    518 {
    519 	int			cnt;
    520 	sctp_saddr_ipif_t	*ipif_obj;
    521 	int			hindex;
    522 
    523 	hindex = SCTP_IPIF_ADDR_HASH(ipif->sctp_ipif_saddr,
    524 	    ipif->sctp_ipif_isv6);
    525 	ipif_obj = list_head(&sctp->sctp_saddrs[hindex].sctp_ipif_list);
    526 	for (cnt = 0; cnt < sctp->sctp_saddrs[hindex].ipif_count; cnt++) {
    527 		if (IN6_ARE_ADDR_EQUAL(&ipif_obj->saddr_ipifp->sctp_ipif_saddr,
    528 		    &ipif->sctp_ipif_saddr)) {
    529 			list_remove(&sctp->sctp_saddrs[hindex].sctp_ipif_list,
    530 			    ipif_obj);
    531 			sctp->sctp_saddrs[hindex].ipif_count--;
    532 			sctp->sctp_nsaddrs--;
    533 			sctp_fix_saddr(sctp, &ipif->sctp_ipif_saddr);
    534 			SCTP_IPIF_REFRELE(ipif_obj->saddr_ipifp);
    535 			kmem_free(ipif_obj, sizeof (sctp_saddr_ipif_t));
    536 			break;
    537 		}
    538 		ipif_obj = list_next(&sctp->sctp_saddrs[hindex].sctp_ipif_list,
    539 		    ipif_obj);
    540 	}
    541 }
    542 
    543 static int
    544 sctp_compare_ipif_list(sctp_ipif_hash_t *list1, sctp_ipif_hash_t *list2)
    545 {
    546 	int			i;
    547 	int			j;
    548 	sctp_saddr_ipif_t	*obj1;
    549 	sctp_saddr_ipif_t	*obj2;
    550 	int			overlap = 0;
    551 
    552 	obj1 = list_head(&list1->sctp_ipif_list);
    553 	for (i = 0; i < list1->ipif_count; i++) {
    554 		obj2 = list_head(&list2->sctp_ipif_list);
    555 		for (j = 0; j < list2->ipif_count; j++) {
    556 			if (IN6_ARE_ADDR_EQUAL(
    557 			    &obj1->saddr_ipifp->sctp_ipif_saddr,
    558 			    &obj2->saddr_ipifp->sctp_ipif_saddr)) {
    559 				overlap++;
    560 				break;
    561 			}
    562 			obj2 = list_next(&list2->sctp_ipif_list,
    563 			    obj2);
    564 		}
    565 		obj1 = list_next(&list1->sctp_ipif_list, obj1);
    566 	}
    567 	return (overlap);
    568 }
    569 
    570 int
    571 sctp_compare_saddrs(sctp_t *sctp1, sctp_t *sctp2)
    572 {
    573 	int		i;
    574 	int		overlap = 0;
    575 
    576 	for (i = 0; i < SCTP_IPIF_HASH; i++) {
    577 		overlap += sctp_compare_ipif_list(&sctp1->sctp_saddrs[i],
    578 		    &sctp2->sctp_saddrs[i]);
    579 	}
    580 
    581 	if (sctp1->sctp_nsaddrs == sctp2->sctp_nsaddrs &&
    582 	    overlap == sctp1->sctp_nsaddrs) {
    583 		return (SCTP_ADDR_EQUAL);
    584 	}
    585 
    586 	if (overlap == sctp1->sctp_nsaddrs)
    587 		return (SCTP_ADDR_SUBSET);
    588 
    589 	if (overlap > 0)
    590 		return (SCTP_ADDR_OVERLAP);
    591 
    592 	return (SCTP_ADDR_DISJOINT);
    593 }
    594 
    595 static int
    596 sctp_copy_ipifs(sctp_ipif_hash_t *list1, sctp_t *sctp2, int sleep)
    597 {
    598 	int			i;
    599 	sctp_saddr_ipif_t	*obj;
    600 	int			error = 0;
    601 
    602 	obj = list_head(&list1->sctp_ipif_list);
    603 	for (i = 0; i < list1->ipif_count; i++) {
    604 		SCTP_IPIF_REFHOLD(obj->saddr_ipifp);
    605 		error = sctp_ipif_hash_insert(sctp2, obj->saddr_ipifp, sleep,
    606 		    B_FALSE, B_FALSE);
    607 		ASSERT(error != EALREADY);
    608 		if (error != 0)
    609 			return (error);
    610 		obj = list_next(&list1->sctp_ipif_list, obj);
    611 	}
    612 	return (error);
    613 }
    614 
    615 int
    616 sctp_dup_saddrs(sctp_t *sctp1, sctp_t *sctp2, int sleep)
    617 {
    618 	int	error = 0;
    619 	int	i;
    620 
    621 	if (sctp1 == NULL || sctp1->sctp_bound_to_all == 1)
    622 		return (sctp_get_all_ipifs(sctp2, sleep));
    623 
    624 	for (i = 0; i < SCTP_IPIF_HASH; i++) {
    625 		if (sctp1->sctp_saddrs[i].ipif_count == 0)
    626 			continue;
    627 		error = sctp_copy_ipifs(&sctp1->sctp_saddrs[i], sctp2, sleep);
    628 		if (error != 0) {
    629 			sctp_free_saddrs(sctp2);
    630 			return (error);
    631 		}
    632 	}
    633 	return (0);
    634 }
    635 
    636 void
    637 sctp_free_saddrs(sctp_t *sctp)
    638 {
    639 	int			i;
    640 	int			l;
    641 	sctp_saddr_ipif_t	*obj;
    642 
    643 	if (sctp->sctp_nsaddrs == 0)
    644 		return;
    645 	for (i = 0; i < SCTP_IPIF_HASH; i++) {
    646 		if (sctp->sctp_saddrs[i].ipif_count == 0)
    647 			continue;
    648 		obj = list_tail(&sctp->sctp_saddrs[i].sctp_ipif_list);
    649 		for (l = 0; l < sctp->sctp_saddrs[i].ipif_count; l++) {
    650 			list_remove(&sctp->sctp_saddrs[i].sctp_ipif_list, obj);
    651 			SCTP_IPIF_REFRELE(obj->saddr_ipifp);
    652 			sctp->sctp_nsaddrs--;
    653 			kmem_free(obj, sizeof (sctp_saddr_ipif_t));
    654 			obj = list_tail(&sctp->sctp_saddrs[i].sctp_ipif_list);
    655 		}
    656 		sctp->sctp_saddrs[i].ipif_count = 0;
    657 	}
    658 	if (sctp->sctp_bound_to_all == 1)
    659 		sctp->sctp_bound_to_all = 0;
    660 	ASSERT(sctp->sctp_nsaddrs == 0);
    661 }
    662 
    663 /*
    664  * Add/Delete the given ILL from the SCTP ILL list. Called with no locks
    665  * held.
    666  */
    667 void
    668 sctp_update_ill(ill_t *ill, int op)
    669 {
    670 	int		i;
    671 	sctp_ill_t	*sctp_ill = NULL;
    672 	uint_t		index;
    673 	netstack_t	*ns = ill->ill_ipst->ips_netstack;
    674 	sctp_stack_t	*sctps = ns->netstack_sctp;
    675 
    676 	rw_enter(&sctps->sctps_g_ills_lock, RW_WRITER);
    677 
    678 	index = SCTP_ILL_HASH_FN(SCTP_ILL_TO_PHYINDEX(ill));
    679 	sctp_ill = list_head(&sctps->sctps_g_ills[index].sctp_ill_list);
    680 	for (i = 0; i < sctps->sctps_g_ills[index].ill_count; i++) {
    681 		if ((sctp_ill->sctp_ill_index == SCTP_ILL_TO_PHYINDEX(ill)) &&
    682 		    (sctp_ill->sctp_ill_isv6 == ill->ill_isv6)) {
    683 			break;
    684 		}
    685 		sctp_ill = list_next(&sctps->sctps_g_ills[index].sctp_ill_list,
    686 		    sctp_ill);
    687 	}
    688 
    689 	switch (op) {
    690 	case SCTP_ILL_INSERT:
    691 		if (sctp_ill != NULL) {
    692 			/* Unmark it if it is condemned */
    693 			if (sctp_ill->sctp_ill_state == SCTP_ILLS_CONDEMNED)
    694 				sctp_ill->sctp_ill_state = 0;
    695 			rw_exit(&sctps->sctps_g_ills_lock);
    696 			return;
    697 		}
    698 		sctp_ill = kmem_zalloc(sizeof (sctp_ill_t), KM_NOSLEEP);
    699 		/* Need to re-try? */
    700 		if (sctp_ill == NULL) {
    701 			cmn_err(CE_WARN, "sctp_update_ill: error adding "
    702 			    "ILL %p to SCTP's ILL list", (void *)ill);
    703 			rw_exit(&sctps->sctps_g_ills_lock);
    704 			return;
    705 		}
    706 		sctp_ill->sctp_ill_name = kmem_zalloc(ill->ill_name_length,
    707 		    KM_NOSLEEP);
    708 		if (sctp_ill->sctp_ill_name == NULL) {
    709 			cmn_err(CE_WARN, "sctp_update_ill: error adding "
    710 			    "ILL %p to SCTP's ILL list", (void *)ill);
    711 			kmem_free(sctp_ill, sizeof (sctp_ill_t));
    712 			rw_exit(&sctps->sctps_g_ills_lock);
    713 			return;
    714 		}
    715 		bcopy(ill->ill_name, sctp_ill->sctp_ill_name,
    716 		    ill->ill_name_length);
    717 		sctp_ill->sctp_ill_name_length = ill->ill_name_length;
    718 		sctp_ill->sctp_ill_index = SCTP_ILL_TO_PHYINDEX(ill);
    719 		sctp_ill->sctp_ill_flags = ill->ill_phyint->phyint_flags;
    720 		sctp_ill->sctp_ill_netstack = ns;	/* No netstack_hold */
    721 		sctp_ill->sctp_ill_isv6 = ill->ill_isv6;
    722 		list_insert_tail(&sctps->sctps_g_ills[index].sctp_ill_list,
    723 		    (void *)sctp_ill);
    724 		sctps->sctps_g_ills[index].ill_count++;
    725 		sctps->sctps_ills_count++;
    726 
    727 		break;
    728 
    729 	case SCTP_ILL_REMOVE:
    730 
    731 		if (sctp_ill == NULL) {
    732 			rw_exit(&sctps->sctps_g_ills_lock);
    733 			return;
    734 		}
    735 		if (sctp_ill->sctp_ill_ipifcnt == 0) {
    736 			list_remove(&sctps->sctps_g_ills[index].sctp_ill_list,
    737 			    (void *)sctp_ill);
    738 			sctps->sctps_g_ills[index].ill_count--;
    739 			sctps->sctps_ills_count--;
    740 			kmem_free(sctp_ill->sctp_ill_name,
    741 			    ill->ill_name_length);
    742 			kmem_free(sctp_ill, sizeof (sctp_ill_t));
    743 		} else {
    744 			sctp_ill->sctp_ill_state = SCTP_ILLS_CONDEMNED;
    745 		}
    746 
    747 		break;
    748 	}
    749 	rw_exit(&sctps->sctps_g_ills_lock);
    750 }
    751 
    752 /*
    753  * The ILL's index is being changed, just remove it from the old list,
    754  * change the SCTP ILL's index and re-insert using the new index.
    755  */
    756 void
    757 sctp_ill_reindex(ill_t *ill, uint_t orig_ill_index)
    758 {
    759 	sctp_ill_t	*sctp_ill = NULL;
    760 	sctp_ill_t	*nxt_sill;
    761 	uint_t		indx;
    762 	uint_t		nindx;
    763 	boolean_t	once = B_FALSE;
    764 	netstack_t	*ns = ill->ill_ipst->ips_netstack;
    765 	sctp_stack_t	*sctps = ns->netstack_sctp;
    766 
    767 	rw_enter(&sctps->sctps_g_ills_lock, RW_WRITER);
    768 
    769 	indx = SCTP_ILL_HASH_FN(orig_ill_index);
    770 	nindx = SCTP_ILL_HASH_FN(SCTP_ILL_TO_PHYINDEX(ill));
    771 	sctp_ill = list_head(&sctps->sctps_g_ills[indx].sctp_ill_list);
    772 	while (sctp_ill != NULL) {
    773 		nxt_sill = list_next(&sctps->sctps_g_ills[indx].sctp_ill_list,
    774 		    sctp_ill);
    775 		if (sctp_ill->sctp_ill_index == orig_ill_index) {
    776 			sctp_ill->sctp_ill_index = SCTP_ILL_TO_PHYINDEX(ill);
    777 			/*
    778 			 * if the new index hashes to the same value, all's
    779 			 * done.
    780 			 */
    781 			if (nindx != indx) {
    782 				list_remove(
    783 				    &sctps->sctps_g_ills[indx].sctp_ill_list,
    784 				    (void *)sctp_ill);
    785 				sctps->sctps_g_ills[indx].ill_count--;
    786 				list_insert_tail(
    787 				    &sctps->sctps_g_ills[nindx].sctp_ill_list,
    788 				    (void *)sctp_ill);
    789 				sctps->sctps_g_ills[nindx].ill_count++;
    790 			}
    791 			if (once)
    792 				break;
    793 			/* We might have one for v4 and for v6 */
    794 			once = B_TRUE;
    795 		}
    796 		sctp_ill = nxt_sill;
    797 	}
    798 	rw_exit(&sctps->sctps_g_ills_lock);
    799 }
    800 
    801 /* move ipif from f_ill to t_ill */
    802 void
    803 sctp_move_ipif(ipif_t *ipif, ill_t *f_ill, ill_t *t_ill)
    804 {
    805 	sctp_ill_t	*fsctp_ill = NULL;
    806 	sctp_ill_t	*tsctp_ill = NULL;
    807 	sctp_ipif_t	*sctp_ipif;
    808 	uint_t		hindex;
    809 	int		i;
    810 	netstack_t	*ns = ipif->ipif_ill->ill_ipst->ips_netstack;
    811 	sctp_stack_t	*sctps = ns->netstack_sctp;
    812 
    813 	rw_enter(&sctps->sctps_g_ills_lock, RW_READER);
    814 	rw_enter(&sctps->sctps_g_ipifs_lock, RW_READER);
    815 
    816 	hindex = SCTP_ILL_HASH_FN(SCTP_ILL_TO_PHYINDEX(f_ill));
    817 	fsctp_ill = list_head(&sctps->sctps_g_ills[hindex].sctp_ill_list);
    818 	for (i = 0; i < sctps->sctps_g_ills[hindex].ill_count; i++) {
    819 		if (fsctp_ill->sctp_ill_index == SCTP_ILL_TO_PHYINDEX(f_ill) &&
    820 		    fsctp_ill->sctp_ill_isv6 == f_ill->ill_isv6) {
    821 			break;
    822 		}
    823 		fsctp_ill = list_next(
    824 		    &sctps->sctps_g_ills[hindex].sctp_ill_list, fsctp_ill);
    825 	}
    826 
    827 	hindex = SCTP_ILL_HASH_FN(SCTP_ILL_TO_PHYINDEX(t_ill));
    828 	tsctp_ill = list_head(&sctps->sctps_g_ills[hindex].sctp_ill_list);
    829 	for (i = 0; i < sctps->sctps_g_ills[hindex].ill_count; i++) {
    830 		if (tsctp_ill->sctp_ill_index == SCTP_ILL_TO_PHYINDEX(t_ill) &&
    831 		    tsctp_ill->sctp_ill_isv6 == t_ill->ill_isv6) {
    832 			break;
    833 		}
    834 		tsctp_ill = list_next(
    835 		    &sctps->sctps_g_ills[hindex].sctp_ill_list, tsctp_ill);
    836 	}
    837 
    838 	hindex = SCTP_IPIF_ADDR_HASH(ipif->ipif_v6lcl_addr,
    839 	    ipif->ipif_ill->ill_isv6);
    840 	sctp_ipif = list_head(&sctps->sctps_g_ipifs[hindex].sctp_ipif_list);
    841 	for (i = 0; i < sctps->sctps_g_ipifs[hindex].ipif_count; i++) {
    842 		if (sctp_ipif->sctp_ipif_id == ipif->ipif_seqid)
    843 			break;
    844 		sctp_ipif = list_next(
    845 		    &sctps->sctps_g_ipifs[hindex].sctp_ipif_list, sctp_ipif);
    846 	}
    847 	/* Should be an ASSERT? */
    848 	if (fsctp_ill == NULL || tsctp_ill == NULL || sctp_ipif == NULL) {
    849 		ip1dbg(("sctp_move_ipif: error moving ipif %p from %p to %p\n",
    850 		    (void *)ipif, (void *)f_ill, (void *)t_ill));
    851 		rw_exit(&sctps->sctps_g_ipifs_lock);
    852 		rw_exit(&sctps->sctps_g_ills_lock);
    853 		return;
    854 	}
    855 	rw_enter(&sctp_ipif->sctp_ipif_lock, RW_WRITER);
    856 	ASSERT(sctp_ipif->sctp_ipif_ill == fsctp_ill);
    857 	sctp_ipif->sctp_ipif_ill = tsctp_ill;
    858 	rw_exit(&sctp_ipif->sctp_ipif_lock);
    859 	(void) atomic_add_32_nv(&fsctp_ill->sctp_ill_ipifcnt, -1);
    860 	atomic_add_32(&tsctp_ill->sctp_ill_ipifcnt, 1);
    861 	rw_exit(&sctps->sctps_g_ipifs_lock);
    862 	rw_exit(&sctps->sctps_g_ills_lock);
    863 }
    864 
    865 /*
    866  * Walk the list of SCTPs and find each that has oipif in it's saddr list, and
    867  * if so replace it with nipif.
    868  */
    869 void
    870 sctp_update_saddrs(sctp_ipif_t *oipif, sctp_ipif_t *nipif, int idx,
    871     sctp_stack_t *sctps)
    872 {
    873 	sctp_t			*sctp;
    874 	sctp_t			*sctp_prev = NULL;
    875 	sctp_saddr_ipif_t	*sobj;
    876 	int			count;
    877 
    878 	mutex_enter(&sctps->sctps_g_lock);
    879 	sctp = list_head(&sctps->sctps_g_list);
    880 	while (sctp != NULL && oipif->sctp_ipif_refcnt > 0) {
    881 		mutex_enter(&sctp->sctp_reflock);
    882 		if (sctp->sctp_condemned ||
    883 		    sctp->sctp_saddrs[idx].ipif_count <= 0) {
    884 			mutex_exit(&sctp->sctp_reflock);
    885 			sctp = list_next(&sctps->sctps_g_list, sctp);
    886 			continue;
    887 		}
    888 		sctp->sctp_refcnt++;
    889 		mutex_exit(&sctp->sctp_reflock);
    890 		mutex_exit(&sctps->sctps_g_lock);
    891 		if (sctp_prev != NULL)
    892 			SCTP_REFRELE(sctp_prev);
    893 
    894 		RUN_SCTP(sctp);
    895 		sobj = list_head(&sctp->sctp_saddrs[idx].sctp_ipif_list);
    896 		for (count = 0; count <
    897 		    sctp->sctp_saddrs[idx].ipif_count; count++) {
    898 			if (sobj->saddr_ipifp == oipif) {
    899 				SCTP_IPIF_REFHOLD(nipif);
    900 				sobj->saddr_ipifp = nipif;
    901 				ASSERT(oipif->sctp_ipif_refcnt > 0);
    902 				/* We have the writer lock */
    903 				oipif->sctp_ipif_refcnt--;
    904 				/*
    905 				 * Can't have more than one referring
    906 				 * to the same sctp_ipif.
    907 				 */
    908 				break;
    909 			}
    910 			sobj = list_next(&sctp->sctp_saddrs[idx].sctp_ipif_list,
    911 			    sobj);
    912 		}
    913 		WAKE_SCTP(sctp);
    914 		sctp_prev = sctp;
    915 		mutex_enter(&sctps->sctps_g_lock);
    916 		sctp = list_next(&sctps->sctps_g_list, sctp);
    917 	}
    918 	mutex_exit(&sctps->sctps_g_lock);
    919 	if (sctp_prev != NULL)
    920 		SCTP_REFRELE(sctp_prev);
    921 }
    922 
    923 /*
    924  * Given an ipif, walk the hash list in the global ipif table and for
    925  * any other SCTP ipif with the same address and non-zero reference, walk
    926  * the SCTP list and update the saddr list, if required, to point to the
    927  * new SCTP ipif. If it is a loopback interface, then there could be
    928  * multiple interfaces with 127.0.0.1 if there are zones configured, so
    929  * check the zoneid in addition to the address.
    930  */
    931 void
    932 sctp_chk_and_updt_saddr(int hindex, sctp_ipif_t *ipif, sctp_stack_t *sctps)
    933 {
    934 	int		cnt;
    935 	sctp_ipif_t	*sipif;
    936 
    937 	ASSERT(sctps->sctps_g_ipifs[hindex].ipif_count > 0);
    938 	ASSERT(ipif->sctp_ipif_state == SCTP_IPIFS_UP);
    939 
    940 	sipif = list_head(&sctps->sctps_g_ipifs[hindex].sctp_ipif_list);
    941 	for (cnt = 0; cnt < sctps->sctps_g_ipifs[hindex].ipif_count; cnt++) {
    942 		rw_enter(&sipif->sctp_ipif_lock, RW_WRITER);
    943 		if (sipif->sctp_ipif_id != ipif->sctp_ipif_id &&
    944 		    IN6_ARE_ADDR_EQUAL(&sipif->sctp_ipif_saddr,
    945 		    &ipif->sctp_ipif_saddr) && sipif->sctp_ipif_refcnt > 0 &&
    946 		    (!SCTP_IS_IPIF_LOOPBACK(ipif) || ipif->sctp_ipif_zoneid ==
    947 		    sipif->sctp_ipif_zoneid)) {
    948 			/*
    949 			 * There can only be one address up at any time
    950 			 * and we are here because ipif has been brought
    951 			 * up.
    952 			 */
    953 			ASSERT(sipif->sctp_ipif_state != SCTP_IPIFS_UP);
    954 			/*
    955 			 * Someone has a reference to this we need to update to
    956 			 * point to the new sipif.
    957 			 */
    958 			sctp_update_saddrs(sipif, ipif, hindex, sctps);
    959 		}
    960 		rw_exit(&sipif->sctp_ipif_lock);
    961 		sipif = list_next(&sctps->sctps_g_ipifs[hindex].sctp_ipif_list,
    962 		    sipif);
    963 	}
    964 }
    965 
    966 /*
    967  * Insert a new SCTP ipif using 'ipif'. v6addr is the address that existed
    968  * prior to the current address in 'ipif'. Only when an existing address
    969  * is changed on an IPIF, will v6addr be specified. If the IPIF already
    970  * exists in the global SCTP ipif table, then we either removed it, if
    971  * it doesn't have any existing reference, or mark it condemned otherwise.
    972  * If an address is being brought up (IPIF_UP), then we need to scan
    973  * the SCTP list to check if there is any SCTP that points to the *same*
    974  * address on a different SCTP ipif and update in that case.
    975  */
    976 void
    977 sctp_update_ipif_addr(ipif_t *ipif, in6_addr_t v6addr)
    978 {
    979 	ill_t		*ill = ipif->ipif_ill;
    980 	int		i;
    981 	sctp_ill_t	*sctp_ill;
    982 	sctp_ill_t	*osctp_ill;
    983 	sctp_ipif_t	*sctp_ipif = NULL;
    984 	sctp_ipif_t	*osctp_ipif = NULL;
    985 	uint_t		ill_index;
    986 	int		hindex;
    987 	sctp_stack_t	*sctps;
    988 
    989 	sctps = ipif->ipif_ill->ill_ipst->ips_netstack->netstack_sctp;
    990 
    991 	/* Index for new address */
    992 	hindex = SCTP_IPIF_ADDR_HASH(ipif->ipif_v6lcl_addr, ill->ill_isv6);
    993 
    994 	/*
    995 	 * The address on this IPIF is changing, we need to look for
    996 	 * this old address and mark it condemned, before creating
    997 	 * one for the new address.
    998 	 */
    999 	osctp_ipif = sctp_lookup_ipif_addr(&v6addr, B_FALSE,
   1000 	    ipif->ipif_zoneid, B_TRUE, SCTP_ILL_TO_PHYINDEX(ill),
   1001 	    ipif->ipif_seqid, B_FALSE, sctps);
   1002 
   1003 	rw_enter(&sctps->sctps_g_ills_lock, RW_READER);
   1004 	rw_enter(&sctps->sctps_g_ipifs_lock, RW_WRITER);
   1005 
   1006 	ill_index = SCTP_ILL_HASH_FN(SCTP_ILL_TO_PHYINDEX(ill));
   1007 	sctp_ill = list_head(&sctps->sctps_g_ills[ill_index].sctp_ill_list);
   1008 	for (i = 0; i < sctps->sctps_g_ills[ill_index].ill_count; i++) {
   1009 		if (sctp_ill->sctp_ill_index == SCTP_ILL_TO_PHYINDEX(ill) &&
   1010 		    sctp_ill->sctp_ill_isv6 == ill->ill_isv6) {
   1011 			break;
   1012 		}
   1013 		sctp_ill = list_next(
   1014 		    &sctps->sctps_g_ills[ill_index].sctp_ill_list, sctp_ill);
   1015 	}
   1016 
   1017 	if (sctp_ill == NULL) {
   1018 		ip1dbg(("sctp_update_ipif_addr: ill not found ..\n"));
   1019 		rw_exit(&sctps->sctps_g_ipifs_lock);
   1020 		rw_exit(&sctps->sctps_g_ills_lock);
   1021 		return;
   1022 	}
   1023 
   1024 	if (osctp_ipif != NULL) {
   1025 
   1026 		/* The address is the same? */
   1027 		if (IN6_ARE_ADDR_EQUAL(&ipif->ipif_v6lcl_addr, &v6addr)) {
   1028 			boolean_t	chk_n_updt = B_FALSE;
   1029 
   1030 			rw_downgrade(&sctps->sctps_g_ipifs_lock);
   1031 			rw_enter(&osctp_ipif->sctp_ipif_lock, RW_WRITER);
   1032 			if (ipif->ipif_flags & IPIF_UP &&
   1033 			    osctp_ipif->sctp_ipif_state != SCTP_IPIFS_UP) {
   1034 				osctp_ipif->sctp_ipif_state = SCTP_IPIFS_UP;
   1035 				chk_n_updt = B_TRUE;
   1036 			} else {
   1037 				osctp_ipif->sctp_ipif_state = SCTP_IPIFS_DOWN;
   1038 			}
   1039 			osctp_ipif->sctp_ipif_flags = ipif->ipif_flags;
   1040 			rw_exit(&osctp_ipif->sctp_ipif_lock);
   1041 			if (chk_n_updt) {
   1042 				sctp_chk_and_updt_saddr(hindex, osctp_ipif,
   1043 				    sctps);
   1044 			}
   1045 			rw_exit(&sctps->sctps_g_ipifs_lock);
   1046 			rw_exit(&sctps->sctps_g_ills_lock);
   1047 			return;
   1048 		}
   1049 		/*
   1050 		 * We are effectively removing this address from the ILL.
   1051 		 */
   1052 		if (osctp_ipif->sctp_ipif_refcnt != 0) {
   1053 			osctp_ipif->sctp_ipif_state = SCTP_IPIFS_CONDEMNED;
   1054 		} else {
   1055 			list_t		*ipif_list;
   1056 			int		ohindex;
   1057 
   1058 			osctp_ill = osctp_ipif->sctp_ipif_ill;
   1059 			/* hash index for the old one */
   1060 			ohindex = SCTP_IPIF_ADDR_HASH(
   1061 			    osctp_ipif->sctp_ipif_saddr,
   1062 			    osctp_ipif->sctp_ipif_isv6);
   1063 
   1064 			ipif_list =
   1065 			    &sctps->sctps_g_ipifs[ohindex].sctp_ipif_list;
   1066 
   1067 			list_remove(ipif_list, (void *)osctp_ipif);
   1068 			sctps->sctps_g_ipifs[ohindex].ipif_count--;
   1069 			sctps->sctps_g_ipifs_count--;
   1070 			rw_destroy(&osctp_ipif->sctp_ipif_lock);
   1071 			kmem_free(osctp_ipif, sizeof (sctp_ipif_t));
   1072 			(void) atomic_add_32_nv(&osctp_ill->sctp_ill_ipifcnt,
   1073 			    -1);
   1074 		}
   1075 	}
   1076 
   1077 	sctp_ipif = kmem_zalloc(sizeof (sctp_ipif_t), KM_NOSLEEP);
   1078 	/* Try again? */
   1079 	if (sctp_ipif == NULL) {
   1080 		cmn_err(CE_WARN, "sctp_update_ipif_addr: error adding "
   1081 		    "IPIF %p to SCTP's IPIF list", (void *)ipif);
   1082 		rw_exit(&sctps->sctps_g_ipifs_lock);
   1083 		rw_exit(&sctps->sctps_g_ills_lock);
   1084 		return;
   1085 	}
   1086 	sctps->sctps_g_ipifs_count++;
   1087 	rw_init(&sctp_ipif->sctp_ipif_lock, NULL, RW_DEFAULT, NULL);
   1088 	sctp_ipif->sctp_ipif_saddr = ipif->ipif_v6lcl_addr;
   1089 	sctp_ipif->sctp_ipif_ill = sctp_ill;
   1090 	sctp_ipif->sctp_ipif_isv6 = ill->ill_isv6;
   1091 	sctp_ipif->sctp_ipif_zoneid = ipif->ipif_zoneid;
   1092 	sctp_ipif->sctp_ipif_id = ipif->ipif_seqid;
   1093 	if (ipif->ipif_flags & IPIF_UP)
   1094 		sctp_ipif->sctp_ipif_state = SCTP_IPIFS_UP;
   1095 	else
   1096 		sctp_ipif->sctp_ipif_state = SCTP_IPIFS_DOWN;
   1097 	sctp_ipif->sctp_ipif_flags = ipif->ipif_flags;
   1098 	/*
   1099 	 * We add it to the head so that it is quicker to find good/recent
   1100 	 * additions.
   1101 	 */
   1102 	list_insert_head(&sctps->sctps_g_ipifs[hindex].sctp_ipif_list,
   1103 	    (void *)sctp_ipif);
   1104 	sctps->sctps_g_ipifs[hindex].ipif_count++;
   1105 	atomic_add_32(&sctp_ill->sctp_ill_ipifcnt, 1);
   1106 	if (sctp_ipif->sctp_ipif_state == SCTP_IPIFS_UP)
   1107 		sctp_chk_and_updt_saddr(hindex, sctp_ipif, sctps);
   1108 	rw_exit(&sctps->sctps_g_ipifs_lock);
   1109 	rw_exit(&sctps->sctps_g_ills_lock);
   1110 }
   1111 
   1112 /* Insert, Remove,  Mark up or Mark down the ipif */
   1113 void
   1114 sctp_update_ipif(ipif_t *ipif, int op)
   1115 {
   1116 	ill_t		*ill = ipif->ipif_ill;
   1117 	int		i;
   1118 	sctp_ill_t	*sctp_ill;
   1119 	sctp_ipif_t	*sctp_ipif;
   1120 	uint_t		ill_index;
   1121 	uint_t		hindex;
   1122 	netstack_t	*ns = ipif->ipif_ill->ill_ipst->ips_netstack;
   1123 	sctp_stack_t	*sctps = ns->netstack_sctp;
   1124 
   1125 	ip2dbg(("sctp_update_ipif: %s %d\n", ill->ill_name, ipif->ipif_seqid));
   1126 
   1127 	rw_enter(&sctps->sctps_g_ills_lock, RW_READER);
   1128 	rw_enter(&sctps->sctps_g_ipifs_lock, RW_WRITER);
   1129 
   1130 	ill_index = SCTP_ILL_HASH_FN(SCTP_ILL_TO_PHYINDEX(ill));
   1131 	sctp_ill = list_head(&sctps->sctps_g_ills[ill_index].sctp_ill_list);
   1132 	for (i = 0; i < sctps->sctps_g_ills[ill_index].ill_count; i++) {
   1133 		if (sctp_ill->sctp_ill_index == SCTP_ILL_TO_PHYINDEX(ill) &&
   1134 		    sctp_ill->sctp_ill_isv6 == ill->ill_isv6) {
   1135 			break;
   1136 		}
   1137 		sctp_ill = list_next(
   1138 		    &sctps->sctps_g_ills[ill_index].sctp_ill_list, sctp_ill);
   1139 	}
   1140 	if (sctp_ill == NULL) {
   1141 		rw_exit(&sctps->sctps_g_ipifs_lock);
   1142 		rw_exit(&sctps->sctps_g_ills_lock);
   1143 		return;
   1144 	}
   1145 
   1146 	hindex = SCTP_IPIF_ADDR_HASH(ipif->ipif_v6lcl_addr,
   1147 	    ipif->ipif_ill->ill_isv6);
   1148 	sctp_ipif = list_head(&sctps->sctps_g_ipifs[hindex].sctp_ipif_list);
   1149 	for (i = 0; i < sctps->sctps_g_ipifs[hindex].ipif_count; i++) {
   1150 		if (sctp_ipif->sctp_ipif_id == ipif->ipif_seqid) {
   1151 			ASSERT(IN6_ARE_ADDR_EQUAL(&sctp_ipif->sctp_ipif_saddr,
   1152 			    &ipif->ipif_v6lcl_addr));
   1153 			break;
   1154 		}
   1155 		sctp_ipif = list_next(
   1156 		    &sctps->sctps_g_ipifs[hindex].sctp_ipif_list,
   1157 		    sctp_ipif);
   1158 	}
   1159 	if (sctp_ipif == NULL) {
   1160 		ip1dbg(("sctp_update_ipif: null sctp_ipif for %d\n", op));
   1161 		rw_exit(&sctps->sctps_g_ipifs_lock);
   1162 		rw_exit(&sctps->sctps_g_ills_lock);
   1163 		return;
   1164 	}
   1165 	ASSERT(sctp_ill == sctp_ipif->sctp_ipif_ill);
   1166 	switch (op) {
   1167 	case SCTP_IPIF_REMOVE:
   1168 	{
   1169 		list_t		*ipif_list;
   1170 		list_t		*ill_list;
   1171 
   1172 		ill_list = &sctps->sctps_g_ills[ill_index].sctp_ill_list;
   1173 		ipif_list = &sctps->sctps_g_ipifs[hindex].sctp_ipif_list;
   1174 		if (sctp_ipif->sctp_ipif_refcnt != 0) {
   1175 			sctp_ipif->sctp_ipif_state = SCTP_IPIFS_CONDEMNED;
   1176 			rw_exit(&sctps->sctps_g_ipifs_lock);
   1177 			rw_exit(&sctps->sctps_g_ills_lock);
   1178 			return;
   1179 		}
   1180 		list_remove(ipif_list, (void *)sctp_ipif);
   1181 		sctps->sctps_g_ipifs[hindex].ipif_count--;
   1182 		sctps->sctps_g_ipifs_count--;
   1183 		rw_destroy(&sctp_ipif->sctp_ipif_lock);
   1184 		kmem_free(sctp_ipif, sizeof (sctp_ipif_t));
   1185 		(void) atomic_add_32_nv(&sctp_ill->sctp_ill_ipifcnt, -1);
   1186 		if (rw_tryupgrade(&sctps->sctps_g_ills_lock) != 0) {
   1187 			rw_downgrade(&sctps->sctps_g_ipifs_lock);
   1188 			if (sctp_ill->sctp_ill_ipifcnt == 0 &&
   1189 			    sctp_ill->sctp_ill_state == SCTP_ILLS_CONDEMNED) {
   1190 				list_remove(ill_list, (void *)sctp_ill);
   1191 				sctps->sctps_ills_count--;
   1192 				sctps->sctps_g_ills[ill_index].ill_count--;
   1193 				kmem_free(sctp_ill->sctp_ill_name,
   1194 				    sctp_ill->sctp_ill_name_length);
   1195 				kmem_free(sctp_ill, sizeof (sctp_ill_t));
   1196 			}
   1197 		}
   1198 		break;
   1199 	}
   1200 
   1201 	case SCTP_IPIF_UP:
   1202 
   1203 		rw_downgrade(&sctps->sctps_g_ipifs_lock);
   1204 		rw_enter(&sctp_ipif->sctp_ipif_lock, RW_WRITER);
   1205 		sctp_ipif->sctp_ipif_state = SCTP_IPIFS_UP;
   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_zoneid = ipif->ipif_zoneid;
   1218 		sctp_ipif->sctp_ipif_flags = ipif->ipif_flags;
   1219 		rw_exit(&sctp_ipif->sctp_ipif_lock);
   1220 
   1221 		break;
   1222 
   1223 	case SCTP_IPIF_DOWN:
   1224 
   1225 		rw_downgrade(&sctps->sctps_g_ipifs_lock);
   1226 		rw_enter(&sctp_ipif->sctp_ipif_lock, RW_WRITER);
   1227 		sctp_ipif->sctp_ipif_state = SCTP_IPIFS_DOWN;
   1228 		sctp_ipif->sctp_ipif_flags = ipif->ipif_flags;
   1229 		rw_exit(&sctp_ipif->sctp_ipif_lock);
   1230 
   1231 		break;
   1232 	}
   1233 	rw_exit(&sctps->sctps_g_ipifs_lock);
   1234 	rw_exit(&sctps->sctps_g_ills_lock);
   1235 }
   1236 
   1237 /*
   1238  * SCTP source address list manipulaton, locking not used (except for
   1239  * sctp locking by the caller.
   1240  */
   1241 
   1242 /* Remove a specific saddr from the list */
   1243 void
   1244 sctp_del_saddr(sctp_t *sctp, sctp_saddr_ipif_t *sp)
   1245 {
   1246 	if (sctp->sctp_conn_tfp != NULL)
   1247 		mutex_enter(&sctp->sctp_conn_tfp->tf_lock);
   1248 
   1249 	if (sctp->sctp_listen_tfp != NULL)
   1250 		mutex_enter(&sctp->sctp_listen_tfp->tf_lock);
   1251 
   1252 	sctp_ipif_hash_remove(sctp, sp->saddr_ipifp);
   1253 
   1254 	if (sctp->sctp_bound_to_all == 1)
   1255 		sctp->sctp_bound_to_all = 0;
   1256 
   1257 	if (sctp->sctp_conn_tfp != NULL)
   1258 		mutex_exit(&sctp->sctp_conn_tfp->tf_lock);
   1259 
   1260 	if (sctp->sctp_listen_tfp != NULL)
   1261 		mutex_exit(&sctp->sctp_listen_tfp->tf_lock);
   1262 }
   1263 
   1264 /*
   1265  * Delete source address from the existing list. No error checking done here
   1266  * Called with no locks held.
   1267  */
   1268 void
   1269 sctp_del_saddr_list(sctp_t *sctp, const void *addrs, int addcnt,
   1270     boolean_t fanout_locked)
   1271 {
   1272 	struct sockaddr_in	*sin4;
   1273 	struct sockaddr_in6	*sin6;
   1274 	int			cnt;
   1275 	in6_addr_t		addr;
   1276 	sctp_ipif_t		*sctp_ipif;
   1277 	int			ifindex = 0;
   1278 	conn_t			*connp = sctp->sctp_connp;
   1279 
   1280 	ASSERT(sctp->sctp_nsaddrs >= addcnt);
   1281 
   1282 	if (!fanout_locked) {
   1283 		if (sctp->sctp_conn_tfp != NULL)
   1284 			mutex_enter(&sctp->sctp_conn_tfp->tf_lock);
   1285 		if (sctp->sctp_listen_tfp != NULL)
   1286 			mutex_enter(&sctp->sctp_listen_tfp->tf_lock);
   1287 	}
   1288 
   1289 	for (cnt = 0; cnt < addcnt; cnt++) {
   1290 		switch (connp->conn_family) {
   1291 		case AF_INET:
   1292 			sin4 = (struct sockaddr_in *)addrs + cnt;
   1293 			IN6_INADDR_TO_V4MAPPED(&sin4->sin_addr, &addr);
   1294 			break;
   1295 
   1296 		case AF_INET6:
   1297 			sin6 = (struct sockaddr_in6 *)addrs + cnt;
   1298 			addr = sin6->sin6_addr;
   1299 			ifindex = sin6->sin6_scope_id;
   1300 			break;
   1301 		}
   1302 		sctp_ipif = sctp_lookup_ipif_addr(&addr, B_FALSE,
   1303 		    IPCL_ZONEID(connp), !connp->conn_allzones,
   1304 		    ifindex, 0, B_TRUE, sctp->sctp_sctps);
   1305 		ASSERT(sctp_ipif != NULL);
   1306 		sctp_ipif_hash_remove(sctp, sctp_ipif);
   1307 	}
   1308 	if (sctp->sctp_bound_to_all == 1)
   1309 		sctp->sctp_bound_to_all = 0;
   1310 
   1311 	if (!fanout_locked) {
   1312 		if (sctp->sctp_conn_tfp != NULL)
   1313 			mutex_exit(&sctp->sctp_conn_tfp->tf_lock);
   1314 		if (sctp->sctp_listen_tfp != NULL)
   1315 			mutex_exit(&sctp->sctp_listen_tfp->tf_lock);
   1316 	}
   1317 }
   1318 
   1319 /*
   1320  * Given an address get the corresponding entry from the list
   1321  * Called with no locks held.
   1322  */
   1323 sctp_saddr_ipif_t *
   1324 sctp_saddr_lookup(sctp_t *sctp, in6_addr_t *addr, uint_t ifindex)
   1325 {
   1326 	int			cnt;
   1327 	sctp_saddr_ipif_t	*ipif_obj;
   1328 	int			hindex;
   1329 	sctp_ipif_t		*sctp_ipif;
   1330 
   1331 	hindex = SCTP_IPIF_ADDR_HASH(*addr, !IN6_IS_ADDR_V4MAPPED(addr));
   1332 	if (sctp->sctp_saddrs[hindex].ipif_count == 0)
   1333 		return (NULL);
   1334 
   1335 	ipif_obj = list_head(&sctp->sctp_saddrs[hindex].sctp_ipif_list);
   1336 	for (cnt = 0; cnt < sctp->sctp_saddrs[hindex].ipif_count; cnt++) {
   1337 		sctp_ipif = ipif_obj->saddr_ipifp;
   1338 		/*
   1339 		 * Zone check shouldn't be needed.
   1340 		 */
   1341 		if (IN6_ARE_ADDR_EQUAL(addr, &sctp_ipif->sctp_ipif_saddr) &&
   1342 		    (ifindex == 0 ||
   1343 		    ifindex == sctp_ipif->sctp_ipif_ill->sctp_ill_index) &&
   1344 		    SCTP_IPIF_USABLE(sctp_ipif->sctp_ipif_state)) {
   1345 			return (ipif_obj);
   1346 		}
   1347 		ipif_obj = list_next(&sctp->sctp_saddrs[hindex].sctp_ipif_list,
   1348 		    ipif_obj);
   1349 	}
   1350 	return (NULL);
   1351 }
   1352 
   1353 /* Given an address, add it to the source address list */
   1354 int
   1355 sctp_saddr_add_addr(sctp_t *sctp, in6_addr_t *addr, uint_t ifindex)
   1356 {
   1357 	sctp_ipif_t		*sctp_ipif;
   1358 	conn_t			*connp = sctp->sctp_connp;
   1359 
   1360 	sctp_ipif = sctp_lookup_ipif_addr(addr, B_TRUE, IPCL_ZONEID(connp),
   1361 	    !connp->conn_allzones, ifindex, 0, B_TRUE, sctp->sctp_sctps);
   1362 	if (sctp_ipif == NULL)
   1363 		return (EINVAL);
   1364 
   1365 	if (sctp_ipif_hash_insert(sctp, sctp_ipif, KM_NOSLEEP, B_FALSE,
   1366 	    B_FALSE) != 0) {
   1367 		SCTP_IPIF_REFRELE(sctp_ipif);
   1368 		return (EINVAL);
   1369 	}
   1370 	return (0);
   1371 }
   1372 
   1373 /*
   1374  * Remove or mark as dontsrc addresses that are currently not part of the
   1375  * association. One would delete addresses when processing an INIT and
   1376  * mark as dontsrc when processing an INIT-ACK.
   1377  */
   1378 void
   1379 sctp_check_saddr(sctp_t *sctp, int supp_af, boolean_t delete,
   1380     in6_addr_t *no_del_addr)
   1381 {
   1382 	int			i;
   1383 	int			l;
   1384 	sctp_saddr_ipif_t	*obj;
   1385 	int			scanned = 0;
   1386 	int			naddr;
   1387 	int			nsaddr;
   1388 	conn_t			*connp = sctp->sctp_connp;
   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 (connp->conn_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 	conn_t			*connp = sctp->sctp_connp;
   1505 	int			family = connp->conn_family;
   1506 	int			max = *addrcnt;
   1507 	size_t			added = 0;
   1508 	struct sockaddr_in6	*sin6;
   1509 	struct sockaddr_in	*sin4;
   1510 	int			scanned = 0;
   1511 	boolean_t		skip_lback = B_FALSE;
   1512 	ip_xmit_attr_t		*ixa = connp->conn_ixa;
   1513 
   1514 	if (sctp->sctp_nsaddrs == 0)
   1515 		return (EINVAL);
   1516 
   1517 	/*
   1518 	 * Skip loopback addresses for non-loopback assoc., ignore
   1519 	 * this on a clustered node.
   1520 	 */
   1521 	if (sctp->sctp_state >= SCTPS_ESTABLISHED && !sctp->sctp_loopback &&
   1522 	    (cl_sctp_check_addrs == NULL)) {
   1523 		skip_lback = B_TRUE;
   1524 	}
   1525 
   1526 	for (i = 0; i < SCTP_IPIF_HASH; i++) {
   1527 		if (sctp->sctp_saddrs[i].ipif_count == 0)
   1528 			continue;
   1529 		obj = list_head(&sctp->sctp_saddrs[i].sctp_ipif_list);
   1530 		for (l = 0; l < sctp->sctp_saddrs[i].ipif_count; l++) {
   1531 			sctp_ipif_t	*ipif = obj->saddr_ipifp;
   1532 			in6_addr_t	addr = ipif->sctp_ipif_saddr;
   1533 
   1534 			scanned++;
   1535 			if ((ipif->sctp_ipif_state == SCTP_IPIFS_CONDEMNED) ||
   1536 			    SCTP_DONT_SRC(obj) ||
   1537 			    (SCTP_IS_IPIF_LOOPBACK(ipif) && skip_lback)) {
   1538 				if (scanned >= sctp->sctp_nsaddrs)
   1539 					goto done;
   1540 				obj = list_next(&sctp->sctp_saddrs[i].
   1541 				    sctp_ipif_list, obj);
   1542 				continue;
   1543 			}
   1544 			switch (family) {
   1545 			case AF_INET:
   1546 				sin4 = (struct sockaddr_in *)myaddrs + added;
   1547 				sin4->sin_family = AF_INET;
   1548 				sin4->sin_port = connp->conn_lport;
   1549 				IN6_V4MAPPED_TO_INADDR(&addr, &sin4->sin_addr);
   1550 				break;
   1551 
   1552 			case AF_INET6:
   1553 				sin6 = (struct sockaddr_in6 *)myaddrs + added;
   1554 				sin6->sin6_family = AF_INET6;
   1555 				sin6->sin6_port = connp->conn_lport;
   1556 				sin6->sin6_addr = addr;
   1557 				/*
   1558 				 * Note that flowinfo is only returned for
   1559 				 * getpeername just like for TCP and UDP.
   1560 				 */
   1561 				sin6->sin6_flowinfo = 0;
   1562 
   1563 				if (IN6_IS_ADDR_LINKSCOPE(&sin6->sin6_addr) &&
   1564 				    (ixa->ixa_flags & IXAF_SCOPEID_SET))
   1565 					sin6->sin6_scope_id = ixa->ixa_scopeid;
   1566 				else
   1567 					sin6->sin6_scope_id = 0;
   1568 				sin6->__sin6_src_id = 0;
   1569 				break;
   1570 			}
   1571 			added++;
   1572 			if (added >= max || scanned >= sctp->sctp_nsaddrs)
   1573 				goto done;
   1574 			obj = list_next(&sctp->sctp_saddrs[i].sctp_ipif_list,
   1575 			    obj);
   1576 		}
   1577 	}
   1578 done:
   1579 	*addrcnt = added;
   1580 	return (0);
   1581 }
   1582 
   1583 /*
   1584  * Given the supported address family, walk through the source address list
   1585  * and return the total length of the available addresses. If 'p' is not
   1586  * null, construct the parameter list for the addresses in 'p'.
   1587  * 'modify' will only be set when we want the source address list to
   1588  * be modified. The source address list will be modified only when
   1589  * generating an INIT chunk. For generating an INIT-ACK 'modify' will
   1590  * be false since the 'sctp' will be that of the listener.
   1591  */
   1592 size_t
   1593 sctp_saddr_info(sctp_t *sctp, int supp_af, uchar_t *p, boolean_t modify)
   1594 {
   1595 	int			i;
   1596 	int			l;
   1597 	sctp_saddr_ipif_t	*obj;
   1598 	size_t			paramlen = 0;
   1599 	sctp_parm_hdr_t		*hdr;
   1600 	int			scanned = 0;
   1601 	int			naddr;
   1602 	int			nsaddr;
   1603 	boolean_t		del_ll = B_FALSE;
   1604 	boolean_t		del_lb = B_FALSE;
   1605 
   1606 
   1607 	/*
   1608 	 * On a clustered node don't bother changing anything
   1609 	 * on the loopback interface.
   1610 	 */
   1611 	if (modify && !sctp->sctp_loopback && (cl_sctp_check_addrs == NULL))
   1612 		del_lb = B_TRUE;
   1613 
   1614 	if (modify && !sctp->sctp_linklocal)
   1615 		del_ll = B_TRUE;
   1616 
   1617 	nsaddr = sctp->sctp_nsaddrs;
   1618 	for (i = 0; i < SCTP_IPIF_HASH; i++) {
   1619 		if (sctp->sctp_saddrs[i].ipif_count == 0)
   1620 			continue;
   1621 		obj = list_head(&sctp->sctp_saddrs[i].sctp_ipif_list);
   1622 		naddr = sctp->sctp_saddrs[i].ipif_count;
   1623 		for (l = 0; l < naddr; l++) {
   1624 			in6_addr_t	addr;
   1625 			sctp_ipif_t	*ipif;
   1626 			boolean_t	ipif_lb;
   1627 			boolean_t	ipif_ll;
   1628 			boolean_t	unsupp_af;
   1629 
   1630 			ipif = obj->saddr_ipifp;
   1631 			scanned++;
   1632 
   1633 			ipif_lb = SCTP_IS_IPIF_LOOPBACK(ipif);
   1634 			ipif_ll = SCTP_IS_IPIF_LINKLOCAL(ipif);
   1635 			unsupp_af = SCTP_UNSUPP_AF(ipif, supp_af);
   1636 			/*
   1637 			 * We need to either delete or skip loopback/linklocal
   1638 			 * or unsupported addresses, if required.
   1639 			 */
   1640 			if ((ipif_ll && del_ll) || (ipif_lb && del_lb) ||
   1641 			    (unsupp_af && modify)) {
   1642 				if (sctp->sctp_bound_to_all == 1)
   1643 					sctp->sctp_bound_to_all = 0;
   1644 				if (scanned < nsaddr) {
   1645 					obj = list_next(&sctp->sctp_saddrs[i].
   1646 					    sctp_ipif_list, obj);
   1647 					sctp_ipif_hash_remove(sctp, ipif);
   1648 					continue;
   1649 				}
   1650 				sctp_ipif_hash_remove(sctp, ipif);
   1651 				goto next_addr;
   1652 			} else if (ipif_ll || unsupp_af ||
   1653 			    (ipif_lb && (cl_sctp_check_addrs == NULL))) {
   1654 				goto next_addr;
   1655 			}
   1656 
   1657 			if (!SCTP_IPIF_USABLE(ipif->sctp_ipif_state))
   1658 				goto next_addr;
   1659 			if (p != NULL)
   1660 				hdr = (sctp_parm_hdr_t *)(p + paramlen);
   1661 			addr = ipif->sctp_ipif_saddr;
   1662 			if (!ipif->sctp_ipif_isv6) {
   1663 				struct in_addr	*v4;
   1664 
   1665 				if (p != NULL) {
   1666 					hdr->sph_type = htons(PARM_ADDR4);
   1667 					hdr->sph_len = htons(PARM_ADDR4_LEN);
   1668 					v4 = (struct in_addr *)(hdr + 1);
   1669 					IN6_V4MAPPED_TO_INADDR(&addr, v4);
   1670 				}
   1671 				paramlen += PARM_ADDR4_LEN;
   1672 			} else {
   1673 				if (p != NULL) {
   1674 					hdr->sph_type = htons(PARM_ADDR6);
   1675 					hdr->sph_len = htons(PARM_ADDR6_LEN);
   1676 					bcopy(&addr, hdr + 1, sizeof (addr));
   1677 				}
   1678 				paramlen += PARM_ADDR6_LEN;
   1679 			}
   1680 next_addr:
   1681 			if (scanned >= nsaddr)
   1682 				return (paramlen);
   1683 			obj = list_next(&sctp->sctp_saddrs[i].sctp_ipif_list,
   1684 			    obj);
   1685 		}
   1686 	}
   1687 	return (paramlen);
   1688 }
   1689 
   1690 /*
   1691  * This is used on a clustered node to obtain a list of addresses, the list
   1692  * consists of sockaddr_in structs for v4 and sockaddr_in6 for v6. The list
   1693  * is then passed onto the clustering module which sends back the correct
   1694  * list based on the port info. Regardless of the input, i.e INADDR_ANY
   1695  * or specific address(es), we create the list since it could be modified by
   1696  * the clustering module. When given a list of addresses, we simply
   1697  * create the list of sockaddr_in or sockaddr_in6 structs using those
   1698  * addresses. If there is an INADDR_ANY in the input list, or if the
   1699  * input is INADDR_ANY, we create a list of sockaddr_in or sockaddr_in6
   1700  * structs consisting all the addresses in the global interface list
   1701  * except those that are hosted on the loopback interface. We create
   1702  * a list of sockaddr_in[6] structs just so that it can be directly input
   1703  * to sctp_valid_addr_list() once the clustering module has processed it.
   1704  */
   1705 int
   1706 sctp_get_addrlist(sctp_t *sctp, const void *addrs, uint32_t *addrcnt,
   1707     uchar_t **addrlist, int *uspec, size_t *size)
   1708 {
   1709 	int			cnt;
   1710 	int			icnt;
   1711 	sctp_ipif_t		*sctp_ipif;
   1712 	struct sockaddr_in	*s4;
   1713 	struct sockaddr_in6	*s6;
   1714 	uchar_t			*p;
   1715 	int			err = 0;
   1716 	sctp_stack_t		*sctps = sctp->sctp_sctps;
   1717 	conn_t			*connp = sctp->sctp_connp;
   1718 
   1719 	*addrlist = NULL;
   1720 	*size = 0;
   1721 
   1722 	/*
   1723 	 * Create a list of sockaddr_in[6] structs using the input list.
   1724 	 */
   1725 	if (connp->conn_family == AF_INET) {
   1726 		*size = sizeof (struct sockaddr_in) * *addrcnt;
   1727 		*addrlist = kmem_zalloc(*size,  KM_SLEEP);
   1728 		p = *addrlist;
   1729 		for (cnt = 0; cnt < *addrcnt; cnt++) {
   1730 			s4 = (struct sockaddr_in *)addrs + cnt;
   1731 			/*
   1732 			 * We need to create a list of all the available
   1733 			 * addresses if there is an INADDR_ANY. However,
   1734 			 * if we are beyond LISTEN, then this is invalid
   1735 			 * (see sctp_valid_addr_list(). So, we just fail
   1736 			 * it here rather than wait till it fails in
   1737 			 * sctp_valid_addr_list().
   1738 			 */
   1739 			if (s4->sin_addr.s_addr == INADDR_ANY) {
   1740 				kmem_free(*addrlist, *size);
   1741 				*addrlist = NULL;
   1742 				*size = 0;
   1743 				if (sctp->sctp_state > SCTPS_LISTEN) {
   1744 					*addrcnt = 0;
   1745 					return (EINVAL);
   1746 				}
   1747 				if (uspec != NULL)
   1748 					*uspec = 1;
   1749 				goto get_all_addrs;
   1750 			} else {
   1751 				bcopy(s4, p, sizeof (*s4));
   1752 				p += sizeof (*s4);
   1753 			}
   1754 		}
   1755 	} else {
   1756 		*size = sizeof (struct sockaddr_in6) * *addrcnt;
   1757 		*addrlist = kmem_zalloc(*size, KM_SLEEP);
   1758 		p = *addrlist;
   1759 		for (cnt = 0; cnt < *addrcnt; cnt++) {
   1760 			s6 = (struct sockaddr_in6 *)addrs + cnt;
   1761 			/*
   1762 			 * Comments for INADDR_ANY, above, apply here too.
   1763 			 */
   1764 			if (IN6_IS_ADDR_UNSPECIFIED(&s6->sin6_addr)) {
   1765 				kmem_free(*addrlist, *size);
   1766 				*size = 0;
   1767 				*addrlist = NULL;
   1768 				if (sctp->sctp_state > SCTPS_LISTEN) {
   1769 					*addrcnt = 0;
   1770 					return (EINVAL);
   1771 				}
   1772 				if (uspec != NULL)
   1773 					*uspec = 1;
   1774 				goto get_all_addrs;
   1775 			} else {
   1776 				bcopy(addrs, p, sizeof (*s6));
   1777 				p += sizeof (*s6);
   1778 			}
   1779 		}
   1780 	}
   1781 	return (err);
   1782 get_all_addrs:
   1783 
   1784 	/*
   1785 	 * Allocate max possible size. We allocate the max. size here because
   1786 	 * the clustering module could end up adding addresses to the list.
   1787 	 * We allocate upfront so that the clustering module need to bother
   1788 	 * re-sizing the list.
   1789 	 */
   1790 	if (connp->conn_family == AF_INET) {
   1791 		*size = sizeof (struct sockaddr_in) *
   1792 		    sctps->sctps_g_ipifs_count;
   1793 	} else {
   1794 		*size = sizeof (struct sockaddr_in6) *
   1795 		    sctps->sctps_g_ipifs_count;
   1796 	}
   1797 	*addrlist = kmem_zalloc(*size, KM_SLEEP);
   1798 	*addrcnt = 0;
   1799 	p = *addrlist;
   1800 	rw_enter(&sctps->sctps_g_ipifs_lock, RW_READER);
   1801 
   1802 	/*
   1803 	 * Walk through the global interface list and add all addresses,
   1804 	 * except those that are hosted on loopback interfaces.
   1805 	 */
   1806 	for (cnt = 0; cnt <  SCTP_IPIF_HASH; cnt++) {
   1807 		if (sctps->sctps_g_ipifs[cnt].ipif_count == 0)
   1808 			continue;
   1809 		sctp_ipif = list_head(
   1810 		    &sctps->sctps_g_ipifs[cnt].sctp_ipif_list);
   1811 		for (icnt = 0;
   1812 		    icnt < sctps->sctps_g_ipifs[cnt].ipif_count;
   1813 		    icnt++) {
   1814 			in6_addr_t	addr;
   1815 
   1816 			rw_enter(&sctp_ipif->sctp_ipif_lock, RW_READER);
   1817 			addr = sctp_ipif->sctp_ipif_saddr;
   1818 			if (SCTP_IPIF_DISCARD(sctp_ipif->sctp_ipif_flags) ||
   1819 			    !SCTP_IPIF_USABLE(sctp_ipif->sctp_ipif_state) ||
   1820 			    SCTP_IS_IPIF_LOOPBACK(sctp_ipif) ||
   1821 			    SCTP_IS_IPIF_LINKLOCAL(sctp_ipif) ||
   1822 			    !SCTP_IPIF_ZONE_MATCH(sctp, sctp_ipif) ||
   1823 			    (connp->conn_family == AF_INET &&
   1824 			    sctp_ipif->sctp_ipif_isv6) ||
   1825 			    (sctp->sctp_connp->conn_ipv6_v6only &&
   1826 			    !sctp_ipif->sctp_ipif_isv6)) {
   1827 				rw_exit(&sctp_ipif->sctp_ipif_lock);
   1828 				sctp_ipif = list_next(
   1829 				    &sctps->sctps_g_ipifs[cnt].sctp_ipif_list,
   1830 				    sctp_ipif);
   1831 				continue;
   1832 			}
   1833 			rw_exit(&sctp_ipif->sctp_ipif_lock);
   1834 			if (connp->conn_family == AF_INET) {
   1835 				s4 = (struct sockaddr_in *)p;
   1836 				IN6_V4MAPPED_TO_INADDR(&addr, &s4->sin_addr);
   1837 				s4->sin_family = AF_INET;
   1838 				p += sizeof (*s4);
   1839 			} else {
   1840 				s6 = (struct sockaddr_in6 *)p;
   1841 				s6->sin6_addr = addr;
   1842 				s6->sin6_family = AF_INET6;
   1843 				s6->sin6_scope_id =
   1844 				    sctp_ipif->sctp_ipif_ill->sctp_ill_index;
   1845 				p += sizeof (*s6);
   1846 			}
   1847 			(*addrcnt)++;
   1848 			sctp_ipif = list_next(
   1849 			    &sctps->sctps_g_ipifs[cnt].sctp_ipif_list,
   1850 			    sctp_ipif);
   1851 		}
   1852 	}
   1853 	rw_exit(&sctps->sctps_g_ipifs_lock);
   1854 	return (err);
   1855 }
   1856 
   1857 /*
   1858  * Get a list of addresses from the source address list. The  caller is
   1859  * responsible for allocating sufficient buffer for this.
   1860  */
   1861 void
   1862 sctp_get_saddr_list(sctp_t *sctp, uchar_t *p, size_t psize)
   1863 {
   1864 	int			cnt;
   1865 	int			icnt;
   1866 	sctp_saddr_ipif_t	*obj;
   1867 	int			naddr;
   1868 	int			scanned = 0;
   1869 
   1870 	for (cnt = 0; cnt < SCTP_IPIF_HASH; cnt++) {
   1871 		if (sctp->sctp_saddrs[cnt].ipif_count == 0)
   1872 			continue;
   1873 		obj = list_head(&sctp->sctp_saddrs[cnt].sctp_ipif_list);
   1874 		naddr = sctp->sctp_saddrs[cnt].ipif_count;
   1875 		for (icnt = 0; icnt < naddr; icnt++) {
   1876 			sctp_ipif_t	*ipif;
   1877 
   1878 			if (psize < sizeof (ipif->sctp_ipif_saddr))
   1879 				return;
   1880 
   1881 			scanned++;
   1882 			ipif = obj->saddr_ipifp;
   1883 			bcopy(&ipif->sctp_ipif_saddr, p,
   1884 			    sizeof (ipif->sctp_ipif_saddr));
   1885 			p += sizeof (ipif->sctp_ipif_saddr);
   1886 			psize -= sizeof (ipif->sctp_ipif_saddr);
   1887 			if (scanned >= sctp->sctp_nsaddrs)
   1888 				return;
   1889 			obj = list_next(
   1890 			    &sctp->sctp_saddrs[icnt].sctp_ipif_list,
   1891 			    obj);
   1892 		}
   1893 	}
   1894 }
   1895 
   1896 /*
   1897  * Get a list of addresses from the remote address list. The  caller is
   1898  * responsible for allocating sufficient buffer for this.
   1899  */
   1900 void
   1901 sctp_get_faddr_list(sctp_t *sctp, uchar_t *p, size_t psize)
   1902 {
   1903 	sctp_faddr_t	*fp;
   1904 
   1905 	for (fp = sctp->sctp_faddrs; fp != NULL; fp = fp->next) {
   1906 		if (psize < sizeof (fp->faddr))
   1907 			return;
   1908 		bcopy(&fp->faddr, p, sizeof (fp->faddr));
   1909 		p += sizeof (fp->faddr);
   1910 		psize -= sizeof (fp->faddr);
   1911 	}
   1912 }
   1913 
   1914 static void
   1915 sctp_free_ills(sctp_stack_t *sctps)
   1916 {
   1917 	int			i;
   1918 	int			l;
   1919 	sctp_ill_t	*sctp_ill;
   1920 
   1921 	if (sctps->sctps_ills_count == 0)
   1922 		return;
   1923 
   1924 	for (i = 0; i < SCTP_ILL_HASH; i++) {
   1925 		sctp_ill = list_tail(&sctps->sctps_g_ills[i].sctp_ill_list);
   1926 		for (l = 0; l < sctps->sctps_g_ills[i].ill_count; l++) {
   1927 			ASSERT(sctp_ill->sctp_ill_ipifcnt == 0);
   1928 			list_remove(&sctps->sctps_g_ills[i].sctp_ill_list,
   1929 			    sctp_ill);
   1930 			sctps->sctps_ills_count--;
   1931 			kmem_free(sctp_ill->sctp_ill_name,
   1932 			    sctp_ill->sctp_ill_name_length);
   1933 			kmem_free(sctp_ill, sizeof (sctp_ill_t));
   1934 			sctp_ill =
   1935 			    list_tail(&sctps->sctps_g_ills[i].sctp_ill_list);
   1936 		}
   1937 		sctps->sctps_g_ills[i].ill_count = 0;
   1938 	}
   1939 	ASSERT(sctps->sctps_ills_count == 0);
   1940 }
   1941 
   1942 static void
   1943 sctp_free_ipifs(sctp_stack_t *sctps)
   1944 {
   1945 	int			i;
   1946 	int			l;
   1947 	sctp_ipif_t	*sctp_ipif;
   1948 	sctp_ill_t	*sctp_ill;
   1949 
   1950 	if (sctps->sctps_g_ipifs_count == 0)
   1951 		return;
   1952 
   1953 	for (i = 0; i < SCTP_IPIF_HASH; i++) {
   1954 		sctp_ipif = list_tail(&sctps->sctps_g_ipifs[i].sctp_ipif_list);
   1955 		for (l = 0; l < sctps->sctps_g_ipifs[i].ipif_count; l++) {
   1956 			sctp_ill = sctp_ipif->sctp_ipif_ill;
   1957 
   1958 			list_remove(&sctps->sctps_g_ipifs[i].sctp_ipif_list,
   1959 			    sctp_ipif);
   1960 			sctps->sctps_g_ipifs_count--;
   1961 			(void) atomic_add_32_nv(&sctp_ill->sctp_ill_ipifcnt,
   1962 			    -1);
   1963 			kmem_free(sctp_ipif, sizeof (sctp_ipif_t));
   1964 			sctp_ipif =
   1965 			    list_tail(&sctps->sctps_g_ipifs[i].sctp_ipif_list);
   1966 		}
   1967 		sctps->sctps_g_ipifs[i].ipif_count = 0;
   1968 	}
   1969 	ASSERT(sctps->sctps_g_ipifs_count == 0);
   1970 }
   1971 
   1972 
   1973 /* Initialize the SCTP ILL list and lock */
   1974 void
   1975 sctp_saddr_init(sctp_stack_t *sctps)
   1976 {
   1977 	int	i;
   1978 
   1979 	sctps->sctps_g_ills = kmem_zalloc(sizeof (sctp_ill_hash_t) *
   1980 	    SCTP_ILL_HASH, KM_SLEEP);
   1981 	sctps->sctps_g_ipifs = kmem_zalloc(sizeof (sctp_ipif_hash_t) *
   1982 	    SCTP_IPIF_HASH, KM_SLEEP);
   1983 
   1984 	rw_init(&sctps->sctps_g_ills_lock, NULL, RW_DEFAULT, NULL);
   1985 	rw_init(&sctps->sctps_g_ipifs_lock, NULL, RW_DEFAULT, NULL);
   1986 
   1987 	for (i = 0; i < SCTP_ILL_HASH; i++) {
   1988 		sctps->sctps_g_ills[i].ill_count = 0;
   1989 		list_create(&sctps->sctps_g_ills[i].sctp_ill_list,
   1990 		    sizeof (sctp_ill_t),
   1991 		    offsetof(sctp_ill_t, sctp_ills));
   1992 	}
   1993 	for (i = 0; i < SCTP_IPIF_HASH; i++) {
   1994 		sctps->sctps_g_ipifs[i].ipif_count = 0;
   1995 		list_create(&sctps->sctps_g_ipifs[i].sctp_ipif_list,
   1996 		    sizeof (sctp_ipif_t), offsetof(sctp_ipif_t, sctp_ipifs));
   1997 	}
   1998 }
   1999 
   2000 void
   2001 sctp_saddr_fini(sctp_stack_t *sctps)
   2002 {
   2003 	int	i;
   2004 
   2005 	sctp_free_ipifs(sctps);
   2006 	sctp_free_ills(sctps);
   2007 
   2008 	for (i = 0; i < SCTP_ILL_HASH; i++)
   2009 		list_destroy(&sctps->sctps_g_ills[i].sctp_ill_list);
   2010 	for (i = 0; i < SCTP_IPIF_HASH; i++)
   2011 		list_destroy(&sctps->sctps_g_ipifs[i].sctp_ipif_list);
   2012 
   2013 	ASSERT(sctps->sctps_ills_count == 0 && sctps->sctps_g_ipifs_count == 0);
   2014 	kmem_free(sctps->sctps_g_ills, sizeof (sctp_ill_hash_t) *
   2015 	    SCTP_ILL_HASH);
   2016 	sctps->sctps_g_ills = NULL;
   2017 	kmem_free(sctps->sctps_g_ipifs, sizeof (sctp_ipif_hash_t) *
   2018 	    SCTP_IPIF_HASH);
   2019 	sctps->sctps_g_ipifs = NULL;
   2020 	rw_destroy(&sctps->sctps_g_ills_lock);
   2021 	rw_destroy(&sctps->sctps_g_ipifs_lock);
   2022 }
   2023