FD.io VPP  v20.01-48-g3e0dafb74
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  if (private_ctx == NULL)
313  return MEMIF_ERR_INVAL_ARG;
314 
315  lm = (libmemif_main_t *) private_ctx;
316 
317  if (events & MEMIF_FD_EVENT_DEL)
318  return memif_del_epoll_fd (lm, fd);
319 
320  uint32_t evt = 0;
321  if (events & MEMIF_FD_EVENT_READ)
322  evt |= EPOLLIN;
323  if (events & MEMIF_FD_EVENT_WRITE)
324  evt |= EPOLLOUT;
325 
326  if (events & MEMIF_FD_EVENT_MOD)
327  return memif_mod_epoll_fd (lm, fd, evt);
328 
329  return memif_add_epoll_fd (lm, fd, evt);
330 }
331 
332 int
334  memif_list_elt_t ** list, uint16_t * len)
335 {
336  memif_list_elt_t *tmp;
337  int i;
338 
339  for (i = 0; i < *len; i++)
340  {
341  if ((*list)[i].data_struct == NULL)
342  {
343  (*list)[i].key = e->key;
344  (*list)[i].data_struct = e->data_struct;
345  return i;
346  }
347  }
348 
349  tmp = lm->realloc (*list, sizeof (memif_list_elt_t) * *len * 2);
350  if (tmp == NULL)
351  return -1;
352 
353  for (i = *len; i < *len * 2; i++)
354  {
355  tmp[i].key = -1;
356  tmp[i].data_struct = NULL;
357  }
358 
359  tmp[*len].key = e->key;
360  tmp[*len].data_struct = e->data_struct;
361  i = *len;
362  *len = *len * 2;
363  *list = tmp;
364 
365  return i;
366 }
367 
368 int
370  int key)
371 {
372  int i;
373  if (key == -1)
374  {
375  *e = NULL;
376  return -1;
377  }
378 
379  for (i = 0; i < len; i++)
380  {
381  if (list[i].key == key)
382  {
383  *e = &list[i];
384  return 0;
385  }
386  }
387  *e = NULL;
388  return -1;
389 }
390 
391 /* does not free memory, only marks element as free */
392 int
393 free_list_elt (memif_list_elt_t * list, uint16_t len, int key)
394 {
395  int i;
396  for (i = 0; i < len; i++)
397  {
398  if (list[i].key == key)
399  {
400  list[i].key = -1;
401  list[i].data_struct = NULL;
402  return 0;
403  }
404  }
405 
406  return -1;
407 }
408 
409 int
412 {
413  int i;
414  for (i = 0; i < len; i++)
415  {
416  if (list[i].key == -1)
417  {
418  if (list[i].data_struct == ctx)
419  {
420  list[i].data_struct = NULL;
421  return 0;
422  }
423  }
424  }
425 
426  return -1;
427 }
428 
429 static void
432 {
433  lm->control_fd_update = cb;
434 }
435 
436 void
441 {
443  lm->add_external_region = ar;
444  lm->get_external_region_addr = gr;
445  lm->del_external_region = dr;
447 }
448 
449 static void
451 {
452  lm->alloc = ma;
453 }
454 
455 static void
457 {
458  lm->realloc = mr;
459 }
460 
461 static void
463 {
464  lm->free = mf;
465 }
466 
467 int
468 memif_set_connection_request_timer (struct itimerspec timer)
469 {
471  int err = MEMIF_ERR_SUCCESS;
472 
473  lm->arm = timer;
474 
475  /* overwrite timer, if already armed */
476  if (lm->disconn_slaves != 0)
477  {
478  if (timerfd_settime (lm->timerfd, 0, &lm->arm, NULL) < 0)
479  {
480  err = memif_syscall_error_handler (errno);
481  }
482  }
483  return err;
484 }
485 
486 int
488  pt_main,
489  struct itimerspec timer)
490 {
491  libmemif_main_t *lm = (libmemif_main_t *) pt_main;
492  int err = MEMIF_ERR_SUCCESS;
493 
494  lm->arm = timer;
495 
496  /* overwrite timer, if already armed */
497  if (lm->disconn_slaves != 0)
498  {
499  if (timerfd_settime (lm->timerfd, 0, &lm->arm, NULL) < 0)
500  {
501  err = memif_syscall_error_handler (errno);
502  }
503  }
504  return err;
505 }
506 
507 int
508 memif_init (memif_control_fd_update_t * on_control_fd_update, char *app_name,
509  memif_alloc_t * memif_alloc, memif_realloc_t * memif_realloc,
510  memif_free_t * memif_free)
511 {
512  int err = MEMIF_ERR_SUCCESS; /* 0 */
514  memset (lm, 0, sizeof (libmemif_main_t));
515 
516  /* register custom memory management */
517  if (memif_alloc != NULL)
518  {
519  memif_alloc_register (lm, memif_alloc);
520  }
521  else
522  memif_alloc_register (lm, malloc);
523 
524  if (memif_realloc != NULL)
525  {
526  memif_realloc_register (lm, memif_realloc);
527  }
528  else
529  memif_realloc_register (lm, realloc);
530 
531  if (memif_free != NULL)
532  memif_free_register (lm, memif_free);
533  else
534  memif_free_register (lm, free);
535 
536  if (app_name != NULL)
537  {
538  uint8_t len = (strlen (app_name) > MEMIF_NAME_LEN)
539  ? strlen (app_name) : MEMIF_NAME_LEN;
540  strncpy ((char *) lm->app_name, app_name, len);
541  }
542  else
543  {
544  strncpy ((char *) lm->app_name, MEMIF_DEFAULT_APP_NAME,
545  strlen (MEMIF_DEFAULT_APP_NAME));
546  }
547 
548  lm->poll_cancel_fd = -1;
549  /* register control fd update callback */
550  if (on_control_fd_update != NULL)
551  memif_control_fd_update_register (lm, on_control_fd_update);
552  else
553  {
554  lm->epfd = epoll_create (1);
556  if ((lm->poll_cancel_fd = eventfd (0, EFD_NONBLOCK)) < 0)
557  {
558  err = errno;
559  DBG ("eventfd: %s", strerror (err));
560  return memif_syscall_error_handler (err);
561  }
563  DBG ("libmemif event polling initialized");
564  }
565 
566  lm->control_list_len = 2;
567  lm->interrupt_list_len = 2;
568  lm->socket_list_len = 1;
569  lm->pending_list_len = 1;
570 
571  lm->control_list =
572  lm->alloc (sizeof (memif_list_elt_t) * lm->control_list_len);
573  if (lm->control_list == NULL)
574  {
575  err = MEMIF_ERR_NOMEM;
576  goto error;
577  }
578  lm->interrupt_list =
579  lm->alloc (sizeof (memif_list_elt_t) * lm->interrupt_list_len);
580  if (lm->interrupt_list == NULL)
581  {
582  err = MEMIF_ERR_NOMEM;
583  goto error;
584  }
585  lm->socket_list =
586  lm->alloc (sizeof (memif_list_elt_t) * lm->socket_list_len);
587  if (lm->socket_list == NULL)
588  {
589  err = MEMIF_ERR_NOMEM;
590  goto error;
591  }
592  lm->pending_list =
593  lm->alloc (sizeof (memif_list_elt_t) * lm->pending_list_len);
594  if (lm->pending_list == NULL)
595  {
596  err = MEMIF_ERR_NOMEM;
597  goto error;
598  }
599 
600  int i;
601  for (i = 0; i < lm->control_list_len; i++)
602  {
603  lm->control_list[i].key = -1;
605  }
606  for (i = 0; i < lm->interrupt_list_len; i++)
607  {
608  lm->interrupt_list[i].key = -1;
610  }
611  for (i = 0; i < lm->socket_list_len; i++)
612  {
613  lm->socket_list[i].key = -1;
614  lm->socket_list[i].data_struct = NULL;
615  }
616  for (i = 0; i < lm->pending_list_len; i++)
617  {
618  lm->pending_list[i].key = -1;
620  }
621 
622  lm->disconn_slaves = 0;
623 
624  lm->timerfd = timerfd_create (CLOCK_REALTIME, TFD_NONBLOCK);
625  if (lm->timerfd < 0)
626  {
627  err = memif_syscall_error_handler (errno);
628  goto error;
629  }
630 
631  lm->arm.it_value.tv_sec = MEMIF_DEFAULT_RECONNECT_PERIOD_SEC;
632  lm->arm.it_value.tv_nsec = MEMIF_DEFAULT_RECONNECT_PERIOD_NSEC;
633  lm->arm.it_interval.tv_sec = MEMIF_DEFAULT_RECONNECT_PERIOD_SEC;
634  lm->arm.it_interval.tv_nsec = MEMIF_DEFAULT_RECONNECT_PERIOD_NSEC;
635 
637  {
638  DBG ("callback type memif_control_fd_update_t error!");
639  err = MEMIF_ERR_CB_FDUPDATE;
640  goto error;
641  }
642 
643  /* Create default socket */
645  lm->default_socket,
647  if (err != MEMIF_ERR_SUCCESS)
648  goto error;
649 
650  return err;
651 
652 error:
653  memif_cleanup ();
654  return err;
655 }
656 
657 int
659  void *private_ctx,
660  memif_control_fd_update_t * on_control_fd_update,
661  char *app_name, memif_alloc_t * memif_alloc,
662  memif_realloc_t * memif_realloc,
663  memif_free_t * memif_free)
664 {
666  int i;
667  libmemif_main_t *lm;
668 
669  /* Allocate unique libmemif main */
670  if (memif_alloc != NULL)
671  lm = memif_alloc (sizeof (libmemif_main_t));
672  else
673  lm = malloc (sizeof (libmemif_main_t));
674 
675  if (lm == NULL)
676  return MEMIF_ERR_NOMEM;
677 
678  memset (lm, 0, sizeof (libmemif_main_t));
679 
680  /* register custom memory management */
681  if (memif_alloc != NULL)
682  {
683  memif_alloc_register (lm, memif_alloc);
684  }
685  else
686  memif_alloc_register (lm, malloc);
687 
688  if (memif_realloc != NULL)
689  {
690  memif_realloc_register (lm, memif_realloc);
691  }
692  else
693  memif_realloc_register (lm, realloc);
694 
695  if (memif_free != NULL)
696  memif_free_register (lm, memif_free);
697  else
698  memif_free_register (lm, free);
699 
700  lm->private_ctx = private_ctx;
701 
702  /* set app name */
703  if (app_name != NULL)
704  {
705  uint8_t len = (strlen (app_name) > MEMIF_NAME_LEN)
706  ? strlen (app_name) : MEMIF_NAME_LEN;
707  strncpy ((char *) lm->app_name, app_name, len);
708  }
709  else
710  {
711  strncpy ((char *) lm->app_name, MEMIF_DEFAULT_APP_NAME,
712  strlen (MEMIF_DEFAULT_APP_NAME));
713  }
714 
715  lm->poll_cancel_fd = -1;
716  /* register control fd update callback */
717  if (on_control_fd_update != NULL)
718  memif_control_fd_update_register (lm, on_control_fd_update);
719  else
720  {
721  lm->epfd = epoll_create (1);
723  if ((lm->poll_cancel_fd = eventfd (0, EFD_NONBLOCK)) < 0)
724  {
725  err = errno;
726  DBG ("eventfd: %s", strerror (err));
727  return memif_syscall_error_handler (err);
728  }
730  lm->private_ctx);
731  DBG ("libmemif event polling initialized");
732  }
733 
734  /* Initialize lists */
735  lm->control_list_len = 2;
736  lm->interrupt_list_len = 2;
737  lm->socket_list_len = 1;
738  lm->pending_list_len = 1;
739 
740  lm->control_list =
741  lm->alloc (sizeof (memif_list_elt_t) * lm->control_list_len);
742  if (lm->control_list == NULL)
743  {
744  err = MEMIF_ERR_NOMEM;
745  goto error;
746  }
747  lm->interrupt_list =
748  lm->alloc (sizeof (memif_list_elt_t) * lm->interrupt_list_len);
749  if (lm->interrupt_list == NULL)
750  {
751  err = MEMIF_ERR_NOMEM;
752  goto error;
753  }
754  lm->socket_list =
755  lm->alloc (sizeof (memif_list_elt_t) * lm->socket_list_len);
756  if (lm->socket_list == NULL)
757  {
758  err = MEMIF_ERR_NOMEM;
759  goto error;
760  }
761  lm->pending_list =
762  lm->alloc (sizeof (memif_list_elt_t) * lm->pending_list_len);
763  if (lm->pending_list == NULL)
764  {
765  err = MEMIF_ERR_NOMEM;
766  goto error;
767  }
768 
769  for (i = 0; i < lm->control_list_len; i++)
770  {
771  lm->control_list[i].key = -1;
773  }
774  for (i = 0; i < lm->interrupt_list_len; i++)
775  {
776  lm->interrupt_list[i].key = -1;
778  }
779  for (i = 0; i < lm->socket_list_len; i++)
780  {
781  lm->socket_list[i].key = -1;
782  lm->socket_list[i].data_struct = NULL;
783  }
784  for (i = 0; i < lm->pending_list_len; i++)
785  {
786  lm->pending_list[i].key = -1;
788  }
789 
790  /* Initialize autoconnect */
791  lm->disconn_slaves = 0;
792 
793  lm->timerfd = timerfd_create (CLOCK_REALTIME, TFD_NONBLOCK);
794  if (lm->timerfd < 0)
795  {
796  err = memif_syscall_error_handler (errno);
797  goto error;
798  }
799 
800  lm->arm.it_value.tv_sec = MEMIF_DEFAULT_RECONNECT_PERIOD_SEC;
801  lm->arm.it_value.tv_nsec = MEMIF_DEFAULT_RECONNECT_PERIOD_NSEC;
802  lm->arm.it_interval.tv_sec = MEMIF_DEFAULT_RECONNECT_PERIOD_SEC;
803  lm->arm.it_interval.tv_nsec = MEMIF_DEFAULT_RECONNECT_PERIOD_NSEC;
804 
806  lm->private_ctx) < 0)
807  {
808  DBG ("callback type memif_control_fd_update_t error!");
809  err = MEMIF_ERR_CB_FDUPDATE;
810  goto error;
811  }
812 
813  *pt_main = lm;
814 
815  return err;
816 
817 error:
818  *pt_main = lm;
819  memif_per_thread_cleanup (pt_main);
820  return err;
821 }
822 
823 static inline memif_ring_t *
825  uint16_t ring_num)
826 {
827  if (&conn->regions[0] == NULL)
828  return NULL;
829  void *p = conn->regions[0].addr;
830  int ring_size =
831  sizeof (memif_ring_t) +
832  sizeof (memif_desc_t) * (1 << conn->run_args.log2_ring_size);
833  p += (ring_num + type * conn->run_args.num_s2m_rings) * ring_size;
834 
835  return (memif_ring_t *) p;
836 }
837 
838 int
840  uint16_t qid)
841 {
843  if (conn == NULL)
844  return MEMIF_ERR_NOCONN;
845  uint8_t num =
846  (conn->args.is_master) ? conn->run_args.num_s2m_rings : conn->
847  run_args.num_m2s_rings;
848  if (qid >= num)
849  return MEMIF_ERR_QID;
850 
851  conn->rx_queues[qid].ring->flags = rx_mode;
852  DBG ("rx_mode flag: %u", conn->rx_queues[qid].ring->flags);
853  return MEMIF_ERR_SUCCESS;
854 }
855 
856 static int
858 {
860  memif_list_elt_t elt;
861  struct stat file_stat;
862  struct sockaddr_un un = { 0 };
863  int on = 1;
864  int err = MEMIF_ERR_SUCCESS;
865 
866  if (ms->type == MEMIF_SOCKET_TYPE_CLIENT)
867  return MEMIF_ERR_INVAL_ARG;
868 
869  /* check if file exists */
870  if (stat ((char *) ms->filename, &file_stat) == 0)
871  {
872  if (S_ISSOCK (file_stat.st_mode))
873  unlink ((char *) ms->filename);
874  else
875  return memif_syscall_error_handler (errno);
876  }
877 
878  ms->fd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
879  if (ms->fd < 0)
880  {
881  err = memif_syscall_error_handler (errno);
882  goto error;
883  }
884 
885  DBG ("socket %d created", ms->fd);
886  un.sun_family = AF_UNIX;
887  strncpy ((char *) un.sun_path, (char *) ms->filename,
888  sizeof (un.sun_path) - 1);
889  if (setsockopt (ms->fd, SOL_SOCKET, SO_PASSCRED, &on, sizeof (on)) < 0)
890  {
891  err = memif_syscall_error_handler (errno);
892  goto error;
893  }
894  if (bind (ms->fd, (struct sockaddr *) &un, sizeof (un)) < 0)
895  {
896  err = memif_syscall_error_handler (errno);
897  goto error;
898  }
899  if (listen (ms->fd, 1) < 0)
900  {
901  err = memif_syscall_error_handler (errno);
902  goto error;
903  }
904  if (stat ((char *) ms->filename, &file_stat) < 0)
905  {
906  err = memif_syscall_error_handler (errno);
907  goto error;
908  }
909 
910  /* add socket to libmemif main */
911  elt.key = ms->fd;
912  elt.data_struct = ms;
913  add_list_elt (lm, &elt, &lm->socket_list, &lm->socket_list_len);
915 
917 
918  return err;
919 
920 error:
921  if (ms->fd > 0)
922  {
923  close (ms->fd);
924  ms->fd = -1;
925  }
926  return err;
927 }
928 
929 int
930 memif_create_socket (memif_socket_handle_t * sock, const char *filename,
931  void *private_ctx)
932 {
934  memif_socket_t *ms = (memif_socket_t *) * sock;
935  int i, err = MEMIF_ERR_SUCCESS;
936 
937  for (i = 0; i < lm->socket_list_len; i++)
938  {
939  if ((ms = (memif_socket_t *) lm->socket_list[i].data_struct) != NULL)
940  {
941  if (strncmp ((char *) ms->filename, filename,
942  strlen ((char *) ms->filename)) == 0)
943  return MEMIF_ERR_INVAL_ARG;
944  }
945  }
946 
947  /* allocate memif_socket_t */
948  ms = NULL;
949  ms = lm->alloc (sizeof (memif_socket_t));
950  if (ms == NULL)
951  {
952  err = MEMIF_ERR_NOMEM;
953  goto error;
954  }
955  memset (ms, 0, sizeof (memif_socket_t));
956  /* set filename */
957  ms->filename = lm->alloc (strlen (filename) + sizeof (char));
958  if (ms->filename == NULL)
959  {
960  err = MEMIF_ERR_NOMEM;
961  goto error;
962  }
963  memset (ms->filename, 0, strlen (filename) + sizeof (char));
964  strncpy ((char *) ms->filename, filename, strlen (filename));
965 
967 
968  ms->interface_list_len = 1;
969  ms->interface_list =
970  lm->alloc (sizeof (memif_list_elt_t) * ms->interface_list_len);
971  if (ms->interface_list == NULL)
972  {
973  err = MEMIF_ERR_NOMEM;
974  goto error;
975  }
976  ms->interface_list[0].key = -1;
978 
979  *sock = ms;
980 
981  return err;
982 
983 error:
984  if (ms != NULL)
985  {
986  if (ms->filename != NULL)
987  {
988  lm->free (ms->filename);
989  ms->filename = NULL;
990  }
991  if (ms->fd > 0)
992  {
993  close (ms->fd);
994  ms->fd = -1;
995  }
996  if (ms->interface_list != NULL)
997  {
998  lm->free (ms->interface_list);
999  ms->interface_list = NULL;
1000  ms->interface_list_len = 0;
1001  }
1002  lm->free (ms);
1003  *sock = ms = NULL;
1004  }
1005  return err;
1006 }
1007 
1008 int
1010  memif_socket_handle_t * sock,
1011  const char *filename, void *private_ctx)
1012 {
1013  libmemif_main_t *lm = (libmemif_main_t *) pt_main;
1014  memif_socket_t *ms = (memif_socket_t *) * sock;
1015  int i, err = MEMIF_ERR_SUCCESS;
1016 
1017  if (lm == NULL)
1018  return MEMIF_ERR_INVAL_ARG;
1019 
1020  for (i = 0; i < lm->socket_list_len; i++)
1021  {
1022  if ((ms = (memif_socket_t *) lm->socket_list[i].data_struct) != NULL)
1023  {
1024  if (strncmp ((char *) ms->filename, filename,
1025  strlen ((char *) ms->filename)) == 0)
1026  return MEMIF_ERR_INVAL_ARG;
1027  }
1028  }
1029 
1030  /* allocate memif_socket_t */
1031  ms = NULL;
1032  ms = lm->alloc (sizeof (memif_socket_t));
1033  if (ms == NULL)
1034  {
1035  err = MEMIF_ERR_NOMEM;
1036  goto error;
1037  }
1038  memset (ms, 0, sizeof (memif_socket_t));
1039  ms->lm = lm;
1040  /* set filename */
1041  ms->filename = lm->alloc (strlen (filename) + sizeof (char));
1042  if (ms->filename == NULL)
1043  {
1044  err = MEMIF_ERR_NOMEM;
1045  goto error;
1046  }
1047  memset (ms->filename, 0, strlen (filename) + sizeof (char));
1048  strncpy ((char *) ms->filename, filename, strlen (filename));
1049 
1051 
1052  ms->interface_list_len = 1;
1053  ms->interface_list =
1054  lm->alloc (sizeof (memif_list_elt_t) * ms->interface_list_len);
1055  if (ms->interface_list == NULL)
1056  {
1057  err = MEMIF_ERR_NOMEM;
1058  goto error;
1059  }
1060  ms->interface_list[0].key = -1;
1061  ms->interface_list[0].data_struct = NULL;
1062 
1063  *sock = ms;
1064 
1065  return err;
1066 
1067 error:
1068  if (ms != NULL)
1069  {
1070  if (ms->filename != NULL)
1071  {
1072  lm->free (ms->filename);
1073  ms->filename = NULL;
1074  }
1075  if (ms->fd > 0)
1076  {
1077  close (ms->fd);
1078  ms->fd = -1;
1079  }
1080  if (ms->interface_list != NULL)
1081  {
1082  lm->free (ms->interface_list);
1083  ms->interface_list = NULL;
1084  ms->interface_list_len = 0;
1085  }
1086  lm->free (ms);
1087  *sock = ms = NULL;
1088  }
1089  return err;
1090 }
1091 
1092 int
1096  memif_interrupt_t * on_interrupt, void *private_ctx)
1097 {
1099  int err, index = 0;
1100  memif_list_elt_t elt;
1101  memif_connection_t *conn = (memif_connection_t *) * c;
1102  memif_socket_t *ms;
1103 
1104  if (conn != NULL)
1105  {
1106  DBG ("This handle already points to existing memif.");
1107  return MEMIF_ERR_CONN;
1108  }
1109 
1110  conn = (memif_connection_t *) lm->alloc (sizeof (memif_connection_t));
1111  if (conn == NULL)
1112  {
1113  err = MEMIF_ERR_NOMEM;
1114  goto error;
1115  }
1116  memset (conn, 0, sizeof (memif_connection_t));
1117 
1118  conn->args.interface_id = args->interface_id;
1119 
1120  if (args->log2_ring_size == 0)
1122  else if (args->log2_ring_size > MEMIF_MAX_LOG2_RING_SIZE)
1123  {
1124  err = MEMIF_ERR_MAX_RING;
1125  goto error;
1126  }
1127  if (args->buffer_size == 0)
1129  if (args->num_s2m_rings == 0)
1131  if (args->num_m2s_rings == 0)
1133 
1134  conn->args.num_s2m_rings = args->num_s2m_rings;
1135  conn->args.num_m2s_rings = args->num_m2s_rings;
1136  conn->args.buffer_size = args->buffer_size;
1137  conn->args.log2_ring_size = args->log2_ring_size;
1138  conn->args.is_master = args->is_master;
1139  conn->args.mode = args->mode;
1140  conn->msg_queue = NULL;
1141  conn->regions = NULL;
1142  conn->tx_queues = NULL;
1143  conn->rx_queues = NULL;
1144  conn->fd = -1;
1145  conn->on_connect = on_connect;
1146  conn->on_disconnect = on_disconnect;
1147  conn->on_interrupt = on_interrupt;
1148  conn->private_ctx = private_ctx;
1149  memset (&conn->run_args, 0, sizeof (memif_conn_run_args_t));
1150 
1151  uint8_t l = strlen ((char *) args->interface_name);
1152  strncpy ((char *) conn->args.interface_name, (char *) args->interface_name,
1153  l);
1154 
1155  if ((l = strlen ((char *) args->secret)) > 0)
1156  strncpy ((char *) conn->args.secret, (char *) args->secret, l);
1157 
1158  if (args->socket != NULL)
1159  conn->args.socket = args->socket;
1160  else if (lm->default_socket != NULL)
1161  conn->args.socket = lm->default_socket;
1162  else
1163  {
1164  err = MEMIF_ERR_INVAL_ARG;
1165  goto error;
1166  }
1167 
1168  ms = (memif_socket_t *) conn->args.socket;
1169 
1170  if ((conn->args.is_master && ms->type == MEMIF_SOCKET_TYPE_CLIENT) ||
1171  (!conn->args.is_master && ms->type == MEMIF_SOCKET_TYPE_LISTENER))
1172  {
1173  err = MEMIF_ERR_INVAL_ARG;
1174  goto error;
1175  }
1176 
1177  elt.key = conn->args.interface_id;
1178  elt.data_struct = conn;
1179  add_list_elt (lm, &elt, &ms->interface_list, &ms->interface_list_len);
1180  ms->use_count++;
1181 
1182  if (conn->args.is_master)
1183  {
1184  if (ms->type == MEMIF_SOCKET_TYPE_NONE)
1185  {
1186  err = memif_socket_start_listening (ms);
1187  if (err != MEMIF_ERR_SUCCESS)
1188  goto error;
1189  }
1190  }
1191  else
1192  {
1193  elt.key = -1;
1194  elt.data_struct = conn;
1195  if ((index =
1196  add_list_elt (lm, &elt, &lm->control_list,
1197  &lm->control_list_len)) < 0)
1198  {
1199  err = MEMIF_ERR_NOMEM;
1200  goto error;
1201  }
1202 
1203  conn->index = index;
1204 
1205  /* try connectiong to master */
1206  err = memif_request_connection (conn);
1207  if ((err != MEMIF_ERR_SUCCESS) && (lm->disconn_slaves == 0))
1208  {
1209  /* connection failed, arm reconnect timer (if not armed) */
1210  if (timerfd_settime (lm->timerfd, 0, &lm->arm, NULL) < 0)
1211  {
1212  err = memif_syscall_error_handler (errno);
1213  goto error;
1214  }
1215  }
1216  lm->disconn_slaves++;
1217  }
1218 
1219  *c = conn;
1220 
1221  return 0;
1222 
1223 error:
1224  if (conn != NULL)
1225  lm->free (conn);
1226  *c = conn = NULL;
1227  return err;
1228 }
1229 
1230 int
1232 {
1233  memif_connection_t *conn = (memif_connection_t *) c;
1234  libmemif_main_t *lm;
1235  memif_socket_t *ms;
1236  int err = MEMIF_ERR_SUCCESS;
1237  int sockfd = -1;
1238  struct sockaddr_un sun;
1239 
1240  if (conn == NULL)
1241  return MEMIF_ERR_NOCONN;
1242 
1243  ms = (memif_socket_t *) conn->args.socket;
1244  lm = get_libmemif_main (ms);
1245 
1246 
1247  if (conn->args.is_master || ms->type == MEMIF_SOCKET_TYPE_LISTENER)
1248  return MEMIF_ERR_INVAL_ARG;
1249  if (conn->fd > 0)
1250  return MEMIF_ERR_ALRCONN;
1251 
1252  sockfd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
1253  if (sockfd < 0)
1254  {
1255  err = memif_syscall_error_handler (errno);
1256  goto error;
1257  }
1258 
1259  sun.sun_family = AF_UNIX;
1260 
1261  strncpy (sun.sun_path, (char *) ms->filename, sizeof (sun.sun_path) - 1);
1262 
1263  if (connect (sockfd, (struct sockaddr *) &sun,
1264  sizeof (struct sockaddr_un)) == 0)
1265  {
1266  conn->fd = sockfd;
1267  conn->read_fn = memif_conn_fd_read_ready;
1268  conn->write_fn = memif_conn_fd_write_ready;
1269  conn->error_fn = memif_conn_fd_error;
1270 
1271  lm->control_list[conn->index].key = conn->fd;
1272 
1273  lm->control_fd_update (sockfd,
1275  MEMIF_FD_EVENT_WRITE, conn->private_ctx);
1276 
1277  lm->disconn_slaves--;
1278  if (lm->disconn_slaves == 0)
1279  {
1280  if (timerfd_settime (lm->timerfd, 0, &lm->disarm, NULL) < 0)
1281  {
1282  err = memif_syscall_error_handler (errno);
1283  return err;
1284  }
1285  }
1286  }
1287  else
1288  {
1289  err = memif_syscall_error_handler (errno);
1290  strcpy ((char *) conn->remote_disconnect_string, memif_strerror (err));
1291  goto error;
1292  }
1293 
1295 
1296  return err;
1297 
1298 error:
1299  if (sockfd > 0)
1300  close (sockfd);
1301  sockfd = -1;
1302  return err;
1303 }
1304 
1305 int
1306 memif_control_fd_handler (int fd, uint8_t events)
1307 {
1308  int i, err = MEMIF_ERR_SUCCESS; /* 0 */
1309  uint16_t num;
1310  memif_list_elt_t *e = NULL;
1311  memif_connection_t *conn;
1313  if (fd == lm->timerfd)
1314  {
1315  uint64_t b;
1316  ssize_t size;
1317  size = read (fd, &b, sizeof (b));
1318 
1319  if (size == -1)
1320  goto error;
1321 
1322  for (i = 0; i < lm->control_list_len; i++)
1323  {
1324  if ((lm->control_list[i].key < 0)
1325  && (lm->control_list[i].data_struct != NULL))
1326  {
1327  conn = lm->control_list[i].data_struct;
1328  if (conn->args.is_master)
1329  continue;
1330  err = memif_request_connection (conn);
1331  if (err != MEMIF_ERR_SUCCESS)
1332  DBG ("memif_request_connection: %s", memif_strerror (err));
1333  }
1334  }
1335  }
1336  else
1337  {
1338  get_list_elt (&e, lm->interrupt_list, lm->interrupt_list_len, fd);
1339  if (e != NULL)
1340  {
1341  if (((memif_connection_t *) e->data_struct)->on_interrupt != NULL)
1342  {
1343  num =
1344  (((memif_connection_t *) e->data_struct)->
1345  args.is_master) ? ((memif_connection_t *) e->
1346  data_struct)->run_args.
1347  num_s2m_rings : ((memif_connection_t *) e->data_struct)->
1348  run_args.num_m2s_rings;
1349  for (i = 0; i < num; i++)
1350  {
1351  if (((memif_connection_t *) e->data_struct)->
1352  rx_queues[i].int_fd == fd)
1353  {
1354  ((memif_connection_t *) e->data_struct)->
1355  on_interrupt ((void *) e->data_struct,
1356  ((memif_connection_t *) e->
1357  data_struct)->private_ctx, i);
1358  return MEMIF_ERR_SUCCESS;
1359  }
1360  }
1361  }
1362  return MEMIF_ERR_SUCCESS;
1363  }
1364  get_list_elt (&e, lm->socket_list, lm->socket_list_len, fd);
1365  if (e != NULL
1366  && ((memif_socket_t *) e->data_struct)->type ==
1368  {
1369  err =
1371  return err;
1372  }
1373 
1374  get_list_elt (&e, lm->pending_list, lm->pending_list_len, fd);
1375  if (e != NULL)
1376  {
1377  err = memif_read_ready (lm, fd);
1378  return err;
1379  }
1380 
1381  get_list_elt (&e, lm->control_list, lm->control_list_len, fd);
1382  if (e != NULL)
1383  {
1384  if (events & MEMIF_FD_EVENT_READ)
1385  {
1386  err =
1387  ((memif_connection_t *) e->data_struct)->
1388  read_fn (e->data_struct);
1389  if (err != MEMIF_ERR_SUCCESS)
1390  return err;
1391  }
1392  if (events & MEMIF_FD_EVENT_WRITE)
1393  {
1394  err =
1395  ((memif_connection_t *) e->data_struct)->
1396  write_fn (e->data_struct);
1397  if (err != MEMIF_ERR_SUCCESS)
1398  return err;
1399  }
1400  if (events & MEMIF_FD_EVENT_ERROR)
1401  {
1402  err =
1403  ((memif_connection_t *) e->data_struct)->
1404  error_fn (e->data_struct);
1405  if (err != MEMIF_ERR_SUCCESS)
1406  return err;
1407  }
1408  }
1409  }
1410 
1411  return MEMIF_ERR_SUCCESS; /* 0 */
1412 
1413 error:
1414  return err;
1415 }
1416 
1417 int
1419  int fd, uint8_t events)
1420 {
1421  int i, err = MEMIF_ERR_SUCCESS; /* 0 */
1422  uint16_t num;
1423  memif_list_elt_t *e = NULL;
1424  memif_connection_t *conn;
1425  libmemif_main_t *lm = (libmemif_main_t *) pt_main;
1426 
1427  if (fd == lm->timerfd)
1428  {
1429  uint64_t b;
1430  ssize_t size;
1431  size = read (fd, &b, sizeof (b));
1432 
1433  if (size == -1)
1434  goto error;
1435 
1436  for (i = 0; i < lm->control_list_len; i++)
1437  {
1438  if ((lm->control_list[i].key < 0)
1439  && (lm->control_list[i].data_struct != NULL))
1440  {
1441  conn = lm->control_list[i].data_struct;
1442  if (conn->args.is_master)
1443  continue;
1444  err = memif_request_connection (conn);
1445  if (err != MEMIF_ERR_SUCCESS)
1446  DBG ("memif_request_connection: %s", memif_strerror (err));
1447  }
1448  }
1449  }
1450  else
1451  {
1452  get_list_elt (&e, lm->interrupt_list, lm->interrupt_list_len, fd);
1453  if (e != NULL)
1454  {
1455  if (((memif_connection_t *) e->data_struct)->on_interrupt != NULL)
1456  {
1457  num =
1458  (((memif_connection_t *) e->data_struct)->
1459  args.is_master) ? ((memif_connection_t *) e->
1460  data_struct)->run_args.
1461  num_s2m_rings : ((memif_connection_t *) e->data_struct)->
1462  run_args.num_m2s_rings;
1463  for (i = 0; i < num; i++)
1464  {
1465  if (((memif_connection_t *) e->data_struct)->
1466  rx_queues[i].int_fd == fd)
1467  {
1468  ((memif_connection_t *) e->data_struct)->
1469  on_interrupt ((void *) e->data_struct,
1470  ((memif_connection_t *) e->
1471  data_struct)->private_ctx, i);
1472  return MEMIF_ERR_SUCCESS;
1473  }
1474  }
1475  }
1476  return MEMIF_ERR_SUCCESS;
1477  }
1478  get_list_elt (&e, lm->socket_list, lm->socket_list_len, fd);
1479  if (e != NULL
1480  && ((memif_socket_t *) e->data_struct)->type ==
1482  {
1483  err =
1485  return err;
1486  }
1487 
1488  get_list_elt (&e, lm->pending_list, lm->pending_list_len, fd);
1489  if (e != NULL)
1490  {
1491  err = memif_read_ready (lm, fd);
1492  return err;
1493  }
1494 
1495  get_list_elt (&e, lm->control_list, lm->control_list_len, fd);
1496  if (e != NULL)
1497  {
1498  if (events & MEMIF_FD_EVENT_READ)
1499  {
1500  err =
1501  ((memif_connection_t *) e->data_struct)->
1502  read_fn (e->data_struct);
1503  if (err != MEMIF_ERR_SUCCESS)
1504  return err;
1505  }
1506  if (events & MEMIF_FD_EVENT_WRITE)
1507  {
1508  err =
1509  ((memif_connection_t *) e->data_struct)->
1510  write_fn (e->data_struct);
1511  if (err != MEMIF_ERR_SUCCESS)
1512  return err;
1513  }
1514  if (events & MEMIF_FD_EVENT_ERROR)
1515  {
1516  err =
1517  ((memif_connection_t *) e->data_struct)->
1518  error_fn (e->data_struct);
1519  if (err != MEMIF_ERR_SUCCESS)
1520  return err;
1521  }
1522  }
1523  }
1524 
1525  return MEMIF_ERR_SUCCESS; /* 0 */
1526 
1527 error:
1528  return err;
1529 }
1530 
1531 int
1532 memif_poll_event (int timeout)
1533 {
1535  struct epoll_event evt;
1536  int en = 0, err = MEMIF_ERR_SUCCESS; /* 0 */
1537  uint32_t events = 0;
1538  uint64_t counter = 0;
1539  ssize_t r = 0;
1540  memset (&evt, 0, sizeof (evt));
1541  evt.events = EPOLLIN | EPOLLOUT;
1542  sigset_t sigset;
1543  sigemptyset (&sigset);
1544  en = epoll_pwait (lm->epfd, &evt, 1, timeout, &sigset);
1545  if (en < 0)
1546  {
1547  err = errno;
1548  DBG ("epoll_pwait: %s", strerror (err));
1549  return memif_syscall_error_handler (err);
1550  }
1551  if (en > 0)
1552  {
1553  if (evt.data.fd == lm->poll_cancel_fd)
1554  {
1555  r = read (evt.data.fd, &counter, sizeof (counter));
1556  if (r == -1)
1557  return MEMIF_ERR_DISCONNECTED;
1558 
1559  return MEMIF_ERR_POLL_CANCEL;
1560  }
1561  if (evt.events & EPOLLIN)
1562  events |= MEMIF_FD_EVENT_READ;
1563  if (evt.events & EPOLLOUT)
1564  events |= MEMIF_FD_EVENT_WRITE;
1565  if (evt.events & EPOLLERR)
1566  events |= MEMIF_FD_EVENT_ERROR;
1567  err = memif_control_fd_handler (evt.data.fd, events);
1568  return err;
1569  }
1570  return 0;
1571 }
1572 
1573 int
1575  int timeout)
1576 {
1577  libmemif_main_t *lm = (libmemif_main_t *) pt_main;
1578  struct epoll_event evt;
1579  int en = 0, err = MEMIF_ERR_SUCCESS; /* 0 */
1580  uint32_t events = 0;
1581  uint64_t counter = 0;
1582  ssize_t r = 0;
1583  memset (&evt, 0, sizeof (evt));
1584  evt.events = EPOLLIN | EPOLLOUT;
1585  sigset_t sigset;
1586  sigemptyset (&sigset);
1587  en = epoll_pwait (lm->epfd, &evt, 1, timeout, &sigset);
1588  if (en < 0)
1589  {
1590  err = errno;
1591  DBG ("epoll_pwait: %s", strerror (err));
1592  return memif_syscall_error_handler (err);
1593  }
1594  if (en > 0)
1595  {
1596  if (evt.data.fd == lm->poll_cancel_fd)
1597  {
1598  r = read (evt.data.fd, &counter, sizeof (counter));
1599  if (r == -1)
1600  return MEMIF_ERR_DISCONNECTED;
1601 
1602  return MEMIF_ERR_POLL_CANCEL;
1603  }
1604  if (evt.events & EPOLLIN)
1605  events |= MEMIF_FD_EVENT_READ;
1606  if (evt.events & EPOLLOUT)
1607  events |= MEMIF_FD_EVENT_WRITE;
1608  if (evt.events & EPOLLERR)
1609  events |= MEMIF_FD_EVENT_ERROR;
1610  err = memif_control_fd_handler (evt.data.fd, events);
1611  return err;
1612  }
1613  return 0;
1614 }
1615 
1616 int
1618 {
1620  uint64_t counter = 1;
1621  ssize_t w = 0;
1622 
1623  if (lm->poll_cancel_fd == -1)
1624  return 0;
1625  w = write (lm->poll_cancel_fd, &counter, sizeof (counter));
1626  if (w < sizeof (counter))
1627  return MEMIF_ERR_INT_WRITE;
1628 
1629  return 0;
1630 }
1631 
1632 int
1634 {
1635  libmemif_main_t *lm = (libmemif_main_t *) pt_main;
1636  uint64_t counter = 1;
1637  ssize_t w = 0;
1638 
1639  if (lm == NULL)
1640  return MEMIF_ERR_INVAL_ARG;
1641 
1642  if (lm->poll_cancel_fd == -1)
1643  return 0;
1644  w = write (lm->poll_cancel_fd, &counter, sizeof (counter));
1645  if (w < sizeof (counter))
1646  return MEMIF_ERR_INT_WRITE;
1647 
1648  return 0;
1649 }
1650 
1651 static void
1653 {
1654  if (*e == NULL)
1655  return;
1656  memif_msg_queue_free (lm, &(*e)->next);
1657  lm->free (*e);
1658  *e = NULL;
1659  return;
1660 }
1661 
1662 /* send disconnect msg and close interface */
1663 int
1665 {
1666  int err = MEMIF_ERR_SUCCESS, i; /* 0 */
1667  memif_queue_t *mq;
1668  libmemif_main_t *lm;
1669  memif_list_elt_t *e;
1670 
1671  if (c == NULL)
1672  {
1673  DBG ("no connection");
1674  return MEMIF_ERR_NOCONN;
1675  }
1676 
1677  lm = get_libmemif_main (c->args.socket);
1678 
1679  c->on_disconnect ((void *) c, c->private_ctx);
1680 
1681  if (c->fd > 0)
1682  {
1683  memif_msg_send_disconnect (c->fd, (uint8_t *) "interface deleted", 0);
1684  lm->control_fd_update (c->fd, MEMIF_FD_EVENT_DEL, c->private_ctx);
1685  close (c->fd);
1686  }
1687  get_list_elt (&e, lm->control_list, lm->control_list_len, c->fd);
1688  if (e != NULL)
1689  {
1690  if (c->args.is_master)
1691  free_list_elt (lm->control_list, lm->control_list_len, c->fd);
1692  e->key = c->fd = -1;
1693  }
1694 
1695  if (c->tx_queues != NULL)
1696  {
1697  for (i = 0; i < c->tx_queues_num; i++)
1698  {
1699  mq = &c->tx_queues[i];
1700  if (mq != NULL)
1701  {
1702  if (mq->int_fd > 0)
1703  close (mq->int_fd);
1705  mq->int_fd);
1706  mq->int_fd = -1;
1707  }
1708  }
1709  lm->free (c->tx_queues);
1710  c->tx_queues = NULL;
1711  }
1712  c->tx_queues_num = 0;
1713 
1714  if (c->rx_queues != NULL)
1715  {
1716  for (i = 0; i < c->rx_queues_num; i++)
1717  {
1718  mq = &c->rx_queues[i];
1719  if (mq != NULL)
1720  {
1721  if (mq->int_fd > 0)
1722  {
1723  if (c->on_interrupt != NULL)
1725  c->private_ctx);
1726  close (mq->int_fd);
1727  }
1729  mq->int_fd);
1730  mq->int_fd = -1;
1731  }
1732  }
1733  lm->free (c->rx_queues);
1734  c->rx_queues = NULL;
1735  }
1736  c->rx_queues_num = 0;
1737 
1738  for (i = 0; i < c->regions_num; i++)
1739  {
1740  if (&c->regions[i] == NULL)
1741  continue;
1742  if (c->regions[i].is_external != 0)
1743  {
1744  lm->del_external_region (c->regions[i].addr,
1745  c->regions[i].region_size,
1746  c->regions[i].fd, c->private_ctx);
1747  }
1748  else
1749  {
1750  if (munmap (c->regions[i].addr, c->regions[i].region_size) < 0)
1751  return memif_syscall_error_handler (errno);
1752  if (c->regions[i].fd > 0)
1753  close (c->regions[i].fd);
1754  c->regions[i].fd = -1;
1755  }
1756  }
1757  lm->free (c->regions);
1758  c->regions = NULL;
1759  c->regions_num = 0;
1760 
1761  memset (&c->run_args, 0, sizeof (memif_conn_run_args_t));
1762 
1763  memif_msg_queue_free (lm, &c->msg_queue);
1764 
1765  if (!(c->args.is_master))
1766  {
1767  if (lm->disconn_slaves == 0)
1768  {
1769  if (timerfd_settime (lm->timerfd, 0, &lm->arm, NULL) < 0)
1770  {
1771  err = memif_syscall_error_handler (errno);
1772  DBG ("timerfd_settime: arm");
1773  }
1774  }
1775  lm->disconn_slaves++;
1776  }
1777 
1778  return err;
1779 }
1780 
1781 const char *
1783 {
1784  memif_socket_t *ms = (memif_socket_t *) sock;
1785 
1786  if (ms == NULL)
1787  return NULL;
1788 
1789  return (char *) ms->filename;
1790 }
1791 
1792 int
1794 {
1795  memif_socket_t *ms = (memif_socket_t *) * sock;
1796  libmemif_main_t *lm;
1797 
1798  /* check if socket is in use */
1799  if (ms == NULL || ms->use_count > 0)
1800  return MEMIF_ERR_INVAL_ARG;
1801 
1802  lm = get_libmemif_main (ms);
1803 
1804  lm->free (ms->interface_list);
1805  ms->interface_list = NULL;
1806  lm->free (ms->filename);
1807  ms->filename = NULL;
1808  lm->free (ms);
1809  *sock = ms = NULL;
1810 
1811  return MEMIF_ERR_SUCCESS;
1812 }
1813 
1814 int
1816 {
1817  memif_connection_t *c = (memif_connection_t *) * conn;
1818  libmemif_main_t *lm;
1819  memif_socket_t *ms = NULL;
1820  int err = MEMIF_ERR_SUCCESS;
1821 
1822  if (c == NULL)
1823  {
1824  DBG ("no connection");
1825  return MEMIF_ERR_NOCONN;
1826  }
1827 
1828  if (c->fd > 0)
1829  {
1830  DBG ("DISCONNECTING");
1831  err = memif_disconnect_internal (c);
1832  if (err == MEMIF_ERR_NOCONN)
1833  return err;
1834  }
1835 
1836  lm = get_libmemif_main (c->args.socket);
1837 
1839 
1840  ms = (memif_socket_t *) c->args.socket;
1841  ms->use_count--;
1843  c->args.interface_id);
1844  if (ms->use_count <= 0)
1845  {
1846  /* stop listening on this socket */
1847  if (ms->type == MEMIF_SOCKET_TYPE_LISTENER)
1848  {
1850  free_list_elt (lm->socket_list, lm->socket_list_len, ms->fd);
1851  close (ms->fd);
1852  ms->fd = -1;
1853  }
1854  /* socket not in use */
1856  }
1857 
1858  if (!c->args.is_master)
1859  {
1860  lm->disconn_slaves--;
1861  if (lm->disconn_slaves <= 0)
1862  {
1863  if (timerfd_settime (lm->timerfd, 0, &lm->disarm, NULL) < 0)
1864  {
1865  err = memif_syscall_error_handler (errno);
1866  DBG ("timerfd_settime: disarm");
1867  }
1868  }
1869  }
1870 
1871  lm->free (c);
1872  c = NULL;
1873 
1874  *conn = c;
1875  return err;
1876 }
1877 
1878 int
1880 {
1881  libmemif_main_t *lm;
1882  memif_region_t *mr;
1883  memif_queue_t *mq;
1884  int i;
1885 
1886  if (c == NULL)
1887  return MEMIF_ERR_INVAL_ARG;
1888 
1889  lm = get_libmemif_main (c->args.socket);
1890 
1891  for (i = 0; i < c->regions_num; i++)
1892  {
1893  mr = &c->regions[i];
1894  if (mr != NULL)
1895  {
1896  if (!mr->addr)
1897  {
1898  if (mr->is_external)
1899  {
1900  if (lm->get_external_region_addr == NULL)
1901  return MEMIF_ERR_INVAL_ARG;
1902  mr->addr =
1903  lm->get_external_region_addr (mr->region_size, mr->fd,
1904  c->private_ctx);
1905  }
1906  else
1907  {
1908  if (mr->fd < 0)
1909  return MEMIF_ERR_NO_SHMFD;
1910 
1911  if ((mr->addr =
1912  mmap (NULL, mr->region_size, PROT_READ | PROT_WRITE,
1913  MAP_SHARED, mr->fd, 0)) == MAP_FAILED)
1914  {
1915  return memif_syscall_error_handler (errno);
1916  }
1917  }
1918  }
1919  }
1920  }
1921 
1922  for (i = 0; i < c->rx_queues_num; i++)
1923  {
1924  mq = &c->rx_queues[i];
1925  if (mq != NULL)
1926  {
1927  mq->ring = c->regions[mq->region].addr + mq->offset;
1928  if (mq->ring->cookie != MEMIF_COOKIE)
1929  {
1930  DBG ("wrong cookie on rx ring %u", i);
1931  return MEMIF_ERR_COOKIE;
1932  }
1933  mq->ring->head = mq->ring->tail = mq->last_head = mq->alloc_bufs =
1934  0;
1935  }
1936  }
1937 
1938  for (i = 0; i < c->tx_queues_num; i++)
1939  {
1940  mq = &c->tx_queues[i];
1941  if (mq != NULL)
1942  {
1943  mq->ring = c->regions[mq->region].addr + mq->offset;
1944  if (mq->ring->cookie != MEMIF_COOKIE)
1945  {
1946  DBG ("wrong cookie on tx ring %u", i);
1947  return MEMIF_ERR_COOKIE;
1948  }
1949  mq->ring->head = mq->ring->tail = mq->last_head = mq->alloc_bufs =
1950  0;
1951  }
1952  }
1953 
1955  c->private_ctx);
1956 
1957  return 0;
1958 }
1959 
1960 static inline int
1962  uint8_t has_buffers)
1963 {
1964  memif_region_t *r;
1965 
1966  r =
1967  lm->realloc (conn->regions,
1968  sizeof (memif_region_t) * ++conn->regions_num);
1969  if (r == NULL)
1970  return MEMIF_ERR_NOMEM;
1971 
1972  conn->regions = r;
1973  r = &conn->regions[conn->regions_num - 1];
1974  memset (r, 0, sizeof (memif_region_t));
1975 
1976  if (has_buffers != 0)
1977  {
1978  r->buffer_offset = 0;
1979  }
1980  else
1981  {
1982  r->buffer_offset =
1983  (conn->run_args.num_s2m_rings +
1984  conn->run_args.num_m2s_rings) * (sizeof (memif_ring_t) +
1985  sizeof (memif_desc_t) *
1986  (1 << conn->
1987  run_args.log2_ring_size));
1988  }
1989 
1990  r->region_size = (has_buffers == 0) ? r->buffer_offset : r->buffer_offset +
1991  conn->run_args.buffer_size * (1 << conn->run_args.log2_ring_size) *
1992  (conn->run_args.num_s2m_rings + conn->run_args.num_m2s_rings);
1993 
1994  if ((r->fd = memfd_create ("memif region 0", MFD_ALLOW_SEALING)) == -1)
1995  return memif_syscall_error_handler (errno);
1996 
1997  if ((fcntl (r->fd, F_ADD_SEALS, F_SEAL_SHRINK)) == -1)
1998  return memif_syscall_error_handler (errno);
1999 
2000  if ((ftruncate (r->fd, r->region_size)) == -1)
2001  return memif_syscall_error_handler (errno);
2002 
2003  if ((r->addr = mmap (NULL, r->region_size, PROT_READ | PROT_WRITE,
2004  MAP_SHARED, r->fd, 0)) == MAP_FAILED)
2005  return memif_syscall_error_handler (errno);
2006 
2007  return MEMIF_ERR_SUCCESS;
2008 }
2009 
2010 static inline int
2012 {
2013  int i, j;
2014  memif_ring_t *ring;
2015 
2016  for (i = 0; i < conn->run_args.num_s2m_rings; i++)
2017  {
2018  ring = memif_get_ring (conn, MEMIF_RING_S2M, i);
2019  DBG ("RING: %p I: %d", ring, i);
2020  ring->head = ring->tail = 0;
2021  ring->cookie = MEMIF_COOKIE;
2022  ring->flags = 0;
2023  for (j = 0; j < (1 << conn->run_args.log2_ring_size); j++)
2024  {
2025  uint16_t slot = i * (1 << conn->run_args.log2_ring_size) + j;
2026  ring->desc[j].region = 1;
2027  ring->desc[j].offset =
2028  conn->regions[1].buffer_offset +
2029  (uint32_t) (slot * conn->run_args.buffer_size);
2030  ring->desc[j].length = conn->run_args.buffer_size;
2031  }
2032  }
2033  for (i = 0; i < conn->run_args.num_m2s_rings; i++)
2034  {
2035  ring = memif_get_ring (conn, MEMIF_RING_M2S, i);
2036  DBG ("RING: %p I: %d", ring, i);
2037  ring->head = ring->tail = 0;
2038  ring->cookie = MEMIF_COOKIE;
2039  ring->flags = 0;
2040  for (j = 0; j < (1 << conn->run_args.log2_ring_size); j++)
2041  {
2042  uint16_t slot = (i + conn->run_args.num_s2m_rings) *
2043  (1 << conn->run_args.log2_ring_size) + j;
2044  ring->desc[j].region = 1;
2045  ring->desc[j].offset =
2046  conn->regions[1].buffer_offset +
2047  (uint32_t) (slot * conn->run_args.buffer_size);
2048  ring->desc[j].length = conn->run_args.buffer_size;
2049  }
2050  }
2051  memif_queue_t *mq;
2052  DBG ("alloc: %p", lm->alloc);
2053  DBG ("size: %lu", sizeof (memif_queue_t) * conn->run_args.num_s2m_rings);
2054  mq =
2055  (memif_queue_t *) lm->alloc (sizeof (memif_queue_t) *
2056  conn->run_args.num_s2m_rings);
2057  if (mq == NULL)
2058  return MEMIF_ERR_NOMEM;
2059 
2060  int x;
2061  memif_list_elt_t e;
2062  for (x = 0; x < conn->run_args.num_s2m_rings; x++)
2063  {
2064  if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
2065  return memif_syscall_error_handler (errno);
2066  e.key = mq[x].int_fd;
2067  e.data_struct = conn;
2068  add_list_elt (lm, &e, &lm->interrupt_list, &lm->interrupt_list_len);
2069 
2070  mq[x].ring = memif_get_ring (conn, MEMIF_RING_S2M, x);
2071  DBG ("RING: %p I: %d", mq[x].ring, x);
2072  mq[x].log2_ring_size = conn->run_args.log2_ring_size;
2073  mq[x].region = 0;
2074  mq[x].offset =
2075  (void *) mq[x].ring - (void *) conn->regions[mq->region].addr;
2076  mq[x].last_head = mq[x].last_tail = 0;
2077  mq[x].alloc_bufs = 0;
2078  }
2079  conn->tx_queues = mq;
2080  conn->tx_queues_num = conn->run_args.num_s2m_rings;
2081 
2082  mq =
2083  (memif_queue_t *) lm->alloc (sizeof (memif_queue_t) *
2084  conn->run_args.num_m2s_rings);
2085  if (mq == NULL)
2086  return MEMIF_ERR_NOMEM;
2087 
2088  for (x = 0; x < conn->run_args.num_m2s_rings; x++)
2089  {
2090  if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
2091  return memif_syscall_error_handler (errno);
2092  e.key = mq[x].int_fd;
2093  e.data_struct = conn;
2094  add_list_elt (lm, &e, &lm->interrupt_list, &lm->interrupt_list_len);
2095 
2096  mq[x].ring = memif_get_ring (conn, MEMIF_RING_M2S, x);
2097  DBG ("RING: %p I: %d", mq[x].ring, x);
2098  mq[x].log2_ring_size = conn->run_args.log2_ring_size;
2099  mq[x].region = 0;
2100  mq[x].offset =
2101  (void *) mq[x].ring - (void *) conn->regions[mq->region].addr;
2102  mq[x].last_head = mq[x].last_tail = 0;
2103  mq[x].alloc_bufs = 0;
2104  }
2105  conn->rx_queues = mq;
2106  conn->rx_queues_num = conn->run_args.num_m2s_rings;
2107 
2108  return MEMIF_ERR_SUCCESS;
2109 }
2110 
2111 int
2113 {
2114  memif_region_t *r;
2115  libmemif_main_t *lm;
2116 
2117  if (conn == NULL)
2118  return MEMIF_ERR_INVAL_ARG;
2119 
2120  lm = get_libmemif_main (conn->args.socket);
2121 
2122  /* region 0. rings */
2123  memif_add_region (lm, conn, /* has_buffers */ 0);
2124 
2125  /* region 1. buffers */
2126  if (lm->add_external_region)
2127  {
2128  r =
2129  (memif_region_t *) lm->realloc (conn->regions,
2130  sizeof (memif_region_t) *
2131  ++conn->regions_num);
2132  if (r == NULL)
2133  return MEMIF_ERR_NOMEM;
2134  conn->regions = r;
2135 
2136  conn->regions[1].region_size =
2137  conn->run_args.buffer_size * (1 << conn->run_args.log2_ring_size) *
2138  (conn->run_args.num_s2m_rings + conn->run_args.num_m2s_rings);
2139  conn->regions[1].buffer_offset = 0;
2140  lm->add_external_region (&conn->regions[1].addr,
2141  conn->regions[1].region_size,
2142  &conn->regions[1].fd, conn->private_ctx);
2143  conn->regions[1].is_external = 1;
2144  }
2145  else
2146  {
2147  memif_add_region (lm, conn, 1);
2148  }
2149 
2150  memif_init_queues (lm, conn);
2151 
2152  return 0;
2153 }
2154 
2155 int
2157  memif_buffer_t * bufs, uint16_t count,
2158  uint16_t * count_out)
2159 {
2161  if (EXPECT_FALSE (c == NULL))
2162  return MEMIF_ERR_NOCONN;
2163  if (EXPECT_FALSE (c->fd < 0))
2164  return MEMIF_ERR_DISCONNECTED;
2165  uint8_t num =
2166  (c->args.is_master) ? c->run_args.num_m2s_rings : c->
2167  run_args.num_s2m_rings;
2168  if (EXPECT_FALSE (qid >= num))
2169  return MEMIF_ERR_QID;
2170  if (EXPECT_FALSE (!count_out))
2171  return MEMIF_ERR_INVAL_ARG;
2172  if (EXPECT_FALSE (c->args.is_master))
2173  return MEMIF_ERR_INVAL_ARG;
2174 
2175  memif_queue_t *mq = &c->tx_queues[qid];
2176  memif_ring_t *ring = mq->ring;
2177  memif_buffer_t *b0;
2178  uint16_t mask = (1 << mq->log2_ring_size) - 1;
2179  uint16_t ring_size;
2180  uint16_t slot, ns;
2181  int err = MEMIF_ERR_SUCCESS; /* 0 */
2182  *count_out = 0;
2183 
2184  ring_size = (1 << mq->log2_ring_size);
2185  slot = (c->args.is_master) ? ring->tail : ring->head;
2186  slot += mq->alloc_bufs;
2187 
2188  /* can only be called by slave */
2189  ns = ring_size - (ring->head + mq->alloc_bufs) + ring->tail;
2190 
2191  b0 = bufs;
2192 
2193  while (count && ns)
2194  {
2195  if (EXPECT_FALSE ((b0->flags & MEMIF_BUFFER_FLAG_RX) == 0))
2196  {
2197  /* not a valid buffer */
2198  count--;
2199  continue;
2200  }
2201  b0->flags &= ~MEMIF_BUFFER_FLAG_RX;
2202 
2203  ((memif_ring_t *) b0->ring)->desc[b0->desc_index & mask].offset = ring->desc[slot & mask].offset; /* put free buffer on rx ring */
2204 
2205  ring->desc[slot & mask].offset =
2206  (uint32_t) (b0->data -
2207  c->regions[ring->desc[slot & mask].region].addr);
2208  ring->desc[slot & mask].flags &= ~MEMIF_DESC_FLAG_NEXT;
2209  ring->desc[slot & mask].flags |=
2211 
2212  b0->desc_index = slot;
2213 
2214  mq->alloc_bufs++;
2215  slot++;
2216 
2217  count--;
2218  ns--;
2219  b0++;
2220  *count_out += 1;
2221  }
2222 
2223  DBG ("allocated: %u/%u bufs. Total %u allocated bufs", *count_out, count,
2224  mq->alloc_bufs);
2225 
2226  if (count)
2227  {
2228  DBG ("ring buffer full! qid: %u", qid);
2229  err = MEMIF_ERR_NOBUF_RING;
2230  }
2231 
2232  return err;
2233 }
2234 
2235 int
2237  memif_buffer_t * bufs, uint16_t count,
2238  uint16_t * count_out, uint16_t size)
2239 {
2241  if (EXPECT_FALSE (c == NULL))
2242  return MEMIF_ERR_NOCONN;
2243  if (EXPECT_FALSE (c->fd < 0))
2244  return MEMIF_ERR_DISCONNECTED;
2245  uint8_t num =
2246  (c->args.is_master) ? c->run_args.num_m2s_rings : c->
2247  run_args.num_s2m_rings;
2248  if (EXPECT_FALSE (qid >= num))
2249  return MEMIF_ERR_QID;
2250  if (EXPECT_FALSE (!count_out))
2251  return MEMIF_ERR_INVAL_ARG;
2252 
2253  libmemif_main_t *lm = get_libmemif_main (c->args.socket);
2254  memif_queue_t *mq = &c->tx_queues[qid];
2255  memif_ring_t *ring = mq->ring;
2256  memif_buffer_t *b0;
2257  uint16_t mask = (1 << mq->log2_ring_size) - 1;
2258  uint32_t offset_mask = c->run_args.buffer_size - 1;
2259  uint16_t ring_size;
2260  uint16_t slot, ns;
2261  int err = MEMIF_ERR_SUCCESS; /* 0 */
2262  uint16_t dst_left, src_left;
2263  uint16_t saved_count;
2264  memif_buffer_t *saved_b;
2265  *count_out = 0;
2266 
2267  ring_size = (1 << mq->log2_ring_size);
2268  slot = (c->args.is_master) ? ring->tail : ring->head;
2269  slot += mq->alloc_bufs;
2270 
2271  if (c->args.is_master)
2272  ns = ring->head - (ring->tail + mq->alloc_bufs);
2273  else
2274  ns = ring_size - (ring->head + mq->alloc_bufs) + ring->tail;
2275 
2276  while (count && ns)
2277  {
2278  b0 = (bufs + *count_out);
2279 
2280  saved_b = b0;
2281  saved_count = count;
2282 
2283  b0->desc_index = slot;
2284  ring->desc[slot & mask].flags = 0;
2285 
2286  /* slave can produce buffer with original length */
2287  dst_left = (c->args.is_master) ? ring->desc[slot & mask].length :
2288  c->run_args.buffer_size;
2289  src_left = size;
2290 
2291  while (src_left)
2292  {
2293  if (EXPECT_FALSE (dst_left == 0))
2294  {
2295  if (count && ns)
2296  {
2297  slot++;
2298  *count_out += 1;
2299  mq->alloc_bufs++;
2300  ns--;
2301 
2302  ring->desc[b0->desc_index & mask].flags |=
2305 
2306  b0 = (bufs + *count_out);
2307  b0->desc_index = slot;
2308  dst_left =
2309  (c->args.is_master) ? ring->desc[slot & mask].
2310  length : c->run_args.buffer_size;
2311  ring->desc[slot & mask].flags = 0;
2312  }
2313  else
2314  {
2315  /* rollback allocated chain buffers */
2316  memset (saved_b, 0, sizeof (memif_buffer_t)
2317  * (saved_count - count + 1));
2318  *count_out -= saved_count - count;
2319  mq->alloc_bufs = saved_count - count;
2320  goto no_ns;
2321  }
2322  }
2323  b0->len = memif_min (dst_left, src_left);
2324 
2325  /* slave resets buffer offset */
2326  if (c->args.is_master == 0)
2327  {
2328  memif_desc_t *d = &ring->desc[slot & mask];
2330  d->offset = lm->get_external_buffer_offset (c->private_ctx);
2331  else
2332  d->offset = d->offset - (d->offset & offset_mask);
2333  }
2334  b0->data = memif_get_buffer (c, ring, slot & mask);
2335 
2336  src_left -= b0->len;
2337  dst_left -= b0->len;
2338  }
2339 
2340  slot++;
2341  *count_out += 1;
2342  mq->alloc_bufs++;
2343  ns--;
2344  count--;
2345  }
2346 
2347 no_ns:
2348 
2349  DBG ("allocated: %u/%u bufs. Total %u allocated bufs", *count_out, count,
2350  mq->alloc_bufs);
2351 
2352  if (count)
2353  {
2354  DBG ("ring buffer full! qid: %u", qid);
2355  err = MEMIF_ERR_NOBUF_RING;
2356  }
2357 
2358  return err;
2359 }
2360 
2361 int
2362 memif_refill_queue (memif_conn_handle_t conn, uint16_t qid, uint16_t count,
2363  uint16_t headroom)
2364 {
2366  if (EXPECT_FALSE (c == NULL))
2367  return MEMIF_ERR_NOCONN;
2368  if (EXPECT_FALSE (c->fd < 0))
2369  return MEMIF_ERR_DISCONNECTED;
2370  uint8_t num =
2371  (c->args.is_master) ? c->run_args.num_s2m_rings : c->
2372  run_args.num_m2s_rings;
2373  if (EXPECT_FALSE (qid >= num))
2374  return MEMIF_ERR_QID;
2375  libmemif_main_t *lm = get_libmemif_main (c->args.socket);
2376  memif_queue_t *mq = &c->rx_queues[qid];
2377  memif_ring_t *ring = mq->ring;
2378  uint16_t mask = (1 << mq->log2_ring_size) - 1;
2379  uint32_t offset_mask = c->run_args.buffer_size - 1;
2380  uint16_t slot;
2381 
2382  if (c->args.is_master)
2383  {
2385  ring->tail =
2386  (ring->tail + count <=
2387  mq->last_head) ? ring->tail + count : mq->last_head;
2388  return MEMIF_ERR_SUCCESS;
2389  }
2390 
2391  uint16_t head = ring->head;
2392  uint16_t ns = (1 << mq->log2_ring_size) - head + mq->last_tail;
2393  head += (count < ns) ? count : ns;
2394 
2395  slot = ring->head;
2396  memif_desc_t *d;
2397  while (slot < head)
2398  {
2399  d = &ring->desc[slot & mask];
2400  d->region = 1;
2401  d->length = c->run_args.buffer_size - headroom;
2403  d->offset = lm->get_external_buffer_offset (c->private_ctx);
2404  else
2405  d->offset = d->offset - (d->offset & offset_mask) + headroom;
2406  slot++;
2407  }
2408 
2410  ring->head = head;
2411 
2412  return MEMIF_ERR_SUCCESS; /* 0 */
2413 }
2414 
2415 int
2417  memif_buffer_t * bufs, uint16_t count, uint16_t * tx)
2418 {
2420  if (EXPECT_FALSE (c == NULL))
2421  return MEMIF_ERR_NOCONN;
2422  if (EXPECT_FALSE (c->fd < 0))
2423  return MEMIF_ERR_DISCONNECTED;
2424  uint8_t num =
2425  (c->args.is_master) ? c->run_args.num_m2s_rings : c->
2426  run_args.num_s2m_rings;
2427  if (EXPECT_FALSE (qid >= num))
2428  return MEMIF_ERR_QID;
2429  if (EXPECT_FALSE (!tx))
2430  return MEMIF_ERR_INVAL_ARG;
2431 
2432  memif_queue_t *mq = &c->tx_queues[qid];
2433  memif_ring_t *ring = mq->ring;
2434  uint16_t mask = (1 << mq->log2_ring_size) - 1;
2435  memif_buffer_t *b0;
2436  *tx = 0;
2437 
2438  if (count > mq->alloc_bufs)
2439  count = mq->alloc_bufs;
2440 
2441  if (EXPECT_FALSE (count == 0))
2442  return MEMIF_ERR_SUCCESS;
2443 
2444  while (count)
2445  {
2446  b0 = (bufs + *tx);
2447  ring->desc[b0->desc_index & mask].length = b0->len;
2448 
2449 #ifdef MEMIF_DBG_SHM
2450  printf ("offset: %-6d\n", ring->desc[b0->desc_index & mask].offset);
2451  printf ("data: %p\n",
2452  memif_get_buffer (c, ring, b0->desc_index & mask));
2453  printf ("index: %u\n", b0->desc_index);
2454  print_bytes (memif_get_buffer (c, ring, b0->desc_index & mask),
2455  ring->desc[b0->desc_index & mask].length, DBG_TX_BUF);
2456 #endif /* MEMIF_DBG_SHM */
2457 
2458  *tx += 1;
2459  count--;
2460  }
2461 
2462 
2464  if (c->args.is_master)
2465  ring->tail = b0->desc_index + 1;
2466  else
2467  ring->head = b0->desc_index + 1;
2468 
2469  mq->alloc_bufs -= *tx;
2470 
2471  if ((ring->flags & MEMIF_RING_FLAG_MASK_INT) == 0)
2472  {
2473  uint64_t a = 1;
2474  int r = write (mq->int_fd, &a, sizeof (a));
2475  if (r < 0)
2476  return MEMIF_ERR_INT_WRITE;
2477  }
2478 
2479  return MEMIF_ERR_SUCCESS; /* 0 */
2480 }
2481 
2482 int
2484  memif_buffer_t * bufs, uint16_t count, uint16_t * rx)
2485 {
2487  if (EXPECT_FALSE (c == NULL))
2488  return MEMIF_ERR_NOCONN;
2489  if (EXPECT_FALSE (c->fd < 0))
2490  return MEMIF_ERR_DISCONNECTED;
2491  uint8_t num =
2492  (c->args.is_master) ? c->run_args.num_s2m_rings : c->
2493  run_args.num_m2s_rings;
2494  if (EXPECT_FALSE (qid >= num))
2495  return MEMIF_ERR_QID;
2496  if (EXPECT_FALSE (!rx))
2497  return MEMIF_ERR_INVAL_ARG;
2498 
2499  memif_queue_t *mq = &c->rx_queues[qid];
2500  memif_ring_t *ring = mq->ring;
2501  uint16_t cur_slot, last_slot;
2502  uint16_t ns;
2503  uint16_t mask = (1 << mq->log2_ring_size) - 1;
2504  memif_buffer_t *b0;
2505  *rx = 0;
2506 
2507  uint64_t b;
2508  ssize_t r = read (mq->int_fd, &b, sizeof (b));
2509  if (EXPECT_FALSE ((r == -1) && (errno != EAGAIN)))
2510  return memif_syscall_error_handler (errno);
2511 
2512  cur_slot = (c->args.is_master) ? mq->last_head : mq->last_tail;
2513  last_slot = (c->args.is_master) ? ring->head : ring->tail;
2514  if (cur_slot == last_slot)
2515  return MEMIF_ERR_SUCCESS;
2516 
2517  ns = last_slot - cur_slot;
2518 
2519  while (ns && count)
2520  {
2521  b0 = (bufs + *rx);
2522 
2523  b0->desc_index = cur_slot;
2524  b0->data = memif_get_buffer (c, ring, cur_slot & mask);
2525  b0->len = ring->desc[cur_slot & mask].length;
2526  /* slave resets buffer length */
2527  if (c->args.is_master == 0)
2528  {
2529  ring->desc[cur_slot & mask].length = c->run_args.buffer_size;
2530  }
2531 
2533  if (ring->desc[cur_slot & mask].flags & MEMIF_DESC_FLAG_NEXT)
2534  {
2536  ring->desc[cur_slot & mask].flags &= ~MEMIF_DESC_FLAG_NEXT;
2537  }
2538 /* b0->offset = ring->desc[cur_slot & mask].offset;*/
2539  b0->ring = ring;
2540 #ifdef MEMIF_DBG_SHM
2541  printf ("data: %p\n", b0->data);
2542  printf ("index: %u\n", b0->desc_index);
2543  printf ("ring: %p\n", b0->ring);
2544  print_bytes (b0->data, b0->len, DBG_RX_BUF);
2545 #endif /* MEMIF_DBG_SHM */
2546  ns--;
2547  *rx += 1;
2548 
2549  count--;
2550  cur_slot++;
2551  }
2552 
2553  if (c->args.is_master)
2554  mq->last_head = cur_slot;
2555  else
2556  mq->last_tail = cur_slot;
2557 
2558  if (ns)
2559  {
2560  DBG ("not enough buffers!");
2561  return MEMIF_ERR_NOBUF;
2562  }
2563 
2564  return MEMIF_ERR_SUCCESS; /* 0 */
2565 }
2566 
2567 int
2569  char *buf, ssize_t buflen)
2570 {
2572  libmemif_main_t *lm;
2573  memif_socket_t *ms;
2574  int err = MEMIF_ERR_SUCCESS, i;
2575  ssize_t l0 = 0, l1;
2576 
2577  if (c == NULL)
2578  return MEMIF_ERR_NOCONN;
2579 
2580  ms = (memif_socket_t *) c->args.socket;
2581  lm = get_libmemif_main (ms);
2582 
2583  l1 = strlen ((char *) c->args.interface_name);
2584  if (l0 + l1 < buflen)
2585  {
2586  md->if_name =
2587  (uint8_t *) strcpy (buf + l0, (char *) c->args.interface_name);
2588  l0 += l1 + 1;
2589  }
2590  else
2591  err = MEMIF_ERR_NOBUF_DET;
2592 
2593  l1 = strlen ((char *) lm->app_name);
2594  if (l0 + l1 < buflen)
2595  {
2596  md->inst_name = (uint8_t *) strcpy (buf + l0, (char *) lm->app_name);
2597  l0 += l1 + 1;
2598  }
2599  else
2600  err = MEMIF_ERR_NOBUF_DET;
2601 
2602  l1 = strlen ((char *) c->remote_if_name);
2603  if (l0 + l1 < buflen)
2604  {
2605  md->remote_if_name =
2606  (uint8_t *) strcpy (buf + l0, (char *) c->remote_if_name);
2607  l0 += l1 + 1;
2608  }
2609  else
2610  err = MEMIF_ERR_NOBUF_DET;
2611 
2612  l1 = strlen ((char *) c->remote_name);
2613  if (l0 + l1 < buflen)
2614  {
2615  md->remote_inst_name =
2616  (uint8_t *) strcpy (buf + l0, (char *) c->remote_name);
2617  l0 += l1 + 1;
2618  }
2619  else
2620  err = MEMIF_ERR_NOBUF_DET;
2621 
2622  md->id = c->args.interface_id;
2623 
2624  if (strlen ((char *) c->args.secret) > 0)
2625  {
2626  l1 = strlen ((char *) c->args.secret);
2627  if (l0 + l1 < buflen)
2628  {
2629  md->secret = (uint8_t *) strcpy (buf + l0, (char *) c->args.secret);
2630  l0 += l1 + 1;
2631  }
2632  else
2633  err = MEMIF_ERR_NOBUF_DET;
2634  }
2635 
2636  md->role = (c->args.is_master) ? 0 : 1;
2637  md->mode = c->args.mode;
2638 
2639  l1 = strlen ((char *) ms->filename);
2640  if (l0 + l1 < buflen)
2641  {
2642  md->socket_filename =
2643  (uint8_t *) strcpy (buf + l0, (char *) ms->filename);
2644  l0 += l1 + 1;
2645  }
2646  else
2647  err = MEMIF_ERR_NOBUF_DET;
2648 
2649  l1 = strlen ((char *) c->remote_disconnect_string);
2650  if (l0 + l1 < buflen)
2651  {
2652  md->error =
2653  (uint8_t *) strcpy (buf + l0, (char *) c->remote_disconnect_string);
2654  l0 += l1 + 1;
2655  }
2656  else
2657  err = MEMIF_ERR_NOBUF_DET;
2658 
2659  md->regions_num = c->regions_num;
2660  l1 = sizeof (memif_region_details_t) * md->regions_num;
2661  if (l0 + l1 <= buflen)
2662  {
2663  md->regions = (memif_region_details_t *) (buf + l0);
2664  for (i = 0; i < md->regions_num; i++)
2665  {
2666  md->regions[i].index = i;
2667  md->regions[i].addr = c->regions[i].addr;
2668  md->regions[i].size = c->regions[i].region_size;
2669  md->regions[i].fd = c->regions[i].fd;
2670  md->regions[i].is_external = c->regions[i].is_external;
2671  }
2672  l0 += l1;
2673  }
2674  else
2675  err = MEMIF_ERR_NOBUF_DET;
2676 
2677  md->rx_queues_num =
2678  (c->args.is_master) ? c->run_args.num_s2m_rings : c->
2679  run_args.num_m2s_rings;
2680 
2681  l1 = sizeof (memif_queue_details_t) * md->rx_queues_num;
2682  if (l0 + l1 <= buflen)
2683  {
2684  md->rx_queues = (memif_queue_details_t *) (buf + l0);
2685  for (i = 0; i < md->rx_queues_num; i++)
2686  {
2687  md->rx_queues[i].region = c->rx_queues[i].region;
2688  md->rx_queues[i].qid = i;
2689  md->rx_queues[i].ring_size = (1 << c->rx_queues[i].log2_ring_size);
2690  md->rx_queues[i].flags = c->rx_queues[i].ring->flags;
2691  md->rx_queues[i].head = c->rx_queues[i].ring->head;
2692  md->rx_queues[i].tail = c->rx_queues[i].ring->tail;
2693  md->rx_queues[i].buffer_size = c->run_args.buffer_size;
2694  }
2695  l0 += l1;
2696  }
2697  else
2698  err = MEMIF_ERR_NOBUF_DET;
2699 
2700  md->tx_queues_num =
2701  (c->args.is_master) ? c->run_args.num_m2s_rings : c->
2702  run_args.num_s2m_rings;
2703 
2704  l1 = sizeof (memif_queue_details_t) * md->tx_queues_num;
2705  if (l0 + l1 <= buflen)
2706  {
2707  md->tx_queues = (memif_queue_details_t *) (buf + l0);
2708  for (i = 0; i < md->tx_queues_num; i++)
2709  {
2710  md->tx_queues[i].region = c->tx_queues[i].region;
2711  md->tx_queues[i].qid = i;
2712  md->tx_queues[i].ring_size = (1 << c->tx_queues[i].log2_ring_size);
2713  md->tx_queues[i].flags = c->tx_queues[i].ring->flags;
2714  md->tx_queues[i].head = c->tx_queues[i].ring->head;
2715  md->tx_queues[i].tail = c->tx_queues[i].ring->tail;
2716  md->tx_queues[i].buffer_size = c->run_args.buffer_size;
2717  }
2718  l0 += l1;
2719  }
2720  else
2721  err = MEMIF_ERR_NOBUF_DET;
2722 
2723  md->link_up_down = (c->fd > 0) ? 1 : 0;
2724 
2725  return err; /* 0 */
2726 }
2727 
2728 int
2729 memif_get_queue_efd (memif_conn_handle_t conn, uint16_t qid, int *efd)
2730 {
2732  uint8_t num;
2733 
2734  *efd = -1;
2735  if (c == NULL)
2736  return MEMIF_ERR_NOCONN;
2737  if (c->fd < 0)
2738  return MEMIF_ERR_DISCONNECTED;
2739 
2740  num =
2741  (c->args.is_master) ? c->run_args.num_s2m_rings : c->
2742  run_args.num_m2s_rings;
2743  if (qid >= num)
2744  return MEMIF_ERR_QID;
2745 
2746  *efd = c->rx_queues[qid].int_fd;
2747 
2748  return MEMIF_ERR_SUCCESS;
2749 }
2750 
2751 int
2753 {
2755  int err;
2756 
2758  if (err != MEMIF_ERR_SUCCESS)
2759  return err;
2760 
2761  if (lm->control_list)
2762  lm->free (lm->control_list);
2763  lm->control_list = NULL;
2764  if (lm->interrupt_list)
2765  lm->free (lm->interrupt_list);
2766  lm->interrupt_list = NULL;
2767  if (lm->socket_list)
2768  lm->free (lm->socket_list);
2769  lm->socket_list = NULL;
2770  if (lm->pending_list)
2771  lm->free (lm->pending_list);
2772  lm->pending_list = NULL;
2773  if (lm->poll_cancel_fd != -1)
2774  close (lm->poll_cancel_fd);
2775 
2776  return MEMIF_ERR_SUCCESS; /* 0 */
2777 }
2778 
2779 int
2781 {
2782  libmemif_main_t *lm = (libmemif_main_t *) * pt_main;
2783 
2784  if (lm == NULL)
2785  return MEMIF_ERR_INVAL_ARG;
2786 
2787  /* No default socket in case of per thread */
2788 
2789  if (lm->control_list)
2790  lm->free (lm->control_list);
2791  lm->control_list = NULL;
2792  if (lm->interrupt_list)
2793  lm->free (lm->interrupt_list);
2794  lm->interrupt_list = NULL;
2795  if (lm->socket_list)
2796  lm->free (lm->socket_list);
2797  lm->socket_list = NULL;
2798  if (lm->pending_list)
2799  lm->free (lm->pending_list);
2800  lm->pending_list = NULL;
2801  if (lm->poll_cancel_fd != -1)
2802  close (lm->poll_cancel_fd);
2803 
2804  lm->free (lm);
2805 
2806  *pt_main = NULL;
2807 
2808  return MEMIF_ERR_SUCCESS; /* 0 */
2809 }
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:1574
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:399
uint8_t * secret
Definition: libmemif.h:404
static char memif_buf[MAX_ERRBUF_LEN]
Definition: main.c:70
Memif region details.
Definition: libmemif.h:368
int on_disconnect(memif_conn_handle_t conn, void *private_ctx)
Definition: main.c:186
void * ring
Definition: libmemif.h:321
#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:294
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
#define NULL
Definition: clib.h:58
uint16_t buffer_size
Definition: libmemif.h:295
uint8_t app_name[MEMIF_NAME_LEN]
uint8_t secret[24]
Definition: libmemif.h:291
static void memif_msg_queue_free(libmemif_main_t *lm, memif_msg_queue_elt_t **e)
Definition: main.c:1652
uint32_t interface_id
Definition: libmemif.h:299
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++)
int 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:1664
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:290
uint16_t desc_index
Definition: libmemif.h:320
#define MEMIF_MEMORY_BARRIER()
Definition: main.c:65
memif_del_external_region_t * del_external_region
uint8_t * remote_inst_name
Definition: libmemif.h:401
static memif_ring_t * memif_get_ring(memif_connection_t *conn, memif_ring_type_t type, uint16_t ring_num)
Definition: main.c:824
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:2362
#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:293
const char * memif_get_socket_filename(memif_socket_handle_t sock)
Get socket filename.
Definition: main.c:1782
uint32_t len
Definition: libmemif.h:322
#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:2568
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:301
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:406
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:658
#define DBG_TX_BUF
Definition: main.c:179
uint16_t flags
Definition: memif.h:151
uint8_t link_up_down
Definition: libmemif.h:416
#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:324
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:300
uint8_t * error
Definition: libmemif.h:415
void * data
Definition: libmemif.h:328
static void memif_free_register(libmemif_main_t *lm, memif_free_t *mf)
Definition: main.c:462
memif_desc_t desc[0]
Definition: memif.h:175
uint16_t buffer_size
Definition: libmemif.h:358
uint8_t * socket_filename
Definition: libmemif.h:407
#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:199
#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:839
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:222
int memif_create_socket(memif_socket_handle_t *sock, const char *filename, void *private_ctx)
Create memif socket.
Definition: main.c:930
u64 size
Definition: vhost_user.h:140
int() memif_interrupt_t(memif_conn_handle_t conn, void *private_ctx, uint16_t qid)
Memif interrupt occured (callback function)
Definition: libmemif.h:172
uint8_t is_master
Definition: libmemif.h:297
uint8_t rx_queues_num
Definition: libmemif.h:410
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:508
int() memif_connection_update_t(memif_conn_handle_t conn, void *private_ctx)
Memif connection status update (callback function)
Definition: libmemif.h:162
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:2729
#define MEMIF_BUFFER_FLAG_RX
states that buffer is from rx ring
Definition: libmemif.h:326
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:2156
#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:450
int memif_init_regions_and_queues(memif_connection_t *conn)
Definition: main.c:2112
u8 len
Definition: ip_types.api:91
static void memif_realloc_register(libmemif_main_t *lm, memif_realloc_t *mr)
Definition: main.c:456
u8 slot
Definition: pci_types.api:22
uint16_t use_count
uint8_t flags
Definition: libmemif.h:327
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:408
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:1009
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:2416
void() memif_free_t(void *ptr)
Memif allocator free.
Definition: libmemif.h:136
#define F_ADD_SEALS
Definition: main.c:108
int get_list_elt(memif_list_elt_t **e, memif_list_elt_t *list, uint16_t len, int key)
Definition: main.c:369
static void memif_control_fd_update_register(libmemif_main_t *lm, memif_control_fd_update_t *cb)
Definition: main.c:430
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:2236
static int memif_add_region(libmemif_main_t *lm, memif_connection_t *conn, uint8_t has_buffers)
Definition: main.c:1961
int memif_poll_event(int timeout)
Memif poll event.
Definition: main.c:1532
memif_list_elt_t * control_list
memif_socket_handle_t default_socket
memif_queue_details_t * rx_queues
Definition: libmemif.h:412
static int memif_socket_start_listening(memif_socket_t *ms)
Definition: main.c:857
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:1418
uint16_t interrupt_list_len
uint8_t role
Definition: libmemif.h:405
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:2752
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:189
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:1093
#define MEMIF_DESC_FLAG_NEXT
Definition: memif.h:152
u8 data[128]
Definition: ipsec_types.api:87
int free_list_elt_ctx(memif_list_elt_t *list, uint16_t len, memif_connection_t *ctx)
Definition: main.c:410
#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:411
#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:487
typedef key
Definition: ipsec_types.api:83
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:468
int memif_control_fd_handler(int fd, uint8_t events)
Memif control file descriptor handler.
Definition: main.c:1306
int memif_request_connection(memif_conn_handle_t c)
Send connection request.
Definition: main.c:1231
uint8_t log2_ring_size
Definition: libmemif.h:296
uint32_t id
Definition: libmemif.h:403
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:2483
memif_rx_mode_t
Definition: libmemif.h:305
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:211
int memif_delete(memif_conn_handle_t *conn)
Memif delete.
Definition: main.c:1815
static int memif_init_queues(libmemif_main_t *lm, memif_connection_t *conn)
Definition: main.c:2011
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:2780
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:1633
Memif queue details.
Definition: libmemif.h:348
memif_region_details_t * regions
Definition: libmemif.h:409
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:1617
#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:413
uint8_t * if_name
Definition: libmemif.h:398
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:1793
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:1879
uint16_t index
Definition: main.c:74
libmemif_main_t libmemif_main
Definition: main.c:68
Memif buffer.
Definition: libmemif.h:318
int free_list_elt(memif_list_elt_t *list, uint16_t len, int key)
Definition: main.c:393
#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:333
memif_region_index_t region
Definition: private.h:120
#define MEMIF_COOKIE
Definition: memif.h:25
Memif connection arguments.
Definition: libmemif.h:288
uint16_t interface_list_len
Memif details.
Definition: libmemif.h:396
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:437
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:152
uint8_t * remote_if_name
Definition: libmemif.h:400