blob: e3e6dfac1c6a9d269197cb2d1f58c6fba6f052bd [file] [log] [blame]
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001/*
Florin Coras5e062572019-03-14 19:07:51 -07002 * Copyright (c) 2016-2019 Cisco and/or its affiliates.
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003 * 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#include <unistd.h>
16#include <stdio.h>
17#include <signal.h>
18#include <dlfcn.h>
19#include <pthread.h>
20#include <time.h>
21#include <stdarg.h>
shrinivasan ganapathy1d359632017-10-15 15:46:09 -070022#include <sys/resource.h>
Dave Wallace048b1d62018-01-03 22:24:41 -050023#include <netinet/tcp.h>
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -070024
Dave Wallace2a865272018-02-07 21:00:42 -050025#include <vcl/ldp_socket_wrapper.h>
26#include <vcl/ldp.h>
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -070027#include <sys/time.h>
28
Florin Coras7baeb712019-01-04 17:05:43 -080029#include <vcl/vcl_locked.h>
Dave Wallace048b1d62018-01-03 22:24:41 -050030#include <vppinfra/time.h>
31#include <vppinfra/bitmap.h>
Florin Coras30e273b2018-11-27 00:04:59 -080032#include <vppinfra/lock.h>
33#include <vppinfra/pool.h>
34#include <vppinfra/hash.h>
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -070035
36#define HAVE_CONSTRUCTOR_ATTRIBUTE
37#ifdef HAVE_CONSTRUCTOR_ATTRIBUTE
38#define CONSTRUCTOR_ATTRIBUTE \
39 __attribute__ ((constructor))
40#else
41#define CONSTRUCTOR_ATTRIBUTE
42#endif /* HAVE_CONSTRUCTOR_ATTRIBUTE */
43
44#define HAVE_DESTRUCTOR_ATTRIBUTE
45#ifdef HAVE_DESTRUCTOR_ATTRIBUTE
46#define DESTRUCTOR_ATTRIBUTE \
47 __attribute__ ((destructor))
48#else
49#define DESTRUCTOR_ATTRIBUTE
50#endif
51
Florin Corasdfe4cf42018-11-28 22:13:45 -080052#define LDP_MAX_NWORKERS 32
53
Florin Corasdfe4cf42018-11-28 22:13:45 -080054typedef struct ldp_worker_ctx_
Dave Wallace048b1d62018-01-03 22:24:41 -050055{
Dave Wallace048b1d62018-01-03 22:24:41 -050056 u8 *io_buffer;
57 clib_time_t clib_time;
Florin Corasdfe4cf42018-11-28 22:13:45 -080058
59 /*
60 * Select state
61 */
Dave Wallace048b1d62018-01-03 22:24:41 -050062 clib_bitmap_t *rd_bitmap;
63 clib_bitmap_t *wr_bitmap;
64 clib_bitmap_t *ex_bitmap;
Florin Coras294afe22019-01-07 17:49:17 -080065 clib_bitmap_t *si_rd_bitmap;
66 clib_bitmap_t *si_wr_bitmap;
67 clib_bitmap_t *si_ex_bitmap;
Dave Wallace048b1d62018-01-03 22:24:41 -050068 clib_bitmap_t *libc_rd_bitmap;
69 clib_bitmap_t *libc_wr_bitmap;
70 clib_bitmap_t *libc_ex_bitmap;
Florin Corasdfe4cf42018-11-28 22:13:45 -080071
72 /*
73 * Poll state
74 */
Dave Wallace048b1d62018-01-03 22:24:41 -050075 vcl_poll_t *vcl_poll;
Florin Coras6917b942018-11-13 22:44:54 -080076 struct pollfd *libc_poll;
77 u16 *libc_poll_idxs;
Florin Corasdfe4cf42018-11-28 22:13:45 -080078
79 /*
80 * Epoll state
81 */
Dave Wallace048b1d62018-01-03 22:24:41 -050082 u8 epoll_wait_vcl;
hanlin4266d4d2020-05-19 17:34:17 +080083 u8 mq_epfd_added;
Florin Coras99368312018-08-02 10:45:44 -070084 int vcl_mq_epfd;
Florin Corasdfe4cf42018-11-28 22:13:45 -080085
86} ldp_worker_ctx_t;
87
Florin Coras294afe22019-01-07 17:49:17 -080088/* clib_bitmap_t, fd_mask and vcl_si_set are used interchangeably. Make sure
89 * they are the same size */
90STATIC_ASSERT (sizeof (clib_bitmap_t) == sizeof (fd_mask),
91 "ldp bitmap size mismatch");
92STATIC_ASSERT (sizeof (vcl_si_set) == sizeof (fd_mask),
93 "ldp bitmap size mismatch");
94
Florin Corasdfe4cf42018-11-28 22:13:45 -080095typedef struct
96{
97 ldp_worker_ctx_t *workers;
98 int init;
99 char app_name[LDP_APP_NAME_MAX];
Florin Coras7baeb712019-01-04 17:05:43 -0800100 u32 vlsh_bit_val;
101 u32 vlsh_bit_mask;
Florin Corasdfe4cf42018-11-28 22:13:45 -0800102 u32 debug;
Yu Ping7b74b072019-05-08 00:40:24 +0800103 u8 transparent_tls;
Florin Corasdfe4cf42018-11-28 22:13:45 -0800104
105 /** vcl needs next epoll_create to go to libc_epoll */
106 u8 vcl_needs_real_epoll;
Dave Wallace2a865272018-02-07 21:00:42 -0500107} ldp_main_t;
Florin Corasdfe4cf42018-11-28 22:13:45 -0800108
Dave Wallace2a865272018-02-07 21:00:42 -0500109#define LDP_DEBUG ldp->debug
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700110
Florin Coras99368312018-08-02 10:45:44 -0700111#define LDBG(_lvl, _fmt, _args...) \
112 if (ldp->debug > _lvl) \
hanlin9f3f18f2019-12-30 16:25:20 +0800113 { \
114 int errno_saved = errno; \
115 clib_warning ("ldp<%d>: " _fmt, getpid(), ##_args); \
116 errno = errno_saved; \
117 }
Florin Coras99368312018-08-02 10:45:44 -0700118
Dave Wallace2a865272018-02-07 21:00:42 -0500119static ldp_main_t ldp_main = {
Florin Coras7baeb712019-01-04 17:05:43 -0800120 .vlsh_bit_val = (1 << LDP_SID_BIT_MIN),
121 .vlsh_bit_mask = (1 << LDP_SID_BIT_MIN) - 1,
Dave Wallace2a865272018-02-07 21:00:42 -0500122 .debug = LDP_DEBUG_INIT,
Yu Ping7b74b072019-05-08 00:40:24 +0800123 .transparent_tls = 0,
Dave Wallace048b1d62018-01-03 22:24:41 -0500124};
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700125
Dave Wallace2a865272018-02-07 21:00:42 -0500126static ldp_main_t *ldp = &ldp_main;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700127
Florin Corasdfe4cf42018-11-28 22:13:45 -0800128static inline ldp_worker_ctx_t *
129ldp_worker_get_current (void)
130{
131 return (ldp->workers + vppcom_worker_index ());
132}
133
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700134/*
135 * RETURN: 0 on success or -1 on error.
136 * */
Dave Wallace048b1d62018-01-03 22:24:41 -0500137static inline void
Dave Wallace2a865272018-02-07 21:00:42 -0500138ldp_set_app_name (char *app_name)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700139{
Benoît Ganne747b3d82019-08-21 18:27:23 +0200140 snprintf (ldp->app_name, LDP_APP_NAME_MAX,
141 "ldp-%d-%s", getpid (), app_name);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700142}
143
Dave Wallace048b1d62018-01-03 22:24:41 -0500144static inline char *
Dave Wallace2a865272018-02-07 21:00:42 -0500145ldp_get_app_name ()
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700146{
Dave Wallace2a865272018-02-07 21:00:42 -0500147 if (ldp->app_name[0] == '\0')
148 ldp_set_app_name ("app");
Dave Wallace048b1d62018-01-03 22:24:41 -0500149
Dave Wallace2a865272018-02-07 21:00:42 -0500150 return ldp->app_name;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700151}
152
Dave Wallace048b1d62018-01-03 22:24:41 -0500153static inline int
Florin Coras7baeb712019-01-04 17:05:43 -0800154ldp_vlsh_to_fd (vls_handle_t vlsh)
Dave Wallace048b1d62018-01-03 22:24:41 -0500155{
Florin Coras7baeb712019-01-04 17:05:43 -0800156 return (vlsh + ldp->vlsh_bit_val);
Dave Wallace048b1d62018-01-03 22:24:41 -0500157}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700158
Florin Coras7baeb712019-01-04 17:05:43 -0800159static inline vls_handle_t
160ldp_fd_to_vlsh (int fd)
Dave Wallace048b1d62018-01-03 22:24:41 -0500161{
Florin Coras7baeb712019-01-04 17:05:43 -0800162 if (fd < ldp->vlsh_bit_val)
163 return VLS_INVALID_HANDLE;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700164
Florin Coras7baeb712019-01-04 17:05:43 -0800165 return (fd - ldp->vlsh_bit_val);
Dave Wallace048b1d62018-01-03 22:24:41 -0500166}
167
Florin Coras2d9b4272019-03-11 10:14:37 -0700168static void
169ldp_alloc_workers (void)
170{
171 if (ldp->workers)
172 return;
173 pool_alloc (ldp->workers, LDP_MAX_NWORKERS);
174}
175
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700176static inline int
Dave Wallace2a865272018-02-07 21:00:42 -0500177ldp_init (void)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700178{
Florin Corasdfe4cf42018-11-28 22:13:45 -0800179 ldp_worker_ctx_t *ldpw;
Florin Coras99368312018-08-02 10:45:44 -0700180 int rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700181
Florin Coras99368312018-08-02 10:45:44 -0700182 if (PREDICT_TRUE (ldp->init))
183 return 0;
184
185 ldp->init = 1;
186 ldp->vcl_needs_real_epoll = 1;
Florin Coras7baeb712019-01-04 17:05:43 -0800187 rv = vls_app_create (ldp_get_app_name ());
Florin Coras99368312018-08-02 10:45:44 -0700188 if (rv != VPPCOM_OK)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700189 {
Florin Coras955bfbb2018-12-04 13:43:45 -0800190 ldp->vcl_needs_real_epoll = 0;
191 if (rv == VPPCOM_EEXIST)
192 return 0;
Florin Coras05ecfcc2018-12-12 18:19:39 -0800193 LDBG (2, "\nERROR: ldp_init: vppcom_app_create()"
194 " failed! rv = %d (%s)\n", rv, vppcom_retval_str (rv));
Florin Coras99368312018-08-02 10:45:44 -0700195 ldp->init = 0;
196 return rv;
197 }
198 ldp->vcl_needs_real_epoll = 0;
Florin Coras2d9b4272019-03-11 10:14:37 -0700199 ldp_alloc_workers ();
Florin Corasdfe4cf42018-11-28 22:13:45 -0800200 ldpw = ldp_worker_get_current ();
Florin Coras99368312018-08-02 10:45:44 -0700201
202 char *env_var_str = getenv (LDP_ENV_DEBUG);
203 if (env_var_str)
204 {
205 u32 tmp;
206 if (sscanf (env_var_str, "%u", &tmp) != 1)
207 clib_warning ("LDP<%d>: WARNING: Invalid LDP debug level specified in"
208 " the env var " LDP_ENV_DEBUG " (%s)!", getpid (),
209 env_var_str);
210 else
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700211 {
Florin Coras99368312018-08-02 10:45:44 -0700212 ldp->debug = tmp;
Florin Coras05ecfcc2018-12-12 18:19:39 -0800213 LDBG (0, "configured LDP debug level (%u) from env var "
214 LDP_ENV_DEBUG "!", ldp->debug);
Florin Coras99368312018-08-02 10:45:44 -0700215 }
216 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500217
Florin Coras99368312018-08-02 10:45:44 -0700218 env_var_str = getenv (LDP_ENV_APP_NAME);
219 if (env_var_str)
220 {
221 ldp_set_app_name (env_var_str);
Florin Coras05ecfcc2018-12-12 18:19:39 -0800222 LDBG (0, "configured LDP app name (%s) from the env var "
223 LDP_ENV_APP_NAME "!", ldp->app_name);
Florin Coras99368312018-08-02 10:45:44 -0700224 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500225
Florin Coras99368312018-08-02 10:45:44 -0700226 env_var_str = getenv (LDP_ENV_SID_BIT);
227 if (env_var_str)
228 {
229 u32 sb;
230 if (sscanf (env_var_str, "%u", &sb) != 1)
231 {
Florin Coras294afe22019-01-07 17:49:17 -0800232 LDBG (0, "WARNING: Invalid LDP sid bit specified in the env var "
233 LDP_ENV_SID_BIT " (%s)! sid bit value %d (0x%x)", env_var_str,
234 ldp->vlsh_bit_val, ldp->vlsh_bit_val);
Florin Coras99368312018-08-02 10:45:44 -0700235 }
236 else if (sb < LDP_SID_BIT_MIN)
237 {
Florin Coras7baeb712019-01-04 17:05:43 -0800238 ldp->vlsh_bit_val = (1 << LDP_SID_BIT_MIN);
239 ldp->vlsh_bit_mask = ldp->vlsh_bit_val - 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500240
Florin Coras294afe22019-01-07 17:49:17 -0800241 LDBG (0, "WARNING: LDP sid bit (%u) specified in the env var "
242 LDP_ENV_SID_BIT " (%s) is too small. Using LDP_SID_BIT_MIN"
243 " (%d)! sid bit value %d (0x%x)", sb, env_var_str,
244 LDP_SID_BIT_MIN, ldp->vlsh_bit_val, ldp->vlsh_bit_val);
Florin Coras99368312018-08-02 10:45:44 -0700245 }
246 else if (sb > LDP_SID_BIT_MAX)
247 {
Florin Coras7baeb712019-01-04 17:05:43 -0800248 ldp->vlsh_bit_val = (1 << LDP_SID_BIT_MAX);
249 ldp->vlsh_bit_mask = ldp->vlsh_bit_val - 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500250
Florin Coras294afe22019-01-07 17:49:17 -0800251 LDBG (0, "WARNING: LDP sid bit (%u) specified in the env var "
252 LDP_ENV_SID_BIT " (%s) is too big. Using LDP_SID_BIT_MAX"
253 " (%d)! sid bit value %d (0x%x)", sb, env_var_str,
254 LDP_SID_BIT_MAX, ldp->vlsh_bit_val, ldp->vlsh_bit_val);
Dave Wallace048b1d62018-01-03 22:24:41 -0500255 }
256 else
257 {
Florin Coras7baeb712019-01-04 17:05:43 -0800258 ldp->vlsh_bit_val = (1 << sb);
259 ldp->vlsh_bit_mask = ldp->vlsh_bit_val - 1;
Florin Coras99368312018-08-02 10:45:44 -0700260
Florin Coras05ecfcc2018-12-12 18:19:39 -0800261 LDBG (0, "configured LDP sid bit (%u) from "
262 LDP_ENV_SID_BIT "! sid bit value %d (0x%x)", sb,
Florin Coras7baeb712019-01-04 17:05:43 -0800263 ldp->vlsh_bit_val, ldp->vlsh_bit_val);
Dave Wallace048b1d62018-01-03 22:24:41 -0500264 }
Florin Coras294afe22019-01-07 17:49:17 -0800265
266 /* Make sure there are enough bits in the fd set for vcl sessions */
267 if (ldp->vlsh_bit_val > FD_SETSIZE / 2)
268 {
269 LDBG (0, "ERROR: LDP vlsh bit value %d > FD_SETSIZE/2 %d!",
270 ldp->vlsh_bit_val, FD_SETSIZE / 2);
271 ldp->init = 0;
272 return -1;
273 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500274 }
Yu Ping7b74b072019-05-08 00:40:24 +0800275 env_var_str = getenv (LDP_ENV_TLS_TRANS);
276 if (env_var_str)
277 {
278 ldp->transparent_tls = 1;
279 }
Florin Coras99368312018-08-02 10:45:44 -0700280
Florin Coras4dee8cd2019-01-29 21:28:16 -0800281 /* *INDENT-OFF* */
282 pool_foreach (ldpw, ldp->workers, ({
283 clib_memset (&ldpw->clib_time, 0, sizeof (ldpw->clib_time));
284 }));
285 /* *INDENT-ON* */
286
Florin Coras05ecfcc2018-12-12 18:19:39 -0800287 LDBG (0, "LDP initialization: done!");
Florin Coras99368312018-08-02 10:45:44 -0700288
289 return 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500290}
291
292int
293close (int fd)
294{
Florin Coras7baeb712019-01-04 17:05:43 -0800295 vls_handle_t vlsh;
296 int rv, epfd;
Dave Wallace048b1d62018-01-03 22:24:41 -0500297
Dave Wallace2a865272018-02-07 21:00:42 -0500298 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500299 return -1;
300
Florin Coras7baeb712019-01-04 17:05:43 -0800301 vlsh = ldp_fd_to_vlsh (fd);
302 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -0500303 {
Florin Coras7baeb712019-01-04 17:05:43 -0800304 epfd = vls_attr (vlsh, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -0500305 if (epfd > 0)
306 {
Florin Coras7baeb712019-01-04 17:05:43 -0800307 LDBG (0, "fd %d: calling libc_close: epfd %u", fd, epfd);
Dave Wallace048b1d62018-01-03 22:24:41 -0500308
309 rv = libc_close (epfd);
310 if (rv < 0)
311 {
312 u32 size = sizeof (epfd);
313 epfd = 0;
314
Florin Coras7baeb712019-01-04 17:05:43 -0800315 (void) vls_attr (vlsh, VPPCOM_ATTR_SET_LIBC_EPFD, &epfd, &size);
Dave Wallace048b1d62018-01-03 22:24:41 -0500316 }
317 }
318 else if (PREDICT_FALSE (epfd < 0))
319 {
320 errno = -epfd;
321 rv = -1;
322 goto done;
323 }
324
Florin Coras7baeb712019-01-04 17:05:43 -0800325 LDBG (0, "fd %d: calling vls_close: vlsh %u", fd, vlsh);
Dave Wallace048b1d62018-01-03 22:24:41 -0500326
Florin Coras7baeb712019-01-04 17:05:43 -0800327 rv = vls_close (vlsh);
Dave Wallace048b1d62018-01-03 22:24:41 -0500328 if (rv != VPPCOM_OK)
329 {
330 errno = -rv;
331 rv = -1;
332 }
333 }
334 else
335 {
Florin Coras7baeb712019-01-04 17:05:43 -0800336 LDBG (0, "fd %d: calling libc_close", fd);
Dave Wallace048b1d62018-01-03 22:24:41 -0500337 rv = libc_close (fd);
338 }
339
340done:
Dave Wallace048b1d62018-01-03 22:24:41 -0500341 return rv;
342}
343
344ssize_t
345read (int fd, void *buf, size_t nbytes)
346{
Florin Coras7baeb712019-01-04 17:05:43 -0800347 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -0500348 ssize_t size;
Dave Wallace048b1d62018-01-03 22:24:41 -0500349
Dave Wallace2a865272018-02-07 21:00:42 -0500350 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500351 return -1;
352
Florin Coras7baeb712019-01-04 17:05:43 -0800353 vlsh = ldp_fd_to_vlsh (fd);
354 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -0500355 {
Florin Coras7baeb712019-01-04 17:05:43 -0800356 size = vls_read (vlsh, buf, nbytes);
Dave Wallace048b1d62018-01-03 22:24:41 -0500357 if (size < 0)
358 {
359 errno = -size;
360 size = -1;
361 }
362 }
363 else
364 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500365 size = libc_read (fd, buf, nbytes);
366 }
367
Dave Wallace048b1d62018-01-03 22:24:41 -0500368 return size;
369}
370
371ssize_t
372readv (int fd, const struct iovec * iov, int iovcnt)
373{
Dave Wallace8aaba562018-01-18 17:21:19 -0500374 int rv = 0, i, total = 0;
Florin Coras7baeb712019-01-04 17:05:43 -0800375 vls_handle_t vlsh;
376 ssize_t size = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500377
Dave Wallace2a865272018-02-07 21:00:42 -0500378 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500379 return -1;
380
Florin Coras7baeb712019-01-04 17:05:43 -0800381 vlsh = ldp_fd_to_vlsh (fd);
382 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -0500383 {
Florin Coras067f9542020-02-14 05:33:46 +0000384 for (i = 0; i < iovcnt; ++i)
Dave Wallace048b1d62018-01-03 22:24:41 -0500385 {
Florin Coras067f9542020-02-14 05:33:46 +0000386 rv = vls_read (vlsh, iov[i].iov_base, iov[i].iov_len);
387 if (rv <= 0)
388 break;
389 else
Dave Wallace048b1d62018-01-03 22:24:41 -0500390 {
Florin Coras067f9542020-02-14 05:33:46 +0000391 total += rv;
392 if (rv < iov[i].iov_len)
Dave Wallace048b1d62018-01-03 22:24:41 -0500393 break;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700394 }
395 }
Florin Coras067f9542020-02-14 05:33:46 +0000396 if (rv < 0 && total == 0)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700397 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500398 errno = -rv;
399 size = -1;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700400 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500401 else
402 size = total;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700403 }
404 else
405 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500406 size = libc_readv (fd, iov, iovcnt);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700407 }
408
Dave Wallace048b1d62018-01-03 22:24:41 -0500409 return size;
410}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700411
Dave Wallace048b1d62018-01-03 22:24:41 -0500412ssize_t
413write (int fd, const void *buf, size_t nbytes)
414{
Florin Coras7baeb712019-01-04 17:05:43 -0800415 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -0500416 ssize_t size = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500417
Dave Wallace2a865272018-02-07 21:00:42 -0500418 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500419 return -1;
420
Florin Coras7baeb712019-01-04 17:05:43 -0800421 vlsh = ldp_fd_to_vlsh (fd);
422 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -0500423 {
Florin Coras7baeb712019-01-04 17:05:43 -0800424 size = vls_write_msg (vlsh, (void *) buf, nbytes);
Dave Wallace048b1d62018-01-03 22:24:41 -0500425 if (size < 0)
426 {
427 errno = -size;
428 size = -1;
429 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700430 }
431 else
432 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500433 size = libc_write (fd, buf, nbytes);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700434 }
435
Dave Wallace048b1d62018-01-03 22:24:41 -0500436 return size;
437}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700438
Dave Wallace048b1d62018-01-03 22:24:41 -0500439ssize_t
440writev (int fd, const struct iovec * iov, int iovcnt)
441{
Dave Wallace048b1d62018-01-03 22:24:41 -0500442 ssize_t size = 0, total = 0;
Florin Coras7baeb712019-01-04 17:05:43 -0800443 vls_handle_t vlsh;
Dave Wallace8aaba562018-01-18 17:21:19 -0500444 int i, rv = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500445
Dave Wallace2a865272018-02-07 21:00:42 -0500446 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500447 return -1;
448
Florin Coras7baeb712019-01-04 17:05:43 -0800449 vlsh = ldp_fd_to_vlsh (fd);
450 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -0500451 {
Florin Coraseda1b8c2020-03-23 16:00:35 +0000452 for (i = 0; i < iovcnt; ++i)
Dave Wallace048b1d62018-01-03 22:24:41 -0500453 {
Florin Coraseda1b8c2020-03-23 16:00:35 +0000454 rv = vls_write_msg (vlsh, iov[i].iov_base, iov[i].iov_len);
455 if (rv < 0)
456 break;
457 else
Dave Wallace048b1d62018-01-03 22:24:41 -0500458 {
Florin Coraseda1b8c2020-03-23 16:00:35 +0000459 total += rv;
460 if (rv < iov[i].iov_len)
Dave Wallace048b1d62018-01-03 22:24:41 -0500461 break;
Dave Wallace048b1d62018-01-03 22:24:41 -0500462 }
463 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500464
Florin Coraseda1b8c2020-03-23 16:00:35 +0000465 if (rv < 0 && total == 0)
Dave Wallace048b1d62018-01-03 22:24:41 -0500466 {
467 errno = -rv;
468 size = -1;
469 }
470 else
471 size = total;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700472 }
473 else
474 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500475 size = libc_writev (fd, iov, iovcnt);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700476 }
477
Dave Wallace048b1d62018-01-03 22:24:41 -0500478 return size;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700479}
480
481int
Dave Wallace048b1d62018-01-03 22:24:41 -0500482fcntl (int fd, int cmd, ...)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700483{
Florin Coras7baeb712019-01-04 17:05:43 -0800484 vls_handle_t vlsh;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700485 int rv = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500486 va_list ap;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700487
Dave Wallace2a865272018-02-07 21:00:42 -0500488 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500489 return -1;
490
491 va_start (ap, cmd);
Florin Coras7baeb712019-01-04 17:05:43 -0800492
493 vlsh = ldp_fd_to_vlsh (fd);
494 LDBG (0, "fd %u vlsh %d, cmd %u", fd, vlsh, cmd);
495 if (vlsh != VLS_INVALID_HANDLE)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700496 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500497 int flags = va_arg (ap, int);
498 u32 size;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700499
Dave Wallace048b1d62018-01-03 22:24:41 -0500500 size = sizeof (flags);
501 rv = -EOPNOTSUPP;
502 switch (cmd)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700503 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500504 case F_SETFL:
Florin Coras7baeb712019-01-04 17:05:43 -0800505 rv = vls_attr (vlsh, VPPCOM_ATTR_SET_FLAGS, &flags, &size);
Dave Wallace048b1d62018-01-03 22:24:41 -0500506 break;
507
508 case F_GETFL:
Florin Coras7baeb712019-01-04 17:05:43 -0800509 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_FLAGS, &flags, &size);
Dave Wallace048b1d62018-01-03 22:24:41 -0500510 if (rv == VPPCOM_OK)
Florin Coras7baeb712019-01-04 17:05:43 -0800511 rv = flags;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700512 break;
Florin Coras173bae32018-11-16 18:56:28 -0800513 case F_SETFD:
514 /* TODO handle this */
515 LDBG (0, "F_SETFD ignored flags %u", flags);
516 rv = 0;
517 break;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700518 default:
Dave Wallace048b1d62018-01-03 22:24:41 -0500519 rv = -EOPNOTSUPP;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700520 break;
521 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500522 if (rv < 0)
523 {
524 errno = -rv;
525 rv = -1;
526 }
527 }
528 else
529 {
Carl Smithe16707b2019-11-13 14:37:39 +1300530#ifdef HAVE_FCNTL64
531 rv = libc_vfcntl64 (fd, cmd, ap);
532#else
Dave Wallace048b1d62018-01-03 22:24:41 -0500533 rv = libc_vfcntl (fd, cmd, ap);
Carl Smithe16707b2019-11-13 14:37:39 +1300534#endif
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700535 }
536
Dave Wallace048b1d62018-01-03 22:24:41 -0500537 va_end (ap);
538
Dave Wallace048b1d62018-01-03 22:24:41 -0500539 return rv;
540}
541
542int
Florin Corasd7586d52020-04-29 02:19:51 +0000543fcntl64 (int fd, int cmd, ...)
544{
545 va_list ap;
546 int rv;
547
548 va_start (ap, cmd);
549 rv = fcntl (fd, cmd, ap);
550 va_end (ap);
551 return rv;
552}
553
554int
Dave Wallace048b1d62018-01-03 22:24:41 -0500555ioctl (int fd, unsigned long int cmd, ...)
556{
Florin Coras7baeb712019-01-04 17:05:43 -0800557 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -0500558 va_list ap;
Florin Coras7baeb712019-01-04 17:05:43 -0800559 int rv;
Dave Wallace048b1d62018-01-03 22:24:41 -0500560
Dave Wallace2a865272018-02-07 21:00:42 -0500561 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500562 return -1;
563
564 va_start (ap, cmd);
Dave Wallace048b1d62018-01-03 22:24:41 -0500565
Florin Coras7baeb712019-01-04 17:05:43 -0800566 vlsh = ldp_fd_to_vlsh (fd);
567 if (vlsh != VLS_INVALID_HANDLE)
568 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500569 switch (cmd)
570 {
571 case FIONREAD:
Florin Coras7baeb712019-01-04 17:05:43 -0800572 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_NREAD, 0, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -0500573 break;
574
575 case FIONBIO:
576 {
577 u32 flags = va_arg (ap, int) ? O_NONBLOCK : 0;
578 u32 size = sizeof (flags);
579
580 /* TBD: When VPPCOM_ATTR_[GS]ET_FLAGS supports flags other than
581 * non-blocking, the flags should be read here and merged
582 * with O_NONBLOCK.
583 */
Florin Coras7baeb712019-01-04 17:05:43 -0800584 rv = vls_attr (vlsh, VPPCOM_ATTR_SET_FLAGS, &flags, &size);
Dave Wallace048b1d62018-01-03 22:24:41 -0500585 }
586 break;
587
588 default:
589 rv = -EOPNOTSUPP;
590 break;
591 }
592 if (rv < 0)
593 {
594 errno = -rv;
595 rv = -1;
596 }
597 }
598 else
599 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500600 rv = libc_vioctl (fd, cmd, ap);
601 }
602
Dave Wallace048b1d62018-01-03 22:24:41 -0500603 va_end (ap);
604 return rv;
605}
606
Florin Coras294afe22019-01-07 17:49:17 -0800607always_inline void
608ldp_select_init_maps (fd_set * __restrict original,
609 clib_bitmap_t ** resultb, clib_bitmap_t ** libcb,
610 clib_bitmap_t ** vclb, int nfds, u32 minbits,
611 u32 n_bytes, uword * si_bits, uword * libc_bits)
612{
613 uword si_bits_set, libc_bits_set;
614 vls_handle_t vlsh;
615 int fd;
616
617 clib_bitmap_validate (*vclb, minbits);
618 clib_bitmap_validate (*libcb, minbits);
619 clib_bitmap_validate (*resultb, minbits);
620 clib_memcpy_fast (*resultb, original, n_bytes);
621 memset (original, 0, n_bytes);
622
623 /* *INDENT-OFF* */
624 clib_bitmap_foreach (fd, *resultb, ({
625 if (fd > nfds)
626 break;
627 vlsh = ldp_fd_to_vlsh (fd);
628 if (vlsh == VLS_INVALID_HANDLE)
629 clib_bitmap_set_no_check (*libcb, fd, 1);
630 else
Florin Corascbce80a2020-04-20 01:32:38 +0000631 *vclb = clib_bitmap_set (*vclb, vlsh_to_session_index (vlsh), 1);
Florin Coras294afe22019-01-07 17:49:17 -0800632 }));
633 /* *INDENT-ON* */
634
635 si_bits_set = clib_bitmap_last_set (*vclb) + 1;
636 *si_bits = (si_bits_set > *si_bits) ? si_bits_set : *si_bits;
Florin Corascbce80a2020-04-20 01:32:38 +0000637 clib_bitmap_validate (*resultb, *si_bits);
Florin Coras294afe22019-01-07 17:49:17 -0800638
639 libc_bits_set = clib_bitmap_last_set (*libcb) + 1;
640 *libc_bits = (libc_bits_set > *libc_bits) ? libc_bits_set : *libc_bits;
641}
642
643always_inline int
644ldp_select_vcl_map_to_libc (clib_bitmap_t * vclb, fd_set * __restrict libcb)
645{
646 vls_handle_t vlsh;
647 uword si;
648 int fd;
649
650 if (!libcb)
651 return 0;
652
653 /* *INDENT-OFF* */
654 clib_bitmap_foreach (si, vclb, ({
655 vlsh = vls_session_index_to_vlsh (si);
Florin Coras54140622020-02-04 19:04:34 +0000656 ASSERT (vlsh != VLS_INVALID_HANDLE);
Florin Coras294afe22019-01-07 17:49:17 -0800657 fd = ldp_vlsh_to_fd (vlsh);
658 if (PREDICT_FALSE (fd < 0))
659 {
660 errno = EBADFD;
661 return -1;
662 }
663 FD_SET (fd, libcb);
664 }));
665 /* *INDENT-ON* */
666
667 return 0;
668}
669
670always_inline void
671ldp_select_libc_map_merge (clib_bitmap_t * result, fd_set * __restrict libcb)
672{
673 uword fd;
674
Florin Coras78b5fa62019-02-21 20:04:15 -0800675 if (!libcb)
676 return;
677
Florin Coras294afe22019-01-07 17:49:17 -0800678 /* *INDENT-OFF* */
679 clib_bitmap_foreach (fd, result, ({
680 FD_SET ((int)fd, libcb);
681 }));
682 /* *INDENT-ON* */
683}
684
Dave Wallace048b1d62018-01-03 22:24:41 -0500685int
Dave Wallace2a865272018-02-07 21:00:42 -0500686ldp_pselect (int nfds, fd_set * __restrict readfds,
687 fd_set * __restrict writefds,
688 fd_set * __restrict exceptfds,
689 const struct timespec *__restrict timeout,
690 const __sigset_t * __restrict sigmask)
Dave Wallace048b1d62018-01-03 22:24:41 -0500691{
Florin Coras294afe22019-01-07 17:49:17 -0800692 u32 minbits = clib_max (nfds, BITS (uword)), n_bytes;
Florin Corasdfe4cf42018-11-28 22:13:45 -0800693 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
Florin Coras294afe22019-01-07 17:49:17 -0800694 struct timespec libc_tspec = { 0 };
695 f64 time_out, vcl_timeout = 0;
696 uword si_bits, libc_bits;
697 int rv, bits_set = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500698
699 if (nfds < 0)
700 {
701 errno = EINVAL;
702 return -1;
703 }
704
Florin Coras4dee8cd2019-01-29 21:28:16 -0800705 if (PREDICT_FALSE (ldpw->clib_time.init_cpu_time == 0))
706 clib_time_init (&ldpw->clib_time);
707
Dave Wallace3ee1fe12018-02-23 01:09:11 -0500708 if (timeout)
709 {
710 time_out = (timeout->tv_sec == 0 && timeout->tv_nsec == 0) ?
Florin Coras7baeb712019-01-04 17:05:43 -0800711 (f64) 0 : (f64) timeout->tv_sec + (f64) timeout->tv_nsec / (f64) 1e9;
Dave Wallace3ee1fe12018-02-23 01:09:11 -0500712
713 /* select as fine grained sleep */
714 if (!nfds)
715 {
Florin Corasdfe4cf42018-11-28 22:13:45 -0800716 time_out += clib_time_now (&ldpw->clib_time);
717 while (clib_time_now (&ldpw->clib_time) < time_out)
Dave Wallace3ee1fe12018-02-23 01:09:11 -0500718 ;
719 return 0;
720 }
721 }
722 else if (!nfds)
723 {
724 errno = EINVAL;
725 return -1;
726 }
727 else
728 time_out = -1;
729
Florin Coras7baeb712019-01-04 17:05:43 -0800730 if (nfds <= ldp->vlsh_bit_val)
Dave Wallace048b1d62018-01-03 22:24:41 -0500731 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500732 rv = libc_pselect (nfds, readfds, writefds, exceptfds,
733 timeout, sigmask);
734 goto done;
735 }
736
Florin Coras294afe22019-01-07 17:49:17 -0800737 si_bits = libc_bits = 0;
738 n_bytes = nfds / 8 + ((nfds % 8) ? 1 : 0);
Florin Coras7baeb712019-01-04 17:05:43 -0800739
Dave Wallace048b1d62018-01-03 22:24:41 -0500740 if (readfds)
Florin Coras294afe22019-01-07 17:49:17 -0800741 ldp_select_init_maps (readfds, &ldpw->rd_bitmap, &ldpw->libc_rd_bitmap,
742 &ldpw->si_rd_bitmap, nfds, minbits, n_bytes,
743 &si_bits, &libc_bits);
Dave Wallace048b1d62018-01-03 22:24:41 -0500744 if (writefds)
Florin Coras294afe22019-01-07 17:49:17 -0800745 ldp_select_init_maps (writefds, &ldpw->wr_bitmap,
746 &ldpw->libc_wr_bitmap, &ldpw->si_wr_bitmap, nfds,
747 minbits, n_bytes, &si_bits, &libc_bits);
Dave Wallace048b1d62018-01-03 22:24:41 -0500748 if (exceptfds)
Florin Coras294afe22019-01-07 17:49:17 -0800749 ldp_select_init_maps (exceptfds, &ldpw->ex_bitmap,
750 &ldpw->libc_ex_bitmap, &ldpw->si_ex_bitmap, nfds,
751 minbits, n_bytes, &si_bits, &libc_bits);
Dave Wallace048b1d62018-01-03 22:24:41 -0500752
Florin Coras294afe22019-01-07 17:49:17 -0800753 if (PREDICT_FALSE (!si_bits && !libc_bits))
Dave Wallace048b1d62018-01-03 22:24:41 -0500754 {
755 errno = EINVAL;
756 rv = -1;
757 goto done;
758 }
759
Florin Coras78b5fa62019-02-21 20:04:15 -0800760 if (!si_bits)
761 libc_tspec = timeout ? *timeout : libc_tspec;
Florin Coras294afe22019-01-07 17:49:17 -0800762
Dave Wallace048b1d62018-01-03 22:24:41 -0500763 do
764 {
Florin Coras294afe22019-01-07 17:49:17 -0800765 if (si_bits)
Dave Wallace048b1d62018-01-03 22:24:41 -0500766 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500767 if (readfds)
Florin Coras294afe22019-01-07 17:49:17 -0800768 clib_memcpy_fast (ldpw->rd_bitmap, ldpw->si_rd_bitmap,
Florin Corascbce80a2020-04-20 01:32:38 +0000769 vec_len (ldpw->si_rd_bitmap) *
Dave Barach178cf492018-11-13 16:34:13 -0500770 sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -0500771 if (writefds)
Florin Coras294afe22019-01-07 17:49:17 -0800772 clib_memcpy_fast (ldpw->wr_bitmap, ldpw->si_wr_bitmap,
Florin Corascbce80a2020-04-20 01:32:38 +0000773 vec_len (ldpw->si_wr_bitmap) *
Dave Barach178cf492018-11-13 16:34:13 -0500774 sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -0500775 if (exceptfds)
Florin Coras294afe22019-01-07 17:49:17 -0800776 clib_memcpy_fast (ldpw->ex_bitmap, ldpw->si_ex_bitmap,
Florin Corascbce80a2020-04-20 01:32:38 +0000777 vec_len (ldpw->si_ex_bitmap) *
Dave Barach178cf492018-11-13 16:34:13 -0500778 sizeof (clib_bitmap_t));
Florin Coras294afe22019-01-07 17:49:17 -0800779
Florin Coras0ef8ef22019-01-18 08:37:13 -0800780 rv = vls_select (si_bits, readfds ? ldpw->rd_bitmap : NULL,
781 writefds ? ldpw->wr_bitmap : NULL,
782 exceptfds ? ldpw->ex_bitmap : NULL, vcl_timeout);
Florin Coras294afe22019-01-07 17:49:17 -0800783 if (rv < 0)
784 {
785 errno = -rv;
786 rv = -1;
Florin Coras5e6222a2020-04-24 17:09:25 +0000787 goto done;
Florin Coras294afe22019-01-07 17:49:17 -0800788 }
789 else if (rv > 0)
790 {
791 if (ldp_select_vcl_map_to_libc (ldpw->rd_bitmap, readfds))
792 {
793 rv = -1;
794 goto done;
795 }
796
797 if (ldp_select_vcl_map_to_libc (ldpw->wr_bitmap, writefds))
798 {
799 rv = -1;
800 goto done;
801 }
802
803 if (ldp_select_vcl_map_to_libc (ldpw->ex_bitmap, exceptfds))
804 {
805 rv = -1;
806 goto done;
807 }
808 bits_set = rv;
809 }
810 }
811 if (libc_bits)
812 {
813 if (readfds)
814 clib_memcpy_fast (ldpw->rd_bitmap, ldpw->libc_rd_bitmap,
815 vec_len (ldpw->libc_rd_bitmap) *
816 sizeof (clib_bitmap_t));
817 if (writefds)
818 clib_memcpy_fast (ldpw->wr_bitmap, ldpw->libc_wr_bitmap,
819 vec_len (ldpw->libc_wr_bitmap) *
820 sizeof (clib_bitmap_t));
821 if (exceptfds)
822 clib_memcpy_fast (ldpw->ex_bitmap, ldpw->libc_ex_bitmap,
823 vec_len (ldpw->libc_ex_bitmap) *
824 sizeof (clib_bitmap_t));
825
Dave Wallace048b1d62018-01-03 22:24:41 -0500826 rv = libc_pselect (libc_bits,
Florin Coras294afe22019-01-07 17:49:17 -0800827 readfds ? (fd_set *) ldpw->rd_bitmap : NULL,
828 writefds ? (fd_set *) ldpw->wr_bitmap : NULL,
829 exceptfds ? (fd_set *) ldpw->ex_bitmap : NULL,
830 &libc_tspec, sigmask);
831 if (rv > 0)
832 {
833 ldp_select_libc_map_merge (ldpw->rd_bitmap, readfds);
834 ldp_select_libc_map_merge (ldpw->wr_bitmap, writefds);
835 ldp_select_libc_map_merge (ldpw->ex_bitmap, exceptfds);
836 bits_set += rv;
837 }
838 }
839
840 if (bits_set)
841 {
842 rv = bits_set;
843 goto done;
Dave Wallace048b1d62018-01-03 22:24:41 -0500844 }
845 }
Florin Corasdfe4cf42018-11-28 22:13:45 -0800846 while ((time_out == -1) || (clib_time_now (&ldpw->clib_time) < time_out));
Dave Wallace048b1d62018-01-03 22:24:41 -0500847 rv = 0;
848
849done:
850 /* TBD: set timeout to amount of time left */
Florin Corasdfe4cf42018-11-28 22:13:45 -0800851 clib_bitmap_zero (ldpw->rd_bitmap);
Florin Coras294afe22019-01-07 17:49:17 -0800852 clib_bitmap_zero (ldpw->si_rd_bitmap);
Florin Corasdfe4cf42018-11-28 22:13:45 -0800853 clib_bitmap_zero (ldpw->libc_rd_bitmap);
854 clib_bitmap_zero (ldpw->wr_bitmap);
Florin Coras294afe22019-01-07 17:49:17 -0800855 clib_bitmap_zero (ldpw->si_wr_bitmap);
Florin Corasdfe4cf42018-11-28 22:13:45 -0800856 clib_bitmap_zero (ldpw->libc_wr_bitmap);
857 clib_bitmap_zero (ldpw->ex_bitmap);
Florin Coras294afe22019-01-07 17:49:17 -0800858 clib_bitmap_zero (ldpw->si_ex_bitmap);
Florin Corasdfe4cf42018-11-28 22:13:45 -0800859 clib_bitmap_zero (ldpw->libc_ex_bitmap);
Dave Wallace048b1d62018-01-03 22:24:41 -0500860
Dave Wallace048b1d62018-01-03 22:24:41 -0500861 return rv;
862}
863
864int
865select (int nfds, fd_set * __restrict readfds,
866 fd_set * __restrict writefds,
867 fd_set * __restrict exceptfds, struct timeval *__restrict timeout)
868{
869 struct timespec tspec;
870
871 if (timeout)
872 {
873 tspec.tv_sec = timeout->tv_sec;
874 tspec.tv_nsec = timeout->tv_usec * 1000;
875 }
Dave Wallace2a865272018-02-07 21:00:42 -0500876 return ldp_pselect (nfds, readfds, writefds, exceptfds,
877 timeout ? &tspec : NULL, NULL);
Dave Wallace048b1d62018-01-03 22:24:41 -0500878}
879
880#ifdef __USE_XOPEN2K
881int
882pselect (int nfds, fd_set * __restrict readfds,
883 fd_set * __restrict writefds,
884 fd_set * __restrict exceptfds,
885 const struct timespec *__restrict timeout,
886 const __sigset_t * __restrict sigmask)
887{
Dave Wallace2a865272018-02-07 21:00:42 -0500888 return ldp_pselect (nfds, readfds, writefds, exceptfds, timeout, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -0500889}
890#endif
891
Yu Ping7b74b072019-05-08 00:40:24 +0800892/* If transparent TLS mode is turned on, then ldp will load key and cert.
893 */
894static int
895load_tls_cert (vls_handle_t vlsh)
896{
897 char *env_var_str = getenv (LDP_ENV_TLS_CERT);
898 char inbuf[4096];
899 char *tls_cert;
900 int cert_size;
901 FILE *fp;
902
903 if (env_var_str)
904 {
905 fp = fopen (env_var_str, "r");
906 if (fp == NULL)
907 {
908 LDBG (0, "ERROR: failed to open cert file %s \n", env_var_str);
909 return -1;
910 }
911 cert_size = fread (inbuf, sizeof (char), sizeof (inbuf), fp);
912 tls_cert = inbuf;
913 vppcom_session_tls_add_cert (vlsh_to_session_index (vlsh), tls_cert,
914 cert_size);
915 fclose (fp);
916 }
917 else
918 {
919 LDBG (0, "ERROR: failed to read LDP environment %s\n",
920 LDP_ENV_TLS_CERT);
921 return -1;
922 }
923 return 0;
924}
925
926static int
927load_tls_key (vls_handle_t vlsh)
928{
929 char *env_var_str = getenv (LDP_ENV_TLS_KEY);
930 char inbuf[4096];
931 char *tls_key;
932 int key_size;
933 FILE *fp;
934
935 if (env_var_str)
936 {
937 fp = fopen (env_var_str, "r");
938 if (fp == NULL)
939 {
940 LDBG (0, "ERROR: failed to open key file %s \n", env_var_str);
941 return -1;
942 }
943 key_size = fread (inbuf, sizeof (char), sizeof (inbuf), fp);
944 tls_key = inbuf;
945 vppcom_session_tls_add_key (vlsh_to_session_index (vlsh), tls_key,
946 key_size);
947 fclose (fp);
948 }
949 else
950 {
951 LDBG (0, "ERROR: failed to read LDP environment %s\n", LDP_ENV_TLS_KEY);
952 return -1;
953 }
954 return 0;
955}
956
Dave Wallace048b1d62018-01-03 22:24:41 -0500957int
958socket (int domain, int type, int protocol)
959{
Florin Coras7baeb712019-01-04 17:05:43 -0800960 int rv, sock_type = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK);
Dave Wallace048b1d62018-01-03 22:24:41 -0500961 u8 is_nonblocking = type & SOCK_NONBLOCK ? 1 : 0;
Florin Coras7baeb712019-01-04 17:05:43 -0800962 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -0500963
Dave Wallace2a865272018-02-07 21:00:42 -0500964 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500965 return -1;
966
967 if (((domain == AF_INET) || (domain == AF_INET6)) &&
968 ((sock_type == SOCK_STREAM) || (sock_type == SOCK_DGRAM)))
969 {
Yu Ping7b74b072019-05-08 00:40:24 +0800970 u8 proto;
971 if (ldp->transparent_tls)
972 {
973 proto = VPPCOM_PROTO_TLS;
974 }
975 else
976 proto = ((sock_type == SOCK_DGRAM) ?
977 VPPCOM_PROTO_UDP : VPPCOM_PROTO_TCP);
Dave Wallace048b1d62018-01-03 22:24:41 -0500978
Florin Coras7baeb712019-01-04 17:05:43 -0800979 LDBG (0, "calling vls_create: proto %u (%s), is_nonblocking %u",
980 proto, vppcom_proto_str (proto), is_nonblocking);
Dave Wallace048b1d62018-01-03 22:24:41 -0500981
Florin Coras7baeb712019-01-04 17:05:43 -0800982 vlsh = vls_create (proto, is_nonblocking);
983 if (vlsh < 0)
Dave Wallace048b1d62018-01-03 22:24:41 -0500984 {
Florin Coras7baeb712019-01-04 17:05:43 -0800985 errno = -vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -0500986 rv = -1;
987 }
988 else
989 {
Yu Ping7b74b072019-05-08 00:40:24 +0800990 if (ldp->transparent_tls)
991 {
992 if (load_tls_cert (vlsh) < 0 || load_tls_key (vlsh) < 0)
993 {
994 return -1;
995 }
996 }
Florin Coras7baeb712019-01-04 17:05:43 -0800997 rv = ldp_vlsh_to_fd (vlsh);
Dave Wallace048b1d62018-01-03 22:24:41 -0500998 }
999 }
1000 else
1001 {
Florin Coras7baeb712019-01-04 17:05:43 -08001002 LDBG (0, "calling libc_socket");
Dave Wallace048b1d62018-01-03 22:24:41 -05001003 rv = libc_socket (domain, type, protocol);
1004 }
1005
Dave Wallace048b1d62018-01-03 22:24:41 -05001006 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001007}
1008
1009/*
1010 * Create two new sockets, of type TYPE in domain DOMAIN and using
1011 * protocol PROTOCOL, which are connected to each other, and put file
1012 * descriptors for them in FDS[0] and FDS[1]. If PROTOCOL is zero,
1013 * one will be chosen automatically.
1014 * Returns 0 on success, -1 for errors.
1015 * */
1016int
Dave Wallace048b1d62018-01-03 22:24:41 -05001017socketpair (int domain, int type, int protocol, int fds[2])
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001018{
Florin Coras7baeb712019-01-04 17:05:43 -08001019 int rv, sock_type = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK);
Dave Wallace048b1d62018-01-03 22:24:41 -05001020
Dave Wallace2a865272018-02-07 21:00:42 -05001021 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001022 return -1;
1023
1024 if (((domain == AF_INET) || (domain == AF_INET6)) &&
1025 ((sock_type == SOCK_STREAM) || (sock_type == SOCK_DGRAM)))
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001026 {
Florin Coras7baeb712019-01-04 17:05:43 -08001027 LDBG (0, "LDP-TBD");
Dave Wallace048b1d62018-01-03 22:24:41 -05001028 errno = ENOSYS;
1029 rv = -1;
1030 }
1031 else
1032 {
Florin Coras7baeb712019-01-04 17:05:43 -08001033 LDBG (1, "calling libc_socketpair");
Florin Coras173bae32018-11-16 18:56:28 -08001034 rv = libc_socketpair (domain, type, protocol, fds);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001035 }
1036
Dave Wallace048b1d62018-01-03 22:24:41 -05001037 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001038}
1039
1040int
Dave Wallace048b1d62018-01-03 22:24:41 -05001041bind (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001042{
Florin Coras7baeb712019-01-04 17:05:43 -08001043 vls_handle_t vlsh;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001044 int rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001045
Dave Wallace2a865272018-02-07 21:00:42 -05001046 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001047 return -1;
1048
Florin Coras7baeb712019-01-04 17:05:43 -08001049 vlsh = ldp_fd_to_vlsh (fd);
1050 if (vlsh != VLS_INVALID_HANDLE)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001051 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001052 vppcom_endpt_t ep;
1053
Dave Wallace048b1d62018-01-03 22:24:41 -05001054 switch (addr->sa_family)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001055 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001056 case AF_INET:
1057 if (len != sizeof (struct sockaddr_in))
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001058 {
Florin Coras7baeb712019-01-04 17:05:43 -08001059 LDBG (0, "ERROR: fd %d: vlsh %u: Invalid AF_INET addr len %u!",
1060 fd, vlsh, len);
Dave Wallace048b1d62018-01-03 22:24:41 -05001061 errno = EINVAL;
1062 rv = -1;
1063 goto done;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001064 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001065 ep.is_ip4 = VPPCOM_IS_IP4;
1066 ep.ip = (u8 *) & ((const struct sockaddr_in *) addr)->sin_addr;
1067 ep.port = (u16) ((const struct sockaddr_in *) addr)->sin_port;
1068 break;
1069
1070 case AF_INET6:
1071 if (len != sizeof (struct sockaddr_in6))
1072 {
Florin Coras7baeb712019-01-04 17:05:43 -08001073 LDBG (0, "ERROR: fd %d: vlsh %u: Invalid AF_INET6 addr len %u!",
1074 fd, vlsh, len);
Dave Wallace048b1d62018-01-03 22:24:41 -05001075 errno = EINVAL;
1076 rv = -1;
1077 goto done;
1078 }
1079 ep.is_ip4 = VPPCOM_IS_IP6;
1080 ep.ip = (u8 *) & ((const struct sockaddr_in6 *) addr)->sin6_addr;
1081 ep.port = (u16) ((const struct sockaddr_in6 *) addr)->sin6_port;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001082 break;
1083
1084 default:
Florin Coras7baeb712019-01-04 17:05:43 -08001085 LDBG (0, "ERROR: fd %d: vlsh %u: Unsupported address family %u!",
1086 fd, vlsh, addr->sa_family);
Dave Wallace048b1d62018-01-03 22:24:41 -05001087 errno = EAFNOSUPPORT;
1088 rv = -1;
1089 goto done;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001090 }
Florin Coras7baeb712019-01-04 17:05:43 -08001091 LDBG (0, "fd %d: calling vls_bind: vlsh %u, addr %p, len %u", fd, vlsh,
1092 addr, len);
Dave Wallace048b1d62018-01-03 22:24:41 -05001093
Florin Coras7baeb712019-01-04 17:05:43 -08001094 rv = vls_bind (vlsh, &ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05001095 if (rv != VPPCOM_OK)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001096 {
1097 errno = -rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001098 rv = -1;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001099 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001100 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001101 else
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001102 {
Florin Coras7baeb712019-01-04 17:05:43 -08001103 LDBG (0, "fd %d: calling libc_bind: addr %p, len %u", fd, addr, len);
Dave Wallace048b1d62018-01-03 22:24:41 -05001104 rv = libc_bind (fd, addr, len);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001105 }
1106
Dave Wallace048b1d62018-01-03 22:24:41 -05001107done:
Florin Coras7baeb712019-01-04 17:05:43 -08001108 LDBG (1, "fd %d: returning %d", fd, rv);
Florin Coras05ecfcc2018-12-12 18:19:39 -08001109
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001110 return rv;
1111}
1112
1113static inline int
Dave Wallace2a865272018-02-07 21:00:42 -05001114ldp_copy_ep_to_sockaddr (__SOCKADDR_ARG addr, socklen_t * __restrict len,
1115 vppcom_endpt_t * ep)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001116{
Dave Wallace048b1d62018-01-03 22:24:41 -05001117 int rv = 0;
1118 int sa_len, copy_len;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001119
Dave Wallace2a865272018-02-07 21:00:42 -05001120 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001121 return -1;
1122
1123 if (addr && len && ep)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001124 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001125 addr->sa_family = (ep->is_ip4 == VPPCOM_IS_IP4) ? AF_INET : AF_INET6;
1126 switch (addr->sa_family)
1127 {
1128 case AF_INET:
1129 ((struct sockaddr_in *) addr)->sin_port = ep->port;
1130 if (*len > sizeof (struct sockaddr_in))
1131 *len = sizeof (struct sockaddr_in);
1132 sa_len = sizeof (struct sockaddr_in) - sizeof (struct in_addr);
1133 copy_len = *len - sa_len;
1134 if (copy_len > 0)
1135 memcpy (&((struct sockaddr_in *) addr)->sin_addr, ep->ip,
1136 copy_len);
1137 break;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001138
Dave Wallace048b1d62018-01-03 22:24:41 -05001139 case AF_INET6:
1140 ((struct sockaddr_in6 *) addr)->sin6_port = ep->port;
1141 if (*len > sizeof (struct sockaddr_in6))
1142 *len = sizeof (struct sockaddr_in6);
1143 sa_len = sizeof (struct sockaddr_in6) - sizeof (struct in6_addr);
1144 copy_len = *len - sa_len;
1145 if (copy_len > 0)
1146 memcpy (((struct sockaddr_in6 *) addr)->sin6_addr.
1147 __in6_u.__u6_addr8, ep->ip, copy_len);
1148 break;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001149
Dave Wallace048b1d62018-01-03 22:24:41 -05001150 default:
1151 /* Not possible */
1152 rv = -EAFNOSUPPORT;
1153 break;
1154 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001155 }
Dave Wallacee695cb42017-11-02 22:04:42 -04001156 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001157}
1158
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001159int
Dave Wallace048b1d62018-01-03 22:24:41 -05001160getsockname (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict len)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001161{
Florin Coras7baeb712019-01-04 17:05:43 -08001162 vls_handle_t vlsh;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001163 int rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001164
Dave Wallace2a865272018-02-07 21:00:42 -05001165 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001166 return -1;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001167
Florin Coras7baeb712019-01-04 17:05:43 -08001168 vlsh = ldp_fd_to_vlsh (fd);
1169 if (vlsh != VLS_INVALID_HANDLE)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001170 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001171 vppcom_endpt_t ep;
1172 u8 addr_buf[sizeof (struct in6_addr)];
1173 u32 size = sizeof (ep);
1174
1175 ep.ip = addr_buf;
Dave Wallace048b1d62018-01-03 22:24:41 -05001176
Florin Coras7baeb712019-01-04 17:05:43 -08001177 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_LCL_ADDR, &ep, &size);
Dave Wallace048b1d62018-01-03 22:24:41 -05001178 if (rv != VPPCOM_OK)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001179 {
1180 errno = -rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001181 rv = -1;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001182 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001183 else
1184 {
Dave Wallace2a865272018-02-07 21:00:42 -05001185 rv = ldp_copy_ep_to_sockaddr (addr, len, &ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05001186 if (rv != VPPCOM_OK)
1187 {
1188 errno = -rv;
1189 rv = -1;
1190 }
1191 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001192 }
1193 else
1194 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001195 rv = libc_getsockname (fd, addr, len);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001196 }
1197
Dave Wallace048b1d62018-01-03 22:24:41 -05001198 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001199}
1200
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001201int
Dave Wallace048b1d62018-01-03 22:24:41 -05001202connect (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001203{
Florin Coras7baeb712019-01-04 17:05:43 -08001204 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05001205 int rv;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001206
Dave Wallace2a865272018-02-07 21:00:42 -05001207 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001208 return -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001209
Dave Wallace048b1d62018-01-03 22:24:41 -05001210 if (!addr)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001211 {
Florin Coras7baeb712019-01-04 17:05:43 -08001212 LDBG (0, "ERROR: fd %d: NULL addr, len %u", fd, len);
Dave Wallace048b1d62018-01-03 22:24:41 -05001213 errno = EINVAL;
1214 rv = -1;
1215 goto done;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001216 }
1217
Florin Coras7baeb712019-01-04 17:05:43 -08001218 vlsh = ldp_fd_to_vlsh (fd);
1219 if (vlsh != VLS_INVALID_HANDLE)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001220 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001221 vppcom_endpt_t ep;
1222
Dave Wallace048b1d62018-01-03 22:24:41 -05001223 switch (addr->sa_family)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001224 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001225 case AF_INET:
1226 if (len != sizeof (struct sockaddr_in))
1227 {
Florin Coras7baeb712019-01-04 17:05:43 -08001228 LDBG (0, "fd %d: ERROR vlsh %u: Invalid AF_INET addr len %u!",
1229 fd, vlsh, len);
Dave Wallace048b1d62018-01-03 22:24:41 -05001230 errno = EINVAL;
1231 rv = -1;
1232 goto done;
1233 }
1234 ep.is_ip4 = VPPCOM_IS_IP4;
1235 ep.ip = (u8 *) & ((const struct sockaddr_in *) addr)->sin_addr;
1236 ep.port = (u16) ((const struct sockaddr_in *) addr)->sin_port;
1237 break;
1238
1239 case AF_INET6:
1240 if (len != sizeof (struct sockaddr_in6))
1241 {
Florin Coras7baeb712019-01-04 17:05:43 -08001242 LDBG (0, "fd %d: ERROR vlsh %u: Invalid AF_INET6 addr len %u!",
1243 fd, vlsh, len);
Dave Wallace048b1d62018-01-03 22:24:41 -05001244 errno = EINVAL;
1245 rv = -1;
1246 goto done;
1247 }
1248 ep.is_ip4 = VPPCOM_IS_IP6;
1249 ep.ip = (u8 *) & ((const struct sockaddr_in6 *) addr)->sin6_addr;
1250 ep.port = (u16) ((const struct sockaddr_in6 *) addr)->sin6_port;
1251 break;
1252
1253 default:
Florin Coras7baeb712019-01-04 17:05:43 -08001254 LDBG (0, "fd %d: ERROR vlsh %u: Unsupported address family %u!",
1255 fd, vlsh, addr->sa_family);
Dave Wallace048b1d62018-01-03 22:24:41 -05001256 errno = EAFNOSUPPORT;
1257 rv = -1;
1258 goto done;
1259 }
Florin Coras7baeb712019-01-04 17:05:43 -08001260 LDBG (0, "fd %d: calling vls_connect(): vlsh %u addr %p len %u", fd,
1261 vlsh, addr, len);
Dave Wallace048b1d62018-01-03 22:24:41 -05001262
Florin Coras7baeb712019-01-04 17:05:43 -08001263 rv = vls_connect (vlsh, &ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05001264 if (rv != VPPCOM_OK)
1265 {
1266 errno = -rv;
1267 rv = -1;
1268 }
1269 }
1270 else
1271 {
Florin Coras7baeb712019-01-04 17:05:43 -08001272 LDBG (0, "fd %d: calling libc_connect(): addr %p, len %u",
1273 fd, addr, len);
Dave Wallace048b1d62018-01-03 22:24:41 -05001274
1275 rv = libc_connect (fd, addr, len);
1276 }
1277
1278done:
Florin Coras7baeb712019-01-04 17:05:43 -08001279 LDBG (1, "fd %d: returning %d (0x%x)", fd, rv, rv);
Dave Wallace048b1d62018-01-03 22:24:41 -05001280 return rv;
1281}
1282
1283int
1284getpeername (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict len)
1285{
Florin Coras7baeb712019-01-04 17:05:43 -08001286 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05001287 int rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001288
Dave Wallace2a865272018-02-07 21:00:42 -05001289 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001290 return -1;
1291
Florin Coras7baeb712019-01-04 17:05:43 -08001292 vlsh = ldp_fd_to_vlsh (fd);
1293 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -05001294 {
1295 vppcom_endpt_t ep;
1296 u8 addr_buf[sizeof (struct in6_addr)];
1297 u32 size = sizeof (ep);
1298
1299 ep.ip = addr_buf;
Florin Coras7baeb712019-01-04 17:05:43 -08001300 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_PEER_ADDR, &ep, &size);
Dave Wallace048b1d62018-01-03 22:24:41 -05001301 if (rv != VPPCOM_OK)
1302 {
1303 errno = -rv;
1304 rv = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001305 }
1306 else
1307 {
Dave Wallace2a865272018-02-07 21:00:42 -05001308 rv = ldp_copy_ep_to_sockaddr (addr, len, &ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05001309 if (rv != VPPCOM_OK)
1310 {
1311 errno = -rv;
1312 rv = -1;
1313 }
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001314 }
1315 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001316 else
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001317 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001318 rv = libc_getpeername (fd, addr, len);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001319 }
1320
Dave Wallace048b1d62018-01-03 22:24:41 -05001321 return rv;
1322}
1323
1324ssize_t
1325send (int fd, const void *buf, size_t n, int flags)
1326{
Florin Coras7baeb712019-01-04 17:05:43 -08001327 vls_handle_t vlsh = ldp_fd_to_vlsh (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05001328 ssize_t size;
Dave Wallace048b1d62018-01-03 22:24:41 -05001329
Dave Wallace2a865272018-02-07 21:00:42 -05001330 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001331 return -1;
1332
Florin Coras7baeb712019-01-04 17:05:43 -08001333 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -05001334 {
Florin Coras7baeb712019-01-04 17:05:43 -08001335 size = vls_sendto (vlsh, (void *) buf, n, flags, NULL);
qchangaa8f63c2018-05-30 11:44:18 -07001336 if (size < VPPCOM_OK)
Dave Wallace048b1d62018-01-03 22:24:41 -05001337 {
1338 errno = -size;
1339 size = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001340 }
1341 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001342 else
1343 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001344 size = libc_send (fd, buf, n, flags);
1345 }
1346
Dave Wallace048b1d62018-01-03 22:24:41 -05001347 return size;
1348}
1349
1350ssize_t
1351sendfile (int out_fd, int in_fd, off_t * offset, size_t len)
1352{
Florin Corasdfe4cf42018-11-28 22:13:45 -08001353 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
Florin Coras7baeb712019-01-04 17:05:43 -08001354 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05001355 ssize_t size = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05001356
Dave Wallace2a865272018-02-07 21:00:42 -05001357 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001358 return -1;
1359
Florin Coras7baeb712019-01-04 17:05:43 -08001360 vlsh = ldp_fd_to_vlsh (out_fd);
1361 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -05001362 {
1363 int rv;
1364 ssize_t results = 0;
1365 size_t n_bytes_left = len;
1366 size_t bytes_to_read;
1367 int nbytes;
Dave Wallace048b1d62018-01-03 22:24:41 -05001368 u8 eagain = 0;
1369 u32 flags, flags_len = sizeof (flags);
1370
Florin Coras7baeb712019-01-04 17:05:43 -08001371 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_FLAGS, &flags, &flags_len);
Dave Wallace048b1d62018-01-03 22:24:41 -05001372 if (PREDICT_FALSE (rv != VPPCOM_OK))
1373 {
Florin Coras7baeb712019-01-04 17:05:43 -08001374 LDBG (0, "ERROR: out fd %d: vls_attr: vlsh %u, returned %d (%s)!",
1375 out_fd, vlsh, rv, vppcom_retval_str (rv));
Dave Wallace048b1d62018-01-03 22:24:41 -05001376
Florin Corasdfe4cf42018-11-28 22:13:45 -08001377 vec_reset_length (ldpw->io_buffer);
Dave Wallace048b1d62018-01-03 22:24:41 -05001378 errno = -rv;
1379 size = -1;
1380 goto done;
1381 }
1382
1383 if (offset)
1384 {
1385 off_t off = lseek (in_fd, *offset, SEEK_SET);
1386 if (PREDICT_FALSE (off == -1))
1387 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001388 size = -1;
1389 goto done;
1390 }
1391
1392 ASSERT (off == *offset);
1393 }
1394
1395 do
1396 {
Florin Coras7baeb712019-01-04 17:05:43 -08001397 size = vls_attr (vlsh, VPPCOM_ATTR_GET_NWRITE, 0, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05001398 if (size < 0)
1399 {
Florin Coras7baeb712019-01-04 17:05:43 -08001400 LDBG (0, "ERROR: fd %d: vls_attr: vlsh %u returned %d (%s)!",
1401 out_fd, vlsh, size, vppcom_retval_str (size));
Florin Corasdfe4cf42018-11-28 22:13:45 -08001402 vec_reset_length (ldpw->io_buffer);
Dave Wallace048b1d62018-01-03 22:24:41 -05001403 errno = -size;
1404 size = -1;
1405 goto done;
1406 }
1407
1408 bytes_to_read = size;
Dave Wallace048b1d62018-01-03 22:24:41 -05001409 if (bytes_to_read == 0)
1410 {
1411 if (flags & O_NONBLOCK)
1412 {
1413 if (!results)
Florin Coras7baeb712019-01-04 17:05:43 -08001414 eagain = 1;
Dave Wallace048b1d62018-01-03 22:24:41 -05001415 goto update_offset;
1416 }
1417 else
1418 continue;
1419 }
1420 bytes_to_read = clib_min (n_bytes_left, bytes_to_read);
Florin Corasdfe4cf42018-11-28 22:13:45 -08001421 vec_validate (ldpw->io_buffer, bytes_to_read);
1422 nbytes = libc_read (in_fd, ldpw->io_buffer, bytes_to_read);
Dave Wallace048b1d62018-01-03 22:24:41 -05001423 if (nbytes < 0)
1424 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001425 if (results == 0)
1426 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08001427 vec_reset_length (ldpw->io_buffer);
Dave Wallace048b1d62018-01-03 22:24:41 -05001428 size = -1;
1429 goto done;
1430 }
1431 goto update_offset;
1432 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001433
Florin Coras7baeb712019-01-04 17:05:43 -08001434 size = vls_write (vlsh, ldpw->io_buffer, nbytes);
Dave Wallace048b1d62018-01-03 22:24:41 -05001435 if (size < 0)
1436 {
1437 if (size == VPPCOM_EAGAIN)
1438 {
1439 if (flags & O_NONBLOCK)
1440 {
1441 if (!results)
Florin Coras7baeb712019-01-04 17:05:43 -08001442 eagain = 1;
Dave Wallace048b1d62018-01-03 22:24:41 -05001443 goto update_offset;
1444 }
1445 else
1446 continue;
1447 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001448 if (results == 0)
1449 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08001450 vec_reset_length (ldpw->io_buffer);
Dave Wallace048b1d62018-01-03 22:24:41 -05001451 errno = -size;
1452 size = -1;
1453 goto done;
1454 }
1455 goto update_offset;
1456 }
1457
1458 results += nbytes;
1459 ASSERT (n_bytes_left >= nbytes);
1460 n_bytes_left = n_bytes_left - nbytes;
1461 }
1462 while (n_bytes_left > 0);
1463
1464 update_offset:
Florin Corasdfe4cf42018-11-28 22:13:45 -08001465 vec_reset_length (ldpw->io_buffer);
Dave Wallace048b1d62018-01-03 22:24:41 -05001466 if (offset)
1467 {
1468 off_t off = lseek (in_fd, *offset, SEEK_SET);
1469 if (PREDICT_FALSE (off == -1))
1470 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001471 size = -1;
1472 goto done;
1473 }
1474
1475 ASSERT (off == *offset);
1476 *offset += results + 1;
1477 }
1478 if (eagain)
1479 {
1480 errno = EAGAIN;
1481 size = -1;
1482 }
1483 else
1484 size = results;
1485 }
1486 else
1487 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001488 size = libc_sendfile (out_fd, in_fd, offset, len);
1489 }
1490
1491done:
Dave Wallace048b1d62018-01-03 22:24:41 -05001492 return size;
1493}
1494
1495ssize_t
1496sendfile64 (int out_fd, int in_fd, off_t * offset, size_t len)
1497{
1498 return sendfile (out_fd, in_fd, offset, len);
1499}
1500
1501ssize_t
1502recv (int fd, void *buf, size_t n, int flags)
1503{
Florin Coras7baeb712019-01-04 17:05:43 -08001504 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05001505 ssize_t size;
Dave Wallace048b1d62018-01-03 22:24:41 -05001506
Dave Wallace2a865272018-02-07 21:00:42 -05001507 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001508 return -1;
1509
Florin Coras7baeb712019-01-04 17:05:43 -08001510 vlsh = ldp_fd_to_vlsh (fd);
1511 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -05001512 {
Florin Coras7baeb712019-01-04 17:05:43 -08001513 size = vls_recvfrom (vlsh, buf, n, flags, NULL);
Dave Wallace048b1d62018-01-03 22:24:41 -05001514 if (size < 0)
Florin Coras2a6642e2020-03-24 15:24:29 +00001515 {
1516 errno = -size;
1517 size = -1;
1518 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001519 }
1520 else
1521 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001522 size = libc_recv (fd, buf, n, flags);
1523 }
1524
Dave Wallace048b1d62018-01-03 22:24:41 -05001525 return size;
1526}
1527
1528ssize_t
1529sendto (int fd, const void *buf, size_t n, int flags,
1530 __CONST_SOCKADDR_ARG addr, socklen_t addr_len)
1531{
Florin Coras7baeb712019-01-04 17:05:43 -08001532 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05001533 ssize_t size;
Dave Wallace048b1d62018-01-03 22:24:41 -05001534
Dave Wallace2a865272018-02-07 21:00:42 -05001535 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001536 return -1;
1537
Florin Coras7baeb712019-01-04 17:05:43 -08001538 vlsh = ldp_fd_to_vlsh (fd);
1539 if (vlsh != INVALID_SESSION_ID)
Dave Wallace048b1d62018-01-03 22:24:41 -05001540 {
1541 vppcom_endpt_t *ep = 0;
1542 vppcom_endpt_t _ep;
1543
1544 if (addr)
1545 {
1546 ep = &_ep;
Dave Wallace048b1d62018-01-03 22:24:41 -05001547 switch (addr->sa_family)
1548 {
1549 case AF_INET:
1550 ep->is_ip4 = VPPCOM_IS_IP4;
1551 ep->ip =
1552 (uint8_t *) & ((const struct sockaddr_in *) addr)->sin_addr;
1553 ep->port =
1554 (uint16_t) ((const struct sockaddr_in *) addr)->sin_port;
1555 break;
1556
1557 case AF_INET6:
1558 ep->is_ip4 = VPPCOM_IS_IP6;
1559 ep->ip =
1560 (uint8_t *) & ((const struct sockaddr_in6 *) addr)->sin6_addr;
1561 ep->port =
1562 (uint16_t) ((const struct sockaddr_in6 *) addr)->sin6_port;
1563 break;
1564
1565 default:
1566 errno = EAFNOSUPPORT;
1567 size = -1;
1568 goto done;
1569 }
1570 }
1571
Florin Coras7baeb712019-01-04 17:05:43 -08001572 size = vls_sendto (vlsh, (void *) buf, n, flags, ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05001573 if (size < 0)
1574 {
1575 errno = -size;
1576 size = -1;
1577 }
1578 }
1579 else
1580 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001581 size = libc_sendto (fd, buf, n, flags, addr, addr_len);
1582 }
1583
1584done:
Dave Wallace048b1d62018-01-03 22:24:41 -05001585 return size;
1586}
1587
1588ssize_t
1589recvfrom (int fd, void *__restrict buf, size_t n, int flags,
1590 __SOCKADDR_ARG addr, socklen_t * __restrict addr_len)
1591{
Florin Coras7baeb712019-01-04 17:05:43 -08001592 vls_handle_t sid;
Haggai Eran46ae2ef2019-02-19 15:04:42 +02001593 ssize_t size, rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001594
Dave Wallace2a865272018-02-07 21:00:42 -05001595 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001596 return -1;
1597
Florin Coras7baeb712019-01-04 17:05:43 -08001598 sid = ldp_fd_to_vlsh (fd);
1599 if (sid != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -05001600 {
1601 vppcom_endpt_t ep;
1602 u8 src_addr[sizeof (struct sockaddr_in6)];
1603
Dave Wallace048b1d62018-01-03 22:24:41 -05001604 if (addr)
1605 {
1606 ep.ip = src_addr;
Florin Coras7baeb712019-01-04 17:05:43 -08001607 size = vls_recvfrom (sid, buf, n, flags, &ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05001608
1609 if (size > 0)
Haggai Eran46ae2ef2019-02-19 15:04:42 +02001610 {
1611 rv = ldp_copy_ep_to_sockaddr (addr, addr_len, &ep);
1612 if (rv < 0)
1613 size = rv;
1614 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001615 }
1616 else
Florin Coras7baeb712019-01-04 17:05:43 -08001617 size = vls_recvfrom (sid, buf, n, flags, NULL);
Dave Wallace048b1d62018-01-03 22:24:41 -05001618
1619 if (size < 0)
1620 {
1621 errno = -size;
1622 size = -1;
1623 }
1624 }
1625 else
1626 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001627 size = libc_recvfrom (fd, buf, n, flags, addr, addr_len);
1628 }
1629
Dave Wallace048b1d62018-01-03 22:24:41 -05001630 return size;
1631}
1632
1633ssize_t
1634sendmsg (int fd, const struct msghdr * message, int flags)
1635{
Florin Coras7baeb712019-01-04 17:05:43 -08001636 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05001637 ssize_t size;
Dave Wallace048b1d62018-01-03 22:24:41 -05001638
Dave Wallace2a865272018-02-07 21:00:42 -05001639 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001640 return -1;
1641
Florin Coras7baeb712019-01-04 17:05:43 -08001642 vlsh = ldp_fd_to_vlsh (fd);
1643 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -05001644 {
Florin Coras7baeb712019-01-04 17:05:43 -08001645 LDBG (0, "LDP-TBD");
Dave Wallace048b1d62018-01-03 22:24:41 -05001646 errno = ENOSYS;
1647 size = -1;
1648 }
1649 else
1650 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001651 size = libc_sendmsg (fd, message, flags);
1652 }
1653
Dave Wallace048b1d62018-01-03 22:24:41 -05001654 return size;
1655}
1656
1657#ifdef USE_GNU
1658int
1659sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags)
1660{
1661 ssize_t size;
1662 const char *func_str;
Florin Coras7baeb712019-01-04 17:05:43 -08001663 u32 sh = ldp_fd_to_vlsh (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05001664
Dave Wallace2a865272018-02-07 21:00:42 -05001665 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001666 return -1;
1667
Florin Coras7baeb712019-01-04 17:05:43 -08001668 if (sh != INVALID_SESSION_ID)
Dave Wallace048b1d62018-01-03 22:24:41 -05001669 {
1670 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
1671 errno = ENOSYS;
1672 size = -1;
1673 }
1674 else
1675 {
1676 func_str = "libc_sendmmsg";
1677
Dave Wallace2a865272018-02-07 21:00:42 -05001678 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001679 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1680 "vmessages %p, vlen %u, flags 0x%x",
1681 getpid (), fd, fd, func_str, vmessages, vlen, flags);
1682
1683 size = libc_sendmmsg (fd, vmessages, vlen, flags);
1684 }
1685
Dave Wallace2a865272018-02-07 21:00:42 -05001686 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001687 {
1688 if (size < 0)
1689 {
1690 int errno_val = errno;
1691 perror (func_str);
1692 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1693 "rv %d, errno = %d", getpid (), fd, fd,
1694 func_str, size, errno_val);
1695 errno = errno_val;
1696 }
1697 else
1698 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1699 getpid (), fd, fd, size, size);
1700 }
1701 return size;
1702}
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001703#endif
1704
Dave Wallace048b1d62018-01-03 22:24:41 -05001705ssize_t
1706recvmsg (int fd, struct msghdr * message, int flags)
1707{
Florin Coras7baeb712019-01-04 17:05:43 -08001708 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05001709 ssize_t size;
Dave Wallace048b1d62018-01-03 22:24:41 -05001710
Dave Wallace2a865272018-02-07 21:00:42 -05001711 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001712 return -1;
1713
Florin Coras7baeb712019-01-04 17:05:43 -08001714 vlsh = ldp_fd_to_vlsh (fd);
1715 if (vlsh != VLS_INVALID_HANDLE)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001716 {
Florin Coras7baeb712019-01-04 17:05:43 -08001717 LDBG (0, "LDP-TBD");
Dave Wallace048b1d62018-01-03 22:24:41 -05001718 errno = ENOSYS;
1719 size = -1;
1720 }
1721 else
1722 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001723 size = libc_recvmsg (fd, message, flags);
1724 }
1725
Dave Wallace048b1d62018-01-03 22:24:41 -05001726 return size;
1727}
1728
1729#ifdef USE_GNU
1730int
1731recvmmsg (int fd, struct mmsghdr *vmessages,
1732 unsigned int vlen, int flags, struct timespec *tmo)
1733{
1734 ssize_t size;
1735 const char *func_str;
Florin Coras7baeb712019-01-04 17:05:43 -08001736 u32 sh = ldp_fd_to_vlsh (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05001737
Dave Wallace2a865272018-02-07 21:00:42 -05001738 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001739 return -1;
1740
Florin Coras7baeb712019-01-04 17:05:43 -08001741 if (sh != INVALID_SESSION_ID)
Dave Wallace048b1d62018-01-03 22:24:41 -05001742 {
1743 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
1744 errno = ENOSYS;
1745 size = -1;
1746 }
1747 else
1748 {
1749 func_str = "libc_recvmmsg";
1750
Dave Wallace2a865272018-02-07 21:00:42 -05001751 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001752 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1753 "vmessages %p, vlen %u, flags 0x%x, tmo %p",
1754 getpid (), fd, fd, func_str, vmessages, vlen,
1755 flags, tmo);
1756
1757 size = libc_recvmmsg (fd, vmessages, vlen, flags, tmo);
1758 }
1759
Dave Wallace2a865272018-02-07 21:00:42 -05001760 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001761 {
1762 if (size < 0)
1763 {
1764 int errno_val = errno;
1765 perror (func_str);
1766 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1767 "rv %d, errno = %d", getpid (), fd, fd,
1768 func_str, size, errno_val);
1769 errno = errno_val;
1770 }
1771 else
1772 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1773 getpid (), fd, fd, size, size);
1774 }
1775 return size;
1776}
1777#endif
1778
1779int
1780getsockopt (int fd, int level, int optname,
1781 void *__restrict optval, socklen_t * __restrict optlen)
1782{
Florin Coras7baeb712019-01-04 17:05:43 -08001783 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05001784 int rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001785
Dave Wallace2a865272018-02-07 21:00:42 -05001786 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001787 return -1;
1788
Florin Coras7baeb712019-01-04 17:05:43 -08001789 vlsh = ldp_fd_to_vlsh (fd);
1790 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -05001791 {
1792 rv = -EOPNOTSUPP;
1793
1794 switch (level)
1795 {
1796 case SOL_TCP:
1797 switch (optname)
1798 {
1799 case TCP_NODELAY:
Florin Coras7baeb712019-01-04 17:05:43 -08001800 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_TCP_NODELAY,
1801 optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001802 break;
1803 case TCP_MAXSEG:
Florin Coras7baeb712019-01-04 17:05:43 -08001804 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_TCP_USER_MSS,
1805 optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001806 break;
1807 case TCP_KEEPIDLE:
Florin Coras7baeb712019-01-04 17:05:43 -08001808 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_TCP_KEEPIDLE,
1809 optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001810 break;
1811 case TCP_KEEPINTVL:
Florin Coras7baeb712019-01-04 17:05:43 -08001812 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_TCP_KEEPINTVL,
1813 optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001814 break;
1815 case TCP_INFO:
1816 if (optval && optlen && (*optlen == sizeof (struct tcp_info)))
1817 {
Florin Coras7baeb712019-01-04 17:05:43 -08001818 LDBG (1, "fd %d: vlsh %u SOL_TCP, TCP_INFO, optval %p, "
1819 "optlen %d: #LDP-NOP#", fd, vlsh, optval, *optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001820 memset (optval, 0, *optlen);
1821 rv = VPPCOM_OK;
1822 }
1823 else
1824 rv = -EFAULT;
1825 break;
Florin Coras0ed24e92019-01-21 09:03:10 -08001826 case TCP_CONGESTION:
Florin Coras0ed24e92019-01-21 09:03:10 -08001827 *optlen = strlen ("cubic");
Dave Barach02500902020-04-04 18:34:41 -04001828 strncpy (optval, "cubic", *optlen + 1);
Florin Coras0ed24e92019-01-21 09:03:10 -08001829 rv = 0;
1830 break;
Dave Wallace048b1d62018-01-03 22:24:41 -05001831 default:
Florin Coras7baeb712019-01-04 17:05:43 -08001832 LDBG (0, "ERROR: fd %d: getsockopt SOL_TCP: sid %u, "
1833 "optname %d unsupported!", fd, vlsh, optname);
Dave Wallace048b1d62018-01-03 22:24:41 -05001834 break;
1835 }
1836 break;
1837 case SOL_IPV6:
1838 switch (optname)
1839 {
1840 case IPV6_V6ONLY:
Florin Coras7baeb712019-01-04 17:05:43 -08001841 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_V6ONLY, optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001842 break;
1843 default:
Florin Coras7baeb712019-01-04 17:05:43 -08001844 LDBG (0, "ERROR: fd %d: getsockopt SOL_IPV6: vlsh %u "
1845 "optname %d unsupported!", fd, vlsh, optname);
Dave Wallace048b1d62018-01-03 22:24:41 -05001846 break;
1847 }
1848 break;
1849 case SOL_SOCKET:
1850 switch (optname)
1851 {
1852 case SO_ACCEPTCONN:
Florin Coras7baeb712019-01-04 17:05:43 -08001853 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_LISTEN, optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001854 break;
1855 case SO_KEEPALIVE:
Florin Coras7baeb712019-01-04 17:05:43 -08001856 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_KEEPALIVE, optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001857 break;
1858 case SO_PROTOCOL:
Florin Coras7baeb712019-01-04 17:05:43 -08001859 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_PROTOCOL, optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001860 *(int *) optval = *(int *) optval ? SOCK_DGRAM : SOCK_STREAM;
1861 break;
1862 case SO_SNDBUF:
Florin Coras7baeb712019-01-04 17:05:43 -08001863 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_TX_FIFO_LEN,
1864 optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001865 break;
1866 case SO_RCVBUF:
Florin Coras7baeb712019-01-04 17:05:43 -08001867 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_RX_FIFO_LEN,
1868 optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001869 break;
1870 case SO_REUSEADDR:
Florin Coras7baeb712019-01-04 17:05:43 -08001871 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_REUSEADDR, optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001872 break;
1873 case SO_BROADCAST:
Florin Coras7baeb712019-01-04 17:05:43 -08001874 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_BROADCAST, optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001875 break;
1876 case SO_ERROR:
Florin Coras7baeb712019-01-04 17:05:43 -08001877 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_ERROR, optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001878 break;
1879 default:
Florin Coras7baeb712019-01-04 17:05:43 -08001880 LDBG (0, "ERROR: fd %d: getsockopt SOL_SOCKET: vlsh %u "
1881 "optname %d unsupported!", fd, vlsh, optname);
Dave Wallace048b1d62018-01-03 22:24:41 -05001882 break;
1883 }
1884 break;
1885 default:
1886 break;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001887 }
1888
Dave Wallace048b1d62018-01-03 22:24:41 -05001889 if (rv != VPPCOM_OK)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001890 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001891 errno = -rv;
1892 rv = -1;
1893 }
1894 }
1895 else
1896 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001897 rv = libc_getsockopt (fd, level, optname, optval, optlen);
1898 }
1899
Dave Wallace048b1d62018-01-03 22:24:41 -05001900 return rv;
1901}
1902
1903int
1904setsockopt (int fd, int level, int optname,
1905 const void *optval, socklen_t optlen)
1906{
Florin Coras7baeb712019-01-04 17:05:43 -08001907 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05001908 int rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001909
Dave Wallace2a865272018-02-07 21:00:42 -05001910 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001911 return -1;
1912
Florin Coras7baeb712019-01-04 17:05:43 -08001913 vlsh = ldp_fd_to_vlsh (fd);
1914 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -05001915 {
1916 rv = -EOPNOTSUPP;
1917
1918 switch (level)
1919 {
1920 case SOL_TCP:
1921 switch (optname)
1922 {
1923 case TCP_NODELAY:
Florin Coras7baeb712019-01-04 17:05:43 -08001924 rv = vls_attr (vlsh, VPPCOM_ATTR_SET_TCP_NODELAY,
1925 (void *) optval, &optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001926 break;
1927 case TCP_MAXSEG:
Florin Coras7baeb712019-01-04 17:05:43 -08001928 rv = vls_attr (vlsh, VPPCOM_ATTR_SET_TCP_USER_MSS,
1929 (void *) optval, &optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001930 break;
1931 case TCP_KEEPIDLE:
Florin Coras7baeb712019-01-04 17:05:43 -08001932 rv = vls_attr (vlsh, VPPCOM_ATTR_SET_TCP_KEEPIDLE,
1933 (void *) optval, &optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001934 break;
1935 case TCP_KEEPINTVL:
Florin Coras7baeb712019-01-04 17:05:43 -08001936 rv = vls_attr (vlsh, VPPCOM_ATTR_SET_TCP_KEEPINTVL,
1937 (void *) optval, &optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001938 break;
Florin Coras0ed24e92019-01-21 09:03:10 -08001939 case TCP_CONGESTION:
Florin Coras8509aa22019-04-04 12:55:30 -07001940 case TCP_CORK:
Florin Coras0ed24e92019-01-21 09:03:10 -08001941 /* Ignore */
1942 rv = 0;
1943 break;
Dave Wallace048b1d62018-01-03 22:24:41 -05001944 default:
Florin Coras7baeb712019-01-04 17:05:43 -08001945 LDBG (0, "ERROR: fd %d: setsockopt() SOL_TCP: vlsh %u"
1946 "optname %d unsupported!", fd, vlsh, optname);
Dave Wallace048b1d62018-01-03 22:24:41 -05001947 break;
1948 }
1949 break;
1950 case SOL_IPV6:
1951 switch (optname)
1952 {
1953 case IPV6_V6ONLY:
Florin Coras7baeb712019-01-04 17:05:43 -08001954 rv = vls_attr (vlsh, VPPCOM_ATTR_SET_V6ONLY,
1955 (void *) optval, &optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001956 break;
1957 default:
Florin Coras7baeb712019-01-04 17:05:43 -08001958 LDBG (0, "ERROR: fd %d: setsockopt SOL_IPV6: vlsh %u"
1959 "optname %d unsupported!", fd, vlsh, optname);
Dave Wallace048b1d62018-01-03 22:24:41 -05001960 break;
1961 }
1962 break;
1963 case SOL_SOCKET:
1964 switch (optname)
1965 {
1966 case SO_KEEPALIVE:
Florin Coras7baeb712019-01-04 17:05:43 -08001967 rv = vls_attr (vlsh, VPPCOM_ATTR_SET_KEEPALIVE,
1968 (void *) optval, &optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001969 break;
1970 case SO_REUSEADDR:
Florin Coras7baeb712019-01-04 17:05:43 -08001971 rv = vls_attr (vlsh, VPPCOM_ATTR_SET_REUSEADDR,
1972 (void *) optval, &optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001973 break;
1974 case SO_BROADCAST:
Florin Coras7baeb712019-01-04 17:05:43 -08001975 rv = vls_attr (vlsh, VPPCOM_ATTR_SET_BROADCAST,
1976 (void *) optval, &optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001977 break;
1978 default:
Florin Coras7baeb712019-01-04 17:05:43 -08001979 LDBG (0, "ERROR: fd %d: setsockopt SOL_SOCKET: vlsh %u "
1980 "optname %d unsupported!", fd, vlsh, optname);
Dave Wallace048b1d62018-01-03 22:24:41 -05001981 break;
1982 }
1983 break;
1984 default:
1985 break;
1986 }
1987
1988 if (rv != VPPCOM_OK)
1989 {
1990 errno = -rv;
1991 rv = -1;
1992 }
1993 }
1994 else
1995 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001996 rv = libc_setsockopt (fd, level, optname, optval, optlen);
1997 }
1998
Dave Wallace048b1d62018-01-03 22:24:41 -05001999 return rv;
2000}
2001
2002int
2003listen (int fd, int n)
2004{
Florin Coras7baeb712019-01-04 17:05:43 -08002005 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05002006 int rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05002007
Dave Wallace2a865272018-02-07 21:00:42 -05002008 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002009 return -1;
2010
Florin Coras7baeb712019-01-04 17:05:43 -08002011 vlsh = ldp_fd_to_vlsh (fd);
2012 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -05002013 {
Florin Coras7baeb712019-01-04 17:05:43 -08002014 LDBG (0, "fd %d: calling vls_listen: vlsh %u, n %d", fd, vlsh, n);
Dave Wallace048b1d62018-01-03 22:24:41 -05002015
Florin Coras7baeb712019-01-04 17:05:43 -08002016 rv = vls_listen (vlsh, n);
Dave Wallace048b1d62018-01-03 22:24:41 -05002017 if (rv != VPPCOM_OK)
2018 {
2019 errno = -rv;
2020 rv = -1;
2021 }
2022 }
2023 else
2024 {
Florin Coras7baeb712019-01-04 17:05:43 -08002025 LDBG (0, "fd %d: calling libc_listen(): n %d", fd, n);
Dave Wallace048b1d62018-01-03 22:24:41 -05002026 rv = libc_listen (fd, n);
2027 }
2028
Florin Coras7baeb712019-01-04 17:05:43 -08002029 LDBG (1, "fd %d: returning %d", fd, rv);
Dave Wallace048b1d62018-01-03 22:24:41 -05002030 return rv;
2031}
2032
2033static inline int
Dave Wallace2a865272018-02-07 21:00:42 -05002034ldp_accept4 (int listen_fd, __SOCKADDR_ARG addr,
2035 socklen_t * __restrict addr_len, int flags)
Dave Wallace048b1d62018-01-03 22:24:41 -05002036{
Florin Coras7baeb712019-01-04 17:05:43 -08002037 vls_handle_t listen_vlsh, accept_vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05002038 int rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05002039
Dave Wallace2a865272018-02-07 21:00:42 -05002040 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002041 return -1;
2042
Florin Coras7baeb712019-01-04 17:05:43 -08002043 listen_vlsh = ldp_fd_to_vlsh (listen_fd);
2044 if (listen_vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -05002045 {
2046 vppcom_endpt_t ep;
2047 u8 src_addr[sizeof (struct sockaddr_in6)];
Dave Wallace8aaba562018-01-18 17:21:19 -05002048 memset (&ep, 0, sizeof (ep));
Dave Wallace048b1d62018-01-03 22:24:41 -05002049 ep.ip = src_addr;
2050
Florin Coras7baeb712019-01-04 17:05:43 -08002051 LDBG (0, "listen fd %d: calling vppcom_session_accept: listen sid %u,"
2052 " ep %p, flags 0x%x", listen_fd, listen_vlsh, ep, flags);
Dave Wallace048b1d62018-01-03 22:24:41 -05002053
Florin Coras7baeb712019-01-04 17:05:43 -08002054 accept_vlsh = vls_accept (listen_vlsh, &ep, flags);
2055 if (accept_vlsh < 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002056 {
Florin Coras7baeb712019-01-04 17:05:43 -08002057 errno = -accept_vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05002058 rv = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002059 }
2060 else
2061 {
Dave Wallace2a865272018-02-07 21:00:42 -05002062 rv = ldp_copy_ep_to_sockaddr (addr, addr_len, &ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05002063 if (rv != VPPCOM_OK)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002064 {
Florin Coras7baeb712019-01-04 17:05:43 -08002065 (void) vls_close (accept_vlsh);
Dave Wallace048b1d62018-01-03 22:24:41 -05002066 errno = -rv;
2067 rv = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002068 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002069 else
2070 {
Florin Coras7baeb712019-01-04 17:05:43 -08002071 rv = ldp_vlsh_to_fd (accept_vlsh);
Dave Wallace048b1d62018-01-03 22:24:41 -05002072 }
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002073 }
2074 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002075 else
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002076 {
Florin Coras7baeb712019-01-04 17:05:43 -08002077 LDBG (0, "listen fd %d: calling libc_accept4(): addr %p, addr_len %p,"
2078 " flags 0x%x", listen_fd, addr, addr_len, flags);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002079
Dave Wallace048b1d62018-01-03 22:24:41 -05002080 rv = libc_accept4 (listen_fd, addr, addr_len, flags);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002081 }
2082
Florin Coras7baeb712019-01-04 17:05:43 -08002083 LDBG (1, "listen fd %d: accept returning %d", listen_fd, rv);
Florin Coras05ecfcc2018-12-12 18:19:39 -08002084
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002085 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002086}
2087
Dave Wallace048b1d62018-01-03 22:24:41 -05002088int
2089accept4 (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict addr_len,
2090 int flags)
2091{
Dave Wallace2a865272018-02-07 21:00:42 -05002092 return ldp_accept4 (fd, addr, addr_len, flags);
Dave Wallace048b1d62018-01-03 22:24:41 -05002093}
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002094
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002095int
Dave Wallace048b1d62018-01-03 22:24:41 -05002096accept (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict addr_len)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002097{
Dave Wallace2a865272018-02-07 21:00:42 -05002098 return ldp_accept4 (fd, addr, addr_len, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05002099}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002100
Dave Wallace048b1d62018-01-03 22:24:41 -05002101int
2102shutdown (int fd, int how)
2103{
Florin Coras7baeb712019-01-04 17:05:43 -08002104 vls_handle_t vlsh;
2105 int rv = 0, flags;
2106 u32 flags_len = sizeof (flags);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002107
Dave Wallace2a865272018-02-07 21:00:42 -05002108 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002109 return -1;
2110
Florin Coras7baeb712019-01-04 17:05:43 -08002111 vlsh = ldp_fd_to_vlsh (fd);
2112 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -05002113 {
Florin Coras7baeb712019-01-04 17:05:43 -08002114 LDBG (0, "called shutdown: fd %u vlsh %u how %d", fd, vlsh, how);
Florin Corasa7a1a222018-12-30 17:11:31 -08002115
Florin Coras7baeb712019-01-04 17:05:43 -08002116 if (vls_attr (vlsh, VPPCOM_ATTR_SET_SHUT, &how, &flags_len))
Florin Corasa7a1a222018-12-30 17:11:31 -08002117 {
Florin Coras7baeb712019-01-04 17:05:43 -08002118 close (fd);
Florin Corasa7a1a222018-12-30 17:11:31 -08002119 return -1;
2120 }
2121
Florin Coras7baeb712019-01-04 17:05:43 -08002122 if (vls_attr (vlsh, VPPCOM_ATTR_GET_SHUT, &flags, &flags_len))
2123 {
2124 close (fd);
2125 return -1;
2126 }
Florin Corasa7a1a222018-12-30 17:11:31 -08002127
Florin Coras7baeb712019-01-04 17:05:43 -08002128 if (flags == SHUT_RDWR)
Florin Corasa7a1a222018-12-30 17:11:31 -08002129 rv = close (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002130 }
2131 else
2132 {
Florin Coras7baeb712019-01-04 17:05:43 -08002133 LDBG (0, "fd %d: calling libc_shutdown: how %d", fd, how);
Dave Wallace048b1d62018-01-03 22:24:41 -05002134 rv = libc_shutdown (fd, how);
2135 }
2136
Dave Wallace048b1d62018-01-03 22:24:41 -05002137 return rv;
2138}
2139
2140int
2141epoll_create1 (int flags)
2142{
Florin Corasdfe4cf42018-11-28 22:13:45 -08002143 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
Florin Coras7baeb712019-01-04 17:05:43 -08002144 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05002145 int rv;
2146
Dave Wallace2a865272018-02-07 21:00:42 -05002147 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002148 return -1;
2149
Florin Coras99368312018-08-02 10:45:44 -07002150 if (ldp->vcl_needs_real_epoll)
2151 {
Florin Coras2d9b4272019-03-11 10:14:37 -07002152 /* Make sure workers have been allocated */
2153 if (!ldp->workers)
2154 {
2155 ldp_alloc_workers ();
2156 ldpw = ldp_worker_get_current ();
2157 }
Florin Coras99368312018-08-02 10:45:44 -07002158 rv = libc_epoll_create1 (flags);
2159 ldp->vcl_needs_real_epoll = 0;
Florin Corasdfe4cf42018-11-28 22:13:45 -08002160 ldpw->vcl_mq_epfd = rv;
Florin Coras05ecfcc2018-12-12 18:19:39 -08002161 LDBG (0, "created vcl epfd %u", rv);
Florin Coras99368312018-08-02 10:45:44 -07002162 return rv;
2163 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002164
Florin Coras7baeb712019-01-04 17:05:43 -08002165 vlsh = vls_epoll_create ();
2166 if (PREDICT_FALSE (vlsh == VLS_INVALID_HANDLE))
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002167 {
Florin Coras7baeb712019-01-04 17:05:43 -08002168 errno = -vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05002169 rv = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002170 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002171 else
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002172 {
Florin Coras7baeb712019-01-04 17:05:43 -08002173 rv = ldp_vlsh_to_fd (vlsh);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002174 }
Florin Coras7baeb712019-01-04 17:05:43 -08002175 LDBG (0, "epoll_create epfd %u vlsh %u", rv, vlsh);
Dave Wallace048b1d62018-01-03 22:24:41 -05002176 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002177}
2178
2179int
Dave Wallace048b1d62018-01-03 22:24:41 -05002180epoll_create (int size)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002181{
Dave Wallace048b1d62018-01-03 22:24:41 -05002182 return epoll_create1 (0);
2183}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002184
Dave Wallace048b1d62018-01-03 22:24:41 -05002185int
2186epoll_ctl (int epfd, int op, int fd, struct epoll_event *event)
2187{
Florin Coras7baeb712019-01-04 17:05:43 -08002188 vls_handle_t vep_vlsh, vlsh;
Florin Coras99368312018-08-02 10:45:44 -07002189 int rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05002190
Dave Wallace2a865272018-02-07 21:00:42 -05002191 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002192 return -1;
2193
Florin Coras7baeb712019-01-04 17:05:43 -08002194 vep_vlsh = ldp_fd_to_vlsh (epfd);
2195 if (PREDICT_FALSE (vep_vlsh == VLS_INVALID_HANDLE))
Dave Wallace048b1d62018-01-03 22:24:41 -05002196 {
Dave Wallace3ee1fe12018-02-23 01:09:11 -05002197 /* The LDP epoll_create1 always creates VCL epfd's.
2198 * The app should never have a kernel base epoll fd unless it
2199 * was acquired outside of the LD_PRELOAD process context.
2200 * In any case, if we get one, punt it to libc_epoll_ctl.
2201 */
Florin Coras7baeb712019-01-04 17:05:43 -08002202 LDBG (1, "epfd %d: calling libc_epoll_ctl: op %d, fd %d"
2203 " event %p", epfd, op, fd, event);
Dave Wallace048b1d62018-01-03 22:24:41 -05002204
2205 rv = libc_epoll_ctl (epfd, op, fd, event);
Florin Coras99368312018-08-02 10:45:44 -07002206 goto done;
2207 }
2208
Florin Coras7baeb712019-01-04 17:05:43 -08002209 vlsh = ldp_fd_to_vlsh (fd);
Florin Coras99368312018-08-02 10:45:44 -07002210
Florin Coras7baeb712019-01-04 17:05:43 -08002211 LDBG (0, "epfd %d ep_vlsh %d, fd %u vlsh %d, op %u", epfd, vep_vlsh, fd,
2212 vlsh, op);
Florin Coras99368312018-08-02 10:45:44 -07002213
Florin Coras7baeb712019-01-04 17:05:43 -08002214 if (vlsh != VLS_INVALID_HANDLE)
Florin Coras99368312018-08-02 10:45:44 -07002215 {
Florin Coras7baeb712019-01-04 17:05:43 -08002216 LDBG (1, "epfd %d: calling vls_epoll_ctl: ep_vlsh %d op %d, vlsh %u,"
2217 " event %p", epfd, vep_vlsh, vlsh, event);
Florin Coras99368312018-08-02 10:45:44 -07002218
Florin Coras7baeb712019-01-04 17:05:43 -08002219 rv = vls_epoll_ctl (vep_vlsh, op, vlsh, event);
Florin Coras99368312018-08-02 10:45:44 -07002220 if (rv != VPPCOM_OK)
2221 {
2222 errno = -rv;
2223 rv = -1;
2224 }
2225 }
2226 else
2227 {
2228 int libc_epfd;
2229 u32 size = sizeof (epfd);
2230
Florin Coras7baeb712019-01-04 17:05:43 -08002231 libc_epfd = vls_attr (vep_vlsh, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
Florin Coras99368312018-08-02 10:45:44 -07002232 if (!libc_epfd)
2233 {
Florin Coras7baeb712019-01-04 17:05:43 -08002234 LDBG (1, "epfd %d, vep_vlsh %d calling libc_epoll_create1: "
2235 "EPOLL_CLOEXEC", epfd, vep_vlsh);
Florin Coras99368312018-08-02 10:45:44 -07002236
2237 libc_epfd = libc_epoll_create1 (EPOLL_CLOEXEC);
2238 if (libc_epfd < 0)
2239 {
2240 rv = libc_epfd;
2241 goto done;
2242 }
2243
Florin Coras7baeb712019-01-04 17:05:43 -08002244 rv = vls_attr (vep_vlsh, VPPCOM_ATTR_SET_LIBC_EPFD, &libc_epfd,
2245 &size);
Florin Coras99368312018-08-02 10:45:44 -07002246 if (rv < 0)
2247 {
2248 errno = -rv;
2249 rv = -1;
2250 goto done;
2251 }
2252 }
2253 else if (PREDICT_FALSE (libc_epfd < 0))
2254 {
2255 errno = -epfd;
2256 rv = -1;
2257 goto done;
2258 }
2259
Florin Coras7baeb712019-01-04 17:05:43 -08002260 LDBG (1, "epfd %d: calling libc_epoll_ctl: libc_epfd %d, op %d, fd %d,"
2261 " event %p", epfd, libc_epfd, op, fd, event);
Florin Coras99368312018-08-02 10:45:44 -07002262
2263 rv = libc_epoll_ctl (libc_epfd, op, fd, event);
Dave Wallace048b1d62018-01-03 22:24:41 -05002264 }
2265
2266done:
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002267 return rv;
2268}
Dave Wallace048b1d62018-01-03 22:24:41 -05002269
2270static inline int
Florin Coras99368312018-08-02 10:45:44 -07002271ldp_epoll_pwait (int epfd, struct epoll_event *events, int maxevents,
2272 int timeout, const sigset_t * sigmask)
Dave Wallace048b1d62018-01-03 22:24:41 -05002273{
Florin Corasdfe4cf42018-11-28 22:13:45 -08002274 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
Florin Coras72f77822019-01-22 19:05:52 -08002275 double time_to_wait = (double) 0, max_time;
Florin Coras99368312018-08-02 10:45:44 -07002276 int libc_epfd, rv = 0;
Florin Coras7baeb712019-01-04 17:05:43 -08002277 vls_handle_t ep_vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05002278
Dave Wallace2a865272018-02-07 21:00:42 -05002279 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002280 return -1;
2281
2282 if (PREDICT_FALSE (!events || (timeout < -1)))
2283 {
2284 errno = EFAULT;
2285 return -1;
2286 }
2287
Florin Corasdfe4cf42018-11-28 22:13:45 -08002288 if (epfd == ldpw->vcl_mq_epfd)
Florin Coras99368312018-08-02 10:45:44 -07002289 return libc_epoll_pwait (epfd, events, maxevents, timeout, sigmask);
2290
Florin Coras7baeb712019-01-04 17:05:43 -08002291 ep_vlsh = ldp_fd_to_vlsh (epfd);
2292 if (PREDICT_FALSE (ep_vlsh == VLS_INVALID_HANDLE))
Dave Wallace048b1d62018-01-03 22:24:41 -05002293 {
Florin Coras7baeb712019-01-04 17:05:43 -08002294 LDBG (0, "epfd %d: bad ep_vlsh %d!", epfd, ep_vlsh);
Dave Wallace048b1d62018-01-03 22:24:41 -05002295 errno = EBADFD;
2296 return -1;
2297 }
2298
Florin Coras4dee8cd2019-01-29 21:28:16 -08002299 if (PREDICT_FALSE (ldpw->clib_time.init_cpu_time == 0))
2300 clib_time_init (&ldpw->clib_time);
Florin Corasb0f662f2018-12-27 14:51:46 -08002301 time_to_wait = ((timeout >= 0) ? (double) timeout / 1000 : 0);
Florin Coras72f77822019-01-22 19:05:52 -08002302 max_time = clib_time_now (&ldpw->clib_time) + time_to_wait;
Dave Wallace048b1d62018-01-03 22:24:41 -05002303
Florin Coras7baeb712019-01-04 17:05:43 -08002304 libc_epfd = vls_attr (ep_vlsh, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05002305 if (PREDICT_FALSE (libc_epfd < 0))
2306 {
2307 errno = -libc_epfd;
2308 rv = -1;
2309 goto done;
2310 }
2311
Florin Coras7baeb712019-01-04 17:05:43 -08002312 LDBG (2, "epfd %d: vep_idx %d, libc_epfd %d, events %p, maxevents %d, "
2313 "timeout %d, sigmask %p: time_to_wait %.02f", epfd, ep_vlsh,
Florin Coras72f77822019-01-22 19:05:52 -08002314 libc_epfd, events, maxevents, timeout, sigmask, time_to_wait);
Dave Wallace048b1d62018-01-03 22:24:41 -05002315 do
2316 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08002317 if (!ldpw->epoll_wait_vcl)
Dave Wallace048b1d62018-01-03 22:24:41 -05002318 {
Florin Coras7baeb712019-01-04 17:05:43 -08002319 rv = vls_epoll_wait (ep_vlsh, events, maxevents, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05002320 if (rv > 0)
2321 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08002322 ldpw->epoll_wait_vcl = 1;
Dave Wallace048b1d62018-01-03 22:24:41 -05002323 goto done;
2324 }
2325 else if (rv < 0)
2326 {
2327 errno = -rv;
2328 rv = -1;
2329 goto done;
2330 }
2331 }
2332 else
Florin Corasdfe4cf42018-11-28 22:13:45 -08002333 ldpw->epoll_wait_vcl = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05002334
2335 if (libc_epfd > 0)
2336 {
Florin Corasb0f662f2018-12-27 14:51:46 -08002337 rv = libc_epoll_pwait (libc_epfd, events, maxevents, 0, sigmask);
Dave Wallace048b1d62018-01-03 22:24:41 -05002338 if (rv != 0)
2339 goto done;
2340 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002341 }
Florin Coras72f77822019-01-22 19:05:52 -08002342 while ((timeout == -1) || (clib_time_now (&ldpw->clib_time) < max_time));
Dave Wallace048b1d62018-01-03 22:24:41 -05002343
2344done:
Dave Wallace048b1d62018-01-03 22:24:41 -05002345 return rv;
2346}
2347
hanlin4266d4d2020-05-19 17:34:17 +08002348static inline int
2349ldp_epoll_pwait_eventfd (int epfd, struct epoll_event *events,
2350 int maxevents, int timeout, const sigset_t * sigmask)
2351{
2352 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
2353 int libc_epfd, rv = 0, num_ev;
2354 vls_handle_t ep_vlsh;
2355
2356 if ((errno = -ldp_init ()))
2357 return -1;
2358
2359 if (PREDICT_FALSE (!events || (timeout < -1)))
2360 {
2361 errno = EFAULT;
2362 return -1;
2363 }
2364
2365 if (epfd == ldpw->vcl_mq_epfd)
2366 return libc_epoll_pwait (epfd, events, maxevents, timeout, sigmask);
2367
2368 ep_vlsh = ldp_fd_to_vlsh (epfd);
2369 if (PREDICT_FALSE (ep_vlsh == VLS_INVALID_HANDLE))
2370 {
2371 LDBG (0, "epfd %d: bad ep_vlsh %d!", epfd, ep_vlsh);
2372 errno = EBADFD;
2373 return -1;
2374 }
2375
2376 libc_epfd = vls_attr (ep_vlsh, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
2377 if (PREDICT_FALSE (!libc_epfd))
2378 {
2379 u32 size = sizeof (epfd);
2380
2381 LDBG (1, "epfd %d, vep_vlsh %d calling libc_epoll_create1: "
2382 "EPOLL_CLOEXEC", epfd, ep_vlsh);
2383 libc_epfd = libc_epoll_create1 (EPOLL_CLOEXEC);
2384 if (libc_epfd < 0)
2385 {
2386 rv = libc_epfd;
2387 goto done;
2388 }
2389
2390 rv = vls_attr (ep_vlsh, VPPCOM_ATTR_SET_LIBC_EPFD, &libc_epfd, &size);
2391 if (rv < 0)
2392 {
2393 errno = -rv;
2394 rv = -1;
2395 goto done;
2396 }
2397 }
2398 if (PREDICT_FALSE (libc_epfd <= 0))
2399 {
2400 errno = -libc_epfd;
2401 rv = -1;
2402 goto done;
2403 }
2404
2405 if (PREDICT_FALSE (!ldpw->mq_epfd_added))
2406 {
2407 struct epoll_event e = { 0 };
2408 e.events = EPOLLIN;
2409 e.data.fd = ldpw->vcl_mq_epfd;
2410 if (libc_epoll_ctl (libc_epfd, EPOLL_CTL_ADD, ldpw->vcl_mq_epfd, &e) <
2411 0)
2412 {
2413 LDBG (0, "epfd %d, add libc mq epoll fd %d to libc epoll fd %d",
2414 epfd, ldpw->vcl_mq_epfd, libc_epfd);
2415 rv = -1;
2416 goto done;
2417 }
2418 ldpw->mq_epfd_added = 1;
2419 }
2420
2421 rv = vls_epoll_wait (ep_vlsh, events, maxevents, 0);
2422 if (rv > 0)
2423 goto done;
2424 else if (rv < 0)
2425 {
2426 errno = -rv;
2427 rv = -1;
2428 goto done;
2429 }
2430
2431 rv = libc_epoll_pwait (libc_epfd, events, maxevents, timeout, sigmask);
2432 if (rv <= 0)
2433 goto done;
2434 for (int i = 0; i < rv; i++)
2435 {
2436 if (events[i].data.fd == ldpw->vcl_mq_epfd)
2437 {
2438 /* We should remove mq epoll fd from events. */
2439 rv--;
2440 if (i != rv)
2441 {
2442 events[i].events = events[rv].events;
2443 events[i].data.u64 = events[rv].data.u64;
2444 }
2445 num_ev = vls_epoll_wait (ep_vlsh, &events[rv], maxevents - rv, 0);
2446 if (PREDICT_TRUE (num_ev > 0))
2447 rv += num_ev;
2448 break;
2449 }
2450 }
2451
2452done:
2453 return rv;
2454}
2455
Dave Wallace048b1d62018-01-03 22:24:41 -05002456int
2457epoll_pwait (int epfd, struct epoll_event *events,
2458 int maxevents, int timeout, const sigset_t * sigmask)
2459{
hanlin4266d4d2020-05-19 17:34:17 +08002460 if (vls_use_eventfd ())
2461 return ldp_epoll_pwait_eventfd (epfd, events, maxevents, timeout,
2462 sigmask);
2463 else
2464 return ldp_epoll_pwait (epfd, events, maxevents, timeout, sigmask);
Dave Wallace048b1d62018-01-03 22:24:41 -05002465}
2466
2467int
2468epoll_wait (int epfd, struct epoll_event *events, int maxevents, int timeout)
2469{
hanlin4266d4d2020-05-19 17:34:17 +08002470 if (vls_use_eventfd ())
2471 return ldp_epoll_pwait_eventfd (epfd, events, maxevents, timeout, NULL);
2472 else
2473 return ldp_epoll_pwait (epfd, events, maxevents, timeout, NULL);
Dave Wallace048b1d62018-01-03 22:24:41 -05002474}
2475
2476int
2477poll (struct pollfd *fds, nfds_t nfds, int timeout)
2478{
Florin Corasdfe4cf42018-11-28 22:13:45 -08002479 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
Florin Coras6917b942018-11-13 22:44:54 -08002480 int rv, i, n_revents = 0;
Florin Coras7baeb712019-01-04 17:05:43 -08002481 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05002482 vcl_poll_t *vp;
Florin Coras4dee8cd2019-01-29 21:28:16 -08002483 double max_time;
Dave Wallace048b1d62018-01-03 22:24:41 -05002484
Florin Coras05ecfcc2018-12-12 18:19:39 -08002485 LDBG (3, "fds %p, nfds %d, timeout %d", fds, nfds, timeout);
Dave Wallace048b1d62018-01-03 22:24:41 -05002486
Florin Coras4dee8cd2019-01-29 21:28:16 -08002487 if (PREDICT_FALSE (ldpw->clib_time.init_cpu_time == 0))
2488 clib_time_init (&ldpw->clib_time);
2489
2490 max_time = (timeout >= 0) ? (f64) timeout / 1000 : 0;
2491 max_time += clib_time_now (&ldpw->clib_time);
Dave Wallace048b1d62018-01-03 22:24:41 -05002492
Dave Wallace048b1d62018-01-03 22:24:41 -05002493 for (i = 0; i < nfds; i++)
2494 {
Florin Coras6917b942018-11-13 22:44:54 -08002495 if (fds[i].fd < 0)
2496 continue;
Dave Wallace048b1d62018-01-03 22:24:41 -05002497
Florin Coras7baeb712019-01-04 17:05:43 -08002498 vlsh = ldp_fd_to_vlsh (fds[i].fd);
2499 if (vlsh != VLS_INVALID_HANDLE)
Florin Coras6917b942018-11-13 22:44:54 -08002500 {
2501 fds[i].fd = -fds[i].fd;
Florin Corasdfe4cf42018-11-28 22:13:45 -08002502 vec_add2 (ldpw->vcl_poll, vp, 1);
Florin Coras6917b942018-11-13 22:44:54 -08002503 vp->fds_ndx = i;
Florin Coras7baeb712019-01-04 17:05:43 -08002504 vp->sh = vlsh_to_sh (vlsh);
Florin Coras6917b942018-11-13 22:44:54 -08002505 vp->events = fds[i].events;
Dave Wallace048b1d62018-01-03 22:24:41 -05002506#ifdef __USE_XOPEN2K
Florin Coras6917b942018-11-13 22:44:54 -08002507 if (fds[i].events & POLLRDNORM)
2508 vp->events |= POLLIN;
2509 if (fds[i].events & POLLWRNORM)
2510 vp->events |= POLLOUT;
Dave Wallace048b1d62018-01-03 22:24:41 -05002511#endif
Florin Coras6917b942018-11-13 22:44:54 -08002512 vp->revents = fds[i].revents;
2513 }
2514 else
2515 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08002516 vec_add1 (ldpw->libc_poll, fds[i]);
2517 vec_add1 (ldpw->libc_poll_idxs, i);
Dave Wallace048b1d62018-01-03 22:24:41 -05002518 }
2519 }
2520
Dave Wallace048b1d62018-01-03 22:24:41 -05002521 do
2522 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08002523 if (vec_len (ldpw->vcl_poll))
Dave Wallace048b1d62018-01-03 22:24:41 -05002524 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08002525 rv = vppcom_poll (ldpw->vcl_poll, vec_len (ldpw->vcl_poll), 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05002526 if (rv < 0)
2527 {
2528 errno = -rv;
2529 rv = -1;
2530 goto done;
2531 }
2532 else
2533 n_revents += rv;
2534 }
2535
Florin Corasdfe4cf42018-11-28 22:13:45 -08002536 if (vec_len (ldpw->libc_poll))
Dave Wallace048b1d62018-01-03 22:24:41 -05002537 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08002538 rv = libc_poll (ldpw->libc_poll, vec_len (ldpw->libc_poll), 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05002539 if (rv < 0)
2540 goto done;
2541 else
2542 n_revents += rv;
2543 }
2544
2545 if (n_revents)
2546 {
2547 rv = n_revents;
2548 goto done;
2549 }
2550 }
Florin Coras4dee8cd2019-01-29 21:28:16 -08002551 while ((timeout < 0) || (clib_time_now (&ldpw->clib_time) < max_time));
Dave Wallace048b1d62018-01-03 22:24:41 -05002552 rv = 0;
2553
2554done:
Florin Corasdfe4cf42018-11-28 22:13:45 -08002555 vec_foreach (vp, ldpw->vcl_poll)
Dave Wallace048b1d62018-01-03 22:24:41 -05002556 {
2557 fds[vp->fds_ndx].fd = -fds[vp->fds_ndx].fd;
Florin Coras6917b942018-11-13 22:44:54 -08002558 fds[vp->fds_ndx].revents = vp->revents;
Dave Wallace048b1d62018-01-03 22:24:41 -05002559#ifdef __USE_XOPEN2K
2560 if ((fds[vp->fds_ndx].revents & POLLIN) &&
2561 (fds[vp->fds_ndx].events & POLLRDNORM))
2562 fds[vp->fds_ndx].revents |= POLLRDNORM;
2563 if ((fds[vp->fds_ndx].revents & POLLOUT) &&
2564 (fds[vp->fds_ndx].events & POLLWRNORM))
2565 fds[vp->fds_ndx].revents |= POLLWRNORM;
2566#endif
2567 }
Florin Corasdfe4cf42018-11-28 22:13:45 -08002568 vec_reset_length (ldpw->vcl_poll);
Dave Wallace048b1d62018-01-03 22:24:41 -05002569
Florin Corasdfe4cf42018-11-28 22:13:45 -08002570 for (i = 0; i < vec_len (ldpw->libc_poll); i++)
Florin Coras6917b942018-11-13 22:44:54 -08002571 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08002572 fds[ldpw->libc_poll_idxs[i]].revents = ldpw->libc_poll[i].revents;
Florin Coras6917b942018-11-13 22:44:54 -08002573 }
Florin Corasdfe4cf42018-11-28 22:13:45 -08002574 vec_reset_length (ldpw->libc_poll_idxs);
2575 vec_reset_length (ldpw->libc_poll);
Florin Coras6917b942018-11-13 22:44:54 -08002576
Dave Wallace048b1d62018-01-03 22:24:41 -05002577 return rv;
2578}
2579
2580#ifdef USE_GNU
2581int
2582ppoll (struct pollfd *fds, nfds_t nfds,
2583 const struct timespec *timeout, const sigset_t * sigmask)
2584{
Dave Wallace2a865272018-02-07 21:00:42 -05002585 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002586 return -1;
2587
2588 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
2589 errno = ENOSYS;
2590
2591
2592 return -1;
2593}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002594#endif
2595
Dave Wallace2a865272018-02-07 21:00:42 -05002596void CONSTRUCTOR_ATTRIBUTE ldp_constructor (void);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002597
Dave Wallace2a865272018-02-07 21:00:42 -05002598void DESTRUCTOR_ATTRIBUTE ldp_destructor (void);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002599
Dave Wallace048b1d62018-01-03 22:24:41 -05002600/*
2601 * This function is called when the library is loaded
2602 */
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002603void
Dave Wallace2a865272018-02-07 21:00:42 -05002604ldp_constructor (void)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002605{
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002606 swrap_constructor ();
Dave Wallace2a865272018-02-07 21:00:42 -05002607 if (ldp_init () != 0)
Florin Corasd89411e2019-03-19 19:44:51 -07002608 {
2609 fprintf (stderr, "\nLDP<%d>: ERROR: ldp_constructor: failed!\n",
2610 getpid ());
2611 _exit (1);
2612 }
Dave Wallace69d01192018-02-22 16:22:09 -05002613 else if (LDP_DEBUG > 0)
Dave Wallace2a865272018-02-07 21:00:42 -05002614 clib_warning ("LDP<%d>: LDP constructor: done!\n", getpid ());
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002615}
2616
2617/*
2618 * This function is called when the library is unloaded
2619 */
2620void
Dave Wallace2a865272018-02-07 21:00:42 -05002621ldp_destructor (void)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002622{
Florin Coras0ef8ef22019-01-18 08:37:13 -08002623 /*
2624 swrap_destructor ();
2625 if (ldp->init)
2626 ldp->init = 0;
2627 */
Dave Wallace048b1d62018-01-03 22:24:41 -05002628
2629 /* Don't use clib_warning() here because that calls writev()
Dave Wallace2a865272018-02-07 21:00:42 -05002630 * which will call ldp_init().
Dave Wallace048b1d62018-01-03 22:24:41 -05002631 */
Dave Wallace69d01192018-02-22 16:22:09 -05002632 if (LDP_DEBUG > 0)
Florin Coras0ef8ef22019-01-18 08:37:13 -08002633 fprintf (stderr, "%s:%d: LDP<%d>: LDP destructor: done!\n",
2634 __func__, __LINE__, getpid ());
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002635}
2636
2637
2638/*
2639 * fd.io coding-style-patch-verification: ON
2640 *
2641 * Local Variables:
2642 * eval: (c-set-style "gnu")
2643 * End:
2644 */