On 02/19/13 18:50, Markus Armbruster wrote: > Your example uses -net to connect additional backends to the hubport. > If I understand you correctly, you can't use -netdev to do that. > Ignorant question: fundamental reason or just not implemented?
(I'll let Stefan correct me, but I should be able to understand it as well, since I reviewed his series...) N 1 NetClientState --------- NICConf ^ ^ | | | | user/tap/socket/ e1000/virtio-net-pci vde/bridge/hubport -device -netdev -netdev describes an object (a backend) derived from NetClientState. NetClientState has a single peer. -device describes a frontend (a guest device). Some of those are network interfaces, derived from NICConf. (They also inherit a bunch of other stuff). NICConf has an array of peers. When a backend is created with -netdev, qemu_new_net_client() is called in such a way that the peer to set is NULL, no links are created. The linkage is established from the NIC side, (a) -net nic,model=...,netdev=...; in qemu_new_nic(), (b) -device e1000,netdev=...; in parse_netdev() I think. All 2*N links are created from the NIC side (two per each guest queue I think), ie. when the frontend is added, that sets the peer link inside all N referencedbackends as well. NetHubPort is a special backend (host device) that forwards to all other NetHubPort backends on the same NetHub. This is internal to NetHubPort. "-net" is super-confusing. (1) -net nic,model=...,netdev=... corresponds to case (a) above, it adds a frontend and "links back" all referenced, pre-existent backends to it. (2) -net nic,model=...[,vlan=...] creates a NetHubPort backend on the specified NetHub (vlan defaults to 0), creates the frontend as well, and links them together. (3) -net BACKEND[,vlan=...], including BACKEND==dump, creates a NetHubPort backend on the specified NetHub, also creates an instance of the requested backend type, and links them together via each one's peer link. ( Regarding the (non-hub) backend created in (3), its peer link is already occupied, hence you cannot set different linkage for it from the frontend side, as in (a) or (b). In (a) it triggers an assert(), in (b) it returns -EEXIST I think. ... I can't actually trigger the assert in (a) -- looks like (b) is always reached first --, but I can trigger the -EEXIST in (b): # qemu -net dump,name=dump0 -net nic,model=e1000,netdev=dump0 qemu-system-x86_64: Property 'e1000.netdev' can't take value 'dump0', it's in use Aborted # qemu -net dump,name=dump0 -device e1000,netdev=dump0 qemu-system-x86_64: -device e1000,netdev=dump0: Property 'e1000.netdev' can't take value 'dump0', it's in use (no abort, exit status 1) ) In order to take a stab at your question at last: - the two (parallel, opposing) links created in (3) connect two backends, - "-netdev" does not set the peer link in the backend, so you cannot use that, - "-device" *would* set the links in both directions, but it's for creating frontends. IOW (3) is unique because it links backend to backend. (It could tempt us to create an infinite loop between two NetHubPorts, ie. "-net hubport,hubid=0"; one path via the NetHub, the other through the direct peer link. net_init_hubport() is smart enough to prevent that; you can only add a hubport with -netdev, which doesn't set the peer link for the backend, and then you can only set it with a -device or -net nic from the other side.) Laszlo