diff options
author | Thomas Hebb <tommyhebb@gmail.com> | 2022-09-29 08:40:35 +0200 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2022-10-03 02:59:37 +0200 |
commit | 2ccada8dc4a3571468a335808fd6fe49b8c6c6dd (patch) | |
tree | 9e4244ff3341aaf86b135fb9c15e5608629f77fa /src/network/networkd-address.h | |
parent | resolve: fix typo (diff) | |
download | systemd-2ccada8dc4a3571468a335808fd6fe49b8c6c6dd.tar.xz systemd-2ccada8dc4a3571468a335808fd6fe49b8c6c6dd.zip |
network: don't forget old RAs when a new one arrives
IPv6 Neighbor Discovery lets us autoconfigure a link's IPv6 addresses,
routes, DNS servers, and DNS search domains by listening for Router
Advertisement (RA) packets broadcast by one or more routers on the link.
Each RA can contain zero or more "options," each describing one piece of
configuration (e.g. a single route).
Currently, when we receive an RA from a router, we delete any addresses,
routes, etc. that originated from that router's previous RAs unless
they're also present as options in the new RA.
That behavior is a violation of RFC 4861[1]. In Section 9, the RFC
states that
Senders MAY send a subset of options in different packets. ... Thus,
a receiver MUST NOT associate any action with the absence of an
option in a particular packet. This protocol specifies that
receivers should only act on the expiration of timers and on the
information that is received in the packets.
Several other passages in the RFC reiterate this. Section 6.2.3:
A router MAY choose not to include some or all options when sending
unsolicited Router Advertisements.
Section 6.3.4:
Hosts accept the union of all received information; the receipt of a
Router Advertisement MUST NOT invalidate all information received in
a previous advertisement or from another source.
At least one consumer router in production today, the Google Nest Wifi,
often sends RAs that omit its global IPv6 prefix. When current versions
of systemd-networkd receive those RAs, they immediately delete the
interface's global IPv6 address, which breaks IPv6 connectivity.
Fix the issue by removing the invalidation logic entirely. It's not
needed at all, since we already invalidate addresses, routes, and DNS
configuration when the interface goes down or their lifetimes expire.
This fix does have the side effect of preventing changes to the .network
file (e.g. denylisted prefixes, whether to add routes from RAs) from
taking effect as soon as a new RA arrives. Instead, a full interface
reconfiguration is needed. But triggering those changes on RA receipt
was already rather arbitrary and out of the administrator's control, so
I think this change is fine.
commit 69203fba700e ("network: ndisc: remove old addresses and routes
after at least one SLAAC address becomes ready") introduced this
behavior. commit 50550722e3ba fixed it partially, by preventing one
router's RAs from invalidating another router's configuration.
[1] https://www.rfc-editor.org/rfc/rfc4861
Fixes: 69203fba700e ("network: ndisc: remove old addresses and routes after at least one SLAAC address becomes ready")
Diffstat (limited to 'src/network/networkd-address.h')
-rw-r--r-- | src/network/networkd-address.h | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/src/network/networkd-address.h b/src/network/networkd-address.h index d1eff9090a..ef29caf4e7 100644 --- a/src/network/networkd-address.h +++ b/src/network/networkd-address.h @@ -120,7 +120,7 @@ int address_compare_func(const Address *a1, const Address *a2); DEFINE_NETWORK_CONFIG_STATE_FUNCTIONS(Address, address); -void link_mark_addresses(Link *link, NetworkConfigSource source, const struct in6_addr *router); +void link_mark_addresses(Link *link, NetworkConfigSource source); CONFIG_PARSER_PROTOTYPE(config_parse_address); CONFIG_PARSER_PROTOTYPE(config_parse_broadcast); |