sctp_output.c (168124) | sctp_output.c (168299) |
---|---|
1/*- 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. --- 17 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> | 1/*- 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. --- 17 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_output.c 168124 2007-03-31 11:47:30Z rrs $"); | 34__FBSDID("$FreeBSD: head/sys/netinet/sctp_output.c 168299 2007-04-03 11:15:32Z rrs $"); |
35 36#include <netinet/sctp_os.h> 37#include <sys/proc.h> 38#include <netinet/sctp_var.h> 39#include <netinet/sctp_sysctl.h> 40#include <netinet/sctp_header.h> 41#include <netinet/sctp_pcb.h> 42#include <netinet/sctputil.h> --- 1943 unchanged lines hidden (view full) --- 1986struct mbuf * 1987sctp_add_addresses_to_i_ia(struct sctp_inpcb *inp, struct sctp_scoping *scope, 1988 struct mbuf *m_at, int cnt_inits_to) 1989{ 1990 struct sctp_vrf *vrf = NULL; 1991 int cnt, limit_out = 0, total_count; 1992 uint32_t vrf_id; 1993 | 35 36#include <netinet/sctp_os.h> 37#include <sys/proc.h> 38#include <netinet/sctp_var.h> 39#include <netinet/sctp_sysctl.h> 40#include <netinet/sctp_header.h> 41#include <netinet/sctp_pcb.h> 42#include <netinet/sctputil.h> --- 1943 unchanged lines hidden (view full) --- 1986struct mbuf * 1987sctp_add_addresses_to_i_ia(struct sctp_inpcb *inp, struct sctp_scoping *scope, 1988 struct mbuf *m_at, int cnt_inits_to) 1989{ 1990 struct sctp_vrf *vrf = NULL; 1991 int cnt, limit_out = 0, total_count; 1992 uint32_t vrf_id; 1993 |
1994 vrf_id = SCTP_DEFAULT_VRFID; | 1994 vrf_id = inp->def_vrf_id; |
1995 SCTP_IPI_ADDR_LOCK(); 1996 vrf = sctp_find_vrf(vrf_id); 1997 if (vrf == NULL) { 1998 SCTP_IPI_ADDR_UNLOCK(); 1999 return (m_at); 2000 } 2001 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { 2002 struct sctp_ifa *sctp_ifap; --- 395 unchanged lines hidden (view full) --- 2398 } 2399 return (0); 2400} 2401 2402 2403 2404static struct sctp_ifa * 2405sctp_choose_boundspecific_inp(struct sctp_inpcb *inp, | 1995 SCTP_IPI_ADDR_LOCK(); 1996 vrf = sctp_find_vrf(vrf_id); 1997 if (vrf == NULL) { 1998 SCTP_IPI_ADDR_UNLOCK(); 1999 return (m_at); 2000 } 2001 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { 2002 struct sctp_ifa *sctp_ifap; --- 395 unchanged lines hidden (view full) --- 2398 } 2399 return (0); 2400} 2401 2402 2403 2404static struct sctp_ifa * 2405sctp_choose_boundspecific_inp(struct sctp_inpcb *inp, |
2406 struct route *ro, | 2406 sctp_route_t * ro, |
2407 uint32_t vrf_id, 2408 int non_asoc_addr_ok, 2409 uint8_t dest_is_priv, 2410 uint8_t dest_is_loop, 2411 sa_family_t fam) 2412{ 2413 struct sctp_laddr *laddr, *starting_point; 2414 void *ifn; 2415 int resettotop = 0; 2416 struct sctp_ifn *sctp_ifn; | 2407 uint32_t vrf_id, 2408 int non_asoc_addr_ok, 2409 uint8_t dest_is_priv, 2410 uint8_t dest_is_loop, 2411 sa_family_t fam) 2412{ 2413 struct sctp_laddr *laddr, *starting_point; 2414 void *ifn; 2415 int resettotop = 0; 2416 struct sctp_ifn *sctp_ifn; |
2417 struct sctp_ifa *sctp_ifa, *pass; | 2417 struct sctp_ifa *sctp_ifa, *sifa; |
2418 struct sctp_vrf *vrf; 2419 uint32_t ifn_index; 2420 2421 vrf = sctp_find_vrf(vrf_id); 2422 if (vrf == NULL) 2423 return (NULL); 2424 2425 ifn = SCTP_GET_IFN_VOID_FROM_ROUTE(ro); --- 4 unchanged lines hidden (view full) --- 2430 * want such an address. Note that we first looked for a prefered 2431 * address. 2432 */ 2433 if (sctp_ifn) { 2434 /* is a prefered one on the interface we route out? */ 2435 LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) { 2436 if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0)) 2437 continue; | 2418 struct sctp_vrf *vrf; 2419 uint32_t ifn_index; 2420 2421 vrf = sctp_find_vrf(vrf_id); 2422 if (vrf == NULL) 2423 return (NULL); 2424 2425 ifn = SCTP_GET_IFN_VOID_FROM_ROUTE(ro); --- 4 unchanged lines hidden (view full) --- 2430 * want such an address. Note that we first looked for a prefered 2431 * address. 2432 */ 2433 if (sctp_ifn) { 2434 /* is a prefered one on the interface we route out? */ 2435 LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) { 2436 if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0)) 2437 continue; |
2438 pass = sctp_is_ifa_addr_prefered(sctp_ifa, dest_is_loop, dest_is_priv, fam); 2439 if (pass == NULL) | 2438 sifa = sctp_is_ifa_addr_prefered(sctp_ifa, dest_is_loop, dest_is_priv, fam); 2439 if (sifa == NULL) |
2440 continue; | 2440 continue; |
2441 if (sctp_is_addr_in_ep(inp, pass)) { 2442 atomic_add_int(&pass->refcount, 1); 2443 return (pass); | 2441 if (sctp_is_addr_in_ep(inp, sifa)) { 2442 atomic_add_int(&sifa->refcount, 1); 2443 return (sifa); |
2444 } 2445 } 2446 } 2447 /* 2448 * ok, now we now need to find one on the list of the addresses. We 2449 * can't get one on the emitting interface so lets find first a 2450 * prefered one. If not that a acceptable one otherwise... we return 2451 * NULL. --- 4 unchanged lines hidden (view full) --- 2456 inp->next_addr_touse = LIST_FIRST(&inp->sctp_addr_list); 2457 resettotop = 1; 2458 } 2459 for (laddr = inp->next_addr_touse; laddr; laddr = LIST_NEXT(laddr, sctp_nxt_addr)) { 2460 if (laddr->ifa == NULL) { 2461 /* address has been removed */ 2462 continue; 2463 } | 2444 } 2445 } 2446 } 2447 /* 2448 * ok, now we now need to find one on the list of the addresses. We 2449 * can't get one on the emitting interface so lets find first a 2450 * prefered one. If not that a acceptable one otherwise... we return 2451 * NULL. --- 4 unchanged lines hidden (view full) --- 2456 inp->next_addr_touse = LIST_FIRST(&inp->sctp_addr_list); 2457 resettotop = 1; 2458 } 2459 for (laddr = inp->next_addr_touse; laddr; laddr = LIST_NEXT(laddr, sctp_nxt_addr)) { 2460 if (laddr->ifa == NULL) { 2461 /* address has been removed */ 2462 continue; 2463 } |
2464 pass = sctp_is_ifa_addr_prefered(laddr->ifa, dest_is_loop, dest_is_priv, fam); 2465 if (pass == NULL) | 2464 sifa = sctp_is_ifa_addr_prefered(laddr->ifa, dest_is_loop, dest_is_priv, fam); 2465 if (sifa == NULL) |
2466 continue; | 2466 continue; |
2467 atomic_add_int(&pass->refcount, 1); 2468 return (pass); | 2467 atomic_add_int(&sifa->refcount, 1); 2468 return (sifa); |
2469 } 2470 if (resettotop == 0) { 2471 inp->next_addr_touse = NULL; 2472 goto once_again; 2473 } 2474 inp->next_addr_touse = starting_point; 2475 resettotop = 0; 2476once_again_too: 2477 if (inp->next_addr_touse == NULL) { 2478 inp->next_addr_touse = LIST_FIRST(&inp->sctp_addr_list); 2479 resettotop = 1; 2480 } 2481 /* ok, what about an acceptable address in the inp */ 2482 for (laddr = inp->next_addr_touse; laddr; laddr = LIST_NEXT(laddr, sctp_nxt_addr)) { 2483 if (laddr->ifa == NULL) { 2484 /* address has been removed */ 2485 continue; 2486 } | 2469 } 2470 if (resettotop == 0) { 2471 inp->next_addr_touse = NULL; 2472 goto once_again; 2473 } 2474 inp->next_addr_touse = starting_point; 2475 resettotop = 0; 2476once_again_too: 2477 if (inp->next_addr_touse == NULL) { 2478 inp->next_addr_touse = LIST_FIRST(&inp->sctp_addr_list); 2479 resettotop = 1; 2480 } 2481 /* ok, what about an acceptable address in the inp */ 2482 for (laddr = inp->next_addr_touse; laddr; laddr = LIST_NEXT(laddr, sctp_nxt_addr)) { 2483 if (laddr->ifa == NULL) { 2484 /* address has been removed */ 2485 continue; 2486 } |
2487 pass = sctp_is_ifa_addr_acceptable(laddr->ifa, dest_is_loop, dest_is_priv, fam); 2488 if (pass == NULL) | 2487 sifa = sctp_is_ifa_addr_acceptable(laddr->ifa, dest_is_loop, dest_is_priv, fam); 2488 if (sifa == NULL) |
2489 continue; | 2489 continue; |
2490 atomic_add_int(&pass->refcount, 1); 2491 return (pass); | 2490 atomic_add_int(&sifa->refcount, 1); 2491 return (sifa); |
2492 } 2493 if (resettotop == 0) { 2494 inp->next_addr_touse = NULL; 2495 goto once_again_too; 2496 } 2497 /* 2498 * no address bound can be a source for the destination we are in 2499 * trouble 2500 */ 2501 return (NULL); 2502} 2503 2504 2505 2506static struct sctp_ifa * 2507sctp_choose_boundspecific_stcb(struct sctp_inpcb *inp, 2508 struct sctp_tcb *stcb, 2509 struct sctp_nets *net, | 2492 } 2493 if (resettotop == 0) { 2494 inp->next_addr_touse = NULL; 2495 goto once_again_too; 2496 } 2497 /* 2498 * no address bound can be a source for the destination we are in 2499 * trouble 2500 */ 2501 return (NULL); 2502} 2503 2504 2505 2506static struct sctp_ifa * 2507sctp_choose_boundspecific_stcb(struct sctp_inpcb *inp, 2508 struct sctp_tcb *stcb, 2509 struct sctp_nets *net, |
2510 struct route *ro, | 2510 sctp_route_t * ro, |
2511 uint32_t vrf_id, 2512 uint8_t dest_is_priv, 2513 uint8_t dest_is_loop, 2514 int non_asoc_addr_ok, 2515 sa_family_t fam) 2516{ 2517 struct sctp_laddr *laddr, *starting_point; 2518 void *ifn; 2519 struct sctp_ifn *sctp_ifn; | 2511 uint32_t vrf_id, 2512 uint8_t dest_is_priv, 2513 uint8_t dest_is_loop, 2514 int non_asoc_addr_ok, 2515 sa_family_t fam) 2516{ 2517 struct sctp_laddr *laddr, *starting_point; 2518 void *ifn; 2519 struct sctp_ifn *sctp_ifn; |
2520 struct sctp_ifa *sctp_ifa, *pass; | 2520 struct sctp_ifa *sctp_ifa, *sifa; |
2521 uint8_t start_at_beginning = 0; 2522 struct sctp_vrf *vrf; 2523 uint32_t ifn_index; 2524 2525 /* 2526 * first question, is the ifn we will emit on in our list, if so, we 2527 * want that one. 2528 */ --- 6 unchanged lines hidden (view full) --- 2535 sctp_ifn = sctp_find_ifn(vrf, ifn, ifn_index); 2536 2537 /* 2538 * first question, is the ifn we will emit on in our list, if so, we 2539 * want that one.. First we look for a prefered. Second we go for an 2540 * acceptable. 2541 */ 2542 if (sctp_ifn) { | 2521 uint8_t start_at_beginning = 0; 2522 struct sctp_vrf *vrf; 2523 uint32_t ifn_index; 2524 2525 /* 2526 * first question, is the ifn we will emit on in our list, if so, we 2527 * want that one. 2528 */ --- 6 unchanged lines hidden (view full) --- 2535 sctp_ifn = sctp_find_ifn(vrf, ifn, ifn_index); 2536 2537 /* 2538 * first question, is the ifn we will emit on in our list, if so, we 2539 * want that one.. First we look for a prefered. Second we go for an 2540 * acceptable. 2541 */ 2542 if (sctp_ifn) { |
2543 /* first try for an prefered address on the ep */ | 2543 /* first try for a prefered address on the ep */ |
2544 LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) { 2545 if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0)) 2546 continue; 2547 if (sctp_is_addr_in_ep(inp, sctp_ifa)) { | 2544 LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) { 2545 if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0)) 2546 continue; 2547 if (sctp_is_addr_in_ep(inp, sctp_ifa)) { |
2548 pass = sctp_is_ifa_addr_prefered(sctp_ifa, dest_is_loop, dest_is_priv, fam); 2549 if (pass == NULL) | 2548 sifa = sctp_is_ifa_addr_prefered(sctp_ifa, dest_is_loop, dest_is_priv, fam); 2549 if (sifa == NULL) |
2550 continue; 2551 if ((non_asoc_addr_ok == 0) && | 2550 continue; 2551 if ((non_asoc_addr_ok == 0) && |
2552 (sctp_is_addr_restricted(stcb, pass))) { | 2552 (sctp_is_addr_restricted(stcb, sifa))) { |
2553 /* on the no-no list */ 2554 continue; 2555 } | 2553 /* on the no-no list */ 2554 continue; 2555 } |
2556 atomic_add_int(&pass->refcount, 1); 2557 return (pass); | 2556 atomic_add_int(&sifa->refcount, 1); 2557 return (sifa); |
2558 } 2559 } 2560 /* next try for an acceptable address on the ep */ 2561 LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) { 2562 if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0)) 2563 continue; 2564 if (sctp_is_addr_in_ep(inp, sctp_ifa)) { | 2558 } 2559 } 2560 /* next try for an acceptable address on the ep */ 2561 LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) { 2562 if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0)) 2563 continue; 2564 if (sctp_is_addr_in_ep(inp, sctp_ifa)) { |
2565 pass = sctp_is_ifa_addr_acceptable(sctp_ifa, dest_is_loop, dest_is_priv, fam); 2566 if (pass == NULL) | 2565 sifa = sctp_is_ifa_addr_acceptable(sctp_ifa, dest_is_loop, dest_is_priv, fam); 2566 if (sifa == NULL) |
2567 continue; 2568 if ((non_asoc_addr_ok == 0) && | 2567 continue; 2568 if ((non_asoc_addr_ok == 0) && |
2569 (sctp_is_addr_restricted(stcb, pass))) { | 2569 (sctp_is_addr_restricted(stcb, sifa))) { |
2570 /* on the no-no list */ 2571 continue; 2572 } | 2570 /* on the no-no list */ 2571 continue; 2572 } |
2573 atomic_add_int(&pass->refcount, 1); 2574 return (pass); | 2573 atomic_add_int(&sifa->refcount, 1); 2574 return (sifa); |
2575 } 2576 } 2577 2578 } 2579 /* 2580 * if we can't find one like that then we must look at all addresses 2581 * bound to pick one at first prefereable then secondly acceptable. 2582 */ --- 5 unchanged lines hidden (view full) --- 2588 } 2589 /* search beginning with the last used address */ 2590 for (laddr = stcb->asoc.last_used_address; laddr; 2591 laddr = LIST_NEXT(laddr, sctp_nxt_addr)) { 2592 if (laddr->ifa == NULL) { 2593 /* address has been removed */ 2594 continue; 2595 } | 2575 } 2576 } 2577 2578 } 2579 /* 2580 * if we can't find one like that then we must look at all addresses 2581 * bound to pick one at first prefereable then secondly acceptable. 2582 */ --- 5 unchanged lines hidden (view full) --- 2588 } 2589 /* search beginning with the last used address */ 2590 for (laddr = stcb->asoc.last_used_address; laddr; 2591 laddr = LIST_NEXT(laddr, sctp_nxt_addr)) { 2592 if (laddr->ifa == NULL) { 2593 /* address has been removed */ 2594 continue; 2595 } |
2596 pass = sctp_is_ifa_addr_prefered(laddr->ifa, dest_is_loop, dest_is_priv, fam); 2597 if (pass == NULL) | 2596 sifa = sctp_is_ifa_addr_prefered(laddr->ifa, dest_is_loop, dest_is_priv, fam); 2597 if (sifa == NULL) |
2598 continue; 2599 if ((non_asoc_addr_ok == 0) && | 2598 continue; 2599 if ((non_asoc_addr_ok == 0) && |
2600 (sctp_is_addr_restricted(stcb, pass))) { | 2600 (sctp_is_addr_restricted(stcb, sifa))) { |
2601 /* on the no-no list */ 2602 continue; 2603 } 2604 stcb->asoc.last_used_address = laddr; | 2601 /* on the no-no list */ 2602 continue; 2603 } 2604 stcb->asoc.last_used_address = laddr; |
2605 atomic_add_int(&pass->refcount, 1); 2606 return (pass); | 2605 atomic_add_int(&sifa->refcount, 1); 2606 return (sifa); |
2607 2608 } 2609 if (start_at_beginning == 0) { 2610 stcb->asoc.last_used_address = NULL; 2611 goto sctp_from_the_top; 2612 } 2613 /* now try for any higher scope than the destination */ 2614 stcb->asoc.last_used_address = starting_point; --- 5 unchanged lines hidden (view full) --- 2620 } 2621 /* search beginning with the last used address */ 2622 for (laddr = stcb->asoc.last_used_address; laddr; 2623 laddr = LIST_NEXT(laddr, sctp_nxt_addr)) { 2624 if (laddr->ifa == NULL) { 2625 /* address has been removed */ 2626 continue; 2627 } | 2607 2608 } 2609 if (start_at_beginning == 0) { 2610 stcb->asoc.last_used_address = NULL; 2611 goto sctp_from_the_top; 2612 } 2613 /* now try for any higher scope than the destination */ 2614 stcb->asoc.last_used_address = starting_point; --- 5 unchanged lines hidden (view full) --- 2620 } 2621 /* search beginning with the last used address */ 2622 for (laddr = stcb->asoc.last_used_address; laddr; 2623 laddr = LIST_NEXT(laddr, sctp_nxt_addr)) { 2624 if (laddr->ifa == NULL) { 2625 /* address has been removed */ 2626 continue; 2627 } |
2628 pass = sctp_is_ifa_addr_acceptable(laddr->ifa, dest_is_loop, dest_is_priv, fam); 2629 if (pass == NULL) | 2628 sifa = sctp_is_ifa_addr_acceptable(laddr->ifa, dest_is_loop, dest_is_priv, fam); 2629 if (sifa == NULL) |
2630 continue; 2631 if ((non_asoc_addr_ok == 0) && | 2630 continue; 2631 if ((non_asoc_addr_ok == 0) && |
2632 (sctp_is_addr_restricted(stcb, pass))) { | 2632 (sctp_is_addr_restricted(stcb, sifa))) { |
2633 /* on the no-no list */ 2634 continue; 2635 } 2636 stcb->asoc.last_used_address = laddr; | 2633 /* on the no-no list */ 2634 continue; 2635 } 2636 stcb->asoc.last_used_address = laddr; |
2637 atomic_add_int(&pass->refcount, 1); 2638 return (pass); | 2637 atomic_add_int(&sifa->refcount, 1); 2638 return (sifa); |
2639 } 2640 if (start_at_beginning == 0) { 2641 stcb->asoc.last_used_address = NULL; 2642 goto sctp_from_the_top2; 2643 } 2644 return (NULL); 2645} 2646 2647static struct sctp_ifa * 2648sctp_select_nth_prefered_addr_from_ifn_boundall(struct sctp_ifn *ifn, 2649 struct sctp_tcb *stcb, 2650 int non_asoc_addr_ok, 2651 uint8_t dest_is_loop, 2652 uint8_t dest_is_priv, 2653 int addr_wanted, 2654 sa_family_t fam) 2655{ | 2639 } 2640 if (start_at_beginning == 0) { 2641 stcb->asoc.last_used_address = NULL; 2642 goto sctp_from_the_top2; 2643 } 2644 return (NULL); 2645} 2646 2647static struct sctp_ifa * 2648sctp_select_nth_prefered_addr_from_ifn_boundall(struct sctp_ifn *ifn, 2649 struct sctp_tcb *stcb, 2650 int non_asoc_addr_ok, 2651 uint8_t dest_is_loop, 2652 uint8_t dest_is_priv, 2653 int addr_wanted, 2654 sa_family_t fam) 2655{ |
2656 struct sctp_ifa *ifa, *pass; | 2656 struct sctp_ifa *ifa, *sifa; |
2657 int num_eligible_addr = 0; 2658 2659 LIST_FOREACH(ifa, &ifn->ifalist, next_ifa) { 2660 if ((ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0)) 2661 continue; | 2657 int num_eligible_addr = 0; 2658 2659 LIST_FOREACH(ifa, &ifn->ifalist, next_ifa) { 2660 if ((ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0)) 2661 continue; |
2662 pass = sctp_is_ifa_addr_prefered(ifa, dest_is_loop, dest_is_priv, fam); 2663 if (pass == NULL) | 2662 sifa = sctp_is_ifa_addr_prefered(ifa, dest_is_loop, dest_is_priv, fam); 2663 if (sifa == NULL) |
2664 continue; 2665 if (stcb) { | 2664 continue; 2665 if (stcb) { |
2666 if ((non_asoc_addr_ok == 0) && sctp_is_addr_restricted(stcb, pass)) { | 2666 if ((non_asoc_addr_ok == 0) && sctp_is_addr_restricted(stcb, sifa)) { |
2667 /* 2668 * It is restricted for some reason.. 2669 * probably not yet added. 2670 */ 2671 continue; 2672 } 2673 } 2674 if (num_eligible_addr >= addr_wanted) { | 2667 /* 2668 * It is restricted for some reason.. 2669 * probably not yet added. 2670 */ 2671 continue; 2672 } 2673 } 2674 if (num_eligible_addr >= addr_wanted) { |
2675 return (pass); | 2675 return (sifa); |
2676 } 2677 num_eligible_addr++; 2678 } 2679 return (NULL); 2680} 2681 2682 2683static int 2684sctp_count_num_prefered_boundall(struct sctp_ifn *ifn, 2685 struct sctp_tcb *stcb, 2686 int non_asoc_addr_ok, 2687 uint8_t dest_is_loop, 2688 uint8_t dest_is_priv, 2689 sa_family_t fam) 2690{ | 2676 } 2677 num_eligible_addr++; 2678 } 2679 return (NULL); 2680} 2681 2682 2683static int 2684sctp_count_num_prefered_boundall(struct sctp_ifn *ifn, 2685 struct sctp_tcb *stcb, 2686 int non_asoc_addr_ok, 2687 uint8_t dest_is_loop, 2688 uint8_t dest_is_priv, 2689 sa_family_t fam) 2690{ |
2691 struct sctp_ifa *ifa, *pass; | 2691 struct sctp_ifa *ifa, *sifa; |
2692 int num_eligible_addr = 0; 2693 2694 LIST_FOREACH(ifa, &ifn->ifalist, next_ifa) { 2695 if ((ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0)) { 2696 continue; 2697 } | 2692 int num_eligible_addr = 0; 2693 2694 LIST_FOREACH(ifa, &ifn->ifalist, next_ifa) { 2695 if ((ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0)) { 2696 continue; 2697 } |
2698 pass = sctp_is_ifa_addr_prefered(ifa, dest_is_loop, dest_is_priv, fam); 2699 if (pass == NULL) { | 2698 sifa = sctp_is_ifa_addr_prefered(ifa, dest_is_loop, dest_is_priv, fam); 2699 if (sifa == NULL) { |
2700 continue; 2701 } 2702 if (stcb) { | 2700 continue; 2701 } 2702 if (stcb) { |
2703 if ((non_asoc_addr_ok == 0) && sctp_is_addr_restricted(stcb, pass)) { | 2703 if ((non_asoc_addr_ok == 0) && sctp_is_addr_restricted(stcb, sifa)) { |
2704 /* 2705 * It is restricted for some reason.. 2706 * probably not yet added. 2707 */ 2708 continue; 2709 } 2710 } 2711 num_eligible_addr++; 2712 } 2713 return (num_eligible_addr); 2714} 2715 2716static struct sctp_ifa * 2717sctp_choose_boundall(struct sctp_inpcb *inp, 2718 struct sctp_tcb *stcb, 2719 struct sctp_nets *net, | 2704 /* 2705 * It is restricted for some reason.. 2706 * probably not yet added. 2707 */ 2708 continue; 2709 } 2710 } 2711 num_eligible_addr++; 2712 } 2713 return (num_eligible_addr); 2714} 2715 2716static struct sctp_ifa * 2717sctp_choose_boundall(struct sctp_inpcb *inp, 2718 struct sctp_tcb *stcb, 2719 struct sctp_nets *net, |
2720 struct route *ro, | 2720 sctp_route_t * ro, |
2721 uint32_t vrf_id, 2722 uint8_t dest_is_priv, 2723 uint8_t dest_is_loop, 2724 int non_asoc_addr_ok, 2725 sa_family_t fam) 2726{ 2727 int cur_addr_num = 0, num_prefered = 0; 2728 void *ifn; 2729 struct sctp_ifn *sctp_ifn, *looked_at = NULL, *emit_ifn; | 2721 uint32_t vrf_id, 2722 uint8_t dest_is_priv, 2723 uint8_t dest_is_loop, 2724 int non_asoc_addr_ok, 2725 sa_family_t fam) 2726{ 2727 int cur_addr_num = 0, num_prefered = 0; 2728 void *ifn; 2729 struct sctp_ifn *sctp_ifn, *looked_at = NULL, *emit_ifn; |
2730 struct sctp_ifa *sctp_ifa, *pass; | 2730 struct sctp_ifa *sctp_ifa, *sifa; |
2731 uint32_t ifn_index; 2732 struct sctp_vrf *vrf; 2733 2734 /* 2735 * For boundall we can use any address in the association. If 2736 * non_asoc_addr_ok is set we can use any address (at least in 2737 * theory). So we look for prefered addresses first. If we find one, 2738 * we use it. Otherwise we next try to get an address on the --- 110 unchanged lines hidden (view full) --- 2849 /* 2850 * Ok we have num_eligible_addr set with how many we can 2851 * use, this may vary from call to call due to addresses 2852 * being deprecated etc.. 2853 */ 2854 if (cur_addr_num >= num_prefered) { 2855 cur_addr_num = 0; 2856 } | 2731 uint32_t ifn_index; 2732 struct sctp_vrf *vrf; 2733 2734 /* 2735 * For boundall we can use any address in the association. If 2736 * non_asoc_addr_ok is set we can use any address (at least in 2737 * theory). So we look for prefered addresses first. If we find one, 2738 * we use it. Otherwise we next try to get an address on the --- 110 unchanged lines hidden (view full) --- 2849 /* 2850 * Ok we have num_eligible_addr set with how many we can 2851 * use, this may vary from call to call due to addresses 2852 * being deprecated etc.. 2853 */ 2854 if (cur_addr_num >= num_prefered) { 2855 cur_addr_num = 0; 2856 } |
2857 pass = sctp_select_nth_prefered_addr_from_ifn_boundall(sctp_ifn, stcb, non_asoc_addr_ok, dest_is_loop, | 2857 sifa = sctp_select_nth_prefered_addr_from_ifn_boundall(sctp_ifn, stcb, non_asoc_addr_ok, dest_is_loop, |
2858 dest_is_priv, cur_addr_num, fam); | 2858 dest_is_priv, cur_addr_num, fam); |
2859 if (pass == NULL) | 2859 if (sifa == NULL) |
2860 continue; 2861 if (net) { 2862 net->indx_of_eligible_next_to_use = cur_addr_num + 1; 2863#ifdef SCTP_DEBUG 2864 if (sctp_debug_on & SCTP_DEBUG_OUTPUT2) { 2865 printf("we selected %d\n", cur_addr_num); 2866 printf("Source:"); | 2860 continue; 2861 if (net) { 2862 net->indx_of_eligible_next_to_use = cur_addr_num + 1; 2863#ifdef SCTP_DEBUG 2864 if (sctp_debug_on & SCTP_DEBUG_OUTPUT2) { 2865 printf("we selected %d\n", cur_addr_num); 2866 printf("Source:"); |
2867 sctp_print_address(&pass->address.sa); | 2867 sctp_print_address(&sifa->address.sa); |
2868 printf("Dest:"); 2869 sctp_print_address(&net->ro._l_addr.sa); 2870 } 2871#endif 2872 } | 2868 printf("Dest:"); 2869 sctp_print_address(&net->ro._l_addr.sa); 2870 } 2871#endif 2872 } |
2873 atomic_add_int(&pass->refcount, 1); 2874 return (pass); | 2873 atomic_add_int(&sifa->refcount, 1); 2874 return (sifa); |
2875 2876 } 2877 2878 /* 2879 * plan_c: See if we have an acceptable address on the emit 2880 * interface 2881 */ 2882#ifdef SCTP_DEBUG 2883 if (sctp_debug_on & SCTP_DEBUG_OUTPUT2) { 2884 printf("Plan C no prefered for Dest, acceptable for?\n"); 2885 } 2886#endif 2887 2888 LIST_FOREACH(sctp_ifa, &emit_ifn->ifalist, next_ifa) { 2889 if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0)) 2890 continue; | 2875 2876 } 2877 2878 /* 2879 * plan_c: See if we have an acceptable address on the emit 2880 * interface 2881 */ 2882#ifdef SCTP_DEBUG 2883 if (sctp_debug_on & SCTP_DEBUG_OUTPUT2) { 2884 printf("Plan C no prefered for Dest, acceptable for?\n"); 2885 } 2886#endif 2887 2888 LIST_FOREACH(sctp_ifa, &emit_ifn->ifalist, next_ifa) { 2889 if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0)) 2890 continue; |
2891 pass = sctp_is_ifa_addr_acceptable(sctp_ifa, dest_is_loop, dest_is_priv, fam); 2892 if (pass == NULL) | 2891 sifa = sctp_is_ifa_addr_acceptable(sctp_ifa, dest_is_loop, dest_is_priv, fam); 2892 if (sifa == NULL) |
2893 continue; 2894 if (stcb) { | 2893 continue; 2894 if (stcb) { |
2895 if ((non_asoc_addr_ok == 0) && sctp_is_addr_restricted(stcb, pass)) { | 2895 if ((non_asoc_addr_ok == 0) && sctp_is_addr_restricted(stcb, sifa)) { |
2896 /* 2897 * It is restricted for some reason.. 2898 * probably not yet added. 2899 */ 2900 continue; 2901 } 2902 } | 2896 /* 2897 * It is restricted for some reason.. 2898 * probably not yet added. 2899 */ 2900 continue; 2901 } 2902 } |
2903 atomic_add_int(&pass->refcount, 1); 2904 return (pass); | 2903 atomic_add_int(&sifa->refcount, 1); 2904 return (sifa); |
2905 } 2906 2907 /* 2908 * plan_d: We are in trouble. No prefered address on the emit 2909 * interface. And not even a perfered address on all interfaces. Go 2910 * out and see if we can find an acceptable address somewhere 2911 * amongst all interfaces. 2912 */ --- 9 unchanged lines hidden (view full) --- 2922 } 2923 if ((sctp_ifn == looked_at) && looked_at) 2924 /* already looked at this guy */ 2925 continue; 2926 2927 LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) { 2928 if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0)) 2929 continue; | 2905 } 2906 2907 /* 2908 * plan_d: We are in trouble. No prefered address on the emit 2909 * interface. And not even a perfered address on all interfaces. Go 2910 * out and see if we can find an acceptable address somewhere 2911 * amongst all interfaces. 2912 */ --- 9 unchanged lines hidden (view full) --- 2922 } 2923 if ((sctp_ifn == looked_at) && looked_at) 2924 /* already looked at this guy */ 2925 continue; 2926 2927 LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) { 2928 if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0)) 2929 continue; |
2930 pass = sctp_is_ifa_addr_acceptable(sctp_ifa, dest_is_loop, dest_is_priv, fam); 2931 if (pass == NULL) | 2930 sifa = sctp_is_ifa_addr_acceptable(sctp_ifa, dest_is_loop, dest_is_priv, fam); 2931 if (sifa == NULL) |
2932 continue; 2933 if (stcb) { | 2932 continue; 2933 if (stcb) { |
2934 if ((non_asoc_addr_ok == 0) && sctp_is_addr_restricted(stcb, pass)) { | 2934 if ((non_asoc_addr_ok == 0) && sctp_is_addr_restricted(stcb, sifa)) { |
2935 /* 2936 * It is restricted for some 2937 * reason.. probably not yet added. 2938 */ 2939 continue; 2940 } 2941 } | 2935 /* 2936 * It is restricted for some 2937 * reason.. probably not yet added. 2938 */ 2939 continue; 2940 } 2941 } |
2942 atomic_add_int(&pass->refcount, 1); 2943 return (pass); | 2942 atomic_add_int(&sifa->refcount, 1); 2943 return (sifa); |
2944 } 2945 } 2946 /* 2947 * Ok we can find NO address to source from that is not on our 2948 * negative list and non_asoc_address is NOT ok, or its on our 2949 * negative list. We cant source to it :-( 2950 */ 2951 return (NULL); 2952} 2953 2954 2955 2956/* tcb may be NULL */ 2957struct sctp_ifa * 2958sctp_source_address_selection(struct sctp_inpcb *inp, 2959 struct sctp_tcb *stcb, | 2944 } 2945 } 2946 /* 2947 * Ok we can find NO address to source from that is not on our 2948 * negative list and non_asoc_address is NOT ok, or its on our 2949 * negative list. We cant source to it :-( 2950 */ 2951 return (NULL); 2952} 2953 2954 2955 2956/* tcb may be NULL */ 2957struct sctp_ifa * 2958sctp_source_address_selection(struct sctp_inpcb *inp, 2959 struct sctp_tcb *stcb, |
2960 struct route *ro, | 2960 sctp_route_t * ro, |
2961 struct sctp_nets *net, 2962 int non_asoc_addr_ok, uint32_t vrf_id) 2963{ 2964 2965 struct sockaddr_in *to = (struct sockaddr_in *)&ro->ro_dst; 2966 struct sockaddr_in6 *to6 = (struct sockaddr_in6 *)&ro->ro_dst; 2967 struct sctp_ifa *answer; 2968 uint8_t dest_is_priv, dest_is_loop; --- 424 unchanged lines hidden (view full) --- 3393 3394 struct sctphdr *sctphdr; 3395 int packet_length; 3396 int o_flgs; 3397 uint32_t csum; 3398 int ret; 3399 unsigned int have_mtu; 3400 uint32_t vrf_id; | 2961 struct sctp_nets *net, 2962 int non_asoc_addr_ok, uint32_t vrf_id) 2963{ 2964 2965 struct sockaddr_in *to = (struct sockaddr_in *)&ro->ro_dst; 2966 struct sockaddr_in6 *to6 = (struct sockaddr_in6 *)&ro->ro_dst; 2967 struct sctp_ifa *answer; 2968 uint8_t dest_is_priv, dest_is_loop; --- 424 unchanged lines hidden (view full) --- 3393 3394 struct sctphdr *sctphdr; 3395 int packet_length; 3396 int o_flgs; 3397 uint32_t csum; 3398 int ret; 3399 unsigned int have_mtu; 3400 uint32_t vrf_id; |
3401 struct route *ro; | 3401 sctp_route_t *ro; |
3402 3403 3404 if ((net) && (net->dest_state & SCTP_ADDR_OUT_OF_SCOPE)) { 3405 sctp_m_freem(m); 3406 return (EFAULT); 3407 } 3408 if (stcb == NULL) { | 3402 3403 3404 if ((net) && (net->dest_state & SCTP_ADDR_OUT_OF_SCOPE)) { 3405 sctp_m_freem(m); 3406 return (EFAULT); 3407 } 3408 if (stcb == NULL) { |
3409 vrf_id = SCTP_DEFAULT_VRFID; | 3409 vrf_id = inp->def_vrf_id; |
3410 } else { 3411 vrf_id = stcb->asoc.vrf_id; 3412 } 3413 3414 /* fill in the HMAC digest for any AUTH chunk in the packet */ 3415 if ((auth != NULL) && (stcb != NULL)) { 3416 sctp_fill_hmac_digest_m(m, auth_offset, auth, stcb); 3417 } --- 13 unchanged lines hidden (view full) --- 3431 } else { 3432 sctphdr->checksum = 0; 3433 csum = sctp_calculate_sum(m, &packet_length, 0); 3434 sctphdr->checksum = csum; 3435 } 3436 3437 if (to->sa_family == AF_INET) { 3438 struct ip *ip = NULL; | 3410 } else { 3411 vrf_id = stcb->asoc.vrf_id; 3412 } 3413 3414 /* fill in the HMAC digest for any AUTH chunk in the packet */ 3415 if ((auth != NULL) && (stcb != NULL)) { 3416 sctp_fill_hmac_digest_m(m, auth_offset, auth, stcb); 3417 } --- 13 unchanged lines hidden (view full) --- 3431 } else { 3432 sctphdr->checksum = 0; 3433 csum = sctp_calculate_sum(m, &packet_length, 0); 3434 sctphdr->checksum = csum; 3435 } 3436 3437 if (to->sa_family == AF_INET) { 3438 struct ip *ip = NULL; |
3439 struct route iproute; | 3439 sctp_route_t iproute; |
3440 uint8_t tos_value; 3441 3442 o_pak = SCTP_GET_HEADER_FOR_OUTPUT(sizeof(struct ip)); 3443 if (o_pak == NULL) { 3444 /* failed to prepend data, give up */ 3445 sctp_m_freem(m); 3446 return (ENOMEM); 3447 } --- 38 unchanged lines hidden (view full) --- 3486 } 3487 ip->ip_p = IPPROTO_SCTP; 3488 ip->ip_sum = 0; 3489 if (net == NULL) { 3490 ro = &iproute; 3491 memset(&iproute, 0, sizeof(iproute)); 3492 memcpy(&ro->ro_dst, to, to->sa_len); 3493 } else { | 3440 uint8_t tos_value; 3441 3442 o_pak = SCTP_GET_HEADER_FOR_OUTPUT(sizeof(struct ip)); 3443 if (o_pak == NULL) { 3444 /* failed to prepend data, give up */ 3445 sctp_m_freem(m); 3446 return (ENOMEM); 3447 } --- 38 unchanged lines hidden (view full) --- 3486 } 3487 ip->ip_p = IPPROTO_SCTP; 3488 ip->ip_sum = 0; 3489 if (net == NULL) { 3490 ro = &iproute; 3491 memset(&iproute, 0, sizeof(iproute)); 3492 memcpy(&ro->ro_dst, to, to->sa_len); 3493 } else { |
3494 ro = (struct route *)&net->ro; | 3494 ro = (sctp_route_t *) & net->ro; |
3495 } 3496 /* Now the address selection part */ 3497 ip->ip_dst.s_addr = ((struct sockaddr_in *)to)->sin_addr.s_addr; 3498 3499 /* call the routine to select the src address */ 3500 if (net) { 3501 if (net->src_addr_selected == 0) { 3502 /* Cache the source address */ --- 186 unchanged lines hidden (view full) --- 3689 tmp = *sin6; 3690 sin6 = &tmp; 3691 3692 /* KAME hack: embed scopeid */ 3693 if (sa6_embedscope(sin6, ip6_use_defzone) != 0) 3694 return (EINVAL); 3695 if (net == NULL) { 3696 memset(&ip6route, 0, sizeof(ip6route)); | 3495 } 3496 /* Now the address selection part */ 3497 ip->ip_dst.s_addr = ((struct sockaddr_in *)to)->sin_addr.s_addr; 3498 3499 /* call the routine to select the src address */ 3500 if (net) { 3501 if (net->src_addr_selected == 0) { 3502 /* Cache the source address */ --- 186 unchanged lines hidden (view full) --- 3689 tmp = *sin6; 3690 sin6 = &tmp; 3691 3692 /* KAME hack: embed scopeid */ 3693 if (sa6_embedscope(sin6, ip6_use_defzone) != 0) 3694 return (EINVAL); 3695 if (net == NULL) { 3696 memset(&ip6route, 0, sizeof(ip6route)); |
3697 ro = (struct route *)&ip6route; | 3697 ro = (sctp_route_t *) & ip6route; |
3698 memcpy(&ro->ro_dst, sin6, sin6->sin6_len); 3699 } else { | 3698 memcpy(&ro->ro_dst, sin6, sin6->sin6_len); 3699 } else { |
3700 ro = (struct route *)&net->ro; | 3700 ro = (sctp_route_t *) & net->ro; |
3701 } 3702 if (stcb != NULL) { 3703 if ((stcb->asoc.ecn_allowed) && ecn_ok) { 3704 /* Enable ECN */ 3705 tosBottom = (((((struct in6pcb *)inp)->in6p_flowinfo & 0x0c) | sctp_get_ect(stcb, chk)) << 4); 3706 } else { 3707 /* No ECN */ 3708 tosBottom = ((((struct in6pcb *)inp)->in6p_flowinfo & 0x0c) << 4); --- 386 unchanged lines hidden (view full) --- 4095 m_at = m; 4096 /* now the addresses */ 4097 { 4098 struct sctp_scoping scp; 4099 4100 /* 4101 * To optimize this we could put the scoping stuff into a 4102 * structure and remove the individual uint8's from the | 3701 } 3702 if (stcb != NULL) { 3703 if ((stcb->asoc.ecn_allowed) && ecn_ok) { 3704 /* Enable ECN */ 3705 tosBottom = (((((struct in6pcb *)inp)->in6p_flowinfo & 0x0c) | sctp_get_ect(stcb, chk)) << 4); 3706 } else { 3707 /* No ECN */ 3708 tosBottom = ((((struct in6pcb *)inp)->in6p_flowinfo & 0x0c) << 4); --- 386 unchanged lines hidden (view full) --- 4095 m_at = m; 4096 /* now the addresses */ 4097 { 4098 struct sctp_scoping scp; 4099 4100 /* 4101 * To optimize this we could put the scoping stuff into a 4102 * structure and remove the individual uint8's from the |
4103 * assoc structure. Then we could just pass in the address | 4103 * assoc structure. Then we could just sifa in the address |
4104 * within the stcb.. but for now this is a quick hack to get 4105 * the address stuff teased apart. 4106 */ 4107 scp.ipv4_addr_legal = stcb->asoc.ipv4_addr_legal; 4108 scp.ipv6_addr_legal = stcb->asoc.ipv6_addr_legal; 4109 scp.loopback_scope = stcb->asoc.loopback_scope; 4110 scp.ipv4_local_scope = stcb->asoc.ipv4_local_scope; 4111 scp.local_scope = stcb->asoc.local_scope; --- 7 unchanged lines hidden (view full) --- 4119 p_len = 0; 4120 for (m_at = m; m_at; m_at = SCTP_BUF_NEXT(m_at)) { 4121 if (SCTP_BUF_NEXT(m_at) == NULL) 4122 m_last = m_at; 4123 p_len += SCTP_BUF_LEN(m_at); 4124 } 4125 initm->msg.ch.chunk_length = htons((p_len - sizeof(struct sctphdr))); 4126 /* | 4104 * within the stcb.. but for now this is a quick hack to get 4105 * the address stuff teased apart. 4106 */ 4107 scp.ipv4_addr_legal = stcb->asoc.ipv4_addr_legal; 4108 scp.ipv6_addr_legal = stcb->asoc.ipv6_addr_legal; 4109 scp.loopback_scope = stcb->asoc.loopback_scope; 4110 scp.ipv4_local_scope = stcb->asoc.ipv4_local_scope; 4111 scp.local_scope = stcb->asoc.local_scope; --- 7 unchanged lines hidden (view full) --- 4119 p_len = 0; 4120 for (m_at = m; m_at; m_at = SCTP_BUF_NEXT(m_at)) { 4121 if (SCTP_BUF_NEXT(m_at) == NULL) 4122 m_last = m_at; 4123 p_len += SCTP_BUF_LEN(m_at); 4124 } 4125 initm->msg.ch.chunk_length = htons((p_len - sizeof(struct sctphdr))); 4126 /* |
4127 * We pass 0 here to NOT set IP_DF if its IPv4, we ignore the return | 4127 * We sifa 0 here to NOT set IP_DF if its IPv4, we ignore the return |
4128 * here since the timer will drive a retranmission. 4129 */ 4130 4131 /* I don't expect this to execute but we will be safe here */ 4132 padval = p_len % 4; 4133 if ((padval) && (m_last)) { 4134 /* 4135 * The compiler worries that m_last may not be set even --- 382 unchanged lines hidden (view full) --- 4518 struct sctp_init_msg *initackm_out; 4519 struct sctp_ecn_supported_param *ecn; 4520 struct sctp_prsctp_supported_param *prsctp; 4521 struct sctp_ecn_nonce_supported_param *ecn_nonce; 4522 struct sctp_supported_chunk_types_param *pr_supported; 4523 struct sockaddr_storage store; 4524 struct sockaddr_in *sin; 4525 struct sockaddr_in6 *sin6; | 4128 * here since the timer will drive a retranmission. 4129 */ 4130 4131 /* I don't expect this to execute but we will be safe here */ 4132 padval = p_len % 4; 4133 if ((padval) && (m_last)) { 4134 /* 4135 * The compiler worries that m_last may not be set even --- 382 unchanged lines hidden (view full) --- 4518 struct sctp_init_msg *initackm_out; 4519 struct sctp_ecn_supported_param *ecn; 4520 struct sctp_prsctp_supported_param *prsctp; 4521 struct sctp_ecn_nonce_supported_param *ecn_nonce; 4522 struct sctp_supported_chunk_types_param *pr_supported; 4523 struct sockaddr_storage store; 4524 struct sockaddr_in *sin; 4525 struct sockaddr_in6 *sin6; |
4526 struct route *ro; | 4526 sctp_route_t *ro; |
4527 struct ip *iph; 4528 struct ip6_hdr *ip6; 4529 struct sockaddr *to; 4530 struct sctp_state_cookie stc; 4531 struct sctp_nets *net = NULL; 4532 int cnt_inits_to = 0; 4533 uint16_t his_limit, i_want; 4534 int abort_flag, padval, sz_of; 4535 int num_ext; 4536 int p_len; 4537 uint32_t vrf_id; 4538 | 4527 struct ip *iph; 4528 struct ip6_hdr *ip6; 4529 struct sockaddr *to; 4530 struct sctp_state_cookie stc; 4531 struct sctp_nets *net = NULL; 4532 int cnt_inits_to = 0; 4533 uint16_t his_limit, i_want; 4534 int abort_flag, padval, sz_of; 4535 int num_ext; 4536 int p_len; 4537 uint32_t vrf_id; 4538 |
4539 vrf_id = SCTP_DEFAULT_VRFID; | |
4540 if (stcb) { 4541 asoc = &stcb->asoc; | 4539 if (stcb) { 4540 asoc = &stcb->asoc; |
4541 vrf_id = asoc->vrf_id; |
|
4542 } else { | 4542 } else { |
4543 vrf_id = inp->def_vrf_id; |
|
4543 asoc = NULL; 4544 } 4545 m_last = NULL; 4546 if ((asoc != NULL) && 4547 (SCTP_GET_STATE(asoc) != SCTP_STATE_COOKIE_WAIT) && 4548 (sctp_are_there_new_addresses(asoc, init_pkt, iphlen, offset))) { 4549 /* new addresses, out of here in non-cookie-wait states */ 4550 /* --- 75 unchanged lines hidden (view full) --- 4626 memset((caddr_t)&store, 0, sizeof(store)); 4627 sin = (struct sockaddr_in *)&store; 4628 sin6 = (struct sockaddr_in6 *)&store; 4629 if (net == NULL) { 4630 to = (struct sockaddr *)&store; 4631 iph = mtod(init_pkt, struct ip *); 4632 if (iph->ip_v == IPVERSION) { 4633 struct sctp_ifa *addr; | 4544 asoc = NULL; 4545 } 4546 m_last = NULL; 4547 if ((asoc != NULL) && 4548 (SCTP_GET_STATE(asoc) != SCTP_STATE_COOKIE_WAIT) && 4549 (sctp_are_there_new_addresses(asoc, init_pkt, iphlen, offset))) { 4550 /* new addresses, out of here in non-cookie-wait states */ 4551 /* --- 75 unchanged lines hidden (view full) --- 4627 memset((caddr_t)&store, 0, sizeof(store)); 4628 sin = (struct sockaddr_in *)&store; 4629 sin6 = (struct sockaddr_in6 *)&store; 4630 if (net == NULL) { 4631 to = (struct sockaddr *)&store; 4632 iph = mtod(init_pkt, struct ip *); 4633 if (iph->ip_v == IPVERSION) { 4634 struct sctp_ifa *addr; |
4634 struct route iproute; | 4635 sctp_route_t iproute; |
4635 4636 sin->sin_family = AF_INET; 4637 sin->sin_len = sizeof(struct sockaddr_in); 4638 sin->sin_port = sh->src_port; 4639 sin->sin_addr = iph->ip_src; 4640 /* lookup address */ 4641 stc.address[0] = sin->sin_addr.s_addr; 4642 stc.address[1] = 0; --- 85 unchanged lines hidden (view full) --- 4728 /* 4729 * If the new destination is SITE_LOCAL then 4730 * we must have site scope in common. 4731 */ 4732 stc.site_scope = 1; 4733 } 4734 /* local from address */ 4735 memset(&iproute6, 0, sizeof(iproute6)); | 4636 4637 sin->sin_family = AF_INET; 4638 sin->sin_len = sizeof(struct sockaddr_in); 4639 sin->sin_port = sh->src_port; 4640 sin->sin_addr = iph->ip_src; 4641 /* lookup address */ 4642 stc.address[0] = sin->sin_addr.s_addr; 4643 stc.address[1] = 0; --- 85 unchanged lines hidden (view full) --- 4729 /* 4730 * If the new destination is SITE_LOCAL then 4731 * we must have site scope in common. 4732 */ 4733 stc.site_scope = 1; 4734 } 4735 /* local from address */ 4736 memset(&iproute6, 0, sizeof(iproute6)); |
4736 ro = (struct route *)&iproute6; | 4737 ro = (sctp_route_t *) & iproute6; |
4737 memcpy(&ro->ro_dst, sin6, sizeof(*sin6)); 4738 addr = sctp_source_address_selection(inp, NULL, 4739 ro, NULL, 0, vrf_id); 4740 if (addr == NULL) 4741 return; 4742 4743 if (ro->ro_rt) { 4744 RTFREE(ro->ro_rt); --- 32 unchanged lines hidden (view full) --- 4777 stc.address[3] = 0; 4778 stc.addr_type = SCTP_IPV4_ADDRESS; 4779 if (net->src_addr_selected == 0) { 4780 /* 4781 * strange case here, the INIT should have 4782 * did the selection. 4783 */ 4784 net->ro._s_addr = sctp_source_address_selection(inp, | 4738 memcpy(&ro->ro_dst, sin6, sizeof(*sin6)); 4739 addr = sctp_source_address_selection(inp, NULL, 4740 ro, NULL, 0, vrf_id); 4741 if (addr == NULL) 4742 return; 4743 4744 if (ro->ro_rt) { 4745 RTFREE(ro->ro_rt); --- 32 unchanged lines hidden (view full) --- 4778 stc.address[3] = 0; 4779 stc.addr_type = SCTP_IPV4_ADDRESS; 4780 if (net->src_addr_selected == 0) { 4781 /* 4782 * strange case here, the INIT should have 4783 * did the selection. 4784 */ 4785 net->ro._s_addr = sctp_source_address_selection(inp, |
4785 stcb, (struct route *)&net->ro, | 4786 stcb, (sctp_route_t *) & net->ro, |
4786 net, 0, vrf_id); 4787 if (net->ro._s_addr == NULL) 4788 return; 4789 4790 net->src_addr_selected = 1; 4791 4792 } 4793 stc.laddress[0] = net->ro._s_addr->address.sin.sin_addr.s_addr; --- 7 unchanged lines hidden (view full) --- 4801 sizeof(struct in6_addr)); 4802 stc.addr_type = SCTP_IPV6_ADDRESS; 4803 if (net->src_addr_selected == 0) { 4804 /* 4805 * strange case here, the INIT should have 4806 * did the selection. 4807 */ 4808 net->ro._s_addr = sctp_source_address_selection(inp, | 4787 net, 0, vrf_id); 4788 if (net->ro._s_addr == NULL) 4789 return; 4790 4791 net->src_addr_selected = 1; 4792 4793 } 4794 stc.laddress[0] = net->ro._s_addr->address.sin.sin_addr.s_addr; --- 7 unchanged lines hidden (view full) --- 4802 sizeof(struct in6_addr)); 4803 stc.addr_type = SCTP_IPV6_ADDRESS; 4804 if (net->src_addr_selected == 0) { 4805 /* 4806 * strange case here, the INIT should have 4807 * did the selection. 4808 */ 4809 net->ro._s_addr = sctp_source_address_selection(inp, |
4809 stcb, (struct route *)&net->ro, | 4810 stcb, (sctp_route_t *) & net->ro, |
4810 net, 0, vrf_id); 4811 if (net->ro._s_addr == NULL) 4812 return; 4813 4814 net->src_addr_selected = 1; 4815 } 4816 memcpy(&stc.laddress, &net->ro._s_addr->address.sin6.sin6_addr, 4817 sizeof(struct in6_addr)); --- 176 unchanged lines hidden (view full) --- 4994 m_at = m; 4995 /* now the addresses */ 4996 { 4997 struct sctp_scoping scp; 4998 4999 /* 5000 * To optimize this we could put the scoping stuff into a 5001 * structure and remove the individual uint8's from the stc | 4811 net, 0, vrf_id); 4812 if (net->ro._s_addr == NULL) 4813 return; 4814 4815 net->src_addr_selected = 1; 4816 } 4817 memcpy(&stc.laddress, &net->ro._s_addr->address.sin6.sin6_addr, 4818 sizeof(struct in6_addr)); --- 176 unchanged lines hidden (view full) --- 4995 m_at = m; 4996 /* now the addresses */ 4997 { 4998 struct sctp_scoping scp; 4999 5000 /* 5001 * To optimize this we could put the scoping stuff into a 5002 * structure and remove the individual uint8's from the stc |
5002 * structure. Then we could just pass in the address within | 5003 * structure. Then we could just sifa in the address within |
5003 * the stc.. but for now this is a quick hack to get the 5004 * address stuff teased apart. 5005 */ 5006 scp.ipv4_addr_legal = stc.ipv4_addr_legal; 5007 scp.ipv6_addr_legal = stc.ipv6_addr_legal; 5008 scp.loopback_scope = stc.loopback_scope; 5009 scp.ipv4_local_scope = stc.ipv4_scope; 5010 scp.local_scope = stc.local_scope; --- 77 unchanged lines hidden (view full) --- 5088 if (SCTP_BUF_NEXT(m_tmp) == NULL) { 5089 /* m_tmp should now point to last one */ 5090 m_last = m_tmp; 5091 break; 5092 } 5093 } 5094 5095 /* | 5004 * the stc.. but for now this is a quick hack to get the 5005 * address stuff teased apart. 5006 */ 5007 scp.ipv4_addr_legal = stc.ipv4_addr_legal; 5008 scp.ipv6_addr_legal = stc.ipv6_addr_legal; 5009 scp.loopback_scope = stc.loopback_scope; 5010 scp.ipv4_local_scope = stc.ipv4_scope; 5011 scp.local_scope = stc.local_scope; --- 77 unchanged lines hidden (view full) --- 5089 if (SCTP_BUF_NEXT(m_tmp) == NULL) { 5090 /* m_tmp should now point to last one */ 5091 m_last = m_tmp; 5092 break; 5093 } 5094 } 5095 5096 /* |
5096 * We pass 0 here to NOT set IP_DF if its IPv4, we ignore the return | 5097 * We sifa 0 here to NOT set IP_DF if its IPv4, we ignore the return |
5097 * here since the timer will drive a retranmission. 5098 */ 5099 padval = p_len % 4; 5100 if ((padval) && (m_last)) { 5101 /* see my previous comments on m_last */ 5102 int ret; 5103 5104 ret = sctp_add_pad_tombuf(m_last, (4 - padval)); --- 310 unchanged lines hidden (view full) --- 5415 sp->msg_is_complete = 1; 5416 sp->some_taken = 0; 5417 sp->data = m; 5418 sp->tail_mbuf = NULL; 5419 sp->length = 0; 5420 at = m; 5421 sctp_set_prsctp_policy(stcb, sp); 5422 /* | 5098 * here since the timer will drive a retranmission. 5099 */ 5100 padval = p_len % 4; 5101 if ((padval) && (m_last)) { 5102 /* see my previous comments on m_last */ 5103 int ret; 5104 5105 ret = sctp_add_pad_tombuf(m_last, (4 - padval)); --- 310 unchanged lines hidden (view full) --- 5416 sp->msg_is_complete = 1; 5417 sp->some_taken = 0; 5418 sp->data = m; 5419 sp->tail_mbuf = NULL; 5420 sp->length = 0; 5421 at = m; 5422 sctp_set_prsctp_policy(stcb, sp); 5423 /* |
5423 * We could in theory (for sendall) pass the length in, but we would | 5424 * We could in theory (for sendall) sifa the length in, but we would |
5424 * still have to hunt through the chain since we need to setup the 5425 * tail_mbuf 5426 */ 5427 while (at) { 5428 if (SCTP_BUF_NEXT(at) == NULL) 5429 sp->tail_mbuf = at; 5430 sp->length += SCTP_BUF_LEN(at); 5431 at = SCTP_BUF_NEXT(at); --- 3832 unchanged lines hidden (view full) --- 9264 9265 /* add checksum */ 9266 if ((sctp_no_csum_on_loopback) && SCTP_IS_IT_LOOPBACK(o_pak)) { 9267 comp_cp->sh.checksum = 0; 9268 } else { 9269 comp_cp->sh.checksum = sctp_calculate_sum(mout, NULL, offset_out); 9270 } 9271 if (iph_out != NULL) { | 5425 * still have to hunt through the chain since we need to setup the 5426 * tail_mbuf 5427 */ 5428 while (at) { 5429 if (SCTP_BUF_NEXT(at) == NULL) 5430 sp->tail_mbuf = at; 5431 sp->length += SCTP_BUF_LEN(at); 5432 at = SCTP_BUF_NEXT(at); --- 3832 unchanged lines hidden (view full) --- 9265 9266 /* add checksum */ 9267 if ((sctp_no_csum_on_loopback) && SCTP_IS_IT_LOOPBACK(o_pak)) { 9268 comp_cp->sh.checksum = 0; 9269 } else { 9270 comp_cp->sh.checksum = sctp_calculate_sum(mout, NULL, offset_out); 9271 } 9272 if (iph_out != NULL) { |
9272 struct route ro; | 9273 sctp_route_t ro; |
9273 9274 bzero(&ro, sizeof ro); 9275 /* set IPv4 length */ 9276 iph_out->ip_len = SCTP_HEADER_LEN(o_pak); 9277 /* out it goes */ 9278 ip_output(o_pak, 0, &ro, IP_RAWOUTPUT, NULL 9279 ,NULL 9280 ); --- 835 unchanged lines hidden (view full) --- 10116 10117 /* add checksum */ 10118 if ((sctp_no_csum_on_loopback) && SCTP_IS_IT_LOOPBACK(m)) { 10119 abm->sh.checksum = 0; 10120 } else { 10121 abm->sh.checksum = sctp_calculate_sum(mout, NULL, iphlen_out); 10122 } 10123 if (iph_out != NULL) { | 9274 9275 bzero(&ro, sizeof ro); 9276 /* set IPv4 length */ 9277 iph_out->ip_len = SCTP_HEADER_LEN(o_pak); 9278 /* out it goes */ 9279 ip_output(o_pak, 0, &ro, IP_RAWOUTPUT, NULL 9280 ,NULL 9281 ); --- 835 unchanged lines hidden (view full) --- 10117 10118 /* add checksum */ 10119 if ((sctp_no_csum_on_loopback) && SCTP_IS_IT_LOOPBACK(m)) { 10120 abm->sh.checksum = 0; 10121 } else { 10122 abm->sh.checksum = sctp_calculate_sum(mout, NULL, iphlen_out); 10123 } 10124 if (iph_out != NULL) { |
10124 struct route ro; | 10125 sctp_route_t ro; |
10125 10126 /* zap the stack pointer to the route */ 10127 bzero(&ro, sizeof ro); 10128#ifdef SCTP_DEBUG 10129 if (sctp_debug_on & SCTP_DEBUG_OUTPUT2) { 10130 printf("sctp_send_abort calling ip_output:\n"); 10131 sctp_print_address_pkt(iph_out, &abm->sh); 10132 } --- 88 unchanged lines hidden (view full) --- 10221 val = 0; 10222 } else { 10223 val = sctp_calculate_sum(scm, NULL, 0); 10224 } 10225 ohdr->checksum = val; 10226 if (iph->ip_v == IPVERSION) { 10227 /* V4 */ 10228 struct ip *out; | 10126 10127 /* zap the stack pointer to the route */ 10128 bzero(&ro, sizeof ro); 10129#ifdef SCTP_DEBUG 10130 if (sctp_debug_on & SCTP_DEBUG_OUTPUT2) { 10131 printf("sctp_send_abort calling ip_output:\n"); 10132 sctp_print_address_pkt(iph_out, &abm->sh); 10133 } --- 88 unchanged lines hidden (view full) --- 10222 val = 0; 10223 } else { 10224 val = sctp_calculate_sum(scm, NULL, 0); 10225 } 10226 ohdr->checksum = val; 10227 if (iph->ip_v == IPVERSION) { 10228 /* V4 */ 10229 struct ip *out; |
10229 struct route ro; | 10230 sctp_route_t ro; |
10230 10231 o_pak = SCTP_GET_HEADER_FOR_OUTPUT(sizeof(struct ip)); 10232 if (o_pak == NULL) { 10233 sctp_m_freem(scm); 10234 return; 10235 } 10236 SCTP_BUF_LEN(SCTP_HEADER_TO_CHAIN(o_pak)) = sizeof(struct ip); 10237 len += sizeof(struct ip); --- 295 unchanged lines hidden (view full) --- 10533 if (control) { 10534 /* process cmsg snd/rcv info (maybe a assoc-id) */ 10535 if (sctp_find_cmsg(SCTP_SNDRCV, (void *)&srcv, control, 10536 sizeof(srcv))) { 10537 /* got one */ 10538 use_rcvinfo = 1; 10539 } 10540 } | 10231 10232 o_pak = SCTP_GET_HEADER_FOR_OUTPUT(sizeof(struct ip)); 10233 if (o_pak == NULL) { 10234 sctp_m_freem(scm); 10235 return; 10236 } 10237 SCTP_BUF_LEN(SCTP_HEADER_TO_CHAIN(o_pak)) = sizeof(struct ip); 10238 len += sizeof(struct ip); --- 295 unchanged lines hidden (view full) --- 10534 if (control) { 10535 /* process cmsg snd/rcv info (maybe a assoc-id) */ 10536 if (sctp_find_cmsg(SCTP_SNDRCV, (void *)&srcv, control, 10537 sizeof(srcv))) { 10538 /* got one */ 10539 use_rcvinfo = 1; 10540 } 10541 } |
10541 error = sctp_lower_sosend(so, addr, uio, top, control, flags, 10542 use_rcvinfo, &srcv, p); | 10542 error = sctp_lower_sosend(so, addr, uio, top, 10543 control, 10544 flags, 10545 use_rcvinfo, &srcv 10546 ,p 10547 ); |
10543 return (error); 10544} 10545 10546 10547int 10548sctp_lower_sosend(struct socket *so, 10549 struct sockaddr *addr, 10550 struct uio *uio, --- 155 unchanged lines hidden (view full) --- 10706 } else if (addr == NULL) { 10707 error = ENOENT; 10708 goto out_unlocked; 10709 } else { 10710 /* 10711 * UDP style, we must go ahead and start the INIT 10712 * process 10713 */ | 10548 return (error); 10549} 10550 10551 10552int 10553sctp_lower_sosend(struct socket *so, 10554 struct sockaddr *addr, 10555 struct uio *uio, --- 155 unchanged lines hidden (view full) --- 10711 } else if (addr == NULL) { 10712 error = ENOENT; 10713 goto out_unlocked; 10714 } else { 10715 /* 10716 * UDP style, we must go ahead and start the INIT 10717 * process 10718 */ |
10714 uint32_t vrf; | 10719 uint32_t vrf_id; |
10715 10716 if ((use_rcvinfo) && (srcv) && 10717 ((srcv->sinfo_flags & SCTP_ABORT) || 10718 ((srcv->sinfo_flags & SCTP_EOF) && 10719 (uio->uio_resid == 0)))) { 10720 /*- 10721 * User asks to abort a non-existant assoc, 10722 * or EOF a non-existant assoc with no data 10723 */ 10724 error = ENOENT; 10725 goto out_unlocked; 10726 } 10727 /* get an asoc/stcb struct */ | 10720 10721 if ((use_rcvinfo) && (srcv) && 10722 ((srcv->sinfo_flags & SCTP_ABORT) || 10723 ((srcv->sinfo_flags & SCTP_EOF) && 10724 (uio->uio_resid == 0)))) { 10725 /*- 10726 * User asks to abort a non-existant assoc, 10727 * or EOF a non-existant assoc with no data 10728 */ 10729 error = ENOENT; 10730 goto out_unlocked; 10731 } 10732 /* get an asoc/stcb struct */ |
10728 vrf = SCTP_DEFAULT_VRFID; 10729 stcb = sctp_aloc_assoc(inp, addr, 1, &error, 0, vrf); | 10733 10734 vrf_id = inp->def_vrf_id; 10735 stcb = sctp_aloc_assoc(inp, addr, 1, &error, 0, vrf_id); |
10730 if (stcb == NULL) { 10731 /* Error is setup for us in the call */ 10732 goto out_unlocked; 10733 } 10734 if (create_lock_applied) { 10735 SCTP_ASOC_CREATE_UNLOCK(inp); 10736 create_lock_applied = 0; 10737 } else { --- 978 unchanged lines hidden --- | 10736 if (stcb == NULL) { 10737 /* Error is setup for us in the call */ 10738 goto out_unlocked; 10739 } 10740 if (create_lock_applied) { 10741 SCTP_ASOC_CREATE_UNLOCK(inp); 10742 create_lock_applied = 0; 10743 } else { --- 978 unchanged lines hidden --- |