summaryrefslogtreecommitdiffstats
path: root/src/libsystemd-network/sd-dhcp-client.c
diff options
context:
space:
mode:
authorDavid Wood <david.wood@cambridgeconsultants.com>2020-02-28 19:28:49 +0100
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2020-03-19 09:08:40 +0100
commit7354900dddb869b4eda9ab2b511763dbb30f94bc (patch)
tree88542f1d9520a2163d555443e640bd132486f75c /src/libsystemd-network/sd-dhcp-client.c
parentnetworkctl: Add support to display IPv6 addrgenmode (diff)
downloadsystemd-7354900dddb869b4eda9ab2b511763dbb30f94bc.tar.xz
systemd-7354900dddb869b4eda9ab2b511763dbb30f94bc.zip
network: Fix split in `SendOption=` on client and server
When specifying `DHCPv4.SendOption=`, it is used by systemd-networkd to set the value of that option within the DHCP request that is sent out. This differs to setting `DHCPServer.SendOption=`, which will place all the options together as suboptions into the vendor-specific information (code 43) option. This commit adds two new config options, `DHCPv4.SendVendorOption=` and `DHCPServer.SendVendorOption=`. These both have the behaviour of the old `DHCPServer.SendOption=` flag, and set the value of the suboption in the vendor-specific information option. The behaviour of `DHCPServer.SendOption=` is then changed to reflect that of `DHCPv4.SendOption=`. It will set the value of the corresponding option in the DHCP request.
Diffstat (limited to 'src/libsystemd-network/sd-dhcp-client.c')
-rw-r--r--src/libsystemd-network/sd-dhcp-client.c42
1 files changed, 36 insertions, 6 deletions
diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c
index 4122d08d96..82553e79ca 100644
--- a/src/libsystemd-network/sd-dhcp-client.c
+++ b/src/libsystemd-network/sd-dhcp-client.c
@@ -89,7 +89,8 @@ struct sd_dhcp_client {
usec_t start_time;
uint64_t attempt;
uint64_t max_attempts;
- OrderedHashmap *options;
+ OrderedHashmap *extra_options;
+ OrderedHashmap *vendor_options;
usec_t request_sent;
sd_event_source *timeout_t1;
sd_event_source *timeout_t2;
@@ -540,17 +541,17 @@ int sd_dhcp_client_set_max_attempts(sd_dhcp_client *client, uint64_t max_attempt
return 0;
}
-int sd_dhcp_client_set_dhcp_option(sd_dhcp_client *client, sd_dhcp_option *v) {
+int sd_dhcp_client_add_option(sd_dhcp_client *client, sd_dhcp_option *v) {
int r;
assert_return(client, -EINVAL);
assert_return(v, -EINVAL);
- r = ordered_hashmap_ensure_allocated(&client->options, &dhcp_option_hash_ops);
+ r = ordered_hashmap_ensure_allocated(&client->extra_options, &dhcp_option_hash_ops);
if (r < 0)
return r;
- r = ordered_hashmap_put(client->options, UINT_TO_PTR(v->option), v);
+ r = ordered_hashmap_put(client->extra_options, UINT_TO_PTR(v->option), v);
if (r < 0)
return r;
@@ -558,6 +559,25 @@ int sd_dhcp_client_set_dhcp_option(sd_dhcp_client *client, sd_dhcp_option *v) {
return 0;
}
+int sd_dhcp_client_add_vendor_option(sd_dhcp_client *client, sd_dhcp_option *v) {
+ int r;
+
+ assert_return(client, -EINVAL);
+ assert_return(v, -EINVAL);
+
+ r = ordered_hashmap_ensure_allocated(&client->vendor_options, &dhcp_option_hash_ops);
+ if (r < 0)
+ return -ENOMEM;
+
+ r = ordered_hashmap_put(client->vendor_options, v, v);
+ if (r < 0)
+ return r;
+
+ sd_dhcp_option_ref(v);
+
+ return 1;
+}
+
int sd_dhcp_client_get_lease(sd_dhcp_client *client, sd_dhcp_lease **ret) {
assert_return(client, -EINVAL);
@@ -884,13 +904,22 @@ static int client_send_discover(sd_dhcp_client *client) {
return r;
}
- ORDERED_HASHMAP_FOREACH(j, client->options, i) {
+ ORDERED_HASHMAP_FOREACH(j, client->extra_options, i) {
r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
j->option, j->length, j->data);
if (r < 0)
return r;
}
+ if (!ordered_hashmap_isempty(client->vendor_options)) {
+ r = dhcp_option_append(
+ &discover->dhcp, optlen, &optoffset, 0,
+ SD_DHCP_OPTION_VENDOR_SPECIFIC,
+ ordered_hashmap_size(client->vendor_options), client->vendor_options);
+ if (r < 0)
+ return r;
+ }
+
r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
SD_DHCP_OPTION_END, 0, NULL);
if (r < 0)
@@ -2073,7 +2102,8 @@ static sd_dhcp_client *dhcp_client_free(sd_dhcp_client *client) {
free(client->hostname);
free(client->vendor_class_identifier);
client->user_class = strv_free(client->user_class);
- ordered_hashmap_free(client->options);
+ ordered_hashmap_free(client->extra_options);
+ ordered_hashmap_free(client->vendor_options);
return mfree(client);
}