From: Susant Sahani Date: Tue, 17 Sep 2019 12:49:22 +0000 (+0200) Subject: network dhcp4: Add support send request options in a generic manner X-Git-Tag: v244-rc1~275 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5bc945bec4adcbe38fb60e80e985b54746a3351c;p=thirdparty%2Fsystemd.git network dhcp4: Add support send request options in a generic manner --- diff --git a/man/systemd.network.xml b/man/systemd.network.xml index 8ecc39ce5e6..0fbc4dfe26f 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -1558,9 +1558,16 @@ - BlackList= + BlackList= + + A whitespace-separated list of IPv4 addresses. DHCP offers from servers in the list are rejected. + + + + + RequestOptions= - A whitespace-separated list of IPv4 addresses. DHCP offers from servers in the list are rejected. + A whitespace-separated list of integers in the range 1–254. diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c index d9951abe247..01fe769fe26 100644 --- a/src/network/networkd-dhcp4.c +++ b/src/network/networkd-dhcp4.c @@ -1078,6 +1078,8 @@ int dhcp4_set_client_identifier(Link *link) { } int dhcp4_configure(Link *link) { + void *request_options; + Iterator i; int r; assert(link); @@ -1163,6 +1165,19 @@ int dhcp4_configure(Link *link) { return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for timezone: %m"); } + SET_FOREACH(request_options, link->network->dhcp_request_options, i) { + uint32_t option = PTR_TO_UINT32(request_options); + + r = sd_dhcp_client_set_request_option(link->dhcp_client, option); + if (r == -EEXIST) { + log_link_debug(link, "DHCP4 CLIENT: Failed to set request flag for '%u' already exists, ignoring.", option); + continue; + } + + if (r < 0) + return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for '%u': %m", option); + } + r = dhcp4_set_hostname(link); if (r < 0) return r; @@ -1357,6 +1372,72 @@ int config_parse_dhcp_user_class( return 0; } +int config_parse_dhcp_request_options( + 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) { + + Network *network = data; + const char *p; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if (isempty(rvalue)) { + network->dhcp_request_options = set_free(network->dhcp_request_options); + return 0; + } + + for (p = rvalue;;) { + _cleanup_free_ char *n = NULL; + uint32_t i; + + r = extract_first_word(&p, &n, NULL, 0); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, + "Failed to parse DHCP request option, ignoring assignment: %s", + rvalue); + return 0; + } + if (r == 0) + return 0; + + r = safe_atou32(n, &i); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, + "DHCP request option is invalid, ignoring assignment: %s", n); + continue; + } + + if (i < 1 || i >= 255) { + log_syntax(unit, LOG_ERR, filename, line, r, + "DHCP request option is invalid, valid range is 1-254, ignoring assignment: %s", n); + continue; + } + + r = set_ensure_allocated(&network->dhcp_request_options, NULL); + if (r < 0) + return log_oom(); + + r = set_put(network->dhcp_request_options, UINT32_TO_PTR(i)); + if (r < 0) + log_syntax(unit, LOG_ERR, filename, line, r, + "Failed to store DHCP request option '%s', ignoring assignment: %m", n); + } + + 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 117b7110d36..fce11ef671e 100644 --- a/src/network/networkd-dhcp4.h +++ b/src/network/networkd-dhcp4.h @@ -26,3 +26,4 @@ CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_client_identifier); 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); diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index 43163a31ecd..8772b0e0599 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -149,6 +149,7 @@ DHCPv4.UseMTU, config_parse_bool, DHCPv4.UseHostname, config_parse_bool, 0, offsetof(Network, dhcp_use_hostname) DHCPv4.UseDomains, config_parse_dhcp_use_domains, 0, offsetof(Network, dhcp_use_domains) DHCPv4.UseRoutes, config_parse_bool, 0, offsetof(Network, dhcp_use_routes) +DHCPv4.RequestOptions, config_parse_dhcp_request_options, 0, 0 DHCPv4.Anonymize, config_parse_bool, 0, offsetof(Network, dhcp_anonymize) DHCPv4.SendHostname, config_parse_bool, 0, offsetof(Network, dhcp_send_hostname) DHCPv4.Hostname, config_parse_hostname, 0, offsetof(Network, dhcp_hostname) diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 0608219429c..2fe4c2d84ab 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -541,6 +541,7 @@ static Network *network_free(Network *network) { strv_free(network->dhcp_user_class); free(network->dhcp_hostname); set_free(network->dhcp_black_listed_ip); + set_free(network->dhcp_request_options); free(network->mac); strv_free(network->ntp); diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index 486b8c31a51..3bb21ef9169 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -102,6 +102,7 @@ struct Network { bool dhcp_send_release; DHCPUseDomains dhcp_use_domains; Set *dhcp_black_listed_ip; + Set *dhcp_request_options; /* DHCPv6 Client support*/ bool dhcp6_use_dns; diff --git a/test/fuzz/fuzz-network-parser/directives.network b/test/fuzz/fuzz-network-parser/directives.network index b688d37d08c..0381d8d90ab 100644 --- a/test/fuzz/fuzz-network-parser/directives.network +++ b/test/fuzz/fuzz-network-parser/directives.network @@ -89,6 +89,7 @@ ListenPort= UseTimezone= RouteTable= BlackList= +RequestOptions= SendRelease= MaxAttempts= [DHCPv6]