diff mbox

[19/19] virtio-net: add tap_has_ufo flag to saved state

Message ID 1256229830-28066-20-git-send-email-markmc@redhat.com
State New
Headers show

Commit Message

Mark McLoughlin Oct. 22, 2009, 4:43 p.m. UTC
If we tell the guest we support UFO and then migrate to host which
doesn't support it, we will find ourselves in grave difficulties.

Prevent this scenario by adding a flag to virtio-net's savevm format
which indicates whether the device requires host UFO support.

[v2:
  - add has_ufo uint8_t field for ease of vmstate conversion
  - use qemu_error()
]

Signed-off-by: Mark McLoughlin <markmc@redhat.com>
---
 hw/virtio-net.c |   23 +++++++++++++++++++++--
 1 files changed, 21 insertions(+), 2 deletions(-)
diff mbox

Patch

diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index 31ac9ef..15b6f45 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -16,7 +16,7 @@ 
 #include "qemu-timer.h"
 #include "virtio-net.h"
 
-#define VIRTIO_NET_VM_VERSION    10
+#define VIRTIO_NET_VM_VERSION    11
 
 #define MAC_TABLE_ENTRIES    64
 #define MAX_VLAN    (1 << 12)   /* Per 802.1Q definition */
@@ -33,6 +33,7 @@  typedef struct VirtIONet
     QEMUTimer *tx_timer;
     int tx_timer_active;
     uint32_t has_vnet_hdr;
+    uint8_t has_ufo;
     struct {
         VirtQueueElement elem;
         ssize_t len;
@@ -134,6 +135,16 @@  static int peer_has_vnet_hdr(VirtIONet *n)
     return n->has_vnet_hdr;
 }
 
+static int peer_has_ufo(VirtIONet *n)
+{
+    if (!peer_has_vnet_hdr(n))
+        return 0;
+
+    n->has_ufo = tap_has_ufo(n->vc->peer);
+
+    return n->has_ufo;
+}
+
 static uint32_t virtio_net_get_features(VirtIODevice *vdev)
 {
     VirtIONet *n = to_virtio_net(vdev);
@@ -158,7 +169,7 @@  static uint32_t virtio_net_get_features(VirtIODevice *vdev)
         features |= (1 << VIRTIO_NET_F_GUEST_TSO6);
         features |= (1 << VIRTIO_NET_F_GUEST_ECN);
 
-        if (tap_has_ufo(n->vc->peer)) {
+        if (peer_has_ufo(n)) {
             features |= (1 << VIRTIO_NET_F_GUEST_UFO);
             features |= (1 << VIRTIO_NET_F_HOST_UFO);
         }
@@ -697,6 +708,7 @@  static void virtio_net_save(QEMUFile *f, void *opaque)
     qemu_put_byte(f, n->nomulti);
     qemu_put_byte(f, n->nouni);
     qemu_put_byte(f, n->nobcast);
+    qemu_put_byte(f, n->has_ufo);
 }
 
 static int virtio_net_load(QEMUFile *f, void *opaque, int version_id)
@@ -771,6 +783,13 @@  static int virtio_net_load(QEMUFile *f, void *opaque, int version_id)
         n->nobcast = qemu_get_byte(f);
     }
 
+    if (version_id >= 11) {
+        if (qemu_get_byte(f) && !peer_has_ufo(n)) {
+            qemu_error("virtio-net: saved image requires TUN_F_UFO support\n");
+            return -1;
+        }
+    }
+
     /* Find the first multicast entry in the saved MAC filter */
     for (i = 0; i < n->mac_table.in_use; i++) {
         if (n->mac_table.macs[i * ETH_ALEN] & 1) {