X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Finterface_cli.c;h=74ac32522d71507eb18547c105880e915f848944;hb=3f4075574;hp=4f6f2cf05a505eae7b59045f44d9176b22112981;hpb=2c77ae484c30ca5a752c5f7ccd336d8e977db9a6;p=vpp.git diff --git a/src/vnet/interface_cli.c b/src/vnet/interface_cli.c index 4f6f2cf05a5..74ac32522d7 100644 --- a/src/vnet/interface_cli.c +++ b/src/vnet/interface_cli.c @@ -53,6 +53,7 @@ #include #include #include +#include static int compare_interface_names (void *a1, void *a2) { @@ -68,33 +69,37 @@ show_or_clear_hw_interfaces (vlib_main_t * vm, vlib_cli_command_t * cmd, int is_show) { clib_error_t *error = 0; + unformat_input_t _line_input, *line_input = &_line_input; vnet_main_t *vnm = vnet_get_main (); vnet_interface_main_t *im = &vnm->interface_main; vnet_hw_interface_t *hi; u32 hw_if_index, *hw_if_indices = 0; int i, verbose = -1, show_bond = 0; - while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) + if (!unformat_user (input, unformat_line_input, line_input)) + goto skip_unformat; + + while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) { /* See if user wants to show a specific interface. */ - if (unformat - (input, "%U", unformat_vnet_hw_interface, vnm, &hw_if_index)) + if (unformat (line_input, "%U", unformat_vnet_hw_interface, vnm, + &hw_if_index)) vec_add1 (hw_if_indices, hw_if_index); /* See if user wants to show an interface with a specific hw_if_index. */ - else if (unformat (input, "%u", &hw_if_index)) + else if (unformat (line_input, "%u", &hw_if_index)) vec_add1 (hw_if_indices, hw_if_index); - else if (unformat (input, "verbose")) + else if (unformat (line_input, "verbose")) verbose = 1; /* this is also the default */ - else if (unformat (input, "detail")) + else if (unformat (line_input, "detail")) verbose = 2; - else if (unformat (input, "brief")) + else if (unformat (line_input, "brief")) verbose = 0; - else if (unformat (input, "bond")) + else if (unformat (line_input, "bond")) { show_bond = 1; if (verbose < 0) @@ -104,11 +109,15 @@ show_or_clear_hw_interfaces (vlib_main_t * vm, else { error = clib_error_return (0, "unknown input `%U'", - format_unformat_error, input); + format_unformat_error, line_input); + unformat_free (line_input); goto done; } } + unformat_free (line_input); + +skip_unformat: /* Gather interfaces. */ if (vec_len (hw_if_indices) == 0) pool_foreach (hi, im->hw_interfaces) @@ -407,7 +416,7 @@ show_sw_interfaces (vlib_main_t * vm, /* Gather interfaces. */ sorted_sis = vec_new (vnet_sw_interface_t, pool_elts (im->sw_interfaces)); - _vec_len (sorted_sis) = 0; + vec_set_len (sorted_sis, 0); /* *INDENT-OFF* */ pool_foreach (si, im->sw_interfaces) { @@ -508,7 +517,8 @@ done: /* *INDENT-OFF* */ VLIB_CLI_COMMAND (show_sw_interfaces_command, static) = { .path = "show interface", - .short_help = "show interface [address|addr|features|feat|vtr] [ [ [..]]] [verbose]", + .short_help = "show interface [address|addr|features|feat|vtr|tag] " + "[ [ [..]]] [verbose]", .function = show_sw_interfaces, .is_mp_safe = 1, }; @@ -1157,6 +1167,7 @@ mtu_cmd (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) u32 hw_if_index, sw_if_index, mtu; ethernet_main_t *em = ðernet_main; u32 mtus[VNET_N_MTU] = { 0, 0, 0, 0 }; + clib_error_t *err; if (unformat (input, "%d %U", &mtu, unformat_vnet_hw_interface, vnm, &hw_if_index)) @@ -1165,22 +1176,14 @@ mtu_cmd (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) * Change physical MTU on interface. Only supported for Ethernet * interfaces */ - vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index); ethernet_interface_t *eif = ethernet_get_interface (em, hw_if_index); if (!eif) return clib_error_return (0, "not supported"); - if (mtu < hi->min_supported_packet_bytes) - return clib_error_return (0, "Invalid mtu (%d): " - "must be >= min pkt bytes (%d)", mtu, - hi->min_supported_packet_bytes); - - if (mtu > hi->max_supported_packet_bytes) - return clib_error_return (0, "Invalid mtu (%d): must be <= (%d)", mtu, - hi->max_supported_packet_bytes); - - vnet_hw_interface_set_mtu (vnm, hw_if_index, mtu); + err = vnet_hw_interface_set_mtu (vnm, hw_if_index, mtu); + if (err) + return err; goto done; } else if (unformat (input, "packet %d %U", &mtu, @@ -1235,7 +1238,7 @@ show_interface_sec_mac_addr_fn (vlib_main_t * vm, unformat_input_t * input, { sorted_sis = vec_new (vnet_sw_interface_t, pool_elts (im->sw_interfaces)); - _vec_len (sorted_sis) = 0; + vec_set_len (sorted_sis, 0); /* *INDENT-OFF* */ pool_foreach (si, im->sw_interfaces) { @@ -1533,7 +1536,12 @@ set_hw_interface_change_rx_mode (vnet_main_t * vnm, u32 hw_if_index, { int rv = vnet_hw_if_set_rx_queue_mode (vnm, queue_indices[i], mode); if (rv) - goto done; + { + error = clib_error_return ( + 0, "unable to set rx-mode on interface %v queue-id %u.\n", + hw->name, queue_id); + goto done; + } } done: @@ -1840,28 +1848,24 @@ VLIB_CLI_COMMAND (cmd_set_if_rx_placement,static) = { }; /* *INDENT-ON* */ -clib_error_t * +int set_hw_interface_tx_queue (u32 hw_if_index, u32 queue_id, uword *bitmap) { vnet_main_t *vnm = vnet_get_main (); - vnet_device_main_t *vdm = &vnet_device_main; - vnet_hw_interface_t *hw; + vlib_thread_main_t *vtm = vlib_get_thread_main (); vnet_hw_if_tx_queue_t *txq; u32 queue_index; u32 thread_index; - hw = vnet_get_hw_interface (vnm, hw_if_index); - /* highest set bit in bitmap should not exceed last worker thread index */ thread_index = clib_bitmap_last_set (bitmap); - if ((thread_index != ~0) && (thread_index > vdm->last_worker_thread_index)) - return clib_error_return (0, "please specify valid thread(s)"); + if ((thread_index != ~0) && (thread_index >= vtm->n_vlib_mains)) + return VNET_API_ERROR_INVALID_VALUE; queue_index = vnet_hw_if_get_tx_queue_index_by_id (vnm, hw_if_index, queue_id); if (queue_index == ~0) - return clib_error_return (0, "unknown queue %u on interface %s", queue_id, - hw->name); + return VNET_API_ERROR_INVALID_QUEUE; txq = vnet_hw_if_get_tx_queue (vnm, queue_index); @@ -1889,6 +1893,7 @@ set_interface_tx_queue (vlib_main_t *vm, unformat_input_t *input, u32 hw_if_index = (u32) ~0; u32 queue_id = (u32) 0; uword *bitmap = 0; + int rv = 0; if (!unformat_user (input, unformat_line_input, line_input)) return 0; @@ -1920,7 +1925,23 @@ set_interface_tx_queue (vlib_main_t *vm, unformat_input_t *input, goto error; } - error = set_hw_interface_tx_queue (hw_if_index, queue_id, bitmap); + rv = set_hw_interface_tx_queue (hw_if_index, queue_id, bitmap); + + switch (rv) + { + case VNET_API_ERROR_INVALID_VALUE: + error = clib_error_return ( + 0, "please specify valid thread(s) - last thread index %u", + clib_bitmap_last_set (bitmap)); + break; + case VNET_API_ERROR_INVALID_QUEUE: + error = clib_error_return ( + 0, "unknown queue %u on interface %s", queue_id, + vnet_get_hw_interface (vnet_get_main (), hw_if_index)->name); + break; + default: + break; + } error: clib_bitmap_free (bitmap); @@ -2364,13 +2385,13 @@ pcap_trace_command_fn (vlib_main_t * vm, * packet capture are preserved, so 'any' can be used to reset * the interface setting. * - * - filter - Use the pcap rx / tx / drop trace filter, which + * - filter - Use the pcap trace rx / tx / drop filter, which * must be configured. Use classify filter pcap... to configure the * filter. The filter will only be executed if the per-interface or * any-interface tests fail. * * - error . - filter packets based on a specific error. - * For example: error {ip4-udp-lookup}.{No listener for dst port} + * For example: error {ip4-udp-lookup}.{no_listener} * * - file - Used to specify the output filename. The file will * be placed in the '/tmp' directory, so only the filename is @@ -2418,6 +2439,72 @@ VLIB_CLI_COMMAND (pcap_tx_trace_command, static) = { }; /* *INDENT-ON* */ +static clib_error_t * +set_pcap_filter_function (vlib_main_t *vm, unformat_input_t *input, + vlib_cli_command_t *cmd) +{ + vnet_pcap_t *pp = &vnet_get_main ()->pcap; + unformat_input_t _line_input, *line_input = &_line_input; + vlib_is_packet_traced_fn_t *res = 0; + clib_error_t *error = 0; + + if (!unformat_user (input, unformat_line_input, line_input)) + return 0; + + while (unformat_check_input (line_input) != (uword) UNFORMAT_END_OF_INPUT) + { + if (unformat (line_input, "%U", unformat_vlib_trace_filter_function, + &res)) + ; + else + { + error = clib_error_create ( + "expected valid trace filter function, got `%U'", + format_unformat_error, line_input); + goto done; + } + } + pp->current_filter_function = res; + +done: + unformat_free (line_input); + + return error; +} + +VLIB_CLI_COMMAND (set_pcap_filter_function_cli, static) = { + .path = "set pcap filter function", + .short_help = "set pcap filter function ", + .function = set_pcap_filter_function, +}; + +static clib_error_t * +show_pcap_filter_function (vlib_main_t *vm, unformat_input_t *input, + vlib_cli_command_t *cmd) +{ + vnet_pcap_t *pp = &vnet_get_main ()->pcap; + vlib_trace_filter_main_t *tfm = &vlib_trace_filter_main; + vlib_is_packet_traced_fn_t *current_trace_filter_fn = + pp->current_filter_function; + vlib_trace_filter_function_registration_t *reg = + tfm->trace_filter_registration; + + while (reg) + { + vlib_cli_output (vm, "%sname:%s description: %s priority: %u", + reg->function == current_trace_filter_fn ? "(*) " : "", + reg->name, reg->description, reg->priority); + reg = reg->next; + } + return 0; +} + +VLIB_CLI_COMMAND (show_pcap_filter_function_cli, static) = { + .path = "show pcap filter function", + .short_help = "show pcap filter function", + .function = show_pcap_filter_function, +}; + static clib_error_t * set_interface_name (vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd) @@ -2467,6 +2554,138 @@ VLIB_CLI_COMMAND (cmd_set_if_name, static) = { .function = set_interface_name, .is_mp_safe = 1, }; + +static clib_error_t * +set_interface_tx_hash_cmd (vlib_main_t *vm, unformat_input_t *input, + vlib_cli_command_t *cmd) +{ + clib_error_t *error = 0; + unformat_input_t _line_input, *line_input = &_line_input; + vnet_main_t *vnm = vnet_get_main (); + vnet_hw_interface_t *hi; + u8 *hash_name = 0; + u32 hw_if_index = (u32) ~0; + vnet_hash_fn_t hf; + vnet_hash_fn_type_t ftype; + + if (!unformat_user (input, unformat_line_input, line_input)) + return 0; + + while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) + { + if (unformat (line_input, "%U", unformat_vnet_hw_interface, vnm, + &hw_if_index)) + ; + else if (unformat (line_input, "hash-name %s", &hash_name)) + ; + else + { + error = clib_error_return (0, "parse error: '%U'", + format_unformat_error, line_input); + unformat_free (line_input); + return error; + } + } + + unformat_free (line_input); + + if (hw_if_index == (u32) ~0) + { + error = clib_error_return (0, "please specify valid interface name"); + goto error; + } + + if (hash_name == 0) + { + error = clib_error_return (0, "hash-name is required"); + goto error; + } + + hi = vnet_get_hw_interface (vnm, hw_if_index); + ftype = + vnet_get_hw_interface_class (vnm, hi->hw_class_index)->tx_hash_fn_type; + hf = vnet_hash_function_from_name ((const char *) hash_name, ftype); + + if (!hf) + { + error = clib_error_return (0, "please specify valid hash name"); + goto error; + } + + hi->hf = hf; +error: + vec_free (hash_name); + return (error); +} + +VLIB_CLI_COMMAND (cmd_set_if_tx_hash, static) = { + .path = "set interface tx-hash", + .short_help = "set interface tx-hash hash-name ", + .function = set_interface_tx_hash_cmd, +}; + +static clib_error_t * +show_tx_hash (vlib_main_t *vm, unformat_input_t *input, + vlib_cli_command_t *cmd) +{ + clib_error_t *error = 0; + unformat_input_t _line_input, *line_input = &_line_input; + vnet_main_t *vnm = vnet_get_main (); + vnet_hw_interface_t *hi; + vnet_hash_function_registration_t *hash; + u32 hw_if_index = (u32) ~0; + vnet_hash_fn_type_t ftype; + + if (!unformat_user (input, unformat_line_input, line_input)) + return 0; + + while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) + { + if (unformat (line_input, "%U", unformat_vnet_hw_interface, vnm, + &hw_if_index)) + ; + else + { + error = clib_error_return (0, "parse error: '%U'", + format_unformat_error, line_input); + unformat_free (line_input); + goto error; + } + } + + unformat_free (line_input); + + if (hw_if_index == (u32) ~0) + { + error = clib_error_return (0, "please specify valid interface name"); + goto error; + } + + hi = vnet_get_hw_interface (vnm, hw_if_index); + ftype = + vnet_get_hw_interface_class (vnm, hi->hw_class_index)->tx_hash_fn_type; + + if (hi->hf) + { + hash = vnet_hash_function_from_func (hi->hf, ftype); + if (hash) + vlib_cli_output (vm, "%U", format_vnet_hash, hash); + else + vlib_cli_output (vm, "no matching hash function found"); + } + else + vlib_cli_output (vm, "no hashing function set"); + +error: + return (error); +} + +VLIB_CLI_COMMAND (cmd_show_tx_hash, static) = { + .path = "show interface tx-hash", + .short_help = "show interface tx-hash [interface]", + .function = show_tx_hash, +}; + /* * fd.io coding-style-patch-verification: ON *