network/ndisc: set IPv6 neighbor reachable time

Closes #31402.
This commit is contained in:
Yu Watanabe 2024-02-20 15:24:09 +09:00
parent a68f007a23
commit 1452d49741
5 changed files with 56 additions and 0 deletions

View file

@ -3347,6 +3347,17 @@ Token=prefixstable:2002:da8:1::</programlisting></para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>UseReachableTime=</varname></term>
<listitem>
<para>Takes a boolean. When true, the reachable time received in the Router Advertisement will be
set on the interface receiving the advertisement. It is used as the base timespan of the validity
of a neighbor entry. Defaults to true.</para>
<xi:include href="version-info.xml" xpointer="v256"/>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>UseRetransmissionTime=</varname></term>
<listitem>

View file

@ -544,6 +544,44 @@ static int ndisc_router_process_icmp6_ratelimit(Link *link, sd_ndisc_router *rt)
return 0;
}
static int ndisc_router_process_reachable_time(Link *link, sd_ndisc_router *rt) {
usec_t reachable_time, msec;
int r;
assert(link);
assert(link->network);
assert(rt);
if (!link->network->ipv6_accept_ra_use_reachable_time)
return 0;
/* Ignore the reachable time field of the RA header if the lifetime is zero. */
r = sd_ndisc_router_get_lifetime(rt, NULL);
if (r <= 0)
return r;
r = sd_ndisc_router_get_reachable_time(rt, &reachable_time);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to get reachable time from RA: %m");
/* 0 is the unspecified value and must not be set (see RFC4861, 6.3.4) */
if (!timestamp_is_set(reachable_time))
return 0;
msec = DIV_ROUND_UP(reachable_time, USEC_PER_MSEC);
if (msec <= 0 || msec > UINT32_MAX) {
log_link_debug(link, "Failed to get reachable time from RA - out of range (%"PRIu64"), ignoring", msec);
return 0;
}
/* Set the reachable time for Neighbor Solicitations. */
r = sysctl_write_ip_neighbor_property_uint32(AF_INET6, link->ifname, "base_reachable_time_ms", (uint32_t) msec);
if (r < 0)
log_link_warning_errno(link, r, "Failed to apply neighbor reachable time (%"PRIu64"), ignoring: %m", msec);
return 0;
}
static int ndisc_router_process_retransmission_time(Link *link, sd_ndisc_router *rt) {
usec_t retrans_time, msec;
int r;
@ -1660,6 +1698,10 @@ static int ndisc_router_handler(Link *link, sd_ndisc_router *rt) {
if (r < 0)
return r;
r = ndisc_router_process_reachable_time(link, rt);
if (r < 0)
return r;
r = ndisc_router_process_retransmission_time(link, rt);
if (r < 0)
return r;

View file

@ -298,6 +298,7 @@ IPv6AcceptRA.UseDNS, config_parse_bool,
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.UseReachableTime, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_reachable_time)
IPv6AcceptRA.UseRetransmissionTime, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_retransmission_time)
IPv6AcceptRA.UseICMP6RateLimit, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_icmp6_ratelimit)
IPv6AcceptRA.DHCPv6Client, config_parse_ipv6_accept_ra_start_dhcp6_client, 0, offsetof(Network, ipv6_accept_ra_start_dhcp6_client)

View file

@ -483,6 +483,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
.ipv6_accept_ra_use_onlink_prefix = true,
.ipv6_accept_ra_use_mtu = true,
.ipv6_accept_ra_use_hop_limit = true,
.ipv6_accept_ra_use_reachable_time = true,
.ipv6_accept_ra_use_retransmission_time = true,
.ipv6_accept_ra_use_icmp6_ratelimit = true,
.ipv6_accept_ra_route_table = RT_TABLE_MAIN,

View file

@ -342,6 +342,7 @@ struct Network {
bool ipv6_accept_ra_use_onlink_prefix;
bool ipv6_accept_ra_use_mtu;
bool ipv6_accept_ra_use_hop_limit;
bool ipv6_accept_ra_use_reachable_time;
bool ipv6_accept_ra_use_retransmission_time;
bool ipv6_accept_ra_use_icmp6_ratelimit;
bool ipv6_accept_ra_quickack;