20 #include <sys/types.h> 22 #include <sys/ioctl.h> 23 #include <sys/socket.h> 27 #include <sys/prctl.h> 33 #include <linux/icmp.h> 34 #include <arpa/inet.h> 36 #include <netinet/if_ether.h> 37 #include <net/if_arp.h> 38 #include <asm/byteorder.h> 43 #include <sys/eventfd.h> 44 #include <sys/timerfd.h> 45 #include <sys/epoll.h> 57 #define ERRLIST_LEN 36 58 #define MAX_ERRBUF_LEN 256 61 #define MEMIF_MEMORY_BARRIER() __builtin_ia32_sfence () 63 #define MEMIF_MEORY_BARRIER() __sync_synchronize () 74 "Unspecified syscall error (build with -DMEMIF_DBG or make debug).",
76 "Permission to resoure denied.",
78 "Socket file does not exist",
80 "System limit on total numer of open files reached.",
82 "Per-process limit on total number of open files reached.",
84 "Connection already requested.",
86 "File descriptor refers to file other than socket, or operation would block.",
88 "Bad file descriptor.",
94 "Memif connection handle does not point to existing conenction",
96 "Memif connection handle points to existing connection",
98 "Callback memif_control_fd_update_t returned error",
100 "File specified by socket filename exists and is not socket.",
102 "Missing shared memory file descriptor. (internal error)",
104 "Invalid cookie on ring. (internal error)",
108 "Not enough memif buffers. There are unreceived data in shared memory.",
110 "Not enough space for memif details in suplied buffer. String data might be malformed.",
112 "Send interrupt error.",
114 "Malformed message received on control channel.",
118 "Incompatible memory interface protocol version.",
120 "Unmatched interface id.",
122 "Slave cannot accept connection reqest.",
124 "Interface is already connected.",
132 "Limit on total number of regions reached.",
134 "Limit on total number of ring reached.",
136 "Missing interrupt file descriptor. (internal error)",
138 "Interface received disconnect request.",
140 "Interface is disconnected.",
142 "Unknown message type received on control channel. (internal error)" 145 #define MEMIF_ERR_UNDEFINED "undefined error" 164 #define DBG_TX_BUF (0) 165 #define DBG_RX_BUF (1) 169 print_bytes (
void *data, uint16_t len, uint8_t q)
172 printf (
"\nTX:\n\t");
174 printf (
"\nRX:\n\t");
176 for (i = 0; i < len; i++)
179 printf (
"\n%d:\t", i);
180 printf (
"%02X ", ((uint8_t *) (data))[i]);
189 DBG_UNIX (
"%s", strerror (err_code));
193 if (err_code == EACCES)
195 if (err_code == ENFILE)
197 if (err_code == EMFILE)
199 if (err_code == ENOMEM)
203 if (err_code == ECONNREFUSED)
205 if (err_code == EALREADY)
207 if (err_code == EAGAIN)
209 if (err_code == EBADF)
211 if (err_code == ENOENT)
223 DBG (
"invalid fd %d", fd);
226 struct epoll_event evt;
227 memset (&evt, 0,
sizeof (evt));
230 if (epoll_ctl (
memif_epfd, EPOLL_CTL_ADD, fd, &evt) < 0)
232 DBG (
"epoll_ctl: %s fd %d", strerror (errno), fd);
235 DBG (
"fd %d added to epoll", fd);
244 DBG (
"invalid fd %d", fd);
247 struct epoll_event evt;
248 memset (&evt, 0,
sizeof (evt));
251 if (epoll_ctl (
memif_epfd, EPOLL_CTL_MOD, fd, &evt) < 0)
253 DBG (
"epoll_ctl: %s fd %d", strerror (errno), fd);
256 DBG (
"fd %d moddified on epoll", fd);
265 DBG (
"invalid fd %d", fd);
268 struct epoll_event evt;
269 memset (&evt, 0,
sizeof (evt));
270 if (epoll_ctl (
memif_epfd, EPOLL_CTL_DEL, fd, &evt) < 0)
272 DBG (
"epoll_ctl: %s fd %d", strerror (errno), fd);
275 DBG (
"fd %d removed from epoll", fd);
303 for (i = 0; i < *len; i++)
305 if ((*list)[i].data_struct ==
NULL)
307 (*list)[
i].key = e->
key;
317 for (i = *len; i < *len * 2; i++)
342 for (i = 0; i < len; i++)
344 if (list[i].key == key)
359 for (i = 0; i < len; i++)
361 if (list[i].key == key)
377 for (i = 0; i < len; i++)
379 if (list[i].key == -1)
381 if (list[i].data_struct == ctx)
407 lm->
app_name = malloc (strlen (app_name) +
sizeof (
char));
408 memset (lm->
app_name, 0, strlen (app_name) +
sizeof (
char));
409 strncpy ((
char *) lm->
app_name, app_name, strlen (app_name));
414 memset (lm->
app_name, 0, strlen (app_name) +
sizeof (
char));
420 if (on_control_fd_update !=
NULL)
426 DBG (
"libmemif event polling initialized");
469 lm->
timerfd = timerfd_create (CLOCK_REALTIME, TFD_NONBLOCK);
473 DBG (
"timerfd: %s", strerror (err));
477 lm->arm.it_value.tv_sec = 2;
478 lm->arm.it_value.tv_nsec = 0;
479 lm->arm.it_interval.tv_sec = 2;
480 lm->arm.it_interval.tv_nsec = 0;
485 DBG (
"callback type memif_control_fd_update_t error!");
496 if (&conn->regions[0] ==
NULL)
498 void *p = conn->regions[0].shm;
501 sizeof (
memif_desc_t) * (1 << conn->run_args.log2_ring_size);
502 p += (ring_num + type * conn->run_args.num_s2m_rings) * ring_size;
515 (conn->args.is_master) ? conn->run_args.num_s2m_rings : conn->run_args.
520 conn->rx_queues[qid].ring->flags = rx_mode;
521 DBG (
"rx_mode flag: %u", conn->rx_queues[qid].ring->flags);
531 int err,
i, index, sockfd = -1;
536 DBG (
"This handle already points to existing memif.");
565 conn->args.mode = args->
mode;
566 conn->msg_queue =
NULL;
567 conn->regions =
NULL;
568 conn->tx_queues =
NULL;
569 conn->rx_queues =
NULL;
574 conn->private_ctx = private_ctx;
578 strncpy ((
char *) conn->args.interface_name, (
char *) args->
interface_name,
582 strncpy ((
char *) conn->args.instance_name, (
char *) args->
instance_name,
587 conn->args.socket_filename = malloc (
sizeof (
char *) * 108);
588 memset (conn->args.socket_filename, 0, 108 * sizeof (
char *));
592 if (conn->args.socket_filename ==
NULL)
597 strncpy ((
char *) conn->args.socket_filename,
605 if (conn->args.socket_filename ==
NULL)
610 strncpy ((
char *) conn->args.socket_filename,
612 conn->args.socket_filename[sdl] =
'/';
613 strncpy ((
char *) (conn->args.socket_filename + 1 + sdl),
619 l = strlen ((
char *) args->
secret);
620 strncpy ((
char *) conn->args.secret, (
char *) args->
secret, l);
623 if (conn->args.is_master)
625 conn->run_args.buffer_size = conn->args.buffer_size;
634 ((
char *) ms->
filename, (
char *) conn->args.socket_filename,
635 strlen ((
char *) ms->
filename)) == 0)
638 elt.
key = conn->args.interface_id;
643 conn->listener_fd = ms->
fd;
649 struct stat file_stat;
650 if (stat ((
char *) conn->args.socket_filename, &file_stat) == 0)
652 if (S_ISSOCK (file_stat.st_mode))
653 unlink ((
char *) conn->args.socket_filename);
657 DBG (
"creating socket file");
660 malloc (strlen ((
char *) conn->args.socket_filename) +
663 strlen ((
char *) conn->args.socket_filename) +
666 (
char *) conn->args.socket_filename,
667 strlen ((
char *) conn->args.socket_filename));
673 struct sockaddr_un un = { 0 };
676 ms->
fd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
682 DBG (
"socket %d created", ms->
fd);
683 un.sun_family = AF_UNIX;
684 strncpy ((
char *) un.sun_path, (
char *) ms->
filename,
685 sizeof (un.sun_path) - 1);
688 (ms->
fd, SOL_SOCKET, SO_PASSCRED, &on, sizeof (on)) < 0)
694 if (bind (ms->
fd, (
struct sockaddr *) &un, sizeof (un)) < 0)
700 if (listen (ms->
fd, 1) < 0)
706 if (stat ((
char *) ms->
filename, &file_stat) < 0)
713 elt.
key = conn->args.interface_id;
718 conn->listener_fd = ms->
fd;
733 if (timerfd_settime (lm->
timerfd, 0, &lm->arm,
NULL) < 0)
761 if (conn->args.socket_filename)
762 free (conn->args.socket_filename);
781 size = read (fd, &b,
sizeof (b));
788 if (conn->args.is_master)
791 struct sockaddr_un sun;
792 sockfd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
799 sun.sun_family = AF_UNIX;
801 strncpy (sun.sun_path, conn->args.socket_filename,
802 sizeof (sun.sun_path) - 1);
804 if (connect (sockfd, (
struct sockaddr *) &sun,
805 sizeof (
struct sockaddr_un)) == 0)
848 data_struct)->run_args.
850 for (i = 0; i < num; i++)
856 data_struct)->on_interrupt ((
void *) e->
data_struct,
924 struct epoll_event evt, *e;
928 memset (&evt, 0,
sizeof (evt));
929 evt.events = EPOLLIN | EPOLLOUT;
931 sigemptyset (&sigset);
932 en = epoll_pwait (
memif_epfd, &evt, 1, timeout, &sigset);
935 DBG (
"epoll_pwait: %s", strerror (errno));
940 if (evt.events & EPOLLIN)
942 if (evt.events & EPOLLOUT)
944 if (evt.events & EPOLLERR)
969 DBG (
"no connection");
978 c->on_disconnect ((
void *) c, c->private_ctx);
989 if (c->args.is_master)
994 if (c->tx_queues !=
NULL)
997 (c->args.is_master) ? c->run_args.num_m2s_rings : c->run_args.
999 for (i = 0; i < num; i++)
1001 mq = &c->tx_queues[
i];
1011 free (c->tx_queues);
1012 c->tx_queues =
NULL;
1015 if (c->rx_queues !=
NULL)
1018 (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
1020 for (i = 0; i < num; i++)
1022 mq = &c->rx_queues[
i];
1027 if (c->on_interrupt !=
NULL)
1036 free (c->rx_queues);
1037 c->rx_queues =
NULL;
1040 if (c->regions !=
NULL)
1042 if (munmap (c->regions[0].shm, c->regions[0].region_size) < 0)
1044 if (c->regions[0].fd > 0)
1045 close (c->regions[0].fd);
1046 c->regions[0].fd = -1;
1055 if (!(c->args.is_master))
1059 if (timerfd_settime (lm->
timerfd, 0, &lm->arm,
NULL) < 0)
1077 DBG (
"no connection");
1088 DBG (
"DISCONNECTING");
1096 if (c->args.is_master)
1105 c->args.interface_id);
1111 close (c->listener_fd);
1112 c->listener_fd = ms->
fd = -1;
1130 DBG (
"timerfd_settime: disarm");
1135 if (c->args.socket_filename)
1136 free (c->args.socket_filename);
1137 c->args.socket_filename =
NULL;
1163 MAP_SHARED, mr->
fd, 0)) == MAP_FAILED)
1171 (c->args.is_master) ? c->run_args.num_m2s_rings : c->run_args.
1173 for (i = 0; i < num; i++)
1175 mq = &c->tx_queues[
i];
1181 DBG (
"wrong cookie on tx ring %u", i);
1189 (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
1191 for (i = 0; i < num; i++)
1193 mq = &c->rx_queues[
i];
1199 DBG (
"wrong cookie on rx ring %u", i);
1216 uint64_t buffer_offset;
1223 if (conn->regions ==
NULL)
1228 (conn->run_args.num_s2m_rings +
1229 conn->run_args.num_m2s_rings) * (
sizeof (
memif_ring_t) +
1231 (1 << conn->run_args.log2_ring_size));
1234 conn->run_args.buffer_size * (1 << conn->run_args.log2_ring_size) *
1235 (conn->run_args.num_s2m_rings + conn->run_args.num_m2s_rings);
1247 MAP_SHARED, r->
fd, 0)) == MAP_FAILED)
1250 for (i = 0; i < conn->run_args.num_s2m_rings; i++)
1253 DBG (
"RING: %p I: %d", ring, i);
1257 for (j = 0; j < (1 << conn->run_args.log2_ring_size); j++)
1259 uint16_t slot = i * (1 << conn->run_args.log2_ring_size) + j;
1262 (uint32_t) (slot * conn->run_args.buffer_size);
1266 for (i = 0; i < conn->run_args.num_m2s_rings; i++)
1269 DBG (
"RING: %p I: %d", ring, i);
1273 for (j = 0; j < (1 << conn->run_args.log2_ring_size); j++)
1277 conn->run_args.num_s2m_rings) *
1278 (1 << conn->run_args.log2_ring_size) + j;
1281 (uint32_t) (slot * conn->run_args.buffer_size);
1288 conn->run_args.num_s2m_rings);
1292 for (x = 0; x < conn->run_args.num_s2m_rings; x++)
1294 if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
1302 DBG (
"RING: %p I: %d", mq[x].ring, x);
1306 (
void *) mq[x].ring - (
void *) conn->regions[mq->
region].shm;
1310 conn->tx_queues = mq;
1314 conn->run_args.num_m2s_rings);
1317 for (x = 0; x < conn->run_args.num_m2s_rings; x++)
1319 if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
1327 DBG (
"RING: %p I: %d", mq[x].ring, x);
1331 (
void *) mq[x].ring - (
void *) conn->regions[mq->
region].shm;
1335 conn->rx_queues = mq;
1343 uint16_t * count_out, uint16_t
size)
1351 (c->args.is_master) ? c->run_args.num_m2s_rings : c->run_args.
1358 uint8_t chain_buf0, chain_buf1;
1360 uint16_t s0, s1, ns;
1379 while ((count > 2) && (ns > 2))
1386 if (chain_buf0 > ns)
1394 if ((chain_buf0 + chain_buf1) > ns)
1397 b0 = (bufs + *count_out);
1398 b1 = (bufs + *count_out + 1);
1410 for (i = 0; i < (
memif_min (chain_buf0, chain_buf1) - 1); i++)
1414 DBG (
"allocating chained buffers");
1417 if (chain_buf0 > chain_buf1)
1419 for (; i < (chain_buf0 - 1); i++)
1424 for (; i < (chain_buf1 - 1); i++)
1430 DBG (
"allocated ring slots %u, %u", s0, s1);
1432 ns -= chain_buf0 + chain_buf1;
1437 b0 = (bufs + *count_out);
1443 if (chain_buf0 > ns)
1451 for (i = 0; i < (chain_buf0 - 1); i++)
1454 DBG (
"allocating chained buffers");
1459 DBG (
"allocated ring slot %u", s0);
1465 DBG (
"allocated: %u/%u bufs. Total %u allocated bufs", *count_out, count,
1470 DBG (
"ring buffer full! qid: %u", qid);
1480 uint16_t * count_out)
1488 (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
1495 uint16_t tail = ring->
tail;
1497 uint8_t chain_buf0, chain_buf1;
1508 b0 = (bufs + *count_out);
1509 b1 = (bufs + *count_out + 1);
1528 b0 = (bufs + *count_out);
1556 (c->args.is_master) ? c->run_args.num_m2s_rings : c->run_args.
1562 uint16_t head = ring->
head;
1564 uint8_t chain_buf0, chain_buf1;
1566 uint16_t curr_buf = 0;
1574 b0 = (bufs + curr_buf);
1575 b1 = (bufs + curr_buf + 1);
1588 for (i = 0; i <
memif_min (chain_buf0, chain_buf1); i++)
1618 #ifdef MEMIF_DBG_SHM 1619 print_bytes (b0->
data +
1625 print_bytes (b1->
data +
1634 if (chain_buf0 > chain_buf1)
1636 for (; i < chain_buf0; i++)
1651 #ifdef MEMIF_DBG_SHM 1652 print_bytes (b0->
data +
1664 for (; i < chain_buf1; i++)
1679 #ifdef MEMIF_DBG_SHM 1680 print_bytes (b1->
data +
1696 DBG (
"invalid b0 data length!");
1701 DBG (
"invalid b1 data length!");
1705 *tx += chain_buf0 + chain_buf1;
1709 b0 = (bufs + curr_buf);
1714 for (i = 0; i < chain_buf0; i++)
1727 #ifdef MEMIF_DBG_SHM 1728 print_bytes (b0->
data +
1741 DBG (
"invalid b0 data length!");
1759 int r = write (mq->
int_fd, &a, sizeof (a));
1777 (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
1783 uint16_t head = ring->
head;
1787 uint16_t curr_buf = 0;
1792 ssize_t r = read (mq->
int_fd, &b, sizeof (b));
1793 if ((r == -1) && (errno != EAGAIN))
1806 DBG (
"ns: %u, count: %u", ns, count);
1807 while ((ns > 2) && (count > 2))
1809 b0 = (bufs + curr_buf);
1810 b1 = (bufs + curr_buf + 1);
1820 #ifdef MEMIF_DBG_SHM 1821 print_bytes (b0->
data +
1833 #ifdef MEMIF_DBG_SHM 1834 print_bytes (b0->
data +
1852 #ifdef MEMIF_DBG_SHM 1853 print_bytes (b1->
data +
1865 #ifdef MEMIF_DBG_SHM 1866 print_bytes (b1->
data +
1879 b0 = (bufs + curr_buf);
1889 #ifdef MEMIF_DBG_SHM 1890 print_bytes (b0->
data +
1903 #ifdef MEMIF_DBG_SHM 1904 print_bytes (b0->
data +
1924 DBG (
"not enough buffers!");
1933 char *buf, ssize_t buflen)
1940 ssize_t l0, l1, total_l;
1943 l1 = strlen ((
char *) c->args.interface_name);
1944 if (l0 + l1 <= buflen)
1946 md->
if_name = strncpy (buf + l0, (
char *) c->args.interface_name, l1);
1953 l1 = strlen ((
char *) c->args.instance_name);
1954 if (l0 + l1 <= buflen)
1956 md->
inst_name = strncpy (buf + l0, (
char *) c->args.instance_name, l1);
1963 l1 = strlen ((
char *) c->remote_if_name);
1964 if (l0 + l1 <= buflen)
1966 md->
remote_if_name = strncpy (buf + l0, (
char *) c->remote_if_name, l1);
1973 l1 = strlen ((
char *) c->remote_name);
1974 if (l0 + l1 <= buflen)
1983 md->
id = c->args.interface_id;
1987 l1 = strlen ((
char *) c->args.secret);
1988 md->
secret = strncpy (buf + l0, (
char *) c->args.secret, l1);
1989 md->
secret[l0 + l1] =
'\0';
1995 md->
role = (c->args.is_master) ? 0 : 1;
1996 md->
mode = c->args.mode;
1998 l1 = strlen ((
char *) c->args.socket_filename);
1999 if (l0 + l1 <= buflen)
2002 strncpy (buf + l0, (
char *) c->args.socket_filename, l1);
2010 (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
2014 if (l0 + l1 <= buflen)
2030 (c->args.is_master) ? c->run_args.num_m2s_rings : c->run_args.
2034 if (l0 + l1 <= buflen)
2064 (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
2069 *efd = c->rx_queues[qid].int_fd;
#define MEMIF_DEFAULT_LOG2_RING_SIZE
sll srl srl sll sra u16x4 i
memif_log2_ring_size_t log2_ring_size
static char memif_buf[MAX_ERRBUF_LEN]
int on_disconnect(memif_conn_handle_t conn, void *private_ctx)
#define MEMIF_FD_EVENT_READ
user needs to set events that occured on fd and pass them to memif_control_fd_handler ...
static int memfd_create(const char *name, unsigned int flags)
memif_interface_id_t interface_id
memif_list_elt_t * pending_list
#define MEMIF_ERR_UNDEFINED
clib_error_t * memif_msg_send_disconnect(memif_if_t *mif, clib_error_t *err)
int memif_disconnect_internal(memif_connection_t *c)
int( memif_control_fd_update_t)(int fd, uint8_t events)
Memif control file descriptor update (callback function)
memif_control_fd_update_t * control_fd_update
static void memif_control_fd_update_register(memif_control_fd_update_t *cb)
uint8_t * remote_inst_name
static memif_ring_t * memif_get_ring(memif_connection_t *conn, memif_ring_type_t type, uint16_t ring_num)
#define MEMIF_DEFAULT_APP_NAME
Default name of application using libmemif.
memif_list_elt_t * interface_list
int on_connect(memif_conn_handle_t conn, void *private_ctx)
memif_list_elt_t * listener_list
int memif_get_details(memif_conn_handle_t conn, memif_details_t *md, char *buf, ssize_t buflen)
Memif get details.
memif_interface_mode_t mode
static clib_error_t * memif_conn_fd_write_ready(clib_file_t *uf, memif_if_t *mif)
int memif_buffer_free(memif_conn_handle_t conn, uint16_t qid, memif_buffer_t *bufs, uint16_t count, uint16_t *count_out)
Memif buffer free.
struct itimerspec arm disarm
char * memif_strerror(int err_code)
Memif strerror.
memif_region_offset_t offset
int memif_syscall_error_handler(int err_code)
memif_list_elt_t * interrupt_list
memif_region_index_t region
static int memif_del_epoll_fd(int fd)
uint8_t interface_name[32]
uint8_t * socket_filename
#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) ...
int memif_set_rx_mode(memif_conn_handle_t c, memif_rx_mode_t rx_mode, uint16_t qid)
Memif set rx mode.
int( memif_interrupt_t)(memif_conn_handle_t conn, void *private_ctx, uint16_t qid)
Memif interrupt occured (callback function)
int( memif_connection_update_t)(memif_conn_handle_t conn, void *private_ctx)
Memif connection status update (callback function)
static int memif_add_epoll_fd(int fd, uint32_t events)
int memif_get_queue_efd(memif_conn_handle_t conn, uint16_t qid, int *efd)
Memif get queue event file descriptor
#define MFD_ALLOW_SEALING
#define MEMIF_DEFAULT_TX_QUEUES
int add_list_elt(memif_list_elt_t *e, memif_list_elt_t **list, uint16_t *len)
int memif_init_regions_and_queues(memif_connection_t *conn)
int on_interrupt(memif_conn_handle_t conn, void *private_ctx, uint16_t qid)
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.
int get_list_elt(memif_list_elt_t **e, memif_list_elt_t *list, uint16_t len, int key)
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.
int memif_poll_event(int timeout)
Memif poll event.
memif_queue_details_t * rx_queues
#define MEMIF_DEFAULT_BUFFER_SIZE
uint8_t instance_name[32]
int memif_cleanup()
Memif cleanup.
const char * memif_errlist[ERRLIST_LEN]
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.
#define MEMIF_DESC_FLAG_NEXT
static void memif_msg_queue_free(memif_msg_queue_elt_t **e)
int free_list_elt_ctx(memif_list_elt_t *list, uint16_t len, memif_connection_t *ctx)
static int memif_mod_epoll_fd(int fd, uint32_t events)
static_always_inline void * memif_get_buffer(memif_if_t *mif, memif_ring_t *ring, u16 slot)
uint16_t interrupt_list_len
#define MEMIF_DEFAULT_RX_QUEUES
#define MEMIF_DEFAULT_SOCKET_DIR
#define MEMIF_RING_FLAG_MASK_INT
void * memif_conn_handle_t
*brief Memif connection handle pointer of type void, pointing to internal structure ...
memif_region_offset_t offset
int memif_control_fd_handler(int fd, uint8_t events)
Memif control file descriptor handler.
#define MEMIF_DEFAULT_SOCKET_FILENAME
int memif_init(memif_control_fd_update_t *on_control_fd_update, char *app_name)
Memif initialization.
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.
uint16_t pending_list_len
memif_list_elt_t * control_list
int memif_delete(memif_conn_handle_t *conn)
Memif delete.
memif_log2_ring_size_t log2_ring_size
#define MEMIF_FD_EVENT_ERROR
inform libmemif that error occured on fd
uint16_t control_list_len
#define MEMIF_FD_EVENT_MOD
update events
memif_queue_details_t * tx_queues
clib_error_t * memif_conn_fd_accept_ready(clib_file_t *uf)
int memif_connect1(memif_connection_t *c)
libmemif_main_t libmemif_main
int free_list_elt(memif_list_elt_t *list, uint16_t len, int key)
#define MEMIF_FD_EVENT_WRITE
memif_region_index_t region
uint16_t listener_list_len
Memif connection arguments.
uint16_t interface_list_len
memif_region_size_t region_size
uint8_t * socket_filename
#define MEMIF_MEORY_BARRIER()
int memif_control_fd_update(int fd, uint8_t events)