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 39 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",
149 "Private headers not supported." 152 #define MEMIF_ERR_UNDEFINED "undefined error" 177 #define DBG_TX_BUF (0) 178 #define DBG_RX_BUF (1) 182 print_bytes (
void *data, uint16_t len, uint8_t q)
185 printf (
"\nTX:\n\t");
187 printf (
"\nRX:\n\t");
189 for (i = 0; i < len; i++)
192 printf (
"\n%d:\t", i);
193 printf (
"%02X ", ((uint8_t *) (data))[i]);
202 DBG (
"%s", strerror (err_code));
206 if (err_code == EACCES)
208 if (err_code == ENFILE)
210 if (err_code == EMFILE)
212 if (err_code == ENOMEM)
216 if (err_code == ECONNREFUSED)
218 if (err_code == EALREADY)
220 if (err_code == EAGAIN)
222 if (err_code == EBADF)
224 if (err_code == ENOENT)
236 DBG (
"invalid fd %d", fd);
239 struct epoll_event evt;
240 memset (&evt, 0,
sizeof (evt));
243 if (epoll_ctl (
memif_epfd, EPOLL_CTL_ADD, fd, &evt) < 0)
245 DBG (
"epoll_ctl: %s fd %d", strerror (errno), fd);
248 DBG (
"fd %d added to epoll", fd);
257 DBG (
"invalid fd %d", fd);
260 struct epoll_event evt;
261 memset (&evt, 0,
sizeof (evt));
264 if (epoll_ctl (
memif_epfd, EPOLL_CTL_MOD, fd, &evt) < 0)
266 DBG (
"epoll_ctl: %s fd %d", strerror (errno), fd);
269 DBG (
"fd %d moddified on epoll", fd);
278 DBG (
"invalid fd %d", fd);
281 struct epoll_event evt;
282 memset (&evt, 0,
sizeof (evt));
283 if (epoll_ctl (
memif_epfd, EPOLL_CTL_DEL, fd, &evt) < 0)
285 DBG (
"epoll_ctl: %s fd %d", strerror (errno), fd);
288 DBG (
"fd %d removed from epoll", fd);
316 for (i = 0; i < *len; i++)
318 if ((*list)[i].data_struct ==
NULL)
320 (*list)[
i].key = e->
key;
330 for (i = *len; i < *len * 2; i++)
355 for (i = 0; i < len; i++)
357 if (list[i].key == key)
372 for (i = 0; i < len; i++)
374 if (list[i].key == key)
390 for (i = 0; i < len; i++)
392 if (list[i].key == -1)
394 if (list[i].data_struct == ctx)
434 if (memif_alloc !=
NULL)
441 if (memif_free !=
NULL)
446 if (app_name !=
NULL)
450 strncpy ((
char *) lm->
app_name, app_name, len);
459 if (on_control_fd_update !=
NULL)
468 DBG (
"eventfd: %s", strerror (err));
472 DBG (
"libmemif event polling initialized");
533 lm->
timerfd = timerfd_create (CLOCK_REALTIME, TFD_NONBLOCK);
540 lm->arm.it_value.tv_sec = 2;
541 lm->arm.it_value.tv_nsec = 0;
542 lm->arm.it_interval.tv_sec = 2;
543 lm->arm.it_interval.tv_nsec = 0;
547 DBG (
"callback type memif_control_fd_update_t error!");
563 if (&conn->regions[0] ==
NULL)
565 void *p = conn->regions[0].shm;
568 sizeof (
memif_desc_t) * (1 << conn->run_args.log2_ring_size);
569 p += (ring_num + type * conn->run_args.num_s2m_rings) * ring_size;
582 (conn->args.is_master) ? conn->run_args.num_s2m_rings : conn->run_args.
587 conn->rx_queues[qid].ring->flags = rx_mode;
588 DBG (
"rx_mode flag: %u", conn->rx_queues[qid].ring->flags);
599 int err,
i, index, sockfd = -1;
604 DBG (
"This handle already points to existing memif.");
636 conn->args.mode = args->
mode;
637 conn->msg_queue =
NULL;
638 conn->regions =
NULL;
639 conn->tx_queues =
NULL;
640 conn->rx_queues =
NULL;
645 conn->private_ctx = private_ctx;
649 strncpy ((
char *) conn->args.interface_name, (
char *) args->
interface_name,
654 conn->args.socket_filename = lm->
alloc (
sizeof (
char *) * 108);
655 if (conn->args.socket_filename ==
NULL)
660 memset (conn->args.socket_filename, 0, 108 * sizeof (
char *));
664 if (conn->args.socket_filename ==
NULL)
669 strncpy ((
char *) conn->args.socket_filename,
677 if (conn->args.socket_filename ==
NULL)
682 strncpy ((
char *) conn->args.socket_filename,
684 conn->args.socket_filename[sdl] =
'/';
685 strncpy ((
char *) (conn->args.socket_filename + 1 + sdl),
691 l = strlen ((
char *) args->
secret);
692 strncpy ((
char *) conn->args.secret, (
char *) args->
secret, l);
695 if (conn->args.is_master)
697 conn->run_args.buffer_size = conn->args.buffer_size;
706 ((
char *) ms->
filename, (
char *) conn->args.socket_filename,
707 strlen ((
char *) ms->
filename)) == 0)
710 elt.
key = conn->args.interface_id;
715 conn->listener_fd = ms->
fd;
721 struct stat file_stat;
722 if (stat ((
char *) conn->args.socket_filename, &file_stat) == 0)
724 if (S_ISSOCK (file_stat.st_mode))
725 unlink ((
char *) conn->args.socket_filename);
729 DBG (
"creating socket file");
737 lm->
alloc (strlen ((
char *) conn->args.socket_filename) +
745 strlen ((
char *) conn->args.socket_filename) +
748 (
char *) conn->args.socket_filename,
749 strlen ((
char *) conn->args.socket_filename));
761 struct sockaddr_un un = { 0 };
764 ms->
fd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
770 DBG (
"socket %d created", ms->
fd);
771 un.sun_family = AF_UNIX;
772 strncpy ((
char *) un.sun_path, (
char *) ms->
filename,
773 sizeof (un.sun_path) - 1);
776 (ms->
fd, SOL_SOCKET, SO_PASSCRED, &on, sizeof (on)) < 0)
782 if (bind (ms->
fd, (
struct sockaddr *) &un, sizeof (un)) < 0)
788 if (listen (ms->
fd, 1) < 0)
794 if (stat ((
char *) ms->
filename, &file_stat) < 0)
801 elt.
key = conn->args.interface_id;
806 conn->listener_fd = ms->
fd;
821 if (timerfd_settime (lm->
timerfd, 0, &lm->arm,
NULL) < 0)
849 if (conn->args.socket_filename)
850 lm->
free (conn->args.socket_filename);
869 size = read (fd, &b,
sizeof (b));
876 if (conn->args.is_master)
879 struct sockaddr_un sun;
880 sockfd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
887 sun.sun_family = AF_UNIX;
889 strncpy (sun.sun_path, conn->args.socket_filename,
890 sizeof (sun.sun_path) - 1);
892 if (connect (sockfd, (
struct sockaddr *) &sun,
893 sizeof (
struct sockaddr_un)) == 0)
936 data_struct)->run_args.
938 for (i = 0; i < num; i++)
944 data_struct)->on_interrupt ((
void *) e->
data_struct,
1012 struct epoll_event evt, *e;
1015 uint32_t events = 0;
1016 uint64_t counter = 0;
1018 memset (&evt, 0,
sizeof (evt));
1019 evt.events = EPOLLIN | EPOLLOUT;
1021 sigemptyset (&sigset);
1022 en = epoll_pwait (
memif_epfd, &evt, 1, timeout, &sigset);
1026 DBG (
"epoll_pwait: %s", strerror (err));
1033 r = read (evt.data.fd, &counter, sizeof (counter));
1036 if (evt.events & EPOLLIN)
1038 if (evt.events & EPOLLOUT)
1040 if (evt.events & EPOLLERR)
1051 uint64_t counter = 1;
1057 if (w <
sizeof (counter))
1080 DBG (
"no connection");
1089 c->on_disconnect ((
void *) c, c->private_ctx);
1100 if (c->args.is_master)
1102 e->
key = c->fd = -1;
1105 if (c->tx_queues !=
NULL)
1108 (c->args.is_master) ? c->run_args.num_m2s_rings : c->run_args.
1110 for (i = 0; i < num; i++)
1112 mq = &c->tx_queues[
i];
1122 lm->
free (c->tx_queues);
1123 c->tx_queues =
NULL;
1126 if (c->rx_queues !=
NULL)
1129 (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
1131 for (i = 0; i < num; i++)
1133 mq = &c->rx_queues[
i];
1138 if (c->on_interrupt !=
NULL)
1147 lm->
free (c->rx_queues);
1148 c->rx_queues =
NULL;
1151 if (c->regions !=
NULL)
1153 if (munmap (c->regions[0].shm, c->regions[0].region_size) < 0)
1155 if (c->regions[0].fd > 0)
1156 close (c->regions[0].fd);
1157 c->regions[0].fd = -1;
1158 lm->
free (c->regions);
1166 if (!(c->args.is_master))
1170 if (timerfd_settime (lm->
timerfd, 0, &lm->arm,
NULL) < 0)
1173 DBG (
"timerfd_settime: arm");
1188 DBG (
"no connection");
1199 DBG (
"DISCONNECTING");
1207 if (c->args.is_master)
1216 c->args.interface_id);
1222 close (c->listener_fd);
1223 c->listener_fd = ms->
fd = -1;
1241 DBG (
"timerfd_settime: disarm");
1246 if (c->args.socket_filename)
1247 lm->
free (c->args.socket_filename);
1248 c->args.socket_filename =
NULL;
1274 MAP_SHARED, mr->
fd, 0)) == MAP_FAILED)
1282 (c->args.is_master) ? c->run_args.num_m2s_rings : c->run_args.
1284 for (i = 0; i < num; i++)
1286 mq = &c->tx_queues[
i];
1292 DBG (
"wrong cookie on tx ring %u", i);
1300 (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
1302 for (i = 0; i < num; i++)
1304 mq = &c->rx_queues[
i];
1310 DBG (
"wrong cookie on rx ring %u", i);
1333 if (conn->regions ==
NULL)
1338 (conn->run_args.num_s2m_rings +
1339 conn->run_args.num_m2s_rings) * (
sizeof (
memif_ring_t) +
1341 (1 << conn->run_args.log2_ring_size));
1344 conn->run_args.buffer_size * (1 << conn->run_args.log2_ring_size) *
1345 (conn->run_args.num_s2m_rings + conn->run_args.num_m2s_rings);
1359 MAP_SHARED, r->
fd, 0)) == MAP_FAILED)
1362 for (i = 0; i < conn->run_args.num_s2m_rings; i++)
1365 DBG (
"RING: %p I: %d", ring, i);
1369 for (j = 0; j < (1 << conn->run_args.log2_ring_size); j++)
1371 uint16_t slot = i * (1 << conn->run_args.log2_ring_size) + j;
1374 (uint32_t) (slot * conn->run_args.buffer_size);
1375 ring->
desc[j].
length = conn->run_args.buffer_size;
1378 for (i = 0; i < conn->run_args.num_m2s_rings; i++)
1381 DBG (
"RING: %p I: %d", ring, i);
1385 for (j = 0; j < (1 << conn->run_args.log2_ring_size); j++)
1389 conn->run_args.num_s2m_rings) *
1390 (1 << conn->run_args.log2_ring_size) + j;
1393 (uint32_t) (slot * conn->run_args.buffer_size);
1394 ring->
desc[j].
length = conn->run_args.buffer_size;
1400 conn->run_args.num_s2m_rings);
1404 for (x = 0; x < conn->run_args.num_s2m_rings; x++)
1406 if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
1414 DBG (
"RING: %p I: %d", mq[x].ring, x);
1418 (
void *) mq[x].ring - (
void *) conn->regions[mq->
region].shm;
1422 conn->tx_queues = mq;
1426 conn->run_args.num_m2s_rings);
1429 for (x = 0; x < conn->run_args.num_m2s_rings; x++)
1431 if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
1439 DBG (
"RING: %p I: %d", mq[x].ring, x);
1443 (
void *) mq[x].ring - (
void *) conn->regions[mq->
region].shm;
1447 conn->rx_queues = mq;
1455 uint16_t * count_out)
1463 (c->args.is_master) ? c->run_args.num_m2s_rings : c->run_args.
1484 slot = (c->args.is_master) ? ring->
tail : ring->
head;
1505 (uint32_t) (b0->
data - c->regions->shm);
1520 DBG (
"allocated: %u/%u bufs. Total %u allocated bufs", *count_out, count,
1525 DBG (
"ring buffer full! qid: %u", qid);
1536 uint16_t * count_out, uint16_t
size)
1544 (c->args.is_master) ? c->run_args.num_m2s_rings : c->run_args.
1558 uint16_t dst_left, src_left;
1559 uint16_t saved_count;
1566 slot = (c->args.is_master) ? ring->
tail : ring->
head;
1569 if (c->args.is_master)
1576 b0 = (bufs + *count_out);
1579 saved_count =
count;
1585 dst_left = (c->args.is_master) ? ring->
desc[slot & mask].
length :
1586 c->run_args.buffer_size;
1605 b0 = (bufs + *count_out);
1608 (c->args.is_master) ? ring->
desc[slot & mask].
length : c->
1609 run_args.buffer_size;
1616 * (saved_count - count + 1));
1617 *count_out -= saved_count -
count;
1625 if (c->args.is_master == 0)
1629 c->regions->buffer_offset) / c->run_args.buffer_size;
1631 c->regions->buffer_offset + (x * c->run_args.buffer_size);
1636 src_left -= b0->
len;
1637 dst_left -= b0->
len;
1649 DBG (
"allocated: %u/%u bufs. Total %u allocated bufs", *count_out, count,
1654 DBG (
"ring buffer full! qid: %u", qid);
1672 (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
1682 if (c->args.is_master)
1686 (ring->
tail + count <=
1691 uint16_t head = ring->
head;
1693 head += (count < ns) ? count : ns;
1697 slot = (c->args.is_master) ? ring->
head : ring->
tail;
1702 c->regions->buffer_offset) / c->run_args.buffer_size;
1704 c->regions->buffer_offset + (x * c->run_args.buffer_size) +
1727 (c->args.is_master) ? c->run_args.num_m2s_rings : c->run_args.
1751 #ifdef MEMIF_DBG_SHM 1753 printf (
"data: %p\n",
1766 if (c->args.is_master)
1776 int r = write (mq->
int_fd, &a, sizeof (a));
1794 (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
1803 uint16_t cur_slot, last_slot;
1810 ssize_t r = read (mq->
int_fd, &b, sizeof (b));
1815 last_slot = (c->args.is_master) ? ring->
head : ring->
tail;
1816 if (cur_slot == last_slot)
1819 ns = last_slot - cur_slot;
1829 if (c->args.is_master == 0)
1831 ring->
desc[cur_slot & mask].
length = c->run_args.buffer_size;
1838 ring->
desc[cur_slot & mask].
flags &= ~MEMIF_DESC_FLAG_NEXT;
1842 #ifdef MEMIF_DBG_SHM 1843 printf (
"data: %p\n", b0->
data);
1845 printf (
"ring: %p\n", b0->
ring);
1855 if (c->args.is_master)
1862 DBG (
"not enough buffers!");
1871 char *buf, ssize_t buflen)
1879 ssize_t l0, l1, total_l;
1882 l1 = strlen ((
char *) c->args.interface_name);
1883 if (l0 + l1 < buflen)
1885 md->
if_name = strcpy (buf + l0, (
char *) c->args.interface_name);
1891 l1 = strlen ((
char *) lm->
app_name);
1892 if (l0 + l1 < buflen)
1900 l1 = strlen ((
char *) c->remote_if_name);
1901 if (l0 + l1 < buflen)
1903 md->
remote_if_name = strcpy (buf + l0, (
char *) c->remote_if_name);
1909 l1 = strlen ((
char *) c->remote_name);
1910 if (l0 + l1 < buflen)
1918 md->
id = c->args.interface_id;
1922 l1 = strlen ((
char *) c->args.secret);
1923 if (l0 + l1 < buflen)
1925 md->
secret = strcpy (buf + l0, (
char *) c->args.secret);
1932 md->
role = (c->args.is_master) ? 0 : 1;
1933 md->
mode = c->args.mode;
1935 l1 = strlen ((
char *) c->args.socket_filename);
1936 if (l0 + l1 < buflen)
1939 strcpy (buf + l0, (
char *) c->args.socket_filename);
1946 (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
1950 if (l0 + l1 <= buflen)
1969 (c->args.is_master) ? c->run_args.num_m2s_rings : c->run_args.
1973 if (l0 + l1 <= buflen)
2006 (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
2011 *efd = c->rx_queues[qid].int_fd;
#define MEMIF_DEFAULT_LOG2_RING_SIZE
static void memif_free_register(memif_free_t *mf)
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)
static void memif_msg_queue_free(libmemif_main_t *lm, memif_msg_queue_elt_t **e)
memif_list_elt_t * pending_list
for(i=1;i<=collision_buckets;i++)
#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)
int memif_refill_queue(memif_conn_handle_t conn, uint16_t qid, uint16_t count, uint16_t headroom)
Memif refill ring.
#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)
static void memif_alloc_register(memif_alloc_t *ma)
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)
struct itimerspec arm disarm
char * memif_strerror(int err_code)
Memif strerror.
memif_region_offset_t offset
#define MEMIF_MAX_LOG2_RING_SIZE
#define MEMIF_BUFFER_FLAG_NEXT
next buffer present (chained buffers)
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_init(memif_control_fd_update_t *on_control_fd_update, char *app_name, memif_alloc_t *memif_alloc, memif_free_t *memif_free)
Memif initialization.
int memif_get_queue_efd(memif_conn_handle_t conn, uint16_t qid, int *efd)
Memif get queue event file descriptor
#define MEMIF_BUFFER_FLAG_RX
states that buffer is from rx ring
#define MFD_ALLOW_SEALING
int memif_buffer_enq_tx(memif_conn_handle_t conn, uint16_t qid, memif_buffer_t *bufs, uint16_t count, uint16_t *count_out)
Memif buffer enq tx.
#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)
void( memif_free_t)(void *ptr)
Memif allocator free.
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
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
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
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.
uint8_t app_name[MEMIF_NAME_LEN]
#define MEMIF_DEFAULT_SOCKET_FILENAME
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
uint16_t memif_get_version()
Memif get version.
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
void *( memif_alloc_t)(size_t size)
Memif allocator alloc.
int memif_control_fd_update(int fd, uint8_t events)