diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c index df6bbcb7c8..82f49e5ac0 100644 --- a/src/network/networkd-dhcp6.c +++ b/src/network/networkd-dhcp6.c @@ -20,16 +20,13 @@ static int dhcp6_lease_address_acquired(sd_dhcp6_client *client, Link *link); -static bool dhcp6_verify_link(Link *link) { - if (!link->network) { - log_link_info(link, "Link is not managed by us"); +static bool dhcp6_get_prefix_delegation(Link *link) { + if (!link->network) return false; - } if (!IN_SET(link->network->router_prefix_delegation, RADV_PREFIX_DELEGATION_DHCP6, RADV_PREFIX_DELEGATION_BOTH)) { - log_link_debug(link, "Link does not request DHCPv6 prefix delegation"); return false; } @@ -50,7 +47,7 @@ static bool dhcp6_enable_prefix_delegation(Link *dhcp6_link) { if (l == dhcp6_link) continue; - if (!dhcp6_verify_link(l)) + if (!dhcp6_get_prefix_delegation(l)) continue; return true; @@ -217,7 +214,7 @@ static int dhcp6_pd_prefix_distribute(Link *dhcp6_link, Iterator *i, if (link == dhcp6_link) continue; - if (!dhcp6_verify_link(link)) + if (!dhcp6_get_prefix_delegation(link)) continue; assigned_link = manager_dhcp6_prefix_get(manager, &prefix.in6); @@ -349,6 +346,70 @@ static int dhcp6_lease_pd_prefix_acquired(sd_dhcp6_client *client, Link *link) { return 0; } +int dhcp6_request_prefix_delegation(Link *link) { + Link *l; + Iterator i; + + assert_return(link, -EINVAL); + assert_return(link->manager, -EOPNOTSUPP); + + if (dhcp6_get_prefix_delegation(link) <= 0) + return 0; + + log_link_debug(link, "Requesting DHCPv6 prefixes to be delegated for new link"); + + HASHMAP_FOREACH(l, link->manager->links, i) { + int r, enabled; + + if (l == link) + continue; + + if (!l->dhcp6_client) + continue; + + r = sd_dhcp6_client_get_prefix_delegation(l->dhcp6_client, &enabled); + if (r < 0) { + log_link_warning_errno(l, r, "Cannot get prefix delegation when adding new link"); + continue; + } + + if (enabled == 0) { + r = sd_dhcp6_client_set_prefix_delegation(l->dhcp6_client, 1); + if (r < 0) { + log_link_warning_errno(l, r, "Cannot enable prefix delegation when adding new link"); + continue; + } + } + + r = sd_dhcp6_client_is_running(l->dhcp6_client); + if (r <= 0) + continue; + + if (enabled != 0) { + log_link_debug(l, "Requesting re-assignment of delegated prefixes after adding new link"); + (void) dhcp6_lease_pd_prefix_acquired(l->dhcp6_client, l); + + continue; + } + + r = sd_dhcp6_client_stop(l->dhcp6_client); + if (r < 0) { + log_link_warning_errno(l, r, "Cannot stop DHCPv6 prefix delegation client after adding new link"); + continue; + } + + r = sd_dhcp6_client_start(l->dhcp6_client); + if (r < 0) { + log_link_warning_errno(l, r, "Cannot restart DHCPv6 prefix delegation client after adding new link"); + continue; + } + + log_link_debug(l, "Restarted DHCPv6 client to acquire prefix delegations after adding new link"); + } + + return 0; +} + static int dhcp6_address_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { _cleanup_(link_unrefp) Link *link = userdata; diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 9b55598482..213c388be4 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -1662,6 +1662,8 @@ static int link_acquire_ipv6_conf(Link *link) { return log_link_warning_errno(link, r, "Could not start IPv6 Router Advertisement: %m"); } + (void) dhcp6_request_prefix_delegation(link); + return 0; } diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h index b686011da4..033cca1576 100644 --- a/src/network/networkd-link.h +++ b/src/network/networkd-link.h @@ -163,6 +163,7 @@ int ipv4ll_configure(Link *link); int dhcp4_configure(Link *link); int dhcp4_set_client_identifier(Link *link); int dhcp4_set_promote_secondaries(Link *link); +int dhcp6_request_prefix_delegation(Link *link); int dhcp6_configure(Link *link); int dhcp6_request_address(Link *link, int ir); int dhcp6_lease_pd_prefix_lost(sd_dhcp6_client *client, Link* link);