slow modem results in dhclient 'no link, giving up', ignores timeout setting

My cable modem takes around 5 minutes to boot up and enable its LAN ports. This is far too slow for freebsd's dhclient, which gives up and causes a bunch of other things to fall over (like the pf outbound NAT rule) because it doesn't set an ip address on the interface using a saved lease. I set a 'timeout' of 600 in dhclient.conf, but it seems to be ignoring it or using a short hardcoded wait time in this case. (Also, the timestamps are all the same for some reason until some services are started; not sure how to get proper timing info for the startup process.)

Code:
Dec  1 09:29:47 srv kernel: Starting dhclient.
Dec  1 09:29:47 srv kernel: re1: no link .....
Dec  1 09:29:47 srv kernel: ......... giving up
Dec  1 09:29:47 srv kernel: /etc/rc.d/dhclient: WARNING: failed to start dhclient
Dec  1 09:29:47 srv kernel: Starting Network: lo0 re0 re1.
...
Dec  1 09:29:47 srv kernel: re1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
Dec  1 09:29:47 srv kernel:  options=8209b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,WOL_MAGIC,LINKSTATE>
Dec  1 09:29:47 srv kernel:  ether ****
Dec  1 09:29:47 srv kernel:  inet6 fe80::****%re1 prefixlen 64 scopeid 0x2
Dec  1 09:29:47 srv kernel:  media: Ethernet autoselect (none)
Dec  1 09:29:47 srv kernel:  status: no carrier
...
Dec  1 09:29:47 srv kernel: re0: link state changed to UP
Dec  1 09:29:47 srv kernel: re1: link state changed to DOWN
Dec  1 09:29:47 srv kernel: lo0: link state changed to UP
Dec  1 09:29:47 srv kernel: re0: link state changed to DOWN
Dec  1 09:29:47 srv kernel: re0: link state changed to UP
Dec  1 09:29:47 srv kernel: re1: link state changed to UP
Dec  1 09:29:47 srv kernel: re1: link state changed to DOWN
Dec  1 09:29:47 srv kernel: re1: link state changed to UP
...
Dec  1 09:29:47 srv kernel: Starting devd.
Dec  1 09:29:47 srv kernel: Waiting 30s for the default route interface: ...
Dec  1 09:29:47 srv kernel: ........................
Dec  1 09:29:47 srv kernel: ..
...
Dec  1 09:29:47 srv kernel: Enabling pf
Dec  1 09:29:47 srv kernel: /etc/pf.conf:25: rule expands to no valid combination
Dec  1 09:29:47 srv kernel: pfctl: Syntax error in config file: pf rules not loaded
Dec  1 09:29:47 srv kernel: /etc/rc: WARNING: Unable to load /etc/pf.conf.
...
Dec  1 09:31:36 srv dhclient[1237]: New IP Address (re1): ****
Dec  1 09:31:36 srv dhclient[1241]: New Subnet Mask (re1): ****
Dec  1 09:31:36 srv dhclient[1245]: New Broadcast Address (re1): ****
Dec  1 09:31:36 srv dhclient[1249]: New Routers (re1): ****
 
Are you using SYNCDHCP?
Why not wait until the cable-modem reaches a usable condition before starting your FreeBSD box?


Update:
Yes, I've seen your other messages. I was just going to delete my message, I assumed it was useless.
 
Yes, as a global setting.
ifconfig_re1="DHCP" synchronous_dhclient="YES"

The router pc is set to automatically power on after power is restored. The modem does so as well. The problem is that synchronous dhclient only waits 10(?) seconds for the wan link before giving up and not doing anything. This behavior seems to be separate from when the link _is_ up, where it will attempt to get a dhcp lease for 'timeout' seconds and then fall back to a saved lease. None of this happens when the link is down, and the manual page doesn't seem to list any settings to control this behavior.

This breaks my ipv6 tunnel script, which requires a valid ip address for the "ifconfig tunnel" command.
It also breaks outbound NAT. Idk if I can make it more robust. nat on re1 inet from !re1 to any -> (re1:0)
 
if the media has no link/carrier dhclient with exit after 10 secs
you can
put a fast booting no management switch between pc and modem
change dhclient_program in rc.conf with some shell script that will wait more / run the original dhclient more times
 
Tbh in that case I'd rather patch dhclient to wait longer.
I made this post to make sure I'm not missing something obvious. I thought about it for a bit, and even though this behavior is inappropriate for a router OS, I also get that it can't just block on foreground dhclient for long because that delays the whole startup procedure. And sometimes the wan link is down on purpose, so waiting for 10 minutes would be pointless.
In that case, it would make more sense to make the system configuration and scripts robust enough to handle starting up without a wan link. Currently I'm seeing multiple failures which require manual recovery - named doesn't bind to wan, pf outright doesn't load and I think fails wide open, and my ipv6 tunnel does not get set up. I don't think writing a polling/retry script for these is the best solution.
 
Any chance you could delay the power on of the FreeBSD host? To give the modem some time to boot?

Modems take a bit of time to boot, my old cable modem certainly took its sweet time.
 
if you patch it you may want to change its name and you don't have to care when you update
also look at dhcpcd in ports
that seems to wait forever if the timeout is 0
 
Could this work with a 6-minute delay?

/etc/rc.conf:

Code:
netwait_enable="YES"
netwait_if="<yourmodemif>0"
netwait_if_timeout="360"

or

Code:
netwait_enable="YES"
netwait_timeout="360"
 
Yeah, that's what my modem did too. When it powers up the ethernet is active, during boot it goes down and up a few times before it's properly active.
 
Could this work with a 6-minute delay?
netwait_enable="YES"
No, in rcorder, dhclient is the very first thing that runs, netwait is really late, right before NETWORKING, and probably meant for non-critical services. It will not postpone dhclient.
 
You can set a static IP, set a timeout, and wait for the ping. Dhclient would be out of the way.

rc.conf()
netwait_enable
(bool) If set to "YES", delays the start of network-reliant
services until netwait_if is up and ICMP packets to a des-
tination defined in netwait_ip are flowing. Link state is
examined first, followed by "pinging" an IP address to ver-
ify network usability. If no destination can be reached or
timeouts are exceeded, network services are started anyway
with no guarantee that the network is usable. Use of this
variable requires both netwait_ip and netwait_if to be set.
⚠️Use of this variable requires both netwait_ip and netwait_if to be set.

Or:
rcorder()
# REQUIRE: networking
 
Back
Top