From 8d71f2b3a6c9ef26a3a39fcaa4281776e9420976 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 10 Jun 2021 01:09:09 +0900 Subject: [PATCH] dhcp: do not use ifindex when generating iaid in tests --- src/libsystemd-network/dhcp-identifier.c | 3 ++- src/libsystemd-network/dhcp-identifier.h | 2 +- src/libsystemd-network/dhcp-internal.h | 4 ++++ src/libsystemd-network/dhcp6-internal.h | 4 ++++ src/libsystemd-network/fuzz-dhcp6-client.c | 1 + src/libsystemd-network/sd-dhcp-client.c | 16 ++++++++++++++-- src/libsystemd-network/sd-dhcp6-client.c | 14 +++++++++++++- src/libsystemd-network/test-dhcp-client.c | 21 +++++++-------------- src/libsystemd-network/test-dhcp6-client.c | 3 ++- 9 files changed, 48 insertions(+), 20 deletions(-) diff --git a/src/libsystemd-network/dhcp-identifier.c b/src/libsystemd-network/dhcp-identifier.c index bffd996824..d1ea992d43 100644 --- a/src/libsystemd-network/dhcp-identifier.c +++ b/src/libsystemd-network/dhcp-identifier.c @@ -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) { diff --git a/src/libsystemd-network/dhcp-identifier.h b/src/libsystemd-network/dhcp-identifier.h index 1d9a9c55ba..6c24af0326 100644 --- a/src/libsystemd-network/dhcp-identifier.h +++ b/src/libsystemd-network/dhcp-identifier.h @@ -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); diff --git a/src/libsystemd-network/dhcp-internal.h b/src/libsystemd-network/dhcp-internal.h index d8c42757aa..16999971d2 100644 --- a/src/libsystemd-network/dhcp-internal.h +++ b/src/libsystemd-network/dhcp-internal.h @@ -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 */ diff --git a/src/libsystemd-network/dhcp6-internal.h b/src/libsystemd-network/dhcp6-internal.h index 34e1f61cb0..f0f814957f 100644 --- a/src/libsystemd-network/dhcp6-internal.h +++ b/src/libsystemd-network/dhcp6-internal.h @@ -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: ", \ diff --git a/src/libsystemd-network/fuzz-dhcp6-client.c b/src/libsystemd-network/fuzz-dhcp6-client.c index 7ebe01286d..f62ab468df 100644 --- a/src/libsystemd-network/fuzz-dhcp6-client.c +++ b/src/libsystemd-network/fuzz-dhcp6-client.c @@ -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); diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c index a15ff8af33..ff021f4eae 100644 --- a/src/libsystemd-network/sd-dhcp-client.c +++ b/src/libsystemd-network/sd-dhcp-client.c @@ -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; diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c index 855a61bb21..e8c47f429a 100644 --- a/src/libsystemd-network/sd-dhcp6-client.c +++ b/src/libsystemd-network/sd-dhcp6-client.c @@ -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; diff --git a/src/libsystemd-network/test-dhcp-client.c b/src/libsystemd-network/test-dhcp-client.c index b464d3d700..6e0fdcd769 100644 --- a/src/libsystemd-network/test-dhcp-client.c +++ b/src/libsystemd-network/test-dhcp-client.c @@ -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); diff --git a/src/libsystemd-network/test-dhcp6-client.c b/src/libsystemd-network/test-dhcp6-client.c index 5d0c5ed2a2..a72c13684d 100644 --- a/src/libsystemd-network/test-dhcp6-client.c +++ b/src/libsystemd-network/test-dhcp6-client.c @@ -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);