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