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