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