Line data Source code
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 0 : api_decode_host_type (vl_api_lcp_itf_host_type_t type)
28 : {
29 0 : if (type == LCP_API_ITF_HOST_TUN)
30 0 : return LCP_ITF_HOST_TUN;
31 :
32 0 : return LCP_ITF_HOST_TAP;
33 : }
34 :
35 : static vl_api_lcp_itf_host_type_t
36 8 : api_encode_host_type (lip_host_type_t type)
37 : {
38 8 : if (type == LCP_ITF_HOST_TUN)
39 4 : return LCP_API_ITF_HOST_TUN;
40 :
41 4 : return LCP_API_ITF_HOST_TAP;
42 : }
43 :
44 : static int
45 0 : 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 0 : host_if_name = netns = 0;
54 :
55 : /* lcp_itf_pair_create expects vec of u8 */
56 0 : host_len = clib_strnlen ((char *) mp_host_if_name, sizeof_host_if_name - 1);
57 0 : vec_add (host_if_name, mp_host_if_name, host_len);
58 0 : vec_add1 (host_if_name, 0);
59 :
60 0 : netns_len = clib_strnlen ((char *) mp_namespace, sizeof_mp_namespace - 1);
61 0 : vec_add (netns, mp_namespace, netns_len);
62 0 : vec_add1 (netns, 0);
63 :
64 0 : rv = lcp_itf_pair_create (phy_sw_if_index, host_if_name, lip_host_type,
65 : netns, host_sw_if_index_p);
66 :
67 0 : vec_free (host_if_name);
68 0 : vec_free (netns);
69 :
70 0 : return rv;
71 : }
72 :
73 : static void
74 0 : 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 0 : VALIDATE_SW_IF_INDEX_END (mp);
82 :
83 0 : phy_sw_if_index = mp->sw_if_index;
84 0 : lip_host_type = api_decode_host_type (mp->host_if_type);
85 0 : if (mp->is_add)
86 : {
87 0 : rv = vl_api_lcp_itf_pair_add (
88 0 : phy_sw_if_index, lip_host_type, mp->host_if_name,
89 0 : sizeof (mp->host_if_name), mp->netns, sizeof (mp->netns), NULL);
90 : }
91 : else
92 : {
93 0 : rv = lcp_itf_pair_delete (phy_sw_if_index);
94 : }
95 :
96 0 : BAD_SW_IF_INDEX_LABEL;
97 0 : REPLY_MACRO_END (VL_API_LCP_ITF_PAIR_ADD_DEL_REPLY);
98 : }
99 :
100 : static void
101 0 : vl_api_lcp_itf_pair_add_del_v2_t_handler (vl_api_lcp_itf_pair_add_del_v2_t *mp)
102 : {
103 0 : u32 phy_sw_if_index, host_sw_if_index = ~0;
104 : vl_api_lcp_itf_pair_add_del_v2_reply_t *rmp;
105 : lip_host_type_t lip_host_type;
106 : int rv;
107 :
108 0 : VALIDATE_SW_IF_INDEX_END (mp);
109 :
110 0 : phy_sw_if_index = mp->sw_if_index;
111 0 : lip_host_type = api_decode_host_type (mp->host_if_type);
112 0 : if (mp->is_add)
113 : {
114 0 : rv = vl_api_lcp_itf_pair_add (phy_sw_if_index, lip_host_type,
115 0 : mp->host_if_name,
116 0 : sizeof (mp->host_if_name), mp->netns,
117 : sizeof (mp->netns), &host_sw_if_index);
118 : }
119 : else
120 : {
121 0 : rv = lcp_itf_pair_delete (phy_sw_if_index);
122 : }
123 :
124 0 : BAD_SW_IF_INDEX_LABEL;
125 0 : REPLY_MACRO2_END (VL_API_LCP_ITF_PAIR_ADD_DEL_V2_REPLY,
126 : { rmp->host_sw_if_index = host_sw_if_index; });
127 : }
128 :
129 : static void
130 8 : send_lcp_itf_pair_details (index_t lipi, vl_api_registration_t *rp,
131 : u32 context)
132 : {
133 : vl_api_lcp_itf_pair_details_t *rmp;
134 8 : lcp_itf_pair_t *lcp_pair = lcp_itf_pair_get (lipi);
135 :
136 8 : REPLY_MACRO_DETAILS4_END (
137 : VL_API_LCP_ITF_PAIR_DETAILS, rp, context, ({
138 : rmp->phy_sw_if_index = lcp_pair->lip_phy_sw_if_index;
139 : rmp->host_sw_if_index = lcp_pair->lip_host_sw_if_index;
140 : rmp->vif_index = lcp_pair->lip_vif_index;
141 : rmp->host_if_type = api_encode_host_type (lcp_pair->lip_host_type);
142 :
143 : memcpy_s (rmp->host_if_name, sizeof (rmp->host_if_name),
144 : lcp_pair->lip_host_name, vec_len (lcp_pair->lip_host_name));
145 : rmp->host_if_name[vec_len (lcp_pair->lip_host_name)] = 0;
146 :
147 : memcpy_s (rmp->netns, sizeof (rmp->netns), lcp_pair->lip_namespace,
148 : vec_len (lcp_pair->lip_namespace));
149 : rmp->netns[vec_len (lcp_pair->lip_namespace)] = 0;
150 : }));
151 8 : }
152 :
153 : static void
154 9 : vl_api_lcp_itf_pair_get_t_handler (vl_api_lcp_itf_pair_get_t *mp)
155 : {
156 : vl_api_lcp_itf_pair_get_reply_t *rmp;
157 9 : i32 rv = 0;
158 :
159 17 : REPLY_AND_DETAILS_MACRO_END (
160 : VL_API_LCP_ITF_PAIR_GET_REPLY, lcp_itf_pair_pool,
161 : ({ send_lcp_itf_pair_details (cursor, rp, mp->context); }));
162 : }
163 :
164 : static void
165 0 : vl_api_lcp_default_ns_set_t_handler (vl_api_lcp_default_ns_set_t *mp)
166 : {
167 : vl_api_lcp_default_ns_set_reply_t *rmp;
168 : int rv;
169 :
170 0 : mp->netns[LCP_NS_LEN - 1] = 0;
171 0 : rv = lcp_set_default_ns (mp->netns);
172 :
173 0 : REPLY_MACRO (VL_API_LCP_DEFAULT_NS_SET_REPLY);
174 : }
175 :
176 : static void
177 0 : vl_api_lcp_default_ns_get_t_handler (vl_api_lcp_default_ns_get_t *mp)
178 : {
179 : vl_api_lcp_default_ns_get_reply_t *rmp;
180 :
181 0 : REPLY_MACRO_DETAILS2 (VL_API_LCP_DEFAULT_NS_GET_REPLY, ({
182 : char *ns = (char *) lcp_get_default_ns ();
183 : if (ns)
184 : clib_strncpy ((char *) rmp->netns, ns,
185 : LCP_NS_LEN - 1);
186 : }));
187 : }
188 :
189 : static void
190 0 : vl_api_lcp_itf_pair_replace_begin_t_handler (
191 : vl_api_lcp_itf_pair_replace_begin_t *mp)
192 : {
193 : vl_api_lcp_itf_pair_replace_begin_reply_t *rmp;
194 : int rv;
195 :
196 0 : rv = lcp_itf_pair_replace_begin ();
197 :
198 0 : REPLY_MACRO (VL_API_LCP_ITF_PAIR_REPLACE_BEGIN_REPLY);
199 : }
200 :
201 : static void
202 0 : vl_api_lcp_itf_pair_replace_end_t_handler (
203 : vl_api_lcp_itf_pair_replace_end_t *mp)
204 : {
205 : vl_api_lcp_itf_pair_replace_end_reply_t *rmp;
206 0 : int rv = 0;
207 :
208 0 : rv = lcp_itf_pair_replace_end ();
209 :
210 0 : REPLY_MACRO (VL_API_LCP_ITF_PAIR_REPLACE_END_REPLY);
211 : }
212 :
213 : /*
214 : * Set up the API message handling tables
215 : */
216 : #include <linux-cp/lcp.api.c>
217 :
218 : static clib_error_t *
219 2 : lcp_api_init (vlib_main_t *vm)
220 : {
221 : /* Ask for a correctly-sized block of API message decode slots */
222 2 : lcp_msg_id_base = setup_message_id_table ();
223 :
224 2 : return (NULL);
225 : }
226 :
227 8 : VLIB_INIT_FUNCTION (lcp_api_init);
228 :
229 : #include <vpp/app/version.h>
230 : VLIB_PLUGIN_REGISTER () = {
231 : .version = VPP_BUILD_VER,
232 : .description = "Linux Control Plane - Interface Mirror",
233 : .default_disabled = 1,
234 : };
235 :
236 : /*
237 : * fd.io coding-style-patch-verification: ON
238 : *
239 : * Local Variables:
240 : * eval: (c-set-style "gnu")
241 : * End:
242 : */
|