]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
networkd-dhcp6: generalize DHCPv6 client (re)starting
authorTom Yan <tom.ty89@gmail.com>
Wed, 1 Jun 2016 06:54:46 +0000 (14:54 +0800)
committerTom Yan <tom.ty89@gmail.com>
Wed, 1 Jun 2016 06:54:46 +0000 (14:54 +0800)
dhcp6_request_address() was merely a function to switch the DHCPv6 client from "stateless" mode to "stateful" mode. It was also a one-way switch. Also, to (re)start the client, we would need to repeat separate function calls.

In this patch, dhcp6_request_address() is made a general starter/manager of the DHCPv6 client. It now takes an extra parameter so we will be specifying which mode the DHCPv6 client should be started in. Also it will keep track of the current mode and compare with the newly requested mode, and only restart the client in case there is a difference between them.

This also makes sure that the DHCPv6 client will be (re)started accordingly as per the Router Advertisement flags.

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

index a44c9ea71d6a2802b4c418b15e2bfee85b4e69f3..50721b1c74ee308b177f06346a5b4511e3c84eed 100644 (file)
@@ -164,19 +164,13 @@ static void dhcp6_handler(sd_dhcp6_client *client, int event, void *userdata) {
         link_check_ready(link);
 }
 
-int dhcp6_request_address(Link *link) {
+int dhcp6_request_address(Link *link, int ir) {
         int r, inf_req;
         bool running;
 
         assert(link);
         assert(link->dhcp6_client);
-
-        r = sd_dhcp6_client_get_information_request(link->dhcp6_client, &inf_req);
-        if (r < 0)
-                return r;
-
-        if (!inf_req)
-                return 0;
+        assert(in_addr_is_link_local(AF_INET6, (const union in_addr_union*)&link->ipv6ll_address) > 0);
 
         r = sd_dhcp6_client_is_running(link->dhcp6_client);
         if (r < 0)
@@ -185,12 +179,27 @@ int dhcp6_request_address(Link *link) {
                 running = !!r;
 
         if (running) {
+                r = sd_dhcp6_client_get_information_request(link->dhcp6_client, &inf_req);
+                if (r < 0)
+                        return r;
+
+                if (inf_req == ir)
+                        return 0;
+
                 r = sd_dhcp6_client_stop(link->dhcp6_client);
                 if (r < 0)
                         return r;
+        } else {
+                r = sd_dhcp6_client_set_local_address(link->dhcp6_client, &link->ipv6ll_address);
+                if (r < 0)
+                        return r;
         }
 
-        r = sd_dhcp6_client_set_information_request(link->dhcp6_client, false);
+        r = sd_dhcp6_client_set_information_request(link->dhcp6_client, ir);
+        if (r < 0)
+                return r;
+
+        r = sd_dhcp6_client_start(link->dhcp6_client);
         if (r < 0)
                 return r;
 
@@ -215,10 +224,6 @@ int dhcp6_configure(Link *link) {
         if (r < 0)
                 goto error;
 
-        r = sd_dhcp6_client_set_information_request(client, true);
-        if (r < 0)
-                goto error;
-
         r = sd_dhcp6_client_set_mac(client,
                                     (const uint8_t *) &link->mac,
                                     sizeof (link->mac), ARPHRD_ETHER);
index 9ac0b47d7707eefcebc37bdea0789d57608f8966..ba4147f875639c4c6bc2fd7a62d1c5fbebca771a 100644 (file)
@@ -1444,15 +1444,12 @@ static int link_acquire_ipv6_conf(Link *link) {
                 assert(link->dhcp6_client);
                 assert(in_addr_is_link_local(AF_INET6, (const union in_addr_union*)&link->ipv6ll_address) > 0);
 
-                log_link_debug(link, "Acquiring DHCPv6 lease");
-
-                r = sd_dhcp6_client_set_local_address(link->dhcp6_client, &link->ipv6ll_address);
-                if (r < 0 && r != -EBUSY)
-                        return log_link_warning_errno(link, r, "Could not set IPv6LL address in DHCP client: %m");
-
-                r = sd_dhcp6_client_start(link->dhcp6_client);
+                /* start DHCPv6 client in stateless mode */
+                r = dhcp6_request_address(link, true);
                 if (r < 0 && r != -EBUSY)
                         return log_link_warning_errno(link, r,  "Could not acquire DHCPv6 lease: %m");
+                else
+                        log_link_debug(link, "Acquiring DHCPv6 lease");
         }
 
         if (link_ipv6_accept_ra_enabled(link)) {
index 14c4a02c7efb5c1f3e440eeb265d51966704ea50..5efefd27d656b878884055dce5ede1b0fe015883 100644 (file)
@@ -160,7 +160,7 @@ int link_set_timezone(Link *link, const char *timezone);
 int ipv4ll_configure(Link *link);
 int dhcp4_configure(Link *link);
 int dhcp6_configure(Link *link);
-int dhcp6_request_address(Link *link);
+int dhcp6_request_address(Link *link, int ir);
 int ndisc_configure(Link *link);
 
 const char* link_state_to_string(LinkState s) _const_;
index 3baca2e63cb61a864ed641e52a66e21302c0189d..db9be024e565665ef5f69c66b23be2997a4380aa 100644 (file)
@@ -149,21 +149,19 @@ static void ndisc_router_handler(sd_ndisc *nd, uint8_t flags, const struct in6_a
         assert(link);
         assert(link->network);
         assert(link->manager);
+        assert(link->dhcp6_client);
+        assert(in_addr_is_link_local(AF_INET6, (const union in_addr_union*)&link->ipv6ll_address) > 0);
 
         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
                 return;
 
         if (flags & (ND_RA_FLAG_MANAGED | ND_RA_FLAG_OTHER)) {
-                if (flags & ND_RA_FLAG_MANAGED)
-                        dhcp6_request_address(link);
-
-                r = sd_dhcp6_client_set_local_address(link->dhcp6_client, &link->ipv6ll_address);
-                if (r < 0 && r != -EBUSY)
-                        log_link_warning_errno(link, r, "Could not set IPv6LL address in DHCP client: %m");
-
-                r = sd_dhcp6_client_start(link->dhcp6_client);
+                /* (re)start DHCPv6 client in stateful or stateless mode according to RA flags */
+                r = dhcp6_request_address(link, flags & ND_RA_FLAG_MANAGED ? false : true);
                 if (r < 0 && r != -EBUSY)
-                        log_link_warning_errno(link, r, "Starting DHCPv6 client on NDisc request failed: %m");
+                        log_link_warning_errno(link, r, "Could not acquire DHCPv6 lease on NDisc request: %m");
+                else
+                        log_link_debug(link, "Acquiring DHCPv6 lease on NDisc request");
         }
 
         if (!gateway)
@@ -199,21 +197,20 @@ static void ndisc_handler(sd_ndisc *nd, int event, void *userdata) {
         int r;
 
         assert(link);
+        assert(link->dhcp6_client);
+        assert(in_addr_is_link_local(AF_INET6, (const union in_addr_union*)&link->ipv6ll_address) > 0);
 
         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
                 return;
 
         switch (event) {
         case SD_NDISC_EVENT_TIMEOUT:
-                dhcp6_request_address(link);
-
-                r = sd_dhcp6_client_set_local_address(link->dhcp6_client, &link->ipv6ll_address);
-                if (r < 0 && r != -EBUSY)
-                        log_link_warning_errno(link, r, "Could not set IPv6LL address in DHCP client: %m");
-
-                r = sd_dhcp6_client_start(link->dhcp6_client);
+                /* (re)start DHCPv6 client in stateful mode */
+                r = dhcp6_request_address(link, false);
                 if (r < 0 && r != -EBUSY)
-                        log_link_warning_errno(link, r, "Starting DHCPv6 client after NDisc timeout failed: %m");
+                        log_link_warning_errno(link, r, "Could not acquire DHCPv6 lease after NDisc timeout: %m");
+                else
+                        log_link_debug(link, "Acquiring DHCPv6 lease after NDisc timeout");
 
                 link->ndisc_configured = true;
                 link_check_ready(link);