diff --git a/hw/qdev.c b/hw/qdev.c
index b32dbfc..e81d662 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -390,6 +390,10 @@ void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
         qdev_prop_set_vlan(dev, "vlan", nd->vlan);
     if (nd->netdev)
         qdev_prop_set_netdev(dev, "netdev", nd->netdev);
+    if (nd->nvectors != NIC_NVECTORS_UNSPECIFIED &&
+        qdev_prop_exists(dev, "vectors")) {
+        qdev_prop_set_uint32(dev, "vectors", nd->nvectors);
+    }
 }
 
 static int next_block_unit[IF_COUNT];
diff --git a/hw/syborg.c b/hw/syborg.c
index 2aec769..2d08cb2 100644
--- a/hw/syborg.c
+++ b/hw/syborg.c
@@ -77,13 +77,13 @@ static void syborg_init(ram_addr_t ram_size,
     sysbus_create_simple("syborg,serial", 0xC0008000, pic[7]);
     sysbus_create_simple("syborg,serial", 0xC0009000, pic[8]);
 
-    if (nd_table[0].vlan) {
+    if (nd_table[0].vlan || nd_table[0].netdev) {
         DeviceState *dev;
         SysBusDevice *s;
 
         qemu_check_nic_model(&nd_table[0], "virtio");
         dev = qdev_create(NULL, "syborg,virtio-net");
-        dev->nd = &nd_table[0];
+        qdev_set_nic_properties(dev, &nd_table[0]);
         qdev_init_nofail(dev);
         s = sysbus_from_qdev(dev);
         sysbus_mmio_map(s, 0, 0xc000c000);
diff --git a/hw/syborg_virtio.c b/hw/syborg_virtio.c
index c1faf3d..6cf5a15 100644
--- a/hw/syborg_virtio.c
+++ b/hw/syborg_virtio.c
@@ -65,6 +65,7 @@ typedef struct {
     qemu_irq irq;
     uint32_t int_enable;
     uint32_t id;
+    NICConf nic;
 } SyborgVirtIOProxy;
 
 static uint32_t syborg_virtio_readl(void *opaque, target_phys_addr_t offset)
@@ -273,14 +274,23 @@ static int syborg_virtio_net_init(SysBusDevice *dev)
     VirtIODevice *vdev;
     SyborgVirtIOProxy *proxy = FROM_SYSBUS(SyborgVirtIOProxy, dev);
 
-    vdev = virtio_net_init(&dev->qdev);
+    vdev = virtio_net_init(&dev->qdev, &proxy->nic);
     return syborg_virtio_init(proxy, vdev);
 }
 
+static SysBusDeviceInfo syborg_virtio_net_info = {
+    .init = syborg_virtio_net_init,
+    .qdev.name  = "syborg,virtio-net",
+    .qdev.size  = sizeof(SyborgVirtIOProxy),
+    .qdev.props = (Property[]) {
+        DEFINE_NIC_PROPERTIES(SyborgVirtIOProxy, nic),
+        DEFINE_PROP_END_OF_LIST(),
+    }
+};
+
 static void syborg_virtio_register_devices(void)
 {
-    sysbus_register_dev("syborg,virtio-net", sizeof(SyborgVirtIOProxy),
-                        syborg_virtio_net_init);
+    sysbus_register_withprop(&syborg_virtio_net_info);
 }
 
 device_init(syborg_virtio_register_devices)
diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index 218f985..f187461 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -700,20 +700,10 @@ static void virtio_net_cleanup(VLANClientState *vc)
 {
     VirtIONet *n = vc->opaque;
 
-    qemu_purge_queued_packets(vc);
-
-    unregister_savevm("virtio-net", n);
-
-    qemu_free(n->mac_table.macs);
-    qemu_free(n->vlans);
-
-    qemu_del_timer(n->tx_timer);
-    qemu_free_timer(n->tx_timer);
-
-    virtio_cleanup(&n->vdev);
+    n->vc = NULL;
 }
 
-VirtIODevice *virtio_net_init(DeviceState *dev)
+VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf)
 {
     VirtIONet *n;
     static int virtio_net_id;
@@ -731,15 +721,16 @@ VirtIODevice *virtio_net_init(DeviceState *dev)
     n->rx_vq = virtio_add_queue(&n->vdev, 256, virtio_net_handle_rx);
     n->tx_vq = virtio_add_queue(&n->vdev, 256, virtio_net_handle_tx);
     n->ctrl_vq = virtio_add_queue(&n->vdev, 64, virtio_net_handle_ctrl);
-    qdev_get_macaddr(dev, n->mac);
+    qemu_macaddr_default_if_unset(&conf->macaddr);
     n->status = VIRTIO_NET_S_LINK_UP;
-    n->vc = qdev_get_vlan_client(dev,
+    n->vc = qemu_new_vlan_client(conf->vlan, conf->peer,
+                                 dev->info->name, dev->id,
                                  virtio_net_can_receive,
                                  virtio_net_receive, NULL,
                                  virtio_net_cleanup, n);
     n->vc->link_status_changed = virtio_net_set_link_status;
 
-    qemu_format_nic_info_str(n->vc, n->mac);
+    qemu_format_nic_info_str(n->vc, conf->macaddr.a);
 
     n->tx_timer = qemu_new_timer(vm_clock, virtio_net_tx_timer, n);
     n->tx_timer_active = 0;
@@ -749,13 +740,27 @@ VirtIODevice *virtio_net_init(DeviceState *dev)
     n->mac_table.macs = qemu_mallocz(MAC_TABLE_ENTRIES * ETH_ALEN);
 
     n->vlans = qemu_mallocz(MAX_VLAN >> 3);
-    if (dev->nd->nvectors == NIC_NVECTORS_UNSPECIFIED)
-        n->vdev.nvectors = 3;
-    else
-        n->vdev.nvectors = dev->nd->nvectors;
 
     register_savevm("virtio-net", virtio_net_id++, VIRTIO_NET_VM_VERSION,
                     virtio_net_save, virtio_net_load, n);
 
     return &n->vdev;
 }
+
+void virtio_net_exit(VirtIODevice *vdev)
+{
+    VirtIONet *n = DO_UPCAST(VirtIONet, vdev, vdev);
+
+    qemu_purge_queued_packets(n->vc);
+
+    unregister_savevm("virtio-net", n);
+
+    qemu_free(n->mac_table.macs);
+    qemu_free(n->vlans);
+
+    qemu_del_timer(n->tx_timer);
+    qemu_free_timer(n->tx_timer);
+
+    virtio_cleanup(&n->vdev);
+    qemu_del_vlan_client(n->vc);
+}
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index e07a2a7..1665b59 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -20,6 +20,7 @@
 #include "sysemu.h"
 #include "msix.h"
 #include "net.h"
+#include "loader.h"
 
 /* from Linux's linux/virtio_pci.h */
 
@@ -90,6 +91,7 @@ typedef struct {
     uint32_t class_code;
     uint32_t nvectors;
     DriveInfo *dinfo;
+    NICConf nic;
 } VirtIOPCIProxy;
 
 /* virtio device */
@@ -493,14 +495,9 @@ static int virtio_net_init_pci(PCIDevice *pci_dev)
     VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
     VirtIODevice *vdev;
 
-    vdev = virtio_net_init(&pci_dev->qdev);
-
-    /* set nvectors from property, unless the user specified something
-     * via -net nic,model=virtio,vectors=n command line option */
-    if (pci_dev->qdev.nd->nvectors == NIC_NVECTORS_UNSPECIFIED)
-        if (proxy->nvectors != NIC_NVECTORS_UNSPECIFIED)
-            vdev->nvectors = proxy->nvectors;
+    vdev = virtio_net_init(&pci_dev->qdev, &proxy->nic);
 
+    vdev->nvectors = proxy->nvectors;
     virtio_init_pci(proxy, vdev,
                     PCI_VENDOR_ID_REDHAT_QUMRANET,
                     PCI_DEVICE_ID_VIRTIO_NET,
@@ -509,9 +506,25 @@ static int virtio_net_init_pci(PCIDevice *pci_dev)
 
     /* make the actual value visible */
     proxy->nvectors = vdev->nvectors;
+
+    if (!pci_dev->qdev.hotplugged) {
+        static int loaded = 0;
+        if (!loaded) {
+            rom_add_option("pxe-virtio.bin");
+            loaded = 1;
+        }
+    }
     return 0;
 }
 
+static int virtio_net_exit_pci(PCIDevice *pci_dev)
+{
+    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
+
+    virtio_net_exit(proxy->vdev);
+    return virtio_exit_pci(pci_dev);
+}
+
 static int virtio_balloon_init_pci(PCIDevice *pci_dev)
 {
     VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
@@ -543,10 +556,10 @@ static PCIDeviceInfo virtio_info[] = {
         .qdev.name  = "virtio-net-pci",
         .qdev.size  = sizeof(VirtIOPCIProxy),
         .init       = virtio_net_init_pci,
-        .exit       = virtio_exit_pci,
+        .exit       = virtio_net_exit_pci,
         .qdev.props = (Property[]) {
-            DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors,
-                               NIC_NVECTORS_UNSPECIFIED),
+            DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 3),
+            DEFINE_NIC_PROPERTIES(VirtIOPCIProxy, nic),
             DEFINE_PROP_END_OF_LIST(),
         },
         .qdev.reset = virtio_pci_reset,
diff --git a/hw/virtio.h b/hw/virtio.h
index 0f9be7d..15ad910 100644
--- a/hw/virtio.h
+++ b/hw/virtio.h
@@ -15,6 +15,7 @@
 #define _QEMU_VIRTIO_H
 
 #include "hw.h"
+#include "net.h"
 #include "qdev.h"
 #include "sysemu.h"
 
@@ -163,8 +164,10 @@ void virtio_bind_device(VirtIODevice *vdev, const VirtIOBindings *binding,
 
 /* Base devices.  */
 VirtIODevice *virtio_blk_init(DeviceState *dev, DriveInfo *dinfo);
-VirtIODevice *virtio_net_init(DeviceState *dev);
+VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf);
 VirtIODevice *virtio_console_init(DeviceState *dev);
 VirtIODevice *virtio_balloon_init(DeviceState *dev);
 
+void virtio_net_exit(VirtIODevice *vdev);
+
 #endif
