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 () 75 "Unspecified syscall error (build with -DMEMIF_DBG or make debug).",
79 "Permission to resource denied.",
81 "Socket file does not exist",
83 "System limit on total numer of open files reached.",
85 "Per-process limit on total number of open files reached.",
87 "Connection already requested.",
89 "File descriptor refers to file other than socket, or operation would block.",
91 "Bad file descriptor.",
97 "Memif connection handle does not point to existing connection",
99 "Memif connection handle points to existing connection",
101 "Callback memif_control_fd_update_t returned error",
103 "File specified by socket filename exists and is not socket.",
105 "Missing shared memory file descriptor. (internal error)",
107 "Invalid cookie on ring. (internal error)",
111 "Not enough memif buffers. There are unreceived data in shared memory.",
113 "Not enough space for memif details in supplied buffer. String data might be malformed.",
115 "Send interrupt error.",
117 "Malformed message received on control channel.",
121 "Incompatible memory interface protocol version.",
123 "Unmatched interface id.",
125 "Slave cannot accept connection request.",
127 "Interface is already connected.",
135 "Limit on total number of regions reached.",
137 "Limit on total number of ring reached.",
139 "Missing interrupt file descriptor. (internal error)",
141 "Interface received disconnect request.",
143 "Interface is disconnected.",
145 "Unknown message type received on control channel. (internal error)",
147 "Memif event polling was canceled.",
149 "Maximum log2 ring size is 15",
151 "Private headers not supported." 154 #define MEMIF_ERR_UNDEFINED "undefined error" 179 #define DBG_TX_BUF (0) 180 #define DBG_RX_BUF (1) 184 print_bytes (
void *
data, uint16_t
len, uint8_t q)
187 printf (
"\nTX:\n\t");
189 printf (
"\nRX:\n\t");
191 for (i = 0; i <
len; i++)
194 printf (
"\n%d:\t", i);
195 printf (
"%02X ", ((uint8_t *) (data))[i]);
204 DBG (
"%s", strerror (err_code));
208 if (err_code == EACCES)
210 if (err_code == ENFILE)
212 if (err_code == EMFILE)
214 if (err_code == ENOMEM)
222 if (err_code == ECONNREFUSED)
224 if (err_code == EALREADY)
226 if (err_code == EAGAIN)
228 if (err_code == EBADF)
230 if (err_code == ENOENT)
241 if (ms != NULL && ms->
lm != NULL)
251 DBG (
"invalid fd %d", fd);
254 struct epoll_event evt;
255 memset (&evt, 0,
sizeof (evt));
258 if (epoll_ctl (lm->
epfd, EPOLL_CTL_ADD, fd, &evt) < 0)
260 DBG (
"epoll_ctl: %s fd %d", strerror (errno), fd);
263 DBG (
"fd %d added to epoll", fd);
272 DBG (
"invalid fd %d", fd);
275 struct epoll_event evt;
276 memset (&evt, 0,
sizeof (evt));
279 if (epoll_ctl (lm->
epfd, EPOLL_CTL_MOD, fd, &evt) < 0)
281 DBG (
"epoll_ctl: %s fd %d", strerror (errno), fd);
284 DBG (
"fd %d modified on epoll", fd);
293 DBG (
"invalid fd %d", fd);
296 struct epoll_event evt;
297 memset (&evt, 0,
sizeof (evt));
298 if (epoll_ctl (lm->
epfd, EPOLL_CTL_DEL, fd, &evt) < 0)
300 DBG (
"epoll_ctl: %s fd %d", strerror (errno), fd);
303 DBG (
"fd %d removed from epoll", fd);
312 lm = (private_ctx == NULL) ? &libmemif_main : (
libmemif_main_t *) private_ctx;
336 for (i = 0; i < *
len; i++)
338 if ((*list)[i].data_struct == NULL)
340 (*list)[
i].key = e->
key;
350 for (i = *len; i < *len * 2; i++)
376 for (i = 0; i <
len; i++)
378 if (list[i].key == key)
393 for (i = 0; i <
len; i++)
395 if (list[i].key == key)
411 for (i = 0; i <
len; i++)
413 if (list[i].
key == -1)
415 if (list[i].data_struct == ctx)
475 if (timerfd_settime (lm->
timerfd, 0, &lm->arm, NULL) < 0)
486 struct itimerspec timer)
496 if (timerfd_settime (lm->
timerfd, 0, &lm->arm, NULL) < 0)
514 if (memif_alloc != NULL)
521 if (memif_realloc != NULL)
528 if (memif_free != NULL)
533 if (app_name != NULL)
537 strncpy ((
char *) lm->
app_name, app_name, len);
547 if (on_control_fd_update != NULL)
551 lm->
epfd = epoll_create (1);
556 DBG (
"eventfd: %s", strerror (err));
560 DBG (
"libmemif event polling initialized");
621 lm->
timerfd = timerfd_create (CLOCK_REALTIME, TFD_NONBLOCK);
635 DBG (
"callback type memif_control_fd_update_t error!");
667 if (memif_alloc != NULL)
678 if (memif_alloc != NULL)
685 if (memif_realloc != NULL)
692 if (memif_free != NULL)
700 if (app_name != NULL)
704 strncpy ((
char *) lm->
app_name, app_name, len);
714 if (on_control_fd_update != NULL)
722 lm->
epfd = epoll_create (1);
727 DBG (
"eventfd: %s", strerror (err));
732 DBG (
"libmemif event polling initialized");
794 lm->
timerfd = timerfd_create (CLOCK_REALTIME, TFD_NONBLOCK);
809 DBG (
"callback type memif_control_fd_update_t error!");
828 if (&conn->regions[0] == NULL)
830 void *p = conn->regions[0].addr;
833 sizeof (
memif_desc_t) * (1 << conn->run_args.log2_ring_size);
834 p += (ring_num + type * conn->run_args.num_s2m_rings) * ring_size;
847 (conn->args.is_master) ? conn->run_args.num_s2m_rings : conn->
848 run_args.num_m2s_rings;
852 conn->rx_queues[qid].ring->flags =
rx_mode;
853 DBG (
"rx_mode flag: %u", conn->rx_queues[qid].ring->flags);
862 struct stat file_stat;
863 struct sockaddr_un un = { 0 };
871 if (stat ((
char *) ms->
filename, &file_stat) == 0)
873 if (S_ISSOCK (file_stat.st_mode))
879 ms->
fd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
886 DBG (
"socket %d created", ms->
fd);
887 un.sun_family = AF_UNIX;
888 strncpy ((
char *) un.sun_path, (
char *) ms->
filename,
889 sizeof (un.sun_path) - 1);
890 if (setsockopt (ms->
fd, SOL_SOCKET, SO_PASSCRED, &on, sizeof (on)) < 0)
895 if (bind (ms->
fd, (
struct sockaddr *) &un, sizeof (un)) < 0)
900 if (listen (ms->
fd, 1) < 0)
905 if (stat ((
char *) ms->
filename, &file_stat) < 0)
943 if (strncmp ((
char *) ms->
filename, filename,
944 strlen ((
char *) ms->
filename)) == 0)
959 ms->
filename = lm->
alloc (strlen (filename) +
sizeof (
char));
965 memset (ms->
filename, 0, strlen (filename) +
sizeof (
char));
966 strncpy ((
char *) ms->
filename, filename, strlen (filename));
1013 const char *filename,
void *private_ctx)
1026 if (strncmp ((
char *) ms->
filename, filename,
1027 strlen ((
char *) ms->
filename)) == 0)
1043 ms->
filename = lm->
alloc (strlen (filename) +
sizeof (
char));
1049 memset (ms->
filename, 0, strlen (filename) +
sizeof (
char));
1050 strncpy ((
char *) ms->
filename, filename, strlen (filename));
1108 DBG (
"This handle already points to existing memif.");
1141 conn->args.mode = args->
mode;
1142 conn->msg_queue = NULL;
1143 conn->regions = NULL;
1144 conn->tx_queues = NULL;
1145 conn->rx_queues = NULL;
1150 conn->private_ctx = private_ctx;
1154 strncpy ((
char *) conn->args.interface_name, (
char *) args->
interface_name,
1157 if ((l = strlen ((
char *) args->
secret)) > 0)
1158 strncpy ((
char *) conn->args.secret, (
char *) args->
secret, l);
1160 if (args->
socket != NULL)
1161 conn->args.socket = args->
socket;
1179 elt.
key = conn->args.interface_id;
1184 if (conn->args.is_master)
1212 if (timerfd_settime (lm->
timerfd, 0, &lm->arm, NULL) < 0)
1240 struct sockaddr_un sun;
1254 sockfd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
1261 sun.sun_family = AF_UNIX;
1263 strncpy (sun.sun_path, (
char *) ms->
filename, sizeof (sun.sun_path) - 1);
1265 if (connect (sockfd, (
struct sockaddr *) &sun,
1266 sizeof (
struct sockaddr_un)) == 0)
1281 if (timerfd_settime (lm->
timerfd, 0, &lm->
disarm, NULL) < 0)
1291 strcpy ((
char *) conn->remote_disconnect_string,
memif_strerror (err));
1318 size = read (fd, &b,
sizeof (b));
1329 if (conn->args.is_master)
1347 data_struct)->run_args.
1349 run_args.num_m2s_rings;
1350 for (i = 0; i < num; i++)
1353 rx_queues[i].int_fd == fd)
1358 data_struct)->private_ctx, i);
1420 int fd, uint8_t events)
1432 size = read (fd, &b,
sizeof (b));
1443 if (conn->args.is_master)
1461 data_struct)->run_args.
1463 run_args.num_m2s_rings;
1464 for (i = 0; i < num; i++)
1467 rx_queues[i].int_fd == fd)
1472 data_struct)->private_ctx, i);
1536 struct epoll_event evt;
1538 uint32_t events = 0;
1539 uint64_t counter = 0;
1541 memset (&evt, 0,
sizeof (evt));
1542 evt.events = EPOLLIN | EPOLLOUT;
1544 sigemptyset (&sigset);
1545 en = epoll_pwait (lm->
epfd, &evt, 1, timeout, &sigset);
1549 DBG (
"epoll_pwait: %s", strerror (err));
1556 r = read (evt.data.fd, &counter, sizeof (counter));
1562 if (evt.events & EPOLLIN)
1564 if (evt.events & EPOLLOUT)
1566 if (evt.events & EPOLLERR)
1579 struct epoll_event evt;
1581 uint32_t events = 0;
1582 uint64_t counter = 0;
1584 memset (&evt, 0,
sizeof (evt));
1585 evt.events = EPOLLIN | EPOLLOUT;
1587 sigemptyset (&sigset);
1588 en = epoll_pwait (lm->
epfd, &evt, 1, timeout, &sigset);
1592 DBG (
"epoll_pwait: %s", strerror (err));
1599 r = read (evt.data.fd, &counter, sizeof (counter));
1605 if (evt.events & EPOLLIN)
1607 if (evt.events & EPOLLOUT)
1609 if (evt.events & EPOLLERR)
1621 uint64_t counter = 1;
1627 if (w <
sizeof (counter))
1637 uint64_t counter = 1;
1646 if (w <
sizeof (counter))
1674 DBG (
"no connection");
1680 c->on_disconnect ((
void *) c, c->private_ctx);
1691 if (c->args.is_master)
1693 e->
key = c->fd = -1;
1696 if (c->tx_queues != NULL)
1698 for (i = 0; i < c->tx_queues_num; i++)
1700 mq = &c->tx_queues[
i];
1710 lm->
free (c->tx_queues);
1711 c->tx_queues = NULL;
1713 c->tx_queues_num = 0;
1715 if (c->rx_queues != NULL)
1717 for (i = 0; i < c->rx_queues_num; i++)
1719 mq = &c->rx_queues[
i];
1724 if (c->on_interrupt != NULL)
1734 lm->
free (c->rx_queues);
1735 c->rx_queues = NULL;
1737 c->rx_queues_num = 0;
1739 for (i = 0; i < c->regions_num; i++)
1741 if (&c->regions[i] == NULL)
1743 if (c->regions[i].is_external != 0)
1746 c->regions[i].region_size,
1747 c->regions[i].fd, c->private_ctx);
1751 if (munmap (c->regions[i].addr, c->regions[i].region_size) < 0)
1753 if (c->regions[i].fd > 0)
1754 close (c->regions[i].fd);
1755 c->regions[
i].fd = -1;
1758 lm->
free (c->regions);
1766 if (!(c->args.is_master))
1770 if (timerfd_settime (lm->
timerfd, 0, &lm->arm, NULL) < 0)
1773 DBG (
"timerfd_settime: arm");
1825 DBG (
"no connection");
1831 DBG (
"DISCONNECTING");
1844 c->args.interface_id);
1859 if (!c->args.is_master)
1864 if (timerfd_settime (lm->
timerfd, 0, &lm->
disarm, NULL) < 0)
1867 DBG (
"timerfd_settime: disarm");
1892 for (i = 0; i < c->regions_num; i++)
1894 mr = &c->regions[
i];
1913 mmap (NULL, mr->
region_size, PROT_READ | PROT_WRITE,
1914 MAP_SHARED, mr->
fd, 0)) == MAP_FAILED)
1923 for (i = 0; i < c->rx_queues_num; i++)
1925 mq = &c->rx_queues[
i];
1931 DBG (
"wrong cookie on rx ring %u", i);
1939 for (i = 0; i < c->tx_queues_num; i++)
1941 mq = &c->tx_queues[
i];
1947 DBG (
"wrong cookie on tx ring %u", i);
1963 uint8_t has_buffers)
1974 r = &conn->regions[conn->regions_num - 1];
1977 if (has_buffers != 0)
1984 (conn->run_args.num_s2m_rings +
1985 conn->run_args.num_m2s_rings) * (
sizeof (
memif_ring_t) +
1988 run_args.log2_ring_size));
1992 conn->run_args.buffer_size * (1 << conn->run_args.log2_ring_size) *
1993 (conn->run_args.num_s2m_rings + conn->run_args.num_m2s_rings);
2005 MAP_SHARED, r->
fd, 0)) == MAP_FAILED)
2017 for (i = 0; i < conn->run_args.num_s2m_rings; i++)
2020 DBG (
"RING: %p I: %d", ring, i);
2024 for (j = 0; j < (1 << conn->run_args.log2_ring_size); j++)
2026 uint16_t
slot = i * (1 << conn->run_args.log2_ring_size) + j;
2029 conn->regions[1].buffer_offset +
2030 (uint32_t) (slot * conn->run_args.buffer_size);
2031 ring->
desc[j].
length = conn->run_args.buffer_size;
2034 for (i = 0; i < conn->run_args.num_m2s_rings; i++)
2037 DBG (
"RING: %p I: %d", ring, i);
2041 for (j = 0; j < (1 << conn->run_args.log2_ring_size); j++)
2043 uint16_t
slot = (i + conn->run_args.num_s2m_rings) *
2044 (1 << conn->run_args.log2_ring_size) + j;
2047 conn->regions[1].buffer_offset +
2048 (uint32_t) (slot * conn->run_args.buffer_size);
2049 ring->
desc[j].
length = conn->run_args.buffer_size;
2057 conn->run_args.num_s2m_rings);
2063 for (x = 0; x < conn->run_args.num_s2m_rings; x++)
2065 if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
2072 DBG (
"RING: %p I: %d", mq[x].ring, x);
2076 (
void *) mq[x].ring - (
void *) conn->regions[mq->
region].addr;
2080 conn->tx_queues = mq;
2081 conn->tx_queues_num = conn->run_args.num_s2m_rings;
2085 conn->run_args.num_m2s_rings);
2089 for (x = 0; x < conn->run_args.num_m2s_rings; x++)
2091 if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
2098 DBG (
"RING: %p I: %d", mq[x].ring, x);
2102 (
void *) mq[x].ring - (
void *) conn->regions[mq->
region].addr;
2106 conn->rx_queues = mq;
2107 conn->rx_queues_num = conn->run_args.num_m2s_rings;
2132 ++conn->regions_num);
2137 conn->regions[1].region_size =
2138 conn->run_args.buffer_size * (1 << conn->run_args.log2_ring_size) *
2139 (conn->run_args.num_s2m_rings + conn->run_args.num_m2s_rings);
2140 conn->regions[1].buffer_offset = 0;
2142 conn->regions[1].region_size,
2143 &conn->regions[1].fd, conn->private_ctx);
2144 conn->regions[1].is_external = 1;
2159 uint16_t * count_out)
2167 (c->args.is_master) ? c->run_args.num_m2s_rings : c->
2168 run_args.num_s2m_rings;
2186 slot = (c->args.is_master) ? ring->
tail : ring->
head;
2207 (uint32_t) (b0->
data -
2208 c->regions[ring->
desc[slot & mask].
region].addr);
2224 DBG (
"allocated: %u/%u bufs. Total %u allocated bufs", *count_out, count,
2229 DBG (
"ring buffer full! qid: %u", qid);
2239 uint16_t * count_out, uint16_t
size)
2247 (c->args.is_master) ? c->run_args.num_m2s_rings : c->
2248 run_args.num_s2m_rings;
2259 uint32_t offset_mask = c->run_args.buffer_size - 1;
2263 uint16_t dst_left, src_left;
2264 uint16_t saved_count;
2269 slot = (c->args.is_master) ? ring->
tail : ring->
head;
2272 if (c->args.is_master)
2279 b0 = (bufs + *count_out);
2282 saved_count =
count;
2288 dst_left = (c->args.is_master) ? ring->
desc[slot & mask].
length :
2289 c->run_args.buffer_size;
2307 b0 = (bufs + *count_out);
2310 (c->args.is_master) ? ring->
desc[slot & mask].
2311 length : c->run_args.buffer_size;
2318 * (saved_count - count + 1));
2319 *count_out -= saved_count -
count;
2327 if (c->args.is_master == 0)
2337 src_left -= b0->
len;
2338 dst_left -= b0->
len;
2350 DBG (
"allocated: %u/%u bufs. Total %u allocated bufs", *count_out, count,
2355 DBG (
"ring buffer full! qid: %u", qid);
2372 (c->args.is_master) ? c->run_args.num_s2m_rings : c->
2373 run_args.num_m2s_rings;
2380 uint32_t offset_mask = c->run_args.buffer_size - 1;
2383 if (c->args.is_master)
2387 (ring->
tail + count <=
2392 uint16_t head = ring->
head;
2394 head += (count < ns) ?
count : ns;
2402 d->
length = c->run_args.buffer_size - headroom;
2426 (c->args.is_master) ? c->run_args.num_m2s_rings : c->
2427 run_args.num_s2m_rings;
2450 #ifdef MEMIF_DBG_SHM 2452 printf (
"data: %p\n",
2465 if (c->args.is_master)
2475 int r = write (mq->
int_fd, &a, sizeof (a));
2493 (c->args.is_master) ? c->run_args.num_s2m_rings : c->
2494 run_args.num_m2s_rings;
2502 uint16_t cur_slot, last_slot;
2512 last_slot = (c->args.is_master) ? ring->
head : ring->
tail;
2513 if (cur_slot == last_slot)
2515 r = read (mq->
int_fd, &b, sizeof (b));
2522 ns = last_slot - cur_slot;
2532 if (c->args.is_master == 0)
2545 #ifdef MEMIF_DBG_SHM 2546 printf (
"data: %p\n", b0->
data);
2548 printf (
"ring: %p\n", b0->
ring);
2558 if (c->args.is_master)
2565 DBG (
"not enough buffers!");
2569 r = read (mq->
int_fd, &b, sizeof (b));
2578 char *buf, ssize_t buflen)
2592 l1 = strlen ((
char *) c->args.interface_name);
2593 if (l0 + l1 < buflen)
2596 (uint8_t *) strcpy (buf + l0, (
char *) c->args.interface_name);
2602 l1 = strlen ((
char *) lm->
app_name);
2603 if (l0 + l1 < buflen)
2611 l1 = strlen ((
char *) c->remote_if_name);
2612 if (l0 + l1 < buflen)
2615 (uint8_t *) strcpy (buf + l0, (
char *) c->remote_if_name);
2621 l1 = strlen ((
char *) c->remote_name);
2622 if (l0 + l1 < buflen)
2625 (uint8_t *) strcpy (buf + l0, (
char *) c->remote_name);
2631 md->
id = c->args.interface_id;
2633 if (strlen ((
char *) c->args.secret) > 0)
2635 l1 = strlen ((
char *) c->args.secret);
2636 if (l0 + l1 < buflen)
2638 md->
secret = (uint8_t *) strcpy (buf + l0, (
char *) c->args.secret);
2645 md->
role = (c->args.is_master) ? 0 : 1;
2646 md->
mode = c->args.mode;
2648 l1 = strlen ((
char *) ms->
filename);
2649 if (l0 + l1 < buflen)
2652 (uint8_t *) strcpy (buf + l0, (
char *) ms->
filename);
2658 l1 = strlen ((
char *) c->remote_disconnect_string);
2659 if (l0 + l1 < buflen)
2662 (uint8_t *) strcpy (buf + l0, (
char *) c->remote_disconnect_string);
2670 if (l0 + l1 <= buflen)
2687 (c->args.is_master) ? c->run_args.num_s2m_rings : c->
2688 run_args.num_m2s_rings;
2691 if (l0 + l1 <= buflen)
2710 (c->args.is_master) ? c->run_args.num_m2s_rings : c->
2711 run_args.num_s2m_rings;
2714 if (l0 + l1 <= buflen)
2750 (c->args.is_master) ? c->run_args.num_s2m_rings : c->
2751 run_args.num_m2s_rings;
2755 *efd = c->rx_queues[qid].int_fd;
#define MEMIF_DEFAULT_LOG2_RING_SIZE
int memif_per_thread_poll_event(memif_per_thread_main_handle_t pt_main, int timeout)
Memif per thread poll event.
struct itimerspec arm disarm
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 occurred on fd and pass them to memif_control_fd_handler ...
Optimized string handling code, including c11-compliant "safe C library" variants.
static int memif_del_epoll_fd(libmemif_main_t *lm, int fd)
uint8_t app_name[MEMIF_NAME_LEN]
static void memif_msg_queue_free(libmemif_main_t *lm, memif_msg_queue_elt_t **e)
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_socket_handle_t socket
#define MEMIF_MEMORY_BARRIER()
memif_del_external_region_t * del_external_region
uint8_t * remote_inst_name
static memif_ring_t * memif_get_ring(memif_connection_t *conn, memif_ring_type_t type, uint16_t ring_num)
int memif_refill_queue(memif_conn_handle_t conn, uint16_t qid, uint16_t count, uint16_t headroom)
Memif refill ring.
#define MEMIF_DEFAULT_APP_NAME
Default name of application using libmemif.
#define MFD_ALLOW_SEALING
memif_list_elt_t * interface_list
int on_connect(memif_conn_handle_t conn, void *private_ctx)
const char * memif_get_socket_filename(memif_socket_handle_t sock)
Get socket filename.
int memif_get_details(memif_conn_handle_t conn, memif_details_t *md, char *buf, ssize_t buflen)
Memif get details.
libmemif_main_t * get_libmemif_main(memif_socket_t *ms)
memif_interface_mode_t mode
static clib_error_t * memif_conn_fd_write_ready(clib_file_t *uf, memif_if_t *mif)
int memif_per_thread_init(memif_per_thread_main_handle_t *pt_main, void *private_ctx, 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 per thread initialization.
char * memif_strerror(int err_code)
Memif strerror.
static int memfd_create(const char *name, unsigned int flags)
memif_region_offset_t offset
struct libmemif_main * lm
#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_region_index_t region
uint8_t interface_name[32]
static void memif_free_register(libmemif_main_t *lm, memif_free_t *mf)
uint8_t * socket_filename
#define MEMIF_DEFAULT_SOCKET_PATH
memif_list_elt_t * pending_list
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.
void * memif_socket_handle_t
Memif socket handle pointer of type void, pointing to internal structure.
int() memif_del_external_region_t(void *addr, uint32_t size, int fd, void *private_ctx)
Delete external region.
int memif_create_socket(memif_socket_handle_t *sock, const char *filename, void *private_ctx)
Create memif socket.
int() memif_interrupt_t(memif_conn_handle_t conn, void *private_ctx, uint16_t qid)
Memif interrupt occurred (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)
memif_list_elt_t * interrupt_list
uint16_t pending_list_len
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
static int memif_mod_epoll_fd(libmemif_main_t *lm, int fd, uint32_t events)
void * malloc(size_t size)
#define MEMIF_DEFAULT_RECONNECT_PERIOD_SEC
static void memif_alloc_register(libmemif_main_t *lm, memif_alloc_t *ma)
int memif_init_regions_and_queues(memif_connection_t *conn)
static void memif_realloc_register(libmemif_main_t *lm, memif_realloc_t *mr)
int on_interrupt(memif_conn_handle_t conn, void *private_ctx, uint16_t qid)
int memif_per_thread_create_socket(memif_per_thread_main_handle_t pt_main, memif_socket_handle_t *sock, const char *filename, void *private_ctx)
Create memif socket.
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.
sll srl srl sll sra u16x4 i
int get_list_elt(memif_list_elt_t **e, memif_list_elt_t *list, uint16_t len, int key)
static void memif_control_fd_update_register(libmemif_main_t *lm, memif_control_fd_update_t *cb)
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_list_elt_t * control_list
memif_socket_handle_t default_socket
memif_queue_details_t * rx_queues
static int memif_socket_start_listening(memif_socket_t *ms)
int memif_per_thread_control_fd_handler(memif_per_thread_main_handle_t pt_main, int fd, uint8_t events)
Memif per thread control file descriptor handler.
uint16_t interrupt_list_len
uint16_t control_list_len
void *() memif_realloc_t(void *ptr, size_t size)
Memif realloc.
#define MEMIF_DEFAULT_BUFFER_SIZE
int memif_cleanup()
Memif cleanup.
memif_realloc_t * realloc
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_always_inline void * memif_get_buffer(memif_if_t *mif, memif_ring_t *ring, u16 slot)
#define MEMIF_DEFAULT_RX_QUEUES
void * memif_per_thread_main_handle_t
Memif per thread main handle Pointer of type void, pointing to internal structure.
memif_get_external_region_addr_t * get_external_region_addr
#define MEMIF_RING_FLAG_MASK_INT
#define MEMIF_DEFAULT_RECONNECT_PERIOD_NSEC
void * realloc(void *p, size_t size)
void * memif_conn_handle_t
Memif connection handle pointer of type void, pointing to internal structure.
memif_region_offset_t offset
int memif_per_thread_set_connection_request_timer(memif_per_thread_main_handle_t pt_main, struct itimerspec timer)
Set connection request timer value.
memif_add_external_region_t * add_external_region
static int memif_add_epoll_fd(libmemif_main_t *lm, int fd, uint32_t events)
memif_get_external_buffer_offset_t * get_external_buffer_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.
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.
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
int memif_per_thread_cleanup(memif_per_thread_main_handle_t *pt_main)
Memif per thread cleanup.
int memif_per_thread_cancel_poll_event(memif_per_thread_main_handle_t pt_main)
Send signal to stop concurrently running memif_poll_event().
memif_region_details_t * regions
memif_control_fd_update_t * control_fd_update
#define MEMIF_FD_EVENT_ERROR
inform libmemif that error occurred on fd
int memif_cancel_poll_event()
#define MEMIF_FD_EVENT_MOD
update events
memif_queue_details_t * tx_queues
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.
int add_list_elt(libmemif_main_t *lm, memif_list_elt_t *e, memif_list_elt_t **list, uint16_t *len)
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
int() memif_control_fd_update_t(int fd, uint8_t events, void *private_ctx)
Memif control file descriptor update (callback function)