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)
463 if (memif_alloc !=
NULL)
470 if (memif_realloc !=
NULL)
477 if (memif_free !=
NULL)
482 if (app_name !=
NULL)
486 strncpy ((
char *) lm->
app_name, app_name, len);
495 if (on_control_fd_update !=
NULL)
504 DBG (
"eventfd: %s", strerror (err));
508 DBG (
"libmemif event polling initialized");
569 lm->
timerfd = timerfd_create (CLOCK_REALTIME, TFD_NONBLOCK);
576 lm->arm.it_value.tv_sec = 2;
577 lm->arm.it_value.tv_nsec = 0;
578 lm->arm.it_interval.tv_sec = 2;
579 lm->arm.it_interval.tv_nsec = 0;
583 DBG (
"callback type memif_control_fd_update_t error!");
599 if (&conn->regions[0] ==
NULL)
601 void *p = conn->regions[0].addr;
604 sizeof (
memif_desc_t) * (1 << conn->run_args.log2_ring_size);
605 p += (ring_num + type * conn->run_args.num_s2m_rings) * ring_size;
618 (conn->args.is_master) ? conn->run_args.num_s2m_rings : conn->
619 run_args.num_m2s_rings;
623 conn->rx_queues[qid].ring->flags = rx_mode;
624 DBG (
"rx_mode flag: %u", conn->rx_queues[qid].ring->flags);
635 int err,
i, index = 0, sockfd = -1;
640 DBG (
"This handle already points to existing memif.");
672 conn->args.mode = args->
mode;
673 conn->msg_queue =
NULL;
674 conn->regions =
NULL;
675 conn->tx_queues =
NULL;
676 conn->rx_queues =
NULL;
681 conn->private_ctx = private_ctx;
685 strncpy ((
char *) conn->args.interface_name, (
char *) args->
interface_name,
690 conn->args.socket_filename = lm->
alloc (
sizeof (
char *) * 108);
691 if (conn->args.socket_filename ==
NULL)
696 memset (conn->args.socket_filename, 0, 108 * sizeof (
char *));
700 if (conn->args.socket_filename ==
NULL)
705 strncpy ((
char *) conn->args.socket_filename,
713 if (conn->args.socket_filename ==
NULL)
718 strncpy ((
char *) conn->args.socket_filename,
720 conn->args.socket_filename[sdl] =
'/';
721 strncpy ((
char *) (conn->args.socket_filename + 1 + sdl),
725 if ((l = strlen ((
char *) args->
secret)) > 0)
727 strncpy ((
char *) conn->args.secret, (
char *) args->
secret, l);
730 if (conn->args.is_master)
732 conn->run_args.buffer_size = conn->args.buffer_size;
741 ((
char *) ms->
filename, (
char *) conn->args.socket_filename,
742 strlen ((
char *) ms->
filename)) == 0)
745 elt.
key = conn->args.interface_id;
750 conn->listener_fd = ms->
fd;
756 struct stat file_stat;
757 if (stat ((
char *) conn->args.socket_filename, &file_stat) == 0)
759 if (S_ISSOCK (file_stat.st_mode))
760 unlink ((
char *) conn->args.socket_filename);
764 DBG (
"creating socket file");
772 lm->
alloc (strlen ((
char *) conn->args.socket_filename) +
780 strlen ((
char *) conn->args.socket_filename) +
783 (
char *) conn->args.socket_filename,
784 strlen ((
char *) conn->args.socket_filename));
796 struct sockaddr_un un = { 0 };
799 ms->
fd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
805 DBG (
"socket %d created", ms->
fd);
806 un.sun_family = AF_UNIX;
807 strncpy ((
char *) un.sun_path, (
char *) ms->
filename,
808 sizeof (un.sun_path) - 1);
811 (ms->
fd, SOL_SOCKET, SO_PASSCRED, &on, sizeof (on)) < 0)
817 if (bind (ms->
fd, (
struct sockaddr *) &un, sizeof (un)) < 0)
823 if (listen (ms->
fd, 1) < 0)
829 if (stat ((
char *) ms->
filename, &file_stat) < 0)
836 elt.
key = conn->args.interface_id;
841 conn->listener_fd = ms->
fd;
856 if (timerfd_settime (lm->
timerfd, 0, &lm->arm,
NULL) < 0)
884 if (conn->args.socket_filename)
885 lm->
free (conn->args.socket_filename);
904 size = read (fd, &b,
sizeof (b));
915 if (conn->args.is_master)
918 struct sockaddr_un sun;
919 sockfd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
926 sun.sun_family = AF_UNIX;
928 strncpy (sun.sun_path, (
char *) conn->args.socket_filename,
929 sizeof (sun.sun_path) - 1);
931 if (connect (sockfd, (
struct sockaddr *) &sun,
932 sizeof (
struct sockaddr_un)) == 0)
958 strcpy ((
char *) conn->remote_disconnect_string,
975 data_struct)->run_args.
977 run_args.num_m2s_rings;
978 for (i = 0; i < num; i++)
981 rx_queues[i].int_fd == fd)
986 data_struct)->private_ctx, i);
1049 struct epoll_event evt;
1051 uint32_t events = 0;
1052 uint64_t counter = 0;
1054 memset (&evt, 0,
sizeof (evt));
1055 evt.events = EPOLLIN | EPOLLOUT;
1057 sigemptyset (&sigset);
1058 en = epoll_pwait (
memif_epfd, &evt, 1, timeout, &sigset);
1062 DBG (
"epoll_pwait: %s", strerror (err));
1069 r = read (evt.data.fd, &counter, sizeof (counter));
1075 if (evt.events & EPOLLIN)
1077 if (evt.events & EPOLLOUT)
1079 if (evt.events & EPOLLERR)
1090 uint64_t counter = 1;
1096 if (w <
sizeof (counter))
1119 DBG (
"no connection");
1128 c->on_disconnect ((
void *) c, c->private_ctx);
1139 if (c->args.is_master)
1141 e->
key = c->fd = -1;
1144 if (c->tx_queues !=
NULL)
1147 (c->args.is_master) ? c->run_args.num_m2s_rings : c->
1148 run_args.num_s2m_rings;
1149 for (i = 0; i < num; i++)
1151 mq = &c->tx_queues[
i];
1161 lm->
free (c->tx_queues);
1162 c->tx_queues =
NULL;
1165 if (c->rx_queues !=
NULL)
1168 (c->args.is_master) ? c->run_args.num_s2m_rings : c->
1169 run_args.num_m2s_rings;
1170 for (i = 0; i < num; i++)
1172 mq = &c->rx_queues[
i];
1177 if (c->on_interrupt !=
NULL)
1186 lm->
free (c->rx_queues);
1187 c->rx_queues =
NULL;
1190 for (i = 0; i < c->regions_num; i++)
1192 if (&c->regions[i] ==
NULL)
1194 if (c->regions[i].is_external != 0)
1197 c->regions[i].region_size,
1198 c->regions[i].fd, c->private_ctx);
1202 if (munmap (c->regions[i].addr, c->regions[i].region_size) < 0)
1204 if (c->regions[i].fd > 0)
1205 close (c->regions[i].fd);
1206 c->regions[
i].fd = -1;
1209 lm->
free (c->regions);
1217 if (!(c->args.is_master))
1221 if (timerfd_settime (lm->
timerfd, 0, &lm->arm,
NULL) < 0)
1224 DBG (
"timerfd_settime: arm");
1239 DBG (
"no connection");
1250 DBG (
"DISCONNECTING");
1258 if (c->args.is_master)
1267 c->args.interface_id);
1273 close (c->listener_fd);
1274 c->listener_fd = ms->
fd = -1;
1292 DBG (
"timerfd_settime: disarm");
1297 if (c->args.socket_filename)
1298 lm->
free (c->args.socket_filename);
1299 c->args.socket_filename =
NULL;
1316 for (i = 0; i < c->regions_num; i++)
1318 mr = &c->regions[
i];
1338 MAP_SHARED, mr->
fd, 0)) == MAP_FAILED)
1347 for (i = 0; i < c->rx_queues_num; i++)
1349 mq = &c->rx_queues[
i];
1355 DBG (
"wrong cookie on rx ring %u", i);
1363 for (i = 0; i < c->tx_queues_num; i++)
1365 mq = &c->tx_queues[
i];
1371 DBG (
"wrong cookie on tx ring %u", i);
1386 uint8_t has_buffers)
1397 r = &conn->regions[conn->regions_num - 1];
1400 if (has_buffers != 0)
1407 (conn->run_args.num_s2m_rings +
1408 conn->run_args.num_m2s_rings) * (
sizeof (
memif_ring_t) +
1411 run_args.log2_ring_size));
1415 conn->run_args.buffer_size * (1 << conn->run_args.log2_ring_size) *
1416 (conn->run_args.num_s2m_rings + conn->run_args.num_m2s_rings);
1428 MAP_SHARED, r->
fd, 0)) == MAP_FAILED)
1440 for (i = 0; i < conn->run_args.num_s2m_rings; i++)
1443 DBG (
"RING: %p I: %d", ring, i);
1447 for (j = 0; j < (1 << conn->run_args.log2_ring_size); j++)
1449 uint16_t slot = i * (1 << conn->run_args.log2_ring_size) + j;
1452 conn->regions[1].buffer_offset +
1453 (uint32_t) (slot * conn->run_args.buffer_size);
1454 ring->
desc[j].
length = conn->run_args.buffer_size;
1457 for (i = 0; i < conn->run_args.num_m2s_rings; i++)
1460 DBG (
"RING: %p I: %d", ring, i);
1464 for (j = 0; j < (1 << conn->run_args.log2_ring_size); j++)
1466 uint16_t slot = (i + conn->run_args.num_s2m_rings) *
1467 (1 << conn->run_args.log2_ring_size) + j;
1470 conn->regions[1].buffer_offset +
1471 (uint32_t) (slot * conn->run_args.buffer_size);
1472 ring->
desc[j].
length = conn->run_args.buffer_size;
1480 conn->run_args.num_s2m_rings);
1486 for (x = 0; x < conn->run_args.num_s2m_rings; x++)
1488 if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
1495 DBG (
"RING: %p I: %d", mq[x].ring, x);
1499 (
void *) mq[x].ring - (
void *) conn->regions[mq->
region].addr;
1503 conn->tx_queues = mq;
1507 conn->run_args.num_m2s_rings);
1511 for (x = 0; x < conn->run_args.num_m2s_rings; x++)
1513 if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
1520 DBG (
"RING: %p I: %d", mq[x].ring, x);
1524 (
void *) mq[x].ring - (
void *) conn->regions[mq->
region].addr;
1528 conn->rx_queues = mq;
1548 ++conn->regions_num);
1553 conn->regions[1].region_size =
1554 conn->run_args.buffer_size * (1 << conn->run_args.log2_ring_size) *
1555 (conn->run_args.num_s2m_rings + conn->run_args.num_m2s_rings);
1556 conn->regions[1].buffer_offset = 0;
1558 conn->regions[1].region_size,
1559 &conn->regions[1].fd, conn->private_ctx);
1560 conn->regions[1].is_external = 1;
1575 uint16_t * count_out)
1583 (c->args.is_master) ? c->run_args.num_m2s_rings : c->
1584 run_args.num_s2m_rings;
1602 slot = (c->args.is_master) ? ring->
tail : ring->
head;
1623 (uint32_t) (b0->
data -
1624 c->regions[ring->
desc[slot & mask].
region].addr);
1639 DBG (
"allocated: %u/%u bufs. Total %u allocated bufs", *count_out, count,
1644 DBG (
"ring buffer full! qid: %u", qid);
1654 uint16_t * count_out, uint16_t
size)
1662 (c->args.is_master) ? c->run_args.num_m2s_rings : c->
1663 run_args.num_s2m_rings;
1674 uint32_t offset_mask = c->run_args.buffer_size - 1;
1678 uint16_t dst_left, src_left;
1679 uint16_t saved_count;
1684 slot = (c->args.is_master) ? ring->
tail : ring->
head;
1687 if (c->args.is_master)
1694 b0 = (bufs + *count_out);
1697 saved_count =
count;
1703 dst_left = (c->args.is_master) ? ring->
desc[slot & mask].
length :
1704 c->run_args.buffer_size;
1722 b0 = (bufs + *count_out);
1725 (c->args.is_master) ? ring->
desc[slot & mask].
1726 length : c->run_args.buffer_size;
1733 * (saved_count - count + 1));
1734 *count_out -= saved_count -
count;
1742 if (c->args.is_master == 0)
1752 src_left -= b0->
len;
1753 dst_left -= b0->
len;
1765 DBG (
"allocated: %u/%u bufs. Total %u allocated bufs", *count_out, count,
1770 DBG (
"ring buffer full! qid: %u", qid);
1787 (c->args.is_master) ? c->run_args.num_s2m_rings : c->
1788 run_args.num_m2s_rings;
1795 uint32_t offset_mask = c->run_args.buffer_size - 1;
1798 if (c->args.is_master)
1802 (ring->
tail + count <=
1807 uint16_t head = ring->
head;
1809 head += (count < ns) ? count : ns;
1815 d = &ring->
desc[slot & mask];
1817 d->
length = c->run_args.buffer_size - headroom;
1841 (c->args.is_master) ? c->run_args.num_m2s_rings : c->
1842 run_args.num_s2m_rings;
1865 #ifdef MEMIF_DBG_SHM 1867 printf (
"data: %p\n",
1880 if (c->args.is_master)
1890 int r = write (mq->
int_fd, &a, sizeof (a));
1908 (c->args.is_master) ? c->run_args.num_s2m_rings : c->
1909 run_args.num_m2s_rings;
1917 uint16_t cur_slot, last_slot;
1924 ssize_t r = read (mq->
int_fd, &b, sizeof (b));
1929 last_slot = (c->args.is_master) ? ring->
head : ring->
tail;
1930 if (cur_slot == last_slot)
1933 ns = last_slot - cur_slot;
1943 if (c->args.is_master == 0)
1945 ring->
desc[cur_slot & mask].
length = c->run_args.buffer_size;
1952 ring->
desc[cur_slot & mask].
flags &= ~MEMIF_DESC_FLAG_NEXT;
1956 #ifdef MEMIF_DBG_SHM 1957 printf (
"data: %p\n", b0->
data);
1959 printf (
"ring: %p\n", b0->
ring);
1969 if (c->args.is_master)
1976 DBG (
"not enough buffers!");
1985 char *buf, ssize_t buflen)
1996 l1 = strlen ((
char *) c->args.interface_name);
1997 if (l0 + l1 < buflen)
2000 (uint8_t *) strcpy (buf + l0, (
char *) c->args.interface_name);
2006 l1 = strlen ((
char *) lm->
app_name);
2007 if (l0 + l1 < buflen)
2015 l1 = strlen ((
char *) c->remote_if_name);
2016 if (l0 + l1 < buflen)
2019 (uint8_t *) strcpy (buf + l0, (
char *) c->remote_if_name);
2025 l1 = strlen ((
char *) c->remote_name);
2026 if (l0 + l1 < buflen)
2029 (uint8_t *) strcpy (buf + l0, (
char *) c->remote_name);
2035 md->
id = c->args.interface_id;
2037 if (strlen ((
char *) c->args.secret) > 0)
2039 l1 = strlen ((
char *) c->args.secret);
2040 if (l0 + l1 < buflen)
2042 md->
secret = (uint8_t *) strcpy (buf + l0, (
char *) c->args.secret);
2049 md->
role = (c->args.is_master) ? 0 : 1;
2050 md->
mode = c->args.mode;
2052 l1 = strlen ((
char *) c->args.socket_filename);
2053 if (l0 + l1 < buflen)
2056 (uint8_t *) strcpy (buf + l0, (
char *) c->args.socket_filename);
2062 l1 = strlen ((
char *) c->remote_disconnect_string);
2063 if (l0 + l1 < buflen)
2066 (uint8_t *) strcpy (buf + l0, (
char *) c->remote_disconnect_string);
2074 if (l0 + l1 <= buflen)
2091 (c->args.is_master) ? c->run_args.num_s2m_rings : c->
2092 run_args.num_m2s_rings;
2095 if (l0 + l1 <= buflen)
2114 (c->args.is_master) ? c->run_args.num_m2s_rings : c->
2115 run_args.num_s2m_rings;
2118 if (l0 + l1 <= buflen)
2151 (c->args.is_master) ? c->run_args.num_s2m_rings : c->
2152 run_args.num_m2s_rings;
2156 *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)
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)
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
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)
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_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)
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
#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
int( memif_add_external_region_t)(void **addr, uint32_t size, int *fd, void *private_ctx)
Add external region.
#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.
memif_del_external_region_t * del_external_region
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.
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)
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
void *( memif_alloc_t)(size_t size)
Memif allocator alloc.
int memif_control_fd_update(int fd, uint8_t events)