X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;ds=sidebyside;f=src%2Fplugins%2Facl%2Fsess_mgmt_node.c;h=eb73fd0bb45e773dc12d6cc723c66a306d79c5ae;hb=c119e796f535046c33430a92949addcf11dbf684;hp=465111a380f8f0b03b4a334e61d90a44917cc6ca;hpb=4bc1796b346efd10f3fb19b176ff089179263a24;p=vpp.git diff --git a/src/plugins/acl/sess_mgmt_node.c b/src/plugins/acl/sess_mgmt_node.c index 465111a380f..eb73fd0bb45 100644 --- a/src/plugins/acl/sess_mgmt_node.c +++ b/src/plugins/acl/sess_mgmt_node.c @@ -17,7 +17,6 @@ #include #include -#include #include @@ -30,41 +29,55 @@ #include #include -// #include -static u64 -fa_session_get_shortest_timeout (acl_main_t * am) +static_always_inline u8 * +format_ip46_session_bihash_kv (u8 * s, va_list * args, int is_ip6) { - int timeout_type; - u64 timeout = ~0LL; - for (timeout_type = 0; timeout_type <= ACL_N_USER_TIMEOUTS; timeout_type++) + fa_5tuple_t a5t; + void *paddr0; + void *paddr1; + void *format_addr_func; + + if (is_ip6) { - if (timeout > am->session_timeout_sec[timeout_type]) - { - timeout = am->session_timeout_sec[timeout_type]; - } + clib_bihash_kv_40_8_t *kv_40_8 = + va_arg (*args, clib_bihash_kv_40_8_t *); + a5t.kv_40_8 = *kv_40_8; + paddr0 = &a5t.ip6_addr[0]; + paddr1 = &a5t.ip6_addr[1]; + format_addr_func = format_ip6_address; } - return timeout; + else + { + clib_bihash_kv_16_8_t *kv_16_8 = + va_arg (*args, clib_bihash_kv_16_8_t *); + a5t.kv_16_8 = *kv_16_8; + paddr0 = &a5t.ip4_addr[0]; + paddr1 = &a5t.ip4_addr[1]; + format_addr_func = format_ip4_address; + } + + fa_full_session_id_t *sess = (fa_full_session_id_t *) & a5t.pkt; + + return (format (s, "l3 %U -> %U %U | sess id %d thread id %d epoch %04x", + format_addr_func, paddr0, + format_addr_func, paddr1, + format_fa_session_l4_key, &a5t.l4, + sess->session_index, sess->thread_index, + sess->intf_policy_epoch)); } static u8 * -format_session_bihash_5tuple (u8 * s, va_list * args) +format_ip6_session_bihash_kv (u8 * s, va_list * args) { - fa_5tuple_t *p5t = va_arg (*args, fa_5tuple_t *); - fa_full_session_id_t *sess = (void *) &p5t->pkt; - - return format (s, "l3 %U -> %U" - " l4 lsb_of_sw_if_index %d proto %d l4_is_input %d l4_slow_path %d l4_reserved0 %d port %d -> %d | sess id %d thread id %d epoch %04x", - format_ip46_address, &p5t->addr[0], - IP46_TYPE_ANY, - format_ip46_address, &p5t->addr[1], - IP46_TYPE_ANY, - p5t->l4.lsb_of_sw_if_index, - p5t->l4.proto, p5t->l4.is_input, p5t->l4.is_slowpath, - p5t->l4.reserved0, p5t->l4.port[0], p5t->l4.port[1], - sess->session_index, sess->thread_index, - sess->intf_policy_epoch); + return format_ip46_session_bihash_kv (s, args, 1); +} + +static u8 * +format_ip4_session_bihash_kv (u8 * s, va_list * args) +{ + return format_ip46_session_bihash_kv (s, args, 0); } @@ -89,12 +102,20 @@ acl_fa_verify_init_sessions (acl_main_t * am) } /* ... and the interface session hash table */ - clib_bihash_init_40_8 (&am->fa_sessions_hash, - "ACL plugin FA session bihash", + clib_bihash_init_40_8 (&am->fa_ip6_sessions_hash, + "ACL plugin FA IPv6 session bihash", am->fa_conn_table_hash_num_buckets, am->fa_conn_table_hash_memory_size); - clib_bihash_set_kvp_format_fn_40_8 (&am->fa_sessions_hash, - format_session_bihash_5tuple); + clib_bihash_set_kvp_format_fn_40_8 (&am->fa_ip6_sessions_hash, + format_ip6_session_bihash_kv); + + clib_bihash_init_16_8 (&am->fa_ip4_sessions_hash, + "ACL plugin FA IPv4 session bihash", + am->fa_conn_table_hash_num_buckets, + am->fa_conn_table_hash_memory_size); + clib_bihash_set_kvp_format_fn_16_8 (&am->fa_ip4_sessions_hash, + format_ip4_session_bihash_kv); + am->fa_sessions_hash_is_initialized = 1; } } @@ -108,14 +129,9 @@ static u64 fa_session_get_list_timeout (acl_main_t * am, fa_session_t * sess) { u64 timeout = am->vlib_main->clib_time.clocks_per_second / 1000; - /* - * we have the shortest possible timeout type in all the lists - * (see README-multicore for the rationale) - */ - if (sess->link_list_id == ACL_TIMEOUT_PURGATORY) - timeout = fa_session_get_timeout (am, sess); - else - timeout *= fa_session_get_shortest_timeout (am); + timeout = fa_session_get_timeout (am, sess); + /* for all user lists, check them twice per timeout */ + timeout >>= (sess->link_list_id != ACL_TIMEOUT_PURGATORY); return timeout; } @@ -153,6 +169,27 @@ acl_fa_check_idle_sessions (acl_main_t * am, u16 thread_index, u64 now) fsid.thread_index = thread_index; int total_expired = 0; + /* let the other threads enqueue more requests while we process, if they like */ + aclp_swap_wip_and_pending_session_change_requests (am, thread_index); + u64 *psr = NULL; + + vec_foreach (psr, pw->wip_session_change_requests) + { + acl_fa_sess_req_t op = *psr >> 32; + fsid.session_index = *psr & 0xffffffff; + switch (op) + { + case ACL_FA_REQ_SESS_RESCHEDULE: + acl_fa_restart_timer_for_session (am, now, fsid); + break; + default: + /* do nothing */ + break; + } + } + if (pw->wip_session_change_requests) + vec_set_len (pw->wip_session_change_requests, 0); + { u8 tt = 0; int n_pending_swipes = 0; @@ -210,6 +247,9 @@ acl_fa_check_idle_sessions (acl_main_t * am, u16 thread_index, u64 now) clib_bitmap_get (pw->pending_clear_sw_if_index_bitmap, sw_if_index); if (am->trace_sessions > 3) { + elog_acl_maybe_trace_X2 (am, + "acl_fa_check_idle_sessions: now %lu sess_timeout_time %lu", + "i8i8", now, sess_timeout_time); elog_acl_maybe_trace_X4 (am, "acl_fa_check_idle_sessions: session %d sw_if_index %d timeout_passed %d clearing_interface %d", "i4i4i4i4", (u32) fsid.session_index, @@ -268,7 +308,7 @@ acl_fa_check_idle_sessions (acl_main_t * am, u16 thread_index, u64 now) total_expired = vec_len (pw->expired); /* zero out the vector which we have acted on */ if (pw->expired) - _vec_len (pw->expired) = 0; + vec_set_len (pw->expired, 0); /* if we were advancing and reached the end * (no more sessions to recycle), reset the fast-forward timestamp */ @@ -320,8 +360,9 @@ send_one_worker_interrupt (vlib_main_t * vm, acl_main_t * am, if (!pw->interrupt_is_pending) { pw->interrupt_is_pending = 1; - vlib_node_set_interrupt_pending (vlib_mains[thread_index], - acl_fa_worker_session_cleaner_process_node.index); + vlib_node_set_interrupt_pending ( + vlib_get_main_by_index (thread_index), + acl_fa_worker_session_cleaner_process_node.index); elog_acl_maybe_trace_X1 (am, "send_one_worker_interrupt: send interrupt to worker %u", "i4", ((u32) thread_index)); @@ -331,6 +372,41 @@ send_one_worker_interrupt (vlib_main_t * vm, acl_main_t * am, } } +void +aclp_post_session_change_request (acl_main_t * am, u32 target_thread, + u32 target_session, u32 request_type) +{ + acl_fa_per_worker_data_t *pw_me = + &am->per_worker_data[os_get_thread_index ()]; + acl_fa_per_worker_data_t *pw = &am->per_worker_data[target_thread]; + clib_spinlock_lock_if_init (&pw->pending_session_change_request_lock); + /* vec_add1 might cause a reallocation */ + vec_add1 (pw->pending_session_change_requests, + (((u64) request_type) << 32) | target_session); + pw->rcvd_session_change_requests++; + pw_me->sent_session_change_requests++; + if (vec_len (pw->pending_session_change_requests) == 1) + { + /* ensure the requests get processed */ + send_one_worker_interrupt (am->vlib_main, am, target_thread); + } + clib_spinlock_unlock_if_init (&pw->pending_session_change_request_lock); +} + +void +aclp_swap_wip_and_pending_session_change_requests (acl_main_t * am, + u32 target_thread) +{ + acl_fa_per_worker_data_t *pw = &am->per_worker_data[target_thread]; + u64 *tmp; + clib_spinlock_lock_if_init (&pw->pending_session_change_request_lock); + tmp = pw->pending_session_change_requests; + pw->pending_session_change_requests = pw->wip_session_change_requests; + pw->wip_session_change_requests = tmp; + clib_spinlock_unlock_if_init (&pw->pending_session_change_request_lock); +} + + static int purgatory_has_connections (vlib_main_t * vm, acl_main_t * am, int thread_index) @@ -484,7 +560,7 @@ send_interrupts_to_workers (vlib_main_t * vm, acl_main_t * am) { int i; /* Can't use vec_len(am->per_worker_data) since the threads might not have come up yet; */ - int n_threads = vec_len (vlib_mains); + int n_threads = vlib_get_n_threads (); for (i = 0; i < n_threads; i++) { send_one_worker_interrupt (vm, am, i); @@ -524,7 +600,7 @@ acl_fa_session_cleaner_process (vlib_main_t * vm, vlib_node_runtime_t * rt, * * Also, while we are at it, calculate the earliest we need to wake up. */ - for (ti = 0; ti < vec_len (vlib_mains); ti++) + for (ti = 0; ti < vlib_get_n_threads (); ti++) { if (ti >= vec_len (am->per_worker_data)) { @@ -620,7 +696,7 @@ acl_fa_session_cleaner_process (vlib_main_t * vm, vlib_node_runtime_t * rt, } } } - acl_log_err + acl_log_info ("ACL_FA_CLEANER_DELETE_BY_SW_IF_INDEX bitmap: %U, clear_all: %u", format_bitmap_hex, clear_sw_if_index_bitmap, clear_all); vec_foreach (pw0, am->per_worker_data) @@ -647,6 +723,7 @@ acl_fa_session_cleaner_process (vlib_main_t * vm, vlib_node_runtime_t * rt, } else { + clib_bitmap_free (pw0->pending_clear_sw_if_index_bitmap); if (clear_all) { /* if we need to clear all, then just clear the interfaces that we are servicing */ @@ -658,7 +735,7 @@ acl_fa_session_cleaner_process (vlib_main_t * vm, vlib_node_runtime_t * rt, pw0->pending_clear_sw_if_index_bitmap = clib_bitmap_dup (clear_sw_if_index_bitmap); } - acl_log_err + acl_log_info ("ACL_FA_CLEANER: thread %u, pending clear bitmap: %U", (am->per_worker_data - pw0), format_bitmap_hex, pw0->pending_clear_sw_if_index_bitmap); @@ -669,8 +746,9 @@ acl_fa_session_cleaner_process (vlib_main_t * vm, vlib_node_runtime_t * rt, send_interrupts_to_workers (vm, am); /* now wait till they all complete */ - acl_log_err ("CLEANER mains len: %u per-worker len: %d", - vec_len (vlib_mains), vec_len (am->per_worker_data)); + acl_log_info ("CLEANER mains len: %u per-worker len: %d", + vlib_get_n_threads (), + vec_len (am->per_worker_data)); vec_foreach (pw0, am->per_worker_data) { CLIB_MEMORY_BARRIER (); @@ -689,7 +767,7 @@ acl_fa_session_cleaner_process (vlib_main_t * vm, vlib_node_runtime_t * rt, } } } - acl_log_err ("ACL_FA_NODE_CLEAN: cleaning done"); + acl_log_info ("ACL_FA_NODE_CLEAN: cleaning done"); clib_bitmap_free (clear_sw_if_index_bitmap); } am->fa_cleaner_cnt_delete_by_sw_index_ok++; @@ -710,7 +788,7 @@ acl_fa_session_cleaner_process (vlib_main_t * vm, vlib_node_runtime_t * rt, send_interrupts_to_workers (vm, am); if (event_data) - _vec_len (event_data) = 0; + vec_set_len (event_data, 0); /* * If the interrupts were not processed yet, ensure we wait a bit, @@ -782,10 +860,8 @@ acl_fa_enable_disable (u32 sw_if_index, int is_input, int enable_disable) { acl_fa_verify_init_sessions (am); am->fa_total_enabled_count++; - void *oldheap = clib_mem_set_heap (am->vlib_main->heap_base); vlib_process_signal_event (am->vlib_main, am->fa_cleaner_node_index, ACL_FA_CLEANER_RESCHEDULE, 0); - clib_mem_set_heap (oldheap); } else { @@ -796,12 +872,10 @@ acl_fa_enable_disable (u32 sw_if_index, int is_input, int enable_disable) { ASSERT (clib_bitmap_get (am->fa_in_acl_on_sw_if_index, sw_if_index) != enable_disable); - void *oldheap = clib_mem_set_heap (am->vlib_main->heap_base); vnet_feature_enable_disable ("ip4-unicast", "acl-plugin-in-ip4-fa", sw_if_index, enable_disable, 0, 0); vnet_feature_enable_disable ("ip6-unicast", "acl-plugin-in-ip6-fa", sw_if_index, enable_disable, 0, 0); - clib_mem_set_heap (oldheap); am->fa_in_acl_on_sw_if_index = clib_bitmap_set (am->fa_in_acl_on_sw_if_index, sw_if_index, enable_disable); @@ -810,12 +884,10 @@ acl_fa_enable_disable (u32 sw_if_index, int is_input, int enable_disable) { ASSERT (clib_bitmap_get (am->fa_out_acl_on_sw_if_index, sw_if_index) != enable_disable); - void *oldheap = clib_mem_set_heap (am->vlib_main->heap_base); vnet_feature_enable_disable ("ip4-output", "acl-plugin-out-ip4-fa", sw_if_index, enable_disable, 0, 0); vnet_feature_enable_disable ("ip6-output", "acl-plugin-out-ip6-fa", sw_if_index, enable_disable, 0, 0); - clib_mem_set_heap (oldheap); am->fa_out_acl_on_sw_if_index = clib_bitmap_set (am->fa_out_acl_on_sw_if_index, sw_if_index, enable_disable); @@ -827,11 +899,9 @@ acl_fa_enable_disable (u32 sw_if_index, int is_input, int enable_disable) clib_warning ("ENABLE-DISABLE: clean the connections on interface %d", sw_if_index); #endif - void *oldheap = clib_mem_set_heap (am->vlib_main->heap_base); vlib_process_signal_event (am->vlib_main, am->fa_cleaner_node_index, ACL_FA_CLEANER_DELETE_BY_SW_IF_INDEX, sw_if_index); - clib_mem_set_heap (oldheap); } } @@ -841,8 +911,13 @@ show_fa_sessions_hash (vlib_main_t * vm, u32 verbose) acl_main_t *am = &acl_main; if (am->fa_sessions_hash_is_initialized) { - vlib_cli_output (vm, "\nSession lookup hash table:\n%U\n\n", - format_bihash_40_8, &am->fa_sessions_hash, verbose); + vlib_cli_output (vm, "\nIPv6 Session lookup hash table:\n%U\n\n", + format_bihash_40_8, &am->fa_ip6_sessions_hash, + verbose); + + vlib_cli_output (vm, "\nIPv4 Session lookup hash table:\n%U\n\n", + format_bihash_16_8, &am->fa_ip4_sessions_hash, + verbose); } else {