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