sd-dhcp6-client: Prevent setting and restarting of DHCPv6 client
authorPatrik Flykt <patrik.flykt@linux.intel.com>
Wed, 23 Sep 2015 10:51:53 +0000 (13:51 +0300)
committerPatrik Flykt <patrik.flykt@linux.intel.com>
Wed, 23 Sep 2015 12:11:09 +0000 (15:11 +0300)
Prevent modifications to index, MAC address, DUID and Information
Request while the DHCPv6 client is running.

Require the DHCPv6 client to be stopped first instead of always
unconditionally restarting it if the caller calls
sd_dhcp6_client_start() more than once. With this change, handling
of for example incoming Router Advertisments becomes much easier.

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

index 2367509..1ab3640 100644 (file)
@@ -125,6 +125,8 @@ int sd_dhcp6_client_set_index(sd_dhcp6_client *client, int interface_index) {
         assert_return(client, -EINVAL);
         assert_return(interface_index >= -1, -EINVAL);
 
+        assert_return(IN_SET(client->state, DHCP6_STATE_STOPPED), -EBUSY);
+
         client->index = interface_index;
 
         return 0;
@@ -140,6 +142,8 @@ int sd_dhcp6_client_set_mac(
         assert_return(addr_len > 0 && addr_len <= MAX_MAC_ADDR_LEN, -EINVAL);
         assert_return(arp_type > 0, -EINVAL);
 
+        assert_return(IN_SET(client->state, DHCP6_STATE_STOPPED), -EBUSY);
+
         if (arp_type == ARPHRD_ETHER)
                 assert_return(addr_len == ETH_ALEN, -EINVAL);
         else if (arp_type == ARPHRD_INFINIBAND)
@@ -173,6 +177,8 @@ int sd_dhcp6_client_set_duid(
         assert_return(duid, -EINVAL);
         assert_return(duid_len > 0 && duid_len <= MAX_DUID_LEN, -EINVAL);
 
+        assert_return(IN_SET(client->state, DHCP6_STATE_STOPPED), -EBUSY);
+
         switch (type) {
         case DHCP6_DUID_LLT:
                 if (duid_len <= sizeof(client->duid.llt))
@@ -205,6 +211,8 @@ int sd_dhcp6_client_set_duid(
 int sd_dhcp6_client_set_information_request(sd_dhcp6_client *client, bool enabled) {
         assert_return(client, -EINVAL);
 
+        assert_return(IN_SET(client->state, DHCP6_STATE_STOPPED), -EBUSY);
+
         client->information_request = enabled;
 
         return 0;
@@ -1126,6 +1134,9 @@ int sd_dhcp6_client_start(sd_dhcp6_client *client) {
         assert_return(client->event, -EINVAL);
         assert_return(client->index > 0, -EINVAL);
 
+        if (!IN_SET(client->state, DHCP6_STATE_STOPPED))
+                return -EALREADY;
+
         r = client_reset(client);
         if (r < 0)
                 return r;