summaryrefslogtreecommitdiff
path: root/src/libsystemd-network
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2022-10-26 06:56:25 +0900
committerYu Watanabe <watanabe.yu+github@gmail.com>2022-10-27 09:12:47 +0900
commit14805b1468dc73bc10d90b69975a5c8914609bb7 (patch)
tree2a25704e5d27f1db1aa397f0ec6685e6ccdb6fb2 /src/libsystemd-network
parent3b1dbdf0c260cafaf83bfa6ddabaa163c017f5cf (diff)
downloadsystemd-14805b1468dc73bc10d90b69975a5c8914609bb7.tar.gz
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()`.
Diffstat (limited to 'src/libsystemd-network')
-rw-r--r--src/libsystemd-network/dhcp-identifier.c38
-rw-r--r--src/libsystemd-network/dhcp-identifier.h4
-rw-r--r--src/libsystemd-network/dhcp6-internal.h2
-rw-r--r--src/libsystemd-network/sd-dhcp-client.c8
-rw-r--r--src/libsystemd-network/sd-dhcp6-client.c3
-rw-r--r--src/libsystemd-network/test-dhcp-client.c8
6 files changed, 13 insertions, 50 deletions
diff --git a/src/libsystemd-network/dhcp-identifier.c b/src/libsystemd-network/dhcp-identifier.c
index 68f6a7cb3c..a27d67a315 100644
--- a/src/libsystemd-network/dhcp-identifier.c
+++ b/src/libsystemd-network/dhcp-identifier.c
@@ -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
diff --git a/src/libsystemd-network/dhcp-identifier.h b/src/libsystemd-network/dhcp-identifier.h
index 8acb8c3210..523dfc4a71 100644
--- a/src/libsystemd-network/dhcp-identifier.h
+++ b/src/libsystemd-network/dhcp-identifier.h
@@ -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_;
diff --git a/src/libsystemd-network/dhcp6-internal.h b/src/libsystemd-network/dhcp6-internal.h
index 13c31c24fc..2afcda3eec 100644
--- a/src/libsystemd-network/dhcp6-internal.h
+++ b/src/libsystemd-network/dhcp6-internal.h
@@ -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;
};
diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c
index 98a19c3cb8..47b4cb121f 100644
--- a/src/libsystemd-network/sd-dhcp-client.c
+++ b/src/libsystemd-network/sd-dhcp-client.c
@@ -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;
diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c
index 8a435a5348..ee48160046 100644
--- a/src/libsystemd-network/sd-dhcp6-client.c
+++ b/src/libsystemd-network/sd-dhcp6-client.c
@@ -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;
diff --git a/src/libsystemd-network/test-dhcp-client.c b/src/libsystemd-network/test-dhcp-client.c
index 8344dc4f4a..0f3a68e990 100644
--- a/src/libsystemd-network/test-dhcp-client.c
+++ b/src/libsystemd-network/test-dhcp-client.c
@@ -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);