Merge pull request #32347 from yuwata/sd-radv-reachable-time

sd-radv: allow to configure reachable time
This commit is contained in:
Luca Boccassi 2024-04-22 14:04:25 +02:00 committed by GitHub
commit f64222b748
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 56 additions and 13 deletions

View file

@ -4017,14 +4017,29 @@ ServerAddress=192.168.0.1/24</programlisting>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>ReachableTimeSec=</varname></term>
<listitem>
<para>Configures the time, used in the Neighbor Unreachability Detection algorithm, for which
clients can assume a neighbor is reachable after having received a reachability confirmation. Takes
a time span in the range 0…4294967295 ms. When 0, clients will handle it as if the value wasn't
specified. Defaults to 0.</para>
<xi:include href="version-info.xml" xpointer="v256"/>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>RetransmitSec=</varname></term>
<listitem><para>Takes a timespan. Configures the retransmit time, used by clients to retransmit Neighbor
Solicitation messages on address resolution and the Neighbor Unreachability Detection algorithm.
An integer, the default unit is seconds, in the range 0…4294967295 msec. Defaults to 0.</para>
<listitem>
<para>Configures the time, used in the Neighbor Unreachability Detection algorithm, for which
clients can use as retransmit time on address resolution and the Neighbor Unreachability Detection
algorithm. Takes a time span in the range 0…4294967295 ms. When 0, clients will handle it as if
the value wasn't specified. Defaults to 0.</para>
<xi:include href="version-info.xml" xpointer="v255"/>
<xi:include href="version-info.xml" xpointer="v255"/>
</listitem>
</varlistentry>

View file

@ -43,9 +43,11 @@
#define RADV_MAX_ROUTER_LIFETIME_USEC (9000 * USEC_PER_SEC)
#define RADV_DEFAULT_ROUTER_LIFETIME_USEC (3 * RADV_DEFAULT_MAX_TIMEOUT_USEC)
/* RFC 4861 section 4.2.
* Retrans Timer
* Reachable Time and Retrans Timer
* 32-bit unsigned integer. The time, in milliseconds. */
#define RADV_MAX_RETRANSMIT_USEC (UINT32_MAX * USEC_PER_MSEC)
#define RADV_MAX_UINT32_MSEC_USEC (UINT32_MAX * USEC_PER_MSEC)
#define RADV_MAX_REACHABLE_TIME_USEC RADV_MAX_UINT32_MSEC_USEC
#define RADV_MAX_RETRANSMIT_USEC RADV_MAX_UINT32_MSEC_USEC
/* draft-ietf-6man-slaac-renum-02 section 4.1.1.
* AdvPreferredLifetime: max(AdvDefaultLifetime, 3 * MaxRtrAdvInterval)
* AdvValidLifetime: 2 * AdvPreferredLifetime */
@ -107,6 +109,7 @@ struct sd_radv {
uint8_t flags;
uint8_t preference;
uint32_t mtu;
usec_t reachable_usec;
usec_t retransmit_usec;
usec_t lifetime_usec; /* timespan */

View file

@ -163,6 +163,7 @@ static int radv_send_router(sd_radv *ra, const struct in6_addr *dst) {
struct nd_router_advert adv = {
.nd_ra_type = ND_ROUTER_ADVERT,
.nd_ra_router_lifetime = usec_to_be16_sec(ra->lifetime_usec),
.nd_ra_reachable = usec_to_be32_msec(ra->reachable_usec),
.nd_ra_retransmit = usec_to_be32_msec(ra->retransmit_usec),
};
struct {
@ -538,6 +539,13 @@ int sd_radv_set_hop_limit(sd_radv *ra, uint8_t hop_limit) {
return 0;
}
int sd_radv_set_reachable_time(sd_radv *ra, uint64_t usec) {
assert_return(ra, -EINVAL);
ra->reachable_usec = usec;
return 0;
}
int sd_radv_set_retransmit(sd_radv *ra, uint64_t usec) {
assert_return(ra, -EINVAL);

View file

@ -199,6 +199,11 @@ TEST(radv) {
assert_se(sd_radv_set_other_information(ra, true) >= 0);
assert_se(sd_radv_set_other_information(ra, false) >= 0);
ASSERT_RETURN_EXPECTED_SE(sd_radv_set_reachable_time(NULL, 10 * USEC_PER_MSEC) < 0);
assert_se(sd_radv_set_reachable_time(ra, 10 * USEC_PER_MSEC) >= 0);
assert_se(sd_radv_set_reachable_time(ra, 0) >= 0);
assert_se(sd_radv_set_reachable_time(ra, USEC_INFINITY) >= 0);
ASSERT_RETURN_EXPECTED_SE(sd_radv_set_retransmit(NULL, 10 * USEC_PER_MSEC) < 0);
assert_se(sd_radv_set_retransmit(ra, 10 * USEC_PER_MSEC) >= 0);
assert_se(sd_radv_set_retransmit(ra, 0) >= 0);

View file

@ -393,7 +393,8 @@ DHCPPrefixDelegation.RouteMetric, config_parse_uint32,
DHCPPrefixDelegation.NetLabel, config_parse_string, CONFIG_PARSE_STRING_SAFE, offsetof(Network, dhcp_pd_netlabel)
DHCPPrefixDelegation.NFTSet, config_parse_nft_set, NFT_SET_PARSE_NETWORK, offsetof(Network, dhcp_pd_nft_set_context)
IPv6SendRA.RouterLifetimeSec, config_parse_router_lifetime, 0, offsetof(Network, router_lifetime_usec)
IPv6SendRA.RetransmitSec, config_parse_router_retransmit, 0, offsetof(Network, router_retransmit_usec)
IPv6SendRA.ReachableTimeSec, config_parse_router_uint32_msec_usec, 0, offsetof(Network, router_reachable_usec)
IPv6SendRA.RetransmitSec, config_parse_router_uint32_msec_usec, 0, offsetof(Network, router_retransmit_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

View file

@ -246,6 +246,7 @@ struct Network {
RADVPrefixDelegation router_prefix_delegation;
usec_t router_lifetime_usec;
uint8_t router_preference;
usec_t router_reachable_usec;
usec_t router_retransmit_usec;
uint8_t router_hop_limit;
bool router_managed;

View file

@ -577,6 +577,10 @@ static int radv_configure(Link *link) {
return r;
}
r = sd_radv_set_reachable_time(link->radv, link->network->router_reachable_usec);
if (r < 0)
return r;
if (link->network->router_retransmit_usec > 0) {
r = sd_radv_set_retransmit(link->radv, link->network->router_retransmit_usec);
if (r < 0)
@ -1496,7 +1500,7 @@ int config_parse_router_lifetime(
return 0;
}
int config_parse_router_retransmit(
int config_parse_router_uint32_msec_usec(
const char *unit,
const char *filename,
unsigned line,
@ -1508,7 +1512,7 @@ int config_parse_router_retransmit(
void *data,
void *userdata) {
usec_t usec, *router_retransmit_usec = ASSERT_PTR(data);
usec_t usec, *router_usec = ASSERT_PTR(data);
int r;
assert(filename);
@ -1517,7 +1521,7 @@ int config_parse_router_retransmit(
assert(rvalue);
if (isempty(rvalue)) {
*router_retransmit_usec = 0;
*router_usec = 0;
return 0;
}
@ -1529,13 +1533,13 @@ int config_parse_router_retransmit(
}
if (usec != USEC_INFINITY &&
usec > RADV_MAX_RETRANSMIT_USEC) {
usec > RADV_MAX_UINT32_MSEC_USEC) {
log_syntax(unit, LOG_WARNING, filename, line, 0,
"Invalid [%s] %s=, ignoring assignment: %s", section, lvalue, rvalue);
return 0;
}
*router_retransmit_usec = usec;
*router_usec = usec;
return 0;
}

View file

@ -86,7 +86,7 @@ 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_retransmit);
CONFIG_PARSER_PROTOTYPE(config_parse_router_uint32_msec_usec);
CONFIG_PARSER_PROTOTYPE(config_parse_router_preference);
CONFIG_PARSER_PROTOTYPE(config_parse_prefix);
CONFIG_PARSER_PROTOTYPE(config_parse_prefix_boolean);

View file

@ -57,6 +57,7 @@ int sd_radv_set_link_local_address(sd_radv *ra, const struct in6_addr *addr);
int sd_radv_set_mac(sd_radv *ra, const struct ether_addr *mac_addr);
int sd_radv_set_mtu(sd_radv *ra, uint32_t mtu);
int sd_radv_set_hop_limit(sd_radv *ra, uint8_t hop_limit);
int sd_radv_set_reachable_time(sd_radv *ra, uint64_t usec);
int sd_radv_set_retransmit(sd_radv *ra, uint64_t usec);
int sd_radv_set_router_lifetime(sd_radv *ra, uint64_t usec);
int sd_radv_set_managed_information(sd_radv *ra, int b);

View file

@ -10,6 +10,8 @@ IPv6SendRA=yes
DNS=_link_local 2002:da8:1:0::1
DNSLifetimeSec=1min
Domains=hogehoge.test
ReachableTimeSec=42
RetransmitSec=500ms
[IPv6Prefix]
Prefix=2002:da8:1:0::/64

View file

@ -5514,6 +5514,9 @@ class NetworkdRATests(unittest.TestCase, Utilities):
print(output)
self.assertRegex(output, '2002:da8:1:0')
self.check_ipv6_neigh_sysctl_attr('veth99', 'base_reachable_time_ms', '42000')
self.check_ipv6_neigh_sysctl_attr('veth99', 'retrans_time_ms', '500')
self.check_netlabel('veth99', '2002:da8:1::/64')
self.check_netlabel('veth99', '2002:da8:2::/64')