[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 17/19] Work around dhclient brokenness
From: |
Mark McLoughlin |
Subject: |
[Qemu-devel] [PATCH 17/19] Work around dhclient brokenness |
Date: |
Wed, 21 Oct 2009 12:27:56 +0100 |
From: Anthony Liguori <address@hidden>
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.
This allows unpatched dhclients to continue to work without needing to update
the guest kernels.
Signed-off-by: Anthony Liguori <address@hidden>
Signed-off-by: Mark McLoughlin <address@hidden>
---
hw/virtio-net.c | 29 +++++++++++++++++++++++++++++
1 files changed, 29 insertions(+), 0 deletions(-)
diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index 19d00a6..4590594 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -369,6 +369,34 @@ static int virtio_net_can_receive(VLANClientState *vc)
return do_virtio_net_can_receive(n, VIRTIO_NET_MAX_BUFSIZE);
}
+/* 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.
+ *
+ * N.B. if we introduce a zero-copy API, this operation is no longer free so
+ * we should provide a mechanism to disable it to avoid polluting the host
+ * cache.
+ */
+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 > 27 && size < 1500) && /* normal sized MTU */
+ (buf[12] == 0x08 && buf[13] == 0x00) && /* ethertype == IPv4 */
+ (buf[23] == 17) && /* ip.protocol == UDP */
+ (buf[34] == 0 && buf[35] == 67)) { /* udp.srcport == bootps */
+ /* FIXME this cast is evil */
+ net_checksum_calculate((uint8_t *)buf, size);
+ hdr->flags &= ~VIRTIO_NET_HDR_F_NEEDS_CSUM;
+ }
+}
+
static int iov_fill(struct iovec *iov, int iovcnt, const void *buf, int count)
{
int offset, i;
@@ -396,6 +424,7 @@ static int receive_header(VirtIONet *n, struct iovec *iov,
int iovcnt,
if (peer_has_vnet_hdr(n)) {
memcpy(hdr, buf, sizeof(*hdr));
offset = sizeof(*hdr);
+ work_around_broken_dhclient(hdr, buf + offset, size - offset);
}
/* We only ever receive a struct virtio_net_hdr from the tapfd,
--
1.6.2.5
- [Qemu-devel] [PATCH 07/19] net: add a client type code, (continued)
- [Qemu-devel] [PATCH 07/19] net: add a client type code, Mark McLoughlin, 2009/10/21
- [Qemu-devel] [PATCH 13/19] net: implement tap support for receive_raw(), Mark McLoughlin, 2009/10/21
- [Qemu-devel] [PATCH 05/19] net: refactor tap initialization, Mark McLoughlin, 2009/10/21
- [Qemu-devel] [PATCH 15/19] net: add tap_set_offload(), Mark McLoughlin, 2009/10/21
- [Qemu-devel] [PATCH 14/19] virtio-net: add vnet_hdr support, Mark McLoughlin, 2009/10/21
- [Qemu-devel] [PATCH 19/19] virtio-net: add tap_has_ufo flag to saved state, Mark McLoughlin, 2009/10/21
- [Qemu-devel] [PATCH 10/19] net: add an API for 'raw' packets, Mark McLoughlin, 2009/10/21
- [Qemu-devel] [PATCH 09/19] net: add flags parameter to packet queue interface, Mark McLoughlin, 2009/10/21
- [Qemu-devel] [PATCH 12/19] net: use qemu_send_packet_raw() in qemu_announce_self(), Mark McLoughlin, 2009/10/21
- [Qemu-devel] [PATCH 16/19] virtio-net: enable tap offload if guest supports it, Mark McLoughlin, 2009/10/21
- [Qemu-devel] [PATCH 17/19] Work around dhclient brokenness,
Mark McLoughlin <=
- [Qemu-devel] [PATCH 18/19] Enable UFO on virtio-net and tap devices, Mark McLoughlin, 2009/10/21
- [Qemu-devel] [PATCH 11/19] net: add receive_raw parameter to qemu_new_vlan_client(), Mark McLoughlin, 2009/10/21