X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=vnet%2Fvnet%2Fspan%2Fspan.c;h=7b5816c79f278507c55afb4f20f184bec87252dd;hb=3a2a1c47bc1f319d1f46abd2a364b3cf82404405;hp=52300454427739f4f2177733ac1cb9144739638f;hpb=fc6e693d0a3e3518b7b8de270542d2b5f9a17150;p=vpp.git diff --git a/vnet/vnet/span/span.c b/vnet/vnet/span/span.c index 52300454427..7b5816c79f2 100644 --- a/vnet/vnet/span/span.c +++ b/vnet/vnet/span/span.c @@ -21,22 +21,59 @@ int span_add_delete_entry (vlib_main_t * vm, - u32 src_sw_if_index, u32 dst_sw_if_index, u8 is_add) + u32 src_sw_if_index, u32 dst_sw_if_index, u8 state) { span_main_t *sm = &span_main; + span_interface_t *si; + u32 new_num_rx_mirror_ports, new_num_tx_mirror_ports; - if ((src_sw_if_index == ~0) || (dst_sw_if_index == ~0 && is_add) + if (state > 3) + return VNET_API_ERROR_UNIMPLEMENTED; + + if ((src_sw_if_index == ~0) || (dst_sw_if_index == ~0 && state > 0) || (src_sw_if_index == dst_sw_if_index)) return VNET_API_ERROR_INVALID_INTERFACE; - vnet_sw_interface_t *sw = - vnet_get_sw_interface (sm->vnet_main, src_sw_if_index); + vnet_sw_interface_t *sw_if; + + sw_if = vnet_get_sw_interface (vnet_get_main (), src_sw_if_index); + if (sw_if->type == VNET_SW_INTERFACE_TYPE_SUB) + return VNET_API_ERROR_UNIMPLEMENTED; - vec_validate_aligned (sm->dst_by_src_sw_if_index, sw->sw_if_index, + vec_validate_aligned (sm->interfaces, src_sw_if_index, CLIB_CACHE_LINE_BYTES); - sm->dst_by_src_sw_if_index[sw->sw_if_index] = is_add ? dst_sw_if_index : 0; - vnet_feature_enable_disable ("device-input", "span-input", - sw->sw_if_index, is_add, 0, 0); + si = vec_elt_at_index (sm->interfaces, src_sw_if_index); + + si->rx_mirror_ports = clib_bitmap_set (si->rx_mirror_ports, dst_sw_if_index, + (state & 1) != 0); + si->tx_mirror_ports = clib_bitmap_set (si->tx_mirror_ports, dst_sw_if_index, + (state & 2) != 0); + + new_num_rx_mirror_ports = clib_bitmap_count_set_bits (si->rx_mirror_ports); + new_num_tx_mirror_ports = clib_bitmap_count_set_bits (si->tx_mirror_ports); + + if (new_num_rx_mirror_ports == 1 && si->num_rx_mirror_ports == 0) + vnet_feature_enable_disable ("device-input", "span-input", + src_sw_if_index, 1, 0, 0); + + if (new_num_rx_mirror_ports == 0 && si->num_rx_mirror_ports == 1) + vnet_feature_enable_disable ("device-input", "span-input", + src_sw_if_index, 0, 0, 0); + + if (new_num_rx_mirror_ports == 1 && si->num_rx_mirror_ports == 0) + vnet_feature_enable_disable ("device-input", "span-output", + src_sw_if_index, 1, 0, 0); + + if (new_num_rx_mirror_ports == 0 && si->num_rx_mirror_ports == 1) + vnet_feature_enable_disable ("device-input", "span-output", + src_sw_if_index, 0, 0, 0); + + si->num_rx_mirror_ports = new_num_rx_mirror_ports; + si->num_tx_mirror_ports = new_num_tx_mirror_ports; + + if (dst_sw_if_index > sm->max_sw_if_index) + sm->max_sw_if_index = dst_sw_if_index; + return 0; } @@ -48,7 +85,7 @@ 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 is_add = 1; + u8 state = 3; while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { @@ -59,13 +96,19 @@ set_interface_span_command_fn (vlib_main_t * vm, sm->vnet_main, &dst_sw_if_index)) ; else if (unformat (input, "disable")) - is_add = 0; + state = 0; + else if (unformat (input, "rx")) + state = 1; + else if (unformat (input, "tx")) + state = 2; + else if (unformat (input, "both")) + state = 3; else break; } int rv = - span_add_delete_entry (vm, src_sw_if_index, dst_sw_if_index, is_add); + span_add_delete_entry (vm, src_sw_if_index, dst_sw_if_index, state); if (rv == VNET_API_ERROR_INVALID_INTERFACE) return clib_error_return (0, "Invalid interface"); return 0; @@ -74,7 +117,7 @@ set_interface_span_command_fn (vlib_main_t * vm, /* *INDENT-OFF* */ VLIB_CLI_COMMAND (set_interface_span_command, static) = { .path = "set interface span", - .short_help = "set interface span [disable | destination ]", + .short_help = "set interface span [disable | destination [both|rx|tx]]", .function = set_interface_span_command_fn, }; /* *INDENT-ON* */ @@ -84,28 +127,43 @@ show_interfaces_span_command_fn (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { - span_main_t *sm = &span_main; + span_interface_t *si; vnet_main_t *vnm = &vnet_main; - u32 src_sw_if_index = 0, *dst_sw_if_index; u8 header = 1; + char *states[] = { "none", "rx", "tx", "both" }; + u8 *s = 0; - vec_foreach (dst_sw_if_index, sm->dst_by_src_sw_if_index) - { - if (*dst_sw_if_index > 0) // && *dst_sw_if_index != ~0) + /* *INDENT-OFF* */ + vec_foreach (si, sm->interfaces) + if (si->num_rx_mirror_ports || si->num_tx_mirror_ports) { + clib_bitmap_t *b; + u32 i; + b = clib_bitmap_dup_or (si->rx_mirror_ports, si->tx_mirror_ports); if (header) { - vlib_cli_output (vm, - "SPAN source interface to destination interface table"); + vlib_cli_output (vm, "%-40s %s", "Source interface", + "Mirror interface (direction)"); header = 0; } - vlib_cli_output (vm, "%32U => %-32U", - format_vnet_sw_if_index_name, vnm, src_sw_if_index, - format_vnet_sw_if_index_name, vnm, *dst_sw_if_index); + s = format (s, "%U", format_vnet_sw_if_index_name, vnm, + si - sm->interfaces); + clib_bitmap_foreach (i, b, ( + { + int state; + state = (clib_bitmap_get (si->rx_mirror_ports, i) + + clib_bitmap_get (si->tx_mirror_ports, i) * 2); + + vlib_cli_output (vm, "%-40v %U (%s)", s, + format_vnet_sw_if_index_name, vnm, i, + states[state]); + vec_reset_length (s); + })); + clib_bitmap_free (b); } - src_sw_if_index++; - } + /* *INDENT-ON* */ + vec_free (s); return 0; }