blob: 5e9ac502b5d3525b2a96d954bfaef531aac424c5 [file] [log] [blame]
Damjan Marionddf6cec2023-11-22 16:25:55 +00001/* SPDX-License-Identifier: Apache-2.0
2 * Copyright (c) 2023 Cisco Systems, Inc.
3 */
4
5#include <vnet/vnet.h>
6#include <vnet/dev/dev.h>
7#include <vnet/dev/api.h>
8
9#include <vlibapi/api.h>
10#include <vlibmemory/api.h>
11
12/* define message IDs */
13#include <dev/dev.api_enum.h>
14#include <dev/dev.api_types.h>
15
16static u16 vnet_dev_api_msg_id_base;
17
18#define REPLY_MSG_ID_BASE (vnet_dev_api_msg_id_base)
19#include <vlibapi/api_helper_macros.h>
20
21#define _(b, n, d) \
22 STATIC_ASSERT ((int) VL_API_DEV_FLAG_##n == (int) VNET_DEV_F_##n, "");
23foreach_vnet_dev_flag;
24#undef _
25
26#define _(b, n, d) \
27 STATIC_ASSERT ((int) VL_API_DEV_PORT_FLAG_##n == (int) VNET_DEV_PORT_F_##n, \
28 "");
29foreach_vnet_dev_port_flag;
30#undef _
31
32static void
33vl_api_dev_attach_t_handler (vl_api_dev_attach_t *mp)
34{
35 vlib_main_t *vm = vlib_get_main ();
36 vl_api_dev_attach_reply_t *rmp;
37 vnet_dev_api_attach_args_t a = {};
38 vnet_dev_rv_t rv;
39 u8 *error_string = 0;
40
41 STATIC_ASSERT (sizeof (mp->device_id) == sizeof (a.device_id), "");
42 STATIC_ASSERT (sizeof (mp->driver_name) == sizeof (a.driver_name), "");
43 STATIC_ASSERT (sizeof (mp->flags) == sizeof (a.flags), "");
44
45 a.flags.n = mp->flags;
46 strncpy (a.device_id, (char *) mp->device_id, sizeof (a.device_id));
47 strncpy (a.driver_name, (char *) mp->driver_name, sizeof (a.driver_name));
48 vec_add (a.args, mp->args.buf, mp->args.length);
49
50 rv = vnet_dev_api_attach (vm, &a);
51
52 if (rv != VNET_DEV_OK)
53 error_string = format (0, "%U", format_vnet_dev_rv, rv);
54
55 vec_free (a.args);
56
Vratko Polak3a9c3eb2023-11-30 17:42:25 +010057 REPLY_MACRO3_END (VL_API_DEV_ATTACH_REPLY, vec_len (error_string), ({
58 rmp->retval = rv;
59 if (error_string)
60 {
61 rmp->dev_index = ~0;
62 vl_api_vec_to_api_string (error_string,
63 &rmp->error_string);
64 }
65 else
66 rmp->dev_index = a.dev_index;
67 }));
Damjan Marionddf6cec2023-11-22 16:25:55 +000068
69 vec_free (a.args);
70 vec_free (error_string);
71}
72
73static void
74vl_api_dev_detach_t_handler (vl_api_dev_detach_t *mp)
75{
76 vlib_main_t *vm = vlib_get_main ();
77 vl_api_dev_detach_reply_t *rmp;
78 vnet_dev_api_detach_args_t a = {};
79 vnet_dev_rv_t rv;
80 u8 *error_string = 0;
81
82 a.dev_index = mp->dev_index;
83
84 rv = vnet_dev_api_detach (vm, &a);
85
86 if (rv != VNET_DEV_OK)
87 error_string = format (0, "%U", format_vnet_dev_rv, rv);
88
Vratko Polak3a9c3eb2023-11-30 17:42:25 +010089 REPLY_MACRO3_END (VL_API_DEV_DETACH_REPLY, vec_len (error_string), ({
90 rmp->retval = rv;
91 if (error_string)
92 vl_api_vec_to_api_string (error_string,
93 &rmp->error_string);
94 }));
Damjan Marionddf6cec2023-11-22 16:25:55 +000095
96 vec_free (error_string);
97}
98
99static void
100vl_api_dev_create_port_if_t_handler (vl_api_dev_create_port_if_t *mp)
101{
102 vlib_main_t *vm = vlib_get_main ();
103 vl_api_dev_create_port_if_reply_t *rmp;
104 vnet_dev_api_create_port_if_args_t a = {};
105 vnet_dev_rv_t rv;
106 u8 *error_string = 0;
107
108 STATIC_ASSERT (sizeof (mp->intf_name) == sizeof (a.intf_name), "");
109 STATIC_ASSERT (sizeof (mp->flags) == sizeof (a.flags), "");
110
111 a.flags.n = mp->flags;
112#define _(n) a.n = mp->n;
113 _ (dev_index)
114 _ (port_id)
115 _ (num_rx_queues)
116 _ (num_tx_queues)
117 _ (rx_queue_size)
118 _ (tx_queue_size)
119#undef _
120
121 strncpy (a.intf_name, (char *) mp->intf_name, sizeof (a.intf_name));
122 vec_add (a.args, mp->args.buf, mp->args.length);
123
124 rv = vnet_dev_api_create_port_if (vm, &a);
125
126 if (rv != VNET_DEV_OK)
127 error_string = format (0, "%U", format_vnet_dev_rv, rv);
128
129 vec_free (a.args);
130
Vratko Polak3a9c3eb2023-11-30 17:42:25 +0100131 REPLY_MACRO3_END (VL_API_DEV_CREATE_PORT_IF_REPLY, vec_len (error_string), ({
132 rmp->retval = rv;
133 if (error_string)
134 {
135 rmp->sw_if_index = ~0;
136 vl_api_vec_to_api_string (error_string,
137 &rmp->error_string);
138 }
139 else
140 rmp->sw_if_index = a.sw_if_index;
141 }));
Damjan Marionddf6cec2023-11-22 16:25:55 +0000142
143 vec_free (a.args);
144 vec_free (error_string);
145}
146
147static void
148vl_api_dev_remove_port_if_t_handler (vl_api_dev_remove_port_if_t *mp)
149{
150 vlib_main_t *vm = vlib_get_main ();
151 vl_api_dev_remove_port_if_reply_t *rmp;
152 vnet_dev_api_remove_port_if_args_t a = {};
153 vnet_dev_rv_t rv;
154 u8 *error_string = 0;
155
156 a.sw_if_index = mp->sw_if_index;
157
158 rv = vnet_dev_api_remove_port_if (vm, &a);
159
160 if (rv != VNET_DEV_OK)
161 error_string = format (0, "%U", format_vnet_dev_rv, rv);
162
Vratko Polak3a9c3eb2023-11-30 17:42:25 +0100163 REPLY_MACRO3_END (VL_API_DEV_REMOVE_PORT_IF_REPLY, vec_len (error_string), ({
164 rmp->retval = rv;
165 if (error_string)
166 vl_api_vec_to_api_string (error_string,
167 &rmp->error_string);
168 }));
Damjan Marionddf6cec2023-11-22 16:25:55 +0000169
170 vec_free (error_string);
171}
172
173/* set tup the API message handling tables */
174
175#include <dev/dev.api.c>
176
177static clib_error_t *
178vnet_dev_api_hookup (vlib_main_t *vm)
179{
180 api_main_t *am = vlibapi_get_main ();
181
182 /* ask for a correctly-sized block of API message decode slots */
183 vnet_dev_api_msg_id_base = setup_message_id_table ();
184
Damjan Marion39e79fd2023-11-29 13:54:15 +0000185 foreach_int (i, VL_API_DEV_ATTACH, VL_API_DEV_DETACH,
186 VL_API_DEV_CREATE_PORT_IF, VL_API_DEV_REMOVE_PORT_IF)
187 vl_api_set_msg_thread_safe (am, vnet_dev_api_msg_id_base + i, 1);
Damjan Marionddf6cec2023-11-22 16:25:55 +0000188
189 return 0;
190}
191
192VLIB_API_INIT_FUNCTION (vnet_dev_api_hookup);