From 4644fee04fb515787bcfbba53b3cabe58c81d317 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Fri, 21 Mar 2014 18:36:32 +0100 Subject: [PATCH] sd-dhcp-client/sd-ipv4ll: allow mac address to be updated at any time 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 | 26 +++++++++++++++---------- src/libsystemd-network/sd-ipv4ll.c | 21 +++++++++++++++++--- 2 files changed, 34 insertions(+), 13 deletions(-) diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c index 59cd30c606c..0728a15550c 100644 --- a/src/libsystemd-network/sd-dhcp-client.c +++ b/src/libsystemd-network/sd-dhcp-client.c @@ -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) { - assert_return(client, -EINVAL); - assert_return(client->state == DHCP_STATE_INIT, -EBUSY); + bool need_restart = false; - 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]); + assert_return(client, -EINVAL); + assert_return(addr, -EINVAL); + + if (memcmp(&client->client_id.mac_addr, addr, ETH_ALEN) == 0) + return 0; + + 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; } diff --git a/src/libsystemd-network/sd-ipv4ll.c b/src/libsystemd-network/sd-ipv4ll.c index 689dce9adff..ad8b4e3b433 100644 --- a/src/libsystemd-network/sd-ipv4ll.c +++ b/src/libsystemd-network/sd-ipv4ll.c @@ -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) { - assert_return(ll, -EINVAL); - assert_return(ll->state == IPV4LL_STATE_INIT, -EBUSY); + bool need_restart = false; - memcpy(&ll->mac_addr.ether_addr_octet, addr, ETH_ALEN); + assert_return(ll, -EINVAL); + 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); + + if (need_restart) + sd_ipv4ll_start(ll); return 0; }