#include <vnet/span/span.h>
+span_main_t span_main;
+
typedef enum
{
SPAN_DISABLE = 0,
static_always_inline u32
span_dst_set (span_mirror_t * sm, u32 dst_sw_if_index, int enable)
{
- sm->mirror_ports =
- clib_bitmap_set (sm->mirror_ports, dst_sw_if_index, enable);
+ if (dst_sw_if_index == ~0)
+ {
+ ASSERT (enable == 0);
+ clib_bitmap_zero (sm->mirror_ports);
+ }
+ else
+ sm->mirror_ports =
+ clib_bitmap_set (sm->mirror_ports, dst_sw_if_index, enable);
+
u32 last = sm->num_mirror_ports;
sm->num_mirror_ports = clib_bitmap_count_set_bits (sm->mirror_ports);
return last;
u32 last_tx_ports_count = span_dst_set (txm, dst_sw_if_index, tx);
int enable_rx = last_rx_ports_count == 0 && rxm->num_mirror_ports == 1;
- int disable_rx = last_rx_ports_count == 1 && rxm->num_mirror_ports == 0;
+ int disable_rx = last_rx_ports_count > 0 && rxm->num_mirror_ports == 0;
int enable_tx = last_tx_ports_count == 0 && txm->num_mirror_ports == 1;
- int disable_tx = last_tx_ports_count == 1 && txm->num_mirror_ports == 0;
+ int disable_tx = last_tx_ports_count > 0 && txm->num_mirror_ports == 0;
switch (sf)
{
return VNET_API_ERROR_UNIMPLEMENTED;
}
- if (dst_sw_if_index > sm->max_sw_if_index)
+ if (dst_sw_if_index != ~0 && dst_sw_if_index > sm->max_sw_if_index)
sm->max_sw_if_index = dst_sw_if_index;
return 0;
}
+static uword
+unformat_span_state (unformat_input_t * input, va_list * args)
+{
+ span_state_t *state = va_arg (*args, span_state_t *);
+ if (unformat (input, "disable"))
+ *state = SPAN_DISABLE;
+ else if (unformat (input, "rx"))
+ *state = SPAN_RX;
+ else if (unformat (input, "tx"))
+ *state = SPAN_TX;
+ else if (unformat (input, "both"))
+ *state = SPAN_BOTH;
+ else
+ return 0;
+ return 1;
+}
+
static clib_error_t *
set_interface_span_command_fn (vlib_main_t * vm,
unformat_input_t * input,
span_main_t *sm = &span_main;
u32 src_sw_if_index = ~0;
u32 dst_sw_if_index = ~0;
- u8 state = SPAN_BOTH;
span_feat_t sf = SPAN_FEAT_DEVICE;
+ span_state_t state = SPAN_BOTH;
+ int state_set = 0;
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
{
else if (unformat (input, "destination %U", unformat_vnet_sw_interface,
sm->vnet_main, &dst_sw_if_index))
;
- else if (unformat (input, "disable"))
- state = SPAN_DISABLE;
- else if (unformat (input, "rx"))
- state = SPAN_RX;
- else if (unformat (input, "tx"))
- state = SPAN_TX;
- else if (unformat (input, "both"))
- state = SPAN_BOTH;
+ else if (unformat (input, "%U", unformat_span_state, &state))
+ {
+ if (state_set)
+ return clib_error_return (0, "Multiple mirror states in input");
+ state_set = 1;
+ }
else if (unformat (input, "l2"))
sf = SPAN_FEAT_L2;
else
- break;
+ return clib_error_return (0, "Invalid input");
}
int rv =
span_interface_t *si;
vnet_main_t *vnm = &vnet_main;
u8 header = 1;
- char *states[] = { "none", "rx", "tx", "both" };
+ static const char *states[] = {
+ [SPAN_DISABLE] = "none",
+ [SPAN_RX] = "rx",
+ [SPAN_TX] = "tx",
+ [SPAN_BOTH] = "both"
+ };
u8 *s = 0;
/* *INDENT-OFF* */
clib_bitmap_t *b = clib_bitmap_dup_or (d, l);
if (header)
{
- vlib_cli_output (vm, "%-20s %-20s %6s %6s", "Source", "Destination",
+ vlib_cli_output (vm, "%-32s %-32s %6s %6s", "Source", "Destination",
"Device", "L2");
header = 0;
}
int l2 = (clib_bitmap_get (lrxm->mirror_ports, i) +
clib_bitmap_get (ltxm->mirror_ports, i) * 2);
- vlib_cli_output (vm, "%-20v %-20U (%6s) (%6s)", s,
+ vlib_cli_output (vm, "%-32v %-32U (%6s) (%6s)", s,
format_vnet_sw_if_index_name, vnm, i,
states[device], states[l2]);
vec_reset_length (s);