16 #include <sys/socket.h> 34 #define VHOST_USER_DEBUG_SOCKET 0 36 #if VHOST_USER_DEBUG_SOCKET == 1 37 #define DBG_SOCK(args...) clib_warning(args); 39 #define DBG_SOCK(args...) 58 #if RTE_VERSION >= RTE_VERSION_NUM(2, 2, 0, 0) 66 #if RTE_VERSION >= RTE_VERSION_NUM(2, 2, 0, 0) 112 struct virtio_memory_regions *region;
113 uint64_t vhost_va = 0;
117 for (regionidx = 0; regionidx < dev->mem->nregions; regionidx++) {
118 region = &dev->mem->regions[regionidx];
119 if ((qemu_va >= region->userspace_address) &&
120 (qemu_va <= region->userspace_address +
121 region->memory_size)) {
122 vhost_va = qemu_va + region->guest_phys_address +
123 region->address_offset -
124 region->userspace_address;
160 #if RTE_VERSION >= RTE_VERSION_NUM(2, 2, 0, 0) 169 #if RTE_VERSION >= RTE_VERSION_NUM(2, 2, 0, 0) 172 for (idx = 0; idx < numqs; idx++)
184 for (i=0; i<mem->nregions; i++) {
185 if ((mem->regions[i].guest_phys_address <= addr) &&
186 ((mem->regions[i].guest_phys_address + mem->regions[i].memory_size) > addr)) {
187 return (
void *) (vui->
region_addr[
i] + addr - mem->regions[
i].guest_phys_address);
190 DBG_SOCK(
"failed to map guest mem addr %lx", addr);
206 #if RTE_VERSION >= RTE_VERSION_NUM(2, 2, 0, 0) 218 if (inactive_cnt > 0) {
226 clib_warning(
"error: inactive vhost-user interface sw_if_index %d not VHOST_USER type!",
238 if (if_id != (
u32)~0)
243 for (j = 0; j < num_qpairs * VIRTIO_QNUM; j++) {
244 memset(xd->
vu_vhost_dev.virtqueue[j], 0,
sizeof(
struct vhost_virtqueue));
277 #if RTE_VERSION >= RTE_VERSION_NUM(2, 2, 0, 0) 283 if (if_id == (
u32)~0)
294 sizeof(
struct virtio_memory_regions));
304 for (j = 0; j < num_qpairs * VIRTIO_QNUM; j++) {
306 memset(xd->
vu_vhost_dev.virtqueue[j], 0,
sizeof(
struct vhost_virtqueue));
316 DBG_SOCK(
"tm->n_vlib_mains: %d. TX %d, RX: %d, num_qpairs: %d, Lock: %p",
349 rnd = (
u32) (now * 1e6);
373 DBG_SOCK(
"xd->device_index: %d, dm->input_cpu_count: %d, " 378 for (q = 0; q < num_qpairs; q++) {
400 VLIB_NODE_STATE_POLLING);
408 #if RTE_VERSION >= RTE_VERSION_NUM(16, 4, 0, 0) 417 #if RTE_VERSION >= RTE_VERSION_NUM(2, 2, 0, 0) 432 *features = rte_vhost_feature_get();
434 #if RTE_VERSION >= RTE_VERSION_NUM(16, 4, 0, 0) 435 #define OFFLOAD_FEATURES ((1ULL << VIRTIO_NET_F_HOST_TSO4) | \ 436 (1ULL << VIRTIO_NET_F_HOST_TSO6) | \ 437 (1ULL << VIRTIO_NET_F_CSUM) | \ 438 (1ULL << VIRTIO_NET_F_GUEST_CSUM) | \ 439 (1ULL << VIRTIO_NET_F_GUEST_TSO4) | \ 440 (1ULL << VIRTIO_NET_F_GUEST_TSO6)) 449 DBG_SOCK(
"supported features: 0x%lx", *features);
457 u16 hdr_len =
sizeof(
struct virtio_net_hdr);
467 if (xd->
vu_vhost_dev.features & (1 << VIRTIO_NET_F_MRG_RXBUF))
468 hdr_len =
sizeof(
struct virtio_net_hdr_mrg_rxbuf);
470 int numqs = VIRTIO_QNUM;
472 #if RTE_VERSION >= RTE_VERSION_NUM(2, 2, 0, 0) 473 int prot_feature = features &
477 for (idx = 0; idx < numqs; idx++) {
479 #if RTE_VERSION >= RTE_VERSION_NUM(2, 2, 0, 0) 497 struct virtio_memory * mem;
512 for (i=0; i < mem->nregions; i++) {
513 u64 mapped_size, mapped_address;
522 mapped_address =
pointer_to_uword(mmap(
NULL, mapped_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd[i], 0));
533 mem->regions[
i].address_offset = mapped_address - mem->regions[
i].guest_phys_address;
537 mem->mapped_address = mem->regions[
i].address_offset;
549 struct vhost_virtqueue *vq;
551 DBG_SOCK(
"idx %u num %u", idx, num);
570 struct vhost_virtqueue *vq;
572 DBG_SOCK(
"idx %u desc 0x%lx used 0x%lx avail 0x%lx log 0x%lx",
573 idx, desc, used, avail, log);
584 #if RTE_VERSION >= RTE_VERSION_NUM(16, 4, 0, 0) 585 vq->log_guest_addr =
log;
588 if (!(vq->desc && vq->used && vq->avail)) {
592 if (vq->last_used_idx != vq->used->idx) {
593 clib_warning(
"last_used_idx (%u) and vq->used->idx (%u) mismatches; " 594 "some packets maybe resent for Tx and dropped for Rx",
595 vq->last_used_idx, vq->used->idx);
596 vq->last_used_idx = vq->used->idx;
597 vq->last_used_idx_res = vq->used->idx;
608 rte_vhost_enable_guest_notification(&xd->
vu_vhost_dev, idx, 0);
618 struct vhost_virtqueue *vq;
626 *num = vq->last_used_idx;
635 DBG_SOCK(
"Stopping vring Q %u of device %d", idx, hw_if_index);
636 #if RTE_VERSION >= RTE_VERSION_NUM(2, 2, 0, 0) 644 #if RTE_VERSION >= RTE_VERSION_NUM(16, 4, 0, 0) 645 vq->log_guest_addr = 0;
650 for (idx = 0; idx < numqs; idx++) {
657 DBG_SOCK(
"Device %d disabled", hw_if_index);
674 struct vhost_virtqueue *vq;
676 DBG_SOCK(
"idx %u num %u", idx, num);
684 vq->last_used_idx = num;
685 vq->last_used_idx_res = num;
697 #if RTE_VERSION >= RTE_VERSION_NUM(2, 2, 0, 0) 700 struct vhost_virtqueue *vq0, *vq1, *vq;
701 int index, vu_is_running = 0;
711 #if RTE_VERSION >= RTE_VERSION_NUM(2, 2, 0, 0) 713 vq->enabled = (vq->desc && vq->avail && vq->used && vring->
enabled) ? 1 : 0;
720 int numqs = VIRTIO_QNUM;
721 #if RTE_VERSION >= RTE_VERSION_NUM(2, 2, 0, 0) 725 for (index = 0; index < numqs; index += 2) {
728 #if RTE_VERSION >= RTE_VERSION_NUM(2, 2, 0, 0) 729 if (vq0->enabled && vq1->enabled)
731 if (vq0->desc && vq0->avail && vq0->used &&
732 vq1->desc && vq1->avail && vq1->used)
739 DBG_SOCK(
"SET_VRING_KICK - idx %d, running %d, fd: %d",
740 idx, vu_is_running, fd);
746 ETH_LINK_FULL_DUPLEX );
752 #if RTE_VERSION >= RTE_VERSION_NUM(2, 2, 0, 0) 757 struct vhost_virtqueue *vq;
787 if (vq->desc && vq->avail && vq->used)
796 __attribute__((unused))
int n;
806 struct vhost_virtqueue *vq;
809 DBG_SOCK(
"SET_VRING_CALL - idx %d, fd %d", idx, fd);
826 template.file_descriptor = fd;
845 struct vhost_virtqueue *vq = xd->
vu_vhost_dev.virtqueue[idx];
848 return (vring->
callfd > 0) && !(vq->avail->flags & VRING_AVAIL_F_NO_INTERRUPT);
862 struct vhost_virtqueue *vq = xd->
vu_vhost_dev.virtqueue[idx];
865 if((vring->
callfd > 0) && !(vq->avail->flags & VRING_AVAIL_F_NO_INTERRUPT)) {
866 eventfd_write(vring->
callfd, (eventfd_t)1);
880 const char * sock_filename,
881 u8 is_server,
u64 feature_mask,
885 memset(vui, 0,
sizeof(*vui));
888 #if RTE_VERSION >= RTE_VERSION_NUM(2, 2, 0, 0) 946 int fd, number_of_fds = 0;
948 vhost_user_msg_t msg;
954 struct cmsghdr *cmsg;
961 DBG_SOCK (
"FD %d doesn't belong to any interface",
973 memset(&mh, 0,
sizeof(mh));
974 memset(control, 0,
sizeof(control));
977 iov[0].iov_base = (
void *) &msg;
982 mh.msg_control = control;
983 mh.msg_controllen =
sizeof(control);
990 if (mh.msg_flags & MSG_CTRUNC) {
994 cmsg = CMSG_FIRSTHDR(&mh);
996 if (cmsg && (cmsg->cmsg_len > 0) && (cmsg->cmsg_level == SOL_SOCKET) &&
997 (cmsg->cmsg_type == SCM_RIGHTS) &&
999 number_of_fds = (cmsg->cmsg_len - CMSG_LEN(0)) /
sizeof(
int);
1000 clib_memcpy(fds, CMSG_DATA(cmsg), number_of_fds *
sizeof(
int));
1004 if ((msg.flags & 7) != 1) {
1005 DBG_SOCK(
"malformed message received. closing socket");
1010 int rv __attribute__((unused));
1016 switch (msg.request) {
1018 DBG_SOCK(
"if %d msg VHOST_USER_GET_FEATURES",
1025 msg.size =
sizeof(msg.u64);
1029 DBG_SOCK(
"if %d msg VHOST_USER_SET_FEATURES features 0x%016lx",
1036 DBG_SOCK(
"if %d msg VHOST_USER_SET_MEM_TABLE nregions %d",
1039 if ((msg.memory.nregions < 1) ||
1042 DBG_SOCK(
"number of mem regions must be between 1 and %i",
1048 if (msg.memory.nregions != number_of_fds) {
1049 DBG_SOCK(
"each memory region must have FD");
1057 DBG_SOCK(
"if %d msg VHOST_USER_SET_VRING_NUM idx %d num %d",
1060 if ((msg.state.num > 32768) ||
1061 (msg.state.num == 0) ||
1062 (msg.state.num % 2))
1069 DBG_SOCK(
"if %d msg VHOST_USER_SET_VRING_ADDR idx %d",
1073 msg.addr.desc_user_addr,
1074 msg.addr.used_user_addr,
1075 msg.addr.avail_user_addr,
1076 msg.addr.log_guest_addr);
1080 DBG_SOCK(
"if %d msg VHOST_USER_SET_OWNER",
1085 DBG_SOCK(
"if %d msg VHOST_USER_RESET_OWNER",
1090 q = (
u8) (msg.u64 & 0xFF);
1092 DBG_SOCK(
"if %d msg VHOST_USER_SET_VRING_CALL u64 %lx, idx: %d",
1095 if (!(msg.u64 & 0x100))
1097 if (number_of_fds != 1)
1109 q = (
u8) (msg.u64 & 0xFF);
1111 DBG_SOCK(
"if %d msg VHOST_USER_SET_VRING_KICK u64 %lx, idx: %d",
1114 if (!(msg.u64 & 0x100))
1116 if (number_of_fds != 1)
1129 q = (
u8) (msg.u64 & 0xFF);
1131 DBG_SOCK(
"if %d msg VHOST_USER_SET_VRING_ERR u64 %lx, idx: %d",
1134 if (!(msg.u64 & 0x100))
1136 if (number_of_fds != 1)
1148 DBG_SOCK(
"if %d msg VHOST_USER_SET_VRING_BASE idx %d num %d",
1155 DBG_SOCK(
"if %d msg VHOST_USER_GET_VRING_BASE idx %d num %d",
1159 msg.size =
sizeof(msg.state);
1165 DBG_SOCK(
"if %d msg VHOST_USER_NONE",
1170 #if RTE_VERSION >= RTE_VERSION_NUM(16, 4, 0, 0) 1171 DBG_SOCK(
"if %d msg VHOST_USER_SET_LOG_BASE",
1174 if (msg.size !=
sizeof(msg.log)) {
1175 DBG_SOCK(
"invalid msg size for VHOST_USER_SET_LOG_BASE: %u instead of %lu",
1176 msg.size,
sizeof(msg.log));
1181 DBG_SOCK(
"VHOST_USER_PROTOCOL_F_LOG_SHMFD not set but VHOST_USER_SET_LOG_BASE received");
1188 ssize_t map_sz = (msg.log.size + msg.log.offset + page_sz) & ~(page_sz - 1);
1190 void *
addr = mmap(0, map_sz, PROT_READ | PROT_WRITE,
1193 DBG_SOCK(
"map log region addr 0 len 0x%lx off 0x%lx fd %d mapped %p",
1194 map_sz, msg.log.offset, fd, addr);
1196 if (addr == MAP_FAILED) {
1197 clib_warning(
"failed to map memory. errno is %d", errno);
1204 msg.size =
sizeof(msg.u64);
1206 DBG_SOCK(
"if %d msg VHOST_USER_SET_LOG_BASE Not-Implemented",
1212 DBG_SOCK(
"if %d msg VHOST_USER_SET_LOG_FD",
1216 #if RTE_VERSION >= RTE_VERSION_NUM(2, 2, 0, 0) 1218 DBG_SOCK(
"if %d msg VHOST_USER_GET_PROTOCOL_FEATURES",
1224 msg.size =
sizeof(msg.u64);
1228 DBG_SOCK(
"if %d msg VHOST_USER_SET_PROTOCOL_FEATURES",
1231 DBG_SOCK(
"VHOST_USER_SET_PROTOCOL_FEATURES: 0x%lx",
1238 DBG_SOCK(
"%d VPP VHOST_USER_SET_VRING_ENABLE IDX: %d, Enable: %d",
1245 DBG_SOCK(
"if %d msg VHOST_USER_GET_QUEUE_NUM:",
1250 msg.size =
sizeof(msg.u64);
1255 DBG_SOCK(
"unknown vhost-user message %d received. closing socket",
1296 DBG_SOCK (
"FD %d doesn't belong to any interface",
1309 int client_fd, client_len;
1310 struct sockaddr_un client;
1320 DBG_SOCK (
"fd %d doesn't belong to any interface",
1329 client_len =
sizeof(client);
1331 (
struct sockaddr *)&client,
1332 (socklen_t *)&client_len);
1339 template.file_descriptor = client_fd;
1353 struct sockaddr_un un;
1356 fd = socket(AF_UNIX, SOCK_STREAM, 0);
1359 return VNET_API_ERROR_SYSCALL_ERROR_1;
1362 un.sun_family = AF_UNIX;
1363 strcpy((
char *) un.sun_path, (
char *) sock_filename);
1366 unlink( (
char *) sock_filename);
1368 len = strlen((
char *) un.sun_path) + strlen((
char *) sock_filename);
1370 if (bind(fd, (
struct sockaddr *) &un, len) == -1) {
1371 rv = VNET_API_ERROR_SYSCALL_ERROR_2;
1375 if (listen(fd, 1) == -1) {
1376 rv = VNET_API_ERROR_SYSCALL_ERROR_3;
1382 template.file_descriptor = fd;
1397 const char * sock_filename,
1401 u8 renumber,
u32 custom_dev_instance,
1413 sw_if_index, feature_mask, renumber, custom_dev_instance, hwaddr);
1430 DBG_SOCK(
"dpdk vhost-user interface created hw_if_index %d", hw_if_idx);
1436 feature_mask, sw_if_index);
1443 const char * sock_filename,
1447 u8 renumber,
u32 custom_dev_instance)
1459 sw_if_index, feature_mask, renumber, custom_dev_instance);
1465 return VNET_API_ERROR_INVALID_SW_IF_INDEX;
1481 feature_mask, &sw_if_idx);
1508 return VNET_API_ERROR_INVALID_SW_IF_INDEX;
1520 DBG_SOCK (
"deleted (deactivated) vhost-user interface sw_if_index %d", sw_if_index);
1531 struct virtio_net * vhost_dev;
1534 u32 * hw_if_indices = 0;
1553 for (i = 0; i <
vec_len (hw_if_indices); i++) {
1557 clib_warning(
"invalid vhost-user interface hw_if_index %d", hw_if_indices[i]);
1565 vhost_dev->virtqueue[0]->vhost_hlen : 0);
1570 vuid->
features = vhost_dev->features;
1572 vuid->
num_regions = (vhost_dev->mem !=
NULL ? vhost_dev->mem->nregions : 0);
1579 strncpy((
char *)vuid->
if_name, (
char *)s,
1587 *out_vuids = r_vuids;
1597 struct sockaddr_un sun;
1606 memset(state, 0,
sizeof(*state));
1607 state->
sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
1608 state->
sun.sun_family = AF_UNIX;
1631 strncpy(state->
sun.sun_path, (
char *) vui->
sock_filename,
sizeof(state->
sun.sun_path) - 1);
1633 if (connect(state->
sockfd, (
struct sockaddr *) &(state->
sun),
sizeof(
struct sockaddr_un)) == 0) {
1640 state->
sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
1649 socklen_t len =
sizeof (error);
1650 int retval = getsockopt(vui->
unix_fd, SOL_SOCKET, SO_ERROR, &error, &len);
1669 u8 * sock_filename =
NULL;
1672 u64 feature_mask = (
u64)~0;
1674 u32 custom_dev_instance = ~0;
1687 if (
unformat (line_input,
"socket %s", &sock_filename))
1689 else if (
unformat (line_input,
"server"))
1691 else if (
unformat (line_input,
"feature-mask 0x%llx", &feature_mask))
1695 else if (
unformat (line_input,
"renumber %d", &custom_dev_instance)) {
1705 if (sock_filename ==
NULL)
1709 is_server, &sw_if_index, feature_mask,
1710 renumber, custom_dev_instance, hw);
1717 .path =
"create vhost-user",
1718 .short_help =
"create vhost-user socket <socket-filename> [server] [feature-mask <hex>] [renumber <dev_instance>]",
1730 u32 sw_if_index = ~0;
1741 if (
unformat (line_input,
"sw_if_index %d", &sw_if_index))
1749 if (sw_if_index == ~0) {
1763 .path =
"delete vhost-user",
1764 .short_help =
"delete vhost-user sw_if_index <nn>",
1768 #define foreach_dpdk_vhost_feature \ 1769 _ (VIRTIO_NET_F_MRG_RXBUF) \ 1770 _ (VIRTIO_NET_F_CTRL_VQ) \ 1771 _ (VIRTIO_NET_F_CTRL_RX) 1783 struct virtio_net * vhost_dev;
1784 u32 hw_if_index, * hw_if_indices = 0;
1788 struct virtio_memory * mem;
1789 struct feat_struct {
u8 bit;
char *str;};
1790 struct feat_struct *feat_entry;
1792 static struct feat_struct feat_array[] = {
1793 #define _(f) { .str = #f, .bit = f, }, 1805 vec_add1 (hw_if_indices, hw_if_index);
1816 if (vec_len (hw_if_indices) == 0) {
1827 for (i = 0; i <
vec_len (hw_if_indices); i++) {
1837 mem = vhost_dev->mem;
1839 vhost_dev->virtqueue[0]->vhost_hlen : 0);
1842 hi->
name, hw_if_indices[i]);
1847 feat_entry = (
struct feat_struct *) &feat_array;
1848 while(feat_entry->str) {
1849 if (xd->
vu_vhost_dev.features & (1 << feat_entry->bit))
1863 vlib_cli_output(vm,
" region fd guest_phys_addr memory_size userspace_addr mmap_offset mmap_addr\n");
1864 vlib_cli_output(vm,
" ====== ===== ================== ================== ================== ================== ==================\n");
1866 for (j = 0; j < mem->nregions; j++) {
1867 vlib_cli_output(vm,
" %d %-5d 0x%016lx 0x%016lx 0x%016lx 0x%016lx 0x%016lx\n", j,
1869 mem->regions[j].guest_phys_address,
1870 mem->regions[j].memory_size,
1871 mem->regions[j].userspace_address,
1872 mem->regions[j].address_offset,
1876 struct vhost_virtqueue *vq = vhost_dev->virtqueue[q];
1877 const char *qtype = (q & 1) ?
"TX" :
"RX";
1881 vlib_cli_output(vm,
" qsz %d last_used_idx %d last_used_idx_res %d\n",
1882 vq->size, vq->last_used_idx, vq->last_used_idx_res);
1884 if (vq->avail && vq->used)
1885 vlib_cli_output(vm,
" avail.flags %x avail.idx %d used.flags %x used.idx %d\n",
1886 vq->avail->flags, vq->avail->idx, vq->used->flags, vq->used->idx);
1888 #if RTE_VERSION >= RTE_VERSION_NUM(2, 2, 0, 0) 1890 vq->kickfd, vq->callfd, vui->
vrings[q].
errfd, vq->enabled);
1892 if (show_descr && vq->enabled) {
1901 vlib_cli_output(vm,
" ===== ================== ===== ====== ===== ==================\n");
1902 for(j = 0; j < vq->size; j++) {
1920 .path =
"show vhost-user",
1921 .short_help =
"show vhost-user interface",
unformat_function_t unformat_vnet_hw_interface
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
void dpdk_device_lock_free(dpdk_device_t *xd)
static clib_error_t * dpdk_vhost_user_socket_read(unix_file_t *uf)
static dpdk_device_t * dpdk_vhost_user_device_from_hw_if_index(u32 hw_if_index)
#define hash_set(h, key, value)
always_inline vlib_thread_main_t * vlib_get_thread_main()
sll srl srl sll sra u16x4 i
vlib_node_registration_t dpdk_io_input_node
(constructor) VLIB_REGISTER_NODE (dpdk_io_input_node)
clib_error_t * vnet_hw_interface_set_flags(vnet_main_t *vnm, u32 hw_if_index, u32 flags)
static void dpdk_vhost_user_vui_init(vnet_main_t *vnm, dpdk_device_t *xd, int sockfd, const char *sock_filename, u8 is_server, u64 feature_mask, u32 *sw_if_index)
u8 dpdk_vhost_user_want_interrupt(dpdk_device_t *xd, int idx)
unix_file_function_t * read_function
#define hash_unset(h, key)
u32 region_fd[VHOST_MEMORY_MAX_NREGIONS]
void ethernet_delete_interface(vnet_main_t *vnm, u32 hw_if_index)
vnet_device_class_t dpdk_device_class
static clib_error_t * dpdk_vhost_user_get_vring_base(u32 hw_if_index, u8 idx, u32 *num)
always_inline void clib_mem_free(void *p)
u32 vhost_coalesce_frames
#define vec_add2_aligned(V, P, N, A)
Add N elements to end of vector V, return pointer to new elements in P.
static clib_error_t * dpdk_vhost_user_socket_error(unix_file_t *uf)
static clib_error_t * dpdk_vhost_user_set_features(u32 hw_if_index, u64 features)
always_inline uword unix_file_add(unix_main_t *um, unix_file_t *template)
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
static clib_error_t * dpdk_vhost_user_callfd_read_ready(unix_file_t *uf)
int vnet_interface_name_renumber(u32 sw_if_index, u32 new_show_dev_instance)
struct virtio_net vu_vhost_dev
#define VHOST_USER_MSG_HDR_SZ
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
u32 per_interface_next_index
#define VHOST_USER_PROTOCOL_FEATURES
clib_error_t * show_vhost_user_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
static clib_error_t * dpdk_vhost_user_set_vring_call(u32 hw_if_index, u8 idx, int fd)
static clib_error_t * dpdk_vhost_user_set_vring_kick(u32 hw_if_index, u8 idx, int fd)
#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)
always_inline vlib_main_t * vlib_get_main(void)
#define VHOST_USER_REPLY_MASK
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
vnet_main_t * vnet_get_main(void)
struct rte_mbuf *** tx_vectors
static void dpdk_vhost_user_if_disconnect(dpdk_device_t *xd)
vlib_node_registration_t dpdk_input_node
(constructor) VLIB_REGISTER_NODE (dpdk_input_node)
dpdk_vu_vring vrings[VHOST_MAX_QUEUE_PAIRS *2]
int input_cpu_first_index
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
always_inline void vlib_node_set_state(vlib_main_t *vm, u32 node_index, vlib_node_state_t new_state)
static clib_error_t * dpdk_vhost_user_get_features(u32 hw_if_index, u64 *features)
#define foreach_dpdk_vhost_feature
#define clib_warning(format, args...)
static clib_error_t * dpdk_vhost_user_set_vring_num(u32 hw_if_index, u8 idx, u32 num)
always_inline u32 random_u32(u32 *seed)
32-bit random number generator
static uword pointer_to_uword(const void *p)
uword dpdk_vhost_user_process_if(vlib_main_t *vm, dpdk_device_t *xd, void *ctx)
#define pool_elt_at_index(p, i)
dpdk_device_and_queue_t ** devices_by_cpu
int vhost_user_delete_if(vnet_main_t *vnm, vlib_main_t *vm, u32 sw_if_index)
unix_file_function_t * error_function
static clib_error_t * dpdk_create_vhost_user_if_internal(u32 *hw_if_index, u32 if_id, u8 *hwaddr)
#define clib_error_return_unix(e, args...)
static void stop_processing_packets(u32 hw_if_index, u8 idx)
u32 main_thread_is_io_node
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)
#define uword_to_pointer(u, type)
static void disable_interface(dpdk_device_t *xd)
u64 region_addr[VHOST_MEMORY_MAX_NREGIONS]
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)
static int dpdk_vhost_user_set_vring_enable(u32 hw_if_index, u8 idx, int enable)
int dpdk_vhost_user_delete_if(vnet_main_t *vnm, vlib_main_t *vm, u32 sw_if_index)
always_inline void * clib_mem_alloc(uword size)
u16 * cpu_socket_id_by_queue
#define vec_free(V)
Free vector's memory (no header).
vhost_user_memory_region_t regions[VHOST_MEMORY_MAX_NREGIONS]
int dpdk_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)
struct rte_mbuf *** rx_vectors
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
static void dpdk_vhost_user_vui_register(vlib_main_t *vm, dpdk_device_t *xd)
static clib_error_t * dpdk_vhost_user_set_vring_base(u32 hw_if_index, u8 idx, u32 num)
static clib_error_t * dpdk_vhost_user_set_protocol_features(u32 hw_if_index, u64 prot_features)
static dpdk_device_t * dpdk_vhost_user_device_from_sw_if_index(u32 sw_if_index)
static clib_error_t * dpdk_vhost_user_connect_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
int dpdk_vhost_user_dump_ifs(vnet_main_t *vnm, vlib_main_t *vm, vhost_user_intf_details_t **out_vuids)
always_inline vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
static int dpdk_vhost_user_init_server_sock(const char *sock_filename, int *sockfd)
static clib_error_t * show_dpdk_vhost_user_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
#define VHOST_USER_PROTOCOL_F_LOG_SHMFD
#define vec_validate_ha(V, I, H, A)
Make sure vector is long enough for given index (general version).
#define VLIB_CLI_COMMAND(x,...)
vlib_worker_thread_t * vlib_worker_threads
void dpdk_vhost_user_process_init(void **ctx)
always_inline void unix_file_del(unix_main_t *um, unix_file_t *f)
uword unformat_ethernet_address(unformat_input_t *input, va_list *args)
#define DPDK_TX_RING_SIZE
void vlib_worker_thread_barrier_sync(vlib_main_t *vm)
u32 * vu_inactive_interfaces_device_index
void dpdk_vhost_user_send_interrupt(vlib_main_t *vm, dpdk_device_t *xd, int idx)
vhost_vring_state_t state
clib_error_t * vhost_user_delete_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
void dpdk_device_lock_init(dpdk_device_t *xd)
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)
void vlib_worker_thread_barrier_release(vlib_main_t *vm)
static void * map_guest_mem(dpdk_device_t *xd, u64 addr)
static long get_huge_page_size(int fd)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
dpdk_device_type_t dev_type
static const char * vhost_message_str[]
always_inline vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
#define VHOST_NET_VRING_IDX_RX
static clib_error_t * dpdk_vhost_user_set_mem_table(u32 hw_if_index, vhost_user_memory_t *vum, int fd[])
void dpdk_vhost_user_process_cleanup(void *ctx)
#define VHOST_USER_F_PROTOCOL_FEATURES
#define VHOST_NET_VRING_IDX_TX
vnet_sw_interface_type_t type
static clib_error_t * dpdk_vhost_user_socksvr_accept_ready(unix_file_t *uf)
#define vec_foreach(var, vec)
Vector iterator.
always_inline f64 vlib_time_now(vlib_main_t *vm)
static uint64_t qva_to_vva(struct virtio_net *dev, uint64_t qemu_va)
static clib_error_t * dpdk_vhost_user_set_vring_addr(u32 hw_if_index, u8 idx, u64 desc, u64 used, u64 avail, u64 log)
#define clib_error_return(e, args...)
#define CLIB_CACHE_LINE_BYTES
int dpdk_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)
static clib_error_t * dpdk_vhost_user_delete_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
clib_error_t * vhost_user_connect_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
vlib_main_t ** vlib_mains
#define DBG_SOCK(args...)
uword * vu_sw_if_index_by_listener_fd
CLIB vectors are ubiquitous dynamically resized arrays with by user defined "headers".
always_inline vnet_sw_interface_t * vnet_get_hw_sw_interface(vnet_main_t *vnm, u32 hw_if_index)
uword * vu_sw_if_index_by_sock_fd