X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fplugins%2Facl%2Facl.c;h=d95e798eb75d8fe496f62f3ed5479569c6b4e066;hb=756cd9441752fc8f84104c9ee19099506ba89f85;hp=7499bc4e1063f12c168e43fc95e1f13291e14ca9;hpb=e1e995db55be2fe1cb371fb6acd86ea9144da914;p=vpp.git diff --git a/src/plugins/acl/acl.c b/src/plugins/acl/acl.c index 7499bc4e106..d95e798eb75 100644 --- a/src/plugins/acl/acl.c +++ b/src/plugins/acl/acl.c @@ -54,6 +54,7 @@ #include "public_inlines.h" acl_main_t acl_main; +acl_main_t *p_acl_main = &acl_main; #define REPLY_MSG_ID_BASE am->msg_id_base #include @@ -121,7 +122,34 @@ acl_set_heap (acl_main_t * am) { if (0 == am->acl_mheap) { + if (0 == am->acl_mheap_size) + { + vlib_thread_main_t *tm = vlib_get_thread_main (); + u64 per_worker_slack = 1000000LL; + u64 per_worker_size = + per_worker_slack + + ((u64) am->fa_conn_table_max_entries) * sizeof (fa_session_t); + u64 per_worker_size_with_slack = per_worker_slack + per_worker_size; + u64 main_slack = 2000000LL; + u64 bihash_size = (u64) am->fa_conn_table_hash_memory_size; + + am->acl_mheap_size = + per_worker_size_with_slack * tm->n_vlib_mains + bihash_size + + main_slack; + } + u64 max_possible = ((uword) ~ 0); + if (am->acl_mheap_size > max_possible) + { + clib_warning ("ACL heap size requested: %lld, max possible %lld", + am->acl_mheap_size, max_possible); + } am->acl_mheap = mheap_alloc (0 /* use VM */ , am->acl_mheap_size); + if (0 == am->acl_mheap) + { + clib_error + ("ACL plugin failed to allocate main heap of %U bytes, abort", + format_memory_size, am->acl_mheap_size); + } mheap_t *h = mheap_header (am->acl_mheap); h->flags |= MHEAP_FLAG_THREAD_SAFE; } @@ -278,6 +306,45 @@ warning_acl_print_acl (vlib_main_t * vm, acl_main_t * am, int acl_index) acl_print_acl_x (print_clib_warning_and_reset, vm, am, acl_index); } +static void +increment_policy_epoch (acl_main_t * am, u32 sw_if_index, int is_input) +{ + + u32 **ppolicy_epoch_by_swi = + is_input ? &am->input_policy_epoch_by_sw_if_index : + &am->output_policy_epoch_by_sw_if_index; + vec_validate (*ppolicy_epoch_by_swi, sw_if_index); + + u32 *p_epoch = vec_elt_at_index ((*ppolicy_epoch_by_swi), sw_if_index); + *p_epoch = + ((1 + *p_epoch) & FA_POLICY_EPOCH_MASK) + + (is_input * FA_POLICY_EPOCH_IS_INPUT); +} + +static void +try_increment_acl_policy_epoch (acl_main_t * am, u32 acl_num, int is_input) +{ + u32 ***p_swi_vec_by_acl = is_input ? &am->input_sw_if_index_vec_by_acl + : &am->output_sw_if_index_vec_by_acl; + if (acl_num < vec_len (*p_swi_vec_by_acl)) + { + u32 *p_swi; + vec_foreach (p_swi, (*p_swi_vec_by_acl)[acl_num]) + { + increment_policy_epoch (am, *p_swi, is_input); + } + + } +} + +static void +policy_notify_acl_change (acl_main_t * am, u32 acl_num) +{ + try_increment_acl_policy_epoch (am, acl_num, 0); + try_increment_acl_policy_epoch (am, acl_num, 1); +} + + static int acl_add_list (u32 count, vl_api_acl_rule_t rules[], @@ -365,6 +432,12 @@ acl_add_list (u32 count, vl_api_acl_rule_t rules[], memcpy (a->tag, tag, sizeof (a->tag)); if (am->trace_acl > 255) warning_acl_print_acl (am->vlib_main, am, *acl_list_index); + if (am->reclassify_sessions) + { + /* a change in an ACLs if they are applied may mean a new policy epoch */ + policy_notify_acl_change (am, *acl_list_index); + } + /* notify the lookup contexts about the ACL changes */ acl_plugin_lookup_context_notify_acl_change (*acl_list_index); clib_mem_set_heap (oldheap); @@ -1241,12 +1314,20 @@ acl_interface_set_inout_acl_list (acl_main_t * am, u32 sw_if_index, (*pinout_acl_vec_by_sw_if_index)[sw_if_index] = vec_dup (vec_acl_list_index); - /* if no commonalities between the ACL# - then we should definitely clear the sessions */ - if (may_clear_sessions && *may_clear_sessions - && !clib_bitmap_is_zero (change_acl_bitmap)) + if (am->reclassify_sessions) { - acl_clear_sessions (am, sw_if_index); - *may_clear_sessions = 0; + /* re-applying ACLs means a new policy epoch */ + increment_policy_epoch (am, sw_if_index, is_input); + } + else + { + /* if no commonalities between the ACL# - then we should definitely clear the sessions */ + if (may_clear_sessions && *may_clear_sessions + && !clib_bitmap_is_zero (change_acl_bitmap)) + { + acl_clear_sessions (am, sw_if_index); + *may_clear_sessions = 0; + } } /* @@ -1266,7 +1347,6 @@ acl_interface_set_inout_acl_list (acl_main_t * am, u32 sw_if_index, lc_index = acl_plugin_get_lookup_context_index (am->interface_acl_user_id, sw_if_index, is_input); - ASSERT (lc_index >= 0); (*pinout_lc_index_by_sw_if_index)[sw_if_index] = lc_index; } acl_plugin_set_acl_vec_for_context (lc_index, vec_acl_list_index); @@ -3175,6 +3255,11 @@ acl_set_aclplugin_fn (vlib_main_t * vm, am->l4_match_nonfirst_fragment = (val != 0); goto done; } + if (unformat (input, "reclassify-sessions %u", &val)) + { + am->reclassify_sessions = (val != 0); + goto done; + } if (unformat (input, "event-trace")) { if (!unformat (input, "%u", &val)) @@ -3544,6 +3629,15 @@ acl_plugin_show_interface (acl_main_t * am, u32 sw_if_index, int show_acl, continue; vlib_cli_output (vm, "sw_if_index %d:\n", swi); + if (swi < vec_len (am->input_policy_epoch_by_sw_if_index)) + vlib_cli_output (vm, " input policy epoch: %x\n", + vec_elt (am->input_policy_epoch_by_sw_if_index, + swi)); + if (swi < vec_len (am->output_policy_epoch_by_sw_if_index)) + vlib_cli_output (vm, " output policy epoch: %x\n", + vec_elt (am->output_policy_epoch_by_sw_if_index, + swi)); + if (intf_has_etype_whitelist (am, swi, 1)) { @@ -3734,13 +3828,21 @@ acl_plugin_show_sessions (acl_main_t * am, ? pw->fa_session_dels_by_sw_if_index [sw_if_index] : 0; + u64 n_epoch_changes = + sw_if_index < + vec_len + (pw->fa_session_epoch_change_by_sw_if_index) + ? + pw->fa_session_epoch_change_by_sw_if_index + [sw_if_index] : 0; vlib_cli_output (vm, - " sw_if_index %d: add %lu - del %lu = %lu", + " sw_if_index %d: add %lu - del %lu = %lu; epoch chg: %lu", sw_if_index, n_adds, n_dels, n_adds - - n_dels); + n_dels, + n_epoch_changes); } )); @@ -3802,6 +3904,7 @@ acl_plugin_show_sessions (acl_main_t * am, am->fa_cleaner_wait_time_increment * 1000.0, ((f64) am->fa_current_cleaner_timer_wait_interval) * 1000.0 / (f64) vm->clib_time.clocks_per_second); + vlib_cli_output (vm, "Reclassify sessions: %d", am->reclassify_sessions); } static clib_error_t * @@ -3976,10 +4079,11 @@ acl_plugin_config (vlib_main_t * vm, unformat_input_t * input) u32 conn_table_hash_buckets; u32 conn_table_hash_memory_size; u32 conn_table_max_entries; - u32 main_heap_size; - u32 hash_heap_size; + uword main_heap_size; + uword hash_heap_size; u32 hash_lookup_hash_buckets; u32 hash_lookup_hash_memory; + u32 reclassify_sessions; while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { @@ -3992,9 +4096,15 @@ acl_plugin_config (vlib_main_t * vm, unformat_input_t * input) else if (unformat (input, "connection count max %d", &conn_table_max_entries)) am->fa_conn_table_max_entries = conn_table_max_entries; - else if (unformat (input, "main heap size %d", &main_heap_size)) + else + if (unformat + (input, "main heap size %U", unformat_memory_size, + &main_heap_size)) am->acl_mheap_size = main_heap_size; - else if (unformat (input, "hash lookup heap size %d", &hash_heap_size)) + else + if (unformat + (input, "hash lookup heap size %U", unformat_memory_size, + &hash_heap_size)) am->hash_lookup_mheap_size = hash_heap_size; else if (unformat (input, "hash lookup hash buckets %d", &hash_lookup_hash_buckets)) @@ -4002,6 +4112,10 @@ acl_plugin_config (vlib_main_t * vm, unformat_input_t * input) else if (unformat (input, "hash lookup hash memory %d", &hash_lookup_hash_memory)) am->hash_lookup_hash_memory = hash_lookup_hash_memory; + else if (unformat (input, "reclassify sessions %d", + &reclassify_sessions)) + am->reclassify_sessions = reclassify_sessions; + else return clib_error_return (0, "unknown input '%U'", format_unformat_error, input); @@ -4035,7 +4149,7 @@ acl_init (vlib_main_t * vm) acl_setup_fa_nodes (); - am->acl_mheap_size = ACL_FA_DEFAULT_HEAP_SIZE; + am->acl_mheap_size = 0; /* auto size when initializing */ am->hash_lookup_mheap_size = ACL_PLUGIN_HASH_LOOKUP_HEAP_SIZE; am->hash_lookup_hash_buckets = ACL_PLUGIN_HASH_LOOKUP_HASH_BUCKETS; @@ -4053,6 +4167,7 @@ acl_init (vlib_main_t * vm) am->fa_conn_table_hash_memory_size = ACL_FA_CONN_TABLE_DEFAULT_HASH_MEMORY_SIZE; am->fa_conn_table_max_entries = ACL_FA_CONN_TABLE_DEFAULT_MAX_ENTRIES; + am->reclassify_sessions = 0; vlib_thread_main_t *tm = vlib_get_thread_main (); vec_validate (am->per_worker_data, tm->n_vlib_mains - 1); {