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