blob: 1c038b0a10230419b725900af41a81675650155f [file] [log] [blame]
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001/*
2 * Copyright (c) 2016 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15#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;
65 clib_bitmap_t *sid_rd_bitmap;
66 clib_bitmap_t *sid_wr_bitmap;
67 clib_bitmap_t *sid_ex_bitmap;
68 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 u8 select_vcl;
72
73 /*
74 * Poll state
75 */
Dave Wallace048b1d62018-01-03 22:24:41 -050076 vcl_poll_t *vcl_poll;
Florin Coras6917b942018-11-13 22:44:54 -080077 struct pollfd *libc_poll;
78 u16 *libc_poll_idxs;
Florin Corasdfe4cf42018-11-28 22:13:45 -080079
80 /*
81 * Epoll state
82 */
Dave Wallace048b1d62018-01-03 22:24:41 -050083 u8 epoll_wait_vcl;
Florin Coras99368312018-08-02 10:45:44 -070084 int vcl_mq_epfd;
Florin Corasdfe4cf42018-11-28 22:13:45 -080085
86} ldp_worker_ctx_t;
87
88typedef struct
89{
90 ldp_worker_ctx_t *workers;
91 int init;
92 char app_name[LDP_APP_NAME_MAX];
Florin Coras7baeb712019-01-04 17:05:43 -080093 u32 vlsh_bit_val;
94 u32 vlsh_bit_mask;
Florin Corasdfe4cf42018-11-28 22:13:45 -080095 u32 debug;
Florin Corasdfe4cf42018-11-28 22:13:45 -080096
97 /** vcl needs next epoll_create to go to libc_epoll */
98 u8 vcl_needs_real_epoll;
Dave Wallace2a865272018-02-07 21:00:42 -050099} ldp_main_t;
Florin Corasdfe4cf42018-11-28 22:13:45 -0800100
Dave Wallace2a865272018-02-07 21:00:42 -0500101#define LDP_DEBUG ldp->debug
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700102
Florin Coras99368312018-08-02 10:45:44 -0700103#define LDBG(_lvl, _fmt, _args...) \
104 if (ldp->debug > _lvl) \
Florin Coras05ecfcc2018-12-12 18:19:39 -0800105 clib_warning ("ldp<%d>: " _fmt, getpid(), ##_args)
Florin Coras99368312018-08-02 10:45:44 -0700106
Dave Wallace2a865272018-02-07 21:00:42 -0500107static ldp_main_t ldp_main = {
Florin Coras7baeb712019-01-04 17:05:43 -0800108 .vlsh_bit_val = (1 << LDP_SID_BIT_MIN),
109 .vlsh_bit_mask = (1 << LDP_SID_BIT_MIN) - 1,
Dave Wallace2a865272018-02-07 21:00:42 -0500110 .debug = LDP_DEBUG_INIT,
Dave Wallace048b1d62018-01-03 22:24:41 -0500111};
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700112
Dave Wallace2a865272018-02-07 21:00:42 -0500113static ldp_main_t *ldp = &ldp_main;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700114
Florin Corasdfe4cf42018-11-28 22:13:45 -0800115static inline ldp_worker_ctx_t *
116ldp_worker_get_current (void)
117{
118 return (ldp->workers + vppcom_worker_index ());
119}
120
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700121/*
122 * RETURN: 0 on success or -1 on error.
123 * */
Dave Wallace048b1d62018-01-03 22:24:41 -0500124static inline void
Dave Wallace2a865272018-02-07 21:00:42 -0500125ldp_set_app_name (char *app_name)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700126{
Dave Wallace2a865272018-02-07 21:00:42 -0500127 int rv = snprintf (ldp->app_name, LDP_APP_NAME_MAX,
128 "ldp-%d-%s", getpid (), app_name);
Dave Wallace048b1d62018-01-03 22:24:41 -0500129
Dave Wallace2a865272018-02-07 21:00:42 -0500130 if (rv >= LDP_APP_NAME_MAX)
131 app_name[LDP_APP_NAME_MAX - 1] = 0;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700132}
133
Dave Wallace048b1d62018-01-03 22:24:41 -0500134static inline char *
Dave Wallace2a865272018-02-07 21:00:42 -0500135ldp_get_app_name ()
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700136{
Dave Wallace2a865272018-02-07 21:00:42 -0500137 if (ldp->app_name[0] == '\0')
138 ldp_set_app_name ("app");
Dave Wallace048b1d62018-01-03 22:24:41 -0500139
Dave Wallace2a865272018-02-07 21:00:42 -0500140 return ldp->app_name;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700141}
142
Dave Wallace048b1d62018-01-03 22:24:41 -0500143static inline int
Florin Coras7baeb712019-01-04 17:05:43 -0800144ldp_vlsh_to_fd (vls_handle_t vlsh)
Dave Wallace048b1d62018-01-03 22:24:41 -0500145{
Florin Coras7baeb712019-01-04 17:05:43 -0800146 return (vlsh + ldp->vlsh_bit_val);
Dave Wallace048b1d62018-01-03 22:24:41 -0500147}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700148
Florin Coras7baeb712019-01-04 17:05:43 -0800149static inline vls_handle_t
150ldp_fd_to_vlsh (int fd)
Dave Wallace048b1d62018-01-03 22:24:41 -0500151{
Florin Coras7baeb712019-01-04 17:05:43 -0800152 if (fd < ldp->vlsh_bit_val)
153 return VLS_INVALID_HANDLE;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700154
Florin Coras7baeb712019-01-04 17:05:43 -0800155 return (fd - ldp->vlsh_bit_val);
Dave Wallace048b1d62018-01-03 22:24:41 -0500156}
157
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700158static inline int
Dave Wallace2a865272018-02-07 21:00:42 -0500159ldp_init (void)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700160{
Florin Corasdfe4cf42018-11-28 22:13:45 -0800161 ldp_worker_ctx_t *ldpw;
Florin Coras99368312018-08-02 10:45:44 -0700162 int rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700163
Florin Coras99368312018-08-02 10:45:44 -0700164 if (PREDICT_TRUE (ldp->init))
165 return 0;
166
167 ldp->init = 1;
168 ldp->vcl_needs_real_epoll = 1;
Florin Coras7baeb712019-01-04 17:05:43 -0800169 rv = vls_app_create (ldp_get_app_name ());
Florin Coras99368312018-08-02 10:45:44 -0700170 if (rv != VPPCOM_OK)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700171 {
Florin Coras955bfbb2018-12-04 13:43:45 -0800172 ldp->vcl_needs_real_epoll = 0;
173 if (rv == VPPCOM_EEXIST)
174 return 0;
Florin Coras05ecfcc2018-12-12 18:19:39 -0800175 LDBG (2, "\nERROR: ldp_init: vppcom_app_create()"
176 " failed! rv = %d (%s)\n", rv, vppcom_retval_str (rv));
Florin Coras99368312018-08-02 10:45:44 -0700177 ldp->init = 0;
178 return rv;
179 }
180 ldp->vcl_needs_real_epoll = 0;
Florin Corasdfe4cf42018-11-28 22:13:45 -0800181 pool_alloc (ldp->workers, LDP_MAX_NWORKERS);
182 ldpw = ldp_worker_get_current ();
Florin Coras99368312018-08-02 10:45:44 -0700183
184 char *env_var_str = getenv (LDP_ENV_DEBUG);
185 if (env_var_str)
186 {
187 u32 tmp;
188 if (sscanf (env_var_str, "%u", &tmp) != 1)
189 clib_warning ("LDP<%d>: WARNING: Invalid LDP debug level specified in"
190 " the env var " LDP_ENV_DEBUG " (%s)!", getpid (),
191 env_var_str);
192 else
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700193 {
Florin Coras99368312018-08-02 10:45:44 -0700194 ldp->debug = tmp;
Florin Coras05ecfcc2018-12-12 18:19:39 -0800195 LDBG (0, "configured LDP debug level (%u) from env var "
196 LDP_ENV_DEBUG "!", ldp->debug);
Florin Coras99368312018-08-02 10:45:44 -0700197 }
198 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500199
Florin Coras99368312018-08-02 10:45:44 -0700200 env_var_str = getenv (LDP_ENV_APP_NAME);
201 if (env_var_str)
202 {
203 ldp_set_app_name (env_var_str);
Florin Coras05ecfcc2018-12-12 18:19:39 -0800204 LDBG (0, "configured LDP app name (%s) from the env var "
205 LDP_ENV_APP_NAME "!", ldp->app_name);
Florin Coras99368312018-08-02 10:45:44 -0700206 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500207
Florin Coras99368312018-08-02 10:45:44 -0700208 env_var_str = getenv (LDP_ENV_SID_BIT);
209 if (env_var_str)
210 {
211 u32 sb;
212 if (sscanf (env_var_str, "%u", &sb) != 1)
213 {
214 clib_warning ("LDP<%d>: WARNING: Invalid LDP sid bit specified in"
215 " the env var " LDP_ENV_SID_BIT " (%s)! sid bit "
216 "value %d (0x%x)", getpid (), env_var_str,
Florin Coras7baeb712019-01-04 17:05:43 -0800217 ldp->vlsh_bit_val, ldp->vlsh_bit_val);
Florin Coras99368312018-08-02 10:45:44 -0700218 }
219 else if (sb < LDP_SID_BIT_MIN)
220 {
Florin Coras7baeb712019-01-04 17:05:43 -0800221 ldp->vlsh_bit_val = (1 << LDP_SID_BIT_MIN);
222 ldp->vlsh_bit_mask = ldp->vlsh_bit_val - 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500223
Florin Coras99368312018-08-02 10:45:44 -0700224 clib_warning ("LDP<%d>: WARNING: LDP sid bit (%u) specified in the"
225 " env var " LDP_ENV_SID_BIT " (%s) is too small. "
226 "Using LDP_SID_BIT_MIN (%d)! sid bit value %d (0x%x)",
227 getpid (), sb, env_var_str, LDP_SID_BIT_MIN,
Florin Coras7baeb712019-01-04 17:05:43 -0800228 ldp->vlsh_bit_val, ldp->vlsh_bit_val);
Florin Coras99368312018-08-02 10:45:44 -0700229 }
230 else if (sb > LDP_SID_BIT_MAX)
231 {
Florin Coras7baeb712019-01-04 17:05:43 -0800232 ldp->vlsh_bit_val = (1 << LDP_SID_BIT_MAX);
233 ldp->vlsh_bit_mask = ldp->vlsh_bit_val - 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500234
Florin Coras99368312018-08-02 10:45:44 -0700235 clib_warning ("LDP<%d>: WARNING: LDP sid bit (%u) specified in the"
236 " env var " LDP_ENV_SID_BIT " (%s) is too big. Using"
237 " LDP_SID_BIT_MAX (%d)! sid bit value %d (0x%x)",
238 getpid (), sb, env_var_str, LDP_SID_BIT_MAX,
Florin Coras7baeb712019-01-04 17:05:43 -0800239 ldp->vlsh_bit_val, ldp->vlsh_bit_val);
Dave Wallace048b1d62018-01-03 22:24:41 -0500240 }
241 else
242 {
Florin Coras7baeb712019-01-04 17:05:43 -0800243 ldp->vlsh_bit_val = (1 << sb);
244 ldp->vlsh_bit_mask = ldp->vlsh_bit_val - 1;
Florin Coras99368312018-08-02 10:45:44 -0700245
Florin Coras05ecfcc2018-12-12 18:19:39 -0800246 LDBG (0, "configured LDP sid bit (%u) from "
247 LDP_ENV_SID_BIT "! sid bit value %d (0x%x)", sb,
Florin Coras7baeb712019-01-04 17:05:43 -0800248 ldp->vlsh_bit_val, ldp->vlsh_bit_val);
Dave Wallace048b1d62018-01-03 22:24:41 -0500249 }
250 }
Florin Coras99368312018-08-02 10:45:44 -0700251
Florin Corasdfe4cf42018-11-28 22:13:45 -0800252 clib_time_init (&ldpw->clib_time);
Florin Coras05ecfcc2018-12-12 18:19:39 -0800253 LDBG (0, "LDP initialization: done!");
Florin Coras99368312018-08-02 10:45:44 -0700254
255 return 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500256}
257
258int
259close (int fd)
260{
Florin Coras7baeb712019-01-04 17:05:43 -0800261 vls_handle_t vlsh;
262 int rv, epfd;
Dave Wallace048b1d62018-01-03 22:24:41 -0500263
Dave Wallace2a865272018-02-07 21:00:42 -0500264 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500265 return -1;
266
Florin Coras7baeb712019-01-04 17:05:43 -0800267 vlsh = ldp_fd_to_vlsh (fd);
268 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -0500269 {
Florin Coras7baeb712019-01-04 17:05:43 -0800270 epfd = vls_attr (vlsh, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -0500271 if (epfd > 0)
272 {
Florin Coras7baeb712019-01-04 17:05:43 -0800273 LDBG (0, "fd %d: calling libc_close: epfd %u", fd, epfd);
Dave Wallace048b1d62018-01-03 22:24:41 -0500274
275 rv = libc_close (epfd);
276 if (rv < 0)
277 {
278 u32 size = sizeof (epfd);
279 epfd = 0;
280
Florin Coras7baeb712019-01-04 17:05:43 -0800281 (void) vls_attr (vlsh, VPPCOM_ATTR_SET_LIBC_EPFD, &epfd, &size);
Dave Wallace048b1d62018-01-03 22:24:41 -0500282 }
283 }
284 else if (PREDICT_FALSE (epfd < 0))
285 {
286 errno = -epfd;
287 rv = -1;
288 goto done;
289 }
290
Florin Coras7baeb712019-01-04 17:05:43 -0800291 LDBG (0, "fd %d: calling vls_close: vlsh %u", fd, vlsh);
Dave Wallace048b1d62018-01-03 22:24:41 -0500292
Florin Coras7baeb712019-01-04 17:05:43 -0800293 rv = vls_close (vlsh);
Dave Wallace048b1d62018-01-03 22:24:41 -0500294 if (rv != VPPCOM_OK)
295 {
296 errno = -rv;
297 rv = -1;
298 }
299 }
300 else
301 {
Florin Coras7baeb712019-01-04 17:05:43 -0800302 LDBG (0, "fd %d: calling libc_close", fd);
Dave Wallace048b1d62018-01-03 22:24:41 -0500303 rv = libc_close (fd);
304 }
305
306done:
Dave Wallace048b1d62018-01-03 22:24:41 -0500307 return rv;
308}
309
310ssize_t
311read (int fd, void *buf, size_t nbytes)
312{
Florin Coras7baeb712019-01-04 17:05:43 -0800313 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -0500314 ssize_t size;
Dave Wallace048b1d62018-01-03 22:24:41 -0500315
Dave Wallace2a865272018-02-07 21:00:42 -0500316 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500317 return -1;
318
Florin Coras7baeb712019-01-04 17:05:43 -0800319 vlsh = ldp_fd_to_vlsh (fd);
320 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -0500321 {
Florin Coras7baeb712019-01-04 17:05:43 -0800322 size = vls_read (vlsh, buf, nbytes);
Dave Wallace048b1d62018-01-03 22:24:41 -0500323 if (size < 0)
324 {
325 errno = -size;
326 size = -1;
327 }
328 }
329 else
330 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500331 size = libc_read (fd, buf, nbytes);
332 }
333
Dave Wallace048b1d62018-01-03 22:24:41 -0500334 return size;
335}
336
337ssize_t
338readv (int fd, const struct iovec * iov, int iovcnt)
339{
Dave Wallace8aaba562018-01-18 17:21:19 -0500340 int rv = 0, i, total = 0;
Florin Coras7baeb712019-01-04 17:05:43 -0800341 vls_handle_t vlsh;
342 ssize_t size = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500343
Dave Wallace2a865272018-02-07 21:00:42 -0500344 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500345 return -1;
346
Florin Coras7baeb712019-01-04 17:05:43 -0800347 vlsh = ldp_fd_to_vlsh (fd);
348 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -0500349 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500350 do
351 {
352 for (i = 0; i < iovcnt; ++i)
353 {
Florin Coras7baeb712019-01-04 17:05:43 -0800354 rv = vls_read (vlsh, iov[i].iov_base, iov[i].iov_len);
Dave Wallace048b1d62018-01-03 22:24:41 -0500355 if (rv < 0)
356 break;
357 else
358 {
359 total += rv;
360 if (rv < iov[i].iov_len)
Florin Coras7baeb712019-01-04 17:05:43 -0800361 break;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700362 }
363 }
364 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500365 while ((rv >= 0) && (total == 0));
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700366
Dave Wallace048b1d62018-01-03 22:24:41 -0500367 if (rv < 0)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700368 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500369 errno = -rv;
370 size = -1;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700371 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500372 else
373 size = total;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700374 }
375 else
376 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500377 size = libc_readv (fd, iov, iovcnt);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700378 }
379
Dave Wallace048b1d62018-01-03 22:24:41 -0500380 return size;
381}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700382
Dave Wallace048b1d62018-01-03 22:24:41 -0500383ssize_t
384write (int fd, const void *buf, size_t nbytes)
385{
Florin Coras7baeb712019-01-04 17:05:43 -0800386 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -0500387 ssize_t size = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500388
Dave Wallace2a865272018-02-07 21:00:42 -0500389 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500390 return -1;
391
Florin Coras7baeb712019-01-04 17:05:43 -0800392 vlsh = ldp_fd_to_vlsh (fd);
393 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -0500394 {
Florin Coras7baeb712019-01-04 17:05:43 -0800395 size = vls_write_msg (vlsh, (void *) buf, nbytes);
Dave Wallace048b1d62018-01-03 22:24:41 -0500396 if (size < 0)
397 {
398 errno = -size;
399 size = -1;
400 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700401 }
402 else
403 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500404 size = libc_write (fd, buf, nbytes);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700405 }
406
Dave Wallace048b1d62018-01-03 22:24:41 -0500407 return size;
408}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700409
Dave Wallace048b1d62018-01-03 22:24:41 -0500410ssize_t
411writev (int fd, const struct iovec * iov, int iovcnt)
412{
Dave Wallace048b1d62018-01-03 22:24:41 -0500413 ssize_t size = 0, total = 0;
Florin Coras7baeb712019-01-04 17:05:43 -0800414 vls_handle_t vlsh;
Dave Wallace8aaba562018-01-18 17:21:19 -0500415 int i, rv = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500416
Dave Wallace2a865272018-02-07 21:00:42 -0500417 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500418 return -1;
419
Florin Coras7baeb712019-01-04 17:05:43 -0800420 vlsh = ldp_fd_to_vlsh (fd);
421 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -0500422 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500423 do
424 {
425 for (i = 0; i < iovcnt; ++i)
426 {
Florin Coras7baeb712019-01-04 17:05:43 -0800427 rv = vls_write_msg (vlsh, iov[i].iov_base, iov[i].iov_len);
Dave Wallace048b1d62018-01-03 22:24:41 -0500428 if (rv < 0)
429 break;
430 else
431 {
432 total += rv;
433 if (rv < iov[i].iov_len)
Florin Corasb0f662f2018-12-27 14:51:46 -0800434 break;
Dave Wallace048b1d62018-01-03 22:24:41 -0500435 }
436 }
437 }
438 while ((rv >= 0) && (total == 0));
439
440 if (rv < 0)
441 {
442 errno = -rv;
443 size = -1;
444 }
445 else
446 size = total;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700447 }
448 else
449 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500450 size = libc_writev (fd, iov, iovcnt);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700451 }
452
Dave Wallace048b1d62018-01-03 22:24:41 -0500453 return size;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700454}
455
456int
Dave Wallace048b1d62018-01-03 22:24:41 -0500457fcntl (int fd, int cmd, ...)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700458{
Florin Coras7baeb712019-01-04 17:05:43 -0800459 vls_handle_t vlsh;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700460 int rv = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500461 va_list ap;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700462
Dave Wallace2a865272018-02-07 21:00:42 -0500463 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500464 return -1;
465
466 va_start (ap, cmd);
Florin Coras7baeb712019-01-04 17:05:43 -0800467
468 vlsh = ldp_fd_to_vlsh (fd);
469 LDBG (0, "fd %u vlsh %d, cmd %u", fd, vlsh, cmd);
470 if (vlsh != VLS_INVALID_HANDLE)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700471 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500472 int flags = va_arg (ap, int);
473 u32 size;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700474
Dave Wallace048b1d62018-01-03 22:24:41 -0500475 size = sizeof (flags);
476 rv = -EOPNOTSUPP;
477 switch (cmd)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700478 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500479 case F_SETFL:
Florin Coras7baeb712019-01-04 17:05:43 -0800480 rv = vls_attr (vlsh, VPPCOM_ATTR_SET_FLAGS, &flags, &size);
Dave Wallace048b1d62018-01-03 22:24:41 -0500481 break;
482
483 case F_GETFL:
Florin Coras7baeb712019-01-04 17:05:43 -0800484 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_FLAGS, &flags, &size);
Dave Wallace048b1d62018-01-03 22:24:41 -0500485 if (rv == VPPCOM_OK)
Florin Coras7baeb712019-01-04 17:05:43 -0800486 rv = flags;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700487 break;
Florin Coras173bae32018-11-16 18:56:28 -0800488 case F_SETFD:
489 /* TODO handle this */
490 LDBG (0, "F_SETFD ignored flags %u", flags);
491 rv = 0;
492 break;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700493 default:
Dave Wallace048b1d62018-01-03 22:24:41 -0500494 rv = -EOPNOTSUPP;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700495 break;
496 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500497 if (rv < 0)
498 {
499 errno = -rv;
500 rv = -1;
501 }
502 }
503 else
504 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500505 rv = libc_vfcntl (fd, cmd, ap);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700506 }
507
Dave Wallace048b1d62018-01-03 22:24:41 -0500508 va_end (ap);
509
Dave Wallace048b1d62018-01-03 22:24:41 -0500510 return rv;
511}
512
513int
514ioctl (int fd, unsigned long int cmd, ...)
515{
Florin Coras7baeb712019-01-04 17:05:43 -0800516 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -0500517 va_list ap;
Florin Coras7baeb712019-01-04 17:05:43 -0800518 int rv;
Dave Wallace048b1d62018-01-03 22:24:41 -0500519
Dave Wallace2a865272018-02-07 21:00:42 -0500520 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500521 return -1;
522
523 va_start (ap, cmd);
Dave Wallace048b1d62018-01-03 22:24:41 -0500524
Florin Coras7baeb712019-01-04 17:05:43 -0800525 vlsh = ldp_fd_to_vlsh (fd);
526 if (vlsh != VLS_INVALID_HANDLE)
527 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500528 switch (cmd)
529 {
530 case FIONREAD:
Florin Coras7baeb712019-01-04 17:05:43 -0800531 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_NREAD, 0, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -0500532 break;
533
534 case FIONBIO:
535 {
536 u32 flags = va_arg (ap, int) ? O_NONBLOCK : 0;
537 u32 size = sizeof (flags);
538
539 /* TBD: When VPPCOM_ATTR_[GS]ET_FLAGS supports flags other than
540 * non-blocking, the flags should be read here and merged
541 * with O_NONBLOCK.
542 */
Florin Coras7baeb712019-01-04 17:05:43 -0800543 rv = vls_attr (vlsh, VPPCOM_ATTR_SET_FLAGS, &flags, &size);
Dave Wallace048b1d62018-01-03 22:24:41 -0500544 }
545 break;
546
547 default:
548 rv = -EOPNOTSUPP;
549 break;
550 }
551 if (rv < 0)
552 {
553 errno = -rv;
554 rv = -1;
555 }
556 }
557 else
558 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500559 rv = libc_vioctl (fd, cmd, ap);
560 }
561
Dave Wallace048b1d62018-01-03 22:24:41 -0500562 va_end (ap);
563 return rv;
564}
565
566int
Dave Wallace2a865272018-02-07 21:00:42 -0500567ldp_pselect (int nfds, fd_set * __restrict readfds,
568 fd_set * __restrict writefds,
569 fd_set * __restrict exceptfds,
570 const struct timespec *__restrict timeout,
571 const __sigset_t * __restrict sigmask)
Dave Wallace048b1d62018-01-03 22:24:41 -0500572{
Florin Coras30e273b2018-11-27 00:04:59 -0800573 uword sid_bits, sid_bits_set, libc_bits, libc_bits_set;
Florin Corasdfe4cf42018-11-28 22:13:45 -0800574 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
Florin Coras7baeb712019-01-04 17:05:43 -0800575 u32 minbits = clib_max (nfds, BITS (uword)), si;
576 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -0500577 f64 time_out;
Florin Coras30e273b2018-11-27 00:04:59 -0800578 int rv, fd;
Dave Wallace048b1d62018-01-03 22:24:41 -0500579
580 if (nfds < 0)
581 {
582 errno = EINVAL;
583 return -1;
584 }
585
Dave Wallace3ee1fe12018-02-23 01:09:11 -0500586 if (timeout)
587 {
588 time_out = (timeout->tv_sec == 0 && timeout->tv_nsec == 0) ?
Florin Coras7baeb712019-01-04 17:05:43 -0800589 (f64) 0 : (f64) timeout->tv_sec + (f64) timeout->tv_nsec / (f64) 1e9;
Dave Wallace3ee1fe12018-02-23 01:09:11 -0500590
591 /* select as fine grained sleep */
592 if (!nfds)
593 {
Florin Corasdfe4cf42018-11-28 22:13:45 -0800594 time_out += clib_time_now (&ldpw->clib_time);
595 while (clib_time_now (&ldpw->clib_time) < time_out)
Dave Wallace3ee1fe12018-02-23 01:09:11 -0500596 ;
597 return 0;
598 }
599 }
600 else if (!nfds)
601 {
602 errno = EINVAL;
603 return -1;
604 }
605 else
606 time_out = -1;
607
608
Florin Coras7baeb712019-01-04 17:05:43 -0800609 if (nfds <= ldp->vlsh_bit_val)
Dave Wallace048b1d62018-01-03 22:24:41 -0500610 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500611 rv = libc_pselect (nfds, readfds, writefds, exceptfds,
612 timeout, sigmask);
613 goto done;
614 }
615
Florin Coras7baeb712019-01-04 17:05:43 -0800616 if (PREDICT_FALSE (ldp->vlsh_bit_val > FD_SETSIZE / 2))
Dave Wallace048b1d62018-01-03 22:24:41 -0500617 {
Florin Coras7baeb712019-01-04 17:05:43 -0800618 LDBG (0, "ERROR: LDP sid bit value %d > FD_SETSIZE/2 %d!",
619 ldp->vlsh_bit_val, FD_SETSIZE / 2);
Dave Wallace048b1d62018-01-03 22:24:41 -0500620 errno = EOVERFLOW;
621 return -1;
622 }
623
Dave Wallace048b1d62018-01-03 22:24:41 -0500624 sid_bits = libc_bits = 0;
Florin Coras173bae32018-11-16 18:56:28 -0800625 u32 n_bytes = nfds / 8 + ((nfds % 8) ? 1 : 0);
Florin Coras7baeb712019-01-04 17:05:43 -0800626
Dave Wallace048b1d62018-01-03 22:24:41 -0500627 if (readfds)
628 {
Florin Corasdfe4cf42018-11-28 22:13:45 -0800629 clib_bitmap_validate (ldpw->sid_rd_bitmap, minbits);
630 clib_bitmap_validate (ldpw->libc_rd_bitmap, minbits);
631 clib_bitmap_validate (ldpw->rd_bitmap, minbits);
632 clib_memcpy_fast (ldpw->rd_bitmap, readfds, n_bytes);
Florin Coras173bae32018-11-16 18:56:28 -0800633 memset (readfds, 0, n_bytes);
Dave Wallace048b1d62018-01-03 22:24:41 -0500634
635 /* *INDENT-OFF* */
Florin Corasdfe4cf42018-11-28 22:13:45 -0800636 clib_bitmap_foreach (fd, ldpw->rd_bitmap, ({
Florin Coras173bae32018-11-16 18:56:28 -0800637 if (fd > nfds)
638 break;
Florin Coras7baeb712019-01-04 17:05:43 -0800639 vlsh = ldp_fd_to_vlsh (fd);
640 if (vlsh == VLS_INVALID_HANDLE)
Florin Corasdfe4cf42018-11-28 22:13:45 -0800641 clib_bitmap_set_no_check (ldpw->libc_rd_bitmap, fd, 1);
Florin Coras173bae32018-11-16 18:56:28 -0800642 else
Florin Corasdfe4cf42018-11-28 22:13:45 -0800643 clib_bitmap_set_no_check (ldpw->sid_rd_bitmap,
Florin Coras7baeb712019-01-04 17:05:43 -0800644 vlsh_to_session_index (vlsh), 1);
Florin Coras173bae32018-11-16 18:56:28 -0800645 }));
Dave Wallace048b1d62018-01-03 22:24:41 -0500646 /* *INDENT-ON* */
647
Florin Corasdfe4cf42018-11-28 22:13:45 -0800648 sid_bits_set = clib_bitmap_last_set (ldpw->sid_rd_bitmap) + 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500649 sid_bits = (sid_bits_set > sid_bits) ? sid_bits_set : sid_bits;
650
Florin Corasdfe4cf42018-11-28 22:13:45 -0800651 libc_bits_set = clib_bitmap_last_set (ldpw->libc_rd_bitmap) + 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500652 libc_bits = (libc_bits_set > libc_bits) ? libc_bits_set : libc_bits;
Dave Wallace048b1d62018-01-03 22:24:41 -0500653 }
654 if (writefds)
655 {
Florin Corasdfe4cf42018-11-28 22:13:45 -0800656 clib_bitmap_validate (ldpw->sid_wr_bitmap, minbits);
657 clib_bitmap_validate (ldpw->libc_wr_bitmap, minbits);
658 clib_bitmap_validate (ldpw->wr_bitmap, minbits);
659 clib_memcpy_fast (ldpw->wr_bitmap, writefds, n_bytes);
Florin Coras173bae32018-11-16 18:56:28 -0800660 memset (writefds, 0, n_bytes);
Dave Wallace048b1d62018-01-03 22:24:41 -0500661
662 /* *INDENT-OFF* */
Florin Corasdfe4cf42018-11-28 22:13:45 -0800663 clib_bitmap_foreach (fd, ldpw->wr_bitmap, ({
Florin Coras173bae32018-11-16 18:56:28 -0800664 if (fd > nfds)
665 break;
Florin Coras7baeb712019-01-04 17:05:43 -0800666 vlsh = ldp_fd_to_vlsh (fd);
667 if (vlsh == VLS_INVALID_HANDLE)
Florin Corasdfe4cf42018-11-28 22:13:45 -0800668 clib_bitmap_set_no_check (ldpw->libc_wr_bitmap, fd, 1);
Florin Coras173bae32018-11-16 18:56:28 -0800669 else
Florin Corasdfe4cf42018-11-28 22:13:45 -0800670 clib_bitmap_set_no_check (ldpw->sid_wr_bitmap,
Florin Coras7baeb712019-01-04 17:05:43 -0800671 vlsh_to_session_index (vlsh), 1);
Florin Coras173bae32018-11-16 18:56:28 -0800672 }));
Dave Wallace048b1d62018-01-03 22:24:41 -0500673 /* *INDENT-ON* */
674
Florin Corasdfe4cf42018-11-28 22:13:45 -0800675 sid_bits_set = clib_bitmap_last_set (ldpw->sid_wr_bitmap) + 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500676 sid_bits = (sid_bits_set > sid_bits) ? sid_bits_set : sid_bits;
677
Florin Corasdfe4cf42018-11-28 22:13:45 -0800678 libc_bits_set = clib_bitmap_last_set (ldpw->libc_wr_bitmap) + 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500679 libc_bits = (libc_bits_set > libc_bits) ? libc_bits_set : libc_bits;
680
Dave Wallace048b1d62018-01-03 22:24:41 -0500681 }
682 if (exceptfds)
683 {
Florin Corasdfe4cf42018-11-28 22:13:45 -0800684 clib_bitmap_validate (ldpw->sid_ex_bitmap, minbits);
685 clib_bitmap_validate (ldpw->libc_ex_bitmap, minbits);
686 clib_bitmap_validate (ldpw->ex_bitmap, minbits);
687 clib_memcpy_fast (ldpw->ex_bitmap, exceptfds, n_bytes);
Florin Coras173bae32018-11-16 18:56:28 -0800688 memset (exceptfds, 0, n_bytes);
Dave Wallace048b1d62018-01-03 22:24:41 -0500689
690 /* *INDENT-OFF* */
Florin Corasdfe4cf42018-11-28 22:13:45 -0800691 clib_bitmap_foreach (fd, ldpw->ex_bitmap, ({
Florin Coras173bae32018-11-16 18:56:28 -0800692 if (fd > nfds)
693 break;
Florin Coras7baeb712019-01-04 17:05:43 -0800694 vlsh = ldp_fd_to_vlsh (fd);
695 if (vlsh == VLS_INVALID_HANDLE)
Florin Corasdfe4cf42018-11-28 22:13:45 -0800696 clib_bitmap_set_no_check (ldpw->libc_ex_bitmap, fd, 1);
Florin Coras173bae32018-11-16 18:56:28 -0800697 else
Florin Corasdfe4cf42018-11-28 22:13:45 -0800698 clib_bitmap_set_no_check (ldpw->sid_ex_bitmap,
Florin Coras7baeb712019-01-04 17:05:43 -0800699 vlsh_to_session_index (vlsh), 1);
Florin Coras173bae32018-11-16 18:56:28 -0800700 }));
Dave Wallace048b1d62018-01-03 22:24:41 -0500701 /* *INDENT-ON* */
702
Florin Corasdfe4cf42018-11-28 22:13:45 -0800703 sid_bits_set = clib_bitmap_last_set (ldpw->sid_ex_bitmap) + 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500704 sid_bits = (sid_bits_set > sid_bits) ? sid_bits_set : sid_bits;
705
Florin Corasdfe4cf42018-11-28 22:13:45 -0800706 libc_bits_set = clib_bitmap_last_set (ldpw->libc_ex_bitmap) + 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500707 libc_bits = (libc_bits_set > libc_bits) ? libc_bits_set : libc_bits;
Dave Wallace048b1d62018-01-03 22:24:41 -0500708 }
709
710 if (PREDICT_FALSE (!sid_bits && !libc_bits))
711 {
712 errno = EINVAL;
713 rv = -1;
714 goto done;
715 }
716
717 do
718 {
719 if (sid_bits)
720 {
Florin Corasdfe4cf42018-11-28 22:13:45 -0800721 if (!ldpw->select_vcl)
Dave Wallace048b1d62018-01-03 22:24:41 -0500722 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500723 if (readfds)
Florin Corasdfe4cf42018-11-28 22:13:45 -0800724 clib_memcpy_fast (ldpw->rd_bitmap, ldpw->sid_rd_bitmap,
725 vec_len (ldpw->rd_bitmap) *
Dave Barach178cf492018-11-13 16:34:13 -0500726 sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -0500727 if (writefds)
Florin Corasdfe4cf42018-11-28 22:13:45 -0800728 clib_memcpy_fast (ldpw->wr_bitmap, ldpw->sid_wr_bitmap,
729 vec_len (ldpw->wr_bitmap) *
Dave Barach178cf492018-11-13 16:34:13 -0500730 sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -0500731 if (exceptfds)
Florin Corasdfe4cf42018-11-28 22:13:45 -0800732 clib_memcpy_fast (ldpw->ex_bitmap, ldpw->sid_ex_bitmap,
733 vec_len (ldpw->ex_bitmap) *
Dave Barach178cf492018-11-13 16:34:13 -0500734 sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -0500735
736 rv = vppcom_select (sid_bits,
David Johnsond9818dd2018-12-14 14:53:41 -0500737 readfds ? (unsigned long *) ldpw->rd_bitmap
738 : NULL,
739 writefds ? (unsigned long *) ldpw->wr_bitmap
740 : NULL,
741 exceptfds ? (unsigned long *)
742 ldpw->ex_bitmap : NULL, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -0500743 if (rv < 0)
744 {
745 errno = -rv;
746 rv = -1;
747 }
748 else if (rv > 0)
749 {
750 if (readfds)
751 {
752 /* *INDENT-OFF* */
Florin Coras7baeb712019-01-04 17:05:43 -0800753 clib_bitmap_foreach (si, ldpw->rd_bitmap, ({
754 vlsh = vls_session_index_to_vlsh (si);
755 fd = ldp_vlsh_to_fd (vlsh);
756 if (PREDICT_FALSE (fd < 0))
757 {
758 errno = EBADFD;
759 rv = -1;
760 goto done;
761 }
762 FD_SET (fd, readfds);
763 }));
Dave Wallace048b1d62018-01-03 22:24:41 -0500764 /* *INDENT-ON* */
765 }
766 if (writefds)
767 {
768 /* *INDENT-OFF* */
Florin Coras7baeb712019-01-04 17:05:43 -0800769 clib_bitmap_foreach (si, ldpw->wr_bitmap, ({
770 vlsh = vls_session_index_to_vlsh (si);
771 fd = ldp_vlsh_to_fd (vlsh);
772 if (PREDICT_FALSE (fd < 0))
773 {
774 errno = EBADFD;
775 rv = -1;
776 goto done;
777 }
778 FD_SET (fd, writefds);
779 }));
Dave Wallace048b1d62018-01-03 22:24:41 -0500780 /* *INDENT-ON* */
781 }
782 if (exceptfds)
783 {
784 /* *INDENT-OFF* */
Florin Coras7baeb712019-01-04 17:05:43 -0800785 clib_bitmap_foreach (si, ldpw->ex_bitmap, ({
786 vlsh = vls_session_index_to_vlsh (si);
787 fd = ldp_vlsh_to_fd (vlsh);
788 if (PREDICT_FALSE (fd < 0))
789 {
790 errno = EBADFD;
791 rv = -1;
792 goto done;
793 }
794 FD_SET (fd, exceptfds);
795 }));
Dave Wallace048b1d62018-01-03 22:24:41 -0500796 /* *INDENT-ON* */
797 }
Florin Corasdfe4cf42018-11-28 22:13:45 -0800798 ldpw->select_vcl = 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500799 goto done;
800 }
801 }
802 else
Florin Corasdfe4cf42018-11-28 22:13:45 -0800803 ldpw->select_vcl = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500804 }
805 if (libc_bits)
806 {
807 struct timespec tspec;
808
Dave Wallace048b1d62018-01-03 22:24:41 -0500809 if (readfds)
Florin Corasdfe4cf42018-11-28 22:13:45 -0800810 clib_memcpy_fast (readfds, ldpw->libc_rd_bitmap,
811 vec_len (ldpw->rd_bitmap) *
Dave Barach178cf492018-11-13 16:34:13 -0500812 sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -0500813 if (writefds)
Florin Corasdfe4cf42018-11-28 22:13:45 -0800814 clib_memcpy_fast (writefds, ldpw->libc_wr_bitmap,
815 vec_len (ldpw->wr_bitmap) *
Dave Barach178cf492018-11-13 16:34:13 -0500816 sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -0500817 if (exceptfds)
Florin Corasdfe4cf42018-11-28 22:13:45 -0800818 clib_memcpy_fast (exceptfds, ldpw->libc_ex_bitmap,
819 vec_len (ldpw->ex_bitmap) *
Dave Barach178cf492018-11-13 16:34:13 -0500820 sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -0500821 tspec.tv_sec = tspec.tv_nsec = 0;
822 rv = libc_pselect (libc_bits,
823 readfds ? readfds : NULL,
824 writefds ? writefds : NULL,
825 exceptfds ? exceptfds : NULL, &tspec, sigmask);
826 if (rv != 0)
827 goto done;
828 }
829 }
Florin Corasdfe4cf42018-11-28 22:13:45 -0800830 while ((time_out == -1) || (clib_time_now (&ldpw->clib_time) < time_out));
Dave Wallace048b1d62018-01-03 22:24:41 -0500831 rv = 0;
832
833done:
834 /* TBD: set timeout to amount of time left */
Florin Corasdfe4cf42018-11-28 22:13:45 -0800835 clib_bitmap_zero (ldpw->rd_bitmap);
836 clib_bitmap_zero (ldpw->sid_rd_bitmap);
837 clib_bitmap_zero (ldpw->libc_rd_bitmap);
838 clib_bitmap_zero (ldpw->wr_bitmap);
839 clib_bitmap_zero (ldpw->sid_wr_bitmap);
840 clib_bitmap_zero (ldpw->libc_wr_bitmap);
841 clib_bitmap_zero (ldpw->ex_bitmap);
842 clib_bitmap_zero (ldpw->sid_ex_bitmap);
843 clib_bitmap_zero (ldpw->libc_ex_bitmap);
Dave Wallace048b1d62018-01-03 22:24:41 -0500844
Dave Wallace048b1d62018-01-03 22:24:41 -0500845 return rv;
846}
847
848int
849select (int nfds, fd_set * __restrict readfds,
850 fd_set * __restrict writefds,
851 fd_set * __restrict exceptfds, struct timeval *__restrict timeout)
852{
853 struct timespec tspec;
854
855 if (timeout)
856 {
857 tspec.tv_sec = timeout->tv_sec;
858 tspec.tv_nsec = timeout->tv_usec * 1000;
859 }
Dave Wallace2a865272018-02-07 21:00:42 -0500860 return ldp_pselect (nfds, readfds, writefds, exceptfds,
861 timeout ? &tspec : NULL, NULL);
Dave Wallace048b1d62018-01-03 22:24:41 -0500862}
863
864#ifdef __USE_XOPEN2K
865int
866pselect (int nfds, fd_set * __restrict readfds,
867 fd_set * __restrict writefds,
868 fd_set * __restrict exceptfds,
869 const struct timespec *__restrict timeout,
870 const __sigset_t * __restrict sigmask)
871{
Dave Wallace2a865272018-02-07 21:00:42 -0500872 return ldp_pselect (nfds, readfds, writefds, exceptfds, timeout, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -0500873}
874#endif
875
876int
877socket (int domain, int type, int protocol)
878{
Florin Coras7baeb712019-01-04 17:05:43 -0800879 int rv, sock_type = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK);
Dave Wallace048b1d62018-01-03 22:24:41 -0500880 u8 is_nonblocking = type & SOCK_NONBLOCK ? 1 : 0;
Florin Coras7baeb712019-01-04 17:05:43 -0800881 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -0500882
Dave Wallace2a865272018-02-07 21:00:42 -0500883 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500884 return -1;
885
886 if (((domain == AF_INET) || (domain == AF_INET6)) &&
887 ((sock_type == SOCK_STREAM) || (sock_type == SOCK_DGRAM)))
888 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500889 u8 proto = ((sock_type == SOCK_DGRAM) ?
890 VPPCOM_PROTO_UDP : VPPCOM_PROTO_TCP);
891
Florin Coras7baeb712019-01-04 17:05:43 -0800892 LDBG (0, "calling vls_create: proto %u (%s), is_nonblocking %u",
893 proto, vppcom_proto_str (proto), is_nonblocking);
Dave Wallace048b1d62018-01-03 22:24:41 -0500894
Florin Coras7baeb712019-01-04 17:05:43 -0800895 vlsh = vls_create (proto, is_nonblocking);
896 if (vlsh < 0)
Dave Wallace048b1d62018-01-03 22:24:41 -0500897 {
Florin Coras7baeb712019-01-04 17:05:43 -0800898 errno = -vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -0500899 rv = -1;
900 }
901 else
902 {
Florin Coras7baeb712019-01-04 17:05:43 -0800903 rv = ldp_vlsh_to_fd (vlsh);
Dave Wallace048b1d62018-01-03 22:24:41 -0500904 }
905 }
906 else
907 {
Florin Coras7baeb712019-01-04 17:05:43 -0800908 LDBG (0, "calling libc_socket");
Dave Wallace048b1d62018-01-03 22:24:41 -0500909 rv = libc_socket (domain, type, protocol);
910 }
911
Dave Wallace048b1d62018-01-03 22:24:41 -0500912 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700913}
914
915/*
916 * Create two new sockets, of type TYPE in domain DOMAIN and using
917 * protocol PROTOCOL, which are connected to each other, and put file
918 * descriptors for them in FDS[0] and FDS[1]. If PROTOCOL is zero,
919 * one will be chosen automatically.
920 * Returns 0 on success, -1 for errors.
921 * */
922int
Dave Wallace048b1d62018-01-03 22:24:41 -0500923socketpair (int domain, int type, int protocol, int fds[2])
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700924{
Florin Coras7baeb712019-01-04 17:05:43 -0800925 int rv, sock_type = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK);
Dave Wallace048b1d62018-01-03 22:24:41 -0500926
Dave Wallace2a865272018-02-07 21:00:42 -0500927 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500928 return -1;
929
930 if (((domain == AF_INET) || (domain == AF_INET6)) &&
931 ((sock_type == SOCK_STREAM) || (sock_type == SOCK_DGRAM)))
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700932 {
Florin Coras7baeb712019-01-04 17:05:43 -0800933 LDBG (0, "LDP-TBD");
Dave Wallace048b1d62018-01-03 22:24:41 -0500934 errno = ENOSYS;
935 rv = -1;
936 }
937 else
938 {
Florin Coras7baeb712019-01-04 17:05:43 -0800939 LDBG (1, "calling libc_socketpair");
Florin Coras173bae32018-11-16 18:56:28 -0800940 rv = libc_socketpair (domain, type, protocol, fds);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700941 }
942
Dave Wallace048b1d62018-01-03 22:24:41 -0500943 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700944}
945
946int
Dave Wallace048b1d62018-01-03 22:24:41 -0500947bind (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700948{
Florin Coras7baeb712019-01-04 17:05:43 -0800949 vls_handle_t vlsh;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700950 int rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700951
Dave Wallace2a865272018-02-07 21:00:42 -0500952 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500953 return -1;
954
Florin Coras7baeb712019-01-04 17:05:43 -0800955 vlsh = ldp_fd_to_vlsh (fd);
956 if (vlsh != VLS_INVALID_HANDLE)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700957 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500958 vppcom_endpt_t ep;
959
Dave Wallace048b1d62018-01-03 22:24:41 -0500960 switch (addr->sa_family)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700961 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500962 case AF_INET:
963 if (len != sizeof (struct sockaddr_in))
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700964 {
Florin Coras7baeb712019-01-04 17:05:43 -0800965 LDBG (0, "ERROR: fd %d: vlsh %u: Invalid AF_INET addr len %u!",
966 fd, vlsh, len);
Dave Wallace048b1d62018-01-03 22:24:41 -0500967 errno = EINVAL;
968 rv = -1;
969 goto done;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700970 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500971 ep.is_ip4 = VPPCOM_IS_IP4;
972 ep.ip = (u8 *) & ((const struct sockaddr_in *) addr)->sin_addr;
973 ep.port = (u16) ((const struct sockaddr_in *) addr)->sin_port;
974 break;
975
976 case AF_INET6:
977 if (len != sizeof (struct sockaddr_in6))
978 {
Florin Coras7baeb712019-01-04 17:05:43 -0800979 LDBG (0, "ERROR: fd %d: vlsh %u: Invalid AF_INET6 addr len %u!",
980 fd, vlsh, len);
Dave Wallace048b1d62018-01-03 22:24:41 -0500981 errno = EINVAL;
982 rv = -1;
983 goto done;
984 }
985 ep.is_ip4 = VPPCOM_IS_IP6;
986 ep.ip = (u8 *) & ((const struct sockaddr_in6 *) addr)->sin6_addr;
987 ep.port = (u16) ((const struct sockaddr_in6 *) addr)->sin6_port;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700988 break;
989
990 default:
Florin Coras7baeb712019-01-04 17:05:43 -0800991 LDBG (0, "ERROR: fd %d: vlsh %u: Unsupported address family %u!",
992 fd, vlsh, addr->sa_family);
Dave Wallace048b1d62018-01-03 22:24:41 -0500993 errno = EAFNOSUPPORT;
994 rv = -1;
995 goto done;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700996 }
Florin Coras7baeb712019-01-04 17:05:43 -0800997 LDBG (0, "fd %d: calling vls_bind: vlsh %u, addr %p, len %u", fd, vlsh,
998 addr, len);
Dave Wallace048b1d62018-01-03 22:24:41 -0500999
Florin Coras7baeb712019-01-04 17:05:43 -08001000 rv = vls_bind (vlsh, &ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05001001 if (rv != VPPCOM_OK)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001002 {
1003 errno = -rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001004 rv = -1;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001005 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001006 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001007 else
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001008 {
Florin Coras7baeb712019-01-04 17:05:43 -08001009 LDBG (0, "fd %d: calling libc_bind: addr %p, len %u", fd, addr, len);
Dave Wallace048b1d62018-01-03 22:24:41 -05001010 rv = libc_bind (fd, addr, len);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001011 }
1012
Dave Wallace048b1d62018-01-03 22:24:41 -05001013done:
Florin Coras7baeb712019-01-04 17:05:43 -08001014 LDBG (1, "fd %d: returning %d", fd, rv);
Florin Coras05ecfcc2018-12-12 18:19:39 -08001015
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001016 return rv;
1017}
1018
1019static inline int
Dave Wallace2a865272018-02-07 21:00:42 -05001020ldp_copy_ep_to_sockaddr (__SOCKADDR_ARG addr, socklen_t * __restrict len,
1021 vppcom_endpt_t * ep)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001022{
Dave Wallace048b1d62018-01-03 22:24:41 -05001023 int rv = 0;
1024 int sa_len, copy_len;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001025
Dave Wallace2a865272018-02-07 21:00:42 -05001026 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001027 return -1;
1028
1029 if (addr && len && ep)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001030 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001031 addr->sa_family = (ep->is_ip4 == VPPCOM_IS_IP4) ? AF_INET : AF_INET6;
1032 switch (addr->sa_family)
1033 {
1034 case AF_INET:
1035 ((struct sockaddr_in *) addr)->sin_port = ep->port;
1036 if (*len > sizeof (struct sockaddr_in))
1037 *len = sizeof (struct sockaddr_in);
1038 sa_len = sizeof (struct sockaddr_in) - sizeof (struct in_addr);
1039 copy_len = *len - sa_len;
1040 if (copy_len > 0)
1041 memcpy (&((struct sockaddr_in *) addr)->sin_addr, ep->ip,
1042 copy_len);
1043 break;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001044
Dave Wallace048b1d62018-01-03 22:24:41 -05001045 case AF_INET6:
1046 ((struct sockaddr_in6 *) addr)->sin6_port = ep->port;
1047 if (*len > sizeof (struct sockaddr_in6))
1048 *len = sizeof (struct sockaddr_in6);
1049 sa_len = sizeof (struct sockaddr_in6) - sizeof (struct in6_addr);
1050 copy_len = *len - sa_len;
1051 if (copy_len > 0)
1052 memcpy (((struct sockaddr_in6 *) addr)->sin6_addr.
1053 __in6_u.__u6_addr8, ep->ip, copy_len);
1054 break;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001055
Dave Wallace048b1d62018-01-03 22:24:41 -05001056 default:
1057 /* Not possible */
1058 rv = -EAFNOSUPPORT;
1059 break;
1060 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001061 }
Dave Wallacee695cb42017-11-02 22:04:42 -04001062 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001063}
1064
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001065int
Dave Wallace048b1d62018-01-03 22:24:41 -05001066getsockname (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict len)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001067{
Florin Coras7baeb712019-01-04 17:05:43 -08001068 vls_handle_t vlsh;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001069 int rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001070
Dave Wallace2a865272018-02-07 21:00:42 -05001071 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001072 return -1;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001073
Florin Coras7baeb712019-01-04 17:05:43 -08001074 vlsh = ldp_fd_to_vlsh (fd);
1075 if (vlsh != VLS_INVALID_HANDLE)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001076 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001077 vppcom_endpt_t ep;
1078 u8 addr_buf[sizeof (struct in6_addr)];
1079 u32 size = sizeof (ep);
1080
1081 ep.ip = addr_buf;
Dave Wallace048b1d62018-01-03 22:24:41 -05001082
Florin Coras7baeb712019-01-04 17:05:43 -08001083 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_LCL_ADDR, &ep, &size);
Dave Wallace048b1d62018-01-03 22:24:41 -05001084 if (rv != VPPCOM_OK)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001085 {
1086 errno = -rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001087 rv = -1;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001088 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001089 else
1090 {
Dave Wallace2a865272018-02-07 21:00:42 -05001091 rv = ldp_copy_ep_to_sockaddr (addr, len, &ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05001092 if (rv != VPPCOM_OK)
1093 {
1094 errno = -rv;
1095 rv = -1;
1096 }
1097 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001098 }
1099 else
1100 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001101 rv = libc_getsockname (fd, addr, len);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001102 }
1103
Dave Wallace048b1d62018-01-03 22:24:41 -05001104 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001105}
1106
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001107int
Dave Wallace048b1d62018-01-03 22:24:41 -05001108connect (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001109{
Florin Coras7baeb712019-01-04 17:05:43 -08001110 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05001111 int rv;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001112
Dave Wallace2a865272018-02-07 21:00:42 -05001113 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001114 return -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001115
Dave Wallace048b1d62018-01-03 22:24:41 -05001116 if (!addr)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001117 {
Florin Coras7baeb712019-01-04 17:05:43 -08001118 LDBG (0, "ERROR: fd %d: NULL addr, len %u", fd, len);
Dave Wallace048b1d62018-01-03 22:24:41 -05001119 errno = EINVAL;
1120 rv = -1;
1121 goto done;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001122 }
1123
Florin Coras7baeb712019-01-04 17:05:43 -08001124 vlsh = ldp_fd_to_vlsh (fd);
1125 if (vlsh != VLS_INVALID_HANDLE)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001126 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001127 vppcom_endpt_t ep;
1128
Dave Wallace048b1d62018-01-03 22:24:41 -05001129 switch (addr->sa_family)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001130 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001131 case AF_INET:
1132 if (len != sizeof (struct sockaddr_in))
1133 {
Florin Coras7baeb712019-01-04 17:05:43 -08001134 LDBG (0, "fd %d: ERROR vlsh %u: Invalid AF_INET addr len %u!",
1135 fd, vlsh, len);
Dave Wallace048b1d62018-01-03 22:24:41 -05001136 errno = EINVAL;
1137 rv = -1;
1138 goto done;
1139 }
1140 ep.is_ip4 = VPPCOM_IS_IP4;
1141 ep.ip = (u8 *) & ((const struct sockaddr_in *) addr)->sin_addr;
1142 ep.port = (u16) ((const struct sockaddr_in *) addr)->sin_port;
1143 break;
1144
1145 case AF_INET6:
1146 if (len != sizeof (struct sockaddr_in6))
1147 {
Florin Coras7baeb712019-01-04 17:05:43 -08001148 LDBG (0, "fd %d: ERROR vlsh %u: Invalid AF_INET6 addr len %u!",
1149 fd, vlsh, len);
Dave Wallace048b1d62018-01-03 22:24:41 -05001150 errno = EINVAL;
1151 rv = -1;
1152 goto done;
1153 }
1154 ep.is_ip4 = VPPCOM_IS_IP6;
1155 ep.ip = (u8 *) & ((const struct sockaddr_in6 *) addr)->sin6_addr;
1156 ep.port = (u16) ((const struct sockaddr_in6 *) addr)->sin6_port;
1157 break;
1158
1159 default:
Florin Coras7baeb712019-01-04 17:05:43 -08001160 LDBG (0, "fd %d: ERROR vlsh %u: Unsupported address family %u!",
1161 fd, vlsh, addr->sa_family);
Dave Wallace048b1d62018-01-03 22:24:41 -05001162 errno = EAFNOSUPPORT;
1163 rv = -1;
1164 goto done;
1165 }
Florin Coras7baeb712019-01-04 17:05:43 -08001166 LDBG (0, "fd %d: calling vls_connect(): vlsh %u addr %p len %u", fd,
1167 vlsh, addr, len);
Dave Wallace048b1d62018-01-03 22:24:41 -05001168
Florin Coras7baeb712019-01-04 17:05:43 -08001169 rv = vls_connect (vlsh, &ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05001170 if (rv != VPPCOM_OK)
1171 {
1172 errno = -rv;
1173 rv = -1;
1174 }
1175 }
1176 else
1177 {
Florin Coras7baeb712019-01-04 17:05:43 -08001178 LDBG (0, "fd %d: calling libc_connect(): addr %p, len %u",
1179 fd, addr, len);
Dave Wallace048b1d62018-01-03 22:24:41 -05001180
1181 rv = libc_connect (fd, addr, len);
1182 }
1183
1184done:
Florin Coras7baeb712019-01-04 17:05:43 -08001185 LDBG (1, "fd %d: returning %d (0x%x)", fd, rv, rv);
Dave Wallace048b1d62018-01-03 22:24:41 -05001186 return rv;
1187}
1188
1189int
1190getpeername (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict len)
1191{
Florin Coras7baeb712019-01-04 17:05:43 -08001192 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05001193 int rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001194
Dave Wallace2a865272018-02-07 21:00:42 -05001195 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001196 return -1;
1197
Florin Coras7baeb712019-01-04 17:05:43 -08001198 vlsh = ldp_fd_to_vlsh (fd);
1199 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -05001200 {
1201 vppcom_endpt_t ep;
1202 u8 addr_buf[sizeof (struct in6_addr)];
1203 u32 size = sizeof (ep);
1204
1205 ep.ip = addr_buf;
Florin Coras7baeb712019-01-04 17:05:43 -08001206 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_PEER_ADDR, &ep, &size);
Dave Wallace048b1d62018-01-03 22:24:41 -05001207 if (rv != VPPCOM_OK)
1208 {
1209 errno = -rv;
1210 rv = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001211 }
1212 else
1213 {
Dave Wallace2a865272018-02-07 21:00:42 -05001214 rv = ldp_copy_ep_to_sockaddr (addr, len, &ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05001215 if (rv != VPPCOM_OK)
1216 {
1217 errno = -rv;
1218 rv = -1;
1219 }
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001220 }
1221 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001222 else
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001223 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001224 rv = libc_getpeername (fd, addr, len);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001225 }
1226
Dave Wallace048b1d62018-01-03 22:24:41 -05001227 return rv;
1228}
1229
1230ssize_t
1231send (int fd, const void *buf, size_t n, int flags)
1232{
Florin Coras7baeb712019-01-04 17:05:43 -08001233 vls_handle_t vlsh = ldp_fd_to_vlsh (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05001234 ssize_t size;
Dave Wallace048b1d62018-01-03 22:24:41 -05001235
Dave Wallace2a865272018-02-07 21:00:42 -05001236 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001237 return -1;
1238
Florin Coras7baeb712019-01-04 17:05:43 -08001239 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -05001240 {
Florin Coras7baeb712019-01-04 17:05:43 -08001241 size = vls_sendto (vlsh, (void *) buf, n, flags, NULL);
qchangaa8f63c2018-05-30 11:44:18 -07001242 if (size < VPPCOM_OK)
Dave Wallace048b1d62018-01-03 22:24:41 -05001243 {
1244 errno = -size;
1245 size = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001246 }
1247 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001248 else
1249 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001250 size = libc_send (fd, buf, n, flags);
1251 }
1252
Dave Wallace048b1d62018-01-03 22:24:41 -05001253 return size;
1254}
1255
1256ssize_t
1257sendfile (int out_fd, int in_fd, off_t * offset, size_t len)
1258{
Florin Corasdfe4cf42018-11-28 22:13:45 -08001259 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
Florin Coras7baeb712019-01-04 17:05:43 -08001260 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05001261 ssize_t size = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05001262
Dave Wallace2a865272018-02-07 21:00:42 -05001263 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001264 return -1;
1265
Florin Coras7baeb712019-01-04 17:05:43 -08001266 vlsh = ldp_fd_to_vlsh (out_fd);
1267 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -05001268 {
1269 int rv;
1270 ssize_t results = 0;
1271 size_t n_bytes_left = len;
1272 size_t bytes_to_read;
1273 int nbytes;
Dave Wallace048b1d62018-01-03 22:24:41 -05001274 u8 eagain = 0;
1275 u32 flags, flags_len = sizeof (flags);
1276
Florin Coras7baeb712019-01-04 17:05:43 -08001277 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_FLAGS, &flags, &flags_len);
Dave Wallace048b1d62018-01-03 22:24:41 -05001278 if (PREDICT_FALSE (rv != VPPCOM_OK))
1279 {
Florin Coras7baeb712019-01-04 17:05:43 -08001280 LDBG (0, "ERROR: out fd %d: vls_attr: vlsh %u, returned %d (%s)!",
1281 out_fd, vlsh, rv, vppcom_retval_str (rv));
Dave Wallace048b1d62018-01-03 22:24:41 -05001282
Florin Corasdfe4cf42018-11-28 22:13:45 -08001283 vec_reset_length (ldpw->io_buffer);
Dave Wallace048b1d62018-01-03 22:24:41 -05001284 errno = -rv;
1285 size = -1;
1286 goto done;
1287 }
1288
1289 if (offset)
1290 {
1291 off_t off = lseek (in_fd, *offset, SEEK_SET);
1292 if (PREDICT_FALSE (off == -1))
1293 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001294 size = -1;
1295 goto done;
1296 }
1297
1298 ASSERT (off == *offset);
1299 }
1300
1301 do
1302 {
Florin Coras7baeb712019-01-04 17:05:43 -08001303 size = vls_attr (vlsh, VPPCOM_ATTR_GET_NWRITE, 0, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05001304 if (size < 0)
1305 {
Florin Coras7baeb712019-01-04 17:05:43 -08001306 LDBG (0, "ERROR: fd %d: vls_attr: vlsh %u returned %d (%s)!",
1307 out_fd, vlsh, size, vppcom_retval_str (size));
Florin Corasdfe4cf42018-11-28 22:13:45 -08001308 vec_reset_length (ldpw->io_buffer);
Dave Wallace048b1d62018-01-03 22:24:41 -05001309 errno = -size;
1310 size = -1;
1311 goto done;
1312 }
1313
1314 bytes_to_read = size;
Dave Wallace048b1d62018-01-03 22:24:41 -05001315 if (bytes_to_read == 0)
1316 {
1317 if (flags & O_NONBLOCK)
1318 {
1319 if (!results)
Florin Coras7baeb712019-01-04 17:05:43 -08001320 eagain = 1;
Dave Wallace048b1d62018-01-03 22:24:41 -05001321 goto update_offset;
1322 }
1323 else
1324 continue;
1325 }
1326 bytes_to_read = clib_min (n_bytes_left, bytes_to_read);
Florin Corasdfe4cf42018-11-28 22:13:45 -08001327 vec_validate (ldpw->io_buffer, bytes_to_read);
1328 nbytes = libc_read (in_fd, ldpw->io_buffer, bytes_to_read);
Dave Wallace048b1d62018-01-03 22:24:41 -05001329 if (nbytes < 0)
1330 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001331 if (results == 0)
1332 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08001333 vec_reset_length (ldpw->io_buffer);
Dave Wallace048b1d62018-01-03 22:24:41 -05001334 size = -1;
1335 goto done;
1336 }
1337 goto update_offset;
1338 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001339
Florin Coras7baeb712019-01-04 17:05:43 -08001340 size = vls_write (vlsh, ldpw->io_buffer, nbytes);
Dave Wallace048b1d62018-01-03 22:24:41 -05001341 if (size < 0)
1342 {
1343 if (size == VPPCOM_EAGAIN)
1344 {
1345 if (flags & O_NONBLOCK)
1346 {
1347 if (!results)
Florin Coras7baeb712019-01-04 17:05:43 -08001348 eagain = 1;
Dave Wallace048b1d62018-01-03 22:24:41 -05001349 goto update_offset;
1350 }
1351 else
1352 continue;
1353 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001354 if (results == 0)
1355 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08001356 vec_reset_length (ldpw->io_buffer);
Dave Wallace048b1d62018-01-03 22:24:41 -05001357 errno = -size;
1358 size = -1;
1359 goto done;
1360 }
1361 goto update_offset;
1362 }
1363
1364 results += nbytes;
1365 ASSERT (n_bytes_left >= nbytes);
1366 n_bytes_left = n_bytes_left - nbytes;
1367 }
1368 while (n_bytes_left > 0);
1369
1370 update_offset:
Florin Corasdfe4cf42018-11-28 22:13:45 -08001371 vec_reset_length (ldpw->io_buffer);
Dave Wallace048b1d62018-01-03 22:24:41 -05001372 if (offset)
1373 {
1374 off_t off = lseek (in_fd, *offset, SEEK_SET);
1375 if (PREDICT_FALSE (off == -1))
1376 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001377 size = -1;
1378 goto done;
1379 }
1380
1381 ASSERT (off == *offset);
1382 *offset += results + 1;
1383 }
1384 if (eagain)
1385 {
1386 errno = EAGAIN;
1387 size = -1;
1388 }
1389 else
1390 size = results;
1391 }
1392 else
1393 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001394 size = libc_sendfile (out_fd, in_fd, offset, len);
1395 }
1396
1397done:
Dave Wallace048b1d62018-01-03 22:24:41 -05001398 return size;
1399}
1400
1401ssize_t
1402sendfile64 (int out_fd, int in_fd, off_t * offset, size_t len)
1403{
1404 return sendfile (out_fd, in_fd, offset, len);
1405}
1406
1407ssize_t
1408recv (int fd, void *buf, size_t n, int flags)
1409{
Florin Coras7baeb712019-01-04 17:05:43 -08001410 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05001411 ssize_t size;
Dave Wallace048b1d62018-01-03 22:24:41 -05001412
Dave Wallace2a865272018-02-07 21:00:42 -05001413 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001414 return -1;
1415
Florin Coras7baeb712019-01-04 17:05:43 -08001416 vlsh = ldp_fd_to_vlsh (fd);
1417 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -05001418 {
Florin Coras7baeb712019-01-04 17:05:43 -08001419 size = vls_recvfrom (vlsh, buf, n, flags, NULL);
Dave Wallace048b1d62018-01-03 22:24:41 -05001420 if (size < 0)
Florin Corasa7a1a222018-12-30 17:11:31 -08001421 errno = -size;
Dave Wallace048b1d62018-01-03 22:24:41 -05001422 }
1423 else
1424 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001425 size = libc_recv (fd, buf, n, flags);
1426 }
1427
Dave Wallace048b1d62018-01-03 22:24:41 -05001428 return size;
1429}
1430
1431ssize_t
1432sendto (int fd, const void *buf, size_t n, int flags,
1433 __CONST_SOCKADDR_ARG addr, socklen_t addr_len)
1434{
Florin Coras7baeb712019-01-04 17:05:43 -08001435 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05001436 ssize_t size;
Dave Wallace048b1d62018-01-03 22:24:41 -05001437
Dave Wallace2a865272018-02-07 21:00:42 -05001438 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001439 return -1;
1440
Florin Coras7baeb712019-01-04 17:05:43 -08001441 vlsh = ldp_fd_to_vlsh (fd);
1442 if (vlsh != INVALID_SESSION_ID)
Dave Wallace048b1d62018-01-03 22:24:41 -05001443 {
1444 vppcom_endpt_t *ep = 0;
1445 vppcom_endpt_t _ep;
1446
1447 if (addr)
1448 {
1449 ep = &_ep;
Dave Wallace048b1d62018-01-03 22:24:41 -05001450 switch (addr->sa_family)
1451 {
1452 case AF_INET:
1453 ep->is_ip4 = VPPCOM_IS_IP4;
1454 ep->ip =
1455 (uint8_t *) & ((const struct sockaddr_in *) addr)->sin_addr;
1456 ep->port =
1457 (uint16_t) ((const struct sockaddr_in *) addr)->sin_port;
1458 break;
1459
1460 case AF_INET6:
1461 ep->is_ip4 = VPPCOM_IS_IP6;
1462 ep->ip =
1463 (uint8_t *) & ((const struct sockaddr_in6 *) addr)->sin6_addr;
1464 ep->port =
1465 (uint16_t) ((const struct sockaddr_in6 *) addr)->sin6_port;
1466 break;
1467
1468 default:
1469 errno = EAFNOSUPPORT;
1470 size = -1;
1471 goto done;
1472 }
1473 }
1474
Florin Coras7baeb712019-01-04 17:05:43 -08001475 size = vls_sendto (vlsh, (void *) buf, n, flags, ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05001476 if (size < 0)
1477 {
1478 errno = -size;
1479 size = -1;
1480 }
1481 }
1482 else
1483 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001484 size = libc_sendto (fd, buf, n, flags, addr, addr_len);
1485 }
1486
1487done:
Dave Wallace048b1d62018-01-03 22:24:41 -05001488 return size;
1489}
1490
1491ssize_t
1492recvfrom (int fd, void *__restrict buf, size_t n, int flags,
1493 __SOCKADDR_ARG addr, socklen_t * __restrict addr_len)
1494{
Florin Coras7baeb712019-01-04 17:05:43 -08001495 vls_handle_t sid;
Dave Wallace048b1d62018-01-03 22:24:41 -05001496 ssize_t size;
Dave Wallace048b1d62018-01-03 22:24:41 -05001497
Dave Wallace2a865272018-02-07 21:00:42 -05001498 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001499 return -1;
1500
Florin Coras7baeb712019-01-04 17:05:43 -08001501 sid = ldp_fd_to_vlsh (fd);
1502 if (sid != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -05001503 {
1504 vppcom_endpt_t ep;
1505 u8 src_addr[sizeof (struct sockaddr_in6)];
1506
Dave Wallace048b1d62018-01-03 22:24:41 -05001507 if (addr)
1508 {
1509 ep.ip = src_addr;
Florin Coras7baeb712019-01-04 17:05:43 -08001510 size = vls_recvfrom (sid, buf, n, flags, &ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05001511
1512 if (size > 0)
Dave Wallace2a865272018-02-07 21:00:42 -05001513 size = ldp_copy_ep_to_sockaddr (addr, addr_len, &ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05001514 }
1515 else
Florin Coras7baeb712019-01-04 17:05:43 -08001516 size = vls_recvfrom (sid, buf, n, flags, NULL);
Dave Wallace048b1d62018-01-03 22:24:41 -05001517
1518 if (size < 0)
1519 {
1520 errno = -size;
1521 size = -1;
1522 }
1523 }
1524 else
1525 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001526 size = libc_recvfrom (fd, buf, n, flags, addr, addr_len);
1527 }
1528
Dave Wallace048b1d62018-01-03 22:24:41 -05001529 return size;
1530}
1531
1532ssize_t
1533sendmsg (int fd, const struct msghdr * message, int flags)
1534{
Florin Coras7baeb712019-01-04 17:05:43 -08001535 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05001536 ssize_t size;
Dave Wallace048b1d62018-01-03 22:24:41 -05001537
Dave Wallace2a865272018-02-07 21:00:42 -05001538 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001539 return -1;
1540
Florin Coras7baeb712019-01-04 17:05:43 -08001541 vlsh = ldp_fd_to_vlsh (fd);
1542 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -05001543 {
Florin Coras7baeb712019-01-04 17:05:43 -08001544 LDBG (0, "LDP-TBD");
Dave Wallace048b1d62018-01-03 22:24:41 -05001545 errno = ENOSYS;
1546 size = -1;
1547 }
1548 else
1549 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001550 size = libc_sendmsg (fd, message, flags);
1551 }
1552
Dave Wallace048b1d62018-01-03 22:24:41 -05001553 return size;
1554}
1555
1556#ifdef USE_GNU
1557int
1558sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags)
1559{
1560 ssize_t size;
1561 const char *func_str;
Florin Coras7baeb712019-01-04 17:05:43 -08001562 u32 sh = ldp_fd_to_vlsh (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05001563
Dave Wallace2a865272018-02-07 21:00:42 -05001564 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001565 return -1;
1566
Florin Coras7baeb712019-01-04 17:05:43 -08001567 if (sh != INVALID_SESSION_ID)
Dave Wallace048b1d62018-01-03 22:24:41 -05001568 {
1569 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
1570 errno = ENOSYS;
1571 size = -1;
1572 }
1573 else
1574 {
1575 func_str = "libc_sendmmsg";
1576
Dave Wallace2a865272018-02-07 21:00:42 -05001577 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001578 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1579 "vmessages %p, vlen %u, flags 0x%x",
1580 getpid (), fd, fd, func_str, vmessages, vlen, flags);
1581
1582 size = libc_sendmmsg (fd, vmessages, vlen, flags);
1583 }
1584
Dave Wallace2a865272018-02-07 21:00:42 -05001585 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001586 {
1587 if (size < 0)
1588 {
1589 int errno_val = errno;
1590 perror (func_str);
1591 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1592 "rv %d, errno = %d", getpid (), fd, fd,
1593 func_str, size, errno_val);
1594 errno = errno_val;
1595 }
1596 else
1597 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1598 getpid (), fd, fd, size, size);
1599 }
1600 return size;
1601}
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001602#endif
1603
Dave Wallace048b1d62018-01-03 22:24:41 -05001604ssize_t
1605recvmsg (int fd, struct msghdr * message, int flags)
1606{
Florin Coras7baeb712019-01-04 17:05:43 -08001607 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05001608 ssize_t size;
Dave Wallace048b1d62018-01-03 22:24:41 -05001609
Dave Wallace2a865272018-02-07 21:00:42 -05001610 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001611 return -1;
1612
Florin Coras7baeb712019-01-04 17:05:43 -08001613 vlsh = ldp_fd_to_vlsh (fd);
1614 if (vlsh != VLS_INVALID_HANDLE)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001615 {
Florin Coras7baeb712019-01-04 17:05:43 -08001616 LDBG (0, "LDP-TBD");
Dave Wallace048b1d62018-01-03 22:24:41 -05001617 errno = ENOSYS;
1618 size = -1;
1619 }
1620 else
1621 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001622 size = libc_recvmsg (fd, message, flags);
1623 }
1624
Dave Wallace048b1d62018-01-03 22:24:41 -05001625 return size;
1626}
1627
1628#ifdef USE_GNU
1629int
1630recvmmsg (int fd, struct mmsghdr *vmessages,
1631 unsigned int vlen, int flags, struct timespec *tmo)
1632{
1633 ssize_t size;
1634 const char *func_str;
Florin Coras7baeb712019-01-04 17:05:43 -08001635 u32 sh = ldp_fd_to_vlsh (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05001636
Dave Wallace2a865272018-02-07 21:00:42 -05001637 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001638 return -1;
1639
Florin Coras7baeb712019-01-04 17:05:43 -08001640 if (sh != INVALID_SESSION_ID)
Dave Wallace048b1d62018-01-03 22:24:41 -05001641 {
1642 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
1643 errno = ENOSYS;
1644 size = -1;
1645 }
1646 else
1647 {
1648 func_str = "libc_recvmmsg";
1649
Dave Wallace2a865272018-02-07 21:00:42 -05001650 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001651 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1652 "vmessages %p, vlen %u, flags 0x%x, tmo %p",
1653 getpid (), fd, fd, func_str, vmessages, vlen,
1654 flags, tmo);
1655
1656 size = libc_recvmmsg (fd, vmessages, vlen, flags, tmo);
1657 }
1658
Dave Wallace2a865272018-02-07 21:00:42 -05001659 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001660 {
1661 if (size < 0)
1662 {
1663 int errno_val = errno;
1664 perror (func_str);
1665 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1666 "rv %d, errno = %d", getpid (), fd, fd,
1667 func_str, size, errno_val);
1668 errno = errno_val;
1669 }
1670 else
1671 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1672 getpid (), fd, fd, size, size);
1673 }
1674 return size;
1675}
1676#endif
1677
1678int
1679getsockopt (int fd, int level, int optname,
1680 void *__restrict optval, socklen_t * __restrict optlen)
1681{
Florin Coras7baeb712019-01-04 17:05:43 -08001682 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05001683 int rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001684
Dave Wallace2a865272018-02-07 21:00:42 -05001685 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001686 return -1;
1687
Florin Coras7baeb712019-01-04 17:05:43 -08001688 vlsh = ldp_fd_to_vlsh (fd);
1689 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -05001690 {
1691 rv = -EOPNOTSUPP;
1692
1693 switch (level)
1694 {
1695 case SOL_TCP:
1696 switch (optname)
1697 {
1698 case TCP_NODELAY:
Florin Coras7baeb712019-01-04 17:05:43 -08001699 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_TCP_NODELAY,
1700 optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001701 break;
1702 case TCP_MAXSEG:
Florin Coras7baeb712019-01-04 17:05:43 -08001703 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_TCP_USER_MSS,
1704 optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001705 break;
1706 case TCP_KEEPIDLE:
Florin Coras7baeb712019-01-04 17:05:43 -08001707 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_TCP_KEEPIDLE,
1708 optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001709 break;
1710 case TCP_KEEPINTVL:
Florin Coras7baeb712019-01-04 17:05:43 -08001711 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_TCP_KEEPINTVL,
1712 optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001713 break;
1714 case TCP_INFO:
1715 if (optval && optlen && (*optlen == sizeof (struct tcp_info)))
1716 {
Florin Coras7baeb712019-01-04 17:05:43 -08001717 LDBG (1, "fd %d: vlsh %u SOL_TCP, TCP_INFO, optval %p, "
1718 "optlen %d: #LDP-NOP#", fd, vlsh, optval, *optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001719 memset (optval, 0, *optlen);
1720 rv = VPPCOM_OK;
1721 }
1722 else
1723 rv = -EFAULT;
1724 break;
1725 default:
Florin Coras7baeb712019-01-04 17:05:43 -08001726 LDBG (0, "ERROR: fd %d: getsockopt SOL_TCP: sid %u, "
1727 "optname %d unsupported!", fd, vlsh, optname);
Dave Wallace048b1d62018-01-03 22:24:41 -05001728 break;
1729 }
1730 break;
1731 case SOL_IPV6:
1732 switch (optname)
1733 {
1734 case IPV6_V6ONLY:
Florin Coras7baeb712019-01-04 17:05:43 -08001735 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_V6ONLY, optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001736 break;
1737 default:
Florin Coras7baeb712019-01-04 17:05:43 -08001738 LDBG (0, "ERROR: fd %d: getsockopt SOL_IPV6: vlsh %u "
1739 "optname %d unsupported!", fd, vlsh, optname);
Dave Wallace048b1d62018-01-03 22:24:41 -05001740 break;
1741 }
1742 break;
1743 case SOL_SOCKET:
1744 switch (optname)
1745 {
1746 case SO_ACCEPTCONN:
Florin Coras7baeb712019-01-04 17:05:43 -08001747 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_LISTEN, optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001748 break;
1749 case SO_KEEPALIVE:
Florin Coras7baeb712019-01-04 17:05:43 -08001750 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_KEEPALIVE, optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001751 break;
1752 case SO_PROTOCOL:
Florin Coras7baeb712019-01-04 17:05:43 -08001753 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_PROTOCOL, optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001754 *(int *) optval = *(int *) optval ? SOCK_DGRAM : SOCK_STREAM;
1755 break;
1756 case SO_SNDBUF:
Florin Coras7baeb712019-01-04 17:05:43 -08001757 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_TX_FIFO_LEN,
1758 optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001759 break;
1760 case SO_RCVBUF:
Florin Coras7baeb712019-01-04 17:05:43 -08001761 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_RX_FIFO_LEN,
1762 optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001763 break;
1764 case SO_REUSEADDR:
Florin Coras7baeb712019-01-04 17:05:43 -08001765 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_REUSEADDR, optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001766 break;
1767 case SO_BROADCAST:
Florin Coras7baeb712019-01-04 17:05:43 -08001768 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_BROADCAST, optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001769 break;
1770 case SO_ERROR:
Florin Coras7baeb712019-01-04 17:05:43 -08001771 rv = vls_attr (vlsh, VPPCOM_ATTR_GET_ERROR, optval, optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001772 break;
1773 default:
Florin Coras7baeb712019-01-04 17:05:43 -08001774 LDBG (0, "ERROR: fd %d: getsockopt SOL_SOCKET: vlsh %u "
1775 "optname %d unsupported!", fd, vlsh, optname);
Dave Wallace048b1d62018-01-03 22:24:41 -05001776 break;
1777 }
1778 break;
1779 default:
1780 break;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001781 }
1782
Dave Wallace048b1d62018-01-03 22:24:41 -05001783 if (rv != VPPCOM_OK)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001784 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001785 errno = -rv;
1786 rv = -1;
1787 }
1788 }
1789 else
1790 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001791 rv = libc_getsockopt (fd, level, optname, optval, optlen);
1792 }
1793
Dave Wallace048b1d62018-01-03 22:24:41 -05001794 return rv;
1795}
1796
1797int
1798setsockopt (int fd, int level, int optname,
1799 const void *optval, socklen_t optlen)
1800{
Florin Coras7baeb712019-01-04 17:05:43 -08001801 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05001802 int rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001803
Dave Wallace2a865272018-02-07 21:00:42 -05001804 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001805 return -1;
1806
Florin Coras7baeb712019-01-04 17:05:43 -08001807 vlsh = ldp_fd_to_vlsh (fd);
1808 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -05001809 {
1810 rv = -EOPNOTSUPP;
1811
1812 switch (level)
1813 {
1814 case SOL_TCP:
1815 switch (optname)
1816 {
1817 case TCP_NODELAY:
Florin Coras7baeb712019-01-04 17:05:43 -08001818 rv = vls_attr (vlsh, VPPCOM_ATTR_SET_TCP_NODELAY,
1819 (void *) optval, &optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001820 break;
1821 case TCP_MAXSEG:
Florin Coras7baeb712019-01-04 17:05:43 -08001822 rv = vls_attr (vlsh, VPPCOM_ATTR_SET_TCP_USER_MSS,
1823 (void *) optval, &optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001824 break;
1825 case TCP_KEEPIDLE:
Florin Coras7baeb712019-01-04 17:05:43 -08001826 rv = vls_attr (vlsh, VPPCOM_ATTR_SET_TCP_KEEPIDLE,
1827 (void *) optval, &optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001828 break;
1829 case TCP_KEEPINTVL:
Florin Coras7baeb712019-01-04 17:05:43 -08001830 rv = vls_attr (vlsh, VPPCOM_ATTR_SET_TCP_KEEPINTVL,
1831 (void *) optval, &optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001832 break;
1833 default:
Florin Coras7baeb712019-01-04 17:05:43 -08001834 LDBG (0, "ERROR: fd %d: setsockopt() SOL_TCP: vlsh %u"
1835 "optname %d unsupported!", fd, vlsh, optname);
Dave Wallace048b1d62018-01-03 22:24:41 -05001836 break;
1837 }
1838 break;
1839 case SOL_IPV6:
1840 switch (optname)
1841 {
1842 case IPV6_V6ONLY:
Florin Coras7baeb712019-01-04 17:05:43 -08001843 rv = vls_attr (vlsh, VPPCOM_ATTR_SET_V6ONLY,
1844 (void *) optval, &optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001845 break;
1846 default:
Florin Coras7baeb712019-01-04 17:05:43 -08001847 LDBG (0, "ERROR: fd %d: setsockopt SOL_IPV6: vlsh %u"
1848 "optname %d unsupported!", fd, vlsh, optname);
Dave Wallace048b1d62018-01-03 22:24:41 -05001849 break;
1850 }
1851 break;
1852 case SOL_SOCKET:
1853 switch (optname)
1854 {
1855 case SO_KEEPALIVE:
Florin Coras7baeb712019-01-04 17:05:43 -08001856 rv = vls_attr (vlsh, VPPCOM_ATTR_SET_KEEPALIVE,
1857 (void *) optval, &optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001858 break;
1859 case SO_REUSEADDR:
Florin Coras7baeb712019-01-04 17:05:43 -08001860 rv = vls_attr (vlsh, VPPCOM_ATTR_SET_REUSEADDR,
1861 (void *) optval, &optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001862 break;
1863 case SO_BROADCAST:
Florin Coras7baeb712019-01-04 17:05:43 -08001864 rv = vls_attr (vlsh, VPPCOM_ATTR_SET_BROADCAST,
1865 (void *) optval, &optlen);
Dave Wallace048b1d62018-01-03 22:24:41 -05001866 break;
1867 default:
Florin Coras7baeb712019-01-04 17:05:43 -08001868 LDBG (0, "ERROR: fd %d: setsockopt SOL_SOCKET: vlsh %u "
1869 "optname %d unsupported!", fd, vlsh, optname);
Dave Wallace048b1d62018-01-03 22:24:41 -05001870 break;
1871 }
1872 break;
1873 default:
1874 break;
1875 }
1876
1877 if (rv != VPPCOM_OK)
1878 {
1879 errno = -rv;
1880 rv = -1;
1881 }
1882 }
1883 else
1884 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001885 rv = libc_setsockopt (fd, level, optname, optval, optlen);
1886 }
1887
Dave Wallace048b1d62018-01-03 22:24:41 -05001888 return rv;
1889}
1890
1891int
1892listen (int fd, int n)
1893{
Florin Coras7baeb712019-01-04 17:05:43 -08001894 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05001895 int rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001896
Dave Wallace2a865272018-02-07 21:00:42 -05001897 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001898 return -1;
1899
Florin Coras7baeb712019-01-04 17:05:43 -08001900 vlsh = ldp_fd_to_vlsh (fd);
1901 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -05001902 {
Florin Coras7baeb712019-01-04 17:05:43 -08001903 LDBG (0, "fd %d: calling vls_listen: vlsh %u, n %d", fd, vlsh, n);
Dave Wallace048b1d62018-01-03 22:24:41 -05001904
Florin Coras7baeb712019-01-04 17:05:43 -08001905 rv = vls_listen (vlsh, n);
Dave Wallace048b1d62018-01-03 22:24:41 -05001906 if (rv != VPPCOM_OK)
1907 {
1908 errno = -rv;
1909 rv = -1;
1910 }
1911 }
1912 else
1913 {
Florin Coras7baeb712019-01-04 17:05:43 -08001914 LDBG (0, "fd %d: calling libc_listen(): n %d", fd, n);
Dave Wallace048b1d62018-01-03 22:24:41 -05001915 rv = libc_listen (fd, n);
1916 }
1917
Florin Coras7baeb712019-01-04 17:05:43 -08001918 LDBG (1, "fd %d: returning %d", fd, rv);
Dave Wallace048b1d62018-01-03 22:24:41 -05001919 return rv;
1920}
1921
1922static inline int
Dave Wallace2a865272018-02-07 21:00:42 -05001923ldp_accept4 (int listen_fd, __SOCKADDR_ARG addr,
1924 socklen_t * __restrict addr_len, int flags)
Dave Wallace048b1d62018-01-03 22:24:41 -05001925{
Florin Coras7baeb712019-01-04 17:05:43 -08001926 vls_handle_t listen_vlsh, accept_vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05001927 int rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001928
Dave Wallace2a865272018-02-07 21:00:42 -05001929 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001930 return -1;
1931
Florin Coras7baeb712019-01-04 17:05:43 -08001932 listen_vlsh = ldp_fd_to_vlsh (listen_fd);
1933 if (listen_vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -05001934 {
1935 vppcom_endpt_t ep;
1936 u8 src_addr[sizeof (struct sockaddr_in6)];
Dave Wallace8aaba562018-01-18 17:21:19 -05001937 memset (&ep, 0, sizeof (ep));
Dave Wallace048b1d62018-01-03 22:24:41 -05001938 ep.ip = src_addr;
1939
Florin Coras7baeb712019-01-04 17:05:43 -08001940 LDBG (0, "listen fd %d: calling vppcom_session_accept: listen sid %u,"
1941 " ep %p, flags 0x%x", listen_fd, listen_vlsh, ep, flags);
Dave Wallace048b1d62018-01-03 22:24:41 -05001942
Florin Coras7baeb712019-01-04 17:05:43 -08001943 accept_vlsh = vls_accept (listen_vlsh, &ep, flags);
1944 if (accept_vlsh < 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001945 {
Florin Coras7baeb712019-01-04 17:05:43 -08001946 errno = -accept_vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05001947 rv = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001948 }
1949 else
1950 {
Dave Wallace2a865272018-02-07 21:00:42 -05001951 rv = ldp_copy_ep_to_sockaddr (addr, addr_len, &ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05001952 if (rv != VPPCOM_OK)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001953 {
Florin Coras7baeb712019-01-04 17:05:43 -08001954 (void) vls_close (accept_vlsh);
Dave Wallace048b1d62018-01-03 22:24:41 -05001955 errno = -rv;
1956 rv = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001957 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001958 else
1959 {
Florin Coras7baeb712019-01-04 17:05:43 -08001960 rv = ldp_vlsh_to_fd (accept_vlsh);
Dave Wallace048b1d62018-01-03 22:24:41 -05001961 }
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001962 }
1963 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001964 else
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001965 {
Florin Coras7baeb712019-01-04 17:05:43 -08001966 LDBG (0, "listen fd %d: calling libc_accept4(): addr %p, addr_len %p,"
1967 " flags 0x%x", listen_fd, addr, addr_len, flags);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001968
Dave Wallace048b1d62018-01-03 22:24:41 -05001969 rv = libc_accept4 (listen_fd, addr, addr_len, flags);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001970 }
1971
Florin Coras7baeb712019-01-04 17:05:43 -08001972 LDBG (1, "listen fd %d: accept returning %d", listen_fd, rv);
Florin Coras05ecfcc2018-12-12 18:19:39 -08001973
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001974 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001975}
1976
Dave Wallace048b1d62018-01-03 22:24:41 -05001977int
1978accept4 (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict addr_len,
1979 int flags)
1980{
Dave Wallace2a865272018-02-07 21:00:42 -05001981 return ldp_accept4 (fd, addr, addr_len, flags);
Dave Wallace048b1d62018-01-03 22:24:41 -05001982}
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001983
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001984int
Dave Wallace048b1d62018-01-03 22:24:41 -05001985accept (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict addr_len)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001986{
Dave Wallace2a865272018-02-07 21:00:42 -05001987 return ldp_accept4 (fd, addr, addr_len, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05001988}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001989
Dave Wallace048b1d62018-01-03 22:24:41 -05001990int
1991shutdown (int fd, int how)
1992{
Florin Coras7baeb712019-01-04 17:05:43 -08001993 vls_handle_t vlsh;
1994 int rv = 0, flags;
1995 u32 flags_len = sizeof (flags);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001996
Dave Wallace2a865272018-02-07 21:00:42 -05001997 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001998 return -1;
1999
Florin Coras7baeb712019-01-04 17:05:43 -08002000 vlsh = ldp_fd_to_vlsh (fd);
2001 if (vlsh != VLS_INVALID_HANDLE)
Dave Wallace048b1d62018-01-03 22:24:41 -05002002 {
Florin Coras7baeb712019-01-04 17:05:43 -08002003 LDBG (0, "called shutdown: fd %u vlsh %u how %d", fd, vlsh, how);
Florin Corasa7a1a222018-12-30 17:11:31 -08002004
Florin Coras7baeb712019-01-04 17:05:43 -08002005 if (vls_attr (vlsh, VPPCOM_ATTR_SET_SHUT, &how, &flags_len))
Florin Corasa7a1a222018-12-30 17:11:31 -08002006 {
Florin Coras7baeb712019-01-04 17:05:43 -08002007 close (fd);
Florin Corasa7a1a222018-12-30 17:11:31 -08002008 return -1;
2009 }
2010
Florin Coras7baeb712019-01-04 17:05:43 -08002011 if (vls_attr (vlsh, VPPCOM_ATTR_GET_SHUT, &flags, &flags_len))
2012 {
2013 close (fd);
2014 return -1;
2015 }
Florin Corasa7a1a222018-12-30 17:11:31 -08002016
Florin Coras7baeb712019-01-04 17:05:43 -08002017 if (flags == SHUT_RDWR)
Florin Corasa7a1a222018-12-30 17:11:31 -08002018 rv = close (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002019 }
2020 else
2021 {
Florin Coras7baeb712019-01-04 17:05:43 -08002022 LDBG (0, "fd %d: calling libc_shutdown: how %d", fd, how);
Dave Wallace048b1d62018-01-03 22:24:41 -05002023 rv = libc_shutdown (fd, how);
2024 }
2025
Dave Wallace048b1d62018-01-03 22:24:41 -05002026 return rv;
2027}
2028
2029int
2030epoll_create1 (int flags)
2031{
Florin Corasdfe4cf42018-11-28 22:13:45 -08002032 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
Florin Coras7baeb712019-01-04 17:05:43 -08002033 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05002034 int rv;
2035
Dave Wallace2a865272018-02-07 21:00:42 -05002036 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002037 return -1;
2038
Florin Coras99368312018-08-02 10:45:44 -07002039 if (ldp->vcl_needs_real_epoll)
2040 {
2041 rv = libc_epoll_create1 (flags);
2042 ldp->vcl_needs_real_epoll = 0;
Florin Corasdfe4cf42018-11-28 22:13:45 -08002043 ldpw->vcl_mq_epfd = rv;
Florin Coras05ecfcc2018-12-12 18:19:39 -08002044 LDBG (0, "created vcl epfd %u", rv);
Florin Coras99368312018-08-02 10:45:44 -07002045 return rv;
2046 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002047
Florin Coras7baeb712019-01-04 17:05:43 -08002048 vlsh = vls_epoll_create ();
2049 if (PREDICT_FALSE (vlsh == VLS_INVALID_HANDLE))
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002050 {
Florin Coras7baeb712019-01-04 17:05:43 -08002051 errno = -vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05002052 rv = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002053 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002054 else
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002055 {
Florin Coras7baeb712019-01-04 17:05:43 -08002056 rv = ldp_vlsh_to_fd (vlsh);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002057 }
Florin Coras7baeb712019-01-04 17:05:43 -08002058 LDBG (0, "epoll_create epfd %u vlsh %u", rv, vlsh);
Dave Wallace048b1d62018-01-03 22:24:41 -05002059 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002060}
2061
2062int
Dave Wallace048b1d62018-01-03 22:24:41 -05002063epoll_create (int size)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002064{
Dave Wallace048b1d62018-01-03 22:24:41 -05002065 return epoll_create1 (0);
2066}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002067
Dave Wallace048b1d62018-01-03 22:24:41 -05002068int
2069epoll_ctl (int epfd, int op, int fd, struct epoll_event *event)
2070{
Florin Coras7baeb712019-01-04 17:05:43 -08002071 vls_handle_t vep_vlsh, vlsh;
Florin Coras99368312018-08-02 10:45:44 -07002072 int rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05002073
Dave Wallace2a865272018-02-07 21:00:42 -05002074 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002075 return -1;
2076
Florin Coras7baeb712019-01-04 17:05:43 -08002077 vep_vlsh = ldp_fd_to_vlsh (epfd);
2078 if (PREDICT_FALSE (vep_vlsh == VLS_INVALID_HANDLE))
Dave Wallace048b1d62018-01-03 22:24:41 -05002079 {
Dave Wallace3ee1fe12018-02-23 01:09:11 -05002080 /* The LDP epoll_create1 always creates VCL epfd's.
2081 * The app should never have a kernel base epoll fd unless it
2082 * was acquired outside of the LD_PRELOAD process context.
2083 * In any case, if we get one, punt it to libc_epoll_ctl.
2084 */
Florin Coras7baeb712019-01-04 17:05:43 -08002085 LDBG (1, "epfd %d: calling libc_epoll_ctl: op %d, fd %d"
2086 " event %p", epfd, op, fd, event);
Dave Wallace048b1d62018-01-03 22:24:41 -05002087
2088 rv = libc_epoll_ctl (epfd, op, fd, event);
Florin Coras99368312018-08-02 10:45:44 -07002089 goto done;
2090 }
2091
Florin Coras7baeb712019-01-04 17:05:43 -08002092 vlsh = ldp_fd_to_vlsh (fd);
Florin Coras99368312018-08-02 10:45:44 -07002093
Florin Coras7baeb712019-01-04 17:05:43 -08002094 LDBG (0, "epfd %d ep_vlsh %d, fd %u vlsh %d, op %u", epfd, vep_vlsh, fd,
2095 vlsh, op);
Florin Coras99368312018-08-02 10:45:44 -07002096
Florin Coras7baeb712019-01-04 17:05:43 -08002097 if (vlsh != VLS_INVALID_HANDLE)
Florin Coras99368312018-08-02 10:45:44 -07002098 {
Florin Coras7baeb712019-01-04 17:05:43 -08002099 LDBG (1, "epfd %d: calling vls_epoll_ctl: ep_vlsh %d op %d, vlsh %u,"
2100 " event %p", epfd, vep_vlsh, vlsh, event);
Florin Coras99368312018-08-02 10:45:44 -07002101
Florin Coras7baeb712019-01-04 17:05:43 -08002102 rv = vls_epoll_ctl (vep_vlsh, op, vlsh, event);
Florin Coras99368312018-08-02 10:45:44 -07002103 if (rv != VPPCOM_OK)
2104 {
2105 errno = -rv;
2106 rv = -1;
2107 }
2108 }
2109 else
2110 {
2111 int libc_epfd;
2112 u32 size = sizeof (epfd);
2113
Florin Coras7baeb712019-01-04 17:05:43 -08002114 libc_epfd = vls_attr (vep_vlsh, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
Florin Coras99368312018-08-02 10:45:44 -07002115 if (!libc_epfd)
2116 {
Florin Coras7baeb712019-01-04 17:05:43 -08002117 LDBG (1, "epfd %d, vep_vlsh %d calling libc_epoll_create1: "
2118 "EPOLL_CLOEXEC", epfd, vep_vlsh);
Florin Coras99368312018-08-02 10:45:44 -07002119
2120 libc_epfd = libc_epoll_create1 (EPOLL_CLOEXEC);
2121 if (libc_epfd < 0)
2122 {
2123 rv = libc_epfd;
2124 goto done;
2125 }
2126
Florin Coras7baeb712019-01-04 17:05:43 -08002127 rv = vls_attr (vep_vlsh, VPPCOM_ATTR_SET_LIBC_EPFD, &libc_epfd,
2128 &size);
Florin Coras99368312018-08-02 10:45:44 -07002129 if (rv < 0)
2130 {
2131 errno = -rv;
2132 rv = -1;
2133 goto done;
2134 }
2135 }
2136 else if (PREDICT_FALSE (libc_epfd < 0))
2137 {
2138 errno = -epfd;
2139 rv = -1;
2140 goto done;
2141 }
2142
Florin Coras7baeb712019-01-04 17:05:43 -08002143 LDBG (1, "epfd %d: calling libc_epoll_ctl: libc_epfd %d, op %d, fd %d,"
2144 " event %p", epfd, libc_epfd, op, fd, event);
Florin Coras99368312018-08-02 10:45:44 -07002145
2146 rv = libc_epoll_ctl (libc_epfd, op, fd, event);
Dave Wallace048b1d62018-01-03 22:24:41 -05002147 }
2148
2149done:
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002150 return rv;
2151}
Dave Wallace048b1d62018-01-03 22:24:41 -05002152
2153static inline int
Florin Coras99368312018-08-02 10:45:44 -07002154ldp_epoll_pwait (int epfd, struct epoll_event *events, int maxevents,
2155 int timeout, const sigset_t * sigmask)
Dave Wallace048b1d62018-01-03 22:24:41 -05002156{
Florin Corasdfe4cf42018-11-28 22:13:45 -08002157 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
Florin Coras99368312018-08-02 10:45:44 -07002158 double time_to_wait = (double) 0, time_out, now = 0;
Florin Coras99368312018-08-02 10:45:44 -07002159 int libc_epfd, rv = 0;
Florin Coras7baeb712019-01-04 17:05:43 -08002160 vls_handle_t ep_vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05002161
Dave Wallace2a865272018-02-07 21:00:42 -05002162 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002163 return -1;
2164
2165 if (PREDICT_FALSE (!events || (timeout < -1)))
2166 {
2167 errno = EFAULT;
2168 return -1;
2169 }
2170
Florin Corasdfe4cf42018-11-28 22:13:45 -08002171 if (epfd == ldpw->vcl_mq_epfd)
Florin Coras99368312018-08-02 10:45:44 -07002172 return libc_epoll_pwait (epfd, events, maxevents, timeout, sigmask);
2173
Florin Coras7baeb712019-01-04 17:05:43 -08002174 ep_vlsh = ldp_fd_to_vlsh (epfd);
2175 if (PREDICT_FALSE (ep_vlsh == VLS_INVALID_HANDLE))
Dave Wallace048b1d62018-01-03 22:24:41 -05002176 {
Florin Coras7baeb712019-01-04 17:05:43 -08002177 LDBG (0, "epfd %d: bad ep_vlsh %d!", epfd, ep_vlsh);
Dave Wallace048b1d62018-01-03 22:24:41 -05002178 errno = EBADFD;
2179 return -1;
2180 }
2181
Florin Corasb0f662f2018-12-27 14:51:46 -08002182 time_to_wait = ((timeout >= 0) ? (double) timeout / 1000 : 0);
Florin Corasdfe4cf42018-11-28 22:13:45 -08002183 time_out = clib_time_now (&ldpw->clib_time) + time_to_wait;
Dave Wallace048b1d62018-01-03 22:24:41 -05002184
Florin Coras7baeb712019-01-04 17:05:43 -08002185 libc_epfd = vls_attr (ep_vlsh, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05002186 if (PREDICT_FALSE (libc_epfd < 0))
2187 {
2188 errno = -libc_epfd;
2189 rv = -1;
2190 goto done;
2191 }
2192
Florin Coras7baeb712019-01-04 17:05:43 -08002193 LDBG (2, "epfd %d: vep_idx %d, libc_epfd %d, events %p, maxevents %d, "
2194 "timeout %d, sigmask %p: time_to_wait %.02f", epfd, ep_vlsh,
2195 libc_epfd, events, maxevents, timeout, sigmask, time_to_wait,
2196 time_out);
Dave Wallace048b1d62018-01-03 22:24:41 -05002197 do
2198 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08002199 if (!ldpw->epoll_wait_vcl)
Dave Wallace048b1d62018-01-03 22:24:41 -05002200 {
Florin Coras7baeb712019-01-04 17:05:43 -08002201 rv = vls_epoll_wait (ep_vlsh, events, maxevents, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05002202 if (rv > 0)
2203 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08002204 ldpw->epoll_wait_vcl = 1;
Dave Wallace048b1d62018-01-03 22:24:41 -05002205 goto done;
2206 }
2207 else if (rv < 0)
2208 {
2209 errno = -rv;
2210 rv = -1;
2211 goto done;
2212 }
2213 }
2214 else
Florin Corasdfe4cf42018-11-28 22:13:45 -08002215 ldpw->epoll_wait_vcl = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05002216
2217 if (libc_epfd > 0)
2218 {
Florin Corasb0f662f2018-12-27 14:51:46 -08002219 rv = libc_epoll_pwait (libc_epfd, events, maxevents, 0, sigmask);
Dave Wallace048b1d62018-01-03 22:24:41 -05002220 if (rv != 0)
2221 goto done;
2222 }
2223
2224 if (timeout != -1)
Florin Corasdfe4cf42018-11-28 22:13:45 -08002225 now = clib_time_now (&ldpw->clib_time);
Dave Wallace048b1d62018-01-03 22:24:41 -05002226 }
2227 while (now < time_out);
2228
2229done:
Dave Wallace048b1d62018-01-03 22:24:41 -05002230 return rv;
2231}
2232
2233int
2234epoll_pwait (int epfd, struct epoll_event *events,
2235 int maxevents, int timeout, const sigset_t * sigmask)
2236{
Dave Wallace2a865272018-02-07 21:00:42 -05002237 return ldp_epoll_pwait (epfd, events, maxevents, timeout, sigmask);
Dave Wallace048b1d62018-01-03 22:24:41 -05002238}
2239
2240int
2241epoll_wait (int epfd, struct epoll_event *events, int maxevents, int timeout)
2242{
Dave Wallace2a865272018-02-07 21:00:42 -05002243 return ldp_epoll_pwait (epfd, events, maxevents, timeout, NULL);
Dave Wallace048b1d62018-01-03 22:24:41 -05002244}
2245
2246int
2247poll (struct pollfd *fds, nfds_t nfds, int timeout)
2248{
Florin Corasdfe4cf42018-11-28 22:13:45 -08002249 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
Florin Coras6917b942018-11-13 22:44:54 -08002250 int rv, i, n_revents = 0;
Florin Coras7baeb712019-01-04 17:05:43 -08002251 vls_handle_t vlsh;
Dave Wallace048b1d62018-01-03 22:24:41 -05002252 vcl_poll_t *vp;
2253 double wait_for_time;
2254
Florin Coras05ecfcc2018-12-12 18:19:39 -08002255 LDBG (3, "fds %p, nfds %d, timeout %d", fds, nfds, timeout);
Dave Wallace048b1d62018-01-03 22:24:41 -05002256
2257 if (timeout >= 0)
2258 wait_for_time = (f64) timeout / 1000;
2259 else
2260 wait_for_time = -1;
2261
Dave Wallace048b1d62018-01-03 22:24:41 -05002262 for (i = 0; i < nfds; i++)
2263 {
Florin Coras6917b942018-11-13 22:44:54 -08002264 if (fds[i].fd < 0)
2265 continue;
Dave Wallace048b1d62018-01-03 22:24:41 -05002266
Florin Coras7baeb712019-01-04 17:05:43 -08002267 vlsh = ldp_fd_to_vlsh (fds[i].fd);
2268 if (vlsh != VLS_INVALID_HANDLE)
Florin Coras6917b942018-11-13 22:44:54 -08002269 {
2270 fds[i].fd = -fds[i].fd;
Florin Corasdfe4cf42018-11-28 22:13:45 -08002271 vec_add2 (ldpw->vcl_poll, vp, 1);
Florin Coras6917b942018-11-13 22:44:54 -08002272 vp->fds_ndx = i;
Florin Coras7baeb712019-01-04 17:05:43 -08002273 vp->sh = vlsh_to_sh (vlsh);
Florin Coras6917b942018-11-13 22:44:54 -08002274 vp->events = fds[i].events;
Dave Wallace048b1d62018-01-03 22:24:41 -05002275#ifdef __USE_XOPEN2K
Florin Coras6917b942018-11-13 22:44:54 -08002276 if (fds[i].events & POLLRDNORM)
2277 vp->events |= POLLIN;
2278 if (fds[i].events & POLLWRNORM)
2279 vp->events |= POLLOUT;
Dave Wallace048b1d62018-01-03 22:24:41 -05002280#endif
Florin Coras6917b942018-11-13 22:44:54 -08002281 vp->revents = fds[i].revents;
2282 }
2283 else
2284 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08002285 vec_add1 (ldpw->libc_poll, fds[i]);
2286 vec_add1 (ldpw->libc_poll_idxs, i);
Dave Wallace048b1d62018-01-03 22:24:41 -05002287 }
2288 }
2289
Dave Wallace048b1d62018-01-03 22:24:41 -05002290 do
2291 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08002292 if (vec_len (ldpw->vcl_poll))
Dave Wallace048b1d62018-01-03 22:24:41 -05002293 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08002294 rv = vppcom_poll (ldpw->vcl_poll, vec_len (ldpw->vcl_poll), 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05002295 if (rv < 0)
2296 {
2297 errno = -rv;
2298 rv = -1;
2299 goto done;
2300 }
2301 else
2302 n_revents += rv;
2303 }
2304
Florin Corasdfe4cf42018-11-28 22:13:45 -08002305 if (vec_len (ldpw->libc_poll))
Dave Wallace048b1d62018-01-03 22:24:41 -05002306 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08002307 rv = libc_poll (ldpw->libc_poll, vec_len (ldpw->libc_poll), 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05002308 if (rv < 0)
2309 goto done;
2310 else
2311 n_revents += rv;
2312 }
2313
2314 if (n_revents)
2315 {
2316 rv = n_revents;
2317 goto done;
2318 }
2319 }
2320 while ((wait_for_time == -1) ||
Florin Corasdfe4cf42018-11-28 22:13:45 -08002321 (clib_time_now (&ldpw->clib_time) < wait_for_time));
Dave Wallace048b1d62018-01-03 22:24:41 -05002322 rv = 0;
2323
2324done:
Florin Corasdfe4cf42018-11-28 22:13:45 -08002325 vec_foreach (vp, ldpw->vcl_poll)
Dave Wallace048b1d62018-01-03 22:24:41 -05002326 {
2327 fds[vp->fds_ndx].fd = -fds[vp->fds_ndx].fd;
Florin Coras6917b942018-11-13 22:44:54 -08002328 fds[vp->fds_ndx].revents = vp->revents;
Dave Wallace048b1d62018-01-03 22:24:41 -05002329#ifdef __USE_XOPEN2K
2330 if ((fds[vp->fds_ndx].revents & POLLIN) &&
2331 (fds[vp->fds_ndx].events & POLLRDNORM))
2332 fds[vp->fds_ndx].revents |= POLLRDNORM;
2333 if ((fds[vp->fds_ndx].revents & POLLOUT) &&
2334 (fds[vp->fds_ndx].events & POLLWRNORM))
2335 fds[vp->fds_ndx].revents |= POLLWRNORM;
2336#endif
2337 }
Florin Corasdfe4cf42018-11-28 22:13:45 -08002338 vec_reset_length (ldpw->vcl_poll);
Dave Wallace048b1d62018-01-03 22:24:41 -05002339
Florin Corasdfe4cf42018-11-28 22:13:45 -08002340 for (i = 0; i < vec_len (ldpw->libc_poll); i++)
Florin Coras6917b942018-11-13 22:44:54 -08002341 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08002342 fds[ldpw->libc_poll_idxs[i]].revents = ldpw->libc_poll[i].revents;
Florin Coras6917b942018-11-13 22:44:54 -08002343 }
Florin Corasdfe4cf42018-11-28 22:13:45 -08002344 vec_reset_length (ldpw->libc_poll_idxs);
2345 vec_reset_length (ldpw->libc_poll);
Florin Coras6917b942018-11-13 22:44:54 -08002346
Dave Wallace048b1d62018-01-03 22:24:41 -05002347 return rv;
2348}
2349
2350#ifdef USE_GNU
2351int
2352ppoll (struct pollfd *fds, nfds_t nfds,
2353 const struct timespec *timeout, const sigset_t * sigmask)
2354{
Dave Wallace2a865272018-02-07 21:00:42 -05002355 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002356 return -1;
2357
2358 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
2359 errno = ENOSYS;
2360
2361
2362 return -1;
2363}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002364#endif
2365
Dave Wallace2a865272018-02-07 21:00:42 -05002366void CONSTRUCTOR_ATTRIBUTE ldp_constructor (void);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002367
Dave Wallace2a865272018-02-07 21:00:42 -05002368void DESTRUCTOR_ATTRIBUTE ldp_destructor (void);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002369
Dave Wallace048b1d62018-01-03 22:24:41 -05002370/*
2371 * This function is called when the library is loaded
2372 */
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002373void
Dave Wallace2a865272018-02-07 21:00:42 -05002374ldp_constructor (void)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002375{
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002376 swrap_constructor ();
Dave Wallace2a865272018-02-07 21:00:42 -05002377 if (ldp_init () != 0)
2378 fprintf (stderr, "\nLDP<%d>: ERROR: ldp_constructor: failed!\n",
Dave Wallace048b1d62018-01-03 22:24:41 -05002379 getpid ());
Dave Wallace69d01192018-02-22 16:22:09 -05002380 else if (LDP_DEBUG > 0)
Dave Wallace2a865272018-02-07 21:00:42 -05002381 clib_warning ("LDP<%d>: LDP constructor: done!\n", getpid ());
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002382}
2383
2384/*
2385 * This function is called when the library is unloaded
2386 */
2387void
Dave Wallace2a865272018-02-07 21:00:42 -05002388ldp_destructor (void)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002389{
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002390 swrap_destructor ();
Dave Wallace2a865272018-02-07 21:00:42 -05002391 if (ldp->init)
Florin Coras940f78f2018-11-30 12:11:20 -08002392 ldp->init = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05002393
2394 /* Don't use clib_warning() here because that calls writev()
Dave Wallace2a865272018-02-07 21:00:42 -05002395 * which will call ldp_init().
Dave Wallace048b1d62018-01-03 22:24:41 -05002396 */
Dave Wallace69d01192018-02-22 16:22:09 -05002397 if (LDP_DEBUG > 0)
2398 printf ("%s:%d: LDP<%d>: LDP destructor: done!\n",
2399 __func__, __LINE__, getpid ());
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002400}
2401
2402
2403/*
2404 * fd.io coding-style-patch-verification: ON
2405 *
2406 * Local Variables:
2407 * eval: (c-set-style "gnu")
2408 * End:
2409 */