]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network/ndisc: set IPv6 neighbor reachable time 31405/head
authorYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 20 Feb 2024 06:24:09 +0000 (15:24 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 20 Feb 2024 06:31:39 +0000 (15:31 +0900)
Closes #31402.

man/systemd.network.xml
src/network/networkd-ndisc.c
src/network/networkd-network-gperf.gperf
src/network/networkd-network.c
src/network/networkd-network.h

index b739e709f53dcc507778649ec5219099e97ec179..32de0ce8446dadbedb17c911aed3f2dd46eb5bf5 100644 (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>
index 99271aa3fdcc96e3f567a547fbfa9ac3dcdd1c6a..d110482c0031b612dcb9d7be42bcef8810c684b2 100644 (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;
index ce3745093808c0d24ca69faaa1e42aacf9097da4..a196da7f0f91ea7e8918e043e434a303eb8593a1 100644 (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)
index 300fba5dd9968be7987864fd4478befe11b0376e..4101296275de0b8967eea52f29979f233f9be690 100644 (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,
index 3ab115c3b9b52abdeb77c1562afc18f497186222..270ffd87a3a4e087e27a2fbdd18bcccf5739e066 100644 (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;