This patch continues the effort to decouple the generic vhost layer
from specific network backend implementations.

Previously, the vhost_net initialization code contained a hardcoded
check for the vhost-user client type to retrieve its acked features
by calling vhost_user_get_acked_features(). This exposed an
internal vhost-user function in a public header and coupled the two
modules.

Following the pattern of recent commits, this patch introduces a
generic helper, qemu_get_acked_features(), and a corresponding
get_acked_features callback in the NetClientInfo struct.

The vhost-user backend is updated to provide this callback, and its
getter function is now static. The call site in vhost_net.c is
simplified to use the new generic helper, removing the type check and
the direct dependency.

Signed-off-by: Laurent Vivier <lviv...@redhat.com>
---
 hw/net/vhost_net.c       | 18 +++++++-----------
 include/net/net.h        |  4 ++++
 include/net/vhost-user.h |  2 --
 net/net.c                | 10 ++++++++++
 net/vhost-user.c         |  3 ++-
 5 files changed, 23 insertions(+), 14 deletions(-)

diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index 3dff819d2dbd..9cfe41b40b41 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -245,8 +245,8 @@ struct vhost_net *vhost_net_init(VhostNetOptions *options)
     int r;
     bool backend_kernel = options->backend_type == VHOST_BACKEND_TYPE_KERNEL;
     struct vhost_net *net = g_new0(struct vhost_net, 1);
-    uint64_t features = 0;
     Error *local_err = NULL;
+    uint64_t features;
 
     if (!options->net_backend) {
         fprintf(stderr, "vhost-net requires net backend to be setup\n");
@@ -297,17 +297,13 @@ struct vhost_net *vhost_net_init(VhostNetOptions *options)
     }
 
     /* Set sane init value. Override when guest acks. */
-#ifdef CONFIG_VHOST_NET_USER
-    if (net->nc->info->type == NET_CLIENT_DRIVER_VHOST_USER) {
-        features = vhost_user_get_acked_features(net->nc);
-        if (~net->dev.features & features) {
-            fprintf(stderr, "vhost lacks feature mask 0x%" PRIx64
-                    " for backend\n",
-                    (uint64_t)(~net->dev.features & features));
-            goto fail;
-        }
+    features = qemu_get_acked_features(net->nc);
+    if (~net->dev.features & features) {
+        fprintf(stderr, "vhost lacks feature mask 0x%" PRIx64
+                " for backend\n",
+                (uint64_t)(~net->dev.features & features));
+        goto fail;
     }
-#endif
 
     vhost_net_ack_features(net, features);
 
diff --git a/include/net/net.h b/include/net/net.h
index dd11be11a39f..37dc97a06752 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -69,6 +69,7 @@ typedef bool (SetSteeringEBPF)(NetClientState *, int);
 typedef bool (NetCheckPeerType)(NetClientState *, ObjectClass *, Error **);
 typedef bool (IsVHostUser)(NetClientState *);
 typedef struct vhost_net *(GetVHostNet)(NetClientState *nc);
+typedef uint64_t (GetAckedFeatures)(NetClientState *nc);
 
 typedef struct NetClientInfo {
     NetClientDriver type;
@@ -97,6 +98,7 @@ typedef struct NetClientInfo {
     const int *vhost_feature_bits;
     IsVHostUser *is_vhost_user;
     GetVHostNet *get_vhost_net;
+    GetAckedFeatures *get_acked_features;
 } NetClientInfo;
 
 struct NetClientState {
@@ -198,6 +200,8 @@ int qemu_set_vnet_le(NetClientState *nc, bool is_le);
 int qemu_set_vnet_be(NetClientState *nc, bool is_be);
 bool qemu_is_vhost_user(NetClientState *nc);
 void qemu_macaddr_default_if_unset(MACAddr *macaddr);
+uint64_t qemu_get_acked_features(NetClientState *nc);
+
 /**
  * qemu_find_nic_info: Obtain NIC configuration information
  * @typename: Name of device object type
diff --git a/include/net/vhost-user.h b/include/net/vhost-user.h
index 0b233a267345..a4d0ce4b8dd1 100644
--- a/include/net/vhost-user.h
+++ b/include/net/vhost-user.h
@@ -11,8 +11,6 @@
 #ifndef VHOST_USER_H
 #define VHOST_USER_H
 
-struct vhost_net;
-uint64_t vhost_user_get_acked_features(NetClientState *nc);
 void vhost_user_save_acked_features(NetClientState *nc);
 
 #endif /* VHOST_USER_H */
diff --git a/net/net.c b/net/net.c
index 8726c59915a3..ba051441053f 100644
--- a/net/net.c
+++ b/net/net.c
@@ -608,6 +608,16 @@ int qemu_set_vnet_be(NetClientState *nc, bool is_be)
 #endif
 }
 
+uint64_t qemu_get_acked_features(NetClientState *nc)
+{
+    if (nc->info->get_acked_features) {
+        return nc->info->get_acked_features(nc);
+    }
+
+    return 0;
+}
+
+
 int qemu_can_receive_packet(NetClientState *nc)
 {
     if (nc->receive_disabled) {
diff --git a/net/vhost-user.c b/net/vhost-user.c
index d8fef801de5a..e590b39503de 100644
--- a/net/vhost-user.c
+++ b/net/vhost-user.c
@@ -81,7 +81,7 @@ static struct vhost_net 
*vhost_user_get_vhost_net(NetClientState *nc)
     return s->vhost_net;
 }
 
-uint64_t vhost_user_get_acked_features(NetClientState *nc)
+static uint64_t vhost_user_get_acked_features(NetClientState *nc)
 {
     NetVhostUserState *s = DO_UPCAST(NetVhostUserState, nc, nc);
     assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_USER);
@@ -283,6 +283,7 @@ static NetClientInfo net_vhost_user_info = {
         .is_vhost_user = vhost_user_is_vhost_user,
         .get_vhost_net = vhost_user_get_vhost_net,
         .vhost_feature_bits = user_feature_bits,
+        .get_acked_features = vhost_user_get_acked_features,
 };
 
 static gboolean net_vhost_user_watch(void *do_not_use, GIOCondition cond,
-- 
2.49.0


Reply via email to