chiark / gitweb /
sd-dhcp-client/sd-ipv4ll: allow mac address to be updated at any time
authorTom Gundersen <teg@jklm.no>
Fri, 21 Mar 2014 17:36:32 +0000 (18:36 +0100)
committerTom Gundersen <teg@jklm.no>
Fri, 21 Mar 2014 17:36:32 +0000 (18:36 +0100)
If necessary, restart the clients to deal with a changing mac address
at runtime. This will solve the problem of starting clients on bridges
before they have received their final MAC address.

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

index 59cd30c..0728a15 100644 (file)
@@ -143,21 +143,27 @@ int sd_dhcp_client_set_index(sd_dhcp_client *client, int interface_index) {
 
 int sd_dhcp_client_set_mac(sd_dhcp_client *client,
                            const struct ether_addr *addr) {
+        bool need_restart = false;
+
         assert_return(client, -EINVAL);
-        assert_return(client->state == DHCP_STATE_INIT, -EBUSY);
+        assert_return(addr, -EINVAL);
+
+        if (memcmp(&client->client_id.mac_addr, addr, ETH_ALEN) == 0)
+                return 0;
 
-        log_dhcp_client(client, "set MAC address to "
-                        "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
-                        addr->ether_addr_octet[0],
-                        addr->ether_addr_octet[1],
-                        addr->ether_addr_octet[2],
-                        addr->ether_addr_octet[3],
-                        addr->ether_addr_octet[4],
-                        addr->ether_addr_octet[5]);
+        if (client->state != DHCP_STATE_INIT) {
+                log_dhcp_client(client, "Changing MAC address on running DHCP "
+                                "client, restarting");
+                sd_dhcp_client_stop(client);
+                need_restart = true;
+        }
 
         memcpy(&client->client_id.mac_addr, addr, ETH_ALEN);
         client->client_id.type = 0x01;
 
+        if (need_restart)
+                sd_dhcp_client_start(client);
+
         return 0;
 }
 
index 689dce9..ad8b4e3 100644 (file)
@@ -375,10 +375,25 @@ int sd_ipv4ll_set_index(sd_ipv4ll *ll, int interface_index) {
 }
 
 int sd_ipv4ll_set_mac(sd_ipv4ll *ll, const struct ether_addr *addr) {
+        bool need_restart = false;
+
         assert_return(ll, -EINVAL);
-        assert_return(ll->state == IPV4LL_STATE_INIT, -EBUSY);
+        assert_return(addr, -EINVAL);
+
+        if (memcmp(&ll->mac_addr, addr, ETH_ALEN) == 0)
+                return 0;
+
+        if (ll->state != IPV4LL_STATE_INIT) {
+                log_ipv4ll(ll, "Changing MAC address on running IPv4LL "
+                           "client, restarting");
+                sd_ipv4ll_stop(ll);
+                need_restart = true;
+        }
+
+        memcpy(&ll->mac_addr, addr, ETH_ALEN);
 
-        memcpy(&ll->mac_addr.ether_addr_octet, addr, ETH_ALEN);
+        if (need_restart)
+                sd_ipv4ll_start(ll);
 
         return 0;
 }