Deleted Added
full compact
sctp_pcb.c (207924) sctp_pcb.c (208160)
1/*-
2 * Copyright (c) 2001-2008, by 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_pcb.c,v 1.38 2005/03/06 16:04:18 itojun Exp $ */
32
33#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2001-2008, by 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_pcb.c,v 1.38 2005/03/06 16:04:18 itojun Exp $ */
32
33#include <sys/cdefs.h>
34__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.c 207924 2010-05-11 17:02:29Z rrs $");
34__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.c 208160 2010-05-16 17:03:56Z 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_pcb.h>
41#include <netinet/sctputil.h>
42#include <netinet/sctp.h>

--- 644 unchanged lines hidden (view full) ---

687 if_name);
688 return (NULL);
689 }
690 SCTP_INCR_LADDR_COUNT();
691 bzero(wi, sizeof(*wi));
692 (void)SCTP_GETTIME_TIMEVAL(&wi->start_time);
693 wi->ifa = sctp_ifap;
694 wi->action = SCTP_ADD_IP_ADDRESS;
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_pcb.h>
41#include <netinet/sctputil.h>
42#include <netinet/sctp.h>

--- 644 unchanged lines hidden (view full) ---

687 if_name);
688 return (NULL);
689 }
690 SCTP_INCR_LADDR_COUNT();
691 bzero(wi, sizeof(*wi));
692 (void)SCTP_GETTIME_TIMEVAL(&wi->start_time);
693 wi->ifa = sctp_ifap;
694 wi->action = SCTP_ADD_IP_ADDRESS;
695 SCTP_IPI_ITERATOR_WQ_LOCK();
696 /*
697 * Should this really be a tailq? As it is we will process
698 * the newest first :-0
699 */
695
696 SCTP_WQ_ADDR_LOCK();
700 LIST_INSERT_HEAD(&SCTP_BASE_INFO(addr_wq), wi, sctp_nxt_addr);
697 LIST_INSERT_HEAD(&SCTP_BASE_INFO(addr_wq), wi, sctp_nxt_addr);
701 SCTP_IPI_ITERATOR_WQ_UNLOCK();
698 SCTP_WQ_ADDR_UNLOCK();
699
702 sctp_timer_start(SCTP_TIMER_TYPE_ADDR_WQ,
703 (struct sctp_inpcb *)NULL,
704 (struct sctp_tcb *)NULL,
705 (struct sctp_nets *)NULL);
706 } else {
707 /* it's ready for use */
708 sctp_ifap->localifa_flags &= ~SCTP_ADDR_DEFER_USE;
709 }

--- 91 unchanged lines hidden (view full) ---

801 sctp_free_ifa(sctp_ifap);
802 return;
803 }
804 SCTP_INCR_LADDR_COUNT();
805 bzero(wi, sizeof(*wi));
806 (void)SCTP_GETTIME_TIMEVAL(&wi->start_time);
807 wi->ifa = sctp_ifap;
808 wi->action = SCTP_DEL_IP_ADDRESS;
700 sctp_timer_start(SCTP_TIMER_TYPE_ADDR_WQ,
701 (struct sctp_inpcb *)NULL,
702 (struct sctp_tcb *)NULL,
703 (struct sctp_nets *)NULL);
704 } else {
705 /* it's ready for use */
706 sctp_ifap->localifa_flags &= ~SCTP_ADDR_DEFER_USE;
707 }

--- 91 unchanged lines hidden (view full) ---

799 sctp_free_ifa(sctp_ifap);
800 return;
801 }
802 SCTP_INCR_LADDR_COUNT();
803 bzero(wi, sizeof(*wi));
804 (void)SCTP_GETTIME_TIMEVAL(&wi->start_time);
805 wi->ifa = sctp_ifap;
806 wi->action = SCTP_DEL_IP_ADDRESS;
809 SCTP_IPI_ITERATOR_WQ_LOCK();
807 SCTP_WQ_ADDR_LOCK();
810 /*
811 * Should this really be a tailq? As it is we will process
812 * the newest first :-0
813 */
814 LIST_INSERT_HEAD(&SCTP_BASE_INFO(addr_wq), wi, sctp_nxt_addr);
808 /*
809 * Should this really be a tailq? As it is we will process
810 * the newest first :-0
811 */
812 LIST_INSERT_HEAD(&SCTP_BASE_INFO(addr_wq), wi, sctp_nxt_addr);
815 SCTP_IPI_ITERATOR_WQ_UNLOCK();
813 SCTP_WQ_ADDR_UNLOCK();
816
817 sctp_timer_start(SCTP_TIMER_TYPE_ADDR_WQ,
818 (struct sctp_inpcb *)NULL,
819 (struct sctp_tcb *)NULL,
820 (struct sctp_nets *)NULL);
821 }
822 return;
823}

--- 2188 unchanged lines hidden (view full) ---

3012 inp->sctp_flags &= ~SCTP_PCB_FLAGS_UNBOUND;
3013 SCTP_INP_WUNLOCK(inp);
3014 SCTP_INP_INFO_WUNLOCK();
3015 return (0);
3016}
3017
3018
3019static void
814
815 sctp_timer_start(SCTP_TIMER_TYPE_ADDR_WQ,
816 (struct sctp_inpcb *)NULL,
817 (struct sctp_tcb *)NULL,
818 (struct sctp_nets *)NULL);
819 }
820 return;
821}

--- 2188 unchanged lines hidden (view full) ---

3010 inp->sctp_flags &= ~SCTP_PCB_FLAGS_UNBOUND;
3011 SCTP_INP_WUNLOCK(inp);
3012 SCTP_INP_INFO_WUNLOCK();
3013 return (0);
3014}
3015
3016
3017static void
3020sctp_iterator_inp_being_freed(struct sctp_inpcb *inp, struct sctp_inpcb *inp_next)
3018sctp_iterator_inp_being_freed(struct sctp_inpcb *inp)
3021{
3019{
3022 struct sctp_iterator *it;
3020 struct sctp_iterator *it, *nit;
3023
3024 /*
3025 * We enter with the only the ITERATOR_LOCK in place and a write
3026 * lock on the inp_info stuff.
3027 */
3021
3022 /*
3023 * We enter with the only the ITERATOR_LOCK in place and a write
3024 * lock on the inp_info stuff.
3025 */
3028
3026 it = sctp_it_ctl.cur_it;
3027 if (it && (it->vn != curvnet)) {
3028 /* Its not looking at our VNET */
3029 return;
3030 }
3031 if (it && (it->inp == inp)) {
3032 /*
3033 * This is tricky and we hold the iterator lock, but when it
3034 * returns and gets the lock (when we release it) the
3035 * iterator will try to operate on inp. We need to stop that
3036 * from happening. But of course the iterator has a
3037 * reference on the stcb and inp. We can mark it and it will
3038 * stop.
3039 *
3040 * If its a single iterator situation, we set the end iterator
3041 * flag. Otherwise we set the iterator to go to the next
3042 * inp.
3043 *
3044 */
3045 if (it->iterator_flags & SCTP_ITERATOR_DO_SINGLE_INP) {
3046 sctp_it_ctl.iterator_flags |= SCTP_ITERATOR_STOP_CUR_IT;
3047 } else {
3048 sctp_it_ctl.iterator_flags |= SCTP_ITERATOR_STOP_CUR_INP;
3049 }
3050 }
3029 /*
3051 /*
3030 * Go through all iterators, we must do this since it is possible
3031 * that some iterator does NOT have the lock, but is waiting for it.
3032 * And the one that had the lock has either moved in the last
3033 * iteration or we just cleared it above. We need to find all of
3034 * those guys. The list of iterators should never be very big
3035 * though.
3052 * Now go through and remove any single reference to our inp that
3053 * may be still pending on the list
3036 */
3054 */
3037 TAILQ_FOREACH(it, &SCTP_BASE_INFO(iteratorhead), sctp_nxt_itr) {
3038 if (it == inp->inp_starting_point_for_iterator)
3039 /* skip this guy, he's special */
3055 SCTP_IPI_ITERATOR_WQ_LOCK();
3056 it = TAILQ_FIRST(&sctp_it_ctl.iteratorhead);
3057 while (it) {
3058 nit = TAILQ_NEXT(it, sctp_nxt_itr);
3059 if (it->vn != curvnet) {
3060 it = nit;
3040 continue;
3061 continue;
3062 }
3041 if (it->inp == inp) {
3063 if (it->inp == inp) {
3042 /*
3043 * This is tricky and we DON'T lock the iterator.
3044 * Reason is he's running but waiting for me since
3045 * inp->inp_starting_point_for_iterator has the lock
3046 * on me (the guy above we skipped). This tells us
3047 * its is not running but waiting for
3048 * inp->inp_starting_point_for_iterator to be
3049 * released by the guy that does have our INP in a
3050 * lock.
3051 */
3064 /* This one points to me is it inp specific? */
3052 if (it->iterator_flags & SCTP_ITERATOR_DO_SINGLE_INP) {
3065 if (it->iterator_flags & SCTP_ITERATOR_DO_SINGLE_INP) {
3053 it->inp = NULL;
3054 it->stcb = NULL;
3066 /* Remove and free this one */
3067 TAILQ_REMOVE(&sctp_it_ctl.iteratorhead,
3068 it, sctp_nxt_itr);
3069 if (it->function_atend != NULL) {
3070 (*it->function_atend) (it->pointer, it->val);
3071 }
3072 SCTP_FREE(it, SCTP_M_ITER);
3055 } else {
3073 } else {
3056 /* set him up to do the next guy not me */
3057 it->inp = inp_next;
3058 it->stcb = NULL;
3074 it->inp = LIST_NEXT(it->inp, sctp_list);
3059 }
3060 }
3075 }
3076 }
3077 it = nit;
3061 }
3078 }
3062 it = inp->inp_starting_point_for_iterator;
3063 if (it) {
3064 if (it->iterator_flags & SCTP_ITERATOR_DO_SINGLE_INP) {
3065 it->inp = NULL;
3066 } else {
3067 it->inp = inp_next;
3068 }
3069 it->stcb = NULL;
3070 }
3079 SCTP_IPI_ITERATOR_WQ_UNLOCK();
3071}
3072
3073/* release sctp_inpcb unbind the port */
3074void
3075sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from)
3076{
3077 /*
3078 * Here we free a endpoint. We must find it (if it is in the Hash
3079 * table) and remove it from there. Then we must also find it in the
3080 * overall list and remove it from there. After all removals are
3081 * complete then any timer has to be stopped. Then start the actual
3082 * freeing. a) Any local lists. b) Any associations. c) The hash of
3083 * all associations. d) finally the ep itself.
3084 */
3085 struct sctp_pcb *m;
3080}
3081
3082/* release sctp_inpcb unbind the port */
3083void
3084sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from)
3085{
3086 /*
3087 * Here we free a endpoint. We must find it (if it is in the Hash
3088 * table) and remove it from there. Then we must also find it in the
3089 * overall list and remove it from there. After all removals are
3090 * complete then any timer has to be stopped. Then start the actual
3091 * freeing. a) Any local lists. b) Any associations. c) The hash of
3092 * all associations. d) finally the ep itself.
3093 */
3094 struct sctp_pcb *m;
3086 struct sctp_inpcb *inp_save;
3087 struct sctp_tcb *asoc, *nasoc;
3088 struct sctp_laddr *laddr, *nladdr;
3089 struct inpcb *ip_pcb;
3090 struct socket *so;
3091
3092 struct sctp_queued_to_read *sq;
3093
3094
3095 int cnt;
3096 sctp_sharedkey_t *shared_key;
3097
3098
3099#ifdef SCTP_LOG_CLOSING
3100 sctp_log_closing(inp, NULL, 0);
3101#endif
3102 SCTP_ITERATOR_LOCK();
3095 struct sctp_tcb *asoc, *nasoc;
3096 struct sctp_laddr *laddr, *nladdr;
3097 struct inpcb *ip_pcb;
3098 struct socket *so;
3099
3100 struct sctp_queued_to_read *sq;
3101
3102
3103 int cnt;
3104 sctp_sharedkey_t *shared_key;
3105
3106
3107#ifdef SCTP_LOG_CLOSING
3108 sctp_log_closing(inp, NULL, 0);
3109#endif
3110 SCTP_ITERATOR_LOCK();
3111
3103 so = inp->sctp_socket;
3104 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) {
3105 /* been here before.. eeks.. get out of here */
3106 SCTP_PRINTF("This conflict in free SHOULD not be happening! from %d, imm %d\n", from, immediate);
3107 SCTP_ITERATOR_UNLOCK();
3108#ifdef SCTP_LOG_CLOSING
3109 sctp_log_closing(inp, NULL, 1);
3110#endif

--- 10 unchanged lines hidden (view full) ---

3121 * passed from the actual closing routines that are called
3122 * via the sockets layer.
3123 */
3124 inp->sctp_flags &= ~SCTP_PCB_FLAGS_CLOSE_IP;
3125 /* socket is gone, so no more wakeups allowed */
3126 inp->sctp_flags |= SCTP_PCB_FLAGS_DONT_WAKE;
3127 inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAKEINPUT;
3128 inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAKEOUTPUT;
3112 so = inp->sctp_socket;
3113 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) {
3114 /* been here before.. eeks.. get out of here */
3115 SCTP_PRINTF("This conflict in free SHOULD not be happening! from %d, imm %d\n", from, immediate);
3116 SCTP_ITERATOR_UNLOCK();
3117#ifdef SCTP_LOG_CLOSING
3118 sctp_log_closing(inp, NULL, 1);
3119#endif

--- 10 unchanged lines hidden (view full) ---

3130 * passed from the actual closing routines that are called
3131 * via the sockets layer.
3132 */
3133 inp->sctp_flags &= ~SCTP_PCB_FLAGS_CLOSE_IP;
3134 /* socket is gone, so no more wakeups allowed */
3135 inp->sctp_flags |= SCTP_PCB_FLAGS_DONT_WAKE;
3136 inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAKEINPUT;
3137 inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAKEOUTPUT;
3138
3139 /* mark any iterators on the list or being processed */
3140 sctp_iterator_inp_being_freed(inp);
3129 }
3130 sctp_timer_stop(SCTP_TIMER_TYPE_NEWCOOKIE, inp, NULL, NULL,
3131 SCTP_FROM_SCTP_PCB + SCTP_LOC_1);
3132
3133 if (inp->control) {
3134 sctp_m_freem(inp->control);
3135 inp->control = NULL;
3136 }

--- 352 unchanged lines hidden (view full) ---

3489 shared_key = LIST_FIRST(&inp->sctp_ep.shared_keys);
3490 while (shared_key) {
3491 LIST_REMOVE(shared_key, next);
3492 sctp_free_sharedkey(shared_key);
3493 /* sa_ignore FREED_MEMORY */
3494 shared_key = LIST_FIRST(&inp->sctp_ep.shared_keys);
3495 }
3496
3141 }
3142 sctp_timer_stop(SCTP_TIMER_TYPE_NEWCOOKIE, inp, NULL, NULL,
3143 SCTP_FROM_SCTP_PCB + SCTP_LOC_1);
3144
3145 if (inp->control) {
3146 sctp_m_freem(inp->control);
3147 inp->control = NULL;
3148 }

--- 352 unchanged lines hidden (view full) ---

3501 shared_key = LIST_FIRST(&inp->sctp_ep.shared_keys);
3502 while (shared_key) {
3503 LIST_REMOVE(shared_key, next);
3504 sctp_free_sharedkey(shared_key);
3505 /* sa_ignore FREED_MEMORY */
3506 shared_key = LIST_FIRST(&inp->sctp_ep.shared_keys);
3507 }
3508
3497 inp_save = LIST_NEXT(inp, sctp_list);
3498 LIST_REMOVE(inp, sctp_list);
3499
3509 LIST_REMOVE(inp, sctp_list);
3510
3500 /* fix any iterators only after out of the list */
3501 sctp_iterator_inp_being_freed(inp, inp_save);
3502 /*
3503 * if we have an address list the following will free the list of
3504 * ifaddr's that are set into this ep. Again macro limitations here,
3505 * since the LIST_FOREACH could be a bad idea.
3506 */
3507 for ((laddr = LIST_FIRST(&inp->sctp_addr_list)); laddr != NULL;
3508 laddr = nladdr) {
3509 nladdr = LIST_NEXT(laddr, sctp_nxt_addr);

--- 1921 unchanged lines hidden (view full) ---

5431 SCTP_BASE_STATS[PCPU_GET(cpuid)].sctps_discontinuitytime.tv_usec = (uint32_t) tv.tv_usec;
5432#else
5433 SCTP_BASE_STAT(sctps_discontinuitytime).tv_sec = (uint32_t) tv.tv_sec;
5434 SCTP_BASE_STAT(sctps_discontinuitytime).tv_usec = (uint32_t) tv.tv_usec;
5435#endif
5436 /* init the empty list of (All) Endpoints */
5437 LIST_INIT(&SCTP_BASE_INFO(listhead));
5438
3511 /*
3512 * if we have an address list the following will free the list of
3513 * ifaddr's that are set into this ep. Again macro limitations here,
3514 * since the LIST_FOREACH could be a bad idea.
3515 */
3516 for ((laddr = LIST_FIRST(&inp->sctp_addr_list)); laddr != NULL;
3517 laddr = nladdr) {
3518 nladdr = LIST_NEXT(laddr, sctp_nxt_addr);

--- 1921 unchanged lines hidden (view full) ---

5440 SCTP_BASE_STATS[PCPU_GET(cpuid)].sctps_discontinuitytime.tv_usec = (uint32_t) tv.tv_usec;
5441#else
5442 SCTP_BASE_STAT(sctps_discontinuitytime).tv_sec = (uint32_t) tv.tv_sec;
5443 SCTP_BASE_STAT(sctps_discontinuitytime).tv_usec = (uint32_t) tv.tv_usec;
5444#endif
5445 /* init the empty list of (All) Endpoints */
5446 LIST_INIT(&SCTP_BASE_INFO(listhead));
5447
5439 /* init the iterator head */
5440 TAILQ_INIT(&SCTP_BASE_INFO(iteratorhead));
5441
5442 /* init the hash table of endpoints */
5443 TUNABLE_INT_FETCH("net.inet.sctp.tcbhashsize", &SCTP_BASE_SYSCTL(sctp_hashtblsize));
5444 TUNABLE_INT_FETCH("net.inet.sctp.pcbhashsize", &SCTP_BASE_SYSCTL(sctp_pcbtblsize));
5445 TUNABLE_INT_FETCH("net.inet.sctp.chunkscale", &SCTP_BASE_SYSCTL(sctp_chunkscale));
5446 SCTP_BASE_INFO(sctp_asochash) = SCTP_HASH_INIT((SCTP_BASE_SYSCTL(sctp_hashtblsize) * 31),
5447 &SCTP_BASE_INFO(hashasocmark));
5448 SCTP_BASE_INFO(sctp_ephash) = SCTP_HASH_INIT(SCTP_BASE_SYSCTL(sctp_hashtblsize),

--- 46 unchanged lines hidden (view full) ---

5495 SCTP_ZONE_INIT(SCTP_BASE_INFO(ipi_zone_asconf_ack), "sctp_asconf_ack",
5496 sizeof(struct sctp_asconf_ack),
5497 (sctp_max_number_of_assoc * SCTP_BASE_SYSCTL(sctp_chunkscale)));
5498
5499
5500 /* Master Lock INIT for info structure */
5501 SCTP_INP_INFO_LOCK_INIT();
5502 SCTP_STATLOG_INIT_LOCK();
5448
5449 /* init the hash table of endpoints */
5450 TUNABLE_INT_FETCH("net.inet.sctp.tcbhashsize", &SCTP_BASE_SYSCTL(sctp_hashtblsize));
5451 TUNABLE_INT_FETCH("net.inet.sctp.pcbhashsize", &SCTP_BASE_SYSCTL(sctp_pcbtblsize));
5452 TUNABLE_INT_FETCH("net.inet.sctp.chunkscale", &SCTP_BASE_SYSCTL(sctp_chunkscale));
5453 SCTP_BASE_INFO(sctp_asochash) = SCTP_HASH_INIT((SCTP_BASE_SYSCTL(sctp_hashtblsize) * 31),
5454 &SCTP_BASE_INFO(hashasocmark));
5455 SCTP_BASE_INFO(sctp_ephash) = SCTP_HASH_INIT(SCTP_BASE_SYSCTL(sctp_hashtblsize),

--- 46 unchanged lines hidden (view full) ---

5502 SCTP_ZONE_INIT(SCTP_BASE_INFO(ipi_zone_asconf_ack), "sctp_asconf_ack",
5503 sizeof(struct sctp_asconf_ack),
5504 (sctp_max_number_of_assoc * SCTP_BASE_SYSCTL(sctp_chunkscale)));
5505
5506
5507 /* Master Lock INIT for info structure */
5508 SCTP_INP_INFO_LOCK_INIT();
5509 SCTP_STATLOG_INIT_LOCK();
5503 SCTP_ITERATOR_LOCK_INIT();
5504
5505 SCTP_IPI_COUNT_INIT();
5506 SCTP_IPI_ADDR_INIT();
5510
5511 SCTP_IPI_COUNT_INIT();
5512 SCTP_IPI_ADDR_INIT();
5507 SCTP_IPI_ITERATOR_WQ_INIT();
5508#ifdef SCTP_PACKET_LOGGING
5509 SCTP_IP_PKTLOG_INIT();
5510#endif
5511 LIST_INIT(&SCTP_BASE_INFO(addr_wq));
5512
5513#ifdef SCTP_PACKET_LOGGING
5514 SCTP_IP_PKTLOG_INIT();
5515#endif
5516 LIST_INIT(&SCTP_BASE_INFO(addr_wq));
5517
5518 SCTP_WQ_ADDR_INIT();
5513 /* not sure if we need all the counts */
5514 SCTP_BASE_INFO(ipi_count_ep) = 0;
5515 /* assoc/tcb zone info */
5516 SCTP_BASE_INFO(ipi_count_asoc) = 0;
5517 /* local addrlist zone info */
5518 SCTP_BASE_INFO(ipi_count_laddr) = 0;
5519 /* remote addrlist zone info */
5520 SCTP_BASE_INFO(ipi_count_raddr) = 0;

--- 11 unchanged lines hidden (view full) ---

5532
5533 SCTP_OS_TIMER_INIT(&SCTP_BASE_INFO(addr_wq_timer.timer));
5534
5535 /* Init the TIMEWAIT list */
5536 for (i = 0; i < SCTP_STACK_VTAG_HASH_SIZE; i++) {
5537 LIST_INIT(&SCTP_BASE_INFO(vtag_timewait)[i]);
5538 }
5539
5519 /* not sure if we need all the counts */
5520 SCTP_BASE_INFO(ipi_count_ep) = 0;
5521 /* assoc/tcb zone info */
5522 SCTP_BASE_INFO(ipi_count_asoc) = 0;
5523 /* local addrlist zone info */
5524 SCTP_BASE_INFO(ipi_count_laddr) = 0;
5525 /* remote addrlist zone info */
5526 SCTP_BASE_INFO(ipi_count_raddr) = 0;

--- 11 unchanged lines hidden (view full) ---

5538
5539 SCTP_OS_TIMER_INIT(&SCTP_BASE_INFO(addr_wq_timer.timer));
5540
5541 /* Init the TIMEWAIT list */
5542 for (i = 0; i < SCTP_STACK_VTAG_HASH_SIZE; i++) {
5543 LIST_INIT(&SCTP_BASE_INFO(vtag_timewait)[i]);
5544 }
5545
5540#if defined(SCTP_USE_THREAD_BASED_ITERATOR)
5541 SCTP_BASE_INFO(iterator_running) = 0;
5542 SCTP_BASE_INFO(threads_must_exit) = 0;
5543 sctp_startup_iterator();
5546 sctp_startup_iterator();
5544#endif
5545
5546 /*
5547 * INIT the default VRF which for BSD is the only one, other O/S's
5548 * may have more. But initially they must start with one and then
5549 * add the VRF's as addresses are added.
5550 */
5551 sctp_init_vrf_list(SCTP_DEFAULT_VRF);
5552

--- 7 unchanged lines hidden (view full) ---

5560{
5561 struct sctp_vrflist *vrf_bucket;
5562 struct sctp_vrf *vrf;
5563 struct sctp_ifn *ifn;
5564 struct sctp_ifa *ifa;
5565 struct sctpvtaghead *chain;
5566 struct sctp_tagblock *twait_block, *prev_twait_block;
5567 struct sctp_laddr *wi;
5547
5548 /*
5549 * INIT the default VRF which for BSD is the only one, other O/S's
5550 * may have more. But initially they must start with one and then
5551 * add the VRF's as addresses are added.
5552 */
5553 sctp_init_vrf_list(SCTP_DEFAULT_VRF);
5554

--- 7 unchanged lines hidden (view full) ---

5562{
5563 struct sctp_vrflist *vrf_bucket;
5564 struct sctp_vrf *vrf;
5565 struct sctp_ifn *ifn;
5566 struct sctp_ifa *ifa;
5567 struct sctpvtaghead *chain;
5568 struct sctp_tagblock *twait_block, *prev_twait_block;
5569 struct sctp_laddr *wi;
5568 struct sctp_iterator *it;
5569 int i;
5570
5570 int i;
5571
5571#if defined(SCTP_USE_THREAD_BASED_ITERATOR)
5572 SCTP_BASE_INFO(threads_must_exit) = 1;
5573 /* Wake the thread up so it will exit now */
5574 sctp_wakeup_iterator();
5572 /*
5573 * Free BSD the it thread never exits but we do clean up. The only
5574 * way freebsd reaches here if we have VRF's but we still add the
5575 * ifdef to make it compile on old versions.
5576 */
5577 {
5578 struct sctp_iterator *it, *nit;
5575
5579
5576#endif
5580 SCTP_IPI_ITERATOR_WQ_LOCK();
5581 it = TAILQ_FIRST(&sctp_it_ctl.iteratorhead);
5582 while (it) {
5583 nit = TAILQ_NEXT(it, sctp_nxt_itr);
5584 if (it->vn != curvnet) {
5585 it = nit;
5586 continue;
5587 }
5588 TAILQ_REMOVE(&sctp_it_ctl.iteratorhead,
5589 it, sctp_nxt_itr);
5590 if (it->function_atend != NULL) {
5591 (*it->function_atend) (it->pointer, it->val);
5592 }
5593 SCTP_FREE(it, SCTP_M_ITER);
5594 it = nit;
5595 }
5596 SCTP_IPI_ITERATOR_WQ_UNLOCK();
5597 SCTP_ITERATOR_LOCK();
5598 if ((sctp_it_ctl.cur_it) &&
5599 (sctp_it_ctl.cur_it->vn == curvnet)) {
5600 sctp_it_ctl.iterator_flags |= SCTP_ITERATOR_STOP_CUR_IT;
5601 }
5602 SCTP_ITERATOR_UNLOCK();
5603 }
5604
5577 SCTP_OS_TIMER_STOP(&SCTP_BASE_INFO(addr_wq_timer.timer));
5605 SCTP_OS_TIMER_STOP(&SCTP_BASE_INFO(addr_wq_timer.timer));
5578 SCTP_IPI_ITERATOR_WQ_LOCK();
5606 SCTP_WQ_ADDR_LOCK();
5579 while ((wi = LIST_FIRST(&SCTP_BASE_INFO(addr_wq))) != NULL) {
5580 LIST_REMOVE(wi, sctp_nxt_addr);
5581 SCTP_DECR_LADDR_COUNT();
5582 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_laddr), wi);
5583 }
5607 while ((wi = LIST_FIRST(&SCTP_BASE_INFO(addr_wq))) != NULL) {
5608 LIST_REMOVE(wi, sctp_nxt_addr);
5609 SCTP_DECR_LADDR_COUNT();
5610 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_laddr), wi);
5611 }
5584 SCTP_IPI_ITERATOR_WQ_UNLOCK();
5585 while ((it = TAILQ_FIRST(&SCTP_BASE_INFO(iteratorhead))) != NULL) {
5586 if (it->function_atend != NULL) {
5587 (*it->function_atend) (it->pointer, it->val);
5588 }
5589 TAILQ_REMOVE(&SCTP_BASE_INFO(iteratorhead), it, sctp_nxt_itr);
5590 SCTP_FREE(it, SCTP_M_ITER);
5591 }
5612 SCTP_WQ_ADDR_UNLOCK();
5592
5593 /*
5594 * free the vrf/ifn/ifa lists and hashes (be sure address monitor is
5595 * destroyed first).
5596 */
5597 vrf_bucket = &SCTP_BASE_INFO(sctp_vrfhash)[(SCTP_DEFAULT_VRFID & SCTP_BASE_INFO(hashvrfmark))];
5598 while ((vrf = LIST_FIRST(vrf_bucket)) != NULL) {
5599 while ((ifn = LIST_FIRST(&vrf->ifnlist)) != NULL) {

--- 35 unchanged lines hidden (view full) ---

5635 }
5636 }
5637
5638 /* free the locks and mutexes */
5639#ifdef SCTP_PACKET_LOGGING
5640 SCTP_IP_PKTLOG_DESTROY();
5641#endif
5642 SCTP_IPI_ADDR_DESTROY();
5613
5614 /*
5615 * free the vrf/ifn/ifa lists and hashes (be sure address monitor is
5616 * destroyed first).
5617 */
5618 vrf_bucket = &SCTP_BASE_INFO(sctp_vrfhash)[(SCTP_DEFAULT_VRFID & SCTP_BASE_INFO(hashvrfmark))];
5619 while ((vrf = LIST_FIRST(vrf_bucket)) != NULL) {
5620 while ((ifn = LIST_FIRST(&vrf->ifnlist)) != NULL) {

--- 35 unchanged lines hidden (view full) ---

5656 }
5657 }
5658
5659 /* free the locks and mutexes */
5660#ifdef SCTP_PACKET_LOGGING
5661 SCTP_IP_PKTLOG_DESTROY();
5662#endif
5663 SCTP_IPI_ADDR_DESTROY();
5643 SCTP_ITERATOR_LOCK_DESTROY();
5644 SCTP_STATLOG_DESTROY();
5645 SCTP_INP_INFO_LOCK_DESTROY();
5646
5664 SCTP_STATLOG_DESTROY();
5665 SCTP_INP_INFO_LOCK_DESTROY();
5666
5667 SCTP_WQ_ADDR_DESTROY();
5668
5647 SCTP_ZONE_DESTROY(SCTP_BASE_INFO(ipi_zone_ep));
5648 SCTP_ZONE_DESTROY(SCTP_BASE_INFO(ipi_zone_asoc));
5649 SCTP_ZONE_DESTROY(SCTP_BASE_INFO(ipi_zone_laddr));
5650 SCTP_ZONE_DESTROY(SCTP_BASE_INFO(ipi_zone_net));
5651 SCTP_ZONE_DESTROY(SCTP_BASE_INFO(ipi_zone_chunk));
5652 SCTP_ZONE_DESTROY(SCTP_BASE_INFO(ipi_zone_readq));
5653 SCTP_ZONE_DESTROY(SCTP_BASE_INFO(ipi_zone_strmoq));
5654 SCTP_ZONE_DESTROY(SCTP_BASE_INFO(ipi_zone_asconf));

--- 972 unchanged lines hidden (view full) ---

6627 it->function_atend = ef;
6628 it->pointer = argp;
6629 it->val = argi;
6630 it->pcb_flags = pcb_state;
6631 it->pcb_features = pcb_features;
6632 it->asoc_state = asoc_state;
6633 it->function_inp_end = inpe;
6634 it->no_chunk_output = chunk_output_off;
5669 SCTP_ZONE_DESTROY(SCTP_BASE_INFO(ipi_zone_ep));
5670 SCTP_ZONE_DESTROY(SCTP_BASE_INFO(ipi_zone_asoc));
5671 SCTP_ZONE_DESTROY(SCTP_BASE_INFO(ipi_zone_laddr));
5672 SCTP_ZONE_DESTROY(SCTP_BASE_INFO(ipi_zone_net));
5673 SCTP_ZONE_DESTROY(SCTP_BASE_INFO(ipi_zone_chunk));
5674 SCTP_ZONE_DESTROY(SCTP_BASE_INFO(ipi_zone_readq));
5675 SCTP_ZONE_DESTROY(SCTP_BASE_INFO(ipi_zone_strmoq));
5676 SCTP_ZONE_DESTROY(SCTP_BASE_INFO(ipi_zone_asconf));

--- 972 unchanged lines hidden (view full) ---

6649 it->function_atend = ef;
6650 it->pointer = argp;
6651 it->val = argi;
6652 it->pcb_flags = pcb_state;
6653 it->pcb_features = pcb_features;
6654 it->asoc_state = asoc_state;
6655 it->function_inp_end = inpe;
6656 it->no_chunk_output = chunk_output_off;
6657 it->vn = curvnet;
6635 if (s_inp) {
6636 it->inp = s_inp;
6637 it->iterator_flags = SCTP_ITERATOR_DO_SINGLE_INP;
6638 } else {
6639 SCTP_INP_INFO_RLOCK();
6640 it->inp = LIST_FIRST(&SCTP_BASE_INFO(listhead));
6641
6642 SCTP_INP_INFO_RUNLOCK();
6643 it->iterator_flags = SCTP_ITERATOR_DO_ALL_INP;
6644
6645 }
6646 SCTP_IPI_ITERATOR_WQ_LOCK();
6647 if (it->inp) {
6648 SCTP_INP_INCR_REF(it->inp);
6649 }
6658 if (s_inp) {
6659 it->inp = s_inp;
6660 it->iterator_flags = SCTP_ITERATOR_DO_SINGLE_INP;
6661 } else {
6662 SCTP_INP_INFO_RLOCK();
6663 it->inp = LIST_FIRST(&SCTP_BASE_INFO(listhead));
6664
6665 SCTP_INP_INFO_RUNLOCK();
6666 it->iterator_flags = SCTP_ITERATOR_DO_ALL_INP;
6667
6668 }
6669 SCTP_IPI_ITERATOR_WQ_LOCK();
6670 if (it->inp) {
6671 SCTP_INP_INCR_REF(it->inp);
6672 }
6650 TAILQ_INSERT_TAIL(&SCTP_BASE_INFO(iteratorhead), it, sctp_nxt_itr);
6651#if defined(SCTP_USE_THREAD_BASED_ITERATOR)
6652 if (SCTP_BASE_INFO(iterator_running) == 0) {
6673 TAILQ_INSERT_TAIL(&sctp_it_ctl.iteratorhead, it, sctp_nxt_itr);
6674 if (sctp_it_ctl.iterator_running == 0) {
6653 sctp_wakeup_iterator();
6654 }
6655 SCTP_IPI_ITERATOR_WQ_UNLOCK();
6675 sctp_wakeup_iterator();
6676 }
6677 SCTP_IPI_ITERATOR_WQ_UNLOCK();
6656#else
6657 if (it->inp)
6658 SCTP_INP_DECR_REF(it->inp);
6659 SCTP_IPI_ITERATOR_WQ_UNLOCK();
6660 /* Init the timer */
6661 SCTP_OS_TIMER_INIT(&it->tmr.timer);
6662 /* add to the list of all iterators */
6663 sctp_timer_start(SCTP_TIMER_TYPE_ITERATOR, (struct sctp_inpcb *)it,
6664 NULL, NULL);
6665#endif
6666 /* sa_ignore MEMLEAK {memory is put on the tailq for the iterator} */
6667 return (0);
6668}
6678 /* sa_ignore MEMLEAK {memory is put on the tailq for the iterator} */
6679 return (0);
6680}