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