diff --git a/man/systemd.network.xml b/man/systemd.network.xml index ae82ae7e02b..146401f6c90 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -1614,8 +1614,7 @@ RouteMetric= - Set the routing metric for routes specified by the - DHCP server. + Set the routing metric for routes specified by the DHCP server. Defaults to 1024. @@ -1734,6 +1733,13 @@ + + RouteMetric= + + Set the routing metric for routes specified by the DHCP server. Defaults to 1024. + + + RapidCommit= diff --git a/src/network/networkd-dhcp-common.c b/src/network/networkd-dhcp-common.c index 66dd8ea08e2..606ae9f3c2f 100644 --- a/src/network/networkd-dhcp-common.c +++ b/src/network/networkd-dhcp-common.c @@ -9,7 +9,6 @@ #include "parse-util.h" #include "string-table.h" #include "strv.h" -#include "web-util.h" int config_parse_dhcp( const char* unit, @@ -63,6 +62,50 @@ int config_parse_dhcp( return 0; } +int config_parse_dhcp_route_metric( + 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; + uint32_t metric; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + r = safe_atou32(rvalue, &metric); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, + "Failed to parse RouteMetric=%s, ignoring assignment: %m", rvalue); + return 0; + } + + if (streq_ptr(section, "DHCPv4")) { + network->dhcp_route_metric = metric; + network->dhcp_route_metric_set = true; + } else if (streq_ptr(section, "DHCPv6")) { + network->dhcp6_route_metric = metric; + network->dhcp6_route_metric_set = true; + } else { /* [DHCP] section */ + if (!network->dhcp_route_metric_set) + network->dhcp_route_metric = metric; + if (!network->dhcp6_route_metric_set) + network->dhcp6_route_metric = metric; + } + + return 0; +} + int config_parse_dhcp_use_dns( const char* unit, const char *filename, @@ -90,41 +133,19 @@ int config_parse_dhcp_use_dns( return 0; } - network->dhcp_use_dns = r; - network->dhcp6_use_dns = r; - - return 0; -} - -int config_parse_dhcp_use_sip( - 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; - int r; - - assert(filename); - assert(lvalue); - assert(rvalue); - assert(data); - - r = parse_boolean(rvalue); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, r, - "Failed to parse UseSIP=%s, ignoring assignment: %m", rvalue); - return 0; + if (streq_ptr(section, "DHCPv4")) { + network->dhcp_use_dns = r; + network->dhcp_use_dns_set = true; + } else if (streq_ptr(section, "DHCPv6")) { + network->dhcp6_use_dns = r; + network->dhcp6_use_dns_set = true; + } else { /* [DHCP] section */ + if (!network->dhcp_use_dns_set) + network->dhcp_use_dns = r; + if (!network->dhcp6_use_dns_set) + network->dhcp6_use_dns = r; } - network->dhcp_use_sip = r; - return 0; } @@ -155,8 +176,18 @@ int config_parse_dhcp_use_ntp( return 0; } - network->dhcp_use_ntp = r; - network->dhcp6_use_ntp = r; + if (streq_ptr(section, "DHCPv4")) { + network->dhcp_use_ntp = r; + network->dhcp_use_ntp_set = true; + } else if (streq_ptr(section, "DHCPv6")) { + network->dhcp6_use_ntp = r; + network->dhcp6_use_ntp_set = true; + } else { /* [DHCP] section */ + if (!network->dhcp_use_ntp_set) + network->dhcp_use_ntp = r; + if (!network->dhcp6_use_ntp_set) + network->dhcp6_use_ntp = r; + } return 0; } @@ -232,41 +263,6 @@ int config_parse_iaid(const char *unit, return 0; } -int config_parse_dhcp6_pd_hint( - 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; - int r; - - assert(filename); - assert(lvalue); - assert(rvalue); - assert(data); - - r = in_addr_prefix_from_string(rvalue, AF_INET6, (union in_addr_union *) &network->dhcp6_pd_address, &network->dhcp6_pd_length); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse PrefixDelegationHint=%s, ignoring assignment", rvalue); - return 0; - } - - if (network->dhcp6_pd_length < 1 || network->dhcp6_pd_length > 128) { - log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid prefix length='%d', ignoring assignment", network->dhcp6_pd_length); - network->dhcp6_pd_length = 0; - return 0; - } - - return 0; -} - int config_parse_dhcp_user_class( const char *unit, const char *filename, @@ -382,47 +378,6 @@ int config_parse_dhcp_vendor_class( 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) > UINT8_MAX) { - 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 d837f89c258..01400a23858 100644 --- a/src/network/networkd-dhcp-common.h +++ b/src/network/networkd-dhcp-common.h @@ -42,14 +42,12 @@ const char *dhcp_option_data_type_to_string(DHCPOptionDataType d) _const_; DHCPOptionDataType dhcp_option_data_type_from_string(const char *d) _pure_; CONFIG_PARSER_PROTOTYPE(config_parse_dhcp); +CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_route_metric); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_use_dns); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_use_domains); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_use_ntp); -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_user_class); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_vendor_class); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_send_option); diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c index 6a1083fd5c9..f86fdc21036 100644 --- a/src/network/networkd-dhcp6.c +++ b/src/network/networkd-dhcp6.c @@ -10,6 +10,7 @@ #include "sd-dhcp6-client.h" +#include "escape.h" #include "hashmap.h" #include "hostname-util.h" #include "missing_network.h" @@ -20,6 +21,7 @@ #include "siphash24.h" #include "string-util.h" #include "radv-internal.h" +#include "web-util.h" static int dhcp6_lease_address_acquired(sd_dhcp6_client *client, Link *link); static Link *dhcp6_prefix_get(Manager *m, struct in6_addr *addr); @@ -1077,3 +1079,79 @@ static int dhcp6_assign_delegated_prefix(Link *link, return 0; } + +int config_parse_dhcp6_pd_hint( + 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; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + r = in_addr_prefix_from_string(rvalue, AF_INET6, (union in_addr_union *) &network->dhcp6_pd_address, &network->dhcp6_pd_length); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse PrefixDelegationHint=%s, ignoring assignment", rvalue); + return 0; + } + + if (network->dhcp6_pd_length < 1 || network->dhcp6_pd_length > 128) { + log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid prefix length='%d', ignoring assignment", network->dhcp6_pd_length); + network->dhcp6_pd_length = 0; + return 0; + } + + 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) > UINT8_MAX) { + 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); +} diff --git a/src/network/networkd-dhcp6.h b/src/network/networkd-dhcp6.h index 26d810f40c3..e7c180897bf 100644 --- a/src/network/networkd-dhcp6.h +++ b/src/network/networkd-dhcp6.h @@ -13,3 +13,6 @@ int dhcp6_configure(Link *link); int dhcp6_request_address(Link *link, int ir); int dhcp6_lease_pd_prefix_lost(sd_dhcp6_client *client, Link* link); int dhcp6_prefix_remove(Manager *m, struct in6_addr *addr); + +CONFIG_PARSER_PROTOTYPE(config_parse_dhcp6_pd_hint); +CONFIG_PARSER_PROTOTYPE(config_parse_dhcp6_mud_url); diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c index 8af7b3c0c3c..6de8428e1e2 100644 --- a/src/network/networkd-ndisc.c +++ b/src/network/networkd-ndisc.c @@ -216,7 +216,7 @@ static int ndisc_router_process_default(Link *link, sd_ndisc_router *rt) { route->family = AF_INET6; route->table = link_get_ipv6_accept_ra_route_table(link); - route->priority = link->network->dhcp_route_metric; + route->priority = link->network->dhcp6_route_metric; route->protocol = RTPROT_RA; route->pref = preference; route->gw = gateway; @@ -451,7 +451,7 @@ static int ndisc_router_process_onlink_prefix(Link *link, sd_ndisc_router *rt) { route->family = AF_INET6; route->table = link_get_ipv6_accept_ra_route_table(link); - route->priority = link->network->dhcp_route_metric; + route->priority = link->network->dhcp6_route_metric; route->protocol = RTPROT_RA; route->flags = RTM_F_PREFIX; route->dst_prefixlen = prefixlen; @@ -512,6 +512,7 @@ static int ndisc_router_process_route(Link *link, sd_ndisc_router *rt) { route->family = AF_INET6; route->table = link_get_ipv6_accept_ra_route_table(link); + route->priority = link->network->dhcp6_route_metric; route->protocol = RTPROT_RA; route->pref = preference; route->gw.in6 = gateway; diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index 4de2e5e8622..b3dde3bfac6 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -11,6 +11,7 @@ _Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"") #include "networkd-dhcp-common.h" #include "networkd-dhcp-server.h" #include "networkd-dhcp4.h" +#include "networkd-dhcp6.h" #include "networkd-ipv4ll.h" #include "networkd-ndisc.h" #include "networkd-network.h" @@ -158,9 +159,9 @@ Route.MultiPathRoute, config_parse_multipath_route, NextHop.Id, config_parse_nexthop_id, 0, 0 NextHop.Gateway, config_parse_nexthop_gateway, 0, 0 DHCPv4.ClientIdentifier, config_parse_dhcp_client_identifier, 0, offsetof(Network, dhcp_client_identifier) -DHCPv4.UseDNS, config_parse_bool, 0, offsetof(Network, dhcp_use_dns) +DHCPv4.UseDNS, config_parse_dhcp_use_dns, 0, 0 DHCPv4.RoutesToDNS, config_parse_bool, 0, offsetof(Network, dhcp_routes_to_dns) -DHCPv4.UseNTP, config_parse_bool, 0, offsetof(Network, dhcp_use_ntp) +DHCPv4.UseNTP, config_parse_dhcp_use_ntp, 0, 0 DHCPv4.UseSIP, config_parse_bool, 0, offsetof(Network, dhcp_use_sip) DHCPv4.UseMTU, config_parse_bool, 0, offsetof(Network, dhcp_use_mtu) DHCPv4.UseHostname, config_parse_bool, 0, offsetof(Network, dhcp_use_hostname) @@ -178,7 +179,7 @@ DHCPv4.MaxAttempts, config_parse_dhcp_max_attempts, DHCPv4.UserClass, config_parse_dhcp_user_class, AF_INET, offsetof(Network, dhcp_user_class) DHCPv4.DUIDType, config_parse_duid_type, 0, offsetof(Network, duid) DHCPv4.DUIDRawData, config_parse_duid_rawdata, 0, offsetof(Network, duid) -DHCPv4.RouteMetric, config_parse_unsigned, 0, offsetof(Network, dhcp_route_metric) +DHCPv4.RouteMetric, config_parse_dhcp_route_metric, 0, 0 DHCPv4.RouteTable, config_parse_section_route_table, 0, 0 DHCPv4.UseTimezone, config_parse_bool, 0, offsetof(Network, dhcp_use_timezone) DHCPv4.IAID, config_parse_iaid, 0, 0 @@ -191,8 +192,8 @@ DHCPv4.SendOption, config_parse_dhcp_send_option, DHCPv4.SendVendorOption, config_parse_dhcp_send_option, 0, offsetof(Network, dhcp_client_send_vendor_options) DHCPv4.RouteMTUBytes, config_parse_mtu, AF_INET, offsetof(Network, dhcp_route_mtu) DHCPv4.FallbackLeaseLifetimeSec, config_parse_dhcp_fallback_lease_lifetime, 0, 0 -DHCPv6.UseDNS, config_parse_bool, 0, offsetof(Network, dhcp6_use_dns) -DHCPv6.UseNTP, config_parse_bool, 0, offsetof(Network, dhcp6_use_ntp) +DHCPv6.UseDNS, config_parse_dhcp_use_dns, 0, 0 +DHCPv6.UseNTP, config_parse_dhcp_use_ntp, 0, 0 DHCPv6.RapidCommit, config_parse_bool, 0, offsetof(Network, rapid_commit) DHCPv6.MUDURL, config_parse_dhcp6_mud_url, 0, 0 DHCPv6.RequestOptions, config_parse_dhcp_request_options, AF_INET6, 0 @@ -204,6 +205,7 @@ DHCPv6.AssignAcquiredDelegatedPrefixAddress, config_parse_bool, DHCPv6.PrefixDelegationHint, config_parse_dhcp6_pd_hint, 0, 0 DHCPv6.WithoutRA, config_parse_bool, 0, offsetof(Network, dhcp6_without_ra) DHCPv6.SendOption, config_parse_dhcp_send_option, AF_INET6, offsetof(Network, dhcp6_client_send_options) +DHCPv6.RouteMetric, config_parse_dhcp_route_metric, 0, 0 IPv6AcceptRA.UseAutonomousPrefix, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_autonomous_prefix) IPv6AcceptRA.UseOnLinkPrefix, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_onlink_prefix) IPv6AcceptRA.UseDNS, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_dns) @@ -394,7 +396,7 @@ DHCP.VendorClassIdentifier, config_parse_string, DHCP.UserClass, config_parse_dhcp_user_class, AF_INET, offsetof(Network, dhcp_user_class) DHCP.DUIDType, config_parse_duid_type, 0, offsetof(Network, duid) DHCP.DUIDRawData, config_parse_duid_rawdata, 0, offsetof(Network, duid) -DHCP.RouteMetric, config_parse_unsigned, 0, offsetof(Network, dhcp_route_metric) +DHCP.RouteMetric, config_parse_dhcp_route_metric, 0, 0 DHCP.RouteTable, config_parse_section_route_table, 0, 0 DHCP.UseTimezone, config_parse_bool, 0, offsetof(Network, dhcp_use_timezone) DHCP.IAID, config_parse_iaid, 0, 0 diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 2e8cba4ae2e..b928f7585c3 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -410,6 +410,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi .dhcp_use_timezone = false, .rapid_commit = true, + .dhcp6_route_metric = DHCP_ROUTE_METRIC, .dhcp6_use_ntp = true, .dhcp6_use_dns = true, diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index 0e879be01b7..95e4d58b974 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -95,7 +95,8 @@ struct Network { char **dhcp_user_class; char *dhcp_hostname; uint64_t dhcp_max_attempts; - unsigned dhcp_route_metric; + uint32_t dhcp_route_metric; + bool dhcp_route_metric_set; uint32_t dhcp_route_table; uint32_t dhcp_fallback_lease_lifetime; uint32_t dhcp_route_mtu; @@ -106,8 +107,10 @@ struct Network { bool dhcp_send_hostname; bool dhcp_broadcast; bool dhcp_use_dns; + bool dhcp_use_dns_set; bool dhcp_routes_to_dns; bool dhcp_use_ntp; + bool dhcp_use_ntp_set; bool dhcp_use_sip; bool dhcp_use_mtu; bool dhcp_use_routes; @@ -129,9 +132,13 @@ struct Network { /* DHCPv6 Client support*/ bool dhcp6_use_dns; + bool dhcp6_use_dns_set; bool dhcp6_use_ntp; + bool dhcp6_use_ntp_set; bool dhcp6_without_ra; uint8_t dhcp6_pd_length; + uint32_t dhcp6_route_metric; + bool dhcp6_route_metric_set; char *dhcp6_mudurl; char **dhcp6_user_class; char **dhcp6_vendor_class; diff --git a/test/fuzz/fuzz-network-parser/directives.network b/test/fuzz/fuzz-network-parser/directives.network index faa38a1c1e0..0b62420e0a9 100644 --- a/test/fuzz/fuzz-network-parser/directives.network +++ b/test/fuzz/fuzz-network-parser/directives.network @@ -121,6 +121,7 @@ UserClass= VendorClass= AssignAcquiredDelegatedPrefixAddress= SendVendorOption= +RouteMetric= [Route] Destination= Protocol=