2 * Copyright 2020 Rubicon Communications, LLC.
4 * SPDX-License-Identifier: Apache-2.0
7 #include <sys/socket.h>
10 #include <vnet/vnet.h>
11 #include <vnet/plugin/plugin.h>
13 #include <vlibapi/api.h>
14 #include <vlibmemory/api.h>
15 #include <vpp/app/version.h>
16 #include <vnet/format_fns.h>
18 #include <linux-cp/lcp_interface.h>
19 #include <linux-cp/lcp.api_enum.h>
20 #include <linux-cp/lcp.api_types.h>
22 static u16 lcp_msg_id_base;
23 #define REPLY_MSG_ID_BASE lcp_msg_id_base
24 #include <vlibapi/api_helper_macros.h>
26 static lip_host_type_t
27 api_decode_host_type (vl_api_lcp_itf_host_type_t type)
29 if (type == LCP_API_ITF_HOST_TUN)
30 return LCP_ITF_HOST_TUN;
32 return LCP_ITF_HOST_TAP;
35 static vl_api_lcp_itf_host_type_t
36 api_encode_host_type (lip_host_type_t type)
38 if (type == LCP_ITF_HOST_TUN)
39 return LCP_API_ITF_HOST_TUN;
41 return LCP_API_ITF_HOST_TAP;
45 lcp_set_auto_intf (u8 is_auto)
47 lcp_main_t *lcpm = &lcp_main;
49 lcpm->auto_intf = (is_auto != 0);
55 lcp_main_t *lcpm = &lcp_main;
57 return lcpm->auto_intf;
61 vl_api_lcp_itf_pair_add (u32 phy_sw_if_index, lip_host_type_t lip_host_type,
62 u8 *mp_host_if_name, size_t sizeof_host_if_name,
63 u8 *mp_namespace, size_t sizeof_mp_namespace,
64 u32 *host_sw_if_index_p)
66 u8 *host_if_name, *netns;
67 int host_len, netns_len, rv;
69 host_if_name = netns = 0;
71 /* lcp_itf_pair_create expects vec of u8 */
72 host_len = clib_strnlen ((char *) mp_host_if_name, sizeof_host_if_name - 1);
73 vec_add (host_if_name, mp_host_if_name, host_len);
74 vec_add1 (host_if_name, 0);
76 netns_len = clib_strnlen ((char *) mp_namespace, sizeof_mp_namespace - 1);
77 vec_add (netns, mp_namespace, netns_len);
80 rv = lcp_itf_pair_create (phy_sw_if_index, host_if_name, lip_host_type,
81 netns, host_sw_if_index_p);
83 vec_free (host_if_name);
90 vl_api_lcp_itf_pair_add_del_t_handler (vl_api_lcp_itf_pair_add_del_t *mp)
93 vl_api_lcp_itf_pair_add_del_reply_t *rmp;
94 lip_host_type_t lip_host_type;
97 if (!vnet_sw_if_index_is_api_valid (mp->sw_if_index))
99 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;
100 goto bad_sw_if_index;
103 phy_sw_if_index = mp->sw_if_index;
104 lip_host_type = api_decode_host_type (mp->host_if_type);
108 vl_api_lcp_itf_pair_add (phy_sw_if_index, lip_host_type,
109 mp->host_if_name, sizeof (mp->host_if_name),
110 mp->namespace, sizeof (mp->namespace), NULL);
114 rv = lcp_itf_pair_delete (phy_sw_if_index);
117 BAD_SW_IF_INDEX_LABEL;
118 REPLY_MACRO (VL_API_LCP_ITF_PAIR_ADD_DEL_REPLY);
122 vl_api_lcp_itf_pair_add_del_v2_t_handler (vl_api_lcp_itf_pair_add_del_v2_t *mp)
124 u32 phy_sw_if_index, host_sw_if_index = ~0;
125 vl_api_lcp_itf_pair_add_del_v2_reply_t *rmp;
126 lip_host_type_t lip_host_type;
129 if (!vnet_sw_if_index_is_api_valid (mp->sw_if_index))
131 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;
132 goto bad_sw_if_index;
135 phy_sw_if_index = mp->sw_if_index;
136 lip_host_type = api_decode_host_type (mp->host_if_type);
139 rv = vl_api_lcp_itf_pair_add (phy_sw_if_index, lip_host_type,
141 sizeof (mp->host_if_name), mp->namespace,
142 sizeof (mp->namespace), &host_sw_if_index);
146 rv = lcp_itf_pair_delete (phy_sw_if_index);
149 BAD_SW_IF_INDEX_LABEL;
150 REPLY_MACRO2 (VL_API_LCP_ITF_PAIR_ADD_DEL_V2_REPLY,
151 { rmp->host_sw_if_index = ntohl (host_sw_if_index); });
155 send_lcp_itf_pair_details (index_t lipi, vl_api_registration_t *rp,
158 vl_api_lcp_itf_pair_details_t *rmp;
159 lcp_itf_pair_t *lcp_pair = lcp_itf_pair_get (lipi);
161 REPLY_MACRO_DETAILS4 (
162 VL_API_LCP_ITF_PAIR_DETAILS, rp, context, ({
163 rmp->phy_sw_if_index = lcp_pair->lip_phy_sw_if_index;
164 rmp->host_sw_if_index = lcp_pair->lip_host_sw_if_index;
165 rmp->vif_index = lcp_pair->lip_vif_index;
166 rmp->host_if_type = api_encode_host_type (lcp_pair->lip_host_type);
168 memcpy_s (rmp->host_if_name, sizeof (rmp->host_if_name),
169 lcp_pair->lip_host_name, vec_len (lcp_pair->lip_host_name));
171 clib_strncpy ((char *) rmp->namespace, (char *) lcp_pair->lip_namespace,
172 vec_len (lcp_pair->lip_namespace));
177 vl_api_lcp_itf_pair_get_t_handler (vl_api_lcp_itf_pair_get_t *mp)
179 vl_api_lcp_itf_pair_get_reply_t *rmp;
182 REPLY_AND_DETAILS_MACRO (
183 VL_API_LCP_ITF_PAIR_GET_REPLY, lcp_itf_pair_pool,
184 ({ send_lcp_itf_pair_details (cursor, rp, mp->context); }));
188 vl_api_lcp_default_ns_set_t_handler (vl_api_lcp_default_ns_set_t *mp)
190 vl_api_lcp_default_ns_set_reply_t *rmp;
193 mp->namespace[LCP_NS_LEN - 1] = 0;
194 rv = lcp_set_default_ns (mp->namespace);
196 REPLY_MACRO (VL_API_LCP_DEFAULT_NS_SET_REPLY);
200 vl_api_lcp_default_ns_get_t_handler (vl_api_lcp_default_ns_get_t *mp)
202 lcp_main_t *lcpm = &lcp_main;
203 vl_api_lcp_default_ns_get_reply_t *rmp;
204 vl_api_registration_t *reg;
207 reg = vl_api_client_index_to_registration (mp->client_index);
211 rmp = vl_msg_api_alloc (sizeof (*rmp));
212 clib_memset (rmp, 0, sizeof (*rmp));
213 rmp->_vl_msg_id = (VL_API_LCP_DEFAULT_NS_GET_REPLY + lcpm->msg_id_base);
214 rmp->context = mp->context;
216 ns = (char *) lcp_get_default_ns ();
218 clib_strncpy ((char *) rmp->namespace, ns, LCP_NS_LEN - 1);
220 vl_api_send_msg (reg, (u8 *) rmp);
224 vl_api_lcp_itf_pair_replace_begin_t_handler (
225 vl_api_lcp_itf_pair_replace_begin_t *mp)
227 vl_api_lcp_itf_pair_replace_begin_reply_t *rmp;
230 rv = lcp_itf_pair_replace_begin ();
232 REPLY_MACRO (VL_API_LCP_ITF_PAIR_REPLACE_BEGIN_REPLY);
236 vl_api_lcp_itf_pair_replace_end_t_handler (
237 vl_api_lcp_itf_pair_replace_end_t *mp)
239 vl_api_lcp_itf_pair_replace_end_reply_t *rmp;
242 rv = lcp_itf_pair_replace_end ();
244 REPLY_MACRO (VL_API_LCP_ITF_PAIR_REPLACE_END_REPLY);
248 * Set up the API message handling tables
250 #include <linux-cp/lcp.api.c>
252 static clib_error_t *
253 lcp_plugin_api_hookup (vlib_main_t *vm)
255 /* Ask for a correctly-sized block of API message decode slots */
256 lcp_msg_id_base = setup_message_id_table ();
261 VLIB_INIT_FUNCTION (lcp_plugin_api_hookup);
263 #include <vpp/app/version.h>
264 VLIB_PLUGIN_REGISTER () = {
265 .version = VPP_BUILD_VER,
266 .description = "Linux Control Plane - Interface Mirror",
267 .default_disabled = 1,
271 * fd.io coding-style-patch-verification: ON
274 * eval: (c-set-style "gnu")