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 vl_api_lcp_itf_pair_add (u32 phy_sw_if_index, lip_host_type_t lip_host_type,
46 u8 *mp_host_if_name, size_t sizeof_host_if_name,
47 u8 *mp_namespace, size_t sizeof_mp_namespace,
48 u32 *host_sw_if_index_p, u32 *vif_index_p)
50 u8 *host_if_name, *netns;
51 int host_len, netns_len, rv;
53 host_if_name = netns = 0;
55 /* lcp_itf_pair_create expects vec of u8 */
56 host_len = clib_strnlen ((char *) mp_host_if_name, sizeof_host_if_name - 1);
57 vec_add (host_if_name, mp_host_if_name, host_len);
58 vec_add1 (host_if_name, 0);
60 netns_len = clib_strnlen ((char *) mp_namespace, sizeof_mp_namespace - 1);
61 vec_add (netns, mp_namespace, netns_len);
64 rv = lcp_itf_pair_create (phy_sw_if_index, host_if_name, lip_host_type,
65 netns, host_sw_if_index_p);
67 if (!rv && (vif_index_p != NULL))
69 lcp_itf_pair_t *pair =
70 lcp_itf_pair_get (lcp_itf_pair_find_by_phy (phy_sw_if_index));
71 *vif_index_p = pair->lip_vif_index;
74 vec_free (host_if_name);
81 vl_api_lcp_itf_pair_add_del_t_handler (vl_api_lcp_itf_pair_add_del_t *mp)
84 vl_api_lcp_itf_pair_add_del_reply_t *rmp;
85 lip_host_type_t lip_host_type;
88 VALIDATE_SW_IF_INDEX_END (mp);
90 phy_sw_if_index = mp->sw_if_index;
91 lip_host_type = api_decode_host_type (mp->host_if_type);
94 rv = vl_api_lcp_itf_pair_add (
95 phy_sw_if_index, lip_host_type, mp->host_if_name,
96 sizeof (mp->host_if_name), mp->netns, sizeof (mp->netns), NULL, NULL);
100 rv = lcp_itf_pair_delete (phy_sw_if_index);
103 BAD_SW_IF_INDEX_LABEL;
104 REPLY_MACRO_END (VL_API_LCP_ITF_PAIR_ADD_DEL_REPLY);
108 vl_api_lcp_itf_pair_add_del_v2_t_handler (vl_api_lcp_itf_pair_add_del_v2_t *mp)
110 u32 phy_sw_if_index, host_sw_if_index = ~0;
111 vl_api_lcp_itf_pair_add_del_v2_reply_t *rmp;
112 lip_host_type_t lip_host_type;
115 VALIDATE_SW_IF_INDEX_END (mp);
117 phy_sw_if_index = mp->sw_if_index;
118 lip_host_type = api_decode_host_type (mp->host_if_type);
121 rv = vl_api_lcp_itf_pair_add (
122 phy_sw_if_index, lip_host_type, mp->host_if_name,
123 sizeof (mp->host_if_name), mp->netns, sizeof (mp->netns),
124 &host_sw_if_index, NULL);
128 rv = lcp_itf_pair_delete (phy_sw_if_index);
131 BAD_SW_IF_INDEX_LABEL;
132 REPLY_MACRO2_END (VL_API_LCP_ITF_PAIR_ADD_DEL_V2_REPLY,
133 { rmp->host_sw_if_index = host_sw_if_index; });
137 vl_api_lcp_itf_pair_add_del_v3_t_handler (vl_api_lcp_itf_pair_add_del_v3_t *mp)
139 u32 phy_sw_if_index, host_sw_if_index = ~0, vif_index = ~0;
140 vl_api_lcp_itf_pair_add_del_v3_reply_t *rmp;
141 lip_host_type_t lip_host_type;
144 VALIDATE_SW_IF_INDEX_END (mp);
146 phy_sw_if_index = mp->sw_if_index;
147 lip_host_type = api_decode_host_type (mp->host_if_type);
150 rv = vl_api_lcp_itf_pair_add (
151 phy_sw_if_index, lip_host_type, mp->host_if_name,
152 sizeof (mp->host_if_name), mp->netns, sizeof (mp->netns),
153 &host_sw_if_index, &vif_index);
157 rv = lcp_itf_pair_delete (phy_sw_if_index);
160 BAD_SW_IF_INDEX_LABEL;
161 REPLY_MACRO2_END (VL_API_LCP_ITF_PAIR_ADD_DEL_V3_REPLY, ({
162 rmp->host_sw_if_index = host_sw_if_index;
163 rmp->vif_index = vif_index;
168 send_lcp_itf_pair_details (index_t lipi, vl_api_registration_t *rp,
171 vl_api_lcp_itf_pair_details_t *rmp;
172 lcp_itf_pair_t *lcp_pair = lcp_itf_pair_get (lipi);
174 REPLY_MACRO_DETAILS4_END (
175 VL_API_LCP_ITF_PAIR_DETAILS, rp, context, ({
176 rmp->phy_sw_if_index = lcp_pair->lip_phy_sw_if_index;
177 rmp->host_sw_if_index = lcp_pair->lip_host_sw_if_index;
178 rmp->vif_index = lcp_pair->lip_vif_index;
179 rmp->host_if_type = api_encode_host_type (lcp_pair->lip_host_type);
181 memcpy_s (rmp->host_if_name, sizeof (rmp->host_if_name),
182 lcp_pair->lip_host_name, vec_len (lcp_pair->lip_host_name));
183 rmp->host_if_name[vec_len (lcp_pair->lip_host_name)] = 0;
185 memcpy_s (rmp->netns, sizeof (rmp->netns), lcp_pair->lip_namespace,
186 vec_len (lcp_pair->lip_namespace));
187 rmp->netns[vec_len (lcp_pair->lip_namespace)] = 0;
192 vl_api_lcp_itf_pair_get_t_handler (vl_api_lcp_itf_pair_get_t *mp)
194 vl_api_lcp_itf_pair_get_reply_t *rmp;
197 REPLY_AND_DETAILS_MACRO_END (
198 VL_API_LCP_ITF_PAIR_GET_REPLY, lcp_itf_pair_pool,
199 ({ send_lcp_itf_pair_details (cursor, rp, mp->context); }));
203 vl_api_lcp_itf_pair_get_v2_t_handler (vl_api_lcp_itf_pair_get_v2_t *mp)
205 vl_api_lcp_itf_pair_get_v2_reply_t *rmp;
208 if (mp->sw_if_index == ~0)
210 REPLY_AND_DETAILS_MACRO_END (
211 VL_API_LCP_ITF_PAIR_GET_REPLY, lcp_itf_pair_pool,
212 ({ send_lcp_itf_pair_details (cursor, rp, mp->context); }));
216 VALIDATE_SW_IF_INDEX_END (mp);
217 send_lcp_itf_pair_details (
218 lcp_itf_pair_find_by_phy (mp->sw_if_index),
219 vl_api_client_index_to_registration (mp->client_index), mp->context);
221 BAD_SW_IF_INDEX_LABEL;
222 REPLY_MACRO2_END (VL_API_LCP_ITF_PAIR_GET_V2_REPLY,
223 ({ rmp->cursor = ~0; }));
228 vl_api_lcp_default_ns_set_t_handler (vl_api_lcp_default_ns_set_t *mp)
230 vl_api_lcp_default_ns_set_reply_t *rmp;
233 mp->netns[LCP_NS_LEN - 1] = 0;
234 rv = lcp_set_default_ns (mp->netns);
236 REPLY_MACRO (VL_API_LCP_DEFAULT_NS_SET_REPLY);
240 vl_api_lcp_default_ns_get_t_handler (vl_api_lcp_default_ns_get_t *mp)
242 vl_api_lcp_default_ns_get_reply_t *rmp;
244 REPLY_MACRO_DETAILS2 (VL_API_LCP_DEFAULT_NS_GET_REPLY, ({
245 char *ns = (char *) lcp_get_default_ns ();
247 clib_strncpy ((char *) rmp->netns, ns,
253 vl_api_lcp_itf_pair_replace_begin_t_handler (
254 vl_api_lcp_itf_pair_replace_begin_t *mp)
256 vl_api_lcp_itf_pair_replace_begin_reply_t *rmp;
259 rv = lcp_itf_pair_replace_begin ();
261 REPLY_MACRO (VL_API_LCP_ITF_PAIR_REPLACE_BEGIN_REPLY);
265 vl_api_lcp_itf_pair_replace_end_t_handler (
266 vl_api_lcp_itf_pair_replace_end_t *mp)
268 vl_api_lcp_itf_pair_replace_end_reply_t *rmp;
271 rv = lcp_itf_pair_replace_end ();
273 REPLY_MACRO (VL_API_LCP_ITF_PAIR_REPLACE_END_REPLY);
277 * Set up the API message handling tables
279 #include <linux-cp/lcp.api.c>
281 static clib_error_t *
282 lcp_api_init (vlib_main_t *vm)
284 /* Ask for a correctly-sized block of API message decode slots */
285 lcp_msg_id_base = setup_message_id_table ();
290 VLIB_INIT_FUNCTION (lcp_api_init);
292 #include <vpp/app/version.h>
293 VLIB_PLUGIN_REGISTER () = {
294 .version = VPP_BUILD_VER,
295 .description = "Linux Control Plane - Interface Mirror",
296 .default_disabled = 1,
300 * fd.io coding-style-patch-verification: ON
303 * eval: (c-set-style "gnu")