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