Add hvparam to disable VNET_HDR on tap devices
authorStratos Psomdakis <psomas@grnet.gr>
Wed, 24 Jul 2013 11:52:55 +0000 (14:52 +0300)
committerGuido Trotter <ultrotter@google.com>
Thu, 25 Jul 2013 11:20:32 +0000 (13:20 +0200)
IFF_VNET_HDR allows tap devices to extract a VIRTIO_NET_HDR from pkts
going through the tap iface, enabling segmentation offload for the
virtio nics.

Current (Debian) kernels (3.2 for Debian Squeeze backrports / Wheezy)
don't seem able to handle well VMs with 'broken' virtio ifaces (e.g.
FreeBSD virtio-net driver), using GSO. Broken or malicious virtio-net
drivers can cause the host kernel to flood the logs with WARNs(),
effectively live-locking the system and affecting its overall stabitlity
(eg DRBD disconnects).

The WARN() flooding has been fixed / ratelimited in Linus' tree, but it
hasn't been backported to -stable.

This patch adds the vnet_hdr hvparam for KVM, to select whether the tap
devices used for KVM virtio ifaces will get created with VNET_HDR
support (IFF_VNET_HDR), even when the underlying kernel supports it, in
order to avoid this issue.

Signed-off-by: Stratos Psomadakis <psomas@grnet.gr>
Reviewed-by: Guido Trotter <ultrotter@google.com>

lib/constants.py
lib/hypervisor/hv_kvm.py

index 0beb4d3..339ead8 100644 (file)
@@ -949,6 +949,7 @@ HV_KVM_EXTRA = "kvm_extra"
 HV_KVM_MACHINE_VERSION = "machine_version"
 HV_KVM_PATH = "kvm_path"
 HV_VIF_TYPE = "vif_type"
+HV_VNET_HDR = "vnet_hdr"
 
 
 HVS_PARAMETER_TYPES = {
@@ -1019,6 +1020,7 @@ HVS_PARAMETER_TYPES = {
   HV_KVM_EXTRA: VTYPE_STRING,
   HV_KVM_MACHINE_VERSION: VTYPE_STRING,
   HV_VIF_TYPE: VTYPE_STRING,
+  HV_VNET_HDR: VTYPE_BOOL,
   }
 
 HVS_PARAMETERS = frozenset(HVS_PARAMETER_TYPES.keys())
@@ -2103,6 +2105,7 @@ HVC_DEFAULTS = {
     HV_VGA: "",
     HV_KVM_EXTRA: "",
     HV_KVM_MACHINE_VERSION: "",
+    HV_VNET_HDR: True,
     },
   HT_FAKE: {},
   HT_CHROOT: {
index 897d1c8..b3eaf7e 100644 (file)
@@ -533,6 +533,7 @@ class KVMHypervisor(hv_base.BaseHypervisor):
     constants.HV_VGA: hv_base.NO_CHECK,
     constants.HV_KVM_EXTRA: hv_base.NO_CHECK,
     constants.HV_KVM_MACHINE_VERSION: hv_base.NO_CHECK,
+    constants.HV_VNET_HDR: hv_base.NO_CHECK,
     }
 
   _VIRTIO = "virtio"
@@ -1520,7 +1521,7 @@ class KVMHypervisor(hv_base.BaseHypervisor):
           devlist = self._GetKVMOutput(kvm_path, self._KVMOPT_DEVICELIST)
           if self._NEW_VIRTIO_RE.search(devlist):
             nic_model = self._VIRTIO_NET_PCI
-            vnet_hdr = True
+            vnet_hdr = up_hvp[constants.HV_VNET_HDR]
         except errors.HypervisorError, _:
           # Older versions of kvm don't support DEVICE_LIST, but they don't
           # have new virtio syntax either.