blob: 091c7e5cff420bdbdc34fdd5da01d7d2833e4fae [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;
Florin Coras99368312018-08-02 10:45:44 -070083 int vcl_mq_epfd;
Florin Corasdfe4cf42018-11-28 22:13:45 -080084
85} ldp_worker_ctx_t;
86
Florin Coras294afe22019-01-07 17:49:17 -080087/* clib_bitmap_t, fd_mask and vcl_si_set are used interchangeably. Make sure
88 * they are the same size */
89STATIC_ASSERT (sizeof (clib_bitmap_t) == sizeof (fd_mask),
90 "ldp bitmap size mismatch");
91STATIC_ASSERT (sizeof (vcl_si_set) == sizeof (fd_mask),
92 "ldp bitmap size mismatch");
93
Florin Corasdfe4cf42018-11-28 22:13:45 -080094typedef struct
95{
96 ldp_worker_ctx_t *workers;
97 int init;
98 char app_name[LDP_APP_NAME_MAX];
Florin Coras7baeb712019-01-04 17:05:43 -080099 u32 vlsh_bit_val;
100 u32 vlsh_bit_mask;
Florin Corasdfe4cf42018-11-28 22:13:45 -0800101 u32 debug;
Yu Ping7b74b072019-05-08 00:40:24 +0800102 u8 transparent_tls;
Florin Corasdfe4cf42018-11-28 22:13:45 -0800103
104 /** vcl needs next epoll_create to go to libc_epoll */
105 u8 vcl_needs_real_epoll;
Dave Wallace2a865272018-02-07 21:00:42 -0500106} ldp_main_t;
Florin Corasdfe4cf42018-11-28 22:13:45 -0800107
Dave Wallace2a865272018-02-07 21:00:42 -0500108#define LDP_DEBUG ldp->debug
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700109
Florin Coras99368312018-08-02 10:45:44 -0700110#define LDBG(_lvl, _fmt, _args...) \
111 if (ldp->debug > _lvl) \
hanlin9f3f18f2019-12-30 16:25:20 +0800112 { \
113 int errno_saved = errno; \
114 clib_warning ("ldp<%d>: " _fmt, getpid(), ##_args); \
115 errno = errno_saved; \
116 }
Florin Coras99368312018-08-02 10:45:44 -0700117
Dave Wallace2a865272018-02-07 21:00:42 -0500118static ldp_main_t ldp_main = {
Florin Coras7baeb712019-01-04 17:05:43 -0800119 .vlsh_bit_val = (1 << LDP_SID_BIT_MIN),
120 .vlsh_bit_mask = (1 << LDP_SID_BIT_MIN) - 1,
Dave Wallace2a865272018-02-07 21:00:42 -0500121 .debug = LDP_DEBUG_INIT,
Yu Ping7b74b072019-05-08 00:40:24 +0800122 .transparent_tls = 0,
Dave Wallace048b1d62018-01-03 22:24:41 -0500123};
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700124
Dave Wallace2a865272018-02-07 21:00:42 -0500125static ldp_main_t *ldp = &ldp_main;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700126
Florin Corasdfe4cf42018-11-28 22:13:45 -0800127static inline ldp_worker_ctx_t *
128ldp_worker_get_current (void)
129{
130 return (ldp->workers + vppcom_worker_index ());
131}
132
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700133/*
134 * RETURN: 0 on success or -1 on error.
135 * */
Dave Wallace048b1d62018-01-03 22:24:41 -0500136static inline void
Dave Wallace2a865272018-02-07 21:00:42 -0500137ldp_set_app_name (char *app_name)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700138{
Benoît Ganne747b3d82019-08-21 18:27:23 +0200139 snprintf (ldp->app_name, LDP_APP_NAME_MAX,
140 "ldp-%d-%s", getpid (), app_name);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700141}
142
Dave Wallace048b1d62018-01-03 22:24:41 -0500143static inline char *
Dave Wallace2a865272018-02-07 21:00:42 -0500144ldp_get_app_name ()
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700145{
Dave Wallace2a865272018-02-07 21:00:42 -0500146 if (ldp->app_name[0] == '\0')
147 ldp_set_app_name ("app");
Dave Wallace048b1d62018-01-03 22:24:41 -0500148
Dave Wallace2a865272018-02-07 21:00:42 -0500149 return ldp->app_name;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700150}
151
Dave Wallace048b1d62018-01-03 22:24:41 -0500152static inline int
Florin Coras7baeb712019-01-04 17:05:43 -0800153ldp_vlsh_to_fd (vls_handle_t vlsh)
Dave Wallace048b1d62018-01-03 22:24:41 -0500154{
Florin Coras7baeb712019-01-04 17:05:43 -0800155 return (vlsh + ldp->vlsh_bit_val);
Dave Wallace048b1d62018-01-03 22:24:41 -0500156}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700157
Florin Coras7baeb712019-01-04 17:05:43 -0800158static inline vls_handle_t
159ldp_fd_to_vlsh (int fd)
Dave Wallace048b1d62018-01-03 22:24:41 -0500160{
Florin Coras7baeb712019-01-04 17:05:43 -0800161 if (fd < ldp->vlsh_bit_val)
162 return VLS_INVALID_HANDLE;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700163
Florin Coras7baeb712019-01-04 17:05:43 -0800164 return (fd - ldp->vlsh_bit_val);
Dave Wallace048b1d62018-01-03 22:24:41 -0500165}
166
Florin Coras2d9b4272019-03-11 10:14:37 -0700167static void
168ldp_alloc_workers (void)
169{
170 if (ldp->workers)
171 return;
172 pool_alloc (ldp->workers, LDP_MAX_NWORKERS);
173}
174
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700175static inline int
Dave Wallace2a865272018-02-07 21:00:42 -0500176ldp_init (void)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700177{
Florin Corasdfe4cf42018-11-28 22:13:45 -0800178 ldp_worker_ctx_t *ldpw;
Florin Coras99368312018-08-02 10:45:44 -0700179 int rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700180
Florin Coras99368312018-08-02 10:45:44 -0700181 if (PREDICT_TRUE (ldp->init))
182 return 0;
183
184 ldp->init = 1;
185 ldp->vcl_needs_real_epoll = 1;
Florin Coras7baeb712019-01-04 17:05:43 -0800186 rv = vls_app_create (ldp_get_app_name ());
Florin Coras99368312018-08-02 10:45:44 -0700187 if (rv != VPPCOM_OK)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700188 {
Florin Coras955bfbb2018-12-04 13:43:45 -0800189 ldp->vcl_needs_real_epoll = 0;
190 if (rv == VPPCOM_EEXIST)
191 return 0;
Florin Coras05ecfcc2018-12-12 18:19:39 -0800192 LDBG (2, "\nERROR: ldp_init: vppcom_app_create()"
193 " failed! rv = %d (%s)\n", rv, vppcom_retval_str (rv));
Florin Coras99368312018-08-02 10:45:44 -0700194 ldp->init = 0;
195 return rv;
196 }
197 ldp->vcl_needs_real_epoll = 0;
Florin Coras2d9b4272019-03-11 10:14:37 -0700198 ldp_alloc_workers ();
Florin Corasdfe4cf42018-11-28 22:13:45 -0800199 ldpw = ldp_worker_get_current ();
Florin Coras99368312018-08-02 10:45:44 -0700200
201 char *env_var_str = getenv (LDP_ENV_DEBUG);
202 if (env_var_str)
203 {
204 u32 tmp;
205 if (sscanf (env_var_str, "%u", &tmp) != 1)
206 clib_warning ("LDP<%d>: WARNING: Invalid LDP debug level specified in"
207 " the env var " LDP_ENV_DEBUG " (%s)!", getpid (),
208 env_var_str);
209 else
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700210 {
Florin Coras99368312018-08-02 10:45:44 -0700211 ldp->debug = tmp;
Florin Coras05ecfcc2018-12-12 18:19:39 -0800212 LDBG (0, "configured LDP debug level (%u) from env var "
213 LDP_ENV_DEBUG "!", ldp->debug);
Florin Coras99368312018-08-02 10:45:44 -0700214 }
215 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500216
Florin Coras99368312018-08-02 10:45:44 -0700217 env_var_str = getenv (LDP_ENV_APP_NAME);
218 if (env_var_str)
219 {
220 ldp_set_app_name (env_var_str);
Florin Coras05ecfcc2018-12-12 18:19:39 -0800221 LDBG (0, "configured LDP app name (%s) from the env var "
222 LDP_ENV_APP_NAME "!", ldp->app_name);
Florin Coras99368312018-08-02 10:45:44 -0700223 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500224
Florin Coras99368312018-08-02 10:45:44 -0700225 env_var_str = getenv (LDP_ENV_SID_BIT);
226 if (env_var_str)
227 {
228 u32 sb;
229 if (sscanf (env_var_str, "%u", &sb) != 1)
230 {
Florin Coras294afe22019-01-07 17:49:17 -0800231 LDBG (0, "WARNING: Invalid LDP sid bit specified in the env var "
232 LDP_ENV_SID_BIT " (%s)! sid bit value %d (0x%x)", env_var_str,
233 ldp->vlsh_bit_val, ldp->vlsh_bit_val);
Florin Coras99368312018-08-02 10:45:44 -0700234 }
235 else if (sb < LDP_SID_BIT_MIN)
236 {
Florin Coras7baeb712019-01-04 17:05:43 -0800237 ldp->vlsh_bit_val = (1 << LDP_SID_BIT_MIN);
238 ldp->vlsh_bit_mask = ldp->vlsh_bit_val - 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500239
Florin Coras294afe22019-01-07 17:49:17 -0800240 LDBG (0, "WARNING: LDP sid bit (%u) specified in the env var "
241 LDP_ENV_SID_BIT " (%s) is too small. Using LDP_SID_BIT_MIN"
242 " (%d)! sid bit value %d (0x%x)", sb, env_var_str,
243 LDP_SID_BIT_MIN, ldp->vlsh_bit_val, ldp->vlsh_bit_val);
Florin Coras99368312018-08-02 10:45:44 -0700244 }
245 else if (sb > LDP_SID_BIT_MAX)
246 {
Florin Coras7baeb712019-01-04 17:05:43 -0800247 ldp->vlsh_bit_val = (1 << LDP_SID_BIT_MAX);
248 ldp->vlsh_bit_mask = ldp->vlsh_bit_val - 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500249
Florin Coras294afe22019-01-07 17:49:17 -0800250 LDBG (0, "WARNING: LDP sid bit (%u) specified in the env var "
251 LDP_ENV_SID_BIT " (%s) is too big. Using LDP_SID_BIT_MAX"
252 " (%d)! sid bit value %d (0x%x)", sb, env_var_str,
253 LDP_SID_BIT_MAX, ldp->vlsh_bit_val, ldp->vlsh_bit_val);
Dave Wallace048b1d62018-01-03 22:24:41 -0500254 }
255 else
256 {
Florin Coras7baeb712019-01-04 17:05:43 -0800257 ldp->vlsh_bit_val = (1 << sb);
258 ldp->vlsh_bit_mask = ldp->vlsh_bit_val - 1;
Florin Coras99368312018-08-02 10:45:44 -0700259
Florin Coras05ecfcc2018-12-12 18:19:39 -0800260 LDBG (0, "configured LDP sid bit (%u) from "
261 LDP_ENV_SID_BIT "! sid bit value %d (0x%x)", sb,
Florin Coras7baeb712019-01-04 17:05:43 -0800262 ldp->vlsh_bit_val, ldp->vlsh_bit_val);
Dave Wallace048b1d62018-01-03 22:24:41 -0500263 }
Florin Coras294afe22019-01-07 17:49:17 -0800264
265 /* Make sure there are enough bits in the fd set for vcl sessions */
266 if (ldp->vlsh_bit_val > FD_SETSIZE / 2)
267 {
268 LDBG (0, "ERROR: LDP vlsh bit value %d > FD_SETSIZE/2 %d!",
269 ldp->vlsh_bit_val, FD_SETSIZE / 2);
270 ldp->init = 0;
271 return -1;
272 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500273 }
Yu Ping7b74b072019-05-08 00:40:24 +0800274 env_var_str = getenv (LDP_ENV_TLS_TRANS);
275 if (env_var_str)
276 {
277 ldp->transparent_tls = 1;
278 }
Florin Coras99368312018-08-02 10:45:44 -0700279
Florin Coras4dee8cd2019-01-29 21:28:16 -0800280 /* *INDENT-OFF* */
281 pool_foreach (ldpw, ldp->workers, ({
282 clib_memset (&ldpw->clib_time, 0, sizeof (ldpw->clib_time));
283 }));
284 /* *INDENT-ON* */
285
Florin Coras05ecfcc2018-12-12 18:19:39 -0800286 LDBG (0, "LDP initialization: done!");
Florin Coras99368312018-08-02 10:45:44 -0700287
288 return 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500289}
290
291int
292close (int fd)
293{
Florin Coras7baeb712019-01-04 17:05:43 -0800294 vls_handle_t vlsh;
295 int rv, epfd;
Dave Wallace048b1d62018-01-03 22:24:41 -0500296
Dave Wallace2a865272018-02-07 21:00:42 -0500297 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500298 return -1;
299
Florin Coras7baeb712019-01-04 17:05:43 -0800300 vlsh = ldp_fd_to_vlsh (fd);
301 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -0500302 {
Florin Coras7baeb712019-01-04 17:05:43 -0800303 epfd = vls_attr (vlsh, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -0500304 if (epfd > 0)
305 {
Florin Coras7baeb712019-01-04 17:05:43 -0800306 LDBG (0, "fd %d: calling libc_close: epfd %u", fd, epfd);
Dave Wallace048b1d62018-01-03 22:24:41 -0500307
308 rv = libc_close (epfd);
309 if (rv < 0)
310 {
311 u32 size = sizeof (epfd);
312 epfd = 0;
313
Florin Coras7baeb712019-01-04 17:05:43 -0800314 (void) vls_attr (vlsh, VPPCOM_ATTR_SET_LIBC_EPFD, &epfd, &size);
Dave Wallace048b1d62018-01-03 22:24:41 -0500315 }
316 }
317 else if (PREDICT_FALSE (epfd < 0))
318 {
319 errno = -epfd;
320 rv = -1;
321 goto done;
322 }
323
Florin Coras7baeb712019-01-04 17:05:43 -0800324 LDBG (0, "fd %d: calling vls_close: vlsh %u", fd, vlsh);
Dave Wallace048b1d62018-01-03 22:24:41 -0500325
Florin Coras7baeb712019-01-04 17:05:43 -0800326 rv = vls_close (vlsh);
Dave Wallace048b1d62018-01-03 22:24:41 -0500327 if (rv != VPPCOM_OK)
328 {
329 errno = -rv;
330 rv = -1;
331 }
332 }
333 else
334 {
Florin Coras7baeb712019-01-04 17:05:43 -0800335 LDBG (0, "fd %d: calling libc_close", fd);
Dave Wallace048b1d62018-01-03 22:24:41 -0500336 rv = libc_close (fd);
337 }
338
339done:
Dave Wallace048b1d62018-01-03 22:24:41 -0500340 return rv;
341}
342
343ssize_t
344read (int fd, void *buf, size_t nbytes)
345{
Florin Coras7baeb712019-01-04 17:05:43 -0800346 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -0500347 ssize_t size;
Dave Wallace048b1d62018-01-03 22:24:41 -0500348
Dave Wallace2a865272018-02-07 21:00:42 -0500349 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500350 return -1;
351
Florin Coras7baeb712019-01-04 17:05:43 -0800352 vlsh = ldp_fd_to_vlsh (fd);
353 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -0500354 {
Florin Coras7baeb712019-01-04 17:05:43 -0800355 size = vls_read (vlsh, buf, nbytes);
Dave Wallace048b1d62018-01-03 22:24:41 -0500356 if (size < 0)
357 {
358 errno = -size;
359 size = -1;
360 }
361 }
362 else
363 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500364 size = libc_read (fd, buf, nbytes);
365 }
366
Dave Wallace048b1d62018-01-03 22:24:41 -0500367 return size;
368}
369
370ssize_t
371readv (int fd, const struct iovec * iov, int iovcnt)
372{
Dave Wallace8aaba562018-01-18 17:21:19 -0500373 int rv = 0, i, total = 0;
Florin Coras7baeb712019-01-04 17:05:43 -0800374 vls_handle_t vlsh;
375 ssize_t size = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500376
Dave Wallace2a865272018-02-07 21:00:42 -0500377 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500378 return -1;
379
Florin Coras7baeb712019-01-04 17:05:43 -0800380 vlsh = ldp_fd_to_vlsh (fd);
381 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -0500382 {
Florin Coras067f9542020-02-14 05:33:46 +0000383 for (i = 0; i < iovcnt; ++i)
Dave Wallace048b1d62018-01-03 22:24:41 -0500384 {
Florin Coras067f9542020-02-14 05:33:46 +0000385 rv = vls_read (vlsh, iov[i].iov_base, iov[i].iov_len);
386 if (rv <= 0)
387 break;
388 else
Dave Wallace048b1d62018-01-03 22:24:41 -0500389 {
Florin Coras067f9542020-02-14 05:33:46 +0000390 total += rv;
391 if (rv < iov[i].iov_len)
Dave Wallace048b1d62018-01-03 22:24:41 -0500392 break;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700393 }
394 }
Florin Coras067f9542020-02-14 05:33:46 +0000395 if (rv < 0 && total == 0)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700396 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500397 errno = -rv;
398 size = -1;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700399 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500400 else
401 size = total;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700402 }
403 else
404 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500405 size = libc_readv (fd, iov, iovcnt);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700406 }
407
Dave Wallace048b1d62018-01-03 22:24:41 -0500408 return size;
409}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700410
Dave Wallace048b1d62018-01-03 22:24:41 -0500411ssize_t
412write (int fd, const void *buf, size_t nbytes)
413{
Florin Coras7baeb712019-01-04 17:05:43 -0800414 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -0500415 ssize_t size = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500416
Dave Wallace2a865272018-02-07 21:00:42 -0500417 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500418 return -1;
419
Florin Coras7baeb712019-01-04 17:05:43 -0800420 vlsh = ldp_fd_to_vlsh (fd);
421 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -0500422 {
Florin Coras7baeb712019-01-04 17:05:43 -0800423 size = vls_write_msg (vlsh, (void *) buf, nbytes);
Dave Wallace048b1d62018-01-03 22:24:41 -0500424 if (size < 0)
425 {
426 errno = -size;
427 size = -1;
428 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700429 }
430 else
431 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500432 size = libc_write (fd, buf, nbytes);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700433 }
434
Dave Wallace048b1d62018-01-03 22:24:41 -0500435 return size;
436}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700437
Dave Wallace048b1d62018-01-03 22:24:41 -0500438ssize_t
439writev (int fd, const struct iovec * iov, int iovcnt)
440{
Dave Wallace048b1d62018-01-03 22:24:41 -0500441 ssize_t size = 0, total = 0;
Florin Coras7baeb712019-01-04 17:05:43 -0800442 vls_handle_t vlsh;
Dave Wallace8aaba562018-01-18 17:21:19 -0500443 int i, rv = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500444
Dave Wallace2a865272018-02-07 21:00:42 -0500445 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500446 return -1;
447
Florin Coras7baeb712019-01-04 17:05:43 -0800448 vlsh = ldp_fd_to_vlsh (fd);
449 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -0500450 {
Florin Coraseda1b8c2020-03-23 16:00:35 +0000451 for (i = 0; i < iovcnt; ++i)
Dave Wallace048b1d62018-01-03 22:24:41 -0500452 {
Florin Coraseda1b8c2020-03-23 16:00:35 +0000453 rv = vls_write_msg (vlsh, iov[i].iov_base, iov[i].iov_len);
454 if (rv < 0)
455 break;
456 else
Dave Wallace048b1d62018-01-03 22:24:41 -0500457 {
Florin Coraseda1b8c2020-03-23 16:00:35 +0000458 total += rv;
459 if (rv < iov[i].iov_len)
Dave Wallace048b1d62018-01-03 22:24:41 -0500460 break;
Dave Wallace048b1d62018-01-03 22:24:41 -0500461 }
462 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500463
Florin Coraseda1b8c2020-03-23 16:00:35 +0000464 if (rv < 0 && total == 0)
Dave Wallace048b1d62018-01-03 22:24:41 -0500465 {
466 errno = -rv;
467 size = -1;
468 }
469 else
470 size = total;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700471 }
472 else
473 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500474 size = libc_writev (fd, iov, iovcnt);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700475 }
476
Dave Wallace048b1d62018-01-03 22:24:41 -0500477 return size;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700478}
479
480int
Dave Wallace048b1d62018-01-03 22:24:41 -0500481fcntl (int fd, int cmd, ...)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700482{
Florin Coras7baeb712019-01-04 17:05:43 -0800483 vls_handle_t vlsh;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700484 int rv = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500485 va_list ap;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700486
Dave Wallace2a865272018-02-07 21:00:42 -0500487 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500488 return -1;
489
490 va_start (ap, cmd);
Florin Coras7baeb712019-01-04 17:05:43 -0800491
492 vlsh = ldp_fd_to_vlsh (fd);
493 LDBG (0, "fd %u vlsh %d, cmd %u", fd, vlsh, cmd);
494 if (vlsh != VLS_INVALID_HANDLE)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700495 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500496 int flags = va_arg (ap, int);
497 u32 size;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700498
Dave Wallace048b1d62018-01-03 22:24:41 -0500499 size = sizeof (flags);
500 rv = -EOPNOTSUPP;
501 switch (cmd)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700502 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500503 case F_SETFL:
Florin Coras7baeb712019-01-04 17:05:43 -0800504 rv = vls_attr (vlsh, VPPCOM_ATTR_SET_FLAGS, &flags, &size);
Dave Wallace048b1d62018-01-03 22:24:41 -0500505 break;
506
507 case F_GETFL:
Florin Coras7baeb712019-01-04 17:05:43 -0800508 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_FLAGS, &flags, &size);
Dave Wallace048b1d62018-01-03 22:24:41 -0500509 if (rv == VPPCOM_OK)
Florin Coras7baeb712019-01-04 17:05:43 -0800510 rv = flags;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700511 break;
Florin Coras173bae32018-11-16 18:56:28 -0800512 case F_SETFD:
513 /* TODO handle this */
514 LDBG (0, "F_SETFD ignored flags %u", flags);
515 rv = 0;
516 break;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700517 default:
Dave Wallace048b1d62018-01-03 22:24:41 -0500518 rv = -EOPNOTSUPP;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700519 break;
520 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500521 if (rv < 0)
522 {
523 errno = -rv;
524 rv = -1;
525 }
526 }
527 else
528 {
Carl Smithe16707b2019-11-13 14:37:39 +1300529#ifdef HAVE_FCNTL64
530 rv = libc_vfcntl64 (fd, cmd, ap);
531#else
Dave Wallace048b1d62018-01-03 22:24:41 -0500532 rv = libc_vfcntl (fd, cmd, ap);
Carl Smithe16707b2019-11-13 14:37:39 +1300533#endif
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700534 }
535
Dave Wallace048b1d62018-01-03 22:24:41 -0500536 va_end (ap);
537
Dave Wallace048b1d62018-01-03 22:24:41 -0500538 return rv;
539}
540
541int
Florin Corasd7586d52020-04-29 02:19:51 +0000542fcntl64 (int fd, int cmd, ...)
543{
544 va_list ap;
545 int rv;
546
547 va_start (ap, cmd);
548 rv = fcntl (fd, cmd, ap);
549 va_end (ap);
550 return rv;
551}
552
553int
Dave Wallace048b1d62018-01-03 22:24:41 -0500554ioctl (int fd, unsigned long int cmd, ...)
555{
Florin Coras7baeb712019-01-04 17:05:43 -0800556 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -0500557 va_list ap;
Florin Coras7baeb712019-01-04 17:05:43 -0800558 int rv;
Dave Wallace048b1d62018-01-03 22:24:41 -0500559
Dave Wallace2a865272018-02-07 21:00:42 -0500560 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500561 return -1;
562
563 va_start (ap, cmd);
Dave Wallace048b1d62018-01-03 22:24:41 -0500564
Florin Coras7baeb712019-01-04 17:05:43 -0800565 vlsh = ldp_fd_to_vlsh (fd);
566 if (vlsh != VLS_INVALID_HANDLE)
567 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500568 switch (cmd)
569 {
570 case FIONREAD:
Florin Coras7baeb712019-01-04 17:05:43 -0800571 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_NREAD, 0, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -0500572 break;
573
574 case FIONBIO:
575 {
576 u32 flags = va_arg (ap, int) ? O_NONBLOCK : 0;
577 u32 size = sizeof (flags);
578
579 /* TBD: When VPPCOM_ATTR_[GS]ET_FLAGS supports flags other than
580 * non-blocking, the flags should be read here and merged
581 * with O_NONBLOCK.
582 */
Florin Coras7baeb712019-01-04 17:05:43 -0800583 rv = vls_attr (vlsh, VPPCOM_ATTR_SET_FLAGS, &flags, &size);
Dave Wallace048b1d62018-01-03 22:24:41 -0500584 }
585 break;
586
587 default:
588 rv = -EOPNOTSUPP;
589 break;
590 }
591 if (rv < 0)
592 {
593 errno = -rv;
594 rv = -1;
595 }
596 }
597 else
598 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500599 rv = libc_vioctl (fd, cmd, ap);
600 }
601
Dave Wallace048b1d62018-01-03 22:24:41 -0500602 va_end (ap);
603 return rv;
604}
605
Florin Coras294afe22019-01-07 17:49:17 -0800606always_inline void
607ldp_select_init_maps (fd_set * __restrict original,
608 clib_bitmap_t ** resultb, clib_bitmap_t ** libcb,
609 clib_bitmap_t ** vclb, int nfds, u32 minbits,
610 u32 n_bytes, uword * si_bits, uword * libc_bits)
611{
612 uword si_bits_set, libc_bits_set;
613 vls_handle_t vlsh;
614 int fd;
615
616 clib_bitmap_validate (*vclb, minbits);
617 clib_bitmap_validate (*libcb, minbits);
618 clib_bitmap_validate (*resultb, minbits);
619 clib_memcpy_fast (*resultb, original, n_bytes);
620 memset (original, 0, n_bytes);
621
622 /* *INDENT-OFF* */
623 clib_bitmap_foreach (fd, *resultb, ({
624 if (fd > nfds)
625 break;
626 vlsh = ldp_fd_to_vlsh (fd);
627 if (vlsh == VLS_INVALID_HANDLE)
628 clib_bitmap_set_no_check (*libcb, fd, 1);
629 else
Florin Corascbce80a2020-04-20 01:32:38 +0000630 *vclb = clib_bitmap_set (*vclb, vlsh_to_session_index (vlsh), 1);
Florin Coras294afe22019-01-07 17:49:17 -0800631 }));
632 /* *INDENT-ON* */
633
634 si_bits_set = clib_bitmap_last_set (*vclb) + 1;
635 *si_bits = (si_bits_set > *si_bits) ? si_bits_set : *si_bits;
Florin Corascbce80a2020-04-20 01:32:38 +0000636 clib_bitmap_validate (*resultb, *si_bits);
Florin Coras294afe22019-01-07 17:49:17 -0800637
638 libc_bits_set = clib_bitmap_last_set (*libcb) + 1;
639 *libc_bits = (libc_bits_set > *libc_bits) ? libc_bits_set : *libc_bits;
640}
641
642always_inline int
643ldp_select_vcl_map_to_libc (clib_bitmap_t * vclb, fd_set * __restrict libcb)
644{
645 vls_handle_t vlsh;
646 uword si;
647 int fd;
648
649 if (!libcb)
650 return 0;
651
652 /* *INDENT-OFF* */
653 clib_bitmap_foreach (si, vclb, ({
654 vlsh = vls_session_index_to_vlsh (si);
Florin Coras54140622020-02-04 19:04:34 +0000655 ASSERT (vlsh != VLS_INVALID_HANDLE);
Florin Coras294afe22019-01-07 17:49:17 -0800656 fd = ldp_vlsh_to_fd (vlsh);
657 if (PREDICT_FALSE (fd < 0))
658 {
659 errno = EBADFD;
660 return -1;
661 }
662 FD_SET (fd, libcb);
663 }));
664 /* *INDENT-ON* */
665
666 return 0;
667}
668
669always_inline void
670ldp_select_libc_map_merge (clib_bitmap_t * result, fd_set * __restrict libcb)
671{
672 uword fd;
673
Florin Coras78b5fa62019-02-21 20:04:15 -0800674 if (!libcb)
675 return;
676
Florin Coras294afe22019-01-07 17:49:17 -0800677 /* *INDENT-OFF* */
678 clib_bitmap_foreach (fd, result, ({
679 FD_SET ((int)fd, libcb);
680 }));
681 /* *INDENT-ON* */
682}
683
Dave Wallace048b1d62018-01-03 22:24:41 -0500684int
Dave Wallace2a865272018-02-07 21:00:42 -0500685ldp_pselect (int nfds, fd_set * __restrict readfds,
686 fd_set * __restrict writefds,
687 fd_set * __restrict exceptfds,
688 const struct timespec *__restrict timeout,
689 const __sigset_t * __restrict sigmask)
Dave Wallace048b1d62018-01-03 22:24:41 -0500690{
Florin Coras294afe22019-01-07 17:49:17 -0800691 u32 minbits = clib_max (nfds, BITS (uword)), n_bytes;
Florin Corasdfe4cf42018-11-28 22:13:45 -0800692 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
Florin Coras294afe22019-01-07 17:49:17 -0800693 struct timespec libc_tspec = { 0 };
694 f64 time_out, vcl_timeout = 0;
695 uword si_bits, libc_bits;
696 int rv, bits_set = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500697
698 if (nfds < 0)
699 {
700 errno = EINVAL;
701 return -1;
702 }
703
Florin Coras4dee8cd2019-01-29 21:28:16 -0800704 if (PREDICT_FALSE (ldpw->clib_time.init_cpu_time == 0))
705 clib_time_init (&ldpw->clib_time);
706
Dave Wallace3ee1fe12018-02-23 01:09:11 -0500707 if (timeout)
708 {
709 time_out = (timeout->tv_sec == 0 && timeout->tv_nsec == 0) ?
Florin Coras7baeb712019-01-04 17:05:43 -0800710 (f64) 0 : (f64) timeout->tv_sec + (f64) timeout->tv_nsec / (f64) 1e9;
Dave Wallace3ee1fe12018-02-23 01:09:11 -0500711
712 /* select as fine grained sleep */
713 if (!nfds)
714 {
Florin Corasdfe4cf42018-11-28 22:13:45 -0800715 time_out += clib_time_now (&ldpw->clib_time);
716 while (clib_time_now (&ldpw->clib_time) < time_out)
Dave Wallace3ee1fe12018-02-23 01:09:11 -0500717 ;
718 return 0;
719 }
720 }
721 else if (!nfds)
722 {
723 errno = EINVAL;
724 return -1;
725 }
726 else
727 time_out = -1;
728
Florin Coras7baeb712019-01-04 17:05:43 -0800729 if (nfds <= ldp->vlsh_bit_val)
Dave Wallace048b1d62018-01-03 22:24:41 -0500730 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500731 rv = libc_pselect (nfds, readfds, writefds, exceptfds,
732 timeout, sigmask);
733 goto done;
734 }
735
Florin Coras294afe22019-01-07 17:49:17 -0800736 si_bits = libc_bits = 0;
737 n_bytes = nfds / 8 + ((nfds % 8) ? 1 : 0);
Florin Coras7baeb712019-01-04 17:05:43 -0800738
Dave Wallace048b1d62018-01-03 22:24:41 -0500739 if (readfds)
Florin Coras294afe22019-01-07 17:49:17 -0800740 ldp_select_init_maps (readfds, &ldpw->rd_bitmap, &ldpw->libc_rd_bitmap,
741 &ldpw->si_rd_bitmap, nfds, minbits, n_bytes,
742 &si_bits, &libc_bits);
Dave Wallace048b1d62018-01-03 22:24:41 -0500743 if (writefds)
Florin Coras294afe22019-01-07 17:49:17 -0800744 ldp_select_init_maps (writefds, &ldpw->wr_bitmap,
745 &ldpw->libc_wr_bitmap, &ldpw->si_wr_bitmap, nfds,
746 minbits, n_bytes, &si_bits, &libc_bits);
Dave Wallace048b1d62018-01-03 22:24:41 -0500747 if (exceptfds)
Florin Coras294afe22019-01-07 17:49:17 -0800748 ldp_select_init_maps (exceptfds, &ldpw->ex_bitmap,
749 &ldpw->libc_ex_bitmap, &ldpw->si_ex_bitmap, nfds,
750 minbits, n_bytes, &si_bits, &libc_bits);
Dave Wallace048b1d62018-01-03 22:24:41 -0500751
Florin Coras294afe22019-01-07 17:49:17 -0800752 if (PREDICT_FALSE (!si_bits && !libc_bits))
Dave Wallace048b1d62018-01-03 22:24:41 -0500753 {
754 errno = EINVAL;
755 rv = -1;
756 goto done;
757 }
758
Florin Coras78b5fa62019-02-21 20:04:15 -0800759 if (!si_bits)
760 libc_tspec = timeout ? *timeout : libc_tspec;
Florin Coras294afe22019-01-07 17:49:17 -0800761
Dave Wallace048b1d62018-01-03 22:24:41 -0500762 do
763 {
Florin Coras294afe22019-01-07 17:49:17 -0800764 if (si_bits)
Dave Wallace048b1d62018-01-03 22:24:41 -0500765 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500766 if (readfds)
Florin Coras294afe22019-01-07 17:49:17 -0800767 clib_memcpy_fast (ldpw->rd_bitmap, ldpw->si_rd_bitmap,
Florin Corascbce80a2020-04-20 01:32:38 +0000768 vec_len (ldpw->si_rd_bitmap) *
Dave Barach178cf492018-11-13 16:34:13 -0500769 sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -0500770 if (writefds)
Florin Coras294afe22019-01-07 17:49:17 -0800771 clib_memcpy_fast (ldpw->wr_bitmap, ldpw->si_wr_bitmap,
Florin Corascbce80a2020-04-20 01:32:38 +0000772 vec_len (ldpw->si_wr_bitmap) *
Dave Barach178cf492018-11-13 16:34:13 -0500773 sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -0500774 if (exceptfds)
Florin Coras294afe22019-01-07 17:49:17 -0800775 clib_memcpy_fast (ldpw->ex_bitmap, ldpw->si_ex_bitmap,
Florin Corascbce80a2020-04-20 01:32:38 +0000776 vec_len (ldpw->si_ex_bitmap) *
Dave Barach178cf492018-11-13 16:34:13 -0500777 sizeof (clib_bitmap_t));
Florin Coras294afe22019-01-07 17:49:17 -0800778
Florin Coras0ef8ef22019-01-18 08:37:13 -0800779 rv = vls_select (si_bits, readfds ? ldpw->rd_bitmap : NULL,
780 writefds ? ldpw->wr_bitmap : NULL,
781 exceptfds ? ldpw->ex_bitmap : NULL, vcl_timeout);
Florin Coras294afe22019-01-07 17:49:17 -0800782 if (rv < 0)
783 {
784 errno = -rv;
785 rv = -1;
Florin Coras5e6222a2020-04-24 17:09:25 +0000786 goto done;
Florin Coras294afe22019-01-07 17:49:17 -0800787 }
788 else if (rv > 0)
789 {
790 if (ldp_select_vcl_map_to_libc (ldpw->rd_bitmap, readfds))
791 {
792 rv = -1;
793 goto done;
794 }
795
796 if (ldp_select_vcl_map_to_libc (ldpw->wr_bitmap, writefds))
797 {
798 rv = -1;
799 goto done;
800 }
801
802 if (ldp_select_vcl_map_to_libc (ldpw->ex_bitmap, exceptfds))
803 {
804 rv = -1;
805 goto done;
806 }
807 bits_set = rv;
808 }
809 }
810 if (libc_bits)
811 {
812 if (readfds)
813 clib_memcpy_fast (ldpw->rd_bitmap, ldpw->libc_rd_bitmap,
814 vec_len (ldpw->libc_rd_bitmap) *
815 sizeof (clib_bitmap_t));
816 if (writefds)
817 clib_memcpy_fast (ldpw->wr_bitmap, ldpw->libc_wr_bitmap,
818 vec_len (ldpw->libc_wr_bitmap) *
819 sizeof (clib_bitmap_t));
820 if (exceptfds)
821 clib_memcpy_fast (ldpw->ex_bitmap, ldpw->libc_ex_bitmap,
822 vec_len (ldpw->libc_ex_bitmap) *
823 sizeof (clib_bitmap_t));
824
Dave Wallace048b1d62018-01-03 22:24:41 -0500825 rv = libc_pselect (libc_bits,
Florin Coras294afe22019-01-07 17:49:17 -0800826 readfds ? (fd_set *) ldpw->rd_bitmap : NULL,
827 writefds ? (fd_set *) ldpw->wr_bitmap : NULL,
828 exceptfds ? (fd_set *) ldpw->ex_bitmap : NULL,
829 &libc_tspec, sigmask);
830 if (rv > 0)
831 {
832 ldp_select_libc_map_merge (ldpw->rd_bitmap, readfds);
833 ldp_select_libc_map_merge (ldpw->wr_bitmap, writefds);
834 ldp_select_libc_map_merge (ldpw->ex_bitmap, exceptfds);
835 bits_set += rv;
836 }
837 }
838
839 if (bits_set)
840 {
841 rv = bits_set;
842 goto done;
Dave Wallace048b1d62018-01-03 22:24:41 -0500843 }
844 }
Florin Corasdfe4cf42018-11-28 22:13:45 -0800845 while ((time_out == -1) || (clib_time_now (&ldpw->clib_time) < time_out));
Dave Wallace048b1d62018-01-03 22:24:41 -0500846 rv = 0;
847
848done:
849 /* TBD: set timeout to amount of time left */
Florin Corasdfe4cf42018-11-28 22:13:45 -0800850 clib_bitmap_zero (ldpw->rd_bitmap);
Florin Coras294afe22019-01-07 17:49:17 -0800851 clib_bitmap_zero (ldpw->si_rd_bitmap);
Florin Corasdfe4cf42018-11-28 22:13:45 -0800852 clib_bitmap_zero (ldpw->libc_rd_bitmap);
853 clib_bitmap_zero (ldpw->wr_bitmap);
Florin Coras294afe22019-01-07 17:49:17 -0800854 clib_bitmap_zero (ldpw->si_wr_bitmap);
Florin Corasdfe4cf42018-11-28 22:13:45 -0800855 clib_bitmap_zero (ldpw->libc_wr_bitmap);
856 clib_bitmap_zero (ldpw->ex_bitmap);
Florin Coras294afe22019-01-07 17:49:17 -0800857 clib_bitmap_zero (ldpw->si_ex_bitmap);
Florin Corasdfe4cf42018-11-28 22:13:45 -0800858 clib_bitmap_zero (ldpw->libc_ex_bitmap);
Dave Wallace048b1d62018-01-03 22:24:41 -0500859
Dave Wallace048b1d62018-01-03 22:24:41 -0500860 return rv;
861}
862
863int
864select (int nfds, fd_set * __restrict readfds,
865 fd_set * __restrict writefds,
866 fd_set * __restrict exceptfds, struct timeval *__restrict timeout)
867{
868 struct timespec tspec;
869
870 if (timeout)
871 {
872 tspec.tv_sec = timeout->tv_sec;
873 tspec.tv_nsec = timeout->tv_usec * 1000;
874 }
Dave Wallace2a865272018-02-07 21:00:42 -0500875 return ldp_pselect (nfds, readfds, writefds, exceptfds,
876 timeout ? &tspec : NULL, NULL);
Dave Wallace048b1d62018-01-03 22:24:41 -0500877}
878
879#ifdef __USE_XOPEN2K
880int
881pselect (int nfds, fd_set * __restrict readfds,
882 fd_set * __restrict writefds,
883 fd_set * __restrict exceptfds,
884 const struct timespec *__restrict timeout,
885 const __sigset_t * __restrict sigmask)
886{
Dave Wallace2a865272018-02-07 21:00:42 -0500887 return ldp_pselect (nfds, readfds, writefds, exceptfds, timeout, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -0500888}
889#endif
890
Yu Ping7b74b072019-05-08 00:40:24 +0800891/* If transparent TLS mode is turned on, then ldp will load key and cert.
892 */
893static int
894load_tls_cert (vls_handle_t vlsh)
895{
896 char *env_var_str = getenv (LDP_ENV_TLS_CERT);
897 char inbuf[4096];
898 char *tls_cert;
899 int cert_size;
900 FILE *fp;
901
902 if (env_var_str)
903 {
904 fp = fopen (env_var_str, "r");
905 if (fp == NULL)
906 {
907 LDBG (0, "ERROR: failed to open cert file %s \n", env_var_str);
908 return -1;
909 }
910 cert_size = fread (inbuf, sizeof (char), sizeof (inbuf), fp);
911 tls_cert = inbuf;
912 vppcom_session_tls_add_cert (vlsh_to_session_index (vlsh), tls_cert,
913 cert_size);
914 fclose (fp);
915 }
916 else
917 {
918 LDBG (0, "ERROR: failed to read LDP environment %s\n",
919 LDP_ENV_TLS_CERT);
920 return -1;
921 }
922 return 0;
923}
924
925static int
926load_tls_key (vls_handle_t vlsh)
927{
928 char *env_var_str = getenv (LDP_ENV_TLS_KEY);
929 char inbuf[4096];
930 char *tls_key;
931 int key_size;
932 FILE *fp;
933
934 if (env_var_str)
935 {
936 fp = fopen (env_var_str, "r");
937 if (fp == NULL)
938 {
939 LDBG (0, "ERROR: failed to open key file %s \n", env_var_str);
940 return -1;
941 }
942 key_size = fread (inbuf, sizeof (char), sizeof (inbuf), fp);
943 tls_key = inbuf;
944 vppcom_session_tls_add_key (vlsh_to_session_index (vlsh), tls_key,
945 key_size);
946 fclose (fp);
947 }
948 else
949 {
950 LDBG (0, "ERROR: failed to read LDP environment %s\n", LDP_ENV_TLS_KEY);
951 return -1;
952 }
953 return 0;
954}
955
Dave Wallace048b1d62018-01-03 22:24:41 -0500956int
957socket (int domain, int type, int protocol)
958{
Florin Coras7baeb712019-01-04 17:05:43 -0800959 int rv, sock_type = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK);
Dave Wallace048b1d62018-01-03 22:24:41 -0500960 u8 is_nonblocking = type & SOCK_NONBLOCK ? 1 : 0;
Florin Coras7baeb712019-01-04 17:05:43 -0800961 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -0500962
Dave Wallace2a865272018-02-07 21:00:42 -0500963 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500964 return -1;
965
966 if (((domain == AF_INET) || (domain == AF_INET6)) &&
967 ((sock_type == SOCK_STREAM) || (sock_type == SOCK_DGRAM)))
968 {
Yu Ping7b74b072019-05-08 00:40:24 +0800969 u8 proto;
970 if (ldp->transparent_tls)
971 {
972 proto = VPPCOM_PROTO_TLS;
973 }
974 else
975 proto = ((sock_type == SOCK_DGRAM) ?
976 VPPCOM_PROTO_UDP : VPPCOM_PROTO_TCP);
Dave Wallace048b1d62018-01-03 22:24:41 -0500977
Florin Coras7baeb712019-01-04 17:05:43 -0800978 LDBG (0, "calling vls_create: proto %u (%s), is_nonblocking %u",
979 proto, vppcom_proto_str (proto), is_nonblocking);
Dave Wallace048b1d62018-01-03 22:24:41 -0500980
Florin Coras7baeb712019-01-04 17:05:43 -0800981 vlsh = vls_create (proto, is_nonblocking);
982 if (vlsh < 0)
Dave Wallace048b1d62018-01-03 22:24:41 -0500983 {
Florin Coras7baeb712019-01-04 17:05:43 -0800984 errno = -vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -0500985 rv = -1;
986 }
987 else
988 {
Yu Ping7b74b072019-05-08 00:40:24 +0800989 if (ldp->transparent_tls)
990 {
991 if (load_tls_cert (vlsh) < 0 || load_tls_key (vlsh) < 0)
992 {
993 return -1;
994 }
995 }
Florin Coras7baeb712019-01-04 17:05:43 -0800996 rv = ldp_vlsh_to_fd (vlsh);
Dave Wallace048b1d62018-01-03 22:24:41 -0500997 }
998 }
999 else
1000 {
Florin Coras7baeb712019-01-04 17:05:43 -08001001 LDBG (0, "calling libc_socket");
Dave Wallace048b1d62018-01-03 22:24:41 -05001002 rv = libc_socket (domain, type, protocol);
1003 }
1004
Dave Wallace048b1d62018-01-03 22:24:41 -05001005 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001006}
1007
1008/*
1009 * Create two new sockets, of type TYPE in domain DOMAIN and using
1010 * protocol PROTOCOL, which are connected to each other, and put file
1011 * descriptors for them in FDS[0] and FDS[1]. If PROTOCOL is zero,
1012 * one will be chosen automatically.
1013 * Returns 0 on success, -1 for errors.
1014 * */
1015int
Dave Wallace048b1d62018-01-03 22:24:41 -05001016socketpair (int domain, int type, int protocol, int fds[2])
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001017{
Florin Coras7baeb712019-01-04 17:05:43 -08001018 int rv, sock_type = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK);
Dave Wallace048b1d62018-01-03 22:24:41 -05001019
Dave Wallace2a865272018-02-07 21:00:42 -05001020 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001021 return -1;
1022
1023 if (((domain == AF_INET) || (domain == AF_INET6)) &&
1024 ((sock_type == SOCK_STREAM) || (sock_type == SOCK_DGRAM)))
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001025 {
Florin Coras7baeb712019-01-04 17:05:43 -08001026 LDBG (0, "LDP-TBD");
Dave Wallace048b1d62018-01-03 22:24:41 -05001027 errno = ENOSYS;
1028 rv = -1;
1029 }
1030 else
1031 {
Florin Coras7baeb712019-01-04 17:05:43 -08001032 LDBG (1, "calling libc_socketpair");
Florin Coras173bae32018-11-16 18:56:28 -08001033 rv = libc_socketpair (domain, type, protocol, fds);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001034 }
1035
Dave Wallace048b1d62018-01-03 22:24:41 -05001036 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001037}
1038
1039int
Dave Wallace048b1d62018-01-03 22:24:41 -05001040bind (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001041{
Florin Coras7baeb712019-01-04 17:05:43 -08001042 vls_handle_t vlsh;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001043 int rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001044
Dave Wallace2a865272018-02-07 21:00:42 -05001045 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001046 return -1;
1047
Florin Coras7baeb712019-01-04 17:05:43 -08001048 vlsh = ldp_fd_to_vlsh (fd);
1049 if (vlsh != VLS_INVALID_HANDLE)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001050 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001051 vppcom_endpt_t ep;
1052
Dave Wallace048b1d62018-01-03 22:24:41 -05001053 switch (addr->sa_family)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001054 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001055 case AF_INET:
1056 if (len != sizeof (struct sockaddr_in))
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001057 {
Florin Coras7baeb712019-01-04 17:05:43 -08001058 LDBG (0, "ERROR: fd %d: vlsh %u: Invalid AF_INET addr len %u!",
1059 fd, vlsh, len);
Dave Wallace048b1d62018-01-03 22:24:41 -05001060 errno = EINVAL;
1061 rv = -1;
1062 goto done;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001063 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001064 ep.is_ip4 = VPPCOM_IS_IP4;
1065 ep.ip = (u8 *) & ((const struct sockaddr_in *) addr)->sin_addr;
1066 ep.port = (u16) ((const struct sockaddr_in *) addr)->sin_port;
1067 break;
1068
1069 case AF_INET6:
1070 if (len != sizeof (struct sockaddr_in6))
1071 {
Florin Coras7baeb712019-01-04 17:05:43 -08001072 LDBG (0, "ERROR: fd %d: vlsh %u: Invalid AF_INET6 addr len %u!",
1073 fd, vlsh, len);
Dave Wallace048b1d62018-01-03 22:24:41 -05001074 errno = EINVAL;
1075 rv = -1;
1076 goto done;
1077 }
1078 ep.is_ip4 = VPPCOM_IS_IP6;
1079 ep.ip = (u8 *) & ((const struct sockaddr_in6 *) addr)->sin6_addr;
1080 ep.port = (u16) ((const struct sockaddr_in6 *) addr)->sin6_port;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001081 break;
1082
1083 default:
Florin Coras7baeb712019-01-04 17:05:43 -08001084 LDBG (0, "ERROR: fd %d: vlsh %u: Unsupported address family %u!",
1085 fd, vlsh, addr->sa_family);
Dave Wallace048b1d62018-01-03 22:24:41 -05001086 errno = EAFNOSUPPORT;
1087 rv = -1;
1088 goto done;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001089 }
Florin Coras7baeb712019-01-04 17:05:43 -08001090 LDBG (0, "fd %d: calling vls_bind: vlsh %u, addr %p, len %u", fd, vlsh,
1091 addr, len);
Dave Wallace048b1d62018-01-03 22:24:41 -05001092
Florin Coras7baeb712019-01-04 17:05:43 -08001093 rv = vls_bind (vlsh, &ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05001094 if (rv != VPPCOM_OK)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001095 {
1096 errno = -rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001097 rv = -1;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001098 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001099 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001100 else
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001101 {
Florin Coras7baeb712019-01-04 17:05:43 -08001102 LDBG (0, "fd %d: calling libc_bind: addr %p, len %u", fd, addr, len);
Dave Wallace048b1d62018-01-03 22:24:41 -05001103 rv = libc_bind (fd, addr, len);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001104 }
1105
Dave Wallace048b1d62018-01-03 22:24:41 -05001106done:
Florin Coras7baeb712019-01-04 17:05:43 -08001107 LDBG (1, "fd %d: returning %d", fd, rv);
Florin Coras05ecfcc2018-12-12 18:19:39 -08001108
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001109 return rv;
1110}
1111
1112static inline int
Dave Wallace2a865272018-02-07 21:00:42 -05001113ldp_copy_ep_to_sockaddr (__SOCKADDR_ARG addr, socklen_t * __restrict len,
1114 vppcom_endpt_t * ep)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001115{
Dave Wallace048b1d62018-01-03 22:24:41 -05001116 int rv = 0;
1117 int sa_len, copy_len;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001118
Dave Wallace2a865272018-02-07 21:00:42 -05001119 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001120 return -1;
1121
1122 if (addr && len && ep)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001123 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001124 addr->sa_family = (ep->is_ip4 == VPPCOM_IS_IP4) ? AF_INET : AF_INET6;
1125 switch (addr->sa_family)
1126 {
1127 case AF_INET:
1128 ((struct sockaddr_in *) addr)->sin_port = ep->port;
1129 if (*len > sizeof (struct sockaddr_in))
1130 *len = sizeof (struct sockaddr_in);
1131 sa_len = sizeof (struct sockaddr_in) - sizeof (struct in_addr);
1132 copy_len = *len - sa_len;
1133 if (copy_len > 0)
1134 memcpy (&((struct sockaddr_in *) addr)->sin_addr, ep->ip,
1135 copy_len);
1136 break;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001137
Dave Wallace048b1d62018-01-03 22:24:41 -05001138 case AF_INET6:
1139 ((struct sockaddr_in6 *) addr)->sin6_port = ep->port;
1140 if (*len > sizeof (struct sockaddr_in6))
1141 *len = sizeof (struct sockaddr_in6);
1142 sa_len = sizeof (struct sockaddr_in6) - sizeof (struct in6_addr);
1143 copy_len = *len - sa_len;
1144 if (copy_len > 0)
1145 memcpy (((struct sockaddr_in6 *) addr)->sin6_addr.
1146 __in6_u.__u6_addr8, ep->ip, copy_len);
1147 break;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001148
Dave Wallace048b1d62018-01-03 22:24:41 -05001149 default:
1150 /* Not possible */
1151 rv = -EAFNOSUPPORT;
1152 break;
1153 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001154 }
Dave Wallacee695cb42017-11-02 22:04:42 -04001155 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001156}
1157
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001158int
Dave Wallace048b1d62018-01-03 22:24:41 -05001159getsockname (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict len)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001160{
Florin Coras7baeb712019-01-04 17:05:43 -08001161 vls_handle_t vlsh;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001162 int rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001163
Dave Wallace2a865272018-02-07 21:00:42 -05001164 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001165 return -1;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001166
Florin Coras7baeb712019-01-04 17:05:43 -08001167 vlsh = ldp_fd_to_vlsh (fd);
1168 if (vlsh != VLS_INVALID_HANDLE)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001169 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001170 vppcom_endpt_t ep;
1171 u8 addr_buf[sizeof (struct in6_addr)];
1172 u32 size = sizeof (ep);
1173
1174 ep.ip = addr_buf;
Dave Wallace048b1d62018-01-03 22:24:41 -05001175
Florin Coras7baeb712019-01-04 17:05:43 -08001176 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_LCL_ADDR, &ep, &size);
Dave Wallace048b1d62018-01-03 22:24:41 -05001177 if (rv != VPPCOM_OK)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001178 {
1179 errno = -rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001180 rv = -1;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001181 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001182 else
1183 {
Dave Wallace2a865272018-02-07 21:00:42 -05001184 rv = ldp_copy_ep_to_sockaddr (addr, len, &ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05001185 if (rv != VPPCOM_OK)
1186 {
1187 errno = -rv;
1188 rv = -1;
1189 }
1190 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001191 }
1192 else
1193 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001194 rv = libc_getsockname (fd, addr, len);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001195 }
1196
Dave Wallace048b1d62018-01-03 22:24:41 -05001197 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001198}
1199
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001200int
Dave Wallace048b1d62018-01-03 22:24:41 -05001201connect (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001202{
Florin Coras7baeb712019-01-04 17:05:43 -08001203 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05001204 int rv;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001205
Dave Wallace2a865272018-02-07 21:00:42 -05001206 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001207 return -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001208
Dave Wallace048b1d62018-01-03 22:24:41 -05001209 if (!addr)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001210 {
Florin Coras7baeb712019-01-04 17:05:43 -08001211 LDBG (0, "ERROR: fd %d: NULL addr, len %u", fd, len);
Dave Wallace048b1d62018-01-03 22:24:41 -05001212 errno = EINVAL;
1213 rv = -1;
1214 goto done;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001215 }
1216
Florin Coras7baeb712019-01-04 17:05:43 -08001217 vlsh = ldp_fd_to_vlsh (fd);
1218 if (vlsh != VLS_INVALID_HANDLE)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001219 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001220 vppcom_endpt_t ep;
1221
Dave Wallace048b1d62018-01-03 22:24:41 -05001222 switch (addr->sa_family)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001223 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001224 case AF_INET:
1225 if (len != sizeof (struct sockaddr_in))
1226 {
Florin Coras7baeb712019-01-04 17:05:43 -08001227 LDBG (0, "fd %d: ERROR vlsh %u: Invalid AF_INET addr len %u!",
1228 fd, vlsh, len);
Dave Wallace048b1d62018-01-03 22:24:41 -05001229 errno = EINVAL;
1230 rv = -1;
1231 goto done;
1232 }
1233 ep.is_ip4 = VPPCOM_IS_IP4;
1234 ep.ip = (u8 *) & ((const struct sockaddr_in *) addr)->sin_addr;
1235 ep.port = (u16) ((const struct sockaddr_in *) addr)->sin_port;
1236 break;
1237
1238 case AF_INET6:
1239 if (len != sizeof (struct sockaddr_in6))
1240 {
Florin Coras7baeb712019-01-04 17:05:43 -08001241 LDBG (0, "fd %d: ERROR vlsh %u: Invalid AF_INET6 addr len %u!",
1242 fd, vlsh, len);
Dave Wallace048b1d62018-01-03 22:24:41 -05001243 errno = EINVAL;
1244 rv = -1;
1245 goto done;
1246 }
1247 ep.is_ip4 = VPPCOM_IS_IP6;
1248 ep.ip = (u8 *) & ((const struct sockaddr_in6 *) addr)->sin6_addr;
1249 ep.port = (u16) ((const struct sockaddr_in6 *) addr)->sin6_port;
1250 break;
1251
1252 default:
Florin Coras7baeb712019-01-04 17:05:43 -08001253 LDBG (0, "fd %d: ERROR vlsh %u: Unsupported address family %u!",
1254 fd, vlsh, addr->sa_family);
Dave Wallace048b1d62018-01-03 22:24:41 -05001255 errno = EAFNOSUPPORT;
1256 rv = -1;
1257 goto done;
1258 }
Florin Coras7baeb712019-01-04 17:05:43 -08001259 LDBG (0, "fd %d: calling vls_connect(): vlsh %u addr %p len %u", fd,
1260 vlsh, addr, len);
Dave Wallace048b1d62018-01-03 22:24:41 -05001261
Florin Coras7baeb712019-01-04 17:05:43 -08001262 rv = vls_connect (vlsh, &ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05001263 if (rv != VPPCOM_OK)
1264 {
1265 errno = -rv;
1266 rv = -1;
1267 }
1268 }
1269 else
1270 {
Florin Coras7baeb712019-01-04 17:05:43 -08001271 LDBG (0, "fd %d: calling libc_connect(): addr %p, len %u",
1272 fd, addr, len);
Dave Wallace048b1d62018-01-03 22:24:41 -05001273
1274 rv = libc_connect (fd, addr, len);
1275 }
1276
1277done:
Florin Coras7baeb712019-01-04 17:05:43 -08001278 LDBG (1, "fd %d: returning %d (0x%x)", fd, rv, rv);
Dave Wallace048b1d62018-01-03 22:24:41 -05001279 return rv;
1280}
1281
1282int
1283getpeername (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict len)
1284{
Florin Coras7baeb712019-01-04 17:05:43 -08001285 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05001286 int rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001287
Dave Wallace2a865272018-02-07 21:00:42 -05001288 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001289 return -1;
1290
Florin Coras7baeb712019-01-04 17:05:43 -08001291 vlsh = ldp_fd_to_vlsh (fd);
1292 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -05001293 {
1294 vppcom_endpt_t ep;
1295 u8 addr_buf[sizeof (struct in6_addr)];
1296 u32 size = sizeof (ep);
1297
1298 ep.ip = addr_buf;
Florin Coras7baeb712019-01-04 17:05:43 -08001299 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_PEER_ADDR, &ep, &size);
Dave Wallace048b1d62018-01-03 22:24:41 -05001300 if (rv != VPPCOM_OK)
1301 {
1302 errno = -rv;
1303 rv = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001304 }
1305 else
1306 {
Dave Wallace2a865272018-02-07 21:00:42 -05001307 rv = ldp_copy_ep_to_sockaddr (addr, len, &ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05001308 if (rv != VPPCOM_OK)
1309 {
1310 errno = -rv;
1311 rv = -1;
1312 }
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001313 }
1314 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001315 else
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001316 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001317 rv = libc_getpeername (fd, addr, len);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001318 }
1319
Dave Wallace048b1d62018-01-03 22:24:41 -05001320 return rv;
1321}
1322
1323ssize_t
1324send (int fd, const void *buf, size_t n, int flags)
1325{
Florin Coras7baeb712019-01-04 17:05:43 -08001326 vls_handle_t vlsh = ldp_fd_to_vlsh (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05001327 ssize_t size;
Dave Wallace048b1d62018-01-03 22:24:41 -05001328
Dave Wallace2a865272018-02-07 21:00:42 -05001329 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001330 return -1;
1331
Florin Coras7baeb712019-01-04 17:05:43 -08001332 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -05001333 {
Florin Coras7baeb712019-01-04 17:05:43 -08001334 size = vls_sendto (vlsh, (void *) buf, n, flags, NULL);
qchangaa8f63c2018-05-30 11:44:18 -07001335 if (size < VPPCOM_OK)
Dave Wallace048b1d62018-01-03 22:24:41 -05001336 {
1337 errno = -size;
1338 size = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001339 }
1340 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001341 else
1342 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001343 size = libc_send (fd, buf, n, flags);
1344 }
1345
Dave Wallace048b1d62018-01-03 22:24:41 -05001346 return size;
1347}
1348
1349ssize_t
1350sendfile (int out_fd, int in_fd, off_t * offset, size_t len)
1351{
Florin Corasdfe4cf42018-11-28 22:13:45 -08001352 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
Florin Coras7baeb712019-01-04 17:05:43 -08001353 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05001354 ssize_t size = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05001355
Dave Wallace2a865272018-02-07 21:00:42 -05001356 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001357 return -1;
1358
Florin Coras7baeb712019-01-04 17:05:43 -08001359 vlsh = ldp_fd_to_vlsh (out_fd);
1360 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -05001361 {
1362 int rv;
1363 ssize_t results = 0;
1364 size_t n_bytes_left = len;
1365 size_t bytes_to_read;
1366 int nbytes;
Dave Wallace048b1d62018-01-03 22:24:41 -05001367 u8 eagain = 0;
1368 u32 flags, flags_len = sizeof (flags);
1369
Florin Coras7baeb712019-01-04 17:05:43 -08001370 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_FLAGS, &flags, &flags_len);
Dave Wallace048b1d62018-01-03 22:24:41 -05001371 if (PREDICT_FALSE (rv != VPPCOM_OK))
1372 {
Florin Coras7baeb712019-01-04 17:05:43 -08001373 LDBG (0, "ERROR: out fd %d: vls_attr: vlsh %u, returned %d (%s)!",
1374 out_fd, vlsh, rv, vppcom_retval_str (rv));
Dave Wallace048b1d62018-01-03 22:24:41 -05001375
Florin Corasdfe4cf42018-11-28 22:13:45 -08001376 vec_reset_length (ldpw->io_buffer);
Dave Wallace048b1d62018-01-03 22:24:41 -05001377 errno = -rv;
1378 size = -1;
1379 goto done;
1380 }
1381
1382 if (offset)
1383 {
1384 off_t off = lseek (in_fd, *offset, SEEK_SET);
1385 if (PREDICT_FALSE (off == -1))
1386 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001387 size = -1;
1388 goto done;
1389 }
1390
1391 ASSERT (off == *offset);
1392 }
1393
1394 do
1395 {
Florin Coras7baeb712019-01-04 17:05:43 -08001396 size = vls_attr (vlsh, VPPCOM_ATTR_GET_NWRITE, 0, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05001397 if (size < 0)
1398 {
Florin Coras7baeb712019-01-04 17:05:43 -08001399 LDBG (0, "ERROR: fd %d: vls_attr: vlsh %u returned %d (%s)!",
1400 out_fd, vlsh, size, vppcom_retval_str (size));
Florin Corasdfe4cf42018-11-28 22:13:45 -08001401 vec_reset_length (ldpw->io_buffer);
Dave Wallace048b1d62018-01-03 22:24:41 -05001402 errno = -size;
1403 size = -1;
1404 goto done;
1405 }
1406
1407 bytes_to_read = size;
Dave Wallace048b1d62018-01-03 22:24:41 -05001408 if (bytes_to_read == 0)
1409 {
1410 if (flags & O_NONBLOCK)
1411 {
1412 if (!results)
Florin Coras7baeb712019-01-04 17:05:43 -08001413 eagain = 1;
Dave Wallace048b1d62018-01-03 22:24:41 -05001414 goto update_offset;
1415 }
1416 else
1417 continue;
1418 }
1419 bytes_to_read = clib_min (n_bytes_left, bytes_to_read);
Florin Corasdfe4cf42018-11-28 22:13:45 -08001420 vec_validate (ldpw->io_buffer, bytes_to_read);
1421 nbytes = libc_read (in_fd, ldpw->io_buffer, bytes_to_read);
Dave Wallace048b1d62018-01-03 22:24:41 -05001422 if (nbytes < 0)
1423 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001424 if (results == 0)
1425 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08001426 vec_reset_length (ldpw->io_buffer);
Dave Wallace048b1d62018-01-03 22:24:41 -05001427 size = -1;
1428 goto done;
1429 }
1430 goto update_offset;
1431 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001432
Florin Coras7baeb712019-01-04 17:05:43 -08001433 size = vls_write (vlsh, ldpw->io_buffer, nbytes);
Dave Wallace048b1d62018-01-03 22:24:41 -05001434 if (size < 0)
1435 {
1436 if (size == VPPCOM_EAGAIN)
1437 {
1438 if (flags & O_NONBLOCK)
1439 {
1440 if (!results)
Florin Coras7baeb712019-01-04 17:05:43 -08001441 eagain = 1;
Dave Wallace048b1d62018-01-03 22:24:41 -05001442 goto update_offset;
1443 }
1444 else
1445 continue;
1446 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001447 if (results == 0)
1448 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08001449 vec_reset_length (ldpw->io_buffer);
Dave Wallace048b1d62018-01-03 22:24:41 -05001450 errno = -size;
1451 size = -1;
1452 goto done;
1453 }
1454 goto update_offset;
1455 }
1456
1457 results += nbytes;
1458 ASSERT (n_bytes_left >= nbytes);
1459 n_bytes_left = n_bytes_left - nbytes;
1460 }
1461 while (n_bytes_left > 0);
1462
1463 update_offset:
Florin Corasdfe4cf42018-11-28 22:13:45 -08001464 vec_reset_length (ldpw->io_buffer);
Dave Wallace048b1d62018-01-03 22:24:41 -05001465 if (offset)
1466 {
1467 off_t off = lseek (in_fd, *offset, SEEK_SET);
1468 if (PREDICT_FALSE (off == -1))
1469 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001470 size = -1;
1471 goto done;
1472 }
1473
1474 ASSERT (off == *offset);
1475 *offset += results + 1;
1476 }
1477 if (eagain)
1478 {
1479 errno = EAGAIN;
1480 size = -1;
1481 }
1482 else
1483 size = results;
1484 }
1485 else
1486 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001487 size = libc_sendfile (out_fd, in_fd, offset, len);
1488 }
1489
1490done:
Dave Wallace048b1d62018-01-03 22:24:41 -05001491 return size;
1492}
1493
1494ssize_t
1495sendfile64 (int out_fd, int in_fd, off_t * offset, size_t len)
1496{
1497 return sendfile (out_fd, in_fd, offset, len);
1498}
1499
1500ssize_t
1501recv (int fd, void *buf, size_t n, int flags)
1502{
Florin Coras7baeb712019-01-04 17:05:43 -08001503 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05001504 ssize_t size;
Dave Wallace048b1d62018-01-03 22:24:41 -05001505
Dave Wallace2a865272018-02-07 21:00:42 -05001506 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001507 return -1;
1508
Florin Coras7baeb712019-01-04 17:05:43 -08001509 vlsh = ldp_fd_to_vlsh (fd);
1510 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -05001511 {
Florin Coras7baeb712019-01-04 17:05:43 -08001512 size = vls_recvfrom (vlsh, buf, n, flags, NULL);
Dave Wallace048b1d62018-01-03 22:24:41 -05001513 if (size < 0)
Florin Coras2a6642e2020-03-24 15:24:29 +00001514 {
1515 errno = -size;
1516 size = -1;
1517 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001518 }
1519 else
1520 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001521 size = libc_recv (fd, buf, n, flags);
1522 }
1523
Dave Wallace048b1d62018-01-03 22:24:41 -05001524 return size;
1525}
1526
1527ssize_t
1528sendto (int fd, const void *buf, size_t n, int flags,
1529 __CONST_SOCKADDR_ARG addr, socklen_t addr_len)
1530{
Florin Coras7baeb712019-01-04 17:05:43 -08001531 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05001532 ssize_t size;
Dave Wallace048b1d62018-01-03 22:24:41 -05001533
Dave Wallace2a865272018-02-07 21:00:42 -05001534 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001535 return -1;
1536
Florin Coras7baeb712019-01-04 17:05:43 -08001537 vlsh = ldp_fd_to_vlsh (fd);
1538 if (vlsh != INVALID_SESSION_ID)
Dave Wallace048b1d62018-01-03 22:24:41 -05001539 {
1540 vppcom_endpt_t *ep = 0;
1541 vppcom_endpt_t _ep;
1542
1543 if (addr)
1544 {
1545 ep = &_ep;
Dave Wallace048b1d62018-01-03 22:24:41 -05001546 switch (addr->sa_family)
1547 {
1548 case AF_INET:
1549 ep->is_ip4 = VPPCOM_IS_IP4;
1550 ep->ip =
1551 (uint8_t *) & ((const struct sockaddr_in *) addr)->sin_addr;
1552 ep->port =
1553 (uint16_t) ((const struct sockaddr_in *) addr)->sin_port;
1554 break;
1555
1556 case AF_INET6:
1557 ep->is_ip4 = VPPCOM_IS_IP6;
1558 ep->ip =
1559 (uint8_t *) & ((const struct sockaddr_in6 *) addr)->sin6_addr;
1560 ep->port =
1561 (uint16_t) ((const struct sockaddr_in6 *) addr)->sin6_port;
1562 break;
1563
1564 default:
1565 errno = EAFNOSUPPORT;
1566 size = -1;
1567 goto done;
1568 }
1569 }
1570
Florin Coras7baeb712019-01-04 17:05:43 -08001571 size = vls_sendto (vlsh, (void *) buf, n, flags, ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05001572 if (size < 0)
1573 {
1574 errno = -size;
1575 size = -1;
1576 }
1577 }
1578 else
1579 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001580 size = libc_sendto (fd, buf, n, flags, addr, addr_len);
1581 }
1582
1583done:
Dave Wallace048b1d62018-01-03 22:24:41 -05001584 return size;
1585}
1586
1587ssize_t
1588recvfrom (int fd, void *__restrict buf, size_t n, int flags,
1589 __SOCKADDR_ARG addr, socklen_t * __restrict addr_len)
1590{
Florin Coras7baeb712019-01-04 17:05:43 -08001591 vls_handle_t sid;
Haggai Eran46ae2ef2019-02-19 15:04:42 +02001592 ssize_t size, rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001593
Dave Wallace2a865272018-02-07 21:00:42 -05001594 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001595 return -1;
1596
Florin Coras7baeb712019-01-04 17:05:43 -08001597 sid = ldp_fd_to_vlsh (fd);
1598 if (sid != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -05001599 {
1600 vppcom_endpt_t ep;
1601 u8 src_addr[sizeof (struct sockaddr_in6)];
1602
Dave Wallace048b1d62018-01-03 22:24:41 -05001603 if (addr)
1604 {
1605 ep.ip = src_addr;
Florin Coras7baeb712019-01-04 17:05:43 -08001606 size = vls_recvfrom (sid, buf, n, flags, &ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05001607
1608 if (size > 0)
Haggai Eran46ae2ef2019-02-19 15:04:42 +02001609 {
1610 rv = ldp_copy_ep_to_sockaddr (addr, addr_len, &ep);
1611 if (rv < 0)
1612 size = rv;
1613 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001614 }
1615 else
Florin Coras7baeb712019-01-04 17:05:43 -08001616 size = vls_recvfrom (sid, buf, n, flags, NULL);
Dave Wallace048b1d62018-01-03 22:24:41 -05001617
1618 if (size < 0)
1619 {
1620 errno = -size;
1621 size = -1;
1622 }
1623 }
1624 else
1625 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001626 size = libc_recvfrom (fd, buf, n, flags, addr, addr_len);
1627 }
1628
Dave Wallace048b1d62018-01-03 22:24:41 -05001629 return size;
1630}
1631
1632ssize_t
1633sendmsg (int fd, const struct msghdr * message, int flags)
1634{
Florin Coras7baeb712019-01-04 17:05:43 -08001635 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05001636 ssize_t size;
Dave Wallace048b1d62018-01-03 22:24:41 -05001637
Dave Wallace2a865272018-02-07 21:00:42 -05001638 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001639 return -1;
1640
Florin Coras7baeb712019-01-04 17:05:43 -08001641 vlsh = ldp_fd_to_vlsh (fd);
1642 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -05001643 {
Florin Coras7baeb712019-01-04 17:05:43 -08001644 LDBG (0, "LDP-TBD");
Dave Wallace048b1d62018-01-03 22:24:41 -05001645 errno = ENOSYS;
1646 size = -1;
1647 }
1648 else
1649 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001650 size = libc_sendmsg (fd, message, flags);
1651 }
1652
Dave Wallace048b1d62018-01-03 22:24:41 -05001653 return size;
1654}
1655
1656#ifdef USE_GNU
1657int
1658sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags)
1659{
1660 ssize_t size;
1661 const char *func_str;
Florin Coras7baeb712019-01-04 17:05:43 -08001662 u32 sh = ldp_fd_to_vlsh (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05001663
Dave Wallace2a865272018-02-07 21:00:42 -05001664 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001665 return -1;
1666
Florin Coras7baeb712019-01-04 17:05:43 -08001667 if (sh != INVALID_SESSION_ID)
Dave Wallace048b1d62018-01-03 22:24:41 -05001668 {
1669 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
1670 errno = ENOSYS;
1671 size = -1;
1672 }
1673 else
1674 {
1675 func_str = "libc_sendmmsg";
1676
Dave Wallace2a865272018-02-07 21:00:42 -05001677 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001678 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1679 "vmessages %p, vlen %u, flags 0x%x",
1680 getpid (), fd, fd, func_str, vmessages, vlen, flags);
1681
1682 size = libc_sendmmsg (fd, vmessages, vlen, flags);
1683 }
1684
Dave Wallace2a865272018-02-07 21:00:42 -05001685 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001686 {
1687 if (size < 0)
1688 {
1689 int errno_val = errno;
1690 perror (func_str);
1691 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1692 "rv %d, errno = %d", getpid (), fd, fd,
1693 func_str, size, errno_val);
1694 errno = errno_val;
1695 }
1696 else
1697 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1698 getpid (), fd, fd, size, size);
1699 }
1700 return size;
1701}
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001702#endif
1703
Dave Wallace048b1d62018-01-03 22:24:41 -05001704ssize_t
1705recvmsg (int fd, struct msghdr * message, int flags)
1706{
Florin Coras7baeb712019-01-04 17:05:43 -08001707 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05001708 ssize_t size;
Dave Wallace048b1d62018-01-03 22:24:41 -05001709
Dave Wallace2a865272018-02-07 21:00:42 -05001710 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001711 return -1;
1712
Florin Coras7baeb712019-01-04 17:05:43 -08001713 vlsh = ldp_fd_to_vlsh (fd);
1714 if (vlsh != VLS_INVALID_HANDLE)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001715 {
Florin Coras7baeb712019-01-04 17:05:43 -08001716 LDBG (0, "LDP-TBD");
Dave Wallace048b1d62018-01-03 22:24:41 -05001717 errno = ENOSYS;
1718 size = -1;
1719 }
1720 else
1721 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001722 size = libc_recvmsg (fd, message, flags);
1723 }
1724
Dave Wallace048b1d62018-01-03 22:24:41 -05001725 return size;
1726}
1727
1728#ifdef USE_GNU
1729int
1730recvmmsg (int fd, struct mmsghdr *vmessages,
1731 unsigned int vlen, int flags, struct timespec *tmo)
1732{
1733 ssize_t size;
1734 const char *func_str;
Florin Coras7baeb712019-01-04 17:05:43 -08001735 u32 sh = ldp_fd_to_vlsh (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05001736
Dave Wallace2a865272018-02-07 21:00:42 -05001737 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001738 return -1;
1739
Florin Coras7baeb712019-01-04 17:05:43 -08001740 if (sh != INVALID_SESSION_ID)
Dave Wallace048b1d62018-01-03 22:24:41 -05001741 {
1742 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
1743 errno = ENOSYS;
1744 size = -1;
1745 }
1746 else
1747 {
1748 func_str = "libc_recvmmsg";
1749
Dave Wallace2a865272018-02-07 21:00:42 -05001750 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001751 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1752 "vmessages %p, vlen %u, flags 0x%x, tmo %p",
1753 getpid (), fd, fd, func_str, vmessages, vlen,
1754 flags, tmo);
1755
1756 size = libc_recvmmsg (fd, vmessages, vlen, flags, tmo);
1757 }
1758
Dave Wallace2a865272018-02-07 21:00:42 -05001759 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001760 {
1761 if (size < 0)
1762 {
1763 int errno_val = errno;
1764 perror (func_str);
1765 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1766 "rv %d, errno = %d", getpid (), fd, fd,
1767 func_str, size, errno_val);
1768 errno = errno_val;
1769 }
1770 else
1771 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1772 getpid (), fd, fd, size, size);
1773 }
1774 return size;
1775}
1776#endif
1777
1778int
1779getsockopt (int fd, int level, int optname,
1780 void *__restrict optval, socklen_t * __restrict optlen)
1781{
Florin Coras7baeb712019-01-04 17:05:43 -08001782 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05001783 int rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001784
Dave Wallace2a865272018-02-07 21:00:42 -05001785 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001786 return -1;
1787
Florin Coras7baeb712019-01-04 17:05:43 -08001788 vlsh = ldp_fd_to_vlsh (fd);
1789 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -05001790 {
1791 rv = -EOPNOTSUPP;
1792
1793 switch (level)
1794 {
1795 case SOL_TCP:
1796 switch (optname)
1797 {
1798 case TCP_NODELAY:
Florin Coras7baeb712019-01-04 17:05:43 -08001799 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_TCP_NODELAY,
1800 optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001801 break;
1802 case TCP_MAXSEG:
Florin Coras7baeb712019-01-04 17:05:43 -08001803 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_TCP_USER_MSS,
1804 optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001805 break;
1806 case TCP_KEEPIDLE:
Florin Coras7baeb712019-01-04 17:05:43 -08001807 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_TCP_KEEPIDLE,
1808 optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001809 break;
1810 case TCP_KEEPINTVL:
Florin Coras7baeb712019-01-04 17:05:43 -08001811 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_TCP_KEEPINTVL,
1812 optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001813 break;
1814 case TCP_INFO:
1815 if (optval && optlen && (*optlen == sizeof (struct tcp_info)))
1816 {
Florin Coras7baeb712019-01-04 17:05:43 -08001817 LDBG (1, "fd %d: vlsh %u SOL_TCP, TCP_INFO, optval %p, "
1818 "optlen %d: #LDP-NOP#", fd, vlsh, optval, *optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001819 memset (optval, 0, *optlen);
1820 rv = VPPCOM_OK;
1821 }
1822 else
1823 rv = -EFAULT;
1824 break;
Florin Coras0ed24e92019-01-21 09:03:10 -08001825 case TCP_CONGESTION:
Florin Coras0ed24e92019-01-21 09:03:10 -08001826 *optlen = strlen ("cubic");
Dave Barach02500902020-04-04 18:34:41 -04001827 strncpy (optval, "cubic", *optlen + 1);
Florin Coras0ed24e92019-01-21 09:03:10 -08001828 rv = 0;
1829 break;
Dave Wallace048b1d62018-01-03 22:24:41 -05001830 default:
Florin Coras7baeb712019-01-04 17:05:43 -08001831 LDBG (0, "ERROR: fd %d: getsockopt SOL_TCP: sid %u, "
1832 "optname %d unsupported!", fd, vlsh, optname);
Dave Wallace048b1d62018-01-03 22:24:41 -05001833 break;
1834 }
1835 break;
1836 case SOL_IPV6:
1837 switch (optname)
1838 {
1839 case IPV6_V6ONLY:
Florin Coras7baeb712019-01-04 17:05:43 -08001840 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_V6ONLY, optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001841 break;
1842 default:
Florin Coras7baeb712019-01-04 17:05:43 -08001843 LDBG (0, "ERROR: fd %d: getsockopt SOL_IPV6: vlsh %u "
1844 "optname %d unsupported!", fd, vlsh, optname);
Dave Wallace048b1d62018-01-03 22:24:41 -05001845 break;
1846 }
1847 break;
1848 case SOL_SOCKET:
1849 switch (optname)
1850 {
1851 case SO_ACCEPTCONN:
Florin Coras7baeb712019-01-04 17:05:43 -08001852 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_LISTEN, optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001853 break;
1854 case SO_KEEPALIVE:
Florin Coras7baeb712019-01-04 17:05:43 -08001855 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_KEEPALIVE, optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001856 break;
1857 case SO_PROTOCOL:
Florin Coras7baeb712019-01-04 17:05:43 -08001858 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_PROTOCOL, optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001859 *(int *) optval = *(int *) optval ? SOCK_DGRAM : SOCK_STREAM;
1860 break;
1861 case SO_SNDBUF:
Florin Coras7baeb712019-01-04 17:05:43 -08001862 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_TX_FIFO_LEN,
1863 optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001864 break;
1865 case SO_RCVBUF:
Florin Coras7baeb712019-01-04 17:05:43 -08001866 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_RX_FIFO_LEN,
1867 optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001868 break;
1869 case SO_REUSEADDR:
Florin Coras7baeb712019-01-04 17:05:43 -08001870 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_REUSEADDR, optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001871 break;
1872 case SO_BROADCAST:
Florin Coras7baeb712019-01-04 17:05:43 -08001873 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_BROADCAST, optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001874 break;
1875 case SO_ERROR:
Florin Coras7baeb712019-01-04 17:05:43 -08001876 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_ERROR, optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001877 break;
1878 default:
Florin Coras7baeb712019-01-04 17:05:43 -08001879 LDBG (0, "ERROR: fd %d: getsockopt SOL_SOCKET: vlsh %u "
1880 "optname %d unsupported!", fd, vlsh, optname);
Dave Wallace048b1d62018-01-03 22:24:41 -05001881 break;
1882 }
1883 break;
1884 default:
1885 break;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001886 }
1887
Dave Wallace048b1d62018-01-03 22:24:41 -05001888 if (rv != VPPCOM_OK)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001889 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001890 errno = -rv;
1891 rv = -1;
1892 }
1893 }
1894 else
1895 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001896 rv = libc_getsockopt (fd, level, optname, optval, optlen);
1897 }
1898
Dave Wallace048b1d62018-01-03 22:24:41 -05001899 return rv;
1900}
1901
1902int
1903setsockopt (int fd, int level, int optname,
1904 const void *optval, socklen_t optlen)
1905{
Florin Coras7baeb712019-01-04 17:05:43 -08001906 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05001907 int rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001908
Dave Wallace2a865272018-02-07 21:00:42 -05001909 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001910 return -1;
1911
Florin Coras7baeb712019-01-04 17:05:43 -08001912 vlsh = ldp_fd_to_vlsh (fd);
1913 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -05001914 {
1915 rv = -EOPNOTSUPP;
1916
1917 switch (level)
1918 {
1919 case SOL_TCP:
1920 switch (optname)
1921 {
1922 case TCP_NODELAY:
Florin Coras7baeb712019-01-04 17:05:43 -08001923 rv = vls_attr (vlsh, VPPCOM_ATTR_SET_TCP_NODELAY,
1924 (void *) optval, &optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001925 break;
1926 case TCP_MAXSEG:
Florin Coras7baeb712019-01-04 17:05:43 -08001927 rv = vls_attr (vlsh, VPPCOM_ATTR_SET_TCP_USER_MSS,
1928 (void *) optval, &optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001929 break;
1930 case TCP_KEEPIDLE:
Florin Coras7baeb712019-01-04 17:05:43 -08001931 rv = vls_attr (vlsh, VPPCOM_ATTR_SET_TCP_KEEPIDLE,
1932 (void *) optval, &optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001933 break;
1934 case TCP_KEEPINTVL:
Florin Coras7baeb712019-01-04 17:05:43 -08001935 rv = vls_attr (vlsh, VPPCOM_ATTR_SET_TCP_KEEPINTVL,
1936 (void *) optval, &optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001937 break;
Florin Coras0ed24e92019-01-21 09:03:10 -08001938 case TCP_CONGESTION:
Florin Coras8509aa22019-04-04 12:55:30 -07001939 case TCP_CORK:
Florin Coras0ed24e92019-01-21 09:03:10 -08001940 /* Ignore */
1941 rv = 0;
1942 break;
Dave Wallace048b1d62018-01-03 22:24:41 -05001943 default:
Florin Coras7baeb712019-01-04 17:05:43 -08001944 LDBG (0, "ERROR: fd %d: setsockopt() SOL_TCP: vlsh %u"
1945 "optname %d unsupported!", fd, vlsh, optname);
Dave Wallace048b1d62018-01-03 22:24:41 -05001946 break;
1947 }
1948 break;
1949 case SOL_IPV6:
1950 switch (optname)
1951 {
1952 case IPV6_V6ONLY:
Florin Coras7baeb712019-01-04 17:05:43 -08001953 rv = vls_attr (vlsh, VPPCOM_ATTR_SET_V6ONLY,
1954 (void *) optval, &optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001955 break;
1956 default:
Florin Coras7baeb712019-01-04 17:05:43 -08001957 LDBG (0, "ERROR: fd %d: setsockopt SOL_IPV6: vlsh %u"
1958 "optname %d unsupported!", fd, vlsh, optname);
Dave Wallace048b1d62018-01-03 22:24:41 -05001959 break;
1960 }
1961 break;
1962 case SOL_SOCKET:
1963 switch (optname)
1964 {
1965 case SO_KEEPALIVE:
Florin Coras7baeb712019-01-04 17:05:43 -08001966 rv = vls_attr (vlsh, VPPCOM_ATTR_SET_KEEPALIVE,
1967 (void *) optval, &optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001968 break;
1969 case SO_REUSEADDR:
Florin Coras7baeb712019-01-04 17:05:43 -08001970 rv = vls_attr (vlsh, VPPCOM_ATTR_SET_REUSEADDR,
1971 (void *) optval, &optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001972 break;
1973 case SO_BROADCAST:
Florin Coras7baeb712019-01-04 17:05:43 -08001974 rv = vls_attr (vlsh, VPPCOM_ATTR_SET_BROADCAST,
1975 (void *) optval, &optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001976 break;
1977 default:
Florin Coras7baeb712019-01-04 17:05:43 -08001978 LDBG (0, "ERROR: fd %d: setsockopt SOL_SOCKET: vlsh %u "
1979 "optname %d unsupported!", fd, vlsh, optname);
Dave Wallace048b1d62018-01-03 22:24:41 -05001980 break;
1981 }
1982 break;
1983 default:
1984 break;
1985 }
1986
1987 if (rv != VPPCOM_OK)
1988 {
1989 errno = -rv;
1990 rv = -1;
1991 }
1992 }
1993 else
1994 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001995 rv = libc_setsockopt (fd, level, optname, optval, optlen);
1996 }
1997
Dave Wallace048b1d62018-01-03 22:24:41 -05001998 return rv;
1999}
2000
2001int
2002listen (int fd, int n)
2003{
Florin Coras7baeb712019-01-04 17:05:43 -08002004 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05002005 int rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05002006
Dave Wallace2a865272018-02-07 21:00:42 -05002007 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002008 return -1;
2009
Florin Coras7baeb712019-01-04 17:05:43 -08002010 vlsh = ldp_fd_to_vlsh (fd);
2011 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -05002012 {
Florin Coras7baeb712019-01-04 17:05:43 -08002013 LDBG (0, "fd %d: calling vls_listen: vlsh %u, n %d", fd, vlsh, n);
Dave Wallace048b1d62018-01-03 22:24:41 -05002014
Florin Coras7baeb712019-01-04 17:05:43 -08002015 rv = vls_listen (vlsh, n);
Dave Wallace048b1d62018-01-03 22:24:41 -05002016 if (rv != VPPCOM_OK)
2017 {
2018 errno = -rv;
2019 rv = -1;
2020 }
2021 }
2022 else
2023 {
Florin Coras7baeb712019-01-04 17:05:43 -08002024 LDBG (0, "fd %d: calling libc_listen(): n %d", fd, n);
Dave Wallace048b1d62018-01-03 22:24:41 -05002025 rv = libc_listen (fd, n);
2026 }
2027
Florin Coras7baeb712019-01-04 17:05:43 -08002028 LDBG (1, "fd %d: returning %d", fd, rv);
Dave Wallace048b1d62018-01-03 22:24:41 -05002029 return rv;
2030}
2031
2032static inline int
Dave Wallace2a865272018-02-07 21:00:42 -05002033ldp_accept4 (int listen_fd, __SOCKADDR_ARG addr,
2034 socklen_t * __restrict addr_len, int flags)
Dave Wallace048b1d62018-01-03 22:24:41 -05002035{
Florin Coras7baeb712019-01-04 17:05:43 -08002036 vls_handle_t listen_vlsh, accept_vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05002037 int rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05002038
Dave Wallace2a865272018-02-07 21:00:42 -05002039 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002040 return -1;
2041
Florin Coras7baeb712019-01-04 17:05:43 -08002042 listen_vlsh = ldp_fd_to_vlsh (listen_fd);
2043 if (listen_vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -05002044 {
2045 vppcom_endpt_t ep;
2046 u8 src_addr[sizeof (struct sockaddr_in6)];
Dave Wallace8aaba562018-01-18 17:21:19 -05002047 memset (&ep, 0, sizeof (ep));
Dave Wallace048b1d62018-01-03 22:24:41 -05002048 ep.ip = src_addr;
2049
Florin Coras7baeb712019-01-04 17:05:43 -08002050 LDBG (0, "listen fd %d: calling vppcom_session_accept: listen sid %u,"
2051 " ep %p, flags 0x%x", listen_fd, listen_vlsh, ep, flags);
Dave Wallace048b1d62018-01-03 22:24:41 -05002052
Florin Coras7baeb712019-01-04 17:05:43 -08002053 accept_vlsh = vls_accept (listen_vlsh, &ep, flags);
2054 if (accept_vlsh < 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002055 {
Florin Coras7baeb712019-01-04 17:05:43 -08002056 errno = -accept_vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05002057 rv = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002058 }
2059 else
2060 {
Dave Wallace2a865272018-02-07 21:00:42 -05002061 rv = ldp_copy_ep_to_sockaddr (addr, addr_len, &ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05002062 if (rv != VPPCOM_OK)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002063 {
Florin Coras7baeb712019-01-04 17:05:43 -08002064 (void) vls_close (accept_vlsh);
Dave Wallace048b1d62018-01-03 22:24:41 -05002065 errno = -rv;
2066 rv = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002067 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002068 else
2069 {
Florin Coras7baeb712019-01-04 17:05:43 -08002070 rv = ldp_vlsh_to_fd (accept_vlsh);
Dave Wallace048b1d62018-01-03 22:24:41 -05002071 }
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002072 }
2073 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002074 else
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002075 {
Florin Coras7baeb712019-01-04 17:05:43 -08002076 LDBG (0, "listen fd %d: calling libc_accept4(): addr %p, addr_len %p,"
2077 " flags 0x%x", listen_fd, addr, addr_len, flags);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002078
Dave Wallace048b1d62018-01-03 22:24:41 -05002079 rv = libc_accept4 (listen_fd, addr, addr_len, flags);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002080 }
2081
Florin Coras7baeb712019-01-04 17:05:43 -08002082 LDBG (1, "listen fd %d: accept returning %d", listen_fd, rv);
Florin Coras05ecfcc2018-12-12 18:19:39 -08002083
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002084 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002085}
2086
Dave Wallace048b1d62018-01-03 22:24:41 -05002087int
2088accept4 (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict addr_len,
2089 int flags)
2090{
Dave Wallace2a865272018-02-07 21:00:42 -05002091 return ldp_accept4 (fd, addr, addr_len, flags);
Dave Wallace048b1d62018-01-03 22:24:41 -05002092}
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002093
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002094int
Dave Wallace048b1d62018-01-03 22:24:41 -05002095accept (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict addr_len)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002096{
Dave Wallace2a865272018-02-07 21:00:42 -05002097 return ldp_accept4 (fd, addr, addr_len, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05002098}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002099
Dave Wallace048b1d62018-01-03 22:24:41 -05002100int
2101shutdown (int fd, int how)
2102{
Florin Coras7baeb712019-01-04 17:05:43 -08002103 vls_handle_t vlsh;
2104 int rv = 0, flags;
2105 u32 flags_len = sizeof (flags);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002106
Dave Wallace2a865272018-02-07 21:00:42 -05002107 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002108 return -1;
2109
Florin Coras7baeb712019-01-04 17:05:43 -08002110 vlsh = ldp_fd_to_vlsh (fd);
2111 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -05002112 {
Florin Coras7baeb712019-01-04 17:05:43 -08002113 LDBG (0, "called shutdown: fd %u vlsh %u how %d", fd, vlsh, how);
Florin Corasa7a1a222018-12-30 17:11:31 -08002114
Florin Coras7baeb712019-01-04 17:05:43 -08002115 if (vls_attr (vlsh, VPPCOM_ATTR_SET_SHUT, &how, &flags_len))
Florin Corasa7a1a222018-12-30 17:11:31 -08002116 {
Florin Coras7baeb712019-01-04 17:05:43 -08002117 close (fd);
Florin Corasa7a1a222018-12-30 17:11:31 -08002118 return -1;
2119 }
2120
Florin Coras7baeb712019-01-04 17:05:43 -08002121 if (vls_attr (vlsh, VPPCOM_ATTR_GET_SHUT, &flags, &flags_len))
2122 {
2123 close (fd);
2124 return -1;
2125 }
Florin Corasa7a1a222018-12-30 17:11:31 -08002126
Florin Coras7baeb712019-01-04 17:05:43 -08002127 if (flags == SHUT_RDWR)
Florin Corasa7a1a222018-12-30 17:11:31 -08002128 rv = close (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002129 }
2130 else
2131 {
Florin Coras7baeb712019-01-04 17:05:43 -08002132 LDBG (0, "fd %d: calling libc_shutdown: how %d", fd, how);
Dave Wallace048b1d62018-01-03 22:24:41 -05002133 rv = libc_shutdown (fd, how);
2134 }
2135
Dave Wallace048b1d62018-01-03 22:24:41 -05002136 return rv;
2137}
2138
2139int
2140epoll_create1 (int flags)
2141{
Florin Corasdfe4cf42018-11-28 22:13:45 -08002142 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
Florin Coras7baeb712019-01-04 17:05:43 -08002143 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05002144 int rv;
2145
Dave Wallace2a865272018-02-07 21:00:42 -05002146 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002147 return -1;
2148
Florin Coras99368312018-08-02 10:45:44 -07002149 if (ldp->vcl_needs_real_epoll)
2150 {
Florin Coras2d9b4272019-03-11 10:14:37 -07002151 /* Make sure workers have been allocated */
2152 if (!ldp->workers)
2153 {
2154 ldp_alloc_workers ();
2155 ldpw = ldp_worker_get_current ();
2156 }
Florin Coras99368312018-08-02 10:45:44 -07002157 rv = libc_epoll_create1 (flags);
2158 ldp->vcl_needs_real_epoll = 0;
Florin Corasdfe4cf42018-11-28 22:13:45 -08002159 ldpw->vcl_mq_epfd = rv;
Florin Coras05ecfcc2018-12-12 18:19:39 -08002160 LDBG (0, "created vcl epfd %u", rv);
Florin Coras99368312018-08-02 10:45:44 -07002161 return rv;
2162 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002163
Florin Coras7baeb712019-01-04 17:05:43 -08002164 vlsh = vls_epoll_create ();
2165 if (PREDICT_FALSE (vlsh == VLS_INVALID_HANDLE))
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002166 {
Florin Coras7baeb712019-01-04 17:05:43 -08002167 errno = -vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05002168 rv = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002169 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002170 else
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002171 {
Florin Coras7baeb712019-01-04 17:05:43 -08002172 rv = ldp_vlsh_to_fd (vlsh);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002173 }
Florin Coras7baeb712019-01-04 17:05:43 -08002174 LDBG (0, "epoll_create epfd %u vlsh %u", rv, vlsh);
Dave Wallace048b1d62018-01-03 22:24:41 -05002175 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002176}
2177
2178int
Dave Wallace048b1d62018-01-03 22:24:41 -05002179epoll_create (int size)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002180{
Dave Wallace048b1d62018-01-03 22:24:41 -05002181 return epoll_create1 (0);
2182}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002183
Dave Wallace048b1d62018-01-03 22:24:41 -05002184int
2185epoll_ctl (int epfd, int op, int fd, struct epoll_event *event)
2186{
Florin Coras7baeb712019-01-04 17:05:43 -08002187 vls_handle_t vep_vlsh, vlsh;
Florin Coras99368312018-08-02 10:45:44 -07002188 int rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05002189
Dave Wallace2a865272018-02-07 21:00:42 -05002190 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002191 return -1;
2192
Florin Coras7baeb712019-01-04 17:05:43 -08002193 vep_vlsh = ldp_fd_to_vlsh (epfd);
2194 if (PREDICT_FALSE (vep_vlsh == VLS_INVALID_HANDLE))
Dave Wallace048b1d62018-01-03 22:24:41 -05002195 {
Dave Wallace3ee1fe12018-02-23 01:09:11 -05002196 /* The LDP epoll_create1 always creates VCL epfd's.
2197 * The app should never have a kernel base epoll fd unless it
2198 * was acquired outside of the LD_PRELOAD process context.
2199 * In any case, if we get one, punt it to libc_epoll_ctl.
2200 */
Florin Coras7baeb712019-01-04 17:05:43 -08002201 LDBG (1, "epfd %d: calling libc_epoll_ctl: op %d, fd %d"
2202 " event %p", epfd, op, fd, event);
Dave Wallace048b1d62018-01-03 22:24:41 -05002203
2204 rv = libc_epoll_ctl (epfd, op, fd, event);
Florin Coras99368312018-08-02 10:45:44 -07002205 goto done;
2206 }
2207
Florin Coras7baeb712019-01-04 17:05:43 -08002208 vlsh = ldp_fd_to_vlsh (fd);
Florin Coras99368312018-08-02 10:45:44 -07002209
Florin Coras7baeb712019-01-04 17:05:43 -08002210 LDBG (0, "epfd %d ep_vlsh %d, fd %u vlsh %d, op %u", epfd, vep_vlsh, fd,
2211 vlsh, op);
Florin Coras99368312018-08-02 10:45:44 -07002212
Florin Coras7baeb712019-01-04 17:05:43 -08002213 if (vlsh != VLS_INVALID_HANDLE)
Florin Coras99368312018-08-02 10:45:44 -07002214 {
Florin Coras7baeb712019-01-04 17:05:43 -08002215 LDBG (1, "epfd %d: calling vls_epoll_ctl: ep_vlsh %d op %d, vlsh %u,"
2216 " event %p", epfd, vep_vlsh, vlsh, event);
Florin Coras99368312018-08-02 10:45:44 -07002217
Florin Coras7baeb712019-01-04 17:05:43 -08002218 rv = vls_epoll_ctl (vep_vlsh, op, vlsh, event);
Florin Coras99368312018-08-02 10:45:44 -07002219 if (rv != VPPCOM_OK)
2220 {
2221 errno = -rv;
2222 rv = -1;
2223 }
2224 }
2225 else
2226 {
2227 int libc_epfd;
2228 u32 size = sizeof (epfd);
2229
Florin Coras7baeb712019-01-04 17:05:43 -08002230 libc_epfd = vls_attr (vep_vlsh, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
Florin Coras99368312018-08-02 10:45:44 -07002231 if (!libc_epfd)
2232 {
Florin Coras7baeb712019-01-04 17:05:43 -08002233 LDBG (1, "epfd %d, vep_vlsh %d calling libc_epoll_create1: "
2234 "EPOLL_CLOEXEC", epfd, vep_vlsh);
Florin Coras99368312018-08-02 10:45:44 -07002235
2236 libc_epfd = libc_epoll_create1 (EPOLL_CLOEXEC);
2237 if (libc_epfd < 0)
2238 {
2239 rv = libc_epfd;
2240 goto done;
2241 }
2242
Florin Coras7baeb712019-01-04 17:05:43 -08002243 rv = vls_attr (vep_vlsh, VPPCOM_ATTR_SET_LIBC_EPFD, &libc_epfd,
2244 &size);
Florin Coras99368312018-08-02 10:45:44 -07002245 if (rv < 0)
2246 {
2247 errno = -rv;
2248 rv = -1;
2249 goto done;
2250 }
2251 }
2252 else if (PREDICT_FALSE (libc_epfd < 0))
2253 {
2254 errno = -epfd;
2255 rv = -1;
2256 goto done;
2257 }
2258
Florin Coras7baeb712019-01-04 17:05:43 -08002259 LDBG (1, "epfd %d: calling libc_epoll_ctl: libc_epfd %d, op %d, fd %d,"
2260 " event %p", epfd, libc_epfd, op, fd, event);
Florin Coras99368312018-08-02 10:45:44 -07002261
2262 rv = libc_epoll_ctl (libc_epfd, op, fd, event);
Dave Wallace048b1d62018-01-03 22:24:41 -05002263 }
2264
2265done:
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002266 return rv;
2267}
Dave Wallace048b1d62018-01-03 22:24:41 -05002268
2269static inline int
Florin Coras99368312018-08-02 10:45:44 -07002270ldp_epoll_pwait (int epfd, struct epoll_event *events, int maxevents,
2271 int timeout, const sigset_t * sigmask)
Dave Wallace048b1d62018-01-03 22:24:41 -05002272{
Florin Corasdfe4cf42018-11-28 22:13:45 -08002273 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
Florin Coras72f77822019-01-22 19:05:52 -08002274 double time_to_wait = (double) 0, max_time;
Florin Coras99368312018-08-02 10:45:44 -07002275 int libc_epfd, rv = 0;
Florin Coras7baeb712019-01-04 17:05:43 -08002276 vls_handle_t ep_vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05002277
Dave Wallace2a865272018-02-07 21:00:42 -05002278 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002279 return -1;
2280
2281 if (PREDICT_FALSE (!events || (timeout < -1)))
2282 {
2283 errno = EFAULT;
2284 return -1;
2285 }
2286
Florin Corasdfe4cf42018-11-28 22:13:45 -08002287 if (epfd == ldpw->vcl_mq_epfd)
Florin Coras99368312018-08-02 10:45:44 -07002288 return libc_epoll_pwait (epfd, events, maxevents, timeout, sigmask);
2289
Florin Coras7baeb712019-01-04 17:05:43 -08002290 ep_vlsh = ldp_fd_to_vlsh (epfd);
2291 if (PREDICT_FALSE (ep_vlsh == VLS_INVALID_HANDLE))
Dave Wallace048b1d62018-01-03 22:24:41 -05002292 {
Florin Coras7baeb712019-01-04 17:05:43 -08002293 LDBG (0, "epfd %d: bad ep_vlsh %d!", epfd, ep_vlsh);
Dave Wallace048b1d62018-01-03 22:24:41 -05002294 errno = EBADFD;
2295 return -1;
2296 }
2297
Florin Coras4dee8cd2019-01-29 21:28:16 -08002298 if (PREDICT_FALSE (ldpw->clib_time.init_cpu_time == 0))
2299 clib_time_init (&ldpw->clib_time);
Florin Corasb0f662f2018-12-27 14:51:46 -08002300 time_to_wait = ((timeout >= 0) ? (double) timeout / 1000 : 0);
Florin Coras72f77822019-01-22 19:05:52 -08002301 max_time = clib_time_now (&ldpw->clib_time) + time_to_wait;
Dave Wallace048b1d62018-01-03 22:24:41 -05002302
Florin Coras7baeb712019-01-04 17:05:43 -08002303 libc_epfd = vls_attr (ep_vlsh, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05002304 if (PREDICT_FALSE (libc_epfd < 0))
2305 {
2306 errno = -libc_epfd;
2307 rv = -1;
2308 goto done;
2309 }
2310
Florin Coras7baeb712019-01-04 17:05:43 -08002311 LDBG (2, "epfd %d: vep_idx %d, libc_epfd %d, events %p, maxevents %d, "
2312 "timeout %d, sigmask %p: time_to_wait %.02f", epfd, ep_vlsh,
Florin Coras72f77822019-01-22 19:05:52 -08002313 libc_epfd, events, maxevents, timeout, sigmask, time_to_wait);
Dave Wallace048b1d62018-01-03 22:24:41 -05002314 do
2315 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08002316 if (!ldpw->epoll_wait_vcl)
Dave Wallace048b1d62018-01-03 22:24:41 -05002317 {
Florin Coras7baeb712019-01-04 17:05:43 -08002318 rv = vls_epoll_wait (ep_vlsh, events, maxevents, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05002319 if (rv > 0)
2320 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08002321 ldpw->epoll_wait_vcl = 1;
Dave Wallace048b1d62018-01-03 22:24:41 -05002322 goto done;
2323 }
2324 else if (rv < 0)
2325 {
2326 errno = -rv;
2327 rv = -1;
2328 goto done;
2329 }
2330 }
2331 else
Florin Corasdfe4cf42018-11-28 22:13:45 -08002332 ldpw->epoll_wait_vcl = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05002333
2334 if (libc_epfd > 0)
2335 {
Florin Corasb0f662f2018-12-27 14:51:46 -08002336 rv = libc_epoll_pwait (libc_epfd, events, maxevents, 0, sigmask);
Dave Wallace048b1d62018-01-03 22:24:41 -05002337 if (rv != 0)
2338 goto done;
2339 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002340 }
Florin Coras72f77822019-01-22 19:05:52 -08002341 while ((timeout == -1) || (clib_time_now (&ldpw->clib_time) < max_time));
Dave Wallace048b1d62018-01-03 22:24:41 -05002342
2343done:
Dave Wallace048b1d62018-01-03 22:24:41 -05002344 return rv;
2345}
2346
2347int
2348epoll_pwait (int epfd, struct epoll_event *events,
2349 int maxevents, int timeout, const sigset_t * sigmask)
2350{
Dave Wallace2a865272018-02-07 21:00:42 -05002351 return ldp_epoll_pwait (epfd, events, maxevents, timeout, sigmask);
Dave Wallace048b1d62018-01-03 22:24:41 -05002352}
2353
2354int
2355epoll_wait (int epfd, struct epoll_event *events, int maxevents, int timeout)
2356{
Dave Wallace2a865272018-02-07 21:00:42 -05002357 return ldp_epoll_pwait (epfd, events, maxevents, timeout, NULL);
Dave Wallace048b1d62018-01-03 22:24:41 -05002358}
2359
2360int
2361poll (struct pollfd *fds, nfds_t nfds, int timeout)
2362{
Florin Corasdfe4cf42018-11-28 22:13:45 -08002363 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
Florin Coras6917b942018-11-13 22:44:54 -08002364 int rv, i, n_revents = 0;
Florin Coras7baeb712019-01-04 17:05:43 -08002365 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05002366 vcl_poll_t *vp;
Florin Coras4dee8cd2019-01-29 21:28:16 -08002367 double max_time;
Dave Wallace048b1d62018-01-03 22:24:41 -05002368
Florin Coras05ecfcc2018-12-12 18:19:39 -08002369 LDBG (3, "fds %p, nfds %d, timeout %d", fds, nfds, timeout);
Dave Wallace048b1d62018-01-03 22:24:41 -05002370
Florin Coras4dee8cd2019-01-29 21:28:16 -08002371 if (PREDICT_FALSE (ldpw->clib_time.init_cpu_time == 0))
2372 clib_time_init (&ldpw->clib_time);
2373
2374 max_time = (timeout >= 0) ? (f64) timeout / 1000 : 0;
2375 max_time += clib_time_now (&ldpw->clib_time);
Dave Wallace048b1d62018-01-03 22:24:41 -05002376
Dave Wallace048b1d62018-01-03 22:24:41 -05002377 for (i = 0; i < nfds; i++)
2378 {
Florin Coras6917b942018-11-13 22:44:54 -08002379 if (fds[i].fd < 0)
2380 continue;
Dave Wallace048b1d62018-01-03 22:24:41 -05002381
Florin Coras7baeb712019-01-04 17:05:43 -08002382 vlsh = ldp_fd_to_vlsh (fds[i].fd);
2383 if (vlsh != VLS_INVALID_HANDLE)
Florin Coras6917b942018-11-13 22:44:54 -08002384 {
2385 fds[i].fd = -fds[i].fd;
Florin Corasdfe4cf42018-11-28 22:13:45 -08002386 vec_add2 (ldpw->vcl_poll, vp, 1);
Florin Coras6917b942018-11-13 22:44:54 -08002387 vp->fds_ndx = i;
Florin Coras7baeb712019-01-04 17:05:43 -08002388 vp->sh = vlsh_to_sh (vlsh);
Florin Coras6917b942018-11-13 22:44:54 -08002389 vp->events = fds[i].events;
Dave Wallace048b1d62018-01-03 22:24:41 -05002390#ifdef __USE_XOPEN2K
Florin Coras6917b942018-11-13 22:44:54 -08002391 if (fds[i].events & POLLRDNORM)
2392 vp->events |= POLLIN;
2393 if (fds[i].events & POLLWRNORM)
2394 vp->events |= POLLOUT;
Dave Wallace048b1d62018-01-03 22:24:41 -05002395#endif
Florin Coras6917b942018-11-13 22:44:54 -08002396 vp->revents = fds[i].revents;
2397 }
2398 else
2399 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08002400 vec_add1 (ldpw->libc_poll, fds[i]);
2401 vec_add1 (ldpw->libc_poll_idxs, i);
Dave Wallace048b1d62018-01-03 22:24:41 -05002402 }
2403 }
2404
Dave Wallace048b1d62018-01-03 22:24:41 -05002405 do
2406 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08002407 if (vec_len (ldpw->vcl_poll))
Dave Wallace048b1d62018-01-03 22:24:41 -05002408 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08002409 rv = vppcom_poll (ldpw->vcl_poll, vec_len (ldpw->vcl_poll), 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05002410 if (rv < 0)
2411 {
2412 errno = -rv;
2413 rv = -1;
2414 goto done;
2415 }
2416 else
2417 n_revents += rv;
2418 }
2419
Florin Corasdfe4cf42018-11-28 22:13:45 -08002420 if (vec_len (ldpw->libc_poll))
Dave Wallace048b1d62018-01-03 22:24:41 -05002421 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08002422 rv = libc_poll (ldpw->libc_poll, vec_len (ldpw->libc_poll), 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05002423 if (rv < 0)
2424 goto done;
2425 else
2426 n_revents += rv;
2427 }
2428
2429 if (n_revents)
2430 {
2431 rv = n_revents;
2432 goto done;
2433 }
2434 }
Florin Coras4dee8cd2019-01-29 21:28:16 -08002435 while ((timeout < 0) || (clib_time_now (&ldpw->clib_time) < max_time));
Dave Wallace048b1d62018-01-03 22:24:41 -05002436 rv = 0;
2437
2438done:
Florin Corasdfe4cf42018-11-28 22:13:45 -08002439 vec_foreach (vp, ldpw->vcl_poll)
Dave Wallace048b1d62018-01-03 22:24:41 -05002440 {
2441 fds[vp->fds_ndx].fd = -fds[vp->fds_ndx].fd;
Florin Coras6917b942018-11-13 22:44:54 -08002442 fds[vp->fds_ndx].revents = vp->revents;
Dave Wallace048b1d62018-01-03 22:24:41 -05002443#ifdef __USE_XOPEN2K
2444 if ((fds[vp->fds_ndx].revents & POLLIN) &&
2445 (fds[vp->fds_ndx].events & POLLRDNORM))
2446 fds[vp->fds_ndx].revents |= POLLRDNORM;
2447 if ((fds[vp->fds_ndx].revents & POLLOUT) &&
2448 (fds[vp->fds_ndx].events & POLLWRNORM))
2449 fds[vp->fds_ndx].revents |= POLLWRNORM;
2450#endif
2451 }
Florin Corasdfe4cf42018-11-28 22:13:45 -08002452 vec_reset_length (ldpw->vcl_poll);
Dave Wallace048b1d62018-01-03 22:24:41 -05002453
Florin Corasdfe4cf42018-11-28 22:13:45 -08002454 for (i = 0; i < vec_len (ldpw->libc_poll); i++)
Florin Coras6917b942018-11-13 22:44:54 -08002455 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08002456 fds[ldpw->libc_poll_idxs[i]].revents = ldpw->libc_poll[i].revents;
Florin Coras6917b942018-11-13 22:44:54 -08002457 }
Florin Corasdfe4cf42018-11-28 22:13:45 -08002458 vec_reset_length (ldpw->libc_poll_idxs);
2459 vec_reset_length (ldpw->libc_poll);
Florin Coras6917b942018-11-13 22:44:54 -08002460
Dave Wallace048b1d62018-01-03 22:24:41 -05002461 return rv;
2462}
2463
2464#ifdef USE_GNU
2465int
2466ppoll (struct pollfd *fds, nfds_t nfds,
2467 const struct timespec *timeout, const sigset_t * sigmask)
2468{
Dave Wallace2a865272018-02-07 21:00:42 -05002469 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002470 return -1;
2471
2472 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
2473 errno = ENOSYS;
2474
2475
2476 return -1;
2477}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002478#endif
2479
Dave Wallace2a865272018-02-07 21:00:42 -05002480void CONSTRUCTOR_ATTRIBUTE ldp_constructor (void);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002481
Dave Wallace2a865272018-02-07 21:00:42 -05002482void DESTRUCTOR_ATTRIBUTE ldp_destructor (void);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002483
Dave Wallace048b1d62018-01-03 22:24:41 -05002484/*
2485 * This function is called when the library is loaded
2486 */
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002487void
Dave Wallace2a865272018-02-07 21:00:42 -05002488ldp_constructor (void)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002489{
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002490 swrap_constructor ();
Dave Wallace2a865272018-02-07 21:00:42 -05002491 if (ldp_init () != 0)
Florin Corasd89411e2019-03-19 19:44:51 -07002492 {
2493 fprintf (stderr, "\nLDP<%d>: ERROR: ldp_constructor: failed!\n",
2494 getpid ());
2495 _exit (1);
2496 }
Dave Wallace69d01192018-02-22 16:22:09 -05002497 else if (LDP_DEBUG > 0)
Dave Wallace2a865272018-02-07 21:00:42 -05002498 clib_warning ("LDP<%d>: LDP constructor: done!\n", getpid ());
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002499}
2500
2501/*
2502 * This function is called when the library is unloaded
2503 */
2504void
Dave Wallace2a865272018-02-07 21:00:42 -05002505ldp_destructor (void)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002506{
Florin Coras0ef8ef22019-01-18 08:37:13 -08002507 /*
2508 swrap_destructor ();
2509 if (ldp->init)
2510 ldp->init = 0;
2511 */
Dave Wallace048b1d62018-01-03 22:24:41 -05002512
2513 /* Don't use clib_warning() here because that calls writev()
Dave Wallace2a865272018-02-07 21:00:42 -05002514 * which will call ldp_init().
Dave Wallace048b1d62018-01-03 22:24:41 -05002515 */
Dave Wallace69d01192018-02-22 16:22:09 -05002516 if (LDP_DEBUG > 0)
Florin Coras0ef8ef22019-01-18 08:37:13 -08002517 fprintf (stderr, "%s:%d: LDP<%d>: LDP destructor: done!\n",
2518 __func__, __LINE__, getpid ());
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002519}
2520
2521
2522/*
2523 * fd.io coding-style-patch-verification: ON
2524 *
2525 * Local Variables:
2526 * eval: (c-set-style "gnu")
2527 * End:
2528 */