static void vserver_new_vq_conn(int fd, void *data, int *remove);
static void vserver_message_handler(int fd, void *dat, int *remove);
-struct vhost_net_device_ops const *ops;
struct connfd_ctx {
struct vhost_server *vserver;
- uint32_t fh;
+ int vid;
};
#define MAX_VHOST_SERVER 1024
[VHOST_USER_GET_VRING_BASE] = "VHOST_USER_GET_VRING_BASE",
[VHOST_USER_SET_VRING_KICK] = "VHOST_USER_SET_VRING_KICK",
[VHOST_USER_SET_VRING_CALL] = "VHOST_USER_SET_VRING_CALL",
- [VHOST_USER_SET_VRING_ERR] = "VHOST_USER_SET_VRING_ERR"
+ [VHOST_USER_SET_VRING_ERR] = "VHOST_USER_SET_VRING_ERR",
+ [VHOST_USER_GET_PROTOCOL_FEATURES] = "VHOST_USER_GET_PROTOCOL_FEATURES",
+ [VHOST_USER_SET_PROTOCOL_FEATURES] = "VHOST_USER_SET_PROTOCOL_FEATURES",
+ [VHOST_USER_GET_QUEUE_NUM] = "VHOST_USER_GET_QUEUE_NUM",
+ [VHOST_USER_SET_VRING_ENABLE] = "VHOST_USER_SET_VRING_ENABLE",
+ [VHOST_USER_SEND_RARP] = "VHOST_USER_SEND_RARP",
};
/**
un.sun_family = AF_UNIX;
snprintf(un.sun_path, sizeof(un.sun_path), "%s", path);
ret = bind(sockfd, (struct sockaddr *)&un, sizeof(un));
- if (ret == -1)
+ if (ret == -1) {
+ RTE_LOG(ERR, VHOST_CONFIG, "fail to bind fd:%d, remove file:%s and try again.\n",
+ sockfd, path);
goto err;
+ }
RTE_LOG(INFO, VHOST_CONFIG, "bind to %s\n", path);
ret = listen(sockfd, MAX_VIRTIO_BACKLOG);
struct vhost_server *vserver = (struct vhost_server *)dat;
int conn_fd;
struct connfd_ctx *ctx;
- int fh;
- struct vhost_device_ctx vdev_ctx = { (pid_t)0, 0 };
+ int vid;
unsigned int size;
conn_fd = accept(fd, NULL, NULL);
return;
}
- fh = ops->new_device(vdev_ctx);
- if (fh == -1) {
+ vid = vhost_new_device();
+ if (vid == -1) {
free(ctx);
close(conn_fd);
return;
}
- vdev_ctx.fh = fh;
size = strnlen(vserver->path, PATH_MAX);
- ops->set_ifname(vdev_ctx, vserver->path,
- size);
+ vhost_set_ifname(vid, vserver->path, size);
- RTE_LOG(INFO, VHOST_CONFIG, "new device, handle is %d\n", fh);
+ RTE_LOG(INFO, VHOST_CONFIG, "new device, handle is %d\n", vid);
ctx->vserver = vserver;
- ctx->fh = fh;
+ ctx->vid = vid;
fdset_add(&g_vhost_server.fdset,
conn_fd, vserver_message_handler, NULL, ctx);
}
static void
vserver_message_handler(int connfd, void *dat, int *remove)
{
- struct vhost_device_ctx ctx;
+ int vid;
struct connfd_ctx *cfd_ctx = (struct connfd_ctx *)dat;
struct VhostUserMsg msg;
uint64_t features;
int ret;
- ctx.fh = cfd_ctx->fh;
+ vid = cfd_ctx->vid;
ret = read_vhost_message(connfd, &msg);
- if (ret < 0) {
- RTE_LOG(ERR, VHOST_CONFIG,
- "vhost read message failed\n");
-
- close(connfd);
- *remove = 1;
- free(cfd_ctx);
- user_destroy_device(ctx);
- ops->destroy_device(ctx);
-
- return;
- } else if (ret == 0) {
- RTE_LOG(INFO, VHOST_CONFIG,
- "vhost peer closed\n");
-
- close(connfd);
- *remove = 1;
- free(cfd_ctx);
- user_destroy_device(ctx);
- ops->destroy_device(ctx);
-
- return;
- }
- if (msg.request > VHOST_USER_MAX) {
- RTE_LOG(ERR, VHOST_CONFIG,
- "vhost read incorrect message\n");
+ if (ret <= 0 || msg.request >= VHOST_USER_MAX) {
+ if (ret < 0)
+ RTE_LOG(ERR, VHOST_CONFIG,
+ "vhost read message failed\n");
+ else if (ret == 0)
+ RTE_LOG(INFO, VHOST_CONFIG,
+ "vhost peer closed\n");
+ else
+ RTE_LOG(ERR, VHOST_CONFIG,
+ "vhost read incorrect message\n");
close(connfd);
*remove = 1;
free(cfd_ctx);
- user_destroy_device(ctx);
- ops->destroy_device(ctx);
+ vhost_destroy_device(vid);
return;
}
vhost_message_str[msg.request]);
switch (msg.request) {
case VHOST_USER_GET_FEATURES:
- ret = ops->get_features(ctx, &features);
+ ret = vhost_get_features(vid, &features);
msg.payload.u64 = features;
msg.size = sizeof(msg.payload.u64);
send_vhost_message(connfd, &msg);
break;
case VHOST_USER_SET_FEATURES:
features = msg.payload.u64;
- ops->set_features(ctx, &features);
+ vhost_set_features(vid, &features);
+ break;
+
+ case VHOST_USER_GET_PROTOCOL_FEATURES:
+ msg.payload.u64 = VHOST_USER_PROTOCOL_FEATURES;
+ msg.size = sizeof(msg.payload.u64);
+ send_vhost_message(connfd, &msg);
+ break;
+ case VHOST_USER_SET_PROTOCOL_FEATURES:
+ user_set_protocol_features(vid, msg.payload.u64);
break;
case VHOST_USER_SET_OWNER:
- ops->set_owner(ctx);
+ vhost_set_owner(vid);
break;
case VHOST_USER_RESET_OWNER:
- ops->reset_owner(ctx);
+ vhost_reset_owner(vid);
break;
case VHOST_USER_SET_MEM_TABLE:
- user_set_mem_table(ctx, &msg);
+ user_set_mem_table(vid, &msg);
break;
case VHOST_USER_SET_LOG_BASE:
- RTE_LOG(INFO, VHOST_CONFIG, "not implemented.\n");
+ user_set_log_base(vid, &msg);
+
+ /* it needs a reply */
+ msg.size = sizeof(msg.payload.u64);
+ send_vhost_message(connfd, &msg);
+ break;
case VHOST_USER_SET_LOG_FD:
close(msg.fds[0]);
RTE_LOG(INFO, VHOST_CONFIG, "not implemented.\n");
break;
case VHOST_USER_SET_VRING_NUM:
- ops->set_vring_num(ctx, &msg.payload.state);
+ vhost_set_vring_num(vid, &msg.payload.state);
break;
case VHOST_USER_SET_VRING_ADDR:
- ops->set_vring_addr(ctx, &msg.payload.addr);
+ vhost_set_vring_addr(vid, &msg.payload.addr);
break;
case VHOST_USER_SET_VRING_BASE:
- ops->set_vring_base(ctx, &msg.payload.state);
+ vhost_set_vring_base(vid, &msg.payload.state);
break;
case VHOST_USER_GET_VRING_BASE:
- ret = user_get_vring_base(ctx, &msg.payload.state);
+ ret = user_get_vring_base(vid, &msg.payload.state);
msg.size = sizeof(msg.payload.state);
send_vhost_message(connfd, &msg);
break;
case VHOST_USER_SET_VRING_KICK:
- user_set_vring_kick(ctx, &msg);
+ user_set_vring_kick(vid, &msg);
break;
case VHOST_USER_SET_VRING_CALL:
- user_set_vring_call(ctx, &msg);
+ user_set_vring_call(vid, &msg);
break;
case VHOST_USER_SET_VRING_ERR:
RTE_LOG(INFO, VHOST_CONFIG, "not implemented\n");
break;
+ case VHOST_USER_GET_QUEUE_NUM:
+ msg.payload.u64 = VHOST_MAX_QUEUE_PAIRS;
+ msg.size = sizeof(msg.payload.u64);
+ send_vhost_message(connfd, &msg);
+ break;
+
+ case VHOST_USER_SET_VRING_ENABLE:
+ user_set_vring_enable(vid, &msg.payload.state);
+ break;
+ case VHOST_USER_SEND_RARP:
+ user_send_rarp(vid, &msg);
+ break;
+
default:
break;
struct vhost_server *vserver;
pthread_mutex_lock(&g_vhost_server.server_mutex);
- if (ops == NULL)
- ops = get_virtio_net_callbacks();
if (g_vhost_server.vserver_cnt == MAX_VHOST_SERVER) {
RTE_LOG(ERR, VHOST_CONFIG,