summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--man/systemd.network.xml12
-rw-r--r--src/network/networkd-link.c50
-rw-r--r--src/network/networkd-link.h1
-rw-r--r--src/network/networkd-manager.c3
-rw-r--r--src/network/networkd-ndisc.c4
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: