net: add qemu_create_nic_bus_devices()

This will instantiate any NICs which live on a given bus type. Each bus
is allowed *one* substitution (for PCI it's virtio → virtio-net-pci, for
Xen it's xen → xen-net-device; no point in overengineering it unless we
actually want more).

Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Reviewed-by: Paul Durrant <paul@xen.org>
Reviewed-by: Thomas Huth <thuth@redhat.com>
This commit is contained in:
David Woodhouse 2023-10-22 09:13:41 +01:00
parent 2cdeca04ad
commit 93125e4b4f
2 changed files with 75 additions and 0 deletions

View File

@ -248,6 +248,28 @@ bool qemu_configure_nic_device(DeviceState *dev, bool match_default,
*/ */
DeviceState *qemu_create_nic_device(const char *typename, bool match_default, DeviceState *qemu_create_nic_device(const char *typename, bool match_default,
const char *alias); const char *alias);
/*
* qemu_create_nic_bus_devices: Create configured NIC devices for a given bus
* @bus: Bus on which to create devices
* @parent_type: Object type for devices to be created (e.g. TYPE_PCI_DEVICE)
* @default_model: Object type name for default NIC model (or %NULL)
* @alias: Additional model string to replace, for user convenience
* @alias_target: Actual object type name to be used in place of @alias
*
* Instantiate dynamic NICs on a given bus, typically a PCI bus. This scans
* for available NIC configurations which either specify a model which is
* a child type of @parent_type, or which do not specify a model when
* @default_model is non-NULL. Each device is instantiated on the given @bus.
*
* A single substitution is supported, e.g. "xen" "xen-net-device" for the
* Xen bus, or "virtio" "virtio-net-pci" for PCI. This allows the user to
* specify a more understandable "model=" parameter on the command line, not
* only the real object typename.
*/
void qemu_create_nic_bus_devices(BusState *bus, const char *parent_type,
const char *default_model,
const char *alias, const char *alias_target);
void print_net_client(Monitor *mon, NetClientState *nc); void print_net_client(Monitor *mon, NetClientState *nc);
void net_socket_rs_init(SocketReadState *rs, void net_socket_rs_init(SocketReadState *rs,
SocketReadStateFinalize *finalize, SocketReadStateFinalize *finalize,

View File

@ -1223,6 +1223,59 @@ DeviceState *qemu_create_nic_device(const char *typename, bool match_default,
return dev; return dev;
} }
void qemu_create_nic_bus_devices(BusState *bus, const char *parent_type,
const char *default_model,
const char *alias, const char *alias_target)
{
GPtrArray *nic_models = qemu_get_nic_models(parent_type);
const char *model;
DeviceState *dev;
NICInfo *nd;
int i;
if (nic_model_help) {
if (alias_target) {
add_nic_model_help(alias_target, alias);
}
for (i = 0; i < nic_models->len - 1; i++) {
add_nic_model_help(nic_models->pdata[i], NULL);
}
}
/* Drop the NULL terminator which would make g_str_equal() unhappy */
nic_models->len--;
for (i = 0; i < nb_nics; i++) {
nd = &nd_table[i];
if (!nd->used || nd->instantiated) {
continue;
}
model = nd->model ? nd->model : default_model;
if (!model) {
continue;
}
/* Each bus type is allowed *one* substitution */
if (g_str_equal(model, alias)) {
model = alias_target;
}
if (!g_ptr_array_find_with_equal_func(nic_models, model,
g_str_equal, NULL)) {
/* This NIC does not live on this bus. */
continue;
}
dev = qdev_new(model);
qdev_set_nic_properties(dev, nd);
qdev_realize_and_unref(dev, bus, &error_fatal);
}
g_ptr_array_free(nic_models, true);
}
static int (* const net_client_init_fun[NET_CLIENT_DRIVER__MAX])( static int (* const net_client_init_fun[NET_CLIENT_DRIVER__MAX])(
const Netdev *netdev, const Netdev *netdev,
const char *name, const char *name,