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);
324 for (i = 0; i < *
len; i++)
326 if ((*list)[i].data_struct ==
NULL)
328 (*list)[
i].key = e->
key;
338 for (i = *len; i < *len * 2; i++)
363 for (i = 0; i <
len; i++)
365 if (list[i].key == key)
380 for (i = 0; i <
len; i++)
382 if (list[i].key == key)
398 for (i = 0; i <
len; i++)
400 if (list[i].
key == -1)
402 if (list[i].data_struct == ctx)
465 if (timerfd_settime (lm->
timerfd, 0, &lm->arm,
NULL) < 0)
482 if (memif_alloc !=
NULL)
489 if (memif_realloc !=
NULL)
496 if (memif_free !=
NULL)
501 if (app_name !=
NULL)
505 strncpy ((
char *) lm->
app_name, app_name, len);
514 if (on_control_fd_update !=
NULL)
523 DBG (
"eventfd: %s", strerror (err));
527 DBG (
"libmemif event polling initialized");
588 lm->
timerfd = timerfd_create (CLOCK_REALTIME, TFD_NONBLOCK);
602 DBG (
"callback type memif_control_fd_update_t error!");
618 if (&conn->regions[0] ==
NULL)
620 void *p = conn->regions[0].addr;
623 sizeof (
memif_desc_t) * (1 << conn->run_args.log2_ring_size);
624 p += (ring_num + type * conn->run_args.num_s2m_rings) * ring_size;
637 (conn->args.is_master) ? conn->run_args.num_s2m_rings : conn->
638 run_args.num_m2s_rings;
642 conn->rx_queues[qid].ring->flags = rx_mode;
643 DBG (
"rx_mode flag: %u", conn->rx_queues[qid].ring->flags);
654 int err,
i, index = 0, sockfd = -1;
659 DBG (
"This handle already points to existing memif.");
691 conn->args.mode = args->
mode;
692 conn->msg_queue =
NULL;
693 conn->regions =
NULL;
694 conn->tx_queues =
NULL;
695 conn->rx_queues =
NULL;
700 conn->private_ctx = private_ctx;
704 strncpy ((
char *) conn->args.interface_name, (
char *) args->
interface_name,
709 conn->args.socket_filename = lm->
alloc (
sizeof (
char *) * 108);
710 if (conn->args.socket_filename ==
NULL)
715 memset (conn->args.socket_filename, 0, 108 * sizeof (
char *));
719 if (conn->args.socket_filename ==
NULL)
724 strncpy ((
char *) conn->args.socket_filename,
732 if (conn->args.socket_filename ==
NULL)
737 strncpy ((
char *) conn->args.socket_filename,
739 conn->args.socket_filename[sdl] =
'/';
740 strncpy ((
char *) (conn->args.socket_filename + 1 + sdl),
744 if ((l = strlen ((
char *) args->
secret)) > 0)
746 strncpy ((
char *) conn->args.secret, (
char *) args->
secret, l);
749 if (conn->args.is_master)
751 conn->run_args.buffer_size = conn->args.buffer_size;
760 ((
char *) ms->
filename, (
char *) conn->args.socket_filename,
761 strlen ((
char *) ms->
filename)) == 0)
764 elt.
key = conn->args.interface_id;
769 conn->listener_fd = ms->
fd;
775 struct stat file_stat;
776 if (stat ((
char *) conn->args.socket_filename, &file_stat) == 0)
778 if (S_ISSOCK (file_stat.st_mode))
779 unlink ((
char *) conn->args.socket_filename);
783 DBG (
"creating socket file");
791 lm->
alloc (strlen ((
char *) conn->args.socket_filename) +
799 strlen ((
char *) conn->args.socket_filename) +
802 (
char *) conn->args.socket_filename,
803 strlen ((
char *) conn->args.socket_filename));
815 struct sockaddr_un un = { 0 };
818 ms->
fd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
824 DBG (
"socket %d created", ms->
fd);
825 un.sun_family = AF_UNIX;
826 strncpy ((
char *) un.sun_path, (
char *) ms->
filename,
827 sizeof (un.sun_path) - 1);
830 (ms->
fd, SOL_SOCKET, SO_PASSCRED, &on, sizeof (on)) < 0)
836 if (bind (ms->
fd, (
struct sockaddr *) &un, sizeof (un)) < 0)
842 if (listen (ms->
fd, 1) < 0)
848 if (stat ((
char *) ms->
filename, &file_stat) < 0)
855 elt.
key = conn->args.interface_id;
860 conn->listener_fd = ms->
fd;
892 if (timerfd_settime (lm->
timerfd, 0, &lm->arm,
NULL) < 0)
906 if (conn->args.socket_filename)
907 lm->
free (conn->args.socket_filename);
921 struct sockaddr_un sun;
923 if (conn->args.is_master)
928 sockfd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
935 sun.sun_family = AF_UNIX;
937 strncpy (sun.sun_path, (
char *) conn->args.socket_filename,
938 sizeof (sun.sun_path) - 1);
940 if (connect (sockfd, (
struct sockaddr *) &sun,
941 sizeof (
struct sockaddr_un)) == 0)
966 strcpy ((
char *) conn->remote_disconnect_string,
993 size = read (fd, &b,
sizeof (b));
1004 if (conn->args.is_master)
1020 data_struct)->run_args.
1022 run_args.num_m2s_rings;
1023 for (i = 0; i < num; i++)
1026 rx_queues[i].int_fd == fd)
1031 data_struct)->private_ctx, i);
1091 struct epoll_event evt;
1093 uint32_t events = 0;
1094 uint64_t counter = 0;
1096 memset (&evt, 0,
sizeof (evt));
1097 evt.events = EPOLLIN | EPOLLOUT;
1099 sigemptyset (&sigset);
1100 en = epoll_pwait (
memif_epfd, &evt, 1, timeout, &sigset);
1104 DBG (
"epoll_pwait: %s", strerror (err));
1111 r = read (evt.data.fd, &counter, sizeof (counter));
1117 if (evt.events & EPOLLIN)
1119 if (evt.events & EPOLLOUT)
1121 if (evt.events & EPOLLERR)
1132 uint64_t counter = 1;
1138 if (w <
sizeof (counter))
1161 DBG (
"no connection");
1170 c->on_disconnect ((
void *) c, c->private_ctx);
1181 if (c->args.is_master)
1183 e->
key = c->fd = -1;
1186 if (c->tx_queues !=
NULL)
1189 (c->args.is_master) ? c->run_args.num_m2s_rings : c->
1190 run_args.num_s2m_rings;
1191 for (i = 0; i < num; i++)
1193 mq = &c->tx_queues[
i];
1203 lm->
free (c->tx_queues);
1204 c->tx_queues =
NULL;
1207 if (c->rx_queues !=
NULL)
1210 (c->args.is_master) ? c->run_args.num_s2m_rings : c->
1211 run_args.num_m2s_rings;
1212 for (i = 0; i < num; i++)
1214 mq = &c->rx_queues[
i];
1219 if (c->on_interrupt !=
NULL)
1228 lm->
free (c->rx_queues);
1229 c->rx_queues =
NULL;
1232 for (i = 0; i < c->regions_num; i++)
1234 if (&c->regions[i] ==
NULL)
1236 if (c->regions[i].is_external != 0)
1239 c->regions[i].region_size,
1240 c->regions[i].fd, c->private_ctx);
1244 if (munmap (c->regions[i].addr, c->regions[i].region_size) < 0)
1246 if (c->regions[i].fd > 0)
1247 close (c->regions[i].fd);
1248 c->regions[
i].fd = -1;
1251 lm->
free (c->regions);
1259 if (!(c->args.is_master))
1263 if (timerfd_settime (lm->
timerfd, 0, &lm->arm,
NULL) < 0)
1266 DBG (
"timerfd_settime: arm");
1281 DBG (
"no connection");
1292 DBG (
"DISCONNECTING");
1300 if (c->args.is_master)
1309 c->args.interface_id);
1315 close (c->listener_fd);
1316 c->listener_fd = ms->
fd = -1;
1334 DBG (
"timerfd_settime: disarm");
1339 if (c->args.socket_filename)
1340 lm->
free (c->args.socket_filename);
1341 c->args.socket_filename =
NULL;
1358 for (i = 0; i < c->regions_num; i++)
1360 mr = &c->regions[
i];
1380 MAP_SHARED, mr->
fd, 0)) == MAP_FAILED)
1389 for (i = 0; i < c->rx_queues_num; i++)
1391 mq = &c->rx_queues[
i];
1397 DBG (
"wrong cookie on rx ring %u", i);
1405 for (i = 0; i < c->tx_queues_num; i++)
1407 mq = &c->tx_queues[
i];
1413 DBG (
"wrong cookie on tx ring %u", i);
1428 uint8_t has_buffers)
1439 r = &conn->regions[conn->regions_num - 1];
1442 if (has_buffers != 0)
1449 (conn->run_args.num_s2m_rings +
1450 conn->run_args.num_m2s_rings) * (
sizeof (
memif_ring_t) +
1453 run_args.log2_ring_size));
1457 conn->run_args.buffer_size * (1 << conn->run_args.log2_ring_size) *
1458 (conn->run_args.num_s2m_rings + conn->run_args.num_m2s_rings);
1470 MAP_SHARED, r->
fd, 0)) == MAP_FAILED)
1482 for (i = 0; i < conn->run_args.num_s2m_rings; i++)
1485 DBG (
"RING: %p I: %d", ring, i);
1489 for (j = 0; j < (1 << conn->run_args.log2_ring_size); j++)
1491 uint16_t slot = i * (1 << conn->run_args.log2_ring_size) + j;
1494 conn->regions[1].buffer_offset +
1495 (uint32_t) (slot * conn->run_args.buffer_size);
1496 ring->
desc[j].
length = conn->run_args.buffer_size;
1499 for (i = 0; i < conn->run_args.num_m2s_rings; i++)
1502 DBG (
"RING: %p I: %d", ring, i);
1506 for (j = 0; j < (1 << conn->run_args.log2_ring_size); j++)
1508 uint16_t slot = (i + conn->run_args.num_s2m_rings) *
1509 (1 << conn->run_args.log2_ring_size) + j;
1512 conn->regions[1].buffer_offset +
1513 (uint32_t) (slot * conn->run_args.buffer_size);
1514 ring->
desc[j].
length = conn->run_args.buffer_size;
1522 conn->run_args.num_s2m_rings);
1528 for (x = 0; x < conn->run_args.num_s2m_rings; x++)
1530 if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
1537 DBG (
"RING: %p I: %d", mq[x].ring, x);
1541 (
void *) mq[x].ring - (
void *) conn->regions[mq->
region].addr;
1545 conn->tx_queues = mq;
1549 conn->run_args.num_m2s_rings);
1553 for (x = 0; x < conn->run_args.num_m2s_rings; x++)
1555 if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
1562 DBG (
"RING: %p I: %d", mq[x].ring, x);
1566 (
void *) mq[x].ring - (
void *) conn->regions[mq->
region].addr;
1570 conn->rx_queues = mq;
1590 ++conn->regions_num);
1595 conn->regions[1].region_size =
1596 conn->run_args.buffer_size * (1 << conn->run_args.log2_ring_size) *
1597 (conn->run_args.num_s2m_rings + conn->run_args.num_m2s_rings);
1598 conn->regions[1].buffer_offset = 0;
1600 conn->regions[1].region_size,
1601 &conn->regions[1].fd, conn->private_ctx);
1602 conn->regions[1].is_external = 1;
1617 uint16_t * count_out)
1625 (c->args.is_master) ? c->run_args.num_m2s_rings : c->
1626 run_args.num_s2m_rings;
1644 slot = (c->args.is_master) ? ring->
tail : ring->
head;
1665 (uint32_t) (b0->
data -
1666 c->regions[ring->
desc[slot & mask].
region].addr);
1681 DBG (
"allocated: %u/%u bufs. Total %u allocated bufs", *count_out, count,
1686 DBG (
"ring buffer full! qid: %u", qid);
1696 uint16_t * count_out, uint16_t
size)
1704 (c->args.is_master) ? c->run_args.num_m2s_rings : c->
1705 run_args.num_s2m_rings;
1716 uint32_t offset_mask = c->run_args.buffer_size - 1;
1720 uint16_t dst_left, src_left;
1721 uint16_t saved_count;
1726 slot = (c->args.is_master) ? ring->
tail : ring->
head;
1729 if (c->args.is_master)
1736 b0 = (bufs + *count_out);
1739 saved_count =
count;
1745 dst_left = (c->args.is_master) ? ring->
desc[slot & mask].
length :
1746 c->run_args.buffer_size;
1764 b0 = (bufs + *count_out);
1767 (c->args.is_master) ? ring->
desc[slot & mask].
1768 length : c->run_args.buffer_size;
1775 * (saved_count - count + 1));
1776 *count_out -= saved_count -
count;
1784 if (c->args.is_master == 0)
1794 src_left -= b0->
len;
1795 dst_left -= b0->
len;
1807 DBG (
"allocated: %u/%u bufs. Total %u allocated bufs", *count_out, count,
1812 DBG (
"ring buffer full! qid: %u", qid);
1829 (c->args.is_master) ? c->run_args.num_s2m_rings : c->
1830 run_args.num_m2s_rings;
1837 uint32_t offset_mask = c->run_args.buffer_size - 1;
1840 if (c->args.is_master)
1844 (ring->
tail + count <=
1849 uint16_t head = ring->
head;
1851 head += (count < ns) ?
count : ns;
1857 d = &ring->
desc[slot & mask];
1859 d->
length = c->run_args.buffer_size - headroom;
1883 (c->args.is_master) ? c->run_args.num_m2s_rings : c->
1884 run_args.num_s2m_rings;
1907 #ifdef MEMIF_DBG_SHM 1909 printf (
"data: %p\n",
1922 if (c->args.is_master)
1932 int r = write (mq->
int_fd, &a, sizeof (a));
1950 (c->args.is_master) ? c->run_args.num_s2m_rings : c->
1951 run_args.num_m2s_rings;
1959 uint16_t cur_slot, last_slot;
1966 ssize_t r = read (mq->
int_fd, &b, sizeof (b));
1971 last_slot = (c->args.is_master) ? ring->
head : ring->
tail;
1972 if (cur_slot == last_slot)
1975 ns = last_slot - cur_slot;
1985 if (c->args.is_master == 0)
1987 ring->
desc[cur_slot & mask].
length = c->run_args.buffer_size;
1994 ring->
desc[cur_slot & mask].
flags &= ~MEMIF_DESC_FLAG_NEXT;
1998 #ifdef MEMIF_DBG_SHM 1999 printf (
"data: %p\n", b0->
data);
2001 printf (
"ring: %p\n", b0->
ring);
2011 if (c->args.is_master)
2018 DBG (
"not enough buffers!");
2027 char *buf, ssize_t buflen)
2038 l1 = strlen ((
char *) c->args.interface_name);
2039 if (l0 + l1 < buflen)
2042 (uint8_t *) strcpy (buf + l0, (
char *) c->args.interface_name);
2048 l1 = strlen ((
char *) lm->
app_name);
2049 if (l0 + l1 < buflen)
2057 l1 = strlen ((
char *) c->remote_if_name);
2058 if (l0 + l1 < buflen)
2061 (uint8_t *) strcpy (buf + l0, (
char *) c->remote_if_name);
2067 l1 = strlen ((
char *) c->remote_name);
2068 if (l0 + l1 < buflen)
2071 (uint8_t *) strcpy (buf + l0, (
char *) c->remote_name);
2077 md->
id = c->args.interface_id;
2079 if (strlen ((
char *) c->args.secret) > 0)
2081 l1 = strlen ((
char *) c->args.secret);
2082 if (l0 + l1 < buflen)
2084 md->
secret = (uint8_t *) strcpy (buf + l0, (
char *) c->args.secret);
2091 md->
role = (c->args.is_master) ? 0 : 1;
2092 md->
mode = c->args.mode;
2094 l1 = strlen ((
char *) c->args.socket_filename);
2095 if (l0 + l1 < buflen)
2098 (uint8_t *) strcpy (buf + l0, (
char *) c->args.socket_filename);
2104 l1 = strlen ((
char *) c->remote_disconnect_string);
2105 if (l0 + l1 < buflen)
2108 (uint8_t *) strcpy (buf + l0, (
char *) c->remote_disconnect_string);
2116 if (l0 + l1 <= buflen)
2133 (c->args.is_master) ? c->run_args.num_s2m_rings : c->
2134 run_args.num_m2s_rings;
2137 if (l0 + l1 <= buflen)
2156 (c->args.is_master) ? c->run_args.num_m2s_rings : c->
2157 run_args.num_s2m_rings;
2160 if (l0 + l1 <= buflen)
2193 (c->args.is_master) ? c->run_args.num_s2m_rings : c->
2194 run_args.num_m2s_rings;
2198 *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 ...
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)
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
int() memif_control_fd_update_t(int fd, uint8_t events)
Memif control file descriptor update (callback function)
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_list_elt_t * listener_list
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
#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
int() memif_add_external_region_t(void **addr, uint32_t size, int *fd, void *private_ctx)
Add external region.
#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_del_external_region_t(void *addr, uint32_t size, int fd, void *private_ctx)
Delete external region.
static int memif_add_epoll_fd(int fd, uint32_t events)
int() memif_interrupt_t(memif_conn_handle_t conn, void *private_ctx, uint16_t qid)
Memif interrupt occured (callback function)
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.
int() memif_connection_update_t(memif_conn_handle_t conn, void *private_ctx)
Memif connection status update (callback function)
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)
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.
void() memif_free_t(void *ptr)
Memif allocator free.
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
void *() memif_realloc_t(void *ptr, size_t size)
Memif realloc.
#define MEMIF_DEFAULT_BUFFER_SIZE
int memif_cleanup()
Memif cleanup.
uint32_t() memif_get_external_buffer_offset_t(void *private_ctx)
Get external buffer offset (optional)
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
#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]
#define MEMIF_DEFAULT_SOCKET_FILENAME
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
void *() memif_alloc_t(size_t size)
Memif allocator alloc.
void *() memif_get_external_region_addr_t(uint32_t size, int fd, void *private_ctx)
Get external region address.
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
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
uint16_t listener_list_len
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
uint8_t * socket_filename
int memif_control_fd_update(int fd, uint8_t events)