l2fib_main_t l2fib_main;
+static void
+incr_mac_address (u8 * mac)
+{
+ u64 tmp = *((u64 *) mac);
+ tmp = clib_net_to_host_u64 (tmp);
+ tmp += 1 << 16; /* skip unused (least significant) octets */
+ tmp = clib_host_to_net_u64 (tmp);
+
+ clib_memcpy (mac, &tmp, 6);
+}
+
/** Format sw_if_index. If the value is ~0, use the text "N/A" */
u8 *
format_vnet_sw_if_index_name_with_NA (u8 * s, va_list * args)
* If the entry already exists then overwrite it
*/
void
-l2fib_add_entry (u64 mac, u32 bd_index,
+l2fib_add_entry (u8 * mac, u32 bd_index,
u32 sw_if_index, u8 static_mac, u8 filter_mac, u8 bvi_mac)
{
l2fib_entry_key_t key;
BVT (clib_bihash_kv) kv;
/* set up key */
- key.raw = l2fib_make_key ((u8 *) & mac, bd_index);
+ key.raw = l2fib_make_key (mac, bd_index);
/* check if entry alread exist */
if (BV (clib_bihash_search) (&fm->mac_table, &kv, &kv))
bd_main_t *bdm = &bd_main;
vnet_main_t *vnm = vnet_get_main ();
clib_error_t *error = 0;
- u64 mac;
+ u8 mac[6];
u32 bd_id;
u32 bd_index;
u32 sw_if_index = ~0;
u32 bvi_mac = 0;
uword *p;
- if (!unformat_user (input, unformat_ethernet_address, &mac))
+ if (!unformat (input, "%U", unformat_ethernet_address, mac))
{
error = clib_error_return (0, "expected mac address `%U'",
format_unformat_error, input);
unformat_input_t * input, vlib_cli_command_t * cmd)
{
clib_error_t *error = 0;
- u64 mac, save_mac;
+ u8 mac[6], save_mac[6];
u32 bd_index = 0;
u32 sw_if_index = 8;
u32 bvi_mac = 0;
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
{
- if (unformat (input, "mac %U", unformat_ethernet_address, &mac))
+ if (unformat (input, "mac %U", unformat_ethernet_address, mac))
mac_set = 1;
else if (unformat (input, "add"))
is_add = 1;
return clib_error_return (0,
"noop: pick at least one of (add,del,check)");
- save_mac = mac;
+ clib_memcpy (save_mac, mac, 6);
if (is_add)
{
for (i = 0; i < count; i++)
{
- u64 tmp;
- l2fib_add_fwd_entry (mac, bd_index, sw_if_index, mac, bvi_mac);
- tmp = clib_net_to_host_u64 (mac);
- tmp >>= 16;
- tmp++;
- tmp <<= 16;
- mac = clib_host_to_net_u64 (tmp);
+ l2fib_add_fwd_entry (mac, bd_index, sw_if_index, *mac, bvi_mac);
+ incr_mac_address (mac);
}
}
BVT (clib_bihash_kv) kv;
l2fib_main_t *mp = &l2fib_main;
- mac = save_mac;
+ clib_memcpy (mac, save_mac, 6);
for (i = 0; i < count; i++)
{
- u64 tmp;
- kv.key = l2fib_make_key ((u8 *) & mac, bd_index);
+ kv.key = l2fib_make_key (mac, bd_index);
if (BV (clib_bihash_search) (&mp->mac_table, &kv, &kv))
{
- clib_warning ("key %U AWOL", format_ethernet_address, &mac);
+ clib_warning ("key %U AWOL", format_ethernet_address, mac);
break;
}
- tmp = clib_net_to_host_u64 (mac);
- tmp >>= 16;
- tmp++;
- tmp <<= 16;
- mac = clib_host_to_net_u64 (tmp);
+ incr_mac_address (mac);
}
}
if (is_del)
{
+ clib_memcpy (mac, save_mac, 6);
+
for (i = 0; i < count; i++)
{
- u64 tmp;
-
l2fib_del_entry (mac, bd_index);
-
- tmp = clib_net_to_host_u64 (mac);
- tmp >>= 16;
- tmp++;
- tmp <<= 16;
- mac = clib_host_to_net_u64 (tmp);
+ incr_mac_address (mac);
}
}
* Return 0 if the entry was deleted, or 1 if it was not found
*/
u32
-l2fib_del_entry (u64 mac, u32 bd_index)
+l2fib_del_entry (u8 * mac, u32 bd_index)
{
- return l2fib_del_entry_by_key (l2fib_make_key ((u8 *) & mac, bd_index));
+ return l2fib_del_entry_by_key (l2fib_make_key (mac, bd_index));
}
/**
{
bd_main_t *bdm = &bd_main;
clib_error_t *error = 0;
- u64 mac;
+ u8 mac[6];
u32 bd_id;
u32 bd_index;
uword *p;
- if (!unformat_user (input, unformat_ethernet_address, &mac))
+ if (!unformat (input, "%U", unformat_ethernet_address, mac))
{
error = clib_error_return (0, "expected mac address `%U'",
format_unformat_error, input);
void
l2fib_start_ager_scan (vlib_main_t * vm)
{
- l2_bridge_domain_t *bd_config;
- int enable = 0;
+ uword evt = L2_MAC_AGE_PROCESS_EVENT_ONE_PASS;
/* check if there is at least one bd with mac aging enabled */
+ l2_bridge_domain_t *bd_config;
vec_foreach (bd_config, l2input_main.bd_configs)
+ {
if (bd_config->bd_id != ~0 && bd_config->mac_age != 0)
- enable = 1;
+ {
+ evt = L2_MAC_AGE_PROCESS_EVENT_START;
+ break;
+ }
+ }
vlib_process_signal_event (vm, l2fib_mac_age_scanner_process_node.index,
- enable ? L2_MAC_AGE_PROCESS_EVENT_START :
- L2_MAC_AGE_PROCESS_EVENT_ONE_PASS, 0);
+ evt, 0);
}
/**
if (result.fields.age_not == 0)
learn_count++;
- if (PREDICT_FALSE (evt_idx >= fm->max_macs_in_event))
+ if (client)
{
- /* event message full, send it and start a new one */
- if (q && (q->cursize < q->maxsize))
+ if (PREDICT_FALSE (evt_idx >= fm->max_macs_in_event))
{
- mp->n_macs = htonl (evt_idx);
- vl_msg_api_send_shmem (q, (u8 *) & mp);
- mp = allocate_mac_evt_buf (client, cl_idx);
+ /* event message full, send it and start a new one */
+ if (q && (q->cursize < q->maxsize))
+ {
+ mp->n_macs = htonl (evt_idx);
+ vl_msg_api_send_shmem (q, (u8 *) & mp);
+ mp = allocate_mac_evt_buf (client, cl_idx);
+ }
+ else
+ {
+ if (q)
+ clib_warning ("MAC event to pid %d queue stuffed!"
+ " %d MAC entries lost", client,
+ evt_idx);
+ }
+ evt_idx = 0;
}
- else
- {
- clib_warning ("MAC event to pid %d queue stuffed!"
- " %d MAC entries lost", client, evt_idx);
- }
- evt_idx = 0;
- }
- if (client)
- {
if (result.fields.lrn_evt)
{
/* copy mac entry to event msg */
}
else
{
- clib_warning ("MAC event to pid %d queue stuffed!"
- " %d MAC entries lost", client, evt_idx);
+ if (q)
+ clib_warning ("MAC event to pid %d queue stuffed!"
+ " %d MAC entries lost", client, evt_idx);
vl_msg_api_free (mp);
}
}
return delta_t + accum_t;
}
-/* Type of scan */
-#define SCAN_MAC_AGE 0
-#define SCAN_MAC_EVENT 1
-
/* Maximum f64 value */
#define TIME_MAX (1.7976931348623157e+308)
l2fib_main_t *fm = &l2fib_main;
l2learn_main_t *lm = &l2learn_main;
bool enabled = 0;
- bool scan = SCAN_MAC_AGE; /* SCAN_FOR_AGE or SCAN_FOR_EVENT */
f64 start_time, next_age_scan_time = TIME_MAX;
while (1)
{
- if (enabled)
+ if (lm->client_pid)
+ vlib_process_wait_for_event_or_clock (vm, fm->event_scan_delay);
+ else if (enabled)
{
- if (lm->client_pid) /* mac event client waiting */
- vlib_process_wait_for_event_or_clock (vm, fm->event_scan_delay);
- else /* agin only */
- {
- f64 t = next_age_scan_time - vlib_time_now (vm);
- if (t < fm->event_scan_delay)
- t = fm->event_scan_delay;
- vlib_process_wait_for_event_or_clock (vm, t);
- }
+ f64 t = next_age_scan_time - vlib_time_now (vm);
+ vlib_process_wait_for_event_or_clock (vm, t);
}
else
vlib_process_wait_for_event (vm);
vec_reset_length (event_data);
start_time = vlib_time_now (vm);
+ enum
+ { SCAN_MAC_AGE, SCAN_MAC_EVENT, SCAN_DISABLE } scan = SCAN_MAC_AGE;
switch (event_type)
{
case ~0: /* timer expired */
- if ((lm->client_pid == 0) || (start_time >= next_age_scan_time))
- {
- scan = SCAN_MAC_AGE;
- if (enabled)
- next_age_scan_time = start_time + L2FIB_AGE_SCAN_INTERVAL;
- else
- next_age_scan_time = TIME_MAX;
- }
- else
+ if (lm->client_pid != 0 && start_time < next_age_scan_time)
scan = SCAN_MAC_EVENT;
break;
case L2_MAC_AGE_PROCESS_EVENT_START:
- scan = SCAN_MAC_AGE;
- next_age_scan_time = start_time + L2FIB_AGE_SCAN_INTERVAL;
enabled = 1;
break;
case L2_MAC_AGE_PROCESS_EVENT_STOP:
enabled = 0;
- next_age_scan_time = TIME_MAX;
- l2fib_main.age_scan_duration = 0;
- l2fib_main.evt_scan_duration = 0;
- continue;
+ scan = SCAN_DISABLE;
+ break;
case L2_MAC_AGE_PROCESS_EVENT_ONE_PASS:
- scan = SCAN_MAC_AGE;
- if (enabled)
- next_age_scan_time = start_time + L2FIB_AGE_SCAN_INTERVAL;
- else
- next_age_scan_time = TIME_MAX;
break;
default:
if (scan == SCAN_MAC_EVENT)
l2fib_main.evt_scan_duration = l2fib_scan (vm, start_time, 1);
else
- l2fib_main.age_scan_duration = l2fib_scan (vm, start_time, 0);
+ {
+ if (scan == SCAN_MAC_AGE)
+ l2fib_main.age_scan_duration = l2fib_scan (vm, start_time, 0);
+ if (scan == SCAN_DISABLE)
+ {
+ l2fib_main.age_scan_duration = 0;
+ l2fib_main.evt_scan_duration = 0;
+ }
+ /* schedule next scan */
+ if (enabled)
+ next_age_scan_time = start_time + L2FIB_AGE_SCAN_INTERVAL;
+ else
+ next_age_scan_time = TIME_MAX;
+ }
}
return 0;
}