Merge pull request #17444 from BtbN/fix_ib_dhcp4
networkd: fix DHCP on InfiniBand interfaces
This commit is contained in:
@@ -135,7 +135,7 @@ typedef struct LinkInfo {
|
||||
sd_device *sd_device;
|
||||
int ifindex;
|
||||
unsigned short iftype;
|
||||
struct ether_addr mac_address;
|
||||
hw_addr_data hw_address;
|
||||
struct ether_addr permanent_mac_address;
|
||||
uint32_t master;
|
||||
uint32_t mtu;
|
||||
@@ -416,13 +416,14 @@ static int decode_link(sd_netlink_message *m, LinkInfo *info, char **patterns, b
|
||||
info->alternative_names = TAKE_PTR(altnames);
|
||||
|
||||
info->has_mac_address =
|
||||
sd_netlink_message_read_ether_addr(m, IFLA_ADDRESS, &info->mac_address) >= 0 &&
|
||||
memcmp(&info->mac_address, ÐER_ADDR_NULL, sizeof(struct ether_addr)) != 0;
|
||||
netlink_message_read_hw_addr(m, IFLA_ADDRESS, &info->hw_address) >= 0 &&
|
||||
memcmp(&info->hw_address, &HW_ADDR_NULL, sizeof(hw_addr_data)) != 0;
|
||||
|
||||
info->has_permanent_mac_address =
|
||||
ethtool_get_permanent_macaddr(NULL, info->name, &info->permanent_mac_address) >= 0 &&
|
||||
memcmp(&info->permanent_mac_address, ÐER_ADDR_NULL, sizeof(struct ether_addr)) != 0 &&
|
||||
memcmp(&info->permanent_mac_address, &info->mac_address, sizeof(struct ether_addr)) != 0;
|
||||
(info->hw_address.length != sizeof(struct ether_addr) ||
|
||||
memcmp(&info->permanent_mac_address, info->hw_address.addr.bytes, sizeof(struct ether_addr)) != 0);
|
||||
|
||||
(void) sd_netlink_message_read_u32(m, IFLA_MTU, &info->mtu);
|
||||
(void) sd_netlink_message_read_u32(m, IFLA_MIN_MTU, &info->min_mtu);
|
||||
@@ -1526,9 +1527,9 @@ static int link_status_one(
|
||||
|
||||
if (info->has_mac_address) {
|
||||
_cleanup_free_ char *description = NULL;
|
||||
char ea[ETHER_ADDR_TO_STRING_MAX];
|
||||
|
||||
(void) ieee_oui(hwdb, &info->mac_address, &description);
|
||||
if (info->hw_address.length == ETH_ALEN)
|
||||
(void) ieee_oui(hwdb, &info->hw_address.addr.ether, &description);
|
||||
|
||||
r = table_add_many(table,
|
||||
TABLE_EMPTY,
|
||||
@@ -1536,7 +1537,7 @@ static int link_status_one(
|
||||
if (r < 0)
|
||||
return table_log_add_error(r);
|
||||
r = table_add_cell_stringf(table, NULL, "%s%s%s%s",
|
||||
ether_addr_to_string(&info->mac_address, ea),
|
||||
HW_ADDR_TO_STR(&info->hw_address),
|
||||
description ? " (" : "",
|
||||
strempty(description),
|
||||
description ? ")" : "");
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1271,14 +1271,24 @@ static int dhcp4_set_client_identifier(Link *link) {
|
||||
return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set DUID: %m");
|
||||
break;
|
||||
}
|
||||
case DHCP_CLIENT_ID_MAC:
|
||||
case DHCP_CLIENT_ID_MAC: {
|
||||
const uint8_t *hw_addr = link->hw_addr.addr.bytes;
|
||||
size_t hw_addr_len = link->hw_addr.length;
|
||||
|
||||
if (link->iftype == ARPHRD_INFINIBAND && hw_addr_len == INFINIBAND_ALEN) {
|
||||
/* set_client_id expects only last 8 bytes of an IB address */
|
||||
hw_addr += INFINIBAND_ALEN - 8;
|
||||
hw_addr_len -= INFINIBAND_ALEN - 8;
|
||||
}
|
||||
|
||||
r = sd_dhcp_client_set_client_id(link->dhcp_client,
|
||||
ARPHRD_ETHER,
|
||||
(const uint8_t *) &link->mac,
|
||||
sizeof(link->mac));
|
||||
link->iftype,
|
||||
hw_addr,
|
||||
hw_addr_len);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set client ID: %m");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
assert_not_reached("Unknown client identifier type.");
|
||||
}
|
||||
@@ -1325,8 +1335,9 @@ 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->bcast_addr.length > 0 ? link->bcast_addr.addr.bytes : NULL,
|
||||
link->hw_addr.length, link->iftype);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set MAC address: %m");
|
||||
|
||||
@@ -1484,7 +1495,9 @@ 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->bcast_addr.length > 0 ? link->bcast_addr.addr.bytes : NULL,
|
||||
link->hw_addr.length, link->iftype);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
@@ -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, link->iftype);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
+15
-17
@@ -421,9 +421,13 @@ 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 = netlink_message_read_hw_addr(message, IFLA_BROADCAST, &link->bcast_addr);
|
||||
if (r < 0)
|
||||
log_link_debug_errno(link, r, "Broadcast 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 +2171,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 +2306,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 +2701,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 +2760,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 +2785,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");
|
||||
}
|
||||
|
||||
@@ -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,8 @@ typedef struct Link {
|
||||
char *kind;
|
||||
unsigned short iftype;
|
||||
char *state_file;
|
||||
struct ether_addr mac;
|
||||
hw_addr_data hw_addr;
|
||||
hw_addr_data bcast_addr;
|
||||
struct ether_addr permanent_mac;
|
||||
struct in6_addr ipv6ll_address;
|
||||
uint32_t mtu;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user