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