vhost-user: introduce vhost-user API
Add vhost_user.c and vhost_user.h that define the functions needed to implement vhost-user backend. Signed-off-by: Laurent Vivier <lvivier@redhat.com>
This commit is contained in:
parent
45b1403f42
commit
b2229bd24f
7 changed files with 1206 additions and 3 deletions
5
Makefile
5
Makefile
|
@ -47,7 +47,7 @@ FLAGS += -DDUAL_STACK_SOCKETS=$(DUAL_STACK_SOCKETS)
|
||||||
PASST_SRCS = arch.c arp.c checksum.c conf.c dhcp.c dhcpv6.c flow.c fwd.c \
|
PASST_SRCS = arch.c arp.c checksum.c conf.c dhcp.c dhcpv6.c flow.c fwd.c \
|
||||||
icmp.c igmp.c inany.c iov.c ip.c isolation.c lineread.c log.c mld.c \
|
icmp.c igmp.c inany.c iov.c ip.c isolation.c lineread.c log.c mld.c \
|
||||||
ndp.c netlink.c packet.c passt.c pasta.c pcap.c pif.c tap.c tcp.c \
|
ndp.c netlink.c packet.c passt.c pasta.c pcap.c pif.c tap.c tcp.c \
|
||||||
tcp_buf.c tcp_splice.c udp.c util.c virtio.c
|
tcp_buf.c tcp_splice.c udp.c util.c vhost_user.c virtio.c
|
||||||
QRAP_SRCS = qrap.c
|
QRAP_SRCS = qrap.c
|
||||||
SRCS = $(PASST_SRCS) $(QRAP_SRCS)
|
SRCS = $(PASST_SRCS) $(QRAP_SRCS)
|
||||||
|
|
||||||
|
@ -56,7 +56,8 @@ MANPAGES = passt.1 pasta.1 qrap.1
|
||||||
PASST_HEADERS = arch.h arp.h checksum.h conf.h dhcp.h dhcpv6.h flow.h fwd.h \
|
PASST_HEADERS = arch.h arp.h checksum.h conf.h dhcp.h dhcpv6.h flow.h fwd.h \
|
||||||
flow_table.h icmp.h inany.h iov.h ip.h isolation.h lineread.h log.h \
|
flow_table.h icmp.h inany.h iov.h ip.h isolation.h lineread.h log.h \
|
||||||
ndp.h netlink.h packet.h passt.h pasta.h pcap.h pif.h siphash.h tap.h \
|
ndp.h netlink.h packet.h passt.h pasta.h pcap.h pif.h siphash.h tap.h \
|
||||||
tcp.h tcp_buf.h tcp_conn.h tcp_splice.h udp.h util.h virtio.h
|
tcp.h tcp_buf.h tcp_conn.h tcp_splice.h udp.h util.h vhost_user.h \
|
||||||
|
virtio.h
|
||||||
HEADERS = $(PASST_HEADERS) seccomp.h
|
HEADERS = $(PASST_HEADERS) seccomp.h
|
||||||
|
|
||||||
C := \#include <linux/tcp.h>\nstruct tcp_info x = { .tcpi_snd_wnd = 0 };
|
C := \#include <linux/tcp.h>\nstruct tcp_info x = { .tcpi_snd_wnd = 0 };
|
||||||
|
|
2
passt.c
2
passt.c
|
@ -73,6 +73,8 @@ char *epoll_type_str[] = {
|
||||||
[EPOLL_TYPE_TAP_PASTA] = "/dev/net/tun device",
|
[EPOLL_TYPE_TAP_PASTA] = "/dev/net/tun device",
|
||||||
[EPOLL_TYPE_TAP_PASST] = "connected qemu socket",
|
[EPOLL_TYPE_TAP_PASST] = "connected qemu socket",
|
||||||
[EPOLL_TYPE_TAP_LISTEN] = "listening qemu socket",
|
[EPOLL_TYPE_TAP_LISTEN] = "listening qemu socket",
|
||||||
|
[EPOLL_TYPE_VHOST_CMD] = "vhost-user command socket",
|
||||||
|
[EPOLL_TYPE_VHOST_KICK] = "vhost-user kick socket",
|
||||||
};
|
};
|
||||||
static_assert(ARRAY_SIZE(epoll_type_str) == EPOLL_NUM_TYPES,
|
static_assert(ARRAY_SIZE(epoll_type_str) == EPOLL_NUM_TYPES,
|
||||||
"epoll_type_str[] doesn't match enum epoll_type");
|
"epoll_type_str[] doesn't match enum epoll_type");
|
||||||
|
|
8
passt.h
8
passt.h
|
@ -42,6 +42,7 @@ union epoll_ref;
|
||||||
#include "fwd.h"
|
#include "fwd.h"
|
||||||
#include "tcp.h"
|
#include "tcp.h"
|
||||||
#include "udp.h"
|
#include "udp.h"
|
||||||
|
#include "vhost_user.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* enum epoll_type - Different types of fds we poll over
|
* enum epoll_type - Different types of fds we poll over
|
||||||
|
@ -73,6 +74,10 @@ enum epoll_type {
|
||||||
EPOLL_TYPE_TAP_PASST,
|
EPOLL_TYPE_TAP_PASST,
|
||||||
/* socket listening for qemu socket connections */
|
/* socket listening for qemu socket connections */
|
||||||
EPOLL_TYPE_TAP_LISTEN,
|
EPOLL_TYPE_TAP_LISTEN,
|
||||||
|
/* vhost-user command socket */
|
||||||
|
EPOLL_TYPE_VHOST_CMD,
|
||||||
|
/* vhost-user kick event socket */
|
||||||
|
EPOLL_TYPE_VHOST_KICK,
|
||||||
|
|
||||||
EPOLL_NUM_TYPES,
|
EPOLL_NUM_TYPES,
|
||||||
};
|
};
|
||||||
|
@ -307,6 +312,9 @@ struct ctx {
|
||||||
|
|
||||||
int low_wmem;
|
int low_wmem;
|
||||||
int low_rmem;
|
int low_rmem;
|
||||||
|
|
||||||
|
/* vhost-user */
|
||||||
|
struct VuDev vdev;
|
||||||
};
|
};
|
||||||
|
|
||||||
void proto_update_l2_buf(const unsigned char *eth_d,
|
void proto_update_l2_buf(const unsigned char *eth_d,
|
||||||
|
|
2
tap.c
2
tap.c
|
@ -1054,7 +1054,7 @@ void packet_add_all_do(struct ctx *c, ssize_t len, char *p,
|
||||||
* tap_sock_reset() - Handle closing or failure of connect AF_UNIX socket
|
* tap_sock_reset() - Handle closing or failure of connect AF_UNIX socket
|
||||||
* @c: Execution context
|
* @c: Execution context
|
||||||
*/
|
*/
|
||||||
static void tap_sock_reset(struct ctx *c)
|
void tap_sock_reset(struct ctx *c)
|
||||||
{
|
{
|
||||||
if (c->one_off) {
|
if (c->one_off) {
|
||||||
info("Client closed connection, exiting");
|
info("Client closed connection, exiting");
|
||||||
|
|
3
tap.h
3
tap.h
|
@ -97,12 +97,15 @@ void tap_handler_pasta(struct ctx *c, uint32_t events,
|
||||||
const struct timespec *now);
|
const struct timespec *now);
|
||||||
void tap_handler_passt(struct ctx *c, uint32_t events,
|
void tap_handler_passt(struct ctx *c, uint32_t events,
|
||||||
const struct timespec *now);
|
const struct timespec *now);
|
||||||
|
void tap_sock_reset(struct ctx *c);
|
||||||
void tap_sock_init(struct ctx *c);
|
void tap_sock_init(struct ctx *c);
|
||||||
void pool_flush_all(void);
|
void pool_flush_all(void);
|
||||||
void tap_handler_all(struct ctx *c, const struct timespec *now);
|
void tap_handler_all(struct ctx *c, const struct timespec *now);
|
||||||
|
|
||||||
void packet_add_do(struct pool *p, size_t len, const char *start,
|
void packet_add_do(struct pool *p, size_t len, const char *start,
|
||||||
const char *func, int line);
|
const char *func, int line);
|
||||||
|
void packet_add_all_do(struct ctx *c, ssize_t len, char *p,
|
||||||
|
const char *func, int line);
|
||||||
#define packet_add_all(p, len, start) \
|
#define packet_add_all(p, len, start) \
|
||||||
packet_add_all_do(p, len, start, __func__, __LINE__)
|
packet_add_all_do(p, len, start, __func__, __LINE__)
|
||||||
|
|
||||||
|
|
1050
vhost_user.c
Normal file
1050
vhost_user.c
Normal file
File diff suppressed because it is too large
Load diff
139
vhost_user.h
Normal file
139
vhost_user.h
Normal file
|
@ -0,0 +1,139 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
/* some parts from subprojects/libvhost-user/libvhost-user.h */
|
||||||
|
|
||||||
|
#ifndef VHOST_USER_H
|
||||||
|
#define VHOST_USER_H
|
||||||
|
|
||||||
|
#include "virtio.h"
|
||||||
|
#include "iov.h"
|
||||||
|
|
||||||
|
#define VHOST_USER_F_PROTOCOL_FEATURES 30
|
||||||
|
|
||||||
|
#define VHOST_MEMORY_BASELINE_NREGIONS 8
|
||||||
|
|
||||||
|
enum vhost_user_protocol_feature {
|
||||||
|
VHOST_USER_PROTOCOL_F_MQ = 0,
|
||||||
|
VHOST_USER_PROTOCOL_F_LOG_SHMFD = 1,
|
||||||
|
VHOST_USER_PROTOCOL_F_RARP = 2,
|
||||||
|
VHOST_USER_PROTOCOL_F_REPLY_ACK = 3,
|
||||||
|
VHOST_USER_PROTOCOL_F_NET_MTU = 4,
|
||||||
|
VHOST_USER_PROTOCOL_F_BACKEND_REQ = 5,
|
||||||
|
VHOST_USER_PROTOCOL_F_CROSS_ENDIAN = 6,
|
||||||
|
VHOST_USER_PROTOCOL_F_CRYPTO_SESSION = 7,
|
||||||
|
VHOST_USER_PROTOCOL_F_PAGEFAULT = 8,
|
||||||
|
VHOST_USER_PROTOCOL_F_CONFIG = 9,
|
||||||
|
VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD = 10,
|
||||||
|
VHOST_USER_PROTOCOL_F_HOST_NOTIFIER = 11,
|
||||||
|
VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD = 12,
|
||||||
|
VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS = 14,
|
||||||
|
VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS = 15,
|
||||||
|
|
||||||
|
VHOST_USER_PROTOCOL_F_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
enum vhost_user_request {
|
||||||
|
VHOST_USER_NONE = 0,
|
||||||
|
VHOST_USER_GET_FEATURES = 1,
|
||||||
|
VHOST_USER_SET_FEATURES = 2,
|
||||||
|
VHOST_USER_SET_OWNER = 3,
|
||||||
|
VHOST_USER_RESET_OWNER = 4,
|
||||||
|
VHOST_USER_SET_MEM_TABLE = 5,
|
||||||
|
VHOST_USER_SET_LOG_BASE = 6,
|
||||||
|
VHOST_USER_SET_LOG_FD = 7,
|
||||||
|
VHOST_USER_SET_VRING_NUM = 8,
|
||||||
|
VHOST_USER_SET_VRING_ADDR = 9,
|
||||||
|
VHOST_USER_SET_VRING_BASE = 10,
|
||||||
|
VHOST_USER_GET_VRING_BASE = 11,
|
||||||
|
VHOST_USER_SET_VRING_KICK = 12,
|
||||||
|
VHOST_USER_SET_VRING_CALL = 13,
|
||||||
|
VHOST_USER_SET_VRING_ERR = 14,
|
||||||
|
VHOST_USER_GET_PROTOCOL_FEATURES = 15,
|
||||||
|
VHOST_USER_SET_PROTOCOL_FEATURES = 16,
|
||||||
|
VHOST_USER_GET_QUEUE_NUM = 17,
|
||||||
|
VHOST_USER_SET_VRING_ENABLE = 18,
|
||||||
|
VHOST_USER_SEND_RARP = 19,
|
||||||
|
VHOST_USER_NET_SET_MTU = 20,
|
||||||
|
VHOST_USER_SET_BACKEND_REQ_FD = 21,
|
||||||
|
VHOST_USER_IOTLB_MSG = 22,
|
||||||
|
VHOST_USER_SET_VRING_ENDIAN = 23,
|
||||||
|
VHOST_USER_GET_CONFIG = 24,
|
||||||
|
VHOST_USER_SET_CONFIG = 25,
|
||||||
|
VHOST_USER_CREATE_CRYPTO_SESSION = 26,
|
||||||
|
VHOST_USER_CLOSE_CRYPTO_SESSION = 27,
|
||||||
|
VHOST_USER_POSTCOPY_ADVISE = 28,
|
||||||
|
VHOST_USER_POSTCOPY_LISTEN = 29,
|
||||||
|
VHOST_USER_POSTCOPY_END = 30,
|
||||||
|
VHOST_USER_GET_INFLIGHT_FD = 31,
|
||||||
|
VHOST_USER_SET_INFLIGHT_FD = 32,
|
||||||
|
VHOST_USER_GPU_SET_SOCKET = 33,
|
||||||
|
VHOST_USER_VRING_KICK = 35,
|
||||||
|
VHOST_USER_GET_MAX_MEM_SLOTS = 36,
|
||||||
|
VHOST_USER_ADD_MEM_REG = 37,
|
||||||
|
VHOST_USER_REM_MEM_REG = 38,
|
||||||
|
VHOST_USER_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
enum vhost_user_request request;
|
||||||
|
|
||||||
|
#define VHOST_USER_VERSION_MASK 0x3
|
||||||
|
#define VHOST_USER_REPLY_MASK (0x1 << 2)
|
||||||
|
#define VHOST_USER_NEED_REPLY_MASK (0x1 << 3)
|
||||||
|
uint32_t flags;
|
||||||
|
uint32_t size; /* the following payload size */
|
||||||
|
} __attribute__ ((__packed__)) vhost_user_header;
|
||||||
|
|
||||||
|
typedef struct VhostUserMemory_region {
|
||||||
|
uint64_t guest_phys_addr;
|
||||||
|
uint64_t memory_size;
|
||||||
|
uint64_t userspace_addr;
|
||||||
|
uint64_t mmap_offset;
|
||||||
|
} VhostUserMemory_region;
|
||||||
|
|
||||||
|
struct VhostUserMemory {
|
||||||
|
uint32_t nregions;
|
||||||
|
uint32_t padding;
|
||||||
|
struct VhostUserMemory_region regions[VHOST_MEMORY_BASELINE_NREGIONS];
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
#define VHOST_USER_VRING_IDX_MASK 0xff
|
||||||
|
#define VHOST_USER_VRING_NOFD_MASK (0x1 << 8)
|
||||||
|
uint64_t u64;
|
||||||
|
struct vhost_vring_state state;
|
||||||
|
struct vhost_vring_addr addr;
|
||||||
|
struct VhostUserMemory memory;
|
||||||
|
} vhost_user_payload;
|
||||||
|
|
||||||
|
typedef struct VhostUserMsg {
|
||||||
|
vhost_user_header hdr;
|
||||||
|
vhost_user_payload payload;
|
||||||
|
|
||||||
|
int fds[VHOST_MEMORY_BASELINE_NREGIONS];
|
||||||
|
int fd_num;
|
||||||
|
uint8_t *data;
|
||||||
|
} __attribute__ ((__packed__)) VhostUserMsg;
|
||||||
|
#define VHOST_USER_HDR_SIZE sizeof(vhost_user_header)
|
||||||
|
|
||||||
|
#define VHOST_USER_RX_QUEUE 0
|
||||||
|
#define VHOST_USER_TX_QUEUE 1
|
||||||
|
|
||||||
|
static inline bool vu_queue_enabled(VuVirtq *vq)
|
||||||
|
{
|
||||||
|
return vq->enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool vu_queue_started(const VuVirtq *vq)
|
||||||
|
{
|
||||||
|
return vq->started;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t tap_send_frames_vu(const struct ctx *c, const struct iovec *iov,
|
||||||
|
size_t n);
|
||||||
|
int vu_send(const struct ctx *c, const void *data, size_t len);
|
||||||
|
void vu_print_capabilities(void);
|
||||||
|
void vu_init(struct ctx *c);
|
||||||
|
void vu_kick_cb(struct ctx *c, union epoll_ref ref);
|
||||||
|
void tap_handler_vu(struct ctx *c, uint32_t events);
|
||||||
|
#endif /* VHOST_USER_H */
|
Loading…
Reference in a new issue