]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: update MAC address in IPv4 ACD clients
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 4 Oct 2020 00:27:42 +0000 (09:27 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 6 Oct 2020 17:59:34 +0000 (02:59 +0900)
When the MAC address of a link is updated, an address on the link may
be under checking address duplication. Or, (currently such code is not
implemented yet, but) address duplication check may be restarted later.
For that case, the IPv4 ACD clients must use the new updated MAC address.

src/network/networkd-address.c
src/network/networkd-address.h
src/network/networkd-link.c

index 0d2fa60eddb82bfd19432f7eb4220d7c65b281bb..000f8cfa93276e6545f12eeea892a70ad955050f 100644 (file)
@@ -1402,6 +1402,51 @@ static int ipv4_dad_configure(Address *address) {
         return sd_ipv4acd_start(address->acd, true);
 }
 
+static int ipv4_dad_update_mac_one(Address *address) {
+        bool running;
+        int r;
+
+        assert(address);
+
+        if (!address->acd)
+                return 0;
+
+        running = sd_ipv4acd_is_running(address->acd);
+
+        if (running) {
+                r = sd_ipv4acd_stop(address->acd);
+                if (r < 0)
+                        return r;
+        }
+
+        r = sd_ipv4acd_set_mac(address->acd, &address->link->mac);
+        if (r < 0)
+                return r;
+
+        if (running) {
+                r = sd_ipv4acd_start(address->acd, true);
+                if (r < 0)
+                        return r;
+        }
+
+        return 0;
+}
+
+int ipv4_dad_update_mac(Link *link) {
+        Address *address;
+        int k, r = 0;
+
+        assert(link);
+
+        SET_FOREACH(address, link->addresses) {
+                k = ipv4_dad_update_mac_one(address);
+                if (k < 0 && r >= 0)
+                        r = k;
+        }
+
+        return r;
+}
+
 int ipv4_dad_stop(Link *link) {
         Address *address;
         int k, r = 0;
index 816e84550b2f2bff76dff01478f0775afb6945b1..88dbefc126944d345422225eb533f66b6e3a126c 100644 (file)
@@ -66,6 +66,7 @@ int link_serialize_addresses(Link *link, FILE *f);
 int link_deserialize_addresses(Link *link, const char *addresses);
 
 int ipv4_dad_stop(Link *link);
+int ipv4_dad_update_mac(Link *link);
 
 int manager_rtnl_process_address(sd_netlink *nl, sd_netlink_message *message, Manager *m);
 
index ce708edabb4bbab97fb793e331b404319504a4be..b32a436be50a6d7c2d573c037f3fc37e4e9cc91c 100644 (file)
@@ -2697,6 +2697,10 @@ int link_update(Link *link, sd_netlink_message *m) {
                         if (r < 0)
                                 return log_link_warning_errno(link, r, "Could not update MAC for NDisc: %m");
                 }
+
+                r = ipv4_dad_update_mac(link);
+                if (r < 0)
+                        return log_link_warning_errno(link, r, "Could not update MAC address in IPv4 ACD client: %m");
         }
 
         old_master = link->master_ifindex;