+static void virtio_net_vnet_pre_save(void *opaque)
+{
+ struct VirtIONetMigTmp *tmp = opaque;
+
+ tmp->has_vnet_hdr = tmp->parent->has_vnet_hdr;
+}
+
+static const VMStateDescription vmstate_virtio_net_has_vnet = {
+ .name = "virtio-net-vnet",
+ .post_load = virtio_net_vnet_post_load,
+ .pre_save = virtio_net_vnet_pre_save,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32(has_vnet_hdr, struct VirtIONetMigTmp),
+ VMSTATE_END_OF_LIST()
+ },
+};
+
+static const VMStateDescription vmstate_virtio_net_device = {
+ .name = "virtio-net-device",
+ .version_id = VIRTIO_NET_VM_VERSION,
+ .minimum_version_id = VIRTIO_NET_VM_VERSION,
+ .post_load = virtio_net_post_load_device,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT8_ARRAY(mac, VirtIONet, ETH_ALEN),
+ VMSTATE_STRUCT_POINTER(vqs, VirtIONet,
+ vmstate_virtio_net_queue_tx_waiting,
+ VirtIONetQueue),
+ VMSTATE_UINT32(mergeable_rx_bufs, VirtIONet),
+ VMSTATE_UINT16(status, VirtIONet),
+ VMSTATE_UINT8(promisc, VirtIONet),
+ VMSTATE_UINT8(allmulti, VirtIONet),
+ VMSTATE_UINT32(mac_table.in_use, VirtIONet),
+
+ /* Guarded pair: If it fits we load it, else we throw it away
+ * - can happen if source has a larger MAC table.; post-load
+ * sets flags in this case.
+ */
+ VMSTATE_VBUFFER_MULTIPLY(mac_table.macs, VirtIONet,
+ 0, mac_table_fits, mac_table.in_use,
+ ETH_ALEN),
+ VMSTATE_UNUSED_VARRAY_UINT32(VirtIONet, mac_table_doesnt_fit, 0,
+ mac_table.in_use, ETH_ALEN),
+
+ /* Note: This is an array of uint32's that's always been saved as a
+ * buffer; hold onto your endiannesses; it's actually used as a bitmap
+ * but based on the uint.
+ */
+ VMSTATE_BUFFER_POINTER_UNSAFE(vlans, VirtIONet, 0, MAX_VLAN >> 3),
+ VMSTATE_WITH_TMP(VirtIONet, struct VirtIONetMigTmp,
+ vmstate_virtio_net_has_vnet),
+ VMSTATE_UINT8(mac_table.multi_overflow, VirtIONet),
+ VMSTATE_UINT8(mac_table.uni_overflow, VirtIONet),
+ VMSTATE_UINT8(alluni, VirtIONet),
+ VMSTATE_UINT8(nomulti, VirtIONet),
+ VMSTATE_UINT8(nouni, VirtIONet),
+ VMSTATE_UINT8(nobcast, VirtIONet),
+ VMSTATE_WITH_TMP(VirtIONet, struct VirtIONetMigTmp,
+ vmstate_virtio_net_has_ufo),
+ VMSTATE_SINGLE_TEST(max_queues, VirtIONet, max_queues_gt_1, 0,
+ vmstate_info_uint16_equal, uint16_t),
+ VMSTATE_UINT16_TEST(curr_queues, VirtIONet, max_queues_gt_1),
+ VMSTATE_WITH_TMP(VirtIONet, struct VirtIONetMigTmp,
+ vmstate_virtio_net_tx_waiting),
+ VMSTATE_UINT64_TEST(curr_guest_offloads, VirtIONet,
+ has_ctrl_guest_offloads),
+ VMSTATE_END_OF_LIST()
+ },
+};
+