To implement in future backend-transfer migration for virtio-net,
i.e. we are going to migrate TAP fd and some other TAP properties,
we'll need a possibility to postpone opening TAP device until the
point where we are know what user wants: open TAP device, or wait
from fd coming in migration stream.
So, new interface is here: since this commit, net backends may
postpone some initialization actions (like opening or connecting)
up to call of .backend_connect() handler.
Currently, for all net drivers, .backend_connect() is called
during set of netdev property, so drivers continue to work with
already "connected" backends.
Still, we add a possibility for drivers to use new
DEFINE_NIC_PROPERTIES_NO_CONNECT() instead of
DEFINE_NIC_PROPERTIES(). This way, driver take responsibility
to call net_backend_connect() in its own. So, in future we'll
use it in vritio-net, to finally implement backand-transfer
migration fot TAP backend.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---
hw/core/qdev-properties-system.c | 29 +++++++++++++++++++++++++++--
include/hw/qdev-properties-system.h | 2 ++
include/net/net.h | 6 ++++++
net/net.c | 15 +++++++++++++++
4 files changed, 50 insertions(+), 2 deletions(-)
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index 13cc91680b..0b2668a45f 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -415,8 +415,8 @@ static void get_netdev(Object *obj, Visitor *v, const char *name,
g_free(p);
}
-static void set_netdev(Object *obj, Visitor *v, const char *name,
- void *opaque, Error **errp)
+static void do_set_netdev(Object *obj, Visitor *v, const char *name,
+ void *opaque, bool connect, Error **errp)
{
const Property *prop = opaque;
NICPeers *peers_ptr = object_field_prop_ptr(obj, prop);
@@ -463,6 +463,12 @@ static void set_netdev(Object *obj, Visitor *v, const char *name,
}
}
+ if (connect) {
+ if (!net_backend_connect(peers[i], errp)) {
+ goto out;
+ }
+ }
+
ncs[i] = peers[i];
ncs[i]->queue_index = i;
}
@@ -474,6 +480,18 @@ out:
g_free(str);
}
+static void set_netdev(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ return do_set_netdev(obj, v, name, opaque, true, errp);
+}
+
+static void set_netdev_no_connect(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ return do_set_netdev(obj, v, name, opaque, false, errp);
+}
+
const PropertyInfo qdev_prop_netdev = {
.type = "str",
.description = "ID of a netdev to use as a backend",
@@ -481,6 +499,13 @@ const PropertyInfo qdev_prop_netdev = {
.set = set_netdev,
};
+const PropertyInfo qdev_prop_netdev_no_connect = {
+ .type = "str",
+ .description = "ID of a netdev to use as a backend",
+ .get = get_netdev,
+ .set = set_netdev_no_connect,
+};
+
/* --- audiodev --- */
static void get_audiodev(Object *obj, Visitor *v, const char* name,
diff --git a/include/hw/qdev-properties-system.h b/include/hw/qdev-properties-system.h
index 5c6cc5eae8..f41b5edadc 100644
--- a/include/hw/qdev-properties-system.h
+++ b/include/hw/qdev-properties-system.h
@@ -41,6 +41,8 @@ extern const PropertyInfo qdev_prop_virtio_gpu_output_list;
DEFINE_PROP(_n, _s, _f, qdev_prop_chr, CharFrontend)
#define DEFINE_PROP_NETDEV(_n, _s, _f) \
DEFINE_PROP(_n, _s, _f, qdev_prop_netdev, NICPeers)
+#define DEFINE_PROP_NETDEV_NO_CONNECT(_n, _s, _f) \
+ DEFINE_PROP(_n, _s, _f, qdev_prop_netdev_no_connect, NICPeers)
#define DEFINE_PROP_DRIVE(_n, _s, _f) \
DEFINE_PROP(_n, _s, _f, qdev_prop_drive, BlockBackend *)
#define DEFINE_PROP_DRIVE_IOTHREAD(_n, _s, _f) \
diff --git a/include/net/net.h b/include/net/net.h
index 72b476ee1d..3aa67db57c 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -51,6 +51,9 @@ typedef struct NetOffloads {
DEFINE_PROP_MACADDR("mac", _state, _conf.macaddr), \
DEFINE_PROP_NETDEV("netdev", _state, _conf.peers)
+#define DEFINE_NIC_PROPERTIES_NO_CONNECT(_state, _conf) \
+ DEFINE_PROP_MACADDR("mac", _state, _conf.macaddr), \
+ DEFINE_PROP_NETDEV_NO_CONNECT("netdev", _state, _conf.peers)
/* Net clients */
@@ -82,6 +85,7 @@ typedef void (NetAnnounce)(NetClientState *);
typedef bool (SetSteeringEBPF)(NetClientState *, int);
typedef bool (NetCheckPeerType)(NetClientState *, ObjectClass *, Error **);
typedef struct vhost_net *(GetVHostNet)(NetClientState *nc);
+typedef bool (NetBackendConnect)(NetClientState *, Error **);
typedef struct NetClientInfo {
NetClientDriver type;
@@ -110,6 +114,7 @@ typedef struct NetClientInfo {
SetSteeringEBPF *set_steering_ebpf;
NetCheckPeerType *check_peer_type;
GetVHostNet *get_vhost_net;
+ NetBackendConnect *backend_connect;
} NetClientInfo;
struct NetClientState {
@@ -322,6 +327,7 @@ void net_cleanup(void);
void hmp_host_net_add(Monitor *mon, const QDict *qdict);
void hmp_host_net_remove(Monitor *mon, const QDict *qdict);
void netdev_add(QemuOpts *opts, Error **errp);
+bool net_backend_connect(NetClientState *nc, Error **errp);
int net_hub_id_for_client(NetClientState *nc, int *id);
diff --git a/net/net.c b/net/net.c
index 27e0d27807..4fc6b1d0a6 100644
--- a/net/net.c
+++ b/net/net.c
@@ -2162,3 +2162,18 @@ int net_fill_rstate(SocketReadState *rs, const uint8_t *buf, int size)
assert(size == 0);
return 0;
}
+
+bool net_backend_connect(NetClientState *nc, Error **errp)
+{
+ if (!nc->info->backend_connect) {
+ /*
+ * For most net backends from net/, the connection with
+ * some external entity is don in init function, defined
+ * in net_client_init_fun[] list. They don't have separate
+ * .backend_connect.
+ */
+ return true;
+ }
+
+ return nc->info->backend_connect(nc, errp);
+}
--
2.48.1
On 30.10.25 20:19, Vladimir Sementsov-Ogievskiy wrote: > To implement in future backend-transfer migration for virtio-net, > i.e. we are going to migrate TAP fd and some other TAP properties, > we'll need a possibility to postpone opening TAP device until the > point where we are know what user wants: open TAP device, or wait > from fd coming in migration stream. > > So, new interface is here: since this commit, net backends may > postpone some initialization actions (like opening or connecting) > up to call of .backend_connect() handler. > > Currently, for all net drivers, .backend_connect() is called > during set of netdev property, so drivers continue to work with > already "connected" backends. > > Still, we add a possibility for drivers to use new > DEFINE_NIC_PROPERTIES_NO_CONNECT() instead of > DEFINE_NIC_PROPERTIES(). This way, driver take responsibility > to call net_backend_connect() in its own. So, in future we'll > use it in vritio-net, to finally implement backand-transfer > migration fot TAP backend. > > Signed-off-by: Vladimir Sementsov-Ogievskiy<vsementsov@yandex-team.ru> fixup for this commit (otherwise new macro is impossible to use): --- a/include/hw/qdev-properties-system.h +++ b/include/hw/qdev-properties-system.h @@ -20,6 +20,7 @@ extern const PropertyInfo qdev_prop_fdc_drive_type; extern const PropertyInfo qdev_prop_drive; extern const PropertyInfo qdev_prop_drive_iothread; extern const PropertyInfo qdev_prop_netdev; +extern const PropertyInfo qdev_prop_netdev_no_connect; extern const PropertyInfo qdev_prop_pci_devfn; extern const PropertyInfo qdev_prop_blocksize; extern const PropertyInfo qdev_prop_pci_host_devaddr; -- Best regards, Vladimir
© 2016 - 2025 Red Hat, Inc.