]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: do not restart DHCPv6 client when WithoutRA= is set
authorYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 14 Oct 2021 07:35:29 +0000 (16:35 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 26 Oct 2021 15:33:44 +0000 (00:33 +0900)
Previously, even if WithoutRA= is specified, the DHCPv6 client may be
restarted in undesired mode when a RA is received.

src/network/networkd-dhcp6.c
src/network/networkd-dhcp6.h
src/network/networkd-ndisc.c

index aba0699780f558cd032597faae1e759394d7412a..8bd69813a87b4b2e9a8ea4351a1165a5ff5d7760 100644 (file)
@@ -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;
 
index a08d03b614421bb580abc47004dc000007e013d8..4a522aebcfd8ec9a0c4ace23370ef541c9dfa951 100644 (file)
@@ -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);
index d7b79f74168ae08b6255ea745d29072518994c39..5f831b58a4054e45604752fbd08187c3d2ab2032 100644 (file)
@@ -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: