]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: make MACAddress= takes hardware address with its length is INFINIBAND_ALEN 21517/head
authorYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 4 Nov 2021 18:20:29 +0000 (03:20 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 25 Nov 2021 13:03:19 +0000 (22:03 +0900)
Also, the multicast and local bits in the specified MAC address for
ethernet are adjusted.

src/network/networkd-link.h
src/network/networkd-network-gperf.gperf
src/network/networkd-network.c
src/network/networkd-network.h
src/network/networkd-setlink.c
test/test-network/systemd-networkd-tests.py

index edf93d720ef2694a4aca00c9d826053c7b5849e1..072c39f387c3f0d71195ee86ca11639ff22b9162 100644 (file)
@@ -56,6 +56,7 @@ typedef struct Link {
         struct hw_addr_data hw_addr;
         struct hw_addr_data bcast_addr;
         struct hw_addr_data permanent_hw_addr;
+        struct hw_addr_data requested_hw_addr;
         struct in6_addr ipv6ll_address;
         uint32_t mtu;
         uint32_t min_mtu;
index 2fdfb1668949eaaeca7e9b21b55136f3647cd9f6..331b88b69b3270f89c5b9c23b1b1e2dcee998fee 100644 (file)
@@ -61,7 +61,7 @@ Match.KernelCommandLine,                     config_parse_net_condition,
 Match.KernelVersion,                         config_parse_net_condition,                               CONDITION_KERNEL_VERSION,      offsetof(Network, conditions)
 Match.Architecture,                          config_parse_net_condition,                               CONDITION_ARCHITECTURE,        offsetof(Network, conditions)
 Match.Firmware,                              config_parse_net_condition,                               CONDITION_FIRMWARE,            offsetof(Network, conditions)
-Link.MACAddress,                             config_parse_ether_addr,                                  0,                             offsetof(Network, mac)
+Link.MACAddress,                             config_parse_hw_addr,                                     0,                             offsetof(Network, hw_addr)
 Link.MTUBytes,                               config_parse_mtu,                                         AF_UNSPEC,                     offsetof(Network, mtu)
 Link.Group,                                  config_parse_link_group,                                  0,                             0
 Link.ARP,                                    config_parse_tristate,                                    0,                             offsetof(Network, arp)
index 82094a49b1168adc7512bc77b08ba052dab8ae34..c97998848cd1532b97347457b306939549b01c1a 100644 (file)
@@ -674,7 +674,6 @@ static Network *network_free(Network *network) {
         set_free(network->dhcp_allow_listed_ip);
         set_free(network->dhcp_request_options);
         set_free(network->dhcp6_request_options);
-        free(network->mac);
         free(network->dhcp6_mudurl);
         strv_free(network->dhcp6_user_class);
         strv_free(network->dhcp6_vendor_class);
index 626b7710f003f95d6de575b9e216c404218f3b98..942210470c20f829f9d913280fa1bbea953c1f03 100644 (file)
@@ -94,7 +94,7 @@ struct Network {
         Hashmap *stacked_netdev_names;
 
         /* [Link] section */
-        struct ether_addr *mac;
+        struct hw_addr_data hw_addr;
         uint32_t mtu;
         int32_t group;
         int arp;
index 4ec47a495f1bb67996af4976451af6702340b6a1..8b4496540903757e10e241e53790a0fa154f861b 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/if_bridge.h>
 
 #include "missing_network.h"
+#include "netif-util.h"
 #include "netlink-util.h"
 #include "networkd-address.h"
 #include "networkd-can.h"
@@ -183,7 +184,7 @@ static int link_set_mac_allow_retry_handler(sd_netlink *rtnl, sd_netlink_message
                 return 0;
         }
 
-        /* set_link_mac_handler() also decrement set_link_messages, so once increment the value. */
+        /* set_link_mac_handler() also decrements set_link_messages, so increment the value once. */
         link->set_link_messages++;
         return link_set_mac_handler(rtnl, m, link);
 }
@@ -463,7 +464,7 @@ static int link_configure(
                         return log_link_debug_errno(link, r, "Could not append IFLA_GROUP attribute: %m");
                 break;
         case SET_LINK_MAC:
-                r = sd_netlink_message_append_ether_addr(req, IFLA_ADDRESS, link->network->mac);
+                r = netlink_message_append_hw_addr(req, IFLA_ADDRESS, &link->requested_hw_addr);
                 if (r < 0)
                         return log_link_debug_errno(link, r, "Could not append IFLA_ADDRESS attribute: %m");
                 break;
@@ -542,7 +543,7 @@ static bool link_is_ready_to_call_set_link(Request *req) {
                 break;
         case SET_LINK_MAC:
                 if (req->netlink_handler == link_set_mac_handler) {
-                        /* This is the second trial to set MTU. On the first attempt
+                        /* This is the second trial to set hardware address. On the first attempt
                          * req->netlink_handler points to link_set_mac_allow_retry_handler().
                          * The first trial failed as the interface was up. */
                         r = link_down(link);
@@ -777,20 +778,21 @@ int link_request_to_set_group(Link *link) {
 }
 
 int link_request_to_set_mac(Link *link, bool allow_retry) {
+        int r;
+
         assert(link);
         assert(link->network);
 
-        if (!link->network->mac)
+        if (link->network->hw_addr.length == 0)
                 return 0;
 
-        if (link->hw_addr.length != sizeof(struct ether_addr)) {
-                /* Note that for now we only support changing hardware addresses on Ethernet. */
-                log_link_debug(link, "Size of the hardware address (%zu) does not match the size of MAC address (%zu), ignoring.",
-                               link->hw_addr.length, sizeof(struct ether_addr));
-                return 0;
-        }
+        link->requested_hw_addr = link->network->hw_addr;
+        r = net_verify_hardware_address(link->ifname, /* warn_invalid = */ true,
+                                        link->iftype, &link->hw_addr, &link->requested_hw_addr);
+        if (r < 0)
+                return r;
 
-        if (ether_addr_equal(&link->hw_addr.ether, link->network->mac))
+        if (hw_addr_equal(&link->hw_addr, &link->requested_hw_addr))
                 return 0;
 
         return link_request_set_link(link, SET_LINK_MAC,
index 9f3d1dce38f1b50bc047dab772c093738c856d0b..d7ec7e9e25c7927daecdf9032b1d2534983dc926 100755 (executable)
@@ -2704,7 +2704,8 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
 
         output = check_output('ip link show dummy98')
         print(output)
-        self.assertRegex(output, '00:01:02:aa:bb:cc')
+        # 00:01:02:aa:bb:cc was requested, and the local bit is set by networkd.
+        self.assertRegex(output, '02:01:02:aa:bb:cc')
 
     def test_ip_link_unmanaged(self):
         copy_unit_to_networkd_unit_path('25-link-section-unmanaged.network', '12-dummy.netdev')