]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-dhcp-client: always use sd_dhcp_client.timeout_ipv6_only_mode for delaying subsequ...
authorYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 19 Oct 2023 16:21:42 +0000 (01:21 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 20 Oct 2023 16:54:08 +0000 (01:54 +0900)
Otherwise, sd_dhcp_client_set_ipv6_connectivity() may not work, as it
checks if the timer event source is enabled or not.

src/libsystemd-network/sd-dhcp-client.c

index d27609655f171237d6ece3b43630a4b603a5854a..5064bf2b4f02a972232c967f552c34805f4dbd69 100644 (file)
@@ -1661,10 +1661,37 @@ static int client_handle_offer(sd_dhcp_client *client, DHCPMessage *message, siz
         return 0;
 }
 
+static int client_enter_requesting_now(sd_dhcp_client *client) {
+        assert(client);
+
+        client_set_state(client, DHCP_STATE_REQUESTING);
+        client->attempt = 0;
+
+        return event_reset_time(client->event, &client->timeout_resend,
+                                CLOCK_BOOTTIME, 0, 0,
+                                client_timeout_resend, client,
+                                client->event_priority, "dhcp4-resend-timer",
+                                /* force_reset = */ true);
+}
+
+static int client_enter_requesting_delayed(sd_event_source *s, uint64_t usec, void *userdata) {
+        sd_dhcp_client *client = ASSERT_PTR(userdata);
+        DHCP_CLIENT_DONT_DESTROY(client);
+        int r;
+
+        r = client_enter_requesting_now(client);
+        if (r < 0)
+                client_stop(client, r);
+
+        return 0;
+}
+
 static int client_enter_requesting(sd_dhcp_client *client) {
         assert(client);
         assert(client->lease);
 
+        (void) event_source_disable(client->timeout_resend);
+
         if (client->lease->ipv6_only_preferred_usec > 0) {
                 if (client->ipv6_acquired) {
                         log_dhcp_client(client,
@@ -1675,17 +1702,16 @@ static int client_enter_requesting(sd_dhcp_client *client) {
                 log_dhcp_client(client,
                                 "Received an OFFER with IPv6-only preferred option, delaying to send REQUEST with %s.",
                                 FORMAT_TIMESPAN(client->lease->ipv6_only_preferred_usec, USEC_PER_SEC));
-        }
 
-        client_set_state(client, DHCP_STATE_REQUESTING);
-        client->attempt = 0;
+                return event_reset_time_relative(client->event, &client->timeout_ipv6_only_mode,
+                                                 CLOCK_BOOTTIME,
+                                                 client->lease->ipv6_only_preferred_usec, 0,
+                                                 client_enter_requesting_delayed, client,
+                                                 client->event_priority, "dhcp4-ipv6-only-mode-timer",
+                                                 /* force_reset = */ true);
+        }
 
-        return event_reset_time_relative(client->event, &client->timeout_resend,
-                                         CLOCK_BOOTTIME,
-                                         client->lease->ipv6_only_preferred_usec, 0,
-                                         client_timeout_resend, client,
-                                         client->event_priority, "dhcp4-resend-timer",
-                                         /* force_reset = */ true);
+        return client_enter_requesting_now(client);
 }
 
 static int client_handle_forcerenew(sd_dhcp_client *client, DHCPMessage *force, size_t len) {
@@ -1887,7 +1913,7 @@ static int client_enter_bound_now(sd_dhcp_client *client, int notify_event) {
         return 0;
 }
 
-static int client_timeout_ipv6_only_mode(sd_event_source *s, uint64_t usec, void *userdata) {
+static int client_enter_bound_delayed(sd_event_source *s, uint64_t usec, void *userdata) {
         sd_dhcp_client *client = ASSERT_PTR(userdata);
         DHCP_CLIENT_DONT_DESTROY(client);
         int r;
@@ -1927,7 +1953,7 @@ static int client_enter_bound(sd_dhcp_client *client, int notify_event) {
                 return event_reset_time_relative(client->event, &client->timeout_ipv6_only_mode,
                                                  CLOCK_BOOTTIME,
                                                  client->lease->ipv6_only_preferred_usec, 0,
-                                                 client_timeout_ipv6_only_mode, client,
+                                                 client_enter_bound_delayed, client,
                                                  client->event_priority, "dhcp4-ipv6-only-mode",
                                                  /* force_reset = */ true);
         }