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)
60 vnet_dev_device_id_t device_id = {};
63 if (!unformat_user (input, unformat_c_string_array, device_id,
65 return clib_error_return (0, "please specify valid device id");
67 dev = vnet_dev_by_id (device_id);
71 vnet_dev_api_detach_args_t a = { .dev_index = dev->index };
72 rv = vnet_dev_api_detach (vm, &a);
75 rv = VNET_DEV_ERR_UNKNOWN_DEVICE;
77 if (rv != VNET_DEV_OK)
78 return clib_error_return (0, "unable to detach '%s': %U", device_id,
79 format_vnet_dev_rv, rv);
84 VLIB_CLI_COMMAND (device_detach_cmd, static) = {
85 .path = "device detach",
86 .short_help = "device detach <device-id>",
87 .function = device_detach_cmd_fn,
92 device_reset_cmd_fn (vlib_main_t *vm, unformat_input_t *input,
93 vlib_cli_command_t *cmd)
95 vnet_dev_api_reset_args_t a = {};
98 if (!unformat_user (input, unformat_c_string_array, a.device_id,
99 sizeof (a.device_id)))
100 return clib_error_return (0, "please specify valid device id");
102 rv = vnet_dev_api_reset (vm, &a);
104 if (rv != VNET_DEV_OK)
105 return clib_error_return (0, "unable to reset '%s': %U", a.device_id,
106 format_vnet_dev_rv, rv);
111 VLIB_CLI_COMMAND (device_reset_cmd, static) = {
112 .path = "device reset",
113 .short_help = "device reset <device-id>",
114 .function = device_reset_cmd_fn,
118 static clib_error_t *
119 device_create_if_cmd_fn (vlib_main_t *vm, unformat_input_t *input,
120 vlib_cli_command_t *cmd)
122 vnet_dev_api_create_port_if_args_t a = {};
124 vnet_dev_device_id_t device_id = {};
128 if (unformat_user (input, unformat_c_string_array, device_id,
130 dev = vnet_dev_by_id (device_id);
133 return clib_error_return (0, "please specify valid device id");
135 a.dev_index = dev->index;
137 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
139 if (!a.intf_name[0] &&
140 unformat (input, "if-name %U", unformat_c_string_array, a.intf_name,
141 sizeof (a.intf_name)))
143 else if (!a.port_id && unformat (input, "port %u", &n))
145 else if (!a.flags.n && unformat (input, "flags %U",
146 unformat_vnet_dev_port_flags, &a.flags))
148 else if (!a.num_rx_queues && unformat (input, "num-rx-queues %u", &n))
150 else if (!a.num_tx_queues && unformat (input, "num-tx-queues %u", &n))
152 else if (!a.rx_queue_size && unformat (input, "rx-queues-size %u", &n))
154 else if (!a.tx_queue_size && unformat (input, "tx-queues-size %u", &n))
156 else if (!a.intf_name[0] &&
157 unformat (input, "name %U", unformat_c_string_array,
158 &a.intf_name, sizeof (a.intf_name)))
160 else if (!a.args && unformat (input, "args %v", &a.args))
163 return clib_error_return (0, "unknown input `%U'",
164 format_unformat_error, input);
167 rv = vnet_dev_api_create_port_if (vm, &a);
171 if (rv != VNET_DEV_OK)
172 return clib_error_return (0, "unable to create_if '%s': %U", device_id,
173 format_vnet_dev_rv, rv);
178 VLIB_CLI_COMMAND (device_create_if_cmd, static) = {
179 .path = "device create-interface",
180 .short_help = "device create-interface <device-id> [port <port-id>] "
181 "[args <iface-args>]",
182 .function = device_create_if_cmd_fn,
186 static clib_error_t *
187 device_remove_if_cmd_fn (vlib_main_t *vm, unformat_input_t *input,
188 vlib_cli_command_t *cmd)
190 vnet_dev_api_remove_port_if_args_t a = { .sw_if_index = ~0 };
191 vnet_main_t *vnm = vnet_get_main ();
194 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
196 if (unformat (input, "%U", unformat_vnet_sw_interface, vnm,
199 else if (unformat (input, "sw-if-index %u", &a.sw_if_index))
202 return clib_error_return (0, "unknown input `%U'",
203 format_unformat_error, input);
206 if (a.sw_if_index == ~0)
207 return clib_error_return (0, "please specify existing interface name");
209 rv = vnet_dev_api_remove_port_if (vm, &a);
211 if (rv != VNET_DEV_OK)
212 return clib_error_return (0, "unable to remove interface: %U",
213 format_vnet_dev_rv, rv);
218 VLIB_CLI_COMMAND (device_remove_if_cmd, static) = {
219 .path = "device remove-interface",
220 .short_help = "device remove-interface [<interface-name> | sw-if-index <n>]",
221 .function = device_remove_if_cmd_fn,
225 static clib_error_t *
226 show_devices_cmd_fn (vlib_main_t *vm, unformat_input_t *input,
227 vlib_cli_command_t *cmd)
229 vnet_dev_main_t *dm = &vnet_dev_main;
230 vnet_dev_format_args_t fa = {}, *a = &fa;
232 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
234 if (unformat (input, "counters"))
236 else if (unformat (input, "all"))
237 fa.show_zero_counters = 1;
238 else if (unformat (input, "debug"))
241 return clib_error_return (0, "unknown input `%U'",
242 format_unformat_error, input);
245 pool_foreach_pointer (dev, dm->devices)
247 vlib_cli_output (vm, "device '%s':", dev->device_id);
248 vlib_cli_output (vm, " %U", format_vnet_dev_info, a, dev);
249 foreach_vnet_dev_port (p, dev)
251 vlib_cli_output (vm, " Port %u:", p->port_id);
252 vlib_cli_output (vm, " %U", format_vnet_dev_port_info, a, p);
254 vlib_cli_output (vm, " %U", format_vnet_dev_counters, a,
257 foreach_vnet_dev_port_rx_queue (q, p)
259 vlib_cli_output (vm, " RX queue %u:", q->queue_id);
260 vlib_cli_output (vm, " %U", format_vnet_dev_rx_queue_info,
264 foreach_vnet_dev_port_tx_queue (q, p)
266 vlib_cli_output (vm, " TX queue %u:", q->queue_id);
267 vlib_cli_output (vm, " %U", format_vnet_dev_tx_queue_info,
275 VLIB_CLI_COMMAND (show_devices_cmd, static) = {
276 .path = "show device",
277 .short_help = "show device [counters]",
278 .function = show_devices_cmd_fn,
282 static clib_error_t *
283 show_device_counters_cmd_fn (vlib_main_t *vm, unformat_input_t *input,
284 vlib_cli_command_t *cmd)
286 vnet_dev_main_t *dm = &vnet_dev_main;
287 vnet_dev_format_args_t fa = { .counters = 1 };
289 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
291 if (unformat (input, "all"))
292 fa.show_zero_counters = 1;
294 return clib_error_return (0, "unknown input `%U'",
295 format_unformat_error, input);
298 pool_foreach_pointer (dev, dm->devices)
300 vlib_cli_output (vm, "device '%s':", dev->device_id);
301 foreach_vnet_dev_port (p, dev)
303 vlib_cli_output (vm, " %U", format_vnet_dev_counters, &fa,
306 foreach_vnet_dev_port_rx_queue (q, p)
309 vlib_cli_output (vm, " RX queue %u:", q->queue_id);
310 vlib_cli_output (vm, " %U", format_vnet_dev_counters, &fa,
314 foreach_vnet_dev_port_tx_queue (q, p)
317 vlib_cli_output (vm, " TX queue %u:", q->queue_id);
318 vlib_cli_output (vm, " %U", format_vnet_dev_counters, &fa,
326 VLIB_CLI_COMMAND (show_device_counters_cmd, static) = {
327 .path = "show device counters",
328 .short_help = "show device counters [all]",
329 .function = show_device_counters_cmd_fn,