From: Timo Rothenpieler Date: Mon, 26 Oct 2020 17:07:49 +0000 (+0100) Subject: network: store full hardware address in Link struct X-Git-Tag: v247-rc2~40^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b8162cd200c69be509475b8f2184a5ac651fc2b0;p=thirdparty%2Fsystemd.git network: store full hardware address in Link struct This passes the legacy ethernet address to functions in a lot of places, which all will need migrated to handle arbitrary size hardware addresses eventually. --- diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c index 9130fae7783..d24104d55af 100644 --- a/src/network/networkd-address.c +++ b/src/network/networkd-address.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #include +#include #include "alloc-util.h" #include "firewall-util.h" @@ -21,16 +22,24 @@ int generate_ipv6_eui_64_address(const Link *link, struct in6_addr *ret) { 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; } @@ -1373,7 +1382,7 @@ static int ipv4_dad_configure(Address *address) { 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; @@ -1403,7 +1412,7 @@ static int ipv4_dad_update_mac_one(Address *address) { 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; diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c index bb8c34f7cc5..5255ec3e1c7 100644 --- a/src/network/networkd-dhcp4.c +++ b/src/network/networkd-dhcp4.c @@ -650,7 +650,7 @@ static int dhcp4_configure_dad(Link *link) { 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; @@ -672,7 +672,7 @@ static int dhcp4_dad_update_mac(Link *link) { 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; @@ -1274,8 +1274,8 @@ static int dhcp4_set_client_identifier(Link *link) { 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; @@ -1325,8 +1325,8 @@ int dhcp4_configure(Link *link) { 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"); @@ -1484,7 +1484,7 @@ int dhcp4_update_mac(Link *link) { 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; diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c index d9cc4ccf413..afff1dfc157 100644 --- a/src/network/networkd-dhcp6.c +++ b/src/network/networkd-dhcp6.c @@ -1357,7 +1357,7 @@ static int dhcp6_set_identifier(Link *link, sd_dhcp6_client *client) { 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; diff --git a/src/network/networkd-ipv4ll.c b/src/network/networkd-ipv4ll.c index 3be395e1ada..2f4107580b7 100644 --- a/src/network/networkd-ipv4ll.c +++ b/src/network/networkd-ipv4ll.c @@ -181,7 +181,7 @@ int ipv4ll_configure(Link *link) { 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; @@ -211,7 +211,7 @@ int ipv4ll_update_mac(Link *link) { 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; diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 9dd29bb2030..09622de868b 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -421,9 +421,9 @@ static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) { 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) @@ -2167,7 +2167,7 @@ static int link_reconfigure_internal(Link *link, sd_netlink_message *m, bool for 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); @@ -2302,7 +2302,7 @@ static int link_initialized_and_synced(Link *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); @@ -2697,7 +2697,7 @@ static int link_admin_state_up(Link *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; @@ -2756,19 +2756,13 @@ int link_update(Link *link, sd_netlink_message *m) { /* 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) @@ -2787,7 +2781,7 @@ int link_update(Link *link, sd_netlink_message *m) { 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"); } diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h index a7ae2645f95..bdeee0fe857 100644 --- a/src/network/networkd-link.h +++ b/src/network/networkd-link.h @@ -16,6 +16,7 @@ #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" @@ -52,7 +53,7 @@ typedef struct Link { 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; diff --git a/src/network/networkd-lldp-rx.c b/src/network/networkd-lldp-rx.c index 65a8a314d60..4d431ac8406 100644 --- a/src/network/networkd-lldp-rx.c +++ b/src/network/networkd-lldp-rx.c @@ -93,7 +93,7 @@ int link_lldp_rx_configure(Link *link) { 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; diff --git a/src/network/networkd-lldp-tx.c b/src/network/networkd-lldp-tx.c index c8e56a5fece..4a1b5fb5f8c 100644 --- a/src/network/networkd-lldp-tx.c +++ b/src/network/networkd-lldp-tx.c @@ -313,7 +313,7 @@ static int link_send_lldp(Link *link) { 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, diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c index 6fde8fe2392..a61eaa9fc86 100644 --- a/src/network/networkd-ndisc.c +++ b/src/network/networkd-ndisc.c @@ -5,6 +5,7 @@ #include #include +#include #include #include "sd-ndisc.h" @@ -593,7 +594,11 @@ static int make_stableprivate_address(Link *link, const struct in6_addr *prefix, 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)); @@ -1257,7 +1262,7 @@ int ndisc_configure(Link *link) { 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; diff --git a/src/network/networkd-radv.c b/src/network/networkd-radv.c index eb10f21cbd4..a4162cf8749 100644 --- a/src/network/networkd-radv.c +++ b/src/network/networkd-radv.c @@ -659,7 +659,7 @@ int radv_configure(Link *link) { 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; @@ -727,7 +727,7 @@ int radv_update_mac(Link *link) { 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;