diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/vnet/span/span.c | 60 |
1 files changed, 44 insertions, 16 deletions
diff --git a/src/vnet/span/span.c b/src/vnet/span/span.c index 6ecd17895ef..2fd9cd87dfb 100644 --- a/src/vnet/span/span.c +++ b/src/vnet/span/span.c @@ -32,8 +32,15 @@ typedef enum 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; @@ -68,9 +75,9 @@ span_add_delete_entry (vlib_main_t * vm, 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) { @@ -92,12 +99,29 @@ span_add_delete_entry (vlib_main_t * vm, 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, @@ -106,8 +130,9 @@ set_interface_span_command_fn (vlib_main_t * vm, 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) { @@ -117,18 +142,16 @@ set_interface_span_command_fn (vlib_main_t * vm, 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 = @@ -155,7 +178,12 @@ show_interfaces_span_command_fn (vlib_main_t * vm, 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* */ |