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: e9efa4d93821 ("net/virtio-user: add new virtual PCI driver")
Cc: sta...@dpdk.org

Signed-off-by: Xiao Wang <xiao.w.w...@intel.com>
---
 drivers/net/virtio/virtio_user/virtio_user_dev.h |  1 +
 drivers/net/virtio/virtio_user_ethdev.c          | 10 +++++-----
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.h 
b/drivers/net/virtio/virtio_user/virtio_user_dev.h
index 56e638f8a..554174e81 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.h
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.h
@@ -44,6 +44,7 @@ struct virtio_user_dev {
                                            * (Vhost-user only)
                                            */
        uint8_t         status;
+       uint16_t        net_status;
        uint16_t        port_id;
        uint8_t         mac_addr[RTE_ETHER_ADDR_LEN];
        char            path[PATH_MAX];
diff --git a/drivers/net/virtio/virtio_user_ethdev.c 
b/drivers/net/virtio/virtio_user_ethdev.c
index e51425c4f..6003f6d50 100644
--- a/drivers/net/virtio/virtio_user_ethdev.c
+++ b/drivers/net/virtio/virtio_user_ethdev.c
@@ -205,7 +205,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);
 
@@ -217,7 +217,7 @@ 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) {
@@ -225,12 +225,12 @@ virtio_user_read_dev_config(struct virtio_hw *hw, size_t 
offset,
                                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))
-- 
2.15.1

Reply via email to