When a prefix is delegated to an interface that is already sending
RAs, send an RA immediately to inform clients of the new prefix.
This allows them to start using it immediately instead of waiting
up to nearly 10 minutes (depending on when the last timed RA was
sent). This type of situation might occur if, for example, an
outage of the WAN connection caused the addresses and prefixes to
be lost and later regained after service was restored. The
condition for the number of RAs sent being above 0 simultaneously
ensures that RADV is already running and that this code doesn't
send any RAs before the timed RAs have started when the interface
first comes up.
While investigating https://github.com/systemd/systemd/issues/16356, I
discovered that networkd stops the radv service before adding or updating
prefixes and then starts it again. This causes networkd to send an RA with
a router lifetime of zero, causing the routes to flap on systems receiving
the RA for a fraction of a second before radv is started again and proper
RAs are sent. That has the potential to cause issues with latency-sensitive
traffic like gaming or VoIP. This patch adds a boolean argument to the
sd_radv_stop() function to control this behavior. The zero lifetime RA is
still sent whenever radv is actually being stopped, but when it is being
restarted for a prefix update (from networkd-dhcp6.c), the final RA is no
longer sent to avoid the route flapping.
The RFC states that lifetime (AdvDefaultLifetime) must be at least
MaxRtrAdvInterval (which more or less corresponds to SD_RADV_DEFAULT_MAX_TIMEOUT_USEC
in systemd).
To fulfill this limit, virtually lower MaxRtrAdvInterval and MinRtrAdvInterval
accordingly.
Also check that min is not lower than 3s and max is not lower than 4s.
According to our CODING_STYLE our library code should generally not log
beyond LOG_DEBUG. Let's hence get rid of log_radv_warning_errno() and
just use log_radv_errno() instead.
This part of the copyright blurb stems from the GPL use recommendations:
https://www.gnu.org/licenses/gpl-howto.en.html
The concept appears to originate in times where version control was per
file, instead of per tree, and was a way to glue the files together.
Ultimately, we nowadays don't live in that world anymore, and this
information is entirely useless anyway, as people are very welcome to
copy these files into any projects they like, and they shouldn't have to
change bits that are part of our copyright header for that.
hence, let's just get rid of this old cruft, and shorten our codebase a
bit.
Let's add "const" where we don't change structures passed.
Also, we generally use "unsigned char" for IP prefix length values, do
so here too. Previously different parts of the sd-radv.h API used
different types for this.
sd_radv_stop is called from two places. if sd_radv_stop is alrady
success then just don't try to close it .
```
systemd-networkd[604]: RADV: Stopping IPv6 Router Advertisement daemon
systemd-networkd[604]: RADV: Unable to send last Router Advertisement with router lifetime set to zero: Bad file descriptor <==================HERE
systemd-networkd[604]: RADV: Updated prefix 2a0a:*:*:fc::/64 preferred 1h valid 2h
systemd-networkd[604]: RADV: Started IPv6 Router Advertisement daemon
```
Closes one of the issue #8960
Files which are installed as-is (any .service and other unit files, .conf
files, .policy files, etc), are left as is. My assumption is that SPDX
identifiers are not yet that well known, so it's better to retain the
extended header to avoid any doubt.
I also kept any copyright lines. We can probably remove them, but it'd nice to
obtain explicit acks from all involved authors before doing that.
Both netinet/icmp6.h and linux/in6.h will define struct in6_addr, and in
user space we want to use the netinet/icmp6.h variant.
Fixes build problem:
In file included from src/libsystemd-network/sd-radv.c:23:0:
/home/hegtvedt/work/os/product/sunrise/root/_build/v2/include/linux/in6.h:30:8:
error: redefinition of 'struct in6_addr'
As DHCPv6 leases may expire at some point, the delegated prefixes
have to be removed. Add a prefix removal function to the Router
Advertisement handling code.
Add a boolean that indicates whether the prefixes will always exist
or if they will time out after the assigned valid lifetime. In the
latter case calculate the expiry times for both preferred and valid
lifetimes for the prefixes, and decrease the remaining lifetimes
each time when a Router Advertisement is sent.
Should the prefix be updated, re-calculate the prefix lifetime. When
updating, update the existing entry, if any, with the lifetimes of
the added entry as the existing entry has its lifetimes set
according to its previously calculated expiry times.
Add Router Advertisement DNS Search List option as specified
in RFC 8106. The search list option uses and identical option
header as the RDNSS option and therefore the option header
structure can be reused.
If systemd is compiled with IDNA support, internationalization
of the provided search domain is applied, after which the search
list is written in wire format into the DNSSL option.
Receive Router Solicitations and send a unicast Router Advertisment
in response. Refactor ICMPv6 packet handling code so that the common
ICMPv6 validation parts are reused between the existing router
discovery and the new functionality adding reception of Router
Solicitation messages.