]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
dhcp: use the attached sd_device object when generating IAID 25142/head
authorYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 25 Oct 2022 21:56:25 +0000 (06:56 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 27 Oct 2022 00:12:47 +0000 (09:12 +0900)
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()`.

src/libsystemd-network/dhcp-identifier.c
src/libsystemd-network/dhcp-identifier.h
src/libsystemd-network/dhcp6-internal.h
src/libsystemd-network/sd-dhcp-client.c
src/libsystemd-network/sd-dhcp6-client.c
src/libsystemd-network/test-dhcp-client.c

index 68f6a7cb3c040845c28668374b5913c2b80026e3..a27d67a315dfe685e8f45a7015d2adc234b19949 100644 (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
index 8acb8c3210a94a7a18706791029344bdc7b26ce8..523dfc4a71ba18df6f4cc7f0dbeaf932b3a35c07 100644 (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_;
index 13c31c24fcb7711033ab7ef066b6f502a716c87c..2afcda3eec13ed820835520b1de32b56c7f8d57b 100644 (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;
 };
 
index 98a19c3cb88c5988c5672e74d49864cce7d7ee0c..47b4cb121f54ad29d26daf96ba94ea88e0b34f4d 100644 (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;
index 8a435a5348fbb3dc2e80e779db6d53e4c9f17b1b..ee48160046005f992e319b4a2e5f7cdc0656307f 100644 (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;
index 8344dc4f4a806505ae1cdbaa9cfe306fc9f9a471..0f3a68e99073e4d36c2cd5eaa23d12cebc407d5f 100644 (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);