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