People often assigns the MAC address of the enslaved interface to e.g.
bridge interface. So, the local assignment bit should not be adjusted.
Fixes #21649.
struct hw_addr_data *ret) {
struct hw_addr_data a = HW_ADDR_NULL;
- bool warn_invalid = false;
+ bool is_static = false;
int r;
assert(netdev);
} else {
a = *hw_addr;
- warn_invalid = true;
+ is_static = true;
}
- r = net_verify_hardware_address(name, warn_invalid, NETDEV_VTABLE(netdev)->iftype,
+ r = net_verify_hardware_address(name, is_static, NETDEV_VTABLE(netdev)->iftype,
parent ? &parent->hw_addr : NULL, &a);
if (r < 0)
return r;
return 0;
link->requested_hw_addr = link->network->hw_addr;
- r = net_verify_hardware_address(link->ifname, /* warn_invalid = */ true,
+ r = net_verify_hardware_address(link->ifname, /* is_static = */ true,
link->iftype, &link->hw_addr, &link->requested_hw_addr);
if (r < 0)
return r;
int net_verify_hardware_address(
const char *ifname,
- bool warn_invalid,
+ bool is_static,
uint16_t iftype,
const struct hw_addr_data *ib_hw_addr, /* current or parent HW address */
struct hw_addr_data *new_hw_addr) {
return 0;
if (new_hw_addr->length != arphrd_to_hw_addr_len(iftype)) {
- if (warn_invalid)
+ if (is_static)
log_link_warning(&link,
"Specified MAC address with invalid length (%zu, expected %zu), refusing.",
new_hw_addr->length, arphrd_to_hw_addr_len(iftype));
/* see eth_random_addr() in the kernel */
if (ether_addr_is_null(&new_hw_addr->ether)) {
- if (warn_invalid)
+ if (is_static)
log_link_warning(&link, "Specified MAC address is null, refusing.");
return -EINVAL;
}
if (ether_addr_is_broadcast(&new_hw_addr->ether)) {
- if (warn_invalid)
+ if (is_static)
log_link_warning(&link, "Specified MAC address is broadcast, refusing.");
return -EINVAL;
}
if (ether_addr_is_multicast(&new_hw_addr->ether)) {
- if (warn_invalid)
+ if (is_static)
log_link_warning(&link, "Specified MAC address has the multicast bit set, clearing the bit.");
new_hw_addr->bytes[0] &= 0xfe;
}
- if (!ether_addr_is_local(&new_hw_addr->ether)) {
- if (warn_invalid)
- log_link_warning(&link, "Specified MAC address does not have the local assignment bit set, setting the bit.");
-
+ if (!is_static && !ether_addr_is_local(&new_hw_addr->ether))
+ /* Adjust local assignment bit when the MAC address is generated randomly. */
new_hw_addr->bytes[0] |= 0x02;
- }
break;
assert(ib_hw_addr);
assert(ib_hw_addr->length == INFINIBAND_ALEN);
- if (warn_invalid &&
+ if (is_static &&
(!memeqzero(new_hw_addr->bytes, INFINIBAND_ALEN - 8) ||
memcmp(new_hw_addr->bytes, ib_hw_addr->bytes, INFINIBAND_ALEN - 8) != 0))
log_link_warning(&link, "Only the last 8 bytes of the InifniBand MAC address can be changed, ignoring the first 12 bytes.");
if (memeqzero(new_hw_addr->bytes + INFINIBAND_ALEN - 8, 8)) {
- if (warn_invalid)
+ if (is_static)
log_link_warning(&link, "The last 8 bytes of the InfiniBand MAC address cannot be null, refusing.");
return -EINVAL;
}
break;
default:
- if (warn_invalid)
+ if (is_static)
log_link_warning(&link, "Unsupported interface type %s%u to set MAC address, refusing.",
strna(arphrd_to_name(iftype)), iftype);
return -EINVAL;
int net_get_unique_predictable_data_from_name(const char *name, const sd_id128_t *key, uint64_t *ret);
int net_verify_hardware_address(
const char *ifname,
- bool warn_invalid,
+ bool is_static,
uint16_t iftype,
const struct hw_addr_data *ib_hw_addr,
struct hw_addr_data *new_hw_addr);
static int link_generate_new_hw_addr(Link *link, struct hw_addr_data *ret) {
struct hw_addr_data hw_addr = HW_ADDR_NULL;
- bool warn_invalid = false;
+ bool is_static = false;
uint8_t *p;
size_t len;
int r;
if (link->config->mac_address_policy == MAC_ADDRESS_POLICY_NONE) {
log_link_debug(link, "Using static MAC address.");
hw_addr = link->config->hw_addr;
- warn_invalid = true;
+ is_static = true;
goto finalize;
}
finalize:
- r = net_verify_hardware_address(link->ifname, warn_invalid, link->iftype, &link->hw_addr, &hw_addr);
+ r = net_verify_hardware_address(link->ifname, is_static, link->iftype, &link->hw_addr, &hw_addr);
if (r < 0)
return r;
output = check_output('ip link show dropin-test')
print(output)
- # 00:50:56:c0:00:28 was requested, and the local bit is set by networkd.
- self.assertRegex(output, '02:50:56:c0:00:28')
+ self.assertRegex(output, '00:50:56:c0:00:28')
def test_match_udev_property(self):
copy_unit_to_networkd_unit_path('12-dummy.netdev', '13-not-match-udev-property.network', '14-match-udev-property.network')
output = check_output('ip link show dummy98')
print(output)
- # 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')
+ self.assertRegex(output, '00: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')