sctp_asconf.c revision 257803
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: head/sys/netinet/sctp_asconf.c 257803 2013-11-07 17:08:09Z 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 it's a good address family */
1893	switch (ifa->address.sa.sa_family) {
1894#ifdef INET6
1895	case AF_INET6:
1896		break;
1897#endif
1898#ifdef INET
1899	case AF_INET:
1900		break;
1901#endif
1902	default:
1903		return;
1904	}
1905#ifdef INET6
1906	/* make sure we're "allowed" to add this type of addr */
1907	if (ifa->address.sa.sa_family == AF_INET6) {
1908		/* invalid if we're not a v6 endpoint */
1909		if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0)
1910			return;
1911		/* is the v6 addr really valid ? */
1912		if (ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
1913			return;
1914		}
1915	}
1916#endif
1917	/* put this address on the "pending/do not use yet" list */
1918	sctp_add_local_addr_restricted(stcb, ifa);
1919	/*
1920	 * check address scope if address is out of scope, don't queue
1921	 * anything... note: this would leave the address on both inp and
1922	 * asoc lists
1923	 */
1924	switch (ifa->address.sa.sa_family) {
1925#ifdef INET6
1926	case AF_INET6:
1927		{
1928			struct sockaddr_in6 *sin6;
1929
1930			sin6 = (struct sockaddr_in6 *)&ifa->address.sin6;
1931			if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
1932				/* we skip unspecifed addresses */
1933				return;
1934			}
1935			if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
1936				if (stcb->asoc.scope.local_scope == 0) {
1937					return;
1938				}
1939				/* is it the right link local scope? */
1940				if (sctp_is_scopeid_in_nets(stcb, &ifa->address.sa) == 0) {
1941					return;
1942				}
1943			}
1944			if (stcb->asoc.scope.site_scope == 0 &&
1945			    IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) {
1946				return;
1947			}
1948			break;
1949		}
1950#endif
1951#ifdef INET
1952	case AF_INET:
1953		{
1954			struct sockaddr_in *sin;
1955			struct in6pcb *inp6;
1956
1957			inp6 = (struct in6pcb *)&inp->ip_inp.inp;
1958			/* invalid if we are a v6 only endpoint */
1959			if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
1960			    SCTP_IPV6_V6ONLY(inp6))
1961				return;
1962
1963			sin = (struct sockaddr_in *)&ifa->address.sa;
1964			if (sin->sin_addr.s_addr == 0) {
1965				/* we skip unspecifed addresses */
1966				return;
1967			}
1968			if (stcb->asoc.scope.ipv4_local_scope == 0 &&
1969			    IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
1970				return;
1971			}
1972			break;
1973		}
1974#endif
1975	default:
1976		/* else, not AF_INET or AF_INET6, so skip */
1977		return;
1978	}
1979
1980	/* queue an asconf for this address add/delete */
1981	if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_DO_ASCONF)) {
1982		/* does the peer do asconf? */
1983		if (stcb->asoc.peer_supports_asconf) {
1984			/* queue an asconf for this addr */
1985			status = sctp_asconf_queue_add(stcb, ifa, type);
1986
1987			/*
1988			 * if queued ok, and in the open state, send out the
1989			 * ASCONF.  If in the non-open state, these will be
1990			 * sent when the state goes open.
1991			 */
1992			if (status == 0 &&
1993			    SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) {
1994#ifdef SCTP_TIMER_BASED_ASCONF
1995				sctp_timer_start(SCTP_TIMER_TYPE_ASCONF, inp,
1996				    stcb, stcb->asoc.primary_destination);
1997#else
1998				sctp_send_asconf(stcb, NULL, addr_locked);
1999#endif
2000			}
2001		}
2002	}
2003}
2004
2005
2006int
2007sctp_asconf_iterator_ep(struct sctp_inpcb *inp, void *ptr, uint32_t val SCTP_UNUSED)
2008{
2009	struct sctp_asconf_iterator *asc;
2010	struct sctp_ifa *ifa;
2011	struct sctp_laddr *l;
2012	int cnt_invalid = 0;
2013
2014	asc = (struct sctp_asconf_iterator *)ptr;
2015	LIST_FOREACH(l, &asc->list_of_work, sctp_nxt_addr) {
2016		ifa = l->ifa;
2017		switch (ifa->address.sa.sa_family) {
2018#ifdef INET6
2019		case AF_INET6:
2020			/* invalid if we're not a v6 endpoint */
2021			if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) {
2022				cnt_invalid++;
2023				if (asc->cnt == cnt_invalid)
2024					return (1);
2025			}
2026			break;
2027#endif
2028#ifdef INET
2029		case AF_INET:
2030			{
2031				/* invalid if we are a v6 only endpoint */
2032				struct in6pcb *inp6;
2033
2034				inp6 = (struct in6pcb *)&inp->ip_inp.inp;
2035				if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
2036				    SCTP_IPV6_V6ONLY(inp6)) {
2037					cnt_invalid++;
2038					if (asc->cnt == cnt_invalid)
2039						return (1);
2040				}
2041				break;
2042			}
2043#endif
2044		default:
2045			/* invalid address family */
2046			cnt_invalid++;
2047			if (asc->cnt == cnt_invalid)
2048				return (1);
2049		}
2050	}
2051	return (0);
2052}
2053
2054static int
2055sctp_asconf_iterator_ep_end(struct sctp_inpcb *inp, void *ptr, uint32_t val SCTP_UNUSED)
2056{
2057	struct sctp_ifa *ifa;
2058	struct sctp_asconf_iterator *asc;
2059	struct sctp_laddr *laddr, *nladdr, *l;
2060
2061	/* Only for specific case not bound all */
2062	asc = (struct sctp_asconf_iterator *)ptr;
2063	LIST_FOREACH(l, &asc->list_of_work, sctp_nxt_addr) {
2064		ifa = l->ifa;
2065		if (l->action == SCTP_ADD_IP_ADDRESS) {
2066			LIST_FOREACH(laddr, &inp->sctp_addr_list,
2067			    sctp_nxt_addr) {
2068				if (laddr->ifa == ifa) {
2069					laddr->action = 0;
2070					break;
2071				}
2072			}
2073		} else if (l->action == SCTP_DEL_IP_ADDRESS) {
2074			LIST_FOREACH_SAFE(laddr, &inp->sctp_addr_list, sctp_nxt_addr, nladdr) {
2075				/* remove only after all guys are done */
2076				if (laddr->ifa == ifa) {
2077					sctp_del_local_addr_ep(inp, ifa);
2078				}
2079			}
2080		}
2081	}
2082	return (0);
2083}
2084
2085void
2086sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
2087    void *ptr, uint32_t val SCTP_UNUSED)
2088{
2089	struct sctp_asconf_iterator *asc;
2090	struct sctp_ifa *ifa;
2091	struct sctp_laddr *l;
2092	int cnt_invalid = 0;
2093	int type, status;
2094	int num_queued = 0;
2095
2096	asc = (struct sctp_asconf_iterator *)ptr;
2097	LIST_FOREACH(l, &asc->list_of_work, sctp_nxt_addr) {
2098		ifa = l->ifa;
2099		type = l->action;
2100
2101		/* address's vrf_id must be the vrf_id of the assoc */
2102		if (ifa->vrf_id != stcb->asoc.vrf_id) {
2103			continue;
2104		}
2105		/* Same checks again for assoc */
2106		switch (ifa->address.sa.sa_family) {
2107#ifdef INET6
2108		case AF_INET6:
2109			{
2110				/* invalid if we're not a v6 endpoint */
2111				struct sockaddr_in6 *sin6;
2112
2113				if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) {
2114					cnt_invalid++;
2115					if (asc->cnt == cnt_invalid)
2116						return;
2117					else
2118						continue;
2119				}
2120				sin6 = (struct sockaddr_in6 *)&ifa->address.sin6;
2121				if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
2122					/* we skip unspecifed addresses */
2123					continue;
2124				}
2125				if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
2126					if (stcb->asoc.scope.local_scope == 0) {
2127						continue;
2128					}
2129					/* is it the right link local scope? */
2130					if (sctp_is_scopeid_in_nets(stcb, &ifa->address.sa) == 0) {
2131						continue;
2132					}
2133				}
2134				break;
2135			}
2136#endif
2137#ifdef INET
2138		case AF_INET:
2139			{
2140				/* invalid if we are a v6 only endpoint */
2141				struct in6pcb *inp6;
2142				struct sockaddr_in *sin;
2143
2144				inp6 = (struct in6pcb *)&inp->ip_inp.inp;
2145				/* invalid if we are a v6 only endpoint */
2146				if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
2147				    SCTP_IPV6_V6ONLY(inp6))
2148					continue;
2149
2150				sin = (struct sockaddr_in *)&ifa->address.sa;
2151				if (sin->sin_addr.s_addr == 0) {
2152					/* we skip unspecifed addresses */
2153					continue;
2154				}
2155				if (stcb->asoc.scope.ipv4_local_scope == 0 &&
2156				    IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
2157					continue;
2158				}
2159				if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
2160				    SCTP_IPV6_V6ONLY(inp6)) {
2161					cnt_invalid++;
2162					if (asc->cnt == cnt_invalid)
2163						return;
2164					else
2165						continue;
2166				}
2167				break;
2168			}
2169#endif
2170		default:
2171			/* invalid address family */
2172			cnt_invalid++;
2173			if (asc->cnt == cnt_invalid)
2174				return;
2175			else
2176				continue;
2177			break;
2178		}
2179
2180		if (type == SCTP_ADD_IP_ADDRESS) {
2181			/* prevent this address from being used as a source */
2182			sctp_add_local_addr_restricted(stcb, ifa);
2183		} else if (type == SCTP_DEL_IP_ADDRESS) {
2184			struct sctp_nets *net;
2185
2186			TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
2187				sctp_rtentry_t *rt;
2188
2189				/* delete this address if cached */
2190				if (net->ro._s_addr == ifa) {
2191					sctp_free_ifa(net->ro._s_addr);
2192					net->ro._s_addr = NULL;
2193					net->src_addr_selected = 0;
2194					rt = net->ro.ro_rt;
2195					if (rt) {
2196						RTFREE(rt);
2197						net->ro.ro_rt = NULL;
2198					}
2199					/*
2200					 * Now we deleted our src address,
2201					 * should we not also now reset the
2202					 * cwnd/rto to start as if its a new
2203					 * address?
2204					 */
2205					stcb->asoc.cc_functions.sctp_set_initial_cc_param(stcb, net);
2206					net->RTO = 0;
2207
2208				}
2209			}
2210		} else if (type == SCTP_SET_PRIM_ADDR) {
2211			if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) {
2212				/* must validate the ifa is in the ep */
2213				if (sctp_is_addr_in_ep(stcb->sctp_ep, ifa) == 0) {
2214					continue;
2215				}
2216			} else {
2217				/* Need to check scopes for this guy */
2218				if (sctp_is_address_in_scope(ifa, &stcb->asoc.scope, 0) == 0) {
2219					continue;
2220				}
2221			}
2222		}
2223		/* queue an asconf for this address add/delete */
2224		if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_DO_ASCONF) &&
2225		    stcb->asoc.peer_supports_asconf) {
2226			/* queue an asconf for this addr */
2227			status = sctp_asconf_queue_add(stcb, ifa, type);
2228			/*
2229			 * if queued ok, and in the open state, update the
2230			 * count of queued params.  If in the non-open
2231			 * state, these get sent when the assoc goes open.
2232			 */
2233			if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) {
2234				if (status >= 0) {
2235					num_queued++;
2236				}
2237			}
2238		}
2239	}
2240	/*
2241	 * If we have queued params in the open state, send out an ASCONF.
2242	 */
2243	if (num_queued > 0) {
2244		sctp_send_asconf(stcb, NULL, SCTP_ADDR_NOT_LOCKED);
2245	}
2246}
2247
2248void
2249sctp_asconf_iterator_end(void *ptr, uint32_t val SCTP_UNUSED)
2250{
2251	struct sctp_asconf_iterator *asc;
2252	struct sctp_ifa *ifa;
2253	struct sctp_laddr *l, *nl;
2254
2255	asc = (struct sctp_asconf_iterator *)ptr;
2256	LIST_FOREACH_SAFE(l, &asc->list_of_work, sctp_nxt_addr, nl) {
2257		ifa = l->ifa;
2258		if (l->action == SCTP_ADD_IP_ADDRESS) {
2259			/* Clear the defer use flag */
2260			ifa->localifa_flags &= ~SCTP_ADDR_DEFER_USE;
2261		}
2262		sctp_free_ifa(ifa);
2263		SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_laddr), l);
2264		SCTP_DECR_LADDR_COUNT();
2265	}
2266	SCTP_FREE(asc, SCTP_M_ASC_IT);
2267}
2268
2269/*
2270 * sa is the sockaddr to ask the peer to set primary to.
2271 * returns: 0 = completed, -1 = error
2272 */
2273int32_t
2274sctp_set_primary_ip_address_sa(struct sctp_tcb *stcb, struct sockaddr *sa)
2275{
2276	uint32_t vrf_id;
2277	struct sctp_ifa *ifa;
2278
2279	/* find the ifa for the desired set primary */
2280	vrf_id = stcb->asoc.vrf_id;
2281	ifa = sctp_find_ifa_by_addr(sa, vrf_id, SCTP_ADDR_NOT_LOCKED);
2282	if (ifa == NULL) {
2283		/* Invalid address */
2284		return (-1);
2285	}
2286	/* queue an ASCONF:SET_PRIM_ADDR to be sent */
2287	if (!sctp_asconf_queue_add(stcb, ifa, SCTP_SET_PRIM_ADDR)) {
2288		/* set primary queuing succeeded */
2289		SCTPDBG(SCTP_DEBUG_ASCONF1,
2290		    "set_primary_ip_address_sa: queued on tcb=%p, ",
2291		    (void *)stcb);
2292		SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
2293		if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) {
2294#ifdef SCTP_TIMER_BASED_ASCONF
2295			sctp_timer_start(SCTP_TIMER_TYPE_ASCONF,
2296			    stcb->sctp_ep, stcb,
2297			    stcb->asoc.primary_destination);
2298#else
2299			sctp_send_asconf(stcb, NULL, SCTP_ADDR_NOT_LOCKED);
2300#endif
2301		}
2302	} else {
2303		SCTPDBG(SCTP_DEBUG_ASCONF1, "set_primary_ip_address_sa: failed to add to queue on tcb=%p, ",
2304		    (void *)stcb);
2305		SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
2306		return (-1);
2307	}
2308	return (0);
2309}
2310
2311void
2312sctp_set_primary_ip_address(struct sctp_ifa *ifa)
2313{
2314	struct sctp_inpcb *inp;
2315
2316	/* go through all our PCB's */
2317	LIST_FOREACH(inp, &SCTP_BASE_INFO(listhead), sctp_list) {
2318		struct sctp_tcb *stcb;
2319
2320		/* process for all associations for this endpoint */
2321		LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
2322			/* queue an ASCONF:SET_PRIM_ADDR to be sent */
2323			if (!sctp_asconf_queue_add(stcb, ifa,
2324			    SCTP_SET_PRIM_ADDR)) {
2325				/* set primary queuing succeeded */
2326				SCTPDBG(SCTP_DEBUG_ASCONF1, "set_primary_ip_address: queued on stcb=%p, ",
2327				    (void *)stcb);
2328				SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, &ifa->address.sa);
2329				if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) {
2330#ifdef SCTP_TIMER_BASED_ASCONF
2331					sctp_timer_start(SCTP_TIMER_TYPE_ASCONF,
2332					    stcb->sctp_ep, stcb,
2333					    stcb->asoc.primary_destination);
2334#else
2335					sctp_send_asconf(stcb, NULL, SCTP_ADDR_NOT_LOCKED);
2336#endif
2337				}
2338			}
2339		}		/* for each stcb */
2340	}			/* for each inp */
2341}
2342
2343int
2344sctp_is_addr_pending(struct sctp_tcb *stcb, struct sctp_ifa *sctp_ifa)
2345{
2346	struct sctp_tmit_chunk *chk, *nchk;
2347	unsigned int offset, asconf_limit;
2348	struct sctp_asconf_chunk *acp;
2349	struct sctp_asconf_paramhdr *aph;
2350	uint8_t aparam_buf[SCTP_PARAM_BUFFER_SIZE];
2351	struct sctp_paramhdr *ph;
2352	int add_cnt, del_cnt;
2353	uint16_t last_param_type;
2354
2355	add_cnt = del_cnt = 0;
2356	last_param_type = 0;
2357	TAILQ_FOREACH_SAFE(chk, &stcb->asoc.asconf_send_queue, sctp_next, nchk) {
2358		if (chk->data == NULL) {
2359			SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: No mbuf data?\n");
2360			continue;
2361		}
2362		offset = 0;
2363		acp = mtod(chk->data, struct sctp_asconf_chunk *);
2364		offset += sizeof(struct sctp_asconf_chunk);
2365		asconf_limit = ntohs(acp->ch.chunk_length);
2366		ph = (struct sctp_paramhdr *)sctp_m_getptr(chk->data, offset, sizeof(struct sctp_paramhdr), aparam_buf);
2367		if (ph == NULL) {
2368			SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: couldn't get lookup addr!\n");
2369			continue;
2370		}
2371		offset += ntohs(ph->param_length);
2372
2373		aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(chk->data, offset, sizeof(struct sctp_asconf_paramhdr), aparam_buf);
2374		if (aph == NULL) {
2375			SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: Empty ASCONF will be sent?\n");
2376			continue;
2377		}
2378		while (aph != NULL) {
2379			unsigned int param_length, param_type;
2380
2381			param_type = ntohs(aph->ph.param_type);
2382			param_length = ntohs(aph->ph.param_length);
2383			if (offset + param_length > asconf_limit) {
2384				/* parameter goes beyond end of chunk! */
2385				break;
2386			}
2387			if (param_length > sizeof(aparam_buf)) {
2388				SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: param length (%u) larger than buffer size!\n", param_length);
2389				break;
2390			}
2391			if (param_length <= sizeof(struct sctp_paramhdr)) {
2392				SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: param length(%u) too short\n", param_length);
2393				break;
2394			}
2395			aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(chk->data, offset, param_length, aparam_buf);
2396			if (aph == NULL) {
2397				SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: couldn't get entire param\n");
2398				break;
2399			}
2400			ph = (struct sctp_paramhdr *)(aph + 1);
2401			if (sctp_addr_match(ph, &sctp_ifa->address.sa) != 0) {
2402				switch (param_type) {
2403				case SCTP_ADD_IP_ADDRESS:
2404					add_cnt++;
2405					break;
2406				case SCTP_DEL_IP_ADDRESS:
2407					del_cnt++;
2408					break;
2409				default:
2410					break;
2411				}
2412				last_param_type = param_type;
2413			}
2414			offset += SCTP_SIZE32(param_length);
2415			if (offset >= asconf_limit) {
2416				/* no more data in the mbuf chain */
2417				break;
2418			}
2419			/* get pointer to next asconf param */
2420			aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(chk->data, offset, sizeof(struct sctp_asconf_paramhdr), aparam_buf);
2421		}
2422	}
2423
2424	/*
2425	 * we want to find the sequences which consist of ADD -> DEL -> ADD
2426	 * or DEL -> ADD
2427	 */
2428	if (add_cnt > del_cnt ||
2429	    (add_cnt == del_cnt && last_param_type == SCTP_ADD_IP_ADDRESS)) {
2430		return (1);
2431	}
2432	return (0);
2433}
2434
2435static struct sockaddr *
2436sctp_find_valid_localaddr(struct sctp_tcb *stcb, int addr_locked)
2437{
2438	struct sctp_vrf *vrf = NULL;
2439	struct sctp_ifn *sctp_ifn;
2440	struct sctp_ifa *sctp_ifa;
2441
2442	if (addr_locked == SCTP_ADDR_NOT_LOCKED)
2443		SCTP_IPI_ADDR_RLOCK();
2444	vrf = sctp_find_vrf(stcb->asoc.vrf_id);
2445	if (vrf == NULL) {
2446		if (addr_locked == SCTP_ADDR_NOT_LOCKED)
2447			SCTP_IPI_ADDR_RUNLOCK();
2448		return (NULL);
2449	}
2450	LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) {
2451		if (stcb->asoc.scope.loopback_scope == 0 &&
2452		    SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) {
2453			/* Skip if loopback_scope not set */
2454			continue;
2455		}
2456		LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
2457			switch (sctp_ifa->address.sa.sa_family) {
2458#ifdef INET
2459			case AF_INET:
2460				if (stcb->asoc.scope.ipv4_addr_legal) {
2461					struct sockaddr_in *sin;
2462
2463					sin = (struct sockaddr_in *)&sctp_ifa->address.sa;
2464					if (sin->sin_addr.s_addr == 0) {
2465						/* skip unspecifed addresses */
2466						continue;
2467					}
2468					if (stcb->asoc.scope.ipv4_local_scope == 0 &&
2469					    IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))
2470						continue;
2471
2472					if (sctp_is_addr_restricted(stcb, sctp_ifa) &&
2473					    (!sctp_is_addr_pending(stcb, sctp_ifa)))
2474						continue;
2475					/*
2476					 * found a valid local v4 address to
2477					 * use
2478					 */
2479					if (addr_locked == SCTP_ADDR_NOT_LOCKED)
2480						SCTP_IPI_ADDR_RUNLOCK();
2481					return (&sctp_ifa->address.sa);
2482				}
2483				break;
2484#endif
2485#ifdef INET6
2486			case AF_INET6:
2487				if (stcb->asoc.scope.ipv6_addr_legal) {
2488					struct sockaddr_in6 *sin6;
2489
2490					if (sctp_ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
2491						continue;
2492					}
2493					sin6 = (struct sockaddr_in6 *)&sctp_ifa->address.sa;
2494					if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
2495						/*
2496						 * we skip unspecifed
2497						 * addresses
2498						 */
2499						continue;
2500					}
2501					if (stcb->asoc.scope.local_scope == 0 &&
2502					    IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
2503						continue;
2504					if (stcb->asoc.scope.site_scope == 0 &&
2505					    IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))
2506						continue;
2507
2508					if (sctp_is_addr_restricted(stcb, sctp_ifa) &&
2509					    (!sctp_is_addr_pending(stcb, sctp_ifa)))
2510						continue;
2511					/*
2512					 * found a valid local v6 address to
2513					 * use
2514					 */
2515					if (addr_locked == SCTP_ADDR_NOT_LOCKED)
2516						SCTP_IPI_ADDR_RUNLOCK();
2517					return (&sctp_ifa->address.sa);
2518				}
2519				break;
2520#endif
2521			default:
2522				break;
2523			}
2524		}
2525	}
2526	/* no valid addresses found */
2527	if (addr_locked == SCTP_ADDR_NOT_LOCKED)
2528		SCTP_IPI_ADDR_RUNLOCK();
2529	return (NULL);
2530}
2531
2532static struct sockaddr *
2533sctp_find_valid_localaddr_ep(struct sctp_tcb *stcb)
2534{
2535	struct sctp_laddr *laddr;
2536
2537	LIST_FOREACH(laddr, &stcb->sctp_ep->sctp_addr_list, sctp_nxt_addr) {
2538		if (laddr->ifa == NULL) {
2539			continue;
2540		}
2541		/* is the address restricted ? */
2542		if (sctp_is_addr_restricted(stcb, laddr->ifa) &&
2543		    (!sctp_is_addr_pending(stcb, laddr->ifa)))
2544			continue;
2545
2546		/* found a valid local address to use */
2547		return (&laddr->ifa->address.sa);
2548	}
2549	/* no valid addresses found */
2550	return (NULL);
2551}
2552
2553/*
2554 * builds an ASCONF chunk from queued ASCONF params.
2555 * returns NULL on error (no mbuf, no ASCONF params queued, etc).
2556 */
2557struct mbuf *
2558sctp_compose_asconf(struct sctp_tcb *stcb, int *retlen, int addr_locked)
2559{
2560	struct mbuf *m_asconf, *m_asconf_chk;
2561	struct sctp_asconf_addr *aa;
2562	struct sctp_asconf_chunk *acp;
2563	struct sctp_asconf_paramhdr *aph;
2564	struct sctp_asconf_addr_param *aap;
2565	uint32_t p_length;
2566	uint32_t correlation_id = 1;	/* 0 is reserved... */
2567	caddr_t ptr, lookup_ptr;
2568	uint8_t lookup_used = 0;
2569
2570	/* are there any asconf params to send? */
2571	TAILQ_FOREACH(aa, &stcb->asoc.asconf_queue, next) {
2572		if (aa->sent == 0)
2573			break;
2574	}
2575	if (aa == NULL)
2576		return (NULL);
2577
2578	/*
2579	 * get a chunk header mbuf and a cluster for the asconf params since
2580	 * it's simpler to fill in the asconf chunk header lookup address on
2581	 * the fly
2582	 */
2583	m_asconf_chk = sctp_get_mbuf_for_msg(sizeof(struct sctp_asconf_chunk), 0, M_NOWAIT, 1, MT_DATA);
2584	if (m_asconf_chk == NULL) {
2585		/* no mbuf's */
2586		SCTPDBG(SCTP_DEBUG_ASCONF1,
2587		    "compose_asconf: couldn't get chunk mbuf!\n");
2588		return (NULL);
2589	}
2590	m_asconf = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_NOWAIT, 1, MT_DATA);
2591	if (m_asconf == NULL) {
2592		/* no mbuf's */
2593		SCTPDBG(SCTP_DEBUG_ASCONF1,
2594		    "compose_asconf: couldn't get mbuf!\n");
2595		sctp_m_freem(m_asconf_chk);
2596		return (NULL);
2597	}
2598	SCTP_BUF_LEN(m_asconf_chk) = sizeof(struct sctp_asconf_chunk);
2599	SCTP_BUF_LEN(m_asconf) = 0;
2600	acp = mtod(m_asconf_chk, struct sctp_asconf_chunk *);
2601	bzero(acp, sizeof(struct sctp_asconf_chunk));
2602	/* save pointers to lookup address and asconf params */
2603	lookup_ptr = (caddr_t)(acp + 1);	/* after the header */
2604	ptr = mtod(m_asconf, caddr_t);	/* beginning of cluster */
2605
2606	/* fill in chunk header info */
2607	acp->ch.chunk_type = SCTP_ASCONF;
2608	acp->ch.chunk_flags = 0;
2609	acp->serial_number = htonl(stcb->asoc.asconf_seq_out);
2610	stcb->asoc.asconf_seq_out++;
2611
2612	/* add parameters... up to smallest MTU allowed */
2613	TAILQ_FOREACH(aa, &stcb->asoc.asconf_queue, next) {
2614		if (aa->sent)
2615			continue;
2616		/* get the parameter length */
2617		p_length = SCTP_SIZE32(aa->ap.aph.ph.param_length);
2618		/* will it fit in current chunk? */
2619		if ((SCTP_BUF_LEN(m_asconf) + p_length > stcb->asoc.smallest_mtu) ||
2620		    (SCTP_BUF_LEN(m_asconf) + p_length > MCLBYTES)) {
2621			/* won't fit, so we're done with this chunk */
2622			break;
2623		}
2624		/* assign (and store) a correlation id */
2625		aa->ap.aph.correlation_id = correlation_id++;
2626
2627		/*
2628		 * fill in address if we're doing a delete this is a simple
2629		 * way for us to fill in the correlation address, which
2630		 * should only be used by the peer if we're deleting our
2631		 * source address and adding a new address (e.g. renumbering
2632		 * case)
2633		 */
2634		if (lookup_used == 0 &&
2635		    (aa->special_del == 0) &&
2636		    aa->ap.aph.ph.param_type == SCTP_DEL_IP_ADDRESS) {
2637			struct sctp_ipv6addr_param *lookup;
2638			uint16_t p_size, addr_size;
2639
2640			lookup = (struct sctp_ipv6addr_param *)lookup_ptr;
2641			lookup->ph.param_type =
2642			    htons(aa->ap.addrp.ph.param_type);
2643			if (aa->ap.addrp.ph.param_type == SCTP_IPV6_ADDRESS) {
2644				/* copy IPv6 address */
2645				p_size = sizeof(struct sctp_ipv6addr_param);
2646				addr_size = sizeof(struct in6_addr);
2647			} else {
2648				/* copy IPv4 address */
2649				p_size = sizeof(struct sctp_ipv4addr_param);
2650				addr_size = sizeof(struct in_addr);
2651			}
2652			lookup->ph.param_length = htons(SCTP_SIZE32(p_size));
2653			memcpy(lookup->addr, &aa->ap.addrp.addr, addr_size);
2654			SCTP_BUF_LEN(m_asconf_chk) += SCTP_SIZE32(p_size);
2655			lookup_used = 1;
2656		}
2657		/* copy into current space */
2658		memcpy(ptr, &aa->ap, p_length);
2659
2660		/* network elements and update lengths */
2661		aph = (struct sctp_asconf_paramhdr *)ptr;
2662		aap = (struct sctp_asconf_addr_param *)ptr;
2663		/* correlation_id is transparent to peer, no htonl needed */
2664		aph->ph.param_type = htons(aph->ph.param_type);
2665		aph->ph.param_length = htons(aph->ph.param_length);
2666		aap->addrp.ph.param_type = htons(aap->addrp.ph.param_type);
2667		aap->addrp.ph.param_length = htons(aap->addrp.ph.param_length);
2668
2669		SCTP_BUF_LEN(m_asconf) += SCTP_SIZE32(p_length);
2670		ptr += SCTP_SIZE32(p_length);
2671
2672		/*
2673		 * these params are removed off the pending list upon
2674		 * getting an ASCONF-ACK back from the peer, just set flag
2675		 */
2676		aa->sent = 1;
2677	}
2678	/* check to see if the lookup addr has been populated yet */
2679	if (lookup_used == 0) {
2680		/* NOTE: if the address param is optional, can skip this... */
2681		/* add any valid (existing) address... */
2682		struct sctp_ipv6addr_param *lookup;
2683		uint16_t p_size, addr_size;
2684		struct sockaddr *found_addr;
2685		caddr_t addr_ptr;
2686
2687		if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL)
2688			found_addr = sctp_find_valid_localaddr(stcb,
2689			    addr_locked);
2690		else
2691			found_addr = sctp_find_valid_localaddr_ep(stcb);
2692
2693		lookup = (struct sctp_ipv6addr_param *)lookup_ptr;
2694		if (found_addr != NULL) {
2695			switch (found_addr->sa_family) {
2696#ifdef INET6
2697			case AF_INET6:
2698				/* copy IPv6 address */
2699				lookup->ph.param_type =
2700				    htons(SCTP_IPV6_ADDRESS);
2701				p_size = sizeof(struct sctp_ipv6addr_param);
2702				addr_size = sizeof(struct in6_addr);
2703				addr_ptr = (caddr_t)&((struct sockaddr_in6 *)
2704				    found_addr)->sin6_addr;
2705				break;
2706#endif
2707#ifdef INET
2708			case AF_INET:
2709				/* copy IPv4 address */
2710				lookup->ph.param_type =
2711				    htons(SCTP_IPV4_ADDRESS);
2712				p_size = sizeof(struct sctp_ipv4addr_param);
2713				addr_size = sizeof(struct in_addr);
2714				addr_ptr = (caddr_t)&((struct sockaddr_in *)
2715				    found_addr)->sin_addr;
2716				break;
2717#endif
2718			default:
2719				p_size = 0;
2720				addr_size = 0;
2721				addr_ptr = NULL;
2722				break;
2723			}
2724			lookup->ph.param_length = htons(SCTP_SIZE32(p_size));
2725			memcpy(lookup->addr, addr_ptr, addr_size);
2726			SCTP_BUF_LEN(m_asconf_chk) += SCTP_SIZE32(p_size);
2727		} else {
2728			/* uh oh... don't have any address?? */
2729			SCTPDBG(SCTP_DEBUG_ASCONF1,
2730			    "compose_asconf: no lookup addr!\n");
2731			/* XXX for now, we send a IPv4 address of 0.0.0.0 */
2732			lookup->ph.param_type = htons(SCTP_IPV4_ADDRESS);
2733			lookup->ph.param_length = htons(SCTP_SIZE32(sizeof(struct sctp_ipv4addr_param)));
2734			bzero(lookup->addr, sizeof(struct in_addr));
2735			SCTP_BUF_LEN(m_asconf_chk) += SCTP_SIZE32(sizeof(struct sctp_ipv4addr_param));
2736		}
2737	}
2738	/* chain it all together */
2739	SCTP_BUF_NEXT(m_asconf_chk) = m_asconf;
2740	*retlen = SCTP_BUF_LEN(m_asconf_chk) + SCTP_BUF_LEN(m_asconf);
2741	acp->ch.chunk_length = htons(*retlen);
2742
2743	return (m_asconf_chk);
2744}
2745
2746/*
2747 * section to handle address changes before an association is up eg. changes
2748 * during INIT/INIT-ACK/COOKIE-ECHO handshake
2749 */
2750
2751/*
2752 * processes the (local) addresses in the INIT-ACK chunk
2753 */
2754static void
2755sctp_process_initack_addresses(struct sctp_tcb *stcb, struct mbuf *m,
2756    unsigned int offset, unsigned int length)
2757{
2758	struct sctp_paramhdr tmp_param, *ph;
2759	uint16_t plen, ptype;
2760	struct sctp_ifa *sctp_ifa;
2761
2762#ifdef INET6
2763	struct sctp_ipv6addr_param addr6_store;
2764	struct sockaddr_in6 sin6;
2765
2766#endif
2767#ifdef INET
2768	struct sctp_ipv4addr_param addr4_store;
2769	struct sockaddr_in sin;
2770
2771#endif
2772	struct sockaddr *sa;
2773	uint32_t vrf_id;
2774
2775	SCTPDBG(SCTP_DEBUG_ASCONF2, "processing init-ack addresses\n");
2776	if (stcb == NULL)	/* Un-needed check for SA */
2777		return;
2778
2779	/* convert to upper bound */
2780	length += offset;
2781
2782	if ((offset + sizeof(struct sctp_paramhdr)) > length) {
2783		return;
2784	}
2785	/* init the addresses */
2786#ifdef INET6
2787	bzero(&sin6, sizeof(sin6));
2788	sin6.sin6_family = AF_INET6;
2789	sin6.sin6_len = sizeof(sin6);
2790	sin6.sin6_port = stcb->rport;
2791#endif
2792
2793#ifdef INET
2794	bzero(&sin, sizeof(sin));
2795	sin.sin_family = AF_INET;
2796	sin.sin_len = sizeof(sin);
2797	sin.sin_port = stcb->rport;
2798#endif
2799
2800	/* go through the addresses in the init-ack */
2801	ph = (struct sctp_paramhdr *)
2802	    sctp_m_getptr(m, offset, sizeof(struct sctp_paramhdr),
2803	    (uint8_t *) & tmp_param);
2804	while (ph != NULL) {
2805		ptype = ntohs(ph->param_type);
2806		plen = ntohs(ph->param_length);
2807		switch (ptype) {
2808#ifdef INET6
2809		case SCTP_IPV6_ADDRESS:
2810			{
2811				struct sctp_ipv6addr_param *a6p;
2812
2813				/* get the entire IPv6 address param */
2814				a6p = (struct sctp_ipv6addr_param *)
2815				    sctp_m_getptr(m, offset,
2816				    sizeof(struct sctp_ipv6addr_param),
2817				    (uint8_t *) & addr6_store);
2818				if (plen != sizeof(struct sctp_ipv6addr_param) ||
2819				    a6p == NULL) {
2820					return;
2821				}
2822				memcpy(&sin6.sin6_addr, a6p->addr,
2823				    sizeof(struct in6_addr));
2824				sa = (struct sockaddr *)&sin6;
2825				break;
2826			}
2827#endif
2828#ifdef INET
2829		case SCTP_IPV4_ADDRESS:
2830			{
2831				struct sctp_ipv4addr_param *a4p;
2832
2833				/* get the entire IPv4 address param */
2834				a4p = (struct sctp_ipv4addr_param *)sctp_m_getptr(m, offset,
2835				    sizeof(struct sctp_ipv4addr_param),
2836				    (uint8_t *) & addr4_store);
2837				if (plen != sizeof(struct sctp_ipv4addr_param) ||
2838				    a4p == NULL) {
2839					return;
2840				}
2841				sin.sin_addr.s_addr = a4p->addr;
2842				sa = (struct sockaddr *)&sin;
2843				break;
2844			}
2845#endif
2846		default:
2847			goto next_addr;
2848		}
2849
2850		/* see if this address really (still) exists */
2851		if (stcb) {
2852			vrf_id = stcb->asoc.vrf_id;
2853		} else {
2854			vrf_id = SCTP_DEFAULT_VRFID;
2855		}
2856		sctp_ifa = sctp_find_ifa_by_addr(sa, vrf_id,
2857		    SCTP_ADDR_NOT_LOCKED);
2858		if (sctp_ifa == NULL) {
2859			/* address doesn't exist anymore */
2860			int status;
2861
2862			/* are ASCONFs allowed ? */
2863			if ((sctp_is_feature_on(stcb->sctp_ep,
2864			    SCTP_PCB_FLAGS_DO_ASCONF)) &&
2865			    stcb->asoc.peer_supports_asconf) {
2866				/* queue an ASCONF DEL_IP_ADDRESS */
2867				status = sctp_asconf_queue_sa_delete(stcb, sa);
2868				/*
2869				 * if queued ok, and in correct state, send
2870				 * out the ASCONF.
2871				 */
2872				if (status == 0 &&
2873				    SCTP_GET_STATE(&stcb->asoc) ==
2874				    SCTP_STATE_OPEN) {
2875#ifdef SCTP_TIMER_BASED_ASCONF
2876					sctp_timer_start(SCTP_TIMER_TYPE_ASCONF,
2877					    stcb->sctp_ep, stcb,
2878					    stcb->asoc.primary_destination);
2879#else
2880					sctp_send_asconf(stcb, NULL, SCTP_ADDR_NOT_LOCKED);
2881#endif
2882				}
2883			}
2884		}
2885next_addr:
2886		/*
2887		 * Sanity check:  Make sure the length isn't 0, otherwise
2888		 * we'll be stuck in this loop for a long time...
2889		 */
2890		if (SCTP_SIZE32(plen) == 0) {
2891			SCTP_PRINTF("process_initack_addrs: bad len (%d) type=%xh\n",
2892			    plen, ptype);
2893			return;
2894		}
2895		/* get next parameter */
2896		offset += SCTP_SIZE32(plen);
2897		if ((offset + sizeof(struct sctp_paramhdr)) > length)
2898			return;
2899		ph = (struct sctp_paramhdr *)sctp_m_getptr(m, offset,
2900		    sizeof(struct sctp_paramhdr), (uint8_t *) & tmp_param);
2901	}			/* while */
2902}
2903
2904/* FIX ME: need to verify return result for v6 address type if v6 disabled */
2905/*
2906 * checks to see if a specific address is in the initack address list returns
2907 * 1 if found, 0 if not
2908 */
2909static uint32_t
2910sctp_addr_in_initack(struct mbuf *m, uint32_t offset, uint32_t length, struct sockaddr *sa)
2911{
2912	struct sctp_paramhdr tmp_param, *ph;
2913	uint16_t plen, ptype;
2914
2915#ifdef INET
2916	struct sockaddr_in *sin;
2917	struct sctp_ipv4addr_param *a4p;
2918	struct sctp_ipv6addr_param addr4_store;
2919
2920#endif
2921#ifdef INET6
2922	struct sockaddr_in6 *sin6;
2923	struct sctp_ipv6addr_param *a6p;
2924	struct sctp_ipv6addr_param addr6_store;
2925	struct sockaddr_in6 sin6_tmp;
2926
2927#endif
2928
2929	switch (sa->sa_family) {
2930#ifdef INET
2931	case AF_INET:
2932		break;
2933#endif
2934#ifdef INET6
2935	case AF_INET6:
2936		break;
2937#endif
2938	default:
2939		return (0);
2940	}
2941
2942	SCTPDBG(SCTP_DEBUG_ASCONF2, "find_initack_addr: starting search for ");
2943	SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, sa);
2944	/* convert to upper bound */
2945	length += offset;
2946
2947	if ((offset + sizeof(struct sctp_paramhdr)) > length) {
2948		SCTPDBG(SCTP_DEBUG_ASCONF1,
2949		    "find_initack_addr: invalid offset?\n");
2950		return (0);
2951	}
2952	/* go through the addresses in the init-ack */
2953	ph = (struct sctp_paramhdr *)sctp_m_getptr(m, offset,
2954	    sizeof(struct sctp_paramhdr), (uint8_t *) & tmp_param);
2955	while (ph != NULL) {
2956		ptype = ntohs(ph->param_type);
2957		plen = ntohs(ph->param_length);
2958		switch (ptype) {
2959#ifdef INET6
2960		case SCTP_IPV6_ADDRESS:
2961			if (sa->sa_family == AF_INET6) {
2962				/* get the entire IPv6 address param */
2963				if (plen != sizeof(struct sctp_ipv6addr_param)) {
2964					break;
2965				}
2966				/* get the entire IPv6 address param */
2967				a6p = (struct sctp_ipv6addr_param *)
2968				    sctp_m_getptr(m, offset,
2969				    sizeof(struct sctp_ipv6addr_param),
2970				    (uint8_t *) & addr6_store);
2971				if (a6p == NULL) {
2972					return (0);
2973				}
2974				sin6 = (struct sockaddr_in6 *)sa;
2975				if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr)) {
2976					/* create a copy and clear scope */
2977					memcpy(&sin6_tmp, sin6,
2978					    sizeof(struct sockaddr_in6));
2979					sin6 = &sin6_tmp;
2980					in6_clearscope(&sin6->sin6_addr);
2981				}
2982				if (memcmp(&sin6->sin6_addr, a6p->addr,
2983				    sizeof(struct in6_addr)) == 0) {
2984					/* found it */
2985					return (1);
2986				}
2987			}
2988			break;
2989#endif				/* INET6 */
2990#ifdef INET
2991		case SCTP_IPV4_ADDRESS:
2992			if (sa->sa_family == AF_INET) {
2993				if (plen != sizeof(struct sctp_ipv4addr_param)) {
2994					break;
2995				}
2996				/* get the entire IPv4 address param */
2997				a4p = (struct sctp_ipv4addr_param *)
2998				    sctp_m_getptr(m, offset,
2999				    sizeof(struct sctp_ipv4addr_param),
3000				    (uint8_t *) & addr4_store);
3001				if (a4p == NULL) {
3002					return (0);
3003				}
3004				sin = (struct sockaddr_in *)sa;
3005				if (sin->sin_addr.s_addr == a4p->addr) {
3006					/* found it */
3007					return (1);
3008				}
3009			}
3010			break;
3011#endif
3012		default:
3013			break;
3014		}
3015		/* get next parameter */
3016		offset += SCTP_SIZE32(plen);
3017		if (offset + sizeof(struct sctp_paramhdr) > length) {
3018			return (0);
3019		}
3020		ph = (struct sctp_paramhdr *)
3021		    sctp_m_getptr(m, offset, sizeof(struct sctp_paramhdr),
3022		    (uint8_t *) & tmp_param);
3023	}			/* while */
3024	/* not found! */
3025	return (0);
3026}
3027
3028/*
3029 * makes sure that the current endpoint local addr list is consistent with
3030 * the new association (eg. subset bound, asconf allowed) adds addresses as
3031 * necessary
3032 */
3033static void
3034sctp_check_address_list_ep(struct sctp_tcb *stcb, struct mbuf *m, int offset,
3035    int length, struct sockaddr *init_addr)
3036{
3037	struct sctp_laddr *laddr;
3038
3039	/* go through the endpoint list */
3040	LIST_FOREACH(laddr, &stcb->sctp_ep->sctp_addr_list, sctp_nxt_addr) {
3041		/* be paranoid and validate the laddr */
3042		if (laddr->ifa == NULL) {
3043			SCTPDBG(SCTP_DEBUG_ASCONF1,
3044			    "check_addr_list_ep: laddr->ifa is NULL");
3045			continue;
3046		}
3047		if (laddr->ifa == NULL) {
3048			SCTPDBG(SCTP_DEBUG_ASCONF1, "check_addr_list_ep: laddr->ifa->ifa_addr is NULL");
3049			continue;
3050		}
3051		/* do i have it implicitly? */
3052		if (sctp_cmpaddr(&laddr->ifa->address.sa, init_addr)) {
3053			continue;
3054		}
3055		/* check to see if in the init-ack */
3056		if (!sctp_addr_in_initack(m, offset, length, &laddr->ifa->address.sa)) {
3057			/* try to add it */
3058			sctp_addr_mgmt_assoc(stcb->sctp_ep, stcb, laddr->ifa,
3059			    SCTP_ADD_IP_ADDRESS, SCTP_ADDR_NOT_LOCKED);
3060		}
3061	}
3062}
3063
3064/*
3065 * makes sure that the current kernel address list is consistent with the new
3066 * association (with all addrs bound) adds addresses as necessary
3067 */
3068static void
3069sctp_check_address_list_all(struct sctp_tcb *stcb, struct mbuf *m, int offset,
3070    int length, struct sockaddr *init_addr,
3071    uint16_t local_scope, uint16_t site_scope,
3072    uint16_t ipv4_scope, uint16_t loopback_scope)
3073{
3074	struct sctp_vrf *vrf = NULL;
3075	struct sctp_ifn *sctp_ifn;
3076	struct sctp_ifa *sctp_ifa;
3077	uint32_t vrf_id;
3078
3079#ifdef INET
3080	struct sockaddr_in *sin;
3081
3082#endif
3083#ifdef INET6
3084	struct sockaddr_in6 *sin6;
3085
3086#endif
3087
3088	if (stcb) {
3089		vrf_id = stcb->asoc.vrf_id;
3090	} else {
3091		return;
3092	}
3093	SCTP_IPI_ADDR_RLOCK();
3094	vrf = sctp_find_vrf(vrf_id);
3095	if (vrf == NULL) {
3096		SCTP_IPI_ADDR_RUNLOCK();
3097		return;
3098	}
3099	/* go through all our known interfaces */
3100	LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) {
3101		if (loopback_scope == 0 && SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) {
3102			/* skip loopback interface */
3103			continue;
3104		}
3105		/* go through each interface address */
3106		LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
3107			/* do i have it implicitly? */
3108			if (sctp_cmpaddr(&sctp_ifa->address.sa, init_addr)) {
3109				continue;
3110			}
3111			switch (sctp_ifa->address.sa.sa_family) {
3112#ifdef INET
3113			case AF_INET:
3114				sin = (struct sockaddr_in *)&sctp_ifa->address.sin;
3115				if ((ipv4_scope == 0) &&
3116				    (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) {
3117					/* private address not in scope */
3118					continue;
3119				}
3120				break;
3121#endif
3122#ifdef INET6
3123			case AF_INET6:
3124				sin6 = (struct sockaddr_in6 *)&sctp_ifa->address.sin6;
3125				if ((local_scope == 0) &&
3126				    (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))) {
3127					continue;
3128				}
3129				if ((site_scope == 0) &&
3130				    (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) {
3131					continue;
3132				}
3133				break;
3134#endif
3135			default:
3136				break;
3137			}
3138			/* check to see if in the init-ack */
3139			if (!sctp_addr_in_initack(m, offset, length, &sctp_ifa->address.sa)) {
3140				/* try to add it */
3141				sctp_addr_mgmt_assoc(stcb->sctp_ep, stcb,
3142				    sctp_ifa, SCTP_ADD_IP_ADDRESS,
3143				    SCTP_ADDR_LOCKED);
3144			}
3145		}		/* end foreach ifa */
3146	}			/* end foreach ifn */
3147	SCTP_IPI_ADDR_RUNLOCK();
3148}
3149
3150/*
3151 * validates an init-ack chunk (from a cookie-echo) with current addresses
3152 * adds addresses from the init-ack into our local address list, if needed
3153 * queues asconf adds/deletes addresses as needed and makes appropriate list
3154 * changes for source address selection m, offset: points to the start of the
3155 * address list in an init-ack chunk length: total length of the address
3156 * params only init_addr: address where my INIT-ACK was sent from
3157 */
3158void
3159sctp_check_address_list(struct sctp_tcb *stcb, struct mbuf *m, int offset,
3160    int length, struct sockaddr *init_addr,
3161    uint16_t local_scope, uint16_t site_scope,
3162    uint16_t ipv4_scope, uint16_t loopback_scope)
3163{
3164	/* process the local addresses in the initack */
3165	sctp_process_initack_addresses(stcb, m, offset, length);
3166
3167	if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
3168		/* bound all case */
3169		sctp_check_address_list_all(stcb, m, offset, length, init_addr,
3170		    local_scope, site_scope, ipv4_scope, loopback_scope);
3171	} else {
3172		/* subset bound case */
3173		if (sctp_is_feature_on(stcb->sctp_ep,
3174		    SCTP_PCB_FLAGS_DO_ASCONF)) {
3175			/* asconf's allowed */
3176			sctp_check_address_list_ep(stcb, m, offset, length,
3177			    init_addr);
3178		}
3179		/* else, no asconfs allowed, so what we sent is what we get */
3180	}
3181}
3182
3183/*
3184 * sctp_bindx() support
3185 */
3186uint32_t
3187sctp_addr_mgmt_ep_sa(struct sctp_inpcb *inp, struct sockaddr *sa,
3188    uint32_t type, uint32_t vrf_id, struct sctp_ifa *sctp_ifap)
3189{
3190	struct sctp_ifa *ifa;
3191	struct sctp_laddr *laddr, *nladdr;
3192
3193	if (sa->sa_len == 0) {
3194		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, EINVAL);
3195		return (EINVAL);
3196	}
3197	if (sctp_ifap) {
3198		ifa = sctp_ifap;
3199	} else if (type == SCTP_ADD_IP_ADDRESS) {
3200		/* For an add the address MUST be on the system */
3201		ifa = sctp_find_ifa_by_addr(sa, vrf_id, SCTP_ADDR_NOT_LOCKED);
3202	} else if (type == SCTP_DEL_IP_ADDRESS) {
3203		/* For a delete we need to find it in the inp */
3204		ifa = sctp_find_ifa_in_ep(inp, sa, SCTP_ADDR_NOT_LOCKED);
3205	} else {
3206		ifa = NULL;
3207	}
3208	if (ifa != NULL) {
3209		if (type == SCTP_ADD_IP_ADDRESS) {
3210			sctp_add_local_addr_ep(inp, ifa, type);
3211		} else if (type == SCTP_DEL_IP_ADDRESS) {
3212			if (inp->laddr_count < 2) {
3213				/* can't delete the last local address */
3214				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, EINVAL);
3215				return (EINVAL);
3216			}
3217			LIST_FOREACH(laddr, &inp->sctp_addr_list,
3218			    sctp_nxt_addr) {
3219				if (ifa == laddr->ifa) {
3220					/* Mark in the delete */
3221					laddr->action = type;
3222				}
3223			}
3224		}
3225		if (LIST_EMPTY(&inp->sctp_asoc_list)) {
3226			/*
3227			 * There is no need to start the iterator if the inp
3228			 * has no associations.
3229			 */
3230			if (type == SCTP_DEL_IP_ADDRESS) {
3231				LIST_FOREACH_SAFE(laddr, &inp->sctp_addr_list, sctp_nxt_addr, nladdr) {
3232					if (laddr->ifa == ifa) {
3233						sctp_del_local_addr_ep(inp, ifa);
3234					}
3235				}
3236			}
3237		} else {
3238			struct sctp_asconf_iterator *asc;
3239			struct sctp_laddr *wi;
3240
3241			SCTP_MALLOC(asc, struct sctp_asconf_iterator *,
3242			    sizeof(struct sctp_asconf_iterator),
3243			    SCTP_M_ASC_IT);
3244			if (asc == NULL) {
3245				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, ENOMEM);
3246				return (ENOMEM);
3247			}
3248			wi = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_laddr), struct sctp_laddr);
3249			if (wi == NULL) {
3250				SCTP_FREE(asc, SCTP_M_ASC_IT);
3251				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, ENOMEM);
3252				return (ENOMEM);
3253			}
3254			LIST_INIT(&asc->list_of_work);
3255			asc->cnt = 1;
3256			SCTP_INCR_LADDR_COUNT();
3257			wi->ifa = ifa;
3258			wi->action = type;
3259			atomic_add_int(&ifa->refcount, 1);
3260			LIST_INSERT_HEAD(&asc->list_of_work, wi, sctp_nxt_addr);
3261			(void)sctp_initiate_iterator(sctp_asconf_iterator_ep,
3262			    sctp_asconf_iterator_stcb,
3263			    sctp_asconf_iterator_ep_end,
3264			    SCTP_PCB_ANY_FLAGS,
3265			    SCTP_PCB_ANY_FEATURES,
3266			    SCTP_ASOC_ANY_STATE,
3267			    (void *)asc, 0,
3268			    sctp_asconf_iterator_end, inp, 0);
3269		}
3270		return (0);
3271	} else {
3272		/* invalid address! */
3273		SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_ASCONF, EADDRNOTAVAIL);
3274		return (EADDRNOTAVAIL);
3275	}
3276}
3277
3278void
3279sctp_asconf_send_nat_state_update(struct sctp_tcb *stcb,
3280    struct sctp_nets *net)
3281{
3282	struct sctp_asconf_addr *aa;
3283	struct sctp_ifa *sctp_ifap;
3284	struct sctp_asconf_tag_param *vtag;
3285
3286#ifdef INET
3287	struct sockaddr_in *to;
3288
3289#endif
3290#ifdef INET6
3291	struct sockaddr_in6 *to6;
3292
3293#endif
3294	if (net == NULL) {
3295		SCTPDBG(SCTP_DEBUG_ASCONF1, "sctp_asconf_send_nat_state_update: Missing net\n");
3296		return;
3297	}
3298	if (stcb == NULL) {
3299		SCTPDBG(SCTP_DEBUG_ASCONF1, "sctp_asconf_send_nat_state_update: Missing stcb\n");
3300		return;
3301	}
3302	/*
3303	 * Need to have in the asconf: - vtagparam(my_vtag/peer_vtag) -
3304	 * add(0.0.0.0) - del(0.0.0.0) - Any global addresses add(addr)
3305	 */
3306	SCTP_MALLOC(aa, struct sctp_asconf_addr *, sizeof(*aa),
3307	    SCTP_M_ASC_ADDR);
3308	if (aa == NULL) {
3309		/* didn't get memory */
3310		SCTPDBG(SCTP_DEBUG_ASCONF1,
3311		    "sctp_asconf_send_nat_state_update: failed to get memory!\n");
3312		return;
3313	}
3314	aa->special_del = 0;
3315	/* fill in asconf address parameter fields */
3316	/* top level elements are "networked" during send */
3317	aa->ifa = NULL;
3318	aa->sent = 0;		/* clear sent flag */
3319	vtag = (struct sctp_asconf_tag_param *)&aa->ap.aph;
3320	vtag->aph.ph.param_type = SCTP_NAT_VTAGS;
3321	vtag->aph.ph.param_length = sizeof(struct sctp_asconf_tag_param);
3322	vtag->local_vtag = htonl(stcb->asoc.my_vtag);
3323	vtag->remote_vtag = htonl(stcb->asoc.peer_vtag);
3324	TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
3325
3326	SCTP_MALLOC(aa, struct sctp_asconf_addr *, sizeof(*aa),
3327	    SCTP_M_ASC_ADDR);
3328	if (aa == NULL) {
3329		/* didn't get memory */
3330		SCTPDBG(SCTP_DEBUG_ASCONF1,
3331		    "sctp_asconf_send_nat_state_update: failed to get memory!\n");
3332		return;
3333	}
3334	memset(aa, 0, sizeof(struct sctp_asconf_addr));
3335	/* fill in asconf address parameter fields */
3336	/* ADD(0.0.0.0) */
3337	switch (net->ro._l_addr.sa.sa_family) {
3338#ifdef INET
3339	case AF_INET:
3340		aa->ap.aph.ph.param_type = SCTP_ADD_IP_ADDRESS;
3341		aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_addrv4_param);
3342		aa->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS;
3343		aa->ap.addrp.ph.param_length = sizeof(struct sctp_ipv4addr_param);
3344		/* No need to add an address, we are using 0.0.0.0 */
3345		TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
3346		break;
3347#endif
3348#ifdef INET6
3349	case AF_INET6:
3350		aa->ap.aph.ph.param_type = SCTP_ADD_IP_ADDRESS;
3351		aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_addr_param);
3352		aa->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS;
3353		aa->ap.addrp.ph.param_length = sizeof(struct sctp_ipv6addr_param);
3354		/* No need to add an address, we are using 0.0.0.0 */
3355		TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
3356		break;
3357#endif
3358	}
3359	SCTP_MALLOC(aa, struct sctp_asconf_addr *, sizeof(*aa),
3360	    SCTP_M_ASC_ADDR);
3361	if (aa == NULL) {
3362		/* didn't get memory */
3363		SCTPDBG(SCTP_DEBUG_ASCONF1,
3364		    "sctp_asconf_send_nat_state_update: failed to get memory!\n");
3365		return;
3366	}
3367	memset(aa, 0, sizeof(struct sctp_asconf_addr));
3368	/* fill in asconf address parameter fields */
3369	/* ADD(0.0.0.0) */
3370	switch (net->ro._l_addr.sa.sa_family) {
3371#ifdef INET
3372	case AF_INET:
3373		aa->ap.aph.ph.param_type = SCTP_ADD_IP_ADDRESS;
3374		aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_addrv4_param);
3375		aa->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS;
3376		aa->ap.addrp.ph.param_length = sizeof(struct sctp_ipv4addr_param);
3377		/* No need to add an address, we are using 0.0.0.0 */
3378		TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
3379		break;
3380#endif
3381#ifdef INET6
3382	case AF_INET6:
3383		aa->ap.aph.ph.param_type = SCTP_DEL_IP_ADDRESS;
3384		aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_addr_param);
3385		aa->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS;
3386		aa->ap.addrp.ph.param_length = sizeof(struct sctp_ipv6addr_param);
3387		/* No need to add an address, we are using 0.0.0.0 */
3388		TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
3389		break;
3390#endif
3391	}
3392	/* Now we must hunt the addresses and add all global addresses */
3393	if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
3394		struct sctp_vrf *vrf = NULL;
3395		struct sctp_ifn *sctp_ifnp;
3396		uint32_t vrf_id;
3397
3398		vrf_id = stcb->sctp_ep->def_vrf_id;
3399		vrf = sctp_find_vrf(vrf_id);
3400		if (vrf == NULL) {
3401			goto skip_rest;
3402		}
3403		SCTP_IPI_ADDR_RLOCK();
3404		LIST_FOREACH(sctp_ifnp, &vrf->ifnlist, next_ifn) {
3405			LIST_FOREACH(sctp_ifap, &sctp_ifnp->ifalist, next_ifa) {
3406				switch (sctp_ifap->address.sa.sa_family) {
3407#ifdef INET
3408				case AF_INET:
3409					to = &sctp_ifap->address.sin;
3410					if (IN4_ISPRIVATE_ADDRESS(&to->sin_addr)) {
3411						continue;
3412					}
3413					if (IN4_ISLOOPBACK_ADDRESS(&to->sin_addr)) {
3414						continue;
3415					}
3416					break;
3417#endif
3418#ifdef INET6
3419				case AF_INET6:
3420					to6 = &sctp_ifap->address.sin6;
3421					if (IN6_IS_ADDR_LOOPBACK(&to6->sin6_addr)) {
3422						continue;
3423					}
3424					if (IN6_IS_ADDR_LINKLOCAL(&to6->sin6_addr)) {
3425						continue;
3426					}
3427					break;
3428#endif
3429				default:
3430					continue;
3431				}
3432				sctp_asconf_queue_mgmt(stcb, sctp_ifap, SCTP_ADD_IP_ADDRESS);
3433			}
3434		}
3435		SCTP_IPI_ADDR_RUNLOCK();
3436	} else {
3437		struct sctp_laddr *laddr;
3438
3439		LIST_FOREACH(laddr, &stcb->sctp_ep->sctp_addr_list, sctp_nxt_addr) {
3440			if (laddr->ifa == NULL) {
3441				continue;
3442			}
3443			if (laddr->ifa->localifa_flags & SCTP_BEING_DELETED)
3444				/*
3445				 * Address being deleted by the system, dont
3446				 * list.
3447				 */
3448				continue;
3449			if (laddr->action == SCTP_DEL_IP_ADDRESS) {
3450				/*
3451				 * Address being deleted on this ep don't
3452				 * list.
3453				 */
3454				continue;
3455			}
3456			sctp_ifap = laddr->ifa;
3457			switch (sctp_ifap->address.sa.sa_family) {
3458#ifdef INET
3459			case AF_INET:
3460				to = &sctp_ifap->address.sin;
3461				if (IN4_ISPRIVATE_ADDRESS(&to->sin_addr)) {
3462					continue;
3463				}
3464				if (IN4_ISLOOPBACK_ADDRESS(&to->sin_addr)) {
3465					continue;
3466				}
3467				break;
3468#endif
3469#ifdef INET6
3470			case AF_INET6:
3471				to6 = &sctp_ifap->address.sin6;
3472				if (IN6_IS_ADDR_LOOPBACK(&to6->sin6_addr)) {
3473					continue;
3474				}
3475				if (IN6_IS_ADDR_LINKLOCAL(&to6->sin6_addr)) {
3476					continue;
3477				}
3478				break;
3479#endif
3480			default:
3481				continue;
3482			}
3483			sctp_asconf_queue_mgmt(stcb, sctp_ifap, SCTP_ADD_IP_ADDRESS);
3484		}
3485	}
3486skip_rest:
3487	/* Now we must send the asconf into the queue */
3488	sctp_send_asconf(stcb, net, SCTP_ADDR_NOT_LOCKED);
3489}
3490