blob: 504155696fb3980b2a30865a36450f2fe4a473e6 [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
Dave Wallace5c7cf1c2017-10-24 04:12:18 -040029#include <vcl/vppcom.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 Corasa7a1a222018-12-30 17:11:31 -080054#define LDP_F_SHUT_RD (1 << 0)
55#define LDP_F_SHUT_WR (1 << 1)
56
Florin Coras30e273b2018-11-27 00:04:59 -080057typedef struct ldp_fd_entry_
58{
Florin Corasdfe4cf42018-11-28 22:13:45 -080059 u32 session_index;
Florin Coras30e273b2018-11-27 00:04:59 -080060 u32 fd;
61 u32 fd_index;
Florin Corasa7a1a222018-12-30 17:11:31 -080062 u32 flags;
Florin Coras30e273b2018-11-27 00:04:59 -080063} ldp_fd_entry_t;
64
Florin Corasdfe4cf42018-11-28 22:13:45 -080065typedef struct ldp_worker_ctx_
Dave Wallace048b1d62018-01-03 22:24:41 -050066{
Dave Wallace048b1d62018-01-03 22:24:41 -050067 u8 *io_buffer;
68 clib_time_t clib_time;
Florin Corasdfe4cf42018-11-28 22:13:45 -080069
70 /*
71 * Select state
72 */
Dave Wallace048b1d62018-01-03 22:24:41 -050073 clib_bitmap_t *rd_bitmap;
74 clib_bitmap_t *wr_bitmap;
75 clib_bitmap_t *ex_bitmap;
76 clib_bitmap_t *sid_rd_bitmap;
77 clib_bitmap_t *sid_wr_bitmap;
78 clib_bitmap_t *sid_ex_bitmap;
79 clib_bitmap_t *libc_rd_bitmap;
80 clib_bitmap_t *libc_wr_bitmap;
81 clib_bitmap_t *libc_ex_bitmap;
Florin Corasdfe4cf42018-11-28 22:13:45 -080082 u8 select_vcl;
83
84 /*
85 * Poll state
86 */
Dave Wallace048b1d62018-01-03 22:24:41 -050087 vcl_poll_t *vcl_poll;
Florin Coras6917b942018-11-13 22:44:54 -080088 struct pollfd *libc_poll;
89 u16 *libc_poll_idxs;
Florin Corasdfe4cf42018-11-28 22:13:45 -080090
91 /*
92 * Epoll state
93 */
Dave Wallace048b1d62018-01-03 22:24:41 -050094 u8 epoll_wait_vcl;
Florin Coras99368312018-08-02 10:45:44 -070095 int vcl_mq_epfd;
Florin Corasdfe4cf42018-11-28 22:13:45 -080096
97} ldp_worker_ctx_t;
98
99typedef struct
100{
101 ldp_worker_ctx_t *workers;
102 int init;
103 char app_name[LDP_APP_NAME_MAX];
104 u32 sid_bit_val;
105 u32 sid_bit_mask;
106 u32 debug;
Florin Coras30e273b2018-11-27 00:04:59 -0800107 ldp_fd_entry_t *fd_pool;
108 clib_rwlock_t fd_table_lock;
Florin Corasdfe4cf42018-11-28 22:13:45 -0800109 uword *session_index_to_fd_table;
110
111 /** vcl needs next epoll_create to go to libc_epoll */
112 u8 vcl_needs_real_epoll;
Dave Wallace2a865272018-02-07 21:00:42 -0500113} ldp_main_t;
Florin Corasdfe4cf42018-11-28 22:13:45 -0800114
Dave Wallace2a865272018-02-07 21:00:42 -0500115#define LDP_DEBUG ldp->debug
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700116
Florin Coras99368312018-08-02 10:45:44 -0700117#define LDBG(_lvl, _fmt, _args...) \
118 if (ldp->debug > _lvl) \
Florin Coras05ecfcc2018-12-12 18:19:39 -0800119 clib_warning ("ldp<%d>: " _fmt, getpid(), ##_args)
Florin Coras99368312018-08-02 10:45:44 -0700120
Dave Wallace2a865272018-02-07 21:00:42 -0500121static ldp_main_t ldp_main = {
122 .sid_bit_val = (1 << LDP_SID_BIT_MIN),
123 .sid_bit_mask = (1 << LDP_SID_BIT_MIN) - 1,
124 .debug = LDP_DEBUG_INIT,
Dave Wallace048b1d62018-01-03 22:24:41 -0500125};
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700126
Dave Wallace2a865272018-02-07 21:00:42 -0500127static ldp_main_t *ldp = &ldp_main;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700128
Florin Corasdfe4cf42018-11-28 22:13:45 -0800129static inline ldp_worker_ctx_t *
130ldp_worker_get_current (void)
131{
132 return (ldp->workers + vppcom_worker_index ());
133}
134
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700135/*
136 * RETURN: 0 on success or -1 on error.
137 * */
Dave Wallace048b1d62018-01-03 22:24:41 -0500138static inline void
Dave Wallace2a865272018-02-07 21:00:42 -0500139ldp_set_app_name (char *app_name)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700140{
Dave Wallace2a865272018-02-07 21:00:42 -0500141 int rv = snprintf (ldp->app_name, LDP_APP_NAME_MAX,
142 "ldp-%d-%s", getpid (), app_name);
Dave Wallace048b1d62018-01-03 22:24:41 -0500143
Dave Wallace2a865272018-02-07 21:00:42 -0500144 if (rv >= LDP_APP_NAME_MAX)
145 app_name[LDP_APP_NAME_MAX - 1] = 0;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700146}
147
Dave Wallace048b1d62018-01-03 22:24:41 -0500148static inline char *
Dave Wallace2a865272018-02-07 21:00:42 -0500149ldp_get_app_name ()
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700150{
Dave Wallace2a865272018-02-07 21:00:42 -0500151 if (ldp->app_name[0] == '\0')
152 ldp_set_app_name ("app");
Dave Wallace048b1d62018-01-03 22:24:41 -0500153
Dave Wallace2a865272018-02-07 21:00:42 -0500154 return ldp->app_name;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700155}
156
Florin Coras30e273b2018-11-27 00:04:59 -0800157static int
158ldp_fd_alloc (u32 sid)
159{
160 ldp_fd_entry_t *fde;
161
162 clib_rwlock_writer_lock (&ldp->fd_table_lock);
163 if (pool_elts (ldp->fd_pool) >= (1ULL << 32) - ldp->sid_bit_val)
164 {
165 clib_rwlock_writer_unlock (&ldp->fd_table_lock);
166 return -1;
167 }
168 pool_get (ldp->fd_pool, fde);
Florin Corasdfe4cf42018-11-28 22:13:45 -0800169 fde->session_index = vppcom_session_index (sid);
Florin Coras30e273b2018-11-27 00:04:59 -0800170 fde->fd_index = fde - ldp->fd_pool;
171 fde->fd = fde->fd_index + ldp->sid_bit_val;
Florin Corasdfe4cf42018-11-28 22:13:45 -0800172 hash_set (ldp->session_index_to_fd_table, fde->session_index, fde->fd);
Florin Coras30e273b2018-11-27 00:04:59 -0800173 clib_rwlock_writer_unlock (&ldp->fd_table_lock);
174 return fde->fd;
175}
176
177static ldp_fd_entry_t *
178ldp_fd_entry_get_w_lock (u32 fd_index)
179{
180 clib_rwlock_reader_lock (&ldp->fd_table_lock);
181 if (pool_is_free_index (ldp->fd_pool, fd_index))
182 return 0;
183
184 return pool_elt_at_index (ldp->fd_pool, fd_index);
185}
186
Dave Wallace048b1d62018-01-03 22:24:41 -0500187static inline int
Dave Wallace2a865272018-02-07 21:00:42 -0500188ldp_fd_from_sid (u32 sid)
Dave Wallace048b1d62018-01-03 22:24:41 -0500189{
Florin Coras30e273b2018-11-27 00:04:59 -0800190 uword *fdp;
191 int fd;
192
193 clib_rwlock_reader_lock (&ldp->fd_table_lock);
Florin Corasdfe4cf42018-11-28 22:13:45 -0800194 fdp = hash_get (ldp->session_index_to_fd_table, vppcom_session_index (sid));
Florin Coras30e273b2018-11-27 00:04:59 -0800195 fd = fdp ? *fdp : -EMFILE;
196 clib_rwlock_reader_unlock (&ldp->fd_table_lock);
197
198 return fd;
Dave Wallace048b1d62018-01-03 22:24:41 -0500199}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700200
Dave Wallace048b1d62018-01-03 22:24:41 -0500201static inline int
Dave Wallace2a865272018-02-07 21:00:42 -0500202ldp_fd_is_sid (int fd)
Dave Wallace048b1d62018-01-03 22:24:41 -0500203{
Florin Coras30e273b2018-11-27 00:04:59 -0800204 return fd >= ldp->sid_bit_val;
Dave Wallace048b1d62018-01-03 22:24:41 -0500205}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700206
Dave Wallace048b1d62018-01-03 22:24:41 -0500207static inline u32
Dave Wallace2a865272018-02-07 21:00:42 -0500208ldp_sid_from_fd (int fd)
Dave Wallace048b1d62018-01-03 22:24:41 -0500209{
Florin Corasdfe4cf42018-11-28 22:13:45 -0800210 u32 fd_index, session_index;
Florin Coras30e273b2018-11-27 00:04:59 -0800211 ldp_fd_entry_t *fde;
Florin Coras30e273b2018-11-27 00:04:59 -0800212
213 if (!ldp_fd_is_sid (fd))
214 return INVALID_SESSION_ID;
215
216 fd_index = fd - ldp->sid_bit_val;
217 fde = ldp_fd_entry_get_w_lock (fd_index);
Florin Corasdfe4cf42018-11-28 22:13:45 -0800218 if (!fde)
219 {
220 LDBG (0, "unknown fd %d", fd);
221 clib_rwlock_reader_unlock (&ldp->fd_table_lock);
222 return INVALID_SESSION_ID;
223 }
224 session_index = fde->session_index;
Florin Coras30e273b2018-11-27 00:04:59 -0800225 clib_rwlock_reader_unlock (&ldp->fd_table_lock);
226
Florin Corasdfe4cf42018-11-28 22:13:45 -0800227 return vppcom_session_handle (session_index);
Florin Coras30e273b2018-11-27 00:04:59 -0800228}
229
230static void
231ldp_fd_free_w_sid (u32 sid)
232{
233 ldp_fd_entry_t *fde;
234 u32 fd_index;
235 int fd;
236
237 fd = ldp_fd_from_sid (sid);
238 if (!fd)
239 return;
240
241 fd_index = fd - ldp->sid_bit_val;
242 fde = ldp_fd_entry_get_w_lock (fd_index);
243 if (fde)
244 {
Florin Corasdfe4cf42018-11-28 22:13:45 -0800245 hash_unset (ldp->session_index_to_fd_table, fde->session_index);
Florin Coras30e273b2018-11-27 00:04:59 -0800246 pool_put (ldp->fd_pool, fde);
247 }
248 clib_rwlock_writer_unlock (&ldp->fd_table_lock);
Dave Wallace048b1d62018-01-03 22:24:41 -0500249}
250
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700251static inline int
Dave Wallace2a865272018-02-07 21:00:42 -0500252ldp_init (void)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700253{
Florin Corasdfe4cf42018-11-28 22:13:45 -0800254 ldp_worker_ctx_t *ldpw;
Florin Coras99368312018-08-02 10:45:44 -0700255 int rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700256
Florin Coras99368312018-08-02 10:45:44 -0700257 if (PREDICT_TRUE (ldp->init))
258 return 0;
259
260 ldp->init = 1;
261 ldp->vcl_needs_real_epoll = 1;
262 rv = vppcom_app_create (ldp_get_app_name ());
263 if (rv != VPPCOM_OK)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700264 {
Florin Coras955bfbb2018-12-04 13:43:45 -0800265 ldp->vcl_needs_real_epoll = 0;
266 if (rv == VPPCOM_EEXIST)
267 return 0;
Florin Coras05ecfcc2018-12-12 18:19:39 -0800268 LDBG (2, "\nERROR: ldp_init: vppcom_app_create()"
269 " failed! rv = %d (%s)\n", rv, vppcom_retval_str (rv));
Florin Coras99368312018-08-02 10:45:44 -0700270 ldp->init = 0;
271 return rv;
272 }
273 ldp->vcl_needs_real_epoll = 0;
Florin Corasdfe4cf42018-11-28 22:13:45 -0800274 pool_alloc (ldp->workers, LDP_MAX_NWORKERS);
275 ldpw = ldp_worker_get_current ();
Florin Coras99368312018-08-02 10:45:44 -0700276
277 char *env_var_str = getenv (LDP_ENV_DEBUG);
278 if (env_var_str)
279 {
280 u32 tmp;
281 if (sscanf (env_var_str, "%u", &tmp) != 1)
282 clib_warning ("LDP<%d>: WARNING: Invalid LDP debug level specified in"
283 " the env var " LDP_ENV_DEBUG " (%s)!", getpid (),
284 env_var_str);
285 else
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700286 {
Florin Coras99368312018-08-02 10:45:44 -0700287 ldp->debug = tmp;
Florin Coras05ecfcc2018-12-12 18:19:39 -0800288 LDBG (0, "configured LDP debug level (%u) from env var "
289 LDP_ENV_DEBUG "!", ldp->debug);
Florin Coras99368312018-08-02 10:45:44 -0700290 }
291 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500292
Florin Coras99368312018-08-02 10:45:44 -0700293 env_var_str = getenv (LDP_ENV_APP_NAME);
294 if (env_var_str)
295 {
296 ldp_set_app_name (env_var_str);
Florin Coras05ecfcc2018-12-12 18:19:39 -0800297 LDBG (0, "configured LDP app name (%s) from the env var "
298 LDP_ENV_APP_NAME "!", ldp->app_name);
Florin Coras99368312018-08-02 10:45:44 -0700299 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500300
Florin Coras99368312018-08-02 10:45:44 -0700301 env_var_str = getenv (LDP_ENV_SID_BIT);
302 if (env_var_str)
303 {
304 u32 sb;
305 if (sscanf (env_var_str, "%u", &sb) != 1)
306 {
307 clib_warning ("LDP<%d>: WARNING: Invalid LDP sid bit specified in"
308 " the env var " LDP_ENV_SID_BIT " (%s)! sid bit "
309 "value %d (0x%x)", getpid (), env_var_str,
310 ldp->sid_bit_val, ldp->sid_bit_val);
311 }
312 else if (sb < LDP_SID_BIT_MIN)
313 {
314 ldp->sid_bit_val = (1 << LDP_SID_BIT_MIN);
315 ldp->sid_bit_mask = ldp->sid_bit_val - 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500316
Florin Coras99368312018-08-02 10:45:44 -0700317 clib_warning ("LDP<%d>: WARNING: LDP sid bit (%u) specified in the"
318 " env var " LDP_ENV_SID_BIT " (%s) is too small. "
319 "Using LDP_SID_BIT_MIN (%d)! sid bit value %d (0x%x)",
320 getpid (), sb, env_var_str, LDP_SID_BIT_MIN,
321 ldp->sid_bit_val, ldp->sid_bit_val);
322 }
323 else if (sb > LDP_SID_BIT_MAX)
324 {
325 ldp->sid_bit_val = (1 << LDP_SID_BIT_MAX);
326 ldp->sid_bit_mask = ldp->sid_bit_val - 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500327
Florin Coras99368312018-08-02 10:45:44 -0700328 clib_warning ("LDP<%d>: WARNING: LDP sid bit (%u) specified in the"
329 " env var " LDP_ENV_SID_BIT " (%s) is too big. Using"
330 " LDP_SID_BIT_MAX (%d)! sid bit value %d (0x%x)",
331 getpid (), sb, env_var_str, LDP_SID_BIT_MAX,
332 ldp->sid_bit_val, ldp->sid_bit_val);
Dave Wallace048b1d62018-01-03 22:24:41 -0500333 }
334 else
335 {
Florin Coras99368312018-08-02 10:45:44 -0700336 ldp->sid_bit_val = (1 << sb);
337 ldp->sid_bit_mask = ldp->sid_bit_val - 1;
338
Florin Coras05ecfcc2018-12-12 18:19:39 -0800339 LDBG (0, "configured LDP sid bit (%u) from "
340 LDP_ENV_SID_BIT "! sid bit value %d (0x%x)", sb,
Florin Coras99368312018-08-02 10:45:44 -0700341 ldp->sid_bit_val, ldp->sid_bit_val);
Dave Wallace048b1d62018-01-03 22:24:41 -0500342 }
343 }
Florin Coras99368312018-08-02 10:45:44 -0700344
Florin Corasdfe4cf42018-11-28 22:13:45 -0800345 clib_time_init (&ldpw->clib_time);
Florin Coras30e273b2018-11-27 00:04:59 -0800346 clib_rwlock_init (&ldp->fd_table_lock);
Florin Coras05ecfcc2018-12-12 18:19:39 -0800347 LDBG (0, "LDP initialization: done!");
Florin Coras99368312018-08-02 10:45:44 -0700348
349 return 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500350}
351
352int
353close (int fd)
354{
Florin Coras47c40e22018-11-26 17:01:36 -0800355 int rv, refcnt;
Dave Wallace2a865272018-02-07 21:00:42 -0500356 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -0500357
Dave Wallace2a865272018-02-07 21:00:42 -0500358 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500359 return -1;
360
361 if (sid != INVALID_SESSION_ID)
362 {
363 int epfd;
364
Dave Wallace048b1d62018-01-03 22:24:41 -0500365 epfd = vppcom_session_attr (sid, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
366 if (epfd > 0)
367 {
Florin Coras05ecfcc2018-12-12 18:19:39 -0800368 LDBG (0, "fd %d (0x%x): calling libc_close: epfd %u (0x%x)",
369 fd, fd, epfd, epfd);
Dave Wallace048b1d62018-01-03 22:24:41 -0500370
371 rv = libc_close (epfd);
372 if (rv < 0)
373 {
374 u32 size = sizeof (epfd);
375 epfd = 0;
376
377 (void) vppcom_session_attr (sid, VPPCOM_ATTR_SET_LIBC_EPFD,
378 &epfd, &size);
379 }
380 }
381 else if (PREDICT_FALSE (epfd < 0))
382 {
383 errno = -epfd;
384 rv = -1;
385 goto done;
386 }
387
Florin Coras05ecfcc2018-12-12 18:19:39 -0800388 LDBG (0, "fd %d (0x%x): calling vppcom_session_close: sid %u (0x%x)",
389 fd, fd, sid, sid);
Dave Wallace048b1d62018-01-03 22:24:41 -0500390
Florin Coras47c40e22018-11-26 17:01:36 -0800391 refcnt = vppcom_session_attr (sid, VPPCOM_ATTR_GET_REFCNT, 0, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -0500392 rv = vppcom_session_close (sid);
393 if (rv != VPPCOM_OK)
394 {
395 errno = -rv;
396 rv = -1;
397 }
Florin Corasb0f662f2018-12-27 14:51:46 -0800398 if (refcnt <= 1)
Florin Coras47c40e22018-11-26 17:01:36 -0800399 ldp_fd_free_w_sid (sid);
Dave Wallace048b1d62018-01-03 22:24:41 -0500400 }
401 else
402 {
Florin Coras05ecfcc2018-12-12 18:19:39 -0800403 LDBG (0, "fd %d (0x%x): calling libc_close", fd, fd);
Dave Wallace048b1d62018-01-03 22:24:41 -0500404 rv = libc_close (fd);
405 }
406
407done:
Florin Coras05ecfcc2018-12-12 18:19:39 -0800408
409 LDBG (1, "fd %d (0x%x): returning %d (0x%x)", fd, fd, rv, rv);
Dave Wallace048b1d62018-01-03 22:24:41 -0500410 return rv;
411}
412
413ssize_t
414read (int fd, void *buf, size_t nbytes)
415{
416 ssize_t size;
Dave Wallace2a865272018-02-07 21:00:42 -0500417 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -0500418
Dave Wallace2a865272018-02-07 21:00:42 -0500419 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500420 return -1;
421
422 if (sid != INVALID_SESSION_ID)
423 {
Florin Coras05ecfcc2018-12-12 18:19:39 -0800424 LDBG (2, "fd %d (0x%x): calling vppcom_session_read(): sid %u (0x%x),"
425 " buf %p, nbytes %u", fd, fd, sid, sid, buf, nbytes);
Dave Wallace048b1d62018-01-03 22:24:41 -0500426
427 size = vppcom_session_read (sid, buf, nbytes);
428 if (size < 0)
429 {
430 errno = -size;
431 size = -1;
432 }
433 }
434 else
435 {
Florin Coras05ecfcc2018-12-12 18:19:39 -0800436 LDBG (2, "fd %d (0x%x): calling libc_read(): buf %p, nbytes %u",
437 fd, fd, buf, nbytes);
Dave Wallace048b1d62018-01-03 22:24:41 -0500438
439 size = libc_read (fd, buf, nbytes);
440 }
441
Florin Coras05ecfcc2018-12-12 18:19:39 -0800442 LDBG (2, "fd %d (0x%x): returning %d (0x%x)", fd, fd, size, size);
Dave Wallace048b1d62018-01-03 22:24:41 -0500443 return size;
444}
445
446ssize_t
447readv (int fd, const struct iovec * iov, int iovcnt)
448{
Dave Wallace048b1d62018-01-03 22:24:41 -0500449 ssize_t size = 0;
Dave Wallace2a865272018-02-07 21:00:42 -0500450 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace8aaba562018-01-18 17:21:19 -0500451 int rv = 0, i, total = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500452
Dave Wallace2a865272018-02-07 21:00:42 -0500453 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500454 return -1;
455
456 if (sid != INVALID_SESSION_ID)
457 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500458 do
459 {
460 for (i = 0; i < iovcnt; ++i)
461 {
Florin Coras05ecfcc2018-12-12 18:19:39 -0800462 LDBG (2, "fd %d (0x%x): calling vppcom_session_read() [%d]:"
463 " sid %u (0x%x), iov %p, iovcnt %d, total %d", fd, fd, i,
464 sid, sid, iov, iovcnt, total);
Dave Wallace048b1d62018-01-03 22:24:41 -0500465
466 rv = vppcom_session_read (sid, iov[i].iov_base, iov[i].iov_len);
467 if (rv < 0)
468 break;
469 else
470 {
471 total += rv;
472 if (rv < iov[i].iov_len)
473 {
Florin Coras05ecfcc2018-12-12 18:19:39 -0800474 LDBG (2, "fd %d (0x%x): rv (%d) < iov[%d].iov_len (%d)",
475 fd, fd, rv, i, iov[i].iov_len);
Dave Wallace048b1d62018-01-03 22:24:41 -0500476 break;
477 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700478 }
479 }
480 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500481 while ((rv >= 0) && (total == 0));
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700482
Dave Wallace048b1d62018-01-03 22:24:41 -0500483 if (rv < 0)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700484 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500485 errno = -rv;
486 size = -1;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700487 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500488 else
489 size = total;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700490 }
491 else
492 {
Florin Coras05ecfcc2018-12-12 18:19:39 -0800493 LDBG (2, "fd %d (0x%x): calling libc_readv(): iov %p, iovcnt %d", fd,
494 fd, iov, iovcnt);
Dave Wallace048b1d62018-01-03 22:24:41 -0500495
496 size = libc_readv (fd, iov, iovcnt);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700497 }
498
Florin Coras05ecfcc2018-12-12 18:19:39 -0800499
500 LDBG (2, "fd %d (0x%x): returning %d (0x%x)", fd, fd, size, size);
Dave Wallace048b1d62018-01-03 22:24:41 -0500501 return size;
502}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700503
Dave Wallace048b1d62018-01-03 22:24:41 -0500504ssize_t
505write (int fd, const void *buf, size_t nbytes)
506{
Dave Wallace048b1d62018-01-03 22:24:41 -0500507 ssize_t size = 0;
Dave Wallace2a865272018-02-07 21:00:42 -0500508 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -0500509
Dave Wallace2a865272018-02-07 21:00:42 -0500510 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500511 return -1;
512
513 if (sid != INVALID_SESSION_ID)
514 {
Florin Coras05ecfcc2018-12-12 18:19:39 -0800515 LDBG (2, "fd %d (0x%x): calling vppcom_session_write(): sid %u (0x%x), "
516 "buf %p, nbytes %u", fd, fd, sid, sid, buf, nbytes);
Dave Wallace048b1d62018-01-03 22:24:41 -0500517
Florin Corasb0f662f2018-12-27 14:51:46 -0800518 size = vppcom_session_write_msg (sid, (void *) buf, nbytes);
Dave Wallace048b1d62018-01-03 22:24:41 -0500519 if (size < 0)
520 {
521 errno = -size;
522 size = -1;
523 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700524 }
525 else
526 {
Florin Coras05ecfcc2018-12-12 18:19:39 -0800527 LDBG (2, "fd %d (0x%x): calling libc_write(): buf %p, nbytes %u",
528 fd, fd, buf, nbytes);
Dave Wallace048b1d62018-01-03 22:24:41 -0500529
530 size = libc_write (fd, buf, nbytes);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700531 }
532
Florin Coras05ecfcc2018-12-12 18:19:39 -0800533 LDBG (2, "fd %d (0x%x): returning %d (0x%x)", fd, fd, size, size);
Dave Wallace048b1d62018-01-03 22:24:41 -0500534 return size;
535}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700536
Dave Wallace048b1d62018-01-03 22:24:41 -0500537ssize_t
538writev (int fd, const struct iovec * iov, int iovcnt)
539{
Dave Wallace048b1d62018-01-03 22:24:41 -0500540 ssize_t size = 0, total = 0;
Dave Wallace2a865272018-02-07 21:00:42 -0500541 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace8aaba562018-01-18 17:21:19 -0500542 int i, rv = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500543
544 /*
545 * Use [f]printf() instead of clib_warning() to prevent recursion SIGSEGV.
546 */
547
Dave Wallace2a865272018-02-07 21:00:42 -0500548 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500549 return -1;
550
551 if (sid != INVALID_SESSION_ID)
552 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500553 do
554 {
555 for (i = 0; i < iovcnt; ++i)
556 {
Florin Corasb0f662f2018-12-27 14:51:46 -0800557 rv = vppcom_session_write_msg (sid, iov[i].iov_base,
558 iov[i].iov_len);
Dave Wallace048b1d62018-01-03 22:24:41 -0500559 if (rv < 0)
560 break;
561 else
562 {
563 total += rv;
564 if (rv < iov[i].iov_len)
Florin Corasb0f662f2018-12-27 14:51:46 -0800565 break;
Dave Wallace048b1d62018-01-03 22:24:41 -0500566 }
567 }
568 }
569 while ((rv >= 0) && (total == 0));
570
571 if (rv < 0)
572 {
573 errno = -rv;
574 size = -1;
575 }
576 else
577 size = total;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700578 }
579 else
580 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500581 size = libc_writev (fd, iov, iovcnt);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700582 }
583
Dave Wallace048b1d62018-01-03 22:24:41 -0500584 return size;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700585}
586
587int
Dave Wallace048b1d62018-01-03 22:24:41 -0500588fcntl (int fd, int cmd, ...)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700589{
Dave Wallace048b1d62018-01-03 22:24:41 -0500590 const char *func_str = __func__;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700591 int rv = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500592 va_list ap;
Dave Wallace2a865272018-02-07 21:00:42 -0500593 u32 sid = ldp_sid_from_fd (fd);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700594
Dave Wallace2a865272018-02-07 21:00:42 -0500595 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500596 return -1;
597
598 va_start (ap, cmd);
599 if (sid != INVALID_SESSION_ID)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700600 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500601 int flags = va_arg (ap, int);
602 u32 size;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700603
Dave Wallace048b1d62018-01-03 22:24:41 -0500604 size = sizeof (flags);
605 rv = -EOPNOTSUPP;
606 switch (cmd)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700607 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500608 case F_SETFL:
609 func_str = "vppcom_session_attr[SET_FLAGS]";
Florin Coras05ecfcc2018-12-12 18:19:39 -0800610 LDBG (2, "fd %d (0x%x): calling %s(): sid %u (0x%x) "
611 "flags %d (0x%x), size %d", fd, fd, func_str, sid,
Florin Coras173bae32018-11-16 18:56:28 -0800612 sid, flags, flags, size);
Dave Wallace048b1d62018-01-03 22:24:41 -0500613
Florin Coras173bae32018-11-16 18:56:28 -0800614 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_FLAGS, &flags,
615 &size);
Dave Wallace048b1d62018-01-03 22:24:41 -0500616 break;
617
618 case F_GETFL:
619 func_str = "vppcom_session_attr[GET_FLAGS]";
Florin Coras05ecfcc2018-12-12 18:19:39 -0800620 LDBG (2, "fd %d (0x%x): calling %s(): sid %u (0x%x), "
621 "flags %d (0x%x), size %d", fd, fd, func_str, sid,
Florin Coras173bae32018-11-16 18:56:28 -0800622 sid, flags, flags, size);
Dave Wallace048b1d62018-01-03 22:24:41 -0500623
Florin Coras173bae32018-11-16 18:56:28 -0800624 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_FLAGS, &flags,
625 &size);
Dave Wallace048b1d62018-01-03 22:24:41 -0500626 if (rv == VPPCOM_OK)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700627 {
Florin Coras05ecfcc2018-12-12 18:19:39 -0800628 LDBG (2, "fd %d (0x%x), cmd %d (F_GETFL): %s() "
629 "returned flags %d (0x%x)", fd, fd, cmd,
Florin Coras173bae32018-11-16 18:56:28 -0800630 func_str, flags, flags);
Dave Wallace048b1d62018-01-03 22:24:41 -0500631 rv = flags;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700632 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700633 break;
Florin Coras173bae32018-11-16 18:56:28 -0800634 case F_SETFD:
635 /* TODO handle this */
636 LDBG (0, "F_SETFD ignored flags %u", flags);
637 rv = 0;
638 break;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700639 default:
Dave Wallace048b1d62018-01-03 22:24:41 -0500640 rv = -EOPNOTSUPP;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700641 break;
642 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500643 if (rv < 0)
644 {
645 errno = -rv;
646 rv = -1;
647 }
648 }
649 else
650 {
651 func_str = "libc_vfcntl";
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700652
Florin Coras05ecfcc2018-12-12 18:19:39 -0800653 LDBG (2, "fd %d (0x%x): calling %s(): cmd %d", fd, fd, func_str, cmd);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700654
Dave Wallace048b1d62018-01-03 22:24:41 -0500655 rv = libc_vfcntl (fd, cmd, ap);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700656 }
657
Dave Wallace048b1d62018-01-03 22:24:41 -0500658 va_end (ap);
659
Dave Wallace2a865272018-02-07 21:00:42 -0500660 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500661 {
662 if (rv < 0)
663 {
664 int errno_val = errno;
665 perror (func_str);
666 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
667 "rv %d, errno = %d", getpid (), fd, fd,
668 func_str, rv, errno_val);
669 errno = errno_val;
670 }
671 else
672 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
673 getpid (), fd, fd, rv, rv);
674 }
675 return rv;
676}
677
678int
679ioctl (int fd, unsigned long int cmd, ...)
680{
681 const char *func_str;
682 int rv;
683 va_list ap;
Dave Wallace2a865272018-02-07 21:00:42 -0500684 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -0500685
Dave Wallace2a865272018-02-07 21:00:42 -0500686 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500687 return -1;
688
689 va_start (ap, cmd);
690 if (sid != INVALID_SESSION_ID)
691 {
692 func_str = "vppcom_session_attr[GET_NREAD]";
693
694 switch (cmd)
695 {
696 case FIONREAD:
Dave Wallace2a865272018-02-07 21:00:42 -0500697 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500698 clib_warning
699 ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x)",
700 getpid (), fd, fd, func_str, sid, sid);
701
702 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_NREAD, 0, 0);
703 break;
704
705 case FIONBIO:
706 {
707 u32 flags = va_arg (ap, int) ? O_NONBLOCK : 0;
708 u32 size = sizeof (flags);
709
710 /* TBD: When VPPCOM_ATTR_[GS]ET_FLAGS supports flags other than
711 * non-blocking, the flags should be read here and merged
712 * with O_NONBLOCK.
713 */
Dave Wallace2a865272018-02-07 21:00:42 -0500714 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500715 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
716 "sid %u (0x%x), flags %d (0x%x), size %d",
717 getpid (), fd, fd, func_str, sid, sid,
718 flags, flags, size);
719
720 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_FLAGS, &flags,
721 &size);
722 }
723 break;
724
725 default:
726 rv = -EOPNOTSUPP;
727 break;
728 }
729 if (rv < 0)
730 {
731 errno = -rv;
732 rv = -1;
733 }
734 }
735 else
736 {
737 func_str = "libc_vioctl";
738
Dave Wallace2a865272018-02-07 21:00:42 -0500739 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500740 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): cmd %d",
741 getpid (), fd, fd, func_str, cmd);
742
743 rv = libc_vioctl (fd, cmd, ap);
744 }
745
Dave Wallace2a865272018-02-07 21:00:42 -0500746 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500747 {
748 if (rv < 0)
749 {
750 int errno_val = errno;
751 perror (func_str);
752 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
753 "rv %d, errno = %d", getpid (), fd, fd,
754 func_str, rv, errno_val);
755 errno = errno_val;
756 }
757 else
758 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
759 getpid (), fd, fd, rv, rv);
760 }
761 va_end (ap);
762 return rv;
763}
764
765int
Dave Wallace2a865272018-02-07 21:00:42 -0500766ldp_pselect (int nfds, fd_set * __restrict readfds,
767 fd_set * __restrict writefds,
768 fd_set * __restrict exceptfds,
769 const struct timespec *__restrict timeout,
770 const __sigset_t * __restrict sigmask)
Dave Wallace048b1d62018-01-03 22:24:41 -0500771{
Florin Coras30e273b2018-11-27 00:04:59 -0800772 uword sid_bits, sid_bits_set, libc_bits, libc_bits_set;
Florin Corasdfe4cf42018-11-28 22:13:45 -0800773 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
Florin Coras30e273b2018-11-27 00:04:59 -0800774 u32 minbits = clib_max (nfds, BITS (uword)), sid;
Dave Wallace048b1d62018-01-03 22:24:41 -0500775 char *func_str = "##";
776 f64 time_out;
Florin Coras30e273b2018-11-27 00:04:59 -0800777 int rv, fd;
Dave Wallace048b1d62018-01-03 22:24:41 -0500778
779 if (nfds < 0)
780 {
781 errno = EINVAL;
782 return -1;
783 }
784
Dave Wallace3ee1fe12018-02-23 01:09:11 -0500785 if (timeout)
786 {
787 time_out = (timeout->tv_sec == 0 && timeout->tv_nsec == 0) ?
788 (f64) 0 : (f64) timeout->tv_sec +
789 (f64) timeout->tv_nsec / (f64) 1000000000;
790
791 /* select as fine grained sleep */
792 if (!nfds)
793 {
Florin Coras05ecfcc2018-12-12 18:19:39 -0800794 LDBG (3, "sleeping for %.02f seconds", time_out);
Dave Wallace3ee1fe12018-02-23 01:09:11 -0500795
Florin Corasdfe4cf42018-11-28 22:13:45 -0800796 time_out += clib_time_now (&ldpw->clib_time);
797 while (clib_time_now (&ldpw->clib_time) < time_out)
Dave Wallace3ee1fe12018-02-23 01:09:11 -0500798 ;
799 return 0;
800 }
801 }
802 else if (!nfds)
803 {
804 errno = EINVAL;
805 return -1;
806 }
807 else
808 time_out = -1;
809
810
Dave Wallace2a865272018-02-07 21:00:42 -0500811 if (nfds <= ldp->sid_bit_val)
Dave Wallace048b1d62018-01-03 22:24:41 -0500812 {
813 func_str = "libc_pselect";
814
Florin Coras05ecfcc2018-12-12 18:19:39 -0800815 LDBG (3, "calling %s(): nfds %d, readfds %p, writefds %p, "
816 "exceptfds %p, timeout %p, sigmask %p", func_str, nfds,
Florin Coras173bae32018-11-16 18:56:28 -0800817 readfds, writefds, exceptfds, timeout, sigmask);
Dave Wallace048b1d62018-01-03 22:24:41 -0500818
819 rv = libc_pselect (nfds, readfds, writefds, exceptfds,
820 timeout, sigmask);
821 goto done;
822 }
823
Dave Wallace2a865272018-02-07 21:00:42 -0500824 if (PREDICT_FALSE (ldp->sid_bit_val > FD_SETSIZE / 2))
Dave Wallace048b1d62018-01-03 22:24:41 -0500825 {
Dave Wallace2a865272018-02-07 21:00:42 -0500826 clib_warning ("LDP<%d>: ERROR: LDP sid bit value %d (0x%x) > "
Dave Wallace048b1d62018-01-03 22:24:41 -0500827 "FD_SETSIZE/2 %d (0x%x)!", getpid (),
Dave Wallace2a865272018-02-07 21:00:42 -0500828 ldp->sid_bit_val, ldp->sid_bit_val,
Dave Wallace048b1d62018-01-03 22:24:41 -0500829 FD_SETSIZE / 2, FD_SETSIZE / 2);
830 errno = EOVERFLOW;
831 return -1;
832 }
833
Dave Wallace048b1d62018-01-03 22:24:41 -0500834 sid_bits = libc_bits = 0;
Florin Coras173bae32018-11-16 18:56:28 -0800835 u32 n_bytes = nfds / 8 + ((nfds % 8) ? 1 : 0);
Dave Wallace048b1d62018-01-03 22:24:41 -0500836 if (readfds)
837 {
Florin Corasdfe4cf42018-11-28 22:13:45 -0800838 clib_bitmap_validate (ldpw->sid_rd_bitmap, minbits);
839 clib_bitmap_validate (ldpw->libc_rd_bitmap, minbits);
840 clib_bitmap_validate (ldpw->rd_bitmap, minbits);
841 clib_memcpy_fast (ldpw->rd_bitmap, readfds, n_bytes);
Florin Coras173bae32018-11-16 18:56:28 -0800842 memset (readfds, 0, n_bytes);
Dave Wallace048b1d62018-01-03 22:24:41 -0500843
844 /* *INDENT-OFF* */
Florin Corasdfe4cf42018-11-28 22:13:45 -0800845 clib_bitmap_foreach (fd, ldpw->rd_bitmap, ({
Florin Coras173bae32018-11-16 18:56:28 -0800846 if (fd > nfds)
847 break;
848 sid = ldp_sid_from_fd (fd);
Florin Coras05ecfcc2018-12-12 18:19:39 -0800849 LDBG (3, "readfds: fd %d (0x%x), sid %u (0x%x)", fd, fd, sid, sid);
Florin Coras173bae32018-11-16 18:56:28 -0800850 if (sid == INVALID_SESSION_ID)
Florin Corasdfe4cf42018-11-28 22:13:45 -0800851 clib_bitmap_set_no_check (ldpw->libc_rd_bitmap, fd, 1);
Florin Coras173bae32018-11-16 18:56:28 -0800852 else
Florin Corasdfe4cf42018-11-28 22:13:45 -0800853 clib_bitmap_set_no_check (ldpw->sid_rd_bitmap,
Florin Coras30e273b2018-11-27 00:04:59 -0800854 vppcom_session_index (sid), 1);
Florin Coras173bae32018-11-16 18:56:28 -0800855 }));
Dave Wallace048b1d62018-01-03 22:24:41 -0500856 /* *INDENT-ON* */
857
Florin Corasdfe4cf42018-11-28 22:13:45 -0800858 sid_bits_set = clib_bitmap_last_set (ldpw->sid_rd_bitmap) + 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500859 sid_bits = (sid_bits_set > sid_bits) ? sid_bits_set : sid_bits;
860
Florin Corasdfe4cf42018-11-28 22:13:45 -0800861 libc_bits_set = clib_bitmap_last_set (ldpw->libc_rd_bitmap) + 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500862 libc_bits = (libc_bits_set > libc_bits) ? libc_bits_set : libc_bits;
863
Florin Coras05ecfcc2018-12-12 18:19:39 -0800864 LDBG (3, "readfds: sid_bits_set %d, sid_bits %d, "
865 "libc_bits_set %d, libc_bits %d", sid_bits_set,
Florin Coras173bae32018-11-16 18:56:28 -0800866 sid_bits, libc_bits_set, libc_bits);
Dave Wallace048b1d62018-01-03 22:24:41 -0500867 }
868 if (writefds)
869 {
Florin Corasdfe4cf42018-11-28 22:13:45 -0800870 clib_bitmap_validate (ldpw->sid_wr_bitmap, minbits);
871 clib_bitmap_validate (ldpw->libc_wr_bitmap, minbits);
872 clib_bitmap_validate (ldpw->wr_bitmap, minbits);
873 clib_memcpy_fast (ldpw->wr_bitmap, writefds, n_bytes);
Florin Coras173bae32018-11-16 18:56:28 -0800874 memset (writefds, 0, n_bytes);
Dave Wallace048b1d62018-01-03 22:24:41 -0500875
876 /* *INDENT-OFF* */
Florin Corasdfe4cf42018-11-28 22:13:45 -0800877 clib_bitmap_foreach (fd, ldpw->wr_bitmap, ({
Florin Coras173bae32018-11-16 18:56:28 -0800878 if (fd > nfds)
879 break;
880 sid = ldp_sid_from_fd (fd);
Florin Coras05ecfcc2018-12-12 18:19:39 -0800881 LDBG (3, "writefds: fd %d (0x%x), sid %u (0x%x)", fd, fd, sid, sid);
Florin Coras173bae32018-11-16 18:56:28 -0800882 if (sid == INVALID_SESSION_ID)
Florin Corasdfe4cf42018-11-28 22:13:45 -0800883 clib_bitmap_set_no_check (ldpw->libc_wr_bitmap, fd, 1);
Florin Coras173bae32018-11-16 18:56:28 -0800884 else
Florin Corasdfe4cf42018-11-28 22:13:45 -0800885 clib_bitmap_set_no_check (ldpw->sid_wr_bitmap,
Florin Coras30e273b2018-11-27 00:04:59 -0800886 vppcom_session_index (sid), 1);
Florin Coras173bae32018-11-16 18:56:28 -0800887 }));
Dave Wallace048b1d62018-01-03 22:24:41 -0500888 /* *INDENT-ON* */
889
Florin Corasdfe4cf42018-11-28 22:13:45 -0800890 sid_bits_set = clib_bitmap_last_set (ldpw->sid_wr_bitmap) + 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500891 sid_bits = (sid_bits_set > sid_bits) ? sid_bits_set : sid_bits;
892
Florin Corasdfe4cf42018-11-28 22:13:45 -0800893 libc_bits_set = clib_bitmap_last_set (ldpw->libc_wr_bitmap) + 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500894 libc_bits = (libc_bits_set > libc_bits) ? libc_bits_set : libc_bits;
895
Florin Coras05ecfcc2018-12-12 18:19:39 -0800896 LDBG (3, "writefds: sid_bits_set %d, sid_bits %d, "
897 "libc_bits_set %d, libc_bits %d",
Florin Coras173bae32018-11-16 18:56:28 -0800898 sid_bits_set, sid_bits, libc_bits_set, libc_bits);
Dave Wallace048b1d62018-01-03 22:24:41 -0500899 }
900 if (exceptfds)
901 {
Florin Corasdfe4cf42018-11-28 22:13:45 -0800902 clib_bitmap_validate (ldpw->sid_ex_bitmap, minbits);
903 clib_bitmap_validate (ldpw->libc_ex_bitmap, minbits);
904 clib_bitmap_validate (ldpw->ex_bitmap, minbits);
905 clib_memcpy_fast (ldpw->ex_bitmap, exceptfds, n_bytes);
Florin Coras173bae32018-11-16 18:56:28 -0800906 memset (exceptfds, 0, n_bytes);
Dave Wallace048b1d62018-01-03 22:24:41 -0500907
908 /* *INDENT-OFF* */
Florin Corasdfe4cf42018-11-28 22:13:45 -0800909 clib_bitmap_foreach (fd, ldpw->ex_bitmap, ({
Florin Coras173bae32018-11-16 18:56:28 -0800910 if (fd > nfds)
911 break;
912 sid = ldp_sid_from_fd (fd);
Florin Coras05ecfcc2018-12-12 18:19:39 -0800913 LDBG (3, "exceptfds: fd %d (0x%x), sid %u (0x%x)", fd, fd, sid, sid);
Florin Coras173bae32018-11-16 18:56:28 -0800914 if (sid == INVALID_SESSION_ID)
Florin Corasdfe4cf42018-11-28 22:13:45 -0800915 clib_bitmap_set_no_check (ldpw->libc_ex_bitmap, fd, 1);
Florin Coras173bae32018-11-16 18:56:28 -0800916 else
Florin Corasdfe4cf42018-11-28 22:13:45 -0800917 clib_bitmap_set_no_check (ldpw->sid_ex_bitmap,
Florin Coras30e273b2018-11-27 00:04:59 -0800918 vppcom_session_index (sid), 1);
Florin Coras173bae32018-11-16 18:56:28 -0800919 }));
Dave Wallace048b1d62018-01-03 22:24:41 -0500920 /* *INDENT-ON* */
921
Florin Corasdfe4cf42018-11-28 22:13:45 -0800922 sid_bits_set = clib_bitmap_last_set (ldpw->sid_ex_bitmap) + 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500923 sid_bits = (sid_bits_set > sid_bits) ? sid_bits_set : sid_bits;
924
Florin Corasdfe4cf42018-11-28 22:13:45 -0800925 libc_bits_set = clib_bitmap_last_set (ldpw->libc_ex_bitmap) + 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500926 libc_bits = (libc_bits_set > libc_bits) ? libc_bits_set : libc_bits;
927
Florin Coras05ecfcc2018-12-12 18:19:39 -0800928 LDBG (3, "exceptfds: sid_bits_set %d, sid_bits %d, "
929 "libc_bits_set %d, libc_bits %d",
Florin Coras173bae32018-11-16 18:56:28 -0800930 sid_bits_set, sid_bits, libc_bits_set, libc_bits);
Dave Wallace048b1d62018-01-03 22:24:41 -0500931 }
932
933 if (PREDICT_FALSE (!sid_bits && !libc_bits))
934 {
935 errno = EINVAL;
936 rv = -1;
937 goto done;
938 }
939
940 do
941 {
942 if (sid_bits)
943 {
Florin Corasdfe4cf42018-11-28 22:13:45 -0800944 if (!ldpw->select_vcl)
Dave Wallace048b1d62018-01-03 22:24:41 -0500945 {
946 func_str = "vppcom_select";
947
948 if (readfds)
Florin Corasdfe4cf42018-11-28 22:13:45 -0800949 clib_memcpy_fast (ldpw->rd_bitmap, ldpw->sid_rd_bitmap,
950 vec_len (ldpw->rd_bitmap) *
Dave Barach178cf492018-11-13 16:34:13 -0500951 sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -0500952 if (writefds)
Florin Corasdfe4cf42018-11-28 22:13:45 -0800953 clib_memcpy_fast (ldpw->wr_bitmap, ldpw->sid_wr_bitmap,
954 vec_len (ldpw->wr_bitmap) *
Dave Barach178cf492018-11-13 16:34:13 -0500955 sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -0500956 if (exceptfds)
Florin Corasdfe4cf42018-11-28 22:13:45 -0800957 clib_memcpy_fast (ldpw->ex_bitmap, ldpw->sid_ex_bitmap,
958 vec_len (ldpw->ex_bitmap) *
Dave Barach178cf492018-11-13 16:34:13 -0500959 sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -0500960
961 rv = vppcom_select (sid_bits,
Florin Corasdfe4cf42018-11-28 22:13:45 -0800962 readfds ? ldpw->rd_bitmap : NULL,
963 writefds ? ldpw->wr_bitmap : NULL,
964 exceptfds ? ldpw->ex_bitmap : NULL, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -0500965 if (rv < 0)
966 {
967 errno = -rv;
968 rv = -1;
969 }
970 else if (rv > 0)
971 {
972 if (readfds)
973 {
974 /* *INDENT-OFF* */
Florin Corasdfe4cf42018-11-28 22:13:45 -0800975 clib_bitmap_foreach (sid, ldpw->rd_bitmap,
Dave Wallace048b1d62018-01-03 22:24:41 -0500976 ({
Florin Coras30e273b2018-11-27 00:04:59 -0800977 fd = ldp_fd_from_sid (vppcom_session_handle (sid));
Dave Wallace048b1d62018-01-03 22:24:41 -0500978 if (PREDICT_FALSE (fd < 0))
979 {
980 errno = EBADFD;
981 rv = -1;
982 goto done;
983 }
984 FD_SET (fd, readfds);
985 }));
986 /* *INDENT-ON* */
987 }
988 if (writefds)
989 {
990 /* *INDENT-OFF* */
Florin Corasdfe4cf42018-11-28 22:13:45 -0800991 clib_bitmap_foreach (sid, ldpw->wr_bitmap,
Dave Wallace048b1d62018-01-03 22:24:41 -0500992 ({
Florin Coras30e273b2018-11-27 00:04:59 -0800993 fd = ldp_fd_from_sid (vppcom_session_handle (sid));
Dave Wallace048b1d62018-01-03 22:24:41 -0500994 if (PREDICT_FALSE (fd < 0))
995 {
996 errno = EBADFD;
997 rv = -1;
998 goto done;
999 }
1000 FD_SET (fd, writefds);
1001 }));
1002 /* *INDENT-ON* */
1003 }
1004 if (exceptfds)
1005 {
1006 /* *INDENT-OFF* */
Florin Corasdfe4cf42018-11-28 22:13:45 -08001007 clib_bitmap_foreach (sid, ldpw->ex_bitmap,
Dave Wallace048b1d62018-01-03 22:24:41 -05001008 ({
Florin Coras30e273b2018-11-27 00:04:59 -08001009 fd = ldp_fd_from_sid (vppcom_session_handle (sid));
Dave Wallace048b1d62018-01-03 22:24:41 -05001010 if (PREDICT_FALSE (fd < 0))
1011 {
1012 errno = EBADFD;
1013 rv = -1;
1014 goto done;
1015 }
1016 FD_SET (fd, exceptfds);
1017 }));
1018 /* *INDENT-ON* */
1019 }
Florin Corasdfe4cf42018-11-28 22:13:45 -08001020 ldpw->select_vcl = 1;
Dave Wallace048b1d62018-01-03 22:24:41 -05001021 goto done;
1022 }
1023 }
1024 else
Florin Corasdfe4cf42018-11-28 22:13:45 -08001025 ldpw->select_vcl = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05001026 }
1027 if (libc_bits)
1028 {
1029 struct timespec tspec;
1030
1031 func_str = "libc_pselect";
1032
1033 if (readfds)
Florin Corasdfe4cf42018-11-28 22:13:45 -08001034 clib_memcpy_fast (readfds, ldpw->libc_rd_bitmap,
1035 vec_len (ldpw->rd_bitmap) *
Dave Barach178cf492018-11-13 16:34:13 -05001036 sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -05001037 if (writefds)
Florin Corasdfe4cf42018-11-28 22:13:45 -08001038 clib_memcpy_fast (writefds, ldpw->libc_wr_bitmap,
1039 vec_len (ldpw->wr_bitmap) *
Dave Barach178cf492018-11-13 16:34:13 -05001040 sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -05001041 if (exceptfds)
Florin Corasdfe4cf42018-11-28 22:13:45 -08001042 clib_memcpy_fast (exceptfds, ldpw->libc_ex_bitmap,
1043 vec_len (ldpw->ex_bitmap) *
Dave Barach178cf492018-11-13 16:34:13 -05001044 sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -05001045 tspec.tv_sec = tspec.tv_nsec = 0;
1046 rv = libc_pselect (libc_bits,
1047 readfds ? readfds : NULL,
1048 writefds ? writefds : NULL,
1049 exceptfds ? exceptfds : NULL, &tspec, sigmask);
1050 if (rv != 0)
1051 goto done;
1052 }
1053 }
Florin Corasdfe4cf42018-11-28 22:13:45 -08001054 while ((time_out == -1) || (clib_time_now (&ldpw->clib_time) < time_out));
Dave Wallace048b1d62018-01-03 22:24:41 -05001055 rv = 0;
1056
1057done:
1058 /* TBD: set timeout to amount of time left */
Florin Corasdfe4cf42018-11-28 22:13:45 -08001059 clib_bitmap_zero (ldpw->rd_bitmap);
1060 clib_bitmap_zero (ldpw->sid_rd_bitmap);
1061 clib_bitmap_zero (ldpw->libc_rd_bitmap);
1062 clib_bitmap_zero (ldpw->wr_bitmap);
1063 clib_bitmap_zero (ldpw->sid_wr_bitmap);
1064 clib_bitmap_zero (ldpw->libc_wr_bitmap);
1065 clib_bitmap_zero (ldpw->ex_bitmap);
1066 clib_bitmap_zero (ldpw->sid_ex_bitmap);
1067 clib_bitmap_zero (ldpw->libc_ex_bitmap);
Dave Wallace048b1d62018-01-03 22:24:41 -05001068
Dave Wallace2a865272018-02-07 21:00:42 -05001069 if (LDP_DEBUG > 3)
Dave Wallace048b1d62018-01-03 22:24:41 -05001070 {
1071 if (rv < 0)
1072 {
1073 int errno_val = errno;
1074 perror (func_str);
1075 clib_warning ("LDP<%d>: ERROR: %s() failed! "
1076 "rv %d, errno = %d", getpid (),
1077 func_str, rv, errno_val);
1078 errno = errno_val;
1079 }
1080 else
1081 clib_warning ("LDP<%d>: returning %d (0x%x)", getpid (), rv, rv);
1082 }
1083 return rv;
1084}
1085
1086int
1087select (int nfds, fd_set * __restrict readfds,
1088 fd_set * __restrict writefds,
1089 fd_set * __restrict exceptfds, struct timeval *__restrict timeout)
1090{
1091 struct timespec tspec;
1092
1093 if (timeout)
1094 {
1095 tspec.tv_sec = timeout->tv_sec;
1096 tspec.tv_nsec = timeout->tv_usec * 1000;
1097 }
Dave Wallace2a865272018-02-07 21:00:42 -05001098 return ldp_pselect (nfds, readfds, writefds, exceptfds,
1099 timeout ? &tspec : NULL, NULL);
Dave Wallace048b1d62018-01-03 22:24:41 -05001100}
1101
1102#ifdef __USE_XOPEN2K
1103int
1104pselect (int nfds, fd_set * __restrict readfds,
1105 fd_set * __restrict writefds,
1106 fd_set * __restrict exceptfds,
1107 const struct timespec *__restrict timeout,
1108 const __sigset_t * __restrict sigmask)
1109{
Dave Wallace2a865272018-02-07 21:00:42 -05001110 return ldp_pselect (nfds, readfds, writefds, exceptfds, timeout, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05001111}
1112#endif
1113
1114int
1115socket (int domain, int type, int protocol)
1116{
1117 const char *func_str;
1118 int rv;
1119 u8 is_nonblocking = type & SOCK_NONBLOCK ? 1 : 0;
1120 int sock_type = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK);
1121
Dave Wallace2a865272018-02-07 21:00:42 -05001122 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001123 return -1;
1124
1125 if (((domain == AF_INET) || (domain == AF_INET6)) &&
1126 ((sock_type == SOCK_STREAM) || (sock_type == SOCK_DGRAM)))
1127 {
1128 int sid;
Dave Wallace048b1d62018-01-03 22:24:41 -05001129 u8 proto = ((sock_type == SOCK_DGRAM) ?
1130 VPPCOM_PROTO_UDP : VPPCOM_PROTO_TCP);
1131
1132 func_str = "vppcom_session_create";
1133
Florin Coras05ecfcc2018-12-12 18:19:39 -08001134 LDBG (0, "calling %s(): proto %u (%s), is_nonblocking %u",
1135 func_str, proto, vppcom_proto_str (proto), is_nonblocking);
Dave Wallace048b1d62018-01-03 22:24:41 -05001136
Dave Wallacec04cbf12018-02-07 18:14:02 -05001137 sid = vppcom_session_create (proto, is_nonblocking);
Dave Wallace048b1d62018-01-03 22:24:41 -05001138 if (sid < 0)
1139 {
1140 errno = -sid;
1141 rv = -1;
1142 }
1143 else
1144 {
Dave Wallace2a865272018-02-07 21:00:42 -05001145 func_str = "ldp_fd_from_sid";
Florin Coras30e273b2018-11-27 00:04:59 -08001146 rv = ldp_fd_alloc (sid);
Dave Wallace048b1d62018-01-03 22:24:41 -05001147 if (rv < 0)
1148 {
1149 (void) vppcom_session_close (sid);
1150 errno = -rv;
1151 rv = -1;
1152 }
1153 }
1154 }
1155 else
1156 {
1157 func_str = "libc_socket";
1158
Florin Coras05ecfcc2018-12-12 18:19:39 -08001159 LDBG (0, "calling %s()", func_str);
Dave Wallace048b1d62018-01-03 22:24:41 -05001160
1161 rv = libc_socket (domain, type, protocol);
1162 }
1163
Dave Wallace2a865272018-02-07 21:00:42 -05001164 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001165 {
1166 if (rv < 0)
1167 {
1168 int errno_val = errno;
1169 perror (func_str);
1170 clib_warning ("LDP<%d>: ERROR: %s() failed! "
1171 "rv %d, errno = %d",
1172 getpid (), func_str, rv, errno_val);
1173 errno = errno_val;
1174 }
1175 else
Florin Coras05ecfcc2018-12-12 18:19:39 -08001176 clib_warning ("returning fd %d (0x%x)", getpid (), rv, rv);
Dave Wallace048b1d62018-01-03 22:24:41 -05001177 }
1178 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001179}
1180
1181/*
1182 * Create two new sockets, of type TYPE in domain DOMAIN and using
1183 * protocol PROTOCOL, which are connected to each other, and put file
1184 * descriptors for them in FDS[0] and FDS[1]. If PROTOCOL is zero,
1185 * one will be chosen automatically.
1186 * Returns 0 on success, -1 for errors.
1187 * */
1188int
Dave Wallace048b1d62018-01-03 22:24:41 -05001189socketpair (int domain, int type, int protocol, int fds[2])
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001190{
Dave Wallace048b1d62018-01-03 22:24:41 -05001191 const char *func_str;
1192 int rv;
1193 int sock_type = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK);
1194
Dave Wallace2a865272018-02-07 21:00:42 -05001195 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001196 return -1;
1197
1198 if (((domain == AF_INET) || (domain == AF_INET6)) &&
1199 ((sock_type == SOCK_STREAM) || (sock_type == SOCK_DGRAM)))
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001200 {
Dave Wallace8aaba562018-01-18 17:21:19 -05001201 func_str = __func__;
1202
Dave Wallace048b1d62018-01-03 22:24:41 -05001203 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
1204 errno = ENOSYS;
1205 rv = -1;
1206 }
1207 else
1208 {
1209 func_str = "libc_socket";
1210
Florin Coras05ecfcc2018-12-12 18:19:39 -08001211 LDBG (1, "calling %s()", func_str);
Dave Wallace048b1d62018-01-03 22:24:41 -05001212
Florin Coras173bae32018-11-16 18:56:28 -08001213 rv = libc_socketpair (domain, type, protocol, fds);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001214 }
1215
Dave Wallace2a865272018-02-07 21:00:42 -05001216 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05001217 {
1218 if (rv < 0)
1219 {
1220 int errno_val = errno;
1221 perror (func_str);
1222 clib_warning ("LDP<%d>: ERROR: %s() failed! "
1223 "rv %d, errno = %d",
1224 getpid (), func_str, rv, errno_val);
1225 errno = errno_val;
1226 }
1227 else
1228 clib_warning ("LDP<%d>: : returning fd %d (0x%x)", getpid (), rv, rv);
1229 }
1230 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001231}
1232
1233int
Dave Wallace048b1d62018-01-03 22:24:41 -05001234bind (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001235{
1236 int rv;
Dave Wallace2a865272018-02-07 21:00:42 -05001237 u32 sid = ldp_sid_from_fd (fd);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001238
Dave Wallace2a865272018-02-07 21:00:42 -05001239 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001240 return -1;
1241
1242 if (sid != INVALID_SESSION_ID)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001243 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001244 vppcom_endpt_t ep;
1245
Dave Wallace048b1d62018-01-03 22:24:41 -05001246 switch (addr->sa_family)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001247 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001248 case AF_INET:
1249 if (len != sizeof (struct sockaddr_in))
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001250 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001251 clib_warning
1252 ("LDP<%d>: ERROR: fd %d (0x%x): sid %u (0x%x): Invalid "
1253 "AF_INET addr len %u!", getpid (), fd, fd, sid, sid, len);
1254 errno = EINVAL;
1255 rv = -1;
1256 goto done;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001257 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001258 ep.is_ip4 = VPPCOM_IS_IP4;
1259 ep.ip = (u8 *) & ((const struct sockaddr_in *) addr)->sin_addr;
1260 ep.port = (u16) ((const struct sockaddr_in *) addr)->sin_port;
1261 break;
1262
1263 case AF_INET6:
1264 if (len != sizeof (struct sockaddr_in6))
1265 {
1266 clib_warning
1267 ("LDP<%d>: ERROR: fd %d (0x%x): sid %u (0x%x): Invalid "
1268 "AF_INET6 addr len %u!", getpid (), fd, fd, sid, sid, len);
1269 errno = EINVAL;
1270 rv = -1;
1271 goto done;
1272 }
1273 ep.is_ip4 = VPPCOM_IS_IP6;
1274 ep.ip = (u8 *) & ((const struct sockaddr_in6 *) addr)->sin6_addr;
1275 ep.port = (u16) ((const struct sockaddr_in6 *) addr)->sin6_port;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001276 break;
1277
1278 default:
Dave Wallace048b1d62018-01-03 22:24:41 -05001279 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): sid %u (0x%x): "
1280 "Unsupported address family %u!",
1281 getpid (), fd, fd, sid, sid, addr->sa_family);
1282 errno = EAFNOSUPPORT;
1283 rv = -1;
1284 goto done;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001285 }
Florin Coras05ecfcc2018-12-12 18:19:39 -08001286 LDBG (0, "fd %d (0x%x): calling vppcom_session_bind(): "
1287 "sid %u (0x%x), addr %p, len %u", fd, fd, sid, sid, addr, len);
Dave Wallace048b1d62018-01-03 22:24:41 -05001288
1289 rv = vppcom_session_bind (sid, &ep);
1290 if (rv != VPPCOM_OK)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001291 {
1292 errno = -rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001293 rv = -1;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001294 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001295 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001296 else
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001297 {
Florin Coras05ecfcc2018-12-12 18:19:39 -08001298 LDBG (0, "fd %d (0x%x): calling libc_bind(): addr %p, len %u",
1299 fd, fd, addr, len);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001300
Dave Wallace048b1d62018-01-03 22:24:41 -05001301 rv = libc_bind (fd, addr, len);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001302 }
1303
Dave Wallace048b1d62018-01-03 22:24:41 -05001304done:
Florin Coras05ecfcc2018-12-12 18:19:39 -08001305 LDBG (1, "fd %d (0x%x): returning %d", fd, fd, rv);
1306
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001307 return rv;
1308}
1309
1310static inline int
Dave Wallace2a865272018-02-07 21:00:42 -05001311ldp_copy_ep_to_sockaddr (__SOCKADDR_ARG addr, socklen_t * __restrict len,
1312 vppcom_endpt_t * ep)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001313{
Dave Wallace048b1d62018-01-03 22:24:41 -05001314 int rv = 0;
1315 int sa_len, copy_len;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001316
Dave Wallace2a865272018-02-07 21:00:42 -05001317 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001318 return -1;
1319
1320 if (addr && len && ep)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001321 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001322 addr->sa_family = (ep->is_ip4 == VPPCOM_IS_IP4) ? AF_INET : AF_INET6;
1323 switch (addr->sa_family)
1324 {
1325 case AF_INET:
1326 ((struct sockaddr_in *) addr)->sin_port = ep->port;
1327 if (*len > sizeof (struct sockaddr_in))
1328 *len = sizeof (struct sockaddr_in);
1329 sa_len = sizeof (struct sockaddr_in) - sizeof (struct in_addr);
1330 copy_len = *len - sa_len;
1331 if (copy_len > 0)
1332 memcpy (&((struct sockaddr_in *) addr)->sin_addr, ep->ip,
1333 copy_len);
1334 break;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001335
Dave Wallace048b1d62018-01-03 22:24:41 -05001336 case AF_INET6:
1337 ((struct sockaddr_in6 *) addr)->sin6_port = ep->port;
1338 if (*len > sizeof (struct sockaddr_in6))
1339 *len = sizeof (struct sockaddr_in6);
1340 sa_len = sizeof (struct sockaddr_in6) - sizeof (struct in6_addr);
1341 copy_len = *len - sa_len;
1342 if (copy_len > 0)
1343 memcpy (((struct sockaddr_in6 *) addr)->sin6_addr.
1344 __in6_u.__u6_addr8, ep->ip, copy_len);
1345 break;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001346
Dave Wallace048b1d62018-01-03 22:24:41 -05001347 default:
1348 /* Not possible */
1349 rv = -EAFNOSUPPORT;
1350 break;
1351 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001352 }
Dave Wallacee695cb42017-11-02 22:04:42 -04001353 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001354}
1355
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001356int
Dave Wallace048b1d62018-01-03 22:24:41 -05001357getsockname (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict len)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001358{
1359 int rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001360 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05001361 u32 sid = ldp_sid_from_fd (fd);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001362
Dave Wallace2a865272018-02-07 21:00:42 -05001363 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001364 return -1;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001365
Dave Wallace048b1d62018-01-03 22:24:41 -05001366 if (sid != INVALID_SESSION_ID)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001367 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001368 vppcom_endpt_t ep;
1369 u8 addr_buf[sizeof (struct in6_addr)];
1370 u32 size = sizeof (ep);
1371
1372 ep.ip = addr_buf;
1373 func_str = "vppcom_session_attr[GET_LCL_ADDR]";
1374
Dave Wallace2a865272018-02-07 21:00:42 -05001375 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001376 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
1377 "addr %p, len %u",
1378 getpid (), fd, fd, func_str, sid, sid, addr, len);
1379
1380 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_LCL_ADDR, &ep, &size);
1381 if (rv != VPPCOM_OK)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001382 {
1383 errno = -rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001384 rv = -1;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001385 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001386 else
1387 {
Dave Wallace2a865272018-02-07 21:00:42 -05001388 rv = ldp_copy_ep_to_sockaddr (addr, len, &ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05001389 if (rv != VPPCOM_OK)
1390 {
1391 errno = -rv;
1392 rv = -1;
1393 }
1394 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001395 }
1396 else
1397 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001398 func_str = "libc_getsockname";
1399
Dave Wallace2a865272018-02-07 21:00:42 -05001400 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001401 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1402 "addr %p, len %u",
1403 getpid (), fd, fd, func_str, addr, len);
1404
1405 rv = libc_getsockname (fd, addr, len);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001406 }
1407
Dave Wallace2a865272018-02-07 21:00:42 -05001408 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001409 {
1410 if (rv < 0)
1411 {
1412 int errno_val = errno;
1413 perror (func_str);
1414 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1415 "rv %d, errno = %d", getpid (), fd, fd,
1416 func_str, rv, errno_val);
1417 errno = errno_val;
1418 }
1419 else
1420 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1421 getpid (), fd, fd, rv, rv);
1422 }
1423 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001424}
1425
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001426int
Dave Wallace048b1d62018-01-03 22:24:41 -05001427connect (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001428{
Dave Wallace048b1d62018-01-03 22:24:41 -05001429 int rv;
Dave Wallace2a865272018-02-07 21:00:42 -05001430 u32 sid = ldp_sid_from_fd (fd);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001431
Dave Wallace2a865272018-02-07 21:00:42 -05001432 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001433 return -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001434
Dave Wallace048b1d62018-01-03 22:24:41 -05001435 if (!addr)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001436 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001437 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): NULL addr, len %u",
1438 getpid (), fd, fd, len);
1439 errno = EINVAL;
1440 rv = -1;
1441 goto done;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001442 }
1443
Dave Wallace048b1d62018-01-03 22:24:41 -05001444 if (sid != INVALID_SESSION_ID)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001445 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001446 vppcom_endpt_t ep;
1447
Dave Wallace048b1d62018-01-03 22:24:41 -05001448 switch (addr->sa_family)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001449 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001450 case AF_INET:
1451 if (len != sizeof (struct sockaddr_in))
1452 {
1453 clib_warning
1454 ("LDP<%d>: fd %d (0x%x): ERROR sid %u (0x%x): Invalid "
1455 "AF_INET addr len %u!", getpid (), fd, fd, sid, sid, len);
1456 errno = EINVAL;
1457 rv = -1;
1458 goto done;
1459 }
1460 ep.is_ip4 = VPPCOM_IS_IP4;
1461 ep.ip = (u8 *) & ((const struct sockaddr_in *) addr)->sin_addr;
1462 ep.port = (u16) ((const struct sockaddr_in *) addr)->sin_port;
1463 break;
1464
1465 case AF_INET6:
1466 if (len != sizeof (struct sockaddr_in6))
1467 {
1468 clib_warning
1469 ("LDP<%d>: fd %d (0x%x): ERROR sid %u (0x%x): Invalid "
1470 "AF_INET6 addr len %u!", getpid (), fd, fd, sid, sid, len);
1471 errno = EINVAL;
1472 rv = -1;
1473 goto done;
1474 }
1475 ep.is_ip4 = VPPCOM_IS_IP6;
1476 ep.ip = (u8 *) & ((const struct sockaddr_in6 *) addr)->sin6_addr;
1477 ep.port = (u16) ((const struct sockaddr_in6 *) addr)->sin6_port;
1478 break;
1479
1480 default:
1481 clib_warning ("LDP<%d>: fd %d (0x%x): ERROR sid %u (0x%x): "
1482 "Unsupported address family %u!",
1483 getpid (), fd, fd, sid, sid, addr->sa_family);
1484 errno = EAFNOSUPPORT;
1485 rv = -1;
1486 goto done;
1487 }
Florin Coras05ecfcc2018-12-12 18:19:39 -08001488 LDBG (0, "fd %d (0x%x): calling vppcom_session_connect(): sid %u (0x%x)"
1489 " addr %p len %u", fd, fd, sid, sid, addr, len);
Dave Wallace048b1d62018-01-03 22:24:41 -05001490
1491 rv = vppcom_session_connect (sid, &ep);
1492 if (rv != VPPCOM_OK)
1493 {
1494 errno = -rv;
1495 rv = -1;
1496 }
1497 }
1498 else
1499 {
Florin Coras05ecfcc2018-12-12 18:19:39 -08001500 LDBG (0, "fd %d (0x%x): calling libc_connect(): addr %p, len %u",
1501 fd, fd, addr, len);
Dave Wallace048b1d62018-01-03 22:24:41 -05001502
1503 rv = libc_connect (fd, addr, len);
1504 }
1505
1506done:
Florin Coras05ecfcc2018-12-12 18:19:39 -08001507 LDBG (1, "fd %d (0x%x): returning %d (0x%x)", fd, fd, rv, rv);
Dave Wallace048b1d62018-01-03 22:24:41 -05001508 return rv;
1509}
1510
1511int
1512getpeername (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict len)
1513{
1514 int rv;
1515 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05001516 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05001517
Dave Wallace2a865272018-02-07 21:00:42 -05001518 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001519 return -1;
1520
Dave Wallace048b1d62018-01-03 22:24:41 -05001521 if (sid != INVALID_SESSION_ID)
1522 {
1523 vppcom_endpt_t ep;
1524 u8 addr_buf[sizeof (struct in6_addr)];
1525 u32 size = sizeof (ep);
1526
1527 ep.ip = addr_buf;
1528 func_str = "vppcom_session_attr[GET_PEER_ADDR]";
1529
Dave Wallace2a865272018-02-07 21:00:42 -05001530 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001531 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
1532 "addr %p, len %u",
1533 getpid (), fd, fd, func_str, sid, sid, addr, len);
1534
1535 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_PEER_ADDR, &ep, &size);
1536 if (rv != VPPCOM_OK)
1537 {
1538 errno = -rv;
1539 rv = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001540 }
1541 else
1542 {
Dave Wallace2a865272018-02-07 21:00:42 -05001543 rv = ldp_copy_ep_to_sockaddr (addr, len, &ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05001544 if (rv != VPPCOM_OK)
1545 {
1546 errno = -rv;
1547 rv = -1;
1548 }
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001549 }
1550 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001551 else
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001552 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001553 func_str = "libc_getpeername";
1554
Dave Wallace2a865272018-02-07 21:00:42 -05001555 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001556 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1557 "addr %p, len %u",
1558 getpid (), fd, fd, func_str, addr, len);
1559
1560 rv = libc_getpeername (fd, addr, len);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001561 }
1562
Dave Wallace2a865272018-02-07 21:00:42 -05001563 if (LDP_DEBUG > 2)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001564 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001565 if (rv < 0)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001566 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001567 int errno_val = errno;
1568 perror (func_str);
1569 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1570 "rv %d, errno = %d", getpid (), fd, fd,
1571 func_str, rv, errno_val);
1572 errno = errno_val;
1573 }
1574 else
1575 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1576 getpid (), fd, fd, rv, rv);
1577 }
1578 return rv;
1579}
1580
1581ssize_t
1582send (int fd, const void *buf, size_t n, int flags)
1583{
1584 ssize_t size;
1585 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05001586 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05001587
Dave Wallace2a865272018-02-07 21:00:42 -05001588 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001589 return -1;
1590
1591 if (sid != INVALID_SESSION_ID)
1592 {
1593
1594 func_str = "vppcom_session_sendto";
1595
Dave Wallace2a865272018-02-07 21:00:42 -05001596 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001597 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
1598 "buf %p, n %u, flags 0x%x",
1599 getpid (), fd, fd, func_str, sid, sid, buf, n, flags);
1600
1601 size = vppcom_session_sendto (sid, (void *) buf, n, flags, NULL);
qchangaa8f63c2018-05-30 11:44:18 -07001602 if (size < VPPCOM_OK)
Dave Wallace048b1d62018-01-03 22:24:41 -05001603 {
1604 errno = -size;
1605 size = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001606 }
1607 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001608 else
1609 {
1610 func_str = "libc_send";
1611
Dave Wallace2a865272018-02-07 21:00:42 -05001612 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001613 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1614 "buf %p, n %u, flags 0x%x",
1615 getpid (), fd, fd, func_str, buf, n, flags);
1616
1617 size = libc_send (fd, buf, n, flags);
1618 }
1619
Dave Wallace2a865272018-02-07 21:00:42 -05001620 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001621 {
1622 if (size < 0)
1623 {
1624 int errno_val = errno;
1625 perror (func_str);
1626 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1627 "rv %d, errno = %d", getpid (), fd, fd,
1628 func_str, size, errno_val);
1629 errno = errno_val;
1630 }
1631 else
1632 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1633 getpid (), fd, fd, size, size);
1634 }
1635 return size;
1636}
1637
1638ssize_t
1639sendfile (int out_fd, int in_fd, off_t * offset, size_t len)
1640{
Florin Corasdfe4cf42018-11-28 22:13:45 -08001641 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
Dave Wallace048b1d62018-01-03 22:24:41 -05001642 ssize_t size = 0;
1643 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05001644 u32 sid = ldp_sid_from_fd (out_fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05001645
Dave Wallace2a865272018-02-07 21:00:42 -05001646 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001647 return -1;
1648
1649 if (sid != INVALID_SESSION_ID)
1650 {
1651 int rv;
1652 ssize_t results = 0;
1653 size_t n_bytes_left = len;
1654 size_t bytes_to_read;
1655 int nbytes;
1656 int errno_val;
1657 u8 eagain = 0;
1658 u32 flags, flags_len = sizeof (flags);
1659
1660 func_str = "vppcom_session_attr[GET_FLAGS]";
1661 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_FLAGS, &flags,
1662 &flags_len);
1663 if (PREDICT_FALSE (rv != VPPCOM_OK))
1664 {
1665 clib_warning ("LDP<%d>: ERROR: out fd %d (0x%x): %s(): "
1666 "sid %u (0x%x), returned %d (%s)!", getpid (),
1667 out_fd, out_fd, func_str, sid, sid, rv,
1668 vppcom_retval_str (rv));
1669
Florin Corasdfe4cf42018-11-28 22:13:45 -08001670 vec_reset_length (ldpw->io_buffer);
Dave Wallace048b1d62018-01-03 22:24:41 -05001671 errno = -rv;
1672 size = -1;
1673 goto done;
1674 }
1675
1676 if (offset)
1677 {
1678 off_t off = lseek (in_fd, *offset, SEEK_SET);
1679 if (PREDICT_FALSE (off == -1))
1680 {
1681 func_str = "lseek";
1682 errno_val = errno;
1683 clib_warning ("LDP<%d>: ERROR: out fd %d (0x%x): %s(): "
1684 "SEEK_SET failed: in_fd %d, offset %p, "
1685 "*offset %ld, rv %ld, errno %d", getpid (),
1686 out_fd, out_fd, in_fd, offset, *offset, off,
1687 errno_val);
1688 errno = errno_val;
1689 size = -1;
1690 goto done;
1691 }
1692
1693 ASSERT (off == *offset);
1694 }
1695
1696 do
1697 {
1698 func_str = "vppcom_session_attr[GET_NWRITE]";
1699 size = vppcom_session_attr (sid, VPPCOM_ATTR_GET_NWRITE, 0, 0);
1700 if (size < 0)
1701 {
1702 clib_warning
1703 ("LDP<%d>: ERROR: fd %d (0x%x): %s(): sid %u (0x%x), "
1704 "returned %d (%s)!", getpid (), out_fd, out_fd, func_str,
1705 sid, sid, size, vppcom_retval_str (size));
Florin Corasdfe4cf42018-11-28 22:13:45 -08001706 vec_reset_length (ldpw->io_buffer);
Dave Wallace048b1d62018-01-03 22:24:41 -05001707 errno = -size;
1708 size = -1;
1709 goto done;
1710 }
1711
1712 bytes_to_read = size;
Dave Wallace2a865272018-02-07 21:00:42 -05001713 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001714 clib_warning
1715 ("LDP<%d>: fd %d (0x%x): called %s(): sid %u (0x%x), "
1716 "results %ld, n_bytes_left %lu, bytes_to_read %lu", getpid (),
1717 out_fd, out_fd, func_str, sid, sid, results, n_bytes_left,
1718 bytes_to_read);
1719
1720 if (bytes_to_read == 0)
1721 {
1722 if (flags & O_NONBLOCK)
1723 {
1724 if (!results)
1725 {
Dave Wallace2a865272018-02-07 21:00:42 -05001726 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001727 clib_warning ("LDP<%d>: fd %d (0x%x): sid %u (0x%x): "
1728 "EAGAIN",
1729 getpid (), out_fd, out_fd, sid, sid);
1730 eagain = 1;
1731 }
1732 goto update_offset;
1733 }
1734 else
1735 continue;
1736 }
1737 bytes_to_read = clib_min (n_bytes_left, bytes_to_read);
Florin Corasdfe4cf42018-11-28 22:13:45 -08001738 vec_validate (ldpw->io_buffer, bytes_to_read);
1739 nbytes = libc_read (in_fd, ldpw->io_buffer, bytes_to_read);
Dave Wallace048b1d62018-01-03 22:24:41 -05001740 if (nbytes < 0)
1741 {
1742 func_str = "libc_read";
1743 errno_val = errno;
1744 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): in_fd (%d), "
1745 "io_buffer %p, bytes_to_read %lu, rv %d, "
1746 "errno %d", getpid (), out_fd, out_fd, func_str,
Florin Corasdfe4cf42018-11-28 22:13:45 -08001747 in_fd, ldpw->io_buffer, bytes_to_read, nbytes,
Dave Wallace048b1d62018-01-03 22:24:41 -05001748 errno_val);
1749 errno = errno_val;
1750
1751 if (results == 0)
1752 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08001753 vec_reset_length (ldpw->io_buffer);
Dave Wallace048b1d62018-01-03 22:24:41 -05001754 size = -1;
1755 goto done;
1756 }
1757 goto update_offset;
1758 }
1759 func_str = "vppcom_session_write";
Dave Wallace2a865272018-02-07 21:00:42 -05001760 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001761 clib_warning
1762 ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
1763 "buf %p, nbytes %u: results %d, n_bytes_left %d", getpid (),
Florin Corasdfe4cf42018-11-28 22:13:45 -08001764 out_fd, out_fd, func_str, sid, sid, ldpw->io_buffer, nbytes,
Dave Wallace048b1d62018-01-03 22:24:41 -05001765 results, n_bytes_left);
1766
Florin Corasdfe4cf42018-11-28 22:13:45 -08001767 size = vppcom_session_write (sid, ldpw->io_buffer, nbytes);
Dave Wallace048b1d62018-01-03 22:24:41 -05001768 if (size < 0)
1769 {
1770 if (size == VPPCOM_EAGAIN)
1771 {
1772 if (flags & O_NONBLOCK)
1773 {
1774 if (!results)
1775 {
Dave Wallace2a865272018-02-07 21:00:42 -05001776 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001777 clib_warning
1778 ("LDP<%d>: fd %d (0x%x): sid %u (0x%x): "
1779 "EAGAIN", getpid (), out_fd, out_fd, sid, sid);
1780 eagain = 1;
1781 }
1782 goto update_offset;
1783 }
1784 else
1785 continue;
1786 }
1787 else
1788 {
1789 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s():"
1790 "sid %u, io_buffer %p, nbytes %u "
1791 "returned %d (%s)",
1792 getpid (), out_fd, out_fd, func_str,
Florin Corasdfe4cf42018-11-28 22:13:45 -08001793 sid, ldpw->io_buffer, nbytes,
Dave Wallace048b1d62018-01-03 22:24:41 -05001794 size, vppcom_retval_str (size));
1795 }
1796 if (results == 0)
1797 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08001798 vec_reset_length (ldpw->io_buffer);
Dave Wallace048b1d62018-01-03 22:24:41 -05001799 errno = -size;
1800 size = -1;
1801 goto done;
1802 }
1803 goto update_offset;
1804 }
1805
1806 results += nbytes;
1807 ASSERT (n_bytes_left >= nbytes);
1808 n_bytes_left = n_bytes_left - nbytes;
1809 }
1810 while (n_bytes_left > 0);
1811
1812 update_offset:
Florin Corasdfe4cf42018-11-28 22:13:45 -08001813 vec_reset_length (ldpw->io_buffer);
Dave Wallace048b1d62018-01-03 22:24:41 -05001814 if (offset)
1815 {
1816 off_t off = lseek (in_fd, *offset, SEEK_SET);
1817 if (PREDICT_FALSE (off == -1))
1818 {
1819 func_str = "lseek";
1820 errno_val = errno;
1821 clib_warning ("LDP<%d>: ERROR: %s(): SEEK_SET failed: "
1822 "in_fd %d, offset %p, *offset %ld, "
1823 "rv %ld, errno %d", getpid (), in_fd,
1824 offset, *offset, off, errno_val);
1825 errno = errno_val;
1826 size = -1;
1827 goto done;
1828 }
1829
1830 ASSERT (off == *offset);
1831 *offset += results + 1;
1832 }
1833 if (eagain)
1834 {
1835 errno = EAGAIN;
1836 size = -1;
1837 }
1838 else
1839 size = results;
1840 }
1841 else
1842 {
1843 func_str = "libc_send";
1844
Dave Wallace2a865272018-02-07 21:00:42 -05001845 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001846 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1847 "in_fd %d, offset %p, len %u",
1848 getpid (), out_fd, out_fd, func_str,
1849 in_fd, offset, len);
1850
1851 size = libc_sendfile (out_fd, in_fd, offset, len);
1852 }
1853
1854done:
Dave Wallace2a865272018-02-07 21:00:42 -05001855 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001856 {
1857 if (size < 0)
1858 {
1859 int errno_val = errno;
1860 perror (func_str);
1861 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1862 "rv %d, errno = %d", getpid (), out_fd, out_fd,
1863 func_str, size, errno_val);
1864 errno = errno_val;
1865 }
1866 else
1867 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1868 getpid (), out_fd, out_fd, size, size);
1869 }
1870 return size;
1871}
1872
1873ssize_t
1874sendfile64 (int out_fd, int in_fd, off_t * offset, size_t len)
1875{
1876 return sendfile (out_fd, in_fd, offset, len);
1877}
1878
1879ssize_t
1880recv (int fd, void *buf, size_t n, int flags)
1881{
1882 ssize_t size;
Florin Corasa7a1a222018-12-30 17:11:31 -08001883 u32 sid;
Dave Wallace048b1d62018-01-03 22:24:41 -05001884
Dave Wallace2a865272018-02-07 21:00:42 -05001885 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001886 return -1;
1887
Florin Corasa7a1a222018-12-30 17:11:31 -08001888 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05001889 if (sid != INVALID_SESSION_ID)
1890 {
Florin Corasa7a1a222018-12-30 17:11:31 -08001891 LDBG (2, "fd %d (0x%x): calling vcl recvfrom: sid %u (0x%x), buf %p,"
1892 " n %u, flags 0x%x", fd, fd, sid, sid, buf, n, flags);
Dave Wallace048b1d62018-01-03 22:24:41 -05001893
1894 size = vppcom_session_recvfrom (sid, buf, n, flags, NULL);
1895 if (size < 0)
Florin Corasa7a1a222018-12-30 17:11:31 -08001896 errno = -size;
Dave Wallace048b1d62018-01-03 22:24:41 -05001897 }
1898 else
1899 {
Florin Corasa7a1a222018-12-30 17:11:31 -08001900 LDBG (2, "fd %d (0x%x): calling libc_recvfrom(): buf %p, n %u, "
1901 "flags 0x%x", fd, fd, buf, n, flags);
Dave Wallace048b1d62018-01-03 22:24:41 -05001902
1903 size = libc_recv (fd, buf, n, flags);
1904 }
1905
Dave Wallace048b1d62018-01-03 22:24:41 -05001906 return size;
1907}
1908
1909ssize_t
1910sendto (int fd, const void *buf, size_t n, int flags,
1911 __CONST_SOCKADDR_ARG addr, socklen_t addr_len)
1912{
1913 ssize_t size;
1914 const char *func_str = __func__;
Dave Wallace2a865272018-02-07 21:00:42 -05001915 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05001916
Dave Wallace2a865272018-02-07 21:00:42 -05001917 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001918 return -1;
1919
1920 if (sid != INVALID_SESSION_ID)
1921 {
1922 vppcom_endpt_t *ep = 0;
1923 vppcom_endpt_t _ep;
1924
1925 if (addr)
1926 {
1927 ep = &_ep;
Dave Wallace048b1d62018-01-03 22:24:41 -05001928 switch (addr->sa_family)
1929 {
1930 case AF_INET:
1931 ep->is_ip4 = VPPCOM_IS_IP4;
1932 ep->ip =
1933 (uint8_t *) & ((const struct sockaddr_in *) addr)->sin_addr;
1934 ep->port =
1935 (uint16_t) ((const struct sockaddr_in *) addr)->sin_port;
1936 break;
1937
1938 case AF_INET6:
1939 ep->is_ip4 = VPPCOM_IS_IP6;
1940 ep->ip =
1941 (uint8_t *) & ((const struct sockaddr_in6 *) addr)->sin6_addr;
1942 ep->port =
1943 (uint16_t) ((const struct sockaddr_in6 *) addr)->sin6_port;
1944 break;
1945
1946 default:
1947 errno = EAFNOSUPPORT;
1948 size = -1;
1949 goto done;
1950 }
1951 }
1952
1953 func_str = "vppcom_session_sendto";
1954
Dave Wallace2a865272018-02-07 21:00:42 -05001955 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001956 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1957 "sid %u (0x%x), buf %p, n %u, flags 0x%x, ep %p",
1958 getpid (), fd, fd, func_str, sid, sid, buf, n,
1959 flags, ep);
1960
1961 size = vppcom_session_sendto (sid, (void *) buf, n, flags, ep);
1962 if (size < 0)
1963 {
1964 errno = -size;
1965 size = -1;
1966 }
1967 }
1968 else
1969 {
1970 func_str = "libc_sendto";
1971
Dave Wallace2a865272018-02-07 21:00:42 -05001972 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001973 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1974 "buf %p, n %u, flags 0x%x, addr %p, addr_len %d",
1975 getpid (), fd, fd, func_str, buf, n, flags,
1976 addr, addr_len);
1977
1978 size = libc_sendto (fd, buf, n, flags, addr, addr_len);
1979 }
1980
1981done:
Dave Wallace2a865272018-02-07 21:00:42 -05001982 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001983 {
1984 if (size < 0)
1985 {
1986 int errno_val = errno;
1987 perror (func_str);
1988 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1989 "rv %d, errno = %d", getpid (), fd, fd,
1990 func_str, size, errno_val);
1991 errno = errno_val;
1992 }
1993 else
1994 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1995 getpid (), fd, fd, size, size);
1996 }
1997 return size;
1998}
1999
2000ssize_t
2001recvfrom (int fd, void *__restrict buf, size_t n, int flags,
2002 __SOCKADDR_ARG addr, socklen_t * __restrict addr_len)
2003{
2004 ssize_t size;
2005 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05002006 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002007
Dave Wallace2a865272018-02-07 21:00:42 -05002008 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002009 return -1;
2010
2011 if (sid != INVALID_SESSION_ID)
2012 {
2013 vppcom_endpt_t ep;
2014 u8 src_addr[sizeof (struct sockaddr_in6)];
2015
2016 func_str = "vppcom_session_recvfrom";
2017
Dave Wallace2a865272018-02-07 21:00:42 -05002018 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002019 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2020 "sid %u (0x%x), buf %p, n %u, flags 0x%x, ep %p",
2021 getpid (), fd, fd, func_str, sid, sid, buf, n,
2022 flags, &ep);
2023 if (addr)
2024 {
2025 ep.ip = src_addr;
2026 size = vppcom_session_recvfrom (sid, buf, n, flags, &ep);
2027
2028 if (size > 0)
Dave Wallace2a865272018-02-07 21:00:42 -05002029 size = ldp_copy_ep_to_sockaddr (addr, addr_len, &ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05002030 }
2031 else
2032 size = vppcom_session_recvfrom (sid, buf, n, flags, NULL);
2033
2034 if (size < 0)
2035 {
2036 errno = -size;
2037 size = -1;
2038 }
2039 }
2040 else
2041 {
2042 func_str = "libc_recvfrom";
2043
Dave Wallace2a865272018-02-07 21:00:42 -05002044 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002045 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2046 "buf %p, n %u, flags 0x%x, addr %p, addr_len %d",
2047 getpid (), fd, fd, func_str, buf, n, flags,
2048 addr, addr_len);
2049
2050 size = libc_recvfrom (fd, buf, n, flags, addr, addr_len);
2051 }
2052
Dave Wallace2a865272018-02-07 21:00:42 -05002053 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002054 {
2055 if (size < 0)
2056 {
2057 int errno_val = errno;
2058 perror (func_str);
2059 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2060 "rv %d, errno = %d", getpid (), fd, fd,
2061 func_str, size, errno_val);
2062 errno = errno_val;
2063 }
2064 else
2065 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2066 getpid (), fd, fd, size, size);
2067 }
2068 return size;
2069}
2070
2071ssize_t
2072sendmsg (int fd, const struct msghdr * message, int flags)
2073{
2074 ssize_t size;
2075 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05002076 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002077
Dave Wallace2a865272018-02-07 21:00:42 -05002078 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002079 return -1;
2080
2081 if (sid != INVALID_SESSION_ID)
2082 {
Dave Wallace8aaba562018-01-18 17:21:19 -05002083 func_str = __func__;
2084
Dave Wallace048b1d62018-01-03 22:24:41 -05002085 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
2086 errno = ENOSYS;
2087 size = -1;
2088 }
2089 else
2090 {
2091 func_str = "libc_sendmsg";
2092
Dave Wallace2a865272018-02-07 21:00:42 -05002093 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002094 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2095 "message %p, flags 0x%x",
2096 getpid (), fd, fd, func_str, message, flags);
2097
2098 size = libc_sendmsg (fd, message, flags);
2099 }
2100
Dave Wallace2a865272018-02-07 21:00:42 -05002101 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002102 {
2103 if (size < 0)
2104 {
2105 int errno_val = errno;
2106 perror (func_str);
2107 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2108 "rv %d, errno = %d", getpid (), fd, fd,
2109 func_str, size, errno_val);
2110 errno = errno_val;
2111 }
2112 else
2113 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2114 getpid (), fd, fd, size, size);
2115 }
2116 return size;
2117}
2118
2119#ifdef USE_GNU
2120int
2121sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags)
2122{
2123 ssize_t size;
2124 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05002125 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002126
Dave Wallace2a865272018-02-07 21:00:42 -05002127 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002128 return -1;
2129
2130 if (sid != INVALID_SESSION_ID)
2131 {
2132 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
2133 errno = ENOSYS;
2134 size = -1;
2135 }
2136 else
2137 {
2138 func_str = "libc_sendmmsg";
2139
Dave Wallace2a865272018-02-07 21:00:42 -05002140 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002141 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2142 "vmessages %p, vlen %u, flags 0x%x",
2143 getpid (), fd, fd, func_str, vmessages, vlen, flags);
2144
2145 size = libc_sendmmsg (fd, vmessages, vlen, flags);
2146 }
2147
Dave Wallace2a865272018-02-07 21:00:42 -05002148 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002149 {
2150 if (size < 0)
2151 {
2152 int errno_val = errno;
2153 perror (func_str);
2154 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2155 "rv %d, errno = %d", getpid (), fd, fd,
2156 func_str, size, errno_val);
2157 errno = errno_val;
2158 }
2159 else
2160 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2161 getpid (), fd, fd, size, size);
2162 }
2163 return size;
2164}
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002165#endif
2166
Dave Wallace048b1d62018-01-03 22:24:41 -05002167ssize_t
2168recvmsg (int fd, struct msghdr * message, int flags)
2169{
2170 ssize_t size;
2171 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05002172 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002173
Dave Wallace2a865272018-02-07 21:00:42 -05002174 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002175 return -1;
2176
2177 if (sid != INVALID_SESSION_ID)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002178 {
Dave Wallace8aaba562018-01-18 17:21:19 -05002179 func_str = __func__;
2180
Dave Wallace048b1d62018-01-03 22:24:41 -05002181 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
2182 errno = ENOSYS;
2183 size = -1;
2184 }
2185 else
2186 {
2187 func_str = "libc_recvmsg";
2188
Dave Wallace2a865272018-02-07 21:00:42 -05002189 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002190 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2191 "message %p, flags 0x%x",
2192 getpid (), fd, fd, func_str, message, flags);
2193
2194 size = libc_recvmsg (fd, message, flags);
2195 }
2196
Dave Wallace2a865272018-02-07 21:00:42 -05002197 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002198 {
2199 if (size < 0)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002200 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002201 int errno_val = errno;
2202 perror (func_str);
2203 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2204 "rv %d, errno = %d", getpid (), fd, fd,
2205 func_str, size, errno_val);
2206 errno = errno_val;
2207 }
2208 else
2209 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2210 getpid (), fd, fd, size, size);
2211 }
2212 return size;
2213}
2214
2215#ifdef USE_GNU
2216int
2217recvmmsg (int fd, struct mmsghdr *vmessages,
2218 unsigned int vlen, int flags, struct timespec *tmo)
2219{
2220 ssize_t size;
2221 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05002222 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002223
Dave Wallace2a865272018-02-07 21:00:42 -05002224 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002225 return -1;
2226
2227 if (sid != INVALID_SESSION_ID)
2228 {
2229 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
2230 errno = ENOSYS;
2231 size = -1;
2232 }
2233 else
2234 {
2235 func_str = "libc_recvmmsg";
2236
Dave Wallace2a865272018-02-07 21:00:42 -05002237 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002238 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2239 "vmessages %p, vlen %u, flags 0x%x, tmo %p",
2240 getpid (), fd, fd, func_str, vmessages, vlen,
2241 flags, tmo);
2242
2243 size = libc_recvmmsg (fd, vmessages, vlen, flags, tmo);
2244 }
2245
Dave Wallace2a865272018-02-07 21:00:42 -05002246 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002247 {
2248 if (size < 0)
2249 {
2250 int errno_val = errno;
2251 perror (func_str);
2252 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2253 "rv %d, errno = %d", getpid (), fd, fd,
2254 func_str, size, errno_val);
2255 errno = errno_val;
2256 }
2257 else
2258 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2259 getpid (), fd, fd, size, size);
2260 }
2261 return size;
2262}
2263#endif
2264
2265int
2266getsockopt (int fd, int level, int optname,
2267 void *__restrict optval, socklen_t * __restrict optlen)
2268{
2269 int rv;
2270 const char *func_str = __func__;
Dave Wallace2a865272018-02-07 21:00:42 -05002271 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace8aaba562018-01-18 17:21:19 -05002272 u32 buflen = optlen ? (u32) * optlen : 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05002273
Dave Wallace2a865272018-02-07 21:00:42 -05002274 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002275 return -1;
2276
2277 if (sid != INVALID_SESSION_ID)
2278 {
2279 rv = -EOPNOTSUPP;
2280
2281 switch (level)
2282 {
2283 case SOL_TCP:
2284 switch (optname)
2285 {
2286 case TCP_NODELAY:
2287 func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_NODELAY]";
Dave Wallace2a865272018-02-07 21:00:42 -05002288 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002289 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2290 "sid %u (0x%x)",
2291 getpid (), fd, fd, func_str, sid, sid);
2292 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TCP_NODELAY,
2293 optval, optlen);
2294 break;
2295 case TCP_MAXSEG:
2296 func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_USER_MSS]";
Dave Wallace2a865272018-02-07 21:00:42 -05002297 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002298 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2299 "sid %u (0x%x)",
2300 getpid (), fd, fd, func_str, sid, sid);
2301 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TCP_USER_MSS,
2302 optval, optlen);
2303 break;
2304 case TCP_KEEPIDLE:
2305 func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_KEEPIDLE]";
Dave Wallace2a865272018-02-07 21:00:42 -05002306 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002307 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2308 "sid %u (0x%x)",
2309 getpid (), fd, fd, func_str, sid, sid);
2310 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TCP_KEEPIDLE,
2311 optval, optlen);
2312 break;
2313 case TCP_KEEPINTVL:
2314 func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_KEEPINTVL]";
Dave Wallace2a865272018-02-07 21:00:42 -05002315 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002316 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2317 "sid %u (0x%x), SOL_TCP",
2318 getpid (), fd, fd, func_str, sid, sid);
2319 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TCP_KEEPINTVL,
2320 optval, optlen);
2321 break;
2322 case TCP_INFO:
2323 if (optval && optlen && (*optlen == sizeof (struct tcp_info)))
2324 {
Dave Wallace2a865272018-02-07 21:00:42 -05002325 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002326 clib_warning ("LDP<%d>: fd %d (0x%x): sid %u (0x%x), "
2327 "SOL_TCP, TCP_INFO, optval %p, "
2328 "optlen %d: #LDP-NOP#",
2329 getpid (), fd, fd, sid, sid,
2330 optval, *optlen);
2331 memset (optval, 0, *optlen);
2332 rv = VPPCOM_OK;
2333 }
2334 else
2335 rv = -EFAULT;
2336 break;
2337 default:
Dave Wallace2a865272018-02-07 21:00:42 -05002338 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002339 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2340 "sid %u (0x%x), SOL_TCP, "
2341 "optname %d unsupported!",
2342 getpid (), fd, fd, func_str, sid, sid, optname);
2343 break;
2344 }
2345 break;
2346 case SOL_IPV6:
2347 switch (optname)
2348 {
2349 case IPV6_V6ONLY:
2350 func_str = "vppcom_session_attr[SOL_IPV6,GET_V6ONLY]";
Dave Wallace2a865272018-02-07 21:00:42 -05002351 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002352 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2353 "sid %u (0x%x)",
2354 getpid (), fd, fd, func_str, sid, sid);
2355 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_V6ONLY,
2356 optval, optlen);
2357 break;
2358 default:
Dave Wallace2a865272018-02-07 21:00:42 -05002359 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002360 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2361 "sid %u (0x%x), SOL_IPV6, "
2362 "optname %d unsupported!",
2363 getpid (), fd, fd, func_str, sid, sid, optname);
2364 break;
2365 }
2366 break;
2367 case SOL_SOCKET:
2368 switch (optname)
2369 {
2370 case SO_ACCEPTCONN:
2371 func_str = "vppcom_session_attr[SOL_SOCKET,GET_ACCEPTCONN]";
Dave Wallace2a865272018-02-07 21:00:42 -05002372 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002373 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2374 "sid %u (0x%x)",
2375 getpid (), fd, fd, func_str, sid, sid);
2376 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_LISTEN,
2377 optval, optlen);
2378 break;
2379 case SO_KEEPALIVE:
2380 func_str = "vppcom_session_attr[SOL_SOCKET,GET_KEEPALIVE]";
Dave Wallace2a865272018-02-07 21:00:42 -05002381 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002382 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2383 "sid %u (0x%x)",
2384 getpid (), fd, fd, func_str, sid, sid);
2385 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_KEEPALIVE,
2386 optval, optlen);
2387 break;
2388 case SO_PROTOCOL:
2389 func_str = "vppcom_session_attr[SOL_SOCKET,GET_PROTOCOL]";
Dave Wallace2a865272018-02-07 21:00:42 -05002390 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002391 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2392 "sid %u (0x%x)",
2393 getpid (), fd, fd, func_str, sid, sid);
2394 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_PROTOCOL,
2395 optval, optlen);
2396 *(int *) optval = *(int *) optval ? SOCK_DGRAM : SOCK_STREAM;
2397 break;
2398 case SO_SNDBUF:
2399 func_str = "vppcom_session_attr[SOL_SOCKET,GET_TX_FIFO_LEN]";
Dave Wallace2a865272018-02-07 21:00:42 -05002400 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002401 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2402 "sid %u (0x%x), optlen %d",
2403 getpid (), fd, fd, func_str, sid, sid, buflen);
2404 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TX_FIFO_LEN,
2405 optval, optlen);
2406 break;
2407 case SO_RCVBUF:
2408 func_str = "vppcom_session_attr[SOL_SOCKET,GET_RX_FIFO_LEN]";
Dave Wallace2a865272018-02-07 21:00:42 -05002409 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002410 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2411 "sid %u (0x%x), optlen %d",
Dave Wallaceb4cd4ff2018-01-19 12:17:08 -05002412 getpid (), fd, fd, func_str, sid, sid, buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002413 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_RX_FIFO_LEN,
2414 optval, optlen);
2415 break;
2416 case SO_REUSEADDR:
2417 func_str = "vppcom_session_attr[SOL_SOCKET,GET_REUSEADDR]";
Dave Wallace2a865272018-02-07 21:00:42 -05002418 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002419 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2420 "sid %u (0x%x)",
2421 getpid (), fd, fd, func_str, sid, sid);
2422 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_REUSEADDR,
2423 optval, optlen);
2424 break;
2425 case SO_BROADCAST:
2426 func_str = "vppcom_session_attr[SOL_SOCKET,GET_BROADCAST]";
Dave Wallace2a865272018-02-07 21:00:42 -05002427 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002428 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2429 "sid %u (0x%x)",
2430 getpid (), fd, fd, func_str, sid, sid);
2431 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_BROADCAST,
2432 optval, optlen);
2433 break;
2434 case SO_ERROR:
2435 func_str = "vppcom_session_attr[SOL_SOCKET,GET_ERROR]";
Dave Wallace2a865272018-02-07 21:00:42 -05002436 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002437 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2438 "sid %u (0x%x)",
2439 getpid (), fd, fd, func_str, sid, sid);
2440 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_ERROR,
2441 optval, optlen);
2442 break;
2443 default:
Dave Wallace2a865272018-02-07 21:00:42 -05002444 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002445 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2446 "sid %u (0x%x), SOL_SOCKET, "
2447 "optname %d unsupported!",
2448 getpid (), fd, fd, func_str, sid, sid, optname);
2449 break;
2450 }
2451 break;
2452 default:
2453 break;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002454 }
2455
Dave Wallace048b1d62018-01-03 22:24:41 -05002456 if (rv != VPPCOM_OK)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002457 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002458 errno = -rv;
2459 rv = -1;
2460 }
2461 }
2462 else
2463 {
2464 func_str = "libc_getsockopt";
2465
Dave Wallace2a865272018-02-07 21:00:42 -05002466 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002467 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): level %d, "
2468 "optname %d, optval %p, optlen %d",
2469 getpid (), fd, fd, func_str, level, optname,
2470 optval, optlen);
2471
2472 rv = libc_getsockopt (fd, level, optname, optval, optlen);
2473 }
2474
Dave Wallace2a865272018-02-07 21:00:42 -05002475 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002476 {
2477 if (rv < 0)
2478 {
2479 int errno_val = errno;
2480 perror (func_str);
2481 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2482 "rv %d, errno = %d", getpid (), fd, fd,
2483 func_str, rv, errno_val);
2484 errno = errno_val;
2485 }
2486 else
2487 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2488 getpid (), fd, fd, rv, rv);
2489 }
2490 return rv;
2491}
2492
2493int
2494setsockopt (int fd, int level, int optname,
2495 const void *optval, socklen_t optlen)
2496{
2497 int rv;
2498 const char *func_str = __func__;
Dave Wallace2a865272018-02-07 21:00:42 -05002499 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002500
Dave Wallace2a865272018-02-07 21:00:42 -05002501 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002502 return -1;
2503
2504 if (sid != INVALID_SESSION_ID)
2505 {
2506 rv = -EOPNOTSUPP;
2507
2508 switch (level)
2509 {
2510 case SOL_TCP:
2511 switch (optname)
2512 {
2513 case TCP_NODELAY:
2514 func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_NODELAY]";
Dave Wallace2a865272018-02-07 21:00:42 -05002515 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002516 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2517 "sid %u (0x%x)",
2518 getpid (), fd, fd, func_str, sid, sid);
2519 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_TCP_NODELAY,
2520 (void *) optval, &optlen);
2521 break;
2522 case TCP_MAXSEG:
2523 func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_USER_MSS]";
Dave Wallace2a865272018-02-07 21:00:42 -05002524 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002525 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2526 "sid %u (0x%x)",
2527 getpid (), fd, fd, func_str, sid, sid);
2528 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_TCP_USER_MSS,
2529 (void *) optval, &optlen);
2530 break;
2531 case TCP_KEEPIDLE:
2532 func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_KEEPIDLE]";
Dave Wallace2a865272018-02-07 21:00:42 -05002533 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002534 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2535 "sid %u (0x%x)",
2536 getpid (), fd, fd, func_str, sid, sid);
2537 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_TCP_KEEPIDLE,
2538 (void *) optval, &optlen);
2539 break;
2540 case TCP_KEEPINTVL:
2541 func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_KEEPINTVL]";
Dave Wallace2a865272018-02-07 21:00:42 -05002542 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002543 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2544 "sid %u (0x%x), SOL_TCP",
2545 getpid (), fd, fd, func_str, sid, sid);
2546 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_TCP_KEEPINTVL,
2547 (void *) optval, &optlen);
2548 break;
2549 default:
Dave Wallace2a865272018-02-07 21:00:42 -05002550 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002551 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2552 "sid %u (0x%x), SOL_TCP, "
2553 "optname %d unsupported!",
2554 getpid (), fd, fd, func_str, sid, sid, optname);
2555 break;
2556 }
2557 break;
2558 case SOL_IPV6:
2559 switch (optname)
2560 {
2561 case IPV6_V6ONLY:
2562 func_str = "vppcom_session_attr[SOL_IPV6,SET_V6ONLY]";
Dave Wallace2a865272018-02-07 21:00:42 -05002563 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002564 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2565 "sid %u (0x%x)",
2566 getpid (), fd, fd, func_str, sid, sid);
2567 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_V6ONLY,
2568 (void *) optval, &optlen);
2569 break;
2570 default:
Dave Wallace2a865272018-02-07 21:00:42 -05002571 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002572 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2573 "sid %u (0x%x), SOL_IPV6, "
2574 "optname %d unsupported!",
2575 getpid (), fd, fd, func_str, sid, sid, optname);
2576 break;
2577 }
2578 break;
2579 case SOL_SOCKET:
2580 switch (optname)
2581 {
2582 case SO_KEEPALIVE:
2583 func_str = "vppcom_session_attr[SOL_SOCKET,SET_KEEPALIVE]";
Dave Wallace2a865272018-02-07 21:00:42 -05002584 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002585 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2586 "sid %u (0x%x)",
2587 getpid (), fd, fd, func_str, sid, sid);
2588 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_KEEPALIVE,
2589 (void *) optval, &optlen);
2590 break;
2591 case SO_REUSEADDR:
2592 func_str = "vppcom_session_attr[SOL_SOCKET,SET_REUSEADDR]";
Dave Wallace2a865272018-02-07 21:00:42 -05002593 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002594 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2595 "sid %u (0x%x)",
2596 getpid (), fd, fd, func_str, sid, sid);
2597 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_REUSEADDR,
2598 (void *) optval, &optlen);
2599 break;
2600 case SO_BROADCAST:
2601 func_str = "vppcom_session_attr[SOL_SOCKET,SET_BROADCAST]";
Dave Wallace2a865272018-02-07 21:00:42 -05002602 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002603 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2604 "sid %u (0x%x)",
2605 getpid (), fd, fd, func_str, sid, sid);
2606 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_BROADCAST,
2607 (void *) optval, &optlen);
2608 break;
2609 default:
Dave Wallace2a865272018-02-07 21:00:42 -05002610 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002611 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2612 "sid %u (0x%x), SOL_SOCKET, "
2613 "optname %d unsupported!",
2614 getpid (), fd, fd, func_str, sid, sid, optname);
2615 break;
2616 }
2617 break;
2618 default:
2619 break;
2620 }
2621
2622 if (rv != VPPCOM_OK)
2623 {
2624 errno = -rv;
2625 rv = -1;
2626 }
2627 }
2628 else
2629 {
2630 func_str = "libc_setsockopt";
2631
Dave Wallace2a865272018-02-07 21:00:42 -05002632 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002633 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): level %d, "
2634 "optname %d, optval %p, optlen %d",
2635 getpid (), fd, fd, func_str, level, optname,
2636 optval, optlen);
2637
2638 rv = libc_setsockopt (fd, level, optname, optval, optlen);
2639 }
2640
Dave Wallace2a865272018-02-07 21:00:42 -05002641 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002642 {
2643 if (rv < 0)
2644 {
2645 int errno_val = errno;
2646 perror (func_str);
2647 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2648 "rv %d, errno = %d", getpid (), fd, fd,
2649 func_str, rv, errno_val);
2650 errno = errno_val;
2651 }
2652 else
2653 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2654 getpid (), fd, fd, rv, rv);
2655 }
2656 return rv;
2657}
2658
2659int
2660listen (int fd, int n)
2661{
2662 int rv;
Dave Wallace2a865272018-02-07 21:00:42 -05002663 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002664
Dave Wallace2a865272018-02-07 21:00:42 -05002665 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002666 return -1;
2667
2668 if (sid != INVALID_SESSION_ID)
2669 {
Florin Coras05ecfcc2018-12-12 18:19:39 -08002670 LDBG (0, "fd %d (0x%x): calling vppcom_session_listen():"
2671 " sid %u (0x%x), n %d", fd, fd, sid, sid, n);
Dave Wallace048b1d62018-01-03 22:24:41 -05002672
2673 rv = vppcom_session_listen (sid, n);
2674 if (rv != VPPCOM_OK)
2675 {
2676 errno = -rv;
2677 rv = -1;
2678 }
2679 }
2680 else
2681 {
Florin Coras05ecfcc2018-12-12 18:19:39 -08002682 LDBG (0, "fd %d (0x%x): calling libc_listen(): n %d", fd, fd, n);
Dave Wallace048b1d62018-01-03 22:24:41 -05002683
2684 rv = libc_listen (fd, n);
2685 }
2686
Florin Coras05ecfcc2018-12-12 18:19:39 -08002687 LDBG (1, "fd %d (0x%x): returning %d (0x%x)", fd, fd, rv, rv);
Dave Wallace048b1d62018-01-03 22:24:41 -05002688 return rv;
2689}
2690
2691static inline int
Dave Wallace2a865272018-02-07 21:00:42 -05002692ldp_accept4 (int listen_fd, __SOCKADDR_ARG addr,
2693 socklen_t * __restrict addr_len, int flags)
Dave Wallace048b1d62018-01-03 22:24:41 -05002694{
2695 int rv;
Dave Wallace2a865272018-02-07 21:00:42 -05002696 u32 listen_sid = ldp_sid_from_fd (listen_fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002697 int accept_sid;
2698
Dave Wallace2a865272018-02-07 21:00:42 -05002699 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002700 return -1;
2701
2702 if (listen_sid != INVALID_SESSION_ID)
2703 {
2704 vppcom_endpt_t ep;
2705 u8 src_addr[sizeof (struct sockaddr_in6)];
Dave Wallace8aaba562018-01-18 17:21:19 -05002706 memset (&ep, 0, sizeof (ep));
Dave Wallace048b1d62018-01-03 22:24:41 -05002707 ep.ip = src_addr;
2708
Florin Coras05ecfcc2018-12-12 18:19:39 -08002709 LDBG (0, "listen fd %d (0x%x): calling vppcom_session_accept:"
2710 " listen sid %u (0x%x), ep %p, flags 0x%x", listen_fd,
2711 listen_fd, listen_sid, listen_sid, ep, flags);
Dave Wallace048b1d62018-01-03 22:24:41 -05002712
2713 accept_sid = vppcom_session_accept (listen_sid, &ep, flags);
2714 if (accept_sid < 0)
2715 {
2716 errno = -accept_sid;
2717 rv = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002718 }
2719 else
2720 {
Dave Wallace2a865272018-02-07 21:00:42 -05002721 rv = ldp_copy_ep_to_sockaddr (addr, addr_len, &ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05002722 if (rv != VPPCOM_OK)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002723 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002724 (void) vppcom_session_close ((u32) accept_sid);
2725 errno = -rv;
2726 rv = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002727 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002728 else
2729 {
Florin Coras30e273b2018-11-27 00:04:59 -08002730 rv = ldp_fd_alloc ((u32) accept_sid);
Dave Wallace048b1d62018-01-03 22:24:41 -05002731 if (rv < 0)
2732 {
2733 (void) vppcom_session_close ((u32) accept_sid);
2734 errno = -rv;
2735 rv = -1;
2736 }
2737 }
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002738 }
2739 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002740 else
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002741 {
Florin Coras05ecfcc2018-12-12 18:19:39 -08002742 LDBG (0, "listen fd %d (0x%x): calling libc_accept4(): "
2743 "addr %p, addr_len %p, flags 0x%x", listen_fd,
2744 listen_fd, addr, addr_len, flags);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002745
Dave Wallace048b1d62018-01-03 22:24:41 -05002746 rv = libc_accept4 (listen_fd, addr, addr_len, flags);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002747 }
2748
Florin Coras05ecfcc2018-12-12 18:19:39 -08002749 LDBG (1, "listen fd %d (0x%x): returning %d (0x%x)", listen_fd, listen_fd,
2750 rv, rv);
2751
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002752 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002753}
2754
Dave Wallace048b1d62018-01-03 22:24:41 -05002755int
2756accept4 (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict addr_len,
2757 int flags)
2758{
Dave Wallace2a865272018-02-07 21:00:42 -05002759 return ldp_accept4 (fd, addr, addr_len, flags);
Dave Wallace048b1d62018-01-03 22:24:41 -05002760}
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002761
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002762int
Dave Wallace048b1d62018-01-03 22:24:41 -05002763accept (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict addr_len)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002764{
Dave Wallace2a865272018-02-07 21:00:42 -05002765 return ldp_accept4 (fd, addr, addr_len, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05002766}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002767
Dave Wallace048b1d62018-01-03 22:24:41 -05002768int
2769shutdown (int fd, int how)
2770{
Florin Corasa7a1a222018-12-30 17:11:31 -08002771 int rv = 0;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002772
Dave Wallace2a865272018-02-07 21:00:42 -05002773 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002774 return -1;
2775
Florin Corasa7a1a222018-12-30 17:11:31 -08002776 if (ldp_fd_is_sid (fd))
Dave Wallace048b1d62018-01-03 22:24:41 -05002777 {
Florin Corasa7a1a222018-12-30 17:11:31 -08002778 u32 fd_index = fd - ldp->sid_bit_val;
2779 ldp_fd_entry_t *fde;
2780
2781 fde = ldp_fd_entry_get_w_lock (fd_index);
2782 if (!fde)
2783 {
2784 clib_rwlock_reader_unlock (&ldp->fd_table_lock);
2785 errno = ENOTCONN;
2786 return -1;
2787 }
2788
2789 if (how == SHUT_RD)
2790 fde->flags |= LDP_F_SHUT_RD;
2791 else if (how == SHUT_WR)
2792 fde->flags |= LDP_F_SHUT_WR;
2793 else if (how == SHUT_RDWR)
2794 fde->flags |= (LDP_F_SHUT_RD | LDP_F_SHUT_WR);
2795
2796 if ((fde->flags & LDP_F_SHUT_RD) && (fde->flags & LDP_F_SHUT_WR))
2797 rv = close (fd);
2798
2799 clib_rwlock_reader_unlock (&ldp->fd_table_lock);
2800 LDBG (0, "fd %d (0x%x): calling vcl shutdown: how %d", fd, fd, how);
Dave Wallace048b1d62018-01-03 22:24:41 -05002801 }
2802 else
2803 {
Florin Corasa7a1a222018-12-30 17:11:31 -08002804 LDBG (1, "fd %d (0x%x): calling libc_shutdown: how %d", fd, fd, how);
Dave Wallace048b1d62018-01-03 22:24:41 -05002805 rv = libc_shutdown (fd, how);
2806 }
2807
Dave Wallace048b1d62018-01-03 22:24:41 -05002808 return rv;
2809}
2810
2811int
2812epoll_create1 (int flags)
2813{
Florin Corasdfe4cf42018-11-28 22:13:45 -08002814 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
Dave Wallace048b1d62018-01-03 22:24:41 -05002815 const char *func_str;
2816 int rv;
2817
Dave Wallace2a865272018-02-07 21:00:42 -05002818 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002819 return -1;
2820
Florin Coras99368312018-08-02 10:45:44 -07002821 if (ldp->vcl_needs_real_epoll)
2822 {
2823 rv = libc_epoll_create1 (flags);
2824 ldp->vcl_needs_real_epoll = 0;
Florin Corasdfe4cf42018-11-28 22:13:45 -08002825 ldpw->vcl_mq_epfd = rv;
Florin Coras05ecfcc2018-12-12 18:19:39 -08002826 LDBG (0, "created vcl epfd %u", rv);
Florin Coras99368312018-08-02 10:45:44 -07002827 return rv;
2828 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002829 func_str = "vppcom_epoll_create";
2830
Florin Coras05ecfcc2018-12-12 18:19:39 -08002831 LDBG (1, "calling %s()", func_str);
Dave Wallace048b1d62018-01-03 22:24:41 -05002832
2833 rv = vppcom_epoll_create ();
2834
2835 if (PREDICT_FALSE (rv < 0))
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002836 {
2837 errno = -rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05002838 rv = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002839 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002840 else
Florin Coras30e273b2018-11-27 00:04:59 -08002841 rv = ldp_fd_alloc ((u32) rv);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002842
Dave Wallace2a865272018-02-07 21:00:42 -05002843 if (LDP_DEBUG > 1)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002844 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002845 if (rv < 0)
2846 {
2847 int errno_val = errno;
2848 perror (func_str);
2849 clib_warning ("LDP<%d>: ERROR: %s() failed! "
2850 "rv %d, errno = %d",
2851 getpid (), func_str, rv, errno_val);
2852 errno = errno_val;
2853 }
2854 else
2855 clib_warning ("LDP<%d>: returning epfd %d (0x%x)", getpid (), rv, rv);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002856 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002857 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002858}
2859
2860int
Dave Wallace048b1d62018-01-03 22:24:41 -05002861epoll_create (int size)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002862{
Dave Wallace048b1d62018-01-03 22:24:41 -05002863 return epoll_create1 (0);
2864}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002865
Dave Wallace048b1d62018-01-03 22:24:41 -05002866int
2867epoll_ctl (int epfd, int op, int fd, struct epoll_event *event)
2868{
Florin Coras99368312018-08-02 10:45:44 -07002869 u32 vep_idx = ldp_sid_from_fd (epfd), sid;
Dave Wallace048b1d62018-01-03 22:24:41 -05002870 const char *func_str;
Florin Coras99368312018-08-02 10:45:44 -07002871 int rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05002872
Dave Wallace2a865272018-02-07 21:00:42 -05002873 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002874 return -1;
2875
Florin Coras99368312018-08-02 10:45:44 -07002876 if (PREDICT_FALSE (vep_idx == INVALID_SESSION_ID))
Dave Wallace048b1d62018-01-03 22:24:41 -05002877 {
Dave Wallace3ee1fe12018-02-23 01:09:11 -05002878 /* The LDP epoll_create1 always creates VCL epfd's.
2879 * The app should never have a kernel base epoll fd unless it
2880 * was acquired outside of the LD_PRELOAD process context.
2881 * In any case, if we get one, punt it to libc_epoll_ctl.
2882 */
Dave Wallace048b1d62018-01-03 22:24:41 -05002883 func_str = "libc_epoll_ctl";
2884
Florin Coras05ecfcc2018-12-12 18:19:39 -08002885 LDBG (1, "epfd %d (0x%x): calling %s(): op %d, fd %d (0x%x),"
2886 " event %p", epfd, epfd, func_str, op, fd, fd, event);
Dave Wallace048b1d62018-01-03 22:24:41 -05002887
2888 rv = libc_epoll_ctl (epfd, op, fd, event);
Florin Coras99368312018-08-02 10:45:44 -07002889 goto done;
2890 }
2891
2892 sid = ldp_sid_from_fd (fd);
2893
Florin Coras05ecfcc2018-12-12 18:19:39 -08002894 LDBG (0, "epfd %d (0x%x), vep_idx %d (0x%x), sid %d (0x%x)",
2895 epfd, epfd, vep_idx, vep_idx, sid, sid);
Florin Coras99368312018-08-02 10:45:44 -07002896
2897 if (sid != INVALID_SESSION_ID)
2898 {
2899 func_str = "vppcom_epoll_ctl";
2900
Florin Coras05ecfcc2018-12-12 18:19:39 -08002901 LDBG (1, "epfd %d (0x%x): calling %s(): vep_idx %d (0x%x),"
2902 " op %d, sid %u (0x%x), event %p", epfd, epfd,
Florin Coras99368312018-08-02 10:45:44 -07002903 func_str, vep_idx, vep_idx, sid, sid, event);
2904
2905 rv = vppcom_epoll_ctl (vep_idx, op, sid, event);
2906 if (rv != VPPCOM_OK)
2907 {
2908 errno = -rv;
2909 rv = -1;
2910 }
2911 }
2912 else
2913 {
2914 int libc_epfd;
2915 u32 size = sizeof (epfd);
2916
2917 func_str = "vppcom_session_attr[GET_LIBC_EPFD]";
2918 libc_epfd = vppcom_session_attr (vep_idx, VPPCOM_ATTR_GET_LIBC_EPFD, 0,
2919 0);
Florin Coras05ecfcc2018-12-12 18:19:39 -08002920 LDBG (1, "epfd %d (0x%x), vep_idx %d (0x%x): %s() "
2921 "returned libc_epfd %d (0x%x)", epfd, epfd,
Florin Coras99368312018-08-02 10:45:44 -07002922 vep_idx, vep_idx, func_str, libc_epfd, libc_epfd);
2923
2924 if (!libc_epfd)
2925 {
2926 func_str = "libc_epoll_create1";
2927
Florin Coras05ecfcc2018-12-12 18:19:39 -08002928 LDBG (1, "epfd %d (0x%x), vep_idx %d (0x%x): "
2929 "calling %s(): EPOLL_CLOEXEC", epfd, epfd,
Florin Coras99368312018-08-02 10:45:44 -07002930 vep_idx, vep_idx, func_str);
2931
2932 libc_epfd = libc_epoll_create1 (EPOLL_CLOEXEC);
2933 if (libc_epfd < 0)
2934 {
2935 rv = libc_epfd;
2936 goto done;
2937 }
2938
2939 func_str = "vppcom_session_attr[SET_LIBC_EPFD]";
Florin Coras05ecfcc2018-12-12 18:19:39 -08002940 LDBG (1, "epfd %d (0x%x): calling %s(): vep_idx %d (0x%x),"
Florin Coras99368312018-08-02 10:45:44 -07002941 " VPPCOM_ATTR_SET_LIBC_EPFD, libc_epfd %d (0x%x), size %d",
Florin Coras05ecfcc2018-12-12 18:19:39 -08002942 epfd, epfd, func_str, vep_idx, vep_idx, libc_epfd,
Florin Coras99368312018-08-02 10:45:44 -07002943 libc_epfd, size);
2944
2945 rv = vppcom_session_attr (vep_idx, VPPCOM_ATTR_SET_LIBC_EPFD,
2946 &libc_epfd, &size);
2947 if (rv < 0)
2948 {
2949 errno = -rv;
2950 rv = -1;
2951 goto done;
2952 }
2953 }
2954 else if (PREDICT_FALSE (libc_epfd < 0))
2955 {
2956 errno = -epfd;
2957 rv = -1;
2958 goto done;
2959 }
2960
2961 func_str = "libc_epoll_ctl";
2962
Florin Coras05ecfcc2018-12-12 18:19:39 -08002963 LDBG (1, "epfd %d (0x%x): calling %s(): libc_epfd %d (0x%x), "
2964 "op %d, fd %d (0x%x), event %p", epfd, epfd, func_str,
Florin Coras99368312018-08-02 10:45:44 -07002965 libc_epfd, libc_epfd, op, fd, fd, event);
2966
2967 rv = libc_epoll_ctl (libc_epfd, op, fd, event);
Dave Wallace048b1d62018-01-03 22:24:41 -05002968 }
2969
2970done:
Dave Wallace2a865272018-02-07 21:00:42 -05002971 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002972 {
2973 if (rv < 0)
2974 {
2975 int errno_val = errno;
2976 perror (func_str);
2977 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2978 "rv %d, errno = %d", getpid (), fd, fd,
2979 func_str, rv, errno_val);
2980 errno = errno_val;
2981 }
2982 else
2983 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2984 getpid (), fd, fd, rv, rv);
2985 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002986 return rv;
2987}
Dave Wallace048b1d62018-01-03 22:24:41 -05002988
2989static inline int
Florin Coras99368312018-08-02 10:45:44 -07002990ldp_epoll_pwait (int epfd, struct epoll_event *events, int maxevents,
2991 int timeout, const sigset_t * sigmask)
Dave Wallace048b1d62018-01-03 22:24:41 -05002992{
Florin Corasdfe4cf42018-11-28 22:13:45 -08002993 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
Florin Coras99368312018-08-02 10:45:44 -07002994 double time_to_wait = (double) 0, time_out, now = 0;
Dave Wallace2a865272018-02-07 21:00:42 -05002995 u32 vep_idx = ldp_sid_from_fd (epfd);
Florin Coras99368312018-08-02 10:45:44 -07002996 int libc_epfd, rv = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05002997
Dave Wallace2a865272018-02-07 21:00:42 -05002998 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002999 return -1;
3000
3001 if (PREDICT_FALSE (!events || (timeout < -1)))
3002 {
3003 errno = EFAULT;
3004 return -1;
3005 }
3006
Florin Corasdfe4cf42018-11-28 22:13:45 -08003007 if (epfd == ldpw->vcl_mq_epfd)
Florin Coras99368312018-08-02 10:45:44 -07003008 return libc_epoll_pwait (epfd, events, maxevents, timeout, sigmask);
3009
Dave Wallace048b1d62018-01-03 22:24:41 -05003010 if (PREDICT_FALSE (vep_idx == INVALID_SESSION_ID))
3011 {
Florin Corasa7a1a222018-12-30 17:11:31 -08003012 LDBG (0, "epfd %d (0x%x): bad vep_idx %d (0x%x)!", epfd, epfd, vep_idx,
3013 vep_idx);
Dave Wallace048b1d62018-01-03 22:24:41 -05003014 errno = EBADFD;
3015 return -1;
3016 }
3017
Florin Corasb0f662f2018-12-27 14:51:46 -08003018 time_to_wait = ((timeout >= 0) ? (double) timeout / 1000 : 0);
Florin Corasdfe4cf42018-11-28 22:13:45 -08003019 time_out = clib_time_now (&ldpw->clib_time) + time_to_wait;
Dave Wallace048b1d62018-01-03 22:24:41 -05003020
Dave Wallace048b1d62018-01-03 22:24:41 -05003021 libc_epfd = vppcom_session_attr (vep_idx, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
3022 if (PREDICT_FALSE (libc_epfd < 0))
3023 {
3024 errno = -libc_epfd;
3025 rv = -1;
3026 goto done;
3027 }
3028
Florin Coras05ecfcc2018-12-12 18:19:39 -08003029 LDBG (2, "epfd %d (0x%x): vep_idx %d (0x%x), libc_epfd %d (0x%x), "
Florin Coras99368312018-08-02 10:45:44 -07003030 "events %p, maxevents %d, timeout %d, sigmask %p: time_to_wait %.02f",
Florin Coras05ecfcc2018-12-12 18:19:39 -08003031 epfd, epfd, vep_idx, vep_idx, libc_epfd, libc_epfd, events,
Florin Coras99368312018-08-02 10:45:44 -07003032 maxevents, timeout, sigmask, time_to_wait, time_out);
Dave Wallace048b1d62018-01-03 22:24:41 -05003033 do
3034 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08003035 if (!ldpw->epoll_wait_vcl)
Dave Wallace048b1d62018-01-03 22:24:41 -05003036 {
Florin Corasa7a1a222018-12-30 17:11:31 -08003037 LDBG (3, "epfd %d (0x%x): calling vcl_epoll_wait: vep_idx %d (0x%x)"
3038 " events %p, maxevents %d", epfd, epfd, vep_idx, vep_idx,
3039 events, maxevents);
Dave Wallace048b1d62018-01-03 22:24:41 -05003040
3041 rv = vppcom_epoll_wait (vep_idx, events, maxevents, 0);
3042 if (rv > 0)
3043 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08003044 ldpw->epoll_wait_vcl = 1;
Dave Wallace048b1d62018-01-03 22:24:41 -05003045 goto done;
3046 }
3047 else if (rv < 0)
3048 {
3049 errno = -rv;
3050 rv = -1;
3051 goto done;
3052 }
3053 }
3054 else
Florin Corasdfe4cf42018-11-28 22:13:45 -08003055 ldpw->epoll_wait_vcl = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05003056
3057 if (libc_epfd > 0)
3058 {
Florin Corasa7a1a222018-12-30 17:11:31 -08003059 LDBG (3, "epfd %d (0x%x): calling libc_epoll_wait: libc_epfd %d "
3060 "(0x%x), events %p, maxevents %d, sigmask %p", epfd, epfd,
3061 libc_epfd, libc_epfd, events, maxevents, sigmask);
Dave Wallace048b1d62018-01-03 22:24:41 -05003062
Florin Corasb0f662f2018-12-27 14:51:46 -08003063 rv = libc_epoll_pwait (libc_epfd, events, maxevents, 0, sigmask);
Dave Wallace048b1d62018-01-03 22:24:41 -05003064 if (rv != 0)
3065 goto done;
3066 }
3067
3068 if (timeout != -1)
Florin Corasdfe4cf42018-11-28 22:13:45 -08003069 now = clib_time_now (&ldpw->clib_time);
Dave Wallace048b1d62018-01-03 22:24:41 -05003070 }
3071 while (now < time_out);
3072
3073done:
Dave Wallace048b1d62018-01-03 22:24:41 -05003074 return rv;
3075}
3076
3077int
3078epoll_pwait (int epfd, struct epoll_event *events,
3079 int maxevents, int timeout, const sigset_t * sigmask)
3080{
Dave Wallace2a865272018-02-07 21:00:42 -05003081 return ldp_epoll_pwait (epfd, events, maxevents, timeout, sigmask);
Dave Wallace048b1d62018-01-03 22:24:41 -05003082}
3083
3084int
3085epoll_wait (int epfd, struct epoll_event *events, int maxevents, int timeout)
3086{
Dave Wallace2a865272018-02-07 21:00:42 -05003087 return ldp_epoll_pwait (epfd, events, maxevents, timeout, NULL);
Dave Wallace048b1d62018-01-03 22:24:41 -05003088}
3089
3090int
3091poll (struct pollfd *fds, nfds_t nfds, int timeout)
3092{
Florin Corasdfe4cf42018-11-28 22:13:45 -08003093 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
Dave Wallace048b1d62018-01-03 22:24:41 -05003094 const char *func_str = __func__;
Florin Coras6917b942018-11-13 22:44:54 -08003095 int rv, i, n_revents = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05003096 u32 sid;
3097 vcl_poll_t *vp;
3098 double wait_for_time;
3099
Florin Coras05ecfcc2018-12-12 18:19:39 -08003100 LDBG (3, "fds %p, nfds %d, timeout %d", fds, nfds, timeout);
Dave Wallace048b1d62018-01-03 22:24:41 -05003101
3102 if (timeout >= 0)
3103 wait_for_time = (f64) timeout / 1000;
3104 else
3105 wait_for_time = -1;
3106
Dave Wallace048b1d62018-01-03 22:24:41 -05003107 for (i = 0; i < nfds; i++)
3108 {
Florin Coras6917b942018-11-13 22:44:54 -08003109 if (fds[i].fd < 0)
3110 continue;
Dave Wallace048b1d62018-01-03 22:24:41 -05003111
Florin Coras05ecfcc2018-12-12 18:19:39 -08003112 LDBG (3, "fds[%d] fd %d (0x%0x) events = 0x%x revents = 0x%x",
3113 i, fds[i].fd, fds[i].fd, fds[i].events, fds[i].revents);
Florin Coras6917b942018-11-13 22:44:54 -08003114
3115 sid = ldp_sid_from_fd (fds[i].fd);
3116 if (sid != INVALID_SESSION_ID)
3117 {
3118 fds[i].fd = -fds[i].fd;
Florin Corasdfe4cf42018-11-28 22:13:45 -08003119 vec_add2 (ldpw->vcl_poll, vp, 1);
Florin Coras6917b942018-11-13 22:44:54 -08003120 vp->fds_ndx = i;
3121 vp->sid = sid;
3122 vp->events = fds[i].events;
Dave Wallace048b1d62018-01-03 22:24:41 -05003123#ifdef __USE_XOPEN2K
Florin Coras6917b942018-11-13 22:44:54 -08003124 if (fds[i].events & POLLRDNORM)
3125 vp->events |= POLLIN;
3126 if (fds[i].events & POLLWRNORM)
3127 vp->events |= POLLOUT;
Dave Wallace048b1d62018-01-03 22:24:41 -05003128#endif
Florin Coras6917b942018-11-13 22:44:54 -08003129 vp->revents = fds[i].revents;
3130 }
3131 else
3132 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08003133 vec_add1 (ldpw->libc_poll, fds[i]);
3134 vec_add1 (ldpw->libc_poll_idxs, i);
Dave Wallace048b1d62018-01-03 22:24:41 -05003135 }
3136 }
3137
Dave Wallace048b1d62018-01-03 22:24:41 -05003138 do
3139 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08003140 if (vec_len (ldpw->vcl_poll))
Dave Wallace048b1d62018-01-03 22:24:41 -05003141 {
3142 func_str = "vppcom_poll";
3143
Florin Coras05ecfcc2018-12-12 18:19:39 -08003144 LDBG (3, "calling %s(): vcl_poll %p, n_sids %u (0x%x): "
3145 "n_libc_fds %u", func_str, ldpw->vcl_poll,
Florin Corasdfe4cf42018-11-28 22:13:45 -08003146 vec_len (ldpw->vcl_poll), vec_len (ldpw->vcl_poll),
3147 vec_len (ldpw->libc_poll));
Dave Wallace048b1d62018-01-03 22:24:41 -05003148
Florin Corasdfe4cf42018-11-28 22:13:45 -08003149 rv = vppcom_poll (ldpw->vcl_poll, vec_len (ldpw->vcl_poll), 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05003150 if (rv < 0)
3151 {
3152 errno = -rv;
3153 rv = -1;
3154 goto done;
3155 }
3156 else
3157 n_revents += rv;
3158 }
3159
Florin Corasdfe4cf42018-11-28 22:13:45 -08003160 if (vec_len (ldpw->libc_poll))
Dave Wallace048b1d62018-01-03 22:24:41 -05003161 {
3162 func_str = "libc_poll";
3163
Florin Coras05ecfcc2018-12-12 18:19:39 -08003164 LDBG (3, "calling %s(): fds %p, nfds %u: n_sids %u",
3165 fds, nfds, vec_len (ldpw->vcl_poll));
Dave Wallace048b1d62018-01-03 22:24:41 -05003166
Florin Corasdfe4cf42018-11-28 22:13:45 -08003167 rv = libc_poll (ldpw->libc_poll, vec_len (ldpw->libc_poll), 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05003168 if (rv < 0)
3169 goto done;
3170 else
3171 n_revents += rv;
3172 }
3173
3174 if (n_revents)
3175 {
3176 rv = n_revents;
3177 goto done;
3178 }
3179 }
3180 while ((wait_for_time == -1) ||
Florin Corasdfe4cf42018-11-28 22:13:45 -08003181 (clib_time_now (&ldpw->clib_time) < wait_for_time));
Dave Wallace048b1d62018-01-03 22:24:41 -05003182 rv = 0;
3183
3184done:
Florin Corasdfe4cf42018-11-28 22:13:45 -08003185 vec_foreach (vp, ldpw->vcl_poll)
Dave Wallace048b1d62018-01-03 22:24:41 -05003186 {
3187 fds[vp->fds_ndx].fd = -fds[vp->fds_ndx].fd;
Florin Coras6917b942018-11-13 22:44:54 -08003188 fds[vp->fds_ndx].revents = vp->revents;
Dave Wallace048b1d62018-01-03 22:24:41 -05003189#ifdef __USE_XOPEN2K
3190 if ((fds[vp->fds_ndx].revents & POLLIN) &&
3191 (fds[vp->fds_ndx].events & POLLRDNORM))
3192 fds[vp->fds_ndx].revents |= POLLRDNORM;
3193 if ((fds[vp->fds_ndx].revents & POLLOUT) &&
3194 (fds[vp->fds_ndx].events & POLLWRNORM))
3195 fds[vp->fds_ndx].revents |= POLLWRNORM;
3196#endif
3197 }
Florin Corasdfe4cf42018-11-28 22:13:45 -08003198 vec_reset_length (ldpw->vcl_poll);
Dave Wallace048b1d62018-01-03 22:24:41 -05003199
Florin Corasdfe4cf42018-11-28 22:13:45 -08003200 for (i = 0; i < vec_len (ldpw->libc_poll); i++)
Florin Coras6917b942018-11-13 22:44:54 -08003201 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08003202 fds[ldpw->libc_poll_idxs[i]].revents = ldpw->libc_poll[i].revents;
Florin Coras6917b942018-11-13 22:44:54 -08003203 }
Florin Corasdfe4cf42018-11-28 22:13:45 -08003204 vec_reset_length (ldpw->libc_poll_idxs);
3205 vec_reset_length (ldpw->libc_poll);
Florin Coras6917b942018-11-13 22:44:54 -08003206
Dave Wallace2a865272018-02-07 21:00:42 -05003207 if (LDP_DEBUG > 3)
Dave Wallace048b1d62018-01-03 22:24:41 -05003208 {
3209 if (rv < 0)
3210 {
3211 int errno_val = errno;
3212 perror (func_str);
3213 clib_warning ("LDP<%d>: ERROR: %s() failed! "
3214 "rv %d, errno = %d", getpid (),
3215 func_str, rv, errno_val);
3216 errno = errno_val;
3217 }
3218 else
3219 {
3220 clib_warning ("LDP<%d>: returning %d (0x%x): n_sids %u, "
3221 "n_libc_fds %d", getpid (), rv, rv,
Florin Corasdfe4cf42018-11-28 22:13:45 -08003222 vec_len (ldpw->vcl_poll), vec_len (ldpw->libc_poll));
Dave Wallace048b1d62018-01-03 22:24:41 -05003223
3224 for (i = 0; i < nfds; i++)
3225 {
3226 if (fds[i].fd >= 0)
3227 {
Dave Wallace2a865272018-02-07 21:00:42 -05003228 if (LDP_DEBUG > 3)
Dave Wallace048b1d62018-01-03 22:24:41 -05003229 clib_warning ("LDP<%d>: fds[%d].fd %d (0x%0x), "
3230 ".events = 0x%x, .revents = 0x%x",
3231 getpid (), i, fds[i].fd, fds[i].fd,
3232 fds[i].events, fds[i].revents);
3233 }
3234 }
3235 }
3236 }
3237
3238 return rv;
3239}
3240
3241#ifdef USE_GNU
3242int
3243ppoll (struct pollfd *fds, nfds_t nfds,
3244 const struct timespec *timeout, const sigset_t * sigmask)
3245{
Dave Wallace2a865272018-02-07 21:00:42 -05003246 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05003247 return -1;
3248
3249 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
3250 errno = ENOSYS;
3251
3252
3253 return -1;
3254}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003255#endif
3256
Dave Wallace2a865272018-02-07 21:00:42 -05003257void CONSTRUCTOR_ATTRIBUTE ldp_constructor (void);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003258
Dave Wallace2a865272018-02-07 21:00:42 -05003259void DESTRUCTOR_ATTRIBUTE ldp_destructor (void);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003260
Dave Wallace048b1d62018-01-03 22:24:41 -05003261/*
3262 * This function is called when the library is loaded
3263 */
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003264void
Dave Wallace2a865272018-02-07 21:00:42 -05003265ldp_constructor (void)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003266{
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003267 swrap_constructor ();
Dave Wallace2a865272018-02-07 21:00:42 -05003268 if (ldp_init () != 0)
3269 fprintf (stderr, "\nLDP<%d>: ERROR: ldp_constructor: failed!\n",
Dave Wallace048b1d62018-01-03 22:24:41 -05003270 getpid ());
Dave Wallace69d01192018-02-22 16:22:09 -05003271 else if (LDP_DEBUG > 0)
Dave Wallace2a865272018-02-07 21:00:42 -05003272 clib_warning ("LDP<%d>: LDP constructor: done!\n", getpid ());
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003273}
3274
3275/*
3276 * This function is called when the library is unloaded
3277 */
3278void
Dave Wallace2a865272018-02-07 21:00:42 -05003279ldp_destructor (void)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003280{
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003281 swrap_destructor ();
Dave Wallace2a865272018-02-07 21:00:42 -05003282 if (ldp->init)
Florin Coras940f78f2018-11-30 12:11:20 -08003283 ldp->init = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05003284
3285 /* Don't use clib_warning() here because that calls writev()
Dave Wallace2a865272018-02-07 21:00:42 -05003286 * which will call ldp_init().
Dave Wallace048b1d62018-01-03 22:24:41 -05003287 */
Dave Wallace69d01192018-02-22 16:22:09 -05003288 if (LDP_DEBUG > 0)
3289 printf ("%s:%d: LDP<%d>: LDP destructor: done!\n",
3290 __func__, __LINE__, getpid ());
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003291}
3292
3293
3294/*
3295 * fd.io coding-style-patch-verification: ON
3296 *
3297 * Local Variables:
3298 * eval: (c-set-style "gnu")
3299 * End:
3300 */