Line data Source code
1 : /*
2 : * Copyright (c) 2022 Cisco and/or its affiliates.
3 : * Licensed under the Apache License, Version 2.0 (the "License");
4 : * you may not use this file except in compliance with the License.
5 : * You may obtain a copy of the License at:
6 : *
7 : * http://www.apache.org/licenses/LICENSE-2.0
8 : *
9 : * Unless required by applicable law or agreed to in writing, software
10 : * distributed under the License is distributed on an "AS IS" BASIS,
11 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : * See the License for the specific language governing permissions and
13 : * limitations under the License.
14 : */
15 :
16 : #include <hs_apps/sapi/vpp_echo_common.h>
17 :
18 : int
19 4 : echo_api_connect_app_socket (echo_main_t *em)
20 : {
21 4 : clib_socket_t *cs = &em->app_api_sock;
22 : clib_error_t *err;
23 4 : int rv = 0;
24 :
25 4 : cs->config = (char *) em->socket_name;
26 4 : cs->flags =
27 4 : CLIB_SOCKET_F_IS_CLIENT | CLIB_SOCKET_F_SEQPACKET | CLIB_SOCKET_F_BLOCKING;
28 :
29 4 : if ((err = clib_socket_init (cs)))
30 : {
31 0 : clib_error_report (err);
32 0 : rv = -1;
33 : }
34 :
35 4 : return rv;
36 : }
37 :
38 : static inline u64
39 12 : echo_vpp_worker_segment_handle (u32 wrk_index)
40 : {
41 12 : return (ECHO_INVALID_SEGMENT_HANDLE - wrk_index - 1);
42 : }
43 :
44 : static int
45 4 : echo_segment_discover_mqs (uword segment_handle, int *fds, u32 n_fds)
46 : {
47 4 : echo_main_t *em = &echo_main;
48 : fifo_segment_t *fs;
49 : u32 fs_index;
50 :
51 4 : fs_index = echo_segment_lookup (segment_handle);
52 4 : if (fs_index == ECHO_INVALID_SEGMENT_INDEX)
53 : {
54 0 : ECHO_LOG (0, "ERROR: mq segment %lx for is not attached!",
55 : segment_handle);
56 0 : return -1;
57 : }
58 :
59 4 : clib_spinlock_lock (&em->segment_handles_lock);
60 :
61 4 : fs = fifo_segment_get_segment (&em->segment_main, fs_index);
62 4 : fifo_segment_msg_qs_discover (fs, fds, n_fds);
63 :
64 4 : clib_spinlock_unlock (&em->segment_handles_lock);
65 :
66 4 : return 0;
67 : }
68 :
69 : static int
70 4 : echo_api_attach_reply_handler (app_sapi_attach_reply_msg_t *mp, int *fds)
71 : {
72 4 : echo_main_t *em = &echo_main;
73 4 : int i, rv, n_fds_used = 0;
74 : u64 segment_handle;
75 : u8 *segment_name;
76 :
77 4 : if (mp->retval)
78 : {
79 0 : ECHO_LOG (0, "attach failed: %U", format_session_error, mp->retval);
80 0 : goto failed;
81 : }
82 :
83 4 : em->my_client_index = mp->api_client_handle;
84 4 : segment_handle = mp->segment_handle;
85 4 : if (segment_handle == ECHO_INVALID_SEGMENT_HANDLE)
86 : {
87 0 : ECHO_LOG (0, "invalid segment handle");
88 0 : goto failed;
89 : }
90 :
91 4 : if (!mp->n_fds)
92 0 : goto failed;
93 :
94 4 : if (mp->fd_flags & SESSION_FD_F_VPP_MQ_SEGMENT)
95 4 : if (echo_segment_attach (echo_vpp_worker_segment_handle (0), "vpp-mq-seg",
96 4 : SSVM_SEGMENT_MEMFD, fds[n_fds_used++]))
97 0 : goto failed;
98 :
99 4 : if (mp->fd_flags & SESSION_FD_F_MEMFD_SEGMENT)
100 : {
101 4 : segment_name = format (0, "memfd-%ld%c", segment_handle, 0);
102 4 : rv = echo_segment_attach (segment_handle, (char *) segment_name,
103 4 : SSVM_SEGMENT_MEMFD, fds[n_fds_used++]);
104 4 : vec_free (segment_name);
105 4 : if (rv != 0)
106 0 : goto failed;
107 : }
108 :
109 4 : echo_segment_attach_mq (segment_handle, mp->app_mq, 0, &em->app_mq);
110 :
111 4 : if (mp->fd_flags & SESSION_FD_F_MQ_EVENTFD)
112 : {
113 0 : ECHO_LOG (0, "SESSION_FD_F_MQ_EVENTFD unsupported!");
114 0 : goto failed;
115 : }
116 :
117 4 : echo_segment_discover_mqs (echo_vpp_worker_segment_handle (0),
118 4 : fds + n_fds_used, mp->n_fds - n_fds_used);
119 4 : echo_segment_attach_mq (echo_vpp_worker_segment_handle (0), mp->vpp_ctrl_mq,
120 4 : mp->vpp_ctrl_mq_thread, &em->ctrl_mq);
121 :
122 4 : em->state = STATE_ATTACHED_NO_CERT;
123 4 : return 0;
124 :
125 0 : failed:
126 :
127 0 : for (i = clib_max (n_fds_used - 1, 0); i < mp->n_fds; i++)
128 0 : close (fds[i]);
129 :
130 0 : return -1;
131 : }
132 :
133 : static int
134 4 : echo_api_send_attach (clib_socket_t *cs)
135 : {
136 4 : echo_main_t *em = &echo_main;
137 4 : app_sapi_msg_t msg = { 0 };
138 4 : app_sapi_attach_msg_t *mp = &msg.attach;
139 : clib_error_t *err;
140 :
141 4 : clib_memcpy (&mp->name, em->app_name, vec_len (em->app_name));
142 4 : mp->options[APP_OPTIONS_FLAGS] =
143 : APP_OPTIONS_FLAGS_ACCEPT_REDIRECT | APP_OPTIONS_FLAGS_ADD_SEGMENT;
144 4 : mp->options[APP_OPTIONS_SEGMENT_SIZE] = 256 << 20;
145 4 : mp->options[APP_OPTIONS_ADD_SEGMENT_SIZE] = 128 << 20;
146 4 : mp->options[APP_OPTIONS_RX_FIFO_SIZE] = em->fifo_size;
147 4 : mp->options[APP_OPTIONS_TX_FIFO_SIZE] = em->fifo_size;
148 4 : mp->options[APP_OPTIONS_PREALLOC_FIFO_PAIRS] = em->prealloc_fifo_pairs;
149 4 : mp->options[APP_OPTIONS_EVT_QUEUE_SIZE] = em->evt_q_size;
150 :
151 4 : msg.type = APP_SAPI_MSG_TYPE_ATTACH;
152 4 : err = clib_socket_sendmsg (cs, &msg, sizeof (msg), 0, 0);
153 4 : if (err)
154 : {
155 0 : clib_error_report (err);
156 0 : return -1;
157 : }
158 :
159 4 : return 0;
160 : }
161 :
162 : int
163 4 : echo_sapi_attach (echo_main_t *em)
164 : {
165 4 : app_sapi_msg_t _rmp, *rmp = &_rmp;
166 : clib_error_t *err;
167 : clib_socket_t *cs;
168 : int fds[32];
169 :
170 4 : cs = &em->app_api_sock;
171 4 : if (echo_api_send_attach (cs))
172 0 : return -1;
173 :
174 : /*
175 : * Wait for attach reply
176 : */
177 4 : err = clib_socket_recvmsg (cs, rmp, sizeof (*rmp), fds, ARRAY_LEN (fds));
178 4 : if (err)
179 : {
180 0 : clib_error_report (err);
181 0 : return -1;
182 : }
183 :
184 4 : if (rmp->type != APP_SAPI_MSG_TYPE_ATTACH_REPLY)
185 0 : return -1;
186 :
187 4 : return echo_api_attach_reply_handler (&rmp->attach_reply, fds);
188 : }
189 :
190 : int
191 4 : echo_sapi_add_cert_key (echo_main_t *em)
192 : {
193 4 : u32 cert_len = test_srv_crt_rsa_len;
194 4 : u32 key_len = test_srv_key_rsa_len;
195 4 : u32 certkey_len = cert_len + key_len;
196 4 : app_sapi_msg_t _msg = { 0 }, *msg = &_msg;
197 : app_sapi_cert_key_add_del_msg_t *mp;
198 4 : app_sapi_msg_t _rmp, *rmp = &_rmp;
199 : clib_error_t *err;
200 : clib_socket_t *cs;
201 4 : u8 *certkey = 0;
202 4 : int rv = -1;
203 :
204 4 : msg->type = APP_SAPI_MSG_TYPE_ADD_DEL_CERT_KEY;
205 4 : mp = &msg->cert_key_add_del;
206 4 : mp->context = ntohl (0xfeedface);
207 4 : mp->cert_len = cert_len;
208 4 : mp->certkey_len = certkey_len;
209 4 : mp->is_add = 1;
210 :
211 4 : vec_validate (certkey, certkey_len - 1);
212 4 : clib_memcpy_fast (certkey, test_srv_crt_rsa, cert_len);
213 4 : clib_memcpy_fast (certkey + cert_len, test_srv_key_rsa, key_len);
214 :
215 4 : cs = &em->app_api_sock;
216 4 : err = clib_socket_sendmsg (cs, msg, sizeof (*msg), 0, 0);
217 4 : if (err)
218 : {
219 0 : clib_error_report (err);
220 0 : goto done;
221 : }
222 :
223 4 : err = clib_socket_sendmsg (cs, certkey, certkey_len, 0, 0);
224 4 : if (err)
225 : {
226 0 : clib_error_report (err);
227 0 : goto done;
228 : }
229 :
230 : /*
231 : * Wait for reply and process it
232 : */
233 4 : err = clib_socket_recvmsg (cs, rmp, sizeof (*rmp), 0, 0);
234 4 : if (err)
235 : {
236 0 : clib_error_report (err);
237 0 : goto done;
238 : }
239 :
240 4 : if (rmp->type != APP_SAPI_MSG_TYPE_ADD_DEL_CERT_KEY_REPLY)
241 : {
242 0 : ECHO_LOG (0, "unexpected reply type %u", rmp->type);
243 0 : goto done;
244 : }
245 :
246 4 : if (!rmp->cert_key_add_del_reply.retval)
247 4 : rv = rmp->cert_key_add_del_reply.index;
248 :
249 4 : em->state = STATE_ATTACHED;
250 4 : em->ckpair_index = rv;
251 :
252 4 : done:
253 :
254 4 : return rv;
255 : }
256 :
257 : int
258 2 : echo_sapi_recv_fd (echo_main_t *em, int *fds, int n_fds)
259 : {
260 2 : app_sapi_msg_t _msg, *msg = &_msg;
261 : clib_error_t *err =
262 2 : clib_socket_recvmsg (&em->app_api_sock, msg, sizeof (*msg), fds, n_fds);
263 2 : if (err)
264 : {
265 0 : clib_error_report (err);
266 0 : return -1;
267 : }
268 2 : return 0;
269 : }
270 :
271 : int
272 4 : echo_sapi_detach (echo_main_t *em)
273 : {
274 4 : clib_socket_t *cs = &em->app_api_sock;
275 4 : clib_socket_close (cs);
276 4 : em->state = STATE_DETACHED;
277 4 : return 0;
278 : }
279 :
280 : int
281 4 : echo_sapi_del_cert_key (echo_main_t *em)
282 : {
283 4 : app_sapi_msg_t _msg = { 0 }, *msg = &_msg;
284 : app_sapi_cert_key_add_del_msg_t *mp;
285 4 : app_sapi_msg_t _rmp, *rmp = &_rmp;
286 : clib_error_t *err;
287 : clib_socket_t *cs;
288 :
289 4 : msg->type = APP_SAPI_MSG_TYPE_ADD_DEL_CERT_KEY;
290 4 : mp = &msg->cert_key_add_del;
291 4 : mp->index = em->ckpair_index;
292 :
293 4 : cs = &em->app_api_sock;
294 4 : err = clib_socket_sendmsg (cs, msg, sizeof (*msg), 0, 0);
295 4 : if (err)
296 : {
297 0 : clib_error_report (err);
298 0 : return -1;
299 : }
300 :
301 : /*
302 : * Wait for reply and process it
303 : */
304 4 : err = clib_socket_recvmsg (cs, rmp, sizeof (*rmp), 0, 0);
305 4 : if (err)
306 : {
307 0 : clib_error_report (err);
308 0 : return -1;
309 : }
310 :
311 4 : if (rmp->type != APP_SAPI_MSG_TYPE_ADD_DEL_CERT_KEY_REPLY)
312 : {
313 0 : ECHO_LOG (0, "unexpected reply type %u", rmp->type);
314 0 : return -1;
315 : }
316 :
317 4 : if (rmp->cert_key_add_del_reply.retval)
318 0 : return -1;
319 :
320 4 : em->state = STATE_CLEANED_CERT_KEY;
321 4 : return 0;
322 : }
323 :
324 : /*
325 : * fd.io coding-style-patch-verification: ON
326 : *
327 : * Local Variables:
328 : * eval: (c-set-style "gnu")
329 : * End:
330 : */
|