Fedora dhclient broken
Monday, December 10. 2018
I'm not a huge fan of NetworkManager. Since I am a fan of many RedHat products, it creates a nice conflict. They develop it, so it is pre-installed in all of RedHat's Linuxes. Luckily its very easy to yank off and replace with something that actually works and is suitable for server computing.
Also, a third player exists in the Linux networking setup -scene. systemd-networkd (https://www.freedesktop.org/software/systemd/man/systemd-networkd.html) does exactly the same as NetworkManager or classic network-scripts would do. It is the newcomer, but since everybody's box already has systemd, using it to run your networking makes sense to some.
I don't know exactly when, but at some point Fedora simply abandoned all the classic ways of doing networking. I know for a fact, that in Fedora 26 ISC's dhclient worked ok, but looks like around the time of 26 release, they simply broke it. Now we're at 29 and it has the same code as 28 did. Since almost nobody uses classic networking, this bug went unnoticed for a while. There is a bug in RedHat's Bugzilla which looks similar to what I'm experiencing: Bug 1314203 - dhclient establishes a lease on the explicitly specified interface, but then endlessly retries old leases on other interfaces, but looks like it didn't get any attention. To make this bug even more difficult to spot, you need to have multiple network interfaces in your machine for this problem to even exist. Most people don't, and looks like those who do, aren't running dhclient
.
The issue, in detail, is following:
When run ifup eno1
, no IP-address will be issued by my ISP for that interface.
When running dhclient in diagnostics mode, with following command:
/sbin/dhclient -1 -d -pf /run/dhclient-eno1.pid -H myPCame eno1
output will be:
Internet Systems Consortium DHCP Client 4.3.6
Copyright 2004-2017 Internet Systems Consortium.
All rights reserved.
For info, please visit https://www.isc.org/software/dhcp/
Listening on LPF/enp3s0f1/90:e2:ba:00:00:01
Sending on LPF/enp3s0f1/90:e2:ba:00:00:01
Listening on LPF/eno1/60:a4:4c:00:00:01
Sending on LPF/eno1/60:a4:4c:00:00:01
Listening on LPF/enp3s0f0/90:e2:ba:00:00:02
Sending on LPF/enp3s0f0/90:e2:ba:00:00:02
Sending on Socket/fallback
DHCPDISCOVER on enp3s0f1 to 255.255.255.255 port 67 interval 3 (xid=0x90249a1f)
DHCPREQUEST on eno1 to 255.255.255.255 port 67 (xid=0xe612e570)
DHCPDISCOVER on enp3s0f0 to 255.255.255.255 port 67 interval 5 (xid=0xb568cb15)
DHCPACK from 62.248.219.2 (xid=0xe612e570)
DHCPREQUEST on enp3s0f0 to 255.255.255.255 port 67 (xid=0xb568cb15)
DHCPOFFER from 84.249.192.3
DHCPACK from 84.249.192.3 (xid=0xb568cb15)
DHCPDISCOVER on enp3s0f1 to 255.255.255.255 port 67 interval
Notice how DHCP-client was requested on network interface eno1
, but it is actually run for all there are. For me, this is a real problem, so I spent a while on it. Bug report is at Bug 1657848 - dhclient ignores given interface and it contains my patch:
--- ../dhcp-4.3.6/common/discover.c 2018-12-10 16:14:50.983316937 +0200
+++ common/discover.c 2018-12-10 15:20:12.825557954 +0200
@@ -587,7 +587,7 @@
state == DISCOVER_REQUESTED))
ir = 0;
else if (state == DISCOVER_UNCONFIGURED)
- ir = INTERFACE_REQUESTED | INTERFACE_AUTOMATIC;
+ ir = INTERFACE_AUTOMATIC;
else {
ir = INTERFACE_REQUESTED;
if (state == DISCOVER_RELAY && local_family == AF_INET) {
My fix is to break the functionality of dhclient
. If you don't specify an interface for dhclient
to run on, it will run on all. To me (or my network-scripts) that won't make any sense, so I'm choosing to run only on specified interfaces, or interface in my case. This patch when applied and compiled to a binary will fully fix the problem.