Server startup slow under BSD with many interfaces
name: dhcpd startup is terribly slow under BSD with hundreds or thousands of interfaces about: the startup is slow because getifaddrs() is walked for all interfaces O(n^2)
Describe the bug When running dhcpd under FreeBSD, bpf.c relies on getifaddrs() to determine the MAC address of each interface. getifaddrs() ends up being iterated entirely for each interface, yielding O(n^2) performance. This is not that big of a deal until you have hundreds or thousands of interfaces (e.g. VLANs) and the restart takes too long (30seconds) for a production network.
To Reproduce Steps to reproduce the behavior:
- Run dhcpd on thousands of interfaces
Expected behavior The startup time is very slow until the daemon responds on BPFs
ISC DHCP version: 4.4.2
OS: FreeBSD 12.1 from FBSD ports
Standard net/isc-dhcp44-server port
Additional context The hw address appears to only be needed when printing the Sending/Listening on BPF log_info lines, so simply skip MAC address lookup when started in quiet mode.
Patch There is probably a better solution, but the following patch addresses the problem under my environment. I don't have permissions to create an MR.
# Avoid expensive call to get_hw_addr in quiet mode (-q) # getifaddrs() is iterated n^2 times the number of interfaces (VLANs) --- common/bpf.c.orig 2020-07-29 16:02:17.000000000 -0400 +++ common/bpf.c 2020-07-29 16:02:20.000000000 -0400 @@ -116,7 +116,9 @@ log_fatal ("Can't attach interface %s to bpf device %s: %m", info -> name, filename); - get_hw_addr(info->name, &info->hw_address); + /* Don't need the hw_address in quiet mode */ + if (!quiet_interface_discovery) + get_hw_addr(info->name, &info->hw_address); return sock; }