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