]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: store full hardware address in Link struct
authorTimo Rothenpieler <timo@rothenpieler.org>
Mon, 26 Oct 2020 17:07:49 +0000 (18:07 +0100)
committerTimo Rothenpieler <timo@rothenpieler.org>
Wed, 28 Oct 2020 13:44:43 +0000 (14:44 +0100)
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.

src/network/networkd-address.c
src/network/networkd-dhcp4.c
src/network/networkd-dhcp6.c
src/network/networkd-ipv4ll.c
src/network/networkd-link.c
src/network/networkd-link.h
src/network/networkd-lldp-rx.c
src/network/networkd-lldp-tx.c
src/network/networkd-ndisc.c
src/network/networkd-radv.c

index 9130fae77830f32bc60a763cc6034d7d60b1c16c..d24104d55afc830406c9692aca45ad2fc9bb3e7c 100644 (file)
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: LGPL-2.1+ */
 
 #include <net/if.h>
+#include <net/if_arp.h>
 
 #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;
 
index bb8c34f7cc5959c048e21a3a6b61c73cb54453ec..5255ec3e1c73099da1983869e838da19af3b31a7 100644 (file)
@@ -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;
 
index d9cc4ccf41326ef4517dd261947c480c8ecd94a6..afff1dfc1571f9294d8be28e7d3ea9959947d430 100644 (file)
@@ -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;
 
index 3be395e1ada6989ef9de339afc85073240660256..2f4107580b79c38e23be0589f5d62cd286dc2749 100644 (file)
@@ -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;
 
index 9dd29bb203081c308980651af22354c23642da08..09622de868bcd50d9088152980dea091d849fe95 100644 (file)
@@ -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");
                 }
index a7ae2645f95817461eaf74e71e581369c48bb779..bdeee0fe857fa5c3b40dcb87af7b85af1c9200ab 100644 (file)
@@ -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;
index 65a8a314d602adf6412fdf74bc7b5d9492a8f52e..4d431ac840693e1616a9dc42036fb29fb105165e 100644 (file)
@@ -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;
 
index c8e56a5fece64efcf06a73531711a8f6978c67c3..4a1b5fb5f8c2e67d29347d1d325c4e1d82011a10 100644 (file)
@@ -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,
index 6fde8fe239259b4650d4939edbab70cfcd65f5f2..a61eaa9fc868018c7dd591f72fe0485a1d10f3f5 100644 (file)
@@ -5,6 +5,7 @@
 
 #include <arpa/inet.h>
 #include <netinet/icmp6.h>
+#include <net/if_arp.h>
 #include <linux/if.h>
 
 #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;
 
index eb10f21cbd456602720043e8a934f8610e91dfdc..a4162cf8749bf43483bedec9f78f9f3b38742c3f 100644 (file)
@@ -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;