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=