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