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);