1 /* SPDX-License-Identifier: Apache-2.0
2 * Copyright (c) 2023 Cisco Systems, Inc.
6 #include <vnet/dev/dev.h>
7 #include <vnet/dev/api.h>
9 #include <vlibapi/api.h>
10 #include <vlibmemory/api.h>
12 /* define message IDs */
13 #include <dev/dev.api_enum.h>
14 #include <dev/dev.api_types.h>
16 static u16 vnet_dev_api_msg_id_base;
18 #define REPLY_MSG_ID_BASE (vnet_dev_api_msg_id_base)
19 #include <vlibapi/api_helper_macros.h>
22 STATIC_ASSERT ((int) VL_API_DEV_FLAG_##n == (int) VNET_DEV_F_##n, "");
23 foreach_vnet_dev_flag;
27 STATIC_ASSERT ((int) VL_API_DEV_PORT_FLAG_##n == (int) VNET_DEV_PORT_F_##n, \
29 foreach_vnet_dev_port_flag;
33 vl_api_dev_attach_t_handler (vl_api_dev_attach_t *mp)
35 vlib_main_t *vm = vlib_get_main ();
36 vl_api_dev_attach_reply_t *rmp;
37 vnet_dev_api_attach_args_t a = {};
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), "");
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);
50 rv = vnet_dev_api_attach (vm, &a);
52 if (rv != VNET_DEV_OK)
53 error_string = format (0, "%U", format_vnet_dev_rv, rv);
57 REPLY_MACRO3_END (VL_API_DEV_ATTACH_REPLY, vec_len (error_string), ({
62 vl_api_vec_to_api_string (error_string,
66 rmp->dev_index = a.dev_index;
70 vec_free (error_string);
74 vl_api_dev_detach_t_handler (vl_api_dev_detach_t *mp)
76 vlib_main_t *vm = vlib_get_main ();
77 vl_api_dev_detach_reply_t *rmp;
78 vnet_dev_api_detach_args_t a = {};
82 a.dev_index = mp->dev_index;
84 rv = vnet_dev_api_detach (vm, &a);
86 if (rv != VNET_DEV_OK)
87 error_string = format (0, "%U", format_vnet_dev_rv, rv);
89 REPLY_MACRO3_END (VL_API_DEV_DETACH_REPLY, vec_len (error_string), ({
92 vl_api_vec_to_api_string (error_string,
96 vec_free (error_string);
100 vl_api_dev_create_port_if_t_handler (vl_api_dev_create_port_if_t *mp)
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 = {};
106 u8 *error_string = 0;
108 STATIC_ASSERT (sizeof (mp->intf_name) == sizeof (a.intf_name), "");
109 STATIC_ASSERT (sizeof (mp->flags) == sizeof (a.flags), "");
111 a.flags.n = mp->flags;
112 #define _(n) a.n = mp->n;
121 strncpy (a.intf_name, (char *) mp->intf_name, sizeof (a.intf_name));
122 vec_add (a.args, mp->args.buf, mp->args.length);
124 rv = vnet_dev_api_create_port_if (vm, &a);
126 if (rv != VNET_DEV_OK)
127 error_string = format (0, "%U", format_vnet_dev_rv, rv);
131 REPLY_MACRO3_END (VL_API_DEV_CREATE_PORT_IF_REPLY, vec_len (error_string), ({
135 rmp->sw_if_index = ~0;
136 vl_api_vec_to_api_string (error_string,
140 rmp->sw_if_index = a.sw_if_index;
144 vec_free (error_string);
148 vl_api_dev_remove_port_if_t_handler (vl_api_dev_remove_port_if_t *mp)
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 = {};
154 u8 *error_string = 0;
156 a.sw_if_index = mp->sw_if_index;
158 rv = vnet_dev_api_remove_port_if (vm, &a);
160 if (rv != VNET_DEV_OK)
161 error_string = format (0, "%U", format_vnet_dev_rv, rv);
163 REPLY_MACRO3_END (VL_API_DEV_REMOVE_PORT_IF_REPLY, vec_len (error_string), ({
166 vl_api_vec_to_api_string (error_string,
170 vec_free (error_string);
173 /* set tup the API message handling tables */
175 #include <dev/dev.api.c>
177 static clib_error_t *
178 vnet_dev_api_hookup (vlib_main_t *vm)
180 api_main_t *am = vlibapi_get_main ();
182 /* ask for a correctly-sized block of API message decode slots */
183 vnet_dev_api_msg_id_base = setup_message_id_table ();
185 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);
192 VLIB_API_INIT_FUNCTION (vnet_dev_api_hookup);