From 5f93e3b7f85e2257406cf601e5f231a872100fcf Mon Sep 17 00:00:00 2001 From: Jerome Tollet Date: Fri, 18 Dec 2020 09:44:24 +0100 Subject: l2: add per bridge domain learn limit Type: feature Signed-off-by: Jerome Tollet Change-Id: I57ed6699050445d9c9aec98eff3aab56735aca54 Signed-off-by: Jerome Tollet --- src/vnet/l2/l2_fib.c | 55 +++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 46 insertions(+), 9 deletions(-) (limited to 'src/vnet/l2/l2_fib.c') 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) { -- cgit 1.2.3-korg