• M
    Fix netdev name lookup in -device, device_add, netdev_del · 85dde9a9
    Markus Armbruster 提交于
    qemu_find_netdev() looks up members of non_vlan_clients by name.  It
    happily returns the first match.  Trouble is the names need not be
    unique.
    
    non_vlan_clients contains host parts (netdevs) and guest parts (NICs).
    
    Netdevs have unique names: a netdev's name is a (mandatory)
    qemu_netdev_opts ID, and these are unique.
    
    NIC names are not unique.  If a NIC has a qdev ID (which is unique),
    that's its name.  Else, we make up a name.  The made-up names are
    unique, but they can clash with qdev IDs.  Even if NICs had unique
    names, they could still clash with netdev names.
    
    Callers of qemu_find_netdev():
    
    * net_init_nic() wants a netdev.  It happens to work because it runs
      before NICs get added to non_vlan_clients.
    
    * do_netdev_del() wants a netdev.  If it gets a NIC, it complains and
      fails.  Bug: a netdev with the same name that comes later in
      non_vlan_clients can't be deleted:
    
        $ qemu-system-x86_64 -nodefaults -vnc :0 -S -monitor stdio -netdev user,id=hostnet0 -device virtio-net-pci,netdev=hostnet0,id=virtio1
        [...]
        (qemu) netdev_add user,id=virtio1
        (qemu) info network
        Devices not on any VLAN:
          hostnet0: net=10.0.2.0, restricted=n peer=virtio1
          virtio1: model=virtio-net-pci,macaddr=52:54:00:12:34:56 peer=hostnet0
          virtio1: net=10.0.2.0, restricted=n
        (qemu) netdev_del virtio1
        Device 'virtio1' not found
    
    * parse_netdev() wants a netdev.  If it gets a NIC, it gets confused.
      With the test setup above:
    
        (qemu) device_add virtio-net-pci,netdev=virtio1
        Property 'virtio-net-pci.netdev' can't take value 'virtio1', it's in use
    
      You can even connect two NICs to each other:
    
        $ qemu-system-x86_64 -nodefaults -vnc :0 -S -monitor stdio -device virtio-net-pci,id=virtio1 -device e1000,netdev=virtio1
        [...]
        Devices not on any VLAN:
          virtio1: model=virtio-net-pci,macaddr=52:54:00:12:34:56 peer=e1000.0
          e1000.0: model=e1000,macaddr=52:54:00:12:34:57 peer=virtio1
        (qemu) q
        Segmentation fault (core dumped)
    
    * do_set_link() works fine for both netdevs and NICs.  Whether it
      really makes sense for netdevs is debatable, but that's outside this
      patch's scope.
    
    Change qemu_find_netdev() to return only netdevs.  This fixes the
    netdev_del and device_add/-device bugs demonstrated above.
    
    To avoid changing set_link, make do_set_link() search non_vlan_clients
    by hand instead of calling qemu_find_netdev().
    Signed-off-by: NMarkus Armbruster <armbru@redhat.com>
    Signed-off-by: NMichael S. Tsirkin <mst@redhat.com>
    85dde9a9
net.c 38.4 KB