blob: ad28136dc07fb94990b956b213e8a20a162ceebc [file] [log] [blame]
Dave Barach59b25652017-09-10 15:04:27 -04001/*
2 *------------------------------------------------------------------
3 * socket_client.c - API message handling over sockets, client code.
4 *
5 * Copyright (c) 2017 Cisco and/or its affiliates.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at:
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *------------------------------------------------------------------
18 */
19
20#include <stdio.h>
Florin Coras90a63982017-12-19 04:50:01 -080021#define __USE_GNU
Nathan Moosbfa03982021-01-15 14:32:07 -080022#define _GNU_SOURCE
Florin Coras90a63982017-12-19 04:50:01 -080023#include <sys/socket.h>
Dave Barach59b25652017-09-10 15:04:27 -040024
Tom Jonesabd6a7b2024-01-29 15:08:01 +000025#ifdef __FreeBSD__
26#define _WANT_UCRED
27#include <sys/types.h>
28#include <sys/param.h>
29#include <sys/ucred.h>
30#include <sys/un.h>
31#endif /* __FreeBSD__ */
32
Florin Coras4d9b9d82018-01-14 12:25:50 -080033#include <svm/ssvm.h>
Florin Corase86a8ed2018-01-05 03:20:25 -080034#include <vlibmemory/socket_client.h>
35#include <vlibmemory/memory_client.h>
Dave Barach59b25652017-09-10 15:04:27 -040036
37#include <vlibmemory/vl_memory_msg_enum.h>
38
39#define vl_typedefs /* define message structures */
40#include <vlibmemory/vl_memory_api_h.h>
41#undef vl_typedefs
42
43#define vl_endianfun /* define message structures */
44#include <vlibmemory/vl_memory_api_h.h>
45#undef vl_endianfun
46
Klement Sekera9b7e8ac2021-11-22 21:26:20 +010047#define vl_calcsizefun
48#include <vlibmemory/vl_memory_api_h.h>
49#undef vl_calcsizefun
50
Dave Barach59b25652017-09-10 15:04:27 -040051/* instantiate all the print functions we know about */
Dave Barach59b25652017-09-10 15:04:27 -040052#define vl_printfun
53#include <vlibmemory/vl_memory_api_h.h>
54#undef vl_printfun
55
56socket_client_main_t socket_client_main;
Florin Coras59cea1a2019-11-25 13:40:42 -080057__thread socket_client_main_t *socket_client_ctx = &socket_client_main;
Dave Barach59b25652017-09-10 15:04:27 -040058
59/* Debug aid */
60u32 vl (void *p) __attribute__ ((weak));
Florin Coras90a63982017-12-19 04:50:01 -080061
Dave Barach59b25652017-09-10 15:04:27 -040062u32
63vl (void *p)
64{
65 return vec_len (p);
66}
67
Florin Coras59cea1a2019-11-25 13:40:42 -080068static socket_client_main_t *
69vl_socket_client_ctx_push (socket_client_main_t * ctx)
Dave Barach59b25652017-09-10 15:04:27 -040070{
Florin Coras59cea1a2019-11-25 13:40:42 -080071 socket_client_main_t *old = socket_client_ctx;
72 socket_client_ctx = ctx;
73 return old;
74}
75
76static void
77vl_socket_client_ctx_pop (socket_client_main_t * old_ctx)
78{
79 socket_client_ctx = old_ctx;
80}
81
82static int
83vl_socket_client_read_internal (socket_client_main_t * scm, int wait)
84{
Florin Coras2881dec2018-10-02 18:29:25 -070085 u32 data_len = 0, msg_size;
Dave Barach59b25652017-09-10 15:04:27 -040086 int n, current_rx_index;
Florin Coras90a63982017-12-19 04:50:01 -080087 msgbuf_t *mbp = 0;
88 f64 timeout;
Dave Barach59b25652017-09-10 15:04:27 -040089
Florin Coras90a63982017-12-19 04:50:01 -080090 if (scm->socket_fd == 0)
91 return -1;
Dave Barach59b25652017-09-10 15:04:27 -040092
Florin Coras90a63982017-12-19 04:50:01 -080093 if (wait)
94 timeout = clib_time_now (&scm->clib_time) + wait;
Dave Barach59b25652017-09-10 15:04:27 -040095
96 while (1)
97 {
Benoît Gannea769a502023-01-26 19:28:16 +010098 current_rx_index = vec_len (scm->socket_rx_buffer);
99 while (current_rx_index < sizeof (*mbp))
Dave Barach59b25652017-09-10 15:04:27 -0400100 {
101 vec_validate (scm->socket_rx_buffer, current_rx_index
102 + scm->socket_buffer_size - 1);
Dave Barach59b25652017-09-10 15:04:27 -0400103 n = read (scm->socket_fd, scm->socket_rx_buffer + current_rx_index,
104 scm->socket_buffer_size);
105 if (n < 0)
106 {
Florin Coras66a10032018-12-21 16:23:09 -0800107 if (errno == EAGAIN)
108 continue;
109
Dave Barach59b25652017-09-10 15:04:27 -0400110 clib_unix_warning ("socket_read");
Benoît Gannea769a502023-01-26 19:28:16 +0100111 vec_set_len (scm->socket_rx_buffer, current_rx_index);
Florin Coras90a63982017-12-19 04:50:01 -0800112 return -1;
Dave Barach59b25652017-09-10 15:04:27 -0400113 }
Benoît Gannea769a502023-01-26 19:28:16 +0100114 current_rx_index += n;
Dave Barach59b25652017-09-10 15:04:27 -0400115 }
Benoît Gannea769a502023-01-26 19:28:16 +0100116 vec_set_len (scm->socket_rx_buffer, current_rx_index);
Dave Barach59b25652017-09-10 15:04:27 -0400117
118#if CLIB_DEBUG > 1
119 if (n > 0)
120 clib_warning ("read %d bytes", n);
121#endif
122
Florin Coras2881dec2018-10-02 18:29:25 -0700123 mbp = (msgbuf_t *) (scm->socket_rx_buffer);
124 data_len = ntohl (mbp->data_len);
125 current_rx_index = vec_len (scm->socket_rx_buffer);
126 vec_validate (scm->socket_rx_buffer, current_rx_index + data_len);
Florin Coras2881dec2018-10-02 18:29:25 -0700127 mbp = (msgbuf_t *) (scm->socket_rx_buffer);
128 msg_size = data_len + sizeof (*mbp);
Dave Barach59b25652017-09-10 15:04:27 -0400129
Benoît Gannea769a502023-01-26 19:28:16 +0100130 while (current_rx_index < msg_size)
Florin Coras2881dec2018-10-02 18:29:25 -0700131 {
Benoît Gannea769a502023-01-26 19:28:16 +0100132 n = read (scm->socket_fd, scm->socket_rx_buffer + current_rx_index,
133 msg_size - current_rx_index);
Florin Coras66a10032018-12-21 16:23:09 -0800134 if (n < 0)
Florin Coras2881dec2018-10-02 18:29:25 -0700135 {
Florin Coras66a10032018-12-21 16:23:09 -0800136 if (errno == EAGAIN)
137 continue;
138
Florin Coras2881dec2018-10-02 18:29:25 -0700139 clib_unix_warning ("socket_read");
Benoît Gannea769a502023-01-26 19:28:16 +0100140 vec_set_len (scm->socket_rx_buffer, current_rx_index);
Florin Coras2881dec2018-10-02 18:29:25 -0700141 return -1;
142 }
Benoît Gannea769a502023-01-26 19:28:16 +0100143 current_rx_index += n;
Florin Coras2881dec2018-10-02 18:29:25 -0700144 }
Benoît Gannea769a502023-01-26 19:28:16 +0100145 vec_set_len (scm->socket_rx_buffer, current_rx_index);
Florin Coras2881dec2018-10-02 18:29:25 -0700146
147 if (vec_len (scm->socket_rx_buffer) >= data_len + sizeof (*mbp))
Dave Barach59b25652017-09-10 15:04:27 -0400148 {
Klement Sekera9b7e8ac2021-11-22 21:26:20 +0100149 vl_msg_api_socket_handler ((void *) (mbp->data), data_len);
Dave Barach59b25652017-09-10 15:04:27 -0400150
Florin Coras2881dec2018-10-02 18:29:25 -0700151 if (vec_len (scm->socket_rx_buffer) == data_len + sizeof (*mbp))
Damjan Marion8bea5892022-04-04 22:40:45 +0200152 vec_set_len (scm->socket_rx_buffer, 0);
Dave Barach59b25652017-09-10 15:04:27 -0400153 else
Florin Coras2881dec2018-10-02 18:29:25 -0700154 vec_delete (scm->socket_rx_buffer, data_len + sizeof (*mbp), 0);
Dave Barach59b25652017-09-10 15:04:27 -0400155 mbp = 0;
156
157 /* Quit if we're out of data, and not expecting a ping reply */
158 if (vec_len (scm->socket_rx_buffer) == 0
159 && scm->control_pings_outstanding == 0)
160 break;
161 }
Florin Coras90a63982017-12-19 04:50:01 -0800162 if (wait && clib_time_now (&scm->clib_time) >= timeout)
163 return -1;
Dave Barach59b25652017-09-10 15:04:27 -0400164 }
Florin Coras90a63982017-12-19 04:50:01 -0800165 return 0;
Dave Barach59b25652017-09-10 15:04:27 -0400166}
167
168int
Florin Coras59cea1a2019-11-25 13:40:42 -0800169vl_socket_client_read (int wait)
Dave Barach59b25652017-09-10 15:04:27 -0400170{
Florin Coras59cea1a2019-11-25 13:40:42 -0800171 return vl_socket_client_read_internal (socket_client_ctx, wait);
172}
173
174int
175vl_socket_client_read2 (socket_client_main_t * scm, int wait)
176{
177 socket_client_main_t *old_ctx;
178 int rv;
179
180 old_ctx = vl_socket_client_ctx_push (scm);
181 rv = vl_socket_client_read_internal (scm, wait);
182 vl_socket_client_ctx_pop (old_ctx);
183 return rv;
184}
185
186static int
187vl_socket_client_write_internal (socket_client_main_t * scm)
188{
Florin Coras90a63982017-12-19 04:50:01 -0800189 int n;
Benoît Ganne8a1d0792023-01-26 17:04:58 +0100190 int len = vec_len (scm->socket_tx_buffer);
Florin Coras90a63982017-12-19 04:50:01 -0800191 msgbuf_t msgbuf = {
192 .q = 0,
193 .gc_mark_timestamp = 0,
Benoît Ganne8a1d0792023-01-26 17:04:58 +0100194 .data_len = htonl (len),
Florin Coras90a63982017-12-19 04:50:01 -0800195 };
196
197 n = write (scm->socket_fd, &msgbuf, sizeof (msgbuf));
198 if (n < sizeof (msgbuf))
199 {
200 clib_unix_warning ("socket write (msgbuf)");
201 return -1;
202 }
203
Benoît Ganne8a1d0792023-01-26 17:04:58 +0100204 n = write (scm->socket_fd, scm->socket_tx_buffer, len);
205
206 vec_set_len (scm->socket_tx_buffer, 0);
207
208 if (n < len)
Florin Coras90a63982017-12-19 04:50:01 -0800209 {
210 clib_unix_warning ("socket write (msg)");
211 return -1;
212 }
213
214 return n;
215}
216
Florin Coras59cea1a2019-11-25 13:40:42 -0800217int
218vl_socket_client_write (void)
219{
220 return vl_socket_client_write_internal (socket_client_ctx);
221}
222
223int
224vl_socket_client_write2 (socket_client_main_t * scm)
225{
226 socket_client_main_t *old_ctx;
227 int rv;
228
229 old_ctx = vl_socket_client_ctx_push (scm);
230 rv = vl_socket_client_write_internal (scm);
231 vl_socket_client_ctx_pop (old_ctx);
232 return rv;
233}
234
235void *
236vl_socket_client_msg_alloc2 (socket_client_main_t * scm, int nbytes)
237{
Benoît Ganne8a1d0792023-01-26 17:04:58 +0100238 vec_set_len (scm->socket_tx_buffer, nbytes);
Florin Coras59cea1a2019-11-25 13:40:42 -0800239 return ((void *) scm->socket_tx_buffer);
240}
241
Florin Coras90a63982017-12-19 04:50:01 -0800242void *
243vl_socket_client_msg_alloc (int nbytes)
244{
Florin Coras59cea1a2019-11-25 13:40:42 -0800245 return vl_socket_client_msg_alloc2 (socket_client_ctx, nbytes);
Florin Coras90a63982017-12-19 04:50:01 -0800246}
247
248void
Florin Coras59cea1a2019-11-25 13:40:42 -0800249vl_socket_client_disconnect2 (socket_client_main_t * scm)
Florin Coras90a63982017-12-19 04:50:01 -0800250{
Florin Corasb384b542018-01-15 01:08:33 -0800251 if (vl_mem_client_is_connected ())
252 {
253 vl_client_disconnect_from_vlib_no_unmap ();
254 ssvm_delete_memfd (&scm->memfd_segment);
255 }
Florin Coras90a63982017-12-19 04:50:01 -0800256 if (scm->socket_fd && (close (scm->socket_fd) < 0))
257 clib_unix_warning ("close");
258 scm->socket_fd = 0;
259}
260
261void
Florin Coras59cea1a2019-11-25 13:40:42 -0800262vl_socket_client_disconnect (void)
263{
264 vl_socket_client_disconnect2 (socket_client_ctx);
265}
266
267void
268vl_socket_client_enable_disable2 (socket_client_main_t * scm, int enable)
269{
270 scm->socket_enable = enable;
271}
272
273void
Florin Coras90a63982017-12-19 04:50:01 -0800274vl_socket_client_enable_disable (int enable)
275{
Florin Coras59cea1a2019-11-25 13:40:42 -0800276 vl_socket_client_enable_disable2 (socket_client_ctx, enable);
Florin Coras90a63982017-12-19 04:50:01 -0800277}
278
Florin Corasd4c70922019-11-28 14:21:21 -0800279static clib_error_t *
280vl_sock_api_recv_fd_msg_internal (socket_client_main_t * scm, int fds[],
281 int n_fds, u32 wait)
Florin Coras90a63982017-12-19 04:50:01 -0800282{
283 char msgbuf[16];
Florin Coras466f2892018-08-03 02:50:43 -0700284 char ctl[CMSG_SPACE (sizeof (int) * n_fds)
285 + CMSG_SPACE (sizeof (struct ucred))];
Florin Coras90a63982017-12-19 04:50:01 -0800286 struct msghdr mh = { 0 };
287 struct iovec iov[1];
Florin Corasb384b542018-01-15 01:08:33 -0800288 ssize_t size = 0;
Tom Jonesabd6a7b2024-01-29 15:08:01 +0000289#ifdef __linux__
Florin Coras90a63982017-12-19 04:50:01 -0800290 struct ucred *cr = 0;
Tom Jonesabd6a7b2024-01-29 15:08:01 +0000291#elif __FreeBSD__
292 struct cmsgcred *cr = 0;
293#endif /* __linux__ */
Florin Coras90a63982017-12-19 04:50:01 -0800294 struct cmsghdr *cmsg;
295 pid_t pid __attribute__ ((unused));
296 uid_t uid __attribute__ ((unused));
297 gid_t gid __attribute__ ((unused));
Florin Corasd4c70922019-11-28 14:21:21 -0800298 int socket_fd;
Florin Corasb384b542018-01-15 01:08:33 -0800299 f64 timeout;
Florin Coras90a63982017-12-19 04:50:01 -0800300
Florin Corasd4c70922019-11-28 14:21:21 -0800301 socket_fd = scm->client_socket.fd;
302
Florin Coras90a63982017-12-19 04:50:01 -0800303 iov[0].iov_base = msgbuf;
304 iov[0].iov_len = 5;
305 mh.msg_iov = iov;
306 mh.msg_iovlen = 1;
307 mh.msg_control = ctl;
308 mh.msg_controllen = sizeof (ctl);
309
Dave Barachb7b92992018-10-17 10:38:51 -0400310 clib_memset (ctl, 0, sizeof (ctl));
Florin Coras90a63982017-12-19 04:50:01 -0800311
Florin Corasb384b542018-01-15 01:08:33 -0800312 if (wait != ~0)
313 {
314 timeout = clib_time_now (&scm->clib_time) + wait;
315 while (size != 5 && clib_time_now (&scm->clib_time) < timeout)
316 size = recvmsg (socket_fd, &mh, MSG_DONTWAIT);
317 }
318 else
319 size = recvmsg (socket_fd, &mh, 0);
320
Florin Coras90a63982017-12-19 04:50:01 -0800321 if (size != 5)
322 {
323 return (size == 0) ? clib_error_return (0, "disconnected") :
324 clib_error_return_unix (0, "recvmsg: malformed message (fd %d)",
325 socket_fd);
326 }
327
328 cmsg = CMSG_FIRSTHDR (&mh);
329 while (cmsg)
330 {
331 if (cmsg->cmsg_level == SOL_SOCKET)
332 {
Tom Jonesabd6a7b2024-01-29 15:08:01 +0000333#ifdef __linux__
Florin Coras90a63982017-12-19 04:50:01 -0800334 if (cmsg->cmsg_type == SCM_CREDENTIALS)
335 {
336 cr = (struct ucred *) CMSG_DATA (cmsg);
337 uid = cr->uid;
338 gid = cr->gid;
339 pid = cr->pid;
340 }
Tom Jonesabd6a7b2024-01-29 15:08:01 +0000341#elif __FreeBSD__
342 if (cmsg->cmsg_type == SCM_CREDS)
343 {
344 cr = (struct cmsgcred *) CMSG_DATA (cmsg);
345 uid = cr->cmcred_uid;
346 gid = cr->cmcred_gid;
347 pid = cr->cmcred_pid;
348 }
349#endif /* __linux__ */
Florin Coras90a63982017-12-19 04:50:01 -0800350 else if (cmsg->cmsg_type == SCM_RIGHTS)
351 {
Dave Barach178cf492018-11-13 16:34:13 -0500352 clib_memcpy_fast (fds, CMSG_DATA (cmsg), sizeof (int) * n_fds);
Florin Coras90a63982017-12-19 04:50:01 -0800353 }
354 }
355 cmsg = CMSG_NXTHDR (&mh, cmsg);
356 }
357 return 0;
358}
359
Florin Corasd4c70922019-11-28 14:21:21 -0800360clib_error_t *
361vl_sock_api_recv_fd_msg (int socket_fd, int fds[], int n_fds, u32 wait)
362{
363 return vl_sock_api_recv_fd_msg_internal (socket_client_ctx, fds, n_fds,
364 wait);
365}
366
367clib_error_t *
368vl_sock_api_recv_fd_msg2 (socket_client_main_t * scm, int socket_fd,
369 int fds[], int n_fds, u32 wait)
370{
371 socket_client_main_t *old_ctx;
372 clib_error_t *error;
373
374 old_ctx = vl_socket_client_ctx_push (scm);
375 error = vl_sock_api_recv_fd_msg_internal (scm, fds, n_fds, wait);
376 vl_socket_client_ctx_pop (old_ctx);
377 return error;
378}
379
Florin Coras90a63982017-12-19 04:50:01 -0800380static void vl_api_sock_init_shm_reply_t_handler
381 (vl_api_sock_init_shm_reply_t * mp)
382{
Florin Coras59cea1a2019-11-25 13:40:42 -0800383 socket_client_main_t *scm = socket_client_ctx;
Florin Corasb384b542018-01-15 01:08:33 -0800384 ssvm_private_t *memfd = &scm->memfd_segment;
Florin Coras90a63982017-12-19 04:50:01 -0800385 i32 retval = ntohl (mp->retval);
Dave Barach39d69112019-11-27 11:42:13 -0500386 api_main_t *am = vlibapi_get_main ();
Florin Corasb384b542018-01-15 01:08:33 -0800387 clib_error_t *error;
388 int my_fd = -1;
Florin Coras90a63982017-12-19 04:50:01 -0800389 u8 *new_name;
390
391 if (retval)
392 {
393 clib_warning ("failed to init shmem");
394 return;
395 }
396
397 /*
398 * Check the socket for the magic fd
399 */
Florin Coras466f2892018-08-03 02:50:43 -0700400 error = vl_sock_api_recv_fd_msg (scm->socket_fd, &my_fd, 1, 5);
Florin Coras90a63982017-12-19 04:50:01 -0800401 if (error)
402 {
Florin Corasb384b542018-01-15 01:08:33 -0800403 clib_error_report (error);
Florin Coras90a63982017-12-19 04:50:01 -0800404 retval = -99;
405 return;
406 }
407
Dave Barachb7b92992018-10-17 10:38:51 -0400408 clib_memset (memfd, 0, sizeof (*memfd));
Florin Corasb384b542018-01-15 01:08:33 -0800409 memfd->fd = my_fd;
Florin Coras90a63982017-12-19 04:50:01 -0800410
411 /* Note: this closes memfd.fd */
Florin Coras5220a262020-09-29 18:11:24 -0700412 retval = ssvm_client_init_memfd (memfd);
Florin Coras90a63982017-12-19 04:50:01 -0800413 if (retval)
414 clib_warning ("WARNING: segment map returned %d", retval);
415
416 /*
417 * Pivot to the memory client segment that vpp just created
418 */
Florin Corasb384b542018-01-15 01:08:33 -0800419 am->vlib_rp = (void *) (memfd->requested_va + MMAP_PAGESIZE);
Florin Coras90a63982017-12-19 04:50:01 -0800420 am->shmem_hdr = (void *) am->vlib_rp->user_ctx;
421
422 new_name = format (0, "%v[shm]%c", scm->name, 0);
423 vl_client_install_client_message_handlers ();
Tomasz Kulasek97dcf5b2019-01-31 18:26:32 +0100424 if (scm->want_shm_pthread)
425 {
426 vl_client_connect_to_vlib_no_map ("pvt", (char *) new_name,
427 32 /* input_queue_length */ );
428 }
429 else
430 {
431 vl_client_connect_to_vlib_no_rx_pthread_no_map ("pvt",
432 (char *) new_name, 32
433 /* input_queue_length */
434 );
435 }
Florin Coras90a63982017-12-19 04:50:01 -0800436 vl_socket_client_enable_disable (0);
437 vec_free (new_name);
438}
439
440static void
441vl_api_sockclnt_create_reply_t_handler (vl_api_sockclnt_create_reply_t * mp)
442{
Florin Coras59cea1a2019-11-25 13:40:42 -0800443 socket_client_main_t *scm = socket_client_ctx;
Florin Coras90a63982017-12-19 04:50:01 -0800444 if (!mp->response)
Florin Coras2881dec2018-10-02 18:29:25 -0700445 {
446 scm->socket_enable = 1;
447 scm->client_index = clib_net_to_host_u32 (mp->index);
448 }
Florin Coras90a63982017-12-19 04:50:01 -0800449}
450
451#define foreach_sock_client_api_msg \
452_(SOCKCLNT_CREATE_REPLY, sockclnt_create_reply) \
453_(SOCK_INIT_SHM_REPLY, sock_init_shm_reply) \
454
Florin Coras90a63982017-12-19 04:50:01 -0800455void
456vl_sock_client_install_message_handlers (void)
457{
458
Filip Tehlar36217e32021-07-23 08:51:10 +0000459#define _(N, n) \
Damjan Mariona2eb5072022-05-20 20:06:01 +0200460 vl_msg_api_config (&(vl_msg_api_msg_config_t){ \
461 .id = VL_API_##N, \
462 .name = #n, \
463 .handler = vl_api_##n##_t_handler, \
464 .endian = vl_api_##n##_t_endian, \
465 .format_fn = vl_api_##n##_t_format, \
466 .size = sizeof (vl_api_##n##_t), \
467 .traced = 0, \
468 .tojson = vl_api_##n##_t_tojson, \
469 .fromjson = vl_api_##n##_t_fromjson, \
470 .calc_size = vl_api_##n##_t_calc_size, \
471 });
Florin Coras90a63982017-12-19 04:50:01 -0800472 foreach_sock_client_api_msg;
473#undef _
474}
475
476int
Florin Coras59cea1a2019-11-25 13:40:42 -0800477vl_socket_client_connect_internal (socket_client_main_t * scm,
478 char *socket_path, char *client_name,
479 u32 socket_buffer_size)
Florin Coras90a63982017-12-19 04:50:01 -0800480{
Dave Barach59b25652017-09-10 15:04:27 -0400481 vl_api_sockclnt_create_t *mp;
Florin Coras90a63982017-12-19 04:50:01 -0800482 clib_socket_t *sock;
Dave Barach59b25652017-09-10 15:04:27 -0400483 clib_error_t *error;
484
485 /* Already connected? */
486 if (scm->socket_fd)
487 return (-2);
488
489 /* bogus call? */
490 if (socket_path == 0 || client_name == 0)
491 return (-3);
492
Florin Coras90a63982017-12-19 04:50:01 -0800493 sock = &scm->client_socket;
Dave Barach59b25652017-09-10 15:04:27 -0400494 sock->config = socket_path;
Florin Coras5fe94572021-05-24 08:58:15 -0700495 sock->flags = CLIB_SOCKET_F_IS_CLIENT;
Dave Barach59b25652017-09-10 15:04:27 -0400496
Florin Coras90a63982017-12-19 04:50:01 -0800497 if ((error = clib_socket_init (sock)))
Dave Barach59b25652017-09-10 15:04:27 -0400498 {
499 clib_error_report (error);
500 return (-1);
501 }
502
Florin Coras90a63982017-12-19 04:50:01 -0800503 vl_sock_client_install_message_handlers ();
504
Dave Barach59b25652017-09-10 15:04:27 -0400505 scm->socket_fd = sock->fd;
Dave Barach59b25652017-09-10 15:04:27 -0400506 scm->socket_buffer_size = socket_buffer_size ? socket_buffer_size :
507 SOCKET_CLIENT_DEFAULT_BUFFER_SIZE;
508 vec_validate (scm->socket_tx_buffer, scm->socket_buffer_size - 1);
509 vec_validate (scm->socket_rx_buffer, scm->socket_buffer_size - 1);
Damjan Marion8bea5892022-04-04 22:40:45 +0200510 vec_set_len (scm->socket_rx_buffer, 0);
511 vec_set_len (scm->socket_tx_buffer, 0);
Florin Coras90a63982017-12-19 04:50:01 -0800512 scm->name = format (0, "%s", client_name);
Dave Barach59b25652017-09-10 15:04:27 -0400513
Florin Coras59cea1a2019-11-25 13:40:42 -0800514 mp = vl_socket_client_msg_alloc2 (scm, sizeof (*mp));
Florin Coras90a63982017-12-19 04:50:01 -0800515 mp->_vl_msg_id = htons (VL_API_SOCKCLNT_CREATE);
Ole Troan7adaa222019-08-27 15:05:27 +0200516 strncpy ((char *) mp->name, client_name, sizeof (mp->name) - 1);
517 mp->name[sizeof (mp->name) - 1] = 0;
Florin Coras90a63982017-12-19 04:50:01 -0800518 mp->context = 0xfeedface;
519
Florin Coras2881dec2018-10-02 18:29:25 -0700520 clib_time_init (&scm->clib_time);
521
Florin Coras59cea1a2019-11-25 13:40:42 -0800522 if (vl_socket_client_write_internal (scm) <= 0)
Florin Coras90a63982017-12-19 04:50:01 -0800523 return (-1);
524
Florin Coras59cea1a2019-11-25 13:40:42 -0800525 if (vl_socket_client_read_internal (scm, 5))
Florin Coras90a63982017-12-19 04:50:01 -0800526 return (-1);
527
Dave Barach59b25652017-09-10 15:04:27 -0400528 return (0);
529}
530
Florin Coras90a63982017-12-19 04:50:01 -0800531int
Florin Coras59cea1a2019-11-25 13:40:42 -0800532vl_socket_client_connect (char *socket_path, char *client_name,
533 u32 socket_buffer_size)
Dave Barach59b25652017-09-10 15:04:27 -0400534{
Florin Coras59cea1a2019-11-25 13:40:42 -0800535 return vl_socket_client_connect_internal (socket_client_ctx, socket_path,
536 client_name, socket_buffer_size);
537}
538
539int
540vl_socket_client_connect2 (socket_client_main_t * scm, char *socket_path,
541 char *client_name, u32 socket_buffer_size)
542{
543 socket_client_main_t *old_ctx;
544 int rv;
545
546 old_ctx = vl_socket_client_ctx_push (scm);
547 rv = vl_socket_client_connect_internal (socket_client_ctx, socket_path,
548 client_name, socket_buffer_size);
549 vl_socket_client_ctx_pop (old_ctx);
550 return rv;
551}
552
553int
554vl_socket_client_init_shm_internal (socket_client_main_t * scm,
555 vl_api_shm_elem_config_t * config,
556 int want_pthread)
557{
Florin Coras90a63982017-12-19 04:50:01 -0800558 vl_api_sock_init_shm_t *mp;
559 int rv, i;
560 u64 *cfg;
Dave Barach59b25652017-09-10 15:04:27 -0400561
Tomasz Kulasek97dcf5b2019-01-31 18:26:32 +0100562 scm->want_shm_pthread = want_pthread;
563
Florin Coras59cea1a2019-11-25 13:40:42 -0800564 mp = vl_socket_client_msg_alloc2 (scm, sizeof (*mp) +
565 vec_len (config) * sizeof (u64));
Dave Barachb7b92992018-10-17 10:38:51 -0400566 clib_memset (mp, 0, sizeof (*mp));
Florin Coras90a63982017-12-19 04:50:01 -0800567 mp->_vl_msg_id = clib_host_to_net_u16 (VL_API_SOCK_INIT_SHM);
Florin Coras2881dec2018-10-02 18:29:25 -0700568 mp->client_index = clib_host_to_net_u32 (scm->client_index);
Florin Coras90a63982017-12-19 04:50:01 -0800569 mp->requested_size = 64 << 20;
570
571 if (config)
572 {
573 for (i = 0; i < vec_len (config); i++)
574 {
575 cfg = (u64 *) & config[i];
576 mp->configs[i] = *cfg;
577 }
578 mp->nitems = vec_len (config);
579 }
Florin Coras59cea1a2019-11-25 13:40:42 -0800580 rv = vl_socket_client_write_internal (scm);
Florin Coras90a63982017-12-19 04:50:01 -0800581 if (rv <= 0)
582 return rv;
583
Florin Coras59cea1a2019-11-25 13:40:42 -0800584 if (vl_socket_client_read_internal (scm, 1))
Florin Coras90a63982017-12-19 04:50:01 -0800585 return -1;
586
587 return 0;
Dave Barach59b25652017-09-10 15:04:27 -0400588}
589
Florin Coras59cea1a2019-11-25 13:40:42 -0800590int
591vl_socket_client_init_shm (vl_api_shm_elem_config_t * config,
592 int want_pthread)
Florin Corasb384b542018-01-15 01:08:33 -0800593{
Florin Coras59cea1a2019-11-25 13:40:42 -0800594 return vl_socket_client_init_shm_internal (socket_client_ctx, config,
595 want_pthread);
596}
597
598int
599vl_socket_client_init_shm2 (socket_client_main_t * scm,
600 vl_api_shm_elem_config_t * config,
601 int want_pthread)
602{
603 socket_client_main_t *old_ctx;
604 int rv;
605
606 old_ctx = vl_socket_client_ctx_push (scm);
607 rv = vl_socket_client_init_shm_internal (socket_client_ctx, config,
608 want_pthread);
609 vl_socket_client_ctx_pop (old_ctx);
610 return rv;
611}
612
613clib_error_t *
614vl_socket_client_recv_fd_msg2 (socket_client_main_t * scm, int fds[],
615 int n_fds, u32 wait)
616{
Florin Corasb384b542018-01-15 01:08:33 -0800617 if (!scm->socket_fd)
618 return clib_error_return (0, "no socket");
Florin Corasd4c70922019-11-28 14:21:21 -0800619 return vl_sock_api_recv_fd_msg_internal (scm, fds, n_fds, wait);
Florin Corasb384b542018-01-15 01:08:33 -0800620}
621
Florin Coras59cea1a2019-11-25 13:40:42 -0800622clib_error_t *
623vl_socket_client_recv_fd_msg (int fds[], int n_fds, u32 wait)
624{
625 return vl_socket_client_recv_fd_msg2 (socket_client_ctx, fds, n_fds, wait);
626}
627
Dave Barach59b25652017-09-10 15:04:27 -0400628/*
629 * fd.io coding-style-patch-verification: ON
630 *
631 * Local Variables:
632 * eval: (c-set-style "gnu")
633 * End:
634 */