linux-cp: Fix API response
[vpp.git] / src / plugins / linux-cp / lcp_api.c
1 /*
2  * Copyright 2020 Rubicon Communications, LLC.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6
7 #include <sys/socket.h>
8 #include <linux/if.h>
9
10 #include <vnet/vnet.h>
11 #include <vnet/plugin/plugin.h>
12
13 #include <vlibapi/api.h>
14 #include <vlibmemory/api.h>
15 #include <vpp/app/version.h>
16 #include <vnet/format_fns.h>
17
18 #include <linux-cp/lcp_interface.h>
19 #include <linux-cp/lcp.api_enum.h>
20 #include <linux-cp/lcp.api_types.h>
21
22 static u16 lcp_msg_id_base;
23 #define REPLY_MSG_ID_BASE lcp_msg_id_base
24 #include <vlibapi/api_helper_macros.h>
25
26 static lip_host_type_t
27 api_decode_host_type (vl_api_lcp_itf_host_type_t type)
28 {
29   if (type == LCP_API_ITF_HOST_TUN)
30     return LCP_ITF_HOST_TUN;
31
32   return LCP_ITF_HOST_TAP;
33 }
34
35 static vl_api_lcp_itf_host_type_t
36 api_encode_host_type (lip_host_type_t type)
37 {
38   if (type == LCP_ITF_HOST_TUN)
39     return LCP_API_ITF_HOST_TUN;
40
41   return LCP_API_ITF_HOST_TAP;
42 }
43
44 static int
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)
49 {
50   u8 *host_if_name, *netns;
51   int host_len, netns_len, rv;
52
53   host_if_name = netns = 0;
54
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);
59
60   netns_len = clib_strnlen ((char *) mp_namespace, sizeof_mp_namespace - 1);
61   vec_add (netns, mp_namespace, netns_len);
62   vec_add1 (netns, 0);
63
64   rv = lcp_itf_pair_create (phy_sw_if_index, host_if_name, lip_host_type,
65                             netns, host_sw_if_index_p);
66
67   vec_free (host_if_name);
68   vec_free (netns);
69
70   return rv;
71 }
72
73 static void
74 vl_api_lcp_itf_pair_add_del_t_handler (vl_api_lcp_itf_pair_add_del_t *mp)
75 {
76   u32 phy_sw_if_index;
77   vl_api_lcp_itf_pair_add_del_reply_t *rmp;
78   lip_host_type_t lip_host_type;
79   int rv;
80
81   VALIDATE_SW_IF_INDEX_END (mp);
82
83   phy_sw_if_index = mp->sw_if_index;
84   lip_host_type = api_decode_host_type (mp->host_if_type);
85   if (mp->is_add)
86     {
87       rv =
88         vl_api_lcp_itf_pair_add (phy_sw_if_index, lip_host_type,
89                                  mp->host_if_name, sizeof (mp->host_if_name),
90                                  mp->namespace, sizeof (mp->namespace), NULL);
91     }
92   else
93     {
94       rv = lcp_itf_pair_delete (phy_sw_if_index);
95     }
96
97   BAD_SW_IF_INDEX_LABEL;
98   REPLY_MACRO (VL_API_LCP_ITF_PAIR_ADD_DEL_REPLY);
99 }
100
101 static void
102 vl_api_lcp_itf_pair_add_del_v2_t_handler (vl_api_lcp_itf_pair_add_del_v2_t *mp)
103 {
104   u32 phy_sw_if_index, host_sw_if_index = ~0;
105   vl_api_lcp_itf_pair_add_del_v2_reply_t *rmp;
106   lip_host_type_t lip_host_type;
107   int rv;
108
109   VALIDATE_SW_IF_INDEX_END (mp);
110
111   phy_sw_if_index = mp->sw_if_index;
112   lip_host_type = api_decode_host_type (mp->host_if_type);
113   if (mp->is_add)
114     {
115       rv = vl_api_lcp_itf_pair_add (phy_sw_if_index, lip_host_type,
116                                     mp->host_if_name,
117                                     sizeof (mp->host_if_name), mp->namespace,
118                                     sizeof (mp->namespace), &host_sw_if_index);
119     }
120   else
121     {
122       rv = lcp_itf_pair_delete (phy_sw_if_index);
123     }
124
125   BAD_SW_IF_INDEX_LABEL;
126   REPLY_MACRO2 (VL_API_LCP_ITF_PAIR_ADD_DEL_V2_REPLY,
127                 { rmp->host_sw_if_index = ntohl (host_sw_if_index); });
128 }
129
130 static void
131 send_lcp_itf_pair_details (index_t lipi, vl_api_registration_t *rp,
132                            u32 context)
133 {
134   vl_api_lcp_itf_pair_details_t *rmp;
135   lcp_itf_pair_t *lcp_pair = lcp_itf_pair_get (lipi);
136
137   REPLY_MACRO_DETAILS4 (
138     VL_API_LCP_ITF_PAIR_DETAILS, rp, context, ({
139       rmp->phy_sw_if_index = ntohl (lcp_pair->lip_phy_sw_if_index);
140       rmp->host_sw_if_index = ntohl (lcp_pair->lip_host_sw_if_index);
141       rmp->vif_index = ntohl (lcp_pair->lip_vif_index);
142       rmp->host_if_type = api_encode_host_type (lcp_pair->lip_host_type);
143
144       memcpy_s (rmp->host_if_name, sizeof (rmp->host_if_name),
145                 lcp_pair->lip_host_name, vec_len (lcp_pair->lip_host_name));
146       rmp->host_if_name[vec_len (lcp_pair->lip_host_name)] = 0;
147
148       memcpy_s (rmp->namespace, sizeof (rmp->namespace),
149                 lcp_pair->lip_namespace, vec_len (lcp_pair->lip_namespace));
150       rmp->namespace[vec_len (lcp_pair->lip_namespace)] = 0;
151     }));
152 }
153
154 static void
155 vl_api_lcp_itf_pair_get_t_handler (vl_api_lcp_itf_pair_get_t *mp)
156 {
157   vl_api_lcp_itf_pair_get_reply_t *rmp;
158   i32 rv = 0;
159
160   REPLY_AND_DETAILS_MACRO (
161     VL_API_LCP_ITF_PAIR_GET_REPLY, lcp_itf_pair_pool,
162     ({ send_lcp_itf_pair_details (cursor, rp, mp->context); }));
163 }
164
165 static void
166 vl_api_lcp_default_ns_set_t_handler (vl_api_lcp_default_ns_set_t *mp)
167 {
168   vl_api_lcp_default_ns_set_reply_t *rmp;
169   int rv;
170
171   mp->namespace[LCP_NS_LEN - 1] = 0;
172   rv = lcp_set_default_ns (mp->namespace);
173
174   REPLY_MACRO (VL_API_LCP_DEFAULT_NS_SET_REPLY);
175 }
176
177 static void
178 vl_api_lcp_default_ns_get_t_handler (vl_api_lcp_default_ns_get_t *mp)
179 {
180   vl_api_lcp_default_ns_get_reply_t *rmp;
181   vl_api_registration_t *reg;
182   char *ns;
183
184   reg = vl_api_client_index_to_registration (mp->client_index);
185   if (!reg)
186     return;
187
188   rmp = vl_msg_api_alloc (sizeof (*rmp));
189   clib_memset (rmp, 0, sizeof (*rmp));
190   rmp->_vl_msg_id = (VL_API_LCP_DEFAULT_NS_GET_REPLY);
191   rmp->context = mp->context;
192
193   ns = (char *) lcp_get_default_ns ();
194   if (ns)
195     clib_strncpy ((char *) rmp->namespace, ns, LCP_NS_LEN - 1);
196
197   vl_api_send_msg (reg, (u8 *) rmp);
198 }
199
200 static void
201 vl_api_lcp_itf_pair_replace_begin_t_handler (
202   vl_api_lcp_itf_pair_replace_begin_t *mp)
203 {
204   vl_api_lcp_itf_pair_replace_begin_reply_t *rmp;
205   int rv;
206
207   rv = lcp_itf_pair_replace_begin ();
208
209   REPLY_MACRO (VL_API_LCP_ITF_PAIR_REPLACE_BEGIN_REPLY);
210 }
211
212 static void
213 vl_api_lcp_itf_pair_replace_end_t_handler (
214   vl_api_lcp_itf_pair_replace_end_t *mp)
215 {
216   vl_api_lcp_itf_pair_replace_end_reply_t *rmp;
217   int rv = 0;
218
219   rv = lcp_itf_pair_replace_end ();
220
221   REPLY_MACRO (VL_API_LCP_ITF_PAIR_REPLACE_END_REPLY);
222 }
223
224 /*
225  * Set up the API message handling tables
226  */
227 #include <linux-cp/lcp.api.c>
228
229 static clib_error_t *
230 lcp_api_init (vlib_main_t *vm)
231 {
232   /* Ask for a correctly-sized block of API message decode slots */
233   lcp_msg_id_base = setup_message_id_table ();
234
235   return (NULL);
236 }
237
238 VLIB_INIT_FUNCTION (lcp_api_init);
239
240 #include <vpp/app/version.h>
241 VLIB_PLUGIN_REGISTER () = {
242   .version = VPP_BUILD_VER,
243   .description = "Linux Control Plane - Interface Mirror",
244   .default_disabled = 1,
245 };
246
247 /*
248  * fd.io coding-style-patch-verification: ON
249  *
250  * Local Variables:
251  * eval: (c-set-style "gnu")
252  * End:
253  */