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