xref: /titanic_52/usr/src/uts/common/inet/sctp/sctp_addr.c (revision 734b6a94890be549309b21156f8ed6d4561cac51)
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 2006 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 zoneid, uint_t);
54 static int		sctp_get_all_ipifs(sctp_t *, int);
55 int			sctp_valid_addr_list(sctp_t *, const void *, uint32_t,
56 			    uchar_t *, size_t);
57 sctp_saddr_ipif_t	*sctp_ipif_lookup(sctp_t *, uint_t);
58 static int		sctp_ipif_hash_insert(sctp_t *, sctp_ipif_t *, int,
59 			    boolean_t dontsrc);
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();
77 void			sctp_saddr_fini();
78 
79 #define	SCTP_IPIF_USABLE(sctp_ipif_state)	\
80 	((sctp_ipif_state) == SCTP_IPIFS_UP ||	\
81 	(sctp_ipif_state) ==  SCTP_IPIFS_DOWN)
82 
83 #define	SCTP_IPIF_DISCARD(sctp_ipif_flags)	\
84 	((sctp_ipif_flags) & (IPIF_PRIVATE | IPIF_DEPRECATED))
85 
86 #define	SCTP_IS_IPIF_LOOPBACK(ipif)		\
87 	((ipif)->sctp_ipif_ill->sctp_ill_flags & PHYI_LOOPBACK)
88 
89 #define	SCTP_IS_IPIF_LINKLOCAL(ipif)		\
90 	((ipif)->sctp_ipif_isv6 && 		\
91 	IN6_IS_ADDR_LINKLOCAL(&(ipif)->sctp_ipif_saddr))
92 
93 #define	SCTP_UNSUPP_AF(ipif, supp_af)	\
94 	((!(ipif)->sctp_ipif_isv6 && !((supp_af) & PARM_SUPP_V4)) ||	\
95 	((ipif)->sctp_ipif_isv6 && !((supp_af) & PARM_SUPP_V6)))
96 
97 #define	SCTP_ILL_HASH_FN(index)		((index) % SCTP_ILL_HASH)
98 #define	SCTP_IPIF_HASH_FN(seqid)	((seqid) % SCTP_IPIF_HASH)
99 #define	SCTP_ILL_TO_PHYINDEX(ill)	((ill)->ill_phyint->phyint_ifindex)
100 
101 /* Global list of SCTP ILLs */
102 sctp_ill_hash_t	sctp_g_ills[SCTP_ILL_HASH];
103 uint32_t	sctp_ills_count = 0;
104 
105 /* Global list of SCTP IPIFs */
106 sctp_ipif_hash_t	sctp_g_ipifs[SCTP_IPIF_HASH];
107 uint32_t		sctp_g_ipifs_count = 0;
108 /*
109  *
110  *
111  * SCTP Interface list manipulation functions, locking used.
112  *
113  *
114  */
115 
116 /*
117  * Delete an SCTP IPIF from the list if the refcount goes to 0 and it is
118  * marked as condemned. Also, check if the ILL needs to go away.
119  * Called with no locks held.
120  */
121 static void
122 sctp_ipif_inactive(sctp_ipif_t *sctp_ipif)
123 {
124 	sctp_ill_t	*sctp_ill;
125 	uint_t		ipif_index;
126 	uint_t		ill_index;
127 
128 	rw_enter(&sctp_g_ills_lock, RW_READER);
129 	rw_enter(&sctp_g_ipifs_lock, RW_WRITER);
130 
131 	ipif_index = SCTP_IPIF_HASH_FN(sctp_ipif->sctp_ipif_id);
132 	sctp_ill = sctp_ipif->sctp_ipif_ill;
133 	ASSERT(sctp_ill != NULL);
134 	ill_index = SCTP_ILL_HASH_FN(sctp_ill->sctp_ill_index);
135 	if (sctp_ipif->sctp_ipif_state != SCTP_IPIFS_CONDEMNED ||
136 	    sctp_ipif->sctp_ipif_refcnt != 0) {
137 		rw_exit(&sctp_g_ipifs_lock);
138 		rw_exit(&sctp_g_ills_lock);
139 		return;
140 	}
141 	list_remove(&sctp_g_ipifs[ipif_index].sctp_ipif_list, sctp_ipif);
142 	sctp_g_ipifs[ipif_index].ipif_count--;
143 	sctp_g_ipifs_count--;
144 	rw_destroy(&sctp_ipif->sctp_ipif_lock);
145 	kmem_free(sctp_ipif, sizeof (sctp_ipif_t));
146 
147 	(void) atomic_add_32_nv(&sctp_ill->sctp_ill_ipifcnt, -1);
148 	if (rw_tryupgrade(&sctp_g_ills_lock) != 0) {
149 		rw_downgrade(&sctp_g_ipifs_lock);
150 		if (sctp_ill->sctp_ill_ipifcnt == 0 &&
151 		    sctp_ill->sctp_ill_state == SCTP_ILLS_CONDEMNED) {
152 			list_remove(&sctp_g_ills[ill_index].sctp_ill_list,
153 			    (void *)sctp_ill);
154 			sctp_g_ills[ill_index].ill_count--;
155 			sctp_ills_count--;
156 			kmem_free(sctp_ill->sctp_ill_name,
157 			    sctp_ill->sctp_ill_name_length);
158 			kmem_free(sctp_ill, sizeof (sctp_ill_t));
159 		}
160 	}
161 	rw_exit(&sctp_g_ipifs_lock);
162 	rw_exit(&sctp_g_ills_lock);
163 }
164 
165 /*
166  * Lookup an SCTP IPIF given an IP address. Increments sctp_ipif refcnt.
167  * Called with no locks held.
168  */
169 static sctp_ipif_t *
170 sctp_lookup_ipif_addr(in6_addr_t *addr, boolean_t refhold, zoneid_t zoneid,
171     uint_t ifindex)
172 {
173 	int		i;
174 	int		j;
175 	sctp_ipif_t	*sctp_ipif;
176 
177 	ASSERT(zoneid != ALL_ZONES);
178 	rw_enter(&sctp_g_ipifs_lock, RW_READER);
179 	for (i = 0; i < SCTP_IPIF_HASH; i++) {
180 		if (sctp_g_ipifs[i].ipif_count == 0)
181 			continue;
182 		sctp_ipif = list_head(&sctp_g_ipifs[i].sctp_ipif_list);
183 		for (j = 0; j < sctp_g_ipifs[i].ipif_count; j++) {
184 			rw_enter(&sctp_ipif->sctp_ipif_lock, RW_READER);
185 			if ((zoneid == sctp_ipif->sctp_ipif_zoneid ||
186 			    sctp_ipif->sctp_ipif_zoneid == ALL_ZONES) &&
187 			    SCTP_IPIF_USABLE(sctp_ipif->sctp_ipif_state) &&
188 			    (ifindex == 0 || ifindex ==
189 			    sctp_ipif->sctp_ipif_ill->sctp_ill_index) &&
190 			    IN6_ARE_ADDR_EQUAL(&sctp_ipif->sctp_ipif_saddr,
191 			    addr)) {
192 				rw_exit(&sctp_ipif->sctp_ipif_lock);
193 				if (refhold)
194 					SCTP_IPIF_REFHOLD(sctp_ipif);
195 				rw_exit(&sctp_g_ipifs_lock);
196 				return (sctp_ipif);
197 			}
198 			rw_exit(&sctp_ipif->sctp_ipif_lock);
199 			sctp_ipif = list_next(&sctp_g_ipifs[i].sctp_ipif_list,
200 			    sctp_ipif);
201 		}
202 	}
203 	rw_exit(&sctp_g_ipifs_lock);
204 	return (NULL);
205 }
206 
207 /*
208  * Populate the list with all the SCTP ipifs for a given ipversion.
209  * Increments sctp_ipif refcnt.
210  * Called with no locks held.
211  */
212 static int
213 sctp_get_all_ipifs(sctp_t *sctp, int sleep)
214 {
215 	sctp_ipif_t		*sctp_ipif;
216 	int			i;
217 	int			j;
218 	int			error = 0;
219 
220 	rw_enter(&sctp_g_ipifs_lock, RW_READER);
221 	for (i = 0; i < SCTP_IPIF_HASH; i++) {
222 		if (sctp_g_ipifs[i].ipif_count == 0)
223 			continue;
224 		sctp_ipif = list_head(&sctp_g_ipifs[i].sctp_ipif_list);
225 		for (j = 0; j < sctp_g_ipifs[i].ipif_count; j++) {
226 			rw_enter(&sctp_ipif->sctp_ipif_lock, RW_READER);
227 			if (SCTP_IPIF_DISCARD(sctp_ipif->sctp_ipif_flags) ||
228 			    !SCTP_IPIF_USABLE(sctp_ipif->sctp_ipif_state) ||
229 			    (sctp_ipif->sctp_ipif_zoneid != ALL_ZONES &&
230 			    sctp_ipif->sctp_ipif_zoneid != sctp->sctp_zoneid) ||
231 			    (sctp->sctp_ipversion == IPV4_VERSION &&
232 			    sctp_ipif->sctp_ipif_isv6) ||
233 			    (sctp->sctp_connp->conn_ipv6_v6only &&
234 			    !sctp_ipif->sctp_ipif_isv6)) {
235 				rw_exit(&sctp_ipif->sctp_ipif_lock);
236 				sctp_ipif = list_next(
237 				    &sctp_g_ipifs[i].sctp_ipif_list, sctp_ipif);
238 				continue;
239 			}
240 			rw_exit(&sctp_ipif->sctp_ipif_lock);
241 			SCTP_IPIF_REFHOLD(sctp_ipif);
242 			error = sctp_ipif_hash_insert(sctp, sctp_ipif, sleep,
243 			    B_FALSE);
244 			if (error != 0)
245 				goto free_stuff;
246 			sctp_ipif = list_next(&sctp_g_ipifs[i].sctp_ipif_list,
247 			    sctp_ipif);
248 		}
249 	}
250 	rw_exit(&sctp_g_ipifs_lock);
251 	return (0);
252 free_stuff:
253 	rw_exit(&sctp_g_ipifs_lock);
254 	sctp_free_saddrs(sctp);
255 	return (ENOMEM);
256 }
257 
258 /*
259  * Given a list of address, fills in the list of SCTP ipifs if all the addresses
260  * are present in the SCTP interface list, return number of addresses filled
261  * or error. If the caller wants the list of addresses, it sends a pre-allocated
262  * buffer - list. Currently, this list is only used on a clustered node when
263  * the SCTP is in the listen state (from sctp_bind_add()). When called on a
264  * clustered node, the input is always a list of addresses (even if the
265  * original bind() was to INADDR_ANY).
266  * Called with no locks held.
267  */
268 int
269 sctp_valid_addr_list(sctp_t *sctp, const void *addrs, uint32_t addrcnt,
270     uchar_t *list, size_t lsize)
271 {
272 	struct sockaddr_in	*sin4;
273 	struct sockaddr_in6	*sin6;
274 	struct in_addr		*addr4;
275 	in6_addr_t		addr;
276 	int			cnt;
277 	int			err = 0;
278 	int			saddr_cnt = 0;
279 	sctp_ipif_t		*ipif;
280 	boolean_t		bind_to_all = B_FALSE;
281 	boolean_t		check_addrs = B_FALSE;
282 	boolean_t		check_lport = B_FALSE;
283 	uchar_t			*p = list;
284 
285 	/*
286 	 * Need to check for port and address depending on the state.
287 	 * After a socket is bound, we need to make sure that subsequent
288 	 * bindx() has correct port.  After an association is established,
289 	 * we need to check for changing the bound address to invalid
290 	 * addresses.
291 	 */
292 	if (sctp->sctp_state >= SCTPS_BOUND) {
293 		check_lport = B_TRUE;
294 		if (sctp->sctp_state > SCTPS_LISTEN)
295 			check_addrs = B_TRUE;
296 	}
297 
298 	if (sctp->sctp_conn_tfp != NULL)
299 		mutex_enter(&sctp->sctp_conn_tfp->tf_lock);
300 	if (sctp->sctp_listen_tfp != NULL)
301 		mutex_enter(&sctp->sctp_listen_tfp->tf_lock);
302 	for (cnt = 0; cnt < addrcnt; cnt++) {
303 		boolean_t	lookup_saddr = B_TRUE;
304 		uint_t		ifindex = 0;
305 
306 		switch (sctp->sctp_family) {
307 		case AF_INET:
308 			sin4 = (struct sockaddr_in *)addrs + cnt;
309 			if (sin4->sin_family != AF_INET || (check_lport &&
310 			    sin4->sin_port != sctp->sctp_lport)) {
311 				err = EINVAL;
312 				goto free_ret;
313 			}
314 			addr4 = &sin4->sin_addr;
315 			if (check_addrs &&
316 			    (addr4->s_addr == INADDR_ANY ||
317 			    addr4->s_addr == INADDR_BROADCAST ||
318 			    IN_MULTICAST(addr4->s_addr))) {
319 				err = EINVAL;
320 				goto free_ret;
321 			}
322 			IN6_INADDR_TO_V4MAPPED(addr4, &addr);
323 			if (!check_addrs && addr4->s_addr == INADDR_ANY) {
324 				lookup_saddr = B_FALSE;
325 				bind_to_all = B_TRUE;
326 			}
327 
328 			break;
329 		case AF_INET6:
330 			sin6 = (struct sockaddr_in6 *)addrs + cnt;
331 			if (sin6->sin6_family != AF_INET6 || (check_lport &&
332 			    sin6->sin6_port != sctp->sctp_lport)) {
333 				err = EINVAL;
334 				goto free_ret;
335 			}
336 			addr = sin6->sin6_addr;
337 			/* Contains the interface index */
338 			ifindex = sin6->sin6_scope_id;
339 			if (sctp->sctp_connp->conn_ipv6_v6only &&
340 			    IN6_IS_ADDR_V4MAPPED(&addr)) {
341 				err = EAFNOSUPPORT;
342 				goto free_ret;
343 			}
344 			if (check_addrs &&
345 			    (IN6_IS_ADDR_LINKLOCAL(&addr) ||
346 			    IN6_IS_ADDR_MULTICAST(&addr) ||
347 			    IN6_IS_ADDR_UNSPECIFIED(&addr))) {
348 				err = EINVAL;
349 				goto free_ret;
350 			}
351 			if (!check_addrs && IN6_IS_ADDR_UNSPECIFIED(&addr)) {
352 				lookup_saddr = B_FALSE;
353 				bind_to_all = B_TRUE;
354 			}
355 
356 			break;
357 		default:
358 			err = EAFNOSUPPORT;
359 			goto free_ret;
360 		}
361 		if (lookup_saddr) {
362 			ipif = sctp_lookup_ipif_addr(&addr, B_TRUE,
363 			    sctp->sctp_zoneid, ifindex);
364 			if (ipif == NULL) {
365 				/* Address not in the list */
366 				err = EINVAL;
367 				goto free_ret;
368 			} else if (check_addrs && SCTP_IS_IPIF_LOOPBACK(ipif) &&
369 			    cl_sctp_check_addrs == NULL) {
370 				SCTP_IPIF_REFRELE(ipif);
371 				err = EINVAL;
372 				goto free_ret;
373 			}
374 		}
375 		if (!bind_to_all) {
376 			/*
377 			 * If an address is added after association setup,
378 			 * we need to wait for the peer to send us an ASCONF
379 			 * ACK before we can start using it.
380 			 * saddr_ipif_dontsrc will be reset (to 0) when we
381 			 * get the ASCONF ACK for this address.
382 			 */
383 			err = sctp_ipif_hash_insert(sctp, ipif, KM_SLEEP,
384 			    check_addrs ? B_TRUE : B_FALSE);
385 			if (err != 0) {
386 				SCTP_IPIF_REFRELE(ipif);
387 				if (check_addrs && err == EALREADY)
388 					err = EADDRINUSE;
389 				goto free_ret;
390 			}
391 			saddr_cnt++;
392 			if (lsize >= sizeof (addr)) {
393 				bcopy(&addr, p, sizeof (addr));
394 				p += sizeof (addr);
395 				lsize -= sizeof (addr);
396 			}
397 		}
398 	}
399 	if (bind_to_all) {
400 		/*
401 		 * Free whatever we might have added before encountering
402 		 * inaddr_any.
403 		 */
404 		if (sctp->sctp_nsaddrs > 0) {
405 			sctp_free_saddrs(sctp);
406 			ASSERT(sctp->sctp_nsaddrs == 0);
407 		}
408 		err = sctp_get_all_ipifs(sctp, KM_SLEEP);
409 		if (err != 0)
410 			return (err);
411 		sctp->sctp_bound_to_all = 1;
412 	}
413 	if (sctp->sctp_listen_tfp != NULL)
414 		mutex_exit(&sctp->sctp_listen_tfp->tf_lock);
415 	if (sctp->sctp_conn_tfp != NULL)
416 		mutex_exit(&sctp->sctp_conn_tfp->tf_lock);
417 	return (0);
418 free_ret:
419 	if (saddr_cnt != 0)
420 		sctp_del_saddr_list(sctp, addrs, saddr_cnt, B_TRUE);
421 	if (sctp->sctp_listen_tfp != NULL)
422 		mutex_exit(&sctp->sctp_listen_tfp->tf_lock);
423 	if (sctp->sctp_conn_tfp != NULL)
424 		mutex_exit(&sctp->sctp_conn_tfp->tf_lock);
425 	return (err);
426 }
427 
428 sctp_saddr_ipif_t *
429 sctp_ipif_lookup(sctp_t *sctp, uint_t ipif_index)
430 {
431 	int			cnt;
432 	int			seqid = SCTP_IPIF_HASH_FN(ipif_index);
433 	sctp_saddr_ipif_t	*ipif_obj;
434 
435 	if (sctp->sctp_saddrs[seqid].ipif_count == 0)
436 		return (NULL);
437 
438 	ipif_obj = list_head(&sctp->sctp_saddrs[seqid].sctp_ipif_list);
439 	for (cnt = 0; cnt < sctp->sctp_saddrs[seqid].ipif_count; cnt++) {
440 		if (ipif_obj->saddr_ipifp->sctp_ipif_id == ipif_index)
441 			return (ipif_obj);
442 		ipif_obj = list_next(&sctp->sctp_saddrs[seqid].sctp_ipif_list,
443 		    ipif_obj);
444 	}
445 	return (NULL);
446 }
447 
448 static int
449 sctp_ipif_hash_insert(sctp_t *sctp, sctp_ipif_t *ipif, int sleep,
450     boolean_t dontsrc)
451 {
452 	int			cnt;
453 	sctp_saddr_ipif_t	*ipif_obj;
454 	int			seqid = SCTP_IPIF_HASH_FN(ipif->sctp_ipif_id);
455 
456 	ipif_obj = list_head(&sctp->sctp_saddrs[seqid].sctp_ipif_list);
457 	for (cnt = 0; cnt < sctp->sctp_saddrs[seqid].ipif_count; cnt++) {
458 		if (ipif_obj->saddr_ipifp->sctp_ipif_id == ipif->sctp_ipif_id)
459 			return (EALREADY);
460 		ipif_obj = list_next(&sctp->sctp_saddrs[seqid].sctp_ipif_list,
461 		    ipif_obj);
462 	}
463 	ipif_obj = kmem_zalloc(sizeof (sctp_saddr_ipif_t), sleep);
464 	if (ipif_obj == NULL) {
465 		/* Need to do something */
466 		return (ENOMEM);
467 	}
468 	ipif_obj->saddr_ipifp = ipif;
469 	ipif_obj->saddr_ipif_dontsrc = dontsrc ? 1 : 0;
470 	list_insert_tail(&sctp->sctp_saddrs[seqid].sctp_ipif_list, ipif_obj);
471 	sctp->sctp_saddrs[seqid].ipif_count++;
472 	sctp->sctp_nsaddrs++;
473 	return (0);
474 }
475 
476 static void
477 sctp_ipif_hash_remove(sctp_t *sctp, sctp_ipif_t *ipif)
478 {
479 	int			cnt;
480 	sctp_saddr_ipif_t	*ipif_obj;
481 	int			seqid = SCTP_IPIF_HASH_FN(ipif->sctp_ipif_id);
482 
483 	ipif_obj = list_head(&sctp->sctp_saddrs[seqid].sctp_ipif_list);
484 	for (cnt = 0; cnt < sctp->sctp_saddrs[seqid].ipif_count; cnt++) {
485 		if (ipif_obj->saddr_ipifp->sctp_ipif_id == ipif->sctp_ipif_id) {
486 			list_remove(&sctp->sctp_saddrs[seqid].sctp_ipif_list,
487 			    ipif_obj);
488 			sctp->sctp_nsaddrs--;
489 			sctp->sctp_saddrs[seqid].ipif_count--;
490 			SCTP_IPIF_REFRELE(ipif_obj->saddr_ipifp);
491 			kmem_free(ipif_obj, sizeof (sctp_saddr_ipif_t));
492 			break;
493 		}
494 		ipif_obj = list_next(&sctp->sctp_saddrs[seqid].sctp_ipif_list,
495 		    ipif_obj);
496 	}
497 }
498 
499 static int
500 sctp_compare_ipif_list(sctp_ipif_hash_t *list1, sctp_ipif_hash_t *list2)
501 {
502 	int			i;
503 	int			j;
504 	sctp_saddr_ipif_t	*obj1;
505 	sctp_saddr_ipif_t	*obj2;
506 	int			overlap = 0;
507 
508 	obj1 = list_head(&list1->sctp_ipif_list);
509 	for (i = 0; i < list1->ipif_count; i++) {
510 		obj2 = list_head(&list2->sctp_ipif_list);
511 		for (j = 0; j < list2->ipif_count; j++) {
512 			if (obj1->saddr_ipifp->sctp_ipif_id ==
513 			    obj2->saddr_ipifp->sctp_ipif_id) {
514 				overlap++;
515 				break;
516 			}
517 			obj2 = list_next(&list2->sctp_ipif_list,
518 			    obj2);
519 		}
520 		obj1 = list_next(&list1->sctp_ipif_list, obj1);
521 	}
522 	return (overlap);
523 }
524 
525 int
526 sctp_compare_saddrs(sctp_t *sctp1, sctp_t *sctp2)
527 {
528 	int		i;
529 	int		overlap = 0;
530 
531 	for (i = 0; i < SCTP_IPIF_HASH; i++) {
532 		overlap += sctp_compare_ipif_list(&sctp1->sctp_saddrs[i],
533 		    &sctp2->sctp_saddrs[i]);
534 	}
535 
536 	if (sctp1->sctp_nsaddrs == sctp2->sctp_nsaddrs &&
537 	    overlap == sctp1->sctp_nsaddrs) {
538 		return (SCTP_ADDR_EQUAL);
539 	}
540 
541 	if (overlap == sctp1->sctp_nsaddrs)
542 		return (SCTP_ADDR_SUBSET);
543 
544 	if (overlap > 0)
545 		return (SCTP_ADDR_OVERLAP);
546 
547 	return (SCTP_ADDR_DISJOINT);
548 }
549 
550 static int
551 sctp_copy_ipifs(sctp_ipif_hash_t *list1, sctp_t *sctp2, int sleep)
552 {
553 	int			i;
554 	sctp_saddr_ipif_t	*obj;
555 	int			error = 0;
556 
557 	obj = list_head(&list1->sctp_ipif_list);
558 	for (i = 0; i < list1->ipif_count; i++) {
559 		SCTP_IPIF_REFHOLD(obj->saddr_ipifp);
560 		error = sctp_ipif_hash_insert(sctp2, obj->saddr_ipifp, sleep,
561 		    B_FALSE);
562 		if (error != 0)
563 			return (error);
564 		obj = list_next(&list1->sctp_ipif_list, obj);
565 	}
566 	return (error);
567 }
568 
569 int
570 sctp_dup_saddrs(sctp_t *sctp1, sctp_t *sctp2, int sleep)
571 {
572 	int	error = 0;
573 	int	i;
574 
575 	if (sctp1 == NULL || sctp1->sctp_bound_to_all == 1)
576 		return (sctp_get_all_ipifs(sctp2, sleep));
577 
578 	for (i = 0; i < SCTP_IPIF_HASH; i++) {
579 		if (sctp1->sctp_saddrs[i].ipif_count == 0)
580 			continue;
581 		error = sctp_copy_ipifs(&sctp1->sctp_saddrs[i], sctp2, sleep);
582 		if (error != 0) {
583 			sctp_free_saddrs(sctp2);
584 			return (error);
585 		}
586 	}
587 	return (0);
588 }
589 
590 void
591 sctp_free_saddrs(sctp_t *sctp)
592 {
593 	int			i;
594 	int			l;
595 	sctp_saddr_ipif_t	*obj;
596 
597 	if (sctp->sctp_nsaddrs == 0)
598 		return;
599 	for (i = 0; i < SCTP_IPIF_HASH; i++) {
600 		if (sctp->sctp_saddrs[i].ipif_count == 0)
601 			continue;
602 		obj = list_tail(&sctp->sctp_saddrs[i].sctp_ipif_list);
603 		for (l = 0; l < sctp->sctp_saddrs[i].ipif_count; l++) {
604 			list_remove(&sctp->sctp_saddrs[i].sctp_ipif_list, obj);
605 			SCTP_IPIF_REFRELE(obj->saddr_ipifp);
606 			sctp->sctp_nsaddrs--;
607 			kmem_free(obj, sizeof (sctp_saddr_ipif_t));
608 			obj = list_tail(&sctp->sctp_saddrs[i].sctp_ipif_list);
609 		}
610 		sctp->sctp_saddrs[i].ipif_count = 0;
611 	}
612 	if (sctp->sctp_bound_to_all == 1)
613 		sctp->sctp_bound_to_all = 0;
614 	ASSERT(sctp->sctp_nsaddrs == 0);
615 }
616 
617 /*
618  * Add/Delete the given ILL from the SCTP ILL list. Called with no locks
619  * held.
620  */
621 void
622 sctp_update_ill(ill_t *ill, int op)
623 {
624 	int		i;
625 	sctp_ill_t	*sctp_ill = NULL;
626 	uint_t		index;
627 
628 	ip2dbg(("sctp_update_ill: %s\n", ill->ill_name));
629 
630 	rw_enter(&sctp_g_ills_lock, RW_WRITER);
631 
632 	index = SCTP_ILL_HASH_FN(SCTP_ILL_TO_PHYINDEX(ill));
633 	sctp_ill = list_head(&sctp_g_ills[index].sctp_ill_list);
634 	for (i = 0; i < sctp_g_ills[index].ill_count; i++) {
635 		if (sctp_ill->sctp_ill_index == SCTP_ILL_TO_PHYINDEX(ill))
636 			break;
637 		sctp_ill = list_next(&sctp_g_ills[index].sctp_ill_list,
638 		    sctp_ill);
639 	}
640 
641 	switch (op) {
642 	case SCTP_ILL_INSERT:
643 		if (sctp_ill != NULL) {
644 			/* Unmark it if it is condemned */
645 			if (sctp_ill->sctp_ill_state == SCTP_ILLS_CONDEMNED)
646 				sctp_ill->sctp_ill_state = 0;
647 			rw_exit(&sctp_g_ills_lock);
648 			return;
649 		}
650 		sctp_ill = kmem_zalloc(sizeof (sctp_ill_t), KM_NOSLEEP);
651 		/* Need to re-try? */
652 		if (sctp_ill == NULL) {
653 			ip1dbg(("sctp_ill_insert: mem error..\n"));
654 			rw_exit(&sctp_g_ills_lock);
655 			return;
656 		}
657 		sctp_ill->sctp_ill_name =
658 		    kmem_zalloc(ill->ill_name_length, KM_NOSLEEP);
659 		if (sctp_ill->sctp_ill_name == NULL) {
660 			ip1dbg(("sctp_ill_insert: mem error..\n"));
661 			kmem_free(sctp_ill, sizeof (sctp_ill_t));
662 			rw_exit(&sctp_g_ills_lock);
663 			return;
664 		}
665 		bcopy(ill->ill_name, sctp_ill->sctp_ill_name,
666 		    ill->ill_name_length);
667 		sctp_ill->sctp_ill_name_length = ill->ill_name_length;
668 		sctp_ill->sctp_ill_index = SCTP_ILL_TO_PHYINDEX(ill);
669 		sctp_ill->sctp_ill_flags = ill->ill_phyint->phyint_flags;
670 		list_insert_tail(&sctp_g_ills[index].sctp_ill_list,
671 		    (void *)sctp_ill);
672 		sctp_g_ills[index].ill_count++;
673 		sctp_ills_count++;
674 
675 		break;
676 
677 	case SCTP_ILL_REMOVE:
678 
679 		if (sctp_ill == NULL) {
680 			rw_exit(&sctp_g_ills_lock);
681 			return;
682 		}
683 		if (sctp_ill->sctp_ill_ipifcnt == 0) {
684 			list_remove(&sctp_g_ills[index].sctp_ill_list,
685 			    (void *)sctp_ill);
686 			sctp_g_ills[index].ill_count--;
687 			sctp_ills_count--;
688 			kmem_free(sctp_ill->sctp_ill_name,
689 			    ill->ill_name_length);
690 			kmem_free(sctp_ill, sizeof (sctp_ill_t));
691 		} else {
692 			sctp_ill->sctp_ill_state = SCTP_ILLS_CONDEMNED;
693 		}
694 
695 		break;
696 	}
697 	rw_exit(&sctp_g_ills_lock);
698 }
699 
700 /* move ipif from f_ill to t_ill */
701 void
702 sctp_move_ipif(ipif_t *ipif, ill_t *f_ill, ill_t *t_ill)
703 {
704 	sctp_ill_t	*fsctp_ill = NULL;
705 	sctp_ill_t	*tsctp_ill = NULL;
706 	sctp_ipif_t	*sctp_ipif;
707 	uint_t		index;
708 	int		i;
709 
710 	rw_enter(&sctp_g_ills_lock, RW_READER);
711 	rw_enter(&sctp_g_ipifs_lock, RW_READER);
712 
713 	index = SCTP_ILL_HASH_FN(SCTP_ILL_TO_PHYINDEX(f_ill));
714 	fsctp_ill = list_head(&sctp_g_ills[index].sctp_ill_list);
715 	for (i = 0; i < sctp_g_ills[index].ill_count; i++) {
716 		if (fsctp_ill->sctp_ill_index == SCTP_ILL_TO_PHYINDEX(f_ill))
717 			break;
718 		fsctp_ill = list_next(&sctp_g_ills[index].sctp_ill_list,
719 		    fsctp_ill);
720 	}
721 
722 	index = SCTP_ILL_HASH_FN(SCTP_ILL_TO_PHYINDEX(t_ill));
723 	tsctp_ill = list_head(&sctp_g_ills[index].sctp_ill_list);
724 	for (i = 0; i < sctp_g_ills[index].ill_count; i++) {
725 		if (tsctp_ill->sctp_ill_index == SCTP_ILL_TO_PHYINDEX(t_ill))
726 			break;
727 		tsctp_ill = list_next(&sctp_g_ills[index].sctp_ill_list,
728 		    tsctp_ill);
729 	}
730 
731 	index = SCTP_IPIF_HASH_FN(ipif->ipif_seqid);
732 	sctp_ipif = list_head(&sctp_g_ipifs[index].sctp_ipif_list);
733 	for (i = 0; i < sctp_g_ipifs[index].ipif_count; i++) {
734 		if (sctp_ipif->sctp_ipif_id == ipif->ipif_seqid)
735 			break;
736 		sctp_ipif = list_next(&sctp_g_ipifs[index].sctp_ipif_list,
737 		    sctp_ipif);
738 	}
739 	/* Should be an ASSERT? */
740 	if (fsctp_ill == NULL || tsctp_ill == NULL || sctp_ipif == NULL) {
741 		ip1dbg(("sctp_move_ipif: error moving ipif %p from %p to %p\n",
742 		    (void *)ipif, (void *)f_ill, (void *)t_ill));
743 		rw_exit(&sctp_g_ipifs_lock);
744 		rw_exit(&sctp_g_ills_lock);
745 		return;
746 	}
747 	rw_enter(&sctp_ipif->sctp_ipif_lock, RW_WRITER);
748 	ASSERT(sctp_ipif->sctp_ipif_ill == fsctp_ill);
749 	sctp_ipif->sctp_ipif_ill = tsctp_ill;
750 	rw_exit(&sctp_ipif->sctp_ipif_lock);
751 	(void) atomic_add_32_nv(&fsctp_ill->sctp_ill_ipifcnt, -1);
752 	atomic_add_32(&tsctp_ill->sctp_ill_ipifcnt, 1);
753 	rw_exit(&sctp_g_ipifs_lock);
754 	rw_exit(&sctp_g_ills_lock);
755 }
756 
757 /* Insert, Remove,  Mark up or Mark down the ipif */
758 void
759 sctp_update_ipif(ipif_t *ipif, int op)
760 {
761 	ill_t		*ill = ipif->ipif_ill;
762 	int		i;
763 	sctp_ill_t	*sctp_ill;
764 	sctp_ipif_t	*sctp_ipif;
765 	uint_t		ill_index;
766 	uint_t		ipif_index;
767 
768 	ip2dbg(("sctp_update_ipif: %s %d\n", ill->ill_name, ipif->ipif_seqid));
769 
770 	rw_enter(&sctp_g_ills_lock, RW_READER);
771 	rw_enter(&sctp_g_ipifs_lock, RW_WRITER);
772 
773 	ill_index = SCTP_ILL_HASH_FN(SCTP_ILL_TO_PHYINDEX(ill));
774 	sctp_ill = list_head(&sctp_g_ills[ill_index].sctp_ill_list);
775 	for (i = 0; i < sctp_g_ills[ill_index].ill_count; i++) {
776 		if (sctp_ill->sctp_ill_index == SCTP_ILL_TO_PHYINDEX(ill))
777 			break;
778 		sctp_ill = list_next(&sctp_g_ills[ill_index].sctp_ill_list,
779 		    sctp_ill);
780 	}
781 	if (sctp_ill == NULL) {
782 		rw_exit(&sctp_g_ipifs_lock);
783 		rw_exit(&sctp_g_ills_lock);
784 		return;
785 	}
786 
787 	ipif_index = SCTP_IPIF_HASH_FN(ipif->ipif_seqid);
788 	sctp_ipif = list_head(&sctp_g_ipifs[ipif_index].sctp_ipif_list);
789 	for (i = 0; i < sctp_g_ipifs[ipif_index].ipif_count; i++) {
790 		if (sctp_ipif->sctp_ipif_id == ipif->ipif_seqid)
791 			break;
792 		sctp_ipif = list_next(&sctp_g_ipifs[ipif_index].sctp_ipif_list,
793 		    sctp_ipif);
794 	}
795 	if (op != SCTP_IPIF_INSERT && sctp_ipif == NULL) {
796 		ip1dbg(("sctp_update_ipif: null sctp_ipif for %d\n", op));
797 		rw_exit(&sctp_g_ipifs_lock);
798 		rw_exit(&sctp_g_ills_lock);
799 		return;
800 	}
801 #ifdef	DEBUG
802 	if (sctp_ipif != NULL)
803 		ASSERT(sctp_ill == sctp_ipif->sctp_ipif_ill);
804 #endif
805 	switch (op) {
806 	case SCTP_IPIF_INSERT:
807 		if (sctp_ipif != NULL) {
808 			if (sctp_ipif->sctp_ipif_state == SCTP_IPIFS_CONDEMNED)
809 				sctp_ipif->sctp_ipif_state = SCTP_IPIFS_INVALID;
810 			rw_exit(&sctp_g_ipifs_lock);
811 			rw_exit(&sctp_g_ills_lock);
812 			return;
813 		}
814 		sctp_ipif = kmem_zalloc(sizeof (sctp_ipif_t), KM_NOSLEEP);
815 		/* Try again? */
816 		if (sctp_ipif == NULL) {
817 			ip1dbg(("sctp_ipif_insert: mem failure..\n"));
818 			rw_exit(&sctp_g_ipifs_lock);
819 			rw_exit(&sctp_g_ills_lock);
820 			return;
821 		}
822 		sctp_ipif->sctp_ipif_id = ipif->ipif_seqid;
823 		sctp_ipif->sctp_ipif_ill = sctp_ill;
824 		sctp_ipif->sctp_ipif_state = SCTP_IPIFS_INVALID;
825 		sctp_ipif->sctp_ipif_mtu = ipif->ipif_mtu;
826 		sctp_ipif->sctp_ipif_zoneid = ipif->ipif_zoneid;
827 		sctp_ipif->sctp_ipif_isv6 = ill->ill_isv6;
828 		sctp_ipif->sctp_ipif_flags = ipif->ipif_flags;
829 		rw_init(&sctp_ipif->sctp_ipif_lock, NULL, RW_DEFAULT, NULL);
830 		list_insert_tail(&sctp_g_ipifs[ipif_index].sctp_ipif_list,
831 		    (void *)sctp_ipif);
832 		sctp_g_ipifs[ipif_index].ipif_count++;
833 		sctp_g_ipifs_count++;
834 		atomic_add_32(&sctp_ill->sctp_ill_ipifcnt, 1);
835 
836 		break;
837 
838 	case SCTP_IPIF_REMOVE:
839 	{
840 		list_t		*ipif_list;
841 		list_t		*ill_list;
842 
843 		ill_list = &sctp_g_ills[ill_index].sctp_ill_list;
844 		ipif_list = &sctp_g_ipifs[ipif_index].sctp_ipif_list;
845 		if (sctp_ipif->sctp_ipif_refcnt != 0) {
846 			sctp_ipif->sctp_ipif_state = SCTP_IPIFS_CONDEMNED;
847 			rw_exit(&sctp_g_ipifs_lock);
848 			rw_exit(&sctp_g_ills_lock);
849 			return;
850 		}
851 		list_remove(ipif_list, (void *)sctp_ipif);
852 		sctp_g_ipifs[ipif_index].ipif_count--;
853 		sctp_g_ipifs_count--;
854 		rw_destroy(&sctp_ipif->sctp_ipif_lock);
855 		kmem_free(sctp_ipif, sizeof (sctp_ipif_t));
856 		(void) atomic_add_32_nv(&sctp_ill->sctp_ill_ipifcnt, -1);
857 		if (rw_tryupgrade(&sctp_g_ills_lock) != 0) {
858 			rw_downgrade(&sctp_g_ipifs_lock);
859 			if (sctp_ill->sctp_ill_ipifcnt == 0 &&
860 			    sctp_ill->sctp_ill_state == SCTP_ILLS_CONDEMNED) {
861 				list_remove(ill_list, (void *)sctp_ill);
862 				sctp_ills_count--;
863 				sctp_g_ills[ill_index].ill_count--;
864 				kmem_free(sctp_ill->sctp_ill_name,
865 				    sctp_ill->sctp_ill_name_length);
866 				kmem_free(sctp_ill, sizeof (sctp_ill_t));
867 			}
868 		}
869 		break;
870 	}
871 
872 	case SCTP_IPIF_UP:
873 
874 		rw_downgrade(&sctp_g_ipifs_lock);
875 		rw_enter(&sctp_ipif->sctp_ipif_lock, RW_WRITER);
876 		sctp_ipif->sctp_ipif_state = SCTP_IPIFS_UP;
877 		sctp_ipif->sctp_ipif_saddr = ipif->ipif_v6lcl_addr;
878 		sctp_ipif->sctp_ipif_flags = ipif->ipif_flags;
879 		sctp_ipif->sctp_ipif_mtu = ipif->ipif_mtu;
880 		rw_exit(&sctp_ipif->sctp_ipif_lock);
881 
882 		break;
883 
884 	case SCTP_IPIF_UPDATE:
885 
886 		rw_downgrade(&sctp_g_ipifs_lock);
887 		rw_enter(&sctp_ipif->sctp_ipif_lock, RW_WRITER);
888 		sctp_ipif->sctp_ipif_mtu = ipif->ipif_mtu;
889 		sctp_ipif->sctp_ipif_saddr = ipif->ipif_v6lcl_addr;
890 		sctp_ipif->sctp_ipif_zoneid = ipif->ipif_zoneid;
891 		sctp_ipif->sctp_ipif_flags = ipif->ipif_flags;
892 		rw_exit(&sctp_ipif->sctp_ipif_lock);
893 
894 		break;
895 
896 	case SCTP_IPIF_DOWN:
897 
898 		rw_downgrade(&sctp_g_ipifs_lock);
899 		rw_enter(&sctp_ipif->sctp_ipif_lock, RW_WRITER);
900 		sctp_ipif->sctp_ipif_state = SCTP_IPIFS_DOWN;
901 		rw_exit(&sctp_ipif->sctp_ipif_lock);
902 
903 		break;
904 	}
905 	rw_exit(&sctp_g_ipifs_lock);
906 	rw_exit(&sctp_g_ills_lock);
907 }
908 
909 /*
910  *
911  *
912  * SCTP source address list manipulaton, locking not used (except for
913  * sctp locking by the caller.
914  *
915  *
916  */
917 
918 /* Remove a specific saddr from the list */
919 void
920 sctp_del_saddr(sctp_t *sctp, sctp_saddr_ipif_t *sp)
921 {
922 	if (sctp->sctp_conn_tfp != NULL)
923 		mutex_enter(&sctp->sctp_conn_tfp->tf_lock);
924 
925 	if (sctp->sctp_listen_tfp != NULL)
926 		mutex_enter(&sctp->sctp_listen_tfp->tf_lock);
927 
928 	sctp_ipif_hash_remove(sctp, sp->saddr_ipifp);
929 
930 	if (sctp->sctp_bound_to_all == 1)
931 		sctp->sctp_bound_to_all = 0;
932 
933 	if (sctp->sctp_conn_tfp != NULL)
934 		mutex_exit(&sctp->sctp_conn_tfp->tf_lock);
935 
936 	if (sctp->sctp_listen_tfp != NULL)
937 		mutex_exit(&sctp->sctp_listen_tfp->tf_lock);
938 }
939 
940 /*
941  * Delete source address from the existing list. No error checking done here
942  * Called with no locks held.
943  */
944 void
945 sctp_del_saddr_list(sctp_t *sctp, const void *addrs, int addcnt,
946     boolean_t fanout_locked)
947 {
948 	struct sockaddr_in	*sin4;
949 	struct sockaddr_in6	*sin6;
950 	int			cnt;
951 	in6_addr_t		addr;
952 	sctp_ipif_t		*sctp_ipif;
953 	int			ifindex = 0;
954 
955 	ASSERT(sctp->sctp_nsaddrs >= addcnt);
956 
957 	if (!fanout_locked) {
958 		if (sctp->sctp_conn_tfp != NULL)
959 			mutex_enter(&sctp->sctp_conn_tfp->tf_lock);
960 		if (sctp->sctp_listen_tfp != NULL)
961 			mutex_enter(&sctp->sctp_listen_tfp->tf_lock);
962 	}
963 
964 	for (cnt = 0; cnt < addcnt; cnt++) {
965 		switch (sctp->sctp_family) {
966 		case AF_INET:
967 			sin4 = (struct sockaddr_in *)addrs + cnt;
968 			IN6_INADDR_TO_V4MAPPED(&sin4->sin_addr, &addr);
969 			break;
970 
971 		case AF_INET6:
972 			sin6 = (struct sockaddr_in6 *)addrs + cnt;
973 			addr = sin6->sin6_addr;
974 			ifindex = sin6->sin6_scope_id;
975 			break;
976 		}
977 		sctp_ipif = sctp_lookup_ipif_addr(&addr, B_FALSE,
978 		    sctp->sctp_zoneid, ifindex);
979 		ASSERT(sctp_ipif != NULL);
980 		sctp_ipif_hash_remove(sctp, sctp_ipif);
981 	}
982 	if (sctp->sctp_bound_to_all == 1)
983 		sctp->sctp_bound_to_all = 0;
984 
985 	if (!fanout_locked) {
986 		if (sctp->sctp_conn_tfp != NULL)
987 			mutex_exit(&sctp->sctp_conn_tfp->tf_lock);
988 		if (sctp->sctp_listen_tfp != NULL)
989 			mutex_exit(&sctp->sctp_listen_tfp->tf_lock);
990 	}
991 }
992 
993 /*
994  * Given an address get the corresponding entry from the list
995  * Called with no locks held.
996  */
997 sctp_saddr_ipif_t *
998 sctp_saddr_lookup(sctp_t *sctp, in6_addr_t *addr, uint_t ifindex)
999 {
1000 	sctp_saddr_ipif_t	*saddr_ipifs;
1001 	sctp_ipif_t		*sctp_ipif;
1002 
1003 	sctp_ipif = sctp_lookup_ipif_addr(addr, B_FALSE, sctp->sctp_zoneid,
1004 	    ifindex);
1005 	if (sctp_ipif == NULL)
1006 		return (NULL);
1007 
1008 	saddr_ipifs = sctp_ipif_lookup(sctp, sctp_ipif->sctp_ipif_id);
1009 	return (saddr_ipifs);
1010 }
1011 
1012 /* Given an address, add it to the source address list */
1013 int
1014 sctp_saddr_add_addr(sctp_t *sctp, in6_addr_t *addr, uint_t ifindex)
1015 {
1016 	sctp_ipif_t		*sctp_ipif;
1017 
1018 	sctp_ipif = sctp_lookup_ipif_addr(addr, B_TRUE, sctp->sctp_zoneid,
1019 	    ifindex);
1020 	if (sctp_ipif == NULL)
1021 		return (EINVAL);
1022 
1023 	if (sctp_ipif_hash_insert(sctp, sctp_ipif, KM_NOSLEEP, B_FALSE) != 0) {
1024 		SCTP_IPIF_REFRELE(sctp_ipif);
1025 		return (EINVAL);
1026 	}
1027 	return (0);
1028 }
1029 
1030 /*
1031  * Remove or mark as dontsrc addresses that are currently not part of the
1032  * association. One would delete addresses when processing an INIT and
1033  * mark as dontsrc when processing an INIT-ACK.
1034  */
1035 void
1036 sctp_check_saddr(sctp_t *sctp, int supp_af, boolean_t delete)
1037 {
1038 	int			i;
1039 	int			l;
1040 	sctp_saddr_ipif_t	*obj;
1041 	int			scanned = 0;
1042 	int			naddr;
1043 	int			nsaddr;
1044 
1045 	ASSERT(!sctp->sctp_loopback && !sctp->sctp_linklocal && supp_af != 0);
1046 
1047 	/*
1048 	 * Irregardless of the supported address in the INIT, v4
1049 	 * must be supported.
1050 	 */
1051 	if (sctp->sctp_family == AF_INET)
1052 		supp_af = PARM_SUPP_V4;
1053 
1054 	nsaddr = sctp->sctp_nsaddrs;
1055 	for (i = 0; i < SCTP_IPIF_HASH; i++) {
1056 		if (sctp->sctp_saddrs[i].ipif_count == 0)
1057 			continue;
1058 		obj = list_head(&sctp->sctp_saddrs[i].sctp_ipif_list);
1059 		naddr = sctp->sctp_saddrs[i].ipif_count;
1060 		for (l = 0; l < naddr; l++) {
1061 			sctp_ipif_t	*ipif;
1062 
1063 			ipif = obj->saddr_ipifp;
1064 			scanned++;
1065 
1066 			/*
1067 			 * Delete/mark dontsrc loopback/linklocal addresses and
1068 			 * unsupported address.
1069 			 * On a clustered node, we trust the clustering module
1070 			 * to do the right thing w.r.t loopback addresses, so
1071 			 * we ignore loopback addresses in this check.
1072 			 */
1073 			if ((SCTP_IS_IPIF_LOOPBACK(ipif) &&
1074 			    cl_sctp_check_addrs == NULL) ||
1075 			    SCTP_IS_IPIF_LINKLOCAL(ipif) ||
1076 			    SCTP_UNSUPP_AF(ipif, supp_af)) {
1077 				if (!delete) {
1078 					obj->saddr_ipif_unconfirmed = 1;
1079 					goto next_obj;
1080 				}
1081 				if (sctp->sctp_bound_to_all == 1)
1082 					sctp->sctp_bound_to_all = 0;
1083 				if (scanned < nsaddr) {
1084 					obj = list_next(&sctp->sctp_saddrs[i].
1085 					    sctp_ipif_list, obj);
1086 					sctp_ipif_hash_remove(sctp, ipif);
1087 					continue;
1088 				}
1089 				sctp_ipif_hash_remove(sctp, ipif);
1090 			}
1091 	next_obj:
1092 			if (scanned >= nsaddr)
1093 				return;
1094 			obj = list_next(&sctp->sctp_saddrs[i].sctp_ipif_list,
1095 			    obj);
1096 		}
1097 	}
1098 }
1099 
1100 
1101 /* Get the first valid address from the list. Called with no locks held */
1102 in6_addr_t
1103 sctp_get_valid_addr(sctp_t *sctp, boolean_t isv6)
1104 {
1105 	int			i;
1106 	int			l;
1107 	sctp_saddr_ipif_t	*obj;
1108 	int			scanned = 0;
1109 	in6_addr_t		addr;
1110 
1111 	for (i = 0; i < SCTP_IPIF_HASH; i++) {
1112 		if (sctp->sctp_saddrs[i].ipif_count == 0)
1113 			continue;
1114 		obj = list_head(&sctp->sctp_saddrs[i].sctp_ipif_list);
1115 		for (l = 0; l < sctp->sctp_saddrs[i].ipif_count; l++) {
1116 			sctp_ipif_t	*ipif;
1117 
1118 			ipif = obj->saddr_ipifp;
1119 			if (!SCTP_DONT_SRC(obj) &&
1120 			    ipif->sctp_ipif_isv6 == isv6 &&
1121 			    ipif->sctp_ipif_state == SCTP_IPIFS_UP) {
1122 				return (ipif->sctp_ipif_saddr);
1123 			}
1124 			scanned++;
1125 			if (scanned >= sctp->sctp_nsaddrs)
1126 				goto got_none;
1127 			obj = list_next(&sctp->sctp_saddrs[i].sctp_ipif_list,
1128 			    obj);
1129 		}
1130 	}
1131 got_none:
1132 	/* Need to double check this */
1133 	if (isv6 == B_TRUE)
1134 		addr =  ipv6_all_zeros;
1135 	else
1136 		IN6_IPADDR_TO_V4MAPPED(0, &addr);
1137 
1138 	return (addr);
1139 }
1140 
1141 /*
1142  * Return the list of local addresses of an association.  The parameter
1143  * myaddrs is supposed to be either (struct sockaddr_in *) or (struct
1144  * sockaddr_in6 *) depending on the address family.
1145  */
1146 int
1147 sctp_getmyaddrs(void *conn, void *myaddrs, int *addrcnt)
1148 {
1149 	int			i;
1150 	int			l;
1151 	sctp_saddr_ipif_t	*obj;
1152 	sctp_t			*sctp = (sctp_t *)conn;
1153 	int			family = sctp->sctp_family;
1154 	int			max = *addrcnt;
1155 	size_t			added = 0;
1156 	struct sockaddr_in6	*sin6;
1157 	struct sockaddr_in	*sin4;
1158 	int			scanned = 0;
1159 	boolean_t		skip_lback = B_FALSE;
1160 
1161 	if (sctp->sctp_nsaddrs == 0)
1162 		return (EINVAL);
1163 
1164 	/*
1165 	 * Skip loopback addresses for non-loopback assoc., ignore
1166 	 * this on a clustered node.
1167 	 */
1168 	if (sctp->sctp_state >= SCTPS_ESTABLISHED && !sctp->sctp_loopback &&
1169 	    (cl_sctp_check_addrs == NULL)) {
1170 		skip_lback = B_TRUE;
1171 	}
1172 
1173 	for (i = 0; i < SCTP_IPIF_HASH; i++) {
1174 		if (sctp->sctp_saddrs[i].ipif_count == 0)
1175 			continue;
1176 		obj = list_head(&sctp->sctp_saddrs[i].sctp_ipif_list);
1177 		for (l = 0; l < sctp->sctp_saddrs[i].ipif_count; l++) {
1178 			sctp_ipif_t	*ipif = obj->saddr_ipifp;
1179 			in6_addr_t	addr = ipif->sctp_ipif_saddr;
1180 
1181 			scanned++;
1182 			if ((ipif->sctp_ipif_state == SCTP_IPIFS_CONDEMNED) ||
1183 			    SCTP_DONT_SRC(obj) ||
1184 			    (SCTP_IS_IPIF_LOOPBACK(ipif) && skip_lback)) {
1185 				if (scanned >= sctp->sctp_nsaddrs)
1186 					goto done;
1187 				obj = list_next(&sctp->sctp_saddrs[i].
1188 				    sctp_ipif_list, obj);
1189 				continue;
1190 			}
1191 			switch (family) {
1192 			case AF_INET:
1193 				sin4 = (struct sockaddr_in *)myaddrs + added;
1194 				sin4->sin_family = AF_INET;
1195 				sin4->sin_port = sctp->sctp_lport;
1196 				IN6_V4MAPPED_TO_INADDR(&addr, &sin4->sin_addr);
1197 				break;
1198 
1199 			case AF_INET6:
1200 				sin6 = (struct sockaddr_in6 *)myaddrs + added;
1201 				sin6->sin6_family = AF_INET6;
1202 				sin6->sin6_port = sctp->sctp_lport;
1203 				sin6->sin6_addr = addr;
1204 				break;
1205 			}
1206 			added++;
1207 			if (added >= max || scanned >= sctp->sctp_nsaddrs)
1208 				goto done;
1209 			obj = list_next(&sctp->sctp_saddrs[i].sctp_ipif_list,
1210 			    obj);
1211 		}
1212 	}
1213 done:
1214 	*addrcnt = added;
1215 	return (0);
1216 }
1217 
1218 /*
1219  * Given the supported address family, walk through the source address list
1220  * and return the total length of the available addresses. If 'p' is not
1221  * null, construct the parameter list for the addresses in 'p'.
1222  * 'modify' will only be set when we want the source address list to
1223  * be modified. The source address list will be modified only when
1224  * generating an INIT chunk. For generating an INIT-ACK 'modify' will
1225  * be false since the 'sctp' will be that of the listener.
1226  */
1227 size_t
1228 sctp_saddr_info(sctp_t *sctp, int supp_af, uchar_t *p, boolean_t modify)
1229 {
1230 	int			i;
1231 	int			l;
1232 	sctp_saddr_ipif_t	*obj;
1233 	size_t			paramlen = 0;
1234 	sctp_parm_hdr_t		*hdr;
1235 	int			scanned = 0;
1236 	int			naddr;
1237 	int			nsaddr;
1238 	boolean_t		del_ll = B_FALSE;
1239 	boolean_t		del_lb = B_FALSE;
1240 
1241 
1242 	/*
1243 	 * On a clustered node don't bother changing anything
1244 	 * on the loopback interface.
1245 	 */
1246 	if (modify && !sctp->sctp_loopback && (cl_sctp_check_addrs == NULL))
1247 		del_lb = B_TRUE;
1248 
1249 	if (modify && !sctp->sctp_linklocal)
1250 		del_ll = B_TRUE;
1251 
1252 	nsaddr = sctp->sctp_nsaddrs;
1253 	for (i = 0; i < SCTP_IPIF_HASH; i++) {
1254 		if (sctp->sctp_saddrs[i].ipif_count == 0)
1255 			continue;
1256 		obj = list_head(&sctp->sctp_saddrs[i].sctp_ipif_list);
1257 		naddr = sctp->sctp_saddrs[i].ipif_count;
1258 		for (l = 0; l < naddr; l++) {
1259 			in6_addr_t	addr;
1260 			sctp_ipif_t	*ipif;
1261 			boolean_t	ipif_lb;
1262 			boolean_t	ipif_ll;
1263 			boolean_t	unsupp_af;
1264 
1265 			ipif = obj->saddr_ipifp;
1266 			scanned++;
1267 
1268 			ipif_lb = SCTP_IS_IPIF_LOOPBACK(ipif);
1269 			ipif_ll = SCTP_IS_IPIF_LINKLOCAL(ipif);
1270 			unsupp_af = SCTP_UNSUPP_AF(ipif, supp_af);
1271 			/*
1272 			 * We need to either delete or skip loopback/linklocal
1273 			 * or unsupported addresses, if required.
1274 			 */
1275 			if ((ipif_ll && del_ll) || (ipif_lb && del_lb) ||
1276 			    (unsupp_af && modify)) {
1277 				if (sctp->sctp_bound_to_all == 1)
1278 					sctp->sctp_bound_to_all = 0;
1279 				if (scanned < nsaddr) {
1280 					obj = list_next(&sctp->sctp_saddrs[i].
1281 					    sctp_ipif_list, obj);
1282 					sctp_ipif_hash_remove(sctp, ipif);
1283 					continue;
1284 				}
1285 				sctp_ipif_hash_remove(sctp, ipif);
1286 				goto next_addr;
1287 			} else if (ipif_ll || unsupp_af ||
1288 			    (ipif_lb && (cl_sctp_check_addrs == NULL))) {
1289 				goto next_addr;
1290 			}
1291 
1292 			if (!SCTP_IPIF_USABLE(ipif->sctp_ipif_state))
1293 				goto next_addr;
1294 			if (p != NULL)
1295 				hdr = (sctp_parm_hdr_t *)(p + paramlen);
1296 			addr = ipif->sctp_ipif_saddr;
1297 			if (!ipif->sctp_ipif_isv6) {
1298 				struct in_addr	*v4;
1299 
1300 				if (p != NULL) {
1301 					hdr->sph_type = htons(PARM_ADDR4);
1302 					hdr->sph_len = htons(PARM_ADDR4_LEN);
1303 					v4 = (struct in_addr *)(hdr + 1);
1304 					IN6_V4MAPPED_TO_INADDR(&addr, v4);
1305 				}
1306 				paramlen += PARM_ADDR4_LEN;
1307 			} else {
1308 				if (p != NULL) {
1309 					hdr->sph_type = htons(PARM_ADDR6);
1310 					hdr->sph_len = htons(PARM_ADDR6_LEN);
1311 					bcopy(&addr, hdr + 1, sizeof (addr));
1312 				}
1313 				paramlen += PARM_ADDR6_LEN;
1314 			}
1315 next_addr:
1316 			if (scanned >= nsaddr)
1317 				return (paramlen);
1318 			obj = list_next(&sctp->sctp_saddrs[i].sctp_ipif_list,
1319 			    obj);
1320 		}
1321 	}
1322 	return (paramlen);
1323 }
1324 
1325 /*
1326  * This is used on a clustered node to obtain a list of addresses, the list
1327  * consists of sockaddr_in structs for v4 and sockaddr_in6 for v6. The list
1328  * is then passed onto the clustering module which sends back the correct
1329  * list based on the port info. Regardless of the input, i.e INADDR_ANY
1330  * or specific address(es), we create the list since it could be modified by
1331  * the clustering module. When given a list of addresses, we simply
1332  * create the list of sockaddr_in or sockaddr_in6 structs using those
1333  * addresses. If there is an INADDR_ANY in the input list, or if the
1334  * input is INADDR_ANY, we create a list of sockaddr_in or sockaddr_in6
1335  * structs consisting all the addresses in the global interface list
1336  * except those that are hosted on the loopback interface. We create
1337  * a list of sockaddr_in[6] structs just so that it can be directly input
1338  * to sctp_valid_addr_list() once the clustering module has processed it.
1339  */
1340 int
1341 sctp_get_addrlist(sctp_t *sctp, const void *addrs, uint32_t *addrcnt,
1342     uchar_t **addrlist, int *uspec, size_t *size)
1343 {
1344 	int			cnt;
1345 	int			icnt;
1346 	sctp_ipif_t		*sctp_ipif;
1347 	struct sockaddr_in	*s4;
1348 	struct sockaddr_in6	*s6;
1349 	uchar_t			*p;
1350 	int			err = 0;
1351 
1352 	*addrlist = NULL;
1353 	*size = 0;
1354 
1355 	/*
1356 	 * Create a list of sockaddr_in[6] structs using the input list.
1357 	 */
1358 	if (sctp->sctp_family == AF_INET) {
1359 		*size = sizeof (struct sockaddr_in) * *addrcnt;
1360 		*addrlist = kmem_zalloc(*size,  KM_SLEEP);
1361 		p = *addrlist;
1362 		for (cnt = 0; cnt < *addrcnt; cnt++) {
1363 			s4 = (struct sockaddr_in *)addrs + cnt;
1364 			/*
1365 			 * We need to create a list of all the available
1366 			 * addresses if there is an INADDR_ANY. However,
1367 			 * if we are beyond LISTEN, then this is invalid
1368 			 * (see sctp_valid_addr_list(). So, we just fail
1369 			 * it here rather than wait till it fails in
1370 			 * sctp_valid_addr_list().
1371 			 */
1372 			if (s4->sin_addr.s_addr == INADDR_ANY) {
1373 				kmem_free(*addrlist, *size);
1374 				*addrlist = NULL;
1375 				*size = 0;
1376 				if (sctp->sctp_state > SCTPS_LISTEN) {
1377 					*addrcnt = 0;
1378 					return (EINVAL);
1379 				}
1380 				if (uspec != NULL)
1381 					*uspec = 1;
1382 				goto get_all_addrs;
1383 			} else {
1384 				bcopy(s4, p, sizeof (*s4));
1385 				p += sizeof (*s4);
1386 			}
1387 		}
1388 	} else {
1389 		*size = sizeof (struct sockaddr_in6) * *addrcnt;
1390 		*addrlist = kmem_zalloc(*size, KM_SLEEP);
1391 		p = *addrlist;
1392 		for (cnt = 0; cnt < *addrcnt; cnt++) {
1393 			s6 = (struct sockaddr_in6 *)addrs + cnt;
1394 			/*
1395 			 * Comments for INADDR_ANY, above, apply here too.
1396 			 */
1397 			if (IN6_IS_ADDR_UNSPECIFIED(&s6->sin6_addr)) {
1398 				kmem_free(*addrlist, *size);
1399 				*size = 0;
1400 				*addrlist = NULL;
1401 				if (sctp->sctp_state > SCTPS_LISTEN) {
1402 					*addrcnt = 0;
1403 					return (EINVAL);
1404 				}
1405 				if (uspec != NULL)
1406 					*uspec = 1;
1407 				goto get_all_addrs;
1408 			} else {
1409 				bcopy(addrs, p, sizeof (*s6));
1410 				p += sizeof (*s6);
1411 			}
1412 		}
1413 	}
1414 	return (err);
1415 get_all_addrs:
1416 
1417 	/*
1418 	 * Allocate max possible size. We allocate the max. size here because
1419 	 * the clustering module could end up adding addresses to the list.
1420 	 * We allocate upfront so that the clustering module need to bother
1421 	 * re-sizing the list.
1422 	 */
1423 	if (sctp->sctp_family == AF_INET)
1424 		*size = sizeof (struct sockaddr_in) * sctp_g_ipifs_count;
1425 	else
1426 		*size = sizeof (struct sockaddr_in6) * sctp_g_ipifs_count;
1427 
1428 	*addrlist = kmem_zalloc(*size, KM_SLEEP);
1429 	*addrcnt = 0;
1430 	p = *addrlist;
1431 	rw_enter(&sctp_g_ipifs_lock, RW_READER);
1432 
1433 	/*
1434 	 * Walk through the global interface list and add all addresses,
1435 	 * except those that are hosted on loopback interfaces.
1436 	 */
1437 	for (cnt = 0; cnt <  SCTP_IPIF_HASH; cnt++) {
1438 		if (sctp_g_ipifs[cnt].ipif_count == 0)
1439 			continue;
1440 		sctp_ipif = list_head(&sctp_g_ipifs[cnt].sctp_ipif_list);
1441 		for (icnt = 0; icnt < sctp_g_ipifs[cnt].ipif_count; icnt++) {
1442 			in6_addr_t	addr;
1443 
1444 			rw_enter(&sctp_ipif->sctp_ipif_lock, RW_READER);
1445 			addr = sctp_ipif->sctp_ipif_saddr;
1446 			if (SCTP_IPIF_DISCARD(sctp_ipif->sctp_ipif_flags) ||
1447 			    !SCTP_IPIF_USABLE(sctp_ipif->sctp_ipif_state) ||
1448 			    SCTP_IS_IPIF_LOOPBACK(sctp_ipif) ||
1449 			    SCTP_IS_IPIF_LINKLOCAL(sctp_ipif) ||
1450 			    sctp_ipif->sctp_ipif_zoneid != sctp->sctp_zoneid ||
1451 			    (sctp->sctp_ipversion == IPV4_VERSION &&
1452 			    sctp_ipif->sctp_ipif_isv6) ||
1453 			    (sctp->sctp_connp->conn_ipv6_v6only &&
1454 			    !sctp_ipif->sctp_ipif_isv6)) {
1455 				rw_exit(&sctp_ipif->sctp_ipif_lock);
1456 				sctp_ipif = list_next(
1457 				    &sctp_g_ipifs[cnt].sctp_ipif_list,
1458 				    sctp_ipif);
1459 				continue;
1460 			}
1461 			rw_exit(&sctp_ipif->sctp_ipif_lock);
1462 			if (sctp->sctp_family == AF_INET) {
1463 				s4 = (struct sockaddr_in *)p;
1464 				IN6_V4MAPPED_TO_INADDR(&addr, &s4->sin_addr);
1465 				s4->sin_family = AF_INET;
1466 				p += sizeof (*s4);
1467 			} else {
1468 				s6 = (struct sockaddr_in6 *)p;
1469 				s6->sin6_addr = addr;
1470 				s6->sin6_family = AF_INET6;
1471 				s6->sin6_scope_id =
1472 				    sctp_ipif->sctp_ipif_ill->sctp_ill_index;
1473 				p += sizeof (*s6);
1474 			}
1475 			(*addrcnt)++;
1476 			sctp_ipif = list_next(&sctp_g_ipifs[cnt].sctp_ipif_list,
1477 			    sctp_ipif);
1478 		}
1479 	}
1480 	rw_exit(&sctp_g_ipifs_lock);
1481 	return (err);
1482 }
1483 
1484 /*
1485  * Get a list of addresses from the source address list. The  caller is
1486  * responsible for allocating sufficient buffer for this.
1487  */
1488 void
1489 sctp_get_saddr_list(sctp_t *sctp, uchar_t *p, size_t psize)
1490 {
1491 	int			cnt;
1492 	int			icnt;
1493 	sctp_saddr_ipif_t	*obj;
1494 	int			naddr;
1495 	int			scanned = 0;
1496 
1497 	for (cnt = 0; cnt < SCTP_IPIF_HASH; cnt++) {
1498 		if (sctp->sctp_saddrs[cnt].ipif_count == 0)
1499 			continue;
1500 		obj = list_head(&sctp->sctp_saddrs[cnt].sctp_ipif_list);
1501 		naddr = sctp->sctp_saddrs[cnt].ipif_count;
1502 		for (icnt = 0; icnt < naddr; icnt++) {
1503 			sctp_ipif_t	*ipif;
1504 
1505 			if (psize < sizeof (ipif->sctp_ipif_saddr))
1506 				return;
1507 
1508 			scanned++;
1509 			ipif = obj->saddr_ipifp;
1510 			bcopy(&ipif->sctp_ipif_saddr, p,
1511 			    sizeof (ipif->sctp_ipif_saddr));
1512 			p += sizeof (ipif->sctp_ipif_saddr);
1513 			psize -= sizeof (ipif->sctp_ipif_saddr);
1514 			if (scanned >= sctp->sctp_nsaddrs)
1515 				return;
1516 			obj = list_next(&sctp->sctp_saddrs[icnt].sctp_ipif_list,
1517 			    obj);
1518 		}
1519 	}
1520 }
1521 
1522 /*
1523  * Get a list of addresses from the remote address list. The  caller is
1524  * responsible for allocating sufficient buffer for this.
1525  */
1526 void
1527 sctp_get_faddr_list(sctp_t *sctp, uchar_t *p, size_t psize)
1528 {
1529 	sctp_faddr_t	*fp;
1530 
1531 	for (fp = sctp->sctp_faddrs; fp != NULL; fp = fp->next) {
1532 		if (psize < sizeof (fp->faddr))
1533 			return;
1534 		bcopy(&fp->faddr, p, sizeof (fp->faddr));
1535 		p += sizeof (fp->faddr);
1536 		psize -= sizeof (fp->faddr);
1537 	}
1538 }
1539 
1540 /* Initialize the SCTP ILL list and lock */
1541 void
1542 sctp_saddr_init()
1543 {
1544 	int	i;
1545 
1546 	rw_init(&sctp_g_ills_lock, NULL, RW_DEFAULT, NULL);
1547 	rw_init(&sctp_g_ipifs_lock, NULL, RW_DEFAULT, NULL);
1548 
1549 	for (i = 0; i < SCTP_ILL_HASH; i++) {
1550 		sctp_g_ills[i].ill_count = 0;
1551 		list_create(&sctp_g_ills[i].sctp_ill_list, sizeof (sctp_ill_t),
1552 		    offsetof(sctp_ill_t, sctp_ills));
1553 	}
1554 	for (i = 0; i < SCTP_IPIF_HASH; i++) {
1555 		sctp_g_ipifs[i].ipif_count = 0;
1556 		list_create(&sctp_g_ipifs[i].sctp_ipif_list,
1557 		    sizeof (sctp_ipif_t), offsetof(sctp_ipif_t, sctp_ipifs));
1558 	}
1559 }
1560 
1561 void
1562 sctp_saddr_fini()
1563 {
1564 	int	i;
1565 
1566 	rw_destroy(&sctp_g_ills_lock);
1567 	rw_destroy(&sctp_g_ipifs_lock);
1568 	ASSERT(sctp_ills_count == 0 && sctp_g_ipifs_count == 0);
1569 	for (i = 0; i < SCTP_ILL_HASH; i++)
1570 		list_destroy(&sctp_g_ills[i].sctp_ill_list);
1571 	for (i = 0; i < SCTP_IPIF_HASH; i++)
1572 		list_destroy(&sctp_g_ipifs[i].sctp_ipif_list);
1573 }
1574