#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_add_trace (vm, node, b[0], sizeof (*t));
t->sw_if_index = sw_if_index0;
t->bd_index = vnet_buffer (b[0])->l2.bd_index;
- clib_memcpy (t->src, h0->src_address, 6);
- clib_memcpy (t->dst, h0->dst_address, 6);
+ clib_memcpy_fast (t->src, h0->src_address, 6);
+ clib_memcpy_fast (t->dst, h0->dst_address, 6);
}
if (b[1]->flags & VLIB_BUFFER_IS_TRACED)
{
vlib_add_trace (vm, node, b[1], sizeof (*t));
t->sw_if_index = sw_if_index1;
t->bd_index = vnet_buffer (b[1])->l2.bd_index;
- clib_memcpy (t->src, h1->src_address, 6);
- clib_memcpy (t->dst, h1->dst_address, 6);
+ clib_memcpy_fast (t->src, h1->src_address, 6);
+ clib_memcpy_fast (t->dst, h1->dst_address, 6);
}
if (b[2]->flags & VLIB_BUFFER_IS_TRACED)
{
vlib_add_trace (vm, node, b[2], sizeof (*t));
t->sw_if_index = sw_if_index2;
t->bd_index = vnet_buffer (b[2])->l2.bd_index;
- clib_memcpy (t->src, h2->src_address, 6);
- clib_memcpy (t->dst, h2->dst_address, 6);
+ clib_memcpy_fast (t->src, h2->src_address, 6);
+ clib_memcpy_fast (t->dst, h2->dst_address, 6);
}
if (b[3]->flags & VLIB_BUFFER_IS_TRACED)
{
vlib_add_trace (vm, node, b[3], sizeof (*t));
t->sw_if_index = sw_if_index3;
t->bd_index = vnet_buffer (b[3])->l2.bd_index;
- clib_memcpy (t->src, h3->src_address, 6);
- clib_memcpy (t->dst, h3->dst_address, 6);
+ clib_memcpy_fast (t->src, h3->src_address, 6);
+ clib_memcpy_fast (t->dst, h3->dst_address, 6);
}
}
l2learn_trace_t *t = vlib_add_trace (vm, node, b[0], sizeof (*t));
t->sw_if_index = sw_if_index0;
t->bd_index = vnet_buffer (b[0])->l2.bd_index;
- clib_memcpy (t->src, h0->src_address, 6);
- clib_memcpy (t->dst, h0->dst_address, 6);
+ clib_memcpy_fast (t->src, h0->src_address, 6);
+ clib_memcpy_fast (t->dst, h0->dst_address, 6);
}
/* process 1 pkt */
}
/* *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,
*/
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;
}