blob: 8883e727ac2fa5229ebecf26a8f0f9229eef244f [file] [log] [blame]
Damjan Marion38c61912023-10-17 16:06:26 +00001/* SPDX-License-Identifier: Apache-2.0
2 * Copyright (c) 2023 Cisco Systems, Inc.
3 */
4
5#include "vppinfra/error.h"
6#include "vppinfra/pool.h"
7#include <vnet/vnet.h>
8#include <vnet/ethernet/ethernet.h>
9#include <vnet/dev/dev.h>
10#include <vnet/dev/api.h>
11#include <vnet/dev/log.h>
12
13VLIB_REGISTER_LOG_CLASS (dev_log, static) = {
14 .class_name = "dev",
15 .subclass_name = "config",
16};
17
18static clib_error_t *
19vnet_dev_config_one_interface (vlib_main_t *vm, unformat_input_t *input,
20 vnet_dev_api_create_port_if_args_t *args)
21{
22 clib_error_t *err = 0;
23
24 log_debug (0, "port %u %U", args->port_id, format_unformat_input, input);
25
26 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
27 {
28 u32 n;
29
30 if (unformat (input, "name %U", unformat_c_string_array, args->intf_name,
31 sizeof (args->intf_name)))
32 ;
33 else if (unformat (input, "num-rx-queues %u", &n))
34 args->num_rx_queues = n;
35 else if (unformat (input, "num-tx-queues %u", &n))
36 args->num_tx_queues = n;
37 else if (unformat (input, "rx-queue-size %u", &n))
38 args->rx_queue_size = n;
39 else if (unformat (input, "tx-queue-size %u", &n))
40 args->tx_queue_size = n;
41 else if (unformat (input, "flags %U", unformat_vnet_dev_port_flags,
42 &args->flags))
43 ;
Damjan Marion69768d92023-11-13 17:33:32 +000044 else if (unformat (input, "args %U", unformat_single_quoted_string,
45 &args->args))
46 ;
Damjan Marion38c61912023-10-17 16:06:26 +000047 else
48 {
49 err = clib_error_return (0, "unknown input '%U'",
50 format_unformat_error, input);
51 break;
52 }
53 }
54 return err;
55}
Damjan Marion38c61912023-10-17 16:06:26 +000056static clib_error_t *
57vnet_dev_config_one_device (vlib_main_t *vm, unformat_input_t *input,
58 char *device_id)
59{
60 log_debug (0, "device %s %U", device_id, format_unformat_input, input);
61 clib_error_t *err = 0;
62 vnet_dev_api_attach_args_t args = {};
63 vnet_dev_api_create_port_if_args_t *if_args_vec = 0, *if_args;
64
65 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
66 {
67 unformat_input_t sub_input;
68 u32 n;
69
70 if (unformat (input, "driver %U", unformat_c_string_array,
71 args.driver_name, sizeof (args.driver_name)))
72 ;
73 else if (unformat (input, "flags %U", unformat_vnet_dev_flags,
74 &args.flags))
75 ;
Damjan Marion69768d92023-11-13 17:33:32 +000076 else if (unformat (input, "args %U", unformat_single_quoted_string,
77 &args.args))
78 ;
Damjan Marion38c61912023-10-17 16:06:26 +000079 else if (unformat (input, "port %u %U", &n, unformat_vlib_cli_sub_input,
80 &sub_input))
81 {
82 vnet_dev_api_create_port_if_args_t *if_args;
83 vec_add2 (if_args_vec, if_args, 1);
84 if_args->port_id = n;
85 err = vnet_dev_config_one_interface (vm, &sub_input, if_args);
86 unformat_free (&sub_input);
87 if (err)
88 break;
89 }
90 else
91 {
92 err = clib_error_return (0, "unknown input '%U'",
93 format_unformat_error, input);
94 break;
95 }
96 }
97
98 if (err == 0)
99 {
100 vnet_dev_rv_t rv;
101
102 clib_memcpy (args.device_id, device_id, sizeof (args.device_id));
103 rv = vnet_dev_api_attach (vm, &args);
Damjan Marion69768d92023-11-13 17:33:32 +0000104 vec_free (args.args);
Damjan Marion38c61912023-10-17 16:06:26 +0000105
106 if (rv == VNET_DEV_OK)
107 {
108 vec_foreach (if_args, if_args_vec)
109 {
Damjan Marionddf6cec2023-11-22 16:25:55 +0000110 if_args->dev_index = args.dev_index;
Damjan Marion38c61912023-10-17 16:06:26 +0000111 rv = vnet_dev_api_create_port_if (vm, if_args);
112 if (rv != VNET_DEV_OK)
113 break;
114 }
Damjan Marion38c61912023-10-17 16:06:26 +0000115 }
Damjan Marion862097a2023-11-15 22:47:37 +0100116
117 if (rv != VNET_DEV_OK)
118 err = clib_error_return (0, "error: %U for device '%s'",
119 format_vnet_dev_rv, rv, device_id);
Damjan Marion38c61912023-10-17 16:06:26 +0000120 }
121
122 vec_free (if_args_vec);
123 return err;
124}
125
126uword
127dev_config_process_node_fn (vlib_main_t *vm, vlib_node_runtime_t *rt,
128 vlib_frame_t *f)
129{
130 vnet_dev_main_t *dm = &vnet_dev_main;
131 unformat_input_t input;
132 clib_error_t *err = 0;
133
134 if (dm->startup_config == 0)
135 return 0;
136
137 unformat_init_vector (&input, dm->startup_config);
138 dm->startup_config = 0;
139
Damjan Marion862097a2023-11-15 22:47:37 +0100140 while (!err && unformat_check_input (&input) != UNFORMAT_END_OF_INPUT)
Damjan Marion38c61912023-10-17 16:06:26 +0000141 {
142 unformat_input_t sub_input;
143 vnet_dev_device_id_t device_id;
144 if (unformat (&input, "dev %U %U", unformat_c_string_array, device_id,
145 sizeof (device_id), unformat_vlib_cli_sub_input,
146 &sub_input))
147 {
148 err = vnet_dev_config_one_device (vm, &sub_input, device_id);
149 unformat_free (&sub_input);
Damjan Marion862097a2023-11-15 22:47:37 +0100150 }
151 else if (unformat (&input, "dev %U", unformat_c_string_array, device_id,
152 sizeof (device_id)))
153 {
154 unformat_input_t no_input = {};
155 unformat_init_vector (&no_input, 0);
156 err = vnet_dev_config_one_device (vm, &no_input, device_id);
157 unformat_free (&no_input);
Damjan Marion38c61912023-10-17 16:06:26 +0000158 }
159 else
Damjan Marion862097a2023-11-15 22:47:37 +0100160 err = clib_error_return (0, "unknown input '%U'",
161 format_unformat_error, &input);
Damjan Marion38c61912023-10-17 16:06:26 +0000162 }
163
164 unformat_free (&input);
165
Damjan Marion862097a2023-11-15 22:47:37 +0100166 if (err)
167 {
168 log_err (0, "%U", format_clib_error, err);
169 clib_error_free (err);
170 }
171
Damjan Marion38c61912023-10-17 16:06:26 +0000172 vlib_node_set_state (vm, rt->node_index, VLIB_NODE_STATE_DISABLED);
173 vlib_node_rename (vm, rt->node_index, "deleted-%u", rt->node_index);
174 vec_add1 (dm->free_process_node_indices, rt->node_index);
175 return 0;
176}
177
178VLIB_REGISTER_NODE (dev_config_process_node) = {
179 .function = dev_config_process_node_fn,
180 .type = VLIB_NODE_TYPE_PROCESS,
181 .name = "dev-config",
182};
183
184static clib_error_t *
185devices_config (vlib_main_t *vm, unformat_input_t *input)
186{
187 vnet_dev_main_t *dm = &vnet_dev_main;
188 uword c;
189
190 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
191 vec_add1 (dm->startup_config, c);
192
193 return 0;
194}
195
196VLIB_CONFIG_FUNCTION (devices_config, "devices");