From 4f1ac4a38d1adf08f849af1a61c7a248932d8e13 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 27 Oct 2021 13:22:49 +0900 Subject: [PATCH] network: radv: refuse invalid router lifetime in conf parser --- man/systemd.network.xml | 3 +- src/network/networkd-network-gperf.gperf | 2 +- src/network/networkd-network.c | 3 +- src/network/networkd-radv.c | 53 ++++++++++++++++++++++++ src/network/networkd-radv.h | 1 + 5 files changed, 59 insertions(+), 3 deletions(-) diff --git a/man/systemd.network.xml b/man/systemd.network.xml index 41a58b36eb..b263220e0c 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -2622,7 +2622,8 @@ Token=prefixstable:2002:da8:1:: RouterLifetimeSec= Takes a timespan. Configures the IPv6 router lifetime in seconds. When set to - 0, the host is not acting as a router. Defaults to 30 minutes. + 0, the host is not acting as a router. The value must be 0 second, or between 4 seconds and + 9000 seconds. Defaults to 1800 seconds (30 minutes). diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index 6631f5bc3e..595dd36121 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -331,7 +331,7 @@ DHCPv6PrefixDelegation.Assign, config_parse_bool, DHCPv6PrefixDelegation.ManageTemporaryAddress, config_parse_bool, 0, offsetof(Network, dhcp6_pd_manage_temporary_address) DHCPv6PrefixDelegation.Token, config_parse_address_generation_type, 0, offsetof(Network, dhcp6_pd_tokens) DHCPv6PrefixDelegation.RouteMetric, config_parse_uint32, 0, offsetof(Network, dhcp6_pd_route_metric) -IPv6SendRA.RouterLifetimeSec, config_parse_sec, 0, offsetof(Network, router_lifetime_usec) +IPv6SendRA.RouterLifetimeSec, config_parse_router_lifetime, 0, offsetof(Network, router_lifetime_usec) IPv6SendRA.Managed, config_parse_bool, 0, offsetof(Network, router_managed) IPv6SendRA.OtherInformation, config_parse_bool, 0, offsetof(Network, router_other_information) IPv6SendRA.RouterPreference, config_parse_router_preference, 0, 0 diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 5469cb4560..1f83a092c5 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -33,6 +33,7 @@ #include "networkd-sriov.h" #include "parse-util.h" #include "path-lookup.h" +#include "radv-internal.h" #include "set.h" #include "socket-util.h" #include "stat-util.h" @@ -421,7 +422,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi .dhcp_server_emit_router = true, .dhcp_server_emit_timezone = true, - .router_lifetime_usec = 30 * USEC_PER_MINUTE, + .router_lifetime_usec = RADV_DEFAULT_ROUTER_LIFETIME_USEC, .router_dns_lifetime_usec = 7 * USEC_PER_DAY, .router_emit_dns = true, .router_emit_domains = true, diff --git a/src/network/networkd-radv.c b/src/network/networkd-radv.c index 7b92e6c4f9..08a8bbf8da 100644 --- a/src/network/networkd-radv.c +++ b/src/network/networkd-radv.c @@ -17,6 +17,7 @@ #include "networkd-radv.h" #include "networkd-route.h" #include "parse-util.h" +#include "radv-internal.h" #include "string-util.h" #include "string-table.h" #include "strv.h" @@ -1256,6 +1257,58 @@ int config_parse_router_prefix_delegation( return 0; } +int config_parse_router_lifetime( + 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) { + + usec_t usec, *lifetime = data; + int r; + + assert(filename); + assert(section); + assert(lvalue); + assert(rvalue); + assert(data); + + if (isempty(rvalue)) { + *lifetime = RADV_DEFAULT_ROUTER_LIFETIME_USEC; + return 0; + } + + r = parse_sec(rvalue, &usec); + if (r < 0) { + log_syntax(unit, LOG_WARNING, filename, line, r, + "Failed to parse router lifetime, ignoring assignment: %s", rvalue); + return 0; + } + if (usec > 0) { + if (usec < RADV_MIN_ROUTER_LIFETIME_USEC) { + log_syntax(unit, LOG_WARNING, filename, line, 0, + "Router lifetime %s is too short, using %s.", + FORMAT_TIMESPAN(usec, USEC_PER_SEC), + FORMAT_TIMESPAN(RADV_MIN_ROUTER_LIFETIME_USEC, USEC_PER_SEC)); + usec = RADV_MIN_ROUTER_LIFETIME_USEC; + } else if (usec > RADV_MAX_ROUTER_LIFETIME_USEC) { + log_syntax(unit, LOG_WARNING, filename, line, 0, + "Router lifetime %s is too large, using %s.", + FORMAT_TIMESPAN(usec, USEC_PER_SEC), + FORMAT_TIMESPAN(RADV_MAX_ROUTER_LIFETIME_USEC, USEC_PER_SEC)); + usec = RADV_MAX_ROUTER_LIFETIME_USEC; + } + } + + *lifetime = usec; + return 0; +} + int config_parse_router_preference( const char *unit, const char *filename, diff --git a/src/network/networkd-radv.h b/src/network/networkd-radv.h index 2d69a6fa27..392c00b37d 100644 --- a/src/network/networkd-radv.h +++ b/src/network/networkd-radv.h @@ -75,6 +75,7 @@ const char* radv_prefix_delegation_to_string(RADVPrefixDelegation i) _const_; RADVPrefixDelegation radv_prefix_delegation_from_string(const char *s) _pure_; CONFIG_PARSER_PROTOTYPE(config_parse_router_prefix_delegation); +CONFIG_PARSER_PROTOTYPE(config_parse_router_lifetime); CONFIG_PARSER_PROTOTYPE(config_parse_router_preference); CONFIG_PARSER_PROTOTYPE(config_parse_prefix); CONFIG_PARSER_PROTOTYPE(config_parse_prefix_boolean);