Skip to content

Commit

Permalink
net/virtio-user: fix status management
Browse files Browse the repository at this point in the history
[ upstream commit d0131e4 ]

Apart from the virtio status, there should be also a network related
status for link status management, current implementation mixes up these
two statuses.

One issue caused by this mixup is when virtio-user running in server mode
and vhost as a client connects to it, a RARP packet will be generated by
virtio-user due to VIRTIO_NET_S_ANNOUNCE bit is detected in the "status"
in interrupt handler.

VIRTIO_NET_S_LINK_UP and VIRTIO_NET_S_ANNOUNCE should be managed by a
separated field. This patch adds a "net_status" field for this purpose.

Fixes: e9efa4d ("net/virtio-user: add new virtual PCI driver")

Signed-off-by: Adrian Moreno <amorenoz@redhat.com>
Signed-off-by: Xiao Wang <xiao.w.wang@intel.com>
Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
  • Loading branch information
XiaoWang1772 authored and kevintraynor committed Aug 28, 2020
1 parent 3eccb8b commit c47cbdd
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 5 deletions.
1 change: 1 addition & 0 deletions drivers/net/virtio/virtio_user/virtio_user_dev.h
Expand Up @@ -36,6 +36,7 @@ struct virtio_user_dev {
uint64_t frontend_features; /* enabled frontend features */
uint64_t unsupported_features; /* unsupported features mask */
uint8_t status;
uint16_t net_status;
uint16_t port_id;
uint8_t mac_addr[ETHER_ADDR_LEN];
char path[PATH_MAX];
Expand Down
10 changes: 5 additions & 5 deletions drivers/net/virtio/virtio_user_ethdev.c
Expand Up @@ -139,7 +139,7 @@ virtio_user_read_dev_config(struct virtio_hw *hw, size_t offset,
}
r = recv(dev->vhostfd, buf, 128, MSG_PEEK);
if (r == 0 || (r < 0 && errno != EAGAIN)) {
dev->status &= (~VIRTIO_NET_S_LINK_UP);
dev->net_status &= (~VIRTIO_NET_S_LINK_UP);
PMD_DRV_LOG(ERR, "virtio-user port %u is down",
hw->port_id);

Expand All @@ -151,20 +151,20 @@ virtio_user_read_dev_config(struct virtio_hw *hw, size_t offset,
virtio_user_delayed_handler,
(void *)hw);
} else {
dev->status |= VIRTIO_NET_S_LINK_UP;
dev->net_status |= VIRTIO_NET_S_LINK_UP;
}
if (fcntl(dev->vhostfd, F_SETFL,
flags & ~O_NONBLOCK) == -1) {
PMD_DRV_LOG(ERR, "error clearing O_NONBLOCK flag");
return;
}
} else if (dev->is_server) {
dev->status &= (~VIRTIO_NET_S_LINK_UP);
dev->net_status &= (~VIRTIO_NET_S_LINK_UP);
if (virtio_user_server_reconnect(dev) >= 0)
dev->status |= VIRTIO_NET_S_LINK_UP;
dev->net_status |= VIRTIO_NET_S_LINK_UP;
}

*(uint16_t *)dst = dev->status;
*(uint16_t *)dst = dev->net_status;
}

if (offset == offsetof(struct virtio_net_config, max_virtqueue_pairs))
Expand Down

0 comments on commit c47cbdd

Please sign in to comment.