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