network/netdev: make MACAddress= take 'none' to suppress generating persistent hardware address

This is mostly equivalent to .link file's MACAddressPolicy=none.
This commit is contained in:
Yu Watanabe 2021-11-28 11:51:08 +09:00
parent 5dcc5b1a11
commit aaa5ca57ae
5 changed files with 46 additions and 7 deletions

View file

@ -254,9 +254,12 @@
<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
@ -264,6 +267,10 @@
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>

View 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 */

View 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);
}

View 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);

View 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");