diff options
-rw-r--r-- | man/systemd.network.xml | 12 | ||||
-rw-r--r-- | src/network/networkd-link.c | 50 | ||||
-rw-r--r-- | src/network/networkd-link.h | 1 | ||||
-rw-r--r-- | src/network/networkd-manager.c | 3 | ||||
-rw-r--r-- | src/network/networkd-ndisc.c | 4 |
5 files changed, 60 insertions, 10 deletions
diff --git a/man/systemd.network.xml b/man/systemd.network.xml index 7d081d22fe..5994869d97 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -227,7 +227,14 @@ <literal>yes</literal>, <literal>no</literal>, <literal>ipv4</literal>, or <literal>ipv6</literal>.</para> - <para>Please note that, by default, the domain name + <para>Note that DHCPv6 will by default be triggered by Router + Advertisment, if that is enabled, regardless of this parameter. + By enabling DHCPv6 support explicitly, the DHCPv6 client will + be started regardless of the presence of routers on the link, + or what flags the routers pass. See + <literal>IPv6AcceptRouterAdvertisements=</literal>.</para> + + <para>Furthermore, note that by default the domain name specified through DHCP is not used for name resolution. See option <option>UseDomains=</option> below.</para> </listitem> @@ -414,6 +421,9 @@ When unset, the kernel default is used, and router advertisements are accepted only when local forwarding is disabled for that interface. + When router advertisements are accepted, they will + trigger the start of the DHCPv6 client if the relevant + flags are passed, or if no routers are found on the link. Takes a boolean. If true, router advertisements are accepted, when false, router advertisements are ignored, independently of the local forwarding state.</para> diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 13d2fc6d0d..3ca9ceb114 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -124,6 +124,28 @@ static bool link_ipv6_forward_enabled(Link *link) { return link->network->ip_forward & ADDRESS_FAMILY_IPV6; } +bool link_ipv6_accept_ra_enabled(Link *link) { + if (link->flags & IFF_LOOPBACK) + return false; + + if (!link->network) + return false; + + /* If unset use system default (enabled if local forwarding is disabled. + * disabled if local forwarding is enabled). + * If set, ignore or enforce RA independent of local forwarding state. + */ + if (link->network->ipv6_accept_ra < 0) + /* default to accept RA if ip_forward is disabled and ignore RA if ip_forward is enabled */ + return !link_ipv6_forward_enabled(link); + else if (link->network->ipv6_accept_ra > 0) + /* accept RA even if ip_forward is enabled */ + return true; + else + /* ignore RA */ + return false; +} + static IPv6PrivacyExtensions link_ipv6_privacy_extensions(Link *link) { if (link->flags & IFF_LOOPBACK) return _IPV6_PRIVACY_EXTENSIONS_INVALID; @@ -485,13 +507,13 @@ static int link_stop_clients(Link *link) { r = log_link_warning_errno(link, r, "Could not stop IPv4 link-local: %m"); } - if(link->ndisc_router_discovery) { - if (link->dhcp6_client) { - k = sd_dhcp6_client_stop(link->dhcp6_client); - if (k < 0) - r = log_link_warning_errno(link, r, "Could not stop DHCPv6 client: %m"); - } + if (link->dhcp6_client) { + k = sd_dhcp6_client_stop(link->dhcp6_client); + if (k < 0) + r = log_link_warning_errno(link, r, "Could not stop DHCPv6 client: %m"); + } + if (link->ndisc_router_discovery) { k = sd_ndisc_stop(link->ndisc_router_discovery); if (k < 0) r = log_link_warning_errno(link, r, "Could not stop IPv6 Router Discovery: %m"); @@ -1242,6 +1264,16 @@ static int link_acquire_conf(Link *link) { } if (link_dhcp6_enabled(link)) { + assert(link->dhcp6_client); + + log_link_debug(link, "Acquiring DHCPv6 lease"); + + r = sd_dhcp6_client_start(link->dhcp6_client); + if (r < 0) + return log_link_warning_errno(link, r, "Could not acquire DHCPv6 lease: %m"); + } + + if (link_ipv6_accept_ra_enabled(link)) { assert(link->ndisc_router_discovery); log_link_debug(link, "Discovering IPv6 routers"); @@ -2041,6 +2073,12 @@ static int link_configure(Link *link) { } if (link_dhcp6_enabled(link)) { + r = dhcp6_configure(link); + if (r < 0) + return r; + } + + if (link_ipv6_accept_ra_enabled(link)) { r = ndisc_configure(link); if (r < 0) return r; diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h index d915e7c9c0..f453665655 100644 --- a/src/network/networkd-link.h +++ b/src/network/networkd-link.h @@ -157,6 +157,7 @@ bool link_ipv6ll_enabled(Link *link); bool link_dhcp4_server_enabled(Link *link); bool link_dhcp4_enabled(Link *link); bool link_dhcp6_enabled(Link *link); +bool link_ipv6_accept_ra_enabled(Link *link); const char* link_state_to_string(LinkState s) _const_; LinkState link_state_from_string(const char *s) _pure_; diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index a5701001c1..6350164074 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -1091,7 +1091,8 @@ static bool manager_check_idle(void *userdata) { link_ipv4ll_enabled(link) || link_dhcp4_server_enabled(link) || link_dhcp4_enabled(link) || - link_dhcp6_enabled(link)) + link_dhcp6_enabled(link) || + link_ipv6_accept_ra_enabled(link)) return false; } diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c index bd5a5d675c..68277d6ad4 100644 --- a/src/network/networkd-ndisc.c +++ b/src/network/networkd-ndisc.c @@ -42,7 +42,7 @@ static void ndisc_router_handler(sd_ndisc *nd, uint8_t flags, const struct in6_a dhcp6_request_address(link); r = sd_dhcp6_client_start(link->dhcp6_client); - if (r < 0 && r != -EBUSY) + if (r < 0 && r != -EALREADY) log_link_warning_errno(link, r, "Starting DHCPv6 client on NDisc request failed: %m"); } } @@ -61,7 +61,7 @@ static void ndisc_handler(sd_ndisc *nd, int event, void *userdata) { dhcp6_request_address(link); r = sd_dhcp6_client_start(link->dhcp6_client); - if (r < 0 && r != -EBUSY) + if (r < 0 && r != -EALREADY) log_link_warning_errno(link, r, "Starting DHCPv6 client after NDisc timeout failed: %m"); break; case SD_NDISC_EVENT_STOP: |