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 resoure 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 conenction",
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 suplied 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 reqest.",
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)
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 moddified 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 if (private_ctx ==
NULL)
339 for (i = 0; i < *
len; i++)
341 if ((*list)[i].data_struct ==
NULL)
343 (*list)[
i].key = e->
key;
353 for (i = *len; i < *len * 2; i++)
379 for (i = 0; i <
len; i++)
381 if (list[i].key == key)
396 for (i = 0; i <
len; i++)
398 if (list[i].key == key)
414 for (i = 0; i <
len; i++)
416 if (list[i].
key == -1)
418 if (list[i].data_struct == ctx)
478 if (timerfd_settime (lm->
timerfd, 0, &lm->arm,
NULL) < 0)
489 struct itimerspec timer)
499 if (timerfd_settime (lm->
timerfd, 0, &lm->arm,
NULL) < 0)
517 if (memif_alloc !=
NULL)
524 if (memif_realloc !=
NULL)
531 if (memif_free !=
NULL)
536 if (app_name !=
NULL)
540 strncpy ((
char *) lm->
app_name, app_name, len);
550 if (on_control_fd_update !=
NULL)
554 lm->
epfd = epoll_create (1);
559 DBG (
"eventfd: %s", strerror (err));
563 DBG (
"libmemif event polling initialized");
624 lm->
timerfd = timerfd_create (CLOCK_REALTIME, TFD_NONBLOCK);
638 DBG (
"callback type memif_control_fd_update_t error!");
670 if (memif_alloc !=
NULL)
681 if (memif_alloc !=
NULL)
688 if (memif_realloc !=
NULL)
695 if (memif_free !=
NULL)
703 if (app_name !=
NULL)
707 strncpy ((
char *) lm->
app_name, app_name, len);
717 if (on_control_fd_update !=
NULL)
721 lm->
epfd = epoll_create (1);
726 DBG (
"eventfd: %s", strerror (err));
731 DBG (
"libmemif event polling initialized");
793 lm->
timerfd = timerfd_create (CLOCK_REALTIME, TFD_NONBLOCK);
808 DBG (
"callback type memif_control_fd_update_t error!");
827 if (&conn->regions[0] ==
NULL)
829 void *p = conn->regions[0].addr;
832 sizeof (
memif_desc_t) * (1 << conn->run_args.log2_ring_size);
833 p += (ring_num + type * conn->run_args.num_s2m_rings) * ring_size;
846 (conn->args.is_master) ? conn->run_args.num_s2m_rings : conn->
847 run_args.num_m2s_rings;
851 conn->rx_queues[qid].ring->flags =
rx_mode;
852 DBG (
"rx_mode flag: %u", conn->rx_queues[qid].ring->flags);
861 struct stat file_stat;
862 struct sockaddr_un un = { 0 };
870 if (stat ((
char *) ms->
filename, &file_stat) == 0)
872 if (S_ISSOCK (file_stat.st_mode))
878 ms->
fd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
885 DBG (
"socket %d created", ms->
fd);
886 un.sun_family = AF_UNIX;
887 strncpy ((
char *) un.sun_path, (
char *) ms->
filename,
888 sizeof (un.sun_path) - 1);
889 if (setsockopt (ms->
fd, SOL_SOCKET, SO_PASSCRED, &on, sizeof (on)) < 0)
894 if (bind (ms->
fd, (
struct sockaddr *) &un, sizeof (un)) < 0)
899 if (listen (ms->
fd, 1) < 0)
904 if (stat ((
char *) ms->
filename, &file_stat) < 0)
941 if (strncmp ((
char *) ms->
filename, filename,
942 strlen ((
char *) ms->
filename)) == 0)
957 ms->
filename = lm->
alloc (strlen (filename) +
sizeof (
char));
963 memset (ms->
filename, 0, strlen (filename) +
sizeof (
char));
964 strncpy ((
char *) ms->
filename, filename, strlen (filename));
1011 const char *filename,
void *private_ctx)
1024 if (strncmp ((
char *) ms->
filename, filename,
1025 strlen ((
char *) ms->
filename)) == 0)
1041 ms->
filename = lm->
alloc (strlen (filename) +
sizeof (
char));
1047 memset (ms->
filename, 0, strlen (filename) +
sizeof (
char));
1048 strncpy ((
char *) ms->
filename, filename, strlen (filename));
1106 DBG (
"This handle already points to existing memif.");
1139 conn->args.mode = args->
mode;
1140 conn->msg_queue =
NULL;
1141 conn->regions =
NULL;
1142 conn->tx_queues =
NULL;
1143 conn->rx_queues =
NULL;
1148 conn->private_ctx = private_ctx;
1152 strncpy ((
char *) conn->args.interface_name, (
char *) args->
interface_name,
1155 if ((l = strlen ((
char *) args->
secret)) > 0)
1156 strncpy ((
char *) conn->args.secret, (
char *) args->
secret, l);
1159 conn->args.socket = args->
socket;
1177 elt.
key = conn->args.interface_id;
1182 if (conn->args.is_master)
1203 conn->
index = index;
1210 if (timerfd_settime (lm->
timerfd, 0, &lm->arm,
NULL) < 0)
1238 struct sockaddr_un sun;
1252 sockfd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
1259 sun.sun_family = AF_UNIX;
1261 strncpy (sun.sun_path, (
char *) ms->
filename, sizeof (sun.sun_path) - 1);
1263 if (connect (sockfd, (
struct sockaddr *) &sun,
1264 sizeof (
struct sockaddr_un)) == 0)
1290 strcpy ((
char *) conn->remote_disconnect_string,
memif_strerror (err));
1317 size = read (fd, &b,
sizeof (b));
1328 if (conn->args.is_master)
1346 data_struct)->run_args.
1348 run_args.num_m2s_rings;
1349 for (i = 0; i < num; i++)
1352 rx_queues[i].int_fd == fd)
1357 data_struct)->private_ctx, i);
1419 int fd, uint8_t events)
1431 size = read (fd, &b,
sizeof (b));
1442 if (conn->args.is_master)
1460 data_struct)->run_args.
1462 run_args.num_m2s_rings;
1463 for (i = 0; i < num; i++)
1466 rx_queues[i].int_fd == fd)
1471 data_struct)->private_ctx, i);
1535 struct epoll_event evt;
1537 uint32_t events = 0;
1538 uint64_t counter = 0;
1540 memset (&evt, 0,
sizeof (evt));
1541 evt.events = EPOLLIN | EPOLLOUT;
1543 sigemptyset (&sigset);
1544 en = epoll_pwait (lm->
epfd, &evt, 1, timeout, &sigset);
1548 DBG (
"epoll_pwait: %s", strerror (err));
1555 r = read (evt.data.fd, &counter, sizeof (counter));
1561 if (evt.events & EPOLLIN)
1563 if (evt.events & EPOLLOUT)
1565 if (evt.events & EPOLLERR)
1578 struct epoll_event evt;
1580 uint32_t events = 0;
1581 uint64_t counter = 0;
1583 memset (&evt, 0,
sizeof (evt));
1584 evt.events = EPOLLIN | EPOLLOUT;
1586 sigemptyset (&sigset);
1587 en = epoll_pwait (lm->
epfd, &evt, 1, timeout, &sigset);
1591 DBG (
"epoll_pwait: %s", strerror (err));
1598 r = read (evt.data.fd, &counter, sizeof (counter));
1604 if (evt.events & EPOLLIN)
1606 if (evt.events & EPOLLOUT)
1608 if (evt.events & EPOLLERR)
1620 uint64_t counter = 1;
1626 if (w <
sizeof (counter))
1636 uint64_t counter = 1;
1645 if (w <
sizeof (counter))
1673 DBG (
"no connection");
1679 c->on_disconnect ((
void *) c, c->private_ctx);
1690 if (c->args.is_master)
1692 e->
key = c->fd = -1;
1695 if (c->tx_queues !=
NULL)
1697 for (i = 0; i < c->tx_queues_num; i++)
1699 mq = &c->tx_queues[
i];
1709 lm->
free (c->tx_queues);
1710 c->tx_queues =
NULL;
1712 c->tx_queues_num = 0;
1714 if (c->rx_queues !=
NULL)
1716 for (i = 0; i < c->rx_queues_num; i++)
1718 mq = &c->rx_queues[
i];
1723 if (c->on_interrupt !=
NULL)
1733 lm->
free (c->rx_queues);
1734 c->rx_queues =
NULL;
1736 c->rx_queues_num = 0;
1738 for (i = 0; i < c->regions_num; i++)
1740 if (&c->regions[i] ==
NULL)
1742 if (c->regions[i].is_external != 0)
1745 c->regions[i].region_size,
1746 c->regions[i].fd, c->private_ctx);
1750 if (munmap (c->regions[i].addr, c->regions[i].region_size) < 0)
1752 if (c->regions[i].fd > 0)
1753 close (c->regions[i].fd);
1754 c->regions[
i].fd = -1;
1757 lm->
free (c->regions);
1765 if (!(c->args.is_master))
1769 if (timerfd_settime (lm->
timerfd, 0, &lm->arm,
NULL) < 0)
1772 DBG (
"timerfd_settime: arm");
1824 DBG (
"no connection");
1830 DBG (
"DISCONNECTING");
1843 c->args.interface_id);
1858 if (!c->args.is_master)
1866 DBG (
"timerfd_settime: disarm");
1891 for (i = 0; i < c->regions_num; i++)
1893 mr = &c->regions[
i];
1913 MAP_SHARED, mr->
fd, 0)) == MAP_FAILED)
1922 for (i = 0; i < c->rx_queues_num; i++)
1924 mq = &c->rx_queues[
i];
1930 DBG (
"wrong cookie on rx ring %u", i);
1938 for (i = 0; i < c->tx_queues_num; i++)
1940 mq = &c->tx_queues[
i];
1946 DBG (
"wrong cookie on tx ring %u", i);
1962 uint8_t has_buffers)
1973 r = &conn->regions[conn->regions_num - 1];
1976 if (has_buffers != 0)
1983 (conn->run_args.num_s2m_rings +
1984 conn->run_args.num_m2s_rings) * (
sizeof (
memif_ring_t) +
1987 run_args.log2_ring_size));
1991 conn->run_args.buffer_size * (1 << conn->run_args.log2_ring_size) *
1992 (conn->run_args.num_s2m_rings + conn->run_args.num_m2s_rings);
2004 MAP_SHARED, r->
fd, 0)) == MAP_FAILED)
2016 for (i = 0; i < conn->run_args.num_s2m_rings; i++)
2019 DBG (
"RING: %p I: %d", ring, i);
2023 for (j = 0; j < (1 << conn->run_args.log2_ring_size); j++)
2025 uint16_t
slot = i * (1 << conn->run_args.log2_ring_size) + j;
2028 conn->regions[1].buffer_offset +
2029 (uint32_t) (slot * conn->run_args.buffer_size);
2030 ring->
desc[j].
length = conn->run_args.buffer_size;
2033 for (i = 0; i < conn->run_args.num_m2s_rings; i++)
2036 DBG (
"RING: %p I: %d", ring, i);
2040 for (j = 0; j < (1 << conn->run_args.log2_ring_size); j++)
2042 uint16_t
slot = (i + conn->run_args.num_s2m_rings) *
2043 (1 << conn->run_args.log2_ring_size) + j;
2046 conn->regions[1].buffer_offset +
2047 (uint32_t) (slot * conn->run_args.buffer_size);
2048 ring->
desc[j].
length = conn->run_args.buffer_size;
2056 conn->run_args.num_s2m_rings);
2062 for (x = 0; x < conn->run_args.num_s2m_rings; x++)
2064 if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
2071 DBG (
"RING: %p I: %d", mq[x].ring, x);
2075 (
void *) mq[x].ring - (
void *) conn->regions[mq->
region].addr;
2079 conn->tx_queues = mq;
2080 conn->tx_queues_num = conn->run_args.num_s2m_rings;
2084 conn->run_args.num_m2s_rings);
2088 for (x = 0; x < conn->run_args.num_m2s_rings; x++)
2090 if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
2097 DBG (
"RING: %p I: %d", mq[x].ring, x);
2101 (
void *) mq[x].ring - (
void *) conn->regions[mq->
region].addr;
2105 conn->rx_queues = mq;
2106 conn->rx_queues_num = conn->run_args.num_m2s_rings;
2131 ++conn->regions_num);
2136 conn->regions[1].region_size =
2137 conn->run_args.buffer_size * (1 << conn->run_args.log2_ring_size) *
2138 (conn->run_args.num_s2m_rings + conn->run_args.num_m2s_rings);
2139 conn->regions[1].buffer_offset = 0;
2141 conn->regions[1].region_size,
2142 &conn->regions[1].fd, conn->private_ctx);
2143 conn->regions[1].is_external = 1;
2158 uint16_t * count_out)
2166 (c->args.is_master) ? c->run_args.num_m2s_rings : c->
2167 run_args.num_s2m_rings;
2185 slot = (c->args.is_master) ? ring->
tail : ring->
head;
2206 (uint32_t) (b0->
data -
2207 c->regions[ring->
desc[slot & mask].
region].addr);
2223 DBG (
"allocated: %u/%u bufs. Total %u allocated bufs", *count_out, count,
2228 DBG (
"ring buffer full! qid: %u", qid);
2238 uint16_t * count_out, uint16_t
size)
2246 (c->args.is_master) ? c->run_args.num_m2s_rings : c->
2247 run_args.num_s2m_rings;
2258 uint32_t offset_mask = c->run_args.buffer_size - 1;
2262 uint16_t dst_left, src_left;
2263 uint16_t saved_count;
2268 slot = (c->args.is_master) ? ring->
tail : ring->
head;
2271 if (c->args.is_master)
2278 b0 = (bufs + *count_out);
2281 saved_count =
count;
2287 dst_left = (c->args.is_master) ? ring->
desc[slot & mask].
length :
2288 c->run_args.buffer_size;
2306 b0 = (bufs + *count_out);
2309 (c->args.is_master) ? ring->
desc[slot & mask].
2310 length : c->run_args.buffer_size;
2317 * (saved_count - count + 1));
2318 *count_out -= saved_count -
count;
2326 if (c->args.is_master == 0)
2336 src_left -= b0->
len;
2337 dst_left -= b0->
len;
2349 DBG (
"allocated: %u/%u bufs. Total %u allocated bufs", *count_out, count,
2354 DBG (
"ring buffer full! qid: %u", qid);
2371 (c->args.is_master) ? c->run_args.num_s2m_rings : c->
2372 run_args.num_m2s_rings;
2379 uint32_t offset_mask = c->run_args.buffer_size - 1;
2382 if (c->args.is_master)
2386 (ring->
tail + count <=
2391 uint16_t head = ring->
head;
2393 head += (count < ns) ?
count : ns;
2399 d = &ring->
desc[slot & mask];
2401 d->
length = c->run_args.buffer_size - headroom;
2425 (c->args.is_master) ? c->run_args.num_m2s_rings : c->
2426 run_args.num_s2m_rings;
2449 #ifdef MEMIF_DBG_SHM 2451 printf (
"data: %p\n",
2464 if (c->args.is_master)
2474 int r = write (mq->
int_fd, &a, sizeof (a));
2492 (c->args.is_master) ? c->run_args.num_s2m_rings : c->
2493 run_args.num_m2s_rings;
2501 uint16_t cur_slot, last_slot;
2508 ssize_t r = read (mq->
int_fd, &b, sizeof (b));
2513 last_slot = (c->args.is_master) ? ring->
head : ring->
tail;
2514 if (cur_slot == last_slot)
2517 ns = last_slot - cur_slot;
2527 if (c->args.is_master == 0)
2529 ring->
desc[cur_slot & mask].
length = c->run_args.buffer_size;
2536 ring->
desc[cur_slot & mask].
flags &= ~MEMIF_DESC_FLAG_NEXT;
2540 #ifdef MEMIF_DBG_SHM 2541 printf (
"data: %p\n", b0->
data);
2543 printf (
"ring: %p\n", b0->
ring);
2553 if (c->args.is_master)
2560 DBG (
"not enough buffers!");
2569 char *buf, ssize_t buflen)
2583 l1 = strlen ((
char *) c->args.interface_name);
2584 if (l0 + l1 < buflen)
2587 (uint8_t *) strcpy (buf + l0, (
char *) c->args.interface_name);
2593 l1 = strlen ((
char *) lm->
app_name);
2594 if (l0 + l1 < buflen)
2602 l1 = strlen ((
char *) c->remote_if_name);
2603 if (l0 + l1 < buflen)
2606 (uint8_t *) strcpy (buf + l0, (
char *) c->remote_if_name);
2612 l1 = strlen ((
char *) c->remote_name);
2613 if (l0 + l1 < buflen)
2616 (uint8_t *) strcpy (buf + l0, (
char *) c->remote_name);
2622 md->
id = c->args.interface_id;
2624 if (strlen ((
char *) c->args.secret) > 0)
2626 l1 = strlen ((
char *) c->args.secret);
2627 if (l0 + l1 < buflen)
2629 md->
secret = (uint8_t *) strcpy (buf + l0, (
char *) c->args.secret);
2636 md->
role = (c->args.is_master) ? 0 : 1;
2637 md->
mode = c->args.mode;
2639 l1 = strlen ((
char *) ms->
filename);
2640 if (l0 + l1 < buflen)
2643 (uint8_t *) strcpy (buf + l0, (
char *) ms->
filename);
2649 l1 = strlen ((
char *) c->remote_disconnect_string);
2650 if (l0 + l1 < buflen)
2653 (uint8_t *) strcpy (buf + l0, (
char *) c->remote_disconnect_string);
2661 if (l0 + l1 <= buflen)
2678 (c->args.is_master) ? c->run_args.num_s2m_rings : c->
2679 run_args.num_m2s_rings;
2682 if (l0 + l1 <= buflen)
2701 (c->args.is_master) ? c->run_args.num_m2s_rings : c->
2702 run_args.num_s2m_rings;
2705 if (l0 + l1 <= buflen)
2741 (c->args.is_master) ? c->run_args.num_s2m_rings : c->
2742 run_args.num_m2s_rings;
2746 *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 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 occured 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 occured (callback function)
int memif_init(memif_control_fd_update_t *on_control_fd_update, char *app_name, memif_alloc_t *memif_alloc, memif_realloc_t *memif_realloc, memif_free_t *memif_free)
Memif initialization.
int() memif_connection_update_t(memif_conn_handle_t conn, void *private_ctx)
Memif connection status update (callback function)
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)
#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.
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 * 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 occured 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)