[systemd-devel] networkd: IPv6 prefix delegation not updated when prefix changes
Tobias Brink
tobias.brink at gmail.com
Mon Apr 13 15:18:25 UTC 2020
Hello systemd devs and users,
my internet connection is established by a router provided by my ISP (a
Fritz Box to be precise). It can hand out delegated IPv6 prefixes via
DHCPv6. I use a Linux box in between this router and my internal network
to provide additional firewalling, OpenVPN, etc. For this, I request an
IPv6 prefix for the internal network using networkd. This works. But the
provider (like most non-business offerings) resets the public IPv4
address and IPv6 prefix from time to time. The prefix delegation on my
Linux box is not updated at this point and the old delegated prefix
expires. Only "networkctl reconfigure" on the external interface leads
to a new prefix delegation being obtained. Routes for the old prefixes,
though, remain indefinitely, potentially causing trouble.
I do believe this to be a problem with networkd, but I'm new to IPv6 and
wanted to ask here first if there's a problem with my configuration or
if the ISP-provided router is maybe buggy instead. If I should instead
open an issue on GitHub or if more information is needed, please tell
me.
All details below:
Setup
=====
I use the current Debian stable (buster) with systemd from backports
(systemd --version: "systemd 244 (244.3-1~bpo10+1)"). I also quickly
tried compiling and running networkd from git master, but the issue
seems to remain unfixed.
Configuration:
#/etc/systemd/network/10-enp3s0.network <- the "external" interface
[Match]
Name=enp3s0
[Network]
Address=<some RFC1918 IPv4 address>
Gateway=<IPv4 gateway>
Address=fdxx:xxxx:xxxx:xxxx::1/64
IPv6AcceptRA=yes
DHCP=ipv6
IPv6PrivacyExtensions=true
[DHCPv6]
# Note: usually, the ISP router is configured to only set the "Other
# Configuration" flag. I also tried changing it to set the "Managed"
# flag in router advertisements, but with the setting below, there
# is no difference in the behavior of networkd.
ForceDHCPv6PDOtherInformation=yes
#/etc/systemd/network/20-br0.network <- the "internal" interface
[Match]
Name=br0
[Network]
Address=<some RFC1918 IPv4 address>
Address=fdxx:xxxx:xxxx:yyyy::1/64
IPv6PrefixDelegation=yes
[IPv6PrefixDelegation]
Managed=yes
OtherInformation=yes
RouterLifetimeSec=7200
EmitDNS=yes
DNS=fdxx:xxxx:xxxx:yyyy::1
DNSLifetimeSec=7200
[IPv6Prefix]
Prefix=fdxx:xxxx:xxxx:yyyy::/64
ValidLifetimeSec=7200
PreferredLifetimeSec=3600
The issue
=========
This is an example observed with the help of tcpdump and log files. I
still have this data if more details are needed.
For the sake of the example, let's say the public IPv6 prefix was
2001:1:0:0::/56 before resetting the internet connection and
2001:2:0:0::/56 after.
0) enps0 has a prefix of 2001:1:0:0::/64 (obtained via router
advertisement); br0 a prefix 2001:1:0:1::/64 (obtained via DHCPv6
prefix delegation).
1) Internet connection is reset. The ISP-provided router sends a router
advertisement with a new IPv6 prefix 2001:2:0:0::/64 with a preferred
lifetime of 3600 and the old prefix 2001:1:0:0::/64 with a preferred
lifetime of 0. The "Other Configuration" flag is set.
2) networkd updates enp3s0 with this prefix. No DHCPv6 traffic is
triggered. The configuration of br0 remains unchanged. The old prefix
is no longer accepted by the ISP and IPv6 connectivity is lost for
the internal network.
3) A while later, the ISP-provided router sends a new router
advertisement, this time only containing the new IPv6 prefix
2001:2:0:0::/64. This triggers no changes in networkd.
4) Still a bit later, networkd wants to renew the 2001:1:0:1::/64 prefix
of br0 and sends a DHCPv6 Renew. The ISP-provided router responds
with "NoBindig", status message "prefix mismatch" (changing later to
"iapd not found"), which is of course correct. networkd, though, just
keeps retrying to renew that prefix without success.
At that point I can use "networkctl reconfigure enp3s0". This (almost)
fixes it and br0 obtains (for example) the new, valid prefix
2001:2:0:1::/64. Unfortunately, the routes for the old prefix
(2001:1:0:1::/64) still remain, even if this prefix no longer "belongs"
to me.
What I would have expected
==========================
Without being too familiar with the relevant RFCs, I would have thought
that networkd would trigger a DHCPv6 Solicit/Renew for the delegated prefixes
after step (1), updating the configuration as needed.
At the very least, in step (4), I would have thought that after being
unsuccessful in renewing the prefix, networkd would try to obtain a new
one. RFC 8415 (Sec. 18.2.10.1) seems to agree as far as I understand:
Upon a NoBinding response for any delegated prefix, the client should
send a Request.
I would also think that routes for which a NoBinding reponse was
received should be removed.
Additionally, it would be nice if "networkctl status <iface>" would
report the delegated prefixes of the interface. Currently, I can only
find them in the logs.
=====
As an aside, thanks for systemd and systemd-networkd. Apart from the
issue above, they have made my life much simpler!
Tobias
More information about the systemd-devel
mailing list