From 0e96961d6206eed0d685ba64cfb2a481cb23b91d Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 18 Nov 2019 18:29:29 +0900 Subject: [PATCH] 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 7e42a6e..7f8da46 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 b194e0b..1d6ddbb 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 a58cf8d..98bb647 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 21f1f31..c90d48e 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 7504e4e..8ca87d9 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 2c0ccd8..fce11ef 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 928253c..f314b1e 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 6b51b16..6e44397 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 a103205..aa74bb4 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; -- 2.7.4