From 5dcc5b1a1146941edeac143eec8fe4a29560078a Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 28 Nov 2021 11:23:42 +0900 Subject: [PATCH 1/3] network/netdev: move config_parse_netdev_kind() at the end --- src/network/netdev/netdev.c | 71 +++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 35 deletions(-) diff --git a/src/network/netdev/netdev.c b/src/network/netdev/netdev.c index 2fd2659ddb..4d0f2e14eb 100644 --- a/src/network/netdev/netdev.c +++ b/src/network/netdev/netdev.c @@ -128,41 +128,6 @@ static const char* const netdev_kind_table[_NETDEV_KIND_MAX] = { DEFINE_STRING_TABLE_LOOKUP(netdev_kind, NetDevKind); -int config_parse_netdev_kind( - 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) { - - NetDevKind k, *kind = data; - - assert(rvalue); - assert(data); - - k = netdev_kind_from_string(rvalue); - if (k < 0) { - log_syntax(unit, LOG_WARNING, filename, line, k, "Failed to parse netdev kind, ignoring assignment: %s", rvalue); - return 0; - } - - if (*kind != _NETDEV_KIND_INVALID && *kind != k) { - log_syntax(unit, LOG_WARNING, filename, line, 0, - "Specified netdev kind is different from the previous value '%s', ignoring assignment: %s", - netdev_kind_to_string(*kind), rvalue); - return 0; - } - - *kind = k; - - return 0; -} - bool netdev_is_managed(NetDev *netdev) { if (!netdev || !netdev->manager || !netdev->ifname) return false; @@ -886,3 +851,39 @@ int netdev_load(Manager *manager, bool reload) { return 0; } + +int config_parse_netdev_kind( + 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) { + + NetDevKind k, *kind = data; + + assert(filename); + assert(rvalue); + assert(data); + + k = netdev_kind_from_string(rvalue); + if (k < 0) { + log_syntax(unit, LOG_WARNING, filename, line, k, "Failed to parse netdev kind, ignoring assignment: %s", rvalue); + return 0; + } + + if (*kind != _NETDEV_KIND_INVALID && *kind != k) { + log_syntax(unit, LOG_WARNING, filename, line, 0, + "Specified netdev kind is different from the previous value '%s', ignoring assignment: %s", + netdev_kind_to_string(*kind), rvalue); + return 0; + } + + *kind = k; + + return 0; +} From aaa5ca57ae073bfc72bc77ca797fd23579d1e185 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 28 Nov 2021 11:51:08 +0900 Subject: [PATCH 2/3] network/netdev: make MACAddress= take 'none' to suppress generating persistent hardware address This is mostly equivalent to .link file's MACAddressPolicy=none. --- man/systemd.netdev.xml | 13 +++++++++--- src/network/netdev/netdev-gperf.gperf | 4 ++-- src/network/netdev/netdev.c | 30 ++++++++++++++++++++++++++- src/network/netdev/netdev.h | 4 ++++ src/network/netdev/veth.c | 2 +- 5 files changed, 46 insertions(+), 7 deletions(-) diff --git a/man/systemd.netdev.xml b/man/systemd.netdev.xml index 9cbd99a0ef..133c6fcc63 100644 --- a/man/systemd.netdev.xml +++ b/man/systemd.netdev.xml @@ -254,9 +254,12 @@ MACAddress= - The MAC address to use for the device. For tun or tap - devices, setting MACAddress= in the [NetDev] section is not - supported. Please specify it in the [Link] section of the corresponding + Specifies the MAC address to use for the device, or takes the special value + none. When none, systemd-networkd + does not request the MAC address for the device, and the kernel will assign a random MAC + address. For tun, tap, or l2tp + devices, the MACAddress= setting in the [NetDev] section is not + supported and will be ignored. Please specify it in the [Link] section of the corresponding systemd.network5 file. If this option is not set, bridge and vlan devices inherit the MAC address of the first slave device or the physical interface, respectively. For other @@ -264,6 +267,10 @@ name and the machine-id5. + Note, even if none is specified, systemd-udevd + will assign the persistent MAC address for the device, as 99-default.link + has MACAddressPolicy=persistent. So, it is also necessary to create a + custom .link file for the device, if the MAC address assignment is not desired. diff --git a/src/network/netdev/netdev-gperf.gperf b/src/network/netdev/netdev-gperf.gperf index d0f493b4ef..316592005f 100644 --- a/src/network/netdev/netdev-gperf.gperf +++ b/src/network/netdev/netdev-gperf.gperf @@ -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 */ diff --git a/src/network/netdev/netdev.c b/src/network/netdev/netdev.c index 4d0f2e14eb..5d88cbdf5f 100644 --- a/src/network/netdev/netdev.c +++ b/src/network/netdev/netdev.c @@ -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); +} diff --git a/src/network/netdev/netdev.h b/src/network/netdev/netdev.h index d480d125a6..ed8a2e33c5 100644 --- a/src/network/netdev/netdev.h +++ b/src/network/netdev/netdev.h @@ -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); diff --git a/src/network/netdev/veth.c b/src/network/netdev/veth.c index f1c05c6205..d7870d7628 100644 --- a/src/network/netdev/veth.c +++ b/src/network/netdev/veth.c @@ -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"); From 5b8bdd20c621dd1a34d4e5b200ef9ea1711bfb14 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 8 Nov 2021 11:36:09 +0900 Subject: [PATCH 3/3] network/netdev: generate persistent MAC address for batadv and bridge This mostly reverts 489f01f806f865eabb55458c98182b06a6c53a62 and deb2cfa4c6885d448eb1f17e5ef1b139106b7e86. As now MACAddress=none is supported. So, users can still disable MAC address assignment. --- man/systemd.netdev.xml | 7 +++---- src/network/netdev/batadv.c | 1 + src/network/netdev/bridge.c | 1 + 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/man/systemd.netdev.xml b/man/systemd.netdev.xml index 133c6fcc63..bd493a8c53 100644 --- a/man/systemd.netdev.xml +++ b/man/systemd.netdev.xml @@ -261,10 +261,9 @@ devices, the MACAddress= setting in the [NetDev] section is not supported and will be ignored. Please specify it in the [Link] section of the corresponding systemd.network5 - file. If this option is not set, bridge and vlan devices - inherit the MAC address of the first slave device or the physical interface, respectively. For other - kind of netdevs, if this option is not set, then the MAC address is generated based on the interface - name and the + file. If this option is not set, vlan device inherits the MAC address of + the master interface. For other kind of netdevs, if this option is not set, then the MAC + address is generated based on the interface name and the machine-id5. Note, even if none is specified, systemd-udevd diff --git a/src/network/netdev/batadv.c b/src/network/netdev/batadv.c index f42f572a36..15f3aee3a6 100644 --- a/src/network/netdev/batadv.c +++ b/src/network/netdev/batadv.c @@ -203,4 +203,5 @@ const NetDevVTable batadv_vtable = { .post_create = netdev_batadv_post_create, .create_type = NETDEV_CREATE_MASTER, .iftype = ARPHRD_ETHER, + .generate_mac = true, }; diff --git a/src/network/netdev/bridge.c b/src/network/netdev/bridge.c index 2d60e441ec..64d65493ca 100644 --- a/src/network/netdev/bridge.c +++ b/src/network/netdev/bridge.c @@ -278,4 +278,5 @@ const NetDevVTable bridge_vtable = { .post_create = netdev_bridge_post_create, .create_type = NETDEV_CREATE_MASTER, .iftype = ARPHRD_ETHER, + .generate_mac = true, };