diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2021-10-14 16:35:29 +0900 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2021-10-27 00:33:44 +0900 |
commit | fac19a21cf1de0805352390378ab9844daa16862 (patch) | |
tree | d7cefa2a9434c8c673e9b406784e18860c334e18 | |
parent | 483566e5ba9e4214e04106ae8760a79a13d710c2 (diff) | |
download | systemd-fac19a21cf1de0805352390378ab9844daa16862.tar.gz |
network: do not restart DHCPv6 client when WithoutRA= is set
Previously, even if WithoutRA= is specified, the DHCPv6 client may be
restarted in undesired mode when a RA is received.
-rw-r--r-- | src/network/networkd-dhcp6.c | 35 | ||||
-rw-r--r-- | src/network/networkd-dhcp6.h | 2 | ||||
-rw-r--r-- | src/network/networkd-ndisc.c | 4 |
3 files changed, 28 insertions, 13 deletions
diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c index aba0699780..8bd69813a8 100644 --- a/src/network/networkd-dhcp6.c +++ b/src/network/networkd-dhcp6.c @@ -1311,26 +1311,31 @@ static void dhcp6_handler(sd_dhcp6_client *client, int event, void *userdata) { } } -int dhcp6_request_information(Link *link, int ir) { - int r, inf_req; - bool running; +int dhcp6_start_on_ra(Link *link, bool information_request) { + int r; assert(link); assert(link->dhcp6_client); assert(link->network); assert(in6_addr_is_link_local(&link->ipv6ll_address)); + if (link->network->dhcp6_without_ra != DHCP6_CLIENT_START_MODE_NO) + /* When WithoutRA= is specified, then the DHCPv6 client should be already runnging in + * the requested mode. Hence, ignore the requests by RA. */ + return 0; + r = sd_dhcp6_client_is_running(link->dhcp6_client); if (r < 0) return r; - running = r; - if (running) { + if (r > 0) { + int inf_req; + r = sd_dhcp6_client_get_information_request(link->dhcp6_client, &inf_req); if (r < 0) return r; - if (inf_req == ir) + if (inf_req == information_request) return 0; r = sd_dhcp6_client_stop(link->dhcp6_client); @@ -1342,7 +1347,7 @@ int dhcp6_request_information(Link *link, int ir) { return r; } - r = sd_dhcp6_client_set_information_request(link->dhcp6_client, ir); + r = sd_dhcp6_client_set_information_request(link->dhcp6_client, information_request); if (r < 0) return r; @@ -1357,6 +1362,7 @@ int dhcp6_start(Link *link) { int r; assert(link); + assert(link->network); if (!link->dhcp6_client) return 0; @@ -1370,15 +1376,24 @@ int dhcp6_start(Link *link) { if (link->network->dhcp6_without_ra == DHCP6_CLIENT_START_MODE_NO) return 0; + if (sd_dhcp6_client_is_running(link->dhcp6_client) > 0) + return 0; + if (!in6_addr_is_link_local(&link->ipv6ll_address)) { log_link_debug(link, "IPv6 link-local address is not set, delaying to start DHCPv6 client."); return 0; } - if (sd_dhcp6_client_is_running(link->dhcp6_client) > 0) - return 0; + r = sd_dhcp6_client_set_local_address(link->dhcp6_client, &link->ipv6ll_address); + if (r < 0) + return r; - r = dhcp6_request_information(link, link->network->dhcp6_without_ra == DHCP6_CLIENT_START_MODE_INFORMATION_REQUEST); + r = sd_dhcp6_client_set_information_request(link->dhcp6_client, + link->network->dhcp6_without_ra == DHCP6_CLIENT_START_MODE_INFORMATION_REQUEST); + if (r < 0) + return r; + + r = sd_dhcp6_client_start(link->dhcp6_client); if (r < 0) return r; diff --git a/src/network/networkd-dhcp6.h b/src/network/networkd-dhcp6.h index a08d03b614..4a522aebcf 100644 --- a/src/network/networkd-dhcp6.h +++ b/src/network/networkd-dhcp6.h @@ -21,7 +21,7 @@ bool link_dhcp6_pd_is_enabled(Link *link); int dhcp6_pd_remove(Link *link, bool only_marked); int dhcp6_update_mac(Link *link); int dhcp6_start(Link *link); -int dhcp6_request_information(Link *link, int ir); +int dhcp6_start_on_ra(Link *link, bool information_request); int dhcp6_request_prefix_delegation(Link *link); int request_process_dhcp6_client(Request *req); diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c index d7b79f7416..5f831b58a4 100644 --- a/src/network/networkd-ndisc.c +++ b/src/network/networkd-ndisc.c @@ -906,13 +906,13 @@ static int ndisc_start_dhcp6_client(Link *link, sd_ndisc_router *rt) { /* (re)start DHCPv6 client in stateful or stateless mode according to RA flags. * Note, if both managed and other information bits are set, then ignore other * information bit. See RFC 4861. */ - r = dhcp6_request_information(link, !(flags & ND_RA_FLAG_MANAGED)); + r = dhcp6_start_on_ra(link, !(flags & ND_RA_FLAG_MANAGED)); break; } case IPV6_ACCEPT_RA_START_DHCP6_CLIENT_ALWAYS: /* When IPv6AcceptRA.DHCPv6Client=always, start dhcp6 client in managed mode * even if the router flags have neither M nor O flags. */ - r = dhcp6_request_information(link, false); + r = dhcp6_start_on_ra(link, /* information_request = */ false); break; default: |