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