From 03d4fc2ed2193dd6a6af45218fff03ebd031de4a Mon Sep 17 00:00:00 2001 From: Patrik Flykt Date: Tue, 2 Oct 2018 12:29:06 -0600 Subject: [PATCH 1/2] networkd-dhcp: Rename function and reduce its logging Rename dhcp6_verify_link() to dhcp6_get_prefix_delegation() in order to be clearer in what it does. Reduce unnecessary logging. --- src/network/networkd-dhcp6.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c index df6bbcb7c8..1a033c116c 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); From 107523437c82de3cca2c444e828382ad5ba4149d Mon Sep 17 00:00:00 2001 From: Patrik Flykt Date: Tue, 2 Oct 2018 12:29:09 -0600 Subject: [PATCH 2/2] networkd-dhcp6: Request prefix delegation for a new link Request prefix delegation for a new downstream link that is enabled after any number of upstream DHCPv6 links. Submit the request after the link has been configured with a link-local address. If the upstream DHCPv6 client has already been configured to request prefixes, attempt to re-assign any possible prefixes between the already existing links and the new one. If no prefixes are yet acquired, nothing will happen right away and any prefixes will be distributed after a reply from the DHCPv6 server. If none of the already existing downstream links have requested DHCPv6 prefixes to be assigned, enable prefix delegation for each client and restart them one by one if they are already running. This causes the DHCPv6 clients to re-acquire addresses and prefixes and to re-distribute them to all links when receiving an updated response from their respective DHCPv6 servers. If the DHCPv6 client in question was not already running, it is set to request prefixes but not restarted. When an error occurs while setting or restarting the DHCPv6 client, log the incident and move over to the next link. Fixes #9758. --- src/network/networkd-dhcp6.c | 64 ++++++++++++++++++++++++++++++++++++ src/network/networkd-link.c | 2 ++ src/network/networkd-link.h | 1 + 3 files changed, 67 insertions(+) diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c index 1a033c116c..82f49e5ac0 100644 --- a/src/network/networkd-dhcp6.c +++ b/src/network/networkd-dhcp6.c @@ -346,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);