X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Finterface_cli.c;h=d37c78942c9b9219327805b27773339518440cb3;hb=6f9ac6559ba155cc15dbc1153900f7bd3c4c9e13;hp=7dbee867dedeaf220aef4818a046a67a2f97ba52;hpb=7cd468a3d7dee7d6c92f69a0bb7061ae208ec727;p=vpp.git diff --git a/src/vnet/interface_cli.c b/src/vnet/interface_cli.c index 7dbee867ded..d37c78942c9 100644 --- a/src/vnet/interface_cli.c +++ b/src/vnet/interface_cli.c @@ -285,8 +285,9 @@ show_sw_interfaces (vlib_main_t * vm, _vec_len (sorted_sis) = 0; pool_foreach (si, im->sw_interfaces, ( { - vec_add1 (sorted_sis, si[0]); - } + if (vnet_swif_is_api_visible + (si)) vec_add1 (sorted_sis, + si[0]);} )); /* Sort by name. */ @@ -415,8 +416,8 @@ done: /* *INDENT-OFF* */ VLIB_CLI_COMMAND (show_sw_interfaces_command, static) = { - .path = "show interfaces", - .short_help = "show interfaces [address|addr|features|feat] [ ...]", + .path = "show interface", + .short_help = "show interface [address|addr|features|feat] [ ...]", .function = show_sw_interfaces, }; /* *INDENT-ON* */ @@ -828,7 +829,7 @@ done: ?*/ VLIB_CLI_COMMAND (set_state_command, static) = { .path = "set interface state", - .short_help = "Set interface state", + .short_help = "set interface state [up|down|punt|enable]", .function = set_state, }; /* *INDENT-ON* */ @@ -843,6 +844,7 @@ set_unnumbered (vlib_main_t * vm, vnet_sw_interface_t *si; int is_set = 0; int is_del = 0; + u32 was_unnum; if (unformat (input, "%U use %U", unformat_vnet_sw_interface, vnm, &unnumbered_sw_if_index, @@ -857,19 +859,37 @@ set_unnumbered (vlib_main_t * vm, format_unformat_error, input); si = vnet_get_sw_interface (vnm, unnumbered_sw_if_index); + was_unnum = (si->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED); + if (is_del) { si->flags &= ~(VNET_SW_INTERFACE_FLAG_UNNUMBERED); si->unnumbered_sw_if_index = (u32) ~ 0; - ip4_sw_interface_enable_disable (unnumbered_sw_if_index, 0); - ip6_sw_interface_enable_disable (unnumbered_sw_if_index, 0); + + ip4_main.lookup_main.if_address_pool_index_by_sw_if_index + [unnumbered_sw_if_index] = ~0; + ip6_main.lookup_main.if_address_pool_index_by_sw_if_index + [unnumbered_sw_if_index] = ~0; } else if (is_set) { si->flags |= VNET_SW_INTERFACE_FLAG_UNNUMBERED; si->unnumbered_sw_if_index = inherit_from_sw_if_index; - ip4_sw_interface_enable_disable (unnumbered_sw_if_index, 1); - ip6_sw_interface_enable_disable (unnumbered_sw_if_index, 1); + + ip4_main.lookup_main.if_address_pool_index_by_sw_if_index + [unnumbered_sw_if_index] = + ip4_main.lookup_main.if_address_pool_index_by_sw_if_index + [inherit_from_sw_if_index]; + ip6_main.lookup_main.if_address_pool_index_by_sw_if_index + [unnumbered_sw_if_index] = + ip6_main.lookup_main.if_address_pool_index_by_sw_if_index + [inherit_from_sw_if_index]; + } + + if (was_unnum != (si->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED)) + { + ip4_sw_interface_enable_disable (unnumbered_sw_if_index, !is_del); + ip6_sw_interface_enable_disable (unnumbered_sw_if_index, !is_del); } return 0; @@ -1155,7 +1175,283 @@ VLIB_CLI_COMMAND (clear_tag_command, static) = { }; /* *INDENT-ON* */ +static clib_error_t * +set_hw_interface_rx_mode (vnet_main_t * vnm, u32 hw_if_index, + u32 queue_id, vnet_hw_interface_rx_mode mode) +{ + vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index); + vnet_device_class_t *dev_class = + vnet_get_device_class (vnm, hw->dev_class_index); + clib_error_t *error; + vnet_hw_interface_rx_mode old_mode; + int rv; + + rv = vnet_hw_interface_get_rx_mode (vnm, hw_if_index, queue_id, &old_mode); + switch (rv) + { + case 0: + if (old_mode == mode) + return 0; /* same rx-mode, no change */ + break; + case VNET_API_ERROR_INVALID_INTERFACE: + return clib_error_return (0, "invalid interface"); + default: + return clib_error_return (0, "unknown error"); + } + + if (dev_class->rx_mode_change_function) + { + error = dev_class->rx_mode_change_function (vnm, hw_if_index, queue_id, + mode); + if (error) + return (error); + } + + rv = vnet_hw_interface_set_rx_mode (vnm, hw_if_index, queue_id, mode); + switch (rv) + { + case 0: + break; + case VNET_API_ERROR_UNSUPPORTED: + return clib_error_return (0, "unsupported"); + case VNET_API_ERROR_INVALID_INTERFACE: + return clib_error_return (0, "invalid interface"); + default: + return clib_error_return (0, "unknown error"); + } + + return 0; +} + +static clib_error_t * +set_interface_rx_mode (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 *hw; + u32 hw_if_index = (u32) ~ 0; + u32 queue_id = (u32) ~ 0; + vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN; + int i; + + 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, "queue %d", &queue_id)) + ; + else if (unformat (line_input, "polling")) + mode = VNET_HW_INTERFACE_RX_MODE_POLLING; + else if (unformat (line_input, "interrupt")) + mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT; + else if (unformat (line_input, "adaptive")) + mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE; + 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) + return clib_error_return (0, "please specify valid interface name"); + + if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN) + return clib_error_return (0, "please specify valid rx-mode"); + + hw = vnet_get_hw_interface (vnm, hw_if_index); + + if (queue_id == ~0) + for (i = 0; i < vec_len (hw->dq_runtime_index_by_queue); i++) + { + error = set_hw_interface_rx_mode (vnm, hw_if_index, i, mode); + if (error) + break; + } + else + error = set_hw_interface_rx_mode (vnm, hw_if_index, queue_id, mode); + + return (error); +} + +/*? + * This command is used to assign a given interface, and optionally a + * given queue, to a different thread. If the 'queue' is not provided, + * it defaults to 0. + * + * @cliexpar + * Example of how to display the interface placement: + * @cliexstart{show interface rx-placement} + * Thread 1 (vpp_wk_0): + * GigabitEthernet0/8/0 queue 0 + * GigabitEthernet0/9/0 queue 0 + * Thread 2 (vpp_wk_1): + * GigabitEthernet0/8/0 queue 1 + * GigabitEthernet0/9/0 queue 1 + * @cliexend + * Example of how to assign a interface and queue to a thread: + * @cliexcmd{set interface placement GigabitEthernet0/8/0 queue 1 thread 1} +?*/ +/* *INDENT-OFF* */ +VLIB_CLI_COMMAND (cmd_set_if_rx_mode,static) = { + .path = "set interface rx-mode", + .short_help = "set interface rx-mode [queue ] [polling | interrupt | adaptive]", + .function = set_interface_rx_mode, +}; +/* *INDENT-ON* */ + +static clib_error_t * +show_interface_rx_placement_fn (vlib_main_t * vm, unformat_input_t * input, + vlib_cli_command_t * cmd) +{ + u8 *s = 0; + vnet_main_t *vnm = vnet_get_main (); + vnet_device_input_runtime_t *rt; + vnet_device_and_queue_t *dq; + vlib_node_t *pn = vlib_get_node_by_name (vm, (u8 *) "device-input"); + uword si; + int index = 0; + + /* *INDENT-OFF* */ + foreach_vlib_main (({ + clib_bitmap_foreach (si, pn->sibling_bitmap, + ({ + rt = vlib_node_get_runtime_data (this_vlib_main, si); + + if (vec_len (rt->devices_and_queues)) + s = format (s, " node %U:\n", format_vlib_node_name, vm, si); + + vec_foreach (dq, rt->devices_and_queues) + { + s = format (s, " %U queue %u (%U)\n", + format_vnet_sw_if_index_name, vnm, dq->hw_if_index, + dq->queue_id, + format_vnet_hw_interface_rx_mode, dq->mode); + } + })); + if (vec_len (s) > 0) + { + vlib_cli_output(vm, "Thread %u (%v):\n%v", index, + vlib_worker_threads[index].name, s); + vec_reset_length (s); + } + index++; + })); + /* *INDENT-ON* */ + + vec_free (s); + return 0; +} + +/* *INDENT-OFF* */ +VLIB_CLI_COMMAND (show_interface_rx_placement, static) = { + .path = "show interface rx-placement", + .short_help = "show interface rx-placement", + .function = show_interface_rx_placement_fn, +}; +/* *INDENT-ON* */ + +static clib_error_t * +set_interface_rx_placement (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_device_main_t *vdm = &vnet_device_main; + vnet_hw_interface_rx_mode mode; + u32 hw_if_index = (u32) ~ 0; + u32 queue_id = (u32) 0; + u32 thread_index = (u32) ~ 0; + int rv; + + 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, "queue %d", &queue_id)) + ; + else if (unformat (line_input, "main", &thread_index)) + thread_index = 0; + else if (unformat (line_input, "worker %d", &thread_index)) + thread_index += vdm->first_worker_thread_index; + 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) + return clib_error_return (0, "please specify valid interface name"); + + if (thread_index > vdm->last_worker_thread_index) + return clib_error_return (0, + "please specify valid worker thread or main"); + + rv = vnet_hw_interface_get_rx_mode (vnm, hw_if_index, queue_id, &mode); + + if (rv) + return clib_error_return (0, "not found"); + + rv = vnet_hw_interface_unassign_rx_thread (vnm, hw_if_index, queue_id); + if (rv) + return clib_error_return (0, "not found"); + + vnet_hw_interface_assign_rx_thread (vnm, hw_if_index, queue_id, + thread_index); + vnet_hw_interface_set_rx_mode (vnm, hw_if_index, queue_id, mode); + + return 0; +} + +/*? + * This command is used to assign a given interface, and optionally a + * given queue, to a different thread. If the 'queue' is not provided, + * it defaults to 0. + * + * @cliexpar + * Example of how to display the interface placement: + * @cliexstart{show interface placement} + * Thread 1 (vpp_wk_0): + * GigabitEthernet0/8/0 queue 0 + * GigabitEthernet0/9/0 queue 0 + * Thread 2 (vpp_wk_1): + * GigabitEthernet0/8/0 queue 1 + * GigabitEthernet0/9/0 queue 1 + * @cliexend + * Example of how to assign a interface and queue to a thread: + * @cliexcmd{set interface placement GigabitEthernet0/8/0 queue 1 thread 1} +?*/ +/* *INDENT-OFF* */ +VLIB_CLI_COMMAND (cmd_set_if_rx_placement,static) = { + .path = "set interface rx-placement", + .short_help = "set interface rx-placement [queue ] " + "[worker | main]", + .function = set_interface_rx_placement, + .is_mp_safe = 1, +}; + +/* *INDENT-ON* */ /* * fd.io coding-style-patch-verification: ON *