linux-cp: fix vector-used-a-C-string overflow
[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 void
45 lcp_set_auto_intf (u8 is_auto)
46 {
47   lcp_main_t *lcpm = &lcp_main;
48
49   lcpm->auto_intf = (is_auto != 0);
50 }
51
52 int
53 lcp_auto_intf (void)
54 {
55   lcp_main_t *lcpm = &lcp_main;
56
57   return lcpm->auto_intf;
58 }
59
60 static void
61 vl_api_lcp_itf_pair_add_del_t_handler (vl_api_lcp_itf_pair_add_del_t *mp)
62 {
63   u32 phy_sw_if_index;
64   vl_api_lcp_itf_pair_add_del_reply_t *rmp;
65   lip_host_type_t lip_host_type;
66   int rv;
67
68   if (!vnet_sw_if_index_is_api_valid (mp->sw_if_index))
69     {
70       rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;
71       goto bad_sw_if_index;
72     }
73
74   phy_sw_if_index = mp->sw_if_index;
75   lip_host_type = api_decode_host_type (mp->host_if_type);
76   if (mp->is_add)
77     {
78       u8 *host_if_name, *netns;
79       int host_len, netns_len;
80
81       host_if_name = netns = 0;
82
83       /* lcp_itf_pair_create expects vec of u8 */
84       host_len = clib_strnlen ((char *) mp->host_if_name,
85                                sizeof (mp->host_if_name) - 1);
86       vec_add (host_if_name, mp->host_if_name, host_len);
87       vec_add1 (host_if_name, 0);
88
89       netns_len =
90         clib_strnlen ((char *) mp->namespace, sizeof (mp->namespace) - 1);
91       vec_add (netns, mp->namespace, netns_len);
92       vec_add1 (netns, 0);
93
94       rv = lcp_itf_pair_create (phy_sw_if_index, host_if_name, lip_host_type,
95                                 netns);
96
97       vec_free (host_if_name);
98       vec_free (netns);
99     }
100   else
101     {
102       rv = lcp_itf_pair_delete (phy_sw_if_index);
103     }
104
105   BAD_SW_IF_INDEX_LABEL;
106   REPLY_MACRO (VL_API_LCP_ITF_PAIR_ADD_DEL_REPLY);
107 }
108
109 static void
110 send_lcp_itf_pair_details (index_t lipi, vl_api_registration_t *rp,
111                            u32 context)
112 {
113   vl_api_lcp_itf_pair_details_t *rmp;
114   lcp_itf_pair_t *lcp_pair = lcp_itf_pair_get (lipi);
115
116   REPLY_MACRO_DETAILS4 (
117     VL_API_LCP_ITF_PAIR_DETAILS, rp, context, ({
118       rmp->phy_sw_if_index = lcp_pair->lip_phy_sw_if_index;
119       rmp->host_sw_if_index = lcp_pair->lip_host_sw_if_index;
120       rmp->vif_index = lcp_pair->lip_vif_index;
121       rmp->host_if_type = api_encode_host_type (lcp_pair->lip_host_type);
122
123       memcpy_s (rmp->host_if_name, sizeof (rmp->host_if_name),
124                 lcp_pair->lip_host_name, vec_len (lcp_pair->lip_host_name));
125
126       clib_strncpy ((char *) rmp->namespace, (char *) lcp_pair->lip_namespace,
127                     vec_len (lcp_pair->lip_namespace));
128     }));
129 }
130
131 static void
132 vl_api_lcp_itf_pair_get_t_handler (vl_api_lcp_itf_pair_get_t *mp)
133 {
134   vl_api_lcp_itf_pair_get_reply_t *rmp;
135   i32 rv = 0;
136
137   REPLY_AND_DETAILS_MACRO (
138     VL_API_LCP_ITF_PAIR_GET_REPLY, lcp_itf_pair_pool,
139     ({ send_lcp_itf_pair_details (cursor, rp, mp->context); }));
140 }
141
142 static void
143 vl_api_lcp_default_ns_set_t_handler (vl_api_lcp_default_ns_set_t *mp)
144 {
145   vl_api_lcp_default_ns_set_reply_t *rmp;
146   int rv;
147
148   mp->namespace[LCP_NS_LEN - 1] = 0;
149   rv = lcp_set_default_ns (mp->namespace);
150
151   REPLY_MACRO (VL_API_LCP_DEFAULT_NS_SET_REPLY);
152 }
153
154 static void
155 vl_api_lcp_default_ns_get_t_handler (vl_api_lcp_default_ns_get_t *mp)
156 {
157   lcp_main_t *lcpm = &lcp_main;
158   vl_api_lcp_default_ns_get_reply_t *rmp;
159   vl_api_registration_t *reg;
160   char *ns;
161
162   reg = vl_api_client_index_to_registration (mp->client_index);
163   if (!reg)
164     return;
165
166   rmp = vl_msg_api_alloc (sizeof (*rmp));
167   clib_memset (rmp, 0, sizeof (*rmp));
168   rmp->_vl_msg_id = (VL_API_LCP_DEFAULT_NS_GET_REPLY + lcpm->msg_id_base);
169   rmp->context = mp->context;
170
171   ns = (char *) lcp_get_default_ns ();
172   if (ns)
173     clib_strncpy ((char *) rmp->namespace, ns, LCP_NS_LEN - 1);
174
175   vl_api_send_msg (reg, (u8 *) rmp);
176 }
177
178 static void
179 vl_api_lcp_itf_pair_replace_begin_t_handler (
180   vl_api_lcp_itf_pair_replace_begin_t *mp)
181 {
182   vl_api_lcp_itf_pair_replace_begin_reply_t *rmp;
183   int rv;
184
185   rv = lcp_itf_pair_replace_begin ();
186
187   REPLY_MACRO (VL_API_LCP_ITF_PAIR_REPLACE_BEGIN_REPLY);
188 }
189
190 static void
191 vl_api_lcp_itf_pair_replace_end_t_handler (
192   vl_api_lcp_itf_pair_replace_end_t *mp)
193 {
194   vl_api_lcp_itf_pair_replace_end_reply_t *rmp;
195   int rv = 0;
196
197   rv = lcp_itf_pair_replace_end ();
198
199   REPLY_MACRO (VL_API_LCP_ITF_PAIR_REPLACE_END_REPLY);
200 }
201
202 /*
203  * Set up the API message handling tables
204  */
205 #include <linux-cp/lcp.api.c>
206
207 static clib_error_t *
208 lcp_plugin_api_hookup (vlib_main_t *vm)
209 {
210   /* Ask for a correctly-sized block of API message decode slots */
211   lcp_msg_id_base = setup_message_id_table ();
212
213   return (NULL);
214 }
215
216 VLIB_INIT_FUNCTION (lcp_plugin_api_hookup);
217
218 #include <vpp/app/version.h>
219 VLIB_PLUGIN_REGISTER () = {
220   .version = VPP_BUILD_VER,
221   .description = "Linux Control Plane - Interface Mirror",
222   .default_disabled = 1,
223 };
224
225 /*
226  * fd.io coding-style-patch-verification: ON
227  *
228  * Local Variables:
229  * eval: (c-set-style "gnu")
230  * End:
231  */