FD.io VPP  v18.04-17-g3a0d853
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 #include <stdint.h>
19 #include <net/if.h>
20 #include <sys/types.h>
21 #include <fcntl.h>
22 #include <sys/ioctl.h>
23 #include <sys/socket.h>
24 #include <sys/un.h>
25 #include <sys/uio.h>
26 #include <sys/mman.h>
27 #include <sys/prctl.h>
28 #include <inttypes.h>
29 #include <string.h>
30 #include <stdio.h>
31 #include <netdb.h>
32 #include <linux/ip.h>
33 #include <linux/icmp.h>
34 #include <arpa/inet.h>
35 #include <stdlib.h>
36 #include <netinet/if_ether.h>
37 #include <net/if_arp.h>
38 #include <asm/byteorder.h>
39 #include <byteswap.h>
40 #include <string.h>
41 #include <errno.h>
42 #include <sys/stat.h>
43 #include <sys/eventfd.h>
44 #include <sys/timerfd.h>
45 #include <sys/epoll.h>
46 #include <signal.h>
47 
48 /* memif protocol msg, ring and descriptor definitions */
49 #include <memif.h>
50 /* memif api */
51 #include <libmemif.h>
52 /* socket messaging functions */
53 #include <socket.h>
54 /* private structs and functions */
55 #include <memif_private.h>
56 
57 #define ERRLIST_LEN 39
58 #define MAX_ERRBUF_LEN 256
59 
60 #if __x86_x64__
61 #define MEMIF_MEMORY_BARRIER() __builtin_ia32_sfence ()
62 #else
63 #define MEMIF_MEMORY_BARRIER() __sync_synchronize ()
64 #endif /* __x86_x64__ */
65 
68 int poll_cancel_fd = -1;
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_ACCES */
77  "Permission to resoure denied.",
78  /* MEMIF_ERR_NO_FILE */
79  "Socket file does not exist",
80  /* MEMIF_ERR_FILE_LIMIT */
81  "System limit on total numer of open files reached.",
82  /* MEMIF_ERR_PROC_FILE_LIMIT */
83  "Per-process limit on total number of open files reached.",
84  /* MEMIF_ERR_ALREADY */
85  "Connection already requested.",
86  /* MEMIF_ERR_AGAIN */
87  "File descriptor refers to file other than socket, or operation would block.",
88  /* MEMIF_ERR_BAD_FD */
89  "Bad file descriptor.",
90  /* MEMIF_ERR_NOMEM */
91  "Out of memory.",
92  /* MEMIF_ERR_INVAL_ARG */
93  "Invalid argument.",
94  /* MEMIF_ERR_NOCONN */
95  "Memif connection handle does not point to existing conenction",
96  /* MEMIF_ERR_CONN */
97  "Memif connection handle points to existing connection",
98  /* MEMIF_ERR_CB_FDUPDATE */
99  "Callback memif_control_fd_update_t returned error",
100  /* MEMIF_ERR_FILE_NOT_SOCK */
101  "File specified by socket filename exists and is not socket.",
102  /* MEMIF_ERR_NO_SHMFD */
103  "Missing shared memory file descriptor. (internal error)",
104  /* MEMIF_ERR_COOKIE */
105  "Invalid cookie on ring. (internal error)",
106  /* MEMIF_ERR_NOBUF_RING */
107  "Ring buffer full.",
108  /* MEMIF_ERR_NOBUF */
109  "Not enough memif buffers. There are unreceived data in shared memory.",
110  /* MEMIF_ERR_NOBUF_DET */
111  "Not enough space for memif details in suplied buffer. String data might be malformed.",
112  /* MEMIF_ERR_INT_WRITE */
113  "Send interrupt error.",
114  /* MEMIF_ERR_MFMSG */
115  "Malformed message received on control channel.",
116  /* MEMIF_ERR_QID */
117  "Invalid queue id",
118  /* MEMIF_ERR_PROTO */
119  "Incompatible memory interface protocol version.",
120  /* MEMIF_ERR_ID */
121  "Unmatched interface id.",
122  /* MEMIF_ERR_ACCSLAVE */
123  "Slave cannot accept connection reqest.",
124  /* MEMIF_ERR_ALRCONN */
125  "Interface is already connected.",
126  /* MEMIF_ERR_MODE */
127  "Mode mismatch.",
128  /* MEMIF_ERR_SECRET */
129  "Secret mismatch.",
130  /* MEMIF_ERR_NOSECRET */
131  "Secret required.",
132  /* MEMIF_ERR_MAXREG */
133  "Limit on total number of regions reached.",
134  /* MEMIF_ERR_MAXRING */
135  "Limit on total number of ring reached.",
136  /* MEMIF_ERR_NO_INTFD */
137  "Missing interrupt file descriptor. (internal error)",
138  /* MEMIF_ERR_DISCONNECT */
139  "Interface received disconnect request.",
140  /* MEMIF_ERR_DISCONNECTED */
141  "Interface is disconnected.",
142  /* MEMIF_ERR_UNKNOWN_MSG */
143  "Unknown message type received on control channel. (internal error)",
144  /* MEMIF_ERR_POLL_CANCEL */
145  "Memif event polling was canceled.",
146  /* MEMIF_ERR_MAX_RING */
147  "Maximum log2 ring size is 15",
148  /* MEMIF_ERR_PRIVHDR */
149  "Private headers not supported."
150 };
151 
152 #define MEMIF_ERR_UNDEFINED "undefined error"
153 
154 char *
155 memif_strerror (int err_code)
156 {
157  if (err_code >= ERRLIST_LEN)
158  {
160  memif_buf[strlen (MEMIF_ERR_UNDEFINED)] = '\0';
161  }
162  else
163  {
164  strncpy (memif_buf, memif_errlist[err_code],
165  strlen (memif_errlist[err_code]));
166  memif_buf[strlen (memif_errlist[err_code])] = '\0';
167  }
168  return memif_buf;
169 }
170 
171 uint16_t
173 {
174  return MEMIF_VERSION;
175 }
176 
177 #define DBG_TX_BUF (0)
178 #define DBG_RX_BUF (1)
179 
180 #ifdef MEMIF_DBG_SHM
181 static void
182 print_bytes (void *data, uint16_t len, uint8_t q)
183 {
184  if (q == DBG_TX_BUF)
185  printf ("\nTX:\n\t");
186  else
187  printf ("\nRX:\n\t");
188  int i;
189  for (i = 0; i < len; i++)
190  {
191  if (i % 8 == 0)
192  printf ("\n%d:\t", i);
193  printf ("%02X ", ((uint8_t *) (data))[i]);
194  }
195  printf ("\n\n");
196 }
197 #endif /* MEMIF_DBG_SHM */
198 
199 int
201 {
202  DBG ("%s", strerror (err_code));
203 
204  if (err_code == 0)
205  return MEMIF_ERR_SUCCESS;
206  if (err_code == EACCES)
207  return MEMIF_ERR_ACCES;
208  if (err_code == ENFILE)
209  return MEMIF_ERR_FILE_LIMIT;
210  if (err_code == EMFILE)
212  if (err_code == ENOMEM)
213  return MEMIF_ERR_NOMEM;
214 /* connection refused if master does not exist
215  this error would spam the user until master was created */
216  if (err_code == ECONNREFUSED)
217  return MEMIF_ERR_SUCCESS;
218  if (err_code == EALREADY)
219  return MEMIF_ERR_ALREADY;
220  if (err_code == EAGAIN)
221  return MEMIF_ERR_AGAIN;
222  if (err_code == EBADF)
223  return MEMIF_ERR_BAD_FD;
224  if (err_code == ENOENT)
225  return MEMIF_ERR_NO_FILE;
226 
227  /* other syscall errors */
228  return MEMIF_ERR_SYSCALL;
229 }
230 
231 static int
232 memif_add_epoll_fd (int fd, uint32_t events)
233 {
234  if (fd < 0)
235  {
236  DBG ("invalid fd %d", fd);
237  return -1;
238  }
239  struct epoll_event evt;
240  memset (&evt, 0, sizeof (evt));
241  evt.events = events;
242  evt.data.fd = fd;
243  if (epoll_ctl (memif_epfd, EPOLL_CTL_ADD, fd, &evt) < 0)
244  {
245  DBG ("epoll_ctl: %s fd %d", strerror (errno), fd);
246  return -1;
247  }
248  DBG ("fd %d added to epoll", fd);
249  return 0;
250 }
251 
252 static int
253 memif_mod_epoll_fd (int fd, uint32_t events)
254 {
255  if (fd < 0)
256  {
257  DBG ("invalid fd %d", fd);
258  return -1;
259  }
260  struct epoll_event evt;
261  memset (&evt, 0, sizeof (evt));
262  evt.events = events;
263  evt.data.fd = fd;
264  if (epoll_ctl (memif_epfd, EPOLL_CTL_MOD, fd, &evt) < 0)
265  {
266  DBG ("epoll_ctl: %s fd %d", strerror (errno), fd);
267  return -1;
268  }
269  DBG ("fd %d moddified on epoll", fd);
270  return 0;
271 }
272 
273 static int
275 {
276  if (fd < 0)
277  {
278  DBG ("invalid fd %d", fd);
279  return -1;
280  }
281  struct epoll_event evt;
282  memset (&evt, 0, sizeof (evt));
283  if (epoll_ctl (memif_epfd, EPOLL_CTL_DEL, fd, &evt) < 0)
284  {
285  DBG ("epoll_ctl: %s fd %d", strerror (errno), fd);
286  return -1;
287  }
288  DBG ("fd %d removed from epoll", fd);
289  return 0;
290 }
291 
292 int
293 memif_control_fd_update (int fd, uint8_t events)
294 {
295  if (events & MEMIF_FD_EVENT_DEL)
296  return memif_del_epoll_fd (fd);
297 
298  uint32_t evt = 0;
299  if (events & MEMIF_FD_EVENT_READ)
300  evt |= EPOLLIN;
301  if (events & MEMIF_FD_EVENT_WRITE)
302  evt |= EPOLLOUT;
303 
304  if (events & MEMIF_FD_EVENT_MOD)
305  return memif_mod_epoll_fd (fd, evt);
306 
307  return memif_add_epoll_fd (fd, evt);
308 }
309 
310 int
311 add_list_elt (memif_list_elt_t * e, memif_list_elt_t ** list, uint16_t * len)
312 {
314 
315  int i;
316  for (i = 0; i < *len; i++)
317  {
318  if ((*list)[i].data_struct == NULL)
319  {
320  (*list)[i].key = e->key;
321  (*list)[i].data_struct = e->data_struct;
322  return i;
323  }
324  }
325  memif_list_elt_t *tmp;
326  tmp = realloc (*list, sizeof (memif_list_elt_t) * *len * 2);
327  if (tmp == NULL)
328  return -1;
329 
330  for (i = *len; i < *len * 2; i++)
331  {
332  tmp[i].key = -1;
333  tmp[i].data_struct = NULL;
334  }
335 
336  tmp[*len].key = e->key;
337  tmp[*len].data_struct = e->data_struct;
338  i = *len;
339  *len = *len * 2;
340  *list = tmp;
341 
342  return i;
343 }
344 
345 int
346 get_list_elt (memif_list_elt_t ** e, memif_list_elt_t * list, uint16_t len,
347  int key)
348 {
349  if (key == -1)
350  {
351  *e = NULL;
352  return -1;
353  }
354  int i;
355  for (i = 0; i < len; i++)
356  {
357  if (list[i].key == key)
358  {
359  *e = &list[i];
360  return 0;
361  }
362  }
363  *e = NULL;
364  return -1;
365 }
366 
367 /* does not free memory, only marks element as free */
368 int
369 free_list_elt (memif_list_elt_t * list, uint16_t len, int key)
370 {
371  int i;
372  for (i = 0; i < len; i++)
373  {
374  if (list[i].key == key)
375  {
376  list[i].key = -1;
377  list[i].data_struct = NULL;
378  return 0;
379  }
380  }
381 
382  return -1;
383 }
384 
385 int
386 free_list_elt_ctx (memif_list_elt_t * list, uint16_t len,
388 {
389  int i;
390  for (i = 0; i < len; i++)
391  {
392  if (list[i].key == -1)
393  {
394  if (list[i].data_struct == ctx)
395  {
396  list[i].data_struct = NULL;
397  return 0;
398  }
399  }
400  }
401 
402  return -1;
403 }
404 
405 static void
407 {
409  lm->control_fd_update = cb;
410 }
411 
412 static void
414 {
416  lm->alloc = ma;
417 }
418 
419 static void
421 {
423  lm->free = mf;
424 }
425 
426 int
427 memif_init (memif_control_fd_update_t * on_control_fd_update, char *app_name,
428  memif_alloc_t * memif_alloc, memif_free_t * memif_free)
429 {
430  int err = MEMIF_ERR_SUCCESS; /* 0 */
432  memset (lm, 0, sizeof (libmemif_main_t));
433 
434  if (memif_alloc != NULL)
435  {
436  memif_alloc_register (memif_alloc);
437  }
438  else
439  memif_alloc_register (malloc);
440 
441  if (memif_free != NULL)
442  memif_free_register (memif_free);
443  else
444  memif_free_register (free);
445 
446  if (app_name != NULL)
447  {
448  uint8_t len = (strlen (app_name) > MEMIF_NAME_LEN)
449  ? strlen (app_name) : MEMIF_NAME_LEN;
450  strncpy ((char *) lm->app_name, app_name, len);
451  }
452  else
453  {
454  strncpy ((char *) lm->app_name, MEMIF_DEFAULT_APP_NAME,
455  strlen (MEMIF_DEFAULT_APP_NAME));
456  }
457 
458  /* register control fd update callback */
459  if (on_control_fd_update != NULL)
460  memif_control_fd_update_register (on_control_fd_update);
461  else
462  {
463  memif_epfd = epoll_create (1);
465  if ((poll_cancel_fd = eventfd (0, EFD_NONBLOCK)) < 0)
466  {
467  err = errno;
468  DBG ("eventfd: %s", strerror (err));
469  return memif_syscall_error_handler (err);
470  }
472  DBG ("libmemif event polling initialized");
473  }
474 
475  lm->control_list_len = 2;
476  lm->interrupt_list_len = 2;
477  lm->listener_list_len = 1;
478  lm->pending_list_len = 1;
479 
480  lm->control_list =
481  lm->alloc (sizeof (memif_list_elt_t) * lm->control_list_len);
482  if (lm->control_list == NULL)
483  {
484  err = MEMIF_ERR_NOMEM;
485  goto error;
486  }
487  lm->interrupt_list =
488  lm->alloc (sizeof (memif_list_elt_t) * lm->interrupt_list_len);
489  if (lm->interrupt_list == NULL)
490  {
491  err = MEMIF_ERR_NOMEM;
492  goto error;
493  }
494  lm->listener_list =
495  lm->alloc (sizeof (memif_list_elt_t) * lm->listener_list_len);
496  if (lm->listener_list == NULL)
497  {
498  err = MEMIF_ERR_NOMEM;
499  goto error;
500  }
501  lm->pending_list =
502  lm->alloc (sizeof (memif_list_elt_t) * lm->pending_list_len);
503  if (lm->pending_list == NULL)
504  {
505  err = MEMIF_ERR_NOMEM;
506  goto error;
507  }
508 
509  int i;
510  for (i = 0; i < lm->control_list_len; i++)
511  {
512  lm->control_list[i].key = -1;
514  }
515  for (i = 0; i < lm->interrupt_list_len; i++)
516  {
517  lm->interrupt_list[i].key = -1;
519  }
520  for (i = 0; i < lm->listener_list_len; i++)
521  {
522  lm->listener_list[i].key = -1;
524  }
525  for (i = 0; i < lm->pending_list_len; i++)
526  {
527  lm->pending_list[i].key = -1;
529  }
530 
531  lm->disconn_slaves = 0;
532 
533  lm->timerfd = timerfd_create (CLOCK_REALTIME, TFD_NONBLOCK);
534  if (lm->timerfd < 0)
535  {
536  err = memif_syscall_error_handler (errno);
537  goto error;
538  }
539 
540  lm->arm.it_value.tv_sec = 2;
541  lm->arm.it_value.tv_nsec = 0;
542  lm->arm.it_interval.tv_sec = 2;
543  lm->arm.it_interval.tv_nsec = 0;
544 
545  if (lm->control_fd_update (lm->timerfd, MEMIF_FD_EVENT_READ) < 0)
546  {
547  DBG ("callback type memif_control_fd_update_t error!");
548  err = MEMIF_ERR_CB_FDUPDATE;
549  goto error;
550  }
551 
552  return err;
553 
554 error:
555  memif_cleanup ();
556  return err;
557 }
558 
559 static inline memif_ring_t *
561  uint16_t ring_num)
562 {
563  if (&conn->regions[0] == NULL)
564  return NULL;
565  void *p = conn->regions[0].shm;
566  int ring_size =
567  sizeof (memif_ring_t) +
568  sizeof (memif_desc_t) * (1 << conn->run_args.log2_ring_size);
569  p += (ring_num + type * conn->run_args.num_s2m_rings) * ring_size;
570 
571  return (memif_ring_t *) p;
572 }
573 
574 int
576  uint16_t qid)
577 {
579  if (conn == NULL)
580  return MEMIF_ERR_NOCONN;
581  uint8_t num =
582  (conn->args.is_master) ? conn->run_args.num_s2m_rings : conn->run_args.
583  num_m2s_rings;
584  if (qid >= num)
585  return MEMIF_ERR_QID;
586 
587  conn->rx_queues[qid].ring->flags = rx_mode;
588  DBG ("rx_mode flag: %u", conn->rx_queues[qid].ring->flags);
589  return MEMIF_ERR_SUCCESS;
590 }
591 
592 int
596  memif_interrupt_t * on_interrupt, void *private_ctx)
597 {
599  int err, i, index, sockfd = -1;
600  memif_list_elt_t list_elt;
601  memif_connection_t *conn = (memif_connection_t *) * c;
602  if (conn != NULL)
603  {
604  DBG ("This handle already points to existing memif.");
605  return MEMIF_ERR_CONN;
606  }
607  conn = (memif_connection_t *) lm->alloc (sizeof (memif_connection_t));
608  if (conn == NULL)
609  {
610  err = MEMIF_ERR_NOMEM;
611  goto error;
612  }
613  memset (conn, 0, sizeof (memif_connection_t));
614 
615  conn->args.interface_id = args->interface_id;
616 
617  if (args->log2_ring_size == 0)
619  else if (args->log2_ring_size > MEMIF_MAX_LOG2_RING_SIZE)
620  {
621  err = MEMIF_ERR_MAX_RING;
622  goto error;
623  }
624  if (args->buffer_size == 0)
626  if (args->num_s2m_rings == 0)
628  if (args->num_m2s_rings == 0)
630 
631  conn->args.num_s2m_rings = args->num_s2m_rings;
632  conn->args.num_m2s_rings = args->num_m2s_rings;
633  conn->args.buffer_size = args->buffer_size;
634  conn->args.log2_ring_size = args->log2_ring_size;
635  conn->args.is_master = args->is_master;
636  conn->args.mode = args->mode;
637  conn->msg_queue = NULL;
638  conn->regions = NULL;
639  conn->tx_queues = NULL;
640  conn->rx_queues = NULL;
641  conn->fd = -1;
642  conn->on_connect = on_connect;
643  conn->on_disconnect = on_disconnect;
644  conn->on_interrupt = on_interrupt;
645  conn->private_ctx = private_ctx;
646  memset (&conn->run_args, 0, sizeof (memif_conn_run_args_t));
647 
648  uint8_t l = strlen ((char *) args->interface_name);
649  strncpy ((char *) conn->args.interface_name, (char *) args->interface_name,
650  l);
651 
652  /* allocate and initialize socket_filename so it can be copyed to sun_path
653  without memory leaks */
654  conn->args.socket_filename = lm->alloc (sizeof (char *) * 108);
655  if (conn->args.socket_filename == NULL)
656  {
657  err = MEMIF_ERR_NOMEM;
658  goto error;
659  }
660  memset (conn->args.socket_filename, 0, 108 * sizeof (char *));
661 
662  if (args->socket_filename)
663  {
664  if (conn->args.socket_filename == NULL)
665  {
666  err = memif_syscall_error_handler (errno);
667  goto error;
668  }
669  strncpy ((char *) conn->args.socket_filename,
670  (char *) args->socket_filename,
671  strlen ((char *) args->socket_filename));
672  }
673  else
674  {
675  uint16_t sdl = strlen (MEMIF_DEFAULT_SOCKET_DIR);
676  uint16_t sfl = strlen (MEMIF_DEFAULT_SOCKET_FILENAME);
677  if (conn->args.socket_filename == NULL)
678  {
679  err = memif_syscall_error_handler (errno);
680  goto error;
681  }
682  strncpy ((char *) conn->args.socket_filename,
684  conn->args.socket_filename[sdl] = '/';
685  strncpy ((char *) (conn->args.socket_filename + 1 + sdl),
687  }
688 
689  if (args->secret)
690  {
691  l = strlen ((char *) args->secret);
692  strncpy ((char *) conn->args.secret, (char *) args->secret, l);
693  }
694 
695  if (conn->args.is_master)
696  {
697  conn->run_args.buffer_size = conn->args.buffer_size;
698  memif_socket_t *ms;
699  memif_list_elt_t elt;
700  for (i = 0; i < lm->listener_list_len; i++)
701  {
702  if ((ms =
704  {
705  if (strncmp
706  ((char *) ms->filename, (char *) conn->args.socket_filename,
707  strlen ((char *) ms->filename)) == 0)
708  {
709  /* add interface to listener socket */
710  elt.key = conn->args.interface_id;
711  *c = elt.data_struct = conn;
712  add_list_elt (&elt, &ms->interface_list,
713  &ms->interface_list_len);
714  ms->use_count++;
715  conn->listener_fd = ms->fd;
716  break;
717  }
718  }
719  else
720  {
721  struct stat file_stat;
722  if (stat ((char *) conn->args.socket_filename, &file_stat) == 0)
723  {
724  if (S_ISSOCK (file_stat.st_mode))
725  unlink ((char *) conn->args.socket_filename);
726  else
727  return memif_syscall_error_handler (errno);
728  }
729  DBG ("creating socket file");
730  ms = lm->alloc (sizeof (memif_socket_t));
731  if (ms == NULL)
732  {
733  err = MEMIF_ERR_NOMEM;
734  goto error;
735  }
736  ms->filename =
737  lm->alloc (strlen ((char *) conn->args.socket_filename) +
738  sizeof (char));
739  if (ms->filename == NULL)
740  {
741  err = MEMIF_ERR_NOMEM;
742  goto error;
743  }
744  memset (ms->filename, 0,
745  strlen ((char *) conn->args.socket_filename) +
746  sizeof (char));
747  strncpy ((char *) ms->filename,
748  (char *) conn->args.socket_filename,
749  strlen ((char *) conn->args.socket_filename));
750  ms->interface_list_len = 1;
751  ms->interface_list =
752  lm->alloc (sizeof (memif_list_elt_t) *
753  ms->interface_list_len);
754  if (ms->interface_list == NULL)
755  {
756  err = MEMIF_ERR_NOMEM;
757  goto error;
758  }
759  ms->interface_list[0].key = -1;
761  struct sockaddr_un un = { 0 };
762  int on = 1;
763 
764  ms->fd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
765  if (ms->fd < 0)
766  {
767  err = memif_syscall_error_handler (errno);
768  goto error;
769  }
770  DBG ("socket %d created", ms->fd);
771  un.sun_family = AF_UNIX;
772  strncpy ((char *) un.sun_path, (char *) ms->filename,
773  sizeof (un.sun_path) - 1);
774  DBG ("sockopt");
775  if (setsockopt
776  (ms->fd, SOL_SOCKET, SO_PASSCRED, &on, sizeof (on)) < 0)
777  {
778  err = memif_syscall_error_handler (errno);
779  goto error;
780  }
781  DBG ("bind");
782  if (bind (ms->fd, (struct sockaddr *) &un, sizeof (un)) < 0)
783  {
784  err = memif_syscall_error_handler (errno);
785  goto error;
786  }
787  DBG ("listen");
788  if (listen (ms->fd, 1) < 0)
789  {
790  err = memif_syscall_error_handler (errno);
791  goto error;
792  }
793  DBG ("stat");
794  if (stat ((char *) ms->filename, &file_stat) < 0)
795  {
796  err = memif_syscall_error_handler (errno);
797  goto error;
798  }
799 
800  /* add interface to listener socket */
801  elt.key = conn->args.interface_id;
802  *c = elt.data_struct = conn;
803  add_list_elt (&elt, &ms->interface_list,
804  &ms->interface_list_len);
805  ms->use_count = 1;
806  conn->listener_fd = ms->fd;
807 
808  /* add listener socket to libmemif main */
809  elt.key = ms->fd;
810  elt.data_struct = ms;
811  add_list_elt (&elt, &lm->listener_list, &lm->listener_list_len);
813  break;
814  }
815  }
816  }
817  else
818  {
819  if (lm->disconn_slaves == 0)
820  {
821  if (timerfd_settime (lm->timerfd, 0, &lm->arm, NULL) < 0)
822  {
823  err = memif_syscall_error_handler (errno);
824  goto error;
825  }
826  }
827 
828  lm->disconn_slaves++;
829 
830  list_elt.key = -1;
831  *c = list_elt.data_struct = conn;
832  if ((index =
833  add_list_elt (&list_elt, &lm->control_list,
834  &lm->control_list_len)) < 0)
835  {
836  err = MEMIF_ERR_NOMEM;
837  goto error;
838  }
839  }
840 
841  conn->index = index;
842 
843  return 0;
844 
845 error:
846  if (sockfd > 0)
847  close (sockfd);
848  sockfd = -1;
849  if (conn->args.socket_filename)
850  lm->free (conn->args.socket_filename);
851  if (conn != NULL)
852  lm->free (conn);
853  *c = conn = NULL;
854  return err;
855 }
856 
857 int
858 memif_control_fd_handler (int fd, uint8_t events)
859 {
860  int i, rv, sockfd = -1, err = MEMIF_ERR_SUCCESS; /* 0 */
861  uint16_t num;
862  memif_list_elt_t *e = NULL;
863  memif_connection_t *conn;
865  if (fd == lm->timerfd)
866  {
867  uint64_t b;
868  ssize_t size;
869  size = read (fd, &b, sizeof (b));
870  for (i = 0; i < lm->control_list_len; i++)
871  {
872  if ((lm->control_list[i].key < 0)
873  && (lm->control_list[i].data_struct != NULL))
874  {
875  conn = lm->control_list[i].data_struct;
876  if (conn->args.is_master)
877  continue;
878 
879  struct sockaddr_un sun;
880  sockfd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
881  if (sockfd < 0)
882  {
883  err = memif_syscall_error_handler (errno);
884  goto error;
885  }
886 
887  sun.sun_family = AF_UNIX;
888 
889  strncpy (sun.sun_path, conn->args.socket_filename,
890  sizeof (sun.sun_path) - 1);
891 
892  if (connect (sockfd, (struct sockaddr *) &sun,
893  sizeof (struct sockaddr_un)) == 0)
894  {
895  conn->fd = sockfd;
896  conn->read_fn = memif_conn_fd_read_ready;
897  conn->write_fn = memif_conn_fd_write_ready;
898  conn->error_fn = memif_conn_fd_error;
899 
900  lm->control_list[conn->index].key = conn->fd;
901 
902  lm->control_fd_update (sockfd,
905 
906  lm->disconn_slaves--;
907  if (lm->disconn_slaves == 0)
908  {
909  if (timerfd_settime (lm->timerfd, 0, &lm->disarm, NULL)
910  < 0)
911  {
912  err = memif_syscall_error_handler (errno);
913  goto error;
914  }
915  }
916  }
917  else
918  {
919  err = memif_syscall_error_handler (errno);
920  goto error;
921  }
922  }
923  }
924  }
925  else
926  {
928  if (e != NULL)
929  {
930  if (((memif_connection_t *) e->data_struct)->on_interrupt != NULL)
931  {
932  num =
933  (((memif_connection_t *) e->data_struct)->args.
934  is_master) ? ((memif_connection_t *) e->data_struct)->
935  run_args.num_s2m_rings : ((memif_connection_t *) e->
936  data_struct)->run_args.
937  num_m2s_rings;
938  for (i = 0; i < num; i++)
939  {
940  if (((memif_connection_t *) e->data_struct)->rx_queues[i].
941  int_fd == fd)
942  {
943  ((memif_connection_t *) e->
944  data_struct)->on_interrupt ((void *) e->data_struct,
945  ((memif_connection_t *)
946  e->data_struct)->
947  private_ctx, i);
948  return MEMIF_ERR_SUCCESS;
949  }
950  }
951  }
952  return MEMIF_ERR_SUCCESS;
953  }
954  get_list_elt (&e, lm->listener_list, lm->listener_list_len, fd);
955  if (e != NULL)
956  {
958  return MEMIF_ERR_SUCCESS;
959  }
960 
961  get_list_elt (&e, lm->pending_list, lm->pending_list_len, fd);
962  if (e != NULL)
963  {
964  memif_read_ready (fd);
965  return MEMIF_ERR_SUCCESS;
966  }
967 
968  get_list_elt (&e, lm->control_list, lm->control_list_len, fd);
969  if (e != NULL)
970  {
971  if (events & MEMIF_FD_EVENT_READ)
972  {
973  err =
974  ((memif_connection_t *) e->data_struct)->read_fn (e->
975  data_struct);
976  if (err != MEMIF_ERR_SUCCESS)
977  return err;
978  }
979  if (events & MEMIF_FD_EVENT_WRITE)
980  {
981  err =
982  ((memif_connection_t *) e->data_struct)->write_fn (e->
983  data_struct);
984  if (err != MEMIF_ERR_SUCCESS)
985  return err;
986  }
987  if (events & MEMIF_FD_EVENT_ERROR)
988  {
989  err =
990  ((memif_connection_t *) e->data_struct)->error_fn (e->
991  data_struct);
992  if (err != MEMIF_ERR_SUCCESS)
993  return err;
994  }
995  }
996  }
997 
998  return MEMIF_ERR_SUCCESS; /* 0 */
999 
1000 error:
1001  if (sockfd > 0)
1002  close (sockfd);
1003  sockfd = -1;
1004  return err;
1005 }
1006 
1007 int
1008 memif_poll_event (int timeout)
1009 {
1011  memif_list_elt_t *elt;
1012  struct epoll_event evt, *e;
1013  int en = 0, err = MEMIF_ERR_SUCCESS, i = 0; /* 0 */
1014  uint16_t num;
1015  uint32_t events = 0;
1016  uint64_t counter = 0;
1017  ssize_t r = 0;
1018  memset (&evt, 0, sizeof (evt));
1019  evt.events = EPOLLIN | EPOLLOUT;
1020  sigset_t sigset;
1021  sigemptyset (&sigset);
1022  en = epoll_pwait (memif_epfd, &evt, 1, timeout, &sigset);
1023  if (en < 0)
1024  {
1025  err = errno;
1026  DBG ("epoll_pwait: %s", strerror (err));
1027  return memif_syscall_error_handler (err);
1028  }
1029  if (en > 0)
1030  {
1031  if (evt.data.fd == poll_cancel_fd)
1032  {
1033  r = read (evt.data.fd, &counter, sizeof (counter));
1034  return MEMIF_ERR_POLL_CANCEL;
1035  }
1036  if (evt.events & EPOLLIN)
1037  events |= MEMIF_FD_EVENT_READ;
1038  if (evt.events & EPOLLOUT)
1039  events |= MEMIF_FD_EVENT_WRITE;
1040  if (evt.events & EPOLLERR)
1041  events |= MEMIF_FD_EVENT_ERROR;
1042  err = memif_control_fd_handler (evt.data.fd, events);
1043  return err;
1044  }
1045  return 0;
1046 }
1047 
1048 int
1050 {
1051  uint64_t counter = 1;
1052  ssize_t w = 0;
1053 
1054  if (poll_cancel_fd == -1)
1055  return 0;
1056  w = write (poll_cancel_fd, &counter, sizeof (counter));
1057  if (w < sizeof (counter))
1058  return MEMIF_ERR_INT_WRITE;
1059 
1060  return 0;
1061 }
1062 
1063 static void
1065 {
1066  if (*e == NULL)
1067  return;
1068  memif_msg_queue_free (lm, &(*e)->next);
1069  lm->free (*e);
1070  *e = NULL;
1071  return;
1072 }
1073 
1074 /* send disconnect msg and close interface */
1075 int
1077 {
1078  if (c == NULL)
1079  {
1080  DBG ("no connection");
1081  return MEMIF_ERR_NOCONN;
1082  }
1083  uint16_t num;
1084  int err = MEMIF_ERR_SUCCESS, i; /* 0 */
1085  memif_queue_t *mq;
1087  memif_list_elt_t *e;
1088 
1089  c->on_disconnect ((void *) c, c->private_ctx);
1090 
1091  if (c->fd > 0)
1092  {
1093  memif_msg_send_disconnect (c->fd, "interface deleted", 0);
1095  close (c->fd);
1096  }
1097  get_list_elt (&e, lm->control_list, lm->control_list_len, c->fd);
1098  if (e != NULL)
1099  {
1100  if (c->args.is_master)
1101  free_list_elt (lm->control_list, lm->control_list_len, c->fd);
1102  e->key = c->fd = -1;
1103  }
1104 
1105  if (c->tx_queues != NULL)
1106  {
1107  num =
1108  (c->args.is_master) ? c->run_args.num_m2s_rings : c->run_args.
1109  num_s2m_rings;
1110  for (i = 0; i < num; i++)
1111  {
1112  mq = &c->tx_queues[i];
1113  if (mq != NULL)
1114  {
1115  if (mq->int_fd > 0)
1116  close (mq->int_fd);
1118  mq->int_fd);
1119  mq->int_fd = -1;
1120  }
1121  }
1122  lm->free (c->tx_queues);
1123  c->tx_queues = NULL;
1124  }
1125 
1126  if (c->rx_queues != NULL)
1127  {
1128  num =
1129  (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
1130  num_m2s_rings;
1131  for (i = 0; i < num; i++)
1132  {
1133  mq = &c->rx_queues[i];
1134  if (mq != NULL)
1135  {
1136  if (mq->int_fd > 0)
1137  {
1138  if (c->on_interrupt != NULL)
1140  close (mq->int_fd);
1141  }
1143  mq->int_fd);
1144  mq->int_fd = -1;
1145  }
1146  }
1147  lm->free (c->rx_queues);
1148  c->rx_queues = NULL;
1149  }
1150 
1151  if (c->regions != NULL)
1152  {
1153  if (munmap (c->regions[0].shm, c->regions[0].region_size) < 0)
1154  return memif_syscall_error_handler (errno);
1155  if (c->regions[0].fd > 0)
1156  close (c->regions[0].fd);
1157  c->regions[0].fd = -1;
1158  lm->free (c->regions);
1159  c->regions = NULL;
1160  }
1161 
1162  memset (&c->run_args, 0, sizeof (memif_conn_run_args_t));
1163 
1164  memif_msg_queue_free (lm, &c->msg_queue);
1165 
1166  if (!(c->args.is_master))
1167  {
1168  if (lm->disconn_slaves == 0)
1169  {
1170  if (timerfd_settime (lm->timerfd, 0, &lm->arm, NULL) < 0)
1171  {
1172  err = memif_syscall_error_handler (errno);
1173  DBG ("timerfd_settime: arm");
1174  }
1175  }
1176  lm->disconn_slaves++;
1177  }
1178 
1179  return err;
1180 }
1181 
1182 int
1184 {
1185  memif_connection_t *c = (memif_connection_t *) * conn;
1186  if (c == NULL)
1187  {
1188  DBG ("no connection");
1189  return MEMIF_ERR_NOCONN;
1190  }
1192  memif_list_elt_t *e = NULL;
1193  memif_socket_t *ms = NULL;
1194 
1195  int err = MEMIF_ERR_SUCCESS;
1196 
1197  if (c->fd > 0)
1198  {
1199  DBG ("DISCONNECTING");
1200  err = memif_disconnect_internal (c);
1201  if (err == MEMIF_ERR_NOCONN)
1202  return err;
1203  }
1204 
1206 
1207  if (c->args.is_master)
1208  {
1210  c->listener_fd);
1211  if (e != NULL)
1212  {
1213  ms = (memif_socket_t *) e->data_struct;
1214  ms->use_count--;
1216  c->args.interface_id);
1217  if (ms->use_count <= 0)
1218  {
1219  lm->control_fd_update (c->listener_fd, MEMIF_FD_EVENT_DEL);
1221  c->listener_fd);
1222  close (c->listener_fd);
1223  c->listener_fd = ms->fd = -1;
1224  lm->free (ms->interface_list);
1225  ms->interface_list = NULL;
1226  lm->free (ms->filename);
1227  ms->filename = NULL;
1228  lm->free (ms);
1229  ms = NULL;
1230  }
1231  }
1232  }
1233  else
1234  {
1235  lm->disconn_slaves--;
1236  if (lm->disconn_slaves <= 0)
1237  {
1238  if (timerfd_settime (lm->timerfd, 0, &lm->disarm, NULL) < 0)
1239  {
1240  err = memif_syscall_error_handler (errno);
1241  DBG ("timerfd_settime: disarm");
1242  }
1243  }
1244  }
1245 
1246  if (c->args.socket_filename)
1247  lm->free (c->args.socket_filename);
1248  c->args.socket_filename = NULL;
1249 
1250  lm->free (c);
1251  c = NULL;
1252 
1253  *conn = c;
1254  return err;
1255 }
1256 
1257 int
1259 {
1261  memif_region_t *mr = c->regions;
1262  memif_queue_t *mq;
1263  int i;
1264  uint16_t num;
1265 
1266  if (mr != NULL)
1267  {
1268  if (!mr->shm)
1269  {
1270  if (mr->fd < 0)
1271  return MEMIF_ERR_NO_SHMFD;
1272 
1273  if ((mr->shm = mmap (NULL, mr->region_size, PROT_READ | PROT_WRITE,
1274  MAP_SHARED, mr->fd, 0)) == MAP_FAILED)
1275  {
1276  return memif_syscall_error_handler (errno);
1277  }
1278  }
1279  }
1280 
1281  num =
1282  (c->args.is_master) ? c->run_args.num_m2s_rings : c->run_args.
1283  num_s2m_rings;
1284  for (i = 0; i < num; i++)
1285  {
1286  mq = &c->tx_queues[i];
1287  if (mq != NULL)
1288  {
1289  mq->ring = c->regions[mq->region].shm + mq->offset;
1290  if (mq->ring->cookie != MEMIF_COOKIE)
1291  {
1292  DBG ("wrong cookie on tx ring %u", i);
1293  return MEMIF_ERR_COOKIE;
1294  }
1295  mq->ring->head = mq->ring->tail = mq->last_head = mq->alloc_bufs =
1296  0;
1297  }
1298  }
1299  num =
1300  (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
1301  num_m2s_rings;
1302  for (i = 0; i < num; i++)
1303  {
1304  mq = &c->rx_queues[i];
1305  if (mq != NULL)
1306  {
1307  mq->ring = c->regions[mq->region].shm + mq->offset;
1308  if (mq->ring->cookie != MEMIF_COOKIE)
1309  {
1310  DBG ("wrong cookie on rx ring %u", i);
1311  return MEMIF_ERR_COOKIE;
1312  }
1313  mq->ring->head = mq->ring->tail = mq->last_head = mq->alloc_bufs =
1314  0;
1315  }
1316  }
1317 
1319 
1320  return 0;
1321 }
1322 
1323 int
1325 {
1326  memif_ring_t *ring = NULL;
1327  memif_region_t *r;
1328  int i, j;
1330  memif_list_elt_t e;
1331 
1332  conn->regions = (memif_region_t *) lm->alloc (sizeof (memif_region_t));
1333  if (conn->regions == NULL)
1334  return MEMIF_ERR_NOMEM;
1335  r = conn->regions;
1336 
1337  r->buffer_offset =
1338  (conn->run_args.num_s2m_rings +
1339  conn->run_args.num_m2s_rings) * (sizeof (memif_ring_t) +
1340  sizeof (memif_desc_t) *
1341  (1 << conn->run_args.log2_ring_size));
1342 
1343  r->region_size = r->buffer_offset +
1344  conn->run_args.buffer_size * (1 << conn->run_args.log2_ring_size) *
1345  (conn->run_args.num_s2m_rings + conn->run_args.num_m2s_rings);
1346 
1347  if ((r->fd =
1348  memfd_create ("memif region 0", MFD_ALLOW_SEALING)) == -1)
1349  if ((r->fd = memfd_create ("memif region 0", MFD_ALLOW_SEALING)) == -1)
1350  return memif_syscall_error_handler (errno);
1351 
1352  if ((fcntl (r->fd, F_ADD_SEALS, F_SEAL_SHRINK)) == -1)
1353  return memif_syscall_error_handler (errno);
1354 
1355  if ((ftruncate (r->fd, r->region_size)) == -1)
1356  return memif_syscall_error_handler (errno);
1357 
1358  if ((r->shm = mmap (NULL, r->region_size, PROT_READ | PROT_WRITE,
1359  MAP_SHARED, r->fd, 0)) == MAP_FAILED)
1360  return memif_syscall_error_handler (errno);
1361 
1362  for (i = 0; i < conn->run_args.num_s2m_rings; i++)
1363  {
1364  ring = memif_get_ring (conn, MEMIF_RING_S2M, i);
1365  DBG ("RING: %p I: %d", ring, i);
1366  ring->head = ring->tail = 0;
1367  ring->cookie = MEMIF_COOKIE;
1368  ring->flags = 0;
1369  for (j = 0; j < (1 << conn->run_args.log2_ring_size); j++)
1370  {
1371  uint16_t slot = i * (1 << conn->run_args.log2_ring_size) + j;
1372  ring->desc[j].region = 0;
1373  ring->desc[j].offset = r->buffer_offset +
1374  (uint32_t) (slot * conn->run_args.buffer_size);
1375  ring->desc[j].length = conn->run_args.buffer_size;
1376  }
1377  }
1378  for (i = 0; i < conn->run_args.num_m2s_rings; i++)
1379  {
1380  ring = memif_get_ring (conn, MEMIF_RING_M2S, i);
1381  DBG ("RING: %p I: %d", ring, i);
1382  ring->head = ring->tail = 0;
1383  ring->cookie = MEMIF_COOKIE;
1384  ring->flags = 0;
1385  for (j = 0; j < (1 << conn->run_args.log2_ring_size); j++)
1386  {
1387  uint16_t slot =
1388  (i +
1389  conn->run_args.num_s2m_rings) *
1390  (1 << conn->run_args.log2_ring_size) + j;
1391  ring->desc[j].region = 0;
1392  ring->desc[j].offset = r->buffer_offset +
1393  (uint32_t) (slot * conn->run_args.buffer_size);
1394  ring->desc[j].length = conn->run_args.buffer_size;
1395  }
1396  }
1397  memif_queue_t *mq;
1398  mq =
1399  (memif_queue_t *) lm->alloc (sizeof (memif_queue_t) *
1400  conn->run_args.num_s2m_rings);
1401  if (mq == NULL)
1402  return MEMIF_ERR_NOMEM;
1403  int x;
1404  for (x = 0; x < conn->run_args.num_s2m_rings; x++)
1405  {
1406  if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
1407  return memif_syscall_error_handler (errno);
1408  /* add int fd to interrupt fd list */
1409  e.key = mq[x].int_fd;
1410  e.data_struct = conn;
1412 
1413  mq[x].ring = memif_get_ring (conn, MEMIF_RING_S2M, x);
1414  DBG ("RING: %p I: %d", mq[x].ring, x);
1415  mq[x].log2_ring_size = conn->run_args.log2_ring_size;
1416  mq[x].region = 0;
1417  mq[x].offset =
1418  (void *) mq[x].ring - (void *) conn->regions[mq->region].shm;
1419  mq[x].last_head = 0;
1420  mq[x].alloc_bufs = 0;
1421  }
1422  conn->tx_queues = mq;
1423 
1424  mq =
1425  (memif_queue_t *) lm->alloc (sizeof (memif_queue_t) *
1426  conn->run_args.num_m2s_rings);
1427  if (mq == NULL)
1428  return MEMIF_ERR_NOMEM;
1429  for (x = 0; x < conn->run_args.num_m2s_rings; x++)
1430  {
1431  if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
1432  return memif_syscall_error_handler (errno);
1433  /* add int fd to interrupt fd list */
1434  e.key = mq[x].int_fd;
1435  e.data_struct = conn;
1437 
1438  mq[x].ring = memif_get_ring (conn, MEMIF_RING_M2S, x);
1439  DBG ("RING: %p I: %d", mq[x].ring, x);
1440  mq[x].log2_ring_size = conn->run_args.log2_ring_size;
1441  mq[x].region = 0;
1442  mq[x].offset =
1443  (void *) mq[x].ring - (void *) conn->regions[mq->region].shm;
1444  mq[x].last_head = 0;
1445  mq[x].alloc_bufs = 0;
1446  }
1447  conn->rx_queues = mq;
1448 
1449  return 0;
1450 }
1451 
1452 int
1454  memif_buffer_t * bufs, uint16_t count,
1455  uint16_t * count_out)
1456 {
1458  if (EXPECT_FALSE (c == NULL))
1459  return MEMIF_ERR_NOCONN;
1460  if (EXPECT_FALSE (c->fd < 0))
1461  return MEMIF_ERR_DISCONNECTED;
1462  uint8_t num =
1463  (c->args.is_master) ? c->run_args.num_m2s_rings : c->run_args.
1464  num_s2m_rings;
1465  if (EXPECT_FALSE (qid >= num))
1466  return MEMIF_ERR_QID;
1467  if (EXPECT_FALSE (!count_out))
1468  return MEMIF_ERR_INVAL_ARG;
1469  if (EXPECT_FALSE (c->args.is_master))
1470  return MEMIF_ERR_INVAL_ARG;
1471 
1472  memif_queue_t *mq = &c->tx_queues[qid];
1473  memif_ring_t *ring = mq->ring;
1474  memif_buffer_t *b0;
1475  uint16_t mask = (1 << mq->log2_ring_size) - 1;
1476  uint16_t ring_size;
1477  uint16_t slot, ns;
1478  int i, err = MEMIF_ERR_SUCCESS; /* 0 */
1479  *count_out = 0;
1480 
1481  ring_size = (1 << mq->log2_ring_size);
1482  ns = ring->tail - mq->last_tail;
1483  mq->last_tail += ns;
1484  slot = (c->args.is_master) ? ring->tail : ring->head;
1485  slot += mq->alloc_bufs;
1486 
1487  /* can only be called by slave */
1488  ns = ring_size - ring->head + mq->alloc_bufs + mq->last_tail;
1489 
1490  b0 = bufs;
1491 
1492  while (count && ns)
1493  {
1494  if (EXPECT_FALSE ((b0->flags & MEMIF_BUFFER_FLAG_RX) == 0))
1495  {
1496  /* not a valid buffer */
1497  count--;
1498  continue;
1499  }
1500  b0->flags &= ~MEMIF_BUFFER_FLAG_RX;
1501 
1502  ((memif_ring_t *) b0->ring)->desc[b0->desc_index & mask].offset = ring->desc[slot & mask].offset; /* put free buffer on rx ring */
1503 
1504  ring->desc[slot & mask].offset =
1505  (uint32_t) (b0->data - c->regions->shm);
1506  ring->desc[slot & mask].flags |=
1508 
1509  b0->desc_index = slot;
1510 
1511  mq->alloc_bufs++;
1512  slot++;
1513 
1514  count--;
1515  ns--;
1516  b0++;
1517  *count_out += 1;
1518  }
1519 
1520  DBG ("allocated: %u/%u bufs. Total %u allocated bufs", *count_out, count,
1521  mq->alloc_bufs);
1522 
1523  if (count)
1524  {
1525  DBG ("ring buffer full! qid: %u", qid);
1526  err = MEMIF_ERR_NOBUF_RING;
1527  }
1528 
1529 error:
1530  return err;
1531 }
1532 
1533 int
1535  memif_buffer_t * bufs, uint16_t count,
1536  uint16_t * count_out, uint16_t size)
1537 {
1539  if (EXPECT_FALSE (c == NULL))
1540  return MEMIF_ERR_NOCONN;
1541  if (EXPECT_FALSE (c->fd < 0))
1542  return MEMIF_ERR_DISCONNECTED;
1543  uint8_t num =
1544  (c->args.is_master) ? c->run_args.num_m2s_rings : c->run_args.
1545  num_s2m_rings;
1546  if (EXPECT_FALSE (qid >= num))
1547  return MEMIF_ERR_QID;
1548  if (EXPECT_FALSE (!count_out))
1549  return MEMIF_ERR_INVAL_ARG;
1550 
1551  memif_queue_t *mq = &c->tx_queues[qid];
1552  memif_ring_t *ring = mq->ring;
1553  memif_buffer_t *b0, *b1;
1554  uint16_t mask = (1 << mq->log2_ring_size) - 1;
1555  uint16_t ring_size;
1556  uint16_t slot, ns;
1557  int i, err = MEMIF_ERR_SUCCESS; /* 0 */
1558  uint16_t dst_left, src_left;
1559  uint16_t saved_count;
1560  memif_buffer_t *saved_b;
1561  *count_out = 0;
1562 
1563  ring_size = (1 << mq->log2_ring_size);
1564  ns = ring->tail - mq->last_tail;
1565  mq->last_tail += ns;
1566  slot = (c->args.is_master) ? ring->tail : ring->head;
1567  slot += mq->alloc_bufs;
1568 
1569  if (c->args.is_master)
1570  ns = ring->head + mq->alloc_bufs - ring->tail;
1571  else
1572  ns = ring_size - ring->head + mq->alloc_bufs + mq->last_tail;
1573 
1574  while (count && ns)
1575  {
1576  b0 = (bufs + *count_out);
1577 
1578  saved_b = b0;
1579  saved_count = count;
1580 
1581  b0->desc_index = slot;
1582  ring->desc[slot & mask].flags = 0;
1583 
1584  /* slave can produce buffer with original length */
1585  dst_left = (c->args.is_master) ? ring->desc[slot & mask].length :
1586  c->run_args.buffer_size;
1587  src_left = size;
1588 
1589  while (src_left)
1590  {
1591  if (EXPECT_FALSE (dst_left == 0))
1592  {
1593  if (count && ns)
1594  {
1595  slot++;
1596  *count_out += 1;
1597  mq->alloc_bufs++;
1598  ns--;
1599  count--;
1600 
1601  ring->desc[b0->desc_index & mask].flags |=
1604 
1605  b0 = (bufs + *count_out);
1606  b0->desc_index = slot;
1607  dst_left =
1608  (c->args.is_master) ? ring->desc[slot & mask].length : c->
1609  run_args.buffer_size;
1610  ring->desc[slot & mask].flags = 0;
1611  }
1612  else
1613  {
1614  /* rollback allocated chain buffers */
1615  memset (saved_b, 0, sizeof (memif_buffer_t)
1616  * (saved_count - count + 1));
1617  *count_out -= saved_count - count;
1618  mq->alloc_bufs = saved_count - count;
1619  goto no_ns;
1620  }
1621  }
1622  b0->len = memif_min (dst_left, src_left);
1623 
1624  /* slave resets buffer offset */
1625  if (c->args.is_master == 0)
1626  {
1627  uint16_t x =
1628  (ring->desc[slot & mask].offset -
1629  c->regions->buffer_offset) / c->run_args.buffer_size;
1630  ring->desc[slot & mask].offset =
1631  c->regions->buffer_offset + (x * c->run_args.buffer_size);
1632  }
1633 
1634  b0->data = c->regions->shm + ring->desc[slot & mask].offset;
1635 
1636  src_left -= b0->len;
1637  dst_left -= b0->len;
1638  }
1639 
1640  slot++;
1641  *count_out += 1;
1642  mq->alloc_bufs++;
1643  ns--;
1644  count--;
1645  }
1646 
1647 no_ns:
1648 
1649  DBG ("allocated: %u/%u bufs. Total %u allocated bufs", *count_out, count,
1650  mq->alloc_bufs);
1651 
1652  if (count)
1653  {
1654  DBG ("ring buffer full! qid: %u", qid);
1655  err = MEMIF_ERR_NOBUF_RING;
1656  }
1657 
1658 error:
1659  return err;
1660 }
1661 
1662 int
1663 memif_refill_queue (memif_conn_handle_t conn, uint16_t qid, uint16_t count,
1664  uint16_t headroom)
1665 {
1667  if (EXPECT_FALSE (c == NULL))
1668  return MEMIF_ERR_NOCONN;
1669  if (EXPECT_FALSE (c->fd < 0))
1670  return MEMIF_ERR_DISCONNECTED;
1671  uint8_t num =
1672  (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
1673  num_m2s_rings;
1674  if (EXPECT_FALSE (qid >= num))
1675  return MEMIF_ERR_QID;
1677  memif_queue_t *mq = &c->rx_queues[qid];
1678  memif_ring_t *ring = mq->ring;
1679  uint16_t mask = (1 << mq->log2_ring_size) - 1;
1680  uint16_t slot;
1681 
1682  if (c->args.is_master)
1683  {
1685  ring->tail =
1686  (ring->tail + count <=
1687  mq->last_head) ? ring->tail + count : mq->last_head;
1688  return MEMIF_ERR_SUCCESS;
1689  }
1690 
1691  uint16_t head = ring->head;
1692  uint16_t ns = (1 << mq->log2_ring_size) - head + mq->last_tail;
1693  head += (count < ns) ? count : ns;
1694 
1695  if (headroom)
1696  {
1697  slot = (c->args.is_master) ? ring->head : ring->tail;
1698  while (slot < head)
1699  {
1700  uint16_t x =
1701  (ring->desc[slot & mask].offset -
1702  c->regions->buffer_offset) / c->run_args.buffer_size;
1703  ring->desc[slot & mask].offset =
1704  c->regions->buffer_offset + (x * c->run_args.buffer_size) +
1705  headroom;
1706 
1707  slot++;
1708  }
1709  }
1710 
1712  ring->head = head;
1713 
1714  return MEMIF_ERR_SUCCESS; /* 0 */
1715 }
1716 
1717 int
1719  memif_buffer_t * bufs, uint16_t count, uint16_t * tx)
1720 {
1722  if (EXPECT_FALSE (c == NULL))
1723  return MEMIF_ERR_NOCONN;
1724  if (EXPECT_FALSE (c->fd < 0))
1725  return MEMIF_ERR_DISCONNECTED;
1726  uint8_t num =
1727  (c->args.is_master) ? c->run_args.num_m2s_rings : c->run_args.
1728  num_s2m_rings;
1729  if (EXPECT_FALSE (qid >= num))
1730  return MEMIF_ERR_QID;
1731  if (EXPECT_FALSE (!tx))
1732  return MEMIF_ERR_INVAL_ARG;
1733 
1734  memif_queue_t *mq = &c->tx_queues[qid];
1735  memif_ring_t *ring = mq->ring;
1736  uint16_t mask = (1 << mq->log2_ring_size) - 1;
1737  memif_buffer_t *b0;
1738  *tx = 0;
1739 
1740  if (count > mq->alloc_bufs)
1741  count = mq->alloc_bufs;
1742 
1743  if (EXPECT_FALSE (count == 0))
1744  return MEMIF_ERR_SUCCESS;
1745 
1746  while (count)
1747  {
1748  b0 = (bufs + *tx);
1749  ring->desc[b0->desc_index & mask].length = b0->len;
1750 
1751 #ifdef MEMIF_DBG_SHM
1752  printf ("offset: %-6d\n", ring->desc[b0->desc_index & mask].offset);
1753  printf ("data: %p\n",
1754  memif_get_buffer (c, ring, b0->desc_index & mask));
1755  printf ("index: %u\n", b0->desc_index);
1756  print_bytes (memif_get_buffer (c, ring, b0->desc_index & mask),
1757  ring->desc[b0->desc_index & mask].length, DBG_TX_BUF);
1758 #endif /* MEMIF_DBG_SHM */
1759 
1760  *tx += 1;
1761  count--;
1762  }
1763 
1764 
1766  if (c->args.is_master)
1767  ring->tail = b0->desc_index + 1;
1768  else
1769  ring->head = b0->desc_index + 1;
1770 
1771  mq->alloc_bufs -= *tx;
1772 
1773  if ((ring->flags & MEMIF_RING_FLAG_MASK_INT) == 0)
1774  {
1775  uint64_t a = 1;
1776  int r = write (mq->int_fd, &a, sizeof (a));
1777  if (r < 0)
1778  return MEMIF_ERR_INT_WRITE;
1779  }
1780 
1781  return MEMIF_ERR_SUCCESS; /* 0 */
1782 }
1783 
1784 int
1786  memif_buffer_t * bufs, uint16_t count, uint16_t * rx)
1787 {
1789  if (EXPECT_FALSE (c == NULL))
1790  return MEMIF_ERR_NOCONN;
1791  if (EXPECT_FALSE (c->fd < 0))
1792  return MEMIF_ERR_DISCONNECTED;
1793  uint8_t num =
1794  (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
1795  num_m2s_rings;
1796  if (EXPECT_FALSE (qid >= num))
1797  return MEMIF_ERR_QID;
1798  if (EXPECT_FALSE (!rx))
1799  return MEMIF_ERR_INVAL_ARG;
1800 
1801  memif_queue_t *mq = &c->rx_queues[qid];
1802  memif_ring_t *ring = mq->ring;
1803  uint16_t cur_slot, last_slot;
1804  uint16_t ns;
1805  uint16_t mask = (1 << mq->log2_ring_size) - 1;
1806  memif_buffer_t *b0, *b1;
1807  *rx = 0;
1808 
1809  uint64_t b;
1810  ssize_t r = read (mq->int_fd, &b, sizeof (b));
1811  if (EXPECT_FALSE ((r == -1) && (errno != EAGAIN)))
1812  return memif_syscall_error_handler (errno);
1813 
1814  cur_slot = (c->args.is_master) ? mq->last_head : mq->last_tail;
1815  last_slot = (c->args.is_master) ? ring->head : ring->tail;
1816  if (cur_slot == last_slot)
1817  return MEMIF_ERR_SUCCESS;
1818 
1819  ns = last_slot - cur_slot;
1820 
1821  while (ns && count)
1822  {
1823  b0 = (bufs + *rx);
1824 
1825  b0->desc_index = cur_slot;
1826  b0->data = memif_get_buffer (c, ring, cur_slot & mask);
1827  b0->len = ring->desc[cur_slot & mask].length;
1828  /* slave resets buffer length */
1829  if (c->args.is_master == 0)
1830  {
1831  ring->desc[cur_slot & mask].length = c->run_args.buffer_size;
1832  }
1833 
1835  if (ring->desc[cur_slot & mask].flags & MEMIF_DESC_FLAG_NEXT)
1836  {
1838  ring->desc[cur_slot & mask].flags &= ~MEMIF_DESC_FLAG_NEXT;
1839  }
1840 /* b0->offset = ring->desc[cur_slot & mask].offset;*/
1841  b0->ring = ring;
1842 #ifdef MEMIF_DBG_SHM
1843  printf ("data: %p\n", b0->data);
1844  printf ("index: %u\n", b0->desc_index);
1845  printf ("ring: %p\n", b0->ring);
1846  print_bytes (b0->data, b0->len, DBG_RX_BUF);
1847 #endif /* MEMIF_DBG_SHM */
1848  ns--;
1849  *rx += 1;
1850 
1851  count--;
1852  cur_slot++;
1853  }
1854 
1855  if (c->args.is_master)
1856  mq->last_head = cur_slot;
1857  else
1858  mq->last_tail = cur_slot;
1859 
1860  if (ns)
1861  {
1862  DBG ("not enough buffers!");
1863  return MEMIF_ERR_NOBUF;
1864  }
1865 
1866  return MEMIF_ERR_SUCCESS; /* 0 */
1867 }
1868 
1869 int
1871  char *buf, ssize_t buflen)
1872 {
1875  if (c == NULL)
1876  return MEMIF_ERR_NOCONN;
1877 
1878  int err = MEMIF_ERR_SUCCESS, i;
1879  ssize_t l0, l1, total_l;
1880  l0 = 0;
1881 
1882  l1 = strlen ((char *) c->args.interface_name);
1883  if (l0 + l1 < buflen)
1884  {
1885  md->if_name = strcpy (buf + l0, (char *) c->args.interface_name);
1886  l0 += l1 + 1;
1887  }
1888  else
1889  err = MEMIF_ERR_NOBUF_DET;
1890 
1891  l1 = strlen ((char *) lm->app_name);
1892  if (l0 + l1 < buflen)
1893  {
1894  md->inst_name = strcpy (buf + l0, (char *) lm->app_name);
1895  l0 += l1 + 1;
1896  }
1897  else
1898  err = MEMIF_ERR_NOBUF_DET;
1899 
1900  l1 = strlen ((char *) c->remote_if_name);
1901  if (l0 + l1 < buflen)
1902  {
1903  md->remote_if_name = strcpy (buf + l0, (char *) c->remote_if_name);
1904  l0 += l1 + 1;
1905  }
1906  else
1907  err = MEMIF_ERR_NOBUF_DET;
1908 
1909  l1 = strlen ((char *) c->remote_name);
1910  if (l0 + l1 < buflen)
1911  {
1912  md->remote_inst_name = strcpy (buf + l0, (char *) c->remote_name);
1913  l0 += l1 + 1;
1914  }
1915  else
1916  err = MEMIF_ERR_NOBUF_DET;
1917 
1918  md->id = c->args.interface_id;
1919 
1920  if (c->args.secret)
1921  {
1922  l1 = strlen ((char *) c->args.secret);
1923  if (l0 + l1 < buflen)
1924  {
1925  md->secret = strcpy (buf + l0, (char *) c->args.secret);
1926  l0 += l1 + 1;
1927  }
1928  else
1929  err = MEMIF_ERR_NOBUF_DET;
1930  }
1931 
1932  md->role = (c->args.is_master) ? 0 : 1;
1933  md->mode = c->args.mode;
1934 
1935  l1 = strlen ((char *) c->args.socket_filename);
1936  if (l0 + l1 < buflen)
1937  {
1938  md->socket_filename =
1939  strcpy (buf + l0, (char *) c->args.socket_filename);
1940  l0 += l1 + 1;
1941  }
1942  else
1943  err = MEMIF_ERR_NOBUF_DET;
1944 
1945  md->rx_queues_num =
1946  (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
1947  num_m2s_rings;
1948 
1949  l1 = sizeof (memif_queue_details_t) * md->rx_queues_num;
1950  if (l0 + l1 <= buflen)
1951  {
1952  md->rx_queues = (memif_queue_details_t *) buf + l0;
1953  l0 += l1;
1954  }
1955  else
1956  err = MEMIF_ERR_NOBUF_DET;
1957 
1958  for (i = 0; i < md->rx_queues_num; i++)
1959  {
1960  md->rx_queues[i].qid = i;
1961  md->rx_queues[i].ring_size = (1 << c->rx_queues[i].log2_ring_size);
1962  md->rx_queues[i].flags = c->rx_queues[i].ring->flags;
1963  md->rx_queues[i].head = c->rx_queues[i].ring->head;
1964  md->rx_queues[i].tail = c->rx_queues[i].ring->tail;
1965  md->rx_queues[i].buffer_size = c->run_args.buffer_size;
1966  }
1967 
1968  md->tx_queues_num =
1969  (c->args.is_master) ? c->run_args.num_m2s_rings : c->run_args.
1970  num_s2m_rings;
1971 
1972  l1 = sizeof (memif_queue_details_t) * md->tx_queues_num;
1973  if (l0 + l1 <= buflen)
1974  {
1975  md->tx_queues = (memif_queue_details_t *) buf + l0;
1976  l0 += l1;
1977  }
1978  else
1979  err = MEMIF_ERR_NOBUF_DET;
1980 
1981  for (i = 0; i < md->tx_queues_num; i++)
1982  {
1983  md->tx_queues[i].qid = i;
1984  md->tx_queues[i].ring_size = (1 << c->tx_queues[i].log2_ring_size);
1985  md->tx_queues[i].flags = c->tx_queues[i].ring->flags;
1986  md->tx_queues[i].head = c->tx_queues[i].ring->head;
1987  md->tx_queues[i].tail = c->tx_queues[i].ring->tail;
1988  md->tx_queues[i].buffer_size = c->run_args.buffer_size;
1989  }
1990 
1991  md->link_up_down = (c->fd > 0) ? 1 : 0;
1992 
1993  return err; /* 0 */
1994 }
1995 
1996 int
1997 memif_get_queue_efd (memif_conn_handle_t conn, uint16_t qid, int *efd)
1998 {
2000  *efd = -1;
2001  if (c == NULL)
2002  return MEMIF_ERR_NOCONN;
2003  if (c->fd < 0)
2004  return MEMIF_ERR_DISCONNECTED;
2005  uint8_t num =
2006  (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
2007  num_m2s_rings;
2008  if (qid >= num)
2009  return MEMIF_ERR_QID;
2010 
2011  *efd = c->rx_queues[qid].int_fd;
2012 
2013  return MEMIF_ERR_SUCCESS;
2014 }
2015 
2016 int
2018 {
2020  if (lm->control_list)
2021  lm->free (lm->control_list);
2022  lm->control_list = NULL;
2023  if (lm->interrupt_list)
2024  lm->free (lm->interrupt_list);
2025  lm->interrupt_list = NULL;
2026  if (lm->listener_list)
2027  lm->free (lm->listener_list);
2028  lm->listener_list = NULL;
2029  if (lm->pending_list)
2030  lm->free (lm->pending_list);
2031  lm->pending_list = NULL;
2032  if (poll_cancel_fd != -1)
2033  close (poll_cancel_fd);
2034 
2035  return MEMIF_ERR_SUCCESS; /* 0 */
2036 }
int poll_cancel_fd
Definition: main.c:68
#define MAX_ERRBUF_LEN
Definition: main.c:58
#define MEMIF_DEFAULT_LOG2_RING_SIZE
Definition: memif_private.h:41
static void memif_free_register(memif_free_t *mf)
Definition: main.c:420
uint8_t * filename
#define EXPECT_FALSE(x)
Definition: memif_private.h:56
a
Definition: bitmap.h:516
uint8_t * inst_name
Definition: libmemif.h:271
uint8_t * secret
Definition: libmemif.h:276
static char memif_buf[MAX_ERRBUF_LEN]
Definition: main.c:70
int on_disconnect(memif_conn_handle_t conn, void *private_ctx)
Definition: main.c:186
void * ring
Definition: libmemif.h:214
#define MEMIF_FD_EVENT_READ
user needs to set events that occured on fd and pass them to memif_control_fd_handler ...
Definition: libmemif.h:87
uint8_t num_m2s_rings
Definition: libmemif.h:187
#define F_ADD_SEALS
Definition: mem.c:40
#define NULL
Definition: clib.h:55
uint16_t buffer_size
Definition: libmemif.h:188
static int memfd_create(const char *name, unsigned int flags)
Definition: syscall.h:44
uint8_t secret[24]
Definition: libmemif.h:184
static void memif_msg_queue_free(libmemif_main_t *lm, memif_msg_queue_elt_t **e)
Definition: main.c:1064
uint32_t interface_id
Definition: libmemif.h:192
memif_list_elt_t * pending_list
int memif_conn_fd_read_ready(memif_connection_t *c)
Definition: socket.c:815
#define MEMIF_NAME_LEN
Definition: memif_private.h:34
uint32_t alloc_bufs
Definition: memif_private.h:89
for(i=1;i<=collision_buckets;i++)
int i
#define MEMIF_ERR_UNDEFINED
Definition: main.c:152
clib_error_t * memif_msg_send_disconnect(memif_if_t *mif, clib_error_t *err)
Definition: socket.c:190
int memif_disconnect_internal(memif_connection_t *c)
Definition: main.c:1076
int( memif_control_fd_update_t)(int fd, uint8_t events)
Memif control file descriptor update (callback function)
Definition: libmemif.h:130
memif_control_fd_update_t * control_fd_update
static void memif_control_fd_update_register(memif_control_fd_update_t *cb)
Definition: main.c:406
uint16_t desc_index
Definition: libmemif.h:213
#define MEMIF_MEMORY_BARRIER()
Definition: main.c:63
uint8_t * remote_inst_name
Definition: libmemif.h:273
static memif_ring_t * memif_get_ring(memif_connection_t *conn, memif_ring_type_t type, uint16_t ring_num)
Definition: main.c:560
uint32_t length
Definition: memif.h:152
int memif_refill_queue(memif_conn_handle_t conn, uint16_t qid, uint16_t count, uint16_t headroom)
Memif refill ring.
Definition: main.c:1663
#define MEMIF_DEFAULT_APP_NAME
Default name of application using libmemif.
Definition: libmemif.h:28
memif_list_elt_t * interface_list
int on_connect(memif_conn_handle_t conn, void *private_ctx)
Definition: main.c:177
uint8_t num_s2m_rings
Definition: libmemif.h:186
static void memif_alloc_register(memif_alloc_t *ma)
Definition: main.c:413
uint32_t len
Definition: libmemif.h:215
memif_list_elt_t * listener_list
int memif_get_details(memif_conn_handle_t conn, memif_details_t *md, char *buf, ssize_t buflen)
Memif get details.
Definition: main.c:1870
uint32_t cookie
Definition: memif.h:166
memif_interface_mode_t mode
Definition: libmemif.h:194
static clib_error_t * memif_conn_fd_write_ready(clib_file_t *uf, memif_if_t *mif)
Definition: socket.c:555
uint16_t disconn_slaves
memif_free_t * free
uint8_t mode
Definition: libmemif.h:278
#define DBG_TX_BUF
Definition: main.c:177
uint16_t flags
Definition: memif.h:149
uint8_t link_up_down
Definition: libmemif.h:285
struct itimerspec arm disarm
#define ERRLIST_LEN
Definition: main.c:57
char * memif_strerror(int err_code)
Memif strerror.
Definition: main.c:155
memif_region_offset_t offset
Definition: private.h:103
#define MEMIF_MAX_LOG2_RING_SIZE
Definition: private.h:29
int memif_epfd
Definition: main.c:67
#define F_SEAL_SHRINK
Definition: mem.c:44
#define MEMIF_BUFFER_FLAG_NEXT
next buffer present (chained buffers)
Definition: libmemif.h:217
int memif_syscall_error_handler(int err_code)
Definition: main.c:200
memif_list_elt_t * interrupt_list
memif_region_index_t region
Definition: memif.h:151
static int memif_del_epoll_fd(int fd)
Definition: main.c:274
u16 last_head
Definition: private.h:105
uint8_t interface_name[32]
Definition: libmemif.h:193
u32 size
void * data
Definition: libmemif.h:221
memif_desc_t desc[0]
Definition: memif.h:173
uint16_t buffer_size
Definition: libmemif.h:249
uint8_t * socket_filename
Definition: libmemif.h:279
#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:92
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:575
int( memif_interrupt_t)(memif_conn_handle_t conn, void *private_ctx, uint16_t qid)
Memif interrupt occured (callback function)
Definition: libmemif.h:149
int( memif_connection_update_t)(memif_conn_handle_t conn, void *private_ctx)
Memif connection status update (callback function)
Definition: libmemif.h:139
static int memif_add_epoll_fd(int fd, uint32_t events)
Definition: main.c:232
uint8_t is_master
Definition: libmemif.h:190
uint8_t rx_queues_num
Definition: libmemif.h:280
int memif_init(memif_control_fd_update_t *on_control_fd_update, char *app_name, memif_alloc_t *memif_alloc, memif_free_t *memif_free)
Memif initialization.
Definition: main.c:427
int memif_get_queue_efd(memif_conn_handle_t conn, uint16_t qid, int *efd)
Memif get queue event file descriptor
Definition: main.c:1997
#define MEMIF_BUFFER_FLAG_RX
states that buffer is from rx ring
Definition: libmemif.h:219
#define MFD_ALLOW_SEALING
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:1453
#define MEMIF_DEFAULT_TX_QUEUES
Definition: private.h:23
uint32_t buffer_offset
Definition: memif_private.h:72
int add_list_elt(memif_list_elt_t *e, memif_list_elt_t **list, uint16_t *len)
Definition: main.c:311
int memif_init_regions_and_queues(memif_connection_t *conn)
Definition: main.c:1324
void( memif_free_t)(void *ptr)
Memif allocator free.
Definition: libmemif.h:114
uint16_t use_count
uint8_t flags
Definition: libmemif.h:220
int on_interrupt(memif_conn_handle_t conn, void *private_ctx, uint16_t qid)
Definition: main.c:287
svmdb_client_t * c
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:1718
int get_list_elt(memif_list_elt_t **e, memif_list_elt_t *list, uint16_t len, int key)
Definition: main.c:346
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:1534
memif_alloc_t * alloc
int memif_poll_event(int timeout)
Memif poll event.
Definition: main.c:1008
memif_queue_details_t * rx_queues
Definition: libmemif.h:282
u16 last_tail
Definition: private.h:106
int memif_read_ready(int fd)
Definition: socket.c:890
uint8_t role
Definition: libmemif.h:277
#define MEMIF_DEFAULT_BUFFER_SIZE
Definition: private.h:24
int memif_cleanup()
Memif cleanup.
Definition: main.c:2017
#define memif_min(a, b)
Definition: memif_private.h:53
const char * memif_errlist[ERRLIST_LEN]
Definition: main.c:72
int memif_create(memif_conn_handle_t *c, memif_conn_args_t *args, memif_connection_update_t *on_connect, memif_connection_update_t *on_disconnect, memif_interrupt_t *on_interrupt, void *private_ctx)
Memory interface create function.
Definition: main.c:593
#define MEMIF_DESC_FLAG_NEXT
Definition: memif.h:150
long ctx[MAX_CONNS]
Definition: main.c:126
int free_list_elt_ctx(memif_list_elt_t *list, uint16_t len, memif_connection_t *ctx)
Definition: main.c:386
static int memif_mod_epoll_fd(int fd, uint32_t events)
Definition: main.c:253
#define MEMIF_VERSION
Definition: memif.h:28
static_always_inline void * memif_get_buffer(memif_if_t *mif, memif_ring_t *ring, u16 slot)
Definition: private.h:268
memif_ring_t * ring
Definition: private.h:100
uint8_t tx_queues_num
Definition: libmemif.h:281
uint16_t interrupt_list_len
#define MEMIF_DEFAULT_RX_QUEUES
Definition: private.h:22
size_t count
Definition: vapi.c:42
#define DBG(...)
Definition: main.c:61
#define MEMIF_DEFAULT_SOCKET_DIR
Definition: memif_private.h:38
#define MEMIF_RING_FLAG_MASK_INT
Definition: memif.h:168
void * memif_conn_handle_t
Memif connection handle pointer of type void, pointing to internal structure.
Definition: libmemif.h:100
memif_region_offset_t offset
Definition: memif.h:153
int memif_control_fd_handler(int fd, uint8_t events)
Memif control file descriptor handler.
Definition: main.c:858
uint8_t app_name[MEMIF_NAME_LEN]
#define MEMIF_DEFAULT_SOCKET_FILENAME
Definition: private.h:20
uint8_t log2_ring_size
Definition: libmemif.h:189
uint32_t id
Definition: libmemif.h:275
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:1785
uint16_t pending_list_len
void * shm
Definition: private.h:85
memif_rx_mode_t
Definition: libmemif.h:198
memif_list_elt_t * control_list
int memif_delete(memif_conn_handle_t *conn)
Memif delete.
Definition: main.c:1183
memif_log2_ring_size_t log2_ring_size
Definition: private.h:101
Memif queue details.
Definition: libmemif.h:240
uint16_t flags
Definition: memif.h:167
#define MEMIF_FD_EVENT_ERROR
inform libmemif that error occured on fd
Definition: libmemif.h:90
int memif_cancel_poll_event()
Definition: main.c:1049
uint16_t control_list_len
#define MEMIF_FD_EVENT_MOD
update events
Definition: libmemif.h:94
#define DBG_RX_BUF
Definition: main.c:178
memif_ring_type_t
Definition: memif.h:47
memif_queue_details_t * tx_queues
Definition: libmemif.h:283
uint8_t * if_name
Definition: libmemif.h:270
volatile uint16_t head
Definition: memif.h:169
clib_error_t * memif_conn_fd_accept_ready(clib_file_t *uf)
Definition: socket.c:643
int memif_conn_fd_error(memif_connection_t *c)
Definition: socket.c:805
int memif_connect1(memif_connection_t *c)
Definition: main.c:1258
uint16_t index
Definition: main.c:74
libmemif_main_t libmemif_main
Definition: main.c:66
Memif buffer.
Definition: libmemif.h:211
int free_list_elt(memif_list_elt_t *list, uint16_t len, int key)
Definition: main.c:369
#define MEMIF_FD_EVENT_WRITE
Definition: libmemif.h:88
uint16_t memif_get_version()
Memif get version.
Definition: main.c:172
memif_region_index_t region
Definition: private.h:102
uint16_t listener_list_len
#define MEMIF_COOKIE
Definition: memif.h:25
Memif connection arguments.
Definition: libmemif.h:181
uint16_t interface_list_len
Memif details.
Definition: libmemif.h:268
volatile uint16_t tail
Definition: memif.h:171
memif_region_size_t region_size
Definition: private.h:86
uint8_t * remote_if_name
Definition: libmemif.h:272
uint8_t * socket_filename
Definition: libmemif.h:183
void *( memif_alloc_t)(size_t size)
Memif allocator alloc.
Definition: libmemif.h:107
int memif_control_fd_update(int fd, uint8_t events)
Definition: main.c:293