mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-21 14:10:25 +01:00
dhcp: merge branch 'th/internal-dhcp6-iaid'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/52
This commit is contained in:
commit
15a2a291ea
6 changed files with 76 additions and 30 deletions
|
|
@ -894,6 +894,7 @@ ip6_start (NMDhcpClient *client,
|
|||
nm_auto (sd_dhcp6_client_unrefp) sd_dhcp6_client *sd_client = NULL;
|
||||
GBytes *hwaddr;
|
||||
const char *hostname;
|
||||
const char *iface;
|
||||
int r, i;
|
||||
const guint8 *duid_arr;
|
||||
gsize duid_len;
|
||||
|
|
@ -928,6 +929,17 @@ ip6_start (NMDhcpClient *client,
|
|||
if (nm_dhcp_client_get_info_only (client))
|
||||
sd_dhcp6_client_set_information_request (sd_client, 1);
|
||||
|
||||
iface = nm_dhcp_client_get_iface (client);
|
||||
|
||||
r = sd_dhcp6_client_set_iaid (sd_client,
|
||||
nm_utils_create_dhcp_iaid (TRUE,
|
||||
(const guint8 *) iface,
|
||||
strlen (iface)));
|
||||
if (r < 0) {
|
||||
nm_utils_error_set_errno (error, r, "failed to set IAID: %s");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
r = sd_dhcp6_client_set_duid (sd_client,
|
||||
unaligned_read_be16 (&duid_arr[0]),
|
||||
&duid_arr[2],
|
||||
|
|
|
|||
|
|
@ -3290,6 +3290,49 @@ nm_utils_hw_addr_gen_stable_eth (NMUtilsStableType stable_type,
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define HASH_KEY ((const guint8[16]) { 0x80, 0x11, 0x8c, 0xc2, 0xfe, 0x4a, 0x03, 0xee, 0x3e, 0xd6, 0x0c, 0x6f, 0x36, 0x39, 0x14, 0x09 })
|
||||
|
||||
/**
|
||||
* nm_utils_create_dhcp_iaid:
|
||||
* @legacy_unstable_byteorder: legacy behavior is to generate a u32 iaid which
|
||||
* is endianness dependant. This is to preserve backward compatibility.
|
||||
* For non-legacy behavior, the returned integer is in stable endianness,
|
||||
* and corresponds to legacy behavior on little endian systems.
|
||||
* @interface_id: the seed for hashing when generating the ID. Usually,
|
||||
* this is the interface name.
|
||||
* @interface_id_len: length of @interface_id
|
||||
*
|
||||
* This corresponds to systemd's dhcp_identifier_set_iaid() for generating
|
||||
* a IAID for the interface.
|
||||
*
|
||||
* Returns: the IAID in host byte order. */
|
||||
guint32
|
||||
nm_utils_create_dhcp_iaid (gboolean legacy_unstable_byteorder,
|
||||
const guint8 *interface_id,
|
||||
gsize interface_id_len)
|
||||
{
|
||||
guint64 u64;
|
||||
guint32 u32;
|
||||
|
||||
u64 = c_siphash_hash (HASH_KEY, interface_id, interface_id_len);
|
||||
u32 = (u64 & 0xffffffffu) ^ (u64 >> 32);
|
||||
if (legacy_unstable_byteorder) {
|
||||
/* legacy systemd code dhcp_identifier_set_iaid() generates the iaid
|
||||
* dependent on the host endianness. Since this function returns the IAID
|
||||
* in native-byte order, we need to account for that.
|
||||
*
|
||||
* On little endian systems, we want the legacy-behavior is identical to
|
||||
* the endianness-agnostic behavior. So, we need to swap the bytes on
|
||||
* big-endian systems.
|
||||
*
|
||||
* (https://github.com/systemd/systemd/pull/10614). */
|
||||
return htole32 (u32);
|
||||
} else {
|
||||
/* we return the value as-is, in native byte order. */
|
||||
return u32;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_utils_dhcp_client_id_systemd_node_specific_full:
|
||||
* @legacy_unstable_byteorder: historically, the code would generate a iaid
|
||||
|
|
@ -3315,7 +3358,6 @@ nm_utils_dhcp_client_id_systemd_node_specific_full (gboolean legacy_unstable_byt
|
|||
const guint8 *machine_id,
|
||||
gsize machine_id_len)
|
||||
{
|
||||
const guint8 HASH_KEY[16] = { 0x80, 0x11, 0x8c, 0xc2, 0xfe, 0x4a, 0x03, 0xee, 0x3e, 0xd6, 0x0c, 0x6f, 0x36, 0x39, 0x14, 0x09 };
|
||||
const guint16 DUID_TYPE_EN = 2;
|
||||
const guint32 SYSTEMD_PEN = 43793;
|
||||
struct _nm_packed {
|
||||
|
|
@ -3344,20 +3386,10 @@ nm_utils_dhcp_client_id_systemd_node_specific_full (gboolean legacy_unstable_byt
|
|||
|
||||
client_id->type = 255;
|
||||
|
||||
u64 = c_siphash_hash (HASH_KEY, interface_id, interface_id_len);
|
||||
u32 = (u64 & 0xffffffffu) ^ (u64 >> 32);
|
||||
if (legacy_unstable_byteorder) {
|
||||
/* original systemd code dhcp_identifier_set_iaid() generates the iaid
|
||||
* in native endianness. Do that too, to preserve compatibility
|
||||
* (https://github.com/systemd/systemd/pull/10614). */
|
||||
u32 = bswap_32 (u32);
|
||||
} else {
|
||||
/* generate fixed byteorder, in a way that on little endian systems
|
||||
* the values agree. Meaning: legacy behavior is identical to this
|
||||
* on little endian. */
|
||||
u32 = be32toh (u32);
|
||||
}
|
||||
unaligned_write_ne32 (&client_id->iaid, u32);
|
||||
u32 = nm_utils_create_dhcp_iaid (legacy_unstable_byteorder,
|
||||
interface_id,
|
||||
interface_id_len);
|
||||
unaligned_write_be32 (&client_id->iaid, u32);
|
||||
|
||||
unaligned_write_be16 (&client_id->duid.type, DUID_TYPE_EN);
|
||||
|
||||
|
|
|
|||
|
|
@ -376,6 +376,10 @@ char *nm_utils_hw_addr_gen_stable_eth (NMUtilsStableType stable_type,
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
guint32 nm_utils_create_dhcp_iaid (gboolean legacy_unstable_byteorder,
|
||||
const guint8 *interface_id,
|
||||
gsize interface_id_len);
|
||||
|
||||
GBytes *nm_utils_dhcp_client_id_systemd_node_specific_full (gboolean legacy_unstable_byteorder,
|
||||
const guint8 *interface_id,
|
||||
gsize interface_id_len,
|
||||
|
|
|
|||
|
|
@ -15,11 +15,6 @@
|
|||
#include "sparse-endian.h"
|
||||
#include "virt.h"
|
||||
|
||||
#if 0 /* NM_IGNORED */
|
||||
#else /* NM_IGNORED */
|
||||
#include <net/if.h>
|
||||
#endif /* NM_IGNORED */
|
||||
|
||||
#define SYSTEMD_PEN 43793
|
||||
#define HASH_KEY SD_ID128_MAKE(80,11,8c,c2,fe,4a,03,ee,3e,d6,0c,6f,36,39,14,09)
|
||||
#define APPLICATION_ID SD_ID128_MAKE(a5,0a,d1,12,bf,60,45,77,a2,fb,74,1a,b1,95,5b,03)
|
||||
|
|
@ -169,14 +164,10 @@ int dhcp_identifier_set_iaid(
|
|||
/* name is a pointer to memory in the sd_device struct, so must
|
||||
* have the same scope */
|
||||
_cleanup_(sd_device_unrefp) sd_device *device = NULL;
|
||||
#else /* NM_IGNORED */
|
||||
char name_buf[IF_NAMESIZE];
|
||||
#endif /* NM_IGNORED */
|
||||
const char *name = NULL;
|
||||
uint64_t id;
|
||||
uint32_t id32;
|
||||
|
||||
#if 0 /* NM_IGNORED */
|
||||
if (detect_container() <= 0) {
|
||||
/* not in a container, udev will be around */
|
||||
char ifindex_str[2 + DECIMAL_STR_MAX(int)];
|
||||
|
|
@ -194,9 +185,6 @@ int dhcp_identifier_set_iaid(
|
|||
name = net_get_name(device);
|
||||
}
|
||||
}
|
||||
#else /* NM_IGNORED */
|
||||
name = if_indextoname(ifindex, name_buf);
|
||||
#endif /* NM_IGNORED */
|
||||
|
||||
if (name)
|
||||
id = siphash24(name, strlen(name), HASH_KEY.bytes);
|
||||
|
|
@ -218,4 +206,9 @@ int dhcp_identifier_set_iaid(
|
|||
|
||||
unaligned_write_ne32(_id, id32);
|
||||
return 0;
|
||||
#else /* NM_IGNORED */
|
||||
/* for NetworkManager, we don't use this function and we should never call here.
|
||||
* This got replaced by nm_utils_create_dhcp_iaid(). */
|
||||
g_return_val_if_reached (-EINVAL);
|
||||
#endif /* NM_IGNORED */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ struct sd_dhcp6_client {
|
|||
struct sd_dhcp6_lease *lease;
|
||||
int fd;
|
||||
bool information_request;
|
||||
bool has_iaid;
|
||||
be16_t *req_opts;
|
||||
size_t req_opts_allocated;
|
||||
size_t req_opts_len;
|
||||
|
|
@ -261,7 +262,6 @@ int sd_dhcp6_client_set_duid(
|
|||
return dhcp6_client_set_duid_internal(client, duid_type, duid, duid_len, 0);
|
||||
}
|
||||
|
||||
#if 0 /* NM_IGNORED */
|
||||
int sd_dhcp6_client_set_duid_llt(
|
||||
sd_dhcp6_client *client,
|
||||
usec_t llt_time) {
|
||||
|
|
@ -274,10 +274,10 @@ int sd_dhcp6_client_set_iaid(sd_dhcp6_client *client, uint32_t iaid) {
|
|||
|
||||
client->ia_na.ia_na.id = htobe32(iaid);
|
||||
client->ia_pd.ia_pd.id = htobe32(iaid);
|
||||
client->has_iaid = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* NM_IGNORED */
|
||||
|
||||
int sd_dhcp6_client_set_fqdn(
|
||||
sd_dhcp6_client *client,
|
||||
|
|
@ -798,7 +798,7 @@ static int client_ensure_iaid(sd_dhcp6_client *client) {
|
|||
|
||||
assert(client);
|
||||
|
||||
if (client->ia_na.ia_na.id)
|
||||
if (client->has_iaid)
|
||||
return 0;
|
||||
|
||||
r = dhcp_identifier_set_iaid(client->ifindex, client->mac_addr, client->mac_addr_len, true, &iaid);
|
||||
|
|
@ -807,6 +807,7 @@ static int client_ensure_iaid(sd_dhcp6_client *client) {
|
|||
|
||||
client->ia_na.ia_na.id = iaid;
|
||||
client->ia_pd.ia_pd.id = iaid;
|
||||
client->has_iaid = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2029,6 +2029,10 @@ test_nm_utils_dhcp_client_id_systemd_node_specific (gconstpointer test_data)
|
|||
g_assert_cmpmem (&cid[5], 2, &duid_type_en, sizeof (duid_type_en));
|
||||
g_assert_cmpmem (&cid[7], 4, &systemd_pen, sizeof (systemd_pen));
|
||||
g_assert_cmpmem (&cid[11], 8, &d->duid_id, sizeof (d->duid_id));
|
||||
|
||||
g_assert_cmpint (iaid, ==, htonl (nm_utils_create_dhcp_iaid (legacy_unstable_byteorder,
|
||||
(const guint8 *) d->ifname,
|
||||
strlen (d->ifname))));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue