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