xref: /freebsd/sys/netinet/sctp_asconf.c (revision 6f63e88c0166ed3e5f2805a9e667c7d24d304cf1)
1 /*-
2  * SPDX-License-Identifier: BSD-3-Clause
3  *
4  * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
5  * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
6  * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are met:
10  *
11  * a) Redistributions of source code must retain the above copyright notice,
12  *    this list of conditions and the following disclaimer.
13  *
14  * b) Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in
16  *    the documentation and/or other materials provided with the distribution.
17  *
18  * c) Neither the name of Cisco Systems, Inc. nor the names of its
19  *    contributors may be used to endorse or promote products derived
20  *    from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
24  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
32  * THE POSSIBILITY OF SUCH DAMAGE.
33  */
34 
35 #include <sys/cdefs.h>
36 __FBSDID("$FreeBSD$");
37 
38 #include <netinet/sctp_os.h>
39 #include <netinet/sctp_var.h>
40 #include <netinet/sctp_sysctl.h>
41 #include <netinet/sctp_pcb.h>
42 #include <netinet/sctp_header.h>
43 #include <netinet/sctputil.h>
44 #include <netinet/sctp_output.h>
45 #include <netinet/sctp_asconf.h>
46 #include <netinet/sctp_timer.h>
47 
48 /*
49  * debug flags:
50  * SCTP_DEBUG_ASCONF1: protocol info, general info and errors
51  * SCTP_DEBUG_ASCONF2: detailed info
52  */
53 
54 
55 /*
56  * RFC 5061
57  *
58  * An ASCONF parameter queue exists per asoc which holds the pending address
59  * operations.  Lists are updated upon receipt of ASCONF-ACK.
60  *
61  * A restricted_addrs list exists per assoc to hold local addresses that are
62  * not (yet) usable by the assoc as a source address.  These addresses are
63  * either pending an ASCONF operation (and exist on the ASCONF parameter
64  * queue), or they are permanently restricted (the peer has returned an
65  * ERROR indication to an ASCONF(ADD), or the peer does not support ASCONF).
66  *
67  * Deleted addresses are always immediately removed from the lists as they will
68  * (shortly) no longer exist in the kernel.  We send ASCONFs as a courtesy,
69  * only if allowed.
70  */
71 
72 /*
73  * ASCONF parameter processing.
74  * response_required: set if a reply is required (eg. SUCCESS_REPORT).
75  * returns a mbuf to an "error" response parameter or NULL/"success" if ok.
76  * FIX: allocating this many mbufs on the fly is pretty inefficient...
77  */
78 static struct mbuf *
79 sctp_asconf_success_response(uint32_t id)
80 {
81 	struct mbuf *m_reply = NULL;
82 	struct sctp_asconf_paramhdr *aph;
83 
84 	m_reply = sctp_get_mbuf_for_msg(sizeof(struct sctp_asconf_paramhdr),
85 	    0, M_NOWAIT, 1, MT_DATA);
86 	if (m_reply == NULL) {
87 		SCTPDBG(SCTP_DEBUG_ASCONF1,
88 		    "asconf_success_response: couldn't get mbuf!\n");
89 		return (NULL);
90 	}
91 	aph = mtod(m_reply, struct sctp_asconf_paramhdr *);
92 	aph->correlation_id = id;
93 	aph->ph.param_type = htons(SCTP_SUCCESS_REPORT);
94 	aph->ph.param_length = sizeof(struct sctp_asconf_paramhdr);
95 	SCTP_BUF_LEN(m_reply) = aph->ph.param_length;
96 	aph->ph.param_length = htons(aph->ph.param_length);
97 
98 	return (m_reply);
99 }
100 
101 static struct mbuf *
102 sctp_asconf_error_response(uint32_t id, uint16_t cause, uint8_t *error_tlv,
103     uint16_t tlv_length)
104 {
105 	struct mbuf *m_reply = NULL;
106 	struct sctp_asconf_paramhdr *aph;
107 	struct sctp_error_cause *error;
108 	uint32_t buf_len;
109 	uint16_t i, param_length, cause_length, padding_length;
110 	uint8_t *tlv;
111 
112 	if (error_tlv == NULL) {
113 		tlv_length = 0;
114 	}
115 	cause_length = sizeof(struct sctp_error_cause) + tlv_length;
116 	param_length = sizeof(struct sctp_asconf_paramhdr) + cause_length;
117 	padding_length = tlv_length % 4;
118 	if (padding_length != 0) {
119 		padding_length = 4 - padding_length;
120 	}
121 	buf_len = param_length + padding_length;
122 	if (buf_len > MLEN) {
123 		SCTPDBG(SCTP_DEBUG_ASCONF1,
124 		    "asconf_error_response: tlv_length (%xh) too big\n",
125 		    tlv_length);
126 		return (NULL);
127 	}
128 	m_reply = sctp_get_mbuf_for_msg(buf_len, 0, M_NOWAIT, 1, MT_DATA);
129 	if (m_reply == NULL) {
130 		SCTPDBG(SCTP_DEBUG_ASCONF1,
131 		    "asconf_error_response: couldn't get mbuf!\n");
132 		return (NULL);
133 	}
134 	aph = mtod(m_reply, struct sctp_asconf_paramhdr *);
135 	aph->ph.param_type = htons(SCTP_ERROR_CAUSE_IND);
136 	aph->ph.param_length = htons(param_length);
137 	aph->correlation_id = id;
138 	error = (struct sctp_error_cause *)(aph + 1);
139 	error->code = htons(cause);
140 	error->length = htons(cause_length);
141 	if (error_tlv != NULL) {
142 		tlv = (uint8_t *)(error + 1);
143 		memcpy(tlv, error_tlv, tlv_length);
144 		for (i = 0; i < padding_length; i++) {
145 			tlv[tlv_length + i] = 0;
146 		}
147 	}
148 	SCTP_BUF_LEN(m_reply) = buf_len;
149 	return (m_reply);
150 }
151 
152 static struct mbuf *
153 sctp_process_asconf_add_ip(struct sockaddr *src, struct sctp_asconf_paramhdr *aph,
154     struct sctp_tcb *stcb, int send_hb, int response_required)
155 {
156 	struct sctp_nets *net;
157 	struct mbuf *m_reply = NULL;
158 	union sctp_sockstore store;
159 	struct sctp_paramhdr *ph;
160 	uint16_t param_type, aparam_length;
161 #if defined(INET) || defined(INET6)
162 	uint16_t param_length;
163 #endif
164 	struct sockaddr *sa;
165 	int zero_address = 0;
166 	int bad_address = 0;
167 #ifdef INET
168 	struct sockaddr_in *sin;
169 	struct sctp_ipv4addr_param *v4addr;
170 #endif
171 #ifdef INET6
172 	struct sockaddr_in6 *sin6;
173 	struct sctp_ipv6addr_param *v6addr;
174 #endif
175 
176 	aparam_length = ntohs(aph->ph.param_length);
177 	if (aparam_length < sizeof(struct sctp_asconf_paramhdr) + sizeof(struct sctp_paramhdr)) {
178 		return (NULL);
179 	}
180 	ph = (struct sctp_paramhdr *)(aph + 1);
181 	param_type = ntohs(ph->param_type);
182 #if defined(INET) || defined(INET6)
183 	param_length = ntohs(ph->param_length);
184 	if (param_length + sizeof(struct sctp_asconf_paramhdr) != aparam_length) {
185 		return (NULL);
186 	}
187 #endif
188 	sa = &store.sa;
189 	switch (param_type) {
190 #ifdef INET
191 	case SCTP_IPV4_ADDRESS:
192 		if (param_length != sizeof(struct sctp_ipv4addr_param)) {
193 			/* invalid param size */
194 			return (NULL);
195 		}
196 		v4addr = (struct sctp_ipv4addr_param *)ph;
197 		sin = &store.sin;
198 		memset(sin, 0, sizeof(*sin));
199 		sin->sin_family = AF_INET;
200 		sin->sin_len = sizeof(struct sockaddr_in);
201 		sin->sin_port = stcb->rport;
202 		sin->sin_addr.s_addr = v4addr->addr;
203 		if ((sin->sin_addr.s_addr == INADDR_BROADCAST) ||
204 		    IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) {
205 			bad_address = 1;
206 		}
207 		if (sin->sin_addr.s_addr == INADDR_ANY)
208 			zero_address = 1;
209 		SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_add_ip: adding ");
210 		SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
211 		break;
212 #endif
213 #ifdef INET6
214 	case SCTP_IPV6_ADDRESS:
215 		if (param_length != sizeof(struct sctp_ipv6addr_param)) {
216 			/* invalid param size */
217 			return (NULL);
218 		}
219 		v6addr = (struct sctp_ipv6addr_param *)ph;
220 		sin6 = &store.sin6;
221 		memset(sin6, 0, sizeof(*sin6));
222 		sin6->sin6_family = AF_INET6;
223 		sin6->sin6_len = sizeof(struct sockaddr_in6);
224 		sin6->sin6_port = stcb->rport;
225 		memcpy((caddr_t)&sin6->sin6_addr, v6addr->addr,
226 		    sizeof(struct in6_addr));
227 		if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) {
228 			bad_address = 1;
229 		}
230 		if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
231 			zero_address = 1;
232 		SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_add_ip: adding ");
233 		SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
234 		break;
235 #endif
236 	default:
237 		m_reply = sctp_asconf_error_response(aph->correlation_id,
238 		    SCTP_CAUSE_INVALID_PARAM, (uint8_t *)aph,
239 		    aparam_length);
240 		return (m_reply);
241 	}			/* end switch */
242 
243 	/* if 0.0.0.0/::0, add the source address instead */
244 	if (zero_address && SCTP_BASE_SYSCTL(sctp_nat_friendly)) {
245 		sa = src;
246 		SCTPDBG(SCTP_DEBUG_ASCONF1,
247 		    "process_asconf_add_ip: using source addr ");
248 		SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, src);
249 	}
250 	net = NULL;
251 	/* add the address */
252 	if (bad_address) {
253 		m_reply = sctp_asconf_error_response(aph->correlation_id,
254 		    SCTP_CAUSE_INVALID_PARAM, (uint8_t *)aph,
255 		    aparam_length);
256 	} else if (sctp_add_remote_addr(stcb, sa, &net, stcb->asoc.port,
257 		    SCTP_DONOT_SETSCOPE,
258 	    SCTP_ADDR_DYNAMIC_ADDED) != 0) {
259 		SCTPDBG(SCTP_DEBUG_ASCONF1,
260 		    "process_asconf_add_ip: error adding address\n");
261 		m_reply = sctp_asconf_error_response(aph->correlation_id,
262 		    SCTP_CAUSE_RESOURCE_SHORTAGE, (uint8_t *)aph,
263 		    aparam_length);
264 	} else {
265 		if (response_required) {
266 			m_reply =
267 			    sctp_asconf_success_response(aph->correlation_id);
268 		}
269 		if (net != NULL) {
270 			/* notify upper layer */
271 			sctp_ulp_notify(SCTP_NOTIFY_ASCONF_ADD_IP, stcb, 0, sa, SCTP_SO_NOT_LOCKED);
272 			sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, stcb->sctp_ep, stcb, net);
273 			sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep,
274 			    stcb, net);
275 			if (send_hb) {
276 				sctp_send_hb(stcb, net, SCTP_SO_NOT_LOCKED);
277 			}
278 		}
279 	}
280 	return (m_reply);
281 }
282 
283 static int
284 sctp_asconf_del_remote_addrs_except(struct sctp_tcb *stcb, struct sockaddr *src)
285 {
286 	struct sctp_nets *src_net, *net, *nnet;
287 
288 	/* make sure the source address exists as a destination net */
289 	src_net = sctp_findnet(stcb, src);
290 	if (src_net == NULL) {
291 		/* not found */
292 		return (-1);
293 	}
294 
295 	/* delete all destination addresses except the source */
296 	TAILQ_FOREACH_SAFE(net, &stcb->asoc.nets, sctp_next, nnet) {
297 		if (net != src_net) {
298 			/* delete this address */
299 			SCTPDBG(SCTP_DEBUG_ASCONF1,
300 			    "asconf_del_remote_addrs_except: deleting ");
301 			SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1,
302 			    (struct sockaddr *)&net->ro._l_addr);
303 			/* notify upper layer */
304 			sctp_ulp_notify(SCTP_NOTIFY_ASCONF_DELETE_IP, stcb, 0,
305 			    (struct sockaddr *)&net->ro._l_addr, SCTP_SO_NOT_LOCKED);
306 			sctp_remove_net(stcb, net);
307 		}
308 	}
309 	return (0);
310 }
311 
312 static struct mbuf *
313 sctp_process_asconf_delete_ip(struct sockaddr *src,
314     struct sctp_asconf_paramhdr *aph,
315     struct sctp_tcb *stcb, int response_required)
316 {
317 	struct mbuf *m_reply = NULL;
318 	union sctp_sockstore store;
319 	struct sctp_paramhdr *ph;
320 	uint16_t param_type, aparam_length;
321 #if defined(INET) || defined(INET6)
322 	uint16_t param_length;
323 #endif
324 	struct sockaddr *sa;
325 	int zero_address = 0;
326 	int result;
327 #ifdef INET
328 	struct sockaddr_in *sin;
329 	struct sctp_ipv4addr_param *v4addr;
330 #endif
331 #ifdef INET6
332 	struct sockaddr_in6 *sin6;
333 	struct sctp_ipv6addr_param *v6addr;
334 #endif
335 
336 	aparam_length = ntohs(aph->ph.param_length);
337 	if (aparam_length < sizeof(struct sctp_asconf_paramhdr) + sizeof(struct sctp_paramhdr)) {
338 		return (NULL);
339 	}
340 	ph = (struct sctp_paramhdr *)(aph + 1);
341 	param_type = ntohs(ph->param_type);
342 #if defined(INET) || defined(INET6)
343 	param_length = ntohs(ph->param_length);
344 	if (param_length + sizeof(struct sctp_asconf_paramhdr) != aparam_length) {
345 		return (NULL);
346 	}
347 #endif
348 	sa = &store.sa;
349 	switch (param_type) {
350 #ifdef INET
351 	case SCTP_IPV4_ADDRESS:
352 		if (param_length != sizeof(struct sctp_ipv4addr_param)) {
353 			/* invalid param size */
354 			return (NULL);
355 		}
356 		v4addr = (struct sctp_ipv4addr_param *)ph;
357 		sin = &store.sin;
358 		memset(sin, 0, sizeof(*sin));
359 		sin->sin_family = AF_INET;
360 		sin->sin_len = sizeof(struct sockaddr_in);
361 		sin->sin_port = stcb->rport;
362 		sin->sin_addr.s_addr = v4addr->addr;
363 		if (sin->sin_addr.s_addr == INADDR_ANY)
364 			zero_address = 1;
365 		SCTPDBG(SCTP_DEBUG_ASCONF1,
366 		    "process_asconf_delete_ip: deleting ");
367 		SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
368 		break;
369 #endif
370 #ifdef INET6
371 	case SCTP_IPV6_ADDRESS:
372 		if (param_length != sizeof(struct sctp_ipv6addr_param)) {
373 			/* invalid param size */
374 			return (NULL);
375 		}
376 		v6addr = (struct sctp_ipv6addr_param *)ph;
377 		sin6 = &store.sin6;
378 		memset(sin6, 0, sizeof(*sin6));
379 		sin6->sin6_family = AF_INET6;
380 		sin6->sin6_len = sizeof(struct sockaddr_in6);
381 		sin6->sin6_port = stcb->rport;
382 		memcpy(&sin6->sin6_addr, v6addr->addr,
383 		    sizeof(struct in6_addr));
384 		if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
385 			zero_address = 1;
386 		SCTPDBG(SCTP_DEBUG_ASCONF1,
387 		    "process_asconf_delete_ip: deleting ");
388 		SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
389 		break;
390 #endif
391 	default:
392 		m_reply = sctp_asconf_error_response(aph->correlation_id,
393 		    SCTP_CAUSE_UNRESOLVABLE_ADDR, (uint8_t *)aph,
394 		    aparam_length);
395 		return (m_reply);
396 	}
397 
398 	/* make sure the source address is not being deleted */
399 	if (sctp_cmpaddr(sa, src)) {
400 		/* trying to delete the source address! */
401 		SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_delete_ip: tried to delete source addr\n");
402 		m_reply = sctp_asconf_error_response(aph->correlation_id,
403 		    SCTP_CAUSE_DELETING_SRC_ADDR, (uint8_t *)aph,
404 		    aparam_length);
405 		return (m_reply);
406 	}
407 
408 	/* if deleting 0.0.0.0/::0, delete all addresses except src addr */
409 	if (zero_address && SCTP_BASE_SYSCTL(sctp_nat_friendly)) {
410 		result = sctp_asconf_del_remote_addrs_except(stcb, src);
411 
412 		if (result) {
413 			/* src address did not exist? */
414 			SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_delete_ip: src addr does not exist?\n");
415 			/* what error to reply with?? */
416 			m_reply =
417 			    sctp_asconf_error_response(aph->correlation_id,
418 			    SCTP_CAUSE_REQUEST_REFUSED, (uint8_t *)aph,
419 			    aparam_length);
420 		} else if (response_required) {
421 			m_reply =
422 			    sctp_asconf_success_response(aph->correlation_id);
423 		}
424 		return (m_reply);
425 	}
426 
427 	/* delete the address */
428 	result = sctp_del_remote_addr(stcb, sa);
429 	/*
430 	 * note if result == -2, the address doesn't exist in the asoc but
431 	 * since it's being deleted anyways, we just ack the delete -- but
432 	 * this probably means something has already gone awry
433 	 */
434 	if (result == -1) {
435 		/* only one address in the asoc */
436 		SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_delete_ip: tried to delete last IP addr!\n");
437 		m_reply = sctp_asconf_error_response(aph->correlation_id,
438 		    SCTP_CAUSE_DELETING_LAST_ADDR, (uint8_t *)aph,
439 		    aparam_length);
440 	} else {
441 		if (response_required) {
442 			m_reply = sctp_asconf_success_response(aph->correlation_id);
443 		}
444 		/* notify upper layer */
445 		sctp_ulp_notify(SCTP_NOTIFY_ASCONF_DELETE_IP, stcb, 0, sa, SCTP_SO_NOT_LOCKED);
446 	}
447 	return (m_reply);
448 }
449 
450 static struct mbuf *
451 sctp_process_asconf_set_primary(struct sockaddr *src,
452     struct sctp_asconf_paramhdr *aph,
453     struct sctp_tcb *stcb, int response_required)
454 {
455 	struct mbuf *m_reply = NULL;
456 	union sctp_sockstore store;
457 	struct sctp_paramhdr *ph;
458 	uint16_t param_type, aparam_length;
459 #if defined(INET) || defined(INET6)
460 	uint16_t param_length;
461 #endif
462 	struct sockaddr *sa;
463 	int zero_address = 0;
464 #ifdef INET
465 	struct sockaddr_in *sin;
466 	struct sctp_ipv4addr_param *v4addr;
467 #endif
468 #ifdef INET6
469 	struct sockaddr_in6 *sin6;
470 	struct sctp_ipv6addr_param *v6addr;
471 #endif
472 
473 	aparam_length = ntohs(aph->ph.param_length);
474 	if (aparam_length < sizeof(struct sctp_asconf_paramhdr) + sizeof(struct sctp_paramhdr)) {
475 		return (NULL);
476 	}
477 	ph = (struct sctp_paramhdr *)(aph + 1);
478 	param_type = ntohs(ph->param_type);
479 #if defined(INET) || defined(INET6)
480 	param_length = ntohs(ph->param_length);
481 	if (param_length + sizeof(struct sctp_asconf_paramhdr) != aparam_length) {
482 		return (NULL);
483 	}
484 #endif
485 	sa = &store.sa;
486 	switch (param_type) {
487 #ifdef INET
488 	case SCTP_IPV4_ADDRESS:
489 		if (param_length != sizeof(struct sctp_ipv4addr_param)) {
490 			/* invalid param size */
491 			return (NULL);
492 		}
493 		v4addr = (struct sctp_ipv4addr_param *)ph;
494 		sin = &store.sin;
495 		memset(sin, 0, sizeof(*sin));
496 		sin->sin_family = AF_INET;
497 		sin->sin_len = sizeof(struct sockaddr_in);
498 		sin->sin_addr.s_addr = v4addr->addr;
499 		if (sin->sin_addr.s_addr == INADDR_ANY)
500 			zero_address = 1;
501 		SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_set_primary: ");
502 		SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
503 		break;
504 #endif
505 #ifdef INET6
506 	case SCTP_IPV6_ADDRESS:
507 		if (param_length != sizeof(struct sctp_ipv6addr_param)) {
508 			/* invalid param size */
509 			return (NULL);
510 		}
511 		v6addr = (struct sctp_ipv6addr_param *)ph;
512 		sin6 = &store.sin6;
513 		memset(sin6, 0, sizeof(*sin6));
514 		sin6->sin6_family = AF_INET6;
515 		sin6->sin6_len = sizeof(struct sockaddr_in6);
516 		memcpy((caddr_t)&sin6->sin6_addr, v6addr->addr,
517 		    sizeof(struct in6_addr));
518 		if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
519 			zero_address = 1;
520 		SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_set_primary: ");
521 		SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
522 		break;
523 #endif
524 	default:
525 		m_reply = sctp_asconf_error_response(aph->correlation_id,
526 		    SCTP_CAUSE_UNRESOLVABLE_ADDR, (uint8_t *)aph,
527 		    aparam_length);
528 		return (m_reply);
529 	}
530 
531 	/* if 0.0.0.0/::0, use the source address instead */
532 	if (zero_address && SCTP_BASE_SYSCTL(sctp_nat_friendly)) {
533 		sa = src;
534 		SCTPDBG(SCTP_DEBUG_ASCONF1,
535 		    "process_asconf_set_primary: using source addr ");
536 		SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, src);
537 	}
538 	/* set the primary address */
539 	if (sctp_set_primary_addr(stcb, sa, NULL) == 0) {
540 		SCTPDBG(SCTP_DEBUG_ASCONF1,
541 		    "process_asconf_set_primary: primary address set\n");
542 		/* notify upper layer */
543 		sctp_ulp_notify(SCTP_NOTIFY_ASCONF_SET_PRIMARY, stcb, 0, sa, SCTP_SO_NOT_LOCKED);
544 		if ((stcb->asoc.primary_destination->dest_state & SCTP_ADDR_REACHABLE) &&
545 		    (!(stcb->asoc.primary_destination->dest_state & SCTP_ADDR_PF)) &&
546 		    (stcb->asoc.alternate)) {
547 			sctp_free_remote_addr(stcb->asoc.alternate);
548 			stcb->asoc.alternate = NULL;
549 		}
550 		if (response_required) {
551 			m_reply = sctp_asconf_success_response(aph->correlation_id);
552 		}
553 		/*
554 		 * Mobility adaptation. Ideally, when the reception of SET
555 		 * PRIMARY with DELETE IP ADDRESS of the previous primary
556 		 * destination, unacknowledged DATA are retransmitted
557 		 * immediately to the new primary destination for seamless
558 		 * handover. If the destination is UNCONFIRMED and marked to
559 		 * REQ_PRIM, The retransmission occur when reception of the
560 		 * HEARTBEAT-ACK.  (See sctp_handle_heartbeat_ack in
561 		 * sctp_input.c) Also, when change of the primary
562 		 * destination, it is better that all subsequent new DATA
563 		 * containing already queued DATA are transmitted to the new
564 		 * primary destination. (by micchie)
565 		 */
566 		if ((sctp_is_mobility_feature_on(stcb->sctp_ep,
567 		    SCTP_MOBILITY_BASE) ||
568 		    sctp_is_mobility_feature_on(stcb->sctp_ep,
569 		    SCTP_MOBILITY_FASTHANDOFF)) &&
570 		    sctp_is_mobility_feature_on(stcb->sctp_ep,
571 		    SCTP_MOBILITY_PRIM_DELETED) &&
572 		    (stcb->asoc.primary_destination->dest_state &
573 		    SCTP_ADDR_UNCONFIRMED) == 0) {
574 
575 			sctp_timer_stop(SCTP_TIMER_TYPE_PRIM_DELETED,
576 			    stcb->sctp_ep, stcb, NULL,
577 			    SCTP_FROM_SCTP_ASCONF + SCTP_LOC_1);
578 			if (sctp_is_mobility_feature_on(stcb->sctp_ep,
579 			    SCTP_MOBILITY_FASTHANDOFF)) {
580 				sctp_assoc_immediate_retrans(stcb,
581 				    stcb->asoc.primary_destination);
582 			}
583 			if (sctp_is_mobility_feature_on(stcb->sctp_ep,
584 			    SCTP_MOBILITY_BASE)) {
585 				sctp_move_chunks_from_net(stcb,
586 				    stcb->asoc.deleted_primary);
587 			}
588 			sctp_delete_prim_timer(stcb->sctp_ep, stcb);
589 		}
590 	} else {
591 		/* couldn't set the requested primary address! */
592 		SCTPDBG(SCTP_DEBUG_ASCONF1,
593 		    "process_asconf_set_primary: set primary failed!\n");
594 		/* must have been an invalid address, so report */
595 		m_reply = sctp_asconf_error_response(aph->correlation_id,
596 		    SCTP_CAUSE_UNRESOLVABLE_ADDR, (uint8_t *)aph,
597 		    aparam_length);
598 	}
599 
600 	return (m_reply);
601 }
602 
603 /*
604  * handles an ASCONF chunk.
605  * if all parameters are processed ok, send a plain (empty) ASCONF-ACK
606  */
607 void
608 sctp_handle_asconf(struct mbuf *m, unsigned int offset,
609     struct sockaddr *src,
610     struct sctp_asconf_chunk *cp, struct sctp_tcb *stcb,
611     int first)
612 {
613 	struct sctp_association *asoc;
614 	uint32_t serial_num;
615 	struct mbuf *n, *m_ack, *m_result, *m_tail;
616 	struct sctp_asconf_ack_chunk *ack_cp;
617 	struct sctp_asconf_paramhdr *aph;
618 	struct sctp_ipv6addr_param *p_addr;
619 	unsigned int asconf_limit, cnt;
620 	int error = 0;		/* did an error occur? */
621 
622 	/* asconf param buffer */
623 	uint8_t aparam_buf[SCTP_PARAM_BUFFER_SIZE];
624 	struct sctp_asconf_ack *ack, *ack_next;
625 
626 	/* verify minimum length */
627 	if (ntohs(cp->ch.chunk_length) < sizeof(struct sctp_asconf_chunk)) {
628 		SCTPDBG(SCTP_DEBUG_ASCONF1,
629 		    "handle_asconf: chunk too small = %xh\n",
630 		    ntohs(cp->ch.chunk_length));
631 		return;
632 	}
633 	asoc = &stcb->asoc;
634 	serial_num = ntohl(cp->serial_number);
635 
636 	if (SCTP_TSN_GE(asoc->asconf_seq_in, serial_num)) {
637 		/* got a duplicate ASCONF */
638 		SCTPDBG(SCTP_DEBUG_ASCONF1,
639 		    "handle_asconf: got duplicate serial number = %xh\n",
640 		    serial_num);
641 		return;
642 	} else if (serial_num != (asoc->asconf_seq_in + 1)) {
643 		SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: incorrect serial number = %xh (expected next = %xh)\n",
644 		    serial_num, asoc->asconf_seq_in + 1);
645 		return;
646 	}
647 
648 	/* it's the expected "next" sequence number, so process it */
649 	asoc->asconf_seq_in = serial_num;	/* update sequence */
650 	/* get length of all the param's in the ASCONF */
651 	asconf_limit = offset + ntohs(cp->ch.chunk_length);
652 	SCTPDBG(SCTP_DEBUG_ASCONF1,
653 	    "handle_asconf: asconf_limit=%u, sequence=%xh\n",
654 	    asconf_limit, serial_num);
655 
656 	if (first) {
657 		/* delete old cache */
658 		SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: Now processing first ASCONF. Try to delete old cache\n");
659 
660 		TAILQ_FOREACH_SAFE(ack, &asoc->asconf_ack_sent, next, ack_next) {
661 			if (ack->serial_number == serial_num)
662 				break;
663 			SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: delete old(%u) < first(%u)\n",
664 			    ack->serial_number, serial_num);
665 			TAILQ_REMOVE(&asoc->asconf_ack_sent, ack, next);
666 			if (ack->data != NULL) {
667 				sctp_m_freem(ack->data);
668 			}
669 			SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_asconf_ack), ack);
670 		}
671 	}
672 
673 	m_ack = sctp_get_mbuf_for_msg(sizeof(struct sctp_asconf_ack_chunk), 0,
674 	    M_NOWAIT, 1, MT_DATA);
675 	if (m_ack == NULL) {
676 		SCTPDBG(SCTP_DEBUG_ASCONF1,
677 		    "handle_asconf: couldn't get mbuf!\n");
678 		return;
679 	}
680 	m_tail = m_ack;		/* current reply chain's tail */
681 
682 	/* fill in ASCONF-ACK header */
683 	ack_cp = mtod(m_ack, struct sctp_asconf_ack_chunk *);
684 	ack_cp->ch.chunk_type = SCTP_ASCONF_ACK;
685 	ack_cp->ch.chunk_flags = 0;
686 	ack_cp->serial_number = htonl(serial_num);
687 	/* set initial lengths (eg. just an ASCONF-ACK), ntohx at the end! */
688 	SCTP_BUF_LEN(m_ack) = sizeof(struct sctp_asconf_ack_chunk);
689 	ack_cp->ch.chunk_length = sizeof(struct sctp_asconf_ack_chunk);
690 
691 	/* skip the lookup address parameter */
692 	offset += sizeof(struct sctp_asconf_chunk);
693 	p_addr = (struct sctp_ipv6addr_param *)sctp_m_getptr(m, offset, sizeof(struct sctp_paramhdr), (uint8_t *)&aparam_buf);
694 	if (p_addr == NULL) {
695 		SCTPDBG(SCTP_DEBUG_ASCONF1,
696 		    "handle_asconf: couldn't get lookup addr!\n");
697 		/* respond with a missing/invalid mandatory parameter error */
698 		sctp_m_freem(m_ack);
699 		return;
700 	}
701 	/* skip lookup addr */
702 	offset += SCTP_SIZE32(ntohs(p_addr->ph.param_length));
703 	/* get pointer to first asconf param in ASCONF */
704 	aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(m, offset, sizeof(struct sctp_asconf_paramhdr), (uint8_t *)&aparam_buf);
705 	if (aph == NULL) {
706 		SCTPDBG(SCTP_DEBUG_ASCONF1, "Empty ASCONF received?\n");
707 		goto send_reply;
708 	}
709 	/* process through all parameters */
710 	cnt = 0;
711 	while (aph != NULL) {
712 		unsigned int param_length, param_type;
713 
714 		param_type = ntohs(aph->ph.param_type);
715 		param_length = ntohs(aph->ph.param_length);
716 		if (offset + param_length > asconf_limit) {
717 			/* parameter goes beyond end of chunk! */
718 			sctp_m_freem(m_ack);
719 			return;
720 		}
721 		m_result = NULL;
722 
723 		if (param_length > sizeof(aparam_buf)) {
724 			SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: param length (%u) larger than buffer size!\n", param_length);
725 			sctp_m_freem(m_ack);
726 			return;
727 		}
728 		if (param_length <= sizeof(struct sctp_paramhdr)) {
729 			SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: param length (%u) too short\n", param_length);
730 			sctp_m_freem(m_ack);
731 			return;
732 		}
733 		/* get the entire parameter */
734 		aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(m, offset, param_length, aparam_buf);
735 		if (aph == NULL) {
736 			SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: couldn't get entire param\n");
737 			sctp_m_freem(m_ack);
738 			return;
739 		}
740 		switch (param_type) {
741 		case SCTP_ADD_IP_ADDRESS:
742 			m_result = sctp_process_asconf_add_ip(src, aph, stcb,
743 			    (cnt < SCTP_BASE_SYSCTL(sctp_hb_maxburst)), error);
744 			cnt++;
745 			break;
746 		case SCTP_DEL_IP_ADDRESS:
747 			m_result = sctp_process_asconf_delete_ip(src, aph, stcb,
748 			    error);
749 			break;
750 		case SCTP_ERROR_CAUSE_IND:
751 			/* not valid in an ASCONF chunk */
752 			break;
753 		case SCTP_SET_PRIM_ADDR:
754 			m_result = sctp_process_asconf_set_primary(src, aph,
755 			    stcb, error);
756 			break;
757 		case SCTP_NAT_VTAGS:
758 			SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: sees a NAT VTAG state parameter\n");
759 			break;
760 		case SCTP_SUCCESS_REPORT:
761 			/* not valid in an ASCONF chunk */
762 			break;
763 		case SCTP_ULP_ADAPTATION:
764 			/* FIX */
765 			break;
766 		default:
767 			if ((param_type & 0x8000) == 0) {
768 				/* Been told to STOP at this param */
769 				asconf_limit = offset;
770 				/*
771 				 * FIX FIX - We need to call
772 				 * sctp_arethere_unrecognized_parameters()
773 				 * to get a operr and send it for any
774 				 * param's with the 0x4000 bit set OR do it
775 				 * here ourselves... note we still must STOP
776 				 * if the 0x8000 bit is clear.
777 				 */
778 			}
779 			/* unknown/invalid param type */
780 			break;
781 		}		/* switch */
782 
783 		/* add any (error) result to the reply mbuf chain */
784 		if (m_result != NULL) {
785 			SCTP_BUF_NEXT(m_tail) = m_result;
786 			m_tail = m_result;
787 			ack_cp->ch.chunk_length += SCTP_BUF_LEN(m_result);
788 			/* set flag to force success reports */
789 			error = 1;
790 		}
791 		offset += SCTP_SIZE32(param_length);
792 		/* update remaining ASCONF message length to process */
793 		if (offset >= asconf_limit) {
794 			/* no more data in the mbuf chain */
795 			break;
796 		}
797 		/* get pointer to next asconf param */
798 		aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(m, offset,
799 		    sizeof(struct sctp_asconf_paramhdr),
800 		    (uint8_t *)&aparam_buf);
801 		if (aph == NULL) {
802 			/* can't get an asconf paramhdr */
803 			SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: can't get asconf param hdr!\n");
804 			/* FIX ME - add error here... */
805 		}
806 	}
807 
808 send_reply:
809 	ack_cp->ch.chunk_length = htons(ack_cp->ch.chunk_length);
810 	/* save the ASCONF-ACK reply */
811 	ack = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_asconf_ack),
812 	    struct sctp_asconf_ack);
813 	if (ack == NULL) {
814 		sctp_m_freem(m_ack);
815 		return;
816 	}
817 	ack->serial_number = serial_num;
818 	ack->last_sent_to = NULL;
819 	ack->data = m_ack;
820 	ack->len = 0;
821 	for (n = m_ack; n != NULL; n = SCTP_BUF_NEXT(n)) {
822 		ack->len += SCTP_BUF_LEN(n);
823 	}
824 	TAILQ_INSERT_TAIL(&stcb->asoc.asconf_ack_sent, ack, next);
825 
826 	/* see if last_control_chunk_from is set properly (use IP src addr) */
827 	if (stcb->asoc.last_control_chunk_from == NULL) {
828 		/*
829 		 * this could happen if the source address was just newly
830 		 * added
831 		 */
832 		SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: looking up net for IP source address\n");
833 		SCTPDBG(SCTP_DEBUG_ASCONF1, "Looking for IP source: ");
834 		SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, src);
835 		/* look up the from address */
836 		stcb->asoc.last_control_chunk_from = sctp_findnet(stcb, src);
837 #ifdef SCTP_DEBUG
838 		if (stcb->asoc.last_control_chunk_from == NULL) {
839 			SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: IP source address not found?!\n");
840 		}
841 #endif
842 	}
843 }
844 
845 /*
846  * does the address match? returns 0 if not, 1 if so
847  */
848 static uint32_t
849 sctp_asconf_addr_match(struct sctp_asconf_addr *aa, struct sockaddr *sa)
850 {
851 	switch (sa->sa_family) {
852 #ifdef INET6
853 	case AF_INET6:
854 		{
855 			/* XXX scopeid */
856 			struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
857 
858 			if ((aa->ap.addrp.ph.param_type == SCTP_IPV6_ADDRESS) &&
859 			    (memcmp(&aa->ap.addrp.addr, &sin6->sin6_addr,
860 			    sizeof(struct in6_addr)) == 0)) {
861 				return (1);
862 			}
863 			break;
864 		}
865 #endif
866 #ifdef INET
867 	case AF_INET:
868 		{
869 			struct sockaddr_in *sin = (struct sockaddr_in *)sa;
870 
871 			if ((aa->ap.addrp.ph.param_type == SCTP_IPV4_ADDRESS) &&
872 			    (memcmp(&aa->ap.addrp.addr, &sin->sin_addr,
873 			    sizeof(struct in_addr)) == 0)) {
874 				return (1);
875 			}
876 			break;
877 		}
878 #endif
879 	default:
880 		break;
881 	}
882 	return (0);
883 }
884 
885 /*
886  * does the address match? returns 0 if not, 1 if so
887  */
888 static uint32_t
889 sctp_addr_match(struct sctp_paramhdr *ph, struct sockaddr *sa)
890 {
891 #if defined(INET) || defined(INET6)
892 	uint16_t param_type, param_length;
893 
894 	param_type = ntohs(ph->param_type);
895 	param_length = ntohs(ph->param_length);
896 #endif
897 	switch (sa->sa_family) {
898 #ifdef INET6
899 	case AF_INET6:
900 		{
901 			/* XXX scopeid */
902 			struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
903 			struct sctp_ipv6addr_param *v6addr;
904 
905 			v6addr = (struct sctp_ipv6addr_param *)ph;
906 			if ((param_type == SCTP_IPV6_ADDRESS) &&
907 			    (param_length == sizeof(struct sctp_ipv6addr_param)) &&
908 			    (memcmp(&v6addr->addr, &sin6->sin6_addr,
909 			    sizeof(struct in6_addr)) == 0)) {
910 				return (1);
911 			}
912 			break;
913 		}
914 #endif
915 #ifdef INET
916 	case AF_INET:
917 		{
918 			struct sockaddr_in *sin = (struct sockaddr_in *)sa;
919 			struct sctp_ipv4addr_param *v4addr;
920 
921 			v4addr = (struct sctp_ipv4addr_param *)ph;
922 			if ((param_type == SCTP_IPV4_ADDRESS) &&
923 			    (param_length == sizeof(struct sctp_ipv4addr_param)) &&
924 			    (memcmp(&v4addr->addr, &sin->sin_addr,
925 			    sizeof(struct in_addr)) == 0)) {
926 				return (1);
927 			}
928 			break;
929 		}
930 #endif
931 	default:
932 		break;
933 	}
934 	return (0);
935 }
936 
937 /*
938  * Cleanup for non-responded/OP ERR'd ASCONF
939  */
940 void
941 sctp_asconf_cleanup(struct sctp_tcb *stcb)
942 {
943 	/*
944 	 * clear out any existing asconfs going out
945 	 */
946 	sctp_timer_stop(SCTP_TIMER_TYPE_ASCONF, stcb->sctp_ep, stcb, NULL,
947 	    SCTP_FROM_SCTP_ASCONF + SCTP_LOC_2);
948 	stcb->asoc.asconf_seq_out_acked = stcb->asoc.asconf_seq_out;
949 	/* remove the old ASCONF on our outbound queue */
950 	sctp_toss_old_asconf(stcb);
951 }
952 
953 /*
954  * cleanup any cached source addresses that may be topologically
955  * incorrect after a new address has been added to this interface.
956  */
957 static void
958 sctp_asconf_nets_cleanup(struct sctp_tcb *stcb, struct sctp_ifn *ifn)
959 {
960 	struct sctp_nets *net;
961 
962 	/*
963 	 * Ideally, we want to only clear cached routes and source addresses
964 	 * that are topologically incorrect.  But since there is no easy way
965 	 * to know whether the newly added address on the ifn would cause a
966 	 * routing change (i.e. a new egress interface would be chosen)
967 	 * without doing a new routing lookup and source address selection,
968 	 * we will (for now) just flush any cached route using a different
969 	 * ifn (and cached source addrs) and let output re-choose them
970 	 * during the next send on that net.
971 	 */
972 	TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
973 		/*
974 		 * clear any cached route (and cached source address) if the
975 		 * route's interface is NOT the same as the address change.
976 		 * If it's the same interface, just clear the cached source
977 		 * address.
978 		 */
979 		if (SCTP_ROUTE_HAS_VALID_IFN(&net->ro) &&
980 		    ((ifn == NULL) ||
981 		    (SCTP_GET_IF_INDEX_FROM_ROUTE(&net->ro) != ifn->ifn_index))) {
982 			/* clear any cached route */
983 			RO_NHFREE(&net->ro);
984 		}
985 		/* clear any cached source address */
986 		if (net->src_addr_selected) {
987 			sctp_free_ifa(net->ro._s_addr);
988 			net->ro._s_addr = NULL;
989 			net->src_addr_selected = 0;
990 		}
991 	}
992 }
993 
994 
995 void
996 sctp_assoc_immediate_retrans(struct sctp_tcb *stcb, struct sctp_nets *dstnet)
997 {
998 	int error;
999 
1000 	if (dstnet->dest_state & SCTP_ADDR_UNCONFIRMED) {
1001 		return;
1002 	}
1003 	if (stcb->asoc.deleted_primary == NULL) {
1004 		return;
1005 	}
1006 
1007 	if (!TAILQ_EMPTY(&stcb->asoc.sent_queue)) {
1008 		SCTPDBG(SCTP_DEBUG_ASCONF1, "assoc_immediate_retrans: Deleted primary is ");
1009 		SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, &stcb->asoc.deleted_primary->ro._l_addr.sa);
1010 		SCTPDBG(SCTP_DEBUG_ASCONF1, "Current Primary is ");
1011 		SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, &stcb->asoc.primary_destination->ro._l_addr.sa);
1012 		sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb,
1013 		    stcb->asoc.deleted_primary,
1014 		    SCTP_FROM_SCTP_ASCONF + SCTP_LOC_3);
1015 		stcb->asoc.num_send_timers_up--;
1016 		if (stcb->asoc.num_send_timers_up < 0) {
1017 			stcb->asoc.num_send_timers_up = 0;
1018 		}
1019 		SCTP_TCB_LOCK_ASSERT(stcb);
1020 		error = sctp_t3rxt_timer(stcb->sctp_ep, stcb,
1021 		    stcb->asoc.deleted_primary);
1022 		if (error) {
1023 			SCTP_INP_DECR_REF(stcb->sctp_ep);
1024 			return;
1025 		}
1026 		SCTP_TCB_LOCK_ASSERT(stcb);
1027 #ifdef SCTP_AUDITING_ENABLED
1028 		sctp_auditing(4, stcb->sctp_ep, stcb, stcb->asoc.deleted_primary);
1029 #endif
1030 		sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_NOT_LOCKED);
1031 		if ((stcb->asoc.num_send_timers_up == 0) &&
1032 		    (stcb->asoc.sent_queue_cnt > 0)) {
1033 			struct sctp_tmit_chunk *chk;
1034 
1035 			chk = TAILQ_FIRST(&stcb->asoc.sent_queue);
1036 			sctp_timer_start(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep,
1037 			    stcb, chk->whoTo);
1038 		}
1039 	}
1040 	return;
1041 }
1042 
1043 static int
1044     sctp_asconf_queue_mgmt(struct sctp_tcb *, struct sctp_ifa *, uint16_t);
1045 
1046 void
1047 sctp_net_immediate_retrans(struct sctp_tcb *stcb, struct sctp_nets *net)
1048 {
1049 	struct sctp_tmit_chunk *chk;
1050 
1051 	SCTPDBG(SCTP_DEBUG_ASCONF1, "net_immediate_retrans: RTO is %d\n", net->RTO);
1052 	sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb, net,
1053 	    SCTP_FROM_SCTP_ASCONF + SCTP_LOC_4);
1054 	stcb->asoc.cc_functions.sctp_set_initial_cc_param(stcb, net);
1055 	net->error_count = 0;
1056 	TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
1057 		if (chk->whoTo == net) {
1058 			if (chk->sent < SCTP_DATAGRAM_RESEND) {
1059 				chk->sent = SCTP_DATAGRAM_RESEND;
1060 				sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
1061 				sctp_flight_size_decrease(chk);
1062 				sctp_total_flight_decrease(stcb, chk);
1063 				net->marked_retrans++;
1064 				stcb->asoc.marked_retrans++;
1065 			}
1066 		}
1067 	}
1068 	if (net->marked_retrans) {
1069 		sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_NOT_LOCKED);
1070 	}
1071 }
1072 
1073 static void
1074 sctp_path_check_and_react(struct sctp_tcb *stcb, struct sctp_ifa *newifa)
1075 {
1076 	struct sctp_nets *net;
1077 	int addrnum, changed;
1078 
1079 	/*
1080 	 * If number of local valid addresses is 1, the valid address is
1081 	 * probably newly added address. Several valid addresses in this
1082 	 * association.  A source address may not be changed.  Additionally,
1083 	 * they can be configured on a same interface as "alias" addresses.
1084 	 * (by micchie)
1085 	 */
1086 	addrnum = sctp_local_addr_count(stcb);
1087 	SCTPDBG(SCTP_DEBUG_ASCONF1, "p_check_react(): %d local addresses\n",
1088 	    addrnum);
1089 	if (addrnum == 1) {
1090 		TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
1091 			/* clear any cached route and source address */
1092 			RO_NHFREE(&net->ro);
1093 			if (net->src_addr_selected) {
1094 				sctp_free_ifa(net->ro._s_addr);
1095 				net->ro._s_addr = NULL;
1096 				net->src_addr_selected = 0;
1097 			}
1098 			/* Retransmit unacknowledged DATA chunks immediately */
1099 			if (sctp_is_mobility_feature_on(stcb->sctp_ep,
1100 			    SCTP_MOBILITY_FASTHANDOFF)) {
1101 				sctp_net_immediate_retrans(stcb, net);
1102 			}
1103 			/* also, SET PRIMARY is maybe already sent */
1104 		}
1105 		return;
1106 	}
1107 
1108 	/* Multiple local addresses exsist in the association.  */
1109 	TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
1110 		/* clear any cached route and source address */
1111 		RO_NHFREE(&net->ro);
1112 		if (net->src_addr_selected) {
1113 			sctp_free_ifa(net->ro._s_addr);
1114 			net->ro._s_addr = NULL;
1115 			net->src_addr_selected = 0;
1116 		}
1117 		/*
1118 		 * Check if the nexthop is corresponding to the new address.
1119 		 * If the new address is corresponding to the current
1120 		 * nexthop, the path will be changed. If the new address is
1121 		 * NOT corresponding to the current nexthop, the path will
1122 		 * not be changed.
1123 		 */
1124 		SCTP_RTALLOC((sctp_route_t *)&net->ro,
1125 		    stcb->sctp_ep->def_vrf_id,
1126 		    stcb->sctp_ep->fibnum);
1127 		if (net->ro.ro_nh == NULL)
1128 			continue;
1129 
1130 		changed = 0;
1131 		switch (net->ro._l_addr.sa.sa_family) {
1132 #ifdef INET
1133 		case AF_INET:
1134 			if (sctp_v4src_match_nexthop(newifa, (sctp_route_t *)&net->ro)) {
1135 				changed = 1;
1136 			}
1137 			break;
1138 #endif
1139 #ifdef INET6
1140 		case AF_INET6:
1141 			if (sctp_v6src_match_nexthop(
1142 			    &newifa->address.sin6, (sctp_route_t *)&net->ro)) {
1143 				changed = 1;
1144 			}
1145 			break;
1146 #endif
1147 		default:
1148 			break;
1149 		}
1150 		/*
1151 		 * if the newly added address does not relate routing
1152 		 * information, we skip.
1153 		 */
1154 		if (changed == 0)
1155 			continue;
1156 		/* Retransmit unacknowledged DATA chunks immediately */
1157 		if (sctp_is_mobility_feature_on(stcb->sctp_ep,
1158 		    SCTP_MOBILITY_FASTHANDOFF)) {
1159 			sctp_net_immediate_retrans(stcb, net);
1160 		}
1161 		/* Send SET PRIMARY for this new address */
1162 		if (net == stcb->asoc.primary_destination) {
1163 			(void)sctp_asconf_queue_mgmt(stcb, newifa,
1164 			    SCTP_SET_PRIM_ADDR);
1165 		}
1166 	}
1167 }
1168 
1169 /*
1170  * process an ADD/DELETE IP ack from peer.
1171  * addr: corresponding sctp_ifa to the address being added/deleted.
1172  * type: SCTP_ADD_IP_ADDRESS or SCTP_DEL_IP_ADDRESS.
1173  * flag: 1=success, 0=failure.
1174  */
1175 static void
1176 sctp_asconf_addr_mgmt_ack(struct sctp_tcb *stcb, struct sctp_ifa *addr, uint32_t flag)
1177 {
1178 	/*
1179 	 * do the necessary asoc list work- if we get a failure indication,
1180 	 * leave the address on the assoc's restricted list.  If we get a
1181 	 * success indication, remove the address from the restricted list.
1182 	 */
1183 	/*
1184 	 * Note: this will only occur for ADD_IP_ADDRESS, since
1185 	 * DEL_IP_ADDRESS is never actually added to the list...
1186 	 */
1187 	if (flag) {
1188 		/* success case, so remove from the restricted list */
1189 		sctp_del_local_addr_restricted(stcb, addr);
1190 
1191 		if (sctp_is_mobility_feature_on(stcb->sctp_ep,
1192 		    SCTP_MOBILITY_BASE) ||
1193 		    sctp_is_mobility_feature_on(stcb->sctp_ep,
1194 		    SCTP_MOBILITY_FASTHANDOFF)) {
1195 			sctp_path_check_and_react(stcb, addr);
1196 			return;
1197 		}
1198 		/* clear any cached/topologically incorrect source addresses */
1199 		sctp_asconf_nets_cleanup(stcb, addr->ifn_p);
1200 	}
1201 	/* else, leave it on the list */
1202 }
1203 
1204 /*
1205  * add an asconf add/delete/set primary IP address parameter to the queue.
1206  * type = SCTP_ADD_IP_ADDRESS, SCTP_DEL_IP_ADDRESS, SCTP_SET_PRIM_ADDR.
1207  * returns 0 if queued, -1 if not queued/removed.
1208  * NOTE: if adding, but a delete for the same address is already scheduled
1209  * (and not yet sent out), simply remove it from queue.  Same for deleting
1210  * an address already scheduled for add.  If a duplicate operation is found,
1211  * ignore the new one.
1212  */
1213 static int
1214 sctp_asconf_queue_mgmt(struct sctp_tcb *stcb, struct sctp_ifa *ifa,
1215     uint16_t type)
1216 {
1217 	struct sctp_asconf_addr *aa, *aa_next;
1218 
1219 	/* make sure the request isn't already in the queue */
1220 	TAILQ_FOREACH_SAFE(aa, &stcb->asoc.asconf_queue, next, aa_next) {
1221 		/* address match? */
1222 		if (sctp_asconf_addr_match(aa, &ifa->address.sa) == 0)
1223 			continue;
1224 		/*
1225 		 * is the request already in queue but not sent? pass the
1226 		 * request already sent in order to resolve the following
1227 		 * case: 1. arrival of ADD, then sent 2. arrival of DEL. we
1228 		 * can't remove the ADD request already sent 3. arrival of
1229 		 * ADD
1230 		 */
1231 		if (aa->ap.aph.ph.param_type == type && aa->sent == 0) {
1232 			return (-1);
1233 		}
1234 		/* is the negative request already in queue, and not sent */
1235 		if ((aa->sent == 0) && (type == SCTP_ADD_IP_ADDRESS) &&
1236 		    (aa->ap.aph.ph.param_type == SCTP_DEL_IP_ADDRESS)) {
1237 			/* add requested, delete already queued */
1238 			TAILQ_REMOVE(&stcb->asoc.asconf_queue, aa, next);
1239 			/* remove the ifa from the restricted list */
1240 			sctp_del_local_addr_restricted(stcb, ifa);
1241 			/* free the asconf param */
1242 			SCTP_FREE(aa, SCTP_M_ASC_ADDR);
1243 			SCTPDBG(SCTP_DEBUG_ASCONF2, "asconf_queue_mgmt: add removes queued entry\n");
1244 			return (-1);
1245 		}
1246 		if ((aa->sent == 0) && (type == SCTP_DEL_IP_ADDRESS) &&
1247 		    (aa->ap.aph.ph.param_type == SCTP_ADD_IP_ADDRESS)) {
1248 			/* delete requested, add already queued */
1249 			TAILQ_REMOVE(&stcb->asoc.asconf_queue, aa, next);
1250 			/* remove the aa->ifa from the restricted list */
1251 			sctp_del_local_addr_restricted(stcb, aa->ifa);
1252 			/* free the asconf param */
1253 			SCTP_FREE(aa, SCTP_M_ASC_ADDR);
1254 			SCTPDBG(SCTP_DEBUG_ASCONF2, "asconf_queue_mgmt: delete removes queued entry\n");
1255 			return (-1);
1256 		}
1257 	}			/* for each aa */
1258 
1259 	/* adding new request to the queue */
1260 	SCTP_MALLOC(aa, struct sctp_asconf_addr *, sizeof(*aa),
1261 	    SCTP_M_ASC_ADDR);
1262 	if (aa == NULL) {
1263 		/* didn't get memory */
1264 		SCTPDBG(SCTP_DEBUG_ASCONF1, "asconf_queue_mgmt: failed to get memory!\n");
1265 		return (-1);
1266 	}
1267 	aa->special_del = 0;
1268 	/* fill in asconf address parameter fields */
1269 	/* top level elements are "networked" during send */
1270 	aa->ap.aph.ph.param_type = type;
1271 	aa->ifa = ifa;
1272 	atomic_add_int(&ifa->refcount, 1);
1273 	/* correlation_id filled in during send routine later... */
1274 	switch (ifa->address.sa.sa_family) {
1275 #ifdef INET6
1276 	case AF_INET6:
1277 		{
1278 			struct sockaddr_in6 *sin6;
1279 
1280 			sin6 = &ifa->address.sin6;
1281 			aa->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS;
1282 			aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv6addr_param));
1283 			aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) +
1284 			    sizeof(struct sctp_ipv6addr_param);
1285 			memcpy(&aa->ap.addrp.addr, &sin6->sin6_addr,
1286 			    sizeof(struct in6_addr));
1287 			break;
1288 		}
1289 #endif
1290 #ifdef INET
1291 	case AF_INET:
1292 		{
1293 			struct sockaddr_in *sin;
1294 
1295 			sin = &ifa->address.sin;
1296 			aa->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS;
1297 			aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv4addr_param));
1298 			aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) +
1299 			    sizeof(struct sctp_ipv4addr_param);
1300 			memcpy(&aa->ap.addrp.addr, &sin->sin_addr,
1301 			    sizeof(struct in_addr));
1302 			break;
1303 		}
1304 #endif
1305 	default:
1306 		/* invalid family! */
1307 		SCTP_FREE(aa, SCTP_M_ASC_ADDR);
1308 		sctp_free_ifa(ifa);
1309 		return (-1);
1310 	}
1311 	aa->sent = 0;		/* clear sent flag */
1312 
1313 	TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
1314 #ifdef SCTP_DEBUG
1315 	if (SCTP_BASE_SYSCTL(sctp_debug_on) & SCTP_DEBUG_ASCONF2) {
1316 		if (type == SCTP_ADD_IP_ADDRESS) {
1317 			SCTP_PRINTF("asconf_queue_mgmt: inserted asconf ADD_IP_ADDRESS: ");
1318 			SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, &ifa->address.sa);
1319 		} else if (type == SCTP_DEL_IP_ADDRESS) {
1320 			SCTP_PRINTF("asconf_queue_mgmt: appended asconf DEL_IP_ADDRESS: ");
1321 			SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, &ifa->address.sa);
1322 		} else {
1323 			SCTP_PRINTF("asconf_queue_mgmt: appended asconf SET_PRIM_ADDR: ");
1324 			SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, &ifa->address.sa);
1325 		}
1326 	}
1327 #endif
1328 
1329 	return (0);
1330 }
1331 
1332 
1333 /*
1334  * add an asconf operation for the given ifa and type.
1335  * type = SCTP_ADD_IP_ADDRESS, SCTP_DEL_IP_ADDRESS, SCTP_SET_PRIM_ADDR.
1336  * returns 0 if completed, -1 if not completed, 1 if immediate send is
1337  * advisable.
1338  */
1339 static int
1340 sctp_asconf_queue_add(struct sctp_tcb *stcb, struct sctp_ifa *ifa,
1341     uint16_t type)
1342 {
1343 	uint32_t status;
1344 	int pending_delete_queued = 0;
1345 	int last;
1346 
1347 	/* see if peer supports ASCONF */
1348 	if (stcb->asoc.asconf_supported == 0) {
1349 		return (-1);
1350 	}
1351 
1352 	/*
1353 	 * if this is deleting the last address from the assoc, mark it as
1354 	 * pending.
1355 	 */
1356 	if ((type == SCTP_DEL_IP_ADDRESS) && !stcb->asoc.asconf_del_pending) {
1357 		if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
1358 			last = (sctp_local_addr_count(stcb) == 0);
1359 		} else {
1360 			last = (sctp_local_addr_count(stcb) == 1);
1361 		}
1362 		if (last) {
1363 			/* set the pending delete info only */
1364 			stcb->asoc.asconf_del_pending = 1;
1365 			stcb->asoc.asconf_addr_del_pending = ifa;
1366 			atomic_add_int(&ifa->refcount, 1);
1367 			SCTPDBG(SCTP_DEBUG_ASCONF2,
1368 			    "asconf_queue_add: mark delete last address pending\n");
1369 			return (-1);
1370 		}
1371 	}
1372 
1373 	/* queue an asconf parameter */
1374 	status = sctp_asconf_queue_mgmt(stcb, ifa, type);
1375 
1376 	/*
1377 	 * if this is an add, and there is a delete also pending (i.e. the
1378 	 * last local address is being changed), queue the pending delete
1379 	 * too.
1380 	 */
1381 	if ((type == SCTP_ADD_IP_ADDRESS) && stcb->asoc.asconf_del_pending && (status == 0)) {
1382 		/* queue in the pending delete */
1383 		if (sctp_asconf_queue_mgmt(stcb,
1384 		    stcb->asoc.asconf_addr_del_pending,
1385 		    SCTP_DEL_IP_ADDRESS) == 0) {
1386 			SCTPDBG(SCTP_DEBUG_ASCONF2, "asconf_queue_add: queuing pending delete\n");
1387 			pending_delete_queued = 1;
1388 			/* clear out the pending delete info */
1389 			stcb->asoc.asconf_del_pending = 0;
1390 			sctp_free_ifa(stcb->asoc.asconf_addr_del_pending);
1391 			stcb->asoc.asconf_addr_del_pending = NULL;
1392 		}
1393 	}
1394 
1395 	if (pending_delete_queued) {
1396 		struct sctp_nets *net;
1397 
1398 		/*
1399 		 * since we know that the only/last address is now being
1400 		 * changed in this case, reset the cwnd/rto on all nets to
1401 		 * start as a new address and path.  Also clear the error
1402 		 * counts to give the assoc the best chance to complete the
1403 		 * address change.
1404 		 */
1405 		TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
1406 			stcb->asoc.cc_functions.sctp_set_initial_cc_param(stcb,
1407 			    net);
1408 			net->RTO = 0;
1409 			net->error_count = 0;
1410 		}
1411 		stcb->asoc.overall_error_count = 0;
1412 		if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
1413 			sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
1414 			    stcb->asoc.overall_error_count,
1415 			    0,
1416 			    SCTP_FROM_SCTP_ASCONF,
1417 			    __LINE__);
1418 		}
1419 
1420 		/* queue in an advisory set primary too */
1421 		(void)sctp_asconf_queue_mgmt(stcb, ifa, SCTP_SET_PRIM_ADDR);
1422 		/* let caller know we should send this out immediately */
1423 		status = 1;
1424 	}
1425 	return (status);
1426 }
1427 
1428 /*-
1429  * add an asconf delete IP address parameter to the queue by sockaddr and
1430  * possibly with no sctp_ifa available.  This is only called by the routine
1431  * that checks the addresses in an INIT-ACK against the current address list.
1432  * returns 0 if completed, non-zero if not completed.
1433  * NOTE: if an add is already scheduled (and not yet sent out), simply
1434  * remove it from queue.  If a duplicate operation is found, ignore the
1435  * new one.
1436  */
1437 static int
1438 sctp_asconf_queue_sa_delete(struct sctp_tcb *stcb, struct sockaddr *sa)
1439 {
1440 	struct sctp_ifa *ifa;
1441 	struct sctp_asconf_addr *aa, *aa_next;
1442 
1443 	if (stcb == NULL) {
1444 		return (-1);
1445 	}
1446 	/* see if peer supports ASCONF */
1447 	if (stcb->asoc.asconf_supported == 0) {
1448 		return (-1);
1449 	}
1450 	/* make sure the request isn't already in the queue */
1451 	TAILQ_FOREACH_SAFE(aa, &stcb->asoc.asconf_queue, next, aa_next) {
1452 		/* address match? */
1453 		if (sctp_asconf_addr_match(aa, sa) == 0)
1454 			continue;
1455 		/* is the request already in queue (sent or not) */
1456 		if (aa->ap.aph.ph.param_type == SCTP_DEL_IP_ADDRESS) {
1457 			return (-1);
1458 		}
1459 		/* is the negative request already in queue, and not sent */
1460 		if (aa->sent == 1)
1461 			continue;
1462 		if (aa->ap.aph.ph.param_type == SCTP_ADD_IP_ADDRESS) {
1463 			/* add already queued, so remove existing entry */
1464 			TAILQ_REMOVE(&stcb->asoc.asconf_queue, aa, next);
1465 			sctp_del_local_addr_restricted(stcb, aa->ifa);
1466 			/* free the entry */
1467 			SCTP_FREE(aa, SCTP_M_ASC_ADDR);
1468 			return (-1);
1469 		}
1470 	}			/* for each aa */
1471 
1472 	/* find any existing ifa-- NOTE ifa CAN be allowed to be NULL */
1473 	ifa = sctp_find_ifa_by_addr(sa, stcb->asoc.vrf_id, SCTP_ADDR_NOT_LOCKED);
1474 
1475 	/* adding new request to the queue */
1476 	SCTP_MALLOC(aa, struct sctp_asconf_addr *, sizeof(*aa),
1477 	    SCTP_M_ASC_ADDR);
1478 	if (aa == NULL) {
1479 		/* didn't get memory */
1480 		SCTPDBG(SCTP_DEBUG_ASCONF1,
1481 		    "sctp_asconf_queue_sa_delete: failed to get memory!\n");
1482 		return (-1);
1483 	}
1484 	aa->special_del = 0;
1485 	/* fill in asconf address parameter fields */
1486 	/* top level elements are "networked" during send */
1487 	aa->ap.aph.ph.param_type = SCTP_DEL_IP_ADDRESS;
1488 	aa->ifa = ifa;
1489 	if (ifa)
1490 		atomic_add_int(&ifa->refcount, 1);
1491 	/* correlation_id filled in during send routine later... */
1492 	switch (sa->sa_family) {
1493 #ifdef INET6
1494 	case AF_INET6:
1495 		{
1496 			/* IPv6 address */
1497 			struct sockaddr_in6 *sin6;
1498 
1499 			sin6 = (struct sockaddr_in6 *)sa;
1500 			aa->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS;
1501 			aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv6addr_param));
1502 			aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) + sizeof(struct sctp_ipv6addr_param);
1503 			memcpy(&aa->ap.addrp.addr, &sin6->sin6_addr,
1504 			    sizeof(struct in6_addr));
1505 			break;
1506 		}
1507 #endif
1508 #ifdef INET
1509 	case AF_INET:
1510 		{
1511 			/* IPv4 address */
1512 			struct sockaddr_in *sin = (struct sockaddr_in *)sa;
1513 
1514 			aa->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS;
1515 			aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv4addr_param));
1516 			aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) + sizeof(struct sctp_ipv4addr_param);
1517 			memcpy(&aa->ap.addrp.addr, &sin->sin_addr,
1518 			    sizeof(struct in_addr));
1519 			break;
1520 		}
1521 #endif
1522 	default:
1523 		/* invalid family! */
1524 		SCTP_FREE(aa, SCTP_M_ASC_ADDR);
1525 		if (ifa)
1526 			sctp_free_ifa(ifa);
1527 		return (-1);
1528 	}
1529 	aa->sent = 0;		/* clear sent flag */
1530 
1531 	/* delete goes to the back of the queue */
1532 	TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
1533 
1534 	/* sa_ignore MEMLEAK {memory is put on the tailq} */
1535 	return (0);
1536 }
1537 
1538 /*
1539  * find a specific asconf param on our "sent" queue
1540  */
1541 static struct sctp_asconf_addr *
1542 sctp_asconf_find_param(struct sctp_tcb *stcb, uint32_t correlation_id)
1543 {
1544 	struct sctp_asconf_addr *aa;
1545 
1546 	TAILQ_FOREACH(aa, &stcb->asoc.asconf_queue, next) {
1547 		if (aa->ap.aph.correlation_id == correlation_id &&
1548 		    aa->sent == 1) {
1549 			/* found it */
1550 			return (aa);
1551 		}
1552 	}
1553 	/* didn't find it */
1554 	return (NULL);
1555 }
1556 
1557 /*
1558  * process an SCTP_ERROR_CAUSE_IND for a ASCONF-ACK parameter and do
1559  * notifications based on the error response
1560  */
1561 static void
1562 sctp_asconf_process_error(struct sctp_tcb *stcb SCTP_UNUSED,
1563     struct sctp_asconf_paramhdr *aph)
1564 {
1565 	struct sctp_error_cause *eh;
1566 	struct sctp_paramhdr *ph;
1567 	uint16_t param_type;
1568 	uint16_t error_code;
1569 
1570 	eh = (struct sctp_error_cause *)(aph + 1);
1571 	ph = (struct sctp_paramhdr *)(eh + 1);
1572 	/* validate lengths */
1573 	if (htons(eh->length) + sizeof(struct sctp_error_cause) >
1574 	    htons(aph->ph.param_length)) {
1575 		/* invalid error cause length */
1576 		SCTPDBG(SCTP_DEBUG_ASCONF1,
1577 		    "asconf_process_error: cause element too long\n");
1578 		return;
1579 	}
1580 	if (htons(ph->param_length) + sizeof(struct sctp_paramhdr) >
1581 	    htons(eh->length)) {
1582 		/* invalid included TLV length */
1583 		SCTPDBG(SCTP_DEBUG_ASCONF1,
1584 		    "asconf_process_error: included TLV too long\n");
1585 		return;
1586 	}
1587 	/* which error code ? */
1588 	error_code = ntohs(eh->code);
1589 	param_type = ntohs(aph->ph.param_type);
1590 	/* FIX: this should go back up the REMOTE_ERROR ULP notify */
1591 	switch (error_code) {
1592 	case SCTP_CAUSE_RESOURCE_SHORTAGE:
1593 		/* we allow ourselves to "try again" for this error */
1594 		break;
1595 	default:
1596 		/* peer can't handle it... */
1597 		switch (param_type) {
1598 		case SCTP_ADD_IP_ADDRESS:
1599 		case SCTP_DEL_IP_ADDRESS:
1600 		case SCTP_SET_PRIM_ADDR:
1601 			break;
1602 		default:
1603 			break;
1604 		}
1605 	}
1606 }
1607 
1608 /*
1609  * process an asconf queue param.
1610  * aparam: parameter to process, will be removed from the queue.
1611  * flag: 1=success case, 0=failure case
1612  */
1613 static void
1614 sctp_asconf_process_param_ack(struct sctp_tcb *stcb,
1615     struct sctp_asconf_addr *aparam, uint32_t flag)
1616 {
1617 	uint16_t param_type;
1618 
1619 	/* process this param */
1620 	param_type = aparam->ap.aph.ph.param_type;
1621 	switch (param_type) {
1622 	case SCTP_ADD_IP_ADDRESS:
1623 		SCTPDBG(SCTP_DEBUG_ASCONF1,
1624 		    "process_param_ack: added IP address\n");
1625 		sctp_asconf_addr_mgmt_ack(stcb, aparam->ifa, flag);
1626 		break;
1627 	case SCTP_DEL_IP_ADDRESS:
1628 		SCTPDBG(SCTP_DEBUG_ASCONF1,
1629 		    "process_param_ack: deleted IP address\n");
1630 		/* nothing really to do... lists already updated */
1631 		break;
1632 	case SCTP_SET_PRIM_ADDR:
1633 		SCTPDBG(SCTP_DEBUG_ASCONF1,
1634 		    "process_param_ack: set primary IP address\n");
1635 		/* nothing to do... peer may start using this addr */
1636 		break;
1637 	default:
1638 		/* should NEVER happen */
1639 		break;
1640 	}
1641 
1642 	/* remove the param and free it */
1643 	TAILQ_REMOVE(&stcb->asoc.asconf_queue, aparam, next);
1644 	if (aparam->ifa)
1645 		sctp_free_ifa(aparam->ifa);
1646 	SCTP_FREE(aparam, SCTP_M_ASC_ADDR);
1647 }
1648 
1649 /*
1650  * cleanup from a bad asconf ack parameter
1651  */
1652 static void
1653 sctp_asconf_ack_clear(struct sctp_tcb *stcb SCTP_UNUSED)
1654 {
1655 	/* assume peer doesn't really know how to do asconfs */
1656 	/* XXX we could free the pending queue here */
1657 
1658 }
1659 
1660 void
1661 sctp_handle_asconf_ack(struct mbuf *m, int offset,
1662     struct sctp_asconf_ack_chunk *cp, struct sctp_tcb *stcb,
1663     struct sctp_nets *net, int *abort_no_unlock)
1664 {
1665 	struct sctp_association *asoc;
1666 	uint32_t serial_num;
1667 	uint16_t ack_length;
1668 	struct sctp_asconf_paramhdr *aph;
1669 	struct sctp_asconf_addr *aa, *aa_next;
1670 	uint32_t last_error_id = 0;	/* last error correlation id */
1671 	uint32_t id;
1672 	struct sctp_asconf_addr *ap;
1673 
1674 	/* asconf param buffer */
1675 	uint8_t aparam_buf[SCTP_PARAM_BUFFER_SIZE];
1676 
1677 	/* verify minimum length */
1678 	if (ntohs(cp->ch.chunk_length) < sizeof(struct sctp_asconf_ack_chunk)) {
1679 		SCTPDBG(SCTP_DEBUG_ASCONF1,
1680 		    "handle_asconf_ack: chunk too small = %xh\n",
1681 		    ntohs(cp->ch.chunk_length));
1682 		return;
1683 	}
1684 	asoc = &stcb->asoc;
1685 	serial_num = ntohl(cp->serial_number);
1686 
1687 	/*
1688 	 * NOTE: we may want to handle this differently- currently, we will
1689 	 * abort when we get an ack for the expected serial number + 1 (eg.
1690 	 * we didn't send it), process an ack normally if it is the expected
1691 	 * serial number, and re-send the previous ack for *ALL* other
1692 	 * serial numbers
1693 	 */
1694 
1695 	/*
1696 	 * if the serial number is the next expected, but I didn't send it,
1697 	 * abort the asoc, since someone probably just hijacked us...
1698 	 */
1699 	if (serial_num == (asoc->asconf_seq_out + 1)) {
1700 		struct mbuf *op_err;
1701 		char msg[SCTP_DIAG_INFO_LEN];
1702 
1703 		SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf_ack: got unexpected next serial number! Aborting asoc!\n");
1704 		snprintf(msg, sizeof(msg), "Never sent serial number %8.8x",
1705 		    serial_num);
1706 		op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
1707 		sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
1708 		*abort_no_unlock = 1;
1709 		return;
1710 	}
1711 	if (serial_num != asoc->asconf_seq_out_acked + 1) {
1712 		/* got a duplicate/unexpected ASCONF-ACK */
1713 		SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf_ack: got duplicate/unexpected serial number = %xh (expected = %xh)\n",
1714 		    serial_num, asoc->asconf_seq_out_acked + 1);
1715 		return;
1716 	}
1717 
1718 	if (serial_num == asoc->asconf_seq_out - 1) {
1719 		/* stop our timer */
1720 		sctp_timer_stop(SCTP_TIMER_TYPE_ASCONF, stcb->sctp_ep, stcb, NULL,
1721 		    SCTP_FROM_SCTP_ASCONF + SCTP_LOC_5);
1722 	}
1723 
1724 	/* process the ASCONF-ACK contents */
1725 	ack_length = ntohs(cp->ch.chunk_length) -
1726 	    sizeof(struct sctp_asconf_ack_chunk);
1727 	offset += sizeof(struct sctp_asconf_ack_chunk);
1728 	/* process through all parameters */
1729 	while (ack_length >= sizeof(struct sctp_asconf_paramhdr)) {
1730 		unsigned int param_length, param_type;
1731 
1732 		/* get pointer to next asconf parameter */
1733 		aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(m, offset,
1734 		    sizeof(struct sctp_asconf_paramhdr), aparam_buf);
1735 		if (aph == NULL) {
1736 			/* can't get an asconf paramhdr */
1737 			sctp_asconf_ack_clear(stcb);
1738 			return;
1739 		}
1740 		param_type = ntohs(aph->ph.param_type);
1741 		param_length = ntohs(aph->ph.param_length);
1742 		if (param_length > ack_length) {
1743 			sctp_asconf_ack_clear(stcb);
1744 			return;
1745 		}
1746 		if (param_length < sizeof(struct sctp_paramhdr)) {
1747 			sctp_asconf_ack_clear(stcb);
1748 			return;
1749 		}
1750 		/* get the complete parameter... */
1751 		if (param_length > sizeof(aparam_buf)) {
1752 			SCTPDBG(SCTP_DEBUG_ASCONF1,
1753 			    "param length (%u) larger than buffer size!\n", param_length);
1754 			sctp_asconf_ack_clear(stcb);
1755 			return;
1756 		}
1757 		aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(m, offset, param_length, aparam_buf);
1758 		if (aph == NULL) {
1759 			sctp_asconf_ack_clear(stcb);
1760 			return;
1761 		}
1762 		/* correlation_id is transparent to peer, no ntohl needed */
1763 		id = aph->correlation_id;
1764 
1765 		switch (param_type) {
1766 		case SCTP_ERROR_CAUSE_IND:
1767 			last_error_id = id;
1768 			/* find the corresponding asconf param in our queue */
1769 			ap = sctp_asconf_find_param(stcb, id);
1770 			if (ap == NULL) {
1771 				/* hmm... can't find this in our queue! */
1772 				break;
1773 			}
1774 			/* process the parameter, failed flag */
1775 			sctp_asconf_process_param_ack(stcb, ap, 0);
1776 			/* process the error response */
1777 			sctp_asconf_process_error(stcb, aph);
1778 			break;
1779 		case SCTP_SUCCESS_REPORT:
1780 			/* find the corresponding asconf param in our queue */
1781 			ap = sctp_asconf_find_param(stcb, id);
1782 			if (ap == NULL) {
1783 				/* hmm... can't find this in our queue! */
1784 				break;
1785 			}
1786 			/* process the parameter, success flag */
1787 			sctp_asconf_process_param_ack(stcb, ap, 1);
1788 			break;
1789 		default:
1790 			break;
1791 		}		/* switch */
1792 
1793 		/* update remaining ASCONF-ACK message length to process */
1794 		ack_length -= SCTP_SIZE32(param_length);
1795 		if (ack_length <= 0) {
1796 			/* no more data in the mbuf chain */
1797 			break;
1798 		}
1799 		offset += SCTP_SIZE32(param_length);
1800 	}			/* while */
1801 
1802 	/*
1803 	 * if there are any "sent" params still on the queue, these are
1804 	 * implicitly "success", or "failed" (if we got an error back) ...
1805 	 * so process these appropriately
1806 	 *
1807 	 * we assume that the correlation_id's are monotonically increasing
1808 	 * beginning from 1 and that we don't have *that* many outstanding
1809 	 * at any given time
1810 	 */
1811 	if (last_error_id == 0)
1812 		last_error_id--;	/* set to "max" value */
1813 	TAILQ_FOREACH_SAFE(aa, &stcb->asoc.asconf_queue, next, aa_next) {
1814 		if (aa->sent == 1) {
1815 			/*
1816 			 * implicitly successful or failed if correlation_id
1817 			 * < last_error_id, then success else, failure
1818 			 */
1819 			if (aa->ap.aph.correlation_id < last_error_id)
1820 				sctp_asconf_process_param_ack(stcb, aa, 1);
1821 			else
1822 				sctp_asconf_process_param_ack(stcb, aa, 0);
1823 		} else {
1824 			/*
1825 			 * since we always process in order (FIFO queue) if
1826 			 * we reach one that hasn't been sent, the rest
1827 			 * should not have been sent either. so, we're
1828 			 * done...
1829 			 */
1830 			break;
1831 		}
1832 	}
1833 
1834 	/* update the next sequence number to use */
1835 	asoc->asconf_seq_out_acked++;
1836 	/* remove the old ASCONF on our outbound queue */
1837 	sctp_toss_old_asconf(stcb);
1838 	if (!TAILQ_EMPTY(&stcb->asoc.asconf_queue)) {
1839 #ifdef SCTP_TIMER_BASED_ASCONF
1840 		/* we have more params, so restart our timer */
1841 		sctp_timer_start(SCTP_TIMER_TYPE_ASCONF, stcb->sctp_ep,
1842 		    stcb, net);
1843 #else
1844 		/* we have more params, so send out more */
1845 		sctp_send_asconf(stcb, net, SCTP_ADDR_NOT_LOCKED);
1846 #endif
1847 	}
1848 }
1849 
1850 #ifdef INET6
1851 static uint32_t
1852 sctp_is_scopeid_in_nets(struct sctp_tcb *stcb, struct sockaddr *sa)
1853 {
1854 	struct sockaddr_in6 *sin6, *net6;
1855 	struct sctp_nets *net;
1856 
1857 	if (sa->sa_family != AF_INET6) {
1858 		/* wrong family */
1859 		return (0);
1860 	}
1861 	sin6 = (struct sockaddr_in6 *)sa;
1862 	if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) == 0) {
1863 		/* not link local address */
1864 		return (0);
1865 	}
1866 	/* hunt through our destination nets list for this scope_id */
1867 	TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
1868 		if (((struct sockaddr *)(&net->ro._l_addr))->sa_family !=
1869 		    AF_INET6)
1870 			continue;
1871 		net6 = (struct sockaddr_in6 *)&net->ro._l_addr;
1872 		if (IN6_IS_ADDR_LINKLOCAL(&net6->sin6_addr) == 0)
1873 			continue;
1874 		if (sctp_is_same_scope(sin6, net6)) {
1875 			/* found one */
1876 			return (1);
1877 		}
1878 	}
1879 	/* didn't find one */
1880 	return (0);
1881 }
1882 #endif
1883 
1884 /*
1885  * address management functions
1886  */
1887 static void
1888 sctp_addr_mgmt_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
1889     struct sctp_ifa *ifa, uint16_t type, int addr_locked)
1890 {
1891 	int status;
1892 
1893 	if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0 ||
1894 	    sctp_is_feature_off(inp, SCTP_PCB_FLAGS_DO_ASCONF)) {
1895 		/* subset bound, no ASCONF allowed case, so ignore */
1896 		return;
1897 	}
1898 	/*
1899 	 * note: we know this is not the subset bound, no ASCONF case eg.
1900 	 * this is boundall or subset bound w/ASCONF allowed
1901 	 */
1902 
1903 	/* first, make sure that the address is IPv4 or IPv6 and not jailed */
1904 	switch (ifa->address.sa.sa_family) {
1905 #ifdef INET6
1906 	case AF_INET6:
1907 		if (prison_check_ip6(inp->ip_inp.inp.inp_cred,
1908 		    &ifa->address.sin6.sin6_addr) != 0) {
1909 			return;
1910 		}
1911 		break;
1912 #endif
1913 #ifdef INET
1914 	case AF_INET:
1915 		if (prison_check_ip4(inp->ip_inp.inp.inp_cred,
1916 		    &ifa->address.sin.sin_addr) != 0) {
1917 			return;
1918 		}
1919 		break;
1920 #endif
1921 	default:
1922 		return;
1923 	}
1924 #ifdef INET6
1925 	/* make sure we're "allowed" to add this type of addr */
1926 	if (ifa->address.sa.sa_family == AF_INET6) {
1927 		/* invalid if we're not a v6 endpoint */
1928 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0)
1929 			return;
1930 		/* is the v6 addr really valid ? */
1931 		if (ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
1932 			return;
1933 		}
1934 	}
1935 #endif
1936 	/* put this address on the "pending/do not use yet" list */
1937 	sctp_add_local_addr_restricted(stcb, ifa);
1938 	/*
1939 	 * check address scope if address is out of scope, don't queue
1940 	 * anything... note: this would leave the address on both inp and
1941 	 * asoc lists
1942 	 */
1943 	switch (ifa->address.sa.sa_family) {
1944 #ifdef INET6
1945 	case AF_INET6:
1946 		{
1947 			struct sockaddr_in6 *sin6;
1948 
1949 			sin6 = &ifa->address.sin6;
1950 			if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
1951 				/* we skip unspecifed addresses */
1952 				return;
1953 			}
1954 			if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
1955 				if (stcb->asoc.scope.local_scope == 0) {
1956 					return;
1957 				}
1958 				/* is it the right link local scope? */
1959 				if (sctp_is_scopeid_in_nets(stcb, &ifa->address.sa) == 0) {
1960 					return;
1961 				}
1962 			}
1963 			if (stcb->asoc.scope.site_scope == 0 &&
1964 			    IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) {
1965 				return;
1966 			}
1967 			break;
1968 		}
1969 #endif
1970 #ifdef INET
1971 	case AF_INET:
1972 		{
1973 			struct sockaddr_in *sin;
1974 
1975 			/* invalid if we are a v6 only endpoint */
1976 			if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
1977 			    SCTP_IPV6_V6ONLY(inp))
1978 				return;
1979 
1980 			sin = &ifa->address.sin;
1981 			if (sin->sin_addr.s_addr == 0) {
1982 				/* we skip unspecifed addresses */
1983 				return;
1984 			}
1985 			if (stcb->asoc.scope.ipv4_local_scope == 0 &&
1986 			    IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
1987 				return;
1988 			}
1989 			break;
1990 		}
1991 #endif
1992 	default:
1993 		/* else, not AF_INET or AF_INET6, so skip */
1994 		return;
1995 	}
1996 
1997 	/* queue an asconf for this address add/delete */
1998 	if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_DO_ASCONF)) {
1999 		/* does the peer do asconf? */
2000 		if (stcb->asoc.asconf_supported) {
2001 			/* queue an asconf for this addr */
2002 			status = sctp_asconf_queue_add(stcb, ifa, type);
2003 
2004 			/*
2005 			 * if queued ok, and in the open state, send out the
2006 			 * ASCONF.  If in the non-open state, these will be
2007 			 * sent when the state goes open.
2008 			 */
2009 			if (status == 0 &&
2010 			    ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) ||
2011 			    (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_RECEIVED))) {
2012 #ifdef SCTP_TIMER_BASED_ASCONF
2013 				sctp_timer_start(SCTP_TIMER_TYPE_ASCONF, inp,
2014 				    stcb, stcb->asoc.primary_destination);
2015 #else
2016 				sctp_send_asconf(stcb, NULL, addr_locked);
2017 #endif
2018 			}
2019 		}
2020 	}
2021 }
2022 
2023 
2024 int
2025 sctp_asconf_iterator_ep(struct sctp_inpcb *inp, void *ptr, uint32_t val SCTP_UNUSED)
2026 {
2027 	struct sctp_asconf_iterator *asc;
2028 	struct sctp_ifa *ifa;
2029 	struct sctp_laddr *l;
2030 	int cnt_invalid = 0;
2031 
2032 	asc = (struct sctp_asconf_iterator *)ptr;
2033 	LIST_FOREACH(l, &asc->list_of_work, sctp_nxt_addr) {
2034 		ifa = l->ifa;
2035 		switch (ifa->address.sa.sa_family) {
2036 #ifdef INET6
2037 		case AF_INET6:
2038 			/* invalid if we're not a v6 endpoint */
2039 			if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) {
2040 				cnt_invalid++;
2041 				if (asc->cnt == cnt_invalid)
2042 					return (1);
2043 			}
2044 			break;
2045 #endif
2046 #ifdef INET
2047 		case AF_INET:
2048 			{
2049 				/* invalid if we are a v6 only endpoint */
2050 				if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
2051 				    SCTP_IPV6_V6ONLY(inp)) {
2052 					cnt_invalid++;
2053 					if (asc->cnt == cnt_invalid)
2054 						return (1);
2055 				}
2056 				break;
2057 			}
2058 #endif
2059 		default:
2060 			/* invalid address family */
2061 			cnt_invalid++;
2062 			if (asc->cnt == cnt_invalid)
2063 				return (1);
2064 		}
2065 	}
2066 	return (0);
2067 }
2068 
2069 static int
2070 sctp_asconf_iterator_ep_end(struct sctp_inpcb *inp, void *ptr, uint32_t val SCTP_UNUSED)
2071 {
2072 	struct sctp_ifa *ifa;
2073 	struct sctp_asconf_iterator *asc;
2074 	struct sctp_laddr *laddr, *nladdr, *l;
2075 
2076 	/* Only for specific case not bound all */
2077 	asc = (struct sctp_asconf_iterator *)ptr;
2078 	LIST_FOREACH(l, &asc->list_of_work, sctp_nxt_addr) {
2079 		ifa = l->ifa;
2080 		if (l->action == SCTP_ADD_IP_ADDRESS) {
2081 			LIST_FOREACH(laddr, &inp->sctp_addr_list,
2082 			    sctp_nxt_addr) {
2083 				if (laddr->ifa == ifa) {
2084 					laddr->action = 0;
2085 					break;
2086 				}
2087 
2088 			}
2089 		} else if (l->action == SCTP_DEL_IP_ADDRESS) {
2090 			LIST_FOREACH_SAFE(laddr, &inp->sctp_addr_list, sctp_nxt_addr, nladdr) {
2091 				/* remove only after all guys are done */
2092 				if (laddr->ifa == ifa) {
2093 					sctp_del_local_addr_ep(inp, ifa);
2094 				}
2095 			}
2096 		}
2097 	}
2098 	return (0);
2099 }
2100 
2101 void
2102 sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
2103     void *ptr, uint32_t val SCTP_UNUSED)
2104 {
2105 	struct sctp_asconf_iterator *asc;
2106 	struct sctp_ifa *ifa;
2107 	struct sctp_laddr *l;
2108 	int cnt_invalid = 0;
2109 	int type, status;
2110 	int num_queued = 0;
2111 
2112 	asc = (struct sctp_asconf_iterator *)ptr;
2113 	LIST_FOREACH(l, &asc->list_of_work, sctp_nxt_addr) {
2114 		ifa = l->ifa;
2115 		type = l->action;
2116 
2117 		/* address's vrf_id must be the vrf_id of the assoc */
2118 		if (ifa->vrf_id != stcb->asoc.vrf_id) {
2119 			continue;
2120 		}
2121 
2122 		/* Same checks again for assoc */
2123 		switch (ifa->address.sa.sa_family) {
2124 #ifdef INET6
2125 		case AF_INET6:
2126 			{
2127 				/* invalid if we're not a v6 endpoint */
2128 				struct sockaddr_in6 *sin6;
2129 
2130 				if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) {
2131 					cnt_invalid++;
2132 					if (asc->cnt == cnt_invalid)
2133 						return;
2134 					else
2135 						continue;
2136 				}
2137 				sin6 = &ifa->address.sin6;
2138 				if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
2139 					/* we skip unspecifed addresses */
2140 					continue;
2141 				}
2142 				if (prison_check_ip6(inp->ip_inp.inp.inp_cred,
2143 				    &sin6->sin6_addr) != 0) {
2144 					continue;
2145 				}
2146 				if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
2147 					if (stcb->asoc.scope.local_scope == 0) {
2148 						continue;
2149 					}
2150 					/* is it the right link local scope? */
2151 					if (sctp_is_scopeid_in_nets(stcb, &ifa->address.sa) == 0) {
2152 						continue;
2153 					}
2154 				}
2155 				break;
2156 			}
2157 #endif
2158 #ifdef INET
2159 		case AF_INET:
2160 			{
2161 				/* invalid if we are a v6 only endpoint */
2162 				struct sockaddr_in *sin;
2163 
2164 				/* invalid if we are a v6 only endpoint */
2165 				if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
2166 				    SCTP_IPV6_V6ONLY(inp))
2167 					continue;
2168 
2169 				sin = &ifa->address.sin;
2170 				if (sin->sin_addr.s_addr == 0) {
2171 					/* we skip unspecifed addresses */
2172 					continue;
2173 				}
2174 				if (prison_check_ip4(inp->ip_inp.inp.inp_cred,
2175 				    &sin->sin_addr) != 0) {
2176 					continue;
2177 				}
2178 				if (stcb->asoc.scope.ipv4_local_scope == 0 &&
2179 				    IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
2180 					continue;
2181 				}
2182 				if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
2183 				    SCTP_IPV6_V6ONLY(inp)) {
2184 					cnt_invalid++;
2185 					if (asc->cnt == cnt_invalid)
2186 						return;
2187 					else
2188 						continue;
2189 				}
2190 				break;
2191 			}
2192 #endif
2193 		default:
2194 			/* invalid address family */
2195 			cnt_invalid++;
2196 			if (asc->cnt == cnt_invalid)
2197 				return;
2198 			else
2199 				continue;
2200 			break;
2201 		}
2202 
2203 		if (type == SCTP_ADD_IP_ADDRESS) {
2204 			/* prevent this address from being used as a source */
2205 			sctp_add_local_addr_restricted(stcb, ifa);
2206 		} else if (type == SCTP_DEL_IP_ADDRESS) {
2207 			struct sctp_nets *net;
2208 
2209 			TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
2210 
2211 				/* delete this address if cached */
2212 				if (net->ro._s_addr == ifa) {
2213 					sctp_free_ifa(net->ro._s_addr);
2214 					net->ro._s_addr = NULL;
2215 					net->src_addr_selected = 0;
2216 					RO_NHFREE(&net->ro);
2217 					/*
2218 					 * Now we deleted our src address,
2219 					 * should we not also now reset the
2220 					 * cwnd/rto to start as if its a new
2221 					 * address?
2222 					 */
2223 					stcb->asoc.cc_functions.sctp_set_initial_cc_param(stcb, net);
2224 					net->RTO = 0;
2225 
2226 				}
2227 			}
2228 		} else if (type == SCTP_SET_PRIM_ADDR) {
2229 			if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) {
2230 				/* must validate the ifa is in the ep */
2231 				if (sctp_is_addr_in_ep(stcb->sctp_ep, ifa) == 0) {
2232 					continue;
2233 				}
2234 			} else {
2235 				/* Need to check scopes for this guy */
2236 				if (sctp_is_address_in_scope(ifa, &stcb->asoc.scope, 0) == 0) {
2237 					continue;
2238 				}
2239 			}
2240 		}
2241 		/* queue an asconf for this address add/delete */
2242 		if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_DO_ASCONF) &&
2243 		    stcb->asoc.asconf_supported == 1) {
2244 			/* queue an asconf for this addr */
2245 			status = sctp_asconf_queue_add(stcb, ifa, type);
2246 			/*
2247 			 * if queued ok, and in the open state, update the
2248 			 * count of queued params.  If in the non-open
2249 			 * state, these get sent when the assoc goes open.
2250 			 */
2251 			if ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) ||
2252 			    (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
2253 				if (status >= 0) {
2254 					num_queued++;
2255 				}
2256 			}
2257 		}
2258 	}
2259 	/*
2260 	 * If we have queued params in the open state, send out an ASCONF.
2261 	 */
2262 	if (num_queued > 0) {
2263 		sctp_send_asconf(stcb, NULL, SCTP_ADDR_NOT_LOCKED);
2264 	}
2265 }
2266 
2267 void
2268 sctp_asconf_iterator_end(void *ptr, uint32_t val SCTP_UNUSED)
2269 {
2270 	struct sctp_asconf_iterator *asc;
2271 	struct sctp_ifa *ifa;
2272 	struct sctp_laddr *l, *nl;
2273 
2274 	asc = (struct sctp_asconf_iterator *)ptr;
2275 	LIST_FOREACH_SAFE(l, &asc->list_of_work, sctp_nxt_addr, nl) {
2276 		ifa = l->ifa;
2277 		if (l->action == SCTP_ADD_IP_ADDRESS) {
2278 			/* Clear the defer use flag */
2279 			ifa->localifa_flags &= ~SCTP_ADDR_DEFER_USE;
2280 		}
2281 		sctp_free_ifa(ifa);
2282 		SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_laddr), l);
2283 		SCTP_DECR_LADDR_COUNT();
2284 	}
2285 	SCTP_FREE(asc, SCTP_M_ASC_IT);
2286 }
2287 
2288 /*
2289  * sa is the sockaddr to ask the peer to set primary to.
2290  * returns: 0 = completed, -1 = error
2291  */
2292 int32_t
2293 sctp_set_primary_ip_address_sa(struct sctp_tcb *stcb, struct sockaddr *sa)
2294 {
2295 	uint32_t vrf_id;
2296 	struct sctp_ifa *ifa;
2297 
2298 	/* find the ifa for the desired set primary */
2299 	vrf_id = stcb->asoc.vrf_id;
2300 	ifa = sctp_find_ifa_by_addr(sa, vrf_id, SCTP_ADDR_NOT_LOCKED);
2301 	if (ifa == NULL) {
2302 		/* Invalid address */
2303 		return (-1);
2304 	}
2305 
2306 	/* queue an ASCONF:SET_PRIM_ADDR to be sent */
2307 	if (!sctp_asconf_queue_add(stcb, ifa, SCTP_SET_PRIM_ADDR)) {
2308 		/* set primary queuing succeeded */
2309 		SCTPDBG(SCTP_DEBUG_ASCONF1,
2310 		    "set_primary_ip_address_sa: queued on tcb=%p, ",
2311 		    (void *)stcb);
2312 		SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
2313 		if ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) ||
2314 		    (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
2315 #ifdef SCTP_TIMER_BASED_ASCONF
2316 			sctp_timer_start(SCTP_TIMER_TYPE_ASCONF,
2317 			    stcb->sctp_ep, stcb,
2318 			    stcb->asoc.primary_destination);
2319 #else
2320 			sctp_send_asconf(stcb, NULL, SCTP_ADDR_NOT_LOCKED);
2321 #endif
2322 		}
2323 	} else {
2324 		SCTPDBG(SCTP_DEBUG_ASCONF1, "set_primary_ip_address_sa: failed to add to queue on tcb=%p, ",
2325 		    (void *)stcb);
2326 		SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
2327 		return (-1);
2328 	}
2329 	return (0);
2330 }
2331 
2332 int
2333 sctp_is_addr_pending(struct sctp_tcb *stcb, struct sctp_ifa *sctp_ifa)
2334 {
2335 	struct sctp_tmit_chunk *chk, *nchk;
2336 	unsigned int offset, asconf_limit;
2337 	struct sctp_asconf_chunk *acp;
2338 	struct sctp_asconf_paramhdr *aph;
2339 	uint8_t aparam_buf[SCTP_PARAM_BUFFER_SIZE];
2340 	struct sctp_paramhdr *ph;
2341 	int add_cnt, del_cnt;
2342 	uint16_t last_param_type;
2343 
2344 	add_cnt = del_cnt = 0;
2345 	last_param_type = 0;
2346 	TAILQ_FOREACH_SAFE(chk, &stcb->asoc.asconf_send_queue, sctp_next, nchk) {
2347 		if (chk->data == NULL) {
2348 			SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: No mbuf data?\n");
2349 			continue;
2350 		}
2351 		offset = 0;
2352 		acp = mtod(chk->data, struct sctp_asconf_chunk *);
2353 		offset += sizeof(struct sctp_asconf_chunk);
2354 		asconf_limit = ntohs(acp->ch.chunk_length);
2355 		ph = (struct sctp_paramhdr *)sctp_m_getptr(chk->data, offset, sizeof(struct sctp_paramhdr), aparam_buf);
2356 		if (ph == NULL) {
2357 			SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: couldn't get lookup addr!\n");
2358 			continue;
2359 		}
2360 		offset += ntohs(ph->param_length);
2361 
2362 		aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(chk->data, offset, sizeof(struct sctp_asconf_paramhdr), aparam_buf);
2363 		if (aph == NULL) {
2364 			SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: Empty ASCONF will be sent?\n");
2365 			continue;
2366 		}
2367 		while (aph != NULL) {
2368 			unsigned int param_length, param_type;
2369 
2370 			param_type = ntohs(aph->ph.param_type);
2371 			param_length = ntohs(aph->ph.param_length);
2372 			if (offset + param_length > asconf_limit) {
2373 				/* parameter goes beyond end of chunk! */
2374 				break;
2375 			}
2376 			if (param_length > sizeof(aparam_buf)) {
2377 				SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: param length (%u) larger than buffer size!\n", param_length);
2378 				break;
2379 			}
2380 			if (param_length <= sizeof(struct sctp_paramhdr)) {
2381 				SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: param length(%u) too short\n", param_length);
2382 				break;
2383 			}
2384 
2385 			aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(chk->data, offset, param_length, aparam_buf);
2386 			if (aph == NULL) {
2387 				SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: couldn't get entire param\n");
2388 				break;
2389 			}
2390 
2391 			ph = (struct sctp_paramhdr *)(aph + 1);
2392 			if (sctp_addr_match(ph, &sctp_ifa->address.sa) != 0) {
2393 				switch (param_type) {
2394 				case SCTP_ADD_IP_ADDRESS:
2395 					add_cnt++;
2396 					break;
2397 				case SCTP_DEL_IP_ADDRESS:
2398 					del_cnt++;
2399 					break;
2400 				default:
2401 					break;
2402 				}
2403 				last_param_type = param_type;
2404 			}
2405 
2406 			offset += SCTP_SIZE32(param_length);
2407 			if (offset >= asconf_limit) {
2408 				/* no more data in the mbuf chain */
2409 				break;
2410 			}
2411 			/* get pointer to next asconf param */
2412 			aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(chk->data, offset, sizeof(struct sctp_asconf_paramhdr), aparam_buf);
2413 		}
2414 	}
2415 
2416 	/*
2417 	 * we want to find the sequences which consist of ADD -> DEL -> ADD
2418 	 * or DEL -> ADD
2419 	 */
2420 	if (add_cnt > del_cnt ||
2421 	    (add_cnt == del_cnt && last_param_type == SCTP_ADD_IP_ADDRESS)) {
2422 		return (1);
2423 	}
2424 	return (0);
2425 }
2426 
2427 static struct sockaddr *
2428 sctp_find_valid_localaddr(struct sctp_tcb *stcb, int addr_locked)
2429 {
2430 	struct sctp_vrf *vrf = NULL;
2431 	struct sctp_ifn *sctp_ifn;
2432 	struct sctp_ifa *sctp_ifa;
2433 
2434 	if (addr_locked == SCTP_ADDR_NOT_LOCKED)
2435 		SCTP_IPI_ADDR_RLOCK();
2436 	vrf = sctp_find_vrf(stcb->asoc.vrf_id);
2437 	if (vrf == NULL) {
2438 		if (addr_locked == SCTP_ADDR_NOT_LOCKED)
2439 			SCTP_IPI_ADDR_RUNLOCK();
2440 		return (NULL);
2441 	}
2442 	LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) {
2443 		if (stcb->asoc.scope.loopback_scope == 0 &&
2444 		    SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) {
2445 			/* Skip if loopback_scope not set */
2446 			continue;
2447 		}
2448 		LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
2449 			switch (sctp_ifa->address.sa.sa_family) {
2450 #ifdef INET
2451 			case AF_INET:
2452 				if (stcb->asoc.scope.ipv4_addr_legal) {
2453 					struct sockaddr_in *sin;
2454 
2455 					sin = &sctp_ifa->address.sin;
2456 					if (sin->sin_addr.s_addr == 0) {
2457 						/* skip unspecifed addresses */
2458 						continue;
2459 					}
2460 					if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred,
2461 					    &sin->sin_addr) != 0) {
2462 						continue;
2463 					}
2464 					if (stcb->asoc.scope.ipv4_local_scope == 0 &&
2465 					    IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))
2466 						continue;
2467 
2468 					if (sctp_is_addr_restricted(stcb, sctp_ifa) &&
2469 					    (!sctp_is_addr_pending(stcb, sctp_ifa)))
2470 						continue;
2471 					/*
2472 					 * found a valid local v4 address to
2473 					 * use
2474 					 */
2475 					if (addr_locked == SCTP_ADDR_NOT_LOCKED)
2476 						SCTP_IPI_ADDR_RUNLOCK();
2477 					return (&sctp_ifa->address.sa);
2478 				}
2479 				break;
2480 #endif
2481 #ifdef INET6
2482 			case AF_INET6:
2483 				if (stcb->asoc.scope.ipv6_addr_legal) {
2484 					struct sockaddr_in6 *sin6;
2485 
2486 					if (sctp_ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
2487 						continue;
2488 					}
2489 
2490 					sin6 = &sctp_ifa->address.sin6;
2491 					if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
2492 						/*
2493 						 * we skip unspecifed
2494 						 * addresses
2495 						 */
2496 						continue;
2497 					}
2498 					if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred,
2499 					    &sin6->sin6_addr) != 0) {
2500 						continue;
2501 					}
2502 					if (stcb->asoc.scope.local_scope == 0 &&
2503 					    IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
2504 						continue;
2505 					if (stcb->asoc.scope.site_scope == 0 &&
2506 					    IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))
2507 						continue;
2508 
2509 					if (sctp_is_addr_restricted(stcb, sctp_ifa) &&
2510 					    (!sctp_is_addr_pending(stcb, sctp_ifa)))
2511 						continue;
2512 					/*
2513 					 * found a valid local v6 address to
2514 					 * use
2515 					 */
2516 					if (addr_locked == SCTP_ADDR_NOT_LOCKED)
2517 						SCTP_IPI_ADDR_RUNLOCK();
2518 					return (&sctp_ifa->address.sa);
2519 				}
2520 				break;
2521 #endif
2522 			default:
2523 				break;
2524 			}
2525 		}
2526 	}
2527 	/* no valid addresses found */
2528 	if (addr_locked == SCTP_ADDR_NOT_LOCKED)
2529 		SCTP_IPI_ADDR_RUNLOCK();
2530 	return (NULL);
2531 }
2532 
2533 static struct sockaddr *
2534 sctp_find_valid_localaddr_ep(struct sctp_tcb *stcb)
2535 {
2536 	struct sctp_laddr *laddr;
2537 
2538 	LIST_FOREACH(laddr, &stcb->sctp_ep->sctp_addr_list, sctp_nxt_addr) {
2539 		if (laddr->ifa == NULL) {
2540 			continue;
2541 		}
2542 		/* is the address restricted ? */
2543 		if (sctp_is_addr_restricted(stcb, laddr->ifa) &&
2544 		    (!sctp_is_addr_pending(stcb, laddr->ifa)))
2545 			continue;
2546 
2547 		/* found a valid local address to use */
2548 		return (&laddr->ifa->address.sa);
2549 	}
2550 	/* no valid addresses found */
2551 	return (NULL);
2552 }
2553 
2554 /*
2555  * builds an ASCONF chunk from queued ASCONF params.
2556  * returns NULL on error (no mbuf, no ASCONF params queued, etc).
2557  */
2558 struct mbuf *
2559 sctp_compose_asconf(struct sctp_tcb *stcb, int *retlen, int addr_locked)
2560 {
2561 	struct mbuf *m_asconf, *m_asconf_chk;
2562 	struct sctp_asconf_addr *aa;
2563 	struct sctp_asconf_chunk *acp;
2564 	struct sctp_asconf_paramhdr *aph;
2565 	struct sctp_asconf_addr_param *aap;
2566 	uint32_t p_length;
2567 	uint32_t correlation_id = 1;	/* 0 is reserved... */
2568 	caddr_t ptr, lookup_ptr;
2569 	uint8_t lookup_used = 0;
2570 
2571 	/* are there any asconf params to send? */
2572 	TAILQ_FOREACH(aa, &stcb->asoc.asconf_queue, next) {
2573 		if (aa->sent == 0)
2574 			break;
2575 	}
2576 	if (aa == NULL)
2577 		return (NULL);
2578 
2579 	/*
2580 	 * get a chunk header mbuf and a cluster for the asconf params since
2581 	 * it's simpler to fill in the asconf chunk header lookup address on
2582 	 * the fly
2583 	 */
2584 	m_asconf_chk = sctp_get_mbuf_for_msg(sizeof(struct sctp_asconf_chunk), 0, M_NOWAIT, 1, MT_DATA);
2585 	if (m_asconf_chk == NULL) {
2586 		/* no mbuf's */
2587 		SCTPDBG(SCTP_DEBUG_ASCONF1,
2588 		    "compose_asconf: couldn't get chunk mbuf!\n");
2589 		return (NULL);
2590 	}
2591 	m_asconf = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_NOWAIT, 1, MT_DATA);
2592 	if (m_asconf == NULL) {
2593 		/* no mbuf's */
2594 		SCTPDBG(SCTP_DEBUG_ASCONF1,
2595 		    "compose_asconf: couldn't get mbuf!\n");
2596 		sctp_m_freem(m_asconf_chk);
2597 		return (NULL);
2598 	}
2599 	SCTP_BUF_LEN(m_asconf_chk) = sizeof(struct sctp_asconf_chunk);
2600 	SCTP_BUF_LEN(m_asconf) = 0;
2601 	acp = mtod(m_asconf_chk, struct sctp_asconf_chunk *);
2602 	memset(acp, 0, sizeof(struct sctp_asconf_chunk));
2603 	/* save pointers to lookup address and asconf params */
2604 	lookup_ptr = (caddr_t)(acp + 1);	/* after the header */
2605 	ptr = mtod(m_asconf, caddr_t);	/* beginning of cluster */
2606 
2607 	/* fill in chunk header info */
2608 	acp->ch.chunk_type = SCTP_ASCONF;
2609 	acp->ch.chunk_flags = 0;
2610 	acp->serial_number = htonl(stcb->asoc.asconf_seq_out);
2611 	stcb->asoc.asconf_seq_out++;
2612 
2613 	/* add parameters... up to smallest MTU allowed */
2614 	TAILQ_FOREACH(aa, &stcb->asoc.asconf_queue, next) {
2615 		if (aa->sent)
2616 			continue;
2617 		/* get the parameter length */
2618 		p_length = SCTP_SIZE32(aa->ap.aph.ph.param_length);
2619 		/* will it fit in current chunk? */
2620 		if ((SCTP_BUF_LEN(m_asconf) + p_length > stcb->asoc.smallest_mtu) ||
2621 		    (SCTP_BUF_LEN(m_asconf) + p_length > MCLBYTES)) {
2622 			/* won't fit, so we're done with this chunk */
2623 			break;
2624 		}
2625 		/* assign (and store) a correlation id */
2626 		aa->ap.aph.correlation_id = correlation_id++;
2627 
2628 		/*
2629 		 * fill in address if we're doing a delete this is a simple
2630 		 * way for us to fill in the correlation address, which
2631 		 * should only be used by the peer if we're deleting our
2632 		 * source address and adding a new address (e.g. renumbering
2633 		 * case)
2634 		 */
2635 		if (lookup_used == 0 &&
2636 		    (aa->special_del == 0) &&
2637 		    aa->ap.aph.ph.param_type == SCTP_DEL_IP_ADDRESS) {
2638 			struct sctp_ipv6addr_param *lookup;
2639 			uint16_t p_size, addr_size;
2640 
2641 			lookup = (struct sctp_ipv6addr_param *)lookup_ptr;
2642 			lookup->ph.param_type =
2643 			    htons(aa->ap.addrp.ph.param_type);
2644 			if (aa->ap.addrp.ph.param_type == SCTP_IPV6_ADDRESS) {
2645 				/* copy IPv6 address */
2646 				p_size = sizeof(struct sctp_ipv6addr_param);
2647 				addr_size = sizeof(struct in6_addr);
2648 			} else {
2649 				/* copy IPv4 address */
2650 				p_size = sizeof(struct sctp_ipv4addr_param);
2651 				addr_size = sizeof(struct in_addr);
2652 			}
2653 			lookup->ph.param_length = htons(SCTP_SIZE32(p_size));
2654 			memcpy(lookup->addr, &aa->ap.addrp.addr, addr_size);
2655 			SCTP_BUF_LEN(m_asconf_chk) += SCTP_SIZE32(p_size);
2656 			lookup_used = 1;
2657 		}
2658 		/* copy into current space */
2659 		memcpy(ptr, &aa->ap, p_length);
2660 
2661 		/* network elements and update lengths */
2662 		aph = (struct sctp_asconf_paramhdr *)ptr;
2663 		aap = (struct sctp_asconf_addr_param *)ptr;
2664 		/* correlation_id is transparent to peer, no htonl needed */
2665 		aph->ph.param_type = htons(aph->ph.param_type);
2666 		aph->ph.param_length = htons(aph->ph.param_length);
2667 		aap->addrp.ph.param_type = htons(aap->addrp.ph.param_type);
2668 		aap->addrp.ph.param_length = htons(aap->addrp.ph.param_length);
2669 
2670 		SCTP_BUF_LEN(m_asconf) += SCTP_SIZE32(p_length);
2671 		ptr += SCTP_SIZE32(p_length);
2672 
2673 		/*
2674 		 * these params are removed off the pending list upon
2675 		 * getting an ASCONF-ACK back from the peer, just set flag
2676 		 */
2677 		aa->sent = 1;
2678 	}
2679 	/* check to see if the lookup addr has been populated yet */
2680 	if (lookup_used == 0) {
2681 		/* NOTE: if the address param is optional, can skip this... */
2682 		/* add any valid (existing) address... */
2683 		struct sctp_ipv6addr_param *lookup;
2684 		uint16_t p_size, addr_size;
2685 		struct sockaddr *found_addr;
2686 		caddr_t addr_ptr;
2687 
2688 		if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL)
2689 			found_addr = sctp_find_valid_localaddr(stcb,
2690 			    addr_locked);
2691 		else
2692 			found_addr = sctp_find_valid_localaddr_ep(stcb);
2693 
2694 		lookup = (struct sctp_ipv6addr_param *)lookup_ptr;
2695 		if (found_addr != NULL) {
2696 			switch (found_addr->sa_family) {
2697 #ifdef INET6
2698 			case AF_INET6:
2699 				/* copy IPv6 address */
2700 				lookup->ph.param_type =
2701 				    htons(SCTP_IPV6_ADDRESS);
2702 				p_size = sizeof(struct sctp_ipv6addr_param);
2703 				addr_size = sizeof(struct in6_addr);
2704 				addr_ptr = (caddr_t)&((struct sockaddr_in6 *)
2705 				    found_addr)->sin6_addr;
2706 				break;
2707 #endif
2708 #ifdef INET
2709 			case AF_INET:
2710 				/* copy IPv4 address */
2711 				lookup->ph.param_type =
2712 				    htons(SCTP_IPV4_ADDRESS);
2713 				p_size = sizeof(struct sctp_ipv4addr_param);
2714 				addr_size = sizeof(struct in_addr);
2715 				addr_ptr = (caddr_t)&((struct sockaddr_in *)
2716 				    found_addr)->sin_addr;
2717 				break;
2718 #endif
2719 			default:
2720 				p_size = 0;
2721 				addr_size = 0;
2722 				addr_ptr = NULL;
2723 				break;
2724 			}
2725 			lookup->ph.param_length = htons(SCTP_SIZE32(p_size));
2726 			memcpy(lookup->addr, addr_ptr, addr_size);
2727 			SCTP_BUF_LEN(m_asconf_chk) += SCTP_SIZE32(p_size);
2728 		} else {
2729 			/* uh oh... don't have any address?? */
2730 			SCTPDBG(SCTP_DEBUG_ASCONF1,
2731 			    "compose_asconf: no lookup addr!\n");
2732 			/* XXX for now, we send a IPv4 address of 0.0.0.0 */
2733 			lookup->ph.param_type = htons(SCTP_IPV4_ADDRESS);
2734 			lookup->ph.param_length = htons(SCTP_SIZE32(sizeof(struct sctp_ipv4addr_param)));
2735 			memset(lookup->addr, 0, sizeof(struct in_addr));
2736 			SCTP_BUF_LEN(m_asconf_chk) += SCTP_SIZE32(sizeof(struct sctp_ipv4addr_param));
2737 		}
2738 	}
2739 	/* chain it all together */
2740 	SCTP_BUF_NEXT(m_asconf_chk) = m_asconf;
2741 	*retlen = SCTP_BUF_LEN(m_asconf_chk) + SCTP_BUF_LEN(m_asconf);
2742 	acp->ch.chunk_length = htons(*retlen);
2743 
2744 	return (m_asconf_chk);
2745 }
2746 
2747 /*
2748  * section to handle address changes before an association is up eg. changes
2749  * during INIT/INIT-ACK/COOKIE-ECHO handshake
2750  */
2751 
2752 /*
2753  * processes the (local) addresses in the INIT-ACK chunk
2754  */
2755 static void
2756 sctp_process_initack_addresses(struct sctp_tcb *stcb, struct mbuf *m,
2757     unsigned int offset, unsigned int length)
2758 {
2759 	struct sctp_paramhdr tmp_param, *ph;
2760 	uint16_t plen, ptype;
2761 	struct sctp_ifa *sctp_ifa;
2762 	union sctp_sockstore store;
2763 #ifdef INET6
2764 	struct sctp_ipv6addr_param addr6_store;
2765 #endif
2766 #ifdef INET
2767 	struct sctp_ipv4addr_param addr4_store;
2768 #endif
2769 
2770 	SCTPDBG(SCTP_DEBUG_ASCONF2, "processing init-ack addresses\n");
2771 	if (stcb == NULL)	/* Un-needed check for SA */
2772 		return;
2773 
2774 	/* convert to upper bound */
2775 	length += offset;
2776 
2777 	if ((offset + sizeof(struct sctp_paramhdr)) > length) {
2778 		return;
2779 	}
2780 	/* go through the addresses in the init-ack */
2781 	ph = (struct sctp_paramhdr *)
2782 	    sctp_m_getptr(m, offset, sizeof(struct sctp_paramhdr),
2783 	    (uint8_t *)&tmp_param);
2784 	while (ph != NULL) {
2785 		ptype = ntohs(ph->param_type);
2786 		plen = ntohs(ph->param_length);
2787 		switch (ptype) {
2788 #ifdef INET6
2789 		case SCTP_IPV6_ADDRESS:
2790 			{
2791 				struct sctp_ipv6addr_param *a6p;
2792 
2793 				/* get the entire IPv6 address param */
2794 				a6p = (struct sctp_ipv6addr_param *)
2795 				    sctp_m_getptr(m, offset,
2796 				    sizeof(struct sctp_ipv6addr_param),
2797 				    (uint8_t *)&addr6_store);
2798 				if (plen != sizeof(struct sctp_ipv6addr_param) ||
2799 				    a6p == NULL) {
2800 					return;
2801 				}
2802 				memset(&store, 0, sizeof(union sctp_sockstore));
2803 				store.sin6.sin6_family = AF_INET6;
2804 				store.sin6.sin6_len = sizeof(struct sockaddr_in6);
2805 				store.sin6.sin6_port = stcb->rport;
2806 				memcpy(&store.sin6.sin6_addr, a6p->addr, sizeof(struct in6_addr));
2807 				break;
2808 			}
2809 #endif
2810 #ifdef INET
2811 		case SCTP_IPV4_ADDRESS:
2812 			{
2813 				struct sctp_ipv4addr_param *a4p;
2814 
2815 				/* get the entire IPv4 address param */
2816 				a4p = (struct sctp_ipv4addr_param *)sctp_m_getptr(m, offset,
2817 				    sizeof(struct sctp_ipv4addr_param),
2818 				    (uint8_t *)&addr4_store);
2819 				if (plen != sizeof(struct sctp_ipv4addr_param) ||
2820 				    a4p == NULL) {
2821 					return;
2822 				}
2823 				memset(&store, 0, sizeof(union sctp_sockstore));
2824 				store.sin.sin_family = AF_INET;
2825 				store.sin.sin_len = sizeof(struct sockaddr_in);
2826 				store.sin.sin_port = stcb->rport;
2827 				store.sin.sin_addr.s_addr = a4p->addr;
2828 				break;
2829 			}
2830 #endif
2831 		default:
2832 			goto next_addr;
2833 		}
2834 
2835 		/* see if this address really (still) exists */
2836 		sctp_ifa = sctp_find_ifa_by_addr(&store.sa, stcb->asoc.vrf_id,
2837 		    SCTP_ADDR_NOT_LOCKED);
2838 		if (sctp_ifa == NULL) {
2839 			/* address doesn't exist anymore */
2840 			int status;
2841 
2842 			/* are ASCONFs allowed ? */
2843 			if ((sctp_is_feature_on(stcb->sctp_ep,
2844 			    SCTP_PCB_FLAGS_DO_ASCONF)) &&
2845 			    stcb->asoc.asconf_supported) {
2846 				/* queue an ASCONF DEL_IP_ADDRESS */
2847 				status = sctp_asconf_queue_sa_delete(stcb, &store.sa);
2848 				/*
2849 				 * if queued ok, and in correct state, send
2850 				 * out the ASCONF.
2851 				 */
2852 				if (status == 0 &&
2853 				    SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) {
2854 #ifdef SCTP_TIMER_BASED_ASCONF
2855 					sctp_timer_start(SCTP_TIMER_TYPE_ASCONF,
2856 					    stcb->sctp_ep, stcb,
2857 					    stcb->asoc.primary_destination);
2858 #else
2859 					sctp_send_asconf(stcb, NULL, SCTP_ADDR_NOT_LOCKED);
2860 #endif
2861 				}
2862 			}
2863 		}
2864 
2865 next_addr:
2866 		/*
2867 		 * Sanity check:  Make sure the length isn't 0, otherwise
2868 		 * we'll be stuck in this loop for a long time...
2869 		 */
2870 		if (SCTP_SIZE32(plen) == 0) {
2871 			SCTP_PRINTF("process_initack_addrs: bad len (%d) type=%xh\n",
2872 			    plen, ptype);
2873 			return;
2874 		}
2875 		/* get next parameter */
2876 		offset += SCTP_SIZE32(plen);
2877 		if ((offset + sizeof(struct sctp_paramhdr)) > length)
2878 			return;
2879 		ph = (struct sctp_paramhdr *)sctp_m_getptr(m, offset,
2880 		    sizeof(struct sctp_paramhdr), (uint8_t *)&tmp_param);
2881 	}			/* while */
2882 }
2883 
2884 /* FIX ME: need to verify return result for v6 address type if v6 disabled */
2885 /*
2886  * checks to see if a specific address is in the initack address list returns
2887  * 1 if found, 0 if not
2888  */
2889 static uint32_t
2890 sctp_addr_in_initack(struct mbuf *m, uint32_t offset, uint32_t length, struct sockaddr *sa)
2891 {
2892 	struct sctp_paramhdr tmp_param, *ph;
2893 	uint16_t plen, ptype;
2894 #ifdef INET
2895 	struct sockaddr_in *sin;
2896 	struct sctp_ipv4addr_param *a4p;
2897 	struct sctp_ipv6addr_param addr4_store;
2898 #endif
2899 #ifdef INET6
2900 	struct sockaddr_in6 *sin6;
2901 	struct sctp_ipv6addr_param *a6p;
2902 	struct sctp_ipv6addr_param addr6_store;
2903 	struct sockaddr_in6 sin6_tmp;
2904 #endif
2905 
2906 	switch (sa->sa_family) {
2907 #ifdef INET
2908 	case AF_INET:
2909 		break;
2910 #endif
2911 #ifdef INET6
2912 	case AF_INET6:
2913 		break;
2914 #endif
2915 	default:
2916 		return (0);
2917 	}
2918 
2919 	SCTPDBG(SCTP_DEBUG_ASCONF2, "find_initack_addr: starting search for ");
2920 	SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, sa);
2921 	/* convert to upper bound */
2922 	length += offset;
2923 
2924 	if ((offset + sizeof(struct sctp_paramhdr)) > length) {
2925 		SCTPDBG(SCTP_DEBUG_ASCONF1,
2926 		    "find_initack_addr: invalid offset?\n");
2927 		return (0);
2928 	}
2929 	/* go through the addresses in the init-ack */
2930 	ph = (struct sctp_paramhdr *)sctp_m_getptr(m, offset,
2931 	    sizeof(struct sctp_paramhdr), (uint8_t *)&tmp_param);
2932 	while (ph != NULL) {
2933 		ptype = ntohs(ph->param_type);
2934 		plen = ntohs(ph->param_length);
2935 		switch (ptype) {
2936 #ifdef INET6
2937 		case SCTP_IPV6_ADDRESS:
2938 			if (sa->sa_family == AF_INET6) {
2939 				/* get the entire IPv6 address param */
2940 				if (plen != sizeof(struct sctp_ipv6addr_param)) {
2941 					break;
2942 				}
2943 				/* get the entire IPv6 address param */
2944 				a6p = (struct sctp_ipv6addr_param *)
2945 				    sctp_m_getptr(m, offset,
2946 				    sizeof(struct sctp_ipv6addr_param),
2947 				    (uint8_t *)&addr6_store);
2948 				if (a6p == NULL) {
2949 					return (0);
2950 				}
2951 				sin6 = (struct sockaddr_in6 *)sa;
2952 				if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr)) {
2953 					/* create a copy and clear scope */
2954 					memcpy(&sin6_tmp, sin6,
2955 					    sizeof(struct sockaddr_in6));
2956 					sin6 = &sin6_tmp;
2957 					in6_clearscope(&sin6->sin6_addr);
2958 				}
2959 				if (memcmp(&sin6->sin6_addr, a6p->addr,
2960 				    sizeof(struct in6_addr)) == 0) {
2961 					/* found it */
2962 					return (1);
2963 				}
2964 			}
2965 			break;
2966 #endif				/* INET6 */
2967 #ifdef INET
2968 		case SCTP_IPV4_ADDRESS:
2969 			if (sa->sa_family == AF_INET) {
2970 				if (plen != sizeof(struct sctp_ipv4addr_param)) {
2971 					break;
2972 				}
2973 				/* get the entire IPv4 address param */
2974 				a4p = (struct sctp_ipv4addr_param *)
2975 				    sctp_m_getptr(m, offset,
2976 				    sizeof(struct sctp_ipv4addr_param),
2977 				    (uint8_t *)&addr4_store);
2978 				if (a4p == NULL) {
2979 					return (0);
2980 				}
2981 				sin = (struct sockaddr_in *)sa;
2982 				if (sin->sin_addr.s_addr == a4p->addr) {
2983 					/* found it */
2984 					return (1);
2985 				}
2986 			}
2987 			break;
2988 #endif
2989 		default:
2990 			break;
2991 		}
2992 		/* get next parameter */
2993 		offset += SCTP_SIZE32(plen);
2994 		if (offset + sizeof(struct sctp_paramhdr) > length) {
2995 			return (0);
2996 		}
2997 		ph = (struct sctp_paramhdr *)
2998 		    sctp_m_getptr(m, offset, sizeof(struct sctp_paramhdr),
2999 		    (uint8_t *)&tmp_param);
3000 	}			/* while */
3001 	/* not found! */
3002 	return (0);
3003 }
3004 
3005 /*
3006  * makes sure that the current endpoint local addr list is consistent with
3007  * the new association (eg. subset bound, asconf allowed) adds addresses as
3008  * necessary
3009  */
3010 static void
3011 sctp_check_address_list_ep(struct sctp_tcb *stcb, struct mbuf *m, int offset,
3012     int length, struct sockaddr *init_addr)
3013 {
3014 	struct sctp_laddr *laddr;
3015 
3016 	/* go through the endpoint list */
3017 	LIST_FOREACH(laddr, &stcb->sctp_ep->sctp_addr_list, sctp_nxt_addr) {
3018 		/* be paranoid and validate the laddr */
3019 		if (laddr->ifa == NULL) {
3020 			SCTPDBG(SCTP_DEBUG_ASCONF1,
3021 			    "check_addr_list_ep: laddr->ifa is NULL");
3022 			continue;
3023 		}
3024 		if (laddr->ifa == NULL) {
3025 			SCTPDBG(SCTP_DEBUG_ASCONF1, "check_addr_list_ep: laddr->ifa->ifa_addr is NULL");
3026 			continue;
3027 		}
3028 		/* do i have it implicitly? */
3029 		if (sctp_cmpaddr(&laddr->ifa->address.sa, init_addr)) {
3030 			continue;
3031 		}
3032 		/* check to see if in the init-ack */
3033 		if (!sctp_addr_in_initack(m, offset, length, &laddr->ifa->address.sa)) {
3034 			/* try to add it */
3035 			sctp_addr_mgmt_assoc(stcb->sctp_ep, stcb, laddr->ifa,
3036 			    SCTP_ADD_IP_ADDRESS, SCTP_ADDR_NOT_LOCKED);
3037 		}
3038 	}
3039 }
3040 
3041 /*
3042  * makes sure that the current kernel address list is consistent with the new
3043  * association (with all addrs bound) adds addresses as necessary
3044  */
3045 static void
3046 sctp_check_address_list_all(struct sctp_tcb *stcb, struct mbuf *m, int offset,
3047     int length, struct sockaddr *init_addr,
3048     uint16_t local_scope, uint16_t site_scope,
3049     uint16_t ipv4_scope, uint16_t loopback_scope)
3050 {
3051 	struct sctp_vrf *vrf = NULL;
3052 	struct sctp_ifn *sctp_ifn;
3053 	struct sctp_ifa *sctp_ifa;
3054 	uint32_t vrf_id;
3055 #ifdef INET
3056 	struct sockaddr_in *sin;
3057 #endif
3058 #ifdef INET6
3059 	struct sockaddr_in6 *sin6;
3060 #endif
3061 
3062 	if (stcb) {
3063 		vrf_id = stcb->asoc.vrf_id;
3064 	} else {
3065 		return;
3066 	}
3067 	SCTP_IPI_ADDR_RLOCK();
3068 	vrf = sctp_find_vrf(vrf_id);
3069 	if (vrf == NULL) {
3070 		SCTP_IPI_ADDR_RUNLOCK();
3071 		return;
3072 	}
3073 	/* go through all our known interfaces */
3074 	LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) {
3075 		if (loopback_scope == 0 && SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) {
3076 			/* skip loopback interface */
3077 			continue;
3078 		}
3079 		/* go through each interface address */
3080 		LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
3081 			/* do i have it implicitly? */
3082 			if (sctp_cmpaddr(&sctp_ifa->address.sa, init_addr)) {
3083 				continue;
3084 			}
3085 			switch (sctp_ifa->address.sa.sa_family) {
3086 #ifdef INET
3087 			case AF_INET:
3088 				sin = &sctp_ifa->address.sin;
3089 				if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred,
3090 				    &sin->sin_addr) != 0) {
3091 					continue;
3092 				}
3093 				if ((ipv4_scope == 0) &&
3094 				    (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) {
3095 					/* private address not in scope */
3096 					continue;
3097 				}
3098 				break;
3099 #endif
3100 #ifdef INET6
3101 			case AF_INET6:
3102 				sin6 = &sctp_ifa->address.sin6;
3103 				if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred,
3104 				    &sin6->sin6_addr) != 0) {
3105 					continue;
3106 				}
3107 				if ((local_scope == 0) &&
3108 				    (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))) {
3109 					continue;
3110 				}
3111 				if ((site_scope == 0) &&
3112 				    (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) {
3113 					continue;
3114 				}
3115 				break;
3116 #endif
3117 			default:
3118 				break;
3119 			}
3120 			/* check to see if in the init-ack */
3121 			if (!sctp_addr_in_initack(m, offset, length, &sctp_ifa->address.sa)) {
3122 				/* try to add it */
3123 				sctp_addr_mgmt_assoc(stcb->sctp_ep, stcb,
3124 				    sctp_ifa, SCTP_ADD_IP_ADDRESS,
3125 				    SCTP_ADDR_LOCKED);
3126 			}
3127 		}		/* end foreach ifa */
3128 	}			/* end foreach ifn */
3129 	SCTP_IPI_ADDR_RUNLOCK();
3130 }
3131 
3132 /*
3133  * validates an init-ack chunk (from a cookie-echo) with current addresses
3134  * adds addresses from the init-ack into our local address list, if needed
3135  * queues asconf adds/deletes addresses as needed and makes appropriate list
3136  * changes for source address selection m, offset: points to the start of the
3137  * address list in an init-ack chunk length: total length of the address
3138  * params only init_addr: address where my INIT-ACK was sent from
3139  */
3140 void
3141 sctp_check_address_list(struct sctp_tcb *stcb, struct mbuf *m, int offset,
3142     int length, struct sockaddr *init_addr,
3143     uint16_t local_scope, uint16_t site_scope,
3144     uint16_t ipv4_scope, uint16_t loopback_scope)
3145 {
3146 	/* process the local addresses in the initack */
3147 	sctp_process_initack_addresses(stcb, m, offset, length);
3148 
3149 	if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
3150 		/* bound all case */
3151 		sctp_check_address_list_all(stcb, m, offset, length, init_addr,
3152 		    local_scope, site_scope, ipv4_scope, loopback_scope);
3153 	} else {
3154 		/* subset bound case */
3155 		if (sctp_is_feature_on(stcb->sctp_ep,
3156 		    SCTP_PCB_FLAGS_DO_ASCONF)) {
3157 			/* asconf's allowed */
3158 			sctp_check_address_list_ep(stcb, m, offset, length,
3159 			    init_addr);
3160 		}
3161 		/* else, no asconfs allowed, so what we sent is what we get */
3162 	}
3163 }
3164 
3165 /*
3166  * sctp_bindx() support
3167  */
3168 uint32_t
3169 sctp_addr_mgmt_ep_sa(struct sctp_inpcb *inp, struct sockaddr *sa,
3170     uint32_t type, uint32_t vrf_id, struct sctp_ifa *sctp_ifap)
3171 {
3172 	struct sctp_ifa *ifa;
3173 	struct sctp_laddr *laddr, *nladdr;
3174 
3175 	if (sa->sa_len == 0) {
3176 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, EINVAL);
3177 		return (EINVAL);
3178 	}
3179 	if (sctp_ifap) {
3180 		ifa = sctp_ifap;
3181 	} else if (type == SCTP_ADD_IP_ADDRESS) {
3182 		/* For an add the address MUST be on the system */
3183 		ifa = sctp_find_ifa_by_addr(sa, vrf_id, SCTP_ADDR_NOT_LOCKED);
3184 	} else if (type == SCTP_DEL_IP_ADDRESS) {
3185 		/* For a delete we need to find it in the inp */
3186 		ifa = sctp_find_ifa_in_ep(inp, sa, SCTP_ADDR_NOT_LOCKED);
3187 	} else {
3188 		ifa = NULL;
3189 	}
3190 	if (ifa != NULL) {
3191 		if (type == SCTP_ADD_IP_ADDRESS) {
3192 			sctp_add_local_addr_ep(inp, ifa, type);
3193 		} else if (type == SCTP_DEL_IP_ADDRESS) {
3194 			if (inp->laddr_count < 2) {
3195 				/* can't delete the last local address */
3196 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, EINVAL);
3197 				return (EINVAL);
3198 			}
3199 			LIST_FOREACH(laddr, &inp->sctp_addr_list,
3200 			    sctp_nxt_addr) {
3201 				if (ifa == laddr->ifa) {
3202 					/* Mark in the delete */
3203 					laddr->action = type;
3204 				}
3205 			}
3206 		}
3207 		if (LIST_EMPTY(&inp->sctp_asoc_list)) {
3208 			/*
3209 			 * There is no need to start the iterator if the inp
3210 			 * has no associations.
3211 			 */
3212 			if (type == SCTP_DEL_IP_ADDRESS) {
3213 				LIST_FOREACH_SAFE(laddr, &inp->sctp_addr_list, sctp_nxt_addr, nladdr) {
3214 					if (laddr->ifa == ifa) {
3215 						sctp_del_local_addr_ep(inp, ifa);
3216 					}
3217 				}
3218 			}
3219 		} else {
3220 			struct sctp_asconf_iterator *asc;
3221 			struct sctp_laddr *wi;
3222 			int ret;
3223 
3224 			SCTP_MALLOC(asc, struct sctp_asconf_iterator *,
3225 			    sizeof(struct sctp_asconf_iterator),
3226 			    SCTP_M_ASC_IT);
3227 			if (asc == NULL) {
3228 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, ENOMEM);
3229 				return (ENOMEM);
3230 			}
3231 			wi = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_laddr), struct sctp_laddr);
3232 			if (wi == NULL) {
3233 				SCTP_FREE(asc, SCTP_M_ASC_IT);
3234 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, ENOMEM);
3235 				return (ENOMEM);
3236 			}
3237 			LIST_INIT(&asc->list_of_work);
3238 			asc->cnt = 1;
3239 			SCTP_INCR_LADDR_COUNT();
3240 			wi->ifa = ifa;
3241 			wi->action = type;
3242 			atomic_add_int(&ifa->refcount, 1);
3243 			LIST_INSERT_HEAD(&asc->list_of_work, wi, sctp_nxt_addr);
3244 			ret = sctp_initiate_iterator(sctp_asconf_iterator_ep,
3245 			    sctp_asconf_iterator_stcb,
3246 			    sctp_asconf_iterator_ep_end,
3247 			    SCTP_PCB_ANY_FLAGS,
3248 			    SCTP_PCB_ANY_FEATURES,
3249 			    SCTP_ASOC_ANY_STATE,
3250 			    (void *)asc, 0,
3251 			    sctp_asconf_iterator_end, inp, 0);
3252 			if (ret) {
3253 				SCTP_PRINTF("Failed to initiate iterator for addr_mgmt_ep_sa\n");
3254 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, EFAULT);
3255 				sctp_asconf_iterator_end(asc, 0);
3256 				return (EFAULT);
3257 			}
3258 		}
3259 		return (0);
3260 	} else {
3261 		/* invalid address! */
3262 		SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_ASCONF, EADDRNOTAVAIL);
3263 		return (EADDRNOTAVAIL);
3264 	}
3265 }
3266 
3267 void
3268 sctp_asconf_send_nat_state_update(struct sctp_tcb *stcb,
3269     struct sctp_nets *net)
3270 {
3271 	struct sctp_asconf_addr *aa;
3272 	struct sctp_ifa *sctp_ifap;
3273 	struct sctp_asconf_tag_param *vtag;
3274 #ifdef INET
3275 	struct sockaddr_in *to;
3276 #endif
3277 #ifdef INET6
3278 	struct sockaddr_in6 *to6;
3279 #endif
3280 	if (net == NULL) {
3281 		SCTPDBG(SCTP_DEBUG_ASCONF1, "sctp_asconf_send_nat_state_update: Missing net\n");
3282 		return;
3283 	}
3284 	if (stcb == NULL) {
3285 		SCTPDBG(SCTP_DEBUG_ASCONF1, "sctp_asconf_send_nat_state_update: Missing stcb\n");
3286 		return;
3287 	}
3288 	/*
3289 	 * Need to have in the asconf: - vtagparam(my_vtag/peer_vtag) -
3290 	 * add(0.0.0.0) - del(0.0.0.0) - Any global addresses add(addr)
3291 	 */
3292 	SCTP_MALLOC(aa, struct sctp_asconf_addr *, sizeof(*aa),
3293 	    SCTP_M_ASC_ADDR);
3294 	if (aa == NULL) {
3295 		/* didn't get memory */
3296 		SCTPDBG(SCTP_DEBUG_ASCONF1,
3297 		    "sctp_asconf_send_nat_state_update: failed to get memory!\n");
3298 		return;
3299 	}
3300 	aa->special_del = 0;
3301 	/* fill in asconf address parameter fields */
3302 	/* top level elements are "networked" during send */
3303 	aa->ifa = NULL;
3304 	aa->sent = 0;		/* clear sent flag */
3305 	vtag = (struct sctp_asconf_tag_param *)&aa->ap.aph;
3306 	vtag->aph.ph.param_type = SCTP_NAT_VTAGS;
3307 	vtag->aph.ph.param_length = sizeof(struct sctp_asconf_tag_param);
3308 	vtag->local_vtag = htonl(stcb->asoc.my_vtag);
3309 	vtag->remote_vtag = htonl(stcb->asoc.peer_vtag);
3310 	TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
3311 
3312 	SCTP_MALLOC(aa, struct sctp_asconf_addr *, sizeof(*aa),
3313 	    SCTP_M_ASC_ADDR);
3314 	if (aa == NULL) {
3315 		/* didn't get memory */
3316 		SCTPDBG(SCTP_DEBUG_ASCONF1,
3317 		    "sctp_asconf_send_nat_state_update: failed to get memory!\n");
3318 		return;
3319 	}
3320 	memset(aa, 0, sizeof(struct sctp_asconf_addr));
3321 	/* fill in asconf address parameter fields */
3322 	/* ADD(0.0.0.0) */
3323 	switch (net->ro._l_addr.sa.sa_family) {
3324 #ifdef INET
3325 	case AF_INET:
3326 		aa->ap.aph.ph.param_type = SCTP_ADD_IP_ADDRESS;
3327 		aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_addrv4_param);
3328 		aa->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS;
3329 		aa->ap.addrp.ph.param_length = sizeof(struct sctp_ipv4addr_param);
3330 		/* No need to add an address, we are using 0.0.0.0 */
3331 		TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
3332 		break;
3333 #endif
3334 #ifdef INET6
3335 	case AF_INET6:
3336 		aa->ap.aph.ph.param_type = SCTP_ADD_IP_ADDRESS;
3337 		aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_addr_param);
3338 		aa->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS;
3339 		aa->ap.addrp.ph.param_length = sizeof(struct sctp_ipv6addr_param);
3340 		/* No need to add an address, we are using 0.0.0.0 */
3341 		TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
3342 		break;
3343 #endif
3344 	default:
3345 		SCTPDBG(SCTP_DEBUG_ASCONF1,
3346 		    "sctp_asconf_send_nat_state_update: unknown address family\n");
3347 		SCTP_FREE(aa, SCTP_M_ASC_ADDR);
3348 		return;
3349 	}
3350 	SCTP_MALLOC(aa, struct sctp_asconf_addr *, sizeof(*aa),
3351 	    SCTP_M_ASC_ADDR);
3352 	if (aa == NULL) {
3353 		/* didn't get memory */
3354 		SCTPDBG(SCTP_DEBUG_ASCONF1,
3355 		    "sctp_asconf_send_nat_state_update: failed to get memory!\n");
3356 		return;
3357 	}
3358 	memset(aa, 0, sizeof(struct sctp_asconf_addr));
3359 	/* fill in asconf address parameter fields */
3360 	/* ADD(0.0.0.0) */
3361 	switch (net->ro._l_addr.sa.sa_family) {
3362 #ifdef INET
3363 	case AF_INET:
3364 		aa->ap.aph.ph.param_type = SCTP_ADD_IP_ADDRESS;
3365 		aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_addrv4_param);
3366 		aa->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS;
3367 		aa->ap.addrp.ph.param_length = sizeof(struct sctp_ipv4addr_param);
3368 		/* No need to add an address, we are using 0.0.0.0 */
3369 		TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
3370 		break;
3371 #endif
3372 #ifdef INET6
3373 	case AF_INET6:
3374 		aa->ap.aph.ph.param_type = SCTP_DEL_IP_ADDRESS;
3375 		aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_addr_param);
3376 		aa->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS;
3377 		aa->ap.addrp.ph.param_length = sizeof(struct sctp_ipv6addr_param);
3378 		/* No need to add an address, we are using 0.0.0.0 */
3379 		TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
3380 		break;
3381 #endif
3382 	default:
3383 		SCTPDBG(SCTP_DEBUG_ASCONF1,
3384 		    "sctp_asconf_send_nat_state_update: unknown address family\n");
3385 		SCTP_FREE(aa, SCTP_M_ASC_ADDR);
3386 		return;
3387 	}
3388 	/* Now we must hunt the addresses and add all global addresses */
3389 	if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
3390 		struct sctp_vrf *vrf = NULL;
3391 		struct sctp_ifn *sctp_ifnp;
3392 		uint32_t vrf_id;
3393 
3394 		vrf_id = stcb->sctp_ep->def_vrf_id;
3395 		vrf = sctp_find_vrf(vrf_id);
3396 		if (vrf == NULL) {
3397 			goto skip_rest;
3398 		}
3399 
3400 		SCTP_IPI_ADDR_RLOCK();
3401 		LIST_FOREACH(sctp_ifnp, &vrf->ifnlist, next_ifn) {
3402 			LIST_FOREACH(sctp_ifap, &sctp_ifnp->ifalist, next_ifa) {
3403 				switch (sctp_ifap->address.sa.sa_family) {
3404 #ifdef INET
3405 				case AF_INET:
3406 					to = &sctp_ifap->address.sin;
3407 					if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred,
3408 					    &to->sin_addr) != 0) {
3409 						continue;
3410 					}
3411 					if (IN4_ISPRIVATE_ADDRESS(&to->sin_addr)) {
3412 						continue;
3413 					}
3414 					if (IN4_ISLOOPBACK_ADDRESS(&to->sin_addr)) {
3415 						continue;
3416 					}
3417 					break;
3418 #endif
3419 #ifdef INET6
3420 				case AF_INET6:
3421 					to6 = &sctp_ifap->address.sin6;
3422 					if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred,
3423 					    &to6->sin6_addr) != 0) {
3424 						continue;
3425 					}
3426 					if (IN6_IS_ADDR_LOOPBACK(&to6->sin6_addr)) {
3427 						continue;
3428 					}
3429 					if (IN6_IS_ADDR_LINKLOCAL(&to6->sin6_addr)) {
3430 						continue;
3431 					}
3432 					break;
3433 #endif
3434 				default:
3435 					continue;
3436 				}
3437 				sctp_asconf_queue_mgmt(stcb, sctp_ifap, SCTP_ADD_IP_ADDRESS);
3438 			}
3439 		}
3440 		SCTP_IPI_ADDR_RUNLOCK();
3441 	} else {
3442 		struct sctp_laddr *laddr;
3443 
3444 		LIST_FOREACH(laddr, &stcb->sctp_ep->sctp_addr_list, sctp_nxt_addr) {
3445 			if (laddr->ifa == NULL) {
3446 				continue;
3447 			}
3448 			if (laddr->ifa->localifa_flags & SCTP_BEING_DELETED)
3449 				/*
3450 				 * Address being deleted by the system, dont
3451 				 * list.
3452 				 */
3453 				continue;
3454 			if (laddr->action == SCTP_DEL_IP_ADDRESS) {
3455 				/*
3456 				 * Address being deleted on this ep don't
3457 				 * list.
3458 				 */
3459 				continue;
3460 			}
3461 			sctp_ifap = laddr->ifa;
3462 			switch (sctp_ifap->address.sa.sa_family) {
3463 #ifdef INET
3464 			case AF_INET:
3465 				to = &sctp_ifap->address.sin;
3466 				if (IN4_ISPRIVATE_ADDRESS(&to->sin_addr)) {
3467 					continue;
3468 				}
3469 				if (IN4_ISLOOPBACK_ADDRESS(&to->sin_addr)) {
3470 					continue;
3471 				}
3472 				break;
3473 #endif
3474 #ifdef INET6
3475 			case AF_INET6:
3476 				to6 = &sctp_ifap->address.sin6;
3477 				if (IN6_IS_ADDR_LOOPBACK(&to6->sin6_addr)) {
3478 					continue;
3479 				}
3480 				if (IN6_IS_ADDR_LINKLOCAL(&to6->sin6_addr)) {
3481 					continue;
3482 				}
3483 				break;
3484 #endif
3485 			default:
3486 				continue;
3487 			}
3488 			sctp_asconf_queue_mgmt(stcb, sctp_ifap, SCTP_ADD_IP_ADDRESS);
3489 		}
3490 	}
3491 skip_rest:
3492 	/* Now we must send the asconf into the queue */
3493 	sctp_send_asconf(stcb, net, SCTP_ADDR_NOT_LOCKED);
3494 }
3495