From: Yu Watanabe Date: Tue, 20 Feb 2024 06:24:09 +0000 (+0900) Subject: network/ndisc: set IPv6 neighbor reachable time X-Git-Tag: v256-rc1~794^2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F31405%2Fhead;p=thirdparty%2Fsystemd.git network/ndisc: set IPv6 neighbor reachable time Closes #31402. --- diff --git a/man/systemd.network.xml b/man/systemd.network.xml index b739e709f53..32de0ce8446 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -3347,6 +3347,17 @@ Token=prefixstable:2002:da8:1:: + + UseReachableTime= + + 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. + + + + + UseRetransmissionTime= diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c index 99271aa3fdc..d110482c003 100644 --- a/src/network/networkd-ndisc.c +++ b/src/network/networkd-ndisc.c @@ -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; diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index ce374509380..a196da7f0f9 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -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) diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 300fba5dd99..4101296275d 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -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, diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index 3ab115c3b9b..270ffd87a3a 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -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;