public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Work around dhclient brokenness
@ 2008-08-15 19:47 Anthony Liguori
  2008-08-18 10:56 ` Avi Kivity
  2008-08-24  8:39 ` Herbert Xu
  0 siblings, 2 replies; 27+ messages in thread
From: Anthony Liguori @ 2008-08-15 19:47 UTC (permalink / raw)
  To: kvm; +Cc: Avi Kivity, Mark McLoughlin, Rusty Russell, Herbert Xu

With the latest GSO/csum offload patches, any guest using an unpatched version
of dhclient (any Ubuntu guest, for instance), will no longer be able to get
a DHCP address.

dhclient is actually at fault here.  It uses AF_PACKET to receive DHCP responses
but does not check auxdata to see if the packet has a valid csum.  This causes
it to throw out the DHCP responses it gets from the virtio interface as there
is not a valid checksum.

Fedora has carried a patch to fix their dhclient (it's needed for Xen too) but
this patch has not made it into a release of dhclient.  AFAIK, the patch is in
the dhclient CVS but I cannot confirm since their CVS is not public.

This patch, suggested by Rusty, looks for UDP packets (of a normal MTU) and
explicitly adds a checksum to them if they are missing one.  We could further
refine the search criteria based on srcport but that's probably unnecessary.

This allows unpatched dhclients to continue to work without needing to update
the guest kernels.

diff --git a/qemu/hw/virtio-net.c b/qemu/hw/virtio-net.c
index 61215b1..2e2ff35 100644
--- a/qemu/hw/virtio-net.c
+++ b/qemu/hw/virtio-net.c
@@ -154,6 +154,29 @@ static int virtio_net_can_receive(void *opaque)
     return 1;
 }
 
+/* dhclient uses AF_PACKET but doesn't pass auxdata to the kernel so
+ * it never finds out that the packets don't have valid checksums.  This
+ * causes dhclient to get upset.  Fedora's carried a patch for ages to
+ * fix this with Xen but it hasn't appeared in an upstream release of
+ * dhclient yet.
+ *
+ * To avoid breaking existing guests, we catch udp packets and add
+ * checksums.  This is terrible but it's better than hacking the guest
+ * kernels.
+ */
+static void work_around_broken_dhclient(struct virtio_net_hdr *hdr,
+                                        const uint8_t *buf, size_t size)
+{
+    if ((hdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) && /* missing csum */
+        (size > 18 && size < 1500) && /* normal sized MTU */
+        (buf[12] == 0x08 && buf[13] == 0x00) && /* ethertype == IPv4 */
+        (buf[23] == 17)) { /* ip.protocol == UDP */
+        /* FIXME this cast is evil */
+        net_checksum_calculate((uint8_t *)buf, size);
+        hdr->flags &= ~VIRTIO_NET_HDR_F_NEEDS_CSUM;
+    }
+}
+
 static void virtio_net_receive(void *opaque, const uint8_t *buf, int size)
 {
     VirtIONet *n = opaque;
@@ -180,6 +203,7 @@ static void virtio_net_receive(void *opaque, const uint8_t *buf, int size)
     if (tap_has_vnet_hdr(n->vc->vlan->first_client)) {
 	memcpy(hdr, buf, sizeof(*hdr));
 	offset += total;
+        work_around_broken_dhclient(hdr, buf + offset, size - offset);
     }
 
     /* copy in packet.  ugh */

^ permalink raw reply related	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2008-08-25  4:01 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-08-15 19:47 [PATCH] Work around dhclient brokenness Anthony Liguori
2008-08-18 10:56 ` Avi Kivity
2008-08-18 11:01   ` Herbert Xu
2008-08-18 11:06     ` Avi Kivity
2008-08-18 11:34       ` Herbert Xu
2008-08-18 11:40         ` Avi Kivity
2008-08-18 11:44           ` Herbert Xu
2008-08-18 12:15             ` Avi Kivity
2008-08-19  0:45             ` Rusty Russell
2008-08-19  3:17               ` Chris Wedgwood
2008-08-19  4:41                 ` Rusty Russell
2008-08-19  5:13                   ` Chris Wedgwood
2008-08-19  5:17                     ` Herbert Xu
2008-08-19  5:28                       ` Chris Wedgwood
2008-08-19  9:10                         ` Rusty Russell
2008-08-19 15:05                           ` Chris Wedgwood
2008-08-25  4:01                             ` Rusty Russell
2008-08-19  9:08                       ` Rusty Russell
2008-08-19  9:56                         ` Herbert Xu
2008-08-19 11:36                           ` Rusty Russell
2008-08-19 23:35                         ` Anthony Liguori
2008-08-19  9:12               ` Avi Kivity
2008-08-19 13:42                 ` Anthony Liguori
2008-08-19 13:50                   ` Avi Kivity
2008-08-19 13:54                     ` Anthony Liguori
2008-08-19 14:00                       ` Avi Kivity
2008-08-24  8:39 ` Herbert Xu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox