#include <vlib/vlib.h>
#include <vnet/vnet.h>
-#include <vnet/pg/pg.h>
#include <vnet/ethernet/ethernet.h>
#include <vlib/cli.h>
return s;
}
-static vlib_node_registration_t l2learn_node;
+extern vlib_node_registration_t l2learn_node;
#define foreach_l2learn_error \
_(L2LEARN, "L2 learn packets") \
u32 * count,
l2fib_entry_result_t * result0, u16 * next0, u8 timestamp)
{
+ l2_bridge_domain_t *bd_config =
+ vec_elt_at_index (l2input_main.bd_configs, vnet_buffer (b0)->l2.bd_index);
/* Set up the default next node (typically L2FWD) */
*next0 = vnet_l2_feature_next (b0, msm->feat_next_node_index,
L2INPUT_FEAT_LEARN);
{
/* Entry in L2FIB with matching sw_if_index matched - normal fast path */
u32 dtime = timestamp - result0->fields.timestamp;
- u32 dsn = result0->fields.sn.as_u16 - vnet_buffer (b0)->l2.l2fib_sn;
+ u32 dsn = (result0->fields.sn - vnet_buffer (b0)->l2.l2fib_sn);
u32 check = (dtime && vnet_buffer (b0)->l2.bd_age) || dsn;
if (PREDICT_TRUE (check == 0))
return; /* Static MAC always age_not */
if (msm->global_learn_count > msm->global_learn_limit)
return; /* Above learn limit - do not update */
+ if (bd_config->learn_count > bd_config->learn_limit)
+ return; /* Above bridge domain learn limit - do not update */
/* Limit updates per l2-learn node call to avoid prolonged update burst
* as dtime advance over 1 minute mark, unless more than 1 min behind
/* Entry not in L2FIB - add it */
counter_base[L2LEARN_ERROR_MISS] += 1;
- if (msm->global_learn_count >= msm->global_learn_limit)
+ if ((msm->global_learn_count >= msm->global_learn_limit) ||
+ (bd_config->learn_count >= bd_config->learn_limit))
{
/*
* Global limit reached. Do not learn the mac but forward the packet.
return;
/* It is ok to learn */
+ /* 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 */
msm->global_learn_count++;
+ bd_config->learn_count++;
result0->raw = 0; /* clear all fields */
result0->fields.sw_if_index = sw_if_index0;
if (msm->client_pid != 0)
if (l2fib_entry_result_is_set_AGE_NOT (result0))
{
/* The mac was provisioned */
+ /* 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 */
msm->global_learn_count++;
+ bd_config->learn_count++;
+
l2fib_entry_result_clear_AGE_NOT (result0);
}
if (msm->client_pid != 0)
/* Update the entry */
result0->fields.timestamp = timestamp;
- result0->fields.sn.as_u16 = vnet_buffer (b0)->l2.l2fib_sn;
+ result0->fields.sn = vnet_buffer (b0)->l2.l2fib_sn;
BVT (clib_bihash_kv) kv;
kv.key = key0->raw;
vlib_prefetch_buffer_header (b[6], LOAD);
vlib_prefetch_buffer_header (b[7], LOAD);
- CLIB_PREFETCH (b[4]->data, CLIB_CACHE_LINE_BYTES, LOAD);
- CLIB_PREFETCH (b[5]->data, CLIB_CACHE_LINE_BYTES, LOAD);
- CLIB_PREFETCH (b[6]->data, CLIB_CACHE_LINE_BYTES, LOAD);
- CLIB_PREFETCH (b[7]->data, CLIB_CACHE_LINE_BYTES, LOAD);
+ clib_prefetch_load (b[4]->data);
+ clib_prefetch_load (b[5]->data);
+ clib_prefetch_load (b[6]->data);
+ clib_prefetch_load (b[7]->data);
}
/* RX interface handles */
return l2learn_node_inline (vm, node, frame, 0 /* do_trace */ );
}
-/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (l2learn_node,static) = {
+VLIB_REGISTER_NODE (l2learn_node) = {
.name = "l2-learn",
.vector_size = sizeof (u32),
.format_trace = format_l2learn_trace,
[L2LEARN_NEXT_L2FWD] = "l2-fwd",
},
};
-/* *INDENT-ON* */
#ifndef CLIB_MARCH_VARIANT
clib_error_t *
*/
mp->global_learn_limit = L2LEARN_DEFAULT_LIMIT;
+ /*
+ * Set the default number of dynamically learned macs to the number
+ * of buckets.
+ */
+ mp->bd_default_learn_limit = L2LEARN_DEFAULT_LIMIT;
return 0;
}
* Example of how to disable learning:
* @cliexcmd{set interface l2 learn GigabitEthernet0/8/0 disable}
?*/
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (int_learn_cli, static) = {
.path = "set interface l2 learn",
.short_help = "set interface l2 learn <interface> [disable]",
.function = int_learn,
};
-/* *INDENT-ON* */
static clib_error_t *