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