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