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:
8 * http://www.apache.org/licenses/LICENSE-2.0
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 *------------------------------------------------------------------
21 #include <sys/types.h>
23 #include <sys/ioctl.h>
24 #include <sys/socket.h>
28 #include <sys/prctl.h>
34 #include <linux/icmp.h>
35 #include <arpa/inet.h>
37 #include <netinet/if_ether.h>
38 #include <net/if_arp.h>
39 #include <asm/byteorder.h>
44 #include <sys/eventfd.h>
45 #include <sys/timerfd.h>
46 #include <sys/epoll.h>
48 #include <linux/memfd.h>
50 /* memif protocol msg, ring and descriptor definitions */
54 /* socket messaging functions */
56 /* private structs and functions */
57 #include <memif_private.h>
59 #define ERRLIST_LEN 40
60 #define MAX_ERRBUF_LEN 256
63 #define MEMIF_MEMORY_BARRIER() __builtin_ia32_sfence ()
65 #define MEMIF_MEMORY_BARRIER() __sync_synchronize ()
66 #endif /* __x86_x64__ */
68 libmemif_main_t libmemif_main;
70 static char memif_buf[MAX_ERRBUF_LEN];
72 const char *memif_errlist[ERRLIST_LEN] = { /* MEMIF_ERR_SUCCESS */
74 /* MEMIF_ERR_SYSCALL */
75 "Unspecified syscall error (build with -DMEMIF_DBG or make debug).",
76 /* MEMIF_ERR_CONNREFUSED */
79 "Permission to resource denied.",
80 /* MEMIF_ERR_NO_FILE */
81 "Socket file does not exist",
82 /* MEMIF_ERR_FILE_LIMIT */
83 "System limit on total numer of open files reached.",
84 /* MEMIF_ERR_PROC_FILE_LIMIT */
85 "Per-process limit on total number of open files reached.",
86 /* MEMIF_ERR_ALREADY */
87 "Connection already requested.",
89 "File descriptor refers to file other than socket, or operation would block.",
90 /* MEMIF_ERR_BAD_FD */
91 "Bad file descriptor.",
94 /* MEMIF_ERR_INVAL_ARG */
96 /* MEMIF_ERR_NOCONN */
97 "Memif connection handle does not point to existing connection",
99 "Memif connection handle points to existing connection",
100 /* MEMIF_ERR_CB_FDUPDATE */
101 "Callback memif_control_fd_update_t returned error",
102 /* MEMIF_ERR_FILE_NOT_SOCK */
103 "File specified by socket filename exists and is not socket.",
104 /* MEMIF_ERR_NO_SHMFD */
105 "Missing shared memory file descriptor. (internal error)",
106 /* MEMIF_ERR_COOKIE */
107 "Invalid cookie on ring. (internal error)",
108 /* MEMIF_ERR_NOBUF_RING */
110 /* MEMIF_ERR_NOBUF */
111 "Not enough memif buffers. There are unreceived data in shared memory.",
112 /* MEMIF_ERR_NOBUF_DET */
113 "Not enough space for memif details in supplied buffer. String data might be malformed.",
114 /* MEMIF_ERR_INT_WRITE */
115 "Send interrupt error.",
116 /* MEMIF_ERR_MFMSG */
117 "Malformed message received on control channel.",
120 /* MEMIF_ERR_PROTO */
121 "Incompatible memory interface protocol version.",
123 "Unmatched interface id.",
124 /* MEMIF_ERR_ACCSLAVE */
125 "Slave cannot accept connection request.",
126 /* MEMIF_ERR_ALRCONN */
127 "Interface is already connected.",
130 /* MEMIF_ERR_SECRET */
132 /* MEMIF_ERR_NOSECRET */
134 /* MEMIF_ERR_MAXREG */
135 "Limit on total number of regions reached.",
136 /* MEMIF_ERR_MAXRING */
137 "Limit on total number of ring reached.",
138 /* MEMIF_ERR_NO_INTFD */
139 "Missing interrupt file descriptor. (internal error)",
140 /* MEMIF_ERR_DISCONNECT */
141 "Interface received disconnect request.",
142 /* MEMIF_ERR_DISCONNECTED */
143 "Interface is disconnected.",
144 /* MEMIF_ERR_UNKNOWN_MSG */
145 "Unknown message type received on control channel. (internal error)",
146 /* MEMIF_ERR_POLL_CANCEL */
147 "Memif event polling was canceled.",
148 /* MEMIF_ERR_MAX_RING */
149 "Maximum log2 ring size is 15",
150 /* MEMIF_ERR_PRIVHDR */
151 "Private headers not supported."
154 #define MEMIF_ERR_UNDEFINED "undefined error"
157 memif_strerror (int err_code)
159 if (err_code >= ERRLIST_LEN)
161 strlcpy (memif_buf, MEMIF_ERR_UNDEFINED, sizeof (memif_buf));
165 strlcpy (memif_buf, memif_errlist[err_code], sizeof (memif_buf));
173 return MEMIF_VERSION;
176 #define DBG_TX_BUF (0)
177 #define DBG_RX_BUF (1)
181 print_bytes (void *data, uint16_t len, uint8_t q)
184 printf ("\nTX:\n\t");
186 printf ("\nRX:\n\t");
188 for (i = 0; i < len; i++)
191 printf ("\n%d:\t", i);
192 printf ("%02X ", ((uint8_t *) (data))[i]);
196 #endif /* MEMIF_DBG_SHM */
199 memif_syscall_error_handler (int err_code)
201 DBG ("%s", strerror (err_code));
204 return MEMIF_ERR_SUCCESS;
205 if (err_code == EACCES)
206 return MEMIF_ERR_ACCES;
207 if (err_code == ENFILE)
208 return MEMIF_ERR_FILE_LIMIT;
209 if (err_code == EMFILE)
210 return MEMIF_ERR_PROC_FILE_LIMIT;
211 if (err_code == ENOMEM)
212 return MEMIF_ERR_NOMEM;
213 /* connection refused if master does not exist
214 this error would spam the user until master was created */
216 if (err_code == ECONNREFUSED)
217 return MEMIF_ERR_SUCCESS;
219 if (err_code == ECONNREFUSED)
220 return MEMIF_ERR_CONNREFUSED;
221 if (err_code == EALREADY)
222 return MEMIF_ERR_ALREADY;
223 if (err_code == EAGAIN)
224 return MEMIF_ERR_AGAIN;
225 if (err_code == EBADF)
226 return MEMIF_ERR_BAD_FD;
227 if (err_code == ENOENT)
228 return MEMIF_ERR_NO_FILE;
230 /* other syscall errors */
231 return MEMIF_ERR_SYSCALL;
236 get_libmemif_main (memif_socket_t * ms)
238 if (ms != NULL && ms->lm != NULL)
240 return &libmemif_main;
244 memif_add_epoll_fd (libmemif_main_t * lm, int fd, uint32_t events)
248 DBG ("invalid fd %d", fd);
251 struct epoll_event evt;
252 memset (&evt, 0, sizeof (evt));
255 if (epoll_ctl (lm->epfd, EPOLL_CTL_ADD, fd, &evt) < 0)
257 DBG ("epoll_ctl: %s fd %d", strerror (errno), fd);
260 DBG ("fd %d added to epoll", fd);
265 memif_mod_epoll_fd (libmemif_main_t * lm, int fd, uint32_t events)
269 DBG ("invalid fd %d", fd);
272 struct epoll_event evt;
273 memset (&evt, 0, sizeof (evt));
276 if (epoll_ctl (lm->epfd, EPOLL_CTL_MOD, fd, &evt) < 0)
278 DBG ("epoll_ctl: %s fd %d", strerror (errno), fd);
281 DBG ("fd %d modified on epoll", fd);
286 memif_del_epoll_fd (libmemif_main_t * lm, int fd)
290 DBG ("invalid fd %d", fd);
293 struct epoll_event evt;
294 memset (&evt, 0, sizeof (evt));
295 if (epoll_ctl (lm->epfd, EPOLL_CTL_DEL, fd, &evt) < 0)
297 DBG ("epoll_ctl: %s fd %d", strerror (errno), fd);
300 DBG ("fd %d removed from epoll", fd);
305 memif_control_fd_update (int fd, uint8_t events, void *private_ctx)
309 lm = (private_ctx == NULL) ? &libmemif_main : (libmemif_main_t *) private_ctx;
311 if (events & MEMIF_FD_EVENT_DEL)
312 return memif_del_epoll_fd (lm, fd);
315 if (events & MEMIF_FD_EVENT_READ)
317 if (events & MEMIF_FD_EVENT_WRITE)
320 if (events & MEMIF_FD_EVENT_MOD)
321 return memif_mod_epoll_fd (lm, fd, evt);
323 return memif_add_epoll_fd (lm, fd, evt);
327 add_list_elt (libmemif_main_t * lm, memif_list_elt_t * e,
328 memif_list_elt_t ** list, uint16_t * len)
330 memif_list_elt_t *tmp;
333 for (i = 0; i < *len; i++)
335 if ((*list)[i].data_struct == NULL)
337 (*list)[i].key = e->key;
338 (*list)[i].data_struct = e->data_struct;
343 tmp = lm->realloc (*list, sizeof (memif_list_elt_t) * *len * 2);
347 for (i = *len; i < *len * 2; i++)
350 tmp[i].data_struct = NULL;
353 tmp[*len].key = e->key;
354 tmp[*len].data_struct = e->data_struct;
363 get_list_elt (memif_list_elt_t ** e, memif_list_elt_t * list, uint16_t len,
373 for (i = 0; i < len; i++)
375 if (list[i].key == key)
385 /* does not free memory, only marks element as free */
387 free_list_elt (memif_list_elt_t * list, uint16_t len, int key)
390 for (i = 0; i < len; i++)
392 if (list[i].key == key)
395 list[i].data_struct = NULL;
404 free_list_elt_ctx (memif_list_elt_t * list, uint16_t len,
405 memif_connection_t * ctx)
408 for (i = 0; i < len; i++)
410 if (list[i].key == -1)
412 if (list[i].data_struct == ctx)
414 list[i].data_struct = NULL;
424 memif_control_fd_update_register (libmemif_main_t * lm,
425 memif_control_fd_update_t * cb)
427 lm->control_fd_update = cb;
431 memif_register_external_region (memif_add_external_region_t * ar,
432 memif_get_external_region_addr_t * gr,
433 memif_del_external_region_t * dr,
434 memif_get_external_buffer_offset_t * go)
436 libmemif_main_t *lm = &libmemif_main;
437 lm->add_external_region = ar;
438 lm->get_external_region_addr = gr;
439 lm->del_external_region = dr;
440 lm->get_external_buffer_offset = go;
444 memif_alloc_register (libmemif_main_t * lm, memif_alloc_t * ma)
450 memif_realloc_register (libmemif_main_t * lm, memif_realloc_t * mr)
456 memif_free_register (libmemif_main_t * lm, memif_free_t * mf)
462 memif_set_connection_request_timer (struct itimerspec timer)
464 libmemif_main_t *lm = &libmemif_main;
465 int err = MEMIF_ERR_SUCCESS;
469 /* overwrite timer, if already armed */
470 if (lm->disconn_slaves != 0)
472 if (timerfd_settime (lm->timerfd, 0, &lm->arm, NULL) < 0)
474 err = memif_syscall_error_handler (errno);
481 memif_per_thread_set_connection_request_timer (memif_per_thread_main_handle_t
483 struct itimerspec timer)
485 libmemif_main_t *lm = (libmemif_main_t *) pt_main;
486 int err = MEMIF_ERR_SUCCESS;
490 /* overwrite timer, if already armed */
491 if (lm->disconn_slaves != 0)
493 if (timerfd_settime (lm->timerfd, 0, &lm->arm, NULL) < 0)
495 err = memif_syscall_error_handler (errno);
502 memif_init (memif_control_fd_update_t * on_control_fd_update, char *app_name,
503 memif_alloc_t * memif_alloc, memif_realloc_t * memif_realloc,
504 memif_free_t * memif_free)
506 int err = MEMIF_ERR_SUCCESS; /* 0 */
507 libmemif_main_t *lm = &libmemif_main;
508 memset (lm, 0, sizeof (libmemif_main_t));
510 /* register custom memory management */
511 if (memif_alloc != NULL)
513 memif_alloc_register (lm, memif_alloc);
516 memif_alloc_register (lm, malloc);
518 if (memif_realloc != NULL)
520 memif_realloc_register (lm, memif_realloc);
523 memif_realloc_register (lm, realloc);
525 if (memif_free != NULL)
526 memif_free_register (lm, memif_free);
528 memif_free_register (lm, free);
530 if (app_name != NULL)
532 strlcpy ((char *) lm->app_name, app_name, sizeof (lm->app_name));
536 strlcpy ((char *) lm->app_name, MEMIF_DEFAULT_APP_NAME,
537 sizeof (lm->app_name));
540 lm->poll_cancel_fd = -1;
541 /* register control fd update callback */
542 if (on_control_fd_update != NULL)
543 memif_control_fd_update_register (lm, on_control_fd_update);
546 lm->epfd = epoll_create (1);
547 memif_control_fd_update_register (lm, memif_control_fd_update);
548 if ((lm->poll_cancel_fd = eventfd (0, EFD_NONBLOCK)) < 0)
551 DBG ("eventfd: %s", strerror (err));
552 return memif_syscall_error_handler (err);
554 lm->control_fd_update (lm->poll_cancel_fd, MEMIF_FD_EVENT_READ, lm->private_ctx);
555 DBG ("libmemif event polling initialized");
558 lm->control_list_len = 2;
559 lm->interrupt_list_len = 2;
560 lm->socket_list_len = 1;
561 lm->pending_list_len = 1;
564 lm->alloc (sizeof (memif_list_elt_t) * lm->control_list_len);
565 if (lm->control_list == NULL)
567 err = MEMIF_ERR_NOMEM;
571 lm->alloc (sizeof (memif_list_elt_t) * lm->interrupt_list_len);
572 if (lm->interrupt_list == NULL)
574 err = MEMIF_ERR_NOMEM;
578 lm->alloc (sizeof (memif_list_elt_t) * lm->socket_list_len);
579 if (lm->socket_list == NULL)
581 err = MEMIF_ERR_NOMEM;
585 lm->alloc (sizeof (memif_list_elt_t) * lm->pending_list_len);
586 if (lm->pending_list == NULL)
588 err = MEMIF_ERR_NOMEM;
593 for (i = 0; i < lm->control_list_len; i++)
595 lm->control_list[i].key = -1;
596 lm->control_list[i].data_struct = NULL;
598 for (i = 0; i < lm->interrupt_list_len; i++)
600 lm->interrupt_list[i].key = -1;
601 lm->interrupt_list[i].data_struct = NULL;
603 for (i = 0; i < lm->socket_list_len; i++)
605 lm->socket_list[i].key = -1;
606 lm->socket_list[i].data_struct = NULL;
608 for (i = 0; i < lm->pending_list_len; i++)
610 lm->pending_list[i].key = -1;
611 lm->pending_list[i].data_struct = NULL;
614 lm->disconn_slaves = 0;
616 lm->timerfd = timerfd_create (CLOCK_REALTIME, TFD_NONBLOCK);
619 err = memif_syscall_error_handler (errno);
623 lm->arm.it_value.tv_sec = MEMIF_DEFAULT_RECONNECT_PERIOD_SEC;
624 lm->arm.it_value.tv_nsec = MEMIF_DEFAULT_RECONNECT_PERIOD_NSEC;
625 lm->arm.it_interval.tv_sec = MEMIF_DEFAULT_RECONNECT_PERIOD_SEC;
626 lm->arm.it_interval.tv_nsec = MEMIF_DEFAULT_RECONNECT_PERIOD_NSEC;
628 if (lm->control_fd_update (lm->timerfd, MEMIF_FD_EVENT_READ, lm->private_ctx) < 0)
630 DBG ("callback type memif_control_fd_update_t error!");
631 err = MEMIF_ERR_CB_FDUPDATE;
635 /* Create default socket */
636 err = memif_create_socket ((memif_socket_handle_t *) &
638 MEMIF_DEFAULT_SOCKET_PATH, NULL);
639 if (err != MEMIF_ERR_SUCCESS)
650 memif_per_thread_init (memif_per_thread_main_handle_t * pt_main,
652 memif_control_fd_update_t * on_control_fd_update,
653 char *app_name, memif_alloc_t * memif_alloc,
654 memif_realloc_t * memif_realloc,
655 memif_free_t * memif_free)
657 memif_err_t err = MEMIF_ERR_SUCCESS;
661 /* Allocate unique libmemif main */
662 if (memif_alloc != NULL)
663 lm = memif_alloc (sizeof (libmemif_main_t));
665 lm = malloc (sizeof (libmemif_main_t));
668 return MEMIF_ERR_NOMEM;
670 memset (lm, 0, sizeof (libmemif_main_t));
672 /* register custom memory management */
673 if (memif_alloc != NULL)
675 memif_alloc_register (lm, memif_alloc);
678 memif_alloc_register (lm, malloc);
680 if (memif_realloc != NULL)
682 memif_realloc_register (lm, memif_realloc);
685 memif_realloc_register (lm, realloc);
687 if (memif_free != NULL)
688 memif_free_register (lm, memif_free);
690 memif_free_register (lm, free);
692 lm->private_ctx = private_ctx;
695 if (app_name != NULL)
697 strlcpy ((char *) lm->app_name, app_name, MEMIF_NAME_LEN);
701 strlcpy ((char *) lm->app_name, MEMIF_DEFAULT_APP_NAME,
702 sizeof (lm->app_name));
705 lm->poll_cancel_fd = -1;
706 /* register control fd update callback */
707 if (on_control_fd_update != NULL)
708 memif_control_fd_update_register (lm, on_control_fd_update);
711 /* private_ctx only used internally by memif_control_fd_update
712 * pointer to this libmemif main
714 lm->private_ctx = lm;
715 lm->epfd = epoll_create (1);
716 memif_control_fd_update_register (lm, memif_control_fd_update);
717 if ((lm->poll_cancel_fd = eventfd (0, EFD_NONBLOCK)) < 0)
720 DBG ("eventfd: %s", strerror (err));
721 return memif_syscall_error_handler (err);
723 lm->control_fd_update (lm->poll_cancel_fd, MEMIF_FD_EVENT_READ,
725 DBG ("libmemif event polling initialized");
728 /* Initialize lists */
729 lm->control_list_len = 2;
730 lm->interrupt_list_len = 2;
731 lm->socket_list_len = 1;
732 lm->pending_list_len = 1;
735 lm->alloc (sizeof (memif_list_elt_t) * lm->control_list_len);
736 if (lm->control_list == NULL)
738 err = MEMIF_ERR_NOMEM;
742 lm->alloc (sizeof (memif_list_elt_t) * lm->interrupt_list_len);
743 if (lm->interrupt_list == NULL)
745 err = MEMIF_ERR_NOMEM;
749 lm->alloc (sizeof (memif_list_elt_t) * lm->socket_list_len);
750 if (lm->socket_list == NULL)
752 err = MEMIF_ERR_NOMEM;
756 lm->alloc (sizeof (memif_list_elt_t) * lm->pending_list_len);
757 if (lm->pending_list == NULL)
759 err = MEMIF_ERR_NOMEM;
763 for (i = 0; i < lm->control_list_len; i++)
765 lm->control_list[i].key = -1;
766 lm->control_list[i].data_struct = NULL;
768 for (i = 0; i < lm->interrupt_list_len; i++)
770 lm->interrupt_list[i].key = -1;
771 lm->interrupt_list[i].data_struct = NULL;
773 for (i = 0; i < lm->socket_list_len; i++)
775 lm->socket_list[i].key = -1;
776 lm->socket_list[i].data_struct = NULL;
778 for (i = 0; i < lm->pending_list_len; i++)
780 lm->pending_list[i].key = -1;
781 lm->pending_list[i].data_struct = NULL;
784 /* Initialize autoconnect */
785 lm->disconn_slaves = 0;
787 lm->timerfd = timerfd_create (CLOCK_REALTIME, TFD_NONBLOCK);
790 err = memif_syscall_error_handler (errno);
794 lm->arm.it_value.tv_sec = MEMIF_DEFAULT_RECONNECT_PERIOD_SEC;
795 lm->arm.it_value.tv_nsec = MEMIF_DEFAULT_RECONNECT_PERIOD_NSEC;
796 lm->arm.it_interval.tv_sec = MEMIF_DEFAULT_RECONNECT_PERIOD_SEC;
797 lm->arm.it_interval.tv_nsec = MEMIF_DEFAULT_RECONNECT_PERIOD_NSEC;
799 if (lm->control_fd_update (lm->timerfd, MEMIF_FD_EVENT_READ,
800 lm->private_ctx) < 0)
802 DBG ("callback type memif_control_fd_update_t error!");
803 err = MEMIF_ERR_CB_FDUPDATE;
813 memif_per_thread_cleanup (pt_main);
817 static inline memif_ring_t *
818 memif_get_ring (memif_connection_t * conn, memif_ring_type_t type,
821 if (&conn->regions[0] == NULL)
823 void *p = conn->regions[0].addr;
825 sizeof (memif_ring_t) +
826 sizeof (memif_desc_t) * (1 << conn->run_args.log2_ring_size);
827 p += (ring_num + type * conn->run_args.num_s2m_rings) * ring_size;
829 return (memif_ring_t *) p;
833 memif_set_rx_mode (memif_conn_handle_t c, memif_rx_mode_t rx_mode,
836 memif_connection_t *conn = (memif_connection_t *) c;
838 return MEMIF_ERR_NOCONN;
840 (conn->args.is_master) ? conn->run_args.num_s2m_rings : conn->
841 run_args.num_m2s_rings;
843 return MEMIF_ERR_QID;
845 conn->rx_queues[qid].ring->flags = rx_mode;
846 DBG ("rx_mode flag: %u", conn->rx_queues[qid].ring->flags);
847 return MEMIF_ERR_SUCCESS;
851 memif_socket_start_listening (memif_socket_t * ms)
853 libmemif_main_t *lm = get_libmemif_main (ms);
854 memif_list_elt_t elt;
855 struct stat file_stat;
856 struct sockaddr_un un = { 0 };
858 int err = MEMIF_ERR_SUCCESS;
860 if (ms->type == MEMIF_SOCKET_TYPE_CLIENT)
861 return MEMIF_ERR_INVAL_ARG;
863 /* check if file exists */
864 if (stat ((char *) ms->filename, &file_stat) == 0)
866 if (S_ISSOCK (file_stat.st_mode))
867 unlink ((char *) ms->filename);
869 return memif_syscall_error_handler (errno);
872 ms->fd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
875 err = memif_syscall_error_handler (errno);
879 DBG ("socket %d created", ms->fd);
880 un.sun_family = AF_UNIX;
881 strlcpy ((char *) un.sun_path, (char *) ms->filename, sizeof (un.sun_path));
882 if (setsockopt (ms->fd, SOL_SOCKET, SO_PASSCRED, &on, sizeof (on)) < 0)
884 err = memif_syscall_error_handler (errno);
887 if (bind (ms->fd, (struct sockaddr *) &un, sizeof (un)) < 0)
889 err = memif_syscall_error_handler (errno);
892 if (listen (ms->fd, 1) < 0)
894 err = memif_syscall_error_handler (errno);
897 if (stat ((char *) ms->filename, &file_stat) < 0)
899 err = memif_syscall_error_handler (errno);
903 /* add socket to libmemif main */
905 elt.data_struct = ms;
906 add_list_elt (lm, &elt, &lm->socket_list, &lm->socket_list_len);
907 /* if lm->private_ctx == lm event polling is done by libmemif */
908 lm->control_fd_update (ms->fd, MEMIF_FD_EVENT_READ, lm->private_ctx);
910 ms->type = MEMIF_SOCKET_TYPE_LISTENER;
924 memif_create_socket (memif_socket_handle_t * sock, const char *filename,
927 libmemif_main_t *lm = &libmemif_main;
928 memif_socket_t *ms = (memif_socket_t *) * sock;
929 int i, err = MEMIF_ERR_SUCCESS;
931 for (i = 0; i < lm->socket_list_len; i++)
933 if ((ms = (memif_socket_t *) lm->socket_list[i].data_struct) != NULL)
935 if (strncmp ((char *) ms->filename, filename,
936 strlen ((char *) ms->filename)) == 0)
937 return MEMIF_ERR_INVAL_ARG;
941 /* allocate memif_socket_t */
943 ms = lm->alloc (sizeof (memif_socket_t));
946 err = MEMIF_ERR_NOMEM;
949 memset (ms, 0, sizeof (memif_socket_t));
951 ms->filename = lm->alloc (strlen (filename) + sizeof (char));
952 if (ms->filename == NULL)
954 err = MEMIF_ERR_NOMEM;
957 memset (ms->filename, 0, strlen (filename) + sizeof (char));
958 strlcpy ((char *) ms->filename, filename, sizeof (ms->filename));
960 ms->type = MEMIF_SOCKET_TYPE_NONE;
962 ms->interface_list_len = 1;
964 lm->alloc (sizeof (memif_list_elt_t) * ms->interface_list_len);
965 if (ms->interface_list == NULL)
967 err = MEMIF_ERR_NOMEM;
970 ms->interface_list[0].key = -1;
971 ms->interface_list[0].data_struct = NULL;
980 if (ms->filename != NULL)
982 lm->free (ms->filename);
990 if (ms->interface_list != NULL)
992 lm->free (ms->interface_list);
993 ms->interface_list = NULL;
994 ms->interface_list_len = 0;
1003 memif_per_thread_create_socket (memif_per_thread_main_handle_t pt_main,
1004 memif_socket_handle_t * sock,
1005 const char *filename, void *private_ctx)
1007 libmemif_main_t *lm = (libmemif_main_t *) pt_main;
1008 memif_socket_t *ms = (memif_socket_t *) * sock;
1009 int i, err = MEMIF_ERR_SUCCESS;
1012 return MEMIF_ERR_INVAL_ARG;
1014 for (i = 0; i < lm->socket_list_len; i++)
1016 if ((ms = (memif_socket_t *) lm->socket_list[i].data_struct) != NULL)
1018 if (strncmp ((char *) ms->filename, filename,
1019 strlen ((char *) ms->filename)) == 0)
1020 return MEMIF_ERR_INVAL_ARG;
1024 /* allocate memif_socket_t */
1026 ms = lm->alloc (sizeof (memif_socket_t));
1029 err = MEMIF_ERR_NOMEM;
1032 memset (ms, 0, sizeof (memif_socket_t));
1035 ms->filename = lm->alloc (strlen (filename) + sizeof (char));
1036 if (ms->filename == NULL)
1038 err = MEMIF_ERR_NOMEM;
1041 memset (ms->filename, 0, strlen (filename) + sizeof (char));
1042 strlcpy ((char *) ms->filename, filename, sizeof (ms->filename));
1044 ms->type = MEMIF_SOCKET_TYPE_NONE;
1046 ms->interface_list_len = 1;
1047 ms->interface_list =
1048 lm->alloc (sizeof (memif_list_elt_t) * ms->interface_list_len);
1049 if (ms->interface_list == NULL)
1051 err = MEMIF_ERR_NOMEM;
1054 ms->interface_list[0].key = -1;
1055 ms->interface_list[0].data_struct = NULL;
1064 if (ms->filename != NULL)
1066 lm->free (ms->filename);
1067 ms->filename = NULL;
1074 if (ms->interface_list != NULL)
1076 lm->free (ms->interface_list);
1077 ms->interface_list = NULL;
1078 ms->interface_list_len = 0;
1087 memif_create (memif_conn_handle_t * c, memif_conn_args_t * args,
1088 memif_connection_update_t * on_connect,
1089 memif_connection_update_t * on_disconnect,
1090 memif_interrupt_t * on_interrupt, void *private_ctx)
1092 libmemif_main_t *lm = get_libmemif_main (args->socket);
1094 memif_list_elt_t elt;
1095 memif_connection_t *conn = (memif_connection_t *) * c;
1100 DBG ("This handle already points to existing memif.");
1101 return MEMIF_ERR_CONN;
1104 conn = (memif_connection_t *) lm->alloc (sizeof (memif_connection_t));
1107 err = MEMIF_ERR_NOMEM;
1110 memset (conn, 0, sizeof (memif_connection_t));
1112 conn->args.interface_id = args->interface_id;
1114 if (args->log2_ring_size == 0)
1115 args->log2_ring_size = MEMIF_DEFAULT_LOG2_RING_SIZE;
1116 else if (args->log2_ring_size > MEMIF_MAX_LOG2_RING_SIZE)
1118 err = MEMIF_ERR_MAX_RING;
1121 if (args->buffer_size == 0)
1122 args->buffer_size = MEMIF_DEFAULT_BUFFER_SIZE;
1123 if (args->num_s2m_rings == 0)
1124 args->num_s2m_rings = MEMIF_DEFAULT_TX_QUEUES;
1125 if (args->num_m2s_rings == 0)
1126 args->num_m2s_rings = MEMIF_DEFAULT_RX_QUEUES;
1128 conn->args.num_s2m_rings = args->num_s2m_rings;
1129 conn->args.num_m2s_rings = args->num_m2s_rings;
1130 conn->args.buffer_size = args->buffer_size;
1131 conn->args.log2_ring_size = args->log2_ring_size;
1132 conn->args.is_master = args->is_master;
1133 conn->args.mode = args->mode;
1134 conn->msg_queue = NULL;
1135 conn->regions = NULL;
1136 conn->tx_queues = NULL;
1137 conn->rx_queues = NULL;
1139 conn->on_connect = on_connect;
1140 conn->on_disconnect = on_disconnect;
1141 conn->on_interrupt = on_interrupt;
1142 conn->private_ctx = private_ctx;
1143 memset (&conn->run_args, 0, sizeof (memif_conn_run_args_t));
1145 strlcpy ((char *) conn->args.interface_name, (char *) args->interface_name,
1146 sizeof (conn->args.interface_name));
1148 if ((strlen ((char *) args->secret)) > 0)
1149 strlcpy ((char *) conn->args.secret, (char *) args->secret,
1150 sizeof (conn->args.secret));
1152 if (args->socket != NULL)
1153 conn->args.socket = args->socket;
1154 else if (lm->default_socket != NULL)
1155 conn->args.socket = lm->default_socket;
1158 err = MEMIF_ERR_INVAL_ARG;
1162 ms = (memif_socket_t *) conn->args.socket;
1164 if ((conn->args.is_master && ms->type == MEMIF_SOCKET_TYPE_CLIENT) ||
1165 (!conn->args.is_master && ms->type == MEMIF_SOCKET_TYPE_LISTENER))
1167 err = MEMIF_ERR_INVAL_ARG;
1171 elt.key = conn->args.interface_id;
1172 elt.data_struct = conn;
1173 add_list_elt (lm, &elt, &ms->interface_list, &ms->interface_list_len);
1176 if (conn->args.is_master)
1178 if (ms->type == MEMIF_SOCKET_TYPE_NONE)
1180 err = memif_socket_start_listening (ms);
1181 if (err != MEMIF_ERR_SUCCESS)
1188 elt.data_struct = conn;
1190 add_list_elt (lm, &elt, &lm->control_list,
1191 &lm->control_list_len)) < 0)
1193 err = MEMIF_ERR_NOMEM;
1197 conn->index = index;
1199 /* try connecting to master */
1200 err = memif_request_connection (conn);
1201 if ((err != MEMIF_ERR_SUCCESS) && (lm->disconn_slaves == 0))
1203 /* connection failed, arm reconnect timer (if not armed) */
1204 if (timerfd_settime (lm->timerfd, 0, &lm->arm, NULL) < 0)
1206 err = memif_syscall_error_handler (errno);
1210 lm->disconn_slaves++;
1225 memif_request_connection (memif_conn_handle_t c)
1227 memif_connection_t *conn = (memif_connection_t *) c;
1228 libmemif_main_t *lm;
1230 int err = MEMIF_ERR_SUCCESS;
1232 struct sockaddr_un sun;
1235 return MEMIF_ERR_NOCONN;
1237 ms = (memif_socket_t *) conn->args.socket;
1238 lm = get_libmemif_main (ms);
1241 if (conn->args.is_master || ms->type == MEMIF_SOCKET_TYPE_LISTENER)
1242 return MEMIF_ERR_INVAL_ARG;
1244 return MEMIF_ERR_ALRCONN;
1246 sockfd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
1249 err = memif_syscall_error_handler (errno);
1253 sun.sun_family = AF_UNIX;
1255 strlcpy (sun.sun_path, (char *) ms->filename, sizeof (sun.sun_path));
1257 if (connect (sockfd, (struct sockaddr *) &sun,
1258 sizeof (struct sockaddr_un)) == 0)
1261 conn->read_fn = memif_conn_fd_read_ready;
1262 conn->write_fn = memif_conn_fd_write_ready;
1263 conn->error_fn = memif_conn_fd_error;
1265 lm->control_list[conn->index].key = conn->fd;
1266 lm->control_fd_update (sockfd,
1267 MEMIF_FD_EVENT_READ |
1268 MEMIF_FD_EVENT_WRITE, lm->private_ctx);
1270 lm->disconn_slaves--;
1271 if (lm->disconn_slaves == 0)
1273 if (timerfd_settime (lm->timerfd, 0, &lm->disarm, NULL) < 0)
1275 err = memif_syscall_error_handler (errno);
1282 err = memif_syscall_error_handler (errno);
1283 strcpy ((char *) conn->remote_disconnect_string, memif_strerror (err));
1287 ms->type = MEMIF_SOCKET_TYPE_CLIENT;
1299 memif_control_fd_handler (int fd, uint8_t events)
1301 int i, err = MEMIF_ERR_SUCCESS; /* 0 */
1303 memif_list_elt_t *e = NULL;
1304 memif_connection_t *conn;
1305 libmemif_main_t *lm = &libmemif_main;
1306 if (fd == lm->timerfd)
1310 size = read (fd, &b, sizeof (b));
1315 for (i = 0; i < lm->control_list_len; i++)
1317 if ((lm->control_list[i].key < 0)
1318 && (lm->control_list[i].data_struct != NULL))
1320 conn = lm->control_list[i].data_struct;
1321 if (conn->args.is_master)
1323 err = memif_request_connection (conn);
1324 if (err != MEMIF_ERR_SUCCESS)
1325 DBG ("memif_request_connection: %s", memif_strerror (err));
1331 get_list_elt (&e, lm->interrupt_list, lm->interrupt_list_len, fd);
1334 if (((memif_connection_t *) e->data_struct)->on_interrupt != NULL)
1337 (((memif_connection_t *) e->data_struct)->
1338 args.is_master) ? ((memif_connection_t *) e->
1339 data_struct)->run_args.
1340 num_s2m_rings : ((memif_connection_t *) e->data_struct)->
1341 run_args.num_m2s_rings;
1342 for (i = 0; i < num; i++)
1344 if (((memif_connection_t *) e->data_struct)->
1345 rx_queues[i].int_fd == fd)
1347 ((memif_connection_t *) e->data_struct)->
1348 on_interrupt ((void *) e->data_struct,
1349 ((memif_connection_t *) e->
1350 data_struct)->private_ctx, i);
1351 return MEMIF_ERR_SUCCESS;
1355 return MEMIF_ERR_SUCCESS;
1357 get_list_elt (&e, lm->socket_list, lm->socket_list_len, fd);
1359 && ((memif_socket_t *) e->data_struct)->type ==
1360 MEMIF_SOCKET_TYPE_LISTENER)
1363 memif_conn_fd_accept_ready ((memif_socket_t *) e->data_struct);
1367 get_list_elt (&e, lm->pending_list, lm->pending_list_len, fd);
1370 err = memif_read_ready (lm, fd);
1374 get_list_elt (&e, lm->control_list, lm->control_list_len, fd);
1377 if (events & MEMIF_FD_EVENT_READ)
1380 ((memif_connection_t *) e->data_struct)->
1381 read_fn (e->data_struct);
1382 if (err != MEMIF_ERR_SUCCESS)
1385 if (events & MEMIF_FD_EVENT_WRITE)
1388 ((memif_connection_t *) e->data_struct)->
1389 write_fn (e->data_struct);
1390 if (err != MEMIF_ERR_SUCCESS)
1393 if (events & MEMIF_FD_EVENT_ERROR)
1396 ((memif_connection_t *) e->data_struct)->
1397 error_fn (e->data_struct);
1398 if (err != MEMIF_ERR_SUCCESS)
1404 return MEMIF_ERR_SUCCESS; /* 0 */
1411 memif_per_thread_control_fd_handler (memif_per_thread_main_handle_t pt_main,
1412 int fd, uint8_t events)
1414 int i, err = MEMIF_ERR_SUCCESS; /* 0 */
1416 memif_list_elt_t *e = NULL;
1417 memif_connection_t *conn;
1418 libmemif_main_t *lm = (libmemif_main_t *) pt_main;
1420 if (fd == lm->timerfd)
1424 size = read (fd, &b, sizeof (b));
1429 for (i = 0; i < lm->control_list_len; i++)
1431 if ((lm->control_list[i].key < 0)
1432 && (lm->control_list[i].data_struct != NULL))
1434 conn = lm->control_list[i].data_struct;
1435 if (conn->args.is_master)
1437 err = memif_request_connection (conn);
1438 if (err != MEMIF_ERR_SUCCESS)
1439 DBG ("memif_request_connection: %s", memif_strerror (err));
1445 get_list_elt (&e, lm->interrupt_list, lm->interrupt_list_len, fd);
1448 if (((memif_connection_t *) e->data_struct)->on_interrupt != NULL)
1451 (((memif_connection_t *) e->data_struct)->
1452 args.is_master) ? ((memif_connection_t *) e->
1453 data_struct)->run_args.
1454 num_s2m_rings : ((memif_connection_t *) e->data_struct)->
1455 run_args.num_m2s_rings;
1456 for (i = 0; i < num; i++)
1458 if (((memif_connection_t *) e->data_struct)->
1459 rx_queues[i].int_fd == fd)
1461 ((memif_connection_t *) e->data_struct)->
1462 on_interrupt ((void *) e->data_struct,
1463 ((memif_connection_t *) e->
1464 data_struct)->private_ctx, i);
1465 return MEMIF_ERR_SUCCESS;
1469 return MEMIF_ERR_SUCCESS;
1471 get_list_elt (&e, lm->socket_list, lm->socket_list_len, fd);
1473 && ((memif_socket_t *) e->data_struct)->type ==
1474 MEMIF_SOCKET_TYPE_LISTENER)
1477 memif_conn_fd_accept_ready ((memif_socket_t *) e->data_struct);
1481 get_list_elt (&e, lm->pending_list, lm->pending_list_len, fd);
1484 err = memif_read_ready (lm, fd);
1488 get_list_elt (&e, lm->control_list, lm->control_list_len, fd);
1491 if (events & MEMIF_FD_EVENT_READ)
1494 ((memif_connection_t *) e->data_struct)->
1495 read_fn (e->data_struct);
1496 if (err != MEMIF_ERR_SUCCESS)
1499 if (events & MEMIF_FD_EVENT_WRITE)
1502 ((memif_connection_t *) e->data_struct)->
1503 write_fn (e->data_struct);
1504 if (err != MEMIF_ERR_SUCCESS)
1507 if (events & MEMIF_FD_EVENT_ERROR)
1510 ((memif_connection_t *) e->data_struct)->
1511 error_fn (e->data_struct);
1512 if (err != MEMIF_ERR_SUCCESS)
1518 return MEMIF_ERR_SUCCESS; /* 0 */
1525 memif_poll_event (int timeout)
1527 libmemif_main_t *lm = &libmemif_main;
1528 struct epoll_event evt;
1529 int en = 0, err = MEMIF_ERR_SUCCESS; /* 0 */
1530 uint32_t events = 0;
1531 uint64_t counter = 0;
1533 memset (&evt, 0, sizeof (evt));
1534 evt.events = EPOLLIN | EPOLLOUT;
1536 sigemptyset (&sigset);
1537 en = epoll_pwait (lm->epfd, &evt, 1, timeout, &sigset);
1541 DBG ("epoll_pwait: %s", strerror (err));
1542 return memif_syscall_error_handler (err);
1546 if (evt.data.fd == lm->poll_cancel_fd)
1548 r = read (evt.data.fd, &counter, sizeof (counter));
1550 return MEMIF_ERR_DISCONNECTED;
1552 return MEMIF_ERR_POLL_CANCEL;
1554 if (evt.events & EPOLLIN)
1555 events |= MEMIF_FD_EVENT_READ;
1556 if (evt.events & EPOLLOUT)
1557 events |= MEMIF_FD_EVENT_WRITE;
1558 if (evt.events & EPOLLERR)
1559 events |= MEMIF_FD_EVENT_ERROR;
1560 err = memif_control_fd_handler (evt.data.fd, events);
1567 memif_per_thread_poll_event (memif_per_thread_main_handle_t pt_main,
1570 libmemif_main_t *lm = (libmemif_main_t *) pt_main;
1571 struct epoll_event evt;
1572 int en = 0, err = MEMIF_ERR_SUCCESS; /* 0 */
1573 uint32_t events = 0;
1574 uint64_t counter = 0;
1576 memset (&evt, 0, sizeof (evt));
1577 evt.events = EPOLLIN | EPOLLOUT;
1579 sigemptyset (&sigset);
1580 en = epoll_pwait (lm->epfd, &evt, 1, timeout, &sigset);
1584 DBG ("epoll_pwait: %s", strerror (err));
1585 return memif_syscall_error_handler (err);
1589 if (evt.data.fd == lm->poll_cancel_fd)
1591 r = read (evt.data.fd, &counter, sizeof (counter));
1593 return MEMIF_ERR_DISCONNECTED;
1595 return MEMIF_ERR_POLL_CANCEL;
1597 if (evt.events & EPOLLIN)
1598 events |= MEMIF_FD_EVENT_READ;
1599 if (evt.events & EPOLLOUT)
1600 events |= MEMIF_FD_EVENT_WRITE;
1601 if (evt.events & EPOLLERR)
1602 events |= MEMIF_FD_EVENT_ERROR;
1603 err = memif_control_fd_handler (evt.data.fd, events);
1610 memif_cancel_poll_event ()
1612 libmemif_main_t *lm = &libmemif_main;
1613 uint64_t counter = 1;
1616 if (lm->poll_cancel_fd == -1)
1618 w = write (lm->poll_cancel_fd, &counter, sizeof (counter));
1619 if (w < sizeof (counter))
1620 return MEMIF_ERR_INT_WRITE;
1626 memif_per_thread_cancel_poll_event (memif_per_thread_main_handle_t pt_main)
1628 libmemif_main_t *lm = (libmemif_main_t *) pt_main;
1629 uint64_t counter = 1;
1633 return MEMIF_ERR_INVAL_ARG;
1635 if (lm->poll_cancel_fd == -1)
1637 w = write (lm->poll_cancel_fd, &counter, sizeof (counter));
1638 if (w < sizeof (counter))
1639 return MEMIF_ERR_INT_WRITE;
1645 memif_msg_queue_free (libmemif_main_t * lm, memif_msg_queue_elt_t ** e)
1649 memif_msg_queue_free (lm, &(*e)->next);
1655 /* send disconnect msg and close interface */
1657 memif_disconnect_internal (memif_connection_t * c)
1659 int err = MEMIF_ERR_SUCCESS, i; /* 0 */
1661 libmemif_main_t *lm;
1662 memif_list_elt_t *e;
1666 DBG ("no connection");
1667 return MEMIF_ERR_NOCONN;
1670 lm = get_libmemif_main (c->args.socket);
1672 c->on_disconnect ((void *) c, c->private_ctx);
1676 memif_msg_send_disconnect (c->fd, (uint8_t *) "interface deleted", 0);
1677 lm->control_fd_update (c->fd, MEMIF_FD_EVENT_DEL, lm->private_ctx);
1680 get_list_elt (&e, lm->control_list, lm->control_list_len, c->fd);
1683 if (c->args.is_master)
1684 free_list_elt (lm->control_list, lm->control_list_len, c->fd);
1685 e->key = c->fd = -1;
1688 if (c->tx_queues != NULL)
1690 for (i = 0; i < c->tx_queues_num; i++)
1692 mq = &c->tx_queues[i];
1697 free_list_elt (lm->interrupt_list, lm->interrupt_list_len,
1702 lm->free (c->tx_queues);
1703 c->tx_queues = NULL;
1705 c->tx_queues_num = 0;
1707 if (c->rx_queues != NULL)
1709 for (i = 0; i < c->rx_queues_num; i++)
1711 mq = &c->rx_queues[i];
1716 if (c->on_interrupt != NULL)
1717 lm->control_fd_update (mq->int_fd, MEMIF_FD_EVENT_DEL,
1721 free_list_elt (lm->interrupt_list, lm->interrupt_list_len,
1726 lm->free (c->rx_queues);
1727 c->rx_queues = NULL;
1729 c->rx_queues_num = 0;
1731 for (i = 0; i < c->regions_num; i++)
1733 if (&c->regions[i] == NULL)
1735 if (c->regions[i].is_external != 0)
1737 lm->del_external_region (c->regions[i].addr,
1738 c->regions[i].region_size,
1739 c->regions[i].fd, c->private_ctx);
1743 if (munmap (c->regions[i].addr, c->regions[i].region_size) < 0)
1744 return memif_syscall_error_handler (errno);
1745 if (c->regions[i].fd > 0)
1746 close (c->regions[i].fd);
1747 c->regions[i].fd = -1;
1750 lm->free (c->regions);
1754 memset (&c->run_args, 0, sizeof (memif_conn_run_args_t));
1756 memif_msg_queue_free (lm, &c->msg_queue);
1758 if (!(c->args.is_master))
1760 if (lm->disconn_slaves == 0)
1762 if (timerfd_settime (lm->timerfd, 0, &lm->arm, NULL) < 0)
1764 err = memif_syscall_error_handler (errno);
1765 DBG ("timerfd_settime: arm");
1768 lm->disconn_slaves++;
1775 memif_get_socket_filename (memif_socket_handle_t sock)
1777 memif_socket_t *ms = (memif_socket_t *) sock;
1782 return (char *) ms->filename;
1786 memif_delete_socket (memif_socket_handle_t * sock)
1788 memif_socket_t *ms = (memif_socket_t *) * sock;
1789 libmemif_main_t *lm;
1791 /* check if socket is in use */
1792 if (ms == NULL || ms->use_count > 0)
1793 return MEMIF_ERR_INVAL_ARG;
1795 lm = get_libmemif_main (ms);
1797 lm->free (ms->interface_list);
1798 ms->interface_list = NULL;
1799 lm->free (ms->filename);
1800 ms->filename = NULL;
1804 return MEMIF_ERR_SUCCESS;
1808 memif_delete (memif_conn_handle_t * conn)
1810 memif_connection_t *c = (memif_connection_t *) * conn;
1811 libmemif_main_t *lm;
1812 memif_socket_t *ms = NULL;
1813 int err = MEMIF_ERR_SUCCESS;
1817 DBG ("no connection");
1818 return MEMIF_ERR_NOCONN;
1823 DBG ("DISCONNECTING");
1824 err = memif_disconnect_internal (c);
1825 if (err == MEMIF_ERR_NOCONN)
1829 lm = get_libmemif_main (c->args.socket);
1831 free_list_elt_ctx (lm->control_list, lm->control_list_len, c);
1833 ms = (memif_socket_t *) c->args.socket;
1835 free_list_elt (ms->interface_list, ms->interface_list_len,
1836 c->args.interface_id);
1837 if (ms->use_count <= 0)
1839 /* stop listening on this socket */
1840 if (ms->type == MEMIF_SOCKET_TYPE_LISTENER)
1842 lm->control_fd_update (ms->fd, MEMIF_FD_EVENT_DEL, lm->private_ctx);
1843 free_list_elt (lm->socket_list, lm->socket_list_len, ms->fd);
1847 /* socket not in use */
1848 ms->type = MEMIF_SOCKET_TYPE_NONE;
1851 if (!c->args.is_master)
1853 lm->disconn_slaves--;
1854 if (lm->disconn_slaves <= 0)
1856 if (timerfd_settime (lm->timerfd, 0, &lm->disarm, NULL) < 0)
1858 err = memif_syscall_error_handler (errno);
1859 DBG ("timerfd_settime: disarm");
1872 memif_connect1 (memif_connection_t * c)
1874 libmemif_main_t *lm;
1880 return MEMIF_ERR_INVAL_ARG;
1882 lm = get_libmemif_main (c->args.socket);
1884 for (i = 0; i < c->regions_num; i++)
1886 mr = &c->regions[i];
1891 if (mr->is_external)
1893 if (lm->get_external_region_addr == NULL)
1894 return MEMIF_ERR_INVAL_ARG;
1896 lm->get_external_region_addr (mr->region_size, mr->fd,
1902 return MEMIF_ERR_NO_SHMFD;
1905 mmap (NULL, mr->region_size, PROT_READ | PROT_WRITE,
1906 MAP_SHARED, mr->fd, 0)) == MAP_FAILED)
1908 return memif_syscall_error_handler (errno);
1915 for (i = 0; i < c->rx_queues_num; i++)
1917 mq = &c->rx_queues[i];
1920 mq->ring = c->regions[mq->region].addr + mq->offset;
1921 if (mq->ring->cookie != MEMIF_COOKIE)
1923 DBG ("wrong cookie on rx ring %u", i);
1924 return MEMIF_ERR_COOKIE;
1926 mq->ring->head = mq->ring->tail = mq->last_head = mq->next_buf = 0;
1930 for (i = 0; i < c->tx_queues_num; i++)
1932 mq = &c->tx_queues[i];
1935 mq->ring = c->regions[mq->region].addr + mq->offset;
1936 if (mq->ring->cookie != MEMIF_COOKIE)
1938 DBG ("wrong cookie on tx ring %u", i);
1939 return MEMIF_ERR_COOKIE;
1941 mq->ring->head = mq->ring->tail = mq->last_head = mq->next_buf = 0;
1945 lm->control_fd_update (c->fd, MEMIF_FD_EVENT_READ | MEMIF_FD_EVENT_MOD,
1952 memif_add_region (libmemif_main_t * lm, memif_connection_t * conn,
1953 uint8_t has_buffers)
1958 lm->realloc (conn->regions,
1959 sizeof (memif_region_t) * ++conn->regions_num);
1961 return MEMIF_ERR_NOMEM;
1964 r = &conn->regions[conn->regions_num - 1];
1965 memset (r, 0, sizeof (memif_region_t));
1967 if (has_buffers != 0)
1969 r->buffer_offset = 0;
1974 (conn->run_args.num_s2m_rings +
1975 conn->run_args.num_m2s_rings) * (sizeof (memif_ring_t) +
1976 sizeof (memif_desc_t) *
1978 run_args.log2_ring_size));
1981 r->region_size = (has_buffers == 0) ? r->buffer_offset : r->buffer_offset +
1982 conn->run_args.buffer_size * (1 << conn->run_args.log2_ring_size) *
1983 (conn->run_args.num_s2m_rings + conn->run_args.num_m2s_rings);
1985 if ((r->fd = memfd_create ("memif region 0", MFD_ALLOW_SEALING)) == -1)
1986 return memif_syscall_error_handler (errno);
1988 if ((fcntl (r->fd, F_ADD_SEALS, F_SEAL_SHRINK)) == -1)
1989 return memif_syscall_error_handler (errno);
1991 if ((ftruncate (r->fd, r->region_size)) == -1)
1992 return memif_syscall_error_handler (errno);
1994 if ((r->addr = mmap (NULL, r->region_size, PROT_READ | PROT_WRITE,
1995 MAP_SHARED, r->fd, 0)) == MAP_FAILED)
1996 return memif_syscall_error_handler (errno);
1998 return MEMIF_ERR_SUCCESS;
2002 memif_init_queues (libmemif_main_t * lm, memif_connection_t * conn)
2007 for (i = 0; i < conn->run_args.num_s2m_rings; i++)
2009 ring = memif_get_ring (conn, MEMIF_RING_S2M, i);
2010 DBG ("RING: %p I: %d", ring, i);
2011 ring->head = ring->tail = 0;
2012 ring->cookie = MEMIF_COOKIE;
2014 for (j = 0; j < (1 << conn->run_args.log2_ring_size); j++)
2016 uint16_t slot = i * (1 << conn->run_args.log2_ring_size) + j;
2017 ring->desc[j].region = 1;
2018 ring->desc[j].offset =
2019 conn->regions[1].buffer_offset +
2020 (uint32_t) (slot * conn->run_args.buffer_size);
2021 ring->desc[j].length = conn->run_args.buffer_size;
2024 for (i = 0; i < conn->run_args.num_m2s_rings; i++)
2026 ring = memif_get_ring (conn, MEMIF_RING_M2S, i);
2027 DBG ("RING: %p I: %d", ring, i);
2028 ring->head = ring->tail = 0;
2029 ring->cookie = MEMIF_COOKIE;
2031 for (j = 0; j < (1 << conn->run_args.log2_ring_size); j++)
2033 uint16_t slot = (i + conn->run_args.num_s2m_rings) *
2034 (1 << conn->run_args.log2_ring_size) + j;
2035 ring->desc[j].region = 1;
2036 ring->desc[j].offset =
2037 conn->regions[1].buffer_offset +
2038 (uint32_t) (slot * conn->run_args.buffer_size);
2039 ring->desc[j].length = conn->run_args.buffer_size;
2043 DBG ("alloc: %p", lm->alloc);
2044 DBG ("size: %lu", sizeof (memif_queue_t) * conn->run_args.num_s2m_rings);
2046 (memif_queue_t *) lm->alloc (sizeof (memif_queue_t) *
2047 conn->run_args.num_s2m_rings);
2049 return MEMIF_ERR_NOMEM;
2053 for (x = 0; x < conn->run_args.num_s2m_rings; x++)
2055 if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
2056 return memif_syscall_error_handler (errno);
2057 e.key = mq[x].int_fd;
2058 e.data_struct = conn;
2059 add_list_elt (lm, &e, &lm->interrupt_list, &lm->interrupt_list_len);
2061 mq[x].ring = memif_get_ring (conn, MEMIF_RING_S2M, x);
2062 DBG ("RING: %p I: %d", mq[x].ring, x);
2063 mq[x].log2_ring_size = conn->run_args.log2_ring_size;
2066 (void *) mq[x].ring - (void *) conn->regions[mq->region].addr;
2067 mq[x].last_head = mq[x].last_tail = 0;
2070 conn->tx_queues = mq;
2071 conn->tx_queues_num = conn->run_args.num_s2m_rings;
2074 (memif_queue_t *) lm->alloc (sizeof (memif_queue_t) *
2075 conn->run_args.num_m2s_rings);
2077 return MEMIF_ERR_NOMEM;
2079 for (x = 0; x < conn->run_args.num_m2s_rings; x++)
2081 if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
2082 return memif_syscall_error_handler (errno);
2083 e.key = mq[x].int_fd;
2084 e.data_struct = conn;
2085 add_list_elt (lm, &e, &lm->interrupt_list, &lm->interrupt_list_len);
2087 mq[x].ring = memif_get_ring (conn, MEMIF_RING_M2S, x);
2088 DBG ("RING: %p I: %d", mq[x].ring, x);
2089 mq[x].log2_ring_size = conn->run_args.log2_ring_size;
2092 (void *) mq[x].ring - (void *) conn->regions[mq->region].addr;
2093 mq[x].last_head = mq[x].last_tail = 0;
2096 conn->rx_queues = mq;
2097 conn->rx_queues_num = conn->run_args.num_m2s_rings;
2099 return MEMIF_ERR_SUCCESS;
2103 memif_init_regions_and_queues (memif_connection_t * conn)
2106 libmemif_main_t *lm;
2109 return MEMIF_ERR_INVAL_ARG;
2111 lm = get_libmemif_main (conn->args.socket);
2113 /* region 0. rings */
2114 memif_add_region (lm, conn, /* has_buffers */ 0);
2116 /* region 1. buffers */
2117 if (lm->add_external_region)
2120 (memif_region_t *) lm->realloc (conn->regions,
2121 sizeof (memif_region_t) *
2122 ++conn->regions_num);
2124 return MEMIF_ERR_NOMEM;
2127 conn->regions[1].region_size =
2128 conn->run_args.buffer_size * (1 << conn->run_args.log2_ring_size) *
2129 (conn->run_args.num_s2m_rings + conn->run_args.num_m2s_rings);
2130 conn->regions[1].buffer_offset = 0;
2131 lm->add_external_region (&conn->regions[1].addr,
2132 conn->regions[1].region_size,
2133 &conn->regions[1].fd, conn->private_ctx);
2134 conn->regions[1].is_external = 1;
2138 memif_add_region (lm, conn, 1);
2141 memif_init_queues (lm, conn);
2147 memif_set_next_free_buffer (memif_conn_handle_t conn, uint16_t qid,
2148 memif_buffer_t *buf)
2150 memif_connection_t *c = (memif_connection_t *) conn;
2151 if (EXPECT_FALSE (c == NULL))
2152 return MEMIF_ERR_NOCONN;
2153 if (EXPECT_FALSE (qid >= c->tx_queues_num))
2154 return MEMIF_ERR_QID;
2155 if (EXPECT_FALSE (buf == NULL))
2156 return MEMIF_ERR_INVAL_ARG;
2158 uint16_t ring_size, ns;
2159 memif_queue_t *mq = &c->tx_queues[qid];
2160 memif_ring_t *ring = mq->ring;
2162 ring_size = (1 << mq->log2_ring_size);
2163 if (c->args.is_master)
2164 ns = ring->head - mq->next_buf;
2166 ns = ring_size - mq->next_buf + ring->tail;
2168 if ((mq->next_buf - buf->desc_index) > ns)
2169 return MEMIF_ERR_INVAL_ARG;
2171 mq->next_buf = buf->desc_index;
2173 return MEMIF_ERR_SUCCESS;
2177 memif_buffer_enq_at_idx_internal (memif_queue_t *from_q, memif_queue_t *to_q,
2178 memif_buffer_t *buf, uint16_t slot)
2180 uint16_t from_mask = (1 << from_q->log2_ring_size) - 1;
2181 uint16_t to_mask = (1 << to_q->log2_ring_size) - 1;
2182 memif_desc_t *from_d, *to_d, tmp_d;
2184 /* Get the descriptors */
2185 from_d = &from_q->ring->desc[buf->desc_index & from_mask];
2186 to_d = &to_q->ring->desc[slot & to_mask];
2188 /* Swap descriptors */
2193 /* Update descriptor index and queue for clients buffer */
2194 buf->desc_index = slot;
2199 memif_buffer_requeue (memif_conn_handle_t conn, memif_buffer_t *buf_a,
2200 memif_buffer_t *buf_b)
2202 memif_connection_t *c = (memif_connection_t *) conn;
2203 if (EXPECT_FALSE (c == NULL))
2204 return MEMIF_ERR_NOCONN;
2205 if (EXPECT_FALSE (c->args.is_master))
2206 return MEMIF_ERR_INVAL_ARG;
2207 if ((buf_a == NULL) || (buf_b == NULL))
2208 return MEMIF_ERR_INVAL_ARG;
2211 /* store buf_a information */
2212 uint16_t index_a = buf_a->desc_index;
2213 memif_queue_t *mq_a = buf_a->queue;
2215 /* swap buffers, buf_a was updated with new desc_index and queue */
2216 memif_buffer_enq_at_idx_internal ((memif_queue_t *) buf_a->queue,
2217 (memif_queue_t *) buf_b->queue, buf_a,
2220 /* update buf_b desc_index and queue */
2221 buf_b->desc_index = index_a;
2222 buf_b->queue = mq_a;
2224 return MEMIF_ERR_SUCCESS;
2228 memif_buffer_enq_tx (memif_conn_handle_t conn, uint16_t qid,
2229 memif_buffer_t * bufs, uint16_t count,
2230 uint16_t * count_out)
2232 memif_connection_t *c = (memif_connection_t *) conn;
2233 if (EXPECT_FALSE (c == NULL))
2234 return MEMIF_ERR_NOCONN;
2235 if (EXPECT_FALSE (c->fd < 0))
2236 return MEMIF_ERR_DISCONNECTED;
2237 if (EXPECT_FALSE (qid >= c->tx_queues_num))
2238 return MEMIF_ERR_QID;
2239 if (EXPECT_FALSE (!count_out))
2240 return MEMIF_ERR_INVAL_ARG;
2241 if (EXPECT_FALSE (c->args.is_master))
2242 return MEMIF_ERR_INVAL_ARG;
2244 memif_queue_t *mq = &c->tx_queues[qid];
2245 memif_ring_t *ring = mq->ring;
2247 uint16_t mask = (1 << mq->log2_ring_size) - 1;
2251 int err = MEMIF_ERR_SUCCESS; /* 0 */
2254 ring_size = (1 << mq->log2_ring_size);
2256 /* can only be called by slave */
2257 ns = ring_size - mq->next_buf + ring->tail;
2263 /* Swaps the descriptors, updates next_buf pointer and updates client
2266 memif_buffer_enq_at_idx_internal ((memif_queue_t *) b0->queue, mq, b0,
2269 mq->next_buf++; /* mark the buffer as allocated */
2276 DBG ("allocated: %u/%u bufs. Next buffer pointer %d", *count_out, count,
2281 DBG ("ring buffer full! qid: %u", qid);
2282 err = MEMIF_ERR_NOBUF_RING;
2289 memif_buffer_alloc (memif_conn_handle_t conn, uint16_t qid,
2290 memif_buffer_t * bufs, uint16_t count,
2291 uint16_t * count_out, uint16_t size)
2293 memif_connection_t *c = (memif_connection_t *) conn;
2294 if (EXPECT_FALSE (c == NULL))
2295 return MEMIF_ERR_NOCONN;
2296 if (EXPECT_FALSE (c->fd < 0))
2297 return MEMIF_ERR_DISCONNECTED;
2299 (c->args.is_master) ? c->run_args.num_m2s_rings : c->
2300 run_args.num_s2m_rings;
2301 if (EXPECT_FALSE (qid >= num))
2302 return MEMIF_ERR_QID;
2303 if (EXPECT_FALSE (!count_out))
2304 return MEMIF_ERR_INVAL_ARG;
2306 libmemif_main_t *lm = get_libmemif_main (c->args.socket);
2307 memif_queue_t *mq = &c->tx_queues[qid];
2308 memif_ring_t *ring = mq->ring;
2310 uint16_t mask = (1 << mq->log2_ring_size) - 1;
2311 uint32_t offset_mask = c->run_args.buffer_size - 1;
2314 int err = MEMIF_ERR_SUCCESS; /* 0 */
2315 uint16_t dst_left, src_left;
2316 uint16_t saved_count;
2317 uint16_t saved_next_buf;
2318 memif_buffer_t *saved_b;
2321 ring_size = (1 << mq->log2_ring_size);
2323 if (c->args.is_master)
2324 ns = ring->head - mq->next_buf;
2326 ns = ring_size - mq->next_buf + ring->tail;
2330 b0 = (bufs + *count_out);
2333 saved_count = count;
2334 saved_next_buf = mq->next_buf;
2336 b0->desc_index = mq->next_buf;
2337 ring->desc[mq->next_buf & mask].flags = 0;
2339 /* slave can produce buffer with original length */
2340 dst_left = (c->args.is_master) ? ring->desc[mq->next_buf & mask].length :
2341 c->run_args.buffer_size;
2346 if (EXPECT_FALSE (dst_left == 0))
2354 ring->desc[b0->desc_index & mask].flags |=
2355 MEMIF_DESC_FLAG_NEXT;
2356 b0->flags |= MEMIF_BUFFER_FLAG_NEXT;
2358 b0 = (bufs + *count_out);
2359 b0->desc_index = mq->next_buf;
2360 dst_left = (c->args.is_master) ?
2361 ring->desc[mq->next_buf & mask].length :
2362 c->run_args.buffer_size;
2363 ring->desc[mq->next_buf & mask].flags = 0;
2367 /* rollback allocated chain buffers */
2368 memset (saved_b, 0, sizeof (memif_buffer_t)
2369 * (saved_count - count + 1));
2370 *count_out -= saved_count - count;
2371 mq->next_buf = saved_next_buf;
2375 b0->len = memif_min (dst_left, src_left);
2377 /* slave resets buffer offset */
2378 if (c->args.is_master == 0)
2380 memif_desc_t *d = &ring->desc[mq->next_buf & mask];
2381 if (lm->get_external_buffer_offset)
2382 d->offset = lm->get_external_buffer_offset (c->private_ctx);
2384 d->offset = d->offset - (d->offset & offset_mask);
2386 b0->data = memif_get_buffer (c, ring, mq->next_buf & mask);
2388 src_left -= b0->len;
2389 dst_left -= b0->len;
2400 DBG ("allocated: %u/%u bufs. Next buffer pointer %d", *count_out, count,
2405 DBG ("ring buffer full! qid: %u", qid);
2406 err = MEMIF_ERR_NOBUF_RING;
2413 memif_refill_queue (memif_conn_handle_t conn, uint16_t qid, uint16_t count,
2416 memif_connection_t *c = (memif_connection_t *) conn;
2417 if (EXPECT_FALSE (c == NULL))
2418 return MEMIF_ERR_NOCONN;
2419 if (EXPECT_FALSE (c->fd < 0))
2420 return MEMIF_ERR_DISCONNECTED;
2422 (c->args.is_master) ? c->run_args.num_s2m_rings : c->
2423 run_args.num_m2s_rings;
2424 if (EXPECT_FALSE (qid >= num))
2425 return MEMIF_ERR_QID;
2426 libmemif_main_t *lm = get_libmemif_main (c->args.socket);
2427 memif_queue_t *mq = &c->rx_queues[qid];
2428 memif_ring_t *ring = mq->ring;
2429 uint16_t mask = (1 << mq->log2_ring_size) - 1;
2430 uint32_t offset_mask = c->run_args.buffer_size - 1;
2431 uint16_t slot, counter = 0;
2433 if (c->args.is_master)
2435 MEMIF_MEMORY_BARRIER ();
2437 (ring->tail + count <=
2438 mq->last_head) ? ring->tail + count : mq->last_head;
2439 return MEMIF_ERR_SUCCESS;
2442 uint16_t head = ring->head;
2444 uint16_t ns = (1 << mq->log2_ring_size) - head + mq->last_tail;
2445 count = (count < ns) ? count : ns;
2448 while (counter < count)
2450 d = &ring->desc[slot & mask];
2452 d->length = c->run_args.buffer_size - headroom;
2453 if (lm->get_external_buffer_offset)
2454 d->offset = lm->get_external_buffer_offset (c->private_ctx);
2456 d->offset = d->offset - (d->offset & offset_mask) + headroom;
2461 MEMIF_MEMORY_BARRIER ();
2464 return MEMIF_ERR_SUCCESS; /* 0 */
2468 memif_tx_burst (memif_conn_handle_t conn, uint16_t qid,
2469 memif_buffer_t * bufs, uint16_t count, uint16_t * tx)
2471 memif_connection_t *c = (memif_connection_t *) conn;
2472 if (EXPECT_FALSE (c == NULL))
2473 return MEMIF_ERR_NOCONN;
2474 if (EXPECT_FALSE (c->fd < 0))
2475 return MEMIF_ERR_DISCONNECTED;
2477 (c->args.is_master) ? c->run_args.num_m2s_rings : c->
2478 run_args.num_s2m_rings;
2479 if (EXPECT_FALSE (qid >= num))
2480 return MEMIF_ERR_QID;
2481 if (EXPECT_FALSE (!tx))
2482 return MEMIF_ERR_INVAL_ARG;
2484 memif_queue_t *mq = &c->tx_queues[qid];
2485 memif_ring_t *ring = mq->ring;
2486 uint16_t mask = (1 << mq->log2_ring_size) - 1;
2487 uint32_t offset_mask = c->run_args.buffer_size - 1;
2490 int64_t data_offset;
2492 int err = MEMIF_ERR_SUCCESS;
2494 if (EXPECT_FALSE (count == 0))
2495 return MEMIF_ERR_SUCCESS;
2498 if (c->args.is_master)
2506 /* set error to MEMIF_ERR_INVAL_ARG and finish the sending process
2508 if ((b0->desc_index & mask) != (index & mask))
2510 err = MEMIF_ERR_INVAL_ARG;
2513 d = &ring->desc[b0->desc_index & mask];
2514 d->length = b0->len;
2515 if (!c->args.is_master)
2518 d->offset = d->offset - (d->offset & offset_mask);
2519 // calculate offset from user data
2520 data_offset = b0->data - (d->offset + c->regions[d->region].addr);
2521 if (data_offset != 0)
2523 /* verify data offset */
2524 if ((data_offset < 0) ||
2525 (data_offset > (d->offset + offset_mask)))
2527 printf ("%ld\n", data_offset);
2528 err = MEMIF_ERR_INVAL_ARG;
2531 d->offset += data_offset;
2535 #ifdef MEMIF_DBG_SHM
2536 printf ("offset: %-6d\n", ring->desc[b0->desc_index & mask].offset);
2537 printf ("data: %p\n",
2538 memif_get_buffer (c, ring, b0->desc_index & mask));
2539 printf ("index: %u\n", b0->desc_index);
2540 print_bytes (memif_get_buffer (c, ring, b0->desc_index & mask),
2541 ring->desc[b0->desc_index & mask].length, DBG_TX_BUF);
2542 #endif /* MEMIF_DBG_SHM */
2550 MEMIF_MEMORY_BARRIER ();
2551 if (c->args.is_master)
2552 ring->tail = b0->desc_index + 1;
2554 ring->head = b0->desc_index + 1;
2556 if ((ring->flags & MEMIF_RING_FLAG_MASK_INT) == 0)
2559 int r = write (mq->int_fd, &a, sizeof (a));
2561 return MEMIF_ERR_INT_WRITE;
2568 memif_rx_burst (memif_conn_handle_t conn, uint16_t qid,
2569 memif_buffer_t * bufs, uint16_t count, uint16_t * rx)
2571 memif_connection_t *c = (memif_connection_t *) conn;
2572 if (EXPECT_FALSE (c == NULL))
2573 return MEMIF_ERR_NOCONN;
2574 if (EXPECT_FALSE (c->fd < 0))
2575 return MEMIF_ERR_DISCONNECTED;
2577 (c->args.is_master) ? c->run_args.num_s2m_rings : c->
2578 run_args.num_m2s_rings;
2579 if (EXPECT_FALSE (qid >= num))
2580 return MEMIF_ERR_QID;
2581 if (EXPECT_FALSE (!rx))
2582 return MEMIF_ERR_INVAL_ARG;
2584 memif_queue_t *mq = &c->rx_queues[qid];
2585 memif_ring_t *ring = mq->ring;
2586 uint16_t cur_slot, last_slot;
2588 uint16_t mask = (1 << mq->log2_ring_size) - 1;
2595 cur_slot = (c->args.is_master) ? mq->last_head : mq->last_tail;
2596 last_slot = (c->args.is_master) ? ring->head : ring->tail;
2597 if (cur_slot == last_slot)
2599 r = read (mq->int_fd, &b, sizeof (b));
2600 if (EXPECT_FALSE ((r == -1) && (errno != EAGAIN)))
2601 return memif_syscall_error_handler (errno);
2603 return MEMIF_ERR_SUCCESS;
2606 ns = last_slot - cur_slot;
2612 b0->desc_index = cur_slot;
2613 b0->data = memif_get_buffer (c, ring, cur_slot & mask);
2614 b0->len = ring->desc[cur_slot & mask].length;
2615 /* slave resets buffer length */
2616 if (c->args.is_master == 0)
2618 ring->desc[cur_slot & mask].length = c->run_args.buffer_size;
2621 if (ring->desc[cur_slot & mask].flags & MEMIF_DESC_FLAG_NEXT)
2623 b0->flags |= MEMIF_BUFFER_FLAG_NEXT;
2624 ring->desc[cur_slot & mask].flags &= ~MEMIF_DESC_FLAG_NEXT;
2628 #ifdef MEMIF_DBG_SHM
2629 printf ("data: %p\n", b0->data);
2630 printf ("index: %u\n", b0->desc_index);
2631 printf ("queue: %p\n", b0->queue);
2632 print_bytes (b0->data, b0->len, DBG_RX_BUF);
2633 #endif /* MEMIF_DBG_SHM */
2641 if (c->args.is_master)
2642 mq->last_head = cur_slot;
2644 mq->last_tail = cur_slot;
2648 DBG ("not enough buffers!");
2649 return MEMIF_ERR_NOBUF;
2652 r = read (mq->int_fd, &b, sizeof (b));
2653 if (EXPECT_FALSE ((r == -1) && (errno != EAGAIN)))
2654 return memif_syscall_error_handler (errno);
2656 return MEMIF_ERR_SUCCESS; /* 0 */
2660 memif_get_details (memif_conn_handle_t conn, memif_details_t * md,
2661 char *buf, ssize_t buflen)
2663 memif_connection_t *c = (memif_connection_t *) conn;
2664 libmemif_main_t *lm;
2666 int err = MEMIF_ERR_SUCCESS, i;
2670 return MEMIF_ERR_NOCONN;
2672 ms = (memif_socket_t *) c->args.socket;
2673 lm = get_libmemif_main (ms);
2675 l1 = strlen ((char *) c->args.interface_name);
2676 if (l0 + l1 < buflen)
2679 (uint8_t *) strcpy (buf + l0, (char *) c->args.interface_name);
2683 err = MEMIF_ERR_NOBUF_DET;
2685 l1 = strlen ((char *) lm->app_name);
2686 if (l0 + l1 < buflen)
2688 md->inst_name = (uint8_t *) strcpy (buf + l0, (char *) lm->app_name);
2692 err = MEMIF_ERR_NOBUF_DET;
2694 l1 = strlen ((char *) c->remote_if_name);
2695 if (l0 + l1 < buflen)
2697 md->remote_if_name =
2698 (uint8_t *) strcpy (buf + l0, (char *) c->remote_if_name);
2702 err = MEMIF_ERR_NOBUF_DET;
2704 l1 = strlen ((char *) c->remote_name);
2705 if (l0 + l1 < buflen)
2707 md->remote_inst_name =
2708 (uint8_t *) strcpy (buf + l0, (char *) c->remote_name);
2712 err = MEMIF_ERR_NOBUF_DET;
2714 md->id = c->args.interface_id;
2716 if (strlen ((char *) c->args.secret) > 0)
2718 l1 = strlen ((char *) c->args.secret);
2719 if (l0 + l1 < buflen)
2721 md->secret = (uint8_t *) strcpy (buf + l0, (char *) c->args.secret);
2725 err = MEMIF_ERR_NOBUF_DET;
2728 md->role = (c->args.is_master) ? 0 : 1;
2729 md->mode = c->args.mode;
2731 l1 = strlen ((char *) ms->filename);
2732 if (l0 + l1 < buflen)
2734 md->socket_filename =
2735 (uint8_t *) strcpy (buf + l0, (char *) ms->filename);
2739 err = MEMIF_ERR_NOBUF_DET;
2741 l1 = strlen ((char *) c->remote_disconnect_string);
2742 if (l0 + l1 < buflen)
2745 (uint8_t *) strcpy (buf + l0, (char *) c->remote_disconnect_string);
2749 err = MEMIF_ERR_NOBUF_DET;
2751 md->regions_num = c->regions_num;
2752 l1 = sizeof (memif_region_details_t) * md->regions_num;
2753 if (l0 + l1 <= buflen)
2755 md->regions = (memif_region_details_t *) (buf + l0);
2756 for (i = 0; i < md->regions_num; i++)
2758 md->regions[i].index = i;
2759 md->regions[i].addr = c->regions[i].addr;
2760 md->regions[i].size = c->regions[i].region_size;
2761 md->regions[i].fd = c->regions[i].fd;
2762 md->regions[i].is_external = c->regions[i].is_external;
2767 err = MEMIF_ERR_NOBUF_DET;
2770 (c->args.is_master) ? c->run_args.num_s2m_rings : c->
2771 run_args.num_m2s_rings;
2773 l1 = sizeof (memif_queue_details_t) * md->rx_queues_num;
2774 if (l0 + l1 <= buflen)
2776 md->rx_queues = (memif_queue_details_t *) (buf + l0);
2777 for (i = 0; i < md->rx_queues_num; i++)
2779 md->rx_queues[i].region = c->rx_queues[i].region;
2780 md->rx_queues[i].qid = i;
2781 md->rx_queues[i].ring_size = (1 << c->rx_queues[i].log2_ring_size);
2782 md->rx_queues[i].flags = c->rx_queues[i].ring->flags;
2783 md->rx_queues[i].head = c->rx_queues[i].ring->head;
2784 md->rx_queues[i].tail = c->rx_queues[i].ring->tail;
2785 md->rx_queues[i].buffer_size = c->run_args.buffer_size;
2790 err = MEMIF_ERR_NOBUF_DET;
2793 (c->args.is_master) ? c->run_args.num_m2s_rings : c->
2794 run_args.num_s2m_rings;
2796 l1 = sizeof (memif_queue_details_t) * md->tx_queues_num;
2797 if (l0 + l1 <= buflen)
2799 md->tx_queues = (memif_queue_details_t *) (buf + l0);
2800 for (i = 0; i < md->tx_queues_num; i++)
2802 md->tx_queues[i].region = c->tx_queues[i].region;
2803 md->tx_queues[i].qid = i;
2804 md->tx_queues[i].ring_size = (1 << c->tx_queues[i].log2_ring_size);
2805 md->tx_queues[i].flags = c->tx_queues[i].ring->flags;
2806 md->tx_queues[i].head = c->tx_queues[i].ring->head;
2807 md->tx_queues[i].tail = c->tx_queues[i].ring->tail;
2808 md->tx_queues[i].buffer_size = c->run_args.buffer_size;
2813 err = MEMIF_ERR_NOBUF_DET;
2815 md->link_up_down = (c->fd > 0) ? 1 : 0;
2821 memif_get_queue_efd (memif_conn_handle_t conn, uint16_t qid, int *efd)
2823 memif_connection_t *c = (memif_connection_t *) conn;
2828 return MEMIF_ERR_NOCONN;
2830 return MEMIF_ERR_DISCONNECTED;
2833 (c->args.is_master) ? c->run_args.num_s2m_rings : c->
2834 run_args.num_m2s_rings;
2836 return MEMIF_ERR_QID;
2838 *efd = c->rx_queues[qid].int_fd;
2840 return MEMIF_ERR_SUCCESS;
2846 libmemif_main_t *lm = &libmemif_main;
2849 err = memif_delete_socket ((memif_socket_handle_t *) & lm->default_socket);
2850 if (err != MEMIF_ERR_SUCCESS)
2853 if (lm->control_list)
2854 lm->free (lm->control_list);
2855 lm->control_list = NULL;
2856 if (lm->interrupt_list)
2857 lm->free (lm->interrupt_list);
2858 lm->interrupt_list = NULL;
2859 if (lm->socket_list)
2860 lm->free (lm->socket_list);
2861 lm->socket_list = NULL;
2862 if (lm->pending_list)
2863 lm->free (lm->pending_list);
2864 lm->pending_list = NULL;
2865 if (lm->poll_cancel_fd != -1)
2866 close (lm->poll_cancel_fd);
2868 return MEMIF_ERR_SUCCESS; /* 0 */
2872 memif_per_thread_cleanup (memif_per_thread_main_handle_t * pt_main)
2874 libmemif_main_t *lm = (libmemif_main_t *) * pt_main;
2877 return MEMIF_ERR_INVAL_ARG;
2879 /* No default socket in case of per thread */
2881 if (lm->control_list)
2882 lm->free (lm->control_list);
2883 lm->control_list = NULL;
2884 if (lm->interrupt_list)
2885 lm->free (lm->interrupt_list);
2886 lm->interrupt_list = NULL;
2887 if (lm->socket_list)
2888 lm->free (lm->socket_list);
2889 lm->socket_list = NULL;
2890 if (lm->pending_list)
2891 lm->free (lm->pending_list);
2892 lm->pending_list = NULL;
2893 if (lm->poll_cancel_fd != -1)
2894 close (lm->poll_cancel_fd);
2900 return MEMIF_ERR_SUCCESS; /* 0 */