diff options
author | Jerome Tollet <jtollet@cisco.com> | 2020-12-18 09:44:24 +0100 |
---|---|---|
committer | John Lo <loj@cisco.com> | 2021-01-06 04:17:09 +0000 |
commit | 5f93e3b7f85e2257406cf601e5f231a872100fcf (patch) | |
tree | a9ae2588b3d28ac380b0a97b827ac52101ebbd52 /src/vnet/l2/l2_fib.c | |
parent | 1b576e0aa08c575a4409b50dc71e8f51d231f199 (diff) |
l2: add per bridge domain learn limit
Type: feature
Signed-off-by: Jerome Tollet <jtollet@cisco.com>
Change-Id: I57ed6699050445d9c9aec98eff3aab56735aca54
Signed-off-by: Jerome Tollet <jtollet@cisco.com>
Diffstat (limited to 'src/vnet/l2/l2_fib.c')
-rw-r--r-- | src/vnet/l2/l2_fib.c | 55 |
1 files changed, 46 insertions, 9 deletions
diff --git a/src/vnet/l2/l2_fib.c b/src/vnet/l2/l2_fib.c index c28c23bc41c..82be6bc0341 100644 --- a/src/vnet/l2/l2_fib.c +++ b/src/vnet/l2/l2_fib.c @@ -212,8 +212,7 @@ l2fib_show_walk_cb (BVT (clib_bihash_kv) * kvp, void *arg) if (ctx->add && !l2fib_entry_result_is_set_AGE_NOT (&result)) return (BIHASH_WALK_CONTINUE); /* skip learned macs */ - bd_config = vec_elt_at_index (l2input_main.bd_configs, - key.fields.bd_index); + bd_config = &vec_elt (l2input_main.bd_configs, key.fields.bd_index); if (l2fib_entry_result_is_set_AGE_NOT (&result)) s = format (s, "no"); @@ -384,6 +383,7 @@ void l2fib_clear_table (void) { l2fib_main_t *mp = &l2fib_main; + l2_bridge_domain_t *bd_config; if (mp->mac_table_initialized == 0) return; @@ -394,6 +394,8 @@ l2fib_clear_table (void) BV (clib_bihash_free) (&mp->mac_table); l2fib_table_init (); l2learn_main.global_learn_count = 0; + vec_foreach (bd_config, l2input_main.bd_configs) + bd_config->learn_count = 0; } /** Clear all entries in L2FIB. @@ -462,9 +464,21 @@ l2fib_add_entry (const u8 * mac, u32 bd_index, { /* decrement counter if overwriting a learned mac */ result.raw = kv.value; - if ((!l2fib_entry_result_is_set_AGE_NOT (&result)) - && (lm->global_learn_count)) - lm->global_learn_count--; + if (!l2fib_entry_result_is_set_AGE_NOT (&result)) + { + l2_bridge_domain_t *bd_config = + vec_elt_at_index (l2input_main.bd_configs, bd_index); + + /* check if learn_count == 0 in case of race condition between 2 + * workers adding an entry simultaneously */ + /* learn_count variable may have little inaccuracy because they are + * not incremented/decremented with atomic operations */ + /* l2fib_scan is call every 2sec fixing potential inaccuracy */ + if (lm->global_learn_count) + lm->global_learn_count--; + if (bd_config->learn_count) + bd_config->learn_count--; + } } /* set up result */ @@ -751,9 +765,15 @@ l2fib_del_entry (const u8 * mac, u32 bd_index, u32 sw_if_index) return 1; /* decrement counter if dynamically learned mac */ - if ((!l2fib_entry_result_is_set_AGE_NOT (&result)) && - (l2learn_main.global_learn_count)) - l2learn_main.global_learn_count--; + if (!l2fib_entry_result_is_set_AGE_NOT (&result)) + { + l2_bridge_domain_t *bd_config = + vec_elt_at_index (l2input_main.bd_configs, bd_index); + if (l2learn_main.global_learn_count) + l2learn_main.global_learn_count--; + if (bd_config->learn_count) + bd_config->learn_count--; + } /* Remove entry from hash table */ BV (clib_bihash_add_del) (&mp->mac_table, &kv, 0 /* is_add */ ); @@ -1051,11 +1071,16 @@ l2fib_scan (vlib_main_t * vm, f64 start_time, u8 event_only) u32 cl_idx = lm->client_index; vl_api_l2_macs_event_t *mp = 0; vl_api_registration_t *reg = 0; + u32 bd_index; + static u32 *bd_learn_counts = 0; /* Don't scan the l2 fib if it hasn't been instantiated yet */ if (alloc_arena (h) == 0) return 0.0; + vec_reset_length (bd_learn_counts); + vec_validate (bd_learn_counts, vec_len (l2input_main.bd_configs) - 1); + if (client) { mp = allocate_mac_evt_buf (client, cl_idx); @@ -1069,6 +1094,9 @@ l2fib_scan (vlib_main_t * vm, f64 start_time, u8 event_only) if (delta_t > 20e-6) { vlib_process_suspend (vm, 100e-6); /* suspend for 100 us */ + /* in case a new bd was created while sleeping */ + vec_validate (bd_learn_counts, + vec_len (l2input_main.bd_configs) - 1); last_start = vlib_time_now (vm); accum_t += delta_t; } @@ -1102,7 +1130,10 @@ l2fib_scan (vlib_main_t * vm, f64 start_time, u8 event_only) l2fib_entry_result_t result = {.raw = v->kvp[k].value }; if (!l2fib_entry_result_is_set_AGE_NOT (&result)) - learn_count++; + { + learn_count++; + vec_elt (bd_learn_counts, key.fields.bd_index)++; + } if (client) { @@ -1190,6 +1221,7 @@ l2fib_scan (vlib_main_t * vm, f64 start_time, u8 event_only) kv.key = key.raw; BV (clib_bihash_add_del) (&fm->mac_table, &kv, 0); learn_count--; + vec_elt (bd_learn_counts, key.fields.bd_index)--; /* * Note: we may have just freed the bucket's backing * storage, so check right here... @@ -1205,6 +1237,11 @@ l2fib_scan (vlib_main_t * vm, f64 start_time, u8 event_only) /* keep learn count consistent */ l2learn_main.global_learn_count = learn_count; + vec_foreach_index (bd_index, l2input_main.bd_configs) + { + vec_elt (l2input_main.bd_configs, bd_index).learn_count = + vec_elt (bd_learn_counts, bd_index); + } if (mp) { |