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> 59 #define ERRLIST_LEN 39 60 #define MAX_ERRBUF_LEN 256 63 #define MEMIF_MEMORY_BARRIER() __builtin_ia32_sfence () 65 #define MEMIF_MEMORY_BARRIER() __sync_synchronize () 77 "Unspecified syscall error (build with -DMEMIF_DBG or make debug).",
79 "Permission to resoure denied.",
81 "Socket file does not exist",
83 "System limit on total numer of open files reached.",
85 "Per-process limit on total number of open files reached.",
87 "Connection already requested.",
89 "File descriptor refers to file other than socket, or operation would block.",
91 "Bad file descriptor.",
97 "Memif connection handle does not point to existing conenction",
99 "Memif connection handle points to existing connection",
101 "Callback memif_control_fd_update_t returned error",
103 "File specified by socket filename exists and is not socket.",
105 "Missing shared memory file descriptor. (internal error)",
107 "Invalid cookie on ring. (internal error)",
111 "Not enough memif buffers. There are unreceived data in shared memory.",
113 "Not enough space for memif details in suplied buffer. String data might be malformed.",
115 "Send interrupt error.",
117 "Malformed message received on control channel.",
121 "Incompatible memory interface protocol version.",
123 "Unmatched interface id.",
125 "Slave cannot accept connection reqest.",
127 "Interface is already connected.",
135 "Limit on total number of regions reached.",
137 "Limit on total number of ring reached.",
139 "Missing interrupt file descriptor. (internal error)",
141 "Interface received disconnect request.",
143 "Interface is disconnected.",
145 "Unknown message type received on control channel. (internal error)",
147 "Memif event polling was canceled.",
149 "Maximum log2 ring size is 15",
151 "Private headers not supported." 154 #define MEMIF_ERR_UNDEFINED "undefined error" 179 #define DBG_TX_BUF (0) 180 #define DBG_RX_BUF (1) 184 print_bytes (
void *data, uint16_t len, uint8_t q)
187 printf (
"\nTX:\n\t");
189 printf (
"\nRX:\n\t");
191 for (i = 0; i < len; i++)
194 printf (
"\n%d:\t", i);
195 printf (
"%02X ", ((uint8_t *) (data))[i]);
204 DBG (
"%s", strerror (err_code));
208 if (err_code == EACCES)
210 if (err_code == ENFILE)
212 if (err_code == EMFILE)
214 if (err_code == ENOMEM)
218 if (err_code == ECONNREFUSED)
220 if (err_code == EALREADY)
222 if (err_code == EAGAIN)
224 if (err_code == EBADF)
226 if (err_code == ENOENT)
238 DBG (
"invalid fd %d", fd);
241 struct epoll_event evt;
242 memset (&evt, 0,
sizeof (evt));
245 if (epoll_ctl (
memif_epfd, EPOLL_CTL_ADD, fd, &evt) < 0)
247 DBG (
"epoll_ctl: %s fd %d", strerror (errno), fd);
250 DBG (
"fd %d added to epoll", fd);
259 DBG (
"invalid fd %d", fd);
262 struct epoll_event evt;
263 memset (&evt, 0,
sizeof (evt));
266 if (epoll_ctl (
memif_epfd, EPOLL_CTL_MOD, fd, &evt) < 0)
268 DBG (
"epoll_ctl: %s fd %d", strerror (errno), fd);
271 DBG (
"fd %d moddified on epoll", fd);
280 DBG (
"invalid fd %d", fd);
283 struct epoll_event evt;
284 memset (&evt, 0,
sizeof (evt));
285 if (epoll_ctl (
memif_epfd, EPOLL_CTL_DEL, fd, &evt) < 0)
287 DBG (
"epoll_ctl: %s fd %d", strerror (errno), fd);
290 DBG (
"fd %d removed from epoll", fd);
318 for (i = 0; i < *len; i++)
320 if ((*list)[i].data_struct ==
NULL)
322 (*list)[
i].key = e->
key;
332 for (i = *len; i < *len * 2; i++)
357 for (i = 0; i < len; i++)
359 if (list[i].key == key)
374 for (i = 0; i < len; i++)
376 if (list[i].key == key)
392 for (i = 0; i < len; i++)
394 if (list[i].key == -1)
396 if (list[i].data_struct == ctx)
436 if (memif_alloc !=
NULL)
443 if (memif_free !=
NULL)
448 if (app_name !=
NULL)
452 strncpy ((
char *) lm->
app_name, app_name, len);
461 if (on_control_fd_update !=
NULL)
470 DBG (
"eventfd: %s", strerror (err));
474 DBG (
"libmemif event polling initialized");
535 lm->
timerfd = timerfd_create (CLOCK_REALTIME, TFD_NONBLOCK);
542 lm->arm.it_value.tv_sec = 2;
543 lm->arm.it_value.tv_nsec = 0;
544 lm->arm.it_interval.tv_sec = 2;
545 lm->arm.it_interval.tv_nsec = 0;
549 DBG (
"callback type memif_control_fd_update_t error!");
565 if (&conn->regions[0] ==
NULL)
567 void *p = conn->regions[0].shm;
570 sizeof (
memif_desc_t) * (1 << conn->run_args.log2_ring_size);
571 p += (ring_num + type * conn->run_args.num_s2m_rings) * ring_size;
584 (conn->args.is_master) ? conn->run_args.num_s2m_rings : conn->run_args.
589 conn->rx_queues[qid].ring->flags = rx_mode;
590 DBG (
"rx_mode flag: %u", conn->rx_queues[qid].ring->flags);
601 int err,
i, index, sockfd = -1;
606 DBG (
"This handle already points to existing memif.");
638 conn->args.mode = args->
mode;
639 conn->msg_queue =
NULL;
640 conn->regions =
NULL;
641 conn->tx_queues =
NULL;
642 conn->rx_queues =
NULL;
647 conn->private_ctx = private_ctx;
651 strncpy ((
char *) conn->args.interface_name, (
char *) args->
interface_name,
656 conn->args.socket_filename = lm->
alloc (
sizeof (
char *) * 108);
657 if (conn->args.socket_filename ==
NULL)
662 memset (conn->args.socket_filename, 0, 108 * sizeof (
char *));
666 if (conn->args.socket_filename ==
NULL)
671 strncpy ((
char *) conn->args.socket_filename,
679 if (conn->args.socket_filename ==
NULL)
684 strncpy ((
char *) conn->args.socket_filename,
686 conn->args.socket_filename[sdl] =
'/';
687 strncpy ((
char *) (conn->args.socket_filename + 1 + sdl),
691 if ((l = strlen ((
char *) args->
secret)) > 0)
693 strncpy ((
char *) conn->args.secret, (
char *) args->
secret, l);
696 if (conn->args.is_master)
698 conn->run_args.buffer_size = conn->args.buffer_size;
707 ((
char *) ms->
filename, (
char *) conn->args.socket_filename,
708 strlen ((
char *) ms->
filename)) == 0)
711 elt.
key = conn->args.interface_id;
716 conn->listener_fd = ms->
fd;
722 struct stat file_stat;
723 if (stat ((
char *) conn->args.socket_filename, &file_stat) == 0)
725 if (S_ISSOCK (file_stat.st_mode))
726 unlink ((
char *) conn->args.socket_filename);
730 DBG (
"creating socket file");
738 lm->
alloc (strlen ((
char *) conn->args.socket_filename) +
746 strlen ((
char *) conn->args.socket_filename) +
749 (
char *) conn->args.socket_filename,
750 strlen ((
char *) conn->args.socket_filename));
762 struct sockaddr_un un = { 0 };
765 ms->
fd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
771 DBG (
"socket %d created", ms->
fd);
772 un.sun_family = AF_UNIX;
773 strncpy ((
char *) un.sun_path, (
char *) ms->
filename,
774 sizeof (un.sun_path) - 1);
777 (ms->
fd, SOL_SOCKET, SO_PASSCRED, &on, sizeof (on)) < 0)
783 if (bind (ms->
fd, (
struct sockaddr *) &un, sizeof (un)) < 0)
789 if (listen (ms->
fd, 1) < 0)
795 if (stat ((
char *) ms->
filename, &file_stat) < 0)
802 elt.
key = conn->args.interface_id;
807 conn->listener_fd = ms->
fd;
822 if (timerfd_settime (lm->
timerfd, 0, &lm->arm,
NULL) < 0)
850 if (conn->args.socket_filename)
851 lm->
free (conn->args.socket_filename);
870 size = read (fd, &b,
sizeof (b));
877 if (conn->args.is_master)
880 struct sockaddr_un sun;
881 sockfd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
888 sun.sun_family = AF_UNIX;
890 strncpy (sun.sun_path, (
char*) conn->args.socket_filename,
891 sizeof (sun.sun_path) - 1);
893 if (connect (sockfd, (
struct sockaddr *) &sun,
894 sizeof (
struct sockaddr_un)) == 0)
937 data_struct)->run_args.
939 for (i = 0; i < num; i++)
945 data_struct)->on_interrupt ((
void *) e->
data_struct,
1013 struct epoll_event evt, *e;
1016 uint32_t events = 0;
1017 uint64_t counter = 0;
1019 memset (&evt, 0,
sizeof (evt));
1020 evt.events = EPOLLIN | EPOLLOUT;
1022 sigemptyset (&sigset);
1023 en = epoll_pwait (
memif_epfd, &evt, 1, timeout, &sigset);
1027 DBG (
"epoll_pwait: %s", strerror (err));
1034 r = read (evt.data.fd, &counter, sizeof (counter));
1037 if (evt.events & EPOLLIN)
1039 if (evt.events & EPOLLOUT)
1041 if (evt.events & EPOLLERR)
1052 uint64_t counter = 1;
1058 if (w <
sizeof (counter))
1081 DBG (
"no connection");
1090 c->on_disconnect ((
void *) c, c->private_ctx);
1101 if (c->args.is_master)
1103 e->
key = c->fd = -1;
1106 if (c->tx_queues !=
NULL)
1109 (c->args.is_master) ? c->run_args.num_m2s_rings : c->run_args.
1111 for (i = 0; i < num; i++)
1113 mq = &c->tx_queues[
i];
1123 lm->
free (c->tx_queues);
1124 c->tx_queues =
NULL;
1127 if (c->rx_queues !=
NULL)
1130 (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
1132 for (i = 0; i < num; i++)
1134 mq = &c->rx_queues[
i];
1139 if (c->on_interrupt !=
NULL)
1148 lm->
free (c->rx_queues);
1149 c->rx_queues =
NULL;
1152 if (c->regions !=
NULL)
1154 if (munmap (c->regions[0].shm, c->regions[0].region_size) < 0)
1156 if (c->regions[0].fd > 0)
1157 close (c->regions[0].fd);
1158 c->regions[0].fd = -1;
1159 lm->
free (c->regions);
1167 if (!(c->args.is_master))
1171 if (timerfd_settime (lm->
timerfd, 0, &lm->arm,
NULL) < 0)
1174 DBG (
"timerfd_settime: arm");
1189 DBG (
"no connection");
1200 DBG (
"DISCONNECTING");
1208 if (c->args.is_master)
1217 c->args.interface_id);
1223 close (c->listener_fd);
1224 c->listener_fd = ms->
fd = -1;
1242 DBG (
"timerfd_settime: disarm");
1247 if (c->args.socket_filename)
1248 lm->
free (c->args.socket_filename);
1249 c->args.socket_filename =
NULL;
1275 MAP_SHARED, mr->
fd, 0)) == MAP_FAILED)
1283 (c->args.is_master) ? c->run_args.num_m2s_rings : c->run_args.
1285 for (i = 0; i < num; i++)
1287 mq = &c->tx_queues[
i];
1293 DBG (
"wrong cookie on tx ring %u", i);
1301 (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
1303 for (i = 0; i < num; i++)
1305 mq = &c->rx_queues[
i];
1311 DBG (
"wrong cookie on rx ring %u", i);
1334 if (conn->regions ==
NULL)
1339 (conn->run_args.num_s2m_rings +
1340 conn->run_args.num_m2s_rings) * (
sizeof (
memif_ring_t) +
1342 (1 << conn->run_args.log2_ring_size));
1345 conn->run_args.buffer_size * (1 << conn->run_args.log2_ring_size) *
1346 (conn->run_args.num_s2m_rings + conn->run_args.num_m2s_rings);
1360 MAP_SHARED, r->
fd, 0)) == MAP_FAILED)
1363 for (i = 0; i < conn->run_args.num_s2m_rings; i++)
1366 DBG (
"RING: %p I: %d", ring, i);
1370 for (j = 0; j < (1 << conn->run_args.log2_ring_size); j++)
1372 uint16_t slot = i * (1 << conn->run_args.log2_ring_size) + j;
1375 (uint32_t) (slot * conn->run_args.buffer_size);
1376 ring->
desc[j].
length = conn->run_args.buffer_size;
1379 for (i = 0; i < conn->run_args.num_m2s_rings; i++)
1382 DBG (
"RING: %p I: %d", ring, i);
1386 for (j = 0; j < (1 << conn->run_args.log2_ring_size); j++)
1390 conn->run_args.num_s2m_rings) *
1391 (1 << conn->run_args.log2_ring_size) + j;
1394 (uint32_t) (slot * conn->run_args.buffer_size);
1395 ring->
desc[j].
length = conn->run_args.buffer_size;
1401 conn->run_args.num_s2m_rings);
1405 for (x = 0; x < conn->run_args.num_s2m_rings; x++)
1407 if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
1415 DBG (
"RING: %p I: %d", mq[x].ring, x);
1419 (
void *) mq[x].ring - (
void *) conn->regions[mq->
region].shm;
1423 conn->tx_queues = mq;
1427 conn->run_args.num_m2s_rings);
1430 for (x = 0; x < conn->run_args.num_m2s_rings; x++)
1432 if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
1440 DBG (
"RING: %p I: %d", mq[x].ring, x);
1444 (
void *) mq[x].ring - (
void *) conn->regions[mq->
region].shm;
1448 conn->rx_queues = mq;
1456 uint16_t * count_out)
1464 (c->args.is_master) ? c->run_args.num_m2s_rings : c->run_args.
1485 slot = (c->args.is_master) ? ring->
tail : ring->
head;
1506 (uint32_t) (b0->
data - c->regions->shm);
1521 DBG (
"allocated: %u/%u bufs. Total %u allocated bufs", *count_out, count,
1526 DBG (
"ring buffer full! qid: %u", qid);
1537 uint16_t * count_out, uint16_t
size)
1545 (c->args.is_master) ? c->run_args.num_m2s_rings : c->run_args.
1559 uint16_t dst_left, src_left;
1560 uint16_t saved_count;
1567 slot = (c->args.is_master) ? ring->
tail : ring->
head;
1570 if (c->args.is_master)
1577 b0 = (bufs + *count_out);
1580 saved_count =
count;
1586 dst_left = (c->args.is_master) ? ring->
desc[slot & mask].
length :
1587 c->run_args.buffer_size;
1606 b0 = (bufs + *count_out);
1609 (c->args.is_master) ? ring->
desc[slot & mask].
length : c->
1610 run_args.buffer_size;
1617 * (saved_count - count + 1));
1618 *count_out -= saved_count -
count;
1626 if (c->args.is_master == 0)
1630 c->regions->buffer_offset) / c->run_args.buffer_size;
1632 c->regions->buffer_offset + (x * c->run_args.buffer_size);
1637 src_left -= b0->
len;
1638 dst_left -= b0->
len;
1650 DBG (
"allocated: %u/%u bufs. Total %u allocated bufs", *count_out, count,
1655 DBG (
"ring buffer full! qid: %u", qid);
1673 (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
1683 if (c->args.is_master)
1687 (ring->
tail + count <=
1692 uint16_t head = ring->
head;
1694 head += (count < ns) ? count : ns;
1698 slot = (c->args.is_master) ? ring->
head : ring->
tail;
1703 c->regions->buffer_offset) / c->run_args.buffer_size;
1705 c->regions->buffer_offset + (x * c->run_args.buffer_size) +
1728 (c->args.is_master) ? c->run_args.num_m2s_rings : c->run_args.
1752 #ifdef MEMIF_DBG_SHM 1754 printf (
"data: %p\n",
1767 if (c->args.is_master)
1777 int r = write (mq->
int_fd, &a, sizeof (a));
1795 (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
1804 uint16_t cur_slot, last_slot;
1811 ssize_t r = read (mq->
int_fd, &b, sizeof (b));
1816 last_slot = (c->args.is_master) ? ring->
head : ring->
tail;
1817 if (cur_slot == last_slot)
1820 ns = last_slot - cur_slot;
1830 if (c->args.is_master == 0)
1832 ring->
desc[cur_slot & mask].
length = c->run_args.buffer_size;
1839 ring->
desc[cur_slot & mask].
flags &= ~MEMIF_DESC_FLAG_NEXT;
1843 #ifdef MEMIF_DBG_SHM 1844 printf (
"data: %p\n", b0->
data);
1846 printf (
"ring: %p\n", b0->
ring);
1856 if (c->args.is_master)
1863 DBG (
"not enough buffers!");
1872 char *buf, ssize_t buflen)
1880 ssize_t l0, l1, total_l;
1883 l1 = strlen ((
char *) c->args.interface_name);
1884 if (l0 + l1 < buflen)
1886 md->
if_name = (uint8_t *) strcpy (buf + l0, (
char *) c->args.interface_name);
1892 l1 = strlen ((
char *) lm->
app_name);
1893 if (l0 + l1 < buflen)
1901 l1 = strlen ((
char *) c->remote_if_name);
1902 if (l0 + l1 < buflen)
1904 md->
remote_if_name = (uint8_t *) strcpy (buf + l0, (
char *) c->remote_if_name);
1910 l1 = strlen ((
char *) c->remote_name);
1911 if (l0 + l1 < buflen)
1913 md->
remote_inst_name = (uint8_t *) strcpy (buf + l0, (
char *) c->remote_name);
1919 md->
id = c->args.interface_id;
1921 if (strlen((
char *) c->args.secret) > 0)
1923 l1 = strlen ((
char *) c->args.secret);
1924 if (l0 + l1 < buflen)
1926 md->
secret = (uint8_t *) strcpy (buf + l0, (
char *) c->args.secret);
1933 md->
role = (c->args.is_master) ? 0 : 1;
1934 md->
mode = c->args.mode;
1936 l1 = strlen ((
char *) c->args.socket_filename);
1937 if (l0 + l1 < buflen)
1940 (uint8_t *) strcpy (buf + l0, (
char *) c->args.socket_filename);
1947 (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
1951 if (l0 + l1 <= buflen)
1970 (c->args.is_master) ? c->run_args.num_m2s_rings : c->run_args.
1974 if (l0 + l1 <= buflen)
2007 (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
2012 *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)