Go to file
Stefan Sperling 3215c8f97b
Fix rt_cmp_dest() for equivalent network prefixes with different netmasks. (#52)
When rt_add() decides that it must delete+add a route in order to change
the routing table entry, a wrong RB tree lookup result can throw it off
the rails. In the case observed, a static /64 prefix was deleted from
vlan1 while dhcpcd intended to delete its reject route bound to lo0.

Given two routes in the table, the loopback reject route installed by
dhcpd for my /48 prefix, and a cloning route for a /64 prefix on vlan1:

2001:db8::/48 ::1         UGR        0        0 32768    56 lo0  
2001:db8::/64 2001:db8::1 UCn        1        2     -     4 vlan1

When searching the OS routing table dhcpcd attempts to tell routes apart
based only on the masked destination address. In the above case the masked
destinations look identical. The only difference is the length of the netmask.
The function rt_cmp_dest() didn't detect this and returned the /64 route
while dhcpcd was in fact searching for the /48 route.

This patch fixes the lookup by running rt_cmp_netmask() if the masked
destination comparison via sa_cmp() leaves us with a tie. With this change
dhcpcd deletes the /48 route as intended, and leaves the /64 route alone.

I had to move the rt_cmp_dest() function down since it needs to use the
static helper function rt_cmp_netmask(), which happened to be defined
just below rt_cmp_dest().

Why am I using an overlapping static prefix? The answer is that my ISP
assigns a static /48 prefix but won't route IPv6 unless my router sends
a DHCPv6 request when it connects via PPPoE. I configure static IPv6 subnets
on LAN interfaces and have configured dhcpcd to obtain a /48 prefix lease
without setting addresses on any internal interfaces.
My dhcpcd.conf contains:
  ipv6only
  noipv6rs
  duid
  persistent
  option rapid_commit
  require dhcp_server_identifier
  script ""
  allowinterfaces pppoe0
  interface pppoe0
    ia_pd 1 /2001:db8::/48

This problem was found on OpenBSD, in case that matters for reproduction
of the issue.
2021-08-31 10:31:15 +01:00
compat Change copyright on setproctitle.h 2020-10-09 20:38:48 +01:00
hooks Force TOP as we know which directory we are in. 2021-02-05 22:41:16 +00:00
src Fix rt_cmp_dest() for equivalent network prefixes with different netmasks. (#52) 2021-08-31 10:31:15 +01:00
tests Force TOP as we know which directory we are in. 2021-02-05 22:41:16 +00:00
.gitignore linux: the default hostname is (none) 2020-03-31 19:45:17 +01:00
BUILDING.md hooks: add NOCARRIER_ROAMING reason 2020-12-27 19:53:31 +00:00
config-null.mk Compile embedded in without a config 2014-04-23 19:09:03 +00:00
configure configure: test -a|o is not POSIX 2021-05-04 12:34:01 -04:00
iconfig.mk make: support gmake-3 again. 2019-02-11 18:02:15 +00:00
LICENSE A belated welcome to 2021 2021-01-31 10:33:21 +00:00
Makefile make: clean before import-src 2020-07-02 14:05:19 +01:00
Makefile.inc install: Create DBDIR with mode 0750 by default 2020-09-15 11:45:21 +01:00
README.md README.md: remove dead reference to phabricator 2021-03-08 09:43:50 +00:00

dhcpcd

dhcpcd is a DHCP and a DHCPv6 client. It's also an IPv4LL (aka ZeroConf) client. In layman's terms, dhcpcd runs on your machine and silently configures your computer to work on the attached networks without trouble and mostly without configuration.

If you're a desktop user then you may also be interested in Network Configurator (dhcpcd-ui) which sits in the notification area and monitors the state of the network via dhcpcd. It also has a nice configuration dialog and the ability to enter a pass phrase for wireless networks.

dhcpcd may not be the only daemon running that wants to configure DNS on the host, so it uses openresolv to ensure they can co-exist.

See BUILDING.md for how to build dhcpcd.

Configuration

You should read the dhcpcd.conf man page and put your options into /etc/dhcpcd.conf. The default configuration file should work for most people just fine. Here it is, in case you lose it.

# A sample configuration for dhcpcd.
# See dhcpcd.conf(5) for details.

# Allow users of this group to interact with dhcpcd via the control socket.
#controlgroup wheel

# Inform the DHCP server of our hostname for DDNS.
hostname

# Use the hardware address of the interface for the Client ID.
#clientid
# or
# Use the same DUID + IAID as set in DHCPv6 for DHCPv4 ClientID as per RFC4361.
# Some non-RFC compliant DHCP servers do not reply with this set.
# In this case, comment out duid and enable clientid above.
duid

# Persist interface configuration when dhcpcd exits.
persistent

# Rapid commit support.
# Safe to enable by default because it requires the equivalent option set
# on the server to actually work.
option rapid_commit

# A list of options to request from the DHCP server.
option domain_name_servers, domain_name, domain_search, host_name
option classless_static_routes
# Respect the network MTU. This is applied to DHCP routes.
option interface_mtu

# Most distributions have NTP support.
#option ntp_servers

# A ServerID is required by RFC2131.
require dhcp_server_identifier

# Generate SLAAC address using the Hardware Address of the interface
#slaac hwaddr
# OR generate Stable Private IPv6 Addresses based from the DUID
slaac private

The dhcpcd man page has a lot of the same options and more, which only apply to calling dhcpcd from the command line.

Compatibility

dhcpcd-5 is only fully command line compatible with dhcpcd-4 For compatibility with older versions, use dhcpcd-4

Upgrading

dhcpcd-7 defaults the database directory to /var/db/dhcpcd instead of /var/db and now stores dhcpcd.duid and dhcpcd.secret in there instead of in /etc.

dhcpcd-9 defaults the run directory to /var/run/dhcpcd instead of /var/run and the prefix of dhcpcd has been removed from the files.

ChangeLog

We no longer supply a ChangeLog. However, you're more than welcome to read the commit log and archived release announcements.