/* SPDX-License-Identifier: LGPL-2.1+ */
#include <net/if.h>
+#include <net/if_arp.h>
#include "alloc-util.h"
#include "firewall-util.h"
assert(link);
assert(ret);
+ if (link->iftype == ARPHRD_INFINIBAND) {
+ /* see RFC4391 section 8 */
+ memcpy(&ret->s6_addr[8], &link->hw_addr.addr.infiniband[12], 8);
+ ret->s6_addr[8] ^= 1 << 1;
+
+ return 0;
+ }
+
/* see RFC4291 section 2.5.1 */
- ret->s6_addr[8] = link->mac.ether_addr_octet[0];
+ ret->s6_addr[8] = link->hw_addr.addr.ether.ether_addr_octet[0];
ret->s6_addr[8] ^= 1 << 1;
- ret->s6_addr[9] = link->mac.ether_addr_octet[1];
- ret->s6_addr[10] = link->mac.ether_addr_octet[2];
+ ret->s6_addr[9] = link->hw_addr.addr.ether.ether_addr_octet[1];
+ ret->s6_addr[10] = link->hw_addr.addr.ether.ether_addr_octet[2];
ret->s6_addr[11] = 0xff;
ret->s6_addr[12] = 0xfe;
- ret->s6_addr[13] = link->mac.ether_addr_octet[3];
- ret->s6_addr[14] = link->mac.ether_addr_octet[4];
- ret->s6_addr[15] = link->mac.ether_addr_octet[5];
+ ret->s6_addr[13] = link->hw_addr.addr.ether.ether_addr_octet[3];
+ ret->s6_addr[14] = link->hw_addr.addr.ether.ether_addr_octet[4];
+ ret->s6_addr[15] = link->hw_addr.addr.ether.ether_addr_octet[5];
return 0;
}
if (r < 0)
return r;
- r = sd_ipv4acd_set_mac(address->acd, &address->link->mac);
+ r = sd_ipv4acd_set_mac(address->acd, &address->link->hw_addr.addr.ether);
if (r < 0)
return r;
if (r < 0)
return r;
- r = sd_ipv4acd_set_mac(address->acd, &address->link->mac);
+ r = sd_ipv4acd_set_mac(address->acd, &address->link->hw_addr.addr.ether);
if (r < 0)
return r;
if (r < 0)
return r;
- r = sd_ipv4acd_set_mac(link->dhcp_acd, &link->mac);
+ r = sd_ipv4acd_set_mac(link->dhcp_acd, &link->hw_addr.addr.ether);
if (r < 0)
return r;
if (r < 0)
return r;
- r = sd_ipv4acd_set_mac(link->dhcp_acd, &link->mac);
+ r = sd_ipv4acd_set_mac(link->dhcp_acd, &link->hw_addr.addr.ether);
if (r < 0)
return r;
case DHCP_CLIENT_ID_MAC:
r = sd_dhcp_client_set_client_id(link->dhcp_client,
ARPHRD_ETHER,
- (const uint8_t *) &link->mac,
- sizeof(link->mac));
+ link->hw_addr.addr.bytes,
+ link->hw_addr.length);
if (r < 0)
return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set client ID: %m");
break;
return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to initialize DHCP4 client: %m");
r = sd_dhcp_client_set_mac(link->dhcp_client,
- (const uint8_t *) &link->mac,
- sizeof (link->mac), ARPHRD_ETHER);
+ link->hw_addr.addr.bytes,
+ link->hw_addr.length, ARPHRD_ETHER);
if (r < 0)
return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set MAC address: %m");
if (!link->dhcp_client)
return 0;
- r = sd_dhcp_client_set_mac(link->dhcp_client, (const uint8_t *) &link->mac, sizeof (link->mac), ARPHRD_ETHER);
+ r = sd_dhcp_client_set_mac(link->dhcp_client, link->hw_addr.addr.bytes, link->hw_addr.length, ARPHRD_ETHER);
if (r < 0)
return r;
assert(link->network);
assert(client);
- r = sd_dhcp6_client_set_mac(client, (const uint8_t *) &link->mac, sizeof (link->mac), ARPHRD_ETHER);
+ r = sd_dhcp6_client_set_mac(client, link->hw_addr.addr.bytes, link->hw_addr.length, ARPHRD_ETHER);
if (r < 0)
return r;
return r;
}
- r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
+ r = sd_ipv4ll_set_mac(link->ipv4ll, &link->hw_addr.addr.ether);
if (r < 0)
return r;
if (r < 0)
return r;
- r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
+ r = sd_ipv4ll_set_mac(link->ipv4ll, &link->hw_addr.addr.ether);
if (r < 0)
return r;
if (r < 0)
log_link_debug_errno(link, r, "New device has no master, continuing without");
- r = sd_netlink_message_read_ether_addr(message, IFLA_ADDRESS, &link->mac);
+ r = netlink_message_read_hw_addr(message, IFLA_ADDRESS, &link->hw_addr);
if (r < 0)
- log_link_debug_errno(link, r, "MAC address not found for new device, continuing without");
+ log_link_debug_errno(link, r, "Hardware address not found for new device, continuing without");
r = ethtool_get_permanent_macaddr(&manager->ethtool_fd, link->ifname, &link->permanent_mac);
if (r < 0)
r = network_get(link->manager, link->iftype, link->sd_device,
link->ifname, link->alternative_names, link->driver,
- &link->mac, &link->permanent_mac,
+ &link->hw_addr.addr.ether, &link->permanent_mac,
link->wlan_iftype, link->ssid, &link->bssid, &network);
if (r == -ENOENT) {
link_enter_unmanaged(link);
r = network_get(link->manager, link->iftype, link->sd_device,
link->ifname, link->alternative_names, link->driver,
- &link->mac, &link->permanent_mac,
+ &link->hw_addr.addr.ether, &link->permanent_mac,
link->wlan_iftype, link->ssid, &link->bssid, &network);
if (r == -ENOENT) {
link_enter_unmanaged(link);
int link_update(Link *link, sd_netlink_message *m) {
_cleanup_strv_free_ char **s = NULL;
- struct ether_addr mac;
+ hw_addr_data hw_addr;
const char *ifname;
uint32_t mtu;
bool had_carrier, carrier_gained, carrier_lost, link_was_admin_up;
/* The kernel may broadcast NEWLINK messages without the MAC address
set, simply ignore them. */
- r = sd_netlink_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
- if (r >= 0 && memcmp(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN) != 0) {
+ r = netlink_message_read_hw_addr(m, IFLA_ADDRESS, &hw_addr);
+ if (r >= 0 && (link->hw_addr.length != hw_addr.length ||
+ memcmp(link->hw_addr.addr.bytes, hw_addr.addr.bytes, hw_addr.length) != 0)) {
- memcpy(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN);
+ memcpy(link->hw_addr.addr.bytes, hw_addr.addr.bytes, hw_addr.length);
- log_link_debug(link, "Gained new MAC address: "
- "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
- mac.ether_addr_octet[0],
- mac.ether_addr_octet[1],
- mac.ether_addr_octet[2],
- mac.ether_addr_octet[3],
- mac.ether_addr_octet[4],
- mac.ether_addr_octet[5]);
+ log_link_debug(link, "Gained new hardware address: %s", HW_ADDR_TO_STR(&hw_addr));
r = ipv4ll_update_mac(link);
if (r < 0)
return log_link_warning_errno(link, r, "Could not update MAC address for Router Advertisement: %m");
if (link->ndisc) {
- r = sd_ndisc_set_mac(link->ndisc, &link->mac);
+ r = sd_ndisc_set_mac(link->ndisc, &link->hw_addr.addr.ether);
if (r < 0)
return log_link_warning_errno(link, r, "Could not update MAC for NDisc: %m");
}
#include "sd-radv.h"
#include "sd-netlink.h"
+#include "ether-addr-util.h"
#include "log-link.h"
#include "network-util.h"
#include "networkd-util.h"
char *kind;
unsigned short iftype;
char *state_file;
- struct ether_addr mac;
+ hw_addr_data hw_addr;
struct ether_addr permanent_mac;
struct in6_addr ipv6ll_address;
uint32_t mtu;
if (r < 0)
return r;
- r = sd_lldp_set_filter_address(link->lldp, &link->mac);
+ r = sd_lldp_set_filter_address(link->lldp, &link->hw_addr.addr.ether);
if (r < 0)
return r;
SD_LLDP_SYSTEM_CAPABILITIES_STATION;
r = lldp_make_packet(link->network->lldp_emit,
- &link->mac,
+ &link->hw_addr.addr.ether,
sd_id128_to_string(machine_id, machine_id_string),
link->ifname,
(uint16_t) ttl,
#include <arpa/inet.h>
#include <netinet/icmp6.h>
+#include <net/if_arp.h>
#include <linux/if.h>
#include "sd-ndisc.h"
l = MAX(DIV_ROUND_UP(prefix_len, 8), 8);
siphash24_compress(prefix, l, &state);
siphash24_compress_string(link->ifname, &state);
- siphash24_compress(&link->mac, sizeof(struct ether_addr), &state);
+ /* Only last 8 bytes of IB MAC are stable */
+ if (link->iftype == ARPHRD_INFINIBAND)
+ siphash24_compress(&link->hw_addr.addr.infiniband[12], 8, &state);
+ else
+ siphash24_compress(link->hw_addr.addr.bytes, link->hw_addr.length, &state);
siphash24_compress(&dad_counter, sizeof(uint8_t), &state);
rid = htole64(siphash24_finalize(&state));
return r;
}
- r = sd_ndisc_set_mac(link->ndisc, &link->mac);
+ r = sd_ndisc_set_mac(link->ndisc, &link->hw_addr.addr.ether);
if (r < 0)
return r;
if (r < 0)
return r;
- r = sd_radv_set_mac(link->radv, &link->mac);
+ r = sd_radv_set_mac(link->radv, &link->hw_addr.addr.ether);
if (r < 0)
return r;
if (r < 0)
return r;
- r = sd_radv_set_mac(link->radv, &link->mac);
+ r = sd_radv_set_mac(link->radv, &link->hw_addr.addr.ether);
if (r < 0)
return r;