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