FD.io VPP  v20.05-21-gb1500e9ff
Vector Packet Processing
main.c
Go to the documentation of this file.
1 /*
2  *------------------------------------------------------------------
3  * Copyright (c) 2017 Cisco and/or its affiliates.
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *------------------------------------------------------------------
16  */
17 
18 #define _GNU_SOURCE
19 #include <stdint.h>
20 #include <net/if.h>
21 #include <sys/types.h>
22 #include <fcntl.h>
23 #include <sys/ioctl.h>
24 #include <sys/socket.h>
25 #include <sys/un.h>
26 #include <sys/uio.h>
27 #include <sys/mman.h>
28 #include <sys/prctl.h>
29 #include <inttypes.h>
30 #include <string.h>
31 #include <stdio.h>
32 #include <netdb.h>
33 #include <linux/ip.h>
34 #include <linux/icmp.h>
35 #include <arpa/inet.h>
36 #include <stdlib.h>
37 #include <netinet/if_ether.h>
38 #include <net/if_arp.h>
39 #include <asm/byteorder.h>
40 #include <byteswap.h>
41 #include <string.h>
42 #include <errno.h>
43 #include <sys/stat.h>
44 #include <sys/eventfd.h>
45 #include <sys/timerfd.h>
46 #include <sys/epoll.h>
47 #include <signal.h>
48 #include <linux/memfd.h>
49 
50 /* memif protocol msg, ring and descriptor definitions */
51 #include <memif.h>
52 /* memif api */
53 #include <libmemif.h>
54 /* socket messaging functions */
55 #include <socket.h>
56 /* private structs and functions */
57 #include <memif_private.h>
58 
59 #define ERRLIST_LEN 40
60 #define MAX_ERRBUF_LEN 256
61 
62 #if __x86_x64__
63 #define MEMIF_MEMORY_BARRIER() __builtin_ia32_sfence ()
64 #else
65 #define MEMIF_MEMORY_BARRIER() __sync_synchronize ()
66 #endif /* __x86_x64__ */
67 
69 
71 
72 const char *memif_errlist[ERRLIST_LEN] = { /* MEMIF_ERR_SUCCESS */
73  "Success.",
74  /* MEMIF_ERR_SYSCALL */
75  "Unspecified syscall error (build with -DMEMIF_DBG or make debug).",
76  /* MEMIF_ERR_CONNREFUSED */
77  "Connection refused",
78  /* MEMIF_ERR_ACCES */
79  "Permission to resoure denied.",
80  /* MEMIF_ERR_NO_FILE */
81  "Socket file does not exist",
82  /* MEMIF_ERR_FILE_LIMIT */
83  "System limit on total numer of open files reached.",
84  /* MEMIF_ERR_PROC_FILE_LIMIT */
85  "Per-process limit on total number of open files reached.",
86  /* MEMIF_ERR_ALREADY */
87  "Connection already requested.",
88  /* MEMIF_ERR_AGAIN */
89  "File descriptor refers to file other than socket, or operation would block.",
90  /* MEMIF_ERR_BAD_FD */
91  "Bad file descriptor.",
92  /* MEMIF_ERR_NOMEM */
93  "Out of memory.",
94  /* MEMIF_ERR_INVAL_ARG */
95  "Invalid argument.",
96  /* MEMIF_ERR_NOCONN */
97  "Memif connection handle does not point to existing conenction",
98  /* MEMIF_ERR_CONN */
99  "Memif connection handle points to existing connection",
100  /* MEMIF_ERR_CB_FDUPDATE */
101  "Callback memif_control_fd_update_t returned error",
102  /* MEMIF_ERR_FILE_NOT_SOCK */
103  "File specified by socket filename exists and is not socket.",
104  /* MEMIF_ERR_NO_SHMFD */
105  "Missing shared memory file descriptor. (internal error)",
106  /* MEMIF_ERR_COOKIE */
107  "Invalid cookie on ring. (internal error)",
108  /* MEMIF_ERR_NOBUF_RING */
109  "Ring buffer full.",
110  /* MEMIF_ERR_NOBUF */
111  "Not enough memif buffers. There are unreceived data in shared memory.",
112  /* MEMIF_ERR_NOBUF_DET */
113  "Not enough space for memif details in suplied buffer. String data might be malformed.",
114  /* MEMIF_ERR_INT_WRITE */
115  "Send interrupt error.",
116  /* MEMIF_ERR_MFMSG */
117  "Malformed message received on control channel.",
118  /* MEMIF_ERR_QID */
119  "Invalid queue id",
120  /* MEMIF_ERR_PROTO */
121  "Incompatible memory interface protocol version.",
122  /* MEMIF_ERR_ID */
123  "Unmatched interface id.",
124  /* MEMIF_ERR_ACCSLAVE */
125  "Slave cannot accept connection reqest.",
126  /* MEMIF_ERR_ALRCONN */
127  "Interface is already connected.",
128  /* MEMIF_ERR_MODE */
129  "Mode mismatch.",
130  /* MEMIF_ERR_SECRET */
131  "Secret mismatch.",
132  /* MEMIF_ERR_NOSECRET */
133  "Secret required.",
134  /* MEMIF_ERR_MAXREG */
135  "Limit on total number of regions reached.",
136  /* MEMIF_ERR_MAXRING */
137  "Limit on total number of ring reached.",
138  /* MEMIF_ERR_NO_INTFD */
139  "Missing interrupt file descriptor. (internal error)",
140  /* MEMIF_ERR_DISCONNECT */
141  "Interface received disconnect request.",
142  /* MEMIF_ERR_DISCONNECTED */
143  "Interface is disconnected.",
144  /* MEMIF_ERR_UNKNOWN_MSG */
145  "Unknown message type received on control channel. (internal error)",
146  /* MEMIF_ERR_POLL_CANCEL */
147  "Memif event polling was canceled.",
148  /* MEMIF_ERR_MAX_RING */
149  "Maximum log2 ring size is 15",
150  /* MEMIF_ERR_PRIVHDR */
151  "Private headers not supported."
152 };
153 
154 #define MEMIF_ERR_UNDEFINED "undefined error"
155 
156 char *
157 memif_strerror (int err_code)
158 {
159  if (err_code >= ERRLIST_LEN)
160  {
162  memif_buf[strlen (MEMIF_ERR_UNDEFINED)] = '\0';
163  }
164  else
165  {
166  strncpy (memif_buf, memif_errlist[err_code],
167  strlen (memif_errlist[err_code]));
168  memif_buf[strlen (memif_errlist[err_code])] = '\0';
169  }
170  return memif_buf;
171 }
172 
173 uint16_t
175 {
176  return MEMIF_VERSION;
177 }
178 
179 #define DBG_TX_BUF (0)
180 #define DBG_RX_BUF (1)
181 
182 #ifdef MEMIF_DBG_SHM
183 static void
184 print_bytes (void *data, uint16_t len, uint8_t q)
185 {
186  if (q == DBG_TX_BUF)
187  printf ("\nTX:\n\t");
188  else
189  printf ("\nRX:\n\t");
190  int i;
191  for (i = 0; i < len; i++)
192  {
193  if (i % 8 == 0)
194  printf ("\n%d:\t", i);
195  printf ("%02X ", ((uint8_t *) (data))[i]);
196  }
197  printf ("\n\n");
198 }
199 #endif /* MEMIF_DBG_SHM */
200 
201 int
203 {
204  DBG ("%s", strerror (err_code));
205 
206  if (err_code == 0)
207  return MEMIF_ERR_SUCCESS;
208  if (err_code == EACCES)
209  return MEMIF_ERR_ACCES;
210  if (err_code == ENFILE)
211  return MEMIF_ERR_FILE_LIMIT;
212  if (err_code == EMFILE)
214  if (err_code == ENOMEM)
215  return MEMIF_ERR_NOMEM;
216 /* connection refused if master does not exist
217  this error would spam the user until master was created */
218 /*
219  if (err_code == ECONNREFUSED)
220  return MEMIF_ERR_SUCCESS;
221 */
222  if (err_code == ECONNREFUSED)
223  return MEMIF_ERR_CONNREFUSED;
224  if (err_code == EALREADY)
225  return MEMIF_ERR_ALREADY;
226  if (err_code == EAGAIN)
227  return MEMIF_ERR_AGAIN;
228  if (err_code == EBADF)
229  return MEMIF_ERR_BAD_FD;
230  if (err_code == ENOENT)
231  return MEMIF_ERR_NO_FILE;
232 
233  /* other syscall errors */
234  return MEMIF_ERR_SYSCALL;
235 }
236 
237 /* Always valid */
240 {
241  if (ms != NULL && ms->lm != NULL)
242  return ms->lm;
243  return &libmemif_main;
244 }
245 
246 static int
247 memif_add_epoll_fd (libmemif_main_t * lm, int fd, uint32_t events)
248 {
249  if (fd < 0)
250  {
251  DBG ("invalid fd %d", fd);
252  return -1;
253  }
254  struct epoll_event evt;
255  memset (&evt, 0, sizeof (evt));
256  evt.events = events;
257  evt.data.fd = fd;
258  if (epoll_ctl (lm->epfd, EPOLL_CTL_ADD, fd, &evt) < 0)
259  {
260  DBG ("epoll_ctl: %s fd %d", strerror (errno), fd);
261  return -1;
262  }
263  DBG ("fd %d added to epoll", fd);
264  return 0;
265 }
266 
267 static int
268 memif_mod_epoll_fd (libmemif_main_t * lm, int fd, uint32_t events)
269 {
270  if (fd < 0)
271  {
272  DBG ("invalid fd %d", fd);
273  return -1;
274  }
275  struct epoll_event evt;
276  memset (&evt, 0, sizeof (evt));
277  evt.events = events;
278  evt.data.fd = fd;
279  if (epoll_ctl (lm->epfd, EPOLL_CTL_MOD, fd, &evt) < 0)
280  {
281  DBG ("epoll_ctl: %s fd %d", strerror (errno), fd);
282  return -1;
283  }
284  DBG ("fd %d moddified on epoll", fd);
285  return 0;
286 }
287 
288 static int
290 {
291  if (fd < 0)
292  {
293  DBG ("invalid fd %d", fd);
294  return -1;
295  }
296  struct epoll_event evt;
297  memset (&evt, 0, sizeof (evt));
298  if (epoll_ctl (lm->epfd, EPOLL_CTL_DEL, fd, &evt) < 0)
299  {
300  DBG ("epoll_ctl: %s fd %d", strerror (errno), fd);
301  return -1;
302  }
303  DBG ("fd %d removed from epoll", fd);
304  return 0;
305 }
306 
307 int
308 memif_control_fd_update (int fd, uint8_t events, void *private_ctx)
309 {
310  libmemif_main_t *lm;
311 
312  lm = (private_ctx == NULL) ? &libmemif_main : (libmemif_main_t *) private_ctx;
313 
314  if (events & MEMIF_FD_EVENT_DEL)
315  return memif_del_epoll_fd (lm, fd);
316 
317  uint32_t evt = 0;
318  if (events & MEMIF_FD_EVENT_READ)
319  evt |= EPOLLIN;
320  if (events & MEMIF_FD_EVENT_WRITE)
321  evt |= EPOLLOUT;
322 
323  if (events & MEMIF_FD_EVENT_MOD)
324  return memif_mod_epoll_fd (lm, fd, evt);
325 
326  return memif_add_epoll_fd (lm, fd, evt);
327 }
328 
329 int
331  memif_list_elt_t ** list, uint16_t * len)
332 {
333  memif_list_elt_t *tmp;
334  int i;
335 
336  for (i = 0; i < *len; i++)
337  {
338  if ((*list)[i].data_struct == NULL)
339  {
340  (*list)[i].key = e->key;
341  (*list)[i].data_struct = e->data_struct;
342  return i;
343  }
344  }
345 
346  tmp = lm->realloc (*list, sizeof (memif_list_elt_t) * *len * 2);
347  if (tmp == NULL)
348  return -1;
349 
350  for (i = *len; i < *len * 2; i++)
351  {
352  tmp[i].key = -1;
353  tmp[i].data_struct = NULL;
354  }
355 
356  tmp[*len].key = e->key;
357  tmp[*len].data_struct = e->data_struct;
358  i = *len;
359  *len = *len * 2;
360  *list = tmp;
361 
362  return i;
363 }
364 
365 int
367  int key)
368 {
369  int i;
370  if (key == -1)
371  {
372  *e = NULL;
373  return -1;
374  }
375 
376  for (i = 0; i < len; i++)
377  {
378  if (list[i].key == key)
379  {
380  *e = &list[i];
381  return 0;
382  }
383  }
384  *e = NULL;
385  return -1;
386 }
387 
388 /* does not free memory, only marks element as free */
389 int
390 free_list_elt (memif_list_elt_t * list, uint16_t len, int key)
391 {
392  int i;
393  for (i = 0; i < len; i++)
394  {
395  if (list[i].key == key)
396  {
397  list[i].key = -1;
398  list[i].data_struct = NULL;
399  return 0;
400  }
401  }
402 
403  return -1;
404 }
405 
406 int
409 {
410  int i;
411  for (i = 0; i < len; i++)
412  {
413  if (list[i].key == -1)
414  {
415  if (list[i].data_struct == ctx)
416  {
417  list[i].data_struct = NULL;
418  return 0;
419  }
420  }
421  }
422 
423  return -1;
424 }
425 
426 static void
429 {
430  lm->control_fd_update = cb;
431 }
432 
433 void
438 {
440  lm->add_external_region = ar;
441  lm->get_external_region_addr = gr;
442  lm->del_external_region = dr;
444 }
445 
446 static void
448 {
449  lm->alloc = ma;
450 }
451 
452 static void
454 {
455  lm->realloc = mr;
456 }
457 
458 static void
460 {
461  lm->free = mf;
462 }
463 
464 int
465 memif_set_connection_request_timer (struct itimerspec timer)
466 {
468  int err = MEMIF_ERR_SUCCESS;
469 
470  lm->arm = timer;
471 
472  /* overwrite timer, if already armed */
473  if (lm->disconn_slaves != 0)
474  {
475  if (timerfd_settime (lm->timerfd, 0, &lm->arm, NULL) < 0)
476  {
477  err = memif_syscall_error_handler (errno);
478  }
479  }
480  return err;
481 }
482 
483 int
485  pt_main,
486  struct itimerspec timer)
487 {
488  libmemif_main_t *lm = (libmemif_main_t *) pt_main;
489  int err = MEMIF_ERR_SUCCESS;
490 
491  lm->arm = timer;
492 
493  /* overwrite timer, if already armed */
494  if (lm->disconn_slaves != 0)
495  {
496  if (timerfd_settime (lm->timerfd, 0, &lm->arm, NULL) < 0)
497  {
498  err = memif_syscall_error_handler (errno);
499  }
500  }
501  return err;
502 }
503 
504 int
505 memif_init (memif_control_fd_update_t * on_control_fd_update, char *app_name,
506  memif_alloc_t * memif_alloc, memif_realloc_t * memif_realloc,
507  memif_free_t * memif_free)
508 {
509  int err = MEMIF_ERR_SUCCESS; /* 0 */
511  memset (lm, 0, sizeof (libmemif_main_t));
512 
513  /* register custom memory management */
514  if (memif_alloc != NULL)
515  {
516  memif_alloc_register (lm, memif_alloc);
517  }
518  else
519  memif_alloc_register (lm, malloc);
520 
521  if (memif_realloc != NULL)
522  {
523  memif_realloc_register (lm, memif_realloc);
524  }
525  else
526  memif_realloc_register (lm, realloc);
527 
528  if (memif_free != NULL)
529  memif_free_register (lm, memif_free);
530  else
531  memif_free_register (lm, free);
532 
533  if (app_name != NULL)
534  {
535  uint8_t len = (strlen (app_name) > MEMIF_NAME_LEN)
536  ? strlen (app_name) : MEMIF_NAME_LEN;
537  strncpy ((char *) lm->app_name, app_name, len);
538  }
539  else
540  {
541  strncpy ((char *) lm->app_name, MEMIF_DEFAULT_APP_NAME,
542  strlen (MEMIF_DEFAULT_APP_NAME));
543  }
544 
545  lm->poll_cancel_fd = -1;
546  /* register control fd update callback */
547  if (on_control_fd_update != NULL)
548  memif_control_fd_update_register (lm, on_control_fd_update);
549  else
550  {
551  lm->epfd = epoll_create (1);
553  if ((lm->poll_cancel_fd = eventfd (0, EFD_NONBLOCK)) < 0)
554  {
555  err = errno;
556  DBG ("eventfd: %s", strerror (err));
557  return memif_syscall_error_handler (err);
558  }
560  DBG ("libmemif event polling initialized");
561  }
562 
563  lm->control_list_len = 2;
564  lm->interrupt_list_len = 2;
565  lm->socket_list_len = 1;
566  lm->pending_list_len = 1;
567 
568  lm->control_list =
569  lm->alloc (sizeof (memif_list_elt_t) * lm->control_list_len);
570  if (lm->control_list == NULL)
571  {
572  err = MEMIF_ERR_NOMEM;
573  goto error;
574  }
575  lm->interrupt_list =
576  lm->alloc (sizeof (memif_list_elt_t) * lm->interrupt_list_len);
577  if (lm->interrupt_list == NULL)
578  {
579  err = MEMIF_ERR_NOMEM;
580  goto error;
581  }
582  lm->socket_list =
583  lm->alloc (sizeof (memif_list_elt_t) * lm->socket_list_len);
584  if (lm->socket_list == NULL)
585  {
586  err = MEMIF_ERR_NOMEM;
587  goto error;
588  }
589  lm->pending_list =
590  lm->alloc (sizeof (memif_list_elt_t) * lm->pending_list_len);
591  if (lm->pending_list == NULL)
592  {
593  err = MEMIF_ERR_NOMEM;
594  goto error;
595  }
596 
597  int i;
598  for (i = 0; i < lm->control_list_len; i++)
599  {
600  lm->control_list[i].key = -1;
601  lm->control_list[i].data_struct = NULL;
602  }
603  for (i = 0; i < lm->interrupt_list_len; i++)
604  {
605  lm->interrupt_list[i].key = -1;
606  lm->interrupt_list[i].data_struct = NULL;
607  }
608  for (i = 0; i < lm->socket_list_len; i++)
609  {
610  lm->socket_list[i].key = -1;
611  lm->socket_list[i].data_struct = NULL;
612  }
613  for (i = 0; i < lm->pending_list_len; i++)
614  {
615  lm->pending_list[i].key = -1;
616  lm->pending_list[i].data_struct = NULL;
617  }
618 
619  lm->disconn_slaves = 0;
620 
621  lm->timerfd = timerfd_create (CLOCK_REALTIME, TFD_NONBLOCK);
622  if (lm->timerfd < 0)
623  {
624  err = memif_syscall_error_handler (errno);
625  goto error;
626  }
627 
628  lm->arm.it_value.tv_sec = MEMIF_DEFAULT_RECONNECT_PERIOD_SEC;
629  lm->arm.it_value.tv_nsec = MEMIF_DEFAULT_RECONNECT_PERIOD_NSEC;
630  lm->arm.it_interval.tv_sec = MEMIF_DEFAULT_RECONNECT_PERIOD_SEC;
631  lm->arm.it_interval.tv_nsec = MEMIF_DEFAULT_RECONNECT_PERIOD_NSEC;
632 
634  {
635  DBG ("callback type memif_control_fd_update_t error!");
636  err = MEMIF_ERR_CB_FDUPDATE;
637  goto error;
638  }
639 
640  /* Create default socket */
642  lm->default_socket,
644  if (err != MEMIF_ERR_SUCCESS)
645  goto error;
646 
647  return err;
648 
649 error:
650  memif_cleanup ();
651  return err;
652 }
653 
654 int
656  void *private_ctx,
657  memif_control_fd_update_t * on_control_fd_update,
658  char *app_name, memif_alloc_t * memif_alloc,
659  memif_realloc_t * memif_realloc,
660  memif_free_t * memif_free)
661 {
663  int i;
664  libmemif_main_t *lm;
665 
666  /* Allocate unique libmemif main */
667  if (memif_alloc != NULL)
668  lm = memif_alloc (sizeof (libmemif_main_t));
669  else
670  lm = malloc (sizeof (libmemif_main_t));
671 
672  if (lm == NULL)
673  return MEMIF_ERR_NOMEM;
674 
675  memset (lm, 0, sizeof (libmemif_main_t));
676 
677  /* register custom memory management */
678  if (memif_alloc != NULL)
679  {
680  memif_alloc_register (lm, memif_alloc);
681  }
682  else
683  memif_alloc_register (lm, malloc);
684 
685  if (memif_realloc != NULL)
686  {
687  memif_realloc_register (lm, memif_realloc);
688  }
689  else
690  memif_realloc_register (lm, realloc);
691 
692  if (memif_free != NULL)
693  memif_free_register (lm, memif_free);
694  else
695  memif_free_register (lm, free);
696 
697  lm->private_ctx = private_ctx;
698 
699  /* set app name */
700  if (app_name != NULL)
701  {
702  uint8_t len = (strlen (app_name) > MEMIF_NAME_LEN)
703  ? strlen (app_name) : MEMIF_NAME_LEN;
704  strncpy ((char *) lm->app_name, app_name, len);
705  }
706  else
707  {
708  strncpy ((char *) lm->app_name, MEMIF_DEFAULT_APP_NAME,
709  strlen (MEMIF_DEFAULT_APP_NAME));
710  }
711 
712  lm->poll_cancel_fd = -1;
713  /* register control fd update callback */
714  if (on_control_fd_update != NULL)
715  memif_control_fd_update_register (lm, on_control_fd_update);
716  else
717  {
718  /* private_ctx only used internally by memif_control_fd_update
719  * pointer to this libmemif main
720  */
721  lm->private_ctx = lm;
722  lm->epfd = epoll_create (1);
724  if ((lm->poll_cancel_fd = eventfd (0, EFD_NONBLOCK)) < 0)
725  {
726  err = errno;
727  DBG ("eventfd: %s", strerror (err));
728  return memif_syscall_error_handler (err);
729  }
731  lm->private_ctx);
732  DBG ("libmemif event polling initialized");
733  }
734 
735  /* Initialize lists */
736  lm->control_list_len = 2;
737  lm->interrupt_list_len = 2;
738  lm->socket_list_len = 1;
739  lm->pending_list_len = 1;
740 
741  lm->control_list =
742  lm->alloc (sizeof (memif_list_elt_t) * lm->control_list_len);
743  if (lm->control_list == NULL)
744  {
745  err = MEMIF_ERR_NOMEM;
746  goto error;
747  }
748  lm->interrupt_list =
749  lm->alloc (sizeof (memif_list_elt_t) * lm->interrupt_list_len);
750  if (lm->interrupt_list == NULL)
751  {
752  err = MEMIF_ERR_NOMEM;
753  goto error;
754  }
755  lm->socket_list =
756  lm->alloc (sizeof (memif_list_elt_t) * lm->socket_list_len);
757  if (lm->socket_list == NULL)
758  {
759  err = MEMIF_ERR_NOMEM;
760  goto error;
761  }
762  lm->pending_list =
763  lm->alloc (sizeof (memif_list_elt_t) * lm->pending_list_len);
764  if (lm->pending_list == NULL)
765  {
766  err = MEMIF_ERR_NOMEM;
767  goto error;
768  }
769 
770  for (i = 0; i < lm->control_list_len; i++)
771  {
772  lm->control_list[i].key = -1;
773  lm->control_list[i].data_struct = NULL;
774  }
775  for (i = 0; i < lm->interrupt_list_len; i++)
776  {
777  lm->interrupt_list[i].key = -1;
778  lm->interrupt_list[i].data_struct = NULL;
779  }
780  for (i = 0; i < lm->socket_list_len; i++)
781  {
782  lm->socket_list[i].key = -1;
783  lm->socket_list[i].data_struct = NULL;
784  }
785  for (i = 0; i < lm->pending_list_len; i++)
786  {
787  lm->pending_list[i].key = -1;
788  lm->pending_list[i].data_struct = NULL;
789  }
790 
791  /* Initialize autoconnect */
792  lm->disconn_slaves = 0;
793 
794  lm->timerfd = timerfd_create (CLOCK_REALTIME, TFD_NONBLOCK);
795  if (lm->timerfd < 0)
796  {
797  err = memif_syscall_error_handler (errno);
798  goto error;
799  }
800 
801  lm->arm.it_value.tv_sec = MEMIF_DEFAULT_RECONNECT_PERIOD_SEC;
802  lm->arm.it_value.tv_nsec = MEMIF_DEFAULT_RECONNECT_PERIOD_NSEC;
803  lm->arm.it_interval.tv_sec = MEMIF_DEFAULT_RECONNECT_PERIOD_SEC;
804  lm->arm.it_interval.tv_nsec = MEMIF_DEFAULT_RECONNECT_PERIOD_NSEC;
805 
807  lm->private_ctx) < 0)
808  {
809  DBG ("callback type memif_control_fd_update_t error!");
810  err = MEMIF_ERR_CB_FDUPDATE;
811  goto error;
812  }
813 
814  *pt_main = lm;
815 
816  return err;
817 
818 error:
819  *pt_main = lm;
820  memif_per_thread_cleanup (pt_main);
821  return err;
822 }
823 
824 static inline memif_ring_t *
826  uint16_t ring_num)
827 {
828  if (&conn->regions[0] == NULL)
829  return NULL;
830  void *p = conn->regions[0].addr;
831  int ring_size =
832  sizeof (memif_ring_t) +
833  sizeof (memif_desc_t) * (1 << conn->run_args.log2_ring_size);
834  p += (ring_num + type * conn->run_args.num_s2m_rings) * ring_size;
835 
836  return (memif_ring_t *) p;
837 }
838 
839 int
841  uint16_t qid)
842 {
844  if (conn == NULL)
845  return MEMIF_ERR_NOCONN;
846  uint8_t num =
847  (conn->args.is_master) ? conn->run_args.num_s2m_rings : conn->
848  run_args.num_m2s_rings;
849  if (qid >= num)
850  return MEMIF_ERR_QID;
851 
852  conn->rx_queues[qid].ring->flags = rx_mode;
853  DBG ("rx_mode flag: %u", conn->rx_queues[qid].ring->flags);
854  return MEMIF_ERR_SUCCESS;
855 }
856 
857 static int
859 {
861  memif_list_elt_t elt;
862  struct stat file_stat;
863  struct sockaddr_un un = { 0 };
864  int on = 1;
865  int err = MEMIF_ERR_SUCCESS;
866 
867  if (ms->type == MEMIF_SOCKET_TYPE_CLIENT)
868  return MEMIF_ERR_INVAL_ARG;
869 
870  /* check if file exists */
871  if (stat ((char *) ms->filename, &file_stat) == 0)
872  {
873  if (S_ISSOCK (file_stat.st_mode))
874  unlink ((char *) ms->filename);
875  else
876  return memif_syscall_error_handler (errno);
877  }
878 
879  ms->fd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
880  if (ms->fd < 0)
881  {
882  err = memif_syscall_error_handler (errno);
883  goto error;
884  }
885 
886  DBG ("socket %d created", ms->fd);
887  un.sun_family = AF_UNIX;
888  strncpy ((char *) un.sun_path, (char *) ms->filename,
889  sizeof (un.sun_path) - 1);
890  if (setsockopt (ms->fd, SOL_SOCKET, SO_PASSCRED, &on, sizeof (on)) < 0)
891  {
892  err = memif_syscall_error_handler (errno);
893  goto error;
894  }
895  if (bind (ms->fd, (struct sockaddr *) &un, sizeof (un)) < 0)
896  {
897  err = memif_syscall_error_handler (errno);
898  goto error;
899  }
900  if (listen (ms->fd, 1) < 0)
901  {
902  err = memif_syscall_error_handler (errno);
903  goto error;
904  }
905  if (stat ((char *) ms->filename, &file_stat) < 0)
906  {
907  err = memif_syscall_error_handler (errno);
908  goto error;
909  }
910 
911  /* add socket to libmemif main */
912  elt.key = ms->fd;
913  elt.data_struct = ms;
914  add_list_elt (lm, &elt, &lm->socket_list, &lm->socket_list_len);
915  /* if lm->private_ctx == lm event polling is done by libmemif */
917 
919 
920  return err;
921 
922 error:
923  if (ms->fd > 0)
924  {
925  close (ms->fd);
926  ms->fd = -1;
927  }
928  return err;
929 }
930 
931 int
932 memif_create_socket (memif_socket_handle_t * sock, const char *filename,
933  void *private_ctx)
934 {
936  memif_socket_t *ms = (memif_socket_t *) * sock;
937  int i, err = MEMIF_ERR_SUCCESS;
938 
939  for (i = 0; i < lm->socket_list_len; i++)
940  {
941  if ((ms = (memif_socket_t *) lm->socket_list[i].data_struct) != NULL)
942  {
943  if (strncmp ((char *) ms->filename, filename,
944  strlen ((char *) ms->filename)) == 0)
945  return MEMIF_ERR_INVAL_ARG;
946  }
947  }
948 
949  /* allocate memif_socket_t */
950  ms = NULL;
951  ms = lm->alloc (sizeof (memif_socket_t));
952  if (ms == NULL)
953  {
954  err = MEMIF_ERR_NOMEM;
955  goto error;
956  }
957  memset (ms, 0, sizeof (memif_socket_t));
958  /* set filename */
959  ms->filename = lm->alloc (strlen (filename) + sizeof (char));
960  if (ms->filename == NULL)
961  {
962  err = MEMIF_ERR_NOMEM;
963  goto error;
964  }
965  memset (ms->filename, 0, strlen (filename) + sizeof (char));
966  strncpy ((char *) ms->filename, filename, strlen (filename));
967 
969 
970  ms->interface_list_len = 1;
971  ms->interface_list =
972  lm->alloc (sizeof (memif_list_elt_t) * ms->interface_list_len);
973  if (ms->interface_list == NULL)
974  {
975  err = MEMIF_ERR_NOMEM;
976  goto error;
977  }
978  ms->interface_list[0].key = -1;
979  ms->interface_list[0].data_struct = NULL;
980 
981  *sock = ms;
982 
983  return err;
984 
985 error:
986  if (ms != NULL)
987  {
988  if (ms->filename != NULL)
989  {
990  lm->free (ms->filename);
991  ms->filename = NULL;
992  }
993  if (ms->fd > 0)
994  {
995  close (ms->fd);
996  ms->fd = -1;
997  }
998  if (ms->interface_list != NULL)
999  {
1000  lm->free (ms->interface_list);
1001  ms->interface_list = NULL;
1002  ms->interface_list_len = 0;
1003  }
1004  lm->free (ms);
1005  *sock = ms = NULL;
1006  }
1007  return err;
1008 }
1009 
1010 int
1012  memif_socket_handle_t * sock,
1013  const char *filename, void *private_ctx)
1014 {
1015  libmemif_main_t *lm = (libmemif_main_t *) pt_main;
1016  memif_socket_t *ms = (memif_socket_t *) * sock;
1017  int i, err = MEMIF_ERR_SUCCESS;
1018 
1019  if (lm == NULL)
1020  return MEMIF_ERR_INVAL_ARG;
1021 
1022  for (i = 0; i < lm->socket_list_len; i++)
1023  {
1024  if ((ms = (memif_socket_t *) lm->socket_list[i].data_struct) != NULL)
1025  {
1026  if (strncmp ((char *) ms->filename, filename,
1027  strlen ((char *) ms->filename)) == 0)
1028  return MEMIF_ERR_INVAL_ARG;
1029  }
1030  }
1031 
1032  /* allocate memif_socket_t */
1033  ms = NULL;
1034  ms = lm->alloc (sizeof (memif_socket_t));
1035  if (ms == NULL)
1036  {
1037  err = MEMIF_ERR_NOMEM;
1038  goto error;
1039  }
1040  memset (ms, 0, sizeof (memif_socket_t));
1041  ms->lm = lm;
1042  /* set filename */
1043  ms->filename = lm->alloc (strlen (filename) + sizeof (char));
1044  if (ms->filename == NULL)
1045  {
1046  err = MEMIF_ERR_NOMEM;
1047  goto error;
1048  }
1049  memset (ms->filename, 0, strlen (filename) + sizeof (char));
1050  strncpy ((char *) ms->filename, filename, strlen (filename));
1051 
1053 
1054  ms->interface_list_len = 1;
1055  ms->interface_list =
1056  lm->alloc (sizeof (memif_list_elt_t) * ms->interface_list_len);
1057  if (ms->interface_list == NULL)
1058  {
1059  err = MEMIF_ERR_NOMEM;
1060  goto error;
1061  }
1062  ms->interface_list[0].key = -1;
1063  ms->interface_list[0].data_struct = NULL;
1064 
1065  *sock = ms;
1066 
1067  return err;
1068 
1069 error:
1070  if (ms != NULL)
1071  {
1072  if (ms->filename != NULL)
1073  {
1074  lm->free (ms->filename);
1075  ms->filename = NULL;
1076  }
1077  if (ms->fd > 0)
1078  {
1079  close (ms->fd);
1080  ms->fd = -1;
1081  }
1082  if (ms->interface_list != NULL)
1083  {
1084  lm->free (ms->interface_list);
1085  ms->interface_list = NULL;
1086  ms->interface_list_len = 0;
1087  }
1088  lm->free (ms);
1089  *sock = ms = NULL;
1090  }
1091  return err;
1092 }
1093 
1094 int
1098  memif_interrupt_t * on_interrupt, void *private_ctx)
1099 {
1101  int err, index = 0;
1102  memif_list_elt_t elt;
1103  memif_connection_t *conn = (memif_connection_t *) * c;
1104  memif_socket_t *ms;
1105 
1106  if (conn != NULL)
1107  {
1108  DBG ("This handle already points to existing memif.");
1109  return MEMIF_ERR_CONN;
1110  }
1111 
1112  conn = (memif_connection_t *) lm->alloc (sizeof (memif_connection_t));
1113  if (conn == NULL)
1114  {
1115  err = MEMIF_ERR_NOMEM;
1116  goto error;
1117  }
1118  memset (conn, 0, sizeof (memif_connection_t));
1119 
1120  conn->args.interface_id = args->interface_id;
1121 
1122  if (args->log2_ring_size == 0)
1124  else if (args->log2_ring_size > MEMIF_MAX_LOG2_RING_SIZE)
1125  {
1126  err = MEMIF_ERR_MAX_RING;
1127  goto error;
1128  }
1129  if (args->buffer_size == 0)
1131  if (args->num_s2m_rings == 0)
1133  if (args->num_m2s_rings == 0)
1135 
1136  conn->args.num_s2m_rings = args->num_s2m_rings;
1137  conn->args.num_m2s_rings = args->num_m2s_rings;
1138  conn->args.buffer_size = args->buffer_size;
1139  conn->args.log2_ring_size = args->log2_ring_size;
1140  conn->args.is_master = args->is_master;
1141  conn->args.mode = args->mode;
1142  conn->msg_queue = NULL;
1143  conn->regions = NULL;
1144  conn->tx_queues = NULL;
1145  conn->rx_queues = NULL;
1146  conn->fd = -1;
1147  conn->on_connect = on_connect;
1148  conn->on_disconnect = on_disconnect;
1149  conn->on_interrupt = on_interrupt;
1150  conn->private_ctx = private_ctx;
1151  memset (&conn->run_args, 0, sizeof (memif_conn_run_args_t));
1152 
1153  uint8_t l = strlen ((char *) args->interface_name);
1154  strncpy ((char *) conn->args.interface_name, (char *) args->interface_name,
1155  l);
1156 
1157  if ((l = strlen ((char *) args->secret)) > 0)
1158  strncpy ((char *) conn->args.secret, (char *) args->secret, l);
1159 
1160  if (args->socket != NULL)
1161  conn->args.socket = args->socket;
1162  else if (lm->default_socket != NULL)
1163  conn->args.socket = lm->default_socket;
1164  else
1165  {
1166  err = MEMIF_ERR_INVAL_ARG;
1167  goto error;
1168  }
1169 
1170  ms = (memif_socket_t *) conn->args.socket;
1171 
1172  if ((conn->args.is_master && ms->type == MEMIF_SOCKET_TYPE_CLIENT) ||
1173  (!conn->args.is_master && ms->type == MEMIF_SOCKET_TYPE_LISTENER))
1174  {
1175  err = MEMIF_ERR_INVAL_ARG;
1176  goto error;
1177  }
1178 
1179  elt.key = conn->args.interface_id;
1180  elt.data_struct = conn;
1181  add_list_elt (lm, &elt, &ms->interface_list, &ms->interface_list_len);
1182  ms->use_count++;
1183 
1184  if (conn->args.is_master)
1185  {
1186  if (ms->type == MEMIF_SOCKET_TYPE_NONE)
1187  {
1188  err = memif_socket_start_listening (ms);
1189  if (err != MEMIF_ERR_SUCCESS)
1190  goto error;
1191  }
1192  }
1193  else
1194  {
1195  elt.key = -1;
1196  elt.data_struct = conn;
1197  if ((index =
1198  add_list_elt (lm, &elt, &lm->control_list,
1199  &lm->control_list_len)) < 0)
1200  {
1201  err = MEMIF_ERR_NOMEM;
1202  goto error;
1203  }
1204 
1205  conn->index = index;
1206 
1207  /* try connectiong to master */
1208  err = memif_request_connection (conn);
1209  if ((err != MEMIF_ERR_SUCCESS) && (lm->disconn_slaves == 0))
1210  {
1211  /* connection failed, arm reconnect timer (if not armed) */
1212  if (timerfd_settime (lm->timerfd, 0, &lm->arm, NULL) < 0)
1213  {
1214  err = memif_syscall_error_handler (errno);
1215  goto error;
1216  }
1217  }
1218  lm->disconn_slaves++;
1219  }
1220 
1221  *c = conn;
1222 
1223  return 0;
1224 
1225 error:
1226  if (conn != NULL)
1227  lm->free (conn);
1228  *c = conn = NULL;
1229  return err;
1230 }
1231 
1232 int
1234 {
1235  memif_connection_t *conn = (memif_connection_t *) c;
1236  libmemif_main_t *lm;
1237  memif_socket_t *ms;
1238  int err = MEMIF_ERR_SUCCESS;
1239  int sockfd = -1;
1240  struct sockaddr_un sun;
1241 
1242  if (conn == NULL)
1243  return MEMIF_ERR_NOCONN;
1244 
1245  ms = (memif_socket_t *) conn->args.socket;
1246  lm = get_libmemif_main (ms);
1247 
1248 
1249  if (conn->args.is_master || ms->type == MEMIF_SOCKET_TYPE_LISTENER)
1250  return MEMIF_ERR_INVAL_ARG;
1251  if (conn->fd > 0)
1252  return MEMIF_ERR_ALRCONN;
1253 
1254  sockfd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
1255  if (sockfd < 0)
1256  {
1257  err = memif_syscall_error_handler (errno);
1258  goto error;
1259  }
1260 
1261  sun.sun_family = AF_UNIX;
1262 
1263  strncpy (sun.sun_path, (char *) ms->filename, sizeof (sun.sun_path) - 1);
1264 
1265  if (connect (sockfd, (struct sockaddr *) &sun,
1266  sizeof (struct sockaddr_un)) == 0)
1267  {
1268  conn->fd = sockfd;
1269  conn->read_fn = memif_conn_fd_read_ready;
1270  conn->write_fn = memif_conn_fd_write_ready;
1271  conn->error_fn = memif_conn_fd_error;
1272 
1273  lm->control_list[conn->index].key = conn->fd;
1274  lm->control_fd_update (sockfd,
1277 
1278  lm->disconn_slaves--;
1279  if (lm->disconn_slaves == 0)
1280  {
1281  if (timerfd_settime (lm->timerfd, 0, &lm->disarm, NULL) < 0)
1282  {
1283  err = memif_syscall_error_handler (errno);
1284  return err;
1285  }
1286  }
1287  }
1288  else
1289  {
1290  err = memif_syscall_error_handler (errno);
1291  strcpy ((char *) conn->remote_disconnect_string, memif_strerror (err));
1292  goto error;
1293  }
1294 
1296 
1297  return err;
1298 
1299 error:
1300  if (sockfd > 0)
1301  close (sockfd);
1302  sockfd = -1;
1303  return err;
1304 }
1305 
1306 int
1307 memif_control_fd_handler (int fd, uint8_t events)
1308 {
1309  int i, err = MEMIF_ERR_SUCCESS; /* 0 */
1310  uint16_t num;
1311  memif_list_elt_t *e = NULL;
1312  memif_connection_t *conn;
1314  if (fd == lm->timerfd)
1315  {
1316  uint64_t b;
1317  ssize_t size;
1318  size = read (fd, &b, sizeof (b));
1319 
1320  if (size == -1)
1321  goto error;
1322 
1323  for (i = 0; i < lm->control_list_len; i++)
1324  {
1325  if ((lm->control_list[i].key < 0)
1326  && (lm->control_list[i].data_struct != NULL))
1327  {
1328  conn = lm->control_list[i].data_struct;
1329  if (conn->args.is_master)
1330  continue;
1331  err = memif_request_connection (conn);
1332  if (err != MEMIF_ERR_SUCCESS)
1333  DBG ("memif_request_connection: %s", memif_strerror (err));
1334  }
1335  }
1336  }
1337  else
1338  {
1339  get_list_elt (&e, lm->interrupt_list, lm->interrupt_list_len, fd);
1340  if (e != NULL)
1341  {
1342  if (((memif_connection_t *) e->data_struct)->on_interrupt != NULL)
1343  {
1344  num =
1345  (((memif_connection_t *) e->data_struct)->
1346  args.is_master) ? ((memif_connection_t *) e->
1347  data_struct)->run_args.
1348  num_s2m_rings : ((memif_connection_t *) e->data_struct)->
1349  run_args.num_m2s_rings;
1350  for (i = 0; i < num; i++)
1351  {
1352  if (((memif_connection_t *) e->data_struct)->
1353  rx_queues[i].int_fd == fd)
1354  {
1355  ((memif_connection_t *) e->data_struct)->
1356  on_interrupt ((void *) e->data_struct,
1357  ((memif_connection_t *) e->
1358  data_struct)->private_ctx, i);
1359  return MEMIF_ERR_SUCCESS;
1360  }
1361  }
1362  }
1363  return MEMIF_ERR_SUCCESS;
1364  }
1365  get_list_elt (&e, lm->socket_list, lm->socket_list_len, fd);
1366  if (e != NULL
1367  && ((memif_socket_t *) e->data_struct)->type ==
1369  {
1370  err =
1372  return err;
1373  }
1374 
1375  get_list_elt (&e, lm->pending_list, lm->pending_list_len, fd);
1376  if (e != NULL)
1377  {
1378  err = memif_read_ready (lm, fd);
1379  return err;
1380  }
1381 
1382  get_list_elt (&e, lm->control_list, lm->control_list_len, fd);
1383  if (e != NULL)
1384  {
1385  if (events & MEMIF_FD_EVENT_READ)
1386  {
1387  err =
1388  ((memif_connection_t *) e->data_struct)->
1389  read_fn (e->data_struct);
1390  if (err != MEMIF_ERR_SUCCESS)
1391  return err;
1392  }
1393  if (events & MEMIF_FD_EVENT_WRITE)
1394  {
1395  err =
1396  ((memif_connection_t *) e->data_struct)->
1397  write_fn (e->data_struct);
1398  if (err != MEMIF_ERR_SUCCESS)
1399  return err;
1400  }
1401  if (events & MEMIF_FD_EVENT_ERROR)
1402  {
1403  err =
1404  ((memif_connection_t *) e->data_struct)->
1405  error_fn (e->data_struct);
1406  if (err != MEMIF_ERR_SUCCESS)
1407  return err;
1408  }
1409  }
1410  }
1411 
1412  return MEMIF_ERR_SUCCESS; /* 0 */
1413 
1414 error:
1415  return err;
1416 }
1417 
1418 int
1420  int fd, uint8_t events)
1421 {
1422  int i, err = MEMIF_ERR_SUCCESS; /* 0 */
1423  uint16_t num;
1424  memif_list_elt_t *e = NULL;
1425  memif_connection_t *conn;
1426  libmemif_main_t *lm = (libmemif_main_t *) pt_main;
1427 
1428  if (fd == lm->timerfd)
1429  {
1430  uint64_t b;
1431  ssize_t size;
1432  size = read (fd, &b, sizeof (b));
1433 
1434  if (size == -1)
1435  goto error;
1436 
1437  for (i = 0; i < lm->control_list_len; i++)
1438  {
1439  if ((lm->control_list[i].key < 0)
1440  && (lm->control_list[i].data_struct != NULL))
1441  {
1442  conn = lm->control_list[i].data_struct;
1443  if (conn->args.is_master)
1444  continue;
1445  err = memif_request_connection (conn);
1446  if (err != MEMIF_ERR_SUCCESS)
1447  DBG ("memif_request_connection: %s", memif_strerror (err));
1448  }
1449  }
1450  }
1451  else
1452  {
1453  get_list_elt (&e, lm->interrupt_list, lm->interrupt_list_len, fd);
1454  if (e != NULL)
1455  {
1456  if (((memif_connection_t *) e->data_struct)->on_interrupt != NULL)
1457  {
1458  num =
1459  (((memif_connection_t *) e->data_struct)->
1460  args.is_master) ? ((memif_connection_t *) e->
1461  data_struct)->run_args.
1462  num_s2m_rings : ((memif_connection_t *) e->data_struct)->
1463  run_args.num_m2s_rings;
1464  for (i = 0; i < num; i++)
1465  {
1466  if (((memif_connection_t *) e->data_struct)->
1467  rx_queues[i].int_fd == fd)
1468  {
1469  ((memif_connection_t *) e->data_struct)->
1470  on_interrupt ((void *) e->data_struct,
1471  ((memif_connection_t *) e->
1472  data_struct)->private_ctx, i);
1473  return MEMIF_ERR_SUCCESS;
1474  }
1475  }
1476  }
1477  return MEMIF_ERR_SUCCESS;
1478  }
1479  get_list_elt (&e, lm->socket_list, lm->socket_list_len, fd);
1480  if (e != NULL
1481  && ((memif_socket_t *) e->data_struct)->type ==
1483  {
1484  err =
1486  return err;
1487  }
1488 
1489  get_list_elt (&e, lm->pending_list, lm->pending_list_len, fd);
1490  if (e != NULL)
1491  {
1492  err = memif_read_ready (lm, fd);
1493  return err;
1494  }
1495 
1496  get_list_elt (&e, lm->control_list, lm->control_list_len, fd);
1497  if (e != NULL)
1498  {
1499  if (events & MEMIF_FD_EVENT_READ)
1500  {
1501  err =
1502  ((memif_connection_t *) e->data_struct)->
1503  read_fn (e->data_struct);
1504  if (err != MEMIF_ERR_SUCCESS)
1505  return err;
1506  }
1507  if (events & MEMIF_FD_EVENT_WRITE)
1508  {
1509  err =
1510  ((memif_connection_t *) e->data_struct)->
1511  write_fn (e->data_struct);
1512  if (err != MEMIF_ERR_SUCCESS)
1513  return err;
1514  }
1515  if (events & MEMIF_FD_EVENT_ERROR)
1516  {
1517  err =
1518  ((memif_connection_t *) e->data_struct)->
1519  error_fn (e->data_struct);
1520  if (err != MEMIF_ERR_SUCCESS)
1521  return err;
1522  }
1523  }
1524  }
1525 
1526  return MEMIF_ERR_SUCCESS; /* 0 */
1527 
1528 error:
1529  return err;
1530 }
1531 
1532 int
1533 memif_poll_event (int timeout)
1534 {
1536  struct epoll_event evt;
1537  int en = 0, err = MEMIF_ERR_SUCCESS; /* 0 */
1538  uint32_t events = 0;
1539  uint64_t counter = 0;
1540  ssize_t r = 0;
1541  memset (&evt, 0, sizeof (evt));
1542  evt.events = EPOLLIN | EPOLLOUT;
1543  sigset_t sigset;
1544  sigemptyset (&sigset);
1545  en = epoll_pwait (lm->epfd, &evt, 1, timeout, &sigset);
1546  if (en < 0)
1547  {
1548  err = errno;
1549  DBG ("epoll_pwait: %s", strerror (err));
1550  return memif_syscall_error_handler (err);
1551  }
1552  if (en > 0)
1553  {
1554  if (evt.data.fd == lm->poll_cancel_fd)
1555  {
1556  r = read (evt.data.fd, &counter, sizeof (counter));
1557  if (r == -1)
1558  return MEMIF_ERR_DISCONNECTED;
1559 
1560  return MEMIF_ERR_POLL_CANCEL;
1561  }
1562  if (evt.events & EPOLLIN)
1563  events |= MEMIF_FD_EVENT_READ;
1564  if (evt.events & EPOLLOUT)
1565  events |= MEMIF_FD_EVENT_WRITE;
1566  if (evt.events & EPOLLERR)
1567  events |= MEMIF_FD_EVENT_ERROR;
1568  err = memif_control_fd_handler (evt.data.fd, events);
1569  return err;
1570  }
1571  return 0;
1572 }
1573 
1574 int
1576  int timeout)
1577 {
1578  libmemif_main_t *lm = (libmemif_main_t *) pt_main;
1579  struct epoll_event evt;
1580  int en = 0, err = MEMIF_ERR_SUCCESS; /* 0 */
1581  uint32_t events = 0;
1582  uint64_t counter = 0;
1583  ssize_t r = 0;
1584  memset (&evt, 0, sizeof (evt));
1585  evt.events = EPOLLIN | EPOLLOUT;
1586  sigset_t sigset;
1587  sigemptyset (&sigset);
1588  en = epoll_pwait (lm->epfd, &evt, 1, timeout, &sigset);
1589  if (en < 0)
1590  {
1591  err = errno;
1592  DBG ("epoll_pwait: %s", strerror (err));
1593  return memif_syscall_error_handler (err);
1594  }
1595  if (en > 0)
1596  {
1597  if (evt.data.fd == lm->poll_cancel_fd)
1598  {
1599  r = read (evt.data.fd, &counter, sizeof (counter));
1600  if (r == -1)
1601  return MEMIF_ERR_DISCONNECTED;
1602 
1603  return MEMIF_ERR_POLL_CANCEL;
1604  }
1605  if (evt.events & EPOLLIN)
1606  events |= MEMIF_FD_EVENT_READ;
1607  if (evt.events & EPOLLOUT)
1608  events |= MEMIF_FD_EVENT_WRITE;
1609  if (evt.events & EPOLLERR)
1610  events |= MEMIF_FD_EVENT_ERROR;
1611  err = memif_control_fd_handler (evt.data.fd, events);
1612  return err;
1613  }
1614  return 0;
1615 }
1616 
1617 int
1619 {
1621  uint64_t counter = 1;
1622  ssize_t w = 0;
1623 
1624  if (lm->poll_cancel_fd == -1)
1625  return 0;
1626  w = write (lm->poll_cancel_fd, &counter, sizeof (counter));
1627  if (w < sizeof (counter))
1628  return MEMIF_ERR_INT_WRITE;
1629 
1630  return 0;
1631 }
1632 
1633 int
1635 {
1636  libmemif_main_t *lm = (libmemif_main_t *) pt_main;
1637  uint64_t counter = 1;
1638  ssize_t w = 0;
1639 
1640  if (lm == NULL)
1641  return MEMIF_ERR_INVAL_ARG;
1642 
1643  if (lm->poll_cancel_fd == -1)
1644  return 0;
1645  w = write (lm->poll_cancel_fd, &counter, sizeof (counter));
1646  if (w < sizeof (counter))
1647  return MEMIF_ERR_INT_WRITE;
1648 
1649  return 0;
1650 }
1651 
1652 static void
1654 {
1655  if (*e == NULL)
1656  return;
1657  memif_msg_queue_free (lm, &(*e)->next);
1658  lm->free (*e);
1659  *e = NULL;
1660  return;
1661 }
1662 
1663 /* send disconnect msg and close interface */
1664 int
1666 {
1667  int err = MEMIF_ERR_SUCCESS, i; /* 0 */
1668  memif_queue_t *mq;
1669  libmemif_main_t *lm;
1670  memif_list_elt_t *e;
1671 
1672  if (c == NULL)
1673  {
1674  DBG ("no connection");
1675  return MEMIF_ERR_NOCONN;
1676  }
1677 
1678  lm = get_libmemif_main (c->args.socket);
1679 
1680  c->on_disconnect ((void *) c, c->private_ctx);
1681 
1682  if (c->fd > 0)
1683  {
1684  memif_msg_send_disconnect (c->fd, (uint8_t *) "interface deleted", 0);
1686  close (c->fd);
1687  }
1688  get_list_elt (&e, lm->control_list, lm->control_list_len, c->fd);
1689  if (e != NULL)
1690  {
1691  if (c->args.is_master)
1692  free_list_elt (lm->control_list, lm->control_list_len, c->fd);
1693  e->key = c->fd = -1;
1694  }
1695 
1696  if (c->tx_queues != NULL)
1697  {
1698  for (i = 0; i < c->tx_queues_num; i++)
1699  {
1700  mq = &c->tx_queues[i];
1701  if (mq != NULL)
1702  {
1703  if (mq->int_fd > 0)
1704  close (mq->int_fd);
1706  mq->int_fd);
1707  mq->int_fd = -1;
1708  }
1709  }
1710  lm->free (c->tx_queues);
1711  c->tx_queues = NULL;
1712  }
1713  c->tx_queues_num = 0;
1714 
1715  if (c->rx_queues != NULL)
1716  {
1717  for (i = 0; i < c->rx_queues_num; i++)
1718  {
1719  mq = &c->rx_queues[i];
1720  if (mq != NULL)
1721  {
1722  if (mq->int_fd > 0)
1723  {
1724  if (c->on_interrupt != NULL)
1726  lm->private_ctx);
1727  close (mq->int_fd);
1728  }
1730  mq->int_fd);
1731  mq->int_fd = -1;
1732  }
1733  }
1734  lm->free (c->rx_queues);
1735  c->rx_queues = NULL;
1736  }
1737  c->rx_queues_num = 0;
1738 
1739  for (i = 0; i < c->regions_num; i++)
1740  {
1741  if (&c->regions[i] == NULL)
1742  continue;
1743  if (c->regions[i].is_external != 0)
1744  {
1745  lm->del_external_region (c->regions[i].addr,
1746  c->regions[i].region_size,
1747  c->regions[i].fd, c->private_ctx);
1748  }
1749  else
1750  {
1751  if (munmap (c->regions[i].addr, c->regions[i].region_size) < 0)
1752  return memif_syscall_error_handler (errno);
1753  if (c->regions[i].fd > 0)
1754  close (c->regions[i].fd);
1755  c->regions[i].fd = -1;
1756  }
1757  }
1758  lm->free (c->regions);
1759  c->regions = NULL;
1760  c->regions_num = 0;
1761 
1762  memset (&c->run_args, 0, sizeof (memif_conn_run_args_t));
1763 
1764  memif_msg_queue_free (lm, &c->msg_queue);
1765 
1766  if (!(c->args.is_master))
1767  {
1768  if (lm->disconn_slaves == 0)
1769  {
1770  if (timerfd_settime (lm->timerfd, 0, &lm->arm, NULL) < 0)
1771  {
1772  err = memif_syscall_error_handler (errno);
1773  DBG ("timerfd_settime: arm");
1774  }
1775  }
1776  lm->disconn_slaves++;
1777  }
1778 
1779  return err;
1780 }
1781 
1782 const char *
1784 {
1785  memif_socket_t *ms = (memif_socket_t *) sock;
1786 
1787  if (ms == NULL)
1788  return NULL;
1789 
1790  return (char *) ms->filename;
1791 }
1792 
1793 int
1795 {
1796  memif_socket_t *ms = (memif_socket_t *) * sock;
1797  libmemif_main_t *lm;
1798 
1799  /* check if socket is in use */
1800  if (ms == NULL || ms->use_count > 0)
1801  return MEMIF_ERR_INVAL_ARG;
1802 
1803  lm = get_libmemif_main (ms);
1804 
1805  lm->free (ms->interface_list);
1806  ms->interface_list = NULL;
1807  lm->free (ms->filename);
1808  ms->filename = NULL;
1809  lm->free (ms);
1810  *sock = ms = NULL;
1811 
1812  return MEMIF_ERR_SUCCESS;
1813 }
1814 
1815 int
1817 {
1818  memif_connection_t *c = (memif_connection_t *) * conn;
1819  libmemif_main_t *lm;
1820  memif_socket_t *ms = NULL;
1821  int err = MEMIF_ERR_SUCCESS;
1822 
1823  if (c == NULL)
1824  {
1825  DBG ("no connection");
1826  return MEMIF_ERR_NOCONN;
1827  }
1828 
1829  if (c->fd > 0)
1830  {
1831  DBG ("DISCONNECTING");
1832  err = memif_disconnect_internal (c);
1833  if (err == MEMIF_ERR_NOCONN)
1834  return err;
1835  }
1836 
1837  lm = get_libmemif_main (c->args.socket);
1838 
1840 
1841  ms = (memif_socket_t *) c->args.socket;
1842  ms->use_count--;
1844  c->args.interface_id);
1845  if (ms->use_count <= 0)
1846  {
1847  /* stop listening on this socket */
1848  if (ms->type == MEMIF_SOCKET_TYPE_LISTENER)
1849  {
1851  free_list_elt (lm->socket_list, lm->socket_list_len, ms->fd);
1852  close (ms->fd);
1853  ms->fd = -1;
1854  }
1855  /* socket not in use */
1857  }
1858 
1859  if (!c->args.is_master)
1860  {
1861  lm->disconn_slaves--;
1862  if (lm->disconn_slaves <= 0)
1863  {
1864  if (timerfd_settime (lm->timerfd, 0, &lm->disarm, NULL) < 0)
1865  {
1866  err = memif_syscall_error_handler (errno);
1867  DBG ("timerfd_settime: disarm");
1868  }
1869  }
1870  }
1871 
1872  lm->free (c);
1873  c = NULL;
1874 
1875  *conn = c;
1876  return err;
1877 }
1878 
1879 int
1881 {
1882  libmemif_main_t *lm;
1883  memif_region_t *mr;
1884  memif_queue_t *mq;
1885  int i;
1886 
1887  if (c == NULL)
1888  return MEMIF_ERR_INVAL_ARG;
1889 
1890  lm = get_libmemif_main (c->args.socket);
1891 
1892  for (i = 0; i < c->regions_num; i++)
1893  {
1894  mr = &c->regions[i];
1895  if (mr != NULL)
1896  {
1897  if (!mr->addr)
1898  {
1899  if (mr->is_external)
1900  {
1901  if (lm->get_external_region_addr == NULL)
1902  return MEMIF_ERR_INVAL_ARG;
1903  mr->addr =
1904  lm->get_external_region_addr (mr->region_size, mr->fd,
1905  c->private_ctx);
1906  }
1907  else
1908  {
1909  if (mr->fd < 0)
1910  return MEMIF_ERR_NO_SHMFD;
1911 
1912  if ((mr->addr =
1913  mmap (NULL, mr->region_size, PROT_READ | PROT_WRITE,
1914  MAP_SHARED, mr->fd, 0)) == MAP_FAILED)
1915  {
1916  return memif_syscall_error_handler (errno);
1917  }
1918  }
1919  }
1920  }
1921  }
1922 
1923  for (i = 0; i < c->rx_queues_num; i++)
1924  {
1925  mq = &c->rx_queues[i];
1926  if (mq != NULL)
1927  {
1928  mq->ring = c->regions[mq->region].addr + mq->offset;
1929  if (mq->ring->cookie != MEMIF_COOKIE)
1930  {
1931  DBG ("wrong cookie on rx ring %u", i);
1932  return MEMIF_ERR_COOKIE;
1933  }
1934  mq->ring->head = mq->ring->tail = mq->last_head = mq->alloc_bufs =
1935  0;
1936  }
1937  }
1938 
1939  for (i = 0; i < c->tx_queues_num; i++)
1940  {
1941  mq = &c->tx_queues[i];
1942  if (mq != NULL)
1943  {
1944  mq->ring = c->regions[mq->region].addr + mq->offset;
1945  if (mq->ring->cookie != MEMIF_COOKIE)
1946  {
1947  DBG ("wrong cookie on tx ring %u", i);
1948  return MEMIF_ERR_COOKIE;
1949  }
1950  mq->ring->head = mq->ring->tail = mq->last_head = mq->alloc_bufs =
1951  0;
1952  }
1953  }
1954 
1956  lm->private_ctx);
1957 
1958  return 0;
1959 }
1960 
1961 static inline int
1963  uint8_t has_buffers)
1964 {
1965  memif_region_t *r;
1966 
1967  r =
1968  lm->realloc (conn->regions,
1969  sizeof (memif_region_t) * ++conn->regions_num);
1970  if (r == NULL)
1971  return MEMIF_ERR_NOMEM;
1972 
1973  conn->regions = r;
1974  r = &conn->regions[conn->regions_num - 1];
1975  memset (r, 0, sizeof (memif_region_t));
1976 
1977  if (has_buffers != 0)
1978  {
1979  r->buffer_offset = 0;
1980  }
1981  else
1982  {
1983  r->buffer_offset =
1984  (conn->run_args.num_s2m_rings +
1985  conn->run_args.num_m2s_rings) * (sizeof (memif_ring_t) +
1986  sizeof (memif_desc_t) *
1987  (1 << conn->
1988  run_args.log2_ring_size));
1989  }
1990 
1991  r->region_size = (has_buffers == 0) ? r->buffer_offset : r->buffer_offset +
1992  conn->run_args.buffer_size * (1 << conn->run_args.log2_ring_size) *
1993  (conn->run_args.num_s2m_rings + conn->run_args.num_m2s_rings);
1994 
1995  if ((r->fd = memfd_create ("memif region 0", MFD_ALLOW_SEALING)) == -1)
1996  return memif_syscall_error_handler (errno);
1997 
1998  if ((fcntl (r->fd, F_ADD_SEALS, F_SEAL_SHRINK)) == -1)
1999  return memif_syscall_error_handler (errno);
2000 
2001  if ((ftruncate (r->fd, r->region_size)) == -1)
2002  return memif_syscall_error_handler (errno);
2003 
2004  if ((r->addr = mmap (NULL, r->region_size, PROT_READ | PROT_WRITE,
2005  MAP_SHARED, r->fd, 0)) == MAP_FAILED)
2006  return memif_syscall_error_handler (errno);
2007 
2008  return MEMIF_ERR_SUCCESS;
2009 }
2010 
2011 static inline int
2013 {
2014  int i, j;
2015  memif_ring_t *ring;
2016 
2017  for (i = 0; i < conn->run_args.num_s2m_rings; i++)
2018  {
2019  ring = memif_get_ring (conn, MEMIF_RING_S2M, i);
2020  DBG ("RING: %p I: %d", ring, i);
2021  ring->head = ring->tail = 0;
2022  ring->cookie = MEMIF_COOKIE;
2023  ring->flags = 0;
2024  for (j = 0; j < (1 << conn->run_args.log2_ring_size); j++)
2025  {
2026  uint16_t slot = i * (1 << conn->run_args.log2_ring_size) + j;
2027  ring->desc[j].region = 1;
2028  ring->desc[j].offset =
2029  conn->regions[1].buffer_offset +
2030  (uint32_t) (slot * conn->run_args.buffer_size);
2031  ring->desc[j].length = conn->run_args.buffer_size;
2032  }
2033  }
2034  for (i = 0; i < conn->run_args.num_m2s_rings; i++)
2035  {
2036  ring = memif_get_ring (conn, MEMIF_RING_M2S, i);
2037  DBG ("RING: %p I: %d", ring, i);
2038  ring->head = ring->tail = 0;
2039  ring->cookie = MEMIF_COOKIE;
2040  ring->flags = 0;
2041  for (j = 0; j < (1 << conn->run_args.log2_ring_size); j++)
2042  {
2043  uint16_t slot = (i + conn->run_args.num_s2m_rings) *
2044  (1 << conn->run_args.log2_ring_size) + j;
2045  ring->desc[j].region = 1;
2046  ring->desc[j].offset =
2047  conn->regions[1].buffer_offset +
2048  (uint32_t) (slot * conn->run_args.buffer_size);
2049  ring->desc[j].length = conn->run_args.buffer_size;
2050  }
2051  }
2052  memif_queue_t *mq;
2053  DBG ("alloc: %p", lm->alloc);
2054  DBG ("size: %lu", sizeof (memif_queue_t) * conn->run_args.num_s2m_rings);
2055  mq =
2056  (memif_queue_t *) lm->alloc (sizeof (memif_queue_t) *
2057  conn->run_args.num_s2m_rings);
2058  if (mq == NULL)
2059  return MEMIF_ERR_NOMEM;
2060 
2061  int x;
2062  memif_list_elt_t e;
2063  for (x = 0; x < conn->run_args.num_s2m_rings; x++)
2064  {
2065  if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
2066  return memif_syscall_error_handler (errno);
2067  e.key = mq[x].int_fd;
2068  e.data_struct = conn;
2069  add_list_elt (lm, &e, &lm->interrupt_list, &lm->interrupt_list_len);
2070 
2071  mq[x].ring = memif_get_ring (conn, MEMIF_RING_S2M, x);
2072  DBG ("RING: %p I: %d", mq[x].ring, x);
2073  mq[x].log2_ring_size = conn->run_args.log2_ring_size;
2074  mq[x].region = 0;
2075  mq[x].offset =
2076  (void *) mq[x].ring - (void *) conn->regions[mq->region].addr;
2077  mq[x].last_head = mq[x].last_tail = 0;
2078  mq[x].alloc_bufs = 0;
2079  }
2080  conn->tx_queues = mq;
2081  conn->tx_queues_num = conn->run_args.num_s2m_rings;
2082 
2083  mq =
2084  (memif_queue_t *) lm->alloc (sizeof (memif_queue_t) *
2085  conn->run_args.num_m2s_rings);
2086  if (mq == NULL)
2087  return MEMIF_ERR_NOMEM;
2088 
2089  for (x = 0; x < conn->run_args.num_m2s_rings; x++)
2090  {
2091  if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
2092  return memif_syscall_error_handler (errno);
2093  e.key = mq[x].int_fd;
2094  e.data_struct = conn;
2095  add_list_elt (lm, &e, &lm->interrupt_list, &lm->interrupt_list_len);
2096 
2097  mq[x].ring = memif_get_ring (conn, MEMIF_RING_M2S, x);
2098  DBG ("RING: %p I: %d", mq[x].ring, x);
2099  mq[x].log2_ring_size = conn->run_args.log2_ring_size;
2100  mq[x].region = 0;
2101  mq[x].offset =
2102  (void *) mq[x].ring - (void *) conn->regions[mq->region].addr;
2103  mq[x].last_head = mq[x].last_tail = 0;
2104  mq[x].alloc_bufs = 0;
2105  }
2106  conn->rx_queues = mq;
2107  conn->rx_queues_num = conn->run_args.num_m2s_rings;
2108 
2109  return MEMIF_ERR_SUCCESS;
2110 }
2111 
2112 int
2114 {
2115  memif_region_t *r;
2116  libmemif_main_t *lm;
2117 
2118  if (conn == NULL)
2119  return MEMIF_ERR_INVAL_ARG;
2120 
2121  lm = get_libmemif_main (conn->args.socket);
2122 
2123  /* region 0. rings */
2124  memif_add_region (lm, conn, /* has_buffers */ 0);
2125 
2126  /* region 1. buffers */
2127  if (lm->add_external_region)
2128  {
2129  r =
2130  (memif_region_t *) lm->realloc (conn->regions,
2131  sizeof (memif_region_t) *
2132  ++conn->regions_num);
2133  if (r == NULL)
2134  return MEMIF_ERR_NOMEM;
2135  conn->regions = r;
2136 
2137  conn->regions[1].region_size =
2138  conn->run_args.buffer_size * (1 << conn->run_args.log2_ring_size) *
2139  (conn->run_args.num_s2m_rings + conn->run_args.num_m2s_rings);
2140  conn->regions[1].buffer_offset = 0;
2141  lm->add_external_region (&conn->regions[1].addr,
2142  conn->regions[1].region_size,
2143  &conn->regions[1].fd, conn->private_ctx);
2144  conn->regions[1].is_external = 1;
2145  }
2146  else
2147  {
2148  memif_add_region (lm, conn, 1);
2149  }
2150 
2151  memif_init_queues (lm, conn);
2152 
2153  return 0;
2154 }
2155 
2156 int
2158  memif_buffer_t * bufs, uint16_t count,
2159  uint16_t * count_out)
2160 {
2162  if (EXPECT_FALSE (c == NULL))
2163  return MEMIF_ERR_NOCONN;
2164  if (EXPECT_FALSE (c->fd < 0))
2165  return MEMIF_ERR_DISCONNECTED;
2166  uint8_t num =
2167  (c->args.is_master) ? c->run_args.num_m2s_rings : c->
2168  run_args.num_s2m_rings;
2169  if (EXPECT_FALSE (qid >= num))
2170  return MEMIF_ERR_QID;
2171  if (EXPECT_FALSE (!count_out))
2172  return MEMIF_ERR_INVAL_ARG;
2173  if (EXPECT_FALSE (c->args.is_master))
2174  return MEMIF_ERR_INVAL_ARG;
2175 
2176  memif_queue_t *mq = &c->tx_queues[qid];
2177  memif_ring_t *ring = mq->ring;
2178  memif_buffer_t *b0;
2179  uint16_t mask = (1 << mq->log2_ring_size) - 1;
2180  uint16_t ring_size;
2181  uint16_t slot, ns;
2182  int err = MEMIF_ERR_SUCCESS; /* 0 */
2183  *count_out = 0;
2184 
2185  ring_size = (1 << mq->log2_ring_size);
2186  slot = (c->args.is_master) ? ring->tail : ring->head;
2187  slot += mq->alloc_bufs;
2188 
2189  /* can only be called by slave */
2190  ns = ring_size - (ring->head + mq->alloc_bufs) + ring->tail;
2191 
2192  b0 = bufs;
2193 
2194  while (count && ns)
2195  {
2196  if (EXPECT_FALSE ((b0->flags & MEMIF_BUFFER_FLAG_RX) == 0))
2197  {
2198  /* not a valid buffer */
2199  count--;
2200  continue;
2201  }
2202  b0->flags &= ~MEMIF_BUFFER_FLAG_RX;
2203 
2204  ((memif_ring_t *) b0->ring)->desc[b0->desc_index & mask].offset = ring->desc[slot & mask].offset; /* put free buffer on rx ring */
2205 
2206  ring->desc[slot & mask].offset =
2207  (uint32_t) (b0->data -
2208  c->regions[ring->desc[slot & mask].region].addr);
2209  ring->desc[slot & mask].flags &= ~MEMIF_DESC_FLAG_NEXT;
2210  ring->desc[slot & mask].flags |=
2212 
2213  b0->desc_index = slot;
2214 
2215  mq->alloc_bufs++;
2216  slot++;
2217 
2218  count--;
2219  ns--;
2220  b0++;
2221  *count_out += 1;
2222  }
2223 
2224  DBG ("allocated: %u/%u bufs. Total %u allocated bufs", *count_out, count,
2225  mq->alloc_bufs);
2226 
2227  if (count)
2228  {
2229  DBG ("ring buffer full! qid: %u", qid);
2230  err = MEMIF_ERR_NOBUF_RING;
2231  }
2232 
2233  return err;
2234 }
2235 
2236 int
2238  memif_buffer_t * bufs, uint16_t count,
2239  uint16_t * count_out, uint16_t size)
2240 {
2242  if (EXPECT_FALSE (c == NULL))
2243  return MEMIF_ERR_NOCONN;
2244  if (EXPECT_FALSE (c->fd < 0))
2245  return MEMIF_ERR_DISCONNECTED;
2246  uint8_t num =
2247  (c->args.is_master) ? c->run_args.num_m2s_rings : c->
2248  run_args.num_s2m_rings;
2249  if (EXPECT_FALSE (qid >= num))
2250  return MEMIF_ERR_QID;
2251  if (EXPECT_FALSE (!count_out))
2252  return MEMIF_ERR_INVAL_ARG;
2253 
2254  libmemif_main_t *lm = get_libmemif_main (c->args.socket);
2255  memif_queue_t *mq = &c->tx_queues[qid];
2256  memif_ring_t *ring = mq->ring;
2257  memif_buffer_t *b0;
2258  uint16_t mask = (1 << mq->log2_ring_size) - 1;
2259  uint32_t offset_mask = c->run_args.buffer_size - 1;
2260  uint16_t ring_size;
2261  uint16_t slot, ns;
2262  int err = MEMIF_ERR_SUCCESS; /* 0 */
2263  uint16_t dst_left, src_left;
2264  uint16_t saved_count;
2265  memif_buffer_t *saved_b;
2266  *count_out = 0;
2267 
2268  ring_size = (1 << mq->log2_ring_size);
2269  slot = (c->args.is_master) ? ring->tail : ring->head;
2270  slot += mq->alloc_bufs;
2271 
2272  if (c->args.is_master)
2273  ns = ring->head - (ring->tail + mq->alloc_bufs);
2274  else
2275  ns = ring_size - (ring->head + mq->alloc_bufs) + ring->tail;
2276 
2277  while (count && ns)
2278  {
2279  b0 = (bufs + *count_out);
2280 
2281  saved_b = b0;
2282  saved_count = count;
2283 
2284  b0->desc_index = slot;
2285  ring->desc[slot & mask].flags = 0;
2286 
2287  /* slave can produce buffer with original length */
2288  dst_left = (c->args.is_master) ? ring->desc[slot & mask].length :
2289  c->run_args.buffer_size;
2290  src_left = size;
2291 
2292  while (src_left)
2293  {
2294  if (EXPECT_FALSE (dst_left == 0))
2295  {
2296  if (count && ns)
2297  {
2298  slot++;
2299  *count_out += 1;
2300  mq->alloc_bufs++;
2301  ns--;
2302 
2303  ring->desc[b0->desc_index & mask].flags |=
2306 
2307  b0 = (bufs + *count_out);
2308  b0->desc_index = slot;
2309  dst_left =
2310  (c->args.is_master) ? ring->desc[slot & mask].
2311  length : c->run_args.buffer_size;
2312  ring->desc[slot & mask].flags = 0;
2313  }
2314  else
2315  {
2316  /* rollback allocated chain buffers */
2317  memset (saved_b, 0, sizeof (memif_buffer_t)
2318  * (saved_count - count + 1));
2319  *count_out -= saved_count - count;
2320  mq->alloc_bufs = saved_count - count;
2321  goto no_ns;
2322  }
2323  }
2324  b0->len = memif_min (dst_left, src_left);
2325 
2326  /* slave resets buffer offset */
2327  if (c->args.is_master == 0)
2328  {
2329  memif_desc_t *d = &ring->desc[slot & mask];
2331  d->offset = lm->get_external_buffer_offset (c->private_ctx);
2332  else
2333  d->offset = d->offset - (d->offset & offset_mask);
2334  }
2335  b0->data = memif_get_buffer (c, ring, slot & mask);
2336 
2337  src_left -= b0->len;
2338  dst_left -= b0->len;
2339  }
2340 
2341  slot++;
2342  *count_out += 1;
2343  mq->alloc_bufs++;
2344  ns--;
2345  count--;
2346  }
2347 
2348 no_ns:
2349 
2350  DBG ("allocated: %u/%u bufs. Total %u allocated bufs", *count_out, count,
2351  mq->alloc_bufs);
2352 
2353  if (count)
2354  {
2355  DBG ("ring buffer full! qid: %u", qid);
2356  err = MEMIF_ERR_NOBUF_RING;
2357  }
2358 
2359  return err;
2360 }
2361 
2362 int
2363 memif_refill_queue (memif_conn_handle_t conn, uint16_t qid, uint16_t count,
2364  uint16_t headroom)
2365 {
2367  if (EXPECT_FALSE (c == NULL))
2368  return MEMIF_ERR_NOCONN;
2369  if (EXPECT_FALSE (c->fd < 0))
2370  return MEMIF_ERR_DISCONNECTED;
2371  uint8_t num =
2372  (c->args.is_master) ? c->run_args.num_s2m_rings : c->
2373  run_args.num_m2s_rings;
2374  if (EXPECT_FALSE (qid >= num))
2375  return MEMIF_ERR_QID;
2376  libmemif_main_t *lm = get_libmemif_main (c->args.socket);
2377  memif_queue_t *mq = &c->rx_queues[qid];
2378  memif_ring_t *ring = mq->ring;
2379  uint16_t mask = (1 << mq->log2_ring_size) - 1;
2380  uint32_t offset_mask = c->run_args.buffer_size - 1;
2381  uint16_t slot;
2382 
2383  if (c->args.is_master)
2384  {
2386  ring->tail =
2387  (ring->tail + count <=
2388  mq->last_head) ? ring->tail + count : mq->last_head;
2389  return MEMIF_ERR_SUCCESS;
2390  }
2391 
2392  uint16_t head = ring->head;
2393  uint16_t ns = (1 << mq->log2_ring_size) - head + mq->last_tail;
2394  head += (count < ns) ? count : ns;
2395 
2396  slot = ring->head;
2397  memif_desc_t *d;
2398  while (slot < head)
2399  {
2400  d = &ring->desc[slot & mask];
2401  d->region = 1;
2402  d->length = c->run_args.buffer_size - headroom;
2404  d->offset = lm->get_external_buffer_offset (c->private_ctx);
2405  else
2406  d->offset = d->offset - (d->offset & offset_mask) + headroom;
2407  slot++;
2408  }
2409 
2411  ring->head = head;
2412 
2413  return MEMIF_ERR_SUCCESS; /* 0 */
2414 }
2415 
2416 int
2418  memif_buffer_t * bufs, uint16_t count, uint16_t * tx)
2419 {
2421  if (EXPECT_FALSE (c == NULL))
2422  return MEMIF_ERR_NOCONN;
2423  if (EXPECT_FALSE (c->fd < 0))
2424  return MEMIF_ERR_DISCONNECTED;
2425  uint8_t num =
2426  (c->args.is_master) ? c->run_args.num_m2s_rings : c->
2427  run_args.num_s2m_rings;
2428  if (EXPECT_FALSE (qid >= num))
2429  return MEMIF_ERR_QID;
2430  if (EXPECT_FALSE (!tx))
2431  return MEMIF_ERR_INVAL_ARG;
2432 
2433  memif_queue_t *mq = &c->tx_queues[qid];
2434  memif_ring_t *ring = mq->ring;
2435  uint16_t mask = (1 << mq->log2_ring_size) - 1;
2436  memif_buffer_t *b0;
2437  *tx = 0;
2438 
2439  if (count > mq->alloc_bufs)
2440  count = mq->alloc_bufs;
2441 
2442  if (EXPECT_FALSE (count == 0))
2443  return MEMIF_ERR_SUCCESS;
2444 
2445  while (count)
2446  {
2447  b0 = (bufs + *tx);
2448  ring->desc[b0->desc_index & mask].length = b0->len;
2449 
2450 #ifdef MEMIF_DBG_SHM
2451  printf ("offset: %-6d\n", ring->desc[b0->desc_index & mask].offset);
2452  printf ("data: %p\n",
2453  memif_get_buffer (c, ring, b0->desc_index & mask));
2454  printf ("index: %u\n", b0->desc_index);
2455  print_bytes (memif_get_buffer (c, ring, b0->desc_index & mask),
2456  ring->desc[b0->desc_index & mask].length, DBG_TX_BUF);
2457 #endif /* MEMIF_DBG_SHM */
2458 
2459  *tx += 1;
2460  count--;
2461  }
2462 
2463 
2465  if (c->args.is_master)
2466  ring->tail = b0->desc_index + 1;
2467  else
2468  ring->head = b0->desc_index + 1;
2469 
2470  mq->alloc_bufs -= *tx;
2471 
2472  if ((ring->flags & MEMIF_RING_FLAG_MASK_INT) == 0)
2473  {
2474  uint64_t a = 1;
2475  int r = write (mq->int_fd, &a, sizeof (a));
2476  if (r < 0)
2477  return MEMIF_ERR_INT_WRITE;
2478  }
2479 
2480  return MEMIF_ERR_SUCCESS; /* 0 */
2481 }
2482 
2483 int
2485  memif_buffer_t * bufs, uint16_t count, uint16_t * rx)
2486 {
2488  if (EXPECT_FALSE (c == NULL))
2489  return MEMIF_ERR_NOCONN;
2490  if (EXPECT_FALSE (c->fd < 0))
2491  return MEMIF_ERR_DISCONNECTED;
2492  uint8_t num =
2493  (c->args.is_master) ? c->run_args.num_s2m_rings : c->
2494  run_args.num_m2s_rings;
2495  if (EXPECT_FALSE (qid >= num))
2496  return MEMIF_ERR_QID;
2497  if (EXPECT_FALSE (!rx))
2498  return MEMIF_ERR_INVAL_ARG;
2499 
2500  memif_queue_t *mq = &c->rx_queues[qid];
2501  memif_ring_t *ring = mq->ring;
2502  uint16_t cur_slot, last_slot;
2503  uint16_t ns;
2504  uint16_t mask = (1 << mq->log2_ring_size) - 1;
2505  memif_buffer_t *b0;
2506  *rx = 0;
2507 
2508  uint64_t b;
2509  ssize_t r;
2510 
2511  cur_slot = (c->args.is_master) ? mq->last_head : mq->last_tail;
2512  last_slot = (c->args.is_master) ? ring->head : ring->tail;
2513  if (cur_slot == last_slot)
2514  {
2515  r = read (mq->int_fd, &b, sizeof (b));
2516  if (EXPECT_FALSE ((r == -1) && (errno != EAGAIN)))
2517  return memif_syscall_error_handler (errno);
2518 
2519  return MEMIF_ERR_SUCCESS;
2520  }
2521 
2522  ns = last_slot - cur_slot;
2523 
2524  while (ns && count)
2525  {
2526  b0 = (bufs + *rx);
2527 
2528  b0->desc_index = cur_slot;
2529  b0->data = memif_get_buffer (c, ring, cur_slot & mask);
2530  b0->len = ring->desc[cur_slot & mask].length;
2531  /* slave resets buffer length */
2532  if (c->args.is_master == 0)
2533  {
2534  ring->desc[cur_slot & mask].length = c->run_args.buffer_size;
2535  }
2536 
2538  if (ring->desc[cur_slot & mask].flags & MEMIF_DESC_FLAG_NEXT)
2539  {
2541  ring->desc[cur_slot & mask].flags &= ~MEMIF_DESC_FLAG_NEXT;
2542  }
2543 /* b0->offset = ring->desc[cur_slot & mask].offset;*/
2544  b0->ring = ring;
2545 #ifdef MEMIF_DBG_SHM
2546  printf ("data: %p\n", b0->data);
2547  printf ("index: %u\n", b0->desc_index);
2548  printf ("ring: %p\n", b0->ring);
2549  print_bytes (b0->data, b0->len, DBG_RX_BUF);
2550 #endif /* MEMIF_DBG_SHM */
2551  ns--;
2552  *rx += 1;
2553 
2554  count--;
2555  cur_slot++;
2556  }
2557 
2558  if (c->args.is_master)
2559  mq->last_head = cur_slot;
2560  else
2561  mq->last_tail = cur_slot;
2562 
2563  if (ns)
2564  {
2565  DBG ("not enough buffers!");
2566  return MEMIF_ERR_NOBUF;
2567  }
2568 
2569  r = read (mq->int_fd, &b, sizeof (b));
2570  if (EXPECT_FALSE ((r == -1) && (errno != EAGAIN)))
2571  return memif_syscall_error_handler (errno);
2572 
2573  return MEMIF_ERR_SUCCESS; /* 0 */
2574 }
2575 
2576 int
2578  char *buf, ssize_t buflen)
2579 {
2581  libmemif_main_t *lm;
2582  memif_socket_t *ms;
2583  int err = MEMIF_ERR_SUCCESS, i;
2584  ssize_t l0 = 0, l1;
2585 
2586  if (c == NULL)
2587  return MEMIF_ERR_NOCONN;
2588 
2589  ms = (memif_socket_t *) c->args.socket;
2590  lm = get_libmemif_main (ms);
2591 
2592  l1 = strlen ((char *) c->args.interface_name);
2593  if (l0 + l1 < buflen)
2594  {
2595  md->if_name =
2596  (uint8_t *) strcpy (buf + l0, (char *) c->args.interface_name);
2597  l0 += l1 + 1;
2598  }
2599  else
2600  err = MEMIF_ERR_NOBUF_DET;
2601 
2602  l1 = strlen ((char *) lm->app_name);
2603  if (l0 + l1 < buflen)
2604  {
2605  md->inst_name = (uint8_t *) strcpy (buf + l0, (char *) lm->app_name);
2606  l0 += l1 + 1;
2607  }
2608  else
2609  err = MEMIF_ERR_NOBUF_DET;
2610 
2611  l1 = strlen ((char *) c->remote_if_name);
2612  if (l0 + l1 < buflen)
2613  {
2614  md->remote_if_name =
2615  (uint8_t *) strcpy (buf + l0, (char *) c->remote_if_name);
2616  l0 += l1 + 1;
2617  }
2618  else
2619  err = MEMIF_ERR_NOBUF_DET;
2620 
2621  l1 = strlen ((char *) c->remote_name);
2622  if (l0 + l1 < buflen)
2623  {
2624  md->remote_inst_name =
2625  (uint8_t *) strcpy (buf + l0, (char *) c->remote_name);
2626  l0 += l1 + 1;
2627  }
2628  else
2629  err = MEMIF_ERR_NOBUF_DET;
2630 
2631  md->id = c->args.interface_id;
2632 
2633  if (strlen ((char *) c->args.secret) > 0)
2634  {
2635  l1 = strlen ((char *) c->args.secret);
2636  if (l0 + l1 < buflen)
2637  {
2638  md->secret = (uint8_t *) strcpy (buf + l0, (char *) c->args.secret);
2639  l0 += l1 + 1;
2640  }
2641  else
2642  err = MEMIF_ERR_NOBUF_DET;
2643  }
2644 
2645  md->role = (c->args.is_master) ? 0 : 1;
2646  md->mode = c->args.mode;
2647 
2648  l1 = strlen ((char *) ms->filename);
2649  if (l0 + l1 < buflen)
2650  {
2651  md->socket_filename =
2652  (uint8_t *) strcpy (buf + l0, (char *) ms->filename);
2653  l0 += l1 + 1;
2654  }
2655  else
2656  err = MEMIF_ERR_NOBUF_DET;
2657 
2658  l1 = strlen ((char *) c->remote_disconnect_string);
2659  if (l0 + l1 < buflen)
2660  {
2661  md->error =
2662  (uint8_t *) strcpy (buf + l0, (char *) c->remote_disconnect_string);
2663  l0 += l1 + 1;
2664  }
2665  else
2666  err = MEMIF_ERR_NOBUF_DET;
2667 
2668  md->regions_num = c->regions_num;
2669  l1 = sizeof (memif_region_details_t) * md->regions_num;
2670  if (l0 + l1 <= buflen)
2671  {
2672  md->regions = (memif_region_details_t *) (buf + l0);
2673  for (i = 0; i < md->regions_num; i++)
2674  {
2675  md->regions[i].index = i;
2676  md->regions[i].addr = c->regions[i].addr;
2677  md->regions[i].size = c->regions[i].region_size;
2678  md->regions[i].fd = c->regions[i].fd;
2679  md->regions[i].is_external = c->regions[i].is_external;
2680  }
2681  l0 += l1;
2682  }
2683  else
2684  err = MEMIF_ERR_NOBUF_DET;
2685 
2686  md->rx_queues_num =
2687  (c->args.is_master) ? c->run_args.num_s2m_rings : c->
2688  run_args.num_m2s_rings;
2689 
2690  l1 = sizeof (memif_queue_details_t) * md->rx_queues_num;
2691  if (l0 + l1 <= buflen)
2692  {
2693  md->rx_queues = (memif_queue_details_t *) (buf + l0);
2694  for (i = 0; i < md->rx_queues_num; i++)
2695  {
2696  md->rx_queues[i].region = c->rx_queues[i].region;
2697  md->rx_queues[i].qid = i;
2698  md->rx_queues[i].ring_size = (1 << c->rx_queues[i].log2_ring_size);
2699  md->rx_queues[i].flags = c->rx_queues[i].ring->flags;
2700  md->rx_queues[i].head = c->rx_queues[i].ring->head;
2701  md->rx_queues[i].tail = c->rx_queues[i].ring->tail;
2702  md->rx_queues[i].buffer_size = c->run_args.buffer_size;
2703  }
2704  l0 += l1;
2705  }
2706  else
2707  err = MEMIF_ERR_NOBUF_DET;
2708 
2709  md->tx_queues_num =
2710  (c->args.is_master) ? c->run_args.num_m2s_rings : c->
2711  run_args.num_s2m_rings;
2712 
2713  l1 = sizeof (memif_queue_details_t) * md->tx_queues_num;
2714  if (l0 + l1 <= buflen)
2715  {
2716  md->tx_queues = (memif_queue_details_t *) (buf + l0);
2717  for (i = 0; i < md->tx_queues_num; i++)
2718  {
2719  md->tx_queues[i].region = c->tx_queues[i].region;
2720  md->tx_queues[i].qid = i;
2721  md->tx_queues[i].ring_size = (1 << c->tx_queues[i].log2_ring_size);
2722  md->tx_queues[i].flags = c->tx_queues[i].ring->flags;
2723  md->tx_queues[i].head = c->tx_queues[i].ring->head;
2724  md->tx_queues[i].tail = c->tx_queues[i].ring->tail;
2725  md->tx_queues[i].buffer_size = c->run_args.buffer_size;
2726  }
2727  l0 += l1;
2728  }
2729  else
2730  err = MEMIF_ERR_NOBUF_DET;
2731 
2732  md->link_up_down = (c->fd > 0) ? 1 : 0;
2733 
2734  return err; /* 0 */
2735 }
2736 
2737 int
2738 memif_get_queue_efd (memif_conn_handle_t conn, uint16_t qid, int *efd)
2739 {
2741  uint8_t num;
2742 
2743  *efd = -1;
2744  if (c == NULL)
2745  return MEMIF_ERR_NOCONN;
2746  if (c->fd < 0)
2747  return MEMIF_ERR_DISCONNECTED;
2748 
2749  num =
2750  (c->args.is_master) ? c->run_args.num_s2m_rings : c->
2751  run_args.num_m2s_rings;
2752  if (qid >= num)
2753  return MEMIF_ERR_QID;
2754 
2755  *efd = c->rx_queues[qid].int_fd;
2756 
2757  return MEMIF_ERR_SUCCESS;
2758 }
2759 
2760 int
2762 {
2764  int err;
2765 
2767  if (err != MEMIF_ERR_SUCCESS)
2768  return err;
2769 
2770  if (lm->control_list)
2771  lm->free (lm->control_list);
2772  lm->control_list = NULL;
2773  if (lm->interrupt_list)
2774  lm->free (lm->interrupt_list);
2775  lm->interrupt_list = NULL;
2776  if (lm->socket_list)
2777  lm->free (lm->socket_list);
2778  lm->socket_list = NULL;
2779  if (lm->pending_list)
2780  lm->free (lm->pending_list);
2781  lm->pending_list = NULL;
2782  if (lm->poll_cancel_fd != -1)
2783  close (lm->poll_cancel_fd);
2784 
2785  return MEMIF_ERR_SUCCESS; /* 0 */
2786 }
2787 
2788 int
2790 {
2791  libmemif_main_t *lm = (libmemif_main_t *) * pt_main;
2792 
2793  if (lm == NULL)
2794  return MEMIF_ERR_INVAL_ARG;
2795 
2796  /* No default socket in case of per thread */
2797 
2798  if (lm->control_list)
2799  lm->free (lm->control_list);
2800  lm->control_list = NULL;
2801  if (lm->interrupt_list)
2802  lm->free (lm->interrupt_list);
2803  lm->interrupt_list = NULL;
2804  if (lm->socket_list)
2805  lm->free (lm->socket_list);
2806  lm->socket_list = NULL;
2807  if (lm->pending_list)
2808  lm->free (lm->pending_list);
2809  lm->pending_list = NULL;
2810  if (lm->poll_cancel_fd != -1)
2811  close (lm->poll_cancel_fd);
2812 
2813  lm->free (lm);
2814 
2815  *pt_main = NULL;
2816 
2817  return MEMIF_ERR_SUCCESS; /* 0 */
2818 }
u8 count
Definition: dhcp.api:208
#define MAX_ERRBUF_LEN
Definition: main.c:60
#define MEMIF_DEFAULT_LOG2_RING_SIZE
Definition: memif_private.h:40
int memif_per_thread_poll_event(memif_per_thread_main_handle_t pt_main, int timeout)
Memif poll event.
Definition: main.c:1575
struct itimerspec arm disarm
uint8_t * filename
#define EXPECT_FALSE(x)
Definition: memif_private.h:57
a
Definition: bitmap.h:538
uint8_t * inst_name
Definition: libmemif.h:404
uint8_t * secret
Definition: libmemif.h:409
static char memif_buf[MAX_ERRBUF_LEN]
Definition: main.c:70
Memif region details.
Definition: libmemif.h:373
int on_disconnect(memif_conn_handle_t conn, void *private_ctx)
Definition: main.c:186
void * ring
Definition: libmemif.h:326
#define MEMIF_FD_EVENT_READ
user needs to set events that occured on fd and pass them to memif_control_fd_handler ...
Definition: libmemif.h:89
uint8_t num_m2s_rings
Definition: libmemif.h:299
Optimized string handling code, including c11-compliant "safe C library" variants.
static int memif_del_epoll_fd(libmemif_main_t *lm, int fd)
Definition: main.c:289
memif_alloc_t * alloc
uint16_t buffer_size
Definition: libmemif.h:300
uint8_t app_name[MEMIF_NAME_LEN]
uint8_t secret[24]
Definition: libmemif.h:296
static void memif_msg_queue_free(libmemif_main_t *lm, memif_msg_queue_elt_t **e)
Definition: main.c:1653
uint32_t interface_id
Definition: libmemif.h:304
int memif_conn_fd_read_ready(memif_connection_t *c)
Definition: socket.c:828
#define MEMIF_NAME_LEN
Definition: memif_private.h:34
uint32_t alloc_bufs
Definition: memif_private.h:98
for(i=1;i<=collision_buckets;i++)
#define MEMIF_ERR_UNDEFINED
Definition: main.c:154
clib_error_t * memif_msg_send_disconnect(memif_if_t *mif, clib_error_t *err)
Definition: socket.c:198
int memif_disconnect_internal(memif_connection_t *c)
Definition: main.c:1665
int memif_control_fd_update(int fd, uint8_t events, void *private_ctx)
Definition: main.c:308
memif_socket_handle_t socket
Definition: libmemif.h:295
uint16_t desc_index
Definition: libmemif.h:325
#define MEMIF_MEMORY_BARRIER()
Definition: main.c:65
memif_del_external_region_t * del_external_region
uint8_t * remote_inst_name
Definition: libmemif.h:406
static memif_ring_t * memif_get_ring(memif_connection_t *conn, memif_ring_type_t type, uint16_t ring_num)
Definition: main.c:825
uint32_t length
Definition: memif.h:154
int memif_refill_queue(memif_conn_handle_t conn, uint16_t qid, uint16_t count, uint16_t headroom)
Memif refill ring.
Definition: main.c:2363
#define MEMIF_DEFAULT_APP_NAME
Default name of application using libmemif.
Definition: libmemif.h:28
#define MFD_ALLOW_SEALING
Definition: main.c:104
memif_list_elt_t * interface_list
memif_socket_type_t type
int on_connect(memif_conn_handle_t conn, void *private_ctx)
Definition: main.c:177
uint8_t num_s2m_rings
Definition: libmemif.h:298
const char * memif_get_socket_filename(memif_socket_handle_t sock)
Get socket filename.
Definition: main.c:1783
uint32_t len
Definition: libmemif.h:327
#define F_SEAL_SHRINK
Definition: main.c:112
int memif_get_details(memif_conn_handle_t conn, memif_details_t *md, char *buf, ssize_t buflen)
Memif get details.
Definition: main.c:2577
libmemif_main_t * get_libmemif_main(memif_socket_t *ms)
Definition: main.c:239
uint32_t cookie
Definition: memif.h:168
memif_interface_mode_t mode
Definition: libmemif.h:306
static clib_error_t * memif_conn_fd_write_ready(clib_file_t *uf, memif_if_t *mif)
Definition: socket.c:568
uint8_t mode
Definition: libmemif.h:411
int memif_per_thread_init(memif_per_thread_main_handle_t *pt_main, void *private_ctx, memif_control_fd_update_t *on_control_fd_update, char *app_name, memif_alloc_t *memif_alloc, memif_realloc_t *memif_realloc, memif_free_t *memif_free)
Memif per thread initialization.
Definition: main.c:655
#define DBG_TX_BUF
Definition: main.c:179
uint16_t flags
Definition: memif.h:151
uint8_t link_up_down
Definition: libmemif.h:421
#define ERRLIST_LEN
Definition: main.c:59
char * memif_strerror(int err_code)
Memif strerror.
Definition: main.c:157
static int memfd_create(const char *name, unsigned int flags)
Definition: main.c:93
memif_region_offset_t offset
Definition: private.h:121
struct libmemif_main * lm
#define MEMIF_MAX_LOG2_RING_SIZE
Definition: private.h:30
#define MEMIF_BUFFER_FLAG_NEXT
next buffer present (chained buffers)
Definition: libmemif.h:329
int memif_syscall_error_handler(int err_code)
Definition: main.c:202
vl_api_fib_path_type_t type
Definition: fib_types.api:123
memif_region_index_t region
Definition: memif.h:153
u16 last_head
Definition: private.h:123
uint8_t interface_name[32]
Definition: libmemif.h:305
uint8_t * error
Definition: libmemif.h:420
void * data
Definition: libmemif.h:333
static void memif_free_register(libmemif_main_t *lm, memif_free_t *mf)
Definition: main.c:459
memif_desc_t desc[0]
Definition: memif.h:175
uint16_t buffer_size
Definition: libmemif.h:363
uint8_t * socket_filename
Definition: libmemif.h:412
#define MEMIF_DEFAULT_SOCKET_PATH
Definition: memif_private.h:38
memif_list_elt_t * pending_list
int() memif_add_external_region_t(void **addr, uint32_t size, int *fd, void *private_ctx)
Add external region.
Definition: libmemif.h:204
#define MEMIF_FD_EVENT_DEL
if set, informs that fd is going to be closed (user may want to stop watching for events on this fd) ...
Definition: libmemif.h:94
int memif_set_rx_mode(memif_conn_handle_t c, memif_rx_mode_t rx_mode, uint16_t qid)
Memif set rx mode.
Definition: main.c:840
long ctx[MAX_CONNS]
Definition: main.c:144
void * memif_socket_handle_t
Memif socket handle pointer of type void, pointing to internal structure.
Definition: libmemif.h:113
int() memif_del_external_region_t(void *addr, uint32_t size, int fd, void *private_ctx)
Delete external region.
Definition: libmemif.h:227
int memif_create_socket(memif_socket_handle_t *sock, const char *filename, void *private_ctx)
Create memif socket.
Definition: main.c:932
u64 size
Definition: vhost_user.h:150
int() memif_interrupt_t(memif_conn_handle_t conn, void *private_ctx, uint16_t qid)
Memif interrupt occured (callback function)
Definition: libmemif.h:177
uint8_t is_master
Definition: libmemif.h:302
uint8_t rx_queues_num
Definition: libmemif.h:415
int memif_init(memif_control_fd_update_t *on_control_fd_update, char *app_name, memif_alloc_t *memif_alloc, memif_realloc_t *memif_realloc, memif_free_t *memif_free)
Memif initialization.
Definition: main.c:505
int() memif_connection_update_t(memif_conn_handle_t conn, void *private_ctx)
Memif connection status update (callback function)
Definition: libmemif.h:167
memif_list_elt_t * interrupt_list
uint16_t pending_list_len
int memif_get_queue_efd(memif_conn_handle_t conn, uint16_t qid, int *efd)
Memif get queue event file descriptor
Definition: main.c:2738
#define MEMIF_BUFFER_FLAG_RX
states that buffer is from rx ring
Definition: libmemif.h:331
int memif_buffer_enq_tx(memif_conn_handle_t conn, uint16_t qid, memif_buffer_t *bufs, uint16_t count, uint16_t *count_out)
Memif buffer enq tx.
Definition: main.c:2157
#define MEMIF_DEFAULT_TX_QUEUES
Definition: private.h:24
static int memif_mod_epoll_fd(libmemif_main_t *lm, int fd, uint32_t events)
Definition: main.c:268
uint32_t buffer_offset
Definition: memif_private.h:80
int memif_read_ready(libmemif_main_t *lm, int fd)
Definition: socket.c:901
#define MEMIF_DEFAULT_RECONNECT_PERIOD_SEC
Definition: memif_private.h:44
static void memif_alloc_register(libmemif_main_t *lm, memif_alloc_t *ma)
Definition: main.c:447
int memif_init_regions_and_queues(memif_connection_t *conn)
Definition: main.c:2113
u8 len
Definition: ip_types.api:92
static void memif_realloc_register(libmemif_main_t *lm, memif_realloc_t *mr)
Definition: main.c:453
u8 slot
Definition: pci_types.api:22
uint16_t use_count
uint8_t flags
Definition: libmemif.h:332
int on_interrupt(memif_conn_handle_t conn, void *private_ctx, uint16_t qid)
Definition: main.c:287
uint8_t regions_num
Definition: libmemif.h:413
svmdb_client_t * c
int memif_per_thread_create_socket(memif_per_thread_main_handle_t pt_main, memif_socket_handle_t *sock, const char *filename, void *private_ctx)
Create memif socket.
Definition: main.c:1011
int memif_tx_burst(memif_conn_handle_t conn, uint16_t qid, memif_buffer_t *bufs, uint16_t count, uint16_t *tx)
Memif transmit buffer burst.
Definition: main.c:2417
void() memif_free_t(void *ptr)
Memif allocator free.
Definition: libmemif.h:136
#define F_ADD_SEALS
Definition: main.c:108
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:317
int get_list_elt(memif_list_elt_t **e, memif_list_elt_t *list, uint16_t len, int key)
Definition: main.c:366
static void memif_control_fd_update_register(libmemif_main_t *lm, memif_control_fd_update_t *cb)
Definition: main.c:427
int memif_buffer_alloc(memif_conn_handle_t conn, uint16_t qid, memif_buffer_t *bufs, uint16_t count, uint16_t *count_out, uint16_t size)
Memif buffer alloc.
Definition: main.c:2237
static int memif_add_region(libmemif_main_t *lm, memif_connection_t *conn, uint8_t has_buffers)
Definition: main.c:1962
int memif_poll_event(int timeout)
Memif poll event.
Definition: main.c:1533
memif_list_elt_t * control_list
memif_socket_handle_t default_socket
memif_queue_details_t * rx_queues
Definition: libmemif.h:417
static int memif_socket_start_listening(memif_socket_t *ms)
Definition: main.c:858
u16 last_tail
Definition: private.h:124
memif_free_t * free
int memif_per_thread_control_fd_handler(memif_per_thread_main_handle_t pt_main, int fd, uint8_t events)
Memif per thread control file descriptor handler.
Definition: main.c:1419
uint16_t interrupt_list_len
uint8_t role
Definition: libmemif.h:410
uint16_t control_list_len
void *() memif_realloc_t(void *ptr, size_t size)
Memif realloc.
Definition: libmemif.h:129
#define MEMIF_DEFAULT_BUFFER_SIZE
Definition: private.h:25
int memif_cleanup()
Memif cleanup.
Definition: main.c:2761
memif_realloc_t * realloc
#define memif_min(a, b)
Definition: memif_private.h:54
uint32_t() memif_get_external_buffer_offset_t(void *private_ctx)
Get external buffer offset (optional)
Definition: libmemif.h:194
const char * memif_errlist[ERRLIST_LEN]
Definition: main.c:72
int memif_create(memif_conn_handle_t *c, memif_conn_args_t *args, memif_connection_update_t *on_connect, memif_connection_update_t *on_disconnect, memif_interrupt_t *on_interrupt, void *private_ctx)
Memory interface create function.
Definition: main.c:1095
#define MEMIF_DESC_FLAG_NEXT
Definition: memif.h:152
u8 data[128]
Definition: ipsec_types.api:89
int free_list_elt_ctx(memif_list_elt_t *list, uint16_t len, memif_connection_t *ctx)
Definition: main.c:407
#define MEMIF_VERSION
Definition: memif.h:28
static_always_inline void * memif_get_buffer(memif_if_t *mif, memif_ring_t *ring, u16 slot)
Definition: private.h:290
memif_ring_t * ring
Definition: private.h:118
uint8_t tx_queues_num
Definition: libmemif.h:416
#define MEMIF_DEFAULT_RX_QUEUES
Definition: private.h:23
void * memif_per_thread_main_handle_t
Memif per thread main handle Pointer of type void, pointing to internal structure.
Definition: libmemif.h:103
#define DBG(...)
Definition: main.c:61
memif_get_external_region_addr_t * get_external_region_addr
#define MEMIF_RING_FLAG_MASK_INT
Definition: memif.h:170
#define MEMIF_DEFAULT_RECONNECT_PERIOD_NSEC
Definition: memif_private.h:45
memif_err_t
Definition: libmemif.h:34
void * memif_conn_handle_t
Memif connection handle pointer of type void, pointing to internal structure.
Definition: libmemif.h:108
memif_region_offset_t offset
Definition: memif.h:155
int memif_per_thread_set_connection_request_timer(memif_per_thread_main_handle_t pt_main, struct itimerspec timer)
Set connection request timer value.
Definition: main.c:484
typedef key
Definition: ipsec_types.api:85
memif_add_external_region_t * add_external_region
static int memif_add_epoll_fd(libmemif_main_t *lm, int fd, uint32_t events)
Definition: main.c:247
memif_get_external_buffer_offset_t * get_external_buffer_offset
int memif_set_connection_request_timer(struct itimerspec timer)
Set connection request timer value.
Definition: main.c:465
int memif_control_fd_handler(int fd, uint8_t events)
Memif control file descriptor handler.
Definition: main.c:1307
int memif_request_connection(memif_conn_handle_t c)
Send connection request.
Definition: main.c:1233
uint8_t log2_ring_size
Definition: libmemif.h:301
uint32_t id
Definition: libmemif.h:408
int memif_rx_burst(memif_conn_handle_t conn, uint16_t qid, memif_buffer_t *bufs, uint16_t count, uint16_t *rx)
Memif receive buffer burst.
Definition: main.c:2484
memif_rx_mode_t
Definition: libmemif.h:310
void *() memif_alloc_t(size_t size)
Memif allocator alloc.
Definition: libmemif.h:120
void *() memif_get_external_region_addr_t(uint32_t size, int fd, void *private_ctx)
Get external region address.
Definition: libmemif.h:216
int memif_delete(memif_conn_handle_t *conn)
Memif delete.
Definition: main.c:1816
static int memif_init_queues(libmemif_main_t *lm, memif_connection_t *conn)
Definition: main.c:2012
memif_log2_ring_size_t log2_ring_size
Definition: private.h:119
int memif_per_thread_cleanup(memif_per_thread_main_handle_t *pt_main)
Memif per thread cleanup.
Definition: main.c:2789
int memif_per_thread_cancel_poll_event(memif_per_thread_main_handle_t pt_main)
Send signal to stop concurrently running memif_poll_event().
Definition: main.c:1634
Memif queue details.
Definition: libmemif.h:353
memif_region_details_t * regions
Definition: libmemif.h:414
memif_control_fd_update_t * control_fd_update
uint16_t flags
Definition: memif.h:169
#define MEMIF_FD_EVENT_ERROR
inform libmemif that error occured on fd
Definition: libmemif.h:92
int memif_cancel_poll_event()
Definition: main.c:1618
#define MEMIF_FD_EVENT_MOD
update events
Definition: libmemif.h:96
#define DBG_RX_BUF
Definition: main.c:180
memif_ring_type_t
Definition: memif.h:49
memif_queue_details_t * tx_queues
Definition: libmemif.h:418
uint8_t * if_name
Definition: libmemif.h:403
volatile uint16_t head
Definition: memif.h:171
memif_list_elt_t * socket_list
int memif_delete_socket(memif_socket_handle_t *sock)
Delete memif socket.
Definition: main.c:1794
uint16_t socket_list_len
clib_error_t * memif_conn_fd_accept_ready(clib_file_t *uf)
Definition: socket.c:657
uint16_t disconn_slaves
int memif_conn_fd_error(memif_connection_t *c)
Definition: socket.c:818
int memif_connect1(memif_connection_t *c)
Definition: main.c:1880
uint16_t index
Definition: main.c:74
libmemif_main_t libmemif_main
Definition: main.c:68
Memif buffer.
Definition: libmemif.h:323
int free_list_elt(memif_list_elt_t *list, uint16_t len, int key)
Definition: main.c:390
#define MEMIF_FD_EVENT_WRITE
Definition: libmemif.h:90
uint16_t memif_get_version()
Memif get version.
Definition: main.c:174
void * private_ctx
int add_list_elt(libmemif_main_t *lm, memif_list_elt_t *e, memif_list_elt_t **list, uint16_t *len)
Definition: main.c:330
memif_region_index_t region
Definition: private.h:120
#define MEMIF_COOKIE
Definition: memif.h:25
Memif connection arguments.
Definition: libmemif.h:293
uint16_t interface_list_len
Memif details.
Definition: libmemif.h:401
volatile uint16_t tail
Definition: memif.h:173
void memif_register_external_region(memif_add_external_region_t *ar, memif_get_external_region_addr_t *gr, memif_del_external_region_t *dr, memif_get_external_buffer_offset_t *go)
Register external region.
Definition: main.c:434
memif_region_size_t region_size
Definition: private.h:103
int() memif_control_fd_update_t(int fd, uint8_t events, void *private_ctx)
Memif control file descriptor update (callback function)
Definition: libmemif.h:157
uint8_t * remote_if_name
Definition: libmemif.h:405