diff --git a/man/systemd.network.xml b/man/systemd.network.xml
index 95b41b28c0..b4fb051be3 100644
--- a/man/systemd.network.xml
+++ b/man/systemd.network.xml
@@ -2628,6 +2628,14 @@ Token=prefixstable:2002:da8:1::
+
+ UseHopLimit=
+
+ Takes a boolean. When true, the hop limit received in the Router Advertisement will be set to routes
+ configured based on the advertisement. See also IPv6HopLimit=. Defaults to true.
+
+
+
UseGateway=
diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c
index 972ba52b9e..5ac6e1f9ec 100644
--- a/src/network/networkd-ndisc.c
+++ b/src/network/networkd-ndisc.c
@@ -168,6 +168,7 @@ static void ndisc_set_route_priority(Link *link, Route *route) {
static int ndisc_request_route(Route *in, Link *link, sd_ndisc_router *rt) {
_cleanup_(route_freep) Route *route = in;
struct in6_addr router;
+ uint8_t hop_limit = 0;
uint32_t mtu = 0;
bool is_new;
int r;
@@ -187,6 +188,12 @@ static int ndisc_request_route(Route *in, Link *link, sd_ndisc_router *rt) {
return log_link_warning_errno(link, r, "Failed to get default router MTU from RA: %m");
}
+ if (link->network->ipv6_accept_ra_use_hop_limit) {
+ r = sd_ndisc_router_get_hop_limit(rt, &hop_limit);
+ if (r < 0 && r != -ENODATA)
+ return log_link_warning_errno(link, r, "Failed to get default router hop limit from RA: %m");
+ }
+
route->source = NETWORK_CONFIG_SOURCE_NDISC;
route->provider.in6 = router;
if (!route->table_set)
@@ -199,6 +206,9 @@ static int ndisc_request_route(Route *in, Link *link, sd_ndisc_router *rt) {
if (route->mtu == 0)
route->mtu = mtu;
+ if (route->hop_limit == 0)
+ route->hop_limit = hop_limit;
+
is_new = route_get(NULL, link, route, NULL) < 0;
r = link_request_route(link, TAKE_PTR(route), true, &link->ndisc_messages,
diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf
index 4049993beb..0f87ce24bb 100644
--- a/src/network/networkd-network-gperf.gperf
+++ b/src/network/networkd-network-gperf.gperf
@@ -283,6 +283,7 @@ IPv6AcceptRA.UseOnLinkPrefix, config_parse_bool,
IPv6AcceptRA.UseDNS, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_dns)
IPv6AcceptRA.UseDomains, config_parse_ipv6_accept_ra_use_domains, 0, offsetof(Network, ipv6_accept_ra_use_domains)
IPv6AcceptRA.UseMTU, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_mtu)
+IPv6AcceptRA.UseHopLimit, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_hop_limit)
IPv6AcceptRA.DHCPv6Client, config_parse_ipv6_accept_ra_start_dhcp6_client, 0, offsetof(Network, ipv6_accept_ra_start_dhcp6_client)
IPv6AcceptRA.RouteTable, config_parse_dhcp_or_ra_route_table, AF_INET6, 0
IPv6AcceptRA.RouteMetric, config_parse_ipv6_accept_ra_route_metric, 0, 0
diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
index 4014842985..b353ea32fe 100644
--- a/src/network/networkd-network.c
+++ b/src/network/networkd-network.c
@@ -484,6 +484,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
.ipv6_accept_ra_use_autonomous_prefix = true,
.ipv6_accept_ra_use_onlink_prefix = true,
.ipv6_accept_ra_use_mtu = true,
+ .ipv6_accept_ra_use_hop_limit = true,
.ipv6_accept_ra_route_table = RT_TABLE_MAIN,
.ipv6_accept_ra_route_metric_high = IPV6RA_ROUTE_METRIC_HIGH,
.ipv6_accept_ra_route_metric_medium = IPV6RA_ROUTE_METRIC_MEDIUM,
diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h
index 0b9775f014..51caf4b944 100644
--- a/src/network/networkd-network.h
+++ b/src/network/networkd-network.h
@@ -319,6 +319,7 @@ struct Network {
bool ipv6_accept_ra_use_autonomous_prefix;
bool ipv6_accept_ra_use_onlink_prefix;
bool ipv6_accept_ra_use_mtu;
+ bool ipv6_accept_ra_use_hop_limit;
bool ipv6_accept_ra_quickack;
bool ipv6_accept_ra_use_captive_portal;
bool active_slave;
diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c
index 283d515b81..5bb2388b41 100644
--- a/src/network/networkd-route.c
+++ b/src/network/networkd-route.c
@@ -1241,6 +1241,12 @@ static int route_configure(const Route *route, uint32_t lifetime_sec, Link *link
return r;
}
+ if (route->hop_limit > 0) {
+ r = sd_netlink_message_append_u32(m, RTAX_HOPLIMIT, route->hop_limit);
+ if (r < 0)
+ return r;
+ }
+
r = sd_netlink_message_close_container(m);
if (r < 0)
return r;
diff --git a/src/network/networkd-route.h b/src/network/networkd-route.h
index 1f84d31733..0ecabc2647 100644
--- a/src/network/networkd-route.h
+++ b/src/network/networkd-route.h
@@ -50,6 +50,7 @@ struct Route {
uint32_t initcwnd;
uint32_t initrwnd;
uint32_t advmss;
+ uint32_t hop_limit;
char *tcp_congestion_control_algo;
unsigned char pref;
unsigned flags;