dhcp: use the attached sd_device object when generating IAID
Note, previously `use_mac` set with `test_mode`. As `dev`, which is set with `client->dev`, is not set when running test or fuzzer. Hence, the condition ``` if (udev_available() && !use_mac) ``` is effectively equivalent to ``` if (dev) ``` So, this commit mostly does not change behavior. Except for the following corner case. The sd_device object assigned from networkd (that is, Link.dev) never has ID_RENAMING udev property, as sd_device objects which has the property are filtered out at `link_check_initialized()` or `manager_udev_process_link()` in networkd-link.c. However, sd_device object created in `dhcp_identifier_set_iaid()` in the previous code may have it. Such situation may (at least, theoretically) happen when the network interface is renamed after initialized, e.g. by creating the following spurious .link file: ``` [Match] OriginalName=eno1 [Link] Name=lan ``` and then trigger uevent for the network interface while systemd-networkd calling `dhcp_identifier_set_iaid()`.
This commit is contained in:
@@ -4,15 +4,11 @@
|
||||
#include <net/ethernet.h>
|
||||
#include <net/if_arp.h>
|
||||
|
||||
#include "sd-device.h"
|
||||
#include "sd-id128.h"
|
||||
|
||||
#include "dhcp-identifier.h"
|
||||
#include "netif-util.h"
|
||||
#include "siphash24.h"
|
||||
#include "sparse-endian.h"
|
||||
#include "string-table.h"
|
||||
#include "udev-util.h"
|
||||
|
||||
#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)
|
||||
@@ -207,48 +203,20 @@ int dhcp_identifier_set_duid(
|
||||
}
|
||||
|
||||
int dhcp_identifier_set_iaid(
|
||||
int ifindex,
|
||||
sd_device *dev,
|
||||
const struct hw_addr_data *hw_addr,
|
||||
bool legacy_unstable_byteorder,
|
||||
bool use_mac,
|
||||
void *ret) {
|
||||
|
||||
/* 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;
|
||||
const char *name = NULL;
|
||||
uint32_t id32;
|
||||
uint64_t id;
|
||||
int r;
|
||||
|
||||
assert(ifindex > 0);
|
||||
assert(hw_addr);
|
||||
assert(ret);
|
||||
|
||||
if (udev_available() && !use_mac) {
|
||||
/* udev should be around */
|
||||
|
||||
r = sd_device_new_from_ifindex(&device, ifindex);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_device_get_is_initialized(device);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
/* not yet ready */
|
||||
return -EBUSY;
|
||||
|
||||
r = device_is_renaming(device);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r > 0)
|
||||
/* device is under renaming */
|
||||
return -EBUSY;
|
||||
|
||||
name = net_get_persistent_name(device);
|
||||
}
|
||||
|
||||
if (dev)
|
||||
name = net_get_persistent_name(dev);
|
||||
if (name)
|
||||
id = siphash24(name, strlen(name), HASH_KEY.bytes);
|
||||
else
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include "sd-device.h"
|
||||
#include "sd-id128.h"
|
||||
|
||||
#include "ether-addr-util.h"
|
||||
@@ -66,10 +67,9 @@ int dhcp_identifier_set_duid(
|
||||
struct duid *ret_duid,
|
||||
size_t *ret_len);
|
||||
int dhcp_identifier_set_iaid(
|
||||
int ifindex,
|
||||
sd_device *dev,
|
||||
const struct hw_addr_data *hw_addr,
|
||||
bool legacy_unstable_byteorder,
|
||||
bool use_mac,
|
||||
void *ret);
|
||||
|
||||
const char *duid_type_to_string(DUIDType t) _const_;
|
||||
|
||||
@@ -80,7 +80,7 @@ struct sd_dhcp6_client {
|
||||
sd_dhcp6_client_callback_t callback;
|
||||
void *userdata;
|
||||
|
||||
/* Ignore ifindex when generating iaid. See dhcp_identifier_set_iaid(). */
|
||||
/* Ignore machine-ID when generating DUID. See dhcp_identifier_set_duid_en(). */
|
||||
bool test_mode;
|
||||
};
|
||||
|
||||
|
||||
@@ -122,7 +122,7 @@ struct sd_dhcp_client {
|
||||
usec_t start_delay;
|
||||
int ip_service_type;
|
||||
|
||||
/* Ignore ifindex when generating iaid. See dhcp_identifier_set_iaid(). */
|
||||
/* Ignore machine-ID when generating DUID. See dhcp_identifier_set_duid_en(). */
|
||||
bool test_mode;
|
||||
};
|
||||
|
||||
@@ -425,9 +425,8 @@ static int dhcp_client_set_iaid_duid_internal(
|
||||
if (iaid_set)
|
||||
client->client_id.ns.iaid = htobe32(iaid);
|
||||
else {
|
||||
r = dhcp_identifier_set_iaid(client->ifindex, &client->hw_addr,
|
||||
r = dhcp_identifier_set_iaid(client->dev, &client->hw_addr,
|
||||
/* legacy_unstable_byteorder = */ true,
|
||||
/* use_mac = */ client->test_mode,
|
||||
&client->client_id.ns.iaid);
|
||||
if (r < 0)
|
||||
return log_dhcp_client_errno(client, r, "Failed to set IAID: %m");
|
||||
@@ -804,9 +803,8 @@ static int client_message_init(
|
||||
|
||||
client->client_id.type = 255;
|
||||
|
||||
r = dhcp_identifier_set_iaid(client->ifindex, &client->hw_addr,
|
||||
r = dhcp_identifier_set_iaid(client->dev, &client->hw_addr,
|
||||
/* legacy_unstable_byteorder = */ true,
|
||||
/* use_mac = */ client->test_mode,
|
||||
&client->client_id.ns.iaid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -300,9 +300,8 @@ static int client_ensure_iaid(sd_dhcp6_client *client) {
|
||||
if (client->iaid_set)
|
||||
return 0;
|
||||
|
||||
r = dhcp_identifier_set_iaid(client->ifindex, &client->hw_addr,
|
||||
r = dhcp_identifier_set_iaid(client->dev, &client->hw_addr,
|
||||
/* legacy_unstable_byteorder = */ true,
|
||||
/* use_mac = */ client->test_mode,
|
||||
&iaid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -144,10 +144,8 @@ static void test_dhcp_identifier_set_iaid(void) {
|
||||
uint32_t iaid_legacy;
|
||||
be32_t iaid;
|
||||
|
||||
assert_se(dhcp_identifier_set_iaid(42, &hw_addr, /* legacy = */ true,
|
||||
/* use_mac = */ true, &iaid_legacy) >= 0);
|
||||
assert_se(dhcp_identifier_set_iaid(42, &hw_addr, /* legacy = */ false,
|
||||
/* use_mac = */ true, &iaid) >= 0);
|
||||
assert_se(dhcp_identifier_set_iaid(NULL, &hw_addr, /* legacy = */ true, &iaid_legacy) >= 0);
|
||||
assert_se(dhcp_identifier_set_iaid(NULL, &hw_addr, /* legacy = */ false, &iaid) >= 0);
|
||||
|
||||
/* we expect, that the MAC address was hashed. The legacy value is in native
|
||||
* endianness. */
|
||||
@@ -169,7 +167,7 @@ static int check_options(uint8_t code, uint8_t len, const void *option, void *us
|
||||
size_t duid_len;
|
||||
|
||||
assert_se(dhcp_identifier_set_duid_en(/* test_mode = */ true, &duid, &duid_len) >= 0);
|
||||
assert_se(dhcp_identifier_set_iaid(42, &hw_addr, /* legacy = */ true, /* use_mac = */ true, &iaid) >= 0);
|
||||
assert_se(dhcp_identifier_set_iaid(NULL, &hw_addr, /* legacy = */ true, &iaid) >= 0);
|
||||
|
||||
assert_se(len == sizeof(uint8_t) + sizeof(uint32_t) + duid_len);
|
||||
assert_se(len == 19);
|
||||
|
||||
Reference in New Issue
Block a user