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