1 /* SPDX-License-Identifier: Apache-2.0
2 * Copyright (c) 2023 Cisco Systems, Inc.
6 #include <vnet/dev/dev.h>
7 #include <vnet/dev/counters.h>
8 #include <vnet/dev/api.h>
11 device_attach_cmd_fn (vlib_main_t *vm, unformat_input_t *input,
12 vlib_cli_command_t *cmd)
14 vnet_dev_api_attach_args_t a = {};
17 if (!unformat_user (input, unformat_c_string_array, a.device_id,
18 sizeof (a.device_id)))
19 return clib_error_return (0, "please specify valid device id");
21 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
23 if (!a.driver_name[0] &&
24 unformat (input, "driver %U", unformat_c_string_array, a.driver_name,
25 sizeof (a.driver_name)))
27 else if (!a.flags.n &&
28 unformat (input, "flags %U", unformat_vnet_dev_flags, &a.flags))
30 else if (!a.args && unformat (input, "args %v", &a.args))
33 return clib_error_return (0, "unknown input `%U'",
34 format_unformat_error, input);
37 rv = vnet_dev_api_attach (vm, &a);
41 if (rv != VNET_DEV_OK)
42 return clib_error_return (0, "unable to attach '%s': %U", a.device_id,
43 format_vnet_dev_rv, rv);
48 VLIB_CLI_COMMAND (device_attach_cmd, static) = {
49 .path = "device attach",
50 .short_help = "device attach <device-id> [driver <name>] "
52 .function = device_attach_cmd_fn,
56 device_detach_cmd_fn (vlib_main_t *vm, unformat_input_t *input,
57 vlib_cli_command_t *cmd)
59 vnet_dev_api_detach_args_t a = {};
62 if (!unformat_user (input, unformat_c_string_array, a.device_id,
63 sizeof (a.device_id)))
64 return clib_error_return (0, "please specify valid device id");
66 rv = vnet_dev_api_detach (vm, &a);
68 if (rv != VNET_DEV_OK)
69 return clib_error_return (0, "unable to detach '%s': %U", a.device_id,
70 format_vnet_dev_rv, rv);
75 VLIB_CLI_COMMAND (device_detach_cmd, static) = {
76 .path = "device detach",
77 .short_help = "device detach <device-id>",
78 .function = device_detach_cmd_fn,
83 device_reset_cmd_fn (vlib_main_t *vm, unformat_input_t *input,
84 vlib_cli_command_t *cmd)
86 vnet_dev_api_reset_args_t a = {};
89 if (!unformat_user (input, unformat_c_string_array, a.device_id,
90 sizeof (a.device_id)))
91 return clib_error_return (0, "please specify valid device id");
93 rv = vnet_dev_api_reset (vm, &a);
95 if (rv != VNET_DEV_OK)
96 return clib_error_return (0, "unable to reset '%s': %U", a.device_id,
97 format_vnet_dev_rv, rv);
102 VLIB_CLI_COMMAND (device_reset_cmd, static) = {
103 .path = "device reset",
104 .short_help = "device reset <device-id>",
105 .function = device_reset_cmd_fn,
109 static clib_error_t *
110 device_create_if_cmd_fn (vlib_main_t *vm, unformat_input_t *input,
111 vlib_cli_command_t *cmd)
113 vnet_dev_api_create_port_if_args_t a = {};
117 if (!unformat_user (input, unformat_c_string_array, a.device_id,
118 sizeof (a.device_id)))
119 return clib_error_return (0, "please specify valid device id");
121 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
123 if (!a.intf_name[0] &&
124 unformat (input, "if-name %U", unformat_c_string_array, a.intf_name,
125 sizeof (a.intf_name)))
127 else if (!a.port_id && unformat (input, "port %u", &n))
129 else if (!a.flags.n && unformat (input, "flags %U",
130 unformat_vnet_dev_port_flags, &a.flags))
132 else if (!a.num_rx_queues && unformat (input, "num-rx-queues %u", &n))
134 else if (!a.num_tx_queues && unformat (input, "num-tx-queues %u", &n))
136 else if (!a.rx_queue_size && unformat (input, "rx-queues-size %u", &n))
138 else if (!a.tx_queue_size && unformat (input, "tx-queues-size %u", &n))
140 else if (!a.intf_name[0] &&
141 unformat (input, "name %U", unformat_c_string_array,
142 &a.intf_name, sizeof (a.intf_name)))
144 else if (!a.args && unformat (input, "args %v", &a.args))
147 return clib_error_return (0, "unknown input `%U'",
148 format_unformat_error, input);
151 rv = vnet_dev_api_create_port_if (vm, &a);
155 if (rv != VNET_DEV_OK)
156 return clib_error_return (0, "unable to create_if '%s': %U", a.device_id,
157 format_vnet_dev_rv, rv);
162 VLIB_CLI_COMMAND (device_create_if_cmd, static) = {
163 .path = "device create-interface",
164 .short_help = "device create-interface <device-id> [port <port-id>] "
165 "[args <iface-args>]",
166 .function = device_create_if_cmd_fn,
170 static clib_error_t *
171 device_remove_if_cmd_fn (vlib_main_t *vm, unformat_input_t *input,
172 vlib_cli_command_t *cmd)
174 vnet_dev_api_remove_port_if_args_t a = { .sw_if_index = ~0 };
175 vnet_main_t *vnm = vnet_get_main ();
178 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
180 if (unformat (input, "%U", unformat_vnet_sw_interface, vnm,
183 else if (unformat (input, "sw-if-index %u", &a.sw_if_index))
186 return clib_error_return (0, "unknown input `%U'",
187 format_unformat_error, input);
190 if (a.sw_if_index == ~0)
191 return clib_error_return (0, "please specify existing interface name");
193 rv = vnet_dev_api_remove_port_if (vm, &a);
195 if (rv != VNET_DEV_OK)
196 return clib_error_return (0, "unable to remove interface: %U",
197 format_vnet_dev_rv, rv);
202 VLIB_CLI_COMMAND (device_remove_if_cmd, static) = {
203 .path = "device remove-interface",
204 .short_help = "device remove-interface [<interface-name> | sw-if-index <n>]",
205 .function = device_remove_if_cmd_fn,
209 static clib_error_t *
210 show_devices_cmd_fn (vlib_main_t *vm, unformat_input_t *input,
211 vlib_cli_command_t *cmd)
213 vnet_dev_main_t *dm = &vnet_dev_main;
214 vnet_dev_format_args_t fa = {}, *a = &fa;
216 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
218 if (unformat (input, "counters"))
220 else if (unformat (input, "all"))
221 fa.show_zero_counters = 1;
222 else if (unformat (input, "debug"))
225 return clib_error_return (0, "unknown input `%U'",
226 format_unformat_error, input);
229 pool_foreach_pointer (dev, dm->devices)
231 vlib_cli_output (vm, "device '%s':", dev->device_id);
232 vlib_cli_output (vm, " %U", format_vnet_dev_info, a, dev);
233 foreach_vnet_dev_port (p, dev)
235 vlib_cli_output (vm, " Port %u:", p->port_id);
236 vlib_cli_output (vm, " %U", format_vnet_dev_port_info, a, p);
238 vlib_cli_output (vm, " %U", format_vnet_dev_counters, a,
241 foreach_vnet_dev_port_rx_queue (q, p)
243 vlib_cli_output (vm, " RX queue %u:", q->queue_id);
244 vlib_cli_output (vm, " %U", format_vnet_dev_rx_queue_info,
248 foreach_vnet_dev_port_tx_queue (q, p)
250 vlib_cli_output (vm, " TX queue %u:", q->queue_id);
251 vlib_cli_output (vm, " %U", format_vnet_dev_tx_queue_info,
259 VLIB_CLI_COMMAND (show_devices_cmd, static) = {
260 .path = "show device",
261 .short_help = "show device [counters]",
262 .function = show_devices_cmd_fn,
266 static clib_error_t *
267 show_device_counters_cmd_fn (vlib_main_t *vm, unformat_input_t *input,
268 vlib_cli_command_t *cmd)
270 vnet_dev_main_t *dm = &vnet_dev_main;
271 vnet_dev_format_args_t fa = { .counters = 1 };
273 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
275 if (unformat (input, "all"))
276 fa.show_zero_counters = 1;
278 return clib_error_return (0, "unknown input `%U'",
279 format_unformat_error, input);
282 pool_foreach_pointer (dev, dm->devices)
284 vlib_cli_output (vm, "device '%s':", dev->device_id);
285 foreach_vnet_dev_port (p, dev)
287 vlib_cli_output (vm, " %U", format_vnet_dev_counters, &fa,
290 foreach_vnet_dev_port_rx_queue (q, p)
293 vlib_cli_output (vm, " RX queue %u:", q->queue_id);
294 vlib_cli_output (vm, " %U", format_vnet_dev_counters, &fa,
298 foreach_vnet_dev_port_tx_queue (q, p)
301 vlib_cli_output (vm, " TX queue %u:", q->queue_id);
302 vlib_cli_output (vm, " %U", format_vnet_dev_counters, &fa,
310 VLIB_CLI_COMMAND (show_device_counters_cmd, static) = {
311 .path = "show device counters",
312 .short_help = "show device counters [all]",
313 .function = show_device_counters_cmd_fn,