I'm sponsoring this case for myself. The timeout is set for 10/9/2007.
Overview
--------
This case proposes a new IP_DHCPINIT_IF socket option that allows our
DHCP client to be entirely sockets-based while maintaining maximum
interoperability with DHCP servers. The proposed stability is
Consolidation Private, and patch binding is requested.
Details
-------
While DHCP is a UDP-based protocol and thus in theory our DHCP client
should be able to use the standard sockets-based API to obtain a lease
for an IPv4 address, subtleties in our IP implementation and in the DHCP
protocol definition itself have thus far prevented this. As a result,
our DHCP client instead makes use of the low-level DLPI API until a
lease on an IPv4 address has been obtained, and then switches over to
sockets.
Complexity and code duplication issues aside (e.g., the client has to do
its own UDP and IP checksum calculations when using DLPI), use of DLPI
prevents DHCP from working with IP-layer technologies such as IPMP,
sidesteps IP Filter policies for DHCP traffic, and interferes with
Dynamic Reconfiguration (e.g., an IP interface trying to obtain a DHCP
lease via DLPI will cause DR removal of the underlying link to fail).
Thus, we'd like to update the DHCP client to be sockets-based.
By and large, resolving the necessary issues to allow this have been
straightforward. One difficulty remains: handling DHCPOFFER and DHCPACK
packets sent by the DHCP server to the DHCP client prior to the client
obtaining a lease. Specifically, RFC2131 (which details DHCP) states:
If 'giaddr' is zero and 'ciaddr' is zero, and the broadcast bit is
set, then the server broadcasts DHCPOFFER and DHCPACK messages to
0xffffffff. If the broadcast bit is not set and 'giaddr' is zero and
'ciaddr' is zero, then the server _unicasts_ DHCPOFFER and DHCPACK
messages to the client's hardware address _and_ 'yiaddr' address.
[ Note that "yiaddr" is the IP address being offered to the client
which it has no a priori knowledge of. ]
... and then goes on to state:
The BROADCAST bit will provide a _hint_ to the DHCP server and BOOTP
relay agent to broadcast any messages to the client on the client's
subnet.
That is, even if the client sets the broadcast bit, the server is free
to ignore the bit and unicast the DHCPOFFER and DHCPACK packets back to
the client. Indeed, it seems that not all DHCP server implementations
respect the broadcast bit -- as evidenced by this Microsoft knowledge
base article:
http://support.microsoft.com/kb/928233
Thus, to preserve interoperability, we propose a simple but admittedly
unfortunate socket option: IP_DHCPINIT_IF. As with other IP_*_IF socket
options, IP_DHCPINIT_IF takes a pointer to an integer indicating the IP
interface to enable "DHCPINIT" mode on. Once DHCPINIT mode is enabled
on an interface, the IP module will treat any IP unicast DHCP packets
received on that interface as if they were sent to an IP address that
was owned by the system. This will allow the DHCP client (which will
have a socket bound to INADDR_ANY and the appropriate DHCP port) to
receive the packets. The DHCP client will then -- as usual -- perform
filtering based on the "xid" contained with the DHCP portion of the
packet to determine if the packet is a response to a previous request.
As with other IP_*_IF socket options, only one interface may be placed
in IP_DHCPINIT_IF mode on a given socket at a time, and specifying an
interface index of zero disables the socket option. Closing the socket
also disables the socket option. Multiple consumers of IP_DHCPINIT_IF
will not interfere with one another -- that is, the interface will
remain in DHCPINIT mode as long as there as at least one socket that has
enabled IP_DHCPINIT_IF for that interface.
Because enabling IP_DHCPINIT_IF disables the IP "fastpath", use of
IP_DHCPINIT_IF will require PRIV_SYS_IP_CONFIG. The DHCP client will
only use IP_DHCPINIT_IF during lease acquisition (the period where DLPI
is currently used).
Because DHCPv6 uses IPv6 link-local addresses, it sidesteps this issue
entirely. Thus, no IPV6_DHCPINIT_IF is necessary.
--
meem