[systemd-devel] [PATCH 19/24] sd-dhcp6-client: Update start function to take a state

Patrik Flykt patrik.flykt at linux.intel.com
Fri Jun 13 06:45:09 PDT 2014


Updated the start function so that the client state can be conveniently
changed with the previous message resend timers cleared. On initial
startup also create and bind to the UDP socket.
---
 src/libsystemd-network/sd-dhcp6-client.c | 62 +++++++++++++++++++++-----------
 1 file changed, 42 insertions(+), 20 deletions(-)

diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c
index 52f4e10..98835f7 100644
--- a/src/libsystemd-network/sd-dhcp6-client.c
+++ b/src/libsystemd-network/sd-dhcp6-client.c
@@ -97,6 +97,8 @@ const char * dhcp6_message_status_table[_DHCP6_STATUS_MAX] = {
 
 DEFINE_STRING_TABLE_LOOKUP(dhcp6_message_status, int);
 
+static int client_start(sd_dhcp6_client *client, enum DHCP6State state);
+
 int sd_dhcp6_client_set_callback(sd_dhcp6_client *client,
                                  sd_dhcp6_client_cb_t cb, void *userdata)
 {
@@ -164,7 +166,7 @@ static int client_initialize(sd_dhcp6_client *client)
                 safe_close(client->fd);
         client->fd = -1;
 
-        client->transaction_id = random_u32() & 0x00ffffff;
+        client->transaction_id = 0;
 
         client->ia_na.timeout_t1 =
                 sd_event_source_unref(client->ia_na.timeout_t1);
@@ -614,36 +616,53 @@ static int client_receive_message(sd_event_source *s, int fd, uint32_t revents,
         return 0;
 }
 
-static int client_start(sd_dhcp6_client *client)
+static int client_start(sd_dhcp6_client *client, enum DHCP6State state)
 {
         int r;
 
         assert_return(client, -EINVAL);
         assert_return(client->event, -EINVAL);
         assert_return(client->index > 0, -EINVAL);
+        assert_return(client->state != state, -EINVAL);
 
-        r = client_ensure_iaid(client);
-        if (r < 0)
-                return r;
+        client->timeout_resend_expire =
+                sd_event_source_unref(client->timeout_resend_expire);
+        client->timeout_resend = sd_event_source_unref(client->timeout_resend);
+        client->retransmit_time = 0;
+        client->retransmit_count = 0;
 
-        r = dhcp6_network_bind_udp_socket(client->index, NULL);
-        if (r < 0)
-                return r;
+        switch (state) {
+        case DHCP6_STATE_STOPPED:
+        case DHCP6_STATE_RS:
+        case DHCP6_STATE_SOLICITATION:
 
-        client->fd = r;
+                r = client_ensure_iaid(client);
+                if (r < 0)
+                        return r;
 
-        r = sd_event_add_io(client->event, &client->receive_message,
-                            client->fd, EPOLLIN, client_receive_message,
-                            client);
-        if (r < 0)
-                return r;
+                r = dhcp6_network_bind_udp_socket(client->index, NULL);
+                if (r < 0)
+                        return r;
 
-        r = sd_event_source_set_priority(client->receive_message,
-                                         client->event_priority);
-        if (r < 0)
-                return r;
+                client->fd = r;
 
-        client->state = DHCP6_STATE_SOLICITATION;
+                r = sd_event_add_io(client->event, &client->receive_message,
+                                    client->fd, EPOLLIN, client_receive_message,
+                                    client);
+                if (r < 0)
+                        return r;
+
+                r = sd_event_source_set_priority(client->receive_message,
+                                                 client->event_priority);
+                if (r < 0)
+                        return r;
+
+                client->state = DHCP6_STATE_SOLICITATION;
+
+                break;
+        }
+
+        client->transaction_id = random_u32() & htobe32(0x00ffffff);
 
         r = sd_event_add_time(client->event, &client->timeout_resend,
                               CLOCK_MONOTONIC, 0, 0, client_timeout_resend,
@@ -680,7 +699,10 @@ static void dhcp6_receive_router_advertisment(icmp6_nd *nd, int event,
 
         case ICMP6_EVENT_ROUTER_ADVERTISMENT_TIMEOUT:
         case ICMP6_EVENT_ROUTER_ADVERTISMENT_MANAGED:
-                r = client_start(client);
+                if (!IN_SET(client->state, DHCP6_STATE_STOPPED, DHCP6_STATE_RS))
+                        break;
+
+                r = client_start(client, DHCP6_STATE_SOLICITATION);
                 if (r < 0)
                         client_stop(client, r);
                 break;
-- 
1.9.1



More information about the systemd-devel mailing list