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:
Yu Watanabe
2022-10-27 09:12:47 +09:00
parent 3b1dbdf0c2
commit 14805b1468
6 changed files with 13 additions and 50 deletions
+3 -35
View File
@@ -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
+2 -2
View File
@@ -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_;
+1 -1
View File
@@ -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;
};
+3 -5
View File
@@ -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;
+1 -2
View File
@@ -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;
+3 -5
View File
@@ -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);