@@ -972,6 +972,58 @@ int net_client_init(Monitor *mon, QemuOpts *opts, int is_netdev)
return -1;
}
+static int net_client_netdev_init(Monitor *mon, QemuOpts *opts, int is_netdev)
+{
+ const char *name;
+ const char *type;
+
+ type = qemu_opt_get(opts, "type");
+ if (!type) {
+ qerror_report(QERR_MISSING_PARAMETER, "type");
+ return -1;
+ }
+
+ if (is_netdev) {
+ if (strcmp(type, "tap") != 0 &&
+#ifdef CONFIG_NET_BRIDGE
+ strcmp(type, "bridge") != 0 &&
+#endif
+#ifdef CONFIG_SLIRP
+ strcmp(type, "user") != 0 &&
+#endif
+#ifdef CONFIG_VDE
+ strcmp(type, "vde") != 0 &&
+#endif
+ strcmp(type, "socket") != 0) {
+ qerror_report(QERR_INVALID_PARAMETER_VALUE, "type",
+ "a netdev backend type");
+ return -1;
+ }
+
+ if (qemu_opt_get(opts, "vlan")) {
+ qerror_report(QERR_INVALID_PARAMETER, "vlan");
+ return -1;
+ }
+ if (qemu_opt_get(opts, "name")) {
+ qerror_report(QERR_INVALID_PARAMETER, "name");
+ return -1;
+ }
+ if (!qemu_opts_id(opts)) {
+ qerror_report(QERR_MISSING_PARAMETER, "id");
+ return -1;
+ }
+ }
+
+ name = qemu_opts_id(opts);
+ if (!name) {
+ name = qemu_opt_get(opts, "name");
+ }
+
+ hostdev_device_add(mon, opts, (char *)name, NULL);
+
+ return 0;
+}
+
static int net_host_check_device(const char *device)
{
int i;
@@ -1188,7 +1240,7 @@ static int net_init_client(QemuOpts *opts, void *dummy)
static int net_init_netdev(QemuOpts *opts, void *dummy)
{
- return net_client_init(NULL, opts, 1);
+ return net_client_netdev_init(NULL, opts, 1);
}
int net_init_clients(void)
@@ -7,6 +7,7 @@
#include "qemu-option.h"
#include "net/queue.h"
#include "vmstate.h"
+#include "qemu/hostdev.h"
struct MACAddr {
uint8_t a[6];
@@ -61,6 +62,7 @@ typedef struct NetClientInfo {
} NetClientInfo;
struct NetClientState {
+ HOSTDevice host_dev;
NetClientInfo *info;
int link_down;
QTAILQ_ENTRY(NetClientState) next;
@@ -777,3 +777,36 @@ int net_slirp_parse_legacy(QemuOptsList *opts_list, const char *optarg, int *ret
return 1;
}
+static hostdevProperty net_user_properties[] = {
+ //DEFINE_PROP_STRING("type", NetClientState, info->type),
+ DEFINE_HOSTDEV_PROP_INT32("link_down", NetClientState,link_down, 0),
+ DEFINE_HOSTDEV_PROP_PEER("peer", NetClientState, peer),
+ //DEFINE_PROP_STRING("model", NetClientState, model),
+ DEFINE_HOSTDEV_PROP_STRING("name", NetClientState, name),
+ //DEFINE_PROP_BIT("receive_disabled", NetClientState, receive_disabled, 0, true),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void net_user_class_init(ObjectClass *klass, void *data)
+{
+ HOSTDeviceClass *k = HOSTDEV_CLASS(klass);
+
+ k->init = net_init_slirp;
+ k->props = net_user_properties;
+}
+
+static TypeInfo net_user_type = {
+ .name = "user",
+ .parent = TYPE_HOSTDEV,
+ .instance_size = sizeof(NetClientState),
+ .class_init = net_user_class_init,
+};
+
+static void net_user_register_types(void)
+{
+#ifdef CONFIG_SLIRP
+ type_register_static(&net_user_type);
+#endif
+}
+
+type_init(net_user_register_types)
@@ -27,6 +27,7 @@
#include "qemu-common.h"
#include "qdict.h"
#include "qemu-option.h"
+#include "qemu/hostdev.h"
#ifdef CONFIG_SLIRP
@@ -31,6 +31,7 @@
#include "qemu-error.h"
#include "qemu-option.h"
#include "qemu_socket.h"
+#include "qemu/hostdev.h"
typedef struct NetSocketState {
NetClientState nc;
@@ -587,10 +588,8 @@ static int net_socket_udp_init(NetClientState *peer,
return 0;
}
-int net_init_socket(QemuOpts *opts,
- Monitor *mon,
- const char *name,
- NetClientState *peer)
+int net_init_socket(QemuOpts *opts, Monitor *mon,
+ const char *name, NetClientState *peer)
{
if (qemu_opt_get(opts, "fd")) {
int fd;
@@ -690,3 +689,29 @@ int net_init_socket(QemuOpts *opts,
}
return 0;
}
+
+static hostdevProperty net_socket_properties[] = {
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void net_socket_class_init(ObjectClass *klass, void *data)
+{
+ HOSTDeviceClass *k = HOSTDEV_CLASS(klass);
+
+ k->init = net_init_socket;
+ k->props = net_socket_properties;
+}
+
+static TypeInfo net_socket_type = {
+ .name = "socket",
+ .parent = TYPE_HOSTDEV,
+ .instance_size = sizeof(NetClientState),
+ .class_init = net_socket_class_init,
+};
+
+static void net_socket_register_types(void)
+{
+ type_register_static(&net_socket_type);
+}
+
+type_init(net_socket_register_types)
@@ -26,8 +26,11 @@
#include "net.h"
#include "qemu-common.h"
+#include "qemu/hostdev.h"
-int net_init_socket(QemuOpts *opts, Monitor *mon,
- const char *name, NetClientState *peer);
+int net_init_socket(QemuOpts *opts,
+ Monitor *mon,
+ const char *name,
+ NetClientState *peer);
#endif /* QEMU_NET_SOCKET_H */
@@ -715,3 +715,49 @@ VHostNetState *tap_get_vhost_net(NetClientState *nc)
assert(nc->info->type == NET_CLIENT_TYPE_TAP);
return s->vhost_net;
}
+
+static hostdevProperty net_tap_properties[] = {
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void net_tap_class_init(ObjectClass *klass, void *data)
+{
+ HOSTDeviceClass *k = HOSTDEV_CLASS(klass);
+
+ k->init = net_init_tap;
+ k->props = net_tap_properties;
+}
+
+static TypeInfo net_tap_type = {
+ .name = "tap",
+ .parent = TYPE_HOSTDEV,
+ .instance_size = sizeof(NetClientState),
+ .class_init = net_tap_class_init,
+};
+
+static hostdevProperty net_bridge_properties[] = {
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void net_bridge_class_init(ObjectClass *klass, void *data)
+{
+ HOSTDeviceClass *k = HOSTDEV_CLASS(klass);
+
+ k->init = net_init_bridge;
+ k->props = net_bridge_properties;
+}
+
+static TypeInfo net_bridge_type = {
+ .name = "bridge",
+ .parent = TYPE_HOSTDEV,
+ .instance_size = sizeof(NetClientState),
+ .class_init = net_bridge_class_init,
+};
+
+static void net_tap_register_types(void)
+{
+ type_register_static(&net_tap_type);
+ type_register_static(&net_bridge_type);
+}
+
+type_init(net_tap_register_types)
@@ -28,6 +28,7 @@
#include "qemu-common.h"
#include "qemu-option.h"
+#include "qemu/hostdev.h"
#define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
#define DEFAULT_NETWORK_DOWN_SCRIPT "/etc/qemu-ifdown"
@@ -1,2 +1,2 @@
qom-y = object.o container.o qom-qobject.o
-qom-twice-y = cpu.o
+qom-twice-y = cpu.o hostdev.o
@@ -2299,8 +2299,6 @@ int main(int argc, char **argv, char **envp)
#endif
}
- module_call_init(MODULE_INIT_QOM);
-
runstate_init();
init_clocks();
@@ -3381,10 +3379,6 @@ int main(int argc, char **argv, char **envp)
}
configure_icount(icount_option);
- if (net_init_clients() < 0) {
- exit(1);
- }
-
/* init the bluetooth world */
if (foreach_device_config(DEV_BT, bt_parse))
exit(1);
@@ -3474,6 +3468,8 @@ int main(int argc, char **argv, char **envp)
if (foreach_device_config(DEV_DEBUGCON, debugcon_parse) < 0)
exit(1);
+ module_call_init(MODULE_INIT_QOM);
+
/* must be after qdev registration but before machine init */
if (vga_model) {
select_vgahw(vga_model);
@@ -3514,6 +3510,10 @@ int main(int argc, char **argv, char **envp)
exit(1);
}
+ if (net_init_clients() < 0) {
+ exit(1);
+ }
+
/* init generic devices */
if (qemu_opts_foreach(qemu_find_opts("device"), device_init_func, NULL, 1) != 0)
exit(1);