sctp_bsd_addr.c (166086) | sctp_bsd_addr.c (167598) |
---|---|
1/*- | 1/*- |
2 * Copyright (c) 2001-2006, Cisco Systems, Inc. All rights reserved. | 2 * Copyright (c) 2001-2007, Cisco Systems, Inc. All rights reserved. |
3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * a) Redistributions of source code must retain the above copyright notice, 8 * this list of conditions and the following disclaimer. 9 * 10 * b) Redistributions in binary form must reproduce the above copyright --- 15 unchanged lines hidden (view full) --- 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 28 * THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31/* $KAME: sctp_output.c,v 1.46 2005/03/06 16:04:17 itojun Exp $ */ 32 33#include <sys/cdefs.h> | 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * a) Redistributions of source code must retain the above copyright notice, 8 * this list of conditions and the following disclaimer. 9 * 10 * b) Redistributions in binary form must reproduce the above copyright --- 15 unchanged lines hidden (view full) --- 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 28 * THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31/* $KAME: sctp_output.c,v 1.46 2005/03/06 16:04:17 itojun Exp $ */ 32 33#include <sys/cdefs.h> |
34__FBSDID("$FreeBSD: head/sys/netinet/sctp_bsd_addr.c 166086 2007-01-18 09:58:43Z rrs $"); | 34__FBSDID("$FreeBSD: head/sys/netinet/sctp_bsd_addr.c 167598 2007-03-15 11:27:14Z rrs $"); |
35 36#include <netinet/sctp_os.h> 37#include <netinet/sctp_var.h> 38#include <netinet/sctp_pcb.h> 39#include <netinet/sctp_header.h> 40#include <netinet/sctputil.h> 41#include <netinet/sctp_output.h> 42#include <netinet/sctp_bsd_addr.h> 43#include <netinet/sctp_uio.h> 44#include <netinet/sctputil.h> 45#include <netinet/sctp_timer.h> 46#include <netinet/sctp_asconf.h> 47#include <netinet/sctp_indata.h> | 35 36#include <netinet/sctp_os.h> 37#include <netinet/sctp_var.h> 38#include <netinet/sctp_pcb.h> 39#include <netinet/sctp_header.h> 40#include <netinet/sctputil.h> 41#include <netinet/sctp_output.h> 42#include <netinet/sctp_bsd_addr.h> 43#include <netinet/sctp_uio.h> 44#include <netinet/sctputil.h> 45#include <netinet/sctp_timer.h> 46#include <netinet/sctp_asconf.h> 47#include <netinet/sctp_indata.h> |
48#include <sys/unistd.h> |
|
48 | 49 |
49 50/* XXX 51 * This module needs to be rewritten with an eye towards getting 52 * rid of the user of ifa.. and use another list method George 53 * as told me of. 54 */ 55 | |
56#ifdef SCTP_DEBUG 57extern uint32_t sctp_debug_on; 58 59#endif 60 | 50#ifdef SCTP_DEBUG 51extern uint32_t sctp_debug_on; 52 53#endif 54 |
61static struct sockaddr_in * 62sctp_is_v4_ifa_addr_prefered(struct ifaddr *ifa, uint8_t loopscope, uint8_t ipv4_scope, uint8_t * sin_loop, uint8_t * sin_local) 63{ 64 struct sockaddr_in *sin; | |
65 | 55 |
66 /* 67 * Here we determine if its a prefered address. A prefered address 68 * means it is the same scope or higher scope then the destination. 69 * L = loopback, P = private, G = global 70 * ----------------------------------------- src | dest | 71 * result ----------------------------------------- L | L | 72 * yes ----------------------------------------- P | L | yes 73 * ----------------------------------------- G | L | yes 74 * ----------------------------------------- L | P | no 75 * ----------------------------------------- P | P | yes 76 * ----------------------------------------- G | P | no 77 * ----------------------------------------- L | G | no 78 * ----------------------------------------- P | G | no 79 * ----------------------------------------- G | G | yes 80 * ----------------------------------------- 81 */ 82 83 if (ifa->ifa_addr->sa_family != AF_INET) { 84 /* forget non-v4 */ 85 return (NULL); 86 } 87 /* Ok the address may be ok */ 88 sin = (struct sockaddr_in *)ifa->ifa_addr; 89 if (sin->sin_addr.s_addr == 0) { 90 return (NULL); 91 } 92 *sin_local = *sin_loop = 0; 93 if ((ifa->ifa_ifp->if_type == IFT_LOOP) || 94 (IN4_ISLOOPBACK_ADDRESS(&sin->sin_addr))) { 95 *sin_loop = 1; 96 *sin_local = 1; 97 } 98 if ((IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) { 99 *sin_local = 1; 100 } 101 if (!loopscope && *sin_loop) { 102 /* Its a loopback address and we don't have loop scope */ 103 return (NULL); 104 } 105 if (!ipv4_scope && *sin_local) { 106 /* 107 * Its a private address, and we don't have private address 108 * scope 109 */ 110 return (NULL); 111 } 112 if (((ipv4_scope == 0) && (loopscope == 0)) && (*sin_local)) { 113 /* its a global src and a private dest */ 114 return (NULL); 115 } 116 /* its a prefered address */ 117 return (sin); 118} 119 120static struct sockaddr_in * 121sctp_is_v4_ifa_addr_acceptable(struct ifaddr *ifa, uint8_t loopscope, uint8_t ipv4_scope, uint8_t * sin_loop, uint8_t * sin_local) | 56#if defined(SCTP_USE_THREAD_BASED_ITERATOR) 57void 58sctp_wakeup_iterator(void) |
122{ | 59{ |
123 struct sockaddr_in *sin; 124 125 /* 126 * Here we determine if its a acceptable address. A acceptable 127 * address means it is the same scope or higher scope but we can 128 * allow for NAT which means its ok to have a global dest and a 129 * private src. 130 * 131 * L = loopback, P = private, G = global 132 * ----------------------------------------- src | dest | 133 * result ----------------------------------------- L | L | 134 * yes ----------------------------------------- P | L | yes 135 * ----------------------------------------- G | L | yes 136 * ----------------------------------------- L | P | no 137 * ----------------------------------------- P | P | yes 138 * ----------------------------------------- G | P | yes - 139 * probably this won't work. 140 * ----------------------------------------- L | G | 141 * no ----------------------------------------- P | G | 142 * yes ----------------------------------------- G | G | 143 * yes ----------------------------------------- 144 */ 145 146 if (ifa->ifa_addr->sa_family != AF_INET) { 147 /* forget non-v4 */ 148 return (NULL); 149 } 150 /* Ok the address may be ok */ 151 sin = (struct sockaddr_in *)ifa->ifa_addr; 152 if (sin->sin_addr.s_addr == 0) { 153 return (NULL); 154 } 155 *sin_local = *sin_loop = 0; 156 if ((ifa->ifa_ifp->if_type == IFT_LOOP) || 157 (IN4_ISLOOPBACK_ADDRESS(&sin->sin_addr))) { 158 *sin_loop = 1; 159 *sin_local = 1; 160 } 161 if ((IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) { 162 *sin_local = 1; 163 } 164 if (!loopscope && *sin_loop) { 165 /* Its a loopback address and we don't have loop scope */ 166 return (NULL); 167 } 168 /* its an acceptable address */ 169 return (sin); | 60 wakeup(&sctppcbinfo.iterator_running); |
170} 171 | 61} 62 |
172/* 173 * This treats the address list on the ep as a restricted list (negative 174 * list). If a the passed address is listed, then the address is NOT allowed 175 * on the association. 176 */ 177int 178sctp_is_addr_restricted(struct sctp_tcb *stcb, struct sockaddr *addr) | 63static void 64sctp_iterator_thread(void *v) |
179{ | 65{ |
180 struct sctp_laddr *laddr; 181 182#ifdef SCTP_DEBUG 183 int cnt = 0; 184 185#endif 186 if (stcb == NULL) { 187 /* There are no restrictions, no TCB :-) */ 188 return (0); | 66 SCTP_IPI_ITERATOR_WQ_LOCK(); 67 sctppcbinfo.iterator_running = 0; 68 while (1) { 69 msleep(&sctppcbinfo.iterator_running, 70 &sctppcbinfo.ipi_iterator_wq_mtx, 71 0, "waiting_for_work", 0); 72 sctp_iterator_worker(); |
189 } | 73 } |
190#ifdef SCTP_DEBUG 191 LIST_FOREACH(laddr, &stcb->asoc.sctp_local_addr_list, sctp_nxt_addr) { 192 cnt++; 193 } 194 if (sctp_debug_on & SCTP_DEBUG_OUTPUT4) { 195 printf("There are %d addresses on the restricted list\n", cnt); 196 } 197 cnt = 0; 198#endif 199 LIST_FOREACH(laddr, &stcb->asoc.sctp_local_addr_list, sctp_nxt_addr) { 200 if (laddr->ifa == NULL) { 201#ifdef SCTP_DEBUG 202 if (sctp_debug_on & SCTP_DEBUG_OUTPUT1) { 203 printf("Help I have fallen and I can't get up!\n"); 204 } 205#endif 206 continue; 207 } 208#ifdef SCTP_DEBUG 209 if (sctp_debug_on & SCTP_DEBUG_OUTPUT4) { 210 cnt++; 211 printf("Restricted address[%d]:", cnt); 212 sctp_print_address(laddr->ifa->ifa_addr); 213 } 214#endif 215 if (sctp_cmpaddr(addr, laddr->ifa->ifa_addr) == 1) { 216 /* Yes it is on the list */ 217 return (1); 218 } 219 } 220 return (0); | |
221} 222 | 74} 75 |
223static int 224sctp_is_addr_in_ep(struct sctp_inpcb *inp, struct ifaddr *ifa) | 76void 77sctp_startup_iterator(void) |
225{ | 78{ |
226 struct sctp_laddr *laddr; | 79 int ret; |
227 | 80 |
228 if (ifa == NULL) 229 return (0); 230 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { 231 if (laddr->ifa == NULL) { 232#ifdef SCTP_DEBUG 233 if (sctp_debug_on & SCTP_DEBUG_OUTPUT1) { 234 printf("Help I have fallen and I can't get up!\n"); 235 } 236#endif 237 continue; 238 } 239 if (laddr->ifa->ifa_addr == NULL) 240 continue; 241 if (laddr->ifa == ifa) 242 /* same pointer */ 243 return (1); 244 if (laddr->ifa->ifa_addr->sa_family != ifa->ifa_addr->sa_family) { 245 /* skip non compatible address comparison */ 246 continue; 247 } 248 if (sctp_cmpaddr(ifa->ifa_addr, laddr->ifa->ifa_addr) == 1) { 249 /* Yes it is restricted */ 250 return (1); 251 } 252 } 253 return (0); | 81 ret = kthread_create(sctp_iterator_thread, 82 (void *)NULL, 83 &sctppcbinfo.thread_proc, 84 RFPROC, 85 SCTP_KTHREAD_PAGES, 86 SCTP_KTRHEAD_NAME); |
254} 255 | 87} 88 |
256 257 258static struct in_addr 259sctp_choose_v4_boundspecific_inp(struct sctp_inpcb *inp, 260 struct route *ro, 261 uint8_t ipv4_scope, 262 uint8_t loopscope) 263{ 264 struct in_addr ans; 265 struct sctp_laddr *laddr; 266 struct sockaddr_in *sin; 267 struct ifnet *ifn; 268 struct ifaddr *ifa; 269 uint8_t sin_loop, sin_local; 270 struct rtentry *rt; 271 272 /* 273 * first question, is the ifn we will emit on in our list, if so, we 274 * want that one. 275 */ 276 rt = ro->ro_rt; 277 ifn = rt->rt_ifp; 278 if (ifn) { 279 /* is a prefered one on the interface we route out? */ 280 TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) { 281 sin = sctp_is_v4_ifa_addr_prefered(ifa, loopscope, ipv4_scope, &sin_loop, &sin_local); 282 if (sin == NULL) 283 continue; 284 if (sctp_is_addr_in_ep(inp, ifa)) { 285 return (sin->sin_addr); 286 } 287 } 288 /* is an acceptable one on the interface we route out? */ 289 TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) { 290 sin = sctp_is_v4_ifa_addr_acceptable(ifa, loopscope, ipv4_scope, &sin_loop, &sin_local); 291 if (sin == NULL) 292 continue; 293 if (sctp_is_addr_in_ep(inp, ifa)) { 294 return (sin->sin_addr); 295 } 296 } 297 } 298 /* ok, what about a prefered address in the inp */ 299 for (laddr = LIST_FIRST(&inp->sctp_addr_list); 300 laddr && (laddr != inp->next_addr_touse); 301 laddr = LIST_NEXT(laddr, sctp_nxt_addr)) { 302 if (laddr->ifa == NULL) { 303 /* address has been removed */ 304 continue; 305 } 306 sin = sctp_is_v4_ifa_addr_prefered(laddr->ifa, loopscope, ipv4_scope, &sin_loop, &sin_local); 307 if (sin == NULL) 308 continue; 309 return (sin->sin_addr); 310 311 } 312 /* ok, what about an acceptable address in the inp */ 313 for (laddr = LIST_FIRST(&inp->sctp_addr_list); 314 laddr && (laddr != inp->next_addr_touse); 315 laddr = LIST_NEXT(laddr, sctp_nxt_addr)) { 316 if (laddr->ifa == NULL) { 317 /* address has been removed */ 318 continue; 319 } 320 sin = sctp_is_v4_ifa_addr_acceptable(laddr->ifa, loopscope, ipv4_scope, &sin_loop, &sin_local); 321 if (sin == NULL) 322 continue; 323 return (sin->sin_addr); 324 325 } 326 327 /* 328 * no address bound can be a source for the destination we are in 329 * trouble 330 */ 331#ifdef SCTP_DEBUG 332 if (sctp_debug_on & SCTP_DEBUG_OUTPUT1) { 333 printf("Src address selection for EP, no acceptable src address found for address\n"); 334 } | |
335#endif | 89#endif |
336 RTFREE(ro->ro_rt); 337 ro->ro_rt = NULL; 338 memset(&ans, 0, sizeof(ans)); 339 return (ans); 340} | |
341 342 | 90 91 |
343 344static struct in_addr 345sctp_choose_v4_boundspecific_stcb(struct sctp_inpcb *inp, 346 struct sctp_tcb *stcb, 347 struct sctp_nets *net, 348 struct route *ro, 349 uint8_t ipv4_scope, 350 uint8_t loopscope, 351 int non_asoc_addr_ok) | 92void 93sctp_gather_internal_ifa_flags(struct sctp_ifa *ifa) |
352{ | 94{ |
353 /* 354 * Here we have two cases, bound all asconf allowed. bound all 355 * asconf not allowed. 356 * 357 */ 358 struct sctp_laddr *laddr, *starting_point; 359 struct in_addr ans; 360 struct ifnet *ifn; 361 struct ifaddr *ifa; 362 uint8_t sin_loop, sin_local, start_at_beginning = 0; 363 struct sockaddr_in *sin; 364 struct rtentry *rt; | 95 struct in6_ifaddr *ifa6; |
365 | 96 |
366 /* 367 * first question, is the ifn we will emit on in our list, if so, we 368 * want that one. 369 */ 370 rt = ro->ro_rt; 371 ifn = rt->rt_ifp; 372 373 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_DO_ASCONF)) { 374 /* 375 * Here we use the list of addresses on the endpoint. Then 376 * the addresses listed on the "restricted" list is just 377 * that, address that have not been added and can't be used 378 * (unless the non_asoc_addr_ok is set). 379 */ 380#ifdef SCTP_DEBUG 381 if (sctp_debug_on & SCTP_DEBUG_OUTPUT1) { 382 printf("Have a STCB - asconf allowed, not bound all have a netgative list\n"); | 97 ifa6 = (struct in6_ifaddr *)ifa->ifa; 98 ifa->flags = ifa6->ia6_flags; 99 if (!ip6_use_deprecated) { 100 if (ifa->flags & 101 IN6_IFF_DEPRECATED) { 102 ifa->localifa_flags |= SCTP_ADDR_IFA_UNUSEABLE; 103 } else { 104 ifa->localifa_flags &= ~SCTP_ADDR_IFA_UNUSEABLE; |
383 } | 105 } |
384#endif 385 /* 386 * first question, is the ifn we will emit on in our list, 387 * if so, we want that one. 388 */ 389 if (ifn) { 390 /* first try for an prefered address on the ep */ 391 TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) { 392 if (sctp_is_addr_in_ep(inp, ifa)) { 393 sin = sctp_is_v4_ifa_addr_prefered(ifa, loopscope, ipv4_scope, &sin_loop, &sin_local); 394 if (sin == NULL) 395 continue; 396 if ((non_asoc_addr_ok == 0) && 397 (sctp_is_addr_restricted(stcb, (struct sockaddr *)sin))) { 398 /* on the no-no list */ 399 continue; 400 } 401 return (sin->sin_addr); 402 } 403 } 404 /* next try for an acceptable address on the ep */ 405 TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) { 406 if (sctp_is_addr_in_ep(inp, ifa)) { 407 sin = sctp_is_v4_ifa_addr_acceptable(ifa, loopscope, ipv4_scope, &sin_loop, &sin_local); 408 if (sin == NULL) 409 continue; 410 if ((non_asoc_addr_ok == 0) && 411 (sctp_is_addr_restricted(stcb, (struct sockaddr *)sin))) { 412 /* on the no-no list */ 413 continue; 414 } 415 return (sin->sin_addr); 416 } 417 } 418 419 } 420 /* 421 * if we can't find one like that then we must look at all 422 * addresses bound to pick one at first prefereable then 423 * secondly acceptable. 424 */ 425 starting_point = stcb->asoc.last_used_address; 426sctpv4_from_the_top: 427 if (stcb->asoc.last_used_address == NULL) { 428 start_at_beginning = 1; 429 stcb->asoc.last_used_address = LIST_FIRST(&inp->sctp_addr_list); 430 } 431 /* search beginning with the last used address */ 432 for (laddr = stcb->asoc.last_used_address; laddr; 433 laddr = LIST_NEXT(laddr, sctp_nxt_addr)) { 434 if (laddr->ifa == NULL) { 435 /* address has been removed */ 436 continue; 437 } 438 sin = sctp_is_v4_ifa_addr_prefered(laddr->ifa, loopscope, ipv4_scope, &sin_loop, &sin_local); 439 if (sin == NULL) 440 continue; 441 if ((non_asoc_addr_ok == 0) && 442 (sctp_is_addr_restricted(stcb, (struct sockaddr *)sin))) { 443 /* on the no-no list */ 444 continue; 445 } 446 return (sin->sin_addr); 447 448 } 449 if (start_at_beginning == 0) { 450 stcb->asoc.last_used_address = NULL; 451 goto sctpv4_from_the_top; 452 } 453 /* now try for any higher scope than the destination */ 454 stcb->asoc.last_used_address = starting_point; 455 start_at_beginning = 0; 456sctpv4_from_the_top2: 457 if (stcb->asoc.last_used_address == NULL) { 458 start_at_beginning = 1; 459 stcb->asoc.last_used_address = LIST_FIRST(&inp->sctp_addr_list); 460 } 461 /* search beginning with the last used address */ 462 for (laddr = stcb->asoc.last_used_address; laddr; 463 laddr = LIST_NEXT(laddr, sctp_nxt_addr)) { 464 if (laddr->ifa == NULL) { 465 /* address has been removed */ 466 continue; 467 } 468 sin = sctp_is_v4_ifa_addr_acceptable(laddr->ifa, loopscope, ipv4_scope, &sin_loop, &sin_local); 469 if (sin == NULL) 470 continue; 471 if ((non_asoc_addr_ok == 0) && 472 (sctp_is_addr_restricted(stcb, (struct sockaddr *)sin))) { 473 /* on the no-no list */ 474 continue; 475 } 476 return (sin->sin_addr); 477 } 478 if (start_at_beginning == 0) { 479 stcb->asoc.last_used_address = NULL; 480 goto sctpv4_from_the_top2; 481 } | |
482 } else { | 106 } else { |
483 /* 484 * Here we have an address list on the association, thats 485 * the only valid source addresses that we can use. 486 */ 487#ifdef SCTP_DEBUG 488 if (sctp_debug_on & SCTP_DEBUG_OUTPUT1) { 489 printf("Have a STCB - no asconf allowed, not bound all have a postive list\n"); 490 } 491#endif 492 /* 493 * First look at all addresses for one that is on the 494 * interface we route out 495 */ 496 LIST_FOREACH(laddr, &stcb->asoc.sctp_local_addr_list, 497 sctp_nxt_addr) { 498 if (laddr->ifa == NULL) { 499 /* address has been removed */ 500 continue; 501 } 502 sin = sctp_is_v4_ifa_addr_prefered(laddr->ifa, loopscope, ipv4_scope, &sin_loop, &sin_local); 503 if (sin == NULL) 504 continue; 505 /* 506 * first question, is laddr->ifa an address 507 * associated with the emit interface 508 */ 509 if (ifn) { 510 TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) { 511 if (laddr->ifa == ifa) { 512 sin = (struct sockaddr_in *)laddr->ifa->ifa_addr; 513 return (sin->sin_addr); 514 } 515 if (sctp_cmpaddr(ifa->ifa_addr, laddr->ifa->ifa_addr) == 1) { 516 sin = (struct sockaddr_in *)laddr->ifa->ifa_addr; 517 return (sin->sin_addr); 518 } 519 } 520 } 521 } 522 /* what about an acceptable one on the interface? */ 523 LIST_FOREACH(laddr, &stcb->asoc.sctp_local_addr_list, 524 sctp_nxt_addr) { 525 if (laddr->ifa == NULL) { 526 /* address has been removed */ 527 continue; 528 } 529 sin = sctp_is_v4_ifa_addr_acceptable(laddr->ifa, loopscope, ipv4_scope, &sin_loop, &sin_local); 530 if (sin == NULL) 531 continue; 532 /* 533 * first question, is laddr->ifa an address 534 * associated with the emit interface 535 */ 536 if (ifn) { 537 TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) { 538 if (laddr->ifa == ifa) { 539 sin = (struct sockaddr_in *)laddr->ifa->ifa_addr; 540 return (sin->sin_addr); 541 } 542 if (sctp_cmpaddr(ifa->ifa_addr, laddr->ifa->ifa_addr) == 1) { 543 sin = (struct sockaddr_in *)laddr->ifa->ifa_addr; 544 return (sin->sin_addr); 545 } 546 } 547 } 548 } 549 /* ok, next one that is preferable in general */ 550 LIST_FOREACH(laddr, &stcb->asoc.sctp_local_addr_list, 551 sctp_nxt_addr) { 552 if (laddr->ifa == NULL) { 553 /* address has been removed */ 554 continue; 555 } 556 sin = sctp_is_v4_ifa_addr_prefered(laddr->ifa, loopscope, ipv4_scope, &sin_loop, &sin_local); 557 if (sin == NULL) 558 continue; 559 return (sin->sin_addr); 560 } 561 562 /* last, what about one that is acceptable */ 563 LIST_FOREACH(laddr, &stcb->asoc.sctp_local_addr_list, 564 sctp_nxt_addr) { 565 if (laddr->ifa == NULL) { 566 /* address has been removed */ 567 continue; 568 } 569 sin = sctp_is_v4_ifa_addr_acceptable(laddr->ifa, loopscope, ipv4_scope, &sin_loop, &sin_local); 570 if (sin == NULL) 571 continue; 572 return (sin->sin_addr); 573 } | 107 ifa->localifa_flags &= ~SCTP_ADDR_IFA_UNUSEABLE; |
574 } | 108 } |
575 RTFREE(ro->ro_rt); 576 ro->ro_rt = NULL; 577 memset(&ans, 0, sizeof(ans)); 578 return (ans); 579} 580 581static struct sockaddr_in * 582sctp_select_v4_nth_prefered_addr_from_ifn_boundall(struct ifnet *ifn, struct sctp_tcb *stcb, int non_asoc_addr_ok, 583 uint8_t loopscope, uint8_t ipv4_scope, int cur_addr_num) 584{ 585 struct ifaddr *ifa; 586 struct sockaddr_in *sin; 587 uint8_t sin_loop, sin_local; 588 int num_eligible_addr = 0; 589 590 TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) { 591 sin = sctp_is_v4_ifa_addr_prefered(ifa, loopscope, ipv4_scope, &sin_loop, &sin_local); 592 if (sin == NULL) 593 continue; 594 if (stcb) { 595 if ((non_asoc_addr_ok == 0) && sctp_is_addr_restricted(stcb, (struct sockaddr *)sin)) { 596 /* 597 * It is restricted for some reason.. 598 * probably not yet added. 599 */ 600 continue; 601 } 602 } 603 if (cur_addr_num == num_eligible_addr) { 604 return (sin); 605 } 606 } 607 return (NULL); 608} 609 610 611static int 612sctp_count_v4_num_prefered_boundall(struct ifnet *ifn, struct sctp_tcb *stcb, int non_asoc_addr_ok, 613 uint8_t loopscope, uint8_t ipv4_scope, uint8_t * sin_loop, uint8_t * sin_local) 614{ 615 struct ifaddr *ifa; 616 struct sockaddr_in *sin; 617 int num_eligible_addr = 0; 618 619 TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) { 620 sin = sctp_is_v4_ifa_addr_prefered(ifa, loopscope, ipv4_scope, sin_loop, sin_local); 621 if (sin == NULL) 622 continue; 623 if (stcb) { 624 if ((non_asoc_addr_ok == 0) && sctp_is_addr_restricted(stcb, (struct sockaddr *)sin)) { 625 /* 626 * It is restricted for some reason.. 627 * probably not yet added. 628 */ 629 continue; 630 } 631 } 632 num_eligible_addr++; 633 } 634 return (num_eligible_addr); 635 636} 637 638static struct in_addr 639sctp_choose_v4_boundall(struct sctp_inpcb *inp, 640 struct sctp_tcb *stcb, 641 struct sctp_nets *net, 642 struct route *ro, 643 uint8_t ipv4_scope, 644 uint8_t loopscope, 645 int non_asoc_addr_ok) 646{ 647 int cur_addr_num = 0, num_prefered = 0; 648 uint8_t sin_loop, sin_local; 649 struct ifnet *ifn; 650 struct sockaddr_in *sin; 651 struct in_addr ans; 652 struct ifaddr *ifa; 653 struct rtentry *rt; 654 655 /* 656 * For v4 we can use (in boundall) any address in the association. 657 * If non_asoc_addr_ok is set we can use any address (at least in 658 * theory). So we look for prefered addresses first. If we find one, 659 * we use it. Otherwise we next try to get an address on the 660 * interface, which we should be able to do (unless non_asoc_addr_ok 661 * is false and we are routed out that way). In these cases where we 662 * can't use the address of the interface we go through all the 663 * ifn's looking for an address we can use and fill that in. Punting 664 * means we send back address 0, which will probably cause problems 665 * actually since then IP will fill in the address of the route ifn, 666 * which means we probably already rejected it.. i.e. here comes an 667 * abort :-<. 668 */ 669 rt = ro->ro_rt; 670 ifn = rt->rt_ifp; 671 if (net) { 672 cur_addr_num = net->indx_of_eligible_next_to_use; 673 } 674 if (ifn == NULL) { 675 goto bound_all_v4_plan_c; 676 } 677 num_prefered = sctp_count_v4_num_prefered_boundall(ifn, stcb, non_asoc_addr_ok, loopscope, ipv4_scope, &sin_loop, &sin_local); 678#ifdef SCTP_DEBUG 679 if (sctp_debug_on & SCTP_DEBUG_OUTPUT1) { 680 printf("Found %d prefered source addresses\n", num_prefered); 681 } 682#endif 683 if (num_prefered == 0) { 684 /* 685 * no eligible addresses, we must use some other interface 686 * address if we can find one. 687 */ 688 goto bound_all_v4_plan_b; 689 } 690 /* 691 * Ok we have num_eligible_addr set with how many we can use, this 692 * may vary from call to call due to addresses being deprecated 693 * etc.. 694 */ 695 if (cur_addr_num >= num_prefered) { 696 cur_addr_num = 0; 697 } 698 /* 699 * select the nth address from the list (where cur_addr_num is the 700 * nth) and 0 is the first one, 1 is the second one etc... 701 */ 702#ifdef SCTP_DEBUG 703 if (sctp_debug_on & SCTP_DEBUG_OUTPUT1) { 704 printf("cur_addr_num:%d\n", cur_addr_num); 705 } 706#endif 707 sin = sctp_select_v4_nth_prefered_addr_from_ifn_boundall(ifn, stcb, non_asoc_addr_ok, loopscope, 708 ipv4_scope, cur_addr_num); 709 710 /* if sin is NULL something changed??, plan_a now */ 711 if (sin) { 712 return (sin->sin_addr); 713 } 714 /* 715 * plan_b: Look at the interface that we emit on and see if we can 716 * find an acceptable address. 717 */ 718bound_all_v4_plan_b: 719 TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) { 720 sin = sctp_is_v4_ifa_addr_acceptable(ifa, loopscope, ipv4_scope, &sin_loop, &sin_local); 721 if (sin == NULL) 722 continue; 723 if (stcb) { 724 if ((non_asoc_addr_ok == 0) && sctp_is_addr_restricted(stcb, (struct sockaddr *)sin)) { 725 /* 726 * It is restricted for some reason.. 727 * probably not yet added. 728 */ 729 continue; 730 } 731 } 732 return (sin->sin_addr); 733 } 734 /* 735 * plan_c: Look at all interfaces and find a prefered address. If we 736 * reache here we are in trouble I think. 737 */ 738bound_all_v4_plan_c: 739 for (ifn = TAILQ_FIRST(&ifnet); 740 ifn && (ifn != inp->next_ifn_touse); 741 ifn = TAILQ_NEXT(ifn, if_list)) { 742 if (loopscope == 0 && ifn->if_type == IFT_LOOP) { 743 /* wrong base scope */ 744 continue; 745 } 746 if (ifn == rt->rt_ifp) 747 /* already looked at this guy */ 748 continue; 749 num_prefered = sctp_count_v4_num_prefered_boundall(ifn, stcb, non_asoc_addr_ok, 750 loopscope, ipv4_scope, &sin_loop, &sin_local); 751#ifdef SCTP_DEBUG 752 if (sctp_debug_on & SCTP_DEBUG_OUTPUT1) { 753 printf("Found ifn:%p %d prefered source addresses\n", ifn, num_prefered); 754 } 755#endif 756 if (num_prefered == 0) { 757 /* 758 * None on this interface. 759 */ 760 continue; 761 } 762 /* 763 * Ok we have num_eligible_addr set with how many we can 764 * use, this may vary from call to call due to addresses 765 * being deprecated etc.. 766 */ 767 if (cur_addr_num >= num_prefered) { 768 cur_addr_num = 0; 769 } 770 sin = sctp_select_v4_nth_prefered_addr_from_ifn_boundall(ifn, stcb, non_asoc_addr_ok, loopscope, 771 ipv4_scope, cur_addr_num); 772 if (sin == NULL) 773 continue; 774 return (sin->sin_addr); 775 776 } 777 778 /* 779 * plan_d: We are in deep trouble. No prefered address on any 780 * interface. And the emit interface does not even have an 781 * acceptable address. Take anything we can get! If this does not 782 * work we are probably going to emit a packet that will illicit an 783 * ABORT, falling through. 784 */ 785 786 for (ifn = TAILQ_FIRST(&ifnet); 787 ifn && (ifn != inp->next_ifn_touse); 788 ifn = TAILQ_NEXT(ifn, if_list)) { 789 if (loopscope == 0 && ifn->if_type == IFT_LOOP) { 790 /* wrong base scope */ 791 continue; 792 } 793 if (ifn == rt->rt_ifp) 794 /* already looked at this guy */ 795 continue; 796 797 TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) { 798 sin = sctp_is_v4_ifa_addr_acceptable(ifa, loopscope, ipv4_scope, &sin_loop, &sin_local); 799 if (sin == NULL) 800 continue; 801 if (stcb) { 802 if ((non_asoc_addr_ok == 0) && sctp_is_addr_restricted(stcb, (struct sockaddr *)sin)) { 803 /* 804 * It is restricted for some 805 * reason.. probably not yet added. 806 */ 807 continue; 808 } 809 } 810 return (sin->sin_addr); 811 } 812 } 813 /* 814 * Ok we can find NO address to source from that is not on our 815 * negative list. It is either the special ASCONF case where we are 816 * sourceing from a intf that has been ifconfig'd to a different 817 * address (i.e. it holds a ADD/DEL/SET-PRIM and the proper lookup 818 * address. OR we are hosed, and this baby is going to abort the 819 * association. 820 */ 821 if (non_asoc_addr_ok) { 822 return (((struct sockaddr_in *)(rt->rt_ifa->ifa_addr))->sin_addr); | 109 if (ifa->flags & 110 (IN6_IFF_DETACHED | 111 IN6_IFF_ANYCAST | 112 IN6_IFF_NOTREADY)) { 113 ifa->localifa_flags |= SCTP_ADDR_IFA_UNUSEABLE; |
823 } else { | 114 } else { |
824 RTFREE(ro->ro_rt); 825 ro->ro_rt = NULL; 826 memset(&ans, 0, sizeof(ans)); 827 return (ans); | 115 ifa->localifa_flags &= ~SCTP_ADDR_IFA_UNUSEABLE; |
828 } 829} 830 831 832 | 116 } 117} 118 119 120 |
833/* tcb may be NULL */ 834struct in_addr 835sctp_ipv4_source_address_selection(struct sctp_inpcb *inp, 836 struct sctp_tcb *stcb, struct route *ro, struct sctp_nets *net, 837 int non_asoc_addr_ok) | 121static uint32_t 122sctp_is_desired_interface_type(struct ifaddr *ifa) |
838{ | 123{ |
839 struct in_addr ans; 840 struct sockaddr_in *to = (struct sockaddr_in *)&ro->ro_dst; 841 uint8_t ipv4_scope, loopscope; | 124 int result; |
842 | 125 |
843 /* 844 * Rules: - Find the route if needed, cache if I can. - Look at 845 * interface address in route, Is it in the bound list. If so we 846 * have the best source. - If not we must rotate amongst the 847 * addresses. 848 * 849 * Cavets and issues 850 * 851 * Do we need to pay attention to scope. We can have a private address 852 * or a global address we are sourcing or sending to. So if we draw 853 * it out source * dest * result 854 * ------------------------------------------ a Private * 855 * Global * NAT? ------------------------------------------ b 856 * Private * Private * No problem 857 * ------------------------------------------ c Global * 858 * Private * Huh, How will this work? 859 * ------------------------------------------ d Global * 860 * Global * No Problem ------------------------------------------ 861 * 862 * And then we add to that what happens if there are multiple addresses 863 * assigned to an interface. Remember the ifa on a ifn is a linked 864 * list of addresses. So one interface can have more than one IPv4 865 * address. What happens if we have both a private and a global 866 * address? Do we then use context of destination to sort out which 867 * one is best? And what about NAT's sending P->G may get you a NAT 868 * translation, or should you select the G thats on the interface in 869 * preference. 870 * 871 * Decisions: 872 * 873 * - count the number of addresses on the interface. - if its one, no 874 * problem except case <c>. For <a> we will assume a NAT out there. 875 * - if there are more than one, then we need to worry about scope P 876 * or G. We should prefer G -> G and P -> P if possible. Then as a 877 * secondary fall back to mixed types G->P being a last ditch one. - 878 * The above all works for bound all, but bound specific we need to 879 * use the same concept but instead only consider the bound 880 * addresses. If the bound set is NOT assigned to the interface then 881 * we must use rotation amongst them. 882 * 883 * Notes: For v4, we can always punt and let ip_output decide by 884 * sending back a source of 0.0.0.0 885 */ 886 887 if (ro->ro_rt == NULL) { 888 /* 889 * Need a route to cache. 890 * 891 */ 892 rtalloc_ign(ro, 0UL); | 126 /* check the interface type to see if it's one we care about */ 127 switch (ifa->ifa_ifp->if_type) { 128 case IFT_ETHER: 129 case IFT_ISO88023: 130 case IFT_ISO88024: 131 case IFT_ISO88025: 132 case IFT_ISO88026: 133 case IFT_STARLAN: 134 case IFT_P10: 135 case IFT_P80: 136 case IFT_HY: 137 case IFT_FDDI: 138 case IFT_XETHER: 139 case IFT_ISDNBASIC: 140 case IFT_ISDNPRIMARY: 141 case IFT_PTPSERIAL: 142 case IFT_PPP: 143 case IFT_LOOP: 144 case IFT_SLIP: 145 case IFT_IP: 146 case IFT_IPOVERCDLC: 147 case IFT_IPOVERCLAW: 148 case IFT_VIRTUALIPADDRESS: 149 result = 1; 150 break; 151 default: 152 result = 0; |
893 } | 153 } |
894 if (ro->ro_rt == NULL) { 895 /* No route to host .. punt */ 896 memset(&ans, 0, sizeof(ans)); 897 return (ans); 898 } 899 /* Setup our scopes */ 900 if (stcb) { 901 ipv4_scope = stcb->asoc.ipv4_local_scope; 902 loopscope = stcb->asoc.loopback_scope; 903 } else { 904 /* Scope based on outbound address */ 905 if ((IN4_ISPRIVATE_ADDRESS(&to->sin_addr))) { 906 ipv4_scope = 1; 907 loopscope = 0; 908 } else if (IN4_ISLOOPBACK_ADDRESS(&to->sin_addr)) { 909 ipv4_scope = 1; 910 loopscope = 1; 911 } else { 912 ipv4_scope = 0; 913 loopscope = 0; 914 } 915 } 916 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { 917 /* 918 * When bound to all if the address list is set it is a 919 * negative list. Addresses being added by asconf. 920 */ 921 return (sctp_choose_v4_boundall(inp, stcb, net, ro, 922 ipv4_scope, loopscope, non_asoc_addr_ok)); 923 } 924 /* 925 * Three possiblities here: 926 * 927 * a) stcb is NULL, which means we operate only from the list of 928 * addresses (ifa's) bound to the assoc and we care not about the 929 * list. b) stcb is NOT-NULL, which means we have an assoc structure 930 * and auto-asconf is on. This means that the list of addresses is a 931 * NOT list. We use the list from the inp, but any listed address in 932 * our list is NOT yet added. However if the non_asoc_addr_ok is set 933 * we CAN use an address NOT available (i.e. being added). Its a 934 * negative list. c) stcb is NOT-NULL, which means we have an assoc 935 * structure and auto-asconf is off. This means that the list of 936 * addresses is the ONLY addresses I can use.. its positive. 937 * 938 * Note we collapse b & c into the same function just like in the v6 939 * address selection. 940 */ 941 if (stcb) { 942 return (sctp_choose_v4_boundspecific_stcb(inp, stcb, net, 943 ro, ipv4_scope, loopscope, non_asoc_addr_ok)); 944 } else { 945 return (sctp_choose_v4_boundspecific_inp(inp, ro, 946 ipv4_scope, loopscope)); 947 } 948 /* this should not be reached */ 949 memset(&ans, 0, sizeof(ans)); 950 return (ans); 951} | |
952 | 154 |
953 954 955static struct sockaddr_in6 * 956sctp_is_v6_ifa_addr_acceptable(struct ifaddr *ifa, int loopscope, int loc_scope, int *sin_loop, int *sin_local) 957{ 958 struct in6_ifaddr *ifa6; 959 struct sockaddr_in6 *sin6; 960 961 962 if (ifa->ifa_addr->sa_family != AF_INET6) { 963 /* forget non-v6 */ 964 return (NULL); 965 } 966 ifa6 = (struct in6_ifaddr *)ifa; 967 /* ok to use deprecated addresses? */ 968 if (!ip6_use_deprecated) { 969 if (IFA6_IS_DEPRECATED(ifa6)) { 970 /* can't use this type */ 971 return (NULL); 972 } 973 } 974 /* are we ok, with the current state of this address? */ 975 if (ifa6->ia6_flags & 976 (IN6_IFF_DETACHED | IN6_IFF_NOTREADY | IN6_IFF_ANYCAST)) { 977 /* Can't use these types */ 978 return (NULL); 979 } 980 /* Ok the address may be ok */ 981 sin6 = (struct sockaddr_in6 *)ifa->ifa_addr; 982 *sin_local = *sin_loop = 0; 983 if ((ifa->ifa_ifp->if_type == IFT_LOOP) || 984 (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr))) { 985 *sin_loop = 1; 986 } 987 if (!loopscope && *sin_loop) { 988 /* Its a loopback address and we don't have loop scope */ 989 return (NULL); 990 } 991 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 992 /* we skip unspecifed addresses */ 993 return (NULL); 994 } 995 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { 996 *sin_local = 1; 997 } 998 if (!loc_scope && *sin_local) { 999 /* 1000 * Its a link local address, and we don't have link local 1001 * scope 1002 */ 1003 return (NULL); 1004 } 1005 return (sin6); | 155 return (result); |
1006} 1007 | 156} 157 |
1008 1009static struct sockaddr_in6 * 1010sctp_choose_v6_boundspecific_stcb(struct sctp_inpcb *inp, 1011 struct sctp_tcb *stcb, 1012 struct sctp_nets *net, 1013 struct route *ro, 1014 uint8_t loc_scope, 1015 uint8_t loopscope, 1016 int non_asoc_addr_ok) | 158static void 159sctp_init_ifns_for_vrf(int vrfid) |
1017{ 1018 /* | 160{ 161 /* |
1019 * Each endpoint has a list of local addresses associated with it. 1020 * The address list is either a "negative list" i.e. those addresses 1021 * that are NOT allowed to be used as a source OR a "postive list" 1022 * i.e. those addresses that CAN be used. 1023 * 1024 * Its a negative list if asconf is allowed. What we do in this case is 1025 * use the ep address list BUT we have to cross check it against the 1026 * negative list. 1027 * 1028 * In the case where NO asconf is allowed, we have just a straight 1029 * association level list that we must use to find a source address. | 162 * Here we must apply ANY locks needed by the IFN we access and also 163 * make sure we lock any IFA that exists as we float through the 164 * list of IFA's |
1030 */ | 165 */ |
1031 struct sctp_laddr *laddr, *starting_point; 1032 struct sockaddr_in6 *sin6; 1033 int sin_loop, sin_local; 1034 int start_at_beginning = 0; | |
1035 struct ifnet *ifn; 1036 struct ifaddr *ifa; | 166 struct ifnet *ifn; 167 struct ifaddr *ifa; |
1037 struct rtentry *rt; | 168 struct in6_ifaddr *ifa6; 169 struct sctp_ifa *sctp_ifa; 170 uint32_t ifa_flags; |
1038 | 171 |
1039 rt = ro->ro_rt; 1040 ifn = rt->rt_ifp; 1041 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_DO_ASCONF)) { 1042#ifdef SCTP_DEBUG 1043 if (sctp_debug_on & SCTP_DEBUG_OUTPUT1) { 1044 printf("Have a STCB - asconf allowed, not bound all have a netgative list\n"); 1045 } 1046#endif 1047 /* 1048 * first question, is the ifn we will emit on in our list, 1049 * if so, we want that one. 1050 */ 1051 if (ifn) { 1052 TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) { 1053 if (sctp_is_addr_in_ep(inp, ifa)) { 1054 sin6 = sctp_is_v6_ifa_addr_acceptable(ifa, loopscope, loc_scope, &sin_loop, &sin_local); 1055 if (sin6 == NULL) 1056 continue; 1057 if ((non_asoc_addr_ok == 0) && 1058 (sctp_is_addr_restricted(stcb, (struct sockaddr *)sin6))) { 1059 /* on the no-no list */ 1060 continue; 1061 } 1062 return (sin6); 1063 } 1064 } 1065 } 1066 starting_point = stcb->asoc.last_used_address; 1067 /* First try for matching scope */ 1068sctp_from_the_top: 1069 if (stcb->asoc.last_used_address == NULL) { 1070 start_at_beginning = 1; 1071 stcb->asoc.last_used_address = LIST_FIRST(&inp->sctp_addr_list); 1072 } 1073 /* search beginning with the last used address */ 1074 for (laddr = stcb->asoc.last_used_address; laddr; 1075 laddr = LIST_NEXT(laddr, sctp_nxt_addr)) { 1076 if (laddr->ifa == NULL) { 1077 /* address has been removed */ | 172 TAILQ_FOREACH(ifn, &ifnet, if_list) { 173 TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) { 174 if (ifa->ifa_addr == NULL) { |
1078 continue; 1079 } | 175 continue; 176 } |
1080 sin6 = sctp_is_v6_ifa_addr_acceptable(laddr->ifa, loopscope, loc_scope, &sin_loop, &sin_local); 1081 if (sin6 == NULL) | 177 if ((ifa->ifa_addr->sa_family != AF_INET) && 178 (ifa->ifa_addr->sa_family != AF_INET6) 179 ) { 180 /* non inet/inet6 skip */ |
1082 continue; | 181 continue; |
1083 if ((non_asoc_addr_ok == 0) && (sctp_is_addr_restricted(stcb, (struct sockaddr *)sin6))) { 1084 /* on the no-no list */ 1085 continue; | |
1086 } | 182 } |
1087 /* is it of matching scope ? */ 1088 if ((loopscope == 0) && 1089 (loc_scope == 0) && 1090 (sin_loop == 0) && 1091 (sin_local == 0)) { 1092 /* all of global scope we are ok with it */ 1093 return (sin6); | 183 if (ifa->ifa_addr->sa_family == AF_INET6) { 184 ifa6 = (struct in6_ifaddr *)ifa; 185 ifa_flags = ifa6->ia6_flags; 186 if (IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr)) { 187 /* skip unspecifed addresses */ 188 continue; 189 } 190 } else if (ifa->ifa_addr->sa_family == AF_INET) { 191 if (((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr == 0) { 192 continue; 193 } |
1094 } | 194 } |
1095 if (loopscope && sin_loop) 1096 /* both on the loopback, thats ok */ 1097 return (sin6); 1098 if (loc_scope && sin_local) 1099 /* both local scope */ 1100 return (sin6); 1101 1102 } 1103 if (start_at_beginning == 0) { 1104 stcb->asoc.last_used_address = NULL; 1105 goto sctp_from_the_top; 1106 } 1107 /* now try for any higher scope than the destination */ 1108 stcb->asoc.last_used_address = starting_point; 1109 start_at_beginning = 0; 1110sctp_from_the_top2: 1111 if (stcb->asoc.last_used_address == NULL) { 1112 start_at_beginning = 1; 1113 stcb->asoc.last_used_address = LIST_FIRST(&inp->sctp_addr_list); 1114 } 1115 /* search beginning with the last used address */ 1116 for (laddr = stcb->asoc.last_used_address; laddr; 1117 laddr = LIST_NEXT(laddr, sctp_nxt_addr)) { 1118 if (laddr->ifa == NULL) { 1119 /* address has been removed */ | 195 if (sctp_is_desired_interface_type(ifa) == 0) { 196 /* non desired type */ |
1120 continue; 1121 } | 197 continue; 198 } |
1122 sin6 = sctp_is_v6_ifa_addr_acceptable(laddr->ifa, loopscope, loc_scope, &sin_loop, &sin_local); 1123 if (sin6 == NULL) 1124 continue; 1125 if ((non_asoc_addr_ok == 0) && (sctp_is_addr_restricted(stcb, (struct sockaddr *)sin6))) { 1126 /* on the no-no list */ 1127 continue; 1128 } 1129 return (sin6); 1130 } 1131 if (start_at_beginning == 0) { 1132 stcb->asoc.last_used_address = NULL; 1133 goto sctp_from_the_top2; 1134 } 1135 } else { 1136#ifdef SCTP_DEBUG 1137 if (sctp_debug_on & SCTP_DEBUG_OUTPUT1) { 1138 printf("Have a STCB - no asconf allowed, not bound all have a postive list\n"); 1139 } 1140#endif 1141 /* First try for interface output match */ 1142 LIST_FOREACH(laddr, &stcb->asoc.sctp_local_addr_list, 1143 sctp_nxt_addr) { 1144 if (laddr->ifa == NULL) { 1145 /* address has been removed */ 1146 continue; 1147 } 1148 sin6 = sctp_is_v6_ifa_addr_acceptable(laddr->ifa, loopscope, loc_scope, &sin_loop, &sin_local); 1149 if (sin6 == NULL) 1150 continue; 1151 /* 1152 * first question, is laddr->ifa an address 1153 * associated with the emit interface 1154 */ 1155 if (ifn) { 1156 TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) { 1157 if (laddr->ifa == ifa) { 1158 sin6 = (struct sockaddr_in6 *)laddr->ifa->ifa_addr; 1159 return (sin6); 1160 } 1161 if (sctp_cmpaddr(ifa->ifa_addr, laddr->ifa->ifa_addr) == 1) { 1162 sin6 = (struct sockaddr_in6 *)laddr->ifa->ifa_addr; 1163 return (sin6); 1164 } | 199 if ((ifa->ifa_addr->sa_family == AF_INET6) || 200 (ifa->ifa_addr->sa_family == AF_INET)) { 201 if (ifa->ifa_addr->sa_family == AF_INET6) { 202 ifa6 = (struct in6_ifaddr *)ifa; 203 ifa_flags = ifa6->ia6_flags; 204 } else { 205 ifa_flags = 0; |
1165 } | 206 } |
207 sctp_ifa = sctp_add_addr_to_vrf(vrfid, 208 (void *)ifn, 209 ifn->if_index, 210 ifn->if_type, 211 ifn->if_xname, 212 (void *)ifa, 213 ifa->ifa_addr, 214 ifa_flags 215 ); 216 if (sctp_ifa) { 217 sctp_ifa->localifa_flags &= ~SCTP_ADDR_DEFER_USE; 218 } |
|
1166 } 1167 } | 219 } 220 } |
1168 /* Next try for matching scope */ 1169 LIST_FOREACH(laddr, &stcb->asoc.sctp_local_addr_list, 1170 sctp_nxt_addr) { 1171 if (laddr->ifa == NULL) { 1172 /* address has been removed */ 1173 continue; 1174 } 1175 sin6 = sctp_is_v6_ifa_addr_acceptable(laddr->ifa, loopscope, loc_scope, &sin_loop, &sin_local); 1176 if (sin6 == NULL) 1177 continue; 1178 1179 if ((loopscope == 0) && 1180 (loc_scope == 0) && 1181 (sin_loop == 0) && 1182 (sin_local == 0)) { 1183 /* all of global scope we are ok with it */ 1184 return (sin6); 1185 } 1186 if (loopscope && sin_loop) 1187 /* both on the loopback, thats ok */ 1188 return (sin6); 1189 if (loc_scope && sin_local) 1190 /* both local scope */ 1191 return (sin6); 1192 } 1193 /* ok, now try for a higher scope in the source address */ 1194 /* First try for matching scope */ 1195 LIST_FOREACH(laddr, &stcb->asoc.sctp_local_addr_list, 1196 sctp_nxt_addr) { 1197 if (laddr->ifa == NULL) { 1198 /* address has been removed */ 1199 continue; 1200 } 1201 sin6 = sctp_is_v6_ifa_addr_acceptable(laddr->ifa, loopscope, loc_scope, &sin_loop, &sin_local); 1202 if (sin6 == NULL) 1203 continue; 1204 return (sin6); 1205 } | |
1206 } | 221 } |
1207 RTFREE(ro->ro_rt); 1208 ro->ro_rt = NULL; 1209 return (NULL); | |
1210} 1211 | 222} 223 |
1212static struct sockaddr_in6 * 1213sctp_choose_v6_boundspecific_inp(struct sctp_inpcb *inp, 1214 struct route *ro, 1215 uint8_t loc_scope, 1216 uint8_t loopscope) | 224 225void 226sctp_init_vrf_list(int vrfid) |
1217{ | 227{ |
1218 /* 1219 * Here we are bound specific and have only an inp. We must find an 1220 * address that is bound that we can give out as a src address. We 1221 * prefer two addresses of same scope if we can find them that way. 1222 */ 1223 struct sctp_laddr *laddr; 1224 struct sockaddr_in6 *sin6; 1225 struct ifnet *ifn; 1226 struct ifaddr *ifa; 1227 int sin_loop, sin_local; 1228 struct rtentry *rt; | 228 if (vrfid > SCTP_MAX_VRF_ID) 229 /* can't do that */ 230 return; |
1229 | 231 |
1230 /* 1231 * first question, is the ifn we will emit on in our list, if so, we 1232 * want that one. 1233 */ | 232 /* Don't care about return here */ 233 (void)sctp_allocate_vrf(vrfid); |
1234 | 234 |
1235 rt = ro->ro_rt; 1236 ifn = rt->rt_ifp; 1237 if (ifn) { 1238 TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) { 1239 sin6 = sctp_is_v6_ifa_addr_acceptable(ifa, loopscope, loc_scope, &sin_loop, &sin_local); 1240 if (sin6 == NULL) 1241 continue; 1242 if (sctp_is_addr_in_ep(inp, ifa)) { 1243 return (sin6); 1244 } 1245 } 1246 } 1247 for (laddr = LIST_FIRST(&inp->sctp_addr_list); 1248 laddr && (laddr != inp->next_addr_touse); 1249 laddr = LIST_NEXT(laddr, sctp_nxt_addr)) { 1250 if (laddr->ifa == NULL) { 1251 /* address has been removed */ 1252 continue; 1253 } 1254 sin6 = sctp_is_v6_ifa_addr_acceptable(laddr->ifa, loopscope, loc_scope, &sin_loop, &sin_local); 1255 if (sin6 == NULL) 1256 continue; 1257 1258 if ((loopscope == 0) && 1259 (loc_scope == 0) && 1260 (sin_loop == 0) && 1261 (sin_local == 0)) { 1262 /* all of global scope we are ok with it */ 1263 return (sin6); 1264 } 1265 if (loopscope && sin_loop) 1266 /* both on the loopback, thats ok */ 1267 return (sin6); 1268 if (loc_scope && sin_local) 1269 /* both local scope */ 1270 return (sin6); 1271 1272 } | |
1273 /* | 235 /* |
1274 * if we reach here, we could not find two addresses of the same 1275 * scope to give out. Lets look for any higher level scope for a 1276 * source address. | 236 * Now we need to build all the ifn's for this vrf and there 237 * addresses |
1277 */ | 238 */ |
1278 for (laddr = LIST_FIRST(&inp->sctp_addr_list); 1279 laddr && (laddr != inp->next_addr_touse); 1280 laddr = LIST_NEXT(laddr, sctp_nxt_addr)) { 1281 if (laddr->ifa == NULL) { 1282 /* address has been removed */ 1283 continue; 1284 } 1285 sin6 = sctp_is_v6_ifa_addr_acceptable(laddr->ifa, loopscope, loc_scope, &sin_loop, &sin_local); 1286 if (sin6 == NULL) 1287 continue; 1288 return (sin6); 1289 } 1290 /* no address bound can be a source for the destination */ 1291#ifdef SCTP_DEBUG 1292 if (sctp_debug_on & SCTP_DEBUG_OUTPUT1) { 1293 printf("Src address selection for EP, no acceptable src address found for address\n"); 1294 } 1295#endif 1296 RTFREE(ro->ro_rt); 1297 ro->ro_rt = NULL; 1298 return (NULL); | 239 sctp_init_ifns_for_vrf(vrfid); |
1299} 1300 | 240} 241 |
242static uint8_t first_time = 0; |
|
1301 | 243 |
1302static struct sockaddr_in6 * 1303sctp_select_v6_nth_addr_from_ifn_boundall(struct ifnet *ifn, struct sctp_tcb *stcb, int non_asoc_addr_ok, uint8_t loopscope, 1304 uint8_t loc_scope, int cur_addr_num, int match_scope) 1305{ 1306 struct ifaddr *ifa; 1307 struct sockaddr_in6 *sin6; 1308 int sin_loop, sin_local; 1309 int num_eligible_addr = 0; | |
1310 | 244 |
1311 TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) { 1312 sin6 = sctp_is_v6_ifa_addr_acceptable(ifa, loopscope, loc_scope, &sin_loop, &sin_local); 1313 if (sin6 == NULL) 1314 continue; 1315 if (stcb) { 1316 if ((non_asoc_addr_ok == 0) && sctp_is_addr_restricted(stcb, (struct sockaddr *)sin6)) { 1317 /* 1318 * It is restricted for some reason.. 1319 * probably not yet added. 1320 */ 1321 continue; 1322 } 1323 } 1324 if (match_scope) { 1325 /* Here we are asked to match scope if possible */ 1326 if (loopscope && sin_loop) 1327 /* src and destination are loopback scope */ 1328 return (sin6); 1329 if (loc_scope && sin_local) 1330 /* src and destination are local scope */ 1331 return (sin6); 1332 if ((loopscope == 0) && 1333 (loc_scope == 0) && 1334 (sin_loop == 0) && 1335 (sin_local == 0)) { 1336 /* src and destination are global scope */ 1337 return (sin6); 1338 } 1339 continue; 1340 } 1341 if (num_eligible_addr == cur_addr_num) { 1342 /* this is it */ 1343 return (sin6); 1344 } 1345 num_eligible_addr++; 1346 } 1347 return (NULL); 1348} 1349 1350 1351static int 1352sctp_count_v6_num_eligible_boundall(struct ifnet *ifn, struct sctp_tcb *stcb, 1353 int non_asoc_addr_ok, uint8_t loopscope, uint8_t loc_scope) | 245void 246sctp_addr_change(struct ifaddr *ifa, int cmd) |
1354{ | 247{ |
1355 struct ifaddr *ifa; 1356 struct sockaddr_in6 *sin6; 1357 int num_eligible_addr = 0; 1358 int sin_loop, sin_local; | 248 struct sctp_laddr *wi; 249 struct sctp_ifa *ifap = NULL; 250 uint32_t ifa_flags = 0; 251 struct in6_ifaddr *ifa6; |
1359 | 252 |
1360 TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) { 1361 sin6 = sctp_is_v6_ifa_addr_acceptable(ifa, loopscope, loc_scope, &sin_loop, &sin_local); 1362 if (sin6 == NULL) 1363 continue; 1364 if (stcb) { 1365 if ((non_asoc_addr_ok == 0) && sctp_is_addr_restricted(stcb, (struct sockaddr *)sin6)) { 1366 /* 1367 * It is restricted for some reason.. 1368 * probably not yet added. 1369 */ 1370 continue; 1371 } 1372 } 1373 num_eligible_addr++; 1374 } 1375 return (num_eligible_addr); 1376} 1377 1378 1379static struct sockaddr_in6 * 1380sctp_choose_v6_boundall(struct sctp_inpcb *inp, 1381 struct sctp_tcb *stcb, 1382 struct sctp_nets *net, 1383 struct route *ro, 1384 uint8_t loc_scope, 1385 uint8_t loopscope, 1386 int non_asoc_addr_ok) 1387{ | |
1388 /* | 253 /* |
1389 * Ok, we are bound all SO any address is ok to use as long as it is 1390 * NOT in the negative list. | 254 * BSD only has one VRF, if this changes we will need to hook in the 255 * right things here to get the id to pass to the address managment 256 * routine. |
1391 */ | 257 */ |
1392 int num_eligible_addr; 1393 int cur_addr_num = 0; 1394 int started_at_beginning = 0; 1395 int match_scope_prefered; 1396 1397 /* 1398 * first question is, how many eligible addresses are there for the 1399 * destination ifn that we are using that are within the proper 1400 * scope? 1401 */ 1402 struct ifnet *ifn; 1403 struct sockaddr_in6 *sin6; 1404 struct rtentry *rt; 1405 1406 rt = ro->ro_rt; 1407 ifn = rt->rt_ifp; 1408 if (net) { 1409 cur_addr_num = net->indx_of_eligible_next_to_use; | 258 if (first_time == 0) { 259 /* Special test to see if my ::1 will showup with this */ 260 first_time = 1; 261 sctp_init_ifns_for_vrf(SCTP_DEFAULT_VRFID); |
1410 } | 262 } |
1411 if (cur_addr_num == 0) { 1412 match_scope_prefered = 1; 1413 } else { 1414 match_scope_prefered = 0; | 263 if ((cmd != RTM_ADD) && (cmd != RTM_DELETE)) { 264 /* don't know what to do with this */ 265 return; |
1415 } | 266 } |
1416 num_eligible_addr = sctp_count_v6_num_eligible_boundall(ifn, stcb, non_asoc_addr_ok, loopscope, loc_scope); 1417#ifdef SCTP_DEBUG 1418 if (sctp_debug_on & SCTP_DEBUG_OUTPUT1) { 1419 printf("Found %d eligible source addresses\n", num_eligible_addr); | 267 if (ifa->ifa_addr == NULL) { 268 return; |
1420 } | 269 } |
1421#endif 1422 if (num_eligible_addr == 0) { 1423 /* 1424 * no eligible addresses, we must use some other interface 1425 * address if we can find one. 1426 */ 1427 goto bound_all_v6_plan_b; | 270 if ((ifa->ifa_addr->sa_family != AF_INET) && 271 (ifa->ifa_addr->sa_family != AF_INET6) 272 ) { 273 /* non inet/inet6 skip */ 274 return; |
1428 } | 275 } |
1429 /* 1430 * Ok we have num_eligible_addr set with how many we can use, this 1431 * may vary from call to call due to addresses being deprecated 1432 * etc.. 1433 */ 1434 if (cur_addr_num >= num_eligible_addr) { 1435 cur_addr_num = 0; 1436 } 1437 /* 1438 * select the nth address from the list (where cur_addr_num is the 1439 * nth) and 0 is the first one, 1 is the second one etc... 1440 */ 1441#ifdef SCTP_DEBUG 1442 if (sctp_debug_on & SCTP_DEBUG_OUTPUT1) { 1443 printf("cur_addr_num:%d match_scope_prefered:%d select it\n", 1444 cur_addr_num, match_scope_prefered); 1445 } 1446#endif 1447 sin6 = sctp_select_v6_nth_addr_from_ifn_boundall(ifn, stcb, non_asoc_addr_ok, loopscope, 1448 loc_scope, cur_addr_num, match_scope_prefered); 1449 if (match_scope_prefered && (sin6 == NULL)) { 1450 /* retry without the preference for matching scope */ 1451#ifdef SCTP_DEBUG 1452 if (sctp_debug_on & SCTP_DEBUG_OUTPUT1) { 1453 printf("retry with no match_scope_prefered\n"); | 276 if (ifa->ifa_addr->sa_family == AF_INET6) { 277 ifa6 = (struct in6_ifaddr *)ifa; 278 ifa_flags = ifa6->ia6_flags; 279 if (IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr)) { 280 /* skip unspecifed addresses */ 281 return; |
1454 } | 282 } |
1455#endif 1456 sin6 = sctp_select_v6_nth_addr_from_ifn_boundall(ifn, stcb, non_asoc_addr_ok, loopscope, 1457 loc_scope, cur_addr_num, 0); 1458 } 1459 if (sin6) { 1460#ifdef SCTP_DEBUG 1461 if (sctp_debug_on & SCTP_DEBUG_OUTPUT1) { 1462 printf("Selected address %d ifn:%p for the route\n", cur_addr_num, ifn); | 283 } else if (ifa->ifa_addr->sa_family == AF_INET) { 284 if (((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr == 0) { 285 return; |
1463 } | 286 } |
1464#endif 1465 if (net) { 1466 /* store so we get the next one */ 1467 if (cur_addr_num < 255) 1468 net->indx_of_eligible_next_to_use = cur_addr_num + 1; 1469 else 1470 net->indx_of_eligible_next_to_use = 0; 1471 } 1472 return (sin6); | |
1473 } | 287 } |
1474 num_eligible_addr = 0; 1475bound_all_v6_plan_b: 1476 /* 1477 * ok, if we reach here we either fell through due to something 1478 * changing during an interupt (unlikely) or we have NO eligible 1479 * source addresses for the ifn of the route (most likely). We must 1480 * look at all the other interfaces EXCEPT rt->rt_ifp and do the 1481 * same game. 1482 */ 1483 if (inp->next_ifn_touse == NULL) { 1484 started_at_beginning = 1; 1485 inp->next_ifn_touse = TAILQ_FIRST(&ifnet); 1486#ifdef SCTP_DEBUG 1487 if (sctp_debug_on & SCTP_DEBUG_OUTPUT1) { 1488 printf("Start at first IFN:%p\n", inp->next_ifn_touse); 1489 } 1490#endif 1491 } else { 1492 inp->next_ifn_touse = TAILQ_NEXT(inp->next_ifn_touse, if_list); 1493#ifdef SCTP_DEBUG 1494 if (sctp_debug_on & SCTP_DEBUG_OUTPUT1) { 1495 printf("Resume at IFN:%p\n", inp->next_ifn_touse); 1496 } 1497#endif 1498 if (inp->next_ifn_touse == NULL) { 1499#ifdef SCTP_DEBUG 1500 if (sctp_debug_on & SCTP_DEBUG_OUTPUT1) { 1501 printf("IFN Resets\n"); 1502 } 1503#endif 1504 started_at_beginning = 1; 1505 inp->next_ifn_touse = TAILQ_FIRST(&ifnet); 1506 } | 288 if (sctp_is_desired_interface_type(ifa) == 0) { 289 /* non desired type */ 290 return; |
1507 } | 291 } |
1508 for (ifn = inp->next_ifn_touse; ifn; 1509 ifn = TAILQ_NEXT(ifn, if_list)) { 1510 if (loopscope == 0 && ifn->if_type == IFT_LOOP) { 1511 /* wrong base scope */ 1512 continue; 1513 } 1514 if (loc_scope && (ifn->if_index != loc_scope)) { 1515 /* 1516 * by definition the scope (from to->sin6_scopeid) 1517 * must match that of the interface. If not then we 1518 * could pick a wrong scope for the address. 1519 * Ususally we don't hit plan-b since the route 1520 * handles this. However we can hit plan-b when we 1521 * send to local-host so the route is the loopback 1522 * interface, but the destination is a link local. 1523 */ 1524 continue; 1525 } 1526 if (ifn == rt->rt_ifp) { 1527 /* already looked at this guy */ 1528 continue; 1529 } | 292 if (cmd == RTM_ADD) { 293 ifap = sctp_add_addr_to_vrf(SCTP_DEFAULT_VRFID, (void *)ifa->ifa_ifp, 294 ifa->ifa_ifp->if_index, ifa->ifa_ifp->if_type, 295 ifa->ifa_ifp->if_xname, 296 (void *)ifa, ifa->ifa_addr, ifa_flags); |
1530 /* | 297 /* |
1531 * Address rotation will only work when we are not rotating 1532 * sourced interfaces and are using the interface of the 1533 * route. We would need to have a per interface index in 1534 * order to do proper rotation. | 298 * Bump up the refcount so that when the timer completes it 299 * will drop back down. |
1535 */ | 300 */ |
1536 num_eligible_addr = sctp_count_v6_num_eligible_boundall(ifn, stcb, non_asoc_addr_ok, loopscope, loc_scope); 1537#ifdef SCTP_DEBUG 1538 if (sctp_debug_on & SCTP_DEBUG_OUTPUT1) { 1539 printf("IFN:%p has %d eligible\n", ifn, num_eligible_addr); 1540 } 1541#endif 1542 if (num_eligible_addr == 0) { 1543 /* none we can use */ 1544 continue; 1545 } 1546 /* 1547 * Ok we have num_eligible_addr set with how many we can 1548 * use, this may vary from call to call due to addresses 1549 * being deprecated etc.. 1550 */ 1551 inp->next_ifn_touse = ifn; | 301 if (ifap) 302 atomic_add_int(&ifap->refcount, 1); |
1552 | 303 |
304 } else if (cmd == RTM_DELETE) { 305 306 ifap = sctp_del_addr_from_vrf(SCTP_DEFAULT_VRFID, ifa->ifa_addr, ifa->ifa_ifp->if_index); |
|
1553 /* | 307 /* |
1554 * select the first one we can find with perference for 1555 * matching scope. | 308 * We don't bump refcount here so when it completes the 309 * final delete will happen. |
1556 */ | 310 */ |
1557 sin6 = sctp_select_v6_nth_addr_from_ifn_boundall(ifn, stcb, non_asoc_addr_ok, loopscope, loc_scope, 0, 1); 1558 if (sin6 == NULL) { 1559 /* 1560 * can't find one with matching scope how about a 1561 * source with higher scope 1562 */ 1563 sin6 = sctp_select_v6_nth_addr_from_ifn_boundall(ifn, stcb, non_asoc_addr_ok, loopscope, loc_scope, 0, 0); 1564 if (sin6 == NULL) 1565 /* Hmm, can't find one in the interface now */ 1566 continue; 1567 } 1568#ifdef SCTP_DEBUG 1569 if (sctp_debug_on & SCTP_DEBUG_OUTPUT1) { 1570 printf("Selected the %d'th address of ifn:%p\n", 1571 cur_addr_num, 1572 ifn); 1573 } 1574#endif 1575 return (sin6); | |
1576 } | 311 } |
1577 if (started_at_beginning == 0) { | 312 if (ifap == NULL) 313 return; 314 315 wi = SCTP_ZONE_GET(sctppcbinfo.ipi_zone_laddr, struct sctp_laddr); 316 if (wi == NULL) { |
1578 /* | 317 /* |
1579 * we have not been through all of them yet, force us to go 1580 * through them all. | 318 * Gak, what can we do? We have lost an address change can 319 * you say HOSED? |
1581 */ 1582#ifdef SCTP_DEBUG | 320 */ 321#ifdef SCTP_DEBUG |
1583 if (sctp_debug_on & SCTP_DEBUG_OUTPUT1) { 1584 printf("Force a recycle\n"); | 322 if (sctp_debug_on & SCTP_DEBUG_PCB1) { 323 printf("Lost and address change ???\n"); |
1585 } | 324 } |
1586#endif 1587 inp->next_ifn_touse = NULL; 1588 goto bound_all_v6_plan_b; 1589 } 1590 RTFREE(ro->ro_rt); 1591 ro->ro_rt = NULL; 1592 return (NULL); | 325#endif /* SCTP_DEBUG */ |
1593 | 326 |
1594} 1595 1596/* stcb and net may be NULL */ 1597struct in6_addr 1598sctp_ipv6_source_address_selection(struct sctp_inpcb *inp, 1599 struct sctp_tcb *stcb, struct route *ro, struct sctp_nets *net, 1600 int non_asoc_addr_ok) 1601{ 1602 struct in6_addr ans; 1603 struct sockaddr_in6 *rt_addr; 1604 uint8_t loc_scope, loopscope; 1605 struct sockaddr_in6 *to = (struct sockaddr_in6 *)&ro->ro_dst; 1606 1607 /* 1608 * This routine is tricky standard v6 src address selection cannot 1609 * take into account what we have bound etc, so we can't use it. 1610 * 1611 * Instead here is what we must do: 1) Make sure we have a route, if we 1612 * don't have a route we can never reach the peer. 2) Once we have a 1613 * route, determine the scope of the route. Link local, loopback or 1614 * global. 3) Next we divide into three types. Either we are bound 1615 * all.. which means we want to use one of the addresses of the 1616 * interface we are going out. <or> 4a) We have not stcb, which 1617 * means we are using the specific addresses bound on an inp, in 1618 * this case we are similar to the stcb case (4b below) accept the 1619 * list is always a positive list.<or> 4b) We are bound specific 1620 * with a stcb, which means we have a list of bound addresses and we 1621 * must see if the ifn of the route is actually one of the bound 1622 * addresses. If not, then we must rotate addresses amongst properly 1623 * scoped bound addresses, if so we use the address of the 1624 * interface. 5) Always, no matter which path we take through the 1625 * above we must be sure the source address we use is allowed to be 1626 * used. I.e. IN6_IFF_DETACHED, IN6_IFF_NOTREADY, and 1627 * IN6_IFF_ANYCAST addresses cannot be used. 6) Addresses that are 1628 * deprecated MAY be used if (!ip6_use_deprecated) { if 1629 * (IFA6_IS_DEPRECATED(ifa6)) { skip the address } } 1630 */ 1631 1632 /*** 1> determine route, if not already done */ 1633 if (ro->ro_rt == NULL) { 1634 /* 1635 * Need a route to cache. 1636 */ 1637 int scope_save; 1638 1639 scope_save = to->sin6_scope_id; 1640 to->sin6_scope_id = 0; 1641 1642 rtalloc_ign(ro, 0UL); 1643 to->sin6_scope_id = scope_save; | 327 /* Opps, must decrement the count */ 328 sctp_free_ifa(ifap); 329 return; |
1644 } | 330 } |
1645 if (ro->ro_rt == NULL) { 1646 /* 1647 * no route to host. this packet is going no-where. We 1648 * probably should make sure we arrange to send back an 1649 * error. 1650 */ 1651#ifdef SCTP_DEBUG 1652 if (sctp_debug_on & SCTP_DEBUG_OUTPUT1) { 1653 printf("No route to host, this packet cannot be sent!\n"); 1654 } 1655#endif 1656 memset(&ans, 0, sizeof(ans)); 1657 return (ans); | 331 SCTP_INCR_LADDR_COUNT(); 332 bzero(wi, sizeof(*wi)); 333 wi->ifa = ifap; 334 if (cmd == RTM_ADD) { 335 wi->action = SCTP_ADD_IP_ADDRESS; 336 } else if (cmd == RTM_DELETE) { 337 wi->action = SCTP_DEL_IP_ADDRESS; |
1658 } | 338 } |
1659 /*** 2a> determine scope for outbound address/route */ 1660 loc_scope = loopscope = 0; | 339 SCTP_IPI_ITERATOR_WQ_LOCK(); |
1661 /* | 340 /* |
1662 * We base our scope on the outbound packet scope and route, NOT the 1663 * TCB (if there is one). This way in local scope we will only use a 1664 * local scope src address when we send to a local address. | 341 * Should this really be a tailq? As it is we will process the 342 * newest first :-0 |
1665 */ | 343 */ |
1666 1667 if (IN6_IS_ADDR_LOOPBACK(&to->sin6_addr)) { 1668 /* 1669 * If the route goes to the loopback address OR the address 1670 * is a loopback address, we are loopback scope. 1671 */ 1672 loc_scope = 0; 1673 loopscope = 1; 1674 if (net != NULL) { 1675 /* mark it as local */ 1676 net->addr_is_local = 1; 1677 } 1678 } else if (IN6_IS_ADDR_LINKLOCAL(&to->sin6_addr)) { 1679 if (to->sin6_scope_id) 1680 loc_scope = to->sin6_scope_id; 1681 else { 1682 loc_scope = 1; 1683 } 1684 loopscope = 0; 1685 } 1686 /* 1687 * now, depending on which way we are bound we call the appropriate 1688 * routine to do steps 3-6 1689 */ 1690#ifdef SCTP_DEBUG 1691 if (sctp_debug_on & SCTP_DEBUG_OUTPUT1) { 1692 printf("Destination address:"); 1693 sctp_print_address((struct sockaddr *)to); 1694 } 1695#endif 1696 1697 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { 1698 rt_addr = sctp_choose_v6_boundall(inp, stcb, net, ro, loc_scope, loopscope, non_asoc_addr_ok); 1699 } else { 1700 if (stcb) 1701 rt_addr = sctp_choose_v6_boundspecific_stcb(inp, stcb, net, ro, loc_scope, loopscope, non_asoc_addr_ok); 1702 else 1703 /* 1704 * we can't have a non-asoc address since we have no 1705 * association 1706 */ 1707 rt_addr = sctp_choose_v6_boundspecific_inp(inp, ro, loc_scope, loopscope); 1708 } 1709 if (rt_addr == NULL) { 1710 /* no suitable address? */ 1711 struct in6_addr in6; 1712 1713#ifdef SCTP_DEBUG 1714 if (sctp_debug_on & SCTP_DEBUG_OUTPUT1) { 1715 printf("V6 packet will reach dead-end no suitable src address\n"); 1716 } 1717#endif 1718 memset(&in6, 0, sizeof(in6)); 1719 return (in6); 1720 } 1721#ifdef SCTP_DEBUG 1722 if (sctp_debug_on & SCTP_DEBUG_OUTPUT1) { 1723 printf("Source address selected is:"); 1724 sctp_print_address((struct sockaddr *)rt_addr); 1725 } 1726#endif 1727 return (rt_addr->sin6_addr); | 344 LIST_INSERT_HEAD(&sctppcbinfo.addr_wq, wi, sctp_nxt_addr); 345 sctp_timer_start(SCTP_TIMER_TYPE_ADDR_WQ, 346 (struct sctp_inpcb *)NULL, 347 (struct sctp_tcb *)NULL, 348 (struct sctp_nets *)NULL); 349 SCTP_IPI_ITERATOR_WQ_UNLOCK(); |
1728} | 350} |
1729 1730 1731static 1732int 1733sctp_is_address_in_scope(struct ifaddr *ifa, 1734 int ipv4_addr_legal, 1735 int ipv6_addr_legal, 1736 int loopback_scope, 1737 int ipv4_local_scope, 1738 int local_scope, 1739 int site_scope) 1740{ 1741 if ((loopback_scope == 0) && 1742 (ifa->ifa_ifp) && 1743 (ifa->ifa_ifp->if_type == IFT_LOOP)) { 1744 /* 1745 * skip loopback if not in scope * 1746 */ 1747 return (0); 1748 } 1749 if ((ifa->ifa_addr->sa_family == AF_INET) && ipv4_addr_legal) { 1750 struct sockaddr_in *sin; 1751 1752 sin = (struct sockaddr_in *)ifa->ifa_addr; 1753 if (sin->sin_addr.s_addr == 0) { 1754 /* not in scope , unspecified */ 1755 return (0); 1756 } 1757 if ((ipv4_local_scope == 0) && 1758 (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) { 1759 /* private address not in scope */ 1760 return (0); 1761 } 1762 } else if ((ifa->ifa_addr->sa_family == AF_INET6) && ipv6_addr_legal) { 1763 struct sockaddr_in6 *sin6; 1764 struct in6_ifaddr *ifa6; 1765 1766 ifa6 = (struct in6_ifaddr *)ifa; 1767 /* ok to use deprecated addresses? */ 1768 if (!ip6_use_deprecated) { 1769 if (ifa6->ia6_flags & 1770 IN6_IFF_DEPRECATED) { 1771 return (0); 1772 } 1773 } 1774 if (ifa6->ia6_flags & 1775 (IN6_IFF_DETACHED | 1776 IN6_IFF_ANYCAST | 1777 IN6_IFF_NOTREADY)) { 1778 return (0); 1779 } 1780 sin6 = (struct sockaddr_in6 *)ifa->ifa_addr; 1781 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 1782 /* skip unspecifed addresses */ 1783 return (0); 1784 } 1785 if ( /* (local_scope == 0) && */ 1786 (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))) { 1787 return (0); 1788 } 1789 if ((site_scope == 0) && 1790 (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) { 1791 return (0); 1792 } 1793 } else { 1794 return (0); 1795 } 1796 return (1); 1797} 1798 1799static struct mbuf * 1800sctp_add_addr_to_mbuf(struct mbuf *m, struct ifaddr *ifa) 1801{ 1802 struct sctp_paramhdr *parmh; 1803 struct mbuf *mret; 1804 int len; 1805 1806 if (ifa->ifa_addr->sa_family == AF_INET) { 1807 len = sizeof(struct sctp_ipv4addr_param); 1808 } else if (ifa->ifa_addr->sa_family == AF_INET6) { 1809 len = sizeof(struct sctp_ipv6addr_param); 1810 } else { 1811 /* unknown type */ 1812 return (m); 1813 } 1814 if (M_TRAILINGSPACE(m) >= len) { 1815 /* easy side we just drop it on the end */ 1816 parmh = (struct sctp_paramhdr *)(SCTP_BUF_AT(m, SCTP_BUF_LEN(m))); 1817 mret = m; 1818 } else { 1819 /* Need more space */ 1820 mret = m; 1821 while (SCTP_BUF_NEXT(mret) != NULL) { 1822 mret = SCTP_BUF_NEXT(mret); 1823 } 1824 SCTP_BUF_NEXT(mret) = sctp_get_mbuf_for_msg(len, 0, M_DONTWAIT, 1, MT_DATA); 1825 if (SCTP_BUF_NEXT(mret) == NULL) { 1826 /* We are hosed, can't add more addresses */ 1827 return (m); 1828 } 1829 mret = SCTP_BUF_NEXT(mret); 1830 parmh = mtod(mret, struct sctp_paramhdr *); 1831 } 1832 /* now add the parameter */ 1833 if (ifa->ifa_addr->sa_family == AF_INET) { 1834 struct sctp_ipv4addr_param *ipv4p; 1835 struct sockaddr_in *sin; 1836 1837 sin = (struct sockaddr_in *)ifa->ifa_addr; 1838 ipv4p = (struct sctp_ipv4addr_param *)parmh; 1839 parmh->param_type = htons(SCTP_IPV4_ADDRESS); 1840 parmh->param_length = htons(len); 1841 ipv4p->addr = sin->sin_addr.s_addr; 1842 SCTP_BUF_LEN(mret) += len; 1843 } else if (ifa->ifa_addr->sa_family == AF_INET6) { 1844 struct sctp_ipv6addr_param *ipv6p; 1845 struct sockaddr_in6 *sin6; 1846 1847 sin6 = (struct sockaddr_in6 *)ifa->ifa_addr; 1848 ipv6p = (struct sctp_ipv6addr_param *)parmh; 1849 parmh->param_type = htons(SCTP_IPV6_ADDRESS); 1850 parmh->param_length = htons(len); 1851 memcpy(ipv6p->addr, &sin6->sin6_addr, 1852 sizeof(ipv6p->addr)); 1853 /* clear embedded scope in the address */ 1854 in6_clearscope((struct in6_addr *)ipv6p->addr); 1855 SCTP_BUF_LEN(mret) += len; 1856 } else { 1857 return (m); 1858 } 1859 return (mret); 1860} 1861 1862 1863struct mbuf * 1864sctp_add_addresses_to_i_ia(struct sctp_inpcb *inp, struct sctp_scoping *scope, struct mbuf *m_at, int cnt_inits_to) 1865{ 1866 int cnt; 1867 1868 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { 1869 struct ifnet *ifn; 1870 struct ifaddr *ifa; 1871 1872 cnt = cnt_inits_to; 1873 TAILQ_FOREACH(ifn, &ifnet, if_list) { 1874 if ((scope->loopback_scope == 0) && 1875 (ifn->if_type == IFT_LOOP)) { 1876 /* 1877 * Skip loopback devices if loopback_scope 1878 * not set 1879 */ 1880 continue; 1881 } 1882 TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) { 1883 if (sctp_is_address_in_scope(ifa, 1884 scope->ipv4_addr_legal, 1885 scope->ipv6_addr_legal, 1886 scope->loopback_scope, 1887 scope->ipv4_local_scope, 1888 scope->local_scope, 1889 scope->site_scope) == 0) { 1890 continue; 1891 } 1892 cnt++; 1893 } 1894 } 1895 if (cnt > 1) { 1896 TAILQ_FOREACH(ifn, &ifnet, if_list) { 1897 if ((scope->loopback_scope == 0) && 1898 (ifn->if_type == IFT_LOOP)) { 1899 /* 1900 * Skip loopback devices if 1901 * loopback_scope not set 1902 */ 1903 continue; 1904 } 1905 TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) { 1906 if (sctp_is_address_in_scope(ifa, 1907 scope->ipv4_addr_legal, 1908 scope->ipv6_addr_legal, 1909 scope->loopback_scope, 1910 scope->ipv4_local_scope, 1911 scope->local_scope, 1912 scope->site_scope) == 0) { 1913 continue; 1914 } 1915 m_at = sctp_add_addr_to_mbuf(m_at, ifa); 1916 } 1917 } 1918 } 1919 } else { 1920 struct sctp_laddr *laddr; 1921 int cnt; 1922 1923 cnt = cnt_inits_to; 1924 /* First, how many ? */ 1925 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { 1926 if (laddr->ifa == NULL) { 1927 continue; 1928 } 1929 if (laddr->ifa->ifa_addr == NULL) 1930 continue; 1931 if (sctp_is_address_in_scope(laddr->ifa, 1932 scope->ipv4_addr_legal, 1933 scope->ipv6_addr_legal, 1934 scope->loopback_scope, 1935 scope->ipv4_local_scope, 1936 scope->local_scope, 1937 scope->site_scope) == 0) { 1938 continue; 1939 } 1940 cnt++; 1941 } 1942 /* 1943 * To get through a NAT we only list addresses if we have 1944 * more than one. That way if you just bind a single address 1945 * we let the source of the init dictate our address. 1946 */ 1947 if (cnt > 1) { 1948 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { 1949 if (laddr->ifa == NULL) { 1950 continue; 1951 } 1952 if (laddr->ifa->ifa_addr == NULL) { 1953 continue; 1954 } 1955 if (sctp_is_address_in_scope(laddr->ifa, 1956 scope->ipv4_addr_legal, 1957 scope->ipv6_addr_legal, 1958 scope->loopback_scope, 1959 scope->ipv4_local_scope, 1960 scope->local_scope, 1961 scope->site_scope) == 0) { 1962 continue; 1963 } 1964 m_at = sctp_add_addr_to_mbuf(m_at, laddr->ifa); 1965 } 1966 } 1967 } 1968 return (m_at); 1969} | |