network/radv: allow to configure the time between retransmitted Neighbor Solicitation (#28888)

This commit is contained in:
Susant Sahani 2023-08-23 09:07:44 +05:30 committed by GitHub
parent 14c5c43985
commit fdc4c67c2a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 75 additions and 0 deletions

View file

@ -3076,6 +3076,15 @@ Token=prefixstable:2002:da8:1::</programlisting></para>
</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 of seconds, in the range 0…4294967295 msec. Defaults to 0.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>RouterPreference=</varname></term>

View file

@ -87,6 +87,7 @@ struct sd_radv {
uint8_t hop_limit;
uint8_t flags;
uint32_t mtu;
uint32_t retransmit_msec;
usec_t lifetime_usec; /* timespan */
int fd;

View file

@ -179,6 +179,7 @@ static int radv_send(sd_radv *ra, const struct in6_addr *dst, usec_t lifetime_us
adv.nd_ra_type = ND_ROUTER_ADVERT;
adv.nd_ra_curhoplimit = ra->hop_limit;
adv.nd_ra_retransmit = htobe32(ra->retransmit_msec);
adv.nd_ra_flags_reserved = ra->flags;
assert_cc(RADV_MAX_ROUTER_LIFETIME_USEC <= UINT16_MAX * USEC_PER_SEC);
adv.nd_ra_router_lifetime = htobe16(DIV_ROUND_UP(lifetime_usec, USEC_PER_SEC));
@ -494,6 +495,17 @@ int sd_radv_set_hop_limit(sd_radv *ra, uint8_t hop_limit) {
return 0;
}
int sd_radv_set_retransmit(sd_radv *ra, uint32_t retransmit_msec) {
assert_return(ra, -EINVAL);
if (ra->state != RADV_STATE_IDLE)
return -EBUSY;
ra->retransmit_msec = retransmit_msec;
return 0;
}
int sd_radv_set_router_lifetime(sd_radv *ra, uint64_t lifetime_usec) {
assert_return(ra, -EINVAL);

View file

@ -368,6 +368,7 @@ DHCPPrefixDelegation.Token, config_parse_address_generation_typ
DHCPPrefixDelegation.RouteMetric, config_parse_uint32, 0, offsetof(Network, dhcp_pd_route_metric)
DHCPPrefixDelegation.NetLabel, config_parse_string, CONFIG_PARSE_STRING_SAFE, offsetof(Network, dhcp_pd_netlabel)
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.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

@ -227,6 +227,7 @@ struct Network {
RADVPrefixDelegation router_prefix_delegation;
usec_t router_lifetime_usec;
uint8_t router_preference;
usec_t router_retransmit_usec;
bool router_managed;
bool router_other_information;
bool router_emit_dns;

View file

@ -486,6 +486,12 @@ static int radv_configure(Link *link) {
return r;
}
if (link->network->router_retransmit_usec > 0) {
r = sd_radv_set_retransmit(link->radv, DIV_ROUND_UP(link->network->router_retransmit_usec, USEC_PER_MSEC));
if (r < 0)
return r;
}
HASHMAP_FOREACH(p, link->network->prefixes_by_section) {
r = radv_set_prefix(link, p);
if (r < 0 && r != -EEXIST)
@ -1305,6 +1311,49 @@ int config_parse_router_lifetime(
return 0;
}
int config_parse_router_retransmit(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
usec_t usec, *router_retransmit_usec = ASSERT_PTR(data);
int r;
assert(filename);
assert(section);
assert(lvalue);
assert(rvalue);
if (isempty(rvalue)) {
*router_retransmit_usec = 0;
return 0;
}
r = parse_sec(rvalue, &usec);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse %s=, ignoring assignment: %s", lvalue, rvalue);
return 0;
}
if (usec != USEC_INFINITY &&
DIV_ROUND_UP(usec, USEC_PER_MSEC) > UINT32_MAX) {
log_syntax(unit, LOG_WARNING, filename, line, 0,
"Invalid %s= must be in the range 0...%"PRIu32"Sec, ignoring: %s", lvalue, UINT32_MAX, rvalue);
return 0;
}
*router_retransmit_usec = usec;
return 0;
}
int config_parse_router_preference(
const char *unit,
const char *filename,

View file

@ -74,6 +74,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_preference);
CONFIG_PARSER_PROTOTYPE(config_parse_prefix);
CONFIG_PARSER_PROTOTYPE(config_parse_prefix_boolean);

View file

@ -53,6 +53,7 @@ int sd_radv_get_ifname(sd_radv *ra, const char **ret);
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_retransmit(sd_radv *ra, uint32_t retransmit_msec);
int sd_radv_set_router_lifetime(sd_radv *ra, uint64_t lifetime_usec);
int sd_radv_set_managed_information(sd_radv *ra, int managed);
int sd_radv_set_other_information(sd_radv *ra, int other);