]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
dhcp: do not use ifindex when generating iaid in tests
authorYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 9 Jun 2021 16:09:09 +0000 (01:09 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 11 Jun 2021 18:19:08 +0000 (03:19 +0900)
src/libsystemd-network/dhcp-identifier.c
src/libsystemd-network/dhcp-identifier.h
src/libsystemd-network/dhcp-internal.h
src/libsystemd-network/dhcp6-internal.h
src/libsystemd-network/fuzz-dhcp6-client.c
src/libsystemd-network/sd-dhcp-client.c
src/libsystemd-network/sd-dhcp6-client.c
src/libsystemd-network/test-dhcp-client.c
src/libsystemd-network/test-dhcp6-client.c

index bffd99682499e92306af3ad1175fbb3c8db43409..d1ea992d43c593a71abfd0b8d830ca191014e77f 100644 (file)
@@ -161,6 +161,7 @@ int dhcp_identifier_set_iaid(
                 const uint8_t *mac,
                 size_t mac_len,
                 bool legacy_unstable_byteorder,
+                bool use_mac,
                 void *_id) {
         /* name is a pointer to memory in the sd_device struct, so must
          * have the same scope */
@@ -170,7 +171,7 @@ int dhcp_identifier_set_iaid(
         uint32_t id32;
         int r;
 
-        if (path_is_read_only_fs("/sys") <= 0) {
+        if (path_is_read_only_fs("/sys") <= 0 && !use_mac) {
                 /* udev should be around */
 
                 if (sd_device_new_from_ifindex(&device, ifindex) >= 0) {
index 1d9a9c55ba907124a76f903b94e1acf160b00ca9..6c24af0326a6d4766f697cc99b58d0cf5f3e463e 100644 (file)
@@ -59,4 +59,4 @@ int dhcp_identifier_set_duid_llt(struct duid *duid, usec_t t, const uint8_t *add
 int dhcp_identifier_set_duid_ll(struct duid *duid, const uint8_t *addr, size_t addr_len, uint16_t arp_type, size_t *len);
 int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len);
 int dhcp_identifier_set_duid_uuid(struct duid *duid, size_t *len);
-int dhcp_identifier_set_iaid(int ifindex, const uint8_t *mac, size_t mac_len, bool legacy_unstable_byteorder, void *_id);
+int dhcp_identifier_set_iaid(int ifindex, const uint8_t *mac, size_t mac_len, bool legacy_unstable_byteorder, bool use_mac, void *_id);
index d8c42757aa62f45581fa753dd1141d6f18a1e232..16999971d2a8bb35783be2760ffc0891fd089bb0 100644 (file)
@@ -30,6 +30,8 @@ typedef struct DHCPServerData {
 
 extern const struct hash_ops dhcp_option_hash_ops;
 
+typedef struct sd_dhcp_client sd_dhcp_client;
+
 int dhcp_network_bind_raw_socket(int ifindex, union sockaddr_union *link, uint32_t xid,
                                  const uint8_t *mac_addr, size_t mac_addr_len,
                                  const uint8_t *bcast_addr, size_t bcast_addr_len,
@@ -62,6 +64,8 @@ void dhcp_packet_append_ip_headers(DHCPPacket *packet, be32_t source_addr,
 
 int dhcp_packet_verify_headers(DHCPPacket *packet, size_t len, bool checksum, uint16_t port);
 
+void dhcp_client_set_test_mode(sd_dhcp_client *client, bool test_mode);
+
 /* If we are invoking callbacks of a dhcp-client, ensure unreffing the
  * client from the callback doesn't destroy the object we are working
  * on */
index 34e1f61cb08c1e52e1f6726f22fec0a01fadb6c1..f0f814957f2b661b88ccb08c4e6379ff481b92e2 100644 (file)
@@ -91,6 +91,8 @@ typedef struct DHCP6IA {
         LIST_HEAD(DHCP6Address, addresses);
 } DHCP6IA;
 
+typedef struct sd_dhcp6_client sd_dhcp6_client;
+
 int dhcp6_option_append(uint8_t **buf, size_t *buflen, uint16_t code,
                         size_t optlen, const void *optval);
 int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, const DHCP6IA *ia);
@@ -118,6 +120,8 @@ int dhcp6_message_type_from_string(const char *s) _pure_;
 const char *dhcp6_message_status_to_string(int s) _const_;
 int dhcp6_message_status_from_string(const char *s) _pure_;
 
+void dhcp6_client_set_test_mode(sd_dhcp6_client *client, bool test_mode);
+
 #define log_dhcp6_client_errno(client, error, fmt, ...)         \
         log_interface_prefix_full_errno(                        \
                 "DHCPv6 client: ",                              \
index 7ebe01286da57a97e189e1225805c0ee4bfbbe33..f62ab468df342fd511133f404068a8662cf66f76 100644 (file)
@@ -33,6 +33,7 @@ static void fuzz_client(const uint8_t *data, size_t size, bool is_information_re
         assert_se(sd_dhcp6_client_set_ifindex(client, 42) == 0);
         assert_se(sd_dhcp6_client_set_local_address(client, &address) >= 0);
         assert_se(sd_dhcp6_client_set_information_request(client, is_information_request_enabled) == 0);
+        dhcp6_client_set_test_mode(client, true);
 
         assert_se(sd_dhcp6_client_start(client) >= 0);
 
index a15ff8af33a1e6bfa602e12fb84478f2f55dcddc..ff021f4eae12df82a119b6bd38f0a44e98f78a4c 100644 (file)
@@ -117,6 +117,9 @@ struct sd_dhcp_client {
         sd_dhcp_lease *lease;
         usec_t start_delay;
         int ip_service_type;
+
+        /* Ignore ifindex when generating iaid. See dhcp_identifier_set_iaid(). */
+        bool test_mode;
 };
 
 static const uint8_t default_req_opts[] = {
@@ -466,7 +469,8 @@ static int dhcp_client_set_iaid_duid_internal(
                 else {
                         r = dhcp_identifier_set_iaid(client->ifindex, client->mac_addr,
                                                      client->mac_addr_len,
-                                                     true,
+                                                     /* 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");
@@ -555,6 +559,12 @@ int sd_dhcp_client_set_duid_llt(
         return dhcp_client_set_iaid_duid_internal(client, false, false, 0, DUID_TYPE_LLT, NULL, 0, llt_time);
 }
 
+void dhcp_client_set_test_mode(sd_dhcp_client *client, bool test_mode) {
+        assert(client);
+
+        client->test_mode = test_mode;
+}
+
 int sd_dhcp_client_set_hostname(
                 sd_dhcp_client *client,
                 const char *hostname) {
@@ -860,7 +870,9 @@ static int client_message_init(
                 client->client_id.type = 255;
 
                 r = dhcp_identifier_set_iaid(client->ifindex, client->mac_addr, client->mac_addr_len,
-                                             true, &client->client_id.ns.iaid);
+                                             /* legacy_unstable_byteorder = */ true,
+                                             /* use_mac = */ client->test_mode,
+                                             &client->client_id.ns.iaid);
                 if (r < 0)
                         return r;
 
index 855a61bb216c0a5e7cfa2681c87fc9df366272d1..e8c47f429a57d9919a35d49ede69854d7452a9a0 100644 (file)
@@ -84,6 +84,9 @@ struct sd_dhcp6_client {
         usec_t information_refresh_time_usec;
         OrderedHashmap *extra_options;
         OrderedHashmap *vendor_options;
+
+        /* Ignore ifindex when generating iaid. See dhcp_identifier_set_iaid(). */
+        bool test_mode;
 };
 
 static const uint16_t default_req_opts[] = {
@@ -398,6 +401,12 @@ int sd_dhcp6_client_set_iaid(sd_dhcp6_client *client, uint32_t iaid) {
         return 0;
 }
 
+void dhcp6_client_set_test_mode(sd_dhcp6_client *client, bool test_mode) {
+        assert(client);
+
+        client->test_mode = test_mode;
+}
+
 int sd_dhcp6_client_get_iaid(sd_dhcp6_client *client, uint32_t *iaid) {
         assert_return(client, -EINVAL);
         assert_return(iaid, -EINVAL);
@@ -1073,7 +1082,10 @@ static int client_ensure_iaid(sd_dhcp6_client *client) {
         if (client->iaid_set)
                 return 0;
 
-        r = dhcp_identifier_set_iaid(client->ifindex, client->mac_addr, client->mac_addr_len, true, &iaid);
+        r = dhcp_identifier_set_iaid(client->ifindex, client->mac_addr, client->mac_addr_len,
+                                     /* legacy_unstable_byteorder = */ true,
+                                     /* use_mac = */ client->test_mode,
+                                     &iaid);
         if (r < 0)
                 return r;
 
index b464d3d700a3e6eeab07fb4c3c76995b7ac5a9b0..6e0fdcd769ae5e483e9b0bfe78ce3e4df3c0144f 100644 (file)
@@ -145,20 +145,11 @@ static void test_checksum(void) {
 static void test_dhcp_identifier_set_iaid(void) {
         uint32_t iaid_legacy;
         be32_t iaid;
-        int ifindex;
 
-        for (;;) {
-                char ifname[IFNAMSIZ];
-
-                /* try to find an ifindex which does not exist. I causes dhcp_identifier_set_iaid()
-                 * to hash the MAC address. */
-                pseudo_random_bytes(&ifindex, sizeof(ifindex));
-                if (ifindex > 0 && !if_indextoname(ifindex, ifname))
-                        break;
-        }
-
-        assert_se(dhcp_identifier_set_iaid(ifindex, mac_addr, sizeof(mac_addr), true, &iaid_legacy) >= 0);
-        assert_se(dhcp_identifier_set_iaid(ifindex, mac_addr, sizeof(mac_addr), false, &iaid) >= 0);
+        assert_se(dhcp_identifier_set_iaid(42, mac_addr, sizeof(mac_addr), /* legacy = */ true,
+                                           /* use_mac = */ true, &iaid_legacy) >= 0);
+        assert_se(dhcp_identifier_set_iaid(42, mac_addr, sizeof(mac_addr), /* legacy = */ false,
+                                           /* use_mac = */ true, &iaid) >= 0);
 
         /* we expect, that the MAC address was hashed. The legacy value is in native
          * endianness. */
@@ -180,7 +171,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(&duid, &duid_len) >= 0);
-                assert_se(dhcp_identifier_set_iaid(42, mac_addr, ETH_ALEN, true, &iaid) >= 0);
+                assert_se(dhcp_identifier_set_iaid(42, mac_addr, ETH_ALEN, true, /* use_mac = */ true, &iaid) >= 0);
 
                 assert_se(len == sizeof(uint8_t) + sizeof(uint32_t) + duid_len);
                 assert_se(len == 19);
@@ -299,6 +290,7 @@ static void test_discover_message(sd_event *e) {
 
         assert_se(sd_dhcp_client_set_ifindex(client, 42) >= 0);
         assert_se(sd_dhcp_client_set_mac(client, mac_addr, bcast_addr, ETH_ALEN, ARPHRD_ETHER) >= 0);
+        dhcp_client_set_test_mode(client, true);
 
         assert_se(sd_dhcp_client_set_request_option(client, 248) >= 0);
 
@@ -516,6 +508,7 @@ static void test_addr_acq(sd_event *e) {
 
         assert_se(sd_dhcp_client_set_ifindex(client, 42) >= 0);
         assert_se(sd_dhcp_client_set_mac(client, mac_addr, bcast_addr, ETH_ALEN, ARPHRD_ETHER) >= 0);
+        dhcp_client_set_test_mode(client, true);
 
         assert_se(sd_dhcp_client_set_callback(client, test_addr_acq_acquired, e) >= 0);
 
index 5d0c5ed2a21624a4602520e80e7c2bc733585885..a72c13684dea6512061fe81efbb5863502f9644f 100644 (file)
@@ -13,6 +13,7 @@
 #include "sd-dhcp6-client.h"
 #include "sd-event.h"
 
+#include "dhcp-identifier.h"
 #include "dhcp6-internal.h"
 #include "dhcp6-lease-internal.h"
 #include "dhcp6-protocol.h"
@@ -24,7 +25,6 @@
 #include "strv.h"
 #include "tests.h"
 #include "time-util.h"
-#include "virt.h"
 
 static struct ether_addr mac_addr = {
         .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}
@@ -952,6 +952,7 @@ static int test_client_solicit(sd_event *e) {
                                           sizeof (mac_addr),
                                           ARPHRD_ETHER) >= 0);
         assert_se(sd_dhcp6_client_set_fqdn(client, "host.lab.intra") == 1);
+        dhcp6_client_set_test_mode(client, true);
 
         assert_se(sd_dhcp6_client_get_information_request(client, &val) >= 0);
         assert_se(val == 0);