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