Merge pull request #20853 from yuwata/network-radv-set-default-timeouts

network: RADV: set default timeouts
This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2021-10-12 10:49:03 +02:00
committed by GitHub
7 changed files with 256 additions and 207 deletions

View File

@@ -2676,9 +2676,9 @@ Token=prefixstable:2002:da8:1::</programlisting></para>
<varlistentry>
<term><varname>DNSLifetimeSec=</varname></term>
<listitem><para>Lifetime in seconds for the DNS server addresses listed
in <varname>DNS=</varname> and search domains listed in
<varname>Domains=</varname>.</para></listitem>
<listitem><para>Lifetime in seconds for the DNS server addresses listed in
<varname>DNS=</varname> and search domains listed in <varname>Domains=</varname>. Defaults to
604800 seconds (one week).</para></listitem>
</varlistentry>
</variablelist>

View File

@@ -936,7 +936,7 @@ _public_ int sd_radv_route_prefix_new(sd_radv_route_prefix **ret) {
DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(sd_radv_route_prefix, sd_radv_route_prefix, mfree);
_public_ int sd_radv_prefix_set_route_prefix(sd_radv_route_prefix *p, const struct in6_addr *in6_addr,
_public_ int sd_radv_route_prefix_set_prefix(sd_radv_route_prefix *p, const struct in6_addr *in6_addr,
unsigned char prefixlen) {
assert_return(p, -EINVAL);
assert_return(in6_addr, -EINVAL);

View File

@@ -342,11 +342,11 @@ IPv6SendRA.Domains, config_parse_radv_search_domains,
IPv6SendRA.DNSLifetimeSec, config_parse_sec, 0, offsetof(Network, router_dns_lifetime_usec)
IPv6SendRA.UplinkInterface, config_parse_uplink, 0, 0
IPv6Prefix.Prefix, config_parse_prefix, 0, 0
IPv6Prefix.OnLink, config_parse_prefix_flags, 0, 0
IPv6Prefix.AddressAutoconfiguration, config_parse_prefix_flags, 0, 0
IPv6Prefix.OnLink, config_parse_prefix_boolean, 0, 0
IPv6Prefix.AddressAutoconfiguration, config_parse_prefix_boolean, 0, 0
IPv6Prefix.ValidLifetimeSec, config_parse_prefix_lifetime, 0, 0
IPv6Prefix.PreferredLifetimeSec, config_parse_prefix_lifetime, 0, 0
IPv6Prefix.Assign, config_parse_prefix_assign, 0, 0
IPv6Prefix.Assign, config_parse_prefix_boolean, 0, 0
IPv6Prefix.RouteMetric, config_parse_prefix_metric, 0, 0
IPv6Prefix.Token, config_parse_prefix_token, 0, 0
IPv6RoutePrefix.Route, config_parse_route_prefix, 0, 0

View File

@@ -420,6 +420,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
.dhcp_server_emit_timezone = true,
.router_lifetime_usec = 30 * USEC_PER_MINUTE,
.router_dns_lifetime_usec = 7 * USEC_PER_DAY,
.router_emit_dns = true,
.router_emit_domains = true,

View File

@@ -68,7 +68,6 @@ Prefix *prefix_free(Prefix *prefix) {
}
network_config_section_free(prefix->section);
sd_radv_prefix_unref(prefix->radv_prefix);
set_free(prefix->tokens);
return mfree(prefix);
@@ -76,21 +75,6 @@ Prefix *prefix_free(Prefix *prefix) {
DEFINE_NETWORK_SECTION_FUNCTIONS(Prefix, prefix_free);
static int prefix_new(Prefix **ret) {
_cleanup_(prefix_freep) Prefix *prefix = NULL;
prefix = new0(Prefix, 1);
if (!prefix)
return -ENOMEM;
if (sd_radv_prefix_new(&prefix->radv_prefix) < 0)
return -ENOMEM;
*ret = TAKE_PTR(prefix);
return 0;
}
static int prefix_new_static(Network *network, const char *filename, unsigned section_line, Prefix **ret) {
_cleanup_(network_config_section_freep) NetworkConfigSection *n = NULL;
_cleanup_(prefix_freep) Prefix *prefix = NULL;
@@ -111,19 +95,25 @@ static int prefix_new_static(Network *network, const char *filename, unsigned se
return 0;
}
r = prefix_new(&prefix);
if (r < 0)
return r;
prefix = new(Prefix, 1);
if (!prefix)
return -ENOMEM;
prefix->network = network;
prefix->section = TAKE_PTR(n);
*prefix = (Prefix) {
.network = network,
.section = TAKE_PTR(n),
.preferred_lifetime = 7 * USEC_PER_DAY,
.valid_lifetime = 30 * USEC_PER_DAY,
.onlink = true,
.address_auto_configuration = true,
};
r = hashmap_ensure_put(&network->prefixes_by_section, &network_config_hash_ops, prefix->section, prefix);
if (r < 0)
return r;
*ret = TAKE_PTR(prefix);
return 0;
}
@@ -137,28 +127,12 @@ RoutePrefix *route_prefix_free(RoutePrefix *prefix) {
}
network_config_section_free(prefix->section);
sd_radv_route_prefix_unref(prefix->radv_route_prefix);
return mfree(prefix);
}
DEFINE_NETWORK_SECTION_FUNCTIONS(RoutePrefix, route_prefix_free);
static int route_prefix_new(RoutePrefix **ret) {
_cleanup_(route_prefix_freep) RoutePrefix *prefix = NULL;
prefix = new0(RoutePrefix, 1);
if (!prefix)
return -ENOMEM;
if (sd_radv_route_prefix_new(&prefix->radv_route_prefix) < 0)
return -ENOMEM;
*ret = TAKE_PTR(prefix);
return 0;
}
static int route_prefix_new_static(Network *network, const char *filename, unsigned section_line, RoutePrefix **ret) {
_cleanup_(network_config_section_freep) NetworkConfigSection *n = NULL;
_cleanup_(route_prefix_freep) RoutePrefix *prefix = NULL;
@@ -179,19 +153,22 @@ static int route_prefix_new_static(Network *network, const char *filename, unsig
return 0;
}
r = route_prefix_new(&prefix);
if (r < 0)
return r;
prefix = new(RoutePrefix, 1);
if (!prefix)
return -ENOMEM;
prefix->network = network;
prefix->section = TAKE_PTR(n);
*prefix = (RoutePrefix) {
.network = network,
.section = TAKE_PTR(n),
.lifetime = 7 * USEC_PER_DAY,
};
r = hashmap_ensure_put(&network->route_prefixes_by_section, &network_config_hash_ops, prefix->section, prefix);
if (r < 0)
return r;
*ret = TAKE_PTR(prefix);
return 0;
}
@@ -206,28 +183,16 @@ int link_request_radv_addresses(Link *link) {
HASHMAP_FOREACH(p, link->network->prefixes_by_section) {
_cleanup_set_free_ Set *addresses = NULL;
struct in6_addr prefix, *a;
uint8_t prefixlen;
struct in6_addr *a;
if (!p->assign)
continue;
r = sd_radv_prefix_get_prefix(p->radv_prefix, &prefix, &prefixlen);
if (r < 0)
return r;
/* radv_generate_addresses() below requires the prefix length <= 64. */
if (prefixlen > 64) {
_cleanup_free_ char *str = NULL;
(void) in6_addr_prefix_to_string(&prefix, prefixlen, &str);
log_link_debug(link,
"Prefix is longer than 64, refusing to assign an address in %s.",
strna(str));
if (p->prefixlen > 64)
continue;
}
r = radv_generate_addresses(link, p->tokens, &prefix, prefixlen, &addresses);
r = radv_generate_addresses(link, p->tokens, &p->prefix, p->prefixlen, &addresses);
if (r < 0)
return r;
@@ -241,7 +206,7 @@ int link_request_radv_addresses(Link *link) {
address->source = NETWORK_CONFIG_SOURCE_STATIC;
address->family = AF_INET6;
address->in_addr.in6 = *a;
address->prefixlen = prefixlen;
address->prefixlen = p->prefixlen;
address->route_metric = p->route_metric;
r = link_request_static_address(link, TAKE_PTR(address), true);
@@ -253,6 +218,77 @@ int link_request_radv_addresses(Link *link) {
return 0;
}
static uint32_t usec_to_lifetime(usec_t usec) {
uint64_t t;
if (usec == USEC_INFINITY)
return UINT32_MAX;
t = DIV_ROUND_UP(usec, USEC_PER_SEC);
if (t >= UINT32_MAX)
return UINT32_MAX;
return (uint32_t) t;
}
static int radv_set_prefix(Link *link, Prefix *prefix) {
_cleanup_(sd_radv_prefix_unrefp) sd_radv_prefix *p = NULL;
int r;
assert(link);
assert(link->radv);
assert(prefix);
r = sd_radv_prefix_new(&p);
if (r < 0)
return r;
r = sd_radv_prefix_set_prefix(p, &prefix->prefix, prefix->prefixlen);
if (r < 0)
return r;
r = sd_radv_prefix_set_preferred_lifetime(p, usec_to_lifetime(prefix->preferred_lifetime));
if (r < 0)
return r;
r = sd_radv_prefix_set_valid_lifetime(p, usec_to_lifetime(prefix->valid_lifetime));
if (r < 0)
return r;
r = sd_radv_prefix_set_onlink(p, prefix->onlink);
if (r < 0)
return r;
r = sd_radv_prefix_set_address_autoconfiguration(p, prefix->address_auto_configuration);
if (r < 0)
return r;
return sd_radv_add_prefix(link->radv, p, false);
}
static int radv_set_route_prefix(Link *link, RoutePrefix *prefix) {
_cleanup_(sd_radv_route_prefix_unrefp) sd_radv_route_prefix *p = NULL;
int r;
assert(link);
assert(link->radv);
assert(prefix);
r = sd_radv_route_prefix_new(&p);
if (r < 0)
return r;
r = sd_radv_route_prefix_set_prefix(p, &prefix->prefix, prefix->prefixlen);
if (r < 0)
return r;
r = sd_radv_route_prefix_set_lifetime(p, usec_to_lifetime(prefix->lifetime));
if (r < 0)
return r;
return sd_radv_add_route_prefix(link->radv, p, false);
}
static int network_get_ipv6_dns(Network *network, struct in6_addr **ret_addresses, size_t *ret_size) {
_cleanup_free_ struct in6_addr *addresses = NULL;
size_t n_addresses = 0;
@@ -288,7 +324,6 @@ static int network_get_ipv6_dns(Network *network, struct in6_addr **ret_addresse
static int radv_set_dns(Link *link, Link *uplink) {
_cleanup_free_ struct in6_addr *dns = NULL;
usec_t lifetime_usec;
size_t n_dns;
int r;
@@ -311,13 +346,10 @@ static int radv_set_dns(Link *link, Link *uplink) {
*(p++) = link->network->router_dns[i];
n_dns = p - dns;
lifetime_usec = link->network->router_dns_lifetime_usec;
goto set_dns;
}
lifetime_usec = SD_RADV_DEFAULT_DNS_LIFETIME_USEC;
r = network_get_ipv6_dns(link->network, &dns, &n_dns);
if (r > 0)
goto set_dns;
@@ -334,26 +366,22 @@ static int radv_set_dns(Link *link, Link *uplink) {
set_dns:
return sd_radv_set_rdnss(link->radv,
DIV_ROUND_UP(lifetime_usec, USEC_PER_SEC),
usec_to_lifetime(link->network->router_dns_lifetime_usec),
dns, n_dns);
}
static int radv_set_domains(Link *link, Link *uplink) {
OrderedSet *search_domains;
usec_t lifetime_usec;
_cleanup_free_ char **s = NULL; /* just free() because the strings are owned by the set */
OrderedSet *search_domains;
if (!link->network->router_emit_domains)
return 0;
search_domains = link->network->router_search_domains;
lifetime_usec = link->network->router_dns_lifetime_usec;
if (search_domains)
goto set_domains;
lifetime_usec = SD_RADV_DEFAULT_DNS_LIFETIME_USEC;
search_domains = link->network->search_domains;
if (search_domains)
goto set_domains;
@@ -374,7 +402,7 @@ set_domains:
return log_oom();
return sd_radv_set_dnssl(link->radv,
DIV_ROUND_UP(lifetime_usec, USEC_PER_SEC),
usec_to_lifetime(link->network->router_dns_lifetime_usec),
s);
}
@@ -455,22 +483,14 @@ static int radv_configure(Link *link) {
}
HASHMAP_FOREACH(p, link->network->prefixes_by_section) {
r = sd_radv_add_prefix(link->radv, p->radv_prefix, false);
if (r == -EEXIST)
continue;
if (r == -ENOEXEC) {
log_link_warning_errno(link, r, "[IPv6Prefix] section configured without Prefix= setting, ignoring section.");
continue;
}
if (r < 0)
r = radv_set_prefix(link, p);
if (r < 0 && r != -EEXIST)
return r;
}
HASHMAP_FOREACH(q, link->network->route_prefixes_by_section) {
r = sd_radv_add_route_prefix(link->radv, q->radv_route_prefix, false);
if (r == -EEXIST)
continue;
if (r < 0)
r = radv_set_route_prefix(link, q);
if (r < 0 && r != -EEXIST)
return r;
}
@@ -643,24 +663,94 @@ int radv_add_prefix(
return 0;
}
static int prefix_section_verify(Prefix *p) {
assert(p);
if (section_is_invalid(p->section))
return -EINVAL;
if (in6_addr_is_null(&p->prefix))
return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
"%s: [IPv6Prefix] section without Prefix= field configured, "
"or specified prefix is the null address. "
"Ignoring [IPv6Prefix] section from line %u.",
p->section->filename, p->section->line);
if (p->prefixlen < 3 || p->prefixlen > 128)
return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
"%s: Invalid prefix length %u is specified in [IPv6Prefix] section. "
"Valid range is 3…128. Ignoring [IPv6Prefix] section from line %u.",
p->section->filename, p->prefixlen, p->section->line);
if (p->prefixlen > 64) {
_cleanup_free_ char *str = NULL;
if (p->assign)
(void) in6_addr_prefix_to_string(&p->prefix, p->prefixlen, &str);
log_info("%s: Unusual prefix length %u (> 64) is specified in [IPv6Prefix] section from line %u%s%s.",
p->section->filename, p->prefixlen, p->section->line,
p->assign ? ", refusing to assign an address in " : "",
p->assign ? strna(str) : "");
p->assign = false;
}
if (p->valid_lifetime == 0)
return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
"%s: The valid lifetime of prefix cannot be zero. "
"Ignoring [IPv6Prefix] section from line %u.",
p->section->filename, p->section->line);
if (p->preferred_lifetime > p->valid_lifetime)
return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
"%s: The preferred lifetime %s is longer than the valid lifetime %s. "
"Ignoring [IPv6Prefix] section from line %u.",
p->section->filename,
FORMAT_TIMESPAN(p->preferred_lifetime, USEC_PER_SEC),
FORMAT_TIMESPAN(p->valid_lifetime, USEC_PER_SEC),
p->section->line);
return 0;
}
void network_drop_invalid_prefixes(Network *network) {
Prefix *prefix;
Prefix *p;
assert(network);
HASHMAP_FOREACH(prefix, network->prefixes_by_section)
if (section_is_invalid(prefix->section))
prefix_free(prefix);
HASHMAP_FOREACH(p, network->prefixes_by_section)
if (prefix_section_verify(p) < 0)
prefix_free(p);
}
static int route_prefix_section_verify(RoutePrefix *p) {
if (section_is_invalid(p->section))
return -EINVAL;
if (p->prefixlen > 128)
return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
"%s: Invalid prefix length %u is specified in [IPv6RoutePrefix] section. "
"Valid range is 0…128. Ignoring [IPv6RoutePrefix] section from line %u.",
p->section->filename, p->prefixlen, p->section->line);
if (p->lifetime == 0)
return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
"%s: The lifetime of route cannot be zero. "
"Ignoring [IPv6RoutePrefix] section from line %u.",
p->section->filename, p->section->line);
return 0;
}
void network_drop_invalid_route_prefixes(Network *network) {
RoutePrefix *prefix;
RoutePrefix *p;
assert(network);
HASHMAP_FOREACH(prefix, network->route_prefixes_by_section)
if (section_is_invalid(prefix->section))
route_prefix_free(prefix);
HASHMAP_FOREACH(p, network->route_prefixes_by_section)
if (route_prefix_section_verify(p) < 0)
route_prefix_free(p);
}
int config_parse_prefix(
@@ -675,40 +765,36 @@ int config_parse_prefix(
void *data,
void *userdata) {
Network *network = userdata;
_cleanup_(prefix_free_or_set_invalidp) Prefix *p = NULL;
uint8_t prefixlen = 64;
union in_addr_union in6addr;
Network *network = userdata;
union in_addr_union a;
int r;
assert(filename);
assert(section);
assert(lvalue);
assert(rvalue);
assert(data);
assert(userdata);
r = prefix_new_static(network, filename, section_line, &p);
if (r < 0)
return log_oom();
r = in_addr_prefix_from_string(rvalue, AF_INET6, &in6addr, &prefixlen);
r = in_addr_prefix_from_string(rvalue, AF_INET6, &a, &p->prefixlen);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r, "Prefix is invalid, ignoring assignment: %s", rvalue);
log_syntax(unit, LOG_WARNING, filename, line, r,
"Prefix is invalid, ignoring assignment: %s", rvalue);
return 0;
}
r = sd_radv_prefix_set_prefix(p->radv_prefix, &in6addr.in6, prefixlen);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to set radv prefix, ignoring assignment: %s", rvalue);
return 0;
}
p = NULL;
(void) in6_addr_mask(&a.in6, p->prefixlen);
p->prefix = a.in6;
TAKE_PTR(p);
return 0;
}
int config_parse_prefix_flags(
int config_parse_prefix_boolean(
const char *unit,
const char *filename,
unsigned line,
@@ -720,15 +806,15 @@ int config_parse_prefix_flags(
void *data,
void *userdata) {
Network *network = userdata;
_cleanup_(prefix_free_or_set_invalidp) Prefix *p = NULL;
Network *network = userdata;
int r;
assert(filename);
assert(section);
assert(lvalue);
assert(rvalue);
assert(data);
assert(userdata);
r = prefix_new_static(network, filename, section_line, &p);
if (r < 0)
@@ -736,21 +822,21 @@ int config_parse_prefix_flags(
r = parse_boolean(rvalue);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse %s=, ignoring assignment: %s", lvalue, rvalue);
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse %s=, ignoring assignment: %s", lvalue, rvalue);
return 0;
}
if (streq(lvalue, "OnLink"))
r = sd_radv_prefix_set_onlink(p->radv_prefix, r);
p->onlink = r;
else if (streq(lvalue, "AddressAutoconfiguration"))
r = sd_radv_prefix_set_address_autoconfiguration(p->radv_prefix, r);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to set %s=, ignoring assignment: %m", lvalue);
return 0;
}
p = NULL;
p->address_auto_configuration = r;
else if (streq(lvalue, "Assign"))
p->assign = r;
else
assert_not_reached();
TAKE_PTR(p);
return 0;
}
@@ -766,8 +852,8 @@ int config_parse_prefix_lifetime(
void *data,
void *userdata) {
Network *network = userdata;
_cleanup_(prefix_free_or_set_invalidp) Prefix *p = NULL;
Network *network = userdata;
usec_t usec;
int r;
@@ -775,72 +861,33 @@ int config_parse_prefix_lifetime(
assert(section);
assert(lvalue);
assert(rvalue);
assert(data);
assert(userdata);
r = prefix_new_static(network, filename, section_line, &p);
if (r < 0)
return log_oom();
r = parse_sec(rvalue, &usec);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r, "Lifetime is invalid, ignoring assignment: %s", rvalue);
return 0;
}
/* a value of 0xffffffff represents infinity */
if (streq(lvalue, "PreferredLifetimeSec"))
r = sd_radv_prefix_set_preferred_lifetime(p->radv_prefix,
DIV_ROUND_UP(usec, USEC_PER_SEC));
else if (streq(lvalue, "ValidLifetimeSec"))
r = sd_radv_prefix_set_valid_lifetime(p->radv_prefix,
DIV_ROUND_UP(usec, USEC_PER_SEC));
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to set %s=, ignoring assignment: %m", lvalue);
return 0;
}
p = NULL;
return 0;
}
int config_parse_prefix_assign(
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) {
Network *network = userdata;
_cleanup_(prefix_free_or_set_invalidp) Prefix *p = NULL;
int r;
assert(filename);
assert(section);
assert(lvalue);
assert(rvalue);
assert(data);
r = prefix_new_static(network, filename, section_line, &p);
if (r < 0)
return log_oom();
r = parse_boolean(rvalue);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse %s=, ignoring assignment: %s",
lvalue, rvalue);
"Lifetime is invalid, ignoring assignment: %s", rvalue);
return 0;
}
p->assign = r;
p = NULL;
if (usec != USEC_INFINITY && DIV_ROUND_UP(usec, USEC_PER_SEC) >= UINT32_MAX) {
log_syntax(unit, LOG_WARNING, filename, line, 0,
"Lifetime is too long, ignoring assignment: %s", rvalue);
return 0;
}
if (streq(lvalue, "PreferredLifetimeSec"))
p->preferred_lifetime = usec;
else if (streq(lvalue, "ValidLifetimeSec"))
p->valid_lifetime = usec;
else
assert_not_reached();
TAKE_PTR(p);
return 0;
}
@@ -856,15 +903,15 @@ int config_parse_prefix_metric(
void *data,
void *userdata) {
Network *network = userdata;
_cleanup_(prefix_free_or_set_invalidp) Prefix *p = NULL;
Network *network = userdata;
int r;
assert(filename);
assert(section);
assert(lvalue);
assert(rvalue);
assert(data);
assert(userdata);
r = prefix_new_static(network, filename, section_line, &p);
if (r < 0)
@@ -879,7 +926,6 @@ int config_parse_prefix_metric(
}
TAKE_PTR(p);
return 0;
}
@@ -930,36 +976,32 @@ int config_parse_route_prefix(
void *data,
void *userdata) {
Network *network = userdata;
_cleanup_(route_prefix_free_or_set_invalidp) RoutePrefix *p = NULL;
uint8_t prefixlen = 64;
union in_addr_union in6addr;
Network *network = userdata;
union in_addr_union a;
int r;
assert(filename);
assert(section);
assert(lvalue);
assert(rvalue);
assert(data);
assert(userdata);
r = route_prefix_new_static(network, filename, section_line, &p);
if (r < 0)
return log_oom();
r = in_addr_prefix_from_string(rvalue, AF_INET6, &in6addr, &prefixlen);
r = in_addr_prefix_from_string(rvalue, AF_INET6, &a, &p->prefixlen);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r, "Route prefix is invalid, ignoring assignment: %s", rvalue);
log_syntax(unit, LOG_WARNING, filename, line, r,
"Route prefix is invalid, ignoring assignment: %s", rvalue);
return 0;
}
r = sd_radv_prefix_set_route_prefix(p->radv_route_prefix, &in6addr.in6, prefixlen);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to set route prefix, ignoring assignment: %m");
return 0;
}
p = NULL;
(void) in6_addr_mask(&a.in6, p->prefixlen);
p->prefix = a.in6;
TAKE_PTR(p);
return 0;
}
@@ -975,8 +1017,8 @@ int config_parse_route_prefix_lifetime(
void *data,
void *userdata) {
Network *network = userdata;
_cleanup_(route_prefix_free_or_set_invalidp) RoutePrefix *p = NULL;
Network *network = userdata;
usec_t usec;
int r;
@@ -984,7 +1026,7 @@ int config_parse_route_prefix_lifetime(
assert(section);
assert(lvalue);
assert(rvalue);
assert(data);
assert(userdata);
r = route_prefix_new_static(network, filename, section_line, &p);
if (r < 0)
@@ -997,16 +1039,15 @@ int config_parse_route_prefix_lifetime(
return 0;
}
/* a value of 0xffffffff represents infinity */
r = sd_radv_route_prefix_set_lifetime(p->radv_route_prefix, DIV_ROUND_UP(usec, USEC_PER_SEC));
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to set route lifetime, ignoring assignment: %m");
if (usec != USEC_INFINITY && DIV_ROUND_UP(usec, USEC_PER_SEC) >= UINT32_MAX) {
log_syntax(unit, LOG_WARNING, filename, line, 0,
"Lifetime is too long, ignoring assignment: %s", rvalue);
return 0;
}
p = NULL;
p->lifetime = usec;
TAKE_PTR(p);
return 0;
}

View File

@@ -31,7 +31,13 @@ typedef struct Prefix {
Network *network;
NetworkConfigSection *section;
sd_radv_prefix *radv_prefix;
struct in6_addr prefix;
uint8_t prefixlen;
usec_t preferred_lifetime;
usec_t valid_lifetime;
bool onlink;
bool address_auto_configuration;
bool assign;
uint32_t route_metric;
@@ -42,7 +48,9 @@ typedef struct RoutePrefix {
Network *network;
NetworkConfigSection *section;
sd_radv_route_prefix *radv_route_prefix;
struct in6_addr prefix;
uint8_t prefixlen;
usec_t lifetime;
} RoutePrefix;
Prefix *prefix_free(Prefix *prefix);
@@ -67,9 +75,8 @@ RADVPrefixDelegation radv_prefix_delegation_from_string(const char *s) _pure_;
CONFIG_PARSER_PROTOTYPE(config_parse_router_prefix_delegation);
CONFIG_PARSER_PROTOTYPE(config_parse_router_preference);
CONFIG_PARSER_PROTOTYPE(config_parse_prefix);
CONFIG_PARSER_PROTOTYPE(config_parse_prefix_flags);
CONFIG_PARSER_PROTOTYPE(config_parse_prefix_boolean);
CONFIG_PARSER_PROTOTYPE(config_parse_prefix_lifetime);
CONFIG_PARSER_PROTOTYPE(config_parse_prefix_assign);
CONFIG_PARSER_PROTOTYPE(config_parse_prefix_metric);
CONFIG_PARSER_PROTOTYPE(config_parse_prefix_token);
CONFIG_PARSER_PROTOTYPE(config_parse_radv_dns);

View File

@@ -91,7 +91,7 @@ int sd_radv_route_prefix_new(sd_radv_route_prefix **ret);
sd_radv_route_prefix *sd_radv_route_prefix_ref(sd_radv_route_prefix *ra);
sd_radv_route_prefix *sd_radv_route_prefix_unref(sd_radv_route_prefix *ra);
int sd_radv_prefix_set_route_prefix(sd_radv_route_prefix *p, const struct in6_addr *in6_addr, unsigned char prefixlen);
int sd_radv_route_prefix_set_prefix(sd_radv_route_prefix *p, const struct in6_addr *in6_addr, unsigned char prefixlen);
int sd_radv_route_prefix_set_lifetime(sd_radv_route_prefix *p, uint32_t valid_lifetime);
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_radv, sd_radv_unref);