FD.io VPP  v18.01-8-g0eacf49
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 s0, s1, ns;
1402  *count_out = 0;
1403  int i, err = MEMIF_ERR_SUCCESS; /* 0 */
1404 
1405  ns = (1 << mq->log2_ring_size) - head + tail;
1406 
1407  /* calculate number of chain buffers */
1408  if (size > ring->desc[0].buffer_length)
1409  {
1410  chain_buf = size / ring->desc[0].buffer_length;
1411  if (((size % ring->desc[0].buffer_length) != 0) || (size == 0))
1412  chain_buf++;
1413  }
1414 
1415  while (count && ns)
1416  {
1417  while ((count > 2) && (ns > 2))
1418  {
1419  s0 = (ring->head + mq->alloc_bufs) & mask;
1420  s1 = (ring->head + mq->alloc_bufs + chain_buf) & mask;
1421 
1422  if ((2 * chain_buf) > ns)
1423  break;
1424 
1425  b0 = (bufs + *count_out);
1426  b1 = (bufs + *count_out + 1);
1427 
1428  b0->desc_index = head + mq->alloc_bufs;
1429  b1->desc_index = head + mq->alloc_bufs + chain_buf;
1430  ring->desc[s0].flags = 0;
1431  ring->desc[s1].flags = 0;
1432  b0->buffer_len = ring->desc[s0].buffer_length * chain_buf;
1433  b1->buffer_len = ring->desc[s1].buffer_length * chain_buf;
1434  /* TODO: support multiple regions -> ring descriptor contains region index */
1435  b0->data = c->regions->shm + ring->desc[s0].offset;
1436  b1->data = c->regions->shm + ring->desc[s1].offset;
1437 
1438  for (i = 0; i < (chain_buf - 1); i++)
1439  {
1440  ring->desc[(s0 + i) & mask].flags |= MEMIF_DESC_FLAG_NEXT;
1441  ring->desc[(s1 + i) & mask].flags |= MEMIF_DESC_FLAG_NEXT;
1442  DBG ("allocating chained buffers");
1443  }
1444 
1445  mq->alloc_bufs += 2 * chain_buf;
1446 
1447  DBG ("allocated ring slots %u, %u", s0, s1);
1448  count -= 2;
1449  ns -= (2 * chain_buf);
1450  *count_out += 2;
1451  }
1452  s0 = (ring->head + mq->alloc_bufs) & mask;
1453 
1454  b0 = (bufs + *count_out);
1455 
1456  if (chain_buf > ns)
1457  break;
1458 
1459  b0->desc_index = head + mq->alloc_bufs;
1460  ring->desc[s0].flags = 0;
1461  b0->buffer_len = ring->desc[s0].buffer_length * chain_buf;
1462  b0->data = c->regions->shm + ring->desc[s0].offset;
1463 
1464  for (i = 0; i < (chain_buf - 1); i++)
1465  {
1466  ring->desc[(s0 + i) & mask].flags |= MEMIF_DESC_FLAG_NEXT;
1467  DBG ("allocating chained buffers");
1468  }
1469 
1470  mq->alloc_bufs += chain_buf;
1471 
1472  DBG ("allocated ring slot %u", s0);
1473  count--;
1474  ns -= chain_buf;
1475  *count_out += 1;
1476  }
1477 
1478  DBG ("allocated: %u/%u bufs. Total %u allocated bufs", *count_out, count,
1479  mq->alloc_bufs);
1480 
1481  if (count)
1482  {
1483  DBG ("ring buffer full! qid: %u", qid);
1484  err = MEMIF_ERR_NOBUF_RING;
1485  }
1486 
1487  return err;
1488 }
1489 
1490 int
1492  memif_buffer_t * bufs, uint16_t count,
1493  uint16_t * count_out)
1494 {
1496  if (c == NULL)
1497  return MEMIF_ERR_NOCONN;
1498  if (c->fd < 0)
1499  return MEMIF_ERR_DISCONNECTED;
1500  uint8_t num =
1501  (c->args.is_master) ? c->run_args.num_s2m_rings : c->
1502  run_args.num_m2s_rings;
1503  if (qid >= num)
1504  return MEMIF_ERR_QID;
1506  memif_queue_t *mq = &c->rx_queues[qid];
1507  memif_ring_t *ring = mq->ring;
1508  uint16_t tail = ring->tail;
1509  uint16_t mask = (1 << mq->log2_ring_size) - 1;
1510  uint8_t chain_buf0, chain_buf1;
1511  memif_buffer_t *b0, *b1;
1512  *count_out = 0;
1513 
1514  if (mq->alloc_bufs < count)
1515  count = mq->alloc_bufs;
1516 
1517  while (count)
1518  {
1519  while (count > 2)
1520  {
1521  b0 = (bufs + *count_out);
1522  b1 = (bufs + *count_out + 1);
1523  chain_buf0 =
1524  b0->buffer_len / ring->desc[b0->desc_index & mask].buffer_length;
1525  if ((b0->buffer_len %
1526  ring->desc[b0->desc_index & mask].buffer_length) != 0)
1527  chain_buf0++;
1528  chain_buf1 =
1529  b1->buffer_len / ring->desc[b1->desc_index & mask].buffer_length;
1530  if ((b1->buffer_len %
1531  ring->desc[b1->desc_index & mask].buffer_length) != 0)
1532  chain_buf1++;
1533  tail = b1->desc_index + chain_buf1;
1534  b0->data = NULL;
1535  b1->data = NULL;
1536 
1537  count -= 2;
1538  *count_out += 2;
1539  mq->alloc_bufs -= chain_buf0 + chain_buf1;
1540  }
1541  b0 = (bufs + *count_out);
1542  chain_buf0 =
1543  b0->buffer_len / ring->desc[b0->desc_index & mask].buffer_length;
1544  if ((b0->buffer_len %
1545  ring->desc[b0->desc_index & mask].buffer_length) != 0)
1546  chain_buf0++;
1547  tail = b0->desc_index + chain_buf0;
1548  b0->data = NULL;
1549 
1550  count--;
1551  *count_out += 1;
1552  mq->alloc_bufs -= chain_buf0;
1553  }
1555  ring->tail = tail;
1556  DBG ("tail: %u", ring->tail);
1557 
1558  return MEMIF_ERR_SUCCESS; /* 0 */
1559 }
1560 
1561 int
1563  memif_buffer_t * bufs, uint16_t count, uint16_t * tx)
1564 {
1566  if (c == NULL)
1567  return MEMIF_ERR_NOCONN;
1568  if (c->fd < 0)
1569  return MEMIF_ERR_DISCONNECTED;
1570  uint8_t num =
1571  (c->args.is_master) ? c->run_args.num_m2s_rings : c->
1572  run_args.num_s2m_rings;
1573  if (qid >= num)
1574  return MEMIF_ERR_QID;
1575  memif_queue_t *mq = &c->tx_queues[qid];
1576  memif_ring_t *ring = mq->ring;
1577  uint16_t head = ring->head;
1578  uint16_t mask = (1 << mq->log2_ring_size) - 1;
1579  uint8_t chain_buf0, chain_buf1;
1580  *tx = 0;
1581  uint16_t curr_buf = 0;
1582  memif_buffer_t *b0, *b1;
1583  int i;
1584 
1585  while (count)
1586  {
1587  while (count > 2)
1588  {
1589  b0 = (bufs + curr_buf);
1590  b1 = (bufs + curr_buf + 1);
1591  chain_buf0 =
1592  b0->buffer_len / ring->desc[b0->desc_index & mask].buffer_length;
1593  if ((b0->buffer_len %
1594  ring->desc[b0->desc_index & mask].buffer_length) != 0)
1595  chain_buf0++;
1596 
1597  chain_buf1 =
1598  b1->buffer_len / ring->desc[b1->desc_index & mask].buffer_length;
1599  if ((b1->buffer_len %
1600  ring->desc[b1->desc_index & mask].buffer_length) != 0)
1601  chain_buf1++;
1602 
1603  for (i = 0; i < memif_min (chain_buf0, chain_buf1); i++)
1604  {
1605  /* b0 */
1606  if (b0->data_len >
1607  ring->desc[(b0->desc_index + i) & mask].buffer_length)
1608  {
1609  b0->data_len -=
1610  ring->desc[(b0->desc_index + i) & mask].length =
1611  ring->desc[(b0->desc_index + i) & mask].buffer_length;
1612  }
1613  else
1614  {
1615  ring->desc[(b0->desc_index + i) & mask].length =
1616  b0->data_len;
1617  b0->data_len = 0;
1618  }
1619  /* b1 */
1620  if (b1->data_len >
1621  ring->desc[(b1->desc_index + i) & mask].buffer_length)
1622  {
1623  b1->data_len -=
1624  ring->desc[(b1->desc_index + i) & mask].length =
1625  ring->desc[(b1->desc_index + i) & mask].buffer_length;
1626  }
1627  else
1628  {
1629  ring->desc[(b1->desc_index + i) & mask].length =
1630  b1->data_len;
1631  b1->data_len = 0;
1632  }
1633 #ifdef MEMIF_DBG_SHM
1634  print_bytes (b0->data +
1635  ring->desc[(b0->desc_index +
1636  i) & mask].buffer_length *
1637  (chain_buf0 - 1),
1638  ring->desc[(b0->desc_index +
1639  i) & mask].buffer_length, DBG_TX_BUF);
1640  print_bytes (b1->data +
1641  ring->desc[(b1->desc_index +
1642  i) & mask].buffer_length *
1643  (chain_buf1 - 1),
1644  ring->desc[(b1->desc_index +
1645  i) & mask].buffer_length, DBG_TX_BUF);
1646 #endif /* MEMIF_DBG_SHM */
1647  }
1648 
1649  if (chain_buf0 > chain_buf1)
1650  {
1651  for (; i < chain_buf0; i++)
1652  {
1653  if (b0->data_len >
1654  ring->desc[(b0->desc_index + i) & mask].buffer_length)
1655  {
1656  b0->data_len -=
1657  ring->desc[(b0->desc_index + i) & mask].length =
1658  ring->desc[(b0->desc_index + i) & mask].buffer_length;
1659  }
1660  else
1661  {
1662  ring->desc[(b0->desc_index + i) & mask].length =
1663  b0->data_len;
1664  b0->data_len = 0;
1665  }
1666 #ifdef MEMIF_DBG_SHM
1667  print_bytes (b0->data +
1668  ring->desc[(b0->desc_index +
1669  i) & mask].buffer_length *
1670  (chain_buf0 - 1),
1671  ring->desc[(b0->desc_index +
1672  i) & mask].buffer_length,
1673  DBG_TX_BUF);
1674 #endif /* MEMIF_DBG_SHM */
1675  }
1676  }
1677  else
1678  {
1679  for (; i < chain_buf1; i++)
1680  {
1681  if (b1->data_len >
1682  ring->desc[(b1->desc_index + i) & mask].buffer_length)
1683  {
1684  b1->data_len -=
1685  ring->desc[(b1->desc_index + i) & mask].length =
1686  ring->desc[(b1->desc_index + i) & mask].buffer_length;
1687  }
1688  else
1689  {
1690  ring->desc[(b1->desc_index + i) & mask].length =
1691  b1->data_len;
1692  b1->data_len = 0;
1693  }
1694 #ifdef MEMIF_DBG_SHM
1695  print_bytes (b1->data +
1696  ring->desc[(b1->desc_index +
1697  i) & mask].buffer_length *
1698  (chain_buf1 - 1),
1699  ring->desc[(b1->desc_index +
1700  i) & mask].buffer_length,
1701  DBG_TX_BUF);
1702 #endif /* MEMIF_DBG_SHM */
1703  }
1704  }
1705 
1706  head = b1->desc_index + chain_buf1;
1707 
1708  b0->data = NULL;
1709 #ifdef MEMIF_DBG
1710  if (b0->data_len != 0)
1711  DBG ("invalid b0 data length!");
1712 #endif /* MEMIF_DBG */
1713  b1->data = NULL;
1714 #ifdef MEMIF_DBG
1715  if (b1->data_len != 0)
1716  DBG ("invalid b1 data length!");
1717 #endif /* MEMIF_DBG */
1718 
1719  count -= 2;
1720  *tx += chain_buf0 + chain_buf1;
1721  curr_buf += 2;
1722  }
1723 
1724  b0 = (bufs + curr_buf);
1725  chain_buf0 =
1726  b0->buffer_len / ring->desc[b0->desc_index & mask].buffer_length;
1727  if ((b0->buffer_len %
1728  ring->desc[b0->desc_index & mask].buffer_length) != 0)
1729  chain_buf0++;
1730 
1731  for (i = 0; i < chain_buf0; i++)
1732  {
1733  if (b0->data_len >
1734  ring->desc[(b0->desc_index + i) & mask].buffer_length)
1735  {
1736  b0->data_len -= ring->desc[(b0->desc_index + i) & mask].length =
1737  ring->desc[(b0->desc_index + i) & mask].buffer_length;
1738  }
1739  else
1740  {
1741  ring->desc[(b0->desc_index + i) & mask].length = b0->data_len;
1742  b0->data_len = 0;
1743  }
1744 #ifdef MEMIF_DBG_SHM
1745  print_bytes (b0->data +
1746  ring->desc[(b0->desc_index + i) & mask].buffer_length *
1747  (chain_buf0 - 1),
1748  ring->desc[(b0->desc_index + i) & mask].buffer_length,
1749  DBG_TX_BUF);
1750 #endif /* MEMIF_DBG_SHM */
1751  }
1752 
1753  head = b0->desc_index + chain_buf0;
1754 
1755  b0->data = NULL;
1756 #ifdef MEMIF_DBG
1757  if (b0->data_len != 0)
1758  DBG ("invalid b0 data length!");
1759 #endif /* MEMIF_DBG */
1760 
1761  count--;
1762  *tx += chain_buf0;
1763  curr_buf++;
1764  }
1766  ring->head = head;
1767 
1768  mq->alloc_bufs -= *tx;
1769 
1770  /* TODO: return num of buffers and packets */
1771  *tx = curr_buf;
1772 
1773  if ((ring->flags & MEMIF_RING_FLAG_MASK_INT) == 0)
1774  {
1775  uint64_t a = 1;
1776  int r = write (mq->int_fd, &a, sizeof (a));
1777  if (r < 0)
1778  return MEMIF_ERR_INT_WRITE;
1779  }
1780 
1781  return MEMIF_ERR_SUCCESS; /* 0 */
1782 }
1783 
1784 int
1786  memif_buffer_t * bufs, uint16_t count, uint16_t * rx)
1787 {
1789  if (c == NULL)
1790  return MEMIF_ERR_NOCONN;
1791  if (c->fd < 0)
1792  return MEMIF_ERR_DISCONNECTED;
1793  uint8_t num =
1794  (c->args.is_master) ? c->run_args.num_s2m_rings : c->
1795  run_args.num_m2s_rings;
1796  if (qid >= num)
1797  return MEMIF_ERR_QID;
1798  memif_queue_t *mq = &c->rx_queues[qid];
1799  memif_ring_t *ring = mq->ring;
1800  uint16_t head = ring->head;
1801  uint16_t ns;
1802  uint16_t mask = (1 << mq->log2_ring_size) - 1;
1803  memif_buffer_t *b0, *b1;
1804  uint16_t curr_buf = 0;
1805  *rx = 0;
1806 #ifdef MEMIF_DBG_SHM
1807  int i;
1808 #endif /* MEMIF_DBG_SHM */
1809 
1810  uint64_t b;
1811  ssize_t r = read (mq->int_fd, &b, sizeof (b));
1812  if ((r == -1) && (errno != EAGAIN))
1813  return memif_syscall_error_handler (errno);
1814 
1815  if (head == mq->last_head)
1816  return 0;
1817 
1818  ns = head - mq->last_head;
1819 
1820  while (ns && count)
1821  {
1822  while ((ns > 2) && (count > 2))
1823  {
1824  b0 = (bufs + curr_buf);
1825  b1 = (bufs + curr_buf + 1);
1826 
1827  b0->desc_index = mq->last_head;
1828  b0->data = memif_get_buffer (conn, ring, mq->last_head & mask);
1829  b0->data_len = ring->desc[mq->last_head & mask].length;
1830  b0->buffer_len = ring->desc[mq->last_head & mask].buffer_length;
1831 #ifdef MEMIF_DBG_SHM
1832  i = 0;
1833  print_bytes (b0->data +
1834  ring->desc[b0->desc_index & mask].buffer_length * i++,
1835  ring->desc[b0->desc_index & mask].buffer_length,
1836  DBG_TX_BUF);
1837 #endif /* MEMIF_DBG_SHM */
1838  ns--;
1839  *rx += 1;
1840  while (ring->desc[mq->last_head & mask].
1842  {
1843  ring->desc[mq->last_head & mask].flags &= ~MEMIF_DESC_FLAG_NEXT;
1844  mq->last_head++;
1845  b0->data_len += ring->desc[mq->last_head & mask].length;
1846  b0->buffer_len +=
1847  ring->desc[mq->last_head & mask].buffer_length;
1848 #ifdef MEMIF_DBG_SHM
1849  print_bytes (b0->data +
1850  ring->desc[b0->desc_index & mask].buffer_length *
1851  i++,
1852  ring->desc[b0->desc_index & mask].buffer_length,
1853  DBG_TX_BUF);
1854 #endif /* MEMIF_DBG_SHM */
1855  ns--;
1856  *rx += 1;
1857  }
1858  mq->last_head++;
1859 
1860  b1->desc_index = mq->last_head;
1861  b1->data = memif_get_buffer (conn, ring, mq->last_head & mask);
1862  b1->data_len = ring->desc[mq->last_head & mask].length;
1863  b1->buffer_len = ring->desc[mq->last_head & mask].buffer_length;
1864 #ifdef MEMIF_DBG_SHM
1865  i = 0;
1866  print_bytes (b1->data +
1867  ring->desc[b1->desc_index & mask].buffer_length * i++,
1868  ring->desc[b1->desc_index & mask].buffer_length,
1869  DBG_TX_BUF);
1870 #endif /* MEMIF_DBG_SHM */
1871  ns--;
1872  *rx += 1;
1873  while (ring->desc[mq->last_head & mask].
1874  flags & MEMIF_DESC_FLAG_NEXT)
1875  {
1876  ring->desc[mq->last_head & mask].flags &= ~MEMIF_DESC_FLAG_NEXT;
1877  mq->last_head++;
1878  b1->data_len += ring->desc[mq->last_head & mask].length;
1879  b1->buffer_len +=
1880  ring->desc[mq->last_head & mask].buffer_length;
1881 #ifdef MEMIF_DBG_SHM
1882  print_bytes (b1->data +
1883  ring->desc[b1->desc_index & mask].buffer_length *
1884  i++,
1885  ring->desc[b1->desc_index & mask].buffer_length,
1886  DBG_TX_BUF);
1887 #endif /* MEMIF_DBG_SHM */
1888  ns--;
1889  *rx += 1;
1890  }
1891  mq->last_head++;
1892 
1893  count -= 2;
1894  curr_buf += 2;
1895  }
1896  b0 = (bufs + curr_buf);
1897 
1898  b0->desc_index = mq->last_head;
1899  b0->data = memif_get_buffer (conn, ring, mq->last_head & mask);
1900  b0->data_len = ring->desc[mq->last_head & mask].length;
1901  b0->buffer_len = ring->desc[mq->last_head & mask].buffer_length;
1902 #ifdef MEMIF_DBG_SHM
1903  i = 0;
1904  print_bytes (b0->data +
1905  ring->desc[b0->desc_index & mask].buffer_length * i++,
1906  ring->desc[b0->desc_index & mask].buffer_length,
1907  DBG_TX_BUF);
1908 #endif /* MEMIF_DBG_SHM */
1909  ns--;
1910  *rx += 1;
1911 
1912  while (ring->desc[mq->last_head & mask].flags & MEMIF_DESC_FLAG_NEXT)
1913  {
1914  ring->desc[mq->last_head & mask].flags &= ~MEMIF_DESC_FLAG_NEXT;
1915  mq->last_head++;
1916  b0->data_len += ring->desc[mq->last_head & mask].length;
1917  b0->buffer_len += ring->desc[mq->last_head & mask].buffer_length;
1918 #ifdef MEMIF_DBG_SHM
1919  print_bytes (b0->data +
1920  ring->desc[b0->desc_index & mask].buffer_length * i++,
1921  ring->desc[b0->desc_index & mask].buffer_length,
1922  DBG_TX_BUF);
1923 #endif /* MEMIF_DBG_SHM */
1924  ns--;
1925  *rx += 1;
1926  }
1927  mq->last_head++;
1928 
1929  count--;
1930  curr_buf++;
1931  }
1932 
1933  mq->alloc_bufs += *rx;
1934 
1935  /* TODO: return num of buffers and packets */
1936  *rx = curr_buf;
1937 
1938  if (ns)
1939  {
1940  DBG ("not enough buffers!");
1941  return MEMIF_ERR_NOBUF;
1942  }
1943 
1944  return MEMIF_ERR_SUCCESS; /* 0 */
1945 }
1946 
1947 int
1949  char *buf, ssize_t buflen)
1950 {
1952  if (c == NULL)
1953  return MEMIF_ERR_NOCONN;
1954 
1955  int err = MEMIF_ERR_SUCCESS, i;
1956  ssize_t l0, l1, total_l;
1957  l0 = 0;
1958 
1959  l1 = strlen ((char *) c->args.interface_name);
1960  if (l0 + l1 < buflen)
1961  {
1962  md->if_name = strcpy (buf + l0, (char *) c->args.interface_name);
1963  l0 += l1 + 1;
1964  }
1965  else
1966  err = MEMIF_ERR_NOBUF_DET;
1967 
1968  l1 = strlen ((char *) c->args.instance_name);
1969  if (l0 + l1 < buflen)
1970  {
1971  md->inst_name = strcpy (buf + l0, (char *) c->args.instance_name);
1972  l0 += l1 + 1;
1973  }
1974  else
1975  err = MEMIF_ERR_NOBUF_DET;
1976 
1977  l1 = strlen ((char *) c->remote_if_name);
1978  if (l0 + l1 < buflen)
1979  {
1980  md->remote_if_name = strcpy (buf + l0, (char *) c->remote_if_name);
1981  l0 += l1 + 1;
1982  }
1983  else
1984  err = MEMIF_ERR_NOBUF_DET;
1985 
1986  l1 = strlen ((char *) c->remote_name);
1987  if (l0 + l1 < buflen)
1988  {
1989  md->remote_inst_name = strcpy (buf + l0, (char *) c->remote_name);
1990  l0 += l1 + 1;
1991  }
1992  else
1993  err = MEMIF_ERR_NOBUF_DET;
1994 
1995  md->id = c->args.interface_id;
1996 
1997  if (c->args.secret)
1998  {
1999  l1 = strlen ((char *) c->args.secret);
2000  if (l0 + l1 < buflen)
2001  {
2002  md->secret = strcpy (buf + l0, (char *) c->args.secret);
2003  l0 += l1 + 1;
2004  }
2005  else
2006  err = MEMIF_ERR_NOBUF_DET;
2007  }
2008 
2009  md->role = (c->args.is_master) ? 0 : 1;
2010  md->mode = c->args.mode;
2011 
2012  l1 = strlen ((char *) c->args.socket_filename);
2013  if (l0 + l1 < buflen)
2014  {
2015  md->socket_filename =
2016  strcpy (buf + l0, (char *) c->args.socket_filename);
2017  l0 += l1 + 1;
2018  }
2019  else
2020  err = MEMIF_ERR_NOBUF_DET;
2021 
2022  md->rx_queues_num =
2023  (c->args.is_master) ? c->run_args.num_s2m_rings : c->
2024  run_args.num_m2s_rings;
2025 
2026  l1 = sizeof (memif_queue_details_t) * md->rx_queues_num;
2027  if (l0 + l1 <= buflen)
2028  {
2029  md->rx_queues = (memif_queue_details_t *) buf + l0;
2030  l0 += l1;
2031  }
2032  else
2033  err = MEMIF_ERR_NOBUF_DET;
2034 
2035  for (i = 0; i < md->rx_queues_num; i++)
2036  {
2037  md->rx_queues[i].qid = i;
2038  md->rx_queues[i].ring_size = (1 << c->rx_queues[i].log2_ring_size);
2039  md->rx_queues[i].flags = c->rx_queues[i].ring->flags;
2040  md->rx_queues[i].head = c->rx_queues[i].ring->head;
2041  md->rx_queues[i].tail = c->rx_queues[i].ring->tail;
2042  md->rx_queues[i].buffer_size = c->run_args.buffer_size;
2043  }
2044 
2045  md->tx_queues_num =
2046  (c->args.is_master) ? c->run_args.num_m2s_rings : c->
2047  run_args.num_s2m_rings;
2048 
2049  l1 = sizeof (memif_queue_details_t) * md->tx_queues_num;
2050  if (l0 + l1 <= buflen)
2051  {
2052  md->tx_queues = (memif_queue_details_t *) buf + l0;
2053  l0 += l1;
2054  }
2055  else
2056  err = MEMIF_ERR_NOBUF_DET;
2057 
2058  for (i = 0; i < md->tx_queues_num; i++)
2059  {
2060  md->tx_queues[i].qid = i;
2061  md->tx_queues[i].ring_size = (1 << c->tx_queues[i].log2_ring_size);
2062  md->tx_queues[i].flags = c->tx_queues[i].ring->flags;
2063  md->tx_queues[i].head = c->tx_queues[i].ring->head;
2064  md->tx_queues[i].tail = c->tx_queues[i].ring->tail;
2065  md->tx_queues[i].buffer_size = c->run_args.buffer_size;
2066  }
2067 
2068  md->link_up_down = (c->fd > 0) ? 1 : 0;
2069 
2070  return err; /* 0 */
2071 }
2072 
2073 int
2074 memif_get_queue_efd (memif_conn_handle_t conn, uint16_t qid, int *efd)
2075 {
2077  *efd = -1;
2078  if (c == NULL)
2079  return MEMIF_ERR_NOCONN;
2080  if (c->fd < 0)
2081  return MEMIF_ERR_DISCONNECTED;
2082  uint8_t num =
2083  (c->args.is_master) ? c->run_args.num_s2m_rings : c->
2084  run_args.num_m2s_rings;
2085  if (qid >= num)
2086  return MEMIF_ERR_QID;
2087 
2088  *efd = c->rx_queues[qid].int_fd;
2089 
2090  return MEMIF_ERR_SUCCESS;
2091 }
2092 
2093 int
2095 {
2097  if (lm->app_name)
2098  free (lm->app_name);
2099  lm->app_name = NULL;
2100  if (lm->control_list)
2101  free (lm->control_list);
2102  lm->control_list = NULL;
2103  if (lm->interrupt_list)
2104  free (lm->interrupt_list);
2105  lm->interrupt_list = NULL;
2106  if (lm->listener_list)
2107  free (lm->listener_list);
2108  lm->listener_list = NULL;
2109  if (lm->pending_list)
2110  free (lm->pending_list);
2111  lm->pending_list = NULL;
2112  if (poll_cancel_fd != -1)
2113  close (poll_cancel_fd);
2114 
2115  return MEMIF_ERR_SUCCESS; /* 0 */
2116 }
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:43
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:800
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:1948
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:540
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:1491
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:2074
#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:1562
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:874
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:2094
#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:225
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:1785
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:628
int memif_conn_fd_error(memif_connection_t *c)
Definition: socket.c:790
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