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