]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network/netdev: make MACAddress= take 'none' to suppress generating persistent hardwa...
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 28 Nov 2021 02:51:08 +0000 (11:51 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 28 Nov 2021 03:04:55 +0000 (12:04 +0900)
This is mostly equivalent to .link file's MACAddressPolicy=none.

man/systemd.netdev.xml
src/network/netdev/netdev-gperf.gperf
src/network/netdev/netdev.c
src/network/netdev/netdev.h
src/network/netdev/veth.c

index 9cbd99a0efc31df9baecc31a9ede071a736073b2..133c6fcc637261658c6c459e1b5afbb8a5a77195 100644 (file)
       <varlistentry>
         <term><varname>MACAddress=</varname></term>
         <listitem>
-          <para>The MAC address to use for the device. For <literal>tun</literal> or <literal>tap</literal>
-          devices, setting <varname>MACAddress=</varname> in the [NetDev] section is not
-          supported. Please specify it in the [Link] section of the corresponding
+          <para>Specifies the MAC address to use for the device, or takes the special value
+          <literal>none</literal>. When <literal>none</literal>, <command>systemd-networkd</command>
+          does not request the MAC address for the device, and the kernel will assign a random MAC
+          address. For <literal>tun</literal>, <literal>tap</literal>, or <literal>l2tp</literal>
+          devices, the <varname>MACAddress=</varname> setting in the [NetDev] section is not
+          supported and will be ignored. Please specify it in the [Link] section of the corresponding
           <citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum></citerefentry>
           file. If this option is not set, <literal>bridge</literal> and <literal>vlan</literal> devices
           inherit the MAC address of the first slave device or the physical interface, respectively. For other
           name and the
           <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
           </para>
+          <para>Note, even if <literal>none</literal> is specified, <command>systemd-udevd</command>
+          will assign the persistent MAC address for the device, as <filename>99-default.link</filename>
+          has <varname>MACAddressPolicy=persistent</varname>. So, it is also necessary to create a
+          custom .link file for the device, if the MAC address assignment is not desired.</para>
         </listitem>
       </varlistentry>
     </variablelist>
index d0f493b4ef596c406876c1c40852091e606a4808..316592005f2838bb3b35f949a65e0e9234cfa89e 100644 (file)
@@ -49,7 +49,7 @@ NetDev.Description,                       config_parse_string,
 NetDev.Name,                              config_parse_ifname,                       0,                             offsetof(NetDev, ifname)
 NetDev.Kind,                              config_parse_netdev_kind,                  0,                             offsetof(NetDev, kind)
 NetDev.MTUBytes,                          config_parse_mtu,                          AF_UNSPEC,                     offsetof(NetDev, mtu)
-NetDev.MACAddress,                        config_parse_hw_addr,                      ETH_ALEN,                      offsetof(NetDev, hw_addr)
+NetDev.MACAddress,                        config_parse_netdev_hw_addr,               ETH_ALEN,                      offsetof(NetDev, hw_addr)
 VLAN.Id,                                  config_parse_vlanid,                       0,                             offsetof(VLan, id)
 VLAN.Protocol,                            config_parse_vlanprotocol,                 0,                             offsetof(VLan, protocol)
 VLAN.GVRP,                                config_parse_tristate,                     0,                             offsetof(VLan, gvrp)
@@ -111,7 +111,7 @@ L2TPSession.PeerSessionId,                config_parse_l2tp_session_id,
 L2TPSession.Layer2SpecificHeader,         config_parse_l2tp_session_l2spec,          0,                             0
 L2TPSession.Name,                         config_parse_l2tp_session_name,            0,                             0
 Peer.Name,                                config_parse_ifname,                       0,                             offsetof(Veth, ifname_peer)
-Peer.MACAddress,                          config_parse_hw_addr,                      ETH_ALEN,                      offsetof(Veth, hw_addr_peer)
+Peer.MACAddress,                          config_parse_netdev_hw_addr,               ETH_ALEN,                      offsetof(Veth, hw_addr_peer)
 VXCAN.Peer,                               config_parse_ifname,                       0,                             offsetof(VxCan, ifname_peer)
 VXLAN.VNI,                                config_parse_uint32,                       0,                             offsetof(VxLan, vni)
 VXLAN.Id,                                 config_parse_uint32,                       0,                             offsetof(VxLan, vni) /* deprecated */
index 4d0f2e14eb7e9bac8620015d00da87dd4d8c8718..5d88cbdf5f12bda3333b35143cf224e2dfec62b6 100644 (file)
@@ -400,6 +400,9 @@ int netdev_generate_hw_addr(NetDev *netdev, const char *name, struct hw_addr_dat
         assert(name);
         assert(hw_addr);
 
+        if (hw_addr_equal(hw_addr, &HW_ADDR_NONE))
+                return 0;
+
         if (hw_addr->length == 0) {
                 uint64_t result;
 
@@ -467,7 +470,7 @@ static int netdev_create(NetDev *netdev, Link *link, link_netlink_message_handle
         if (r < 0)
                 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IFNAME, attribute: %m");
 
-        if (netdev->hw_addr.length > 0) {
+        if (netdev->hw_addr.length > 0 && !hw_addr_equal(&netdev->hw_addr, &HW_ADDR_NULL)) {
                 r = netlink_message_append_hw_addr(m, IFLA_ADDRESS, &netdev->hw_addr);
                 if (r < 0)
                         return log_netdev_error_errno(netdev, r, "Could not append IFLA_ADDRESS attribute: %m");
@@ -887,3 +890,28 @@ int config_parse_netdev_kind(
 
         return 0;
 }
+
+int config_parse_netdev_hw_addr(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        struct hw_addr_data *hw_addr = data;
+
+        assert(rvalue);
+        assert(data);
+
+        if (streq(rvalue, "none")) {
+                *hw_addr = HW_ADDR_NONE;
+                return 0;
+        }
+
+        return config_parse_hw_addr(unit, filename, line, section, section_line, lvalue, ltype, rvalue, data, userdata);
+}
index d480d125a69bdbfed026425e12cba02dc41ed746..ed8a2e33c51addc8c101b41790f26d92dd0b70ce 100644 (file)
@@ -10,6 +10,9 @@
 #include "networkd-link.h"
 #include "time-util.h"
 
+/* Special hardware address value to suppress generating persistent hardware address for the netdev. */
+#define HW_ADDR_NONE ((struct hw_addr_data) { .length = 1, })
+
 #define NETDEV_COMMON_SECTIONS "Match\0NetDev\0"
 /* This is the list of known sections. We need to ignore them in the initial parsing phase. */
 #define NETDEV_OTHER_SECTIONS                     \
@@ -215,6 +218,7 @@ static inline NetDevCreateType netdev_get_create_type(NetDev *netdev) {
 }
 
 CONFIG_PARSER_PROTOTYPE(config_parse_netdev_kind);
+CONFIG_PARSER_PROTOTYPE(config_parse_netdev_hw_addr);
 
 /* gperf */
 const struct ConfigPerfItem* network_netdev_gperf_lookup(const char *key, GPERF_LEN_TYPE length);
index f1c05c6205204a2f21e9d7bfddd9f5be401ed2f8..d7870d7628a476c38c2ebed88f513a599bcc1d41 100644 (file)
@@ -31,7 +31,7 @@ static int netdev_veth_fill_message_create(NetDev *netdev, Link *link, sd_netlin
                         return log_netdev_error_errno(netdev, r, "Failed to add netlink interface name: %m");
         }
 
-        if (v->hw_addr_peer.length > 0) {
+        if (v->hw_addr_peer.length > 0 && !hw_addr_equal(&v->hw_addr_peer, &HW_ADDR_NULL)) {
                 r = netlink_message_append_hw_addr(m, IFLA_ADDRESS, &v->hw_addr_peer);
                 if (r < 0)
                         return log_netdev_error_errno(netdev, r, "Could not append IFLA_ADDRESS attribute: %m");