FD.io VPP  v19.04.1-1-ge4a0f9f
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
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
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
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_set_connection_request_timer(struct itimerspec timer)
456 {
458  int err = MEMIF_ERR_SUCCESS;
459 
460  lm->arm = timer;
461 
462  /* overwrite timer, if already armed */
463  if (lm->disconn_slaves != 0)
464  {
465  if (timerfd_settime (lm->timerfd, 0, &lm->arm, NULL) < 0)
466  {
467  err = memif_syscall_error_handler (errno);
468  }
469  }
470  return err;
471 }
472 
473 int
474 memif_init (memif_control_fd_update_t * on_control_fd_update, char *app_name,
475  memif_alloc_t * memif_alloc, memif_realloc_t * memif_realloc,
476  memif_free_t * memif_free)
477 {
478  int err = MEMIF_ERR_SUCCESS; /* 0 */
480  memset (lm, 0, sizeof (libmemif_main_t));
481 
482  if (memif_alloc != NULL)
483  {
484  memif_alloc_register (memif_alloc);
485  }
486  else
487  memif_alloc_register (malloc);
488 
489  if (memif_realloc != NULL)
490  {
491  memif_realloc_register (memif_realloc);
492  }
493  else
494  memif_realloc_register (realloc);
495 
496  if (memif_free != NULL)
497  memif_free_register (memif_free);
498  else
499  memif_free_register (free);
500 
501  if (app_name != NULL)
502  {
503  uint8_t len = (strlen (app_name) > MEMIF_NAME_LEN)
504  ? strlen (app_name) : MEMIF_NAME_LEN;
505  strncpy ((char *) lm->app_name, app_name, len);
506  }
507  else
508  {
509  strncpy ((char *) lm->app_name, MEMIF_DEFAULT_APP_NAME,
510  strlen (MEMIF_DEFAULT_APP_NAME));
511  }
512 
513  /* register control fd update callback */
514  if (on_control_fd_update != NULL)
515  memif_control_fd_update_register (on_control_fd_update);
516  else
517  {
518  memif_epfd = epoll_create (1);
520  if ((poll_cancel_fd = eventfd (0, EFD_NONBLOCK)) < 0)
521  {
522  err = errno;
523  DBG ("eventfd: %s", strerror (err));
524  return memif_syscall_error_handler (err);
525  }
527  DBG ("libmemif event polling initialized");
528  }
529 
530  lm->control_list_len = 2;
531  lm->interrupt_list_len = 2;
532  lm->listener_list_len = 1;
533  lm->pending_list_len = 1;
534 
535  lm->control_list =
536  lm->alloc (sizeof (memif_list_elt_t) * lm->control_list_len);
537  if (lm->control_list == NULL)
538  {
539  err = MEMIF_ERR_NOMEM;
540  goto error;
541  }
542  lm->interrupt_list =
543  lm->alloc (sizeof (memif_list_elt_t) * lm->interrupt_list_len);
544  if (lm->interrupt_list == NULL)
545  {
546  err = MEMIF_ERR_NOMEM;
547  goto error;
548  }
549  lm->listener_list =
550  lm->alloc (sizeof (memif_list_elt_t) * lm->listener_list_len);
551  if (lm->listener_list == NULL)
552  {
553  err = MEMIF_ERR_NOMEM;
554  goto error;
555  }
556  lm->pending_list =
557  lm->alloc (sizeof (memif_list_elt_t) * lm->pending_list_len);
558  if (lm->pending_list == NULL)
559  {
560  err = MEMIF_ERR_NOMEM;
561  goto error;
562  }
563 
564  int i;
565  for (i = 0; i < lm->control_list_len; i++)
566  {
567  lm->control_list[i].key = -1;
569  }
570  for (i = 0; i < lm->interrupt_list_len; i++)
571  {
572  lm->interrupt_list[i].key = -1;
574  }
575  for (i = 0; i < lm->listener_list_len; i++)
576  {
577  lm->listener_list[i].key = -1;
579  }
580  for (i = 0; i < lm->pending_list_len; i++)
581  {
582  lm->pending_list[i].key = -1;
584  }
585 
586  lm->disconn_slaves = 0;
587 
588  lm->timerfd = timerfd_create (CLOCK_REALTIME, TFD_NONBLOCK);
589  if (lm->timerfd < 0)
590  {
591  err = memif_syscall_error_handler (errno);
592  goto error;
593  }
594 
595  lm->arm.it_value.tv_sec = MEMIF_DEFAULT_RECONNECT_PERIOD_SEC;
596  lm->arm.it_value.tv_nsec = MEMIF_DEFAULT_RECONNECT_PERIOD_NSEC;
597  lm->arm.it_interval.tv_sec = MEMIF_DEFAULT_RECONNECT_PERIOD_SEC;
598  lm->arm.it_interval.tv_nsec = MEMIF_DEFAULT_RECONNECT_PERIOD_NSEC;
599 
600  if (lm->control_fd_update (lm->timerfd, MEMIF_FD_EVENT_READ) < 0)
601  {
602  DBG ("callback type memif_control_fd_update_t error!");
603  err = MEMIF_ERR_CB_FDUPDATE;
604  goto error;
605  }
606 
607  return err;
608 
609 error:
610  memif_cleanup ();
611  return err;
612 }
613 
614 static inline memif_ring_t *
616  uint16_t ring_num)
617 {
618  if (&conn->regions[0] == NULL)
619  return NULL;
620  void *p = conn->regions[0].addr;
621  int ring_size =
622  sizeof (memif_ring_t) +
623  sizeof (memif_desc_t) * (1 << conn->run_args.log2_ring_size);
624  p += (ring_num + type * conn->run_args.num_s2m_rings) * ring_size;
625 
626  return (memif_ring_t *) p;
627 }
628 
629 int
631  uint16_t qid)
632 {
634  if (conn == NULL)
635  return MEMIF_ERR_NOCONN;
636  uint8_t num =
637  (conn->args.is_master) ? conn->run_args.num_s2m_rings : conn->
638  run_args.num_m2s_rings;
639  if (qid >= num)
640  return MEMIF_ERR_QID;
641 
642  conn->rx_queues[qid].ring->flags = rx_mode;
643  DBG ("rx_mode flag: %u", conn->rx_queues[qid].ring->flags);
644  return MEMIF_ERR_SUCCESS;
645 }
646 
647 int
651  memif_interrupt_t * on_interrupt, void *private_ctx)
652 {
654  int err, i, index = 0, sockfd = -1;
655  memif_list_elt_t list_elt;
656  memif_connection_t *conn = (memif_connection_t *) * c;
657  if (conn != NULL)
658  {
659  DBG ("This handle already points to existing memif.");
660  return MEMIF_ERR_CONN;
661  }
662  conn = (memif_connection_t *) lm->alloc (sizeof (memif_connection_t));
663  if (conn == NULL)
664  {
665  err = MEMIF_ERR_NOMEM;
666  goto error;
667  }
668  memset (conn, 0, sizeof (memif_connection_t));
669 
670  conn->args.interface_id = args->interface_id;
671 
672  if (args->log2_ring_size == 0)
674  else if (args->log2_ring_size > MEMIF_MAX_LOG2_RING_SIZE)
675  {
676  err = MEMIF_ERR_MAX_RING;
677  goto error;
678  }
679  if (args->buffer_size == 0)
681  if (args->num_s2m_rings == 0)
683  if (args->num_m2s_rings == 0)
685 
686  conn->args.num_s2m_rings = args->num_s2m_rings;
687  conn->args.num_m2s_rings = args->num_m2s_rings;
688  conn->args.buffer_size = args->buffer_size;
689  conn->args.log2_ring_size = args->log2_ring_size;
690  conn->args.is_master = args->is_master;
691  conn->args.mode = args->mode;
692  conn->msg_queue = NULL;
693  conn->regions = NULL;
694  conn->tx_queues = NULL;
695  conn->rx_queues = NULL;
696  conn->fd = -1;
697  conn->on_connect = on_connect;
698  conn->on_disconnect = on_disconnect;
699  conn->on_interrupt = on_interrupt;
700  conn->private_ctx = private_ctx;
701  memset (&conn->run_args, 0, sizeof (memif_conn_run_args_t));
702 
703  uint8_t l = strlen ((char *) args->interface_name);
704  strncpy ((char *) conn->args.interface_name, (char *) args->interface_name,
705  l);
706 
707  /* allocate and initialize socket_filename so it can be copyed to sun_path
708  without memory leaks */
709  conn->args.socket_filename = lm->alloc (sizeof (char *) * 108);
710  if (conn->args.socket_filename == NULL)
711  {
712  err = MEMIF_ERR_NOMEM;
713  goto error;
714  }
715  memset (conn->args.socket_filename, 0, 108 * sizeof (char *));
716 
717  if (args->socket_filename)
718  {
719  if (conn->args.socket_filename == NULL)
720  {
721  err = memif_syscall_error_handler (errno);
722  goto error;
723  }
724  strncpy ((char *) conn->args.socket_filename,
725  (char *) args->socket_filename,
726  strlen ((char *) args->socket_filename));
727  }
728  else
729  {
730  uint16_t sdl = strlen (MEMIF_DEFAULT_SOCKET_DIR);
731  uint16_t sfl = strlen (MEMIF_DEFAULT_SOCKET_FILENAME);
732  if (conn->args.socket_filename == NULL)
733  {
734  err = memif_syscall_error_handler (errno);
735  goto error;
736  }
737  strncpy ((char *) conn->args.socket_filename,
739  conn->args.socket_filename[sdl] = '/';
740  strncpy ((char *) (conn->args.socket_filename + 1 + sdl),
742  }
743 
744  if ((l = strlen ((char *) args->secret)) > 0)
745  {
746  strncpy ((char *) conn->args.secret, (char *) args->secret, l);
747  }
748 
749  if (conn->args.is_master)
750  {
751  conn->run_args.buffer_size = conn->args.buffer_size;
752  memif_socket_t *ms;
753  memif_list_elt_t elt;
754  for (i = 0; i < lm->listener_list_len; i++)
755  {
756  if ((ms =
758  {
759  if (strncmp
760  ((char *) ms->filename, (char *) conn->args.socket_filename,
761  strlen ((char *) ms->filename)) == 0)
762  {
763  /* add interface to listener socket */
764  elt.key = conn->args.interface_id;
765  *c = elt.data_struct = conn;
766  add_list_elt (&elt, &ms->interface_list,
767  &ms->interface_list_len);
768  ms->use_count++;
769  conn->listener_fd = ms->fd;
770  break;
771  }
772  }
773  else
774  {
775  struct stat file_stat;
776  if (stat ((char *) conn->args.socket_filename, &file_stat) == 0)
777  {
778  if (S_ISSOCK (file_stat.st_mode))
779  unlink ((char *) conn->args.socket_filename);
780  else
781  return memif_syscall_error_handler (errno);
782  }
783  DBG ("creating socket file");
784  ms = lm->alloc (sizeof (memif_socket_t));
785  if (ms == NULL)
786  {
787  err = MEMIF_ERR_NOMEM;
788  goto error;
789  }
790  ms->filename =
791  lm->alloc (strlen ((char *) conn->args.socket_filename) +
792  sizeof (char));
793  if (ms->filename == NULL)
794  {
795  err = MEMIF_ERR_NOMEM;
796  goto error;
797  }
798  memset (ms->filename, 0,
799  strlen ((char *) conn->args.socket_filename) +
800  sizeof (char));
801  strncpy ((char *) ms->filename,
802  (char *) conn->args.socket_filename,
803  strlen ((char *) conn->args.socket_filename));
804  ms->interface_list_len = 1;
805  ms->interface_list =
806  lm->alloc (sizeof (memif_list_elt_t) *
807  ms->interface_list_len);
808  if (ms->interface_list == NULL)
809  {
810  err = MEMIF_ERR_NOMEM;
811  goto error;
812  }
813  ms->interface_list[0].key = -1;
815  struct sockaddr_un un = { 0 };
816  int on = 1;
817 
818  ms->fd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
819  if (ms->fd < 0)
820  {
821  err = memif_syscall_error_handler (errno);
822  goto error;
823  }
824  DBG ("socket %d created", ms->fd);
825  un.sun_family = AF_UNIX;
826  strncpy ((char *) un.sun_path, (char *) ms->filename,
827  sizeof (un.sun_path) - 1);
828  DBG ("sockopt");
829  if (setsockopt
830  (ms->fd, SOL_SOCKET, SO_PASSCRED, &on, sizeof (on)) < 0)
831  {
832  err = memif_syscall_error_handler (errno);
833  goto error;
834  }
835  DBG ("bind");
836  if (bind (ms->fd, (struct sockaddr *) &un, sizeof (un)) < 0)
837  {
838  err = memif_syscall_error_handler (errno);
839  goto error;
840  }
841  DBG ("listen");
842  if (listen (ms->fd, 1) < 0)
843  {
844  err = memif_syscall_error_handler (errno);
845  goto error;
846  }
847  DBG ("stat");
848  if (stat ((char *) ms->filename, &file_stat) < 0)
849  {
850  err = memif_syscall_error_handler (errno);
851  goto error;
852  }
853 
854  /* add interface to listener socket */
855  elt.key = conn->args.interface_id;
856  *c = elt.data_struct = conn;
857  add_list_elt (&elt, &ms->interface_list,
858  &ms->interface_list_len);
859  ms->use_count = 1;
860  conn->listener_fd = ms->fd;
861 
862  /* add listener socket to libmemif main */
863  elt.key = ms->fd;
864  elt.data_struct = ms;
865  add_list_elt (&elt, &lm->listener_list, &lm->listener_list_len);
867  break;
868  }
869  }
870  }
871  else
872  {
873  lm->disconn_slaves++;
874 
875  list_elt.key = -1;
876  *c = list_elt.data_struct = conn;
877  if ((index =
878  add_list_elt (&list_elt, &lm->control_list,
879  &lm->control_list_len)) < 0)
880  {
881  err = MEMIF_ERR_NOMEM;
882  goto error;
883  }
884 
885  conn->index = index;
886 
887  /* try connectiong to master */
888  err = memif_request_connection(conn);
889  if ((err < 0) && (lm->disconn_slaves == 1))
890  {
891  /* connection failed, arm reconnect timer (if not armed) */
892  if (timerfd_settime (lm->timerfd, 0, &lm->arm, NULL) < 0)
893  {
894  err = memif_syscall_error_handler (errno);
895  goto error;
896  }
897  }
898  }
899 
900  return 0;
901 
902 error:
903  if (sockfd > 0)
904  close (sockfd);
905  sockfd = -1;
906  if (conn->args.socket_filename)
907  lm->free (conn->args.socket_filename);
908  if (conn != NULL)
909  lm->free (conn);
910  *c = conn = NULL;
911  return err;
912 }
913 
914 int
916 {
919  int err = MEMIF_ERR_SUCCESS;
920  int sockfd = -1;
921  struct sockaddr_un sun;
922 
923  if (conn->args.is_master)
924  return MEMIF_ERR_INVAL_ARG;
925  if (conn->fd > 0)
926  return MEMIF_ERR_ALRCONN;
927 
928  sockfd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
929  if (sockfd < 0)
930  {
931  err = memif_syscall_error_handler (errno);
932  goto error;
933  }
934 
935  sun.sun_family = AF_UNIX;
936 
937  strncpy (sun.sun_path, (char *) conn->args.socket_filename,
938  sizeof (sun.sun_path) - 1);
939 
940  if (connect (sockfd, (struct sockaddr *) &sun,
941  sizeof (struct sockaddr_un)) == 0)
942  {
943  conn->fd = sockfd;
944  conn->read_fn = memif_conn_fd_read_ready;
945  conn->write_fn = memif_conn_fd_write_ready;
946  conn->error_fn = memif_conn_fd_error;
947 
948  lm->control_list[conn->index].key = conn->fd;
949 
950  lm->control_fd_update (sockfd,
953 
954  lm->disconn_slaves--;
955  if (lm->disconn_slaves == 0)
956  {
957  if (timerfd_settime (lm->timerfd, 0, &lm->disarm, NULL) < 0)
958  {
959  err = memif_syscall_error_handler (errno);
960  return err;
961  }
962  }
963  }
964  else
965  {
966  strcpy ((char *) conn->remote_disconnect_string,
968  (errno)));
969  goto error;
970  }
971 
972  return err;
973 
974 error:
975  if (sockfd > 0)
976  close (sockfd);
977  sockfd = -1;
978  return err;
979 }
980 
981 int
982 memif_control_fd_handler (int fd, uint8_t events)
983 {
984  int i, err = MEMIF_ERR_SUCCESS; /* 0 */
985  uint16_t num;
986  memif_list_elt_t *e = NULL;
987  memif_connection_t *conn;
989  if (fd == lm->timerfd)
990  {
991  uint64_t b;
992  ssize_t size;
993  size = read (fd, &b, sizeof (b));
994 
995  if (size == -1)
996  goto error;
997 
998  for (i = 0; i < lm->control_list_len; i++)
999  {
1000  if ((lm->control_list[i].key < 0)
1001  && (lm->control_list[i].data_struct != NULL))
1002  {
1003  conn = lm->control_list[i].data_struct;
1004  if (conn->args.is_master)
1005  continue;
1007  }
1008  }
1009  }
1010  else
1011  {
1012  get_list_elt (&e, lm->interrupt_list, lm->interrupt_list_len, fd);
1013  if (e != NULL)
1014  {
1015  if (((memif_connection_t *) e->data_struct)->on_interrupt != NULL)
1016  {
1017  num =
1018  (((memif_connection_t *) e->data_struct)->
1019  args.is_master) ? ((memif_connection_t *) e->
1020  data_struct)->run_args.
1021  num_s2m_rings : ((memif_connection_t *) e->data_struct)->
1022  run_args.num_m2s_rings;
1023  for (i = 0; i < num; i++)
1024  {
1025  if (((memif_connection_t *) e->data_struct)->
1026  rx_queues[i].int_fd == fd)
1027  {
1028  ((memif_connection_t *) e->data_struct)->
1029  on_interrupt ((void *) e->data_struct,
1030  ((memif_connection_t *) e->
1031  data_struct)->private_ctx, i);
1032  return MEMIF_ERR_SUCCESS;
1033  }
1034  }
1035  }
1036  return MEMIF_ERR_SUCCESS;
1037  }
1038  get_list_elt (&e, lm->listener_list, lm->listener_list_len, fd);
1039  if (e != NULL)
1040  {
1042  return err;
1043  }
1044 
1045  get_list_elt (&e, lm->pending_list, lm->pending_list_len, fd);
1046  if (e != NULL)
1047  {
1048  err = memif_read_ready (fd);
1049  return err;
1050  }
1051 
1052  get_list_elt (&e, lm->control_list, lm->control_list_len, fd);
1053  if (e != NULL)
1054  {
1055  if (events & MEMIF_FD_EVENT_READ)
1056  {
1057  err =
1058  ((memif_connection_t *) e->data_struct)->
1059  read_fn (e->data_struct);
1060  if (err != MEMIF_ERR_SUCCESS)
1061  return err;
1062  }
1063  if (events & MEMIF_FD_EVENT_WRITE)
1064  {
1065  err =
1066  ((memif_connection_t *) e->data_struct)->
1067  write_fn (e->data_struct);
1068  if (err != MEMIF_ERR_SUCCESS)
1069  return err;
1070  }
1071  if (events & MEMIF_FD_EVENT_ERROR)
1072  {
1073  err =
1074  ((memif_connection_t *) e->data_struct)->
1075  error_fn (e->data_struct);
1076  if (err != MEMIF_ERR_SUCCESS)
1077  return err;
1078  }
1079  }
1080  }
1081 
1082  return MEMIF_ERR_SUCCESS; /* 0 */
1083 
1084 error:
1085  return err;
1086 }
1087 
1088 int
1089 memif_poll_event (int timeout)
1090 {
1091  struct epoll_event evt;
1092  int en = 0, err = MEMIF_ERR_SUCCESS; /* 0 */
1093  uint32_t events = 0;
1094  uint64_t counter = 0;
1095  ssize_t r = 0;
1096  memset (&evt, 0, sizeof (evt));
1097  evt.events = EPOLLIN | EPOLLOUT;
1098  sigset_t sigset;
1099  sigemptyset (&sigset);
1100  en = epoll_pwait (memif_epfd, &evt, 1, timeout, &sigset);
1101  if (en < 0)
1102  {
1103  err = errno;
1104  DBG ("epoll_pwait: %s", strerror (err));
1105  return memif_syscall_error_handler (err);
1106  }
1107  if (en > 0)
1108  {
1109  if (evt.data.fd == poll_cancel_fd)
1110  {
1111  r = read (evt.data.fd, &counter, sizeof (counter));
1112  if (r == -1)
1113  return MEMIF_ERR_DISCONNECTED;
1114 
1115  return MEMIF_ERR_POLL_CANCEL;
1116  }
1117  if (evt.events & EPOLLIN)
1118  events |= MEMIF_FD_EVENT_READ;
1119  if (evt.events & EPOLLOUT)
1120  events |= MEMIF_FD_EVENT_WRITE;
1121  if (evt.events & EPOLLERR)
1122  events |= MEMIF_FD_EVENT_ERROR;
1123  err = memif_control_fd_handler (evt.data.fd, events);
1124  return err;
1125  }
1126  return 0;
1127 }
1128 
1129 int
1131 {
1132  uint64_t counter = 1;
1133  ssize_t w = 0;
1134 
1135  if (poll_cancel_fd == -1)
1136  return 0;
1137  w = write (poll_cancel_fd, &counter, sizeof (counter));
1138  if (w < sizeof (counter))
1139  return MEMIF_ERR_INT_WRITE;
1140 
1141  return 0;
1142 }
1143 
1144 static void
1146 {
1147  if (*e == NULL)
1148  return;
1149  memif_msg_queue_free (lm, &(*e)->next);
1150  lm->free (*e);
1151  *e = NULL;
1152  return;
1153 }
1154 
1155 /* send disconnect msg and close interface */
1156 int
1158 {
1159  if (c == NULL)
1160  {
1161  DBG ("no connection");
1162  return MEMIF_ERR_NOCONN;
1163  }
1164  uint16_t num;
1165  int err = MEMIF_ERR_SUCCESS, i; /* 0 */
1166  memif_queue_t *mq;
1168  memif_list_elt_t *e;
1169 
1170  c->on_disconnect ((void *) c, c->private_ctx);
1171 
1172  if (c->fd > 0)
1173  {
1174  memif_msg_send_disconnect (c->fd, (uint8_t *) "interface deleted", 0);
1176  close (c->fd);
1177  }
1178  get_list_elt (&e, lm->control_list, lm->control_list_len, c->fd);
1179  if (e != NULL)
1180  {
1181  if (c->args.is_master)
1182  free_list_elt (lm->control_list, lm->control_list_len, c->fd);
1183  e->key = c->fd = -1;
1184  }
1185 
1186  if (c->tx_queues != NULL)
1187  {
1188  num =
1189  (c->args.is_master) ? c->run_args.num_m2s_rings : c->
1190  run_args.num_s2m_rings;
1191  for (i = 0; i < num; i++)
1192  {
1193  mq = &c->tx_queues[i];
1194  if (mq != NULL)
1195  {
1196  if (mq->int_fd > 0)
1197  close (mq->int_fd);
1199  mq->int_fd);
1200  mq->int_fd = -1;
1201  }
1202  }
1203  lm->free (c->tx_queues);
1204  c->tx_queues = NULL;
1205  }
1206 
1207  if (c->rx_queues != NULL)
1208  {
1209  num =
1210  (c->args.is_master) ? c->run_args.num_s2m_rings : c->
1211  run_args.num_m2s_rings;
1212  for (i = 0; i < num; i++)
1213  {
1214  mq = &c->rx_queues[i];
1215  if (mq != NULL)
1216  {
1217  if (mq->int_fd > 0)
1218  {
1219  if (c->on_interrupt != NULL)
1221  close (mq->int_fd);
1222  }
1224  mq->int_fd);
1225  mq->int_fd = -1;
1226  }
1227  }
1228  lm->free (c->rx_queues);
1229  c->rx_queues = NULL;
1230  }
1231 
1232  for (i = 0; i < c->regions_num; i++)
1233  {
1234  if (&c->regions[i] == NULL)
1235  continue;
1236  if (c->regions[i].is_external != 0)
1237  {
1238  lm->del_external_region (c->regions[i].addr,
1239  c->regions[i].region_size,
1240  c->regions[i].fd, c->private_ctx);
1241  }
1242  else
1243  {
1244  if (munmap (c->regions[i].addr, c->regions[i].region_size) < 0)
1245  return memif_syscall_error_handler (errno);
1246  if (c->regions[i].fd > 0)
1247  close (c->regions[i].fd);
1248  c->regions[i].fd = -1;
1249  }
1250  }
1251  lm->free (c->regions);
1252  c->regions = NULL;
1253  c->regions_num = 0;
1254 
1255  memset (&c->run_args, 0, sizeof (memif_conn_run_args_t));
1256 
1257  memif_msg_queue_free (lm, &c->msg_queue);
1258 
1259  if (!(c->args.is_master))
1260  {
1261  if (lm->disconn_slaves == 0)
1262  {
1263  if (timerfd_settime (lm->timerfd, 0, &lm->arm, NULL) < 0)
1264  {
1265  err = memif_syscall_error_handler (errno);
1266  DBG ("timerfd_settime: arm");
1267  }
1268  }
1269  lm->disconn_slaves++;
1270  }
1271 
1272  return err;
1273 }
1274 
1275 int
1277 {
1278  memif_connection_t *c = (memif_connection_t *) * conn;
1279  if (c == NULL)
1280  {
1281  DBG ("no connection");
1282  return MEMIF_ERR_NOCONN;
1283  }
1285  memif_list_elt_t *e = NULL;
1286  memif_socket_t *ms = NULL;
1287 
1288  int err = MEMIF_ERR_SUCCESS;
1289 
1290  if (c->fd > 0)
1291  {
1292  DBG ("DISCONNECTING");
1293  err = memif_disconnect_internal (c);
1294  if (err == MEMIF_ERR_NOCONN)
1295  return err;
1296  }
1297 
1299 
1300  if (c->args.is_master)
1301  {
1303  c->listener_fd);
1304  if (e != NULL)
1305  {
1306  ms = (memif_socket_t *) e->data_struct;
1307  ms->use_count--;
1309  c->args.interface_id);
1310  if (ms->use_count <= 0)
1311  {
1312  lm->control_fd_update (c->listener_fd, MEMIF_FD_EVENT_DEL);
1314  c->listener_fd);
1315  close (c->listener_fd);
1316  c->listener_fd = ms->fd = -1;
1317  lm->free (ms->interface_list);
1318  ms->interface_list = NULL;
1319  lm->free (ms->filename);
1320  ms->filename = NULL;
1321  lm->free (ms);
1322  ms = NULL;
1323  }
1324  }
1325  }
1326  else
1327  {
1328  lm->disconn_slaves--;
1329  if (lm->disconn_slaves <= 0)
1330  {
1331  if (timerfd_settime (lm->timerfd, 0, &lm->disarm, NULL) < 0)
1332  {
1333  err = memif_syscall_error_handler (errno);
1334  DBG ("timerfd_settime: disarm");
1335  }
1336  }
1337  }
1338 
1339  if (c->args.socket_filename)
1340  lm->free (c->args.socket_filename);
1341  c->args.socket_filename = NULL;
1342 
1343  lm->free (c);
1344  c = NULL;
1345 
1346  *conn = c;
1347  return err;
1348 }
1349 
1350 int
1352 {
1354  memif_region_t *mr;
1355  memif_queue_t *mq;
1356  int i;
1357 
1358  for (i = 0; i < c->regions_num; i++)
1359  {
1360  mr = &c->regions[i];
1361  if (mr != NULL)
1362  {
1363  if (!mr->addr)
1364  {
1365  if (mr->is_external)
1366  {
1367  if (lm->get_external_region_addr == NULL)
1368  return 99; /* FIXME: proper error report */
1369  mr->addr =
1370  lm->get_external_region_addr (mr->region_size, mr->fd,
1371  c->private_ctx);
1372  }
1373  else
1374  {
1375  if (mr->fd < 0)
1376  return MEMIF_ERR_NO_SHMFD;
1377 
1378  if ((mr->addr =
1379  mmap (NULL, mr->region_size, PROT_READ | PROT_WRITE,
1380  MAP_SHARED, mr->fd, 0)) == MAP_FAILED)
1381  {
1382  return memif_syscall_error_handler (errno);
1383  }
1384  }
1385  }
1386  }
1387  }
1388 
1389  for (i = 0; i < c->rx_queues_num; i++)
1390  {
1391  mq = &c->rx_queues[i];
1392  if (mq != NULL)
1393  {
1394  mq->ring = c->regions[mq->region].addr + mq->offset;
1395  if (mq->ring->cookie != MEMIF_COOKIE)
1396  {
1397  DBG ("wrong cookie on rx ring %u", i);
1398  return MEMIF_ERR_COOKIE;
1399  }
1400  mq->ring->head = mq->ring->tail = mq->last_head = mq->alloc_bufs =
1401  0;
1402  }
1403  }
1404 
1405  for (i = 0; i < c->tx_queues_num; i++)
1406  {
1407  mq = &c->tx_queues[i];
1408  if (mq != NULL)
1409  {
1410  mq->ring = c->regions[mq->region].addr + mq->offset;
1411  if (mq->ring->cookie != MEMIF_COOKIE)
1412  {
1413  DBG ("wrong cookie on tx ring %u", i);
1414  return MEMIF_ERR_COOKIE;
1415  }
1416  mq->ring->head = mq->ring->tail = mq->last_head = mq->alloc_bufs =
1417  0;
1418  }
1419  }
1420 
1422 
1423  return 0;
1424 }
1425 
1426 static inline int
1428  uint8_t has_buffers)
1429 {
1430  memif_region_t *r;
1431 
1432  r =
1433  lm->realloc (conn->regions,
1434  sizeof (memif_region_t) * ++conn->regions_num);
1435  if (r == NULL)
1436  return MEMIF_ERR_NOMEM;
1437 
1438  conn->regions = r;
1439  r = &conn->regions[conn->regions_num - 1];
1440  memset (r, 0, sizeof (memif_region_t));
1441 
1442  if (has_buffers != 0)
1443  {
1444  r->buffer_offset = 0;
1445  }
1446  else
1447  {
1448  r->buffer_offset =
1449  (conn->run_args.num_s2m_rings +
1450  conn->run_args.num_m2s_rings) * (sizeof (memif_ring_t) +
1451  sizeof (memif_desc_t) *
1452  (1 << conn->
1453  run_args.log2_ring_size));
1454  }
1455 
1456  r->region_size = (has_buffers == 0) ? r->buffer_offset : r->buffer_offset +
1457  conn->run_args.buffer_size * (1 << conn->run_args.log2_ring_size) *
1458  (conn->run_args.num_s2m_rings + conn->run_args.num_m2s_rings);
1459 
1460  if ((r->fd = memfd_create ("memif region 0", MFD_ALLOW_SEALING)) == -1)
1461  return memif_syscall_error_handler (errno);
1462 
1463  if ((fcntl (r->fd, F_ADD_SEALS, F_SEAL_SHRINK)) == -1)
1464  return memif_syscall_error_handler (errno);
1465 
1466  if ((ftruncate (r->fd, r->region_size)) == -1)
1467  return memif_syscall_error_handler (errno);
1468 
1469  if ((r->addr = mmap (NULL, r->region_size, PROT_READ | PROT_WRITE,
1470  MAP_SHARED, r->fd, 0)) == MAP_FAILED)
1471  return memif_syscall_error_handler (errno);
1472 
1473  return MEMIF_ERR_SUCCESS;
1474 }
1475 
1476 static inline int
1478 {
1479  int i, j;
1480  memif_ring_t *ring;
1481 
1482  for (i = 0; i < conn->run_args.num_s2m_rings; i++)
1483  {
1484  ring = memif_get_ring (conn, MEMIF_RING_S2M, i);
1485  DBG ("RING: %p I: %d", ring, i);
1486  ring->head = ring->tail = 0;
1487  ring->cookie = MEMIF_COOKIE;
1488  ring->flags = 0;
1489  for (j = 0; j < (1 << conn->run_args.log2_ring_size); j++)
1490  {
1491  uint16_t slot = i * (1 << conn->run_args.log2_ring_size) + j;
1492  ring->desc[j].region = 1;
1493  ring->desc[j].offset =
1494  conn->regions[1].buffer_offset +
1495  (uint32_t) (slot * conn->run_args.buffer_size);
1496  ring->desc[j].length = conn->run_args.buffer_size;
1497  }
1498  }
1499  for (i = 0; i < conn->run_args.num_m2s_rings; i++)
1500  {
1501  ring = memif_get_ring (conn, MEMIF_RING_M2S, i);
1502  DBG ("RING: %p I: %d", ring, i);
1503  ring->head = ring->tail = 0;
1504  ring->cookie = MEMIF_COOKIE;
1505  ring->flags = 0;
1506  for (j = 0; j < (1 << conn->run_args.log2_ring_size); j++)
1507  {
1508  uint16_t slot = (i + conn->run_args.num_s2m_rings) *
1509  (1 << conn->run_args.log2_ring_size) + j;
1510  ring->desc[j].region = 1;
1511  ring->desc[j].offset =
1512  conn->regions[1].buffer_offset +
1513  (uint32_t) (slot * conn->run_args.buffer_size);
1514  ring->desc[j].length = conn->run_args.buffer_size;
1515  }
1516  }
1517  memif_queue_t *mq;
1518  DBG ("alloc: %p", lm->alloc);
1519  DBG ("size: %lu", sizeof (memif_queue_t) * conn->run_args.num_s2m_rings);
1520  mq =
1521  (memif_queue_t *) lm->alloc (sizeof (memif_queue_t) *
1522  conn->run_args.num_s2m_rings);
1523  if (mq == NULL)
1524  return MEMIF_ERR_NOMEM;
1525 
1526  int x;
1527  memif_list_elt_t e;
1528  for (x = 0; x < conn->run_args.num_s2m_rings; x++)
1529  {
1530  if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
1531  return memif_syscall_error_handler (errno);
1532  e.key = mq[x].int_fd;
1533  e.data_struct = conn;
1535 
1536  mq[x].ring = memif_get_ring (conn, MEMIF_RING_S2M, x);
1537  DBG ("RING: %p I: %d", mq[x].ring, x);
1538  mq[x].log2_ring_size = conn->run_args.log2_ring_size;
1539  mq[x].region = 0;
1540  mq[x].offset =
1541  (void *) mq[x].ring - (void *) conn->regions[mq->region].addr;
1542  mq[x].last_head = mq[x].last_tail = 0;
1543  mq[x].alloc_bufs = 0;
1544  }
1545  conn->tx_queues = mq;
1546 
1547  mq =
1548  (memif_queue_t *) lm->alloc (sizeof (memif_queue_t) *
1549  conn->run_args.num_m2s_rings);
1550  if (mq == NULL)
1551  return MEMIF_ERR_NOMEM;
1552 
1553  for (x = 0; x < conn->run_args.num_m2s_rings; x++)
1554  {
1555  if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
1556  return memif_syscall_error_handler (errno);
1557  e.key = mq[x].int_fd;
1558  e.data_struct = conn;
1560 
1561  mq[x].ring = memif_get_ring (conn, MEMIF_RING_M2S, x);
1562  DBG ("RING: %p I: %d", mq[x].ring, x);
1563  mq[x].log2_ring_size = conn->run_args.log2_ring_size;
1564  mq[x].region = 0;
1565  mq[x].offset =
1566  (void *) mq[x].ring - (void *) conn->regions[mq->region].addr;
1567  mq[x].last_head = mq[x].last_tail = 0;
1568  mq[x].alloc_bufs = 0;
1569  }
1570  conn->rx_queues = mq;
1571 
1572  return MEMIF_ERR_SUCCESS;
1573 }
1574 
1575 int
1577 {
1578  memif_region_t *r;
1580 
1581  /* region 0. rings */
1582  memif_add_region (lm, conn, /* has_buffers */ 0);
1583 
1584  /* region 1. buffers */
1585  if (lm->add_external_region)
1586  {
1587  r =
1588  (memif_region_t *) lm->realloc (conn->regions,
1589  sizeof (memif_region_t) *
1590  ++conn->regions_num);
1591  if (r == NULL)
1592  return MEMIF_ERR_NOMEM;
1593  conn->regions = r;
1594 
1595  conn->regions[1].region_size =
1596  conn->run_args.buffer_size * (1 << conn->run_args.log2_ring_size) *
1597  (conn->run_args.num_s2m_rings + conn->run_args.num_m2s_rings);
1598  conn->regions[1].buffer_offset = 0;
1599  lm->add_external_region (&conn->regions[1].addr,
1600  conn->regions[1].region_size,
1601  &conn->regions[1].fd, conn->private_ctx);
1602  conn->regions[1].is_external = 1;
1603  }
1604  else
1605  {
1606  memif_add_region (lm, conn, 1);
1607  }
1608 
1609  memif_init_queues (lm, conn);
1610 
1611  return 0;
1612 }
1613 
1614 int
1616  memif_buffer_t * bufs, uint16_t count,
1617  uint16_t * count_out)
1618 {
1620  if (EXPECT_FALSE (c == NULL))
1621  return MEMIF_ERR_NOCONN;
1622  if (EXPECT_FALSE (c->fd < 0))
1623  return MEMIF_ERR_DISCONNECTED;
1624  uint8_t num =
1625  (c->args.is_master) ? c->run_args.num_m2s_rings : c->
1626  run_args.num_s2m_rings;
1627  if (EXPECT_FALSE (qid >= num))
1628  return MEMIF_ERR_QID;
1629  if (EXPECT_FALSE (!count_out))
1630  return MEMIF_ERR_INVAL_ARG;
1631  if (EXPECT_FALSE (c->args.is_master))
1632  return MEMIF_ERR_INVAL_ARG;
1633 
1634  memif_queue_t *mq = &c->tx_queues[qid];
1635  memif_ring_t *ring = mq->ring;
1636  memif_buffer_t *b0;
1637  uint16_t mask = (1 << mq->log2_ring_size) - 1;
1638  uint16_t ring_size;
1639  uint16_t slot, ns;
1640  int err = MEMIF_ERR_SUCCESS; /* 0 */
1641  *count_out = 0;
1642 
1643  ring_size = (1 << mq->log2_ring_size);
1644  slot = (c->args.is_master) ? ring->tail : ring->head;
1645  slot += mq->alloc_bufs;
1646 
1647  /* can only be called by slave */
1648  ns = ring_size - (ring->head + mq->alloc_bufs) + ring->tail;
1649 
1650  b0 = bufs;
1651 
1652  while (count && ns)
1653  {
1654  if (EXPECT_FALSE ((b0->flags & MEMIF_BUFFER_FLAG_RX) == 0))
1655  {
1656  /* not a valid buffer */
1657  count--;
1658  continue;
1659  }
1660  b0->flags &= ~MEMIF_BUFFER_FLAG_RX;
1661 
1662  ((memif_ring_t *) b0->ring)->desc[b0->desc_index & mask].offset = ring->desc[slot & mask].offset; /* put free buffer on rx ring */
1663 
1664  ring->desc[slot & mask].offset =
1665  (uint32_t) (b0->data -
1666  c->regions[ring->desc[slot & mask].region].addr);
1667  ring->desc[slot & mask].flags |=
1669 
1670  b0->desc_index = slot;
1671 
1672  mq->alloc_bufs++;
1673  slot++;
1674 
1675  count--;
1676  ns--;
1677  b0++;
1678  *count_out += 1;
1679  }
1680 
1681  DBG ("allocated: %u/%u bufs. Total %u allocated bufs", *count_out, count,
1682  mq->alloc_bufs);
1683 
1684  if (count)
1685  {
1686  DBG ("ring buffer full! qid: %u", qid);
1687  err = MEMIF_ERR_NOBUF_RING;
1688  }
1689 
1690  return err;
1691 }
1692 
1693 int
1695  memif_buffer_t * bufs, uint16_t count,
1696  uint16_t * count_out, uint16_t size)
1697 {
1699  if (EXPECT_FALSE (c == NULL))
1700  return MEMIF_ERR_NOCONN;
1701  if (EXPECT_FALSE (c->fd < 0))
1702  return MEMIF_ERR_DISCONNECTED;
1703  uint8_t num =
1704  (c->args.is_master) ? c->run_args.num_m2s_rings : c->
1705  run_args.num_s2m_rings;
1706  if (EXPECT_FALSE (qid >= num))
1707  return MEMIF_ERR_QID;
1708  if (EXPECT_FALSE (!count_out))
1709  return MEMIF_ERR_INVAL_ARG;
1710 
1712  memif_queue_t *mq = &c->tx_queues[qid];
1713  memif_ring_t *ring = mq->ring;
1714  memif_buffer_t *b0;
1715  uint16_t mask = (1 << mq->log2_ring_size) - 1;
1716  uint32_t offset_mask = c->run_args.buffer_size - 1;
1717  uint16_t ring_size;
1718  uint16_t slot, ns;
1719  int err = MEMIF_ERR_SUCCESS; /* 0 */
1720  uint16_t dst_left, src_left;
1721  uint16_t saved_count;
1722  memif_buffer_t *saved_b;
1723  *count_out = 0;
1724 
1725  ring_size = (1 << mq->log2_ring_size);
1726  slot = (c->args.is_master) ? ring->tail : ring->head;
1727  slot += mq->alloc_bufs;
1728 
1729  if (c->args.is_master)
1730  ns = ring->head - (ring->tail + mq->alloc_bufs);
1731  else
1732  ns = ring_size - (ring->head + mq->alloc_bufs) + ring->tail;
1733 
1734  while (count && ns)
1735  {
1736  b0 = (bufs + *count_out);
1737 
1738  saved_b = b0;
1739  saved_count = count;
1740 
1741  b0->desc_index = slot;
1742  ring->desc[slot & mask].flags = 0;
1743 
1744  /* slave can produce buffer with original length */
1745  dst_left = (c->args.is_master) ? ring->desc[slot & mask].length :
1746  c->run_args.buffer_size;
1747  src_left = size;
1748 
1749  while (src_left)
1750  {
1751  if (EXPECT_FALSE (dst_left == 0))
1752  {
1753  if (count && ns)
1754  {
1755  slot++;
1756  *count_out += 1;
1757  mq->alloc_bufs++;
1758  ns--;
1759 
1760  ring->desc[b0->desc_index & mask].flags |=
1763 
1764  b0 = (bufs + *count_out);
1765  b0->desc_index = slot;
1766  dst_left =
1767  (c->args.is_master) ? ring->desc[slot & mask].
1768  length : c->run_args.buffer_size;
1769  ring->desc[slot & mask].flags = 0;
1770  }
1771  else
1772  {
1773  /* rollback allocated chain buffers */
1774  memset (saved_b, 0, sizeof (memif_buffer_t)
1775  * (saved_count - count + 1));
1776  *count_out -= saved_count - count;
1777  mq->alloc_bufs = saved_count - count;
1778  goto no_ns;
1779  }
1780  }
1781  b0->len = memif_min (dst_left, src_left);
1782 
1783  /* slave resets buffer offset */
1784  if (c->args.is_master == 0)
1785  {
1786  memif_desc_t *d = &ring->desc[slot & mask];
1788  d->offset = lm->get_external_buffer_offset (c->private_ctx);
1789  else
1790  d->offset = d->offset - (d->offset & offset_mask);
1791  }
1792  b0->data = memif_get_buffer (c, ring, slot & mask);
1793 
1794  src_left -= b0->len;
1795  dst_left -= b0->len;
1796  }
1797 
1798  slot++;
1799  *count_out += 1;
1800  mq->alloc_bufs++;
1801  ns--;
1802  count--;
1803  }
1804 
1805 no_ns:
1806 
1807  DBG ("allocated: %u/%u bufs. Total %u allocated bufs", *count_out, count,
1808  mq->alloc_bufs);
1809 
1810  if (count)
1811  {
1812  DBG ("ring buffer full! qid: %u", qid);
1813  err = MEMIF_ERR_NOBUF_RING;
1814  }
1815 
1816  return err;
1817 }
1818 
1819 int
1820 memif_refill_queue (memif_conn_handle_t conn, uint16_t qid, uint16_t count,
1821  uint16_t headroom)
1822 {
1824  if (EXPECT_FALSE (c == NULL))
1825  return MEMIF_ERR_NOCONN;
1826  if (EXPECT_FALSE (c->fd < 0))
1827  return MEMIF_ERR_DISCONNECTED;
1828  uint8_t num =
1829  (c->args.is_master) ? c->run_args.num_s2m_rings : c->
1830  run_args.num_m2s_rings;
1831  if (EXPECT_FALSE (qid >= num))
1832  return MEMIF_ERR_QID;
1834  memif_queue_t *mq = &c->rx_queues[qid];
1835  memif_ring_t *ring = mq->ring;
1836  uint16_t mask = (1 << mq->log2_ring_size) - 1;
1837  uint32_t offset_mask = c->run_args.buffer_size - 1;
1838  uint16_t slot;
1839 
1840  if (c->args.is_master)
1841  {
1843  ring->tail =
1844  (ring->tail + count <=
1845  mq->last_head) ? ring->tail + count : mq->last_head;
1846  return MEMIF_ERR_SUCCESS;
1847  }
1848 
1849  uint16_t head = ring->head;
1850  uint16_t ns = (1 << mq->log2_ring_size) - head + mq->last_tail;
1851  head += (count < ns) ? count : ns;
1852 
1853  slot = ring->head;
1854  memif_desc_t *d;
1855  while (slot < head)
1856  {
1857  d = &ring->desc[slot & mask];
1858  d->region = 1;
1859  d->length = c->run_args.buffer_size - headroom;
1861  d->offset = lm->get_external_buffer_offset (c->private_ctx);
1862  else
1863  d->offset = d->offset - (d->offset & offset_mask) + headroom;
1864  slot++;
1865  }
1866 
1868  ring->head = head;
1869 
1870  return MEMIF_ERR_SUCCESS; /* 0 */
1871 }
1872 
1873 int
1875  memif_buffer_t * bufs, uint16_t count, uint16_t * tx)
1876 {
1878  if (EXPECT_FALSE (c == NULL))
1879  return MEMIF_ERR_NOCONN;
1880  if (EXPECT_FALSE (c->fd < 0))
1881  return MEMIF_ERR_DISCONNECTED;
1882  uint8_t num =
1883  (c->args.is_master) ? c->run_args.num_m2s_rings : c->
1884  run_args.num_s2m_rings;
1885  if (EXPECT_FALSE (qid >= num))
1886  return MEMIF_ERR_QID;
1887  if (EXPECT_FALSE (!tx))
1888  return MEMIF_ERR_INVAL_ARG;
1889 
1890  memif_queue_t *mq = &c->tx_queues[qid];
1891  memif_ring_t *ring = mq->ring;
1892  uint16_t mask = (1 << mq->log2_ring_size) - 1;
1893  memif_buffer_t *b0;
1894  *tx = 0;
1895 
1896  if (count > mq->alloc_bufs)
1897  count = mq->alloc_bufs;
1898 
1899  if (EXPECT_FALSE (count == 0))
1900  return MEMIF_ERR_SUCCESS;
1901 
1902  while (count)
1903  {
1904  b0 = (bufs + *tx);
1905  ring->desc[b0->desc_index & mask].length = b0->len;
1906 
1907 #ifdef MEMIF_DBG_SHM
1908  printf ("offset: %-6d\n", ring->desc[b0->desc_index & mask].offset);
1909  printf ("data: %p\n",
1910  memif_get_buffer (c, ring, b0->desc_index & mask));
1911  printf ("index: %u\n", b0->desc_index);
1912  print_bytes (memif_get_buffer (c, ring, b0->desc_index & mask),
1913  ring->desc[b0->desc_index & mask].length, DBG_TX_BUF);
1914 #endif /* MEMIF_DBG_SHM */
1915 
1916  *tx += 1;
1917  count--;
1918  }
1919 
1920 
1922  if (c->args.is_master)
1923  ring->tail = b0->desc_index + 1;
1924  else
1925  ring->head = b0->desc_index + 1;
1926 
1927  mq->alloc_bufs -= *tx;
1928 
1929  if ((ring->flags & MEMIF_RING_FLAG_MASK_INT) == 0)
1930  {
1931  uint64_t a = 1;
1932  int r = write (mq->int_fd, &a, sizeof (a));
1933  if (r < 0)
1934  return MEMIF_ERR_INT_WRITE;
1935  }
1936 
1937  return MEMIF_ERR_SUCCESS; /* 0 */
1938 }
1939 
1940 int
1942  memif_buffer_t * bufs, uint16_t count, uint16_t * rx)
1943 {
1945  if (EXPECT_FALSE (c == NULL))
1946  return MEMIF_ERR_NOCONN;
1947  if (EXPECT_FALSE (c->fd < 0))
1948  return MEMIF_ERR_DISCONNECTED;
1949  uint8_t num =
1950  (c->args.is_master) ? c->run_args.num_s2m_rings : c->
1951  run_args.num_m2s_rings;
1952  if (EXPECT_FALSE (qid >= num))
1953  return MEMIF_ERR_QID;
1954  if (EXPECT_FALSE (!rx))
1955  return MEMIF_ERR_INVAL_ARG;
1956 
1957  memif_queue_t *mq = &c->rx_queues[qid];
1958  memif_ring_t *ring = mq->ring;
1959  uint16_t cur_slot, last_slot;
1960  uint16_t ns;
1961  uint16_t mask = (1 << mq->log2_ring_size) - 1;
1962  memif_buffer_t *b0;
1963  *rx = 0;
1964 
1965  uint64_t b;
1966  ssize_t r = read (mq->int_fd, &b, sizeof (b));
1967  if (EXPECT_FALSE ((r == -1) && (errno != EAGAIN)))
1968  return memif_syscall_error_handler (errno);
1969 
1970  cur_slot = (c->args.is_master) ? mq->last_head : mq->last_tail;
1971  last_slot = (c->args.is_master) ? ring->head : ring->tail;
1972  if (cur_slot == last_slot)
1973  return MEMIF_ERR_SUCCESS;
1974 
1975  ns = last_slot - cur_slot;
1976 
1977  while (ns && count)
1978  {
1979  b0 = (bufs + *rx);
1980 
1981  b0->desc_index = cur_slot;
1982  b0->data = memif_get_buffer (c, ring, cur_slot & mask);
1983  b0->len = ring->desc[cur_slot & mask].length;
1984  /* slave resets buffer length */
1985  if (c->args.is_master == 0)
1986  {
1987  ring->desc[cur_slot & mask].length = c->run_args.buffer_size;
1988  }
1989 
1991  if (ring->desc[cur_slot & mask].flags & MEMIF_DESC_FLAG_NEXT)
1992  {
1994  ring->desc[cur_slot & mask].flags &= ~MEMIF_DESC_FLAG_NEXT;
1995  }
1996 /* b0->offset = ring->desc[cur_slot & mask].offset;*/
1997  b0->ring = ring;
1998 #ifdef MEMIF_DBG_SHM
1999  printf ("data: %p\n", b0->data);
2000  printf ("index: %u\n", b0->desc_index);
2001  printf ("ring: %p\n", b0->ring);
2002  print_bytes (b0->data, b0->len, DBG_RX_BUF);
2003 #endif /* MEMIF_DBG_SHM */
2004  ns--;
2005  *rx += 1;
2006 
2007  count--;
2008  cur_slot++;
2009  }
2010 
2011  if (c->args.is_master)
2012  mq->last_head = cur_slot;
2013  else
2014  mq->last_tail = cur_slot;
2015 
2016  if (ns)
2017  {
2018  DBG ("not enough buffers!");
2019  return MEMIF_ERR_NOBUF;
2020  }
2021 
2022  return MEMIF_ERR_SUCCESS; /* 0 */
2023 }
2024 
2025 int
2027  char *buf, ssize_t buflen)
2028 {
2031  if (c == NULL)
2032  return MEMIF_ERR_NOCONN;
2033 
2034  int err = MEMIF_ERR_SUCCESS, i;
2035  ssize_t l0, l1;
2036  l0 = 0;
2037 
2038  l1 = strlen ((char *) c->args.interface_name);
2039  if (l0 + l1 < buflen)
2040  {
2041  md->if_name =
2042  (uint8_t *) strcpy (buf + l0, (char *) c->args.interface_name);
2043  l0 += l1 + 1;
2044  }
2045  else
2046  err = MEMIF_ERR_NOBUF_DET;
2047 
2048  l1 = strlen ((char *) lm->app_name);
2049  if (l0 + l1 < buflen)
2050  {
2051  md->inst_name = (uint8_t *) strcpy (buf + l0, (char *) lm->app_name);
2052  l0 += l1 + 1;
2053  }
2054  else
2055  err = MEMIF_ERR_NOBUF_DET;
2056 
2057  l1 = strlen ((char *) c->remote_if_name);
2058  if (l0 + l1 < buflen)
2059  {
2060  md->remote_if_name =
2061  (uint8_t *) strcpy (buf + l0, (char *) c->remote_if_name);
2062  l0 += l1 + 1;
2063  }
2064  else
2065  err = MEMIF_ERR_NOBUF_DET;
2066 
2067  l1 = strlen ((char *) c->remote_name);
2068  if (l0 + l1 < buflen)
2069  {
2070  md->remote_inst_name =
2071  (uint8_t *) strcpy (buf + l0, (char *) c->remote_name);
2072  l0 += l1 + 1;
2073  }
2074  else
2075  err = MEMIF_ERR_NOBUF_DET;
2076 
2077  md->id = c->args.interface_id;
2078 
2079  if (strlen ((char *) c->args.secret) > 0)
2080  {
2081  l1 = strlen ((char *) c->args.secret);
2082  if (l0 + l1 < buflen)
2083  {
2084  md->secret = (uint8_t *) strcpy (buf + l0, (char *) c->args.secret);
2085  l0 += l1 + 1;
2086  }
2087  else
2088  err = MEMIF_ERR_NOBUF_DET;
2089  }
2090 
2091  md->role = (c->args.is_master) ? 0 : 1;
2092  md->mode = c->args.mode;
2093 
2094  l1 = strlen ((char *) c->args.socket_filename);
2095  if (l0 + l1 < buflen)
2096  {
2097  md->socket_filename =
2098  (uint8_t *) strcpy (buf + l0, (char *) c->args.socket_filename);
2099  l0 += l1 + 1;
2100  }
2101  else
2102  err = MEMIF_ERR_NOBUF_DET;
2103 
2104  l1 = strlen ((char *) c->remote_disconnect_string);
2105  if (l0 + l1 < buflen)
2106  {
2107  md->error =
2108  (uint8_t *) strcpy (buf + l0, (char *) c->remote_disconnect_string);
2109  l0 += l1 + 1;
2110  }
2111  else
2112  err = MEMIF_ERR_NOBUF_DET;
2113 
2114  md->regions_num = c->regions_num;
2115  l1 = sizeof (memif_region_details_t) * md->regions_num;
2116  if (l0 + l1 <= buflen)
2117  {
2118  md->regions = (memif_region_details_t *) (buf + l0);
2119  for (i = 0; i < md->regions_num; i++)
2120  {
2121  md->regions[i].index = i;
2122  md->regions[i].addr = c->regions[i].addr;
2123  md->regions[i].size = c->regions[i].region_size;
2124  md->regions[i].fd = c->regions[i].fd;
2125  md->regions[i].is_external = c->regions[i].is_external;
2126  }
2127  l0 += l1;
2128  }
2129  else
2130  err = MEMIF_ERR_NOBUF_DET;
2131 
2132  md->rx_queues_num =
2133  (c->args.is_master) ? c->run_args.num_s2m_rings : c->
2134  run_args.num_m2s_rings;
2135 
2136  l1 = sizeof (memif_queue_details_t) * md->rx_queues_num;
2137  if (l0 + l1 <= buflen)
2138  {
2139  md->rx_queues = (memif_queue_details_t *) (buf + l0);
2140  for (i = 0; i < md->rx_queues_num; i++)
2141  {
2142  md->rx_queues[i].region = c->rx_queues[i].region;
2143  md->rx_queues[i].qid = i;
2144  md->rx_queues[i].ring_size = (1 << c->rx_queues[i].log2_ring_size);
2145  md->rx_queues[i].flags = c->rx_queues[i].ring->flags;
2146  md->rx_queues[i].head = c->rx_queues[i].ring->head;
2147  md->rx_queues[i].tail = c->rx_queues[i].ring->tail;
2148  md->rx_queues[i].buffer_size = c->run_args.buffer_size;
2149  }
2150  l0 += l1;
2151  }
2152  else
2153  err = MEMIF_ERR_NOBUF_DET;
2154 
2155  md->tx_queues_num =
2156  (c->args.is_master) ? c->run_args.num_m2s_rings : c->
2157  run_args.num_s2m_rings;
2158 
2159  l1 = sizeof (memif_queue_details_t) * md->tx_queues_num;
2160  if (l0 + l1 <= buflen)
2161  {
2162  md->tx_queues = (memif_queue_details_t *) (buf + l0);
2163  for (i = 0; i < md->tx_queues_num; i++)
2164  {
2165  md->tx_queues[i].region = c->tx_queues[i].region;
2166  md->tx_queues[i].qid = i;
2167  md->tx_queues[i].ring_size = (1 << c->tx_queues[i].log2_ring_size);
2168  md->tx_queues[i].flags = c->tx_queues[i].ring->flags;
2169  md->tx_queues[i].head = c->tx_queues[i].ring->head;
2170  md->tx_queues[i].tail = c->tx_queues[i].ring->tail;
2171  md->tx_queues[i].buffer_size = c->run_args.buffer_size;
2172  }
2173  l0 += l1;
2174  }
2175  else
2176  err = MEMIF_ERR_NOBUF_DET;
2177 
2178  md->link_up_down = (c->fd > 0) ? 1 : 0;
2179 
2180  return err; /* 0 */
2181 }
2182 
2183 int
2184 memif_get_queue_efd (memif_conn_handle_t conn, uint16_t qid, int *efd)
2185 {
2187  *efd = -1;
2188  if (c == NULL)
2189  return MEMIF_ERR_NOCONN;
2190  if (c->fd < 0)
2191  return MEMIF_ERR_DISCONNECTED;
2192  uint8_t num =
2193  (c->args.is_master) ? c->run_args.num_s2m_rings : c->
2194  run_args.num_m2s_rings;
2195  if (qid >= num)
2196  return MEMIF_ERR_QID;
2197 
2198  *efd = c->rx_queues[qid].int_fd;
2199 
2200  return MEMIF_ERR_SUCCESS;
2201 }
2202 
2203 int
2205 {
2207  if (lm->control_list)
2208  lm->free (lm->control_list);
2209  lm->control_list = NULL;
2210  if (lm->interrupt_list)
2211  lm->free (lm->interrupt_list);
2212  lm->interrupt_list = NULL;
2213  if (lm->listener_list)
2214  lm->free (lm->listener_list);
2215  lm->listener_list = NULL;
2216  if (lm->pending_list)
2217  lm->free (lm->pending_list);
2218  lm->pending_list = NULL;
2219  if (poll_cancel_fd != -1)
2220  close (poll_cancel_fd);
2221 
2222  return MEMIF_ERR_SUCCESS; /* 0 */
2223 }
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:58
a
Definition: bitmap.h:538
uint8_t * inst_name
Definition: libmemif.h:365
uint8_t * secret
Definition: libmemif.h:370
static char memif_buf[MAX_ERRBUF_LEN]
Definition: main.c:72
Memif region details.
Definition: libmemif.h:334
int on_disconnect(memif_conn_handle_t conn, void *private_ctx)
Definition: main.c:186
void * ring
Definition: libmemif.h:287
#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:89
uint8_t num_m2s_rings
Definition: libmemif.h:260
Optimized string handling code, including c11-compliant "safe C library" variants.
#define NULL
Definition: clib.h:58
uint16_t buffer_size
Definition: libmemif.h:261
uint8_t secret[24]
Definition: libmemif.h:257
static void memif_msg_queue_free(libmemif_main_t *lm, memif_msg_queue_elt_t **e)
Definition: main.c:1145
uint32_t interface_id
Definition: libmemif.h:265
memif_list_elt_t * pending_list
int memif_conn_fd_read_ready(memif_connection_t *c)
Definition: socket.c:827
#define MEMIF_NAME_LEN
Definition: memif_private.h:34
uint32_t alloc_bufs
Definition: memif_private.h:92
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:1157
int( memif_control_fd_update_t)(int fd, uint8_t events)
Memif control file descriptor update (callback function)
Definition: libmemif.h:141
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
u8 data[128]
Definition: ipsec.api:248
uint16_t desc_index
Definition: libmemif.h:286
#define MEMIF_MEMORY_BARRIER()
Definition: main.c:65
uint8_t * remote_inst_name
Definition: libmemif.h:367
static memif_ring_t * memif_get_ring(memif_connection_t *conn, memif_ring_type_t type, uint16_t ring_num)
Definition: main.c:615
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:1820
#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:259
static void memif_realloc_register(memif_realloc_t *mr)
Definition: main.c:441
static void memif_alloc_register(memif_alloc_t *ma)
Definition: main.c:434
uint32_t len
Definition: libmemif.h:288
#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:2026
uint32_t cookie
Definition: memif.h:166
memif_interface_mode_t mode
Definition: libmemif.h:267
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:372
#define DBG_TX_BUF
Definition: main.c:181
uint16_t flags
Definition: memif.h:149
uint8_t link_up_down
Definition: libmemif.h:382
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:121
void *( memif_realloc_t)(void *ptr, size_t size)
Memif realloc.
Definition: libmemif.h:118
#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:290
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:123
uint8_t interface_name[32]
Definition: libmemif.h:266
uint8_t * error
Definition: libmemif.h:381
uword size
void * data
Definition: libmemif.h:294
memif_desc_t desc[0]
Definition: memif.h:173
uint16_t buffer_size
Definition: libmemif.h:324
uint8_t * socket_filename
Definition: libmemif.h:373
#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:94
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:630
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:160
int( memif_connection_update_t)(memif_conn_handle_t conn, void *private_ctx)
Memif connection status update (callback function)
Definition: libmemif.h:150
static int memif_add_epoll_fd(int fd, uint32_t events)
Definition: main.c:240
uint8_t is_master
Definition: libmemif.h:263
uint8_t rx_queues_num
Definition: libmemif.h:376
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:474
void *( memif_get_external_region_addr_t)(uint32_t size, int fd, void *private_ctx)
Get external region address.
Definition: libmemif.h:199
int memif_get_queue_efd(memif_conn_handle_t conn, uint16_t qid, int *efd)
Memif get queue event file descriptor
Definition: main.c:2184
#define MEMIF_BUFFER_FLAG_RX
states that buffer is from rx ring
Definition: libmemif.h:292
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:1615
#define MEMIF_DEFAULT_TX_QUEUES
Definition: private.h:24
uint32_t buffer_offset
Definition: memif_private.h:74
int add_list_elt(memif_list_elt_t *e, memif_list_elt_t **list, uint16_t *len)
Definition: main.c:319
#define MEMIF_DEFAULT_RECONNECT_PERIOD_SEC
Definition: memif_private.h:45
int memif_init_regions_and_queues(memif_connection_t *conn)
Definition: main.c:1576
void( memif_free_t)(void *ptr)
Memif allocator free.
Definition: libmemif.h:125
u8 len
Definition: ip_types.api:49
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:210
uint8_t flags
Definition: libmemif.h:293
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:374
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:1874
#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:1694
static int memif_add_region(libmemif_main_t *lm, memif_connection_t *conn, uint8_t has_buffers)
Definition: main.c:1427
memif_alloc_t * alloc
int memif_poll_event(int timeout)
Memif poll event.
Definition: main.c:1089
memif_queue_details_t * rx_queues
Definition: libmemif.h:378
u16 last_tail
Definition: private.h:124
int memif_read_ready(int fd)
Definition: socket.c:902
uint8_t role
Definition: libmemif.h:371
#define MEMIF_DEFAULT_BUFFER_SIZE
Definition: private.h:25
int memif_cleanup()
Memif cleanup.
Definition: main.c:2204
#define memif_min(a, b)
Definition: memif_private.h:55
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:648
#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:290
memif_ring_t * ring
Definition: private.h:118
uint8_t tx_queues_num
Definition: libmemif.h:377
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:187
size_t count
Definition: vapi.c:47
#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
#define MEMIF_DEFAULT_RECONNECT_PERIOD_NSEC
Definition: memif_private.h:46
void * memif_conn_handle_t
Memif connection handle pointer of type void, pointing to internal structure.
Definition: libmemif.h:102
memif_region_offset_t offset
Definition: memif.h:153
int memif_set_connection_request_timer(struct itimerspec timer)
Set connection request timer value.
Definition: main.c:455
int memif_control_fd_handler(int fd, uint8_t events)
Memif control file descriptor handler.
Definition: main.c:982
memif_del_external_region_t * del_external_region
uint8_t app_name[MEMIF_NAME_LEN]
#define MEMIF_DEFAULT_SOCKET_FILENAME
Definition: private.h:21
int memif_request_connection(memif_conn_handle_t c)
Send connection request.
Definition: main.c:915
uint8_t log2_ring_size
Definition: libmemif.h:262
typedef key
Definition: ipsec.api:244
uint32_t id
Definition: libmemif.h:369
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:1941
uint16_t pending_list_len
memif_rx_mode_t
Definition: libmemif.h:271
memif_list_elt_t * control_list
int memif_delete(memif_conn_handle_t *conn)
Memif delete.
Definition: main.c:1276
static int memif_init_queues(libmemif_main_t *lm, memif_connection_t *conn)
Definition: main.c:1477
memif_log2_ring_size_t log2_ring_size
Definition: private.h:119
Memif queue details.
Definition: libmemif.h:314
memif_region_details_t * regions
Definition: libmemif.h:375
uint16_t flags
Definition: memif.h:167
#define MEMIF_FD_EVENT_ERROR
inform libmemif that error occured on fd
Definition: libmemif.h:92
int memif_cancel_poll_event()
Definition: main.c:1130
uint16_t control_list_len
#define MEMIF_FD_EVENT_MOD
update events
Definition: libmemif.h:96
#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:379
uint32_t( memif_get_external_buffer_offset_t)(void *private_ctx)
Get external buffer offset (optional)
Definition: libmemif.h:177
uint8_t * if_name
Definition: libmemif.h:364
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:817
int memif_connect1(memif_connection_t *c)
Definition: main.c:1351
uint16_t index
Definition: main.c:74
libmemif_main_t libmemif_main
Definition: main.c:68
Memif buffer.
Definition: libmemif.h:284
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:90
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:120
uint16_t listener_list_len
#define MEMIF_COOKIE
Definition: memif.h:25
Memif connection arguments.
Definition: libmemif.h:254
uint16_t interface_list_len
Memif details.
Definition: libmemif.h:362
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:366
uint8_t * socket_filename
Definition: libmemif.h:256
void *( memif_alloc_t)(size_t size)
Memif allocator alloc.
Definition: libmemif.h:109
int memif_control_fd_update(int fd, uint8_t events)
Definition: main.c:301