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