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 40 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).",
81 "Permission to resoure denied.",
83 "Socket file does not exist",
85 "System limit on total numer of open files reached.",
87 "Per-process limit on total number of open files reached.",
89 "Connection already requested.",
91 "File descriptor refers to file other than socket, or operation would block.",
93 "Bad file descriptor.",
99 "Memif connection handle does not point to existing conenction",
101 "Memif connection handle points to existing connection",
103 "Callback memif_control_fd_update_t returned error",
105 "File specified by socket filename exists and is not socket.",
107 "Missing shared memory file descriptor. (internal error)",
109 "Invalid cookie on ring. (internal error)",
113 "Not enough memif buffers. There are unreceived data in shared memory.",
115 "Not enough space for memif details in suplied buffer. String data might be malformed.",
117 "Send interrupt error.",
119 "Malformed message received on control channel.",
123 "Incompatible memory interface protocol version.",
125 "Unmatched interface id.",
127 "Slave cannot accept connection reqest.",
129 "Interface is already connected.",
137 "Limit on total number of regions reached.",
139 "Limit on total number of ring reached.",
141 "Missing interrupt file descriptor. (internal error)",
143 "Interface received disconnect request.",
145 "Interface is disconnected.",
147 "Unknown message type received on control channel. (internal error)",
149 "Memif event polling was canceled.",
151 "Maximum log2 ring size is 15",
153 "Private headers not supported." 156 #define MEMIF_ERR_UNDEFINED "undefined error" 181 #define DBG_TX_BUF (0) 182 #define DBG_RX_BUF (1) 186 print_bytes (
void *
data, uint16_t
len, uint8_t q)
189 printf (
"\nTX:\n\t");
191 printf (
"\nRX:\n\t");
193 for (i = 0; i <
len; i++)
196 printf (
"\n%d:\t", i);
197 printf (
"%02X ", ((uint8_t *) (data))[i]);
206 DBG (
"%s", strerror (err_code));
210 if (err_code == EACCES)
212 if (err_code == ENFILE)
214 if (err_code == EMFILE)
216 if (err_code == ENOMEM)
224 if (err_code == ECONNREFUSED)
226 if (err_code == EALREADY)
228 if (err_code == EAGAIN)
230 if (err_code == EBADF)
232 if (err_code == ENOENT)
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_ADD, fd, &evt) < 0)
253 DBG (
"epoll_ctl: %s fd %d", strerror (errno), fd);
256 DBG (
"fd %d added to epoll", fd);
265 DBG (
"invalid fd %d", fd);
268 struct epoll_event evt;
269 memset (&evt, 0,
sizeof (evt));
272 if (epoll_ctl (
memif_epfd, EPOLL_CTL_MOD, fd, &evt) < 0)
274 DBG (
"epoll_ctl: %s fd %d", strerror (errno), fd);
277 DBG (
"fd %d moddified on epoll", fd);
286 DBG (
"invalid fd %d", fd);
289 struct epoll_event evt;
290 memset (&evt, 0,
sizeof (evt));
291 if (epoll_ctl (
memif_epfd, EPOLL_CTL_DEL, fd, &evt) < 0)
293 DBG (
"epoll_ctl: %s fd %d", strerror (errno), fd);
296 DBG (
"fd %d removed from epoll", fd);
325 for (i = 0; i < *
len; i++)
327 if ((*list)[i].data_struct ==
NULL)
329 (*list)[
i].key = e->
key;
339 for (i = *len; i < *len * 2; i++)
365 for (i = 0; i <
len; i++)
367 if (list[i].key == key)
382 for (i = 0; i <
len; i++)
384 if (list[i].key == key)
400 for (i = 0; i <
len; i++)
402 if (list[i].
key == -1)
404 if (list[i].data_struct == ctx)
467 if (timerfd_settime (lm->
timerfd, 0, &lm->arm,
NULL) < 0)
484 if (memif_alloc !=
NULL)
491 if (memif_realloc !=
NULL)
498 if (memif_free !=
NULL)
503 if (app_name !=
NULL)
507 strncpy ((
char *) lm->
app_name, app_name, len);
516 if (on_control_fd_update !=
NULL)
525 DBG (
"eventfd: %s", strerror (err));
529 DBG (
"libmemif event polling initialized");
590 lm->
timerfd = timerfd_create (CLOCK_REALTIME, TFD_NONBLOCK);
604 DBG (
"callback type memif_control_fd_update_t error!");
620 if (&conn->regions[0] ==
NULL)
622 void *p = conn->regions[0].addr;
625 sizeof (
memif_desc_t) * (1 << conn->run_args.log2_ring_size);
626 p += (ring_num + type * conn->run_args.num_s2m_rings) * ring_size;
639 (conn->args.is_master) ? conn->run_args.num_s2m_rings : conn->
640 run_args.num_m2s_rings;
644 conn->rx_queues[qid].ring->flags = rx_mode;
645 DBG (
"rx_mode flag: %u", conn->rx_queues[qid].ring->flags);
654 struct stat file_stat;
655 struct sockaddr_un un = { 0 };
663 if (stat ((
char *) ms->
filename, &file_stat) == 0)
665 if (S_ISSOCK (file_stat.st_mode))
671 ms->
fd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
678 DBG (
"socket %d created", ms->
fd);
679 un.sun_family = AF_UNIX;
680 strncpy ((
char *) un.sun_path, (
char *) ms->
filename,
681 sizeof (un.sun_path) - 1);
682 if (setsockopt (ms->
fd, SOL_SOCKET, SO_PASSCRED, &on, sizeof (on)) < 0)
687 if (bind (ms->
fd, (
struct sockaddr *) &un, sizeof (un)) < 0)
692 if (listen (ms->
fd, 1) < 0)
697 if (stat ((
char *) ms->
filename, &file_stat) < 0)
734 if (strncmp ((
char *) ms->
filename, filename,
735 strlen ((
char *) ms->
filename)) == 0)
750 ms->
filename = lm->
alloc (strlen (filename) +
sizeof (
char));
756 memset (ms->
filename, 0, strlen (filename) +
sizeof (
char));
757 strncpy ((
char *) ms->
filename, filename, strlen (filename));
815 DBG (
"This handle already points to existing memif.");
847 conn->args.mode = args->
mode;
848 conn->msg_queue =
NULL;
849 conn->regions =
NULL;
850 conn->tx_queues =
NULL;
851 conn->rx_queues =
NULL;
856 conn->private_ctx = private_ctx;
860 strncpy ((
char *) conn->args.interface_name, (
char *) args->
interface_name,
863 if ((l = strlen ((
char *) args->
secret)) > 0)
864 strncpy ((
char *) conn->args.secret, (
char *) args->
secret, l);
867 conn->args.socket = args->
socket;
890 elt.
key = conn->args.interface_id;
895 if (conn->args.is_master)
920 if (timerfd_settime (lm->
timerfd, 0, &lm->arm,
NULL) < 0)
948 struct sockaddr_un sun;
960 sockfd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
967 sun.sun_family = AF_UNIX;
969 strncpy (sun.sun_path, (
char *) ms->
filename, sizeof (sun.sun_path) - 1);
971 if (connect (sockfd, (
struct sockaddr *) &sun,
972 sizeof (
struct sockaddr_un)) == 0)
998 strcpy ((
char *) conn->remote_disconnect_string,
1026 size = read (fd, &b,
sizeof (b));
1037 if (conn->args.is_master)
1055 data_struct)->run_args.
1057 run_args.num_m2s_rings;
1058 for (i = 0; i < num; i++)
1061 rx_queues[i].int_fd == fd)
1066 data_struct)->private_ctx, i);
1129 struct epoll_event evt;
1131 uint32_t events = 0;
1132 uint64_t counter = 0;
1134 memset (&evt, 0,
sizeof (evt));
1135 evt.events = EPOLLIN | EPOLLOUT;
1137 sigemptyset (&sigset);
1138 en = epoll_pwait (
memif_epfd, &evt, 1, timeout, &sigset);
1142 DBG (
"epoll_pwait: %s", strerror (err));
1149 r = read (evt.data.fd, &counter, sizeof (counter));
1155 if (evt.events & EPOLLIN)
1157 if (evt.events & EPOLLOUT)
1159 if (evt.events & EPOLLERR)
1170 uint64_t counter = 1;
1176 if (w <
sizeof (counter))
1199 DBG (
"no connection");
1208 c->on_disconnect ((
void *) c, c->private_ctx);
1219 if (c->args.is_master)
1221 e->
key = c->fd = -1;
1224 if (c->tx_queues !=
NULL)
1227 (c->args.is_master) ? c->run_args.num_m2s_rings : c->
1228 run_args.num_s2m_rings;
1229 for (i = 0; i < num; i++)
1231 mq = &c->tx_queues[
i];
1241 lm->
free (c->tx_queues);
1242 c->tx_queues =
NULL;
1245 if (c->rx_queues !=
NULL)
1248 (c->args.is_master) ? c->run_args.num_s2m_rings : c->
1249 run_args.num_m2s_rings;
1250 for (i = 0; i < num; i++)
1252 mq = &c->rx_queues[
i];
1257 if (c->on_interrupt !=
NULL)
1267 lm->
free (c->rx_queues);
1268 c->rx_queues =
NULL;
1271 for (i = 0; i < c->regions_num; i++)
1273 if (&c->regions[i] ==
NULL)
1275 if (c->regions[i].is_external != 0)
1278 c->regions[i].region_size,
1279 c->regions[i].fd, c->private_ctx);
1283 if (munmap (c->regions[i].addr, c->regions[i].region_size) < 0)
1285 if (c->regions[i].fd > 0)
1286 close (c->regions[i].fd);
1287 c->regions[
i].fd = -1;
1290 lm->
free (c->regions);
1298 if (!(c->args.is_master))
1302 if (timerfd_settime (lm->
timerfd, 0, &lm->arm,
NULL) < 0)
1305 DBG (
"timerfd_settime: arm");
1344 DBG (
"no connection");
1350 DBG (
"DISCONNECTING");
1361 c->args.interface_id);
1376 if (!c->args.is_master)
1384 DBG (
"timerfd_settime: disarm");
1404 for (i = 0; i < c->regions_num; i++)
1406 mr = &c->regions[
i];
1426 MAP_SHARED, mr->
fd, 0)) == MAP_FAILED)
1435 for (i = 0; i < c->rx_queues_num; i++)
1437 mq = &c->rx_queues[
i];
1443 DBG (
"wrong cookie on rx ring %u", i);
1451 for (i = 0; i < c->tx_queues_num; i++)
1453 mq = &c->tx_queues[
i];
1459 DBG (
"wrong cookie on tx ring %u", i);
1475 uint8_t has_buffers)
1486 r = &conn->regions[conn->regions_num - 1];
1489 if (has_buffers != 0)
1496 (conn->run_args.num_s2m_rings +
1497 conn->run_args.num_m2s_rings) * (
sizeof (
memif_ring_t) +
1500 run_args.log2_ring_size));
1504 conn->run_args.buffer_size * (1 << conn->run_args.log2_ring_size) *
1505 (conn->run_args.num_s2m_rings + conn->run_args.num_m2s_rings);
1517 MAP_SHARED, r->
fd, 0)) == MAP_FAILED)
1529 for (i = 0; i < conn->run_args.num_s2m_rings; i++)
1532 DBG (
"RING: %p I: %d", ring, i);
1536 for (j = 0; j < (1 << conn->run_args.log2_ring_size); j++)
1538 uint16_t slot = i * (1 << conn->run_args.log2_ring_size) + j;
1541 conn->regions[1].buffer_offset +
1542 (uint32_t) (slot * conn->run_args.buffer_size);
1543 ring->
desc[j].
length = conn->run_args.buffer_size;
1546 for (i = 0; i < conn->run_args.num_m2s_rings; i++)
1549 DBG (
"RING: %p I: %d", ring, i);
1553 for (j = 0; j < (1 << conn->run_args.log2_ring_size); j++)
1555 uint16_t slot = (i + conn->run_args.num_s2m_rings) *
1556 (1 << conn->run_args.log2_ring_size) + j;
1559 conn->regions[1].buffer_offset +
1560 (uint32_t) (slot * conn->run_args.buffer_size);
1561 ring->
desc[j].
length = conn->run_args.buffer_size;
1569 conn->run_args.num_s2m_rings);
1575 for (x = 0; x < conn->run_args.num_s2m_rings; x++)
1577 if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
1584 DBG (
"RING: %p I: %d", mq[x].ring, x);
1588 (
void *) mq[x].ring - (
void *) conn->regions[mq->
region].addr;
1592 conn->tx_queues = mq;
1596 conn->run_args.num_m2s_rings);
1600 for (x = 0; x < conn->run_args.num_m2s_rings; x++)
1602 if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
1609 DBG (
"RING: %p I: %d", mq[x].ring, x);
1613 (
void *) mq[x].ring - (
void *) conn->regions[mq->
region].addr;
1617 conn->rx_queues = mq;
1637 ++conn->regions_num);
1642 conn->regions[1].region_size =
1643 conn->run_args.buffer_size * (1 << conn->run_args.log2_ring_size) *
1644 (conn->run_args.num_s2m_rings + conn->run_args.num_m2s_rings);
1645 conn->regions[1].buffer_offset = 0;
1647 conn->regions[1].region_size,
1648 &conn->regions[1].fd, conn->private_ctx);
1649 conn->regions[1].is_external = 1;
1664 uint16_t * count_out)
1672 (c->args.is_master) ? c->run_args.num_m2s_rings : c->
1673 run_args.num_s2m_rings;
1691 slot = (c->args.is_master) ? ring->
tail : ring->
head;
1712 (uint32_t) (b0->
data -
1713 c->regions[ring->
desc[slot & mask].
region].addr);
1729 DBG (
"allocated: %u/%u bufs. Total %u allocated bufs", *count_out, count,
1734 DBG (
"ring buffer full! qid: %u", qid);
1744 uint16_t * count_out, uint16_t
size)
1752 (c->args.is_master) ? c->run_args.num_m2s_rings : c->
1753 run_args.num_s2m_rings;
1764 uint32_t offset_mask = c->run_args.buffer_size - 1;
1768 uint16_t dst_left, src_left;
1769 uint16_t saved_count;
1774 slot = (c->args.is_master) ? ring->
tail : ring->
head;
1777 if (c->args.is_master)
1784 b0 = (bufs + *count_out);
1787 saved_count =
count;
1793 dst_left = (c->args.is_master) ? ring->
desc[slot & mask].
length :
1794 c->run_args.buffer_size;
1812 b0 = (bufs + *count_out);
1815 (c->args.is_master) ? ring->
desc[slot & mask].
1816 length : c->run_args.buffer_size;
1823 * (saved_count - count + 1));
1824 *count_out -= saved_count -
count;
1832 if (c->args.is_master == 0)
1842 src_left -= b0->
len;
1843 dst_left -= b0->
len;
1855 DBG (
"allocated: %u/%u bufs. Total %u allocated bufs", *count_out, count,
1860 DBG (
"ring buffer full! qid: %u", qid);
1877 (c->args.is_master) ? c->run_args.num_s2m_rings : c->
1878 run_args.num_m2s_rings;
1885 uint32_t offset_mask = c->run_args.buffer_size - 1;
1888 if (c->args.is_master)
1892 (ring->
tail + count <=
1897 uint16_t head = ring->
head;
1899 head += (count < ns) ? count : ns;
1905 d = &ring->
desc[slot & mask];
1907 d->
length = c->run_args.buffer_size - headroom;
1931 (c->args.is_master) ? c->run_args.num_m2s_rings : c->
1932 run_args.num_s2m_rings;
1955 #ifdef MEMIF_DBG_SHM 1957 printf (
"data: %p\n",
1970 if (c->args.is_master)
1980 int r = write (mq->
int_fd, &a, sizeof (a));
1998 (c->args.is_master) ? c->run_args.num_s2m_rings : c->
1999 run_args.num_m2s_rings;
2007 uint16_t cur_slot, last_slot;
2014 ssize_t r = read (mq->
int_fd, &b, sizeof (b));
2019 last_slot = (c->args.is_master) ? ring->
head : ring->
tail;
2020 if (cur_slot == last_slot)
2023 ns = last_slot - cur_slot;
2033 if (c->args.is_master == 0)
2035 ring->
desc[cur_slot & mask].
length = c->run_args.buffer_size;
2042 ring->
desc[cur_slot & mask].
flags &= ~MEMIF_DESC_FLAG_NEXT;
2046 #ifdef MEMIF_DBG_SHM 2047 printf (
"data: %p\n", b0->
data);
2049 printf (
"ring: %p\n", b0->
ring);
2059 if (c->args.is_master)
2066 DBG (
"not enough buffers!");
2075 char *buf, ssize_t buflen)
2088 l1 = strlen ((
char *) c->args.interface_name);
2089 if (l0 + l1 < buflen)
2092 (uint8_t *) strcpy (buf + l0, (
char *) c->args.interface_name);
2098 l1 = strlen ((
char *) lm->
app_name);
2099 if (l0 + l1 < buflen)
2107 l1 = strlen ((
char *) c->remote_if_name);
2108 if (l0 + l1 < buflen)
2111 (uint8_t *) strcpy (buf + l0, (
char *) c->remote_if_name);
2117 l1 = strlen ((
char *) c->remote_name);
2118 if (l0 + l1 < buflen)
2121 (uint8_t *) strcpy (buf + l0, (
char *) c->remote_name);
2127 md->
id = c->args.interface_id;
2129 if (strlen ((
char *) c->args.secret) > 0)
2131 l1 = strlen ((
char *) c->args.secret);
2132 if (l0 + l1 < buflen)
2134 md->
secret = (uint8_t *) strcpy (buf + l0, (
char *) c->args.secret);
2141 md->
role = (c->args.is_master) ? 0 : 1;
2142 md->
mode = c->args.mode;
2144 l1 = strlen ((
char *) ms->
filename);
2145 if (l0 + l1 < buflen)
2148 (uint8_t *) strcpy (buf + l0, (
char *) ms->
filename);
2154 l1 = strlen ((
char *) c->remote_disconnect_string);
2155 if (l0 + l1 < buflen)
2158 (uint8_t *) strcpy (buf + l0, (
char *) c->remote_disconnect_string);
2166 if (l0 + l1 <= buflen)
2183 (c->args.is_master) ? c->run_args.num_s2m_rings : c->
2184 run_args.num_m2s_rings;
2187 if (l0 + l1 <= buflen)
2206 (c->args.is_master) ? c->run_args.num_m2s_rings : c->
2207 run_args.num_s2m_rings;
2210 if (l0 + l1 <= buflen)
2246 (c->args.is_master) ? c->run_args.num_s2m_rings : c->
2247 run_args.num_m2s_rings;
2251 *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)
int( memif_control_fd_update_t)(int fd, uint8_t events, void *private_ctx)
Memif control file descriptor update (callback function)
#define MEMIF_FD_EVENT_READ
user needs to set events that occured on fd and pass them to memif_control_fd_handler ...
Optimized string handling code, including c11-compliant "safe C library" variants.
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(int fd, uint8_t events, void *private_ctx)
memif_control_fd_update_t * control_fd_update
static void memif_control_fd_update_register(memif_control_fd_update_t *cb)
memif_socket_handle_t socket
#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)
memif_get_external_buffer_offset_t * get_external_buffer_offset
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.
#define MFD_ALLOW_SEALING
memif_list_elt_t * interface_list
int on_connect(memif_conn_handle_t conn, void *private_ctx)
static void memif_realloc_register(memif_realloc_t *mr)
static void memif_alloc_register(memif_alloc_t *ma)
memif_realloc_t * realloc
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.
static int memfd_create(const char *name, unsigned int flags)
memif_region_offset_t offset
void *( memif_realloc_t)(void *ptr, size_t size)
Memif realloc.
#define MEMIF_MAX_LOG2_RING_SIZE
#define MEMIF_BUFFER_FLAG_NEXT
next buffer present (chained buffers)
int memif_syscall_error_handler(int err_code)
vl_api_fib_path_type_t type
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_DEFAULT_SOCKET_PATH
#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)
void * memif_socket_handle_t
Memif socket handle pointer of type void, pointing to internal structure.
int memif_create_socket(memif_socket_handle_t *sock, const char *filename, void *private_ctx)
Create memif socket.
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_realloc_t *memif_realloc, memif_free_t *memif_free)
Memif initialization.
void *( memif_get_external_region_addr_t)(uint32_t size, int fd, void *private_ctx)
Get external region address.
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
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)
#define MEMIF_DEFAULT_RECONNECT_PERIOD_SEC
int memif_init_regions_and_queues(memif_connection_t *conn)
void( memif_free_t)(void *ptr)
Memif allocator free.
int( memif_del_external_region_t)(void *addr, uint32_t size, int fd, void *private_ctx)
Delete external region.
memif_add_external_region_t * add_external_region
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.
static int memif_add_region(libmemif_main_t *lm, memif_connection_t *conn, uint8_t has_buffers)
int memif_poll_event(int timeout)
Memif poll event.
memif_queue_details_t * rx_queues
static int memif_socket_start_listening(memif_socket_t *ms)
#define MEMIF_DEFAULT_BUFFER_SIZE
memif_socket_handle_t default_socket
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
int( memif_add_external_region_t)(void **addr, uint32_t size, int *fd, void *private_ctx)
Add external region.
#define MEMIF_RING_FLAG_MASK_INT
#define MEMIF_DEFAULT_RECONNECT_PERIOD_NSEC
void * memif_conn_handle_t
Memif connection handle pointer of type void, pointing to internal structure.
memif_region_offset_t offset
int memif_set_connection_request_timer(struct itimerspec timer)
Set connection request timer value.
int memif_control_fd_handler(int fd, uint8_t events)
Memif control file descriptor handler.
memif_del_external_region_t * del_external_region
uint8_t app_name[MEMIF_NAME_LEN]
int memif_request_connection(memif_conn_handle_t c)
Send connection request.
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.
static int memif_init_queues(libmemif_main_t *lm, memif_connection_t *conn)
memif_log2_ring_size_t log2_ring_size
memif_region_details_t * regions
#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
uint32_t( memif_get_external_buffer_offset_t)(void *private_ctx)
Get external buffer offset (optional)
memif_list_elt_t * socket_list
int memif_delete_socket(memif_socket_handle_t *sock)
Delete memif socket.
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_get_external_region_addr_t * get_external_region_addr
memif_region_index_t region
Memif connection arguments.
uint16_t interface_list_len
void memif_register_external_region(memif_add_external_region_t *ar, memif_get_external_region_addr_t *gr, memif_del_external_region_t *dr, memif_get_external_buffer_offset_t *go)
Register external region.
memif_region_size_t region_size
void *( memif_alloc_t)(size_t size)
Memif allocator alloc.