blob: d0cf2b913670d1c810de0545df7e1b06b214c9e4 [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 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500383 do
384 {
385 for (i = 0; i < iovcnt; ++i)
386 {
Florin Coras7baeb712019-01-04 17:05:43 -0800387 rv = vls_read (vlsh, iov[i].iov_base, iov[i].iov_len);
Dave Wallace048b1d62018-01-03 22:24:41 -0500388 if (rv < 0)
389 break;
390 else
391 {
392 total += rv;
393 if (rv < iov[i].iov_len)
Florin Coras7baeb712019-01-04 17:05:43 -0800394 break;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700395 }
396 }
397 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500398 while ((rv >= 0) && (total == 0));
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700399
Dave Wallace048b1d62018-01-03 22:24:41 -0500400 if (rv < 0)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700401 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500402 errno = -rv;
403 size = -1;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700404 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500405 else
406 size = total;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700407 }
408 else
409 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500410 size = libc_readv (fd, iov, iovcnt);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700411 }
412
Dave Wallace048b1d62018-01-03 22:24:41 -0500413 return size;
414}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700415
Dave Wallace048b1d62018-01-03 22:24:41 -0500416ssize_t
417write (int fd, const void *buf, size_t nbytes)
418{
Florin Coras7baeb712019-01-04 17:05:43 -0800419 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -0500420 ssize_t size = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500421
Dave Wallace2a865272018-02-07 21:00:42 -0500422 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500423 return -1;
424
Florin Coras7baeb712019-01-04 17:05:43 -0800425 vlsh = ldp_fd_to_vlsh (fd);
426 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -0500427 {
Florin Coras7baeb712019-01-04 17:05:43 -0800428 size = vls_write_msg (vlsh, (void *) buf, nbytes);
Dave Wallace048b1d62018-01-03 22:24:41 -0500429 if (size < 0)
430 {
431 errno = -size;
432 size = -1;
433 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700434 }
435 else
436 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500437 size = libc_write (fd, buf, nbytes);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700438 }
439
Dave Wallace048b1d62018-01-03 22:24:41 -0500440 return size;
441}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700442
Dave Wallace048b1d62018-01-03 22:24:41 -0500443ssize_t
444writev (int fd, const struct iovec * iov, int iovcnt)
445{
Dave Wallace048b1d62018-01-03 22:24:41 -0500446 ssize_t size = 0, total = 0;
Florin Coras7baeb712019-01-04 17:05:43 -0800447 vls_handle_t vlsh;
Dave Wallace8aaba562018-01-18 17:21:19 -0500448 int i, rv = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500449
Dave Wallace2a865272018-02-07 21:00:42 -0500450 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500451 return -1;
452
Florin Coras7baeb712019-01-04 17:05:43 -0800453 vlsh = ldp_fd_to_vlsh (fd);
454 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -0500455 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500456 do
457 {
458 for (i = 0; i < iovcnt; ++i)
459 {
Florin Coras7baeb712019-01-04 17:05:43 -0800460 rv = vls_write_msg (vlsh, iov[i].iov_base, iov[i].iov_len);
Dave Wallace048b1d62018-01-03 22:24:41 -0500461 if (rv < 0)
462 break;
463 else
464 {
465 total += rv;
466 if (rv < iov[i].iov_len)
Florin Corasb0f662f2018-12-27 14:51:46 -0800467 break;
Dave Wallace048b1d62018-01-03 22:24:41 -0500468 }
469 }
470 }
471 while ((rv >= 0) && (total == 0));
472
473 if (rv < 0)
474 {
475 errno = -rv;
476 size = -1;
477 }
478 else
479 size = total;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700480 }
481 else
482 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500483 size = libc_writev (fd, iov, iovcnt);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700484 }
485
Dave Wallace048b1d62018-01-03 22:24:41 -0500486 return size;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700487}
488
Carl Smithe16707b2019-11-13 14:37:39 +1300489#ifdef HAVE_FCNTL64
490int
491fcntl64 (int fd, int cmd, ...)
492#else
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700493int
Dave Wallace048b1d62018-01-03 22:24:41 -0500494fcntl (int fd, int cmd, ...)
Carl Smithe16707b2019-11-13 14:37:39 +1300495#endif
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700496{
Florin Coras7baeb712019-01-04 17:05:43 -0800497 vls_handle_t vlsh;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700498 int rv = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500499 va_list ap;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700500
Dave Wallace2a865272018-02-07 21:00:42 -0500501 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500502 return -1;
503
504 va_start (ap, cmd);
Florin Coras7baeb712019-01-04 17:05:43 -0800505
506 vlsh = ldp_fd_to_vlsh (fd);
507 LDBG (0, "fd %u vlsh %d, cmd %u", fd, vlsh, cmd);
508 if (vlsh != VLS_INVALID_HANDLE)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700509 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500510 int flags = va_arg (ap, int);
511 u32 size;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700512
Dave Wallace048b1d62018-01-03 22:24:41 -0500513 size = sizeof (flags);
514 rv = -EOPNOTSUPP;
515 switch (cmd)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700516 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500517 case F_SETFL:
Florin Coras7baeb712019-01-04 17:05:43 -0800518 rv = vls_attr (vlsh, VPPCOM_ATTR_SET_FLAGS, &flags, &size);
Dave Wallace048b1d62018-01-03 22:24:41 -0500519 break;
520
521 case F_GETFL:
Florin Coras7baeb712019-01-04 17:05:43 -0800522 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_FLAGS, &flags, &size);
Dave Wallace048b1d62018-01-03 22:24:41 -0500523 if (rv == VPPCOM_OK)
Florin Coras7baeb712019-01-04 17:05:43 -0800524 rv = flags;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700525 break;
Florin Coras173bae32018-11-16 18:56:28 -0800526 case F_SETFD:
527 /* TODO handle this */
528 LDBG (0, "F_SETFD ignored flags %u", flags);
529 rv = 0;
530 break;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700531 default:
Dave Wallace048b1d62018-01-03 22:24:41 -0500532 rv = -EOPNOTSUPP;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700533 break;
534 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500535 if (rv < 0)
536 {
537 errno = -rv;
538 rv = -1;
539 }
540 }
541 else
542 {
Carl Smithe16707b2019-11-13 14:37:39 +1300543#ifdef HAVE_FCNTL64
544 rv = libc_vfcntl64 (fd, cmd, ap);
545#else
Dave Wallace048b1d62018-01-03 22:24:41 -0500546 rv = libc_vfcntl (fd, cmd, ap);
Carl Smithe16707b2019-11-13 14:37:39 +1300547#endif
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700548 }
549
Dave Wallace048b1d62018-01-03 22:24:41 -0500550 va_end (ap);
551
Dave Wallace048b1d62018-01-03 22:24:41 -0500552 return rv;
553}
554
555int
556ioctl (int fd, unsigned long int cmd, ...)
557{
Florin Coras7baeb712019-01-04 17:05:43 -0800558 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -0500559 va_list ap;
Florin Coras7baeb712019-01-04 17:05:43 -0800560 int rv;
Dave Wallace048b1d62018-01-03 22:24:41 -0500561
Dave Wallace2a865272018-02-07 21:00:42 -0500562 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500563 return -1;
564
565 va_start (ap, cmd);
Dave Wallace048b1d62018-01-03 22:24:41 -0500566
Florin Coras7baeb712019-01-04 17:05:43 -0800567 vlsh = ldp_fd_to_vlsh (fd);
568 if (vlsh != VLS_INVALID_HANDLE)
569 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500570 switch (cmd)
571 {
572 case FIONREAD:
Florin Coras7baeb712019-01-04 17:05:43 -0800573 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_NREAD, 0, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -0500574 break;
575
576 case FIONBIO:
577 {
578 u32 flags = va_arg (ap, int) ? O_NONBLOCK : 0;
579 u32 size = sizeof (flags);
580
581 /* TBD: When VPPCOM_ATTR_[GS]ET_FLAGS supports flags other than
582 * non-blocking, the flags should be read here and merged
583 * with O_NONBLOCK.
584 */
Florin Coras7baeb712019-01-04 17:05:43 -0800585 rv = vls_attr (vlsh, VPPCOM_ATTR_SET_FLAGS, &flags, &size);
Dave Wallace048b1d62018-01-03 22:24:41 -0500586 }
587 break;
588
589 default:
590 rv = -EOPNOTSUPP;
591 break;
592 }
593 if (rv < 0)
594 {
595 errno = -rv;
596 rv = -1;
597 }
598 }
599 else
600 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500601 rv = libc_vioctl (fd, cmd, ap);
602 }
603
Dave Wallace048b1d62018-01-03 22:24:41 -0500604 va_end (ap);
605 return rv;
606}
607
Florin Coras294afe22019-01-07 17:49:17 -0800608always_inline void
609ldp_select_init_maps (fd_set * __restrict original,
610 clib_bitmap_t ** resultb, clib_bitmap_t ** libcb,
611 clib_bitmap_t ** vclb, int nfds, u32 minbits,
612 u32 n_bytes, uword * si_bits, uword * libc_bits)
613{
614 uword si_bits_set, libc_bits_set;
615 vls_handle_t vlsh;
616 int fd;
617
618 clib_bitmap_validate (*vclb, minbits);
619 clib_bitmap_validate (*libcb, minbits);
620 clib_bitmap_validate (*resultb, minbits);
621 clib_memcpy_fast (*resultb, original, n_bytes);
622 memset (original, 0, n_bytes);
623
624 /* *INDENT-OFF* */
625 clib_bitmap_foreach (fd, *resultb, ({
626 if (fd > nfds)
627 break;
628 vlsh = ldp_fd_to_vlsh (fd);
629 if (vlsh == VLS_INVALID_HANDLE)
630 clib_bitmap_set_no_check (*libcb, fd, 1);
631 else
632 clib_bitmap_set_no_check (*vclb, vlsh_to_session_index (vlsh), 1);
633 }));
634 /* *INDENT-ON* */
635
636 si_bits_set = clib_bitmap_last_set (*vclb) + 1;
637 *si_bits = (si_bits_set > *si_bits) ? si_bits_set : *si_bits;
638
639 libc_bits_set = clib_bitmap_last_set (*libcb) + 1;
640 *libc_bits = (libc_bits_set > *libc_bits) ? libc_bits_set : *libc_bits;
641}
642
643always_inline int
644ldp_select_vcl_map_to_libc (clib_bitmap_t * vclb, fd_set * __restrict libcb)
645{
646 vls_handle_t vlsh;
647 uword si;
648 int fd;
649
650 if (!libcb)
651 return 0;
652
653 /* *INDENT-OFF* */
654 clib_bitmap_foreach (si, vclb, ({
655 vlsh = vls_session_index_to_vlsh (si);
Florin Coras54140622020-02-04 19:04:34 +0000656 ASSERT (vlsh != VLS_INVALID_HANDLE);
Florin Coras294afe22019-01-07 17:49:17 -0800657 fd = ldp_vlsh_to_fd (vlsh);
658 if (PREDICT_FALSE (fd < 0))
659 {
660 errno = EBADFD;
661 return -1;
662 }
663 FD_SET (fd, libcb);
664 }));
665 /* *INDENT-ON* */
666
667 return 0;
668}
669
670always_inline void
671ldp_select_libc_map_merge (clib_bitmap_t * result, fd_set * __restrict libcb)
672{
673 uword fd;
674
Florin Coras78b5fa62019-02-21 20:04:15 -0800675 if (!libcb)
676 return;
677
Florin Coras294afe22019-01-07 17:49:17 -0800678 /* *INDENT-OFF* */
679 clib_bitmap_foreach (fd, result, ({
680 FD_SET ((int)fd, libcb);
681 }));
682 /* *INDENT-ON* */
683}
684
Dave Wallace048b1d62018-01-03 22:24:41 -0500685int
Dave Wallace2a865272018-02-07 21:00:42 -0500686ldp_pselect (int nfds, fd_set * __restrict readfds,
687 fd_set * __restrict writefds,
688 fd_set * __restrict exceptfds,
689 const struct timespec *__restrict timeout,
690 const __sigset_t * __restrict sigmask)
Dave Wallace048b1d62018-01-03 22:24:41 -0500691{
Florin Coras294afe22019-01-07 17:49:17 -0800692 u32 minbits = clib_max (nfds, BITS (uword)), n_bytes;
Florin Corasdfe4cf42018-11-28 22:13:45 -0800693 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
Florin Coras294afe22019-01-07 17:49:17 -0800694 struct timespec libc_tspec = { 0 };
695 f64 time_out, vcl_timeout = 0;
696 uword si_bits, libc_bits;
697 int rv, bits_set = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500698
699 if (nfds < 0)
700 {
701 errno = EINVAL;
702 return -1;
703 }
704
Florin Coras4dee8cd2019-01-29 21:28:16 -0800705 if (PREDICT_FALSE (ldpw->clib_time.init_cpu_time == 0))
706 clib_time_init (&ldpw->clib_time);
707
Dave Wallace3ee1fe12018-02-23 01:09:11 -0500708 if (timeout)
709 {
710 time_out = (timeout->tv_sec == 0 && timeout->tv_nsec == 0) ?
Florin Coras7baeb712019-01-04 17:05:43 -0800711 (f64) 0 : (f64) timeout->tv_sec + (f64) timeout->tv_nsec / (f64) 1e9;
Dave Wallace3ee1fe12018-02-23 01:09:11 -0500712
713 /* select as fine grained sleep */
714 if (!nfds)
715 {
Florin Corasdfe4cf42018-11-28 22:13:45 -0800716 time_out += clib_time_now (&ldpw->clib_time);
717 while (clib_time_now (&ldpw->clib_time) < time_out)
Dave Wallace3ee1fe12018-02-23 01:09:11 -0500718 ;
719 return 0;
720 }
721 }
722 else if (!nfds)
723 {
724 errno = EINVAL;
725 return -1;
726 }
727 else
728 time_out = -1;
729
Florin Coras7baeb712019-01-04 17:05:43 -0800730 if (nfds <= ldp->vlsh_bit_val)
Dave Wallace048b1d62018-01-03 22:24:41 -0500731 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500732 rv = libc_pselect (nfds, readfds, writefds, exceptfds,
733 timeout, sigmask);
734 goto done;
735 }
736
Florin Coras294afe22019-01-07 17:49:17 -0800737 si_bits = libc_bits = 0;
738 n_bytes = nfds / 8 + ((nfds % 8) ? 1 : 0);
Florin Coras7baeb712019-01-04 17:05:43 -0800739
Dave Wallace048b1d62018-01-03 22:24:41 -0500740 if (readfds)
Florin Coras294afe22019-01-07 17:49:17 -0800741 ldp_select_init_maps (readfds, &ldpw->rd_bitmap, &ldpw->libc_rd_bitmap,
742 &ldpw->si_rd_bitmap, nfds, minbits, n_bytes,
743 &si_bits, &libc_bits);
Dave Wallace048b1d62018-01-03 22:24:41 -0500744 if (writefds)
Florin Coras294afe22019-01-07 17:49:17 -0800745 ldp_select_init_maps (writefds, &ldpw->wr_bitmap,
746 &ldpw->libc_wr_bitmap, &ldpw->si_wr_bitmap, nfds,
747 minbits, n_bytes, &si_bits, &libc_bits);
Dave Wallace048b1d62018-01-03 22:24:41 -0500748 if (exceptfds)
Florin Coras294afe22019-01-07 17:49:17 -0800749 ldp_select_init_maps (exceptfds, &ldpw->ex_bitmap,
750 &ldpw->libc_ex_bitmap, &ldpw->si_ex_bitmap, nfds,
751 minbits, n_bytes, &si_bits, &libc_bits);
Dave Wallace048b1d62018-01-03 22:24:41 -0500752
Florin Coras294afe22019-01-07 17:49:17 -0800753 if (PREDICT_FALSE (!si_bits && !libc_bits))
Dave Wallace048b1d62018-01-03 22:24:41 -0500754 {
755 errno = EINVAL;
756 rv = -1;
757 goto done;
758 }
759
Florin Coras78b5fa62019-02-21 20:04:15 -0800760 if (!si_bits)
761 libc_tspec = timeout ? *timeout : libc_tspec;
Florin Coras294afe22019-01-07 17:49:17 -0800762
Dave Wallace048b1d62018-01-03 22:24:41 -0500763 do
764 {
Florin Coras294afe22019-01-07 17:49:17 -0800765 if (si_bits)
Dave Wallace048b1d62018-01-03 22:24:41 -0500766 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500767 if (readfds)
Florin Coras294afe22019-01-07 17:49:17 -0800768 clib_memcpy_fast (ldpw->rd_bitmap, ldpw->si_rd_bitmap,
Florin Corasdfe4cf42018-11-28 22:13:45 -0800769 vec_len (ldpw->rd_bitmap) *
Dave Barach178cf492018-11-13 16:34:13 -0500770 sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -0500771 if (writefds)
Florin Coras294afe22019-01-07 17:49:17 -0800772 clib_memcpy_fast (ldpw->wr_bitmap, ldpw->si_wr_bitmap,
Florin Corasdfe4cf42018-11-28 22:13:45 -0800773 vec_len (ldpw->wr_bitmap) *
Dave Barach178cf492018-11-13 16:34:13 -0500774 sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -0500775 if (exceptfds)
Florin Coras294afe22019-01-07 17:49:17 -0800776 clib_memcpy_fast (ldpw->ex_bitmap, ldpw->si_ex_bitmap,
Florin Corasdfe4cf42018-11-28 22:13:45 -0800777 vec_len (ldpw->ex_bitmap) *
Dave Barach178cf492018-11-13 16:34:13 -0500778 sizeof (clib_bitmap_t));
Florin Coras294afe22019-01-07 17:49:17 -0800779
Florin Coras0ef8ef22019-01-18 08:37:13 -0800780 rv = vls_select (si_bits, readfds ? ldpw->rd_bitmap : NULL,
781 writefds ? ldpw->wr_bitmap : NULL,
782 exceptfds ? ldpw->ex_bitmap : NULL, vcl_timeout);
Florin Coras294afe22019-01-07 17:49:17 -0800783 if (rv < 0)
784 {
785 errno = -rv;
786 rv = -1;
787 }
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 Corasa7a1a222018-12-30 17:11:31 -08001514 errno = -size;
Dave Wallace048b1d62018-01-03 22:24:41 -05001515 }
1516 else
1517 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001518 size = libc_recv (fd, buf, n, flags);
1519 }
1520
Dave Wallace048b1d62018-01-03 22:24:41 -05001521 return size;
1522}
1523
1524ssize_t
1525sendto (int fd, const void *buf, size_t n, int flags,
1526 __CONST_SOCKADDR_ARG addr, socklen_t addr_len)
1527{
Florin Coras7baeb712019-01-04 17:05:43 -08001528 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05001529 ssize_t size;
Dave Wallace048b1d62018-01-03 22:24:41 -05001530
Dave Wallace2a865272018-02-07 21:00:42 -05001531 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001532 return -1;
1533
Florin Coras7baeb712019-01-04 17:05:43 -08001534 vlsh = ldp_fd_to_vlsh (fd);
1535 if (vlsh != INVALID_SESSION_ID)
Dave Wallace048b1d62018-01-03 22:24:41 -05001536 {
1537 vppcom_endpt_t *ep = 0;
1538 vppcom_endpt_t _ep;
1539
1540 if (addr)
1541 {
1542 ep = &_ep;
Dave Wallace048b1d62018-01-03 22:24:41 -05001543 switch (addr->sa_family)
1544 {
1545 case AF_INET:
1546 ep->is_ip4 = VPPCOM_IS_IP4;
1547 ep->ip =
1548 (uint8_t *) & ((const struct sockaddr_in *) addr)->sin_addr;
1549 ep->port =
1550 (uint16_t) ((const struct sockaddr_in *) addr)->sin_port;
1551 break;
1552
1553 case AF_INET6:
1554 ep->is_ip4 = VPPCOM_IS_IP6;
1555 ep->ip =
1556 (uint8_t *) & ((const struct sockaddr_in6 *) addr)->sin6_addr;
1557 ep->port =
1558 (uint16_t) ((const struct sockaddr_in6 *) addr)->sin6_port;
1559 break;
1560
1561 default:
1562 errno = EAFNOSUPPORT;
1563 size = -1;
1564 goto done;
1565 }
1566 }
1567
Florin Coras7baeb712019-01-04 17:05:43 -08001568 size = vls_sendto (vlsh, (void *) buf, n, flags, ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05001569 if (size < 0)
1570 {
1571 errno = -size;
1572 size = -1;
1573 }
1574 }
1575 else
1576 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001577 size = libc_sendto (fd, buf, n, flags, addr, addr_len);
1578 }
1579
1580done:
Dave Wallace048b1d62018-01-03 22:24:41 -05001581 return size;
1582}
1583
1584ssize_t
1585recvfrom (int fd, void *__restrict buf, size_t n, int flags,
1586 __SOCKADDR_ARG addr, socklen_t * __restrict addr_len)
1587{
Florin Coras7baeb712019-01-04 17:05:43 -08001588 vls_handle_t sid;
Haggai Eran46ae2ef2019-02-19 15:04:42 +02001589 ssize_t size, rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001590
Dave Wallace2a865272018-02-07 21:00:42 -05001591 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001592 return -1;
1593
Florin Coras7baeb712019-01-04 17:05:43 -08001594 sid = ldp_fd_to_vlsh (fd);
1595 if (sid != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -05001596 {
1597 vppcom_endpt_t ep;
1598 u8 src_addr[sizeof (struct sockaddr_in6)];
1599
Dave Wallace048b1d62018-01-03 22:24:41 -05001600 if (addr)
1601 {
1602 ep.ip = src_addr;
Florin Coras7baeb712019-01-04 17:05:43 -08001603 size = vls_recvfrom (sid, buf, n, flags, &ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05001604
1605 if (size > 0)
Haggai Eran46ae2ef2019-02-19 15:04:42 +02001606 {
1607 rv = ldp_copy_ep_to_sockaddr (addr, addr_len, &ep);
1608 if (rv < 0)
1609 size = rv;
1610 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001611 }
1612 else
Florin Coras7baeb712019-01-04 17:05:43 -08001613 size = vls_recvfrom (sid, buf, n, flags, NULL);
Dave Wallace048b1d62018-01-03 22:24:41 -05001614
1615 if (size < 0)
1616 {
1617 errno = -size;
1618 size = -1;
1619 }
1620 }
1621 else
1622 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001623 size = libc_recvfrom (fd, buf, n, flags, addr, addr_len);
1624 }
1625
Dave Wallace048b1d62018-01-03 22:24:41 -05001626 return size;
1627}
1628
1629ssize_t
1630sendmsg (int fd, const struct msghdr * message, int flags)
1631{
Florin Coras7baeb712019-01-04 17:05:43 -08001632 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05001633 ssize_t size;
Dave Wallace048b1d62018-01-03 22:24:41 -05001634
Dave Wallace2a865272018-02-07 21:00:42 -05001635 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001636 return -1;
1637
Florin Coras7baeb712019-01-04 17:05:43 -08001638 vlsh = ldp_fd_to_vlsh (fd);
1639 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -05001640 {
Florin Coras7baeb712019-01-04 17:05:43 -08001641 LDBG (0, "LDP-TBD");
Dave Wallace048b1d62018-01-03 22:24:41 -05001642 errno = ENOSYS;
1643 size = -1;
1644 }
1645 else
1646 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001647 size = libc_sendmsg (fd, message, flags);
1648 }
1649
Dave Wallace048b1d62018-01-03 22:24:41 -05001650 return size;
1651}
1652
1653#ifdef USE_GNU
1654int
1655sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags)
1656{
1657 ssize_t size;
1658 const char *func_str;
Florin Coras7baeb712019-01-04 17:05:43 -08001659 u32 sh = ldp_fd_to_vlsh (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05001660
Dave Wallace2a865272018-02-07 21:00:42 -05001661 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001662 return -1;
1663
Florin Coras7baeb712019-01-04 17:05:43 -08001664 if (sh != INVALID_SESSION_ID)
Dave Wallace048b1d62018-01-03 22:24:41 -05001665 {
1666 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
1667 errno = ENOSYS;
1668 size = -1;
1669 }
1670 else
1671 {
1672 func_str = "libc_sendmmsg";
1673
Dave Wallace2a865272018-02-07 21:00:42 -05001674 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001675 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1676 "vmessages %p, vlen %u, flags 0x%x",
1677 getpid (), fd, fd, func_str, vmessages, vlen, flags);
1678
1679 size = libc_sendmmsg (fd, vmessages, vlen, flags);
1680 }
1681
Dave Wallace2a865272018-02-07 21:00:42 -05001682 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001683 {
1684 if (size < 0)
1685 {
1686 int errno_val = errno;
1687 perror (func_str);
1688 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1689 "rv %d, errno = %d", getpid (), fd, fd,
1690 func_str, size, errno_val);
1691 errno = errno_val;
1692 }
1693 else
1694 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1695 getpid (), fd, fd, size, size);
1696 }
1697 return size;
1698}
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001699#endif
1700
Dave Wallace048b1d62018-01-03 22:24:41 -05001701ssize_t
1702recvmsg (int fd, struct msghdr * message, int flags)
1703{
Florin Coras7baeb712019-01-04 17:05:43 -08001704 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05001705 ssize_t size;
Dave Wallace048b1d62018-01-03 22:24:41 -05001706
Dave Wallace2a865272018-02-07 21:00:42 -05001707 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001708 return -1;
1709
Florin Coras7baeb712019-01-04 17:05:43 -08001710 vlsh = ldp_fd_to_vlsh (fd);
1711 if (vlsh != VLS_INVALID_HANDLE)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001712 {
Florin Coras7baeb712019-01-04 17:05:43 -08001713 LDBG (0, "LDP-TBD");
Dave Wallace048b1d62018-01-03 22:24:41 -05001714 errno = ENOSYS;
1715 size = -1;
1716 }
1717 else
1718 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001719 size = libc_recvmsg (fd, message, flags);
1720 }
1721
Dave Wallace048b1d62018-01-03 22:24:41 -05001722 return size;
1723}
1724
1725#ifdef USE_GNU
1726int
1727recvmmsg (int fd, struct mmsghdr *vmessages,
1728 unsigned int vlen, int flags, struct timespec *tmo)
1729{
1730 ssize_t size;
1731 const char *func_str;
Florin Coras7baeb712019-01-04 17:05:43 -08001732 u32 sh = ldp_fd_to_vlsh (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05001733
Dave Wallace2a865272018-02-07 21:00:42 -05001734 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001735 return -1;
1736
Florin Coras7baeb712019-01-04 17:05:43 -08001737 if (sh != INVALID_SESSION_ID)
Dave Wallace048b1d62018-01-03 22:24:41 -05001738 {
1739 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
1740 errno = ENOSYS;
1741 size = -1;
1742 }
1743 else
1744 {
1745 func_str = "libc_recvmmsg";
1746
Dave Wallace2a865272018-02-07 21:00:42 -05001747 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001748 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1749 "vmessages %p, vlen %u, flags 0x%x, tmo %p",
1750 getpid (), fd, fd, func_str, vmessages, vlen,
1751 flags, tmo);
1752
1753 size = libc_recvmmsg (fd, vmessages, vlen, flags, tmo);
1754 }
1755
Dave Wallace2a865272018-02-07 21:00:42 -05001756 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001757 {
1758 if (size < 0)
1759 {
1760 int errno_val = errno;
1761 perror (func_str);
1762 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1763 "rv %d, errno = %d", getpid (), fd, fd,
1764 func_str, size, errno_val);
1765 errno = errno_val;
1766 }
1767 else
1768 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1769 getpid (), fd, fd, size, size);
1770 }
1771 return size;
1772}
1773#endif
1774
1775int
1776getsockopt (int fd, int level, int optname,
1777 void *__restrict optval, socklen_t * __restrict optlen)
1778{
Florin Coras7baeb712019-01-04 17:05:43 -08001779 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05001780 int rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001781
Dave Wallace2a865272018-02-07 21:00:42 -05001782 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001783 return -1;
1784
Florin Coras7baeb712019-01-04 17:05:43 -08001785 vlsh = ldp_fd_to_vlsh (fd);
1786 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -05001787 {
1788 rv = -EOPNOTSUPP;
1789
1790 switch (level)
1791 {
1792 case SOL_TCP:
1793 switch (optname)
1794 {
1795 case TCP_NODELAY:
Florin Coras7baeb712019-01-04 17:05:43 -08001796 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_TCP_NODELAY,
1797 optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001798 break;
1799 case TCP_MAXSEG:
Florin Coras7baeb712019-01-04 17:05:43 -08001800 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_TCP_USER_MSS,
1801 optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001802 break;
1803 case TCP_KEEPIDLE:
Florin Coras7baeb712019-01-04 17:05:43 -08001804 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_TCP_KEEPIDLE,
1805 optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001806 break;
1807 case TCP_KEEPINTVL:
Florin Coras7baeb712019-01-04 17:05:43 -08001808 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_TCP_KEEPINTVL,
1809 optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001810 break;
1811 case TCP_INFO:
1812 if (optval && optlen && (*optlen == sizeof (struct tcp_info)))
1813 {
Florin Coras7baeb712019-01-04 17:05:43 -08001814 LDBG (1, "fd %d: vlsh %u SOL_TCP, TCP_INFO, optval %p, "
1815 "optlen %d: #LDP-NOP#", fd, vlsh, optval, *optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001816 memset (optval, 0, *optlen);
1817 rv = VPPCOM_OK;
1818 }
1819 else
1820 rv = -EFAULT;
1821 break;
Florin Coras0ed24e92019-01-21 09:03:10 -08001822 case TCP_CONGESTION:
1823 strcpy (optval, "cubic");
1824 *optlen = strlen ("cubic");
1825 rv = 0;
1826 break;
Dave Wallace048b1d62018-01-03 22:24:41 -05001827 default:
Florin Coras7baeb712019-01-04 17:05:43 -08001828 LDBG (0, "ERROR: fd %d: getsockopt SOL_TCP: sid %u, "
1829 "optname %d unsupported!", fd, vlsh, optname);
Dave Wallace048b1d62018-01-03 22:24:41 -05001830 break;
1831 }
1832 break;
1833 case SOL_IPV6:
1834 switch (optname)
1835 {
1836 case IPV6_V6ONLY:
Florin Coras7baeb712019-01-04 17:05:43 -08001837 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_V6ONLY, optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001838 break;
1839 default:
Florin Coras7baeb712019-01-04 17:05:43 -08001840 LDBG (0, "ERROR: fd %d: getsockopt SOL_IPV6: vlsh %u "
1841 "optname %d unsupported!", fd, vlsh, optname);
Dave Wallace048b1d62018-01-03 22:24:41 -05001842 break;
1843 }
1844 break;
1845 case SOL_SOCKET:
1846 switch (optname)
1847 {
1848 case SO_ACCEPTCONN:
Florin Coras7baeb712019-01-04 17:05:43 -08001849 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_LISTEN, optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001850 break;
1851 case SO_KEEPALIVE:
Florin Coras7baeb712019-01-04 17:05:43 -08001852 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_KEEPALIVE, optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001853 break;
1854 case SO_PROTOCOL:
Florin Coras7baeb712019-01-04 17:05:43 -08001855 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_PROTOCOL, optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001856 *(int *) optval = *(int *) optval ? SOCK_DGRAM : SOCK_STREAM;
1857 break;
1858 case SO_SNDBUF:
Florin Coras7baeb712019-01-04 17:05:43 -08001859 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_TX_FIFO_LEN,
1860 optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001861 break;
1862 case SO_RCVBUF:
Florin Coras7baeb712019-01-04 17:05:43 -08001863 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_RX_FIFO_LEN,
1864 optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001865 break;
1866 case SO_REUSEADDR:
Florin Coras7baeb712019-01-04 17:05:43 -08001867 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_REUSEADDR, optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001868 break;
1869 case SO_BROADCAST:
Florin Coras7baeb712019-01-04 17:05:43 -08001870 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_BROADCAST, optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001871 break;
1872 case SO_ERROR:
Florin Coras7baeb712019-01-04 17:05:43 -08001873 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_ERROR, optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001874 break;
1875 default:
Florin Coras7baeb712019-01-04 17:05:43 -08001876 LDBG (0, "ERROR: fd %d: getsockopt SOL_SOCKET: vlsh %u "
1877 "optname %d unsupported!", fd, vlsh, optname);
Dave Wallace048b1d62018-01-03 22:24:41 -05001878 break;
1879 }
1880 break;
1881 default:
1882 break;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001883 }
1884
Dave Wallace048b1d62018-01-03 22:24:41 -05001885 if (rv != VPPCOM_OK)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001886 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001887 errno = -rv;
1888 rv = -1;
1889 }
1890 }
1891 else
1892 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001893 rv = libc_getsockopt (fd, level, optname, optval, optlen);
1894 }
1895
Dave Wallace048b1d62018-01-03 22:24:41 -05001896 return rv;
1897}
1898
1899int
1900setsockopt (int fd, int level, int optname,
1901 const void *optval, socklen_t optlen)
1902{
Florin Coras7baeb712019-01-04 17:05:43 -08001903 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05001904 int rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001905
Dave Wallace2a865272018-02-07 21:00:42 -05001906 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001907 return -1;
1908
Florin Coras7baeb712019-01-04 17:05:43 -08001909 vlsh = ldp_fd_to_vlsh (fd);
1910 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -05001911 {
1912 rv = -EOPNOTSUPP;
1913
1914 switch (level)
1915 {
1916 case SOL_TCP:
1917 switch (optname)
1918 {
1919 case TCP_NODELAY:
Florin Coras7baeb712019-01-04 17:05:43 -08001920 rv = vls_attr (vlsh, VPPCOM_ATTR_SET_TCP_NODELAY,
1921 (void *) optval, &optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001922 break;
1923 case TCP_MAXSEG:
Florin Coras7baeb712019-01-04 17:05:43 -08001924 rv = vls_attr (vlsh, VPPCOM_ATTR_SET_TCP_USER_MSS,
1925 (void *) optval, &optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001926 break;
1927 case TCP_KEEPIDLE:
Florin Coras7baeb712019-01-04 17:05:43 -08001928 rv = vls_attr (vlsh, VPPCOM_ATTR_SET_TCP_KEEPIDLE,
1929 (void *) optval, &optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001930 break;
1931 case TCP_KEEPINTVL:
Florin Coras7baeb712019-01-04 17:05:43 -08001932 rv = vls_attr (vlsh, VPPCOM_ATTR_SET_TCP_KEEPINTVL,
1933 (void *) optval, &optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001934 break;
Florin Coras0ed24e92019-01-21 09:03:10 -08001935 case TCP_CONGESTION:
Florin Coras8509aa22019-04-04 12:55:30 -07001936 case TCP_CORK:
Florin Coras0ed24e92019-01-21 09:03:10 -08001937 /* Ignore */
1938 rv = 0;
1939 break;
Dave Wallace048b1d62018-01-03 22:24:41 -05001940 default:
Florin Coras7baeb712019-01-04 17:05:43 -08001941 LDBG (0, "ERROR: fd %d: setsockopt() SOL_TCP: vlsh %u"
1942 "optname %d unsupported!", fd, vlsh, optname);
Dave Wallace048b1d62018-01-03 22:24:41 -05001943 break;
1944 }
1945 break;
1946 case SOL_IPV6:
1947 switch (optname)
1948 {
1949 case IPV6_V6ONLY:
Florin Coras7baeb712019-01-04 17:05:43 -08001950 rv = vls_attr (vlsh, VPPCOM_ATTR_SET_V6ONLY,
1951 (void *) optval, &optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001952 break;
1953 default:
Florin Coras7baeb712019-01-04 17:05:43 -08001954 LDBG (0, "ERROR: fd %d: setsockopt SOL_IPV6: vlsh %u"
1955 "optname %d unsupported!", fd, vlsh, optname);
Dave Wallace048b1d62018-01-03 22:24:41 -05001956 break;
1957 }
1958 break;
1959 case SOL_SOCKET:
1960 switch (optname)
1961 {
1962 case SO_KEEPALIVE:
Florin Coras7baeb712019-01-04 17:05:43 -08001963 rv = vls_attr (vlsh, VPPCOM_ATTR_SET_KEEPALIVE,
1964 (void *) optval, &optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001965 break;
1966 case SO_REUSEADDR:
Florin Coras7baeb712019-01-04 17:05:43 -08001967 rv = vls_attr (vlsh, VPPCOM_ATTR_SET_REUSEADDR,
1968 (void *) optval, &optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001969 break;
1970 case SO_BROADCAST:
Florin Coras7baeb712019-01-04 17:05:43 -08001971 rv = vls_attr (vlsh, VPPCOM_ATTR_SET_BROADCAST,
1972 (void *) optval, &optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001973 break;
1974 default:
Florin Coras7baeb712019-01-04 17:05:43 -08001975 LDBG (0, "ERROR: fd %d: setsockopt SOL_SOCKET: vlsh %u "
1976 "optname %d unsupported!", fd, vlsh, optname);
Dave Wallace048b1d62018-01-03 22:24:41 -05001977 break;
1978 }
1979 break;
1980 default:
1981 break;
1982 }
1983
1984 if (rv != VPPCOM_OK)
1985 {
1986 errno = -rv;
1987 rv = -1;
1988 }
1989 }
1990 else
1991 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001992 rv = libc_setsockopt (fd, level, optname, optval, optlen);
1993 }
1994
Dave Wallace048b1d62018-01-03 22:24:41 -05001995 return rv;
1996}
1997
1998int
1999listen (int fd, int n)
2000{
Florin Coras7baeb712019-01-04 17:05:43 -08002001 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05002002 int rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05002003
Dave Wallace2a865272018-02-07 21:00:42 -05002004 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002005 return -1;
2006
Florin Coras7baeb712019-01-04 17:05:43 -08002007 vlsh = ldp_fd_to_vlsh (fd);
2008 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -05002009 {
Florin Coras7baeb712019-01-04 17:05:43 -08002010 LDBG (0, "fd %d: calling vls_listen: vlsh %u, n %d", fd, vlsh, n);
Dave Wallace048b1d62018-01-03 22:24:41 -05002011
Florin Coras7baeb712019-01-04 17:05:43 -08002012 rv = vls_listen (vlsh, n);
Dave Wallace048b1d62018-01-03 22:24:41 -05002013 if (rv != VPPCOM_OK)
2014 {
2015 errno = -rv;
2016 rv = -1;
2017 }
2018 }
2019 else
2020 {
Florin Coras7baeb712019-01-04 17:05:43 -08002021 LDBG (0, "fd %d: calling libc_listen(): n %d", fd, n);
Dave Wallace048b1d62018-01-03 22:24:41 -05002022 rv = libc_listen (fd, n);
2023 }
2024
Florin Coras7baeb712019-01-04 17:05:43 -08002025 LDBG (1, "fd %d: returning %d", fd, rv);
Dave Wallace048b1d62018-01-03 22:24:41 -05002026 return rv;
2027}
2028
2029static inline int
Dave Wallace2a865272018-02-07 21:00:42 -05002030ldp_accept4 (int listen_fd, __SOCKADDR_ARG addr,
2031 socklen_t * __restrict addr_len, int flags)
Dave Wallace048b1d62018-01-03 22:24:41 -05002032{
Florin Coras7baeb712019-01-04 17:05:43 -08002033 vls_handle_t listen_vlsh, accept_vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05002034 int rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05002035
Dave Wallace2a865272018-02-07 21:00:42 -05002036 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002037 return -1;
2038
Florin Coras7baeb712019-01-04 17:05:43 -08002039 listen_vlsh = ldp_fd_to_vlsh (listen_fd);
2040 if (listen_vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -05002041 {
2042 vppcom_endpt_t ep;
2043 u8 src_addr[sizeof (struct sockaddr_in6)];
Dave Wallace8aaba562018-01-18 17:21:19 -05002044 memset (&ep, 0, sizeof (ep));
Dave Wallace048b1d62018-01-03 22:24:41 -05002045 ep.ip = src_addr;
2046
Florin Coras7baeb712019-01-04 17:05:43 -08002047 LDBG (0, "listen fd %d: calling vppcom_session_accept: listen sid %u,"
2048 " ep %p, flags 0x%x", listen_fd, listen_vlsh, ep, flags);
Dave Wallace048b1d62018-01-03 22:24:41 -05002049
Florin Coras7baeb712019-01-04 17:05:43 -08002050 accept_vlsh = vls_accept (listen_vlsh, &ep, flags);
2051 if (accept_vlsh < 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002052 {
Florin Coras7baeb712019-01-04 17:05:43 -08002053 errno = -accept_vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05002054 rv = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002055 }
2056 else
2057 {
Dave Wallace2a865272018-02-07 21:00:42 -05002058 rv = ldp_copy_ep_to_sockaddr (addr, addr_len, &ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05002059 if (rv != VPPCOM_OK)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002060 {
Florin Coras7baeb712019-01-04 17:05:43 -08002061 (void) vls_close (accept_vlsh);
Dave Wallace048b1d62018-01-03 22:24:41 -05002062 errno = -rv;
2063 rv = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002064 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002065 else
2066 {
Florin Coras7baeb712019-01-04 17:05:43 -08002067 rv = ldp_vlsh_to_fd (accept_vlsh);
Dave Wallace048b1d62018-01-03 22:24:41 -05002068 }
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002069 }
2070 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002071 else
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002072 {
Florin Coras7baeb712019-01-04 17:05:43 -08002073 LDBG (0, "listen fd %d: calling libc_accept4(): addr %p, addr_len %p,"
2074 " flags 0x%x", listen_fd, addr, addr_len, flags);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002075
Dave Wallace048b1d62018-01-03 22:24:41 -05002076 rv = libc_accept4 (listen_fd, addr, addr_len, flags);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002077 }
2078
Florin Coras7baeb712019-01-04 17:05:43 -08002079 LDBG (1, "listen fd %d: accept returning %d", listen_fd, rv);
Florin Coras05ecfcc2018-12-12 18:19:39 -08002080
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002081 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002082}
2083
Dave Wallace048b1d62018-01-03 22:24:41 -05002084int
2085accept4 (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict addr_len,
2086 int flags)
2087{
Dave Wallace2a865272018-02-07 21:00:42 -05002088 return ldp_accept4 (fd, addr, addr_len, flags);
Dave Wallace048b1d62018-01-03 22:24:41 -05002089}
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002090
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002091int
Dave Wallace048b1d62018-01-03 22:24:41 -05002092accept (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict addr_len)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002093{
Dave Wallace2a865272018-02-07 21:00:42 -05002094 return ldp_accept4 (fd, addr, addr_len, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05002095}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002096
Dave Wallace048b1d62018-01-03 22:24:41 -05002097int
2098shutdown (int fd, int how)
2099{
Florin Coras7baeb712019-01-04 17:05:43 -08002100 vls_handle_t vlsh;
2101 int rv = 0, flags;
2102 u32 flags_len = sizeof (flags);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002103
Dave Wallace2a865272018-02-07 21:00:42 -05002104 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002105 return -1;
2106
Florin Coras7baeb712019-01-04 17:05:43 -08002107 vlsh = ldp_fd_to_vlsh (fd);
2108 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -05002109 {
Florin Coras7baeb712019-01-04 17:05:43 -08002110 LDBG (0, "called shutdown: fd %u vlsh %u how %d", fd, vlsh, how);
Florin Corasa7a1a222018-12-30 17:11:31 -08002111
Florin Coras7baeb712019-01-04 17:05:43 -08002112 if (vls_attr (vlsh, VPPCOM_ATTR_SET_SHUT, &how, &flags_len))
Florin Corasa7a1a222018-12-30 17:11:31 -08002113 {
Florin Coras7baeb712019-01-04 17:05:43 -08002114 close (fd);
Florin Corasa7a1a222018-12-30 17:11:31 -08002115 return -1;
2116 }
2117
Florin Coras7baeb712019-01-04 17:05:43 -08002118 if (vls_attr (vlsh, VPPCOM_ATTR_GET_SHUT, &flags, &flags_len))
2119 {
2120 close (fd);
2121 return -1;
2122 }
Florin Corasa7a1a222018-12-30 17:11:31 -08002123
Florin Coras7baeb712019-01-04 17:05:43 -08002124 if (flags == SHUT_RDWR)
Florin Corasa7a1a222018-12-30 17:11:31 -08002125 rv = close (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002126 }
2127 else
2128 {
Florin Coras7baeb712019-01-04 17:05:43 -08002129 LDBG (0, "fd %d: calling libc_shutdown: how %d", fd, how);
Dave Wallace048b1d62018-01-03 22:24:41 -05002130 rv = libc_shutdown (fd, how);
2131 }
2132
Dave Wallace048b1d62018-01-03 22:24:41 -05002133 return rv;
2134}
2135
2136int
2137epoll_create1 (int flags)
2138{
Florin Corasdfe4cf42018-11-28 22:13:45 -08002139 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
Florin Coras7baeb712019-01-04 17:05:43 -08002140 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05002141 int rv;
2142
Dave Wallace2a865272018-02-07 21:00:42 -05002143 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002144 return -1;
2145
Florin Coras99368312018-08-02 10:45:44 -07002146 if (ldp->vcl_needs_real_epoll)
2147 {
Florin Coras2d9b4272019-03-11 10:14:37 -07002148 /* Make sure workers have been allocated */
2149 if (!ldp->workers)
2150 {
2151 ldp_alloc_workers ();
2152 ldpw = ldp_worker_get_current ();
2153 }
Florin Coras99368312018-08-02 10:45:44 -07002154 rv = libc_epoll_create1 (flags);
2155 ldp->vcl_needs_real_epoll = 0;
Florin Corasdfe4cf42018-11-28 22:13:45 -08002156 ldpw->vcl_mq_epfd = rv;
Florin Coras05ecfcc2018-12-12 18:19:39 -08002157 LDBG (0, "created vcl epfd %u", rv);
Florin Coras99368312018-08-02 10:45:44 -07002158 return rv;
2159 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002160
Florin Coras7baeb712019-01-04 17:05:43 -08002161 vlsh = vls_epoll_create ();
2162 if (PREDICT_FALSE (vlsh == VLS_INVALID_HANDLE))
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002163 {
Florin Coras7baeb712019-01-04 17:05:43 -08002164 errno = -vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05002165 rv = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002166 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002167 else
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002168 {
Florin Coras7baeb712019-01-04 17:05:43 -08002169 rv = ldp_vlsh_to_fd (vlsh);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002170 }
Florin Coras7baeb712019-01-04 17:05:43 -08002171 LDBG (0, "epoll_create epfd %u vlsh %u", rv, vlsh);
Dave Wallace048b1d62018-01-03 22:24:41 -05002172 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002173}
2174
2175int
Dave Wallace048b1d62018-01-03 22:24:41 -05002176epoll_create (int size)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002177{
Dave Wallace048b1d62018-01-03 22:24:41 -05002178 return epoll_create1 (0);
2179}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002180
Dave Wallace048b1d62018-01-03 22:24:41 -05002181int
2182epoll_ctl (int epfd, int op, int fd, struct epoll_event *event)
2183{
Florin Coras7baeb712019-01-04 17:05:43 -08002184 vls_handle_t vep_vlsh, vlsh;
Florin Coras99368312018-08-02 10:45:44 -07002185 int rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05002186
Dave Wallace2a865272018-02-07 21:00:42 -05002187 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002188 return -1;
2189
Florin Coras7baeb712019-01-04 17:05:43 -08002190 vep_vlsh = ldp_fd_to_vlsh (epfd);
2191 if (PREDICT_FALSE (vep_vlsh == VLS_INVALID_HANDLE))
Dave Wallace048b1d62018-01-03 22:24:41 -05002192 {
Dave Wallace3ee1fe12018-02-23 01:09:11 -05002193 /* The LDP epoll_create1 always creates VCL epfd's.
2194 * The app should never have a kernel base epoll fd unless it
2195 * was acquired outside of the LD_PRELOAD process context.
2196 * In any case, if we get one, punt it to libc_epoll_ctl.
2197 */
Florin Coras7baeb712019-01-04 17:05:43 -08002198 LDBG (1, "epfd %d: calling libc_epoll_ctl: op %d, fd %d"
2199 " event %p", epfd, op, fd, event);
Dave Wallace048b1d62018-01-03 22:24:41 -05002200
2201 rv = libc_epoll_ctl (epfd, op, fd, event);
Florin Coras99368312018-08-02 10:45:44 -07002202 goto done;
2203 }
2204
Florin Coras7baeb712019-01-04 17:05:43 -08002205 vlsh = ldp_fd_to_vlsh (fd);
Florin Coras99368312018-08-02 10:45:44 -07002206
Florin Coras7baeb712019-01-04 17:05:43 -08002207 LDBG (0, "epfd %d ep_vlsh %d, fd %u vlsh %d, op %u", epfd, vep_vlsh, fd,
2208 vlsh, op);
Florin Coras99368312018-08-02 10:45:44 -07002209
Florin Coras7baeb712019-01-04 17:05:43 -08002210 if (vlsh != VLS_INVALID_HANDLE)
Florin Coras99368312018-08-02 10:45:44 -07002211 {
Florin Coras7baeb712019-01-04 17:05:43 -08002212 LDBG (1, "epfd %d: calling vls_epoll_ctl: ep_vlsh %d op %d, vlsh %u,"
2213 " event %p", epfd, vep_vlsh, vlsh, event);
Florin Coras99368312018-08-02 10:45:44 -07002214
Florin Coras7baeb712019-01-04 17:05:43 -08002215 rv = vls_epoll_ctl (vep_vlsh, op, vlsh, event);
Florin Coras99368312018-08-02 10:45:44 -07002216 if (rv != VPPCOM_OK)
2217 {
2218 errno = -rv;
2219 rv = -1;
2220 }
2221 }
2222 else
2223 {
2224 int libc_epfd;
2225 u32 size = sizeof (epfd);
2226
Florin Coras7baeb712019-01-04 17:05:43 -08002227 libc_epfd = vls_attr (vep_vlsh, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
Florin Coras99368312018-08-02 10:45:44 -07002228 if (!libc_epfd)
2229 {
Florin Coras7baeb712019-01-04 17:05:43 -08002230 LDBG (1, "epfd %d, vep_vlsh %d calling libc_epoll_create1: "
2231 "EPOLL_CLOEXEC", epfd, vep_vlsh);
Florin Coras99368312018-08-02 10:45:44 -07002232
2233 libc_epfd = libc_epoll_create1 (EPOLL_CLOEXEC);
2234 if (libc_epfd < 0)
2235 {
2236 rv = libc_epfd;
2237 goto done;
2238 }
2239
Florin Coras7baeb712019-01-04 17:05:43 -08002240 rv = vls_attr (vep_vlsh, VPPCOM_ATTR_SET_LIBC_EPFD, &libc_epfd,
2241 &size);
Florin Coras99368312018-08-02 10:45:44 -07002242 if (rv < 0)
2243 {
2244 errno = -rv;
2245 rv = -1;
2246 goto done;
2247 }
2248 }
2249 else if (PREDICT_FALSE (libc_epfd < 0))
2250 {
2251 errno = -epfd;
2252 rv = -1;
2253 goto done;
2254 }
2255
Florin Coras7baeb712019-01-04 17:05:43 -08002256 LDBG (1, "epfd %d: calling libc_epoll_ctl: libc_epfd %d, op %d, fd %d,"
2257 " event %p", epfd, libc_epfd, op, fd, event);
Florin Coras99368312018-08-02 10:45:44 -07002258
2259 rv = libc_epoll_ctl (libc_epfd, op, fd, event);
Dave Wallace048b1d62018-01-03 22:24:41 -05002260 }
2261
2262done:
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002263 return rv;
2264}
Dave Wallace048b1d62018-01-03 22:24:41 -05002265
2266static inline int
Florin Coras99368312018-08-02 10:45:44 -07002267ldp_epoll_pwait (int epfd, struct epoll_event *events, int maxevents,
2268 int timeout, const sigset_t * sigmask)
Dave Wallace048b1d62018-01-03 22:24:41 -05002269{
Florin Corasdfe4cf42018-11-28 22:13:45 -08002270 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
Florin Coras72f77822019-01-22 19:05:52 -08002271 double time_to_wait = (double) 0, max_time;
Florin Coras99368312018-08-02 10:45:44 -07002272 int libc_epfd, rv = 0;
Florin Coras7baeb712019-01-04 17:05:43 -08002273 vls_handle_t ep_vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05002274
Dave Wallace2a865272018-02-07 21:00:42 -05002275 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002276 return -1;
2277
2278 if (PREDICT_FALSE (!events || (timeout < -1)))
2279 {
2280 errno = EFAULT;
2281 return -1;
2282 }
2283
Florin Corasdfe4cf42018-11-28 22:13:45 -08002284 if (epfd == ldpw->vcl_mq_epfd)
Florin Coras99368312018-08-02 10:45:44 -07002285 return libc_epoll_pwait (epfd, events, maxevents, timeout, sigmask);
2286
Florin Coras7baeb712019-01-04 17:05:43 -08002287 ep_vlsh = ldp_fd_to_vlsh (epfd);
2288 if (PREDICT_FALSE (ep_vlsh == VLS_INVALID_HANDLE))
Dave Wallace048b1d62018-01-03 22:24:41 -05002289 {
Florin Coras7baeb712019-01-04 17:05:43 -08002290 LDBG (0, "epfd %d: bad ep_vlsh %d!", epfd, ep_vlsh);
Dave Wallace048b1d62018-01-03 22:24:41 -05002291 errno = EBADFD;
2292 return -1;
2293 }
2294
Florin Coras4dee8cd2019-01-29 21:28:16 -08002295 if (PREDICT_FALSE (ldpw->clib_time.init_cpu_time == 0))
2296 clib_time_init (&ldpw->clib_time);
Florin Corasb0f662f2018-12-27 14:51:46 -08002297 time_to_wait = ((timeout >= 0) ? (double) timeout / 1000 : 0);
Florin Coras72f77822019-01-22 19:05:52 -08002298 max_time = clib_time_now (&ldpw->clib_time) + time_to_wait;
Dave Wallace048b1d62018-01-03 22:24:41 -05002299
Florin Coras7baeb712019-01-04 17:05:43 -08002300 libc_epfd = vls_attr (ep_vlsh, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05002301 if (PREDICT_FALSE (libc_epfd < 0))
2302 {
2303 errno = -libc_epfd;
2304 rv = -1;
2305 goto done;
2306 }
2307
Florin Coras7baeb712019-01-04 17:05:43 -08002308 LDBG (2, "epfd %d: vep_idx %d, libc_epfd %d, events %p, maxevents %d, "
2309 "timeout %d, sigmask %p: time_to_wait %.02f", epfd, ep_vlsh,
Florin Coras72f77822019-01-22 19:05:52 -08002310 libc_epfd, events, maxevents, timeout, sigmask, time_to_wait);
Dave Wallace048b1d62018-01-03 22:24:41 -05002311 do
2312 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08002313 if (!ldpw->epoll_wait_vcl)
Dave Wallace048b1d62018-01-03 22:24:41 -05002314 {
Florin Coras7baeb712019-01-04 17:05:43 -08002315 rv = vls_epoll_wait (ep_vlsh, events, maxevents, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05002316 if (rv > 0)
2317 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08002318 ldpw->epoll_wait_vcl = 1;
Dave Wallace048b1d62018-01-03 22:24:41 -05002319 goto done;
2320 }
2321 else if (rv < 0)
2322 {
2323 errno = -rv;
2324 rv = -1;
2325 goto done;
2326 }
2327 }
2328 else
Florin Corasdfe4cf42018-11-28 22:13:45 -08002329 ldpw->epoll_wait_vcl = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05002330
2331 if (libc_epfd > 0)
2332 {
Florin Corasb0f662f2018-12-27 14:51:46 -08002333 rv = libc_epoll_pwait (libc_epfd, events, maxevents, 0, sigmask);
Dave Wallace048b1d62018-01-03 22:24:41 -05002334 if (rv != 0)
2335 goto done;
2336 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002337 }
Florin Coras72f77822019-01-22 19:05:52 -08002338 while ((timeout == -1) || (clib_time_now (&ldpw->clib_time) < max_time));
Dave Wallace048b1d62018-01-03 22:24:41 -05002339
2340done:
Dave Wallace048b1d62018-01-03 22:24:41 -05002341 return rv;
2342}
2343
2344int
2345epoll_pwait (int epfd, struct epoll_event *events,
2346 int maxevents, int timeout, const sigset_t * sigmask)
2347{
Dave Wallace2a865272018-02-07 21:00:42 -05002348 return ldp_epoll_pwait (epfd, events, maxevents, timeout, sigmask);
Dave Wallace048b1d62018-01-03 22:24:41 -05002349}
2350
2351int
2352epoll_wait (int epfd, struct epoll_event *events, int maxevents, int timeout)
2353{
Dave Wallace2a865272018-02-07 21:00:42 -05002354 return ldp_epoll_pwait (epfd, events, maxevents, timeout, NULL);
Dave Wallace048b1d62018-01-03 22:24:41 -05002355}
2356
2357int
2358poll (struct pollfd *fds, nfds_t nfds, int timeout)
2359{
Florin Corasdfe4cf42018-11-28 22:13:45 -08002360 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
Florin Coras6917b942018-11-13 22:44:54 -08002361 int rv, i, n_revents = 0;
Florin Coras7baeb712019-01-04 17:05:43 -08002362 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05002363 vcl_poll_t *vp;
Florin Coras4dee8cd2019-01-29 21:28:16 -08002364 double max_time;
Dave Wallace048b1d62018-01-03 22:24:41 -05002365
Florin Coras05ecfcc2018-12-12 18:19:39 -08002366 LDBG (3, "fds %p, nfds %d, timeout %d", fds, nfds, timeout);
Dave Wallace048b1d62018-01-03 22:24:41 -05002367
Florin Coras4dee8cd2019-01-29 21:28:16 -08002368 if (PREDICT_FALSE (ldpw->clib_time.init_cpu_time == 0))
2369 clib_time_init (&ldpw->clib_time);
2370
2371 max_time = (timeout >= 0) ? (f64) timeout / 1000 : 0;
2372 max_time += clib_time_now (&ldpw->clib_time);
Dave Wallace048b1d62018-01-03 22:24:41 -05002373
Dave Wallace048b1d62018-01-03 22:24:41 -05002374 for (i = 0; i < nfds; i++)
2375 {
Florin Coras6917b942018-11-13 22:44:54 -08002376 if (fds[i].fd < 0)
2377 continue;
Dave Wallace048b1d62018-01-03 22:24:41 -05002378
Florin Coras7baeb712019-01-04 17:05:43 -08002379 vlsh = ldp_fd_to_vlsh (fds[i].fd);
2380 if (vlsh != VLS_INVALID_HANDLE)
Florin Coras6917b942018-11-13 22:44:54 -08002381 {
2382 fds[i].fd = -fds[i].fd;
Florin Corasdfe4cf42018-11-28 22:13:45 -08002383 vec_add2 (ldpw->vcl_poll, vp, 1);
Florin Coras6917b942018-11-13 22:44:54 -08002384 vp->fds_ndx = i;
Florin Coras7baeb712019-01-04 17:05:43 -08002385 vp->sh = vlsh_to_sh (vlsh);
Florin Coras6917b942018-11-13 22:44:54 -08002386 vp->events = fds[i].events;
Dave Wallace048b1d62018-01-03 22:24:41 -05002387#ifdef __USE_XOPEN2K
Florin Coras6917b942018-11-13 22:44:54 -08002388 if (fds[i].events & POLLRDNORM)
2389 vp->events |= POLLIN;
2390 if (fds[i].events & POLLWRNORM)
2391 vp->events |= POLLOUT;
Dave Wallace048b1d62018-01-03 22:24:41 -05002392#endif
Florin Coras6917b942018-11-13 22:44:54 -08002393 vp->revents = fds[i].revents;
2394 }
2395 else
2396 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08002397 vec_add1 (ldpw->libc_poll, fds[i]);
2398 vec_add1 (ldpw->libc_poll_idxs, i);
Dave Wallace048b1d62018-01-03 22:24:41 -05002399 }
2400 }
2401
Dave Wallace048b1d62018-01-03 22:24:41 -05002402 do
2403 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08002404 if (vec_len (ldpw->vcl_poll))
Dave Wallace048b1d62018-01-03 22:24:41 -05002405 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08002406 rv = vppcom_poll (ldpw->vcl_poll, vec_len (ldpw->vcl_poll), 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05002407 if (rv < 0)
2408 {
2409 errno = -rv;
2410 rv = -1;
2411 goto done;
2412 }
2413 else
2414 n_revents += rv;
2415 }
2416
Florin Corasdfe4cf42018-11-28 22:13:45 -08002417 if (vec_len (ldpw->libc_poll))
Dave Wallace048b1d62018-01-03 22:24:41 -05002418 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08002419 rv = libc_poll (ldpw->libc_poll, vec_len (ldpw->libc_poll), 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05002420 if (rv < 0)
2421 goto done;
2422 else
2423 n_revents += rv;
2424 }
2425
2426 if (n_revents)
2427 {
2428 rv = n_revents;
2429 goto done;
2430 }
2431 }
Florin Coras4dee8cd2019-01-29 21:28:16 -08002432 while ((timeout < 0) || (clib_time_now (&ldpw->clib_time) < max_time));
Dave Wallace048b1d62018-01-03 22:24:41 -05002433 rv = 0;
2434
2435done:
Florin Corasdfe4cf42018-11-28 22:13:45 -08002436 vec_foreach (vp, ldpw->vcl_poll)
Dave Wallace048b1d62018-01-03 22:24:41 -05002437 {
2438 fds[vp->fds_ndx].fd = -fds[vp->fds_ndx].fd;
Florin Coras6917b942018-11-13 22:44:54 -08002439 fds[vp->fds_ndx].revents = vp->revents;
Dave Wallace048b1d62018-01-03 22:24:41 -05002440#ifdef __USE_XOPEN2K
2441 if ((fds[vp->fds_ndx].revents & POLLIN) &&
2442 (fds[vp->fds_ndx].events & POLLRDNORM))
2443 fds[vp->fds_ndx].revents |= POLLRDNORM;
2444 if ((fds[vp->fds_ndx].revents & POLLOUT) &&
2445 (fds[vp->fds_ndx].events & POLLWRNORM))
2446 fds[vp->fds_ndx].revents |= POLLWRNORM;
2447#endif
2448 }
Florin Corasdfe4cf42018-11-28 22:13:45 -08002449 vec_reset_length (ldpw->vcl_poll);
Dave Wallace048b1d62018-01-03 22:24:41 -05002450
Florin Corasdfe4cf42018-11-28 22:13:45 -08002451 for (i = 0; i < vec_len (ldpw->libc_poll); i++)
Florin Coras6917b942018-11-13 22:44:54 -08002452 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08002453 fds[ldpw->libc_poll_idxs[i]].revents = ldpw->libc_poll[i].revents;
Florin Coras6917b942018-11-13 22:44:54 -08002454 }
Florin Corasdfe4cf42018-11-28 22:13:45 -08002455 vec_reset_length (ldpw->libc_poll_idxs);
2456 vec_reset_length (ldpw->libc_poll);
Florin Coras6917b942018-11-13 22:44:54 -08002457
Dave Wallace048b1d62018-01-03 22:24:41 -05002458 return rv;
2459}
2460
2461#ifdef USE_GNU
2462int
2463ppoll (struct pollfd *fds, nfds_t nfds,
2464 const struct timespec *timeout, const sigset_t * sigmask)
2465{
Dave Wallace2a865272018-02-07 21:00:42 -05002466 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002467 return -1;
2468
2469 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
2470 errno = ENOSYS;
2471
2472
2473 return -1;
2474}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002475#endif
2476
Dave Wallace2a865272018-02-07 21:00:42 -05002477void CONSTRUCTOR_ATTRIBUTE ldp_constructor (void);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002478
Dave Wallace2a865272018-02-07 21:00:42 -05002479void DESTRUCTOR_ATTRIBUTE ldp_destructor (void);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002480
Dave Wallace048b1d62018-01-03 22:24:41 -05002481/*
2482 * This function is called when the library is loaded
2483 */
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002484void
Dave Wallace2a865272018-02-07 21:00:42 -05002485ldp_constructor (void)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002486{
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002487 swrap_constructor ();
Dave Wallace2a865272018-02-07 21:00:42 -05002488 if (ldp_init () != 0)
Florin Corasd89411e2019-03-19 19:44:51 -07002489 {
2490 fprintf (stderr, "\nLDP<%d>: ERROR: ldp_constructor: failed!\n",
2491 getpid ());
2492 _exit (1);
2493 }
Dave Wallace69d01192018-02-22 16:22:09 -05002494 else if (LDP_DEBUG > 0)
Dave Wallace2a865272018-02-07 21:00:42 -05002495 clib_warning ("LDP<%d>: LDP constructor: done!\n", getpid ());
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002496}
2497
2498/*
2499 * This function is called when the library is unloaded
2500 */
2501void
Dave Wallace2a865272018-02-07 21:00:42 -05002502ldp_destructor (void)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002503{
Florin Coras0ef8ef22019-01-18 08:37:13 -08002504 /*
2505 swrap_destructor ();
2506 if (ldp->init)
2507 ldp->init = 0;
2508 */
Dave Wallace048b1d62018-01-03 22:24:41 -05002509
2510 /* Don't use clib_warning() here because that calls writev()
Dave Wallace2a865272018-02-07 21:00:42 -05002511 * which will call ldp_init().
Dave Wallace048b1d62018-01-03 22:24:41 -05002512 */
Dave Wallace69d01192018-02-22 16:22:09 -05002513 if (LDP_DEBUG > 0)
Florin Coras0ef8ef22019-01-18 08:37:13 -08002514 fprintf (stderr, "%s:%d: LDP<%d>: LDP destructor: done!\n",
2515 __func__, __LINE__, getpid ());
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002516}
2517
2518
2519/*
2520 * fd.io coding-style-patch-verification: ON
2521 *
2522 * Local Variables:
2523 * eval: (c-set-style "gnu")
2524 * End:
2525 */