summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--net/hub.c27
-rw-r--r--net/hub.h3
-rw-r--r--net/net.c2
-rw-r--r--qapi/net.json4
-rw-r--r--qemu-options.hx8
5 files changed, 32 insertions, 12 deletions
diff --git a/net/hub.c b/net/hub.c
index 14b4eec68f..5e84a9ad93 100644
--- a/net/hub.c
+++ b/net/hub.c
@@ -13,6 +13,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "qapi/error.h"
 #include "monitor/monitor.h"
 #include "net/net.h"
 #include "clients.h"
@@ -140,7 +141,8 @@ static NetClientInfo net_hub_port_info = {
     .cleanup = net_hub_port_cleanup,
 };
 
-static NetHubPort *net_hub_port_new(NetHub *hub, const char *name)
+static NetHubPort *net_hub_port_new(NetHub *hub, const char *name,
+                                    NetClientState *hubpeer)
 {
     NetClientState *nc;
     NetHubPort *port;
@@ -153,7 +155,7 @@ static NetHubPort *net_hub_port_new(NetHub *hub, const char *name)
         name = default_name;
     }
 
-    nc = qemu_new_net_client(&net_hub_port_info, NULL, "hub", name);
+    nc = qemu_new_net_client(&net_hub_port_info, hubpeer, "hub", name);
     port = DO_UPCAST(NetHubPort, nc, nc);
     port->id = id;
     port->hub = hub;
@@ -165,11 +167,14 @@ static NetHubPort *net_hub_port_new(NetHub *hub, const char *name)
 
 /**
  * Create a port on a given hub
+ * @hub_id: Number of the hub
  * @name: Net client name or NULL for default name.
+ * @hubpeer: Peer to use (if "netdev=id" has been specified)
  *
  * If there is no existing hub with the given id then a new hub is created.
  */
-NetClientState *net_hub_add_port(int hub_id, const char *name)
+NetClientState *net_hub_add_port(int hub_id, const char *name,
+                                 NetClientState *hubpeer)
 {
     NetHub *hub;
     NetHubPort *port;
@@ -184,7 +189,7 @@ NetClientState *net_hub_add_port(int hub_id, const char *name)
         hub = net_hub_new(hub_id);
     }
 
-    port = net_hub_port_new(hub, name);
+    port = net_hub_port_new(hub, name, hubpeer);
     return &port->nc;
 }
 
@@ -232,7 +237,7 @@ NetClientState *net_hub_port_find(int hub_id)
         }
     }
 
-    nc = net_hub_add_port(hub_id, NULL);
+    nc = net_hub_add_port(hub_id, NULL, NULL);
     return nc;
 }
 
@@ -286,12 +291,22 @@ int net_init_hubport(const Netdev *netdev, const char *name,
                      NetClientState *peer, Error **errp)
 {
     const NetdevHubPortOptions *hubport;
+    NetClientState *hubpeer = NULL;
 
     assert(netdev->type == NET_CLIENT_DRIVER_HUBPORT);
     assert(!peer);
     hubport = &netdev->u.hubport;
 
-    net_hub_add_port(hubport->hubid, name);
+    if (hubport->has_netdev) {
+        hubpeer = qemu_find_netdev(hubport->netdev);
+        if (!hubpeer) {
+            error_setg(errp, "netdev '%s' not found", hubport->netdev);
+            return -1;
+        }
+    }
+
+    net_hub_add_port(hubport->hubid, name, hubpeer);
+
     return 0;
 }
 
diff --git a/net/hub.h b/net/hub.h
index a625effe00..6a16f0487a 100644
--- a/net/hub.h
+++ b/net/hub.h
@@ -17,7 +17,8 @@
 
 #include "qemu-common.h"
 
-NetClientState *net_hub_add_port(int hub_id, const char *name);
+NetClientState *net_hub_add_port(int hub_id, const char *name,
+                                 NetClientState *hubpeer);
 NetClientState *net_hub_find_client_by_name(int hub_id, const char *name);
 void net_hub_info(Monitor *mon);
 void net_hub_check_clients(void);
diff --git a/net/net.c b/net/net.c
index 2b81c93193..e1569e7d89 100644
--- a/net/net.c
+++ b/net/net.c
@@ -1063,7 +1063,7 @@ static int net_client_init1(const void *object, bool is_netdev, Error **errp)
         /* Do not add to a vlan if it's a nic with a netdev= parameter. */
         if (netdev->type != NET_CLIENT_DRIVER_NIC ||
             !opts->u.nic.has_netdev) {
-            peer = net_hub_add_port(net->has_vlan ? net->vlan : 0, NULL);
+            peer = net_hub_add_port(net->has_vlan ? net->vlan : 0, NULL, NULL);
         }
 
         if (net->has_vlan && !vlan_warned) {
diff --git a/qapi/net.json b/qapi/net.json
index 4beff5d582..1238ba5de1 100644
--- a/qapi/net.json
+++ b/qapi/net.json
@@ -410,12 +410,14 @@
 # Connect two or more net clients through a software hub.
 #
 # @hubid: hub identifier number
+# @netdev: used to connect hub to a netdev instead of a device (since 2.12)
 #
 # Since: 1.2
 ##
 { 'struct': 'NetdevHubPortOptions',
   'data': {
-    'hubid':     'int32' } }
+    'hubid':     'int32',
+    '*netdev':    'str' } }
 
 ##
 # @NetdevNetmapOptions:
diff --git a/qemu-options.hx b/qemu-options.hx
index 1d73fb151d..56b9a8692e 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -2000,7 +2000,7 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
 #endif
     "-netdev vhost-user,id=str,chardev=dev[,vhostforce=on|off]\n"
     "                configure a vhost-user network, backed by a chardev 'dev'\n"
-    "-netdev hubport,id=str,hubid=n\n"
+    "-netdev hubport,id=str,hubid=n[,netdev=nd]\n"
     "                configure a hub port on QEMU VLAN 'n'\n", QEMU_ARCH_ALL)
 DEF("net", HAS_ARG, QEMU_OPTION_net,
     "-net nic[,vlan=n][,netdev=nd][,macaddr=mac][,model=type][,name=str][,addr=str][,vectors=v]\n"
@@ -2428,13 +2428,15 @@ vde_switch -F -sock /tmp/myswitch
 qemu-system-i386 linux.img -net nic -net vde,sock=/tmp/myswitch
 @end example
 
-@item -netdev hubport,id=@var{id},hubid=@var{hubid}
+@item -netdev hubport,id=@var{id},hubid=@var{hubid}[,netdev=@var{nd}]
 
 Create a hub port on QEMU "vlan" @var{hubid}.
 
 The hubport netdev lets you connect a NIC to a QEMU "vlan" instead of a single
 netdev.  @code{-net} and @code{-device} with parameter @option{vlan} create the
-required hub automatically.
+required hub automatically. Alternatively, you can also connect the hubport
+to another netdev with ID @var{nd} by using the @option{netdev=@var{nd}}
+option.
 
 @item -netdev vhost-user,chardev=@var{id}[,vhostforce=on|off][,queues=n]