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> 86 ssize_t map_sz = (vui->
regions[
i].memory_size +
88 page_sz - 1) & ~(page_sz - 1);
94 vu_log_debug (vui,
"unmap memory region %d addr 0x%lx len 0x%lx " 102 vu_log_err (vui,
"failed to unmap memory region (errno %d)",
124 u32 thread_index = 0;
142 if (thread_index == 0)
145 for (thread_index = 0;
179 vu_log_warn (vui,
"unable to set rx mode for interface %d, " 187 int i, found[2] = { };
193 return found[0] && found[1];
204 is_ready ?
"ready" :
"down");
232 __attribute__ ((unused))
int n;
255 __attribute__ ((unused))
int n;
298 if (qid == 0 || qid == 1)
321 if (vring->
errfd != -1)
323 close (vring->
errfd);
361 int fd, number_of_fds = 0;
363 vhost_user_msg_t msg;
368 struct cmsghdr *cmsg;
385 iov[0].iov_base = (
void *) &msg;
390 mh.msg_control = control;
391 mh.msg_controllen =
sizeof (control);
399 vu_log_debug (vui,
"recvmsg returned error %d %s", errno,
404 vu_log_debug (vui,
"n (%d) != VHOST_USER_MSG_HDR_SZ (%d)",
410 if (mh.msg_flags & MSG_CTRUNC)
416 cmsg = CMSG_FIRSTHDR (&mh);
418 if (cmsg && (cmsg->cmsg_len > 0) && (cmsg->cmsg_level == SOL_SOCKET) &&
419 (cmsg->cmsg_type == SCM_RIGHTS) &&
420 (cmsg->cmsg_len - CMSG_LEN (0) <=
421 VHOST_MEMORY_MAX_NREGIONS *
sizeof (
int)))
423 number_of_fds = (cmsg->cmsg_len - CMSG_LEN (0)) /
sizeof (
int);
428 if ((msg.flags & 7) != 1)
430 vu_log_debug (vui,
"malformed message received. closing socket");
444 else if (rv != msg.size)
446 vu_log_debug (vui,
"message too short (read %dB should be %dB)", rv,
456 msg.u64 = (1ULL << FEAT_VIRTIO_NET_F_MRG_RXBUF) |
457 (1ULL << FEAT_VIRTIO_NET_F_CTRL_VQ) |
458 (1ULL << FEAT_VIRTIO_F_ANY_LAYOUT) |
459 (1ULL << FEAT_VIRTIO_F_INDIRECT_DESC) |
460 (1ULL << FEAT_VHOST_F_LOG_ALL) |
461 (1ULL << FEAT_VIRTIO_NET_F_GUEST_ANNOUNCE) |
462 (1ULL << FEAT_VIRTIO_NET_F_MQ) |
463 (1ULL << FEAT_VHOST_USER_F_PROTOCOL_FEATURES) |
464 (1ULL << FEAT_VIRTIO_F_VERSION_1);
470 msg.size =
sizeof (msg.u64);
471 vu_log_debug (vui,
"if %d msg VHOST_USER_GET_FEATURES - reply " 483 vu_log_debug (vui,
"if %d msg VHOST_USER_SET_FEATURES features " 489 ((1 << FEAT_VIRTIO_NET_F_MRG_RXBUF) |
490 (1ULL << FEAT_VIRTIO_F_VERSION_1)))
496 (vui->
features & (1 << FEAT_VIRTIO_F_ANY_LAYOUT)) ? 1 : 0;
515 vu_log_debug (vui,
"if %d msg VHOST_USER_SET_MEM_TABLE nregions %d",
518 if ((msg.memory.nregions < 1) ||
519 (msg.memory.nregions > VHOST_MEMORY_MAX_NREGIONS))
521 vu_log_debug (vui,
"number of mem regions must be between 1 and %i",
522 VHOST_MEMORY_MAX_NREGIONS);
526 if (msg.memory.nregions != number_of_fds)
534 for (i = 0; i < msg.memory.nregions; i++)
539 ssize_t map_sz = (msg.memory.regions[
i].memory_size +
540 msg.memory.regions[
i].mmap_offset +
541 page_sz - 1) & ~(page_sz - 1);
543 region_mmap_addr[
i] = mmap (0, map_sz, PROT_READ | PROT_WRITE,
544 MAP_SHARED, fds[i], 0);
545 if (region_mmap_addr[i] == MAP_FAILED)
547 vu_log_err (vui,
"failed to map memory. errno is %d", errno);
548 for (j = 0; j <
i; j++)
549 munmap (region_mmap_addr[j], map_sz);
552 vu_log_debug (vui,
"map memory region %d addr 0 len 0x%lx fd %d " 553 "mapped 0x%lx page_sz 0x%x", i, map_sz, fds[i],
554 region_mmap_addr[i], page_sz);
559 for (i = 0; i < msg.memory.nregions; i++)
562 sizeof (vhost_user_memory_region_t));
596 vu_log_debug (vui,
"if %d msg VHOST_USER_SET_VRING_NUM idx %d num %d",
599 if ((msg.state.num > 32768) ||
600 (msg.state.num == 0) ||
601 ((msg.state.num - 1) & msg.state.num))
607 vu_log_debug (vui,
"if %d msg VHOST_USER_SET_VRING_ADDR idx %d",
610 if (msg.state.index >= VHOST_VRING_MAX_N)
612 vu_log_debug (vui,
"invalid vring index VHOST_USER_SET_VRING_ADDR:" 613 " %d >= %d", msg.state.index, VHOST_VRING_MAX_N);
617 if (msg.size < sizeof (msg.addr))
619 vu_log_debug (vui,
"vhost message is too short (%d < %d)",
620 msg.size, sizeof (msg.addr));
628 if ((desc == NULL) || (used == NULL) || (avail == NULL))
630 vu_log_debug (vui,
"failed to map user memory for hw_if_index %d",
650 if (!(vui->
features & (1 << FEAT_VHOST_USER_F_PROTOCOL_FEATURES)))
673 vu_log_debug (vui,
"if %d msg VHOST_USER_SET_VRING_CALL %d",
676 q = (
u8) (msg.u64 & 0xFF);
689 if (number_of_fds != 1)
696 template.file_descriptor = fds[0];
697 template.private_data =
706 vu_log_debug (vui,
"if %d msg VHOST_USER_SET_VRING_KICK %d",
709 q = (
u8) (msg.u64 & 0xFF);
721 if (number_of_fds != 1)
728 template.file_descriptor = fds[0];
729 template.private_data =
745 vu_log_debug (vui,
"if %d msg VHOST_USER_SET_VRING_ERR %d",
748 q = (
u8) (msg.u64 & 0xFF);
755 if (number_of_fds != 1)
765 vu_log_debug (vui,
"if %d msg VHOST_USER_SET_VRING_BASE idx %d num %d",
773 if (msg.state.index >= VHOST_VRING_MAX_N)
775 vu_log_debug (vui,
"invalid vring index VHOST_USER_GET_VRING_BASE:" 776 " %d >= %d", msg.state.index, VHOST_VRING_MAX_N);
788 msg.size =
sizeof (msg.state);
796 vu_log_debug (vui,
"if %d msg VHOST_USER_GET_VRING_BASE idx %d num %d",
816 if (msg.size != sizeof (msg.log))
818 vu_log_debug (vui,
"invalid msg size for VHOST_USER_SET_LOG_BASE:" 819 " %d instead of %d", msg.size, sizeof (msg.log));
825 vu_log_debug (vui,
"VHOST_USER_PROTOCOL_F_LOG_SHMFD not set but " 826 "VHOST_USER_SET_LOG_BASE received");
834 (msg.log.size + msg.log.offset + page_sz - 1) & ~(page_sz - 1);
836 void *log_base_addr = mmap (0, map_sz, PROT_READ | PROT_WRITE,
839 vu_log_debug (vui,
"map log region addr 0 len 0x%lx off 0x%lx fd %d " 840 "mapped 0x%lx", map_sz, msg.log.offset, fd,
843 if (log_base_addr == MAP_FAILED)
845 vu_log_err (vui,
"failed to map memory. errno is %d", errno);
856 msg.size =
sizeof (msg.u64);
874 msg.size =
sizeof (msg.u64);
875 vu_log_debug (vui,
"if %d msg VHOST_USER_GET_PROTOCOL_FEATURES - " 887 vu_log_debug (vui,
"if %d msg VHOST_USER_SET_PROTOCOL_FEATURES " 895 msg.size =
sizeof (msg.u64);
896 vu_log_debug (vui,
"if %d msg VHOST_USER_GET_QUEUE_NUM - reply %d",
908 vu_log_debug (vui,
"if %d VHOST_USER_SET_VRING_ENABLE: %s queue %d",
909 vui->
hw_if_index, msg.state.num ?
"enable" :
"disable",
911 if (msg.state.index >= VHOST_VRING_MAX_N)
913 vu_log_debug (vui,
"invalid vring idx VHOST_USER_SET_VRING_ENABLE:" 914 " %d >= %d", msg.state.index, VHOST_VRING_MAX_N);
924 vu_log_debug (vui,
"unknown vhost-user message %d received. " 925 "closing socket", msg.request);
957 int client_fd, client_len;
958 struct sockaddr_un client;
965 client_len =
sizeof (client);
967 (
struct sockaddr *) &client,
968 (socklen_t *) & client_len);
975 vu_log_debug (vui,
"Close client socket for vhost interface %d, fd %d",
980 vu_log_debug (vui,
"New client socket for vhost interface %d, fd %d",
984 template.file_descriptor = client_fd;
1030 f64 timeout = 3153600000.0 ;
1031 uword event_type, *event_data = 0;
1034 f64 now, poll_time_remaining;
1040 poll_time_remaining =
1049 timeout = poll_time_remaining;
1070 next_timeout = timeout;
1071 for (qid = 0; qid < VHOST_VRING_MAX_N / 2; qid += 2)
1073 vhost_user_vring_t *rxvq = &vui->vrings[qid];
1074 vhost_user_vring_t *txvq = &vui->vrings[qid + 1];
1076 if (txvq->qid == -1)
1078 if (txvq->n_since_last_int)
1080 if (now >= txvq->int_deadline)
1081 vhost_user_send_call (vm, txvq);
1083 next_timeout = txvq->int_deadline - now;
1086 if (rxvq->n_since_last_int)
1088 if (now >= rxvq->int_deadline)
1089 vhost_user_send_call (vm, rxvq);
1091 next_timeout = rxvq->int_deadline - now;
1094 if ((next_timeout < timeout) && (next_timeout > 0.0))
1095 timeout = next_timeout;
1102 clib_warning (
"BUG: unhandled event type %d", event_type);
1109 timeout = 3153600000.0;
1118 .name =
"vhost-user-send-interrupt-process",
1128 struct sockaddr_un sun;
1131 f64 timeout = 3153600000.0 ;
1132 uword *event_data = 0;
1135 sun.sun_family = AF_UNIX;
1150 if (vui->unix_server_index == ~0) {
1151 if (vui->clib_file_index == ~0)
1154 ((sockfd = socket (AF_UNIX, SOCK_STREAM, 0)) < 0))
1160 if (!vui->sock_errno || (vui->sock_errno != errno))
1163 (
"Error: Could not open unix socket for %s",
1164 vui->sock_filename);
1165 vui->sock_errno = errno;
1171 strncpy (sun.sun_path, (char *) vui->sock_filename,
1172 sizeof (sun.sun_path) - 1);
1175 if (fcntl(sockfd, F_SETFL, O_NONBLOCK) < 0)
1176 clib_unix_warning (
"fcntl");
1178 if (connect (sockfd, (struct sockaddr *) &sun,
1179 sizeof (struct sockaddr_un)) == 0)
1182 if (fcntl(sockfd, F_SETFL, 0) < 0)
1183 clib_unix_warning (
"fcntl2");
1185 vui->sock_errno = 0;
1186 template.file_descriptor = sockfd;
1187 template.private_data =
1188 vui - vhost_user_main.vhost_user_interfaces;
1189 vui->clib_file_index = clib_file_add (&file_main, &template);
1196 vui->sock_errno = errno;
1203 socklen_t len = sizeof (error);
1204 int fd = UNIX_GET_FD(vui->clib_file_index);
1206 getsockopt (fd, SOL_SOCKET, SO_ERROR, &error, &len);
1210 vu_log_debug (vui,
"getsockopt returned %d", retval);
1211 vhost_user_if_disconnect (vui);
1225 .name =
"vhost-user-process",
1253 if (txvq->
qid != -1)
1259 vu_log_warn (vui,
"unable to unassign interface %d, " 1294 return VNET_API_ERROR_INVALID_SW_IF_INDEX;
1298 vu_log_debug (vui,
"Deleting vhost-user interface %s (instance %d)",
1305 if (txvq->
qid == -1)
1351 vhost_user_delete_if (vnm, vm, vui->sw_if_index);
1367 struct sockaddr_un
un = { };
1370 if ((fd = socket (AF_UNIX, SOCK_STREAM, 0)) < 0)
1371 return VNET_API_ERROR_SYSCALL_ERROR_1;
1373 un.sun_family = AF_UNIX;
1374 strncpy ((
char *) un.sun_path, (
char *) sock_filename,
1375 sizeof (un.sun_path) - 1);
1378 unlink ((
char *) sock_filename);
1380 if (bind (fd, (
struct sockaddr *) &un,
sizeof (un)) == -1)
1382 rv = VNET_API_ERROR_SYSCALL_ERROR_2;
1386 if (listen (fd, 1) == -1)
1388 rv = VNET_API_ERROR_SYSCALL_ERROR_3;
1442 const char *sock_filename,
1452 if (server_sock_fd != -1)
1456 template.file_descriptor = server_sock_fd;
1488 (FEATURE_VIRTIO_NET_F_HOST_GUEST_TSO_FEATURE_BITS)))
1517 const char *sock_filename,
1521 u8 renumber,
u32 custom_dev_instance,
u8 * hwaddr,
1527 int server_sock_fd = -1;
1531 if (sock_filename == NULL || !(strlen (sock_filename) > 0))
1533 return VNET_API_ERROR_INVALID_ARGUMENT;
1544 return VNET_API_ERROR_IF_ALREADY_EXISTS;
1563 feature_mask, &sw_if_idx, enable_gso);
1571 *sw_if_index = sw_if_idx;
1581 const char *sock_filename,
1584 u64 feature_mask,
u8 renumber,
u32 custom_dev_instance,
1590 int server_sock_fd = -1;
1599 return VNET_API_ERROR_INVALID_SW_IF_INDEX;
1601 if (sock_filename == NULL || !(strlen (sock_filename) > 0))
1602 return VNET_API_ERROR_INVALID_ARGUMENT;
1611 if (if_index && (*if_index != vui->
if_index))
1612 return VNET_API_ERROR_IF_ALREADY_EXISTS;
1617 &server_sock_fd)) != 0)
1622 sock_filename, feature_mask, &sw_if_idx, enable_gso);
1639 u8 *sock_filename = NULL;
1642 u64 feature_mask = (
u64) ~ (0ULL);
1644 u32 custom_dev_instance = ~0;
1658 if (
unformat (line_input,
"socket %s", &sock_filename))
1660 else if (
unformat (line_input,
"server"))
1662 else if (
unformat (line_input,
"gso"))
1664 else if (
unformat (line_input,
"feature-mask 0x%llx", &feature_mask))
1670 else if (
unformat (line_input,
"renumber %d", &custom_dev_instance))
1686 is_server, &sw_if_index, feature_mask,
1687 renumber, custom_dev_instance, hw,
1720 if (
unformat (line_input,
"sw_if_index %d", &sw_if_index))
1760 u32 *hw_if_indices = 0;
1772 for (i = 0; i <
vec_len (hw_if_indices); i++)
1789 strncpy ((
char *) vuid->
if_name, (
char *) s,
1797 *out_vuids = r_vuids;
1811 u32 hw_if_index, *hw_if_indices = 0;
1822 struct feat_struct *feat_entry;
1824 static struct feat_struct feat_array[] = {
1825 #define _(s,b) { .str = #s, .bit = b, }, 1831 #define foreach_protocol_feature \ 1832 _(VHOST_USER_PROTOCOL_F_MQ) \ 1833 _(VHOST_USER_PROTOCOL_F_LOG_SHMFD) 1835 static struct feat_struct proto_feat_array[] = {
1836 #define _(s) { .str = #s, .bit = s}, 1854 vec_add1 (hw_if_indices, hw_if_index);
1865 if (
vec_len (hw_if_indices) == 0)
1874 vlib_cli_output (vm,
" Number of rx virtqueues in interrupt mode: %d",
1878 for (i = 0; i <
vec_len (hw_if_indices); i++)
1889 " features mask (0x%llx): \n" 1890 " features (0x%llx): \n",
1894 feat_entry = (
struct feat_struct *) &feat_array;
1895 while (feat_entry->str)
1897 if (vui->
features & (1ULL << feat_entry->bit))
1905 feat_entry = (
struct feat_struct *) &proto_feat_array;
1906 while (feat_entry->str)
1930 if (txvq->
qid == -1)
1958 " region fd guest_phys_addr memory_size userspace_addr mmap_offset mmap_addr\n");
1960 " ====== ===== ================== ================== ================== ================== ==================\n");
1962 for (j = 0; j < vui->
nregions; j++)
1965 " %d %-5d 0x%016lx 0x%016lx 0x%016lx 0x%016lx 0x%016lx\n",
1967 vui->
regions[j].guest_phys_addr,
1969 vui->
regions[j].userspace_addr,
1979 (q & 1) ?
"RX" :
"TX",
1983 " qsz %d last_avail_idx %d last_used_idx %d\n",
1990 " avail.flags %x avail.idx %d used.flags %x used.idx %d\n",
2005 " id addr len flags next user_addr\n");
2007 " ===== ================== ===== ====== ===== ==================\n");
2012 " %-5d 0x%016lx %-5d 0x%04x %-5d 0x%016lx\n",
2091 .path =
"create vhost-user",
2092 .short_help =
"create vhost-user socket <socket-filename> [server] " 2093 "[feature-mask <hex>] [hwaddr <mac-addr>] [renumber <dev_instance>] [gso]",
2113 .path =
"delete vhost-user",
2114 .short_help =
"delete vhost-user {<interface> | sw_if_index <sw_idx>}",
2253 .path =
"show vhost-user",
2254 .short_help =
"show vhost-user [<interface> [<interface> [..]]] [descriptors]",
2271 else if (
unformat (input,
"dont-dump-memory"))
unformat_function_t unformat_vnet_hw_interface
vlib_log_class_t vlib_log_register_class(char *class, char *subclass)
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
#define vec_foreach_index(var, v)
Iterate over vector indices.
static void clib_file_del(clib_file_main_t *um, clib_file_t *f)
format_function_t format_vnet_hw_if_index_name
#define vu_log_warn(dev, f,...)
static uword random_default_seed(void)
Default random seed (unix/linux user-mode)
#define VHOST_USER_PROTOCOL_F_LOG_SHMFD
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...
VNET_HW_INTERFACE_CLASS(vhost_interface_class, static)
vhost_cpu_t * cpus
Per-CPU data for vhost-user.
void ethernet_delete_interface(vnet_main_t *vnm, u32 hw_if_index)
vnet_main_t * vnet_get_main(void)
u64 region_guest_addr_hi[VHOST_MEMORY_MAX_NREGIONS]
static clib_error_t * vhost_user_socksvr_accept_ready(clib_file_t *uf)
#define VHOST_VRING_MAX_N
#define clib_memcpy_fast(a, b, c)
uword mhash_unset(mhash_t *h, void *key, uword *old_value)
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
static f64 vlib_time_now(vlib_main_t *vm)
static_always_inline void vhost_user_update_iface_state(vhost_user_intf_t *vui)
#define VLIB_BUFFER_PRE_DATA_SIZE
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
vnet_device_class_t vhost_user_device_class
#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 clib_error_t * vhost_user_callfd_read_ready(clib_file_t *uf)
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
#define VHOST_USER_EVENT_START_TIMER
static_always_inline void vhost_user_vring_init(vhost_user_intf_t *vui, u32 qid)
unformat_function_t unformat_vnet_sw_interface
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, u8 enable_gso)
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
format_function_t format_vnet_sw_if_index_name
#define VHOST_USER_VRING_NOFD_MASK
static_always_inline void vhost_user_rx_thread_placement(vhost_user_intf_t *vui, u32 qid)
Unassign existing interface/queue to thread mappings and re-assign new interface/queue to thread mapp...
static uword vlib_process_suspend_time_is_zero(f64 dt)
Returns TRUE if a process suspend time is less than 10us.
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
clib_file_function_t * read_function
#define vlib_worker_thread_barrier_sync(X)
static vnet_sw_interface_t * vnet_get_hw_sw_interface(vnet_main_t *vnm, u32 hw_if_index)
#define clib_memcpy(d, s, n)
static void vhost_user_vui_init(vnet_main_t *vnm, vhost_user_intf_t *vui, int server_sock_fd, const char *sock_filename, u64 feature_mask, u32 *sw_if_index, u8 enable_gso)
#define vu_log_debug(dev, f,...)
vnet_hw_interface_rx_mode
#define static_always_inline
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
vl_api_interface_index_t sw_if_index
#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 clib_error_t * vhost_user_socket_read(clib_file_t *uf)
#define UNIX_GET_FD(unixfd_idx)
static_always_inline void vhost_user_thread_placement(vhost_user_intf_t *vui, u32 qid)
static_always_inline void * map_guest_mem(vhost_user_intf_t *vui, uword addr, u32 *hint)
static_always_inline void vnet_device_input_set_interrupt_pending(vnet_main_t *vnm, u32 hw_if_index, u16 queue_id)
vnet_hw_interface_flags_t flags
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
#define VRING_USED_F_NO_NOTIFY
#define clib_error_return(e, args...)
clib_file_main_t file_main
static vlib_node_registration_t vhost_user_process_node
(constructor) VLIB_REGISTER_NODE (vhost_user_process_node)
static clib_error_t * vhost_user_kickfd_read_ready(clib_file_t *uf)
static clib_error_t * vhost_user_socket_error(clib_file_t *uf)
void vhost_user_unmap_all(void)
static_always_inline void vhost_user_tx_thread_placement(vhost_user_intf_t *vui)
#define VHOST_USER_PROTOCOL_F_MQ
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
static_always_inline uword vnet_get_device_input_thread_index(vnet_main_t *vnm, u32 hw_if_index, u16 queue_id)
static void vhost_user_term_if(vhost_user_intf_t *vui)
Disables and reset interface structure.
static void vlib_process_signal_event(vlib_main_t *vm, uword node_index, uword type_opaque, uword data)
static_always_inline int vhost_user_intf_ready(vhost_user_intf_t *vui)
Returns whether at least one TX and one RX vring are enabled.
u32 random
Pseudo random iterator.
uword mhash_set_mem(mhash_t *h, void *key, uword *new_value, uword *old_value)
vlib_node_registration_t vhost_user_input_node
(constructor) VLIB_REGISTER_NODE (vhost_user_input_node)
#define clib_error_return_unix(e, args...)
int vnet_hw_interface_get_rx_mode(vnet_main_t *vnm, u32 hw_if_index, u16 queue_id, vnet_hw_interface_rx_mode *mode)
#define pool_put(P, E)
Free an object E in pool P.
int vhost_user_delete_if(vnet_main_t *vnm, vlib_main_t *vm, u32 sw_if_index)
format_function_t format_vnet_hw_interface_rx_mode
#define VLIB_CONFIG_FUNCTION(x, n,...)
vhost_user_main_t vhost_user_main
#define VHOST_USER_MSG_HDR_SZ
u32 region_mmap_fd[VHOST_MEMORY_MAX_NREGIONS]
int vhost_user_dump_ifs(vnet_main_t *vnm, vlib_main_t *vm, vhost_user_intf_details_t **out_vuids)
vhost_user_memory_region_t regions[VHOST_MEMORY_MAX_NREGIONS]
vlib_log_class_t log_default
static_always_inline void vhost_user_update_gso_interface_count(vhost_user_intf_t *vui, u8 add)
#define VHOST_VRING_IDX_RX(qid)
u32 * show_dev_instance_by_real_dev_instance
static_always_inline void vhost_user_vring_close(vhost_user_intf_t *vui, u32 qid)
vhost_user_intf_t * vhost_user_interfaces
#define VLIB_REGISTER_NODE(x,...)
static void mhash_init_c_string(mhash_t *h, uword n_value_bytes)
#define vec_free(V)
Free vector's memory (no header).
static void unmap_all_mem_regions(vhost_user_intf_t *vui)
static clib_error_t * vhost_user_config(vlib_main_t *vm, unformat_input_t *input)
#define VLIB_MAIN_LOOP_EXIT_FUNCTION(x)
#define VHOST_USER_EVENT_STOP_TIMER
static vnet_hw_interface_t * vnet_get_sup_hw_interface_api_visible_or_null(vnet_main_t *vnm, u32 sw_if_index)
#define clib_warning(format, args...)
static uword vhost_user_process(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
clib_error_t * vhost_user_delete_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
vl_api_vxlan_gbp_api_tunnel_mode_t mode
#define foreach_protocol_feature
static int vhost_user_init_server_sock(const char *sock_filename, int *sock_fd)
Open server unix socket on specified sock_filename.
#define VLIB_CLI_COMMAND(x,...)
uword unformat_ethernet_address(unformat_input_t *input, va_list *args)
clib_error_t * show_vhost_user_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
#define VHOST_VRING_F_LOG
void vnet_hw_interface_assign_rx_thread(vnet_main_t *vnm, u32 hw_if_index, u16 queue_id, uword thread_index)
static uword * mhash_get(mhash_t *h, const void *key)
#define vu_log_err(dev, f,...)
static uword clib_file_add(clib_file_main_t *um, clib_file_t *template)
static_always_inline void vhost_user_if_disconnect(vhost_user_intf_t *vui)
static void clib_mem_free(void *p)
volatile u32 * vring_locks[VHOST_VRING_MAX_N]
mhash_t if_index_by_sock_name
static clib_error_t * vhost_user_exit(vlib_main_t *vm)
#define clib_error_report(e)
vlib_node_registration_t vhost_user_send_interrupt_node
(constructor) VLIB_REGISTER_NODE (vhost_user_send_interrupt_node)
static uword pointer_to_uword(const void *p)
static void vhost_user_create_ethernet(vnet_main_t *vnm, vlib_main_t *vm, vhost_user_intf_t *vui, u8 *hwaddress)
Create ethernet interface for vhost user interface.
static vlib_main_t * vlib_get_main(void)
struct _vlib_node_registration vlib_node_registration_t
void * region_mmap_addr[VHOST_MEMORY_MAX_NREGIONS]
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, u8 enable_gso)
static long get_huge_page_size(int fd)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
clib_error_t * ethernet_register_interface(vnet_main_t *vnm, u32 dev_class_index, u32 dev_instance, const u8 *address, u32 *hw_if_index_return, ethernet_flag_change_function_t flag_change)
vhost_user_vring_t vrings[VHOST_VRING_MAX_N]
clib_error_t * vnet_hw_interface_set_flags(vnet_main_t *vnm, u32 hw_if_index, vnet_hw_interface_flags_t flags)
static void vhost_user_set_interrupt_pending(vhost_user_intf_t *vui, u32 ifq)
#define VHOST_MEMORY_MAX_NREGIONS
clib_error_t * vhost_user_connect_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
void vnet_sw_interface_set_mtu(vnet_main_t *vnm, u32 sw_if_index, u32 mtu)
int vnet_hw_interface_unassign_rx_thread(vnet_main_t *vnm, u32 hw_if_index, u16 queue_id)
static void * clib_mem_alloc_aligned(uword size, uword align)
static u32 random_u32(u32 *seed)
32-bit random number generator
void vlib_worker_thread_barrier_release(vlib_main_t *vm)
static vlib_thread_main_t * vlib_get_thread_main()
u64 region_guest_addr_lo[VHOST_MEMORY_MAX_NREGIONS]
#define vec_foreach(var, vec)
Vector iterator.
int vnet_hw_interface_set_rx_mode(vnet_main_t *vnm, u32 hw_if_index, u16 queue_id, vnet_hw_interface_rx_mode mode)
static clib_error_t * vhost_user_init(vlib_main_t *vm)
static_always_inline void * map_user_mem(vhost_user_intf_t *vui, uword addr)
#define CLIB_CACHE_LINE_BYTES
static uword vhost_user_send_interrupt_process(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
#define FEATURE_VIRTIO_NET_F_HOST_GUEST_TSO_FEATURE_BITS
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
vl_api_address_union_t un
static void vnet_hw_interface_set_input_node(vnet_main_t *vnm, u32 hw_if_index, u32 node_index)
int dont_dump_vhost_user_memory