External DHCP detection is broken for a variety of reasons

Bug #1628645 reported by Mike Pontillo on 2016-09-28
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Mike Pontillo

Bug Description

There are a several major issues with the current external DHCP detection code:

(1) We are not parsing the DHCP options; we use a hard-coded index into the packet to get the DHCP server identifier (IP address).*

(2) The way we bind to the sending socket doesn't work for interfaces with no address. So we cannot discover external DHCP servers on interfaces with no IP address configured.**

(3) The way we bind to the receive socket causes a race condition that makes it likely the DHCP offer will come in before we are listening to the receive socket.

(4) Since we set the 'broadcast' flag in the DHCP discover packet, we don't reliably receive replies from all servers. (It ignores packets from the DD-WRT router I tested it with, for example.) This is because the DHCP server assumes it cannot talk to the client on a unicast IP/MAC and broadcasts the response from a bogus IP address instead, which the Linux TCP/IP stack never sends up to the socket. One way to fix this is to listen to DHCP replies via something like 'tcpdump' or libpcap instead of a UDP socket. Another way to fix this is to unset the broadcast flag.

(5) UDP is unreliable, and we only send a single DHCP discover packet out before assuming no servers responded.

(6) The deferToThread() call was used to cover too much code. It should
only need to cover code that could block.

(7) It is difficult to debug MAAS's interpretation of DHCP offer packets.

In provisioningserver/dhcp/detect.py, the following code exists:

        self.dhcp_server_ID = socket.inet_ntoa(data[245:249])

That is, we assume that the DHCP server address will always be contained in bytes 245 through 249 of the DHCP reply payload.

This is an incorrect assumption. DHCP replies contain variable length options. A deeper knowledge of the DHCP packet is required in order to correctly interpret DHCP replies and detect DHCP servers operating external to MAAS.

Fixing (2) requires additional privileges. To be specific, we need a way of sending a DHCP probe out directly on the interface, and a way of listening for the replies without relying on a socket bound to a unicast IP address. The listening portion is partially done in this branch (via `maas-rack observe-dhcp`) to ease debugging and support, but changing the design to use it in MAAS is a drastic design change that will not happen along with the other bug fixes to be done for this feature.

Related branches

Changed in maas:
importance: Undecided → High
milestone: none → 2.1.0
summary: - MAAS incorrectly interprets DHCP packets when detecting external DHCP
+ External DHCP detection is broken for a variety of reasons
description: updated
Changed in maas:
status: Triaged → In Progress
importance: High → Critical
description: updated
Changed in maas:
status: In Progress → Fix Committed
Changed in maas:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers