[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC PATCH 1/2] Implement netdev_set command
From: |
Vasilis Liaskovitis |
Subject: |
[Qemu-devel] [RFC PATCH 1/2] Implement netdev_set command |
Date: |
Wed, 2 May 2012 18:06:41 +0200 |
This command can be used to attach a host backend network device (netdev) to a
guest nic. Syntax is:
netdev_set nicid netdevid
This patch adds qmp and hmp support for the command.
Signed-off-by: Vasilis Liaskovitis <address@hidden>
---
hmp-commands.hx | 14 +++++++++++++
hmp.c | 10 +++++++++
hmp.h | 1 +
net.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
net.h | 1 +
qapi-schema.json | 16 ++++++++++++++
qmp-commands.hx | 25 +++++++++++++++++++++++
7 files changed, 125 insertions(+), 0 deletions(-)
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 54b8592..65ae0bf 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1032,6 +1032,20 @@ STEXI
Remove host network device.
ETEXI
+ {
+ .name = "netdev_set",
+ .args_type = "nicid:s,netdevid:s",
+ .params = "nicid netdevid",
+ .help = "attach host network device to nic",
+ .mhandler.cmd = hmp_netdev_set,
+ },
+
+STEXI
address@hidden netdev_del
address@hidden netdev_del
+Attach host network device to nic.
+ETEXI
+
#ifdef CONFIG_SLIRP
{
.name = "hostfwd_add",
diff --git a/hmp.c b/hmp.c
index 17fddb9..2a817ee 100644
--- a/hmp.c
+++ b/hmp.c
@@ -973,3 +973,13 @@ void hmp_netdev_del(Monitor *mon, const QDict *qdict)
qmp_netdev_del(id, &err);
hmp_handle_error(mon, &err);
}
+
+void hmp_netdev_set(Monitor *mon, const QDict *qdict)
+{
+ const char *nicid = qdict_get_str(qdict, "nicid");
+ const char *netdevid = qdict_get_str(qdict, "netdevid");
+ Error *err = NULL;
+
+ qmp_netdev_set(nicid, netdevid, &err);
+ hmp_handle_error(mon, &err);
+}
diff --git a/hmp.h b/hmp.h
index ca005df..90b12cd 100644
--- a/hmp.h
+++ b/hmp.h
@@ -63,5 +63,6 @@ void hmp_migrate(Monitor *mon, const QDict *qdict);
void hmp_device_del(Monitor *mon, const QDict *qdict);
void hmp_netdev_add(Monitor *mon, const QDict *qdict);
void hmp_netdev_del(Monitor *mon, const QDict *qdict);
+void hmp_netdev_set(Monitor *mon, const QDict *qdict);
#endif
diff --git a/net.c b/net.c
index 4aa416c..a8358a7 100644
--- a/net.c
+++ b/net.c
@@ -674,6 +674,21 @@ VLANClientState *qemu_find_netdev(const char *id)
return NULL;
}
+VLANClientState *qemu_find_nic(const char *id)
+{
+ VLANClientState *vc;
+
+ QTAILQ_FOREACH(vc, &non_vlan_clients, next) {
+ if (vc->info->type != NET_CLIENT_TYPE_NIC)
+ continue;
+ if (!strcmp(vc->name, id)) {
+ return vc;
+ }
+ }
+
+ return NULL;
+}
+
static int nic_get_free_idx(void)
{
int index;
@@ -1283,6 +1298,49 @@ void qmp_netdev_del(const char *id, Error **errp)
qemu_opts_del(qemu_opts_find(qemu_find_opts_err("netdev", errp), id));
}
+void qmp_netdev_set(const char *nicid, const char *netdevid, Error **errp)
+{
+ VLANClientState *vc, *nic;
+ NICState *nicstate;
+ DeviceState *qdev;
+
+ nic = qemu_find_nic(nicid);
+ if (!nic) {
+ error_set(errp, QERR_DEVICE_NOT_FOUND, nicid);
+ }
+
+ qdev = qdev_find_recursive(sysbus_get_default(), nicid);
+ if (!qdev) {
+ error_set(errp, QERR_DEVICE_NOT_FOUND, nicid);
+ }
+
+ vc = qemu_find_netdev(netdevid);
+ if (!vc) {
+ error_set(errp, QERR_DEVICE_NOT_FOUND, netdevid);
+ return;
+ }
+
+ /* for now, only allow tap device assignment*/
+ if (vc->info->type != NET_CLIENT_TYPE_TAP) {
+ error_set(errp, QERR_INVALID_PARAMETER, netdevid);
+ return;
+ }
+
+ vc->peer = nic;
+ if (nic->peer)
+ nic->peer->peer = NULL;
+ nic->peer = vc;
+
+ nicstate = DO_UPCAST(NICState, nc, nic);
+ if (nicstate->peer_deleted == true)
+ nicstate->peer_deleted = false;
+ nicstate->conf->peer = vc;
+
+ /* this is a hack, qdev properties should not be set after nic
+ * initialization */
+ qdev_prop_parse(qdev, "netdev", netdevid);
+}
+
static void print_net_client(Monitor *mon, VLANClientState *vc)
{
monitor_printf(mon, "%s: type=%s,%s\n", vc->name,
diff --git a/net.h b/net.h
index bdc2a06..c8abf17 100644
--- a/net.h
+++ b/net.h
@@ -90,6 +90,7 @@ struct VLANState {
VLANState *qemu_find_vlan(int id, int allocate);
VLANClientState *qemu_find_netdev(const char *id);
+VLANClientState *qemu_find_nic(const char *id);
VLANClientState *qemu_new_net_client(NetClientInfo *info,
VLANState *vlan,
VLANClientState *peer,
diff --git a/qapi-schema.json b/qapi-schema.json
index 5b4ba12..9127238 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -1765,3 +1765,19 @@
# Since: 0.14.0
##
{ 'command': 'netdev_del', 'data': {'id': 'str'} }
+
+##
+# @netdev_set:
+#
+# Attach a network backend to a network device.
+#
+# @id: the name of the network device to attach to
+# @netdev: the name of the network backend to attach
+#
+# Returns: Nothing on success
+# If @id is not a valid network device, DeviceNotFound
+# If @netdev is not a valid network backend, DeviceNotFound
+#
+# Since: 0.14.0
+##
+{ 'command': 'netdev_set', 'data': {'nicid': 'str', 'netdevid': 'str'} }
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 7a68cad..ee278e4 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -657,6 +657,31 @@ Example:
EQMP
{
+ .name = "netdev_set",
+ .args_type = "nicid:s,netdevid:s",
+ .mhandler.cmd_new = qmp_marshal_input_netdev_set,
+ },
+
+SQMP
+netdev_set
+----------
+
+Attach host network device to guest nic.
+
+Arguments:
+
+- "nicid": the nic device's ID, must be unique (json-string)
+- "netdevid": the host network device's ID, must be unique (json-string)
+
+Example:
+
+-> { "execute": "netdev_set", "arguments": { "nicid": "nic1", "netdevid":
"netdev1" } }
+<- { "return": {} }
+
+
+EQMP
+
+ {
.name = "block_resize",
.args_type = "device:B,size:o",
.mhandler.cmd_new = qmp_marshal_input_block_resize,
--
1.7.9