From d8b736bd0c7dcd4e3735d7557e92fb894a169190 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 18 Nov 2019 17:33:58 +0900 Subject: [PATCH 1/3] network: rename SendRawOption= to SendOption= As DHCPv4.SendOption= and DHCPServer.SendRawOption= take the same format. --- man/systemd.network.xml | 34 +++++++++---------- src/network/networkd-dhcp-server.c | 2 +- src/network/networkd-dhcp-server.h | 2 +- src/network/networkd-network-gperf.gperf | 2 +- .../fuzz-network-parser/directives.network | 2 +- 5 files changed, 21 insertions(+), 21 deletions(-) diff --git a/man/systemd.network.xml b/man/systemd.network.xml index e87ca1f287..8b401eeaf9 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -1643,14 +1643,13 @@ SendOption= Send an arbitrary option in the DHCPv4 request. Takes a DHCP option number, data type - and data separated with a colon (option: - type:value). The option - number must be an interger in the range 1..254. The type takes one of - uint8, uint16, uint32, - ipv4address, or string. - Special characters in the data string may be escaped using + and data separated with a colon + (option:type:value). + The option number must be an interger in the range 1..254. The type takes one of uint8, + uint16, uint32, ipv4address, or + string. Special characters in the data string may be escaped using C-style - escapes. This option can be specified multiple times. If an empty string is specified, + escapes. This setting can be specified multiple times. If an empty string is specified, then all options specified earlier are cleared. Defaults to unset. @@ -1905,16 +1904,17 @@ - SendRawOption= - - Send a raw option with value via DHCPv4 server. Takes a DHCP option, data type and data - (option:type:value). The option ranges [1-254]. The type takes one of uint8, - uint16, uint32, ipv4address, or string. - Special characters in the data string may be escaped using - C-style - escapes. This option can be specified multiple times. If an empty string is specified, then all - options specified earlier are cleared. Defaults to unset. - + SendOption= + + Send a raw option with value via DHCPv4 server. Takes a DHCP option number, data type + and data (option:type:value). + The option number is an integer in the range 1..254. The type takes one of uint8, + uint16, uint32, ipv4address, or + string. Special characters in the data string may be escaped using + C-style + escapes. This setting can be specified multiple times. If an empty string is specified, + then all options specified earlier are cleared. Defaults to unset. + diff --git a/src/network/networkd-dhcp-server.c b/src/network/networkd-dhcp-server.c index 79ac325926..8102c1be96 100644 --- a/src/network/networkd-dhcp-server.c +++ b/src/network/networkd-dhcp-server.c @@ -480,7 +480,7 @@ int config_parse_dhcp_server_sip( } } -int config_parse_dhcp_server_raw_option_data( +int config_parse_dhcp_server_option_data( const char *unit, const char *filename, unsigned line, diff --git a/src/network/networkd-dhcp-server.h b/src/network/networkd-dhcp-server.h index e0a7799b1c..21f1f31b15 100644 --- a/src/network/networkd-dhcp-server.h +++ b/src/network/networkd-dhcp-server.h @@ -12,4 +12,4 @@ int dhcp4_server_configure(Link *link); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_dns); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_ntp); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_sip); -CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_raw_option_data); +CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_option_data); diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index a99ef94d32..928253cae0 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -200,7 +200,7 @@ DHCPServer.EmitTimezone, config_parse_bool, DHCPServer.Timezone, config_parse_timezone, 0, offsetof(Network, dhcp_server_timezone) DHCPServer.PoolOffset, config_parse_uint32, 0, offsetof(Network, dhcp_server_pool_offset) DHCPServer.PoolSize, config_parse_uint32, 0, offsetof(Network, dhcp_server_pool_size) -DHCPServer.SendRawOption, config_parse_dhcp_server_raw_option_data, 0, 0 +DHCPServer.SendOption, config_parse_dhcp_server_option_data, 0, 0 Bridge.Cost, config_parse_uint32, 0, offsetof(Network, cost) Bridge.UseBPDU, config_parse_tristate, 0, offsetof(Network, use_bpdu) Bridge.HairPin, config_parse_tristate, 0, offsetof(Network, hairpin) diff --git a/test/fuzz/fuzz-network-parser/directives.network b/test/fuzz/fuzz-network-parser/directives.network index a5f54610da..cb10ca306a 100644 --- a/test/fuzz/fuzz-network-parser/directives.network +++ b/test/fuzz/fuzz-network-parser/directives.network @@ -259,7 +259,7 @@ MaxLeaseTimeSec= DefaultLeaseTimeSec= EmitTimezone= DNS= -SendRawOption= +SendOption= [NextHop] Id= Gateway= From 461dbb2fa97b5c03b19462bf0f462c9f96a59f1b Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 18 Nov 2019 18:14:18 +0900 Subject: [PATCH 2/3] dhcp: remove struct sd_dhcp_raw_option sd_dhcp_raw_option and sd_dhcp_option are essentially equivalent. --- src/libsystemd-network/dhcp-internal.h | 10 ++++ src/libsystemd-network/dhcp-option.c | 44 ++++++++++++++++- src/libsystemd-network/dhcp-server-internal.h | 9 ---- src/libsystemd-network/sd-dhcp-client.c | 48 ------------------- src/libsystemd-network/sd-dhcp-server.c | 46 ++---------------- src/network/networkd-dhcp-server.c | 19 ++++---- src/network/networkd-network.c | 2 +- src/network/networkd-network.h | 2 +- src/systemd/meson.build | 1 + src/systemd/sd-dhcp-client.h | 6 +-- src/systemd/sd-dhcp-option.h | 38 +++++++++++++++ src/systemd/sd-dhcp-server.h | 11 +---- 12 files changed, 109 insertions(+), 127 deletions(-) create mode 100644 src/systemd/sd-dhcp-option.h diff --git a/src/libsystemd-network/dhcp-internal.h b/src/libsystemd-network/dhcp-internal.h index c231773bdd..6a803d7b05 100644 --- a/src/libsystemd-network/dhcp-internal.h +++ b/src/libsystemd-network/dhcp-internal.h @@ -15,6 +15,16 @@ #include "dhcp-protocol.h" #include "socket-util.h" +typedef struct sd_dhcp_option { + unsigned n_ref; + + uint8_t option; + void *data; + size_t length; +} sd_dhcp_option; + +extern const struct hash_ops dhcp_option_hash_ops; + 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, uint16_t arp_type, diff --git a/src/libsystemd-network/dhcp-option.c b/src/libsystemd-network/dhcp-option.c index 061cfde2f0..e03c1a894d 100644 --- a/src/libsystemd-network/dhcp-option.c +++ b/src/libsystemd-network/dhcp-option.c @@ -79,7 +79,7 @@ static int option_append(uint8_t options[], size_t size, size_t *offset, break; case SD_DHCP_OPTION_VENDOR_SPECIFIC: { OrderedHashmap *s = (OrderedHashmap *) optval; - struct sd_dhcp_raw_option *p; + struct sd_dhcp_option *p; size_t l = 0; Iterator i; @@ -95,7 +95,7 @@ static int option_append(uint8_t options[], size_t size, size_t *offset, *offset += 2; ORDERED_HASHMAP_FOREACH(p, s, i) { - options[*offset] = p->type; + options[*offset] = p->option; options[*offset + 1] = p->length; memcpy(&options[*offset + 2], p->data, p->length); *offset += 2 + p->length; @@ -315,3 +315,43 @@ int dhcp_option_parse(DHCPMessage *message, size_t len, dhcp_option_callback_t c return message_type; } + +static sd_dhcp_option* dhcp_option_free(sd_dhcp_option *i) { + if (!i) + return NULL; + + free(i->data); + return mfree(i); +} + +int sd_dhcp_option_new(uint8_t option, const void *data, size_t length, sd_dhcp_option **ret) { + assert_return(ret, -EINVAL); + assert_return(length == 0 || data, -EINVAL); + + _cleanup_free_ void *q = memdup(data, length); + if (!q) + return -ENOMEM; + + sd_dhcp_option *p = new(sd_dhcp_option, 1); + if (!p) + return -ENOMEM; + + *p = (sd_dhcp_option) { + .n_ref = 1, + .option = option, + .length = length, + .data = TAKE_PTR(q), + }; + + *ret = TAKE_PTR(p); + return 0; +} + +DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_dhcp_option, sd_dhcp_option, dhcp_option_free); +DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR( + dhcp_option_hash_ops, + void, + trivial_hash_func, + trivial_compare_func, + sd_dhcp_option, + sd_dhcp_option_unref); diff --git a/src/libsystemd-network/dhcp-server-internal.h b/src/libsystemd-network/dhcp-server-internal.h index e537d9e622..42c3ceb8b1 100644 --- a/src/libsystemd-network/dhcp-server-internal.h +++ b/src/libsystemd-network/dhcp-server-internal.h @@ -37,15 +37,6 @@ typedef struct DHCPLease { usec_t expiration; } DHCPLease; -struct sd_dhcp_raw_option { - unsigned n_ref; - - uint8_t type; - uint8_t length; - - void *data; -}; - struct sd_dhcp_server { unsigned n_ref; diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c index f03989a5a7..bc666098d1 100644 --- a/src/libsystemd-network/sd-dhcp-client.c +++ b/src/libsystemd-network/sd-dhcp-client.c @@ -34,14 +34,6 @@ #define RESTART_AFTER_NAK_MIN_USEC (1 * USEC_PER_SEC) #define RESTART_AFTER_NAK_MAX_USEC (30 * USEC_PER_MINUTE) -struct sd_dhcp_option { - unsigned n_ref; - - uint8_t option; - void *data; - size_t length; -}; - struct sd_dhcp_client { unsigned n_ref; @@ -538,46 +530,6 @@ int sd_dhcp_client_set_max_attempts(sd_dhcp_client *client, uint64_t max_attempt return 0; } -static sd_dhcp_option* dhcp_option_free(sd_dhcp_option *i) { - if (!i) - return NULL; - - free(i->data); - return mfree(i); -} - -int sd_dhcp_option_new(uint8_t option, void *data, size_t length, sd_dhcp_option **ret) { - assert_return(ret, -EINVAL); - assert_return(length == 0 || data, -EINVAL); - - _cleanup_free_ void *q = memdup(data, length); - if (!q) - return -ENOMEM; - - sd_dhcp_option *p = new(sd_dhcp_option, 1); - if (!p) - return -ENOMEM; - - *p = (sd_dhcp_option) { - .n_ref = 1, - .option = option, - .length = length, - .data = TAKE_PTR(q), - }; - - *ret = TAKE_PTR(p); - return 0; -} - -DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_dhcp_option, sd_dhcp_option, dhcp_option_free); -DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR( - dhcp_option_hash_ops, - void, - trivial_hash_func, - trivial_compare_func, - sd_dhcp_option, - sd_dhcp_option_unref); - int sd_dhcp_client_set_dhcp_option(sd_dhcp_client *client, sd_dhcp_option *v) { int r; diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c index 3316c8bda4..9e51bf74f5 100644 --- a/src/libsystemd-network/sd-dhcp-server.c +++ b/src/libsystemd-network/sd-dhcp-server.c @@ -127,46 +127,6 @@ int client_id_compare_func(const DHCPClientId *a, const DHCPClientId *b) { DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(dhcp_lease_hash_ops, DHCPClientId, client_id_hash_func, client_id_compare_func, DHCPLease, dhcp_lease_free); -static sd_dhcp_raw_option* raw_option_free(sd_dhcp_raw_option *i) { - if (!i) - return NULL; - - free(i->data); - return mfree(i); -} - -_public_ int sd_dhcp_raw_option_new(uint8_t type, char *data, size_t length, sd_dhcp_raw_option **ret) { - _cleanup_(sd_dhcp_raw_option_unrefp) sd_dhcp_raw_option *p = NULL; - - assert_return(ret, -EINVAL); - - p = new(sd_dhcp_raw_option, 1); - if (!p) - return -ENOMEM; - - *p = (sd_dhcp_raw_option) { - .n_ref = 1, - .data = memdup(data, length), - .length = length, - .type = type, - }; - - if (!p->data) - return -ENOMEM; - - *ret = TAKE_PTR(p); - return 0; -} - -DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_dhcp_raw_option, sd_dhcp_raw_option, raw_option_free); -DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR( - dhcp_raw_options_hash_ops, - void, - trivial_hash_func, - trivial_compare_func, - sd_dhcp_raw_option, - sd_dhcp_raw_option_unref); - static sd_dhcp_server *dhcp_server_free(sd_dhcp_server *server) { assert(server); @@ -1222,13 +1182,13 @@ int sd_dhcp_server_set_emit_router(sd_dhcp_server *server, int enabled) { return 1; } -int sd_dhcp_server_add_raw_option(sd_dhcp_server *server, sd_dhcp_raw_option *v) { +int sd_dhcp_server_add_option(sd_dhcp_server *server, sd_dhcp_option *v) { int r; assert_return(server, -EINVAL); assert_return(v, -EINVAL); - r = ordered_hashmap_ensure_allocated(&server->raw_option, &dhcp_raw_options_hash_ops); + r = ordered_hashmap_ensure_allocated(&server->raw_option, &dhcp_option_hash_ops); if (r < 0) return -ENOMEM; @@ -1236,7 +1196,7 @@ int sd_dhcp_server_add_raw_option(sd_dhcp_server *server, sd_dhcp_raw_option *v) if (r < 0) return r; - sd_dhcp_raw_option_ref(v); + sd_dhcp_option_ref(v); return 1; } diff --git a/src/network/networkd-dhcp-server.c b/src/network/networkd-dhcp-server.c index 8102c1be96..a58cf8de8a 100644 --- a/src/network/networkd-dhcp-server.c +++ b/src/network/networkd-dhcp-server.c @@ -2,6 +2,7 @@ #include "sd-dhcp-server.h" +#include "dhcp-internal.h" #include "escape.h" #include "networkd-dhcp-server.h" #include "networkd-link.h" @@ -192,7 +193,7 @@ static int link_push_uplink_sip_to_dhcp_server(Link *link, sd_dhcp_server *s) { int dhcp4_server_configure(Link *link) { bool acquired_uplink = false; - sd_dhcp_raw_option *p; + sd_dhcp_option *p; Link *uplink = NULL; Address *address; Iterator i; @@ -305,8 +306,8 @@ int dhcp4_server_configure(Link *link) { return r; } - ORDERED_HASHMAP_FOREACH(p, link->network->dhcp_server_raw_options, i) { - r = sd_dhcp_server_add_raw_option(link->dhcp_server, p); + ORDERED_HASHMAP_FOREACH(p, link->network->dhcp_server_options, i) { + r = sd_dhcp_server_add_option(link->dhcp_server, p); if (r == -EEXIST) continue; if (r < 0) @@ -492,7 +493,7 @@ int config_parse_dhcp_server_option_data( void *data, void *userdata) { - _cleanup_(sd_dhcp_raw_option_unrefp) sd_dhcp_raw_option *opt = NULL, *old = NULL; + _cleanup_(sd_dhcp_option_unrefp) sd_dhcp_option *opt = NULL, *old = NULL; _cleanup_free_ char *word = NULL, *q = NULL; union in_addr_union addr; DHCPOptionDataType type; @@ -512,7 +513,7 @@ int config_parse_dhcp_server_option_data( assert(data); if (isempty(rvalue)) { - network->dhcp_server_raw_options = ordered_hashmap_free(network->dhcp_server_raw_options); + network->dhcp_server_options = ordered_hashmap_free(network->dhcp_server_options); return 0; } @@ -619,20 +620,20 @@ int config_parse_dhcp_server_option_data( return -EINVAL; } - r = sd_dhcp_raw_option_new(u, udata, sz, &opt); + r = sd_dhcp_option_new(u, udata, sz, &opt); if (r < 0) { log_syntax(unit, LOG_ERR, filename, line, r, "Failed to store DHCP send raw option '%s', ignoring assignment: %m", rvalue); return 0; } - r = ordered_hashmap_ensure_allocated(&network->dhcp_server_raw_options, &dhcp_raw_options_hash_ops); + r = ordered_hashmap_ensure_allocated(&network->dhcp_server_options, &dhcp_option_hash_ops); if (r < 0) return log_oom(); /* Overwrite existing option */ - old = ordered_hashmap_remove(network->dhcp_server_raw_options, UINT_TO_PTR(u)); - r = ordered_hashmap_put(network->dhcp_server_raw_options, UINT_TO_PTR(u), opt); + old = ordered_hashmap_remove(network->dhcp_server_options, UINT_TO_PTR(u)); + r = ordered_hashmap_put(network->dhcp_server_options, UINT_TO_PTR(u), opt); if (r < 0) { log_syntax(unit, LOG_ERR, filename, line, r, "Failed to store DHCP server send raw option '%s'", rvalue); diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 8727fd329f..6b51b16d9b 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -687,7 +687,7 @@ static Network *network_free(Network *network) { set_free_free(network->dnssec_negative_trust_anchors); ordered_hashmap_free(network->dhcp_send_options); - ordered_hashmap_free(network->dhcp_server_raw_options); + ordered_hashmap_free(network->dhcp_server_options); return mfree(network); } diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index 9c4dcf0532..a1032051f1 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -115,7 +115,7 @@ struct Network { Set *dhcp_black_listed_ip; Set *dhcp_request_options; OrderedHashmap *dhcp_send_options; - OrderedHashmap *dhcp_server_raw_options; + OrderedHashmap *dhcp_server_options; /* DHCPv6 Client support*/ bool dhcp6_use_dns; diff --git a/src/systemd/meson.build b/src/systemd/meson.build index 75c48b07a5..05196554ac 100644 --- a/src/systemd/meson.build +++ b/src/systemd/meson.build @@ -22,6 +22,7 @@ _not_installed_headers = ''' sd-dhcp6-lease.h sd-dhcp-client.h sd-dhcp-lease.h + sd-dhcp-option.h sd-dhcp-server.h sd-ipv4acd.h sd-ipv4ll.h diff --git a/src/systemd/sd-dhcp-client.h b/src/systemd/sd-dhcp-client.h index a44e6e35a2..f97e35b654 100644 --- a/src/systemd/sd-dhcp-client.h +++ b/src/systemd/sd-dhcp-client.h @@ -26,6 +26,7 @@ #include #include "sd-dhcp-lease.h" +#include "sd-dhcp-option.h" #include "sd-event.h" #include "_sd-common.h" @@ -99,7 +100,6 @@ enum { }; typedef struct sd_dhcp_client sd_dhcp_client; -typedef struct sd_dhcp_option sd_dhcp_option; typedef int (*sd_dhcp_client_callback_t)(sd_dhcp_client *client, int event, void *userdata); int sd_dhcp_client_set_callback( @@ -179,9 +179,6 @@ int sd_dhcp_client_set_service_type( sd_dhcp_client *client, int type); -int sd_dhcp_option_new(uint8_t option, void *data, size_t length, sd_dhcp_option **ret); -sd_dhcp_option* sd_dhcp_option_ref(sd_dhcp_option *i); -sd_dhcp_option* sd_dhcp_option_unref(sd_dhcp_option *i); int sd_dhcp_client_set_dhcp_option(sd_dhcp_client *client, sd_dhcp_option *v); int sd_dhcp_client_stop(sd_dhcp_client *client); @@ -204,7 +201,6 @@ int sd_dhcp_client_detach_event(sd_dhcp_client *client); sd_event *sd_dhcp_client_get_event(sd_dhcp_client *client); _SD_DEFINE_POINTER_CLEANUP_FUNC(sd_dhcp_client, sd_dhcp_client_unref); -_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_dhcp_option, sd_dhcp_option_unref); _SD_END_DECLARATIONS; diff --git a/src/systemd/sd-dhcp-option.h b/src/systemd/sd-dhcp-option.h new file mode 100644 index 0000000000..45dbd27985 --- /dev/null +++ b/src/systemd/sd-dhcp-option.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ +#ifndef foosddhcpoptionhfoo +#define foosddhcpoptionhfoo + +/*** + Copyright © 2013 Intel Corporation. All rights reserved. + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include +#include + +#include "_sd-common.h" + +_SD_BEGIN_DECLARATIONS; + +typedef struct sd_dhcp_option sd_dhcp_option; + +int sd_dhcp_option_new(uint8_t option, const void *data, size_t length, sd_dhcp_option **ret); +sd_dhcp_option *sd_dhcp_option_ref(sd_dhcp_option *ra); +sd_dhcp_option *sd_dhcp_option_unref(sd_dhcp_option *ra); + +_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_dhcp_option, sd_dhcp_option_unref); + +_SD_END_DECLARATIONS; + +#endif diff --git a/src/systemd/sd-dhcp-server.h b/src/systemd/sd-dhcp-server.h index ba1bc4458a..5950506c9b 100644 --- a/src/systemd/sd-dhcp-server.h +++ b/src/systemd/sd-dhcp-server.h @@ -21,26 +21,20 @@ #include #include +#include "sd-dhcp-option.h" #include "sd-event.h" #include "_sd-common.h" _SD_BEGIN_DECLARATIONS; -extern const struct hash_ops dhcp_raw_options_hash_ops; - typedef struct sd_dhcp_server sd_dhcp_server; -typedef struct sd_dhcp_raw_option sd_dhcp_raw_option; int sd_dhcp_server_new(sd_dhcp_server **ret, int ifindex); sd_dhcp_server *sd_dhcp_server_ref(sd_dhcp_server *server); sd_dhcp_server *sd_dhcp_server_unref(sd_dhcp_server *server); -int sd_dhcp_raw_option_new(uint8_t type, char *data, size_t lengt, sd_dhcp_raw_option **ret); -sd_dhcp_raw_option *sd_dhcp_raw_option_ref(sd_dhcp_raw_option *ra); -sd_dhcp_raw_option *sd_dhcp_raw_option_unref(sd_dhcp_raw_option *ra); - int sd_dhcp_server_attach_event(sd_dhcp_server *client, sd_event *event, int64_t priority); int sd_dhcp_server_detach_event(sd_dhcp_server *client); sd_event *sd_dhcp_server_get_event(sd_dhcp_server *client); @@ -58,7 +52,7 @@ int sd_dhcp_server_set_ntp(sd_dhcp_server *server, const struct in_addr ntp[], u int sd_dhcp_server_set_sip(sd_dhcp_server *server, const struct in_addr sip[], unsigned n); int sd_dhcp_server_set_emit_router(sd_dhcp_server *server, int enabled); -int sd_dhcp_server_add_raw_option(sd_dhcp_server *server, sd_dhcp_raw_option *v); +int sd_dhcp_server_add_option(sd_dhcp_server *server, sd_dhcp_option *v); int sd_dhcp_server_set_max_lease_time(sd_dhcp_server *server, uint32_t t); int sd_dhcp_server_set_default_lease_time(sd_dhcp_server *server, uint32_t t); @@ -66,7 +60,6 @@ int sd_dhcp_server_set_default_lease_time(sd_dhcp_server *server, uint32_t t); int sd_dhcp_server_forcerenew(sd_dhcp_server *server); _SD_DEFINE_POINTER_CLEANUP_FUNC(sd_dhcp_server, sd_dhcp_server_unref); -_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_dhcp_raw_option, sd_dhcp_raw_option_unref); _SD_END_DECLARATIONS; From 0e96961d6206eed0d685ba64cfb2a481cb23b91d Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 18 Nov 2019 18:29:29 +0900 Subject: [PATCH 3/3] network: unify config_parse_dhcp_server_option_data() and config_parse_dhcp_send_option() --- src/network/networkd-dhcp-common.c | 163 ++++++++++++++++++++++ src/network/networkd-dhcp-common.h | 1 + src/network/networkd-dhcp-server.c | 168 +---------------------- src/network/networkd-dhcp-server.h | 1 - src/network/networkd-dhcp4.c | 164 +--------------------- src/network/networkd-dhcp4.h | 1 - src/network/networkd-network-gperf.gperf | 4 +- src/network/networkd-network.c | 4 +- src/network/networkd-network.h | 4 +- 9 files changed, 172 insertions(+), 338 deletions(-) diff --git a/src/network/networkd-dhcp-common.c b/src/network/networkd-dhcp-common.c index 7e42a6edd4..7f8da46cf5 100644 --- a/src/network/networkd-dhcp-common.c +++ b/src/network/networkd-dhcp-common.c @@ -1,5 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ +#include "dhcp-internal.h" +#include "escape.h" #include "in-addr-util.h" #include "networkd-dhcp-common.h" #include "networkd-network.h" @@ -263,6 +265,167 @@ int config_parse_dhcp6_pd_hint( return 0; } +int config_parse_dhcp_send_option( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + _cleanup_(sd_dhcp_option_unrefp) sd_dhcp_option *opt = NULL, *old = NULL; + _cleanup_free_ char *word = NULL, *q = NULL; + OrderedHashmap **options = userdata; + union in_addr_union addr; + DHCPOptionDataType type; + uint8_t u, uint8_data; + uint16_t uint16_data; + uint32_t uint32_data; + const void *udata; + const char *p; + ssize_t sz; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if (isempty(rvalue)) { + *options = ordered_hashmap_free(*options); + return 0; + } + + p = rvalue; + r = extract_first_word(&p, &word, ":", 0); + if (r == -ENOMEM) + return log_oom(); + if (r <= 0) { + log_syntax(unit, LOG_ERR, filename, line, r, + "Invalid DHCP option, ignoring assignment: %s", rvalue); + return 0; + } + + r = safe_atou8(word, &u); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, + "Invalid DHCP option, ignoring assignment: %s", rvalue); + return 0; + } + if (u < 1 || u >= 255) { + log_syntax(unit, LOG_ERR, filename, line, 0, + "Invalid DHCP option, valid range is 1-254, ignoring assignment: %s", rvalue); + return 0; + } + + free(word); + r = extract_first_word(&p, &word, ":", 0); + if (r == -ENOMEM) + return log_oom(); + if (r <= 0) { + log_syntax(unit, LOG_ERR, filename, line, r, + "Invalid DHCP option, ignoring assignment: %s", rvalue); + return 0; + } + + type = dhcp_option_data_type_from_string(word); + if (type < 0) { + log_syntax(unit, LOG_ERR, filename, line, 0, + "Invalid DHCP option data type, ignoring assignment: %s", p); + return 0; + } + + switch(type) { + case DHCP_OPTION_DATA_UINT8:{ + r = safe_atou8(p, &uint8_data); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, + "Failed to parse DHCPv4 uint8 data, ignoring assignment: %s", p); + return 0; + } + + udata = &uint8_data; + sz = sizeof(uint8_t); + break; + } + case DHCP_OPTION_DATA_UINT16:{ + r = safe_atou16(p, &uint16_data); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, + "Failed to parse DHCPv4 uint16 data, ignoring assignment: %s", p); + return 0; + } + + udata = &uint16_data; + sz = sizeof(uint16_t); + break; + } + case DHCP_OPTION_DATA_UINT32: { + r = safe_atou32(p, &uint32_data); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, + "Failed to parse DHCPv4 uint32 data, ignoring assignment: %s", p); + return 0; + } + + udata = &uint32_data; + sz = sizeof(uint32_t); + + break; + } + case DHCP_OPTION_DATA_IPV4ADDRESS: { + r = in_addr_from_string(AF_INET, p, &addr); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, + "Failed to parse DHCPv4 ipv4address data, ignoring assignment: %s", p); + return 0; + } + + udata = &addr.in; + sz = sizeof(addr.in.s_addr); + break; + } + case DHCP_OPTION_DATA_STRING: + sz = cunescape(p, 0, &q); + if (sz < 0) { + log_syntax(unit, LOG_ERR, filename, line, sz, + "Failed to decode DHCPv4 option data, ignoring assignment: %s", p); + } + + udata = q; + break; + default: + return -EINVAL; + } + + r = sd_dhcp_option_new(u, udata, sz, &opt); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, + "Failed to store DHCPv4 option '%s', ignoring assignment: %m", rvalue); + return 0; + } + + r = ordered_hashmap_ensure_allocated(options, &dhcp_option_hash_ops); + if (r < 0) + return log_oom(); + + /* Overwrite existing option */ + old = ordered_hashmap_remove(*options, UINT_TO_PTR(u)); + r = ordered_hashmap_put(*options, UINT_TO_PTR(u), opt); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, + "Failed to store DHCPv4 option '%s', ignoring assignment: %m", rvalue); + return 0; + } + + TAKE_PTR(opt); + return 0; +} + DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_use_domains, dhcp_use_domains, DHCPUseDomains, "Failed to parse DHCP use domains setting"); diff --git a/src/network/networkd-dhcp-common.h b/src/network/networkd-dhcp-common.h index b194e0bfb7..1d6ddbb8cc 100644 --- a/src/network/networkd-dhcp-common.h +++ b/src/network/networkd-dhcp-common.h @@ -48,3 +48,4 @@ CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_use_sip); CONFIG_PARSER_PROTOTYPE(config_parse_iaid); CONFIG_PARSER_PROTOTYPE(config_parse_section_route_table); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp6_pd_hint); +CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_send_option); diff --git a/src/network/networkd-dhcp-server.c b/src/network/networkd-dhcp-server.c index a58cf8de8a..98bb647bd7 100644 --- a/src/network/networkd-dhcp-server.c +++ b/src/network/networkd-dhcp-server.c @@ -2,8 +2,6 @@ #include "sd-dhcp-server.h" -#include "dhcp-internal.h" -#include "escape.h" #include "networkd-dhcp-server.h" #include "networkd-link.h" #include "networkd-manager.h" @@ -306,7 +304,7 @@ int dhcp4_server_configure(Link *link) { return r; } - ORDERED_HASHMAP_FOREACH(p, link->network->dhcp_server_options, i) { + ORDERED_HASHMAP_FOREACH(p, link->network->dhcp_server_send_options, i) { r = sd_dhcp_server_add_option(link->dhcp_server, p); if (r == -EEXIST) continue; @@ -480,167 +478,3 @@ int config_parse_dhcp_server_sip( n->dhcp_server_sip = m; } } - -int config_parse_dhcp_server_option_data( - const char *unit, - const char *filename, - unsigned line, - const char *section, - unsigned section_line, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { - - _cleanup_(sd_dhcp_option_unrefp) sd_dhcp_option *opt = NULL, *old = NULL; - _cleanup_free_ char *word = NULL, *q = NULL; - union in_addr_union addr; - DHCPOptionDataType type; - Network *network = data; - uint16_t uint16_data; - uint32_t uint32_data; - uint8_t uint8_data; - const char *p; - void *udata; - ssize_t sz; - uint8_t u; - int r; - - assert(filename); - assert(lvalue); - assert(rvalue); - assert(data); - - if (isempty(rvalue)) { - network->dhcp_server_options = ordered_hashmap_free(network->dhcp_server_options); - return 0; - } - - p = rvalue; - r = extract_first_word(&p, &word, ":", 0); - if (r == -ENOMEM) - return log_oom(); - if (r <= 0) { - log_syntax(unit, LOG_ERR, filename, line, r, - "Invalid DHCP server send raw option, ignoring assignment: %s", rvalue); - return 0; - } - - r = safe_atou8(word, &u); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, r, - "Failed to parse DHCP server send raw option type, ignoring assignment: %s", rvalue); - return 0; - } - if (u < 1 || u >= 255) { - log_syntax(unit, LOG_ERR, filename, line, 0, - "Invalid DHCP server send raw option, valid range is 1-254, ignoring assignment: %s", rvalue); - return 0; - } - - free(word); - - r = extract_first_word(&p, &word, ":", 0); - if (r == -ENOMEM) - return log_oom(); - if (r <= 0) { - log_syntax(unit, LOG_ERR, filename, line, r, - "Invalid DHCP server send raw option, ignoring assignment: %s", rvalue); - return 0; - } - - type = dhcp_option_data_type_from_string(word); - if (type < 0) { - log_syntax(unit, LOG_ERR, filename, line, 0, - "Invalid DHCP server send data type, ignoring assignment: %s", p); - return 0; - } - - switch(type) { - case DHCP_OPTION_DATA_UINT8:{ - r = safe_atou8(p, &uint8_data); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, r, - "Failed to parse DHCPv4 vendor specific uint8 data, ignoring assignment: %s", p); - return 0; - } - - udata = &uint8_data; - sz = sizeof(uint8_t); - break; - } - case DHCP_OPTION_DATA_UINT16:{ - r = safe_atou16(p, &uint16_data); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, r, - "Failed to parse DHCPv4 vendor specific uint16 data, ignoring assignment: %s", p); - return 0; - } - - udata = &uint16_data; - sz = sizeof(uint16_t); - break; - } - case DHCP_OPTION_DATA_UINT32: { - r = safe_atou32(p, &uint32_data); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, r, - "Failed to parse DHCPv4 vendor specific uint32 data, ignoring assignment: %s", p); - return 0; - } - - udata = &uint32_data; - sz = sizeof(uint32_t); - - break; - } - case DHCP_OPTION_DATA_IPV4ADDRESS: { - r = in_addr_from_string(AF_INET, p, &addr); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, r, - "Failed to parse DHCPv4 vendor specific ipv4address data, ignoring assignment: %s", p); - return 0; - } - - udata = &addr.in; - sz = sizeof(addr.in.s_addr); - break; - } - case DHCP_OPTION_DATA_STRING: - sz = cunescape(p, 0, &q); - if (sz < 0) { - log_syntax(unit, LOG_ERR, filename, line, sz, - "Failed to decode option data, ignoring assignment: %s", p); - } - - udata = q; - break; - default: - return -EINVAL; - } - - r = sd_dhcp_option_new(u, udata, sz, &opt); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, r, - "Failed to store DHCP send raw option '%s', ignoring assignment: %m", rvalue); - return 0; - } - - r = ordered_hashmap_ensure_allocated(&network->dhcp_server_options, &dhcp_option_hash_ops); - if (r < 0) - return log_oom(); - - /* Overwrite existing option */ - old = ordered_hashmap_remove(network->dhcp_server_options, UINT_TO_PTR(u)); - r = ordered_hashmap_put(network->dhcp_server_options, UINT_TO_PTR(u), opt); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, r, - "Failed to store DHCP server send raw option '%s'", rvalue); - return 0; - } - - TAKE_PTR(opt); - - return 0; -} diff --git a/src/network/networkd-dhcp-server.h b/src/network/networkd-dhcp-server.h index 21f1f31b15..c90d48ec00 100644 --- a/src/network/networkd-dhcp-server.h +++ b/src/network/networkd-dhcp-server.h @@ -12,4 +12,3 @@ int dhcp4_server_configure(Link *link); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_dns); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_ntp); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_sip); -CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_option_data); diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c index 7504e4eb27..8ca87d99d4 100644 --- a/src/network/networkd-dhcp4.c +++ b/src/network/networkd-dhcp4.c @@ -6,7 +6,6 @@ #include "alloc-util.h" #include "dhcp-client-internal.h" -#include "escape.h" #include "hostname-util.h" #include "parse-util.h" #include "network-internal.h" @@ -1295,7 +1294,7 @@ int dhcp4_configure(Link *link) { return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for '%u': %m", option); } - ORDERED_HASHMAP_FOREACH(send_option, link->network->dhcp_send_options, i) { + ORDERED_HASHMAP_FOREACH(send_option, link->network->dhcp_client_send_options, i) { r = sd_dhcp_client_set_dhcp_option(link->dhcp_client, send_option); if (r < 0) return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set send option: %m"); @@ -1566,167 +1565,6 @@ int config_parse_dhcp_request_options( return 0; } -int config_parse_dhcp_send_option( - const char *unit, - const char *filename, - unsigned line, - const char *section, - unsigned section_line, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { - - _cleanup_(sd_dhcp_option_unrefp) sd_dhcp_option *opt = NULL, *old = NULL; - _cleanup_free_ char *word = NULL, *q = NULL; - union in_addr_union addr; - DHCPOptionDataType type; - Network *network = data; - uint8_t u, uint8_data; - uint16_t uint16_data; - uint32_t uint32_data; - const char *p; - void *udata; - ssize_t sz; - int r; - - assert(filename); - assert(lvalue); - assert(rvalue); - assert(data); - - if (isempty(rvalue)) { - network->dhcp_send_options = ordered_hashmap_free(network->dhcp_send_options); - return 0; - } - - p = rvalue; - r = extract_first_word(&p, &word, ":", 0); - if (r == -ENOMEM) - return log_oom(); - if (r <= 0) { - log_syntax(unit, LOG_ERR, filename, line, r, - "Invalid DHCP send option, ignoring assignment: %s", rvalue); - return 0; - } - - r = safe_atou8(word, &u); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, r, - "Invalid DHCP send option, ignoring assignment: %s", rvalue); - return 0; - } - if (u < 1 || u >= 255) { - log_syntax(unit, LOG_ERR, filename, line, 0, - "Invalid DHCP send option, valid range is 1-254, ignoring assignment: %s", rvalue); - return 0; - } - - free(word); - r = extract_first_word(&p, &word, ":", 0); - if (r == -ENOMEM) - return log_oom(); - if (r <= 0) { - log_syntax(unit, LOG_ERR, filename, line, r, - "Invalid DHCP send option, ignoring assignment: %s", rvalue); - return 0; - } - - type = dhcp_option_data_type_from_string(word); - if (type < 0) { - log_syntax(unit, LOG_ERR, filename, line, 0, - "Invalid DHCP send data type, ignoring assignment: %s", p); - return 0; - } - - switch(type) { - case DHCP_OPTION_DATA_UINT8:{ - r = safe_atou8(p, &uint8_data); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, r, - "Failed to parse DHCPv4 uint8 data, ignoring assignment: %s", p); - return 0; - } - - udata = &uint8_data; - sz = sizeof(uint8_t); - break; - } - case DHCP_OPTION_DATA_UINT16:{ - r = safe_atou16(p, &uint16_data); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, r, - "Failed to parse DHCPv4 uint16 data, ignoring assignment: %s", p); - return 0; - } - - udata = &uint16_data; - sz = sizeof(uint16_t); - break; - } - case DHCP_OPTION_DATA_UINT32: { - r = safe_atou32(p, &uint32_data); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, r, - "Failed to parse DHCPv4 uint32 data, ignoring assignment: %s", p); - return 0; - } - - udata = &uint32_data; - sz = sizeof(uint32_t); - - break; - } - case DHCP_OPTION_DATA_IPV4ADDRESS: { - r = in_addr_from_string(AF_INET, p, &addr); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, r, - "Failed to parse DHCPv4 ipv4address data, ignoring assignment: %s", p); - return 0; - } - - udata = &addr.in; - sz = sizeof(addr.in.s_addr); - break; - } - case DHCP_OPTION_DATA_STRING: - sz = cunescape(p, 0, &q); - if (sz < 0) { - log_syntax(unit, LOG_ERR, filename, line, sz, - "Failed to decode option data, ignoring assignment: %s", p); - } - - udata = q; - break; - default: - return -EINVAL; - } - - r = sd_dhcp_option_new(u, udata, sz, &opt); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, r, - "Failed to store DHCP send option '%s', ignoring assignment: %m", rvalue); - return 0; - } - - r = ordered_hashmap_ensure_allocated(&network->dhcp_send_options, &dhcp_option_hash_ops); - if (r < 0) - return log_oom(); - - /* Overwrite existing option */ - old = ordered_hashmap_remove(network->dhcp_send_options, UINT_TO_PTR(u)); - r = ordered_hashmap_put(network->dhcp_send_options, UINT_TO_PTR(u), opt); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, r, - "Failed to store DHCP send option '%s'", rvalue); - return 0; - } - - TAKE_PTR(opt); - return 0; -} - static const char* const dhcp_client_identifier_table[_DHCP_CLIENT_ID_MAX] = { [DHCP_CLIENT_ID_MAC] = "mac", [DHCP_CLIENT_ID_DUID] = "duid", diff --git a/src/network/networkd-dhcp4.h b/src/network/networkd-dhcp4.h index 2c0ccd80df..fce11ef671 100644 --- a/src/network/networkd-dhcp4.h +++ b/src/network/networkd-dhcp4.h @@ -27,4 +27,3 @@ CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_black_listed_ip_address); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_max_attempts); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_user_class); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_request_options); -CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_send_option); diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index 928253cae0..f314b1ec16 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -175,7 +175,7 @@ DHCPv4.ListenPort, config_parse_uint16, DHCPv4.SendRelease, config_parse_bool, 0, offsetof(Network, dhcp_send_release) DHCPv4.BlackList, config_parse_dhcp_black_listed_ip_address, 0, 0 DHCPv4.IPServiceType, config_parse_ip_service_type, 0, offsetof(Network, ip_service_type) -DHCPv4.SendOption, config_parse_dhcp_send_option, 0, 0 +DHCPv4.SendOption, config_parse_dhcp_send_option, 0, offsetof(Network, dhcp_client_send_options) DHCPv6.UseDNS, config_parse_bool, 0, offsetof(Network, dhcp6_use_dns) DHCPv6.UseNTP, config_parse_bool, 0, offsetof(Network, dhcp6_use_ntp) DHCPv6.RapidCommit, config_parse_bool, 0, offsetof(Network, rapid_commit) @@ -200,7 +200,7 @@ DHCPServer.EmitTimezone, config_parse_bool, DHCPServer.Timezone, config_parse_timezone, 0, offsetof(Network, dhcp_server_timezone) DHCPServer.PoolOffset, config_parse_uint32, 0, offsetof(Network, dhcp_server_pool_offset) DHCPServer.PoolSize, config_parse_uint32, 0, offsetof(Network, dhcp_server_pool_size) -DHCPServer.SendOption, config_parse_dhcp_server_option_data, 0, 0 +DHCPServer.SendOption, config_parse_dhcp_send_option, 0, offsetof(Network, dhcp_server_send_options) Bridge.Cost, config_parse_uint32, 0, offsetof(Network, cost) Bridge.UseBPDU, config_parse_tristate, 0, offsetof(Network, use_bpdu) Bridge.HairPin, config_parse_tristate, 0, offsetof(Network, hairpin) diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 6b51b16d9b..6e443975f1 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -686,8 +686,8 @@ static Network *network_free(Network *network) { set_free_free(network->dnssec_negative_trust_anchors); - ordered_hashmap_free(network->dhcp_send_options); - ordered_hashmap_free(network->dhcp_server_options); + ordered_hashmap_free(network->dhcp_client_send_options); + ordered_hashmap_free(network->dhcp_server_send_options); return mfree(network); } diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index a1032051f1..aa74bb4ae7 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -114,8 +114,8 @@ struct Network { DHCPUseDomains dhcp_use_domains; Set *dhcp_black_listed_ip; Set *dhcp_request_options; - OrderedHashmap *dhcp_send_options; - OrderedHashmap *dhcp_server_options; + OrderedHashmap *dhcp_client_send_options; + OrderedHashmap *dhcp_server_send_options; /* DHCPv6 Client support*/ bool dhcp6_use_dns;