if (!link_dhcp6_pd_is_enabled(link))
continue;
+ if (link->network->dhcp6_pd_announce && !link->radv)
+ continue;
+
if (link == dhcp6_link && !link->network->dhcp6_pd_assign)
continue;
if (!link_dhcp6_pd_is_enabled(link))
return 0;
+ if (link->network->dhcp6_pd_announce && !link->radv)
+ return 0;
+
link_mark_addresses(link, NETWORK_CONFIG_SOURCE_DHCP6PD, NULL);
link_mark_routes(link, NETWORK_CONFIG_SOURCE_DHCP6PD, NULL);
if (!link_dhcp6_pd_is_enabled(link))
return 0;
+ if (link->network->dhcp6_pd_announce && !link->radv)
+ return 0;
+
if (link->dhcp6_pd_messages == 0) {
link->dhcp6_pd_configured = false;
assert(link);
- if (link->radv) {
- assert(link->radv);
- assert(in6_addr_is_link_local(&link->ipv6ll_address));
-
- log_link_debug(link, "Starting IPv6 Router Advertisements");
-
- r = sd_radv_start(link->radv);
- if (r < 0)
- return log_link_warning_errno(link, r, "Could not start IPv6 Router Advertisement: %m");
- }
+ r = radv_start(link);
+ if (r < 0)
+ return log_link_warning_errno(link, r, "Failed to start IPv6 Router Advertisement engine: %m");
r = ndisc_start(link);
if (r < 0)
if (r < 0)
return log_link_warning_errno(link, r, "Failed to start DHCPv6 client: %m");
- r = dhcp6_request_prefix_delegation(link);
- if (r < 0)
- return log_link_warning_errno(link, r, "Failed to request DHCPv6 prefix delegation: %m");
-
return 0;
}
int r;
assert(link);
+ assert(link->network);
r = link_acquire_dynamic_ipv4_conf(link);
if (r < 0)
return r;
}
+ if (!link_radv_enabled(link) || !link->network->dhcp6_pd_announce) {
+ /* DHCPv6PD downstream does not require IPv6LL address. But may require RADV to be
+ * configured, and RADV may not be configured yet here. Only acquire subnet prefix when
+ * RADV is disabled, or the announcement of the prefix is disabled. Otherwise, the
+ * below will be called in radv_start(). */
+ r = dhcp6_request_prefix_delegation(link);
+ if (r < 0)
+ return log_link_warning_errno(link, r, "Failed to request DHCPv6 prefix delegation: %m");
+ }
+
if (link->lldp_tx) {
r = sd_lldp_tx_start(link->lldp_tx);
if (r < 0)
#include "dns-domain.h"
#include "networkd-address-generation.h"
#include "networkd-address.h"
+#include "networkd-dhcp6.h"
#include "networkd-link.h"
#include "networkd-manager.h"
#include "networkd-network.h"
}
}
-static bool link_radv_enabled(Link *link) {
+bool link_radv_enabled(Link *link) {
assert(link);
if (!link_ipv6ll_enabled(link))
return log_link_warning_errno(link, r, "Failed to configure IPv6 Router Advertisement engine: %m");
if (link_has_carrier(link)) {
- r = sd_radv_start(link->radv);
+ r = radv_start(link);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to start IPv6 Router Advertisement engine: %m");
}
return 0;
}
+int radv_start(Link *link) {
+ int r;
+
+ assert(link);
+ assert(link->network);
+
+ if (!link->radv)
+ return 0;
+
+ if (!link_has_carrier(link))
+ return 0;
+
+ if (in6_addr_is_null(&link->ipv6ll_address))
+ return 0;
+
+ if (sd_radv_is_running(link->radv))
+ return 0;
+
+ if (link->network->dhcp6_pd_announce) {
+ r = dhcp6_request_prefix_delegation(link);
+ if (r < 0)
+ return log_link_debug_errno(link, r, "Failed to request DHCPv6 prefix delegation: %m");
+ }
+
+ log_link_debug(link, "Starting IPv6 Router Advertisements");
+ return sd_radv_start(link->radv);
+}
+
int radv_add_prefix(
Link *link,
const struct in6_addr *prefix,
int link_request_radv_addresses(Link *link);
+bool link_radv_enabled(Link *link);
+int radv_start(Link *link);
int radv_update_mac(Link *link);
int radv_add_prefix(Link *link, const struct in6_addr *prefix, uint8_t prefix_len,
usec_t lifetime_preferred_usec, usec_t lifetime_valid_usec);