From 3175a8c21bc2c40f4f43c3b7e42203af2898a93a Mon Sep 17 00:00:00 2001 From: Susant Sahani Date: Mon, 30 Mar 2020 16:31:10 +0200 Subject: [PATCH] network: DHCPv6 Add support to send MUD URL --- man/systemd.network.xml | 10 +++++ src/network/networkd-dhcp-common.c | 43 +++++++++++++++++++ src/network/networkd-dhcp-common.h | 1 + src/network/networkd-dhcp6.c | 6 +++ src/network/networkd-network-gperf.gperf | 1 + src/network/networkd-network.c | 1 + src/network/networkd-network.h | 1 + .../fuzz-network-parser/directives.network | 1 + 8 files changed, 64 insertions(+) diff --git a/man/systemd.network.xml b/man/systemd.network.xml index 5457e668dd2..201e33ed6e0 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -1691,6 +1691,16 @@ + + MUDURL= + + When configured, the Manufacturer Usage Descriptions (MUD) URL will be sent to the DHCPV6 server. + Takes an URL of length up to 255 characters. A superficial verification that the string is a valid URL + will be performed. DHCPv6 clients are intended to have at most one MUD URL associated with them. See + RFC 8520. + + + ForceDHCPv6PDOtherInformation= diff --git a/src/network/networkd-dhcp-common.c b/src/network/networkd-dhcp-common.c index 8664d8cdc0d..0473aba6159 100644 --- a/src/network/networkd-dhcp-common.c +++ b/src/network/networkd-dhcp-common.c @@ -8,6 +8,7 @@ #include "parse-util.h" #include "string-table.h" #include "strv.h" +#include "web-util.h" int config_parse_dhcp( const char* unit, @@ -265,6 +266,48 @@ int config_parse_dhcp6_pd_hint( return 0; } +int config_parse_dhcp6_mud_url( + 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_free_ char *unescaped = NULL; + Network *network = data; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + + if (isempty(rvalue)) { + network->dhcp6_mudurl = mfree(network->dhcp6_mudurl); + return 0; + } + + r = cunescape(rvalue, 0, &unescaped); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, + "Failed to Failed to unescape MUD URL, ignoring: %s", rvalue); + return 0; + } + + if (!http_url_is_valid(unescaped) || strlen(unescaped) > 255) { + log_syntax(unit, LOG_ERR, filename, line, 0, + "Failed to parse MUD URL '%s', ignoring: %m", rvalue); + + return 0; + } + + return free_and_replace(network->dhcp6_mudurl, unescaped); +} + int config_parse_dhcp_send_option( const char *unit, const char *filename, diff --git a/src/network/networkd-dhcp-common.h b/src/network/networkd-dhcp-common.h index 1d6ddbb8cc0..ca86016ef2a 100644 --- a/src/network/networkd-dhcp-common.h +++ b/src/network/networkd-dhcp-common.h @@ -48,4 +48,5 @@ 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_dhcp6_mud_url); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_send_option); diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c index 7304270c60b..3580498e351 100644 --- a/src/network/networkd-dhcp6.c +++ b/src/network/networkd-dhcp6.c @@ -676,6 +676,12 @@ int dhcp6_configure(Link *link) { return log_link_error_errno(link, r, "DHCP6 CLIENT: Failed to set request flag for rapid commit: %m"); } + if (link->network->dhcp6_mudurl) { + r = sd_dhcp6_client_set_request_mud_url(client, link->network->dhcp6_mudurl); + if (r < 0) + return log_link_error_errno(link, r, "DHCP6 CLIENT: Failed to set MUD URL: %m"); + } + r = sd_dhcp6_client_set_callback(client, dhcp6_handler, link); if (r < 0) return log_link_error_errno(link, r, "DHCP6 CLIENT: Failed to set callback: %m"); diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index fd996327a55..d98b32b7568 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -189,6 +189,7 @@ DHCPv4.RouteMTUBytes, config_parse_mtu, 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) +DHCPv6.MUDURL, config_parse_dhcp6_mud_url, 0, 0 DHCPv6.ForceDHCPv6PDOtherInformation, config_parse_bool, 0, offsetof(Network, dhcp6_force_pd_other_information) DHCPv6.PrefixDelegationHint, config_parse_dhcp6_pd_hint, 0, 0 DHCPv6.WithoutRA, config_parse_bool, 0, offsetof(Network, dhcp6_without_ra) diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index e7ead446c76..46a5a5320a0 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -644,6 +644,7 @@ static Network *network_free(Network *network) { set_free(network->dhcp_black_listed_ip); set_free(network->dhcp_request_options); free(network->mac); + free(network->dhcp6_mudurl); if (network->dhcp_acd) sd_ipv4acd_unref(network->dhcp_acd); diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index f747ccaf101..3b48e4238dc 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -130,6 +130,7 @@ struct Network { bool dhcp6_use_ntp; bool dhcp6_without_ra; uint8_t dhcp6_pd_length; + char *dhcp6_mudurl; struct in6_addr dhcp6_pd_address; /* DHCP Server Support */ diff --git a/test/fuzz/fuzz-network-parser/directives.network b/test/fuzz/fuzz-network-parser/directives.network index 4418fc01495..76a4c42403c 100644 --- a/test/fuzz/fuzz-network-parser/directives.network +++ b/test/fuzz/fuzz-network-parser/directives.network @@ -110,6 +110,7 @@ RapidCommit= ForceDHCPv6PDOtherInformation= PrefixDelegationHint= WithoutRA= +MUDURL= [Route] Destination= Protocol=