networkd: dhcp6 - split up configure() method
authorTom Gundersen <teg@jklm.no>
Tue, 10 Nov 2015 14:43:52 +0000 (15:43 +0100)
committerTom Gundersen <teg@jklm.no>
Wed, 11 Nov 2015 14:42:38 +0000 (15:42 +0100)
Enabling address acquisition, configuring the client and starting the client are now
split out. This to better handle the client being repeatedly enabled due to router
advertisements.

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

index c3332bb..3ec9b84 100644 (file)
@@ -165,83 +165,82 @@ static void dhcp6_handler(sd_dhcp6_client *client, int event, void *userdata) {
         link_check_ready(link);
 }
 
-int dhcp6_configure(Link *link, bool inf_req) {
-        int r, information_request;
+int dhcp6_request_address(Link *link) {
+        int r, inf_req;
+        bool running;
 
-        assert_return(link, -EINVAL);
+        assert(link);
+        assert(link->dhcp6_client);
 
-        link->dhcp6_configured = false;
+        r = sd_dhcp6_client_get_information_request(link->dhcp6_client, &inf_req);
+        if (r < 0)
+                return r;
 
-        if (link->dhcp6_client) {
-                r = sd_dhcp6_client_get_information_request(link->dhcp6_client, &information_request);
-                if (r < 0) {
-                        log_link_warning_errno(link, r, "Could not get DHCPv6 Information request setting: %m");
-                        goto error;
-                }
+        if (!inf_req)
+                return 0;
 
-                if (information_request && !inf_req) {
-                        r = sd_dhcp6_client_stop(link->dhcp6_client);
-                        if (r < 0) {
-                                log_link_warning_errno(link, r, "Could not stop DHCPv6 while setting Managed mode: %m");
-                                goto error;
-                        }
+        r = sd_dhcp6_client_is_running(link->dhcp6_client);
+        if (r < 0)
+                return r;
+        else
+                running = !!r;
 
-                        r = sd_dhcp6_client_set_information_request(link->dhcp6_client, false);
-                        if (r < 0) {
-                                log_link_warning_errno(link, r, "Could not unset DHCPv6 Information request: %m");
-                                goto error;
-                        }
+        if (running) {
+                r = sd_dhcp6_client_stop(link->dhcp6_client);
+                if (r < 0)
+                        return r;
+        }
 
-                }
+        r = sd_dhcp6_client_set_information_request(link->dhcp6_client, false);
+        if (r < 0)
+                return r;
 
+        if (running) {
                 r = sd_dhcp6_client_start(link->dhcp6_client);
-                if (r < 0 && r != -EALREADY) {
-                        log_link_warning_errno(link, r, "Could not restart DHCPv6: %m");
-                        goto error;
-                }
+                if (r < 0)
+                        return r;
+        }
 
-                if (r == -EALREADY)
-                        link->dhcp6_configured = true;
+        return 0;
+}
 
+int dhcp6_configure(Link *link) {
+        sd_dhcp6_client *client = NULL;
+        int r;
+
+        assert(link);
+
+        r = sd_dhcp6_client_new(&client);
+        if (r < 0)
                 return r;
-        }
 
-        r = sd_dhcp6_client_new(&link->dhcp6_client);
+        r = sd_dhcp6_client_attach_event(client, NULL, 0);
         if (r < 0)
                 goto error;
 
-        r = sd_dhcp6_client_attach_event(link->dhcp6_client, NULL, 0);
+        r = sd_dhcp6_client_set_information_request(client, true);
         if (r < 0)
-                goto error;
+                return r;
 
-        r = sd_dhcp6_client_set_mac(link->dhcp6_client,
+        r = sd_dhcp6_client_set_mac(client,
                                     (const uint8_t *) &link->mac,
                                     sizeof (link->mac), ARPHRD_ETHER);
         if (r < 0)
                 goto error;
 
-        r = sd_dhcp6_client_set_index(link->dhcp6_client, link->ifindex);
+        r = sd_dhcp6_client_set_index(client, link->ifindex);
         if (r < 0)
                 goto error;
 
-        r = sd_dhcp6_client_set_callback(link->dhcp6_client, dhcp6_handler,
-                                         link);
+        r = sd_dhcp6_client_set_callback(client, dhcp6_handler, link);
         if (r < 0)
                 goto error;
 
-        if (inf_req) {
-                r = sd_dhcp6_client_set_information_request(link->dhcp6_client, true);
-                if (r < 0)
-                        goto error;
-        }
-
-        r = sd_dhcp6_client_start(link->dhcp6_client);
-        if (r < 0)
-                goto error;
+        link->dhcp6_client = client;
 
-        return r;
+        return 0;
 
- error:
-        link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
+error:
+        sd_dhcp6_client_unref(client);
         return r;
 }
index a220418..d915e7c 100644 (file)
@@ -147,7 +147,8 @@ int link_set_timezone(Link *link, const char *timezone);
 
 int ipv4ll_configure(Link *link);
 int dhcp4_configure(Link *link);
-int dhcp6_configure(Link *link, bool information_request);
+int dhcp6_configure(Link *link);
+int dhcp6_request_address(Link *link);
 int ndisc_configure(Link *link);
 
 bool link_lldp_enabled(Link *link);
index dfbc5a8..bd5a5d6 100644 (file)
@@ -29,6 +29,7 @@
 
 static void ndisc_router_handler(sd_ndisc *nd, uint8_t flags, const struct in6_addr *gateway, unsigned lifetime, int pref, void *userdata) {
         Link *link = userdata;
+        int r;
 
         assert(link);
         assert(link->network);
@@ -36,14 +37,19 @@ static void ndisc_router_handler(sd_ndisc *nd, uint8_t flags, const struct in6_a
         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
                 return;
 
-        if (flags & ND_RA_FLAG_MANAGED)
-                dhcp6_configure(link, false);
-        else if (flags & ND_RA_FLAG_OTHER)
-                dhcp6_configure(link, true);
+        if (flags & (ND_RA_FLAG_MANAGED | ND_RA_FLAG_OTHER)) {
+                if (flags & ND_RA_FLAG_MANAGED)
+                        dhcp6_request_address(link);
+
+                r = sd_dhcp6_client_start(link->dhcp6_client);
+                if (r < 0 && r != -EBUSY)
+                        log_link_warning_errno(link, r, "Starting DHCPv6 client on NDisc request failed: %m");
+        }
 }
 
 static void ndisc_handler(sd_ndisc *nd, int event, void *userdata) {
         Link *link = userdata;
+        int r;
 
         assert(link);
 
@@ -52,7 +58,11 @@ static void ndisc_handler(sd_ndisc *nd, int event, void *userdata) {
 
         switch (event) {
         case SD_NDISC_EVENT_TIMEOUT:
-                dhcp6_configure(link, false);
+                dhcp6_request_address(link);
+
+                r = sd_dhcp6_client_start(link->dhcp6_client);
+                if (r < 0 && r != -EBUSY)
+                        log_link_warning_errno(link, r, "Starting DHCPv6 client after NDisc timeout failed: %m");
                 break;
         case SD_NDISC_EVENT_STOP:
                 break;