32 #ifndef CLIB_MARCH_VARIANT 70 s =
format (s,
"l2-learn: sw_if_index %d dst %U src %U bd_index %d",
79 #define foreach_l2learn_error \ 80 _(L2LEARN, "L2 learn packets") \ 81 _(MISS, "L2 learn misses") \ 82 _(MAC_MOVE, "L2 mac moves") \ 83 _(MAC_MOVE_VIOLATE, "L2 mac move violations") \ 84 _(LIMIT, "L2 not learned due to limit") \ 85 _(HIT_UPDATE, "L2 learn hit updates") \ 86 _(FILTER_DROP, "L2 filter mac drops") 90 #define _(sym,str) L2LEARN_ERROR_##sym, 97 #define _(sym,string) string, 131 u32 dtime = timestamp - result0->
fields.timestamp;
137 if (l2fib_entry_result_is_set_AGE_NOT (result0))
145 if ((*count > 2) && (dtime == 1) && (dsn == 0))
148 counter_base[L2LEARN_ERROR_HIT_UPDATE] += 1;
151 else if (result0->
raw == ~0)
154 counter_base[L2LEARN_ERROR_MISS] += 1;
162 counter_base[L2LEARN_ERROR_LIMIT] += 1;
175 result0->
fields.sw_if_index = sw_if_index0;
177 l2fib_entry_result_set_LRN_EVT (result0);
179 l2fib_entry_result_clear_LRN_EVT (result0);
184 if (l2fib_entry_result_is_set_FILTER (result0))
188 b0->
error = node->
errors[L2LEARN_ERROR_FILTER_DROP];
193 if (l2fib_entry_result_is_set_STATIC (result0))
199 b0->
error = node->
errors[L2LEARN_ERROR_MAC_MOVE_VIOLATE];
208 result0->
fields.sw_if_index = sw_if_index0;
209 if (l2fib_entry_result_is_set_AGE_NOT (result0))
213 l2fib_entry_result_clear_AGE_NOT (result0);
217 (L2FIB_ENTRY_RESULT_FLAG_LRN_EVT |
218 L2FIB_ENTRY_RESULT_FLAG_LRN_MOV));
221 (L2FIB_ENTRY_RESULT_FLAG_LRN_EVT |
222 L2FIB_ENTRY_RESULT_FLAG_LRN_MOV));
223 counter_base[L2LEARN_ERROR_MAC_MOVE] += 1;
227 result0->
fields.timestamp = timestamp;
230 BVT (clib_bihash_kv) kv;
232 kv.value = result0->
raw;
236 cached_key->
raw = ~0;
264 cached_result.
raw = ~0;
268 u32 sw_if_index0, sw_if_index1, sw_if_index2, sw_if_index3;
272 u32 bucket0, bucket1, bucket2, bucket3;
304 if (b[0]->
flags & VLIB_BUFFER_IS_TRACED)
313 if (b[1]->
flags & VLIB_BUFFER_IS_TRACED)
322 if (b[2]->
flags & VLIB_BUFFER_IS_TRACED)
331 if (b[3]->
flags & VLIB_BUFFER_IS_TRACED)
344 L2LEARN_ERROR_L2LEARN, 4);
355 &key0, &key1, &key2, &key3,
356 &bucket0, &bucket1, &bucket2, &bucket3,
357 &result0, &result1, &result2, &result3);
360 b[0], sw_if_index0, &key0, &cached_key,
361 &count, &result0, next, timestamp);
364 b[1], sw_if_index1, &key1, &cached_key,
365 &count, &result1, next + 1, timestamp);
368 b[2], sw_if_index2, &key2, &cached_key,
369 &count, &result2, next + 2, timestamp);
372 b[3], sw_if_index3, &key3, &cached_key,
373 &count, &result3, next + 3, timestamp);
403 L2LEARN_ERROR_L2LEARN, 1);
408 &key0, &bucket0, &result0);
411 b[0], sw_if_index0, &key0, &cached_key,
412 &count, &result0, next, timestamp);
435 .vector_size =
sizeof (
u32),
452 #ifndef CLIB_MARCH_VARIANT 469 mp->mac_table = get_mac_table ();
530 .path =
"set interface l2 learn",
531 .short_help =
"set interface l2 learn <interface> [disable]",
vnet_main_t * vnet_get_main(void)
static f64 vlib_time_now(vlib_main_t *vm)
static_always_inline void l2learn_process(vlib_node_runtime_t *node, l2learn_main_t *msm, u64 *counter_base, vlib_buffer_t *b0, u32 sw_if_index0, l2fib_entry_key_t *key0, l2fib_entry_key_t *cached_key, u32 *count, l2fib_entry_result_t *result0, u16 *next0, u8 timestamp)
Perform learning on one packet based on the mac table lookup result.
clib_error_t * l2learn_init(vlib_main_t *vm)
unformat_function_t unformat_vnet_sw_interface
#define VLIB_NODE_FN(node)
vlib_error_t * errors
Vector of errors for this node.
static u32 vnet_l2_feature_next(vlib_buffer_t *b, u32 *next_nodes, u32 feat_bit)
Return the graph node index for the feature corresponding to the next set bit after clearing the curr...
l2learn_main_t l2learn_main
#define static_always_inline
u8 * format_ethernet_address(u8 *s, va_list *args)
int clib_bihash_add_del(clib_bihash *h, clib_bihash_kv *add_v, int is_add)
Add or delete a (key,value) pair from a bi-hash table.
#define VLIB_INIT_FUNCTION(x)
struct l2fib_entry_result_t_::@243::@245 fields
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
static void l2fib_entry_result_clear_bits(l2fib_entry_result_t *r, l2fib_entry_result_flags_t bits)
#define clib_error_return(e, args...)
static char * l2learn_error_strings[]
vlib_error_main_t error_main
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
#define VLIB_CONFIG_FUNCTION(x, n,...)
static_always_inline uword l2learn_node_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, int do_trace)
static u8 * format_l2learn_trace(u8 *s, va_list *args)
vlib_error_t error
Error code for buffers to be enqueued to error handler.
static void vlib_node_increment_counter(vlib_main_t *vm, u32 node_index, u32 counter_index, u64 increment)
#define VLIB_REGISTER_NODE(x,...)
#define CLIB_PREFETCH(addr, size, type)
static_always_inline void vlib_buffer_enqueue_to_next(vlib_main_t *vm, vlib_node_runtime_t *node, u32 *buffers, u16 *nexts, uword count)
static void feat_bitmap_init_next_nodes(vlib_main_t *vm, u32 node_index, u32 num_features, char **feat_names, u32 *next_nodes)
Initialize the feature next-node indexes of a graph node.
#define foreach_l2learn_error
static clib_error_t * l2learn_config(vlib_main_t *vm, unformat_input_t *input)
#define clib_memcpy(a, b, c)
static clib_error_t * int_learn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Set subinterface learn enable/disable.
u32 feat_next_node_index[32]
#define VLIB_CLI_COMMAND(x,...)
struct l2fib_entry_key_t::@235::@237 fields
static void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
struct _vlib_node_registration vlib_node_registration_t
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
static foreach_l2fib_entry_result_attr void l2fib_entry_result_set_bits(l2fib_entry_result_t *r, l2fib_entry_result_flags_t bits)
static vlib_node_t * vlib_get_node(vlib_main_t *vm, u32 i)
Get vlib node by index.
static_always_inline void l2fib_lookup_1(BVT(clib_bihash)*mac_table, l2fib_entry_key_t *cached_key, l2fib_entry_result_t *cached_result, u8 *mac0, u16 bd_index0, l2fib_entry_key_t *key0, u32 *bucket0, l2fib_entry_result_t *result0)
Lookup the entry for mac and bd_index in the mac table for 1 packet.
static_always_inline void vlib_get_buffers(vlib_main_t *vm, u32 *bi, vlib_buffer_t **b, int count)
Translate array of buffer indices into buffer pointers.
#define VLIB_NODE_FLAG_TRACE
static_always_inline void l2fib_lookup_4(BVT(clib_bihash)*mac_table, l2fib_entry_key_t *cached_key, l2fib_entry_result_t *cached_result, const u8 *mac0, const u8 *mac1, const u8 *mac2, const u8 *mac3, u16 bd_index0, u16 bd_index1, u16 bd_index2, u16 bd_index3, l2fib_entry_key_t *key0, l2fib_entry_key_t *key1, l2fib_entry_key_t *key2, l2fib_entry_key_t *key3, u32 *bucket0, u32 *bucket1, u32 *bucket2, u32 *bucket3, l2fib_entry_result_t *result0, l2fib_entry_result_t *result1, l2fib_entry_result_t *result2, l2fib_entry_result_t *result3)
#define CLIB_CACHE_LINE_BYTES
static vlib_node_registration_t l2learn_node
(constructor) VLIB_REGISTER_NODE (l2learn_node)
#define L2LEARN_DEFAULT_LIMIT