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, 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));
911 if (conn->args.is_master)
914 struct sockaddr_un sun;
915 sockfd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
922 sun.sun_family = AF_UNIX;
924 strncpy (sun.sun_path, (
char *) conn->args.socket_filename,
925 sizeof (sun.sun_path) - 1);
927 if (connect (sockfd, (
struct sockaddr *) &sun,
928 sizeof (
struct sockaddr_un)) == 0)
954 strcpy ((
char *) conn->remote_disconnect_string,
971 data_struct)->run_args.
973 run_args.num_m2s_rings;
974 for (i = 0; i < num; i++)
977 rx_queues[i].int_fd == fd)
982 data_struct)->private_ctx, i);
1047 struct epoll_event evt, *e;
1050 uint32_t events = 0;
1051 uint64_t counter = 0;
1053 memset (&evt, 0,
sizeof (evt));
1054 evt.events = EPOLLIN | EPOLLOUT;
1056 sigemptyset (&sigset);
1057 en = epoll_pwait (
memif_epfd, &evt, 1, timeout, &sigset);
1061 DBG (
"epoll_pwait: %s", strerror (err));
1068 r = read (evt.data.fd, &counter, sizeof (counter));
1071 if (evt.events & EPOLLIN)
1073 if (evt.events & EPOLLOUT)
1075 if (evt.events & EPOLLERR)
1086 uint64_t counter = 1;
1092 if (w <
sizeof (counter))
1115 DBG (
"no connection");
1124 c->on_disconnect ((
void *) c, c->private_ctx);
1135 if (c->args.is_master)
1137 e->
key = c->fd = -1;
1140 if (c->tx_queues !=
NULL)
1143 (c->args.is_master) ? c->run_args.num_m2s_rings : c->
1144 run_args.num_s2m_rings;
1145 for (i = 0; i < num; i++)
1147 mq = &c->tx_queues[
i];
1157 lm->
free (c->tx_queues);
1158 c->tx_queues =
NULL;
1161 if (c->rx_queues !=
NULL)
1164 (c->args.is_master) ? c->run_args.num_s2m_rings : c->
1165 run_args.num_m2s_rings;
1166 for (i = 0; i < num; i++)
1168 mq = &c->rx_queues[
i];
1173 if (c->on_interrupt !=
NULL)
1182 lm->
free (c->rx_queues);
1183 c->rx_queues =
NULL;
1186 for (i = 0; i < c->regions_num; i++)
1188 if (&c->regions[i] ==
NULL)
1190 if (c->regions[i].is_external != 0)
1193 c->regions[i].region_size,
1194 c->regions[i].fd, c->private_ctx);
1198 if (munmap (c->regions[i].addr, c->regions[i].region_size) < 0)
1200 if (c->regions[i].fd > 0)
1201 close (c->regions[i].fd);
1202 c->regions[
i].fd = -1;
1205 lm->
free (c->regions);
1213 if (!(c->args.is_master))
1217 if (timerfd_settime (lm->
timerfd, 0, &lm->arm,
NULL) < 0)
1220 DBG (
"timerfd_settime: arm");
1235 DBG (
"no connection");
1246 DBG (
"DISCONNECTING");
1254 if (c->args.is_master)
1263 c->args.interface_id);
1269 close (c->listener_fd);
1270 c->listener_fd = ms->
fd = -1;
1288 DBG (
"timerfd_settime: disarm");
1293 if (c->args.socket_filename)
1294 lm->
free (c->args.socket_filename);
1295 c->args.socket_filename =
NULL;
1313 for (i = 0; i < c->regions_num; i++)
1315 mr = &c->regions[
i];
1335 MAP_SHARED, mr->
fd, 0)) == MAP_FAILED)
1344 for (i = 0; i < c->rx_queues_num; i++)
1346 mq = &c->rx_queues[
i];
1352 DBG (
"wrong cookie on rx ring %u", i);
1360 for (i = 0; i < c->tx_queues_num; i++)
1362 mq = &c->tx_queues[
i];
1368 DBG (
"wrong cookie on tx ring %u", i);
1383 uint8_t has_buffers)
1394 r = &conn->regions[conn->regions_num - 1];
1397 if (has_buffers != 0)
1404 (conn->run_args.num_s2m_rings +
1405 conn->run_args.num_m2s_rings) * (
sizeof (
memif_ring_t) +
1408 run_args.log2_ring_size));
1412 conn->run_args.buffer_size * (1 << conn->run_args.log2_ring_size) *
1413 (conn->run_args.num_s2m_rings + conn->run_args.num_m2s_rings);
1425 MAP_SHARED, r->
fd, 0)) == MAP_FAILED)
1437 for (i = 0; i < conn->run_args.num_s2m_rings; i++)
1440 DBG (
"RING: %p I: %d", ring, i);
1444 for (j = 0; j < (1 << conn->run_args.log2_ring_size); j++)
1446 uint16_t slot = i * (1 << conn->run_args.log2_ring_size) + j;
1449 conn->regions[1].buffer_offset +
1450 (uint32_t) (slot * conn->run_args.buffer_size);
1451 ring->
desc[j].
length = conn->run_args.buffer_size;
1454 for (i = 0; i < conn->run_args.num_m2s_rings; i++)
1457 DBG (
"RING: %p I: %d", ring, i);
1461 for (j = 0; j < (1 << conn->run_args.log2_ring_size); j++)
1463 uint16_t slot = (i + conn->run_args.num_s2m_rings) *
1464 (1 << conn->run_args.log2_ring_size) + j;
1467 conn->regions[1].buffer_offset +
1468 (uint32_t) (slot * conn->run_args.buffer_size);
1469 ring->
desc[j].
length = conn->run_args.buffer_size;
1477 conn->run_args.num_s2m_rings);
1483 for (x = 0; x < conn->run_args.num_s2m_rings; x++)
1485 if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
1492 DBG (
"RING: %p I: %d", mq[x].ring, x);
1496 (
void *) mq[x].ring - (
void *) conn->regions[mq->
region].addr;
1500 conn->tx_queues = mq;
1504 conn->run_args.num_m2s_rings);
1508 for (x = 0; x < conn->run_args.num_m2s_rings; x++)
1510 if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
1517 DBG (
"RING: %p I: %d", mq[x].ring, x);
1521 (
void *) mq[x].ring - (
void *) conn->regions[mq->
region].addr;
1525 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);
1655 uint16_t * count_out, uint16_t
size)
1663 (c->args.is_master) ? c->run_args.num_m2s_rings : c->
1664 run_args.num_s2m_rings;
1675 uint32_t offset_mask = c->run_args.buffer_size - 1;
1679 uint16_t dst_left, src_left;
1680 uint16_t saved_count;
1685 slot = (c->args.is_master) ? ring->
tail : ring->
head;
1688 if (c->args.is_master)
1695 b0 = (bufs + *count_out);
1698 saved_count =
count;
1704 dst_left = (c->args.is_master) ? ring->
desc[slot & mask].
length :
1705 c->run_args.buffer_size;
1723 b0 = (bufs + *count_out);
1726 (c->args.is_master) ? ring->
desc[slot & mask].
1727 length : c->run_args.buffer_size;
1734 * (saved_count - count + 1));
1735 *count_out -= saved_count -
count;
1743 if (c->args.is_master == 0)
1753 src_left -= b0->
len;
1754 dst_left -= b0->
len;
1766 DBG (
"allocated: %u/%u bufs. Total %u allocated bufs", *count_out, count,
1771 DBG (
"ring buffer full! qid: %u", qid);
1789 (c->args.is_master) ? c->run_args.num_s2m_rings : c->
1790 run_args.num_m2s_rings;
1797 uint32_t offset_mask = c->run_args.buffer_size - 1;
1800 if (c->args.is_master)
1804 (ring->
tail + count <=
1809 uint16_t head = ring->
head;
1811 head += (count < ns) ? count : ns;
1817 d = &ring->
desc[slot & mask];
1819 d->
length = c->run_args.buffer_size - headroom;
1843 (c->args.is_master) ? c->run_args.num_m2s_rings : c->
1844 run_args.num_s2m_rings;
1867 #ifdef MEMIF_DBG_SHM 1869 printf (
"data: %p\n",
1882 if (c->args.is_master)
1892 int r = write (mq->
int_fd, &a, sizeof (a));
1910 (c->args.is_master) ? c->run_args.num_s2m_rings : c->
1911 run_args.num_m2s_rings;
1919 uint16_t cur_slot, last_slot;
1926 ssize_t r = read (mq->
int_fd, &b, sizeof (b));
1931 last_slot = (c->args.is_master) ? ring->
head : ring->
tail;
1932 if (cur_slot == last_slot)
1935 ns = last_slot - cur_slot;
1945 if (c->args.is_master == 0)
1947 ring->
desc[cur_slot & mask].
length = c->run_args.buffer_size;
1954 ring->
desc[cur_slot & mask].
flags &= ~MEMIF_DESC_FLAG_NEXT;
1958 #ifdef MEMIF_DBG_SHM 1959 printf (
"data: %p\n", b0->
data);
1961 printf (
"ring: %p\n", b0->
ring);
1971 if (c->args.is_master)
1978 DBG (
"not enough buffers!");
1987 char *buf, ssize_t buflen)
1995 ssize_t l0, l1, total_l;
1998 l1 = strlen ((
char *) c->args.interface_name);
1999 if (l0 + l1 < buflen)
2002 (uint8_t *) strcpy (buf + l0, (
char *) c->args.interface_name);
2008 l1 = strlen ((
char *) lm->
app_name);
2009 if (l0 + l1 < buflen)
2017 l1 = strlen ((
char *) c->remote_if_name);
2018 if (l0 + l1 < buflen)
2021 (uint8_t *) strcpy (buf + l0, (
char *) c->remote_if_name);
2027 l1 = strlen ((
char *) c->remote_name);
2028 if (l0 + l1 < buflen)
2031 (uint8_t *) strcpy (buf + l0, (
char *) c->remote_name);
2037 md->
id = c->args.interface_id;
2039 if (strlen ((
char *) c->args.secret) > 0)
2041 l1 = strlen ((
char *) c->args.secret);
2042 if (l0 + l1 < buflen)
2044 md->
secret = (uint8_t *) strcpy (buf + l0, (
char *) c->args.secret);
2051 md->
role = (c->args.is_master) ? 0 : 1;
2052 md->
mode = c->args.mode;
2054 l1 = strlen ((
char *) c->args.socket_filename);
2055 if (l0 + l1 < buflen)
2058 (uint8_t *) strcpy (buf + l0, (
char *) c->args.socket_filename);
2064 l1 = strlen ((
char *) c->remote_disconnect_string);
2065 if (l0 + l1 < buflen)
2068 (uint8_t *) strcpy (buf + l0, (
char *) c->remote_disconnect_string);
2076 if (l0 + l1 <= buflen)
2094 (c->args.is_master) ? c->run_args.num_s2m_rings : c->
2095 run_args.num_m2s_rings;
2098 if (l0 + l1 <= buflen)
2118 (c->args.is_master) ? c->run_args.num_m2s_rings : c->
2119 run_args.num_s2m_rings;
2122 if (l0 + l1 <= buflen)
2156 (c->args.is_master) ? c->run_args.num_s2m_rings : c->
2157 run_args.num_m2s_rings;
2161 *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 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)
memset(h->entries, 0, sizeof(h->entries[0])*entries)
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)