21 #include <sys/ioctl.h> 22 #include <sys/socket.h> 25 #include <sys/types.h> 27 #include <netinet/in.h> 30 #include <linux/if_arp.h> 31 #include <linux/if_tun.h> 42 #define VHOST_USER_DEBUG_SOCKET 0 43 #define VHOST_USER_DEBUG_VQ 0 47 #define VHOST_USER_COPY_TX_HDR 0 49 #if VHOST_USER_DEBUG_SOCKET == 1 50 #define DBG_SOCK(args...) clib_warning(args); 52 #define DBG_SOCK(args...) 55 #if VHOST_USER_DEBUG_VQ == 1 56 #define DBG_VQ(args...) clib_warning(args); 58 #define DBG_VQ(args...) 63 #define foreach_vhost_user_tx_func_error \ 65 _(NOT_READY, "vhost user state error") \ 66 _(PKT_DROP_NOBUF, "tx packet drops (no available descriptors)") \ 67 _(MMAP_FAIL, "mmap failure") 71 #define _(f,s) VHOST_USER_TX_FUNC_ERROR_##f, 83 #define foreach_vhost_user_input_func_error \ 84 _(NO_ERROR, "no error") \ 85 _(NO_BUFFER, "no available buffer") \ 86 _(MMAP_FAIL, "mmap failure") \ 87 _(UNDERSIZED_FRAME, "undersized ethernet frame received (< 14 bytes)") \ 88 _(FULL_RX_QUEUE, "full rx queue (possible driver tx drop)") 92 #define _(f,s) VHOST_USER_INPUT_FUNC_ERROR_##f, 110 .name =
"vhost-user",
118 u32 show_dev_instance = ~0;
124 if (show_dev_instance != ~0)
125 i = show_dev_instance;
127 s =
format (s,
"VirtualEthernet0/0/%d", i);
142 DBG_SOCK (
"renumbered vhost-user interface dev_instance %d to %d",
163 DBG_VQ (
"failed to map guest mem addr %llx", addr);
205 page_sz) & ~(page_sz - 1);
212 (
"unmap memory region %d addr 0x%lx len 0x%lx page_sz 0x%x", i,
219 clib_warning (
"failed to unmap memory region (errno %d)",
232 __attribute__ ((unused))
int n;
271 #define VHOST_LOG_PAGE 0x1000 276 || !(vui->
features & (1 << FEAT_VHOST_F_LOG_ALL))))
282 DBG_SOCK (
"vhost_user_log_dirty_pages(): out of range\n");
295 #define vhost_user_log_dirty_ring(vui, vq, member) \ 296 if (PREDICT_FALSE(vq->log_used)) { \ 297 vhost_user_log_dirty_pages(vui, vq->log_guest_addr + STRUCT_OFFSET_OF(vring_used_t, member), \ 298 sizeof(vq->used->member)); \ 305 int fd, number_of_fds = 0;
307 vhost_user_msg_t msg;
312 struct cmsghdr *cmsg;
318 p =
hash_get (vum->vhost_user_interface_index_by_sock_fd,
330 memset (&mh, 0,
sizeof (mh));
331 memset (control, 0,
sizeof (control));
337 iov[0].iov_base = (
void *) &msg;
342 mh.msg_control = control;
343 mh.msg_controllen =
sizeof (control);
353 if (mh.msg_flags & MSG_CTRUNC)
358 cmsg = CMSG_FIRSTHDR (&mh);
360 if (cmsg && (cmsg->cmsg_len > 0) && (cmsg->cmsg_level == SOL_SOCKET) &&
361 (cmsg->cmsg_type == SCM_RIGHTS) &&
362 (cmsg->cmsg_len - CMSG_LEN (0) <=
363 VHOST_MEMORY_MAX_NREGIONS *
sizeof (
int)))
365 number_of_fds = (cmsg->cmsg_len - CMSG_LEN (0)) /
sizeof (
int);
366 clib_memcpy (fds, CMSG_DATA (cmsg), number_of_fds *
sizeof (
int));
370 if ((msg.flags & 7) != 1)
372 DBG_SOCK (
"malformed message received. closing socket");
377 int rv __attribute__ ((unused));
388 msg.u64 = (1 << FEAT_VIRTIO_NET_F_MRG_RXBUF) |
389 (1 << FEAT_VIRTIO_F_ANY_LAYOUT) |
390 (1 << FEAT_VHOST_F_LOG_ALL) |
391 (1 << FEAT_VIRTIO_NET_F_GUEST_ANNOUNCE) |
392 (1 << FEAT_VHOST_USER_F_PROTOCOL_FEATURES);
395 msg.size =
sizeof (msg.u64);
399 DBG_SOCK (
"if %d msg VHOST_USER_SET_FEATURES features 0x%016llx",
404 if (vui->
features & (1 << FEAT_VIRTIO_NET_F_MRG_RXBUF))
410 (vui->
features & (1 << FEAT_VIRTIO_F_ANY_LAYOUT)) ? 1 : 0;
416 for (q = 0; q < 2; q++)
430 DBG_SOCK (
"if %d msg VHOST_USER_SET_MEM_TABLE nregions %d",
433 if ((msg.memory.nregions < 1) ||
434 (msg.memory.nregions > VHOST_MEMORY_MAX_NREGIONS))
437 DBG_SOCK (
"number of mem regions must be between 1 and %i",
438 VHOST_MEMORY_MAX_NREGIONS);
443 if (msg.memory.nregions != number_of_fds)
445 DBG_SOCK (
"each memory region must have FD");
449 for (i = 0; i < msg.memory.nregions; i++)
459 page_sz) & ~(page_sz - 1);
462 MAP_SHARED, fds[i], 0);
465 (
"map memory region %d addr 0 len 0x%lx fd %d mapped 0x%lx " 471 clib_warning (
"failed to map memory. errno is %d", errno);
477 vui->
nregions = msg.memory.nregions;
481 DBG_SOCK (
"if %d msg VHOST_USER_SET_VRING_NUM idx %d num %d",
484 if ((msg.state.num > 32768) ||
485 (msg.state.num == 0) ||
488 vui->
vrings[msg.state.index].
qsz = msg.state.num;
492 DBG_SOCK (
"if %d msg VHOST_USER_SET_VRING_ADDR idx %d",
495 vui->
vrings[msg.state.index].
desc = (vring_desc_t *)
497 vui->
vrings[msg.state.index].
used = (vring_used_t *)
499 vui->
vrings[msg.state.index].
avail = (vring_avail_t *)
506 DBG_SOCK (
"failed to map user memory for hw_if_index %d",
518 if (!(vui->
features & (1 << FEAT_VHOST_USER_F_PROTOCOL_FEATURES)))
527 vui->
vrings[msg.state.index].
used->flags |= 1;
539 DBG_SOCK (
"if %d msg VHOST_USER_SET_VRING_CALL u64 %d",
542 q = (
u8) (msg.u64 & 0xFF);
544 if (!(msg.u64 & 0x100))
546 if (number_of_fds != 1)
558 template.file_descriptor = fds[0];
566 DBG_SOCK (
"if %d msg VHOST_USER_SET_VRING_KICK u64 %d",
569 q = (
u8) (msg.u64 & 0xFF);
571 if (!(msg.u64 & 0x100))
573 if (number_of_fds != 1)
583 DBG_SOCK (
"if %d msg VHOST_USER_SET_VRING_ERR u64 %d",
586 q = (
u8) (msg.u64 & 0xFF);
588 if (!(msg.u64 & 0x100))
590 if (number_of_fds != 1)
602 DBG_SOCK (
"if %d msg VHOST_USER_SET_VRING_BASE idx %d num %d",
609 DBG_SOCK (
"if %d msg VHOST_USER_GET_VRING_BASE idx %d num %d",
617 msg.size =
sizeof (msg.state);
629 if (msg.size != sizeof (msg.log))
632 (
"invalid msg size for VHOST_USER_SET_LOG_BASE: %d instead of %d",
633 msg.size, sizeof (msg.log));
641 (
"VHOST_USER_PROTOCOL_F_LOG_SHMFD not set but VHOST_USER_SET_LOG_BASE received");
649 (msg.log.size + msg.log.offset + page_sz) & ~(page_sz - 1);
651 vui->
log_base_addr = mmap (0, map_sz, PROT_READ | PROT_WRITE,
655 (
"map log region addr 0 len 0x%lx off 0x%lx fd %d mapped 0x%lx",
660 clib_warning (
"failed to map memory. errno is %d", errno);
668 msg.size =
sizeof (msg.u64);
679 DBG_SOCK (
"if %d msg VHOST_USER_GET_PROTOCOL_FEATURES",
684 msg.size =
sizeof (msg.u64);
688 DBG_SOCK (
"if %d msg VHOST_USER_SET_PROTOCOL_FEATURES features 0x%lx",
696 DBG_SOCK (
"if %d VHOST_USER_SET_VRING_ENABLE, enable: %d",
702 DBG_SOCK (
"unknown vhost-user message %d received. closing socket",
763 int client_fd, client_len;
764 struct sockaddr_un client;
780 client_len =
sizeof (client);
782 (
struct sockaddr *) &client,
783 (socklen_t *) & client_len);
790 template.file_descriptor = client_fd;
849 #if VHOST_USER_COPY_TX_HDR == 1 850 virtio_net_hdr_t hdr;
867 #if VHOST_USER_COPY_TX_HDR == 1 871 s =
format (s,
"%U virtqueue %d",
874 #if VHOST_USER_COPY_TX_HDR == 1 875 s =
format (s,
"\n%Uvirtio_net_hdr flags 0x%02x gso_type %u hdr_len %u",
877 t->hdr.flags, t->hdr.gso_type, t->hdr.hdr_len);
910 #if VHOST_USER_COPY_TX_HDR == 1 923 int rv __attribute__ ((unused));
925 rv = write (vq->
callfd, &x, sizeof (x));
938 uword n_rx_packets = 0, n_rx_bytes = 0;
940 u32 n_left_to_next, *to_next;
945 u32 cpu_index, rx_len, drops, flush;
976 VHOST_USER_INPUT_FUNC_ERROR_FULL_RX_QUEUE, 1);
990 qsz_mask = txvq->
qsz - 1;
1024 flush = n_left - _vec_len (vum->
rx_buffers[cpu_index]);
1033 VHOST_USER_INPUT_FUNC_ERROR_NO_BUFFER, flush);
1036 u16 desc_chain_head =
1054 while (n_left > 0 && n_left_to_next > 0)
1057 u32 bi_head, bi_current;
1058 u16 desc_chain_head, desc_current;
1059 u8 error = VHOST_USER_INPUT_FUNC_ERROR_NO_ERROR;
1061 desc_chain_head = desc_current =
1063 bi_head = bi_current = vum->
rx_buffers[cpu_index][--rx_len];
1077 offset = txvq->
desc[desc_current].len;
1086 error = VHOST_USER_INPUT_FUNC_ERROR_MMAP_FAIL;
1090 #if VHOST_USER_COPY_TX_HDR == 1 1092 clib_memcpy (b->pre_data, buffer_addr, sizeof (virtio_net_hdr_t));
1095 if (txvq->
desc[desc_current].len > offset)
1109 error = VHOST_USER_INPUT_FUNC_ERROR_NO_BUFFER;
1116 if (txvq->
desc[desc_current].flags & VIRTQ_DESC_F_NEXT)
1117 desc_current = txvq->
desc[desc_current].next;
1132 error == VHOST_USER_INPUT_FUNC_ERROR_NO_ERROR))
1134 error = VHOST_USER_INPUT_FUNC_ERROR_UNDERSIZED_FRAME;
1160 to_next[0] = bi_head;
1164 to_next, n_left_to_next,
1173 _vec_len (vum->
rx_buffers[cpu_index]) = rx_len;
1188 if ((txvq->
callfd > 0) && !(txvq->
avail->flags & 1))
1210 return n_rx_packets;
1223 uword n_rx_packets = 0;
1238 return n_rx_packets;
1245 .name =
"vhost-user-input",
1248 .state = VLIB_NODE_STATE_DISABLED,
1274 uword n_packets = 0;
1280 u8 error = VHOST_USER_TX_FUNC_ERROR_NONE;
1290 error = VHOST_USER_TX_FUNC_ERROR_NOT_READY;
1296 while (__sync_lock_test_and_set (vui->lockp, 1))
1304 error = VHOST_USER_TX_FUNC_ERROR_NOT_READY;
1310 error = VHOST_USER_TX_FUNC_ERROR_PKT_DROP_NOBUF;
1314 used_index = rxvq->
used->idx;
1315 qsz_mask = rxvq->
qsz - 1;
1320 u16 desc_chain_head, desc_current, desc_len;
1333 error = VHOST_USER_TX_FUNC_ERROR_PKT_DROP_NOBUF;
1337 desc_current = desc_chain_head =
1339 offset = vui->virtio_net_hdr_sz;
1345 error = VHOST_USER_TX_FUNC_ERROR_MMAP_FAIL;
1352 virtio_net_hdr_mrg_rxbuf_t *hdr =
1353 (virtio_net_hdr_mrg_rxbuf_t *) buffer_addr;
1355 hdr->hdr.gso_type = 0;
1358 vui->virtio_net_hdr_sz);
1360 if (vui->virtio_net_hdr_sz == 12)
1361 hdr->num_buffers = 1;
1388 if (rxvq->
desc[desc_current].len <= offset)
1393 desc_current = rxvq->
desc[desc_current].next;
1398 used_index -= hdr->num_buffers - 1;
1400 error = VHOST_USER_TX_FUNC_ERROR_MMAP_FAIL;
1404 else if (vui->virtio_net_hdr_sz == 12)
1408 rxvq->
used->ring[used_index & qsz_mask].id =
1410 rxvq->
used->ring[used_index & qsz_mask].len = desc_len;
1412 ring[used_index & qsz_mask]);
1421 used_index -= hdr->num_buffers - 1;
1423 error = VHOST_USER_TX_FUNC_ERROR_PKT_DROP_NOBUF;
1430 desc_current = desc_chain_head;
1438 used_index -= hdr->num_buffers - 1;
1440 error = VHOST_USER_TX_FUNC_ERROR_MMAP_FAIL;
1446 error = VHOST_USER_TX_FUNC_ERROR_PKT_DROP_NOBUF;
1453 (rxvq->
desc[desc_current].len -
1454 offset) ? (rxvq->
desc[desc_current].len - offset) : bytes_left;
1461 rxvq->
desc[desc_current].addr + offset,
1463 bytes_left -= bytes_to_copy;
1464 offset += bytes_to_copy;
1465 buffer_addr += bytes_to_copy;
1466 desc_len += bytes_to_copy;
1470 rxvq->
used->ring[used_index & qsz_mask].id = desc_chain_head;
1471 rxvq->
used->ring[used_index & qsz_mask].len = desc_len;
1480 rxvq->
used->idx = used_index;
1484 if ((rxvq->
callfd > 0) && !(rxvq->
avail->flags & 1))
1497 if (
PREDICT_FALSE (n_left && error != VHOST_USER_TX_FUNC_ERROR_NONE))
1531 .name =
"vhost-user",
1538 .no_flatten_output_chains = 1,
1551 struct sockaddr_un sun;
1554 f64 timeout = 3153600000.0 ;
1555 uword *event_data = 0;
1557 sockfd = socket (AF_UNIX, SOCK_STREAM, 0);
1558 sun.sun_family = AF_UNIX;
1585 sizeof (sun.sun_path) - 1);
1588 (sockfd, (
struct sockaddr *) &sun,
1589 sizeof (
struct sockaddr_un)) == 0)
1593 template.file_descriptor = sockfd;
1598 sockfd = socket (AF_UNIX, SOCK_STREAM, 0);
1611 socklen_t len =
sizeof (error);
1613 getsockopt (vui->
unix_fd, SOL_SOCKET, SO_ERROR, &error, &len);
1625 .function = vhost_user_process,
1627 .name =
"vhost-user-process",
1642 return VNET_API_ERROR_INVALID_SW_IF_INDEX;
1661 DBG_SOCK (
"deleted (deactivated) vhost-user interface instance %d", p[0]);
1671 struct sockaddr_un un = { };
1674 fd = socket (AF_UNIX, SOCK_STREAM, 0);
1678 return VNET_API_ERROR_SYSCALL_ERROR_1;
1681 un.sun_family = AF_UNIX;
1682 strncpy ((
char *) un.sun_path, (
char *) sock_filename,
1683 sizeof (un.sun_path) - 1);
1686 unlink ((
char *) sock_filename);
1688 if (bind (fd, (
struct sockaddr *) &un,
sizeof (un)) == -1)
1690 rv = VNET_API_ERROR_SYSCALL_ERROR_2;
1694 if (listen (fd, 1) == -1)
1696 rv = VNET_API_ERROR_SYSCALL_ERROR_3;
1702 template.file_descriptor = fd;
1720 if (inactive_cnt > 0)
1728 DBG_SOCK (
"reusing inactive vhost-user interface index %d",
1759 rnd = (
u32) (now * 1e6);
1769 vhost_user_dev_class.index,
1784 const char *sock_filename,
1785 u8 is_server,
u64 feature_mask,
u32 * sw_if_index)
1805 for (q = 0; q < 2; q++)
1847 VLIB_NODE_STATE_POLLING);
1851 VLIB_NODE_STATE_POLLING);
1860 const char *sock_filename,
1864 u8 renumber,
u32 custom_dev_instance,
u8 * hwaddr)
1884 feature_mask, &sw_if_idx);
1894 *sw_if_index = sw_if_idx;
1901 const char *sock_filename,
1904 u64 feature_mask,
u8 renumber,
u32 custom_dev_instance)
1916 return VNET_API_ERROR_INVALID_SW_IF_INDEX;
1937 feature_mask, &sw_if_idx);
1955 u8 *sock_filename =
NULL;
1958 u64 feature_mask = (
u64) ~ 0;
1960 u32 custom_dev_instance = ~0;
1970 if (
unformat (line_input,
"socket %s", &sock_filename))
1972 else if (
unformat (line_input,
"server"))
1974 else if (
unformat (line_input,
"feature-mask 0x%llx", &feature_mask))
1980 else if (
unformat (line_input,
"renumber %d", &custom_dev_instance))
1994 is_server, &sw_if_index, feature_mask,
1995 renumber, custom_dev_instance, hw)))
2013 u32 sw_if_index = ~0;
2021 if (
unformat (line_input,
"sw_if_index %d", &sw_if_index))
2045 u32 *hw_if_indices = 0;
2059 for (i = 0; i <
vec_len (hw_if_indices); i++)
2076 strncpy ((
char *) vuid->
if_name, (
char *) s,
2084 *out_vuids = r_vuids;
2098 u32 hw_if_index, *hw_if_indices = 0;
2107 struct feat_struct *feat_entry;
2109 static struct feat_struct feat_array[] = {
2110 #define _(s,b) { .str = #s, .bit = b, }, 2121 vec_add1 (hw_if_indices, hw_if_index);
2133 if (
vec_len (hw_if_indices) == 0)
2145 for (i = 0; i <
vec_len (hw_if_indices); i++)
2150 hi->
name, hw_if_indices[i]);
2155 feat_entry = (
struct feat_struct *) &feat_array;
2156 while (feat_entry->str)
2158 if (vui->
features & (1 << feat_entry->bit))
2177 " region fd guest_phys_addr memory_size userspace_addr mmap_offset mmap_addr\n");
2179 " ====== ===== ================== ================== ================== ================== ==================\n");
2181 for (j = 0; j < vui->
nregions; j++)
2184 " %d %-5d 0x%016lx 0x%016lx 0x%016lx 0x%016lx 0x%016lx\n",
2197 " qsz %d last_avail_idx %d last_used_idx %d\n",
2203 " avail.flags %x avail.idx %d used.flags %x used.idx %d\n",
2217 " id addr len flags next user_addr\n");
2219 " ===== ================== ===== ====== ===== ==================\n");
2220 for (j = 0; j < vui->
vrings[q].
qsz; j++)
2223 " %-5d 0x%016lx %-5d 0x%04x %-5d 0x%016lx\n",
2249 .path =
"create vhost-user",
2250 .short_help =
"create vhost-user socket <socket-filename> [server] [feature-mask <hex>] [renumber <dev_instance>]",
2255 .path =
"delete vhost-user",
2256 .short_help =
"delete vhost-user sw_if_index <nn>",
2261 .path =
"show vhost-user",
2262 .short_help =
"show vhost-user interface",
2279 else if (
unformat (input,
"dont-dump-memory"))
unformat_function_t unformat_vnet_hw_interface
static clib_error_t * vhost_user_init(vlib_main_t *vm)
static void vhost_user_vui_init(vnet_main_t *vnm, vhost_user_intf_t *vui, int sockfd, const char *sock_filename, u8 is_server, u64 feature_mask, u32 *sw_if_index)
void vlib_put_next_frame(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, u32 n_vectors_left)
Release pointer to next frame vector data.
static void vlib_increment_simple_counter(vlib_simple_counter_main_t *cm, u32 cpu_index, u32 index, u32 increment)
Increment a simple counter.
static void vhost_user_if_disconnect(vhost_user_intf_t *vui)
#define hash_set(h, key, value)
static uword vhost_user_intfc_tx(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
sll srl srl sll sra u16x4 i
clib_error_t * vnet_hw_interface_set_flags(vnet_main_t *vnm, u32 hw_if_index, u32 flags)
static u32 vlib_get_trace_count(vlib_main_t *vm, vlib_node_runtime_t *rt)
static f64 vlib_process_wait_for_event_or_clock(vlib_main_t *vm, f64 dt)
Suspend a cooperative multi-tasking thread Waits for an event, or for the indicated number of seconds...
unix_file_function_t * read_function
#define hash_unset(h, key)
static void vhost_user_create_ethernet(vnet_main_t *vnm, vlib_main_t *vm, vhost_user_intf_t *vui, u8 *hwaddress)
void ethernet_delete_interface(vnet_main_t *vnm, u32 hw_if_index)
static vlib_main_t * vlib_get_main(void)
static clib_error_t * vhost_user_socket_error(unix_file_t *uf)
static void * map_guest_mem(vhost_user_intf_t *vui, uword addr)
uword * vhost_user_interface_index_by_sock_fd
vnet_interface_main_t interface_main
#define VLIB_BUFFER_TRACE_TRAJECTORY_INIT(b)
static vhost_user_intf_t * vhost_user_vui_new()
static void vlib_error_count(vlib_main_t *vm, uword node_index, uword counter, uword increment)
u32 vlib_buffer_alloc_from_free_list(vlib_main_t *vm, u32 *buffers, u32 n_buffers, u32 free_list_index)
Allocate buffers from specific freelist into supplied array.
static f64 vlib_time_now(vlib_main_t *vm)
static uword vhost_user_input(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *f)
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
int vnet_interface_name_renumber(u32 sw_if_index, u32 new_show_dev_instance)
static u32 vhost_user_if_input(vlib_main_t *vm, vhost_user_main_t *vum, vhost_user_intf_t *vui, vlib_node_runtime_t *node)
static u8 * format_vhost_user_input_trace(u8 *s, va_list *va)
struct _vlib_node_registration vlib_node_registration_t
#define VHOST_USER_MSG_HDR_SZ
static clib_error_t * vhost_user_interface_admin_up_down(vnet_main_t *vnm, u32 hw_if_index, u32 flags)
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
static void vhost_user_vui_register(vlib_main_t *vm, vhost_user_intf_t *vui)
static vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
clib_error_t * show_vhost_user_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
#define clib_error_report(e)
#define VNET_HW_INTERFACE_FLAG_LINK_UP
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
static char * vhost_user_input_func_error_strings[]
static char * vhost_user_tx_func_error_strings[]
#define vec_alloc(V, N)
Allocate space for N more elements (no header, unspecified alignment)
format_function_t format_vnet_sw_if_index_name
static uword unix_file_add(unix_main_t *um, unix_file_t *template)
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
static int vhost_user_name_renumber(vnet_hw_interface_t *hi, u32 new_dev_instance)
static vnet_sw_interface_t * vnet_get_hw_sw_interface(vnet_main_t *vnm, u32 hw_if_index)
static void vlib_trace_buffer(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, vlib_buffer_t *b, int follow_chain)
#define VHOST_VRING_F_LOG
vnet_main_t * vnet_get_main(void)
vhost_user_vring_t vrings[2]
VNET_DEVICE_CLASS(vhost_user_dev_class, static)
static u8 * format_vhost_user_interface_name(u8 *s, va_list *args)
#define vlib_prefetch_buffer_with_index(vm, bi, type)
Prefetch buffer metadata by buffer index The first 64 bytes of buffer contains most header informatio...
#define VLIB_INIT_FUNCTION(x)
static uword vlib_process_get_events(vlib_main_t *vm, uword **data_vector)
Return the first event type which has occurred and a vector of per-event data of that type...
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
vlib_combined_counter_main_t * combined_sw_if_counters
int input_cpu_first_index
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
void vhost_user_rx_trace(vlib_main_t *vm, vlib_node_runtime_t *node, vhost_user_intf_t *vui, i16 virtqueue)
u8 pre_data[VLIB_BUFFER_PRE_DATA_SIZE]
Space for inserting data before buffer start.
vhost_user_tx_func_error_t
#define clib_warning(format, args...)
static void unmap_all_mem_regions(vhost_user_intf_t *vui)
VLIB_DEVICE_TX_FUNCTION_MULTIARCH(vhost_user_dev_class, vhost_user_intfc_tx)
vhost_user_input_func_error_t
#define vlib_call_init_function(vm, x)
static clib_error_t * vhost_user_socket_read(unix_file_t *uf)
static uword pointer_to_uword(const void *p)
#define VLIB_BUFFER_NEXT_PRESENT
vlib_main_t ** vlib_mains
#define VLIB_BUFFER_PRE_DATA_SIZE
static void unix_file_del(unix_main_t *um, unix_file_t *f)
format_function_t format_vnet_sw_interface_name
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
u16 current_length
Nbytes between current data and the end of this buffer.
static void vlib_process_signal_event(vlib_main_t *vm, uword node_index, uword type_opaque, uword data)
int vhost_user_delete_if(vnet_main_t *vnm, vlib_main_t *vm, u32 sw_if_index)
static void * map_user_mem(vhost_user_intf_t *vui, uword addr)
uword os_get_cpu_number(void)
#define clib_error_return_unix(e, args...)
#define VLIB_CONFIG_FUNCTION(x, n,...)
#define vhost_user_log_dirty_ring(vui, vq, member)
static vlib_node_registration_t vhost_user_process_node
(constructor) VLIB_REGISTER_NODE (vhost_user_process_node)
void vhost_user_unmap_all(void)
vlib_simple_counter_main_t * sw_if_counters
u32 region_mmap_fd[VHOST_MEMORY_MAX_NREGIONS]
static void vhost_user_send_call(vlib_main_t *vm, vhost_user_vring_t *vq)
vhost_user_memory_region_t regions[VHOST_MEMORY_MAX_NREGIONS]
#define vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next, n_left_to_next, bi0, next0)
Finish enqueueing one buffer forward in the graph.
#define vlib_get_next_frame(vm, node, next_index, vectors, n_vectors_left)
Get pointer to next frame vector data by (vlib_node_runtime_t, next_index).
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
int vhost_user_dump_ifs(vnet_main_t *vnm, vlib_main_t *vm, vhost_user_intf_details_t **out_vuids)
vlib_error_t error
Error code for buffers to be enqueued to error handler.
static void vhost_user_log_dirty_pages(vhost_user_intf_t *vui, u64 addr, u64 len)
static void vlib_buffer_chain_init(vlib_buffer_t *first)
static clib_error_t * vhost_user_exit(vlib_main_t *vm)
u8 * format_ethernet_header_with_length(u8 *s, va_list *args)
u32 * show_dev_instance_by_real_dev_instance
int vhost_user_create_if(vnet_main_t *vnm, vlib_main_t *vm, const char *sock_filename, u8 is_server, u32 *sw_if_index, u64 feature_mask, u8 renumber, u32 custom_dev_instance, u8 *hwaddr)
vhost_user_intf_t * vhost_user_interfaces
#define CLIB_PREFETCH(addr, size, type)
#define vec_free(V)
Free vector's memory (no header).
static vlib_thread_main_t * vlib_get_thread_main()
#define VLIB_MAIN_LOOP_EXIT_FUNCTION(x)
int vhost_user_modify_if(vnet_main_t *vnm, vlib_main_t *vm, const char *sock_filename, u8 is_server, u32 sw_if_index, u64 feature_mask, u8 renumber, u32 custom_dev_instance)
#define clib_memcpy(a, b, c)
#define VHOST_MEMORY_MAX_NREGIONS
void vlib_worker_thread_barrier_sync(vlib_main_t *vm)
#define VHOST_USER_PROTOCOL_F_LOG_SHMFD
#define VLIB_BUFFER_DEFAULT_FREE_LIST_INDEX
u32 * vhost_user_inactive_interfaces_index
#define hash_create(elts, value_bytes)
#define VNET_SW_INTERFACE_FLAG_ADMIN_UP
u32 max_l3_packet_bytes[VLIB_N_RX_TX]
uword unformat_ethernet_address(unformat_input_t *input, va_list *args)
static void vlib_increment_combined_counter(vlib_combined_counter_main_t *cm, u32 cpu_index, u32 index, u32 packet_increment, u32 byte_increment)
Increment a combined counter.
void vlib_buffer_free(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Free buffers Frees the entire buffer chain for each buffer.
static long get_huge_page_size(int fd)
u32 next_buffer
Next buffer for this linked-list of buffers.
clib_error_t * vhost_user_delete_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
u16 vlib_buffer_chain_append_data_with_alloc(vlib_main_t *vm, u32 free_list_index, vlib_buffer_t *first, vlib_buffer_t **last, void *data, u16 data_len)
#define VIRTQ_DESC_F_NEXT
clib_error_t * ethernet_register_interface(vnet_main_t *vnm, u32 dev_class_index, u32 dev_instance, u8 *address, u32 *hw_if_index_return, ethernet_flag_change_function_t flag_change)
static void * vlib_frame_args(vlib_frame_t *f)
Get pointer to frame scalar data.
static void vlib_node_set_state(vlib_main_t *vm, u32 node_index, vlib_node_state_t new_state)
Set node dispatch state.
static void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
u32 total_length_not_including_first_buffer
Only valid for first buffer in chain.
#define foreach_vhost_user_tx_func_error
void * region_mmap_addr[VHOST_MEMORY_MAX_NREGIONS]
VLIB_CLI_COMMAND(set_interface_ip_source_and_port_range_check_command, static)
static clib_error_t * vhost_user_socksvr_accept_ready(unix_file_t *uf)
static clib_error_t * vhost_user_config(vlib_main_t *vm, unformat_input_t *input)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
static int vhost_user_init_server_sock(const char *sock_filename, int *sockfd)
#define VHOST_NET_VRING_IDX_RX
uword * vhost_user_interface_index_by_listener_fd
vlib_node_registration_t vhost_user_input_node
(constructor) VLIB_REGISTER_NODE (vhost_user_input_node)
#define DBG_SOCK(args...)
struct clib_bihash_value offset
template key/value backing page structure
static vhost_user_main_t vhost_user_main
static void * clib_mem_alloc_aligned(uword size, uword align)
#define VLIB_NODE_FUNCTION_MULTIARCH(node, fn)
static u32 random_u32(u32 *seed)
32-bit random number generator
#define VHOST_NET_VRING_IDX_TX
void vlib_worker_thread_barrier_release(vlib_main_t *vm)
#define VLIB_REGISTER_NODE(x,...)
static clib_error_t * vhost_user_callfd_read_ready(unix_file_t *uf)
#define vec_foreach(var, vec)
Vector iterator.
#define foreach_vhost_user_input_func_error
#define CLIB_MEMORY_BARRIER()
#define clib_error_return(e, args...)
static void vlib_set_trace_count(vlib_main_t *vm, vlib_node_runtime_t *rt, u32 count)
#define vec_validate_init_empty(V, I, INIT)
Make sure vector is long enough for given index and initialize empty space (no header, unspecified alignment)
#define CLIB_CACHE_LINE_BYTES
u32 flags
buffer flags: VLIB_BUFFER_IS_TRACED: trace this buffer.
uword * vhost_user_interface_index_by_sw_if_index
uword runtime_data[(128-1 *sizeof(vlib_node_function_t *)-1 *sizeof(vlib_error_t *)-11 *sizeof(u32)-5 *sizeof(u16))/sizeof(uword)]
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
clib_error_t * vhost_user_connect_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
VNET_HW_INTERFACE_CLASS(vhost_interface_class, static)
int dont_dump_vhost_user_memory