dhcp: fix generating MAC based client-id for infiniband

For infiniband, only the last 8 bytes for the 20 bytes hardware address
are relevant. At least, with respect to the settings

  - ipv4.dhcp-client-id=mac
  - ipv4.dhcp-client-id=perm-mac
  - ipv6.dhcp-duid=ll
  - ipv6.dhcp-duid=llt
  - ipv6.dhcp-duid=stable-ll
  - ipv6.dhcp-duid=stable-llt

This is also what ISC dhclient on Fedora/RHEL does ([1], [2]).

[1] https://bugzilla.redhat.com/show_bug.cgi?id=660681
[2] 3ccf3c8d81/f/dhcp-lpf-ib.patch

https://bugzilla.redhat.com/show_bug.cgi?id=1658057
(cherry picked from commit 4523a376cc)
This commit is contained in:
Thomas Haller 2018-12-19 13:34:41 +01:00
parent fd3658e25f
commit ba132ab58e

View file

@ -7474,6 +7474,22 @@ _ASSERT_arp_type (guint16 arp_type,
nm_assert (hwaddr);
}
static void
_hwaddr_get_relevant_part (guint16 arp_type,
const guint8 **hwaddr,
gsize *hwaddr_len)
{
nm_assert (hwaddr);
nm_assert (hwaddr_len);
_ASSERT_arp_type (arp_type, *hwaddr, *hwaddr_len);
/* for infiniband, we only consider the last 8 bytes. */
if (arp_type == ARPHRD_INFINIBAND) {
*hwaddr += (INFINIBAND_ALEN - 8);
*hwaddr_len = 8;
}
}
static GBytes *
dhcp4_get_client_id_mac (guint16 arp_type,
const guint8 *hwaddr,
@ -7482,7 +7498,7 @@ dhcp4_get_client_id_mac (guint16 arp_type,
guint8 *client_id_buf;
const guint8 hwaddr_type = arp_type;
_ASSERT_arp_type (arp_type, hwaddr, hwaddr_len);
_hwaddr_get_relevant_part (arp_type, &hwaddr, &hwaddr_len);
client_id_buf = g_malloc (hwaddr_len + 1);
client_id_buf[0] = hwaddr_type;
@ -8233,7 +8249,7 @@ generate_duid_llt (guint16 arp_type,
const guint16 hw_type = htons (arp_type);
const guint32 duid_time = htonl (NM_MAX (0, time - EPOCH_DATETIME_200001010000));
_ASSERT_arp_type (arp_type, hwaddr, hwaddr_len);
_hwaddr_get_relevant_part (arp_type, &hwaddr, &hwaddr_len);
arr = g_new (guint8, 2 + 2 + 4 + hwaddr_len);
@ -8254,7 +8270,7 @@ generate_duid_ll (guint16 arp_type,
const guint16 duid_type = htons (3);
const guint16 hw_type = htons (arp_type);
_ASSERT_arp_type (arp_type, hwaddr, hwaddr_len);
_hwaddr_get_relevant_part (arp_type, &hwaddr, &hwaddr_len);
arr = g_new (guint8, 2 + 2 + hwaddr_len);