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 38 58 #define MAX_ERRBUF_LEN 256 61 #define MEMIF_MEMORY_BARRIER() __builtin_ia32_sfence () 63 #define MEMIF_MEMORY_BARRIER() __sync_synchronize () 75 "Unspecified syscall error (build with -DMEMIF_DBG or make debug).",
77 "Permission to resoure denied.",
79 "Socket file does not exist",
81 "System limit on total numer of open files reached.",
83 "Per-process limit on total number of open files reached.",
85 "Connection already requested.",
87 "File descriptor refers to file other than socket, or operation would block.",
89 "Bad file descriptor.",
95 "Memif connection handle does not point to existing conenction",
97 "Memif connection handle points to existing connection",
99 "Callback memif_control_fd_update_t returned error",
101 "File specified by socket filename exists and is not socket.",
103 "Missing shared memory file descriptor. (internal error)",
105 "Invalid cookie on ring. (internal error)",
109 "Not enough memif buffers. There are unreceived data in shared memory.",
111 "Not enough space for memif details in suplied buffer. String data might be malformed.",
113 "Send interrupt error.",
115 "Malformed message received on control channel.",
119 "Incompatible memory interface protocol version.",
121 "Unmatched interface id.",
123 "Slave cannot accept connection reqest.",
125 "Interface is already connected.",
133 "Limit on total number of regions reached.",
135 "Limit on total number of ring reached.",
137 "Missing interrupt file descriptor. (internal error)",
139 "Interface received disconnect request.",
141 "Interface is disconnected.",
143 "Unknown message type received on control channel. (internal error)",
145 "Memif event polling was canceled.",
147 "Maximum log2 ring size is 15" 150 #define MEMIF_ERR_UNDEFINED "undefined error" 169 #define DBG_TX_BUF (0) 170 #define DBG_RX_BUF (1) 174 print_bytes (
void *data, uint16_t len, uint8_t q)
177 printf (
"\nTX:\n\t");
179 printf (
"\nRX:\n\t");
181 for (i = 0; i < len; i++)
184 printf (
"\n%d:\t", i);
185 printf (
"%02X ", ((uint8_t *) (data))[i]);
194 DBG_UNIX (
"%s", strerror (err_code));
198 if (err_code == EACCES)
200 if (err_code == ENFILE)
202 if (err_code == EMFILE)
204 if (err_code == ENOMEM)
208 if (err_code == ECONNREFUSED)
210 if (err_code == EALREADY)
212 if (err_code == EAGAIN)
214 if (err_code == EBADF)
216 if (err_code == ENOENT)
228 DBG (
"invalid fd %d", fd);
231 struct epoll_event evt;
232 memset (&evt, 0,
sizeof (evt));
235 if (epoll_ctl (
memif_epfd, EPOLL_CTL_ADD, fd, &evt) < 0)
237 DBG (
"epoll_ctl: %s fd %d", strerror (errno), fd);
240 DBG (
"fd %d added to epoll", fd);
249 DBG (
"invalid fd %d", fd);
252 struct epoll_event evt;
253 memset (&evt, 0,
sizeof (evt));
256 if (epoll_ctl (
memif_epfd, EPOLL_CTL_MOD, fd, &evt) < 0)
258 DBG (
"epoll_ctl: %s fd %d", strerror (errno), fd);
261 DBG (
"fd %d moddified on epoll", fd);
270 DBG (
"invalid fd %d", fd);
273 struct epoll_event evt;
274 memset (&evt, 0,
sizeof (evt));
275 if (epoll_ctl (
memif_epfd, EPOLL_CTL_DEL, fd, &evt) < 0)
277 DBG (
"epoll_ctl: %s fd %d", strerror (errno), fd);
280 DBG (
"fd %d removed from epoll", fd);
308 for (i = 0; i < *len; i++)
310 if ((*list)[i].data_struct ==
NULL)
312 (*list)[
i].key = e->
key;
322 for (i = *len; i < *len * 2; i++)
347 for (i = 0; i < len; i++)
349 if (list[i].key == key)
364 for (i = 0; i < len; i++)
366 if (list[i].key == key)
382 for (i = 0; i < len; i++)
384 if (list[i].key == -1)
386 if (list[i].data_struct == ctx)
412 lm->
app_name = malloc (strlen (app_name) +
sizeof (
char));
413 memset (lm->
app_name, 0, strlen (app_name) +
sizeof (
char));
414 strncpy ((
char *) lm->
app_name, app_name, strlen (app_name));
419 memset (lm->
app_name, 0, strlen (app_name) +
sizeof (
char));
425 if (on_control_fd_update !=
NULL)
434 DBG (
"eventfd: %s", strerror (err));
438 DBG (
"libmemif event polling initialized");
481 lm->
timerfd = timerfd_create (CLOCK_REALTIME, TFD_NONBLOCK);
485 DBG (
"timerfd: %s", strerror (err));
489 lm->arm.it_value.tv_sec = 2;
490 lm->arm.it_value.tv_nsec = 0;
491 lm->arm.it_interval.tv_sec = 2;
492 lm->arm.it_interval.tv_nsec = 0;
497 DBG (
"callback type memif_control_fd_update_t error!");
508 if (&conn->regions[0] ==
NULL)
510 void *p = conn->regions[0].shm;
513 sizeof (
memif_desc_t) * (1 << conn->run_args.log2_ring_size);
514 p += (ring_num + type * conn->run_args.num_s2m_rings) * ring_size;
527 (conn->args.is_master) ? conn->run_args.num_s2m_rings : conn->
528 run_args.num_m2s_rings;
532 conn->rx_queues[qid].ring->flags = rx_mode;
533 DBG (
"rx_mode flag: %u", conn->rx_queues[qid].ring->flags);
543 int err,
i, index, sockfd = -1;
548 DBG (
"This handle already points to existing memif.");
582 conn->args.mode = args->
mode;
583 conn->msg_queue =
NULL;
584 conn->regions =
NULL;
585 conn->tx_queues =
NULL;
586 conn->rx_queues =
NULL;
591 conn->private_ctx = private_ctx;
595 strncpy ((
char *) conn->args.interface_name, (
char *) args->
interface_name,
599 strncpy ((
char *) conn->args.instance_name, (
char *) args->
instance_name,
604 conn->args.socket_filename = malloc (
sizeof (
char *) * 108);
605 memset (conn->args.socket_filename, 0, 108 * sizeof (
char *));
609 if (conn->args.socket_filename ==
NULL)
614 strncpy ((
char *) conn->args.socket_filename,
622 if (conn->args.socket_filename ==
NULL)
627 strncpy ((
char *) conn->args.socket_filename,
629 conn->args.socket_filename[sdl] =
'/';
630 strncpy ((
char *) (conn->args.socket_filename + 1 + sdl),
636 l = strlen ((
char *) args->
secret);
637 strncpy ((
char *) conn->args.secret, (
char *) args->
secret, l);
640 if (conn->args.is_master)
642 conn->run_args.buffer_size = conn->args.buffer_size;
651 ((
char *) ms->
filename, (
char *) conn->args.socket_filename,
652 strlen ((
char *) ms->
filename)) == 0)
655 elt.
key = conn->args.interface_id;
660 conn->listener_fd = ms->
fd;
666 struct stat file_stat;
667 if (stat ((
char *) conn->args.socket_filename, &file_stat) == 0)
669 if (S_ISSOCK (file_stat.st_mode))
670 unlink ((
char *) conn->args.socket_filename);
674 DBG (
"creating socket file");
677 malloc (strlen ((
char *) conn->args.socket_filename) +
680 strlen ((
char *) conn->args.socket_filename) +
683 (
char *) conn->args.socket_filename,
684 strlen ((
char *) conn->args.socket_filename));
690 struct sockaddr_un un = { 0 };
693 ms->
fd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
699 DBG (
"socket %d created", ms->
fd);
700 un.sun_family = AF_UNIX;
701 strncpy ((
char *) un.sun_path, (
char *) ms->
filename,
702 sizeof (un.sun_path) - 1);
705 (ms->
fd, SOL_SOCKET, SO_PASSCRED, &on, sizeof (on)) < 0)
711 if (bind (ms->
fd, (
struct sockaddr *) &un, sizeof (un)) < 0)
717 if (listen (ms->
fd, 1) < 0)
723 if (stat ((
char *) ms->
filename, &file_stat) < 0)
730 elt.
key = conn->args.interface_id;
735 conn->listener_fd = ms->
fd;
750 if (timerfd_settime (lm->
timerfd, 0, &lm->arm,
NULL) < 0)
778 if (conn->args.socket_filename)
779 free (conn->args.socket_filename);
798 size = read (fd, &b,
sizeof (b));
805 if (conn->args.is_master)
808 struct sockaddr_un sun;
809 sockfd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
816 sun.sun_family = AF_UNIX;
818 strncpy (sun.sun_path, conn->args.socket_filename,
819 sizeof (sun.sun_path) - 1);
821 if (connect (sockfd, (
struct sockaddr *) &sun,
822 sizeof (
struct sockaddr_un)) == 0)
864 data_struct)->run_args.
866 run_args.num_m2s_rings;
867 for (i = 0; i < num; i++)
870 rx_queues[i].int_fd == fd)
875 data_struct)->private_ctx, i);
940 struct epoll_event evt, *e;
944 uint64_t counter = 0;
946 memset (&evt, 0,
sizeof (evt));
947 evt.events = EPOLLIN | EPOLLOUT;
949 sigemptyset (&sigset);
950 en = epoll_pwait (
memif_epfd, &evt, 1, timeout, &sigset);
954 DBG (
"epoll_pwait: %s", strerror (err));
961 r = read (evt.data.fd, &counter, sizeof (counter));
964 if (evt.events & EPOLLIN)
966 if (evt.events & EPOLLOUT)
968 if (evt.events & EPOLLERR)
979 uint64_t counter = 1;
985 if (w <
sizeof (counter))
1008 DBG (
"no connection");
1017 c->on_disconnect ((
void *) c, c->private_ctx);
1028 if (c->args.is_master)
1030 e->
key = c->fd = -1;
1033 if (c->tx_queues !=
NULL)
1036 (c->args.is_master) ? c->run_args.num_m2s_rings : c->
1037 run_args.num_s2m_rings;
1038 for (i = 0; i < num; i++)
1040 mq = &c->tx_queues[
i];
1050 free (c->tx_queues);
1051 c->tx_queues =
NULL;
1054 if (c->rx_queues !=
NULL)
1057 (c->args.is_master) ? c->run_args.num_s2m_rings : c->
1058 run_args.num_m2s_rings;
1059 for (i = 0; i < num; i++)
1061 mq = &c->rx_queues[
i];
1066 if (c->on_interrupt !=
NULL)
1075 free (c->rx_queues);
1076 c->rx_queues =
NULL;
1079 if (c->regions !=
NULL)
1081 if (munmap (c->regions[0].shm, c->regions[0].region_size) < 0)
1083 if (c->regions[0].fd > 0)
1084 close (c->regions[0].fd);
1085 c->regions[0].fd = -1;
1094 if (!(c->args.is_master))
1098 if (timerfd_settime (lm->
timerfd, 0, &lm->arm,
NULL) < 0)
1116 DBG (
"no connection");
1127 DBG (
"DISCONNECTING");
1135 if (c->args.is_master)
1144 c->args.interface_id);
1150 close (c->listener_fd);
1151 c->listener_fd = ms->
fd = -1;
1169 DBG (
"timerfd_settime: disarm");
1174 if (c->args.socket_filename)
1175 free (c->args.socket_filename);
1176 c->args.socket_filename =
NULL;
1202 MAP_SHARED, mr->
fd, 0)) == MAP_FAILED)
1210 (c->args.is_master) ? c->run_args.num_m2s_rings : c->
1211 run_args.num_s2m_rings;
1212 for (i = 0; i < num; i++)
1214 mq = &c->tx_queues[
i];
1220 DBG (
"wrong cookie on tx ring %u", i);
1228 (c->args.is_master) ? c->run_args.num_s2m_rings : c->
1229 run_args.num_m2s_rings;
1230 for (i = 0; i < num; i++)
1232 mq = &c->rx_queues[
i];
1238 DBG (
"wrong cookie on rx ring %u", i);
1255 uint64_t buffer_offset;
1262 if (conn->regions ==
NULL)
1267 (conn->run_args.num_s2m_rings +
1268 conn->run_args.num_m2s_rings) * (
sizeof (
memif_ring_t) +
1270 (1 << conn->run_args.log2_ring_size));
1273 conn->run_args.buffer_size * (1 << conn->run_args.log2_ring_size) *
1274 (conn->run_args.num_s2m_rings + conn->run_args.num_m2s_rings);
1286 MAP_SHARED, r->
fd, 0)) == MAP_FAILED)
1289 for (i = 0; i < conn->run_args.num_s2m_rings; i++)
1292 DBG (
"RING: %p I: %d", ring, i);
1296 for (j = 0; j < (1 << conn->run_args.log2_ring_size); j++)
1298 uint16_t slot = i * (1 << conn->run_args.log2_ring_size) + j;
1301 (uint32_t) (slot * conn->run_args.buffer_size);
1305 for (i = 0; i < conn->run_args.num_m2s_rings; i++)
1308 DBG (
"RING: %p I: %d", ring, i);
1312 for (j = 0; j < (1 << conn->run_args.log2_ring_size); j++)
1316 conn->run_args.num_s2m_rings) *
1317 (1 << conn->run_args.log2_ring_size) + j;
1320 (uint32_t) (slot * conn->run_args.buffer_size);
1327 conn->run_args.num_s2m_rings);
1331 for (x = 0; x < conn->run_args.num_s2m_rings; x++)
1333 if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
1341 DBG (
"RING: %p I: %d", mq[x].ring, x);
1345 (
void *) mq[x].ring - (
void *) conn->regions[mq->
region].shm;
1349 conn->tx_queues = mq;
1353 conn->run_args.num_m2s_rings);
1356 for (x = 0; x < conn->run_args.num_m2s_rings; x++)
1358 if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
1366 DBG (
"RING: %p I: %d", mq[x].ring, x);
1370 (
void *) mq[x].ring - (
void *) conn->regions[mq->
region].shm;
1374 conn->rx_queues = mq;
1382 uint16_t * count_out, uint16_t
size)
1390 (c->args.is_master) ? c->run_args.num_m2s_rings : c->
1391 run_args.num_s2m_rings;
1397 uint8_t chain_buf = 1;
1399 uint16_t head = ring->
head;
1400 uint16_t tail = ring->
tail;
1401 uint16_t s0, s1, ns;
1417 while ((count > 2) && (ns > 2))
1422 if ((2 * chain_buf) > ns)
1425 b0 = (bufs + *count_out);
1426 b1 = (bufs + *count_out + 1);
1438 for (i = 0; i < (chain_buf - 1); i++)
1442 DBG (
"allocating chained buffers");
1447 DBG (
"allocated ring slots %u, %u", s0, s1);
1449 ns -= (2 * chain_buf);
1454 b0 = (bufs + *count_out);
1464 for (i = 0; i < (chain_buf - 1); i++)
1467 DBG (
"allocating chained buffers");
1472 DBG (
"allocated ring slot %u", s0);
1478 DBG (
"allocated: %u/%u bufs. Total %u allocated bufs", *count_out, count,
1483 DBG (
"ring buffer full! qid: %u", qid);
1493 uint16_t * count_out)
1501 (c->args.is_master) ? c->run_args.num_s2m_rings : c->
1502 run_args.num_m2s_rings;
1508 uint16_t tail = ring->
tail;
1510 uint8_t chain_buf0, chain_buf1;
1521 b0 = (bufs + *count_out);
1522 b1 = (bufs + *count_out + 1);
1541 b0 = (bufs + *count_out);
1571 (c->args.is_master) ? c->run_args.num_m2s_rings : c->
1572 run_args.num_s2m_rings;
1577 uint16_t head = ring->
head;
1579 uint8_t chain_buf0, chain_buf1;
1581 uint16_t curr_buf = 0;
1589 b0 = (bufs + curr_buf);
1590 b1 = (bufs + curr_buf + 1);
1603 for (i = 0; i <
memif_min (chain_buf0, chain_buf1); i++)
1633 #ifdef MEMIF_DBG_SHM 1634 print_bytes (b0->
data +
1640 print_bytes (b1->
data +
1649 if (chain_buf0 > chain_buf1)
1651 for (; i < chain_buf0; i++)
1666 #ifdef MEMIF_DBG_SHM 1667 print_bytes (b0->
data +
1679 for (; i < chain_buf1; i++)
1694 #ifdef MEMIF_DBG_SHM 1695 print_bytes (b1->
data +
1711 DBG (
"invalid b0 data length!");
1716 DBG (
"invalid b1 data length!");
1720 *tx += chain_buf0 + chain_buf1;
1724 b0 = (bufs + curr_buf);
1731 for (i = 0; i < chain_buf0; i++)
1744 #ifdef MEMIF_DBG_SHM 1745 print_bytes (b0->
data +
1758 DBG (
"invalid b0 data length!");
1776 int r = write (mq->
int_fd, &a, sizeof (a));
1794 (c->args.is_master) ? c->run_args.num_s2m_rings : c->
1795 run_args.num_m2s_rings;
1800 uint16_t head = ring->
head;
1804 uint16_t curr_buf = 0;
1806 #ifdef MEMIF_DBG_SHM 1811 ssize_t r = read (mq->
int_fd, &b, sizeof (b));
1812 if ((r == -1) && (errno != EAGAIN))
1822 while ((ns > 2) && (count > 2))
1824 b0 = (bufs + curr_buf);
1825 b1 = (bufs + curr_buf + 1);
1831 #ifdef MEMIF_DBG_SHM 1833 print_bytes (b0->
data +
1848 #ifdef MEMIF_DBG_SHM 1849 print_bytes (b0->
data +
1864 #ifdef MEMIF_DBG_SHM 1866 print_bytes (b1->
data +
1874 flags & MEMIF_DESC_FLAG_NEXT)
1881 #ifdef MEMIF_DBG_SHM 1882 print_bytes (b1->
data +
1896 b0 = (bufs + curr_buf);
1902 #ifdef MEMIF_DBG_SHM 1904 print_bytes (b0->
data +
1918 #ifdef MEMIF_DBG_SHM 1919 print_bytes (b0->
data +
1940 DBG (
"not enough buffers!");
1949 char *buf, ssize_t buflen)
1956 ssize_t l0, l1, total_l;
1959 l1 = strlen ((
char *) c->args.interface_name);
1960 if (l0 + l1 < buflen)
1962 md->
if_name = strcpy (buf + l0, (
char *) c->args.interface_name);
1968 l1 = strlen ((
char *) c->args.instance_name);
1969 if (l0 + l1 < buflen)
1971 md->
inst_name = strcpy (buf + l0, (
char *) c->args.instance_name);
1977 l1 = strlen ((
char *) c->remote_if_name);
1978 if (l0 + l1 < buflen)
1980 md->
remote_if_name = strcpy (buf + l0, (
char *) c->remote_if_name);
1986 l1 = strlen ((
char *) c->remote_name);
1987 if (l0 + l1 < buflen)
1995 md->
id = c->args.interface_id;
1999 l1 = strlen ((
char *) c->args.secret);
2000 if (l0 + l1 < buflen)
2002 md->
secret = strcpy (buf + l0, (
char *) c->args.secret);
2009 md->
role = (c->args.is_master) ? 0 : 1;
2010 md->
mode = c->args.mode;
2012 l1 = strlen ((
char *) c->args.socket_filename);
2013 if (l0 + l1 < buflen)
2016 strcpy (buf + l0, (
char *) c->args.socket_filename);
2023 (c->args.is_master) ? c->run_args.num_s2m_rings : c->
2024 run_args.num_m2s_rings;
2027 if (l0 + l1 <= buflen)
2046 (c->args.is_master) ? c->run_args.num_m2s_rings : c->
2047 run_args.num_s2m_rings;
2050 if (l0 + l1 <= buflen)
2083 (c->args.is_master) ? c->run_args.num_s2m_rings : c->
2084 run_args.num_m2s_rings;
2088 *efd = c->rx_queues[qid].int_fd;
#define MEMIF_DEFAULT_LOG2_RING_SIZE
sll srl srl sll sra u16x4 i
#define MFD_ALLOW_SEALING
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)
#define MEMIF_MEMORY_BARRIER()
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
#define MEMIF_MAX_LOG2_RING_SIZE
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 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
int memif_cancel_poll_event()
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
int memif_control_fd_update(int fd, uint8_t events)