From b54d081873ac975e06be2569a17e6150779e3018 Mon Sep 17 00:00:00 2001 From: Neale Ranns Date: Thu, 6 Sep 2018 06:22:56 -0700 Subject: [PATCH] L2-FIB: replace bit-fields with flags Change-Id: Ic31da442a0e0477569d53b4a72627bbb25e93365 Signed-off-by: Neale Ranns --- src/vnet/l2/l2_api.c | 16 ++++++---- src/vnet/l2/l2_fib.c | 63 ++++++++++++++++++------------------ src/vnet/l2/l2_fib.h | 86 +++++++++++++++++++++++++++++++++++++++----------- src/vnet/l2/l2_fwd.c | 6 ++-- src/vnet/l2/l2_input.c | 4 ++- src/vnet/l2/l2_learn.c | 26 ++++++++++----- 6 files changed, 132 insertions(+), 69 deletions(-) diff --git a/src/vnet/l2/l2_api.c b/src/vnet/l2/l2_api.c index 39e52b1ecef..088e490ff14 100644 --- a/src/vnet/l2/l2_api.c +++ b/src/vnet/l2/l2_api.c @@ -142,9 +142,9 @@ send_l2fib_table_entry (vpe_api_main_t * am, clib_memcpy (mp->mac, l2fe_key->fields.mac, 6); mp->sw_if_index = ntohl (l2fe_res->fields.sw_if_index); - mp->static_mac = l2fe_res->fields.static_mac; - mp->filter_mac = l2fe_res->fields.filter; - mp->bvi_mac = l2fe_res->fields.bvi; + mp->static_mac = l2fib_entry_result_is_set_STATIC (l2fe_res); + mp->filter_mac = l2fib_entry_result_is_set_FILTER (l2fe_res); + mp->bvi_mac = l2fib_entry_result_is_set_BVI (l2fe_res); mp->context = context; vl_api_send_msg (reg, (u8 *) mp); @@ -215,6 +215,7 @@ vl_api_l2fib_add_del_t_handler (vl_api_l2fib_add_del_t * mp) l2fib_add_filter_entry (mac, bd_index); else { + l2fib_entry_result_flags_t flags = L2FIB_ENTRY_RESULT_FLAG_NONE; u32 sw_if_index = ntohl (mp->sw_if_index); VALIDATE_SW_IF_INDEX (mp); if (vec_len (l2im->configs) <= sw_if_index) @@ -232,10 +233,11 @@ vl_api_l2fib_add_del_t_handler (vl_api_l2fib_add_del_t * mp) goto bad_sw_if_index; } } - u8 static_mac = mp->static_mac ? 1 : 0; - u8 bvi_mac = mp->bvi_mac ? 1 : 0; - l2fib_add_fwd_entry (mac, bd_index, sw_if_index, static_mac, - bvi_mac); + if (mp->static_mac) + flags |= L2FIB_ENTRY_RESULT_FLAG_STATIC; + if (mp->bvi_mac) + flags |= L2FIB_ENTRY_RESULT_FLAG_BVI; + l2fib_add_entry (mac, bd_index, sw_if_index, flags); } } else diff --git a/src/vnet/l2/l2_fib.c b/src/vnet/l2/l2_fib.c index 085ac8c3256..60d0db56d9d 100644 --- a/src/vnet/l2/l2_fib.c +++ b/src/vnet/l2/l2_fib.c @@ -163,16 +163,16 @@ l2fib_show_walk_cb (BVT (clib_bihash_kv) * kvp, void *arg) { u8 *s = NULL; - if (ctx->learn && result.fields.age_not) + if (ctx->learn && l2fib_entry_result_is_set_AGE_NOT (&result)) return; /* skip provisioned macs */ - if (ctx->add && !result.fields.age_not) + if (ctx->add && !l2fib_entry_result_is_set_AGE_NOT (&result)) return; /* skip learned macs */ bd_config = vec_elt_at_index (l2input_main.bd_configs, key.fields.bd_index); - if (result.fields.age_not) + if (l2fib_entry_result_is_set_AGE_NOT (&result)) s = format (s, "no"); else if (bd_config->mac_age == 0) s = format (s, "-"); @@ -189,10 +189,10 @@ l2fib_show_walk_cb (BVT (clib_bihash_kv) * kvp, void *arg) key.fields.bd_index, result.fields.sw_if_index == ~0 ? -1 : result.fields.sw_if_index, - result.fields.sn.bd, result.fields.sn.swif, - s, result.fields.static_mac ? "*" : "-", - result.fields.filter ? "*" : "-", - result.fields.bvi ? "*" : "-", + result.fields.sn.bd, result.fields.sn.swif, s, + l2fib_entry_result_is_set_STATIC (&result) ? "*" : "-", + l2fib_entry_result_is_set_FILTER (&result) ? "*" : "-", + l2fib_entry_result_is_set_BVI (&result) ? "*" : "-", format_vnet_sw_if_index_name_with_NA, ctx->vnm, result.fields.sw_if_index); vec_free (s); @@ -377,7 +377,7 @@ l2fib_cur_seq_num (u32 bd_index, u32 sw_if_index) */ void l2fib_add_entry (u8 * mac, u32 bd_index, - u32 sw_if_index, u8 static_mac, u8 filter_mac, u8 bvi_mac) + u32 sw_if_index, l2fib_entry_result_flags_t flags) { l2fib_entry_key_t key; l2fib_entry_result_t result; @@ -394,17 +394,18 @@ l2fib_add_entry (u8 * mac, u32 bd_index, { /* decrement counter if overwriting a learned mac */ result.raw = kv.value; - if ((result.fields.age_not == 0) && (lm->global_learn_count)) + if ((!l2fib_entry_result_is_set_AGE_NOT (&result)) + && (lm->global_learn_count)) lm->global_learn_count--; } /* set up result */ result.raw = 0; /* clear all fields */ result.fields.sw_if_index = sw_if_index; - result.fields.static_mac = static_mac; - result.fields.filter = filter_mac; - result.fields.bvi = bvi_mac; - result.fields.age_not = 1; /* no aging for provisioned entry */ + result.fields.flags = flags; + + /* no aging for provisioned entry */ + l2fib_entry_result_set_AGE_NOT (&result); kv.key = key.raw; kv.value = result.raw; @@ -430,9 +431,10 @@ l2fib_add (vlib_main_t * vm, u32 bd_id; u32 bd_index; u32 sw_if_index = ~0; - u32 static_mac = 0; - u32 bvi_mac = 0; uword *p; + l2fib_entry_result_flags_t flags; + + flags = L2FIB_ENTRY_RESULT_FLAG_NONE; if (!unformat (input, "%U", unformat_ethernet_address, mac)) { @@ -470,14 +472,9 @@ l2fib_add (vlib_main_t * vm, } if (unformat (input, "static")) - { - static_mac = 1; - } + flags |= L2FIB_ENTRY_RESULT_FLAG_STATIC; else if (unformat (input, "bvi")) - { - bvi_mac = 1; - static_mac = 1; - } + flags |= (L2FIB_ENTRY_RESULT_FLAG_STATIC | L2FIB_ENTRY_RESULT_FLAG_BVI); if (vec_len (l2input_main.configs) <= sw_if_index) { @@ -486,7 +483,7 @@ l2fib_add (vlib_main_t * vm, goto done; } - l2fib_add_fwd_entry (mac, bd_index, sw_if_index, static_mac, bvi_mac); + l2fib_add_entry (mac, bd_index, sw_if_index, flags); done: return error; @@ -536,7 +533,6 @@ l2fib_test_command_fn (vlib_main_t * vm, u8 mac[6], save_mac[6]; u32 bd_index = 0; u32 sw_if_index = 8; - u32 bvi_mac = 0; u32 is_add = 0; u32 is_del = 0; u32 is_check = 0; @@ -573,7 +569,8 @@ l2fib_test_command_fn (vlib_main_t * vm, { for (i = 0; i < count; i++) { - l2fib_add_fwd_entry (mac, bd_index, sw_if_index, *mac, bvi_mac); + l2fib_add_entry (mac, bd_index, sw_if_index, + L2FIB_ENTRY_RESULT_FLAG_NONE); incr_mac_address (mac); } } @@ -682,7 +679,8 @@ l2fib_del_entry (u8 * mac, u32 bd_index, u32 sw_if_index) return 1; /* decrement counter if dynamically learned mac */ - if ((result.fields.age_not == 0) && (l2learn_main.global_learn_count)) + if ((!l2fib_entry_result_is_set_AGE_NOT (&result)) && + (l2learn_main.global_learn_count)) l2learn_main.global_learn_count--; /* Remove entry from hash table */ @@ -1025,7 +1023,7 @@ l2fib_scan (vlib_main_t * vm, f64 start_time, u8 event_only) l2fib_entry_key_t key = {.raw = v->kvp[k].key }; l2fib_entry_result_t result = {.raw = v->kvp[k].value }; - if (result.fields.age_not == 0) + if (!l2fib_entry_result_is_set_AGE_NOT (&result)) learn_count++; if (client) @@ -1049,18 +1047,19 @@ l2fib_scan (vlib_main_t * vm, f64 start_time, u8 event_only) evt_idx = 0; } - if (result.fields.lrn_evt) + if (l2fib_entry_result_is_set_LRN_EVT (&result)) { /* copy mac entry to event msg */ clib_memcpy (mp->mac[evt_idx].mac_addr, key.fields.mac, 6); - mp->mac[evt_idx].action = result.fields.lrn_mov ? + mp->mac[evt_idx].action = + l2fib_entry_result_is_set_LRN_MOV (&result) ? MAC_EVENT_ACTION_MOVE : MAC_EVENT_ACTION_ADD; mp->mac[evt_idx].sw_if_index = htonl (result.fields.sw_if_index); /* clear event bits and update mac entry */ - result.fields.lrn_evt = 0; - result.fields.lrn_mov = 0; + l2fib_entry_result_clear_LRN_EVT (&result); + l2fib_entry_result_clear_LRN_MOV (&result); BVT (clib_bihash_kv) kv; kv.key = key.raw; kv.value = result.raw; @@ -1070,7 +1069,7 @@ l2fib_scan (vlib_main_t * vm, f64 start_time, u8 event_only) } } - if (event_only || result.fields.age_not) + if (event_only || l2fib_entry_result_is_set_AGE_NOT (&result)) continue; /* skip aging - static_mac alsways age_not */ /* start aging processing */ diff --git a/src/vnet/l2/l2_fib.h b/src/vnet/l2/l2_fib.h index 50fd474087b..a958023eaea 100644 --- a/src/vnet/l2/l2_fib.h +++ b/src/vnet/l2/l2_fib.h @@ -102,24 +102,44 @@ typedef struct }; } l2fib_seq_num_t; +/** + * Flags associated with an L2 Fib Entry + * - static mac, no MAC move + * - not subject to age + * - mac is for a bridged virtual interface + * - drop packets to/from this mac + * - MAC learned to be sent in L2 MAC event + * -MAC learned is a MAC move + */ +#define foreach_l2fib_entry_result_attr \ + _(STATIC, 0, "static") \ + _(AGE_NOT, 1, "age-not") \ + _(BVI, 2, "bvi") \ + _(FILTER, 3, "filter") \ + _(LRN_EVT, 4, "learn-event") \ + _(LRN_MOV, 5, "learn-move") + +typedef enum l2fib_entry_result_flags_t_ +{ + L2FIB_ENTRY_RESULT_FLAG_NONE = 0, +#define _(a,v,s) L2FIB_ENTRY_RESULT_FLAG_##a = (1 << v), + foreach_l2fib_entry_result_attr +#undef _ +} __attribute__ ((packed)) l2fib_entry_result_flags_t; + +STATIC_ASSERT_SIZEOF (l2fib_entry_result_flags_t, 1); + /* * The l2fib entry results */ -typedef struct +typedef struct l2fib_entry_result_t_ { union { struct { u32 sw_if_index; /* output sw_if_index (L3 intf if bvi==1) */ - - u8 static_mac:1; /* static mac, no MAC move */ - u8 age_not:1; /* not subject to age */ - u8 bvi:1; /* mac is for a bridged virtual interface */ - u8 filter:1; /* drop packets to/from this mac */ - u8 lrn_evt:1; /* MAC learned to be sent in L2 MAC event */ - u8 lrn_mov:1; /* MAC learned is a MAC move */ - u8 unused:2; + l2fib_entry_result_flags_t flags; u8 timestamp; /* timestamp for aging */ l2fib_seq_num_t sn; /* bd/int seq num */ @@ -130,6 +150,41 @@ typedef struct STATIC_ASSERT_SIZEOF (l2fib_entry_result_t, 8); +#define _(a,v,s) \ + always_inline int \ + l2fib_entry_result_is_set_##a (const l2fib_entry_result_t *r) { \ + return (r->fields.flags & L2FIB_ENTRY_RESULT_FLAG_##a); \ + } +foreach_l2fib_entry_result_attr +#undef _ +#define _(a,v,s) \ + always_inline void \ + l2fib_entry_result_set_##a (l2fib_entry_result_t *r) { \ + r->fields.flags |= L2FIB_ENTRY_RESULT_FLAG_##a; \ + } + foreach_l2fib_entry_result_attr +#undef _ +#define _(a,v,s) \ + always_inline void \ + l2fib_entry_result_clear_##a (l2fib_entry_result_t *r) { \ + r->fields.flags &= ~L2FIB_ENTRY_RESULT_FLAG_##a; \ + } + foreach_l2fib_entry_result_attr +#undef _ + static inline void +l2fib_entry_result_set_bits (l2fib_entry_result_t * r, + l2fib_entry_result_flags_t bits) +{ + r->fields.flags |= bits; +} + +static inline void +l2fib_entry_result_clear_bits (l2fib_entry_result_t * r, + l2fib_entry_result_flags_t bits) +{ + r->fields.flags &= ~bits; +} + /* L2 MAC event entry action enums (see mac_entry definition in l2.api) */ typedef enum { @@ -387,19 +442,14 @@ void l2fib_clear_table (void); void l2fib_add_entry (u8 * mac, u32 bd_index, - u32 sw_if_index, u8 static_mac, u8 drop_mac, u8 bvi_mac); - -static inline void -l2fib_add_fwd_entry (u8 * mac, u32 bd_index, u32 sw_if_index, u8 static_mac, - u8 bvi_mac) -{ - l2fib_add_entry (mac, bd_index, sw_if_index, static_mac, 0, bvi_mac); -} + u32 sw_if_index, l2fib_entry_result_flags_t flags); static inline void l2fib_add_filter_entry (u8 * mac, u32 bd_index) { - l2fib_add_entry (mac, bd_index, ~0, 1, 1, 0); + l2fib_add_entry (mac, bd_index, ~0, + (L2FIB_ENTRY_RESULT_FLAG_FILTER | + L2FIB_ENTRY_RESULT_FLAG_STATIC)); } u32 l2fib_del_entry (u8 * mac, u32 bd_index, u32 sw_if_index); diff --git a/src/vnet/l2/l2_fwd.c b/src/vnet/l2/l2_fwd.c index c1b8519a832..8c03683b133 100644 --- a/src/vnet/l2/l2_fwd.c +++ b/src/vnet/l2/l2_fwd.c @@ -145,7 +145,7 @@ l2fwd_process (vlib_main_t * vm, int l2fib_seq_num_valid = 1; /* check l2fib seq num for stale entries */ - if (!result0->fields.age_not) + if (!l2fib_entry_result_is_set_AGE_NOT (result0)) { l2fib_seq_num_t in_sn = {.as_u16 = vnet_buffer (b0)->l2.l2fib_sn }; l2fib_seq_num_t expected_sn = { @@ -168,13 +168,13 @@ l2fwd_process (vlib_main_t * vm, *next0 = L2FWD_NEXT_DROP; } /* perform filter check */ - else if (PREDICT_FALSE (result0->fields.filter)) + else if (PREDICT_FALSE (l2fib_entry_result_is_set_FILTER (result0))) { b0->error = node->errors[L2FWD_ERROR_FILTER_DROP]; *next0 = L2FWD_NEXT_DROP; } /* perform BVI check */ - else if (PREDICT_FALSE (result0->fields.bvi)) + else if (PREDICT_FALSE (l2fib_entry_result_is_set_BVI (result0))) { u32 rc; rc = l2_to_bvi (vm, diff --git a/src/vnet/l2/l2_input.c b/src/vnet/l2/l2_input.c index feab40c2cd3..fd6f9eb462c 100644 --- a/src/vnet/l2/l2_input.c +++ b/src/vnet/l2/l2_input.c @@ -684,7 +684,9 @@ set_int_l2_mode (vlib_main_t * vm, vnet_main_t * vnet_main, /* */ config->bvi = 1; /* create the l2fib entry for the bvi interface */ - l2fib_add_fwd_entry (hi->hw_address, bd_index, sw_if_index, 1, 1); /* static + bvi */ + l2fib_add_entry (hi->hw_address, bd_index, sw_if_index, + L2FIB_ENTRY_RESULT_FLAG_BVI | + L2FIB_ENTRY_RESULT_FLAG_STATIC); /* Disable learning by default. no use since l2fib entry is static. */ config->feature_bitmap &= ~L2INPUT_FEAT_LEARN; diff --git a/src/vnet/l2/l2_learn.c b/src/vnet/l2/l2_learn.c index 04e0721ebeb..eff5822cb5f 100644 --- a/src/vnet/l2/l2_learn.c +++ b/src/vnet/l2/l2_learn.c @@ -132,7 +132,7 @@ l2learn_process (vlib_node_runtime_t * node, if (PREDICT_TRUE (check == 0)) return; /* MAC entry up to date */ - if (result0->fields.age_not) + if (l2fib_entry_result_is_set_AGE_NOT (result0)) return; /* Static MAC always age_not */ if (msm->global_learn_count > msm->global_learn_limit) return; /* Above learn limit - do not update */ @@ -171,12 +171,15 @@ l2learn_process (vlib_node_runtime_t * node, msm->global_learn_count++; result0->raw = 0; /* clear all fields */ result0->fields.sw_if_index = sw_if_index0; - result0->fields.lrn_evt = (msm->client_pid != 0); + if (msm->client_pid != 0) + l2fib_entry_result_set_LRN_EVT (result0); + else + l2fib_entry_result_clear_LRN_EVT (result0); } else { /* Entry in L2FIB with different sw_if_index - mac move or filter */ - if (result0->fields.filter) + if (l2fib_entry_result_is_set_FILTER (result0)) { ASSERT (result0->fields.sw_if_index == ~0); /* drop packet because lookup matched a filter mac entry */ @@ -185,7 +188,7 @@ l2learn_process (vlib_node_runtime_t * node, return; } - if (result0->fields.static_mac) + if (l2fib_entry_result_is_set_STATIC (result0)) { /* * Don't overwrite a static mac @@ -201,13 +204,20 @@ l2learn_process (vlib_node_runtime_t * node, * TODO: check global/bridge domain/interface learn limits */ result0->fields.sw_if_index = sw_if_index0; - if (result0->fields.age_not) /* The mac was provisioned */ + if (l2fib_entry_result_is_set_AGE_NOT (result0)) { + /* The mac was provisioned */ msm->global_learn_count++; - result0->fields.age_not = 0; + l2fib_entry_result_clear_AGE_NOT (result0); } - result0->fields.lrn_evt = (msm->client_pid != 0); - result0->fields.lrn_mov = (msm->client_pid != 0); + if (msm->client_pid != 0) + l2fib_entry_result_set_bits (result0, + (L2FIB_ENTRY_RESULT_FLAG_LRN_EVT | + L2FIB_ENTRY_RESULT_FLAG_LRN_MOV)); + else + l2fib_entry_result_clear_bits (result0, + (L2FIB_ENTRY_RESULT_FLAG_LRN_EVT | + L2FIB_ENTRY_RESULT_FLAG_LRN_MOV)); counter_base[L2LEARN_ERROR_MAC_MOVE] += 1; } -- 2.16.6