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