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