|
FD.io VPP
v21.10.1-2-g0a485f517
Vector Packet Processing
|
Go to the documentation of this file.
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"
176 #define DBG_TX_BUF (0)
177 #define DBG_RX_BUF (1)
181 print_bytes (
void *
data, uint16_t
len, uint8_t q)
184 printf (
"\nTX:\n\t");
186 printf (
"\nRX:\n\t");
191 printf (
"\n%d:\t",
i);
192 printf (
"%02X ", ((uint8_t *) (
data))[
i]);
201 DBG (
"%s", strerror (err_code));
205 if (err_code == EACCES)
207 if (err_code == ENFILE)
209 if (err_code == EMFILE)
211 if (err_code == ENOMEM)
219 if (err_code == ECONNREFUSED)
221 if (err_code == EALREADY)
223 if (err_code == EAGAIN)
225 if (err_code == EBADF)
227 if (err_code == ENOENT)
238 if (ms != NULL && ms->
lm != NULL)
248 DBG (
"invalid fd %d", fd);
251 struct epoll_event evt;
252 memset (&evt, 0,
sizeof (evt));
255 if (epoll_ctl (lm->
epfd, EPOLL_CTL_ADD, fd, &evt) < 0)
257 DBG (
"epoll_ctl: %s fd %d", strerror (errno), fd);
260 DBG (
"fd %d added to epoll", fd);
269 DBG (
"invalid fd %d", fd);
272 struct epoll_event evt;
273 memset (&evt, 0,
sizeof (evt));
276 if (epoll_ctl (lm->
epfd, EPOLL_CTL_MOD, fd, &evt) < 0)
278 DBG (
"epoll_ctl: %s fd %d", strerror (errno), fd);
281 DBG (
"fd %d modified on epoll", fd);
290 DBG (
"invalid fd %d", fd);
293 struct epoll_event evt;
294 memset (&evt, 0,
sizeof (evt));
295 if (epoll_ctl (lm->
epfd, EPOLL_CTL_DEL, fd, &evt) < 0)
297 DBG (
"epoll_ctl: %s fd %d", strerror (errno), fd);
300 DBG (
"fd %d removed from epoll", fd);
333 for (
i = 0;
i < *
len;
i++)
335 if ((*list)[
i].data_struct == NULL)
337 (*list)[
i].key = e->
key;
350 tmp[
i].data_struct = NULL;
410 if (list[
i].
key == -1)
412 if (list[
i].data_struct ==
ctx)
472 if (timerfd_settime (lm->
timerfd, 0, &lm->arm, NULL) < 0)
483 struct itimerspec timer)
493 if (timerfd_settime (lm->
timerfd, 0, &lm->arm, NULL) < 0)
511 if (memif_alloc != NULL)
518 if (memif_realloc != NULL)
525 if (memif_free != NULL)
542 if (on_control_fd_update != NULL)
546 lm->
epfd = epoll_create (1);
551 DBG (
"eventfd: %s", strerror (err));
555 DBG (
"libmemif event polling initialized");
616 lm->
timerfd = timerfd_create (CLOCK_REALTIME, TFD_NONBLOCK);
630 DBG (
"callback type memif_control_fd_update_t error!");
662 if (memif_alloc != NULL)
673 if (memif_alloc != NULL)
680 if (memif_realloc != NULL)
687 if (memif_free != NULL)
707 if (on_control_fd_update != NULL)
715 lm->
epfd = epoll_create (1);
720 DBG (
"eventfd: %s", strerror (err));
725 DBG (
"libmemif event polling initialized");
787 lm->
timerfd = timerfd_create (CLOCK_REALTIME, TFD_NONBLOCK);
802 DBG (
"callback type memif_control_fd_update_t error!");
821 if (&conn->regions[0] == NULL)
823 void *p = conn->regions[0].addr;
826 sizeof (
memif_desc_t) * (1 << conn->run_args.log2_ring_size);
827 p += (ring_num +
type * conn->run_args.num_s2m_rings) * ring_size;
840 (conn->args.is_master) ? conn->run_args.num_s2m_rings : conn->
841 run_args.num_m2s_rings;
845 conn->rx_queues[qid].ring->flags =
rx_mode;
846 DBG (
"rx_mode flag: %u", conn->rx_queues[qid].ring->flags);
855 struct stat file_stat;
856 struct sockaddr_un
un = { 0 };
864 if (stat ((
char *) ms->
filename, &file_stat) == 0)
866 if (S_ISSOCK (file_stat.st_mode))
872 ms->
fd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
879 DBG (
"socket %d created", ms->
fd);
880 un.sun_family = AF_UNIX;
882 if (setsockopt (ms->
fd, SOL_SOCKET, SO_PASSCRED, &on, sizeof (on)) < 0)
887 if (bind (ms->
fd, (
struct sockaddr *) &
un, sizeof (
un)) < 0)
892 if (listen (ms->
fd, 1) < 0)
897 if (stat ((
char *) ms->
filename, &file_stat) < 0)
905 elt.data_struct = ms;
935 if (strncmp ((
char *) ms->
filename, filename,
936 strlen ((
char *) ms->
filename)) == 0)
994 const char *filename,
void *private_ctx)
1007 if (strncmp ((
char *) ms->
filename, filename,
1008 strlen ((
char *) ms->
filename)) == 0)
1078 DBG (
"This handle already points to existing memif.");
1111 conn->args.mode = args->
mode;
1112 conn->msg_queue = NULL;
1113 conn->regions = NULL;
1114 conn->tx_queues = NULL;
1115 conn->rx_queues = NULL;
1120 conn->private_ctx = private_ctx;
1124 sizeof (conn->args.interface_name));
1126 if ((strlen ((
char *) args->
secret)) > 0)
1128 sizeof (conn->args.secret));
1130 if (args->
socket != NULL)
1131 conn->args.socket = args->
socket;
1149 elt.key = conn->args.interface_id;
1150 elt.data_struct = conn;
1154 if (conn->args.is_master)
1166 elt.data_struct = conn;
1182 if (timerfd_settime (lm->
timerfd, 0, &lm->arm, NULL) < 0)
1210 struct sockaddr_un sun;
1224 sockfd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
1231 sun.sun_family = AF_UNIX;
1235 if (connect (sockfd, (
struct sockaddr *) &sun,
1236 sizeof (
struct sockaddr_un)) == 0)
1251 if (timerfd_settime (lm->
timerfd, 0, &lm->
disarm, NULL) < 0)
1261 strcpy ((
char *) conn->remote_disconnect_string,
memif_strerror (err));
1288 size = read (fd, &
b,
sizeof (
b));
1299 if (conn->args.is_master)
1317 data_struct)->run_args.
1319 run_args.num_m2s_rings;
1320 for (
i = 0;
i < num;
i++)
1323 rx_queues[
i].int_fd == fd)
1328 data_struct)->private_ctx,
i);
1402 size = read (fd, &
b,
sizeof (
b));
1413 if (conn->args.is_master)
1431 data_struct)->run_args.
1433 run_args.num_m2s_rings;
1434 for (
i = 0;
i < num;
i++)
1437 rx_queues[
i].int_fd == fd)
1442 data_struct)->private_ctx,
i);
1506 struct epoll_event evt;
1509 uint64_t counter = 0;
1511 memset (&evt, 0,
sizeof (evt));
1512 evt.events = EPOLLIN | EPOLLOUT;
1514 sigemptyset (&sigset);
1515 en = epoll_pwait (lm->
epfd, &evt, 1, timeout, &sigset);
1519 DBG (
"epoll_pwait: %s", strerror (err));
1526 r = read (evt.data.fd, &counter, sizeof (counter));
1532 if (evt.events & EPOLLIN)
1534 if (evt.events & EPOLLOUT)
1536 if (evt.events & EPOLLERR)
1549 struct epoll_event evt;
1552 uint64_t counter = 0;
1554 memset (&evt, 0,
sizeof (evt));
1555 evt.events = EPOLLIN | EPOLLOUT;
1557 sigemptyset (&sigset);
1558 en = epoll_pwait (lm->
epfd, &evt, 1, timeout, &sigset);
1562 DBG (
"epoll_pwait: %s", strerror (err));
1569 r = read (evt.data.fd, &counter, sizeof (counter));
1575 if (evt.events & EPOLLIN)
1577 if (evt.events & EPOLLOUT)
1579 if (evt.events & EPOLLERR)
1591 uint64_t counter = 1;
1597 if (w <
sizeof (counter))
1607 uint64_t counter = 1;
1616 if (w <
sizeof (counter))
1644 DBG (
"no connection");
1650 c->on_disconnect ((
void *)
c,
c->private_ctx);
1661 if (
c->args.is_master)
1663 e->
key =
c->fd = -1;
1666 if (
c->tx_queues != NULL)
1668 for (
i = 0;
i <
c->tx_queues_num;
i++)
1670 mq = &
c->tx_queues[
i];
1680 lm->
free (
c->tx_queues);
1681 c->tx_queues = NULL;
1683 c->tx_queues_num = 0;
1685 if (
c->rx_queues != NULL)
1687 for (
i = 0;
i <
c->rx_queues_num;
i++)
1689 mq = &
c->rx_queues[
i];
1694 if (
c->on_interrupt != NULL)
1704 lm->
free (
c->rx_queues);
1705 c->rx_queues = NULL;
1707 c->rx_queues_num = 0;
1709 for (
i = 0;
i <
c->regions_num;
i++)
1711 if (&
c->regions[
i] == NULL)
1713 if (
c->regions[
i].is_external != 0)
1716 c->regions[
i].region_size,
1717 c->regions[
i].fd,
c->private_ctx);
1721 if (munmap (
c->regions[
i].addr,
c->regions[
i].region_size) < 0)
1723 if (
c->regions[
i].fd > 0)
1724 close (
c->regions[
i].fd);
1725 c->regions[
i].fd = -1;
1728 lm->
free (
c->regions);
1736 if (!(
c->args.is_master))
1740 if (timerfd_settime (lm->
timerfd, 0, &lm->arm, NULL) < 0)
1743 DBG (
"timerfd_settime: arm");
1793 DBG (
"no connection");
1799 DBG (
"DISCONNECTING");
1812 c->args.interface_id);
1827 if (!
c->args.is_master)
1832 if (timerfd_settime (lm->
timerfd, 0, &lm->
disarm, NULL) < 0)
1835 DBG (
"timerfd_settime: disarm");
1860 for (
i = 0;
i <
c->regions_num;
i++)
1862 mr = &
c->regions[
i];
1881 mmap (NULL, mr->
region_size, PROT_READ | PROT_WRITE,
1882 MAP_SHARED, mr->
fd, 0)) == MAP_FAILED)
1891 for (
i = 0;
i <
c->rx_queues_num;
i++)
1893 mq = &
c->rx_queues[
i];
1899 DBG (
"wrong cookie on rx ring %u",
i);
1906 for (
i = 0;
i <
c->tx_queues_num;
i++)
1908 mq = &
c->tx_queues[
i];
1914 DBG (
"wrong cookie on tx ring %u",
i);
1929 uint8_t has_buffers)
1940 r = &conn->regions[conn->regions_num - 1];
1943 if (has_buffers != 0)
1945 r->buffer_offset = 0;
1950 (conn->run_args.num_s2m_rings +
1951 conn->run_args.num_m2s_rings) * (
sizeof (
memif_ring_t) +
1954 run_args.log2_ring_size));
1957 r->region_size = (has_buffers == 0) ?
r->buffer_offset :
r->buffer_offset +
1958 conn->run_args.buffer_size * (1 << conn->run_args.log2_ring_size) *
1959 (conn->run_args.num_s2m_rings + conn->run_args.num_m2s_rings);
1967 if ((ftruncate (
r->fd,
r->region_size)) == -1)
1970 if ((
r->addr = mmap (NULL,
r->region_size, PROT_READ | PROT_WRITE,
1971 MAP_SHARED,
r->fd, 0)) == MAP_FAILED)
1983 for (
i = 0;
i < conn->run_args.num_s2m_rings;
i++)
1986 DBG (
"RING: %p I: %d", ring,
i);
1990 for (j = 0; j < (1 << conn->run_args.log2_ring_size); j++)
1992 uint16_t
slot =
i * (1 << conn->run_args.log2_ring_size) + j;
1995 conn->regions[1].buffer_offset +
1996 (uint32_t) (
slot * conn->run_args.buffer_size);
1997 ring->
desc[j].
length = conn->run_args.buffer_size;
2000 for (
i = 0;
i < conn->run_args.num_m2s_rings;
i++)
2003 DBG (
"RING: %p I: %d", ring,
i);
2007 for (j = 0; j < (1 << conn->run_args.log2_ring_size); j++)
2009 uint16_t
slot = (
i + conn->run_args.num_s2m_rings) *
2010 (1 << conn->run_args.log2_ring_size) + j;
2013 conn->regions[1].buffer_offset +
2014 (uint32_t) (
slot * conn->run_args.buffer_size);
2015 ring->
desc[j].
length = conn->run_args.buffer_size;
2023 conn->run_args.num_s2m_rings);
2029 for (x = 0; x < conn->run_args.num_s2m_rings; x++)
2031 if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
2038 DBG (
"RING: %p I: %d", mq[x].ring, x);
2042 (
void *) mq[x].ring - (
void *) conn->regions[mq->
region].addr;
2046 conn->tx_queues = mq;
2047 conn->tx_queues_num = conn->run_args.num_s2m_rings;
2051 conn->run_args.num_m2s_rings);
2055 for (x = 0; x < conn->run_args.num_m2s_rings; x++)
2057 if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
2064 DBG (
"RING: %p I: %d", mq[x].ring, x);
2068 (
void *) mq[x].ring - (
void *) conn->regions[mq->
region].addr;
2072 conn->rx_queues = mq;
2073 conn->rx_queues_num = conn->run_args.num_m2s_rings;
2098 ++conn->regions_num);
2103 conn->regions[1].region_size =
2104 conn->run_args.buffer_size * (1 << conn->run_args.log2_ring_size) *
2105 (conn->run_args.num_s2m_rings + conn->run_args.num_m2s_rings);
2106 conn->regions[1].buffer_offset = 0;
2108 conn->regions[1].region_size,
2109 &conn->regions[1].fd, conn->private_ctx);
2110 conn->regions[1].is_external = 1;
2134 uint16_t ring_size, ns;
2139 if (
c->args.is_master)
2161 from_d = &from_q->
ring->
desc[
buf->desc_index & from_mask];
2183 if ((buf_a == NULL) || (buf_b == NULL))
2198 buf_b->
queue = mq_a;
2206 uint16_t * count_out)
2252 DBG (
"allocated: %u/%u bufs. Next buffer pointer %d", *count_out,
count,
2257 DBG (
"ring buffer full! qid: %u", qid);
2267 uint16_t * count_out, uint16_t
size)
2275 (
c->args.is_master) ?
c->run_args.num_m2s_rings :
c->
2276 run_args.num_s2m_rings;
2287 uint32_t offset_mask =
c->run_args.buffer_size - 1;
2291 uint16_t dst_left, src_left;
2292 uint16_t saved_count;
2293 uint16_t saved_next_buf;
2299 if (
c->args.is_master)
2306 b0 = (
bufs + *count_out);
2309 saved_count =
count;
2317 c->run_args.buffer_size;
2334 b0 = (
bufs + *count_out);
2336 dst_left = (
c->args.is_master) ?
2338 c->run_args.buffer_size;
2345 * (saved_count -
count + 1));
2346 *count_out -= saved_count -
count;
2354 if (
c->args.is_master == 0)
2364 src_left -= b0->
len;
2365 dst_left -= b0->
len;
2376 DBG (
"allocated: %u/%u bufs. Next buffer pointer %d", *count_out,
count,
2381 DBG (
"ring buffer full! qid: %u", qid);
2398 (
c->args.is_master) ?
c->run_args.num_s2m_rings :
c->
2399 run_args.num_m2s_rings;
2406 uint32_t offset_mask =
c->run_args.buffer_size - 1;
2407 uint16_t
slot, counter = 0;
2409 if (
c->args.is_master)
2418 uint16_t head = ring->
head;
2424 while (counter <
count)
2428 d->
length =
c->run_args.buffer_size - headroom;
2453 (
c->args.is_master) ?
c->run_args.num_m2s_rings :
c->
2454 run_args.num_s2m_rings;
2463 uint32_t offset_mask =
c->run_args.buffer_size - 1;
2466 int64_t data_offset;
2474 if (
c->args.is_master)
2491 if (!
c->args.is_master)
2497 if (data_offset != 0)
2500 if ((data_offset < 0) ||
2501 ((data_offset + b0->
len) >
c->run_args.buffer_size))
2503 DBG (
"slot: %d, data_offset: %d, length: %d",
2508 d->
offset += data_offset;
2512 #ifdef MEMIF_DBG_SHM
2514 printf (
"data: %p\n",
2528 if (
c->args.is_master)
2536 int r = write (mq->
int_fd, &
a, sizeof (
a));
2554 (
c->args.is_master) ?
c->run_args.num_s2m_rings :
c->
2555 run_args.num_m2s_rings;
2563 uint16_t cur_slot, last_slot;
2573 last_slot = (
c->args.is_master) ? ring->
head : ring->
tail;
2574 if (cur_slot == last_slot)
2583 ns = last_slot - cur_slot;
2593 if (
c->args.is_master == 0)
2605 #ifdef MEMIF_DBG_SHM
2606 printf (
"data: %p\n", b0->
data);
2608 printf (
"queue: %p\n", b0->
queue);
2618 if (
c->args.is_master)
2625 DBG (
"not enough buffers!");
2638 char *
buf, ssize_t buflen)
2652 l1 = strlen ((
char *)
c->args.interface_name);
2653 if (l0 + l1 < buflen)
2656 (uint8_t *) strcpy (
buf + l0, (
char *)
c->args.interface_name);
2662 l1 = strlen ((
char *) lm->
app_name);
2663 if (l0 + l1 < buflen)
2671 l1 = strlen ((
char *)
c->remote_if_name);
2672 if (l0 + l1 < buflen)
2675 (uint8_t *) strcpy (
buf + l0, (
char *)
c->remote_if_name);
2681 l1 = strlen ((
char *)
c->remote_name);
2682 if (l0 + l1 < buflen)
2685 (uint8_t *) strcpy (
buf + l0, (
char *)
c->remote_name);
2691 md->
id =
c->args.interface_id;
2693 if (strlen ((
char *)
c->args.secret) > 0)
2695 l1 = strlen ((
char *)
c->args.secret);
2696 if (l0 + l1 < buflen)
2698 md->
secret = (uint8_t *) strcpy (
buf + l0, (
char *)
c->args.secret);
2705 md->
role = (
c->args.is_master) ? 0 : 1;
2706 md->
mode =
c->args.mode;
2708 l1 = strlen ((
char *) ms->
filename);
2709 if (l0 + l1 < buflen)
2712 (uint8_t *) strcpy (
buf + l0, (
char *) ms->
filename);
2718 l1 = strlen ((
char *)
c->remote_disconnect_string);
2719 if (l0 + l1 < buflen)
2722 (uint8_t *) strcpy (
buf + l0, (
char *)
c->remote_disconnect_string);
2730 if (l0 + l1 <= buflen)
2747 (
c->args.is_master) ?
c->run_args.num_s2m_rings :
c->
2748 run_args.num_m2s_rings;
2751 if (l0 + l1 <= buflen)
2770 (
c->args.is_master) ?
c->run_args.num_m2s_rings :
c->
2771 run_args.num_s2m_rings;
2774 if (l0 + l1 <= buflen)
2810 (
c->args.is_master) ?
c->run_args.num_s2m_rings :
c->
2811 run_args.num_m2s_rings;
2815 *efd =
c->rx_queues[qid].int_fd;
#define MEMIF_DEFAULT_APP_NAME
Default name of application using libmemif.
@ MEMIF_SOCKET_TYPE_LISTENER
memif_socket_handle_t default_socket
#define MEMIF_FD_EVENT_MOD
update events
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.
int memif_connect1(memif_connection_t *c)
int free_list_elt_ctx(memif_list_elt_t *list, uint16_t len, memif_connection_t *ctx)
vlib_buffer_t * bufs[VLIB_FRAME_SIZE]
clib_error_t * memif_conn_fd_accept_ready(clib_file_t *uf)
memif_add_external_region_t * add_external_region
static int memif_socket_start_listening(memif_socket_t *ms)
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.
#define MEMIF_FD_EVENT_WRITE
int on_connect(memif_conn_handle_t conn, void *private_ctx)
void * realloc(void *p, size_t size)
memif_interface_mode_t mode
memif_del_external_region_t * del_external_region
uint16_t pending_list_len
void() memif_free_t(void *ptr)
Memif allocator free.
memif_region_size_t region_size
#define MEMIF_DEFAULT_SOCKET_PATH
static void memif_alloc_register(libmemif_main_t *lm, memif_alloc_t *ma)
uint8_t app_name[MEMIF_NAME_LEN]
const char * memif_get_socket_filename(memif_socket_handle_t sock)
Get socket filename.
void *() memif_alloc_t(size_t size)
Memif allocator alloc.
uint32_t() memif_get_external_buffer_offset_t(void *private_ctx)
Get external buffer offset (optional)
int memif_per_thread_cleanup(memif_per_thread_main_handle_t *pt_main)
Memif per thread cleanup.
int memif_per_thread_poll_event(memif_per_thread_main_handle_t pt_main, int timeout)
Memif per thread poll event.
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.
Memif connection arguments.
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.
int memif_control_fd_update(int fd, uint8_t events, void *private_ctx)
void * memif_per_thread_main_handle_t
Memif per thread main handle Pointer of type void, pointing to internal structure.
memif_get_external_buffer_offset_t * get_external_buffer_offset
int memif_get_details(memif_conn_handle_t conn, memif_details_t *md, char *buf, ssize_t buflen)
Memif get details.
memif_get_external_region_addr_t * get_external_region_addr
static size_t strlcpy(char *dest, const char *src, size_t len)
memif_queue_details_t * tx_queues
vnet_hw_if_output_node_runtime_t * r
#define MEMIF_DEFAULT_RECONNECT_PERIOD_SEC
#define MEMIF_ERR_UNDEFINED
memif_region_index_t region
int on_disconnect(memif_conn_handle_t conn, void *private_ctx)
memif_log2_ring_size_t log2_ring_size
int free_list_elt(memif_list_elt_t *list, uint16_t len, int key)
int memif_request_connection(memif_conn_handle_t c)
Send connection request.
clib_error_t * memif_msg_send_disconnect(memif_if_t *mif, clib_error_t *err)
@ MEMIF_SOCKET_TYPE_CLIENT
#define MEMIF_MAX_LOG2_RING_SIZE
#define MEMIF_DEFAULT_LOG2_RING_SIZE
const char * memif_errlist[ERRLIST_LEN]
#define MEMIF_BUFFER_FLAG_NEXT
next buffer present (chained buffers)
int on_interrupt(memif_conn_handle_t conn, void *private_ctx, uint16_t qid)
memif_realloc_t * realloc
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_cancel_poll_event()
static void memif_control_fd_update_register(libmemif_main_t *lm, memif_control_fd_update_t *cb)
int memif_create_socket(memif_socket_handle_t *sock, const char *filename, void *private_ctx)
Create memif socket.
int memif_delete_socket(memif_socket_handle_t *sock)
Delete memif socket.
int() memif_add_external_region_t(void **addr, uint32_t size, int *fd, void *private_ctx)
Add external region.
void * memif_socket_handle_t
Memif socket handle pointer of type void, pointing to internal structure.
int get_list_elt(memif_list_elt_t **e, memif_list_elt_t *list, uint16_t len, int key)
memif_region_index_t region
uint16_t memif_get_version()
Memif get version.
static char memif_buf[MAX_ERRBUF_LEN]
memif_list_elt_t * interface_list
memif_list_elt_t * pending_list
memif_list_elt_t * socket_list
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.
int memif_per_thread_set_connection_request_timer(memif_per_thread_main_handle_t pt_main, struct itimerspec timer)
Set connection request timer value.
uint8_t * remote_inst_name
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.
if(node->flags &VLIB_NODE_FLAG_TRACE) vnet_interface_output_trace(vm
#define MEMIF_DESC_FLAG_NEXT
int() memif_connection_update_t(memif_conn_handle_t conn, void *private_ctx)
Memif connection status update (callback function)
void *() memif_realloc_t(void *ptr, size_t size)
Memif realloc.
static memif_ring_t * memif_get_ring(memif_connection_t *conn, memif_ring_type_t type, uint16_t ring_num)
static perfmon_event_t events[]
struct libmemif_main * lm
static int memif_add_epoll_fd(libmemif_main_t *lm, int fd, uint32_t events)
int memif_set_rx_mode(memif_conn_handle_t c, memif_rx_mode_t rx_mode, uint16_t qid)
Memif set rx mode.
static_always_inline void * memif_get_buffer(memif_if_t *mif, memif_ring_t *ring, u16 slot)
#define MFD_ALLOW_SEALING
int memif_cleanup()
Memif cleanup.
#define MEMIF_FD_EVENT_ERROR
inform libmemif that error occurred on fd
int memif_per_thread_cancel_poll_event(memif_per_thread_main_handle_t pt_main)
Send signal to stop concurrently running memif_poll_event().
static clib_error_t * memif_conn_fd_write_ready(clib_file_t *uf, memif_if_t *mif)
int() memif_del_external_region_t(void *addr, uint32_t size, int fd, void *private_ctx)
Delete external region.
#define MEMIF_DEFAULT_RX_QUEUES
memif_control_fd_update_t * control_fd_update
static int memif_add_region(libmemif_main_t *lm, memif_connection_t *conn, uint8_t has_buffers)
#define MEMIF_DEFAULT_BUFFER_SIZE
#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)
memif_socket_handle_t socket
int memif_set_next_free_buffer(memif_conn_handle_t conn, uint16_t qid, memif_buffer_t *buf)
Memif set next free buffer.
struct itimerspec arm disarm
uint16_t control_list_len
int memif_init_regions_and_queues(memif_connection_t *conn)
void * memif_conn_handle_t
Memif connection handle pointer of type void, pointing to internal structure.
int memif_get_queue_efd(memif_conn_handle_t conn, uint16_t qid, int *efd)
Memif get queue event file descriptor.
static int memfd_create(const char *name, unsigned int flags)
int() memif_control_fd_update_t(int fd, uint8_t events, void *private_ctx)
Memif control file descriptor update (callback function)
uint8_t * socket_filename
memif_region_details_t * regions
#define MEMIF_DEFAULT_TX_QUEUES
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 memif_control_fd_handler(int fd, uint8_t events)
Memif control file descriptor handler.
static int memif_init_queues(libmemif_main_t *lm, memif_connection_t *conn)
uint16_t interface_list_len
void *() memif_get_external_region_addr_t(uint32_t size, int fd, void *private_ctx)
Get external region address.
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.
int memif_set_connection_request_timer(struct itimerspec timer)
Set connection request timer value.
int memif_disconnect_internal(memif_connection_t *c)
for(i=1;i<=collision_buckets;i++)
libmemif_main_t libmemif_main
static void memif_buffer_enq_at_idx_internal(memif_queue_t *from_q, memif_queue_t *to_q, memif_buffer_t *buf, uint16_t slot)
uint8_t interface_name[32]
int memif_delete(memif_conn_handle_t *conn)
Memif delete.
memif_region_offset_t offset
@ MEMIF_ERR_PROC_FILE_LIMIT
static void memif_msg_queue_free(libmemif_main_t *lm, memif_msg_queue_elt_t **e)
int memif_buffer_requeue(memif_conn_handle_t conn, memif_buffer_t *buf_a, memif_buffer_t *buf_b)
Memif buffer enq tx at idx.
int() memif_interrupt_t(memif_conn_handle_t conn, void *private_ctx, uint16_t qid)
Memif interrupt occurred (callback function)
int memif_syscall_error_handler(int err_code)
char * memif_strerror(int err_code)
Memif strerror.
void * malloc(size_t size)
#define MEMIF_RING_FLAG_MASK_INT
memif_list_elt_t * interrupt_list
static void memif_free_register(libmemif_main_t *lm, memif_free_t *mf)
#define MEMIF_DEFAULT_RECONNECT_PERIOD_NSEC
libmemif_main_t * get_libmemif_main(memif_socket_t *ms)
#define MEMIF_MEMORY_BARRIER()
memif_queue_details_t * rx_queues
uint16_t interrupt_list_len
int memif_poll_event(int timeout)
Memif poll event.
memif_region_offset_t offset
static void memif_realloc_register(libmemif_main_t *lm, memif_realloc_t *mr)
memif_list_elt_t * control_list
static int memif_del_epoll_fd(libmemif_main_t *lm, int fd)
int memif_refill_queue(memif_conn_handle_t conn, uint16_t qid, uint16_t count, uint16_t headroom)
Memif refill queue.
#define MEMIF_FD_EVENT_READ
user needs to set events that occurred on fd and pass them to memif_control_fd_handler
vl_api_fib_path_type_t type
int add_list_elt(libmemif_main_t *lm, memif_list_elt_t *e, memif_list_elt_t **list, uint16_t *len)
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.
static int memif_mod_epoll_fd(libmemif_main_t *lm, int fd, uint32_t events)
vl_api_address_union_t un