]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-dhcp6-client: use OrderedSet for vendor option
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 6 Feb 2022 20:37:02 +0000 (05:37 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 14 Feb 2022 05:58:49 +0000 (14:58 +0900)
This also fixes memleak.

src/libsystemd-network/dhcp6-internal.h
src/libsystemd-network/dhcp6-option.c
src/libsystemd-network/sd-dhcp6-client.c

index 40578220d32b5dd5ea0a76c63ea1febee0fe3be3..75bf879540d7b9fdac4ddff1d79fdb3be7669e11 100644 (file)
@@ -18,6 +18,7 @@
 #include "list.h"
 #include "macro.h"
 #include "network-common.h"
+#include "ordered-set.h"
 #include "sparse-endian.h"
 
 typedef struct sd_dhcp6_option {
@@ -124,7 +125,7 @@ typedef struct sd_dhcp6_client {
         usec_t information_request_time_usec;
         usec_t information_refresh_time_usec;
         OrderedHashmap *extra_options;
-        OrderedHashmap *vendor_options;
+        OrderedSet *vendor_options;
 
         /* Ignore ifindex when generating iaid. See dhcp_identifier_set_iaid(). */
         bool test_mode;
@@ -137,7 +138,7 @@ int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, const DHCP6IA *ia);
 int dhcp6_option_append_fqdn(uint8_t **buf, size_t *buflen, const char *fqdn);
 int dhcp6_option_append_user_class(uint8_t **buf, size_t *buflen, char * const *user_class);
 int dhcp6_option_append_vendor_class(uint8_t **buf, size_t *buflen, char * const *user_class);
-int dhcp6_option_append_vendor_option(uint8_t **buf, size_t *buflen, OrderedHashmap *vendor_options);
+int dhcp6_option_append_vendor_option(uint8_t **buf, size_t *buflen, OrderedSet *vendor_options);
 
 int dhcp6_option_parse(
                 const uint8_t *buf,
index ac032f07fd3d35fecc7eefa32d0886503df63242..544887b9bcc51f6fdacb7175bd1c10b9191510fa 100644 (file)
@@ -246,7 +246,7 @@ int dhcp6_option_append(uint8_t **buf, size_t *buflen, uint16_t code,
         return 0;
 }
 
-int dhcp6_option_append_vendor_option(uint8_t **buf, size_t *buflen, OrderedHashmap *vendor_options) {
+int dhcp6_option_append_vendor_option(uint8_t **buf, size_t *buflen, OrderedSet *vendor_options) {
         sd_dhcp6_option *options;
         int r;
 
@@ -255,7 +255,7 @@ int dhcp6_option_append_vendor_option(uint8_t **buf, size_t *buflen, OrderedHash
         assert(buflen);
         assert(vendor_options);
 
-        ORDERED_HASHMAP_FOREACH(options, vendor_options) {
+        ORDERED_SET_FOREACH(options, vendor_options) {
                 _cleanup_free_ uint8_t *p = NULL;
                 size_t total;
 
index 87f297e2d6cf92ab82369289e1bffc324ff30215..b59dce74a9720968f884b9a1f233e695db48a22d 100644 (file)
@@ -249,9 +249,14 @@ int sd_dhcp6_client_add_vendor_option(sd_dhcp6_client *client, sd_dhcp6_option *
 
         assert_return(client, -EINVAL);
         assert_return(!sd_dhcp6_client_is_running(client), -EBUSY);
-        assert_return(v, -EINVAL);
 
-        r = ordered_hashmap_ensure_put(&client->vendor_options, &dhcp6_option_hash_ops, v, v);
+        if (!v) {
+                /* Clear the previous assignments. */
+                ordered_set_clear(client->vendor_options);
+                return 0;
+        }
+
+        r = ordered_set_ensure_put(&client->vendor_options, &dhcp6_option_hash_ops, v);
         if (r < 0)
                 return r;
 
@@ -706,7 +711,7 @@ static int client_append_common_options_in_managed_mode(
                         return r;
         }
 
-        if (!ordered_hashmap_isempty(client->vendor_options)) {
+        if (!ordered_set_isempty(client->vendor_options)) {
                 r = dhcp6_option_append_vendor_option(opt, optlen, client->vendor_options);
                 if (r < 0)
                         return r;
@@ -1500,6 +1505,7 @@ static sd_dhcp6_client *dhcp6_client_free(sd_dhcp6_client *client) {
         free(client->mudurl);
         dhcp6_ia_clear_addresses(&client->ia_pd);
         ordered_hashmap_free(client->extra_options);
+        ordered_set_free(client->vendor_options);
         strv_free(client->user_class);
         strv_free(client->vendor_class);
         free(client->ifname);