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} |