mirror of
https://github.com/morgan9e/systemd
synced 2026-04-14 00:14:32 +09:00
Merge pull request #20853 from yuwata/network-radv-set-default-timeouts
network: RADV: set default timeouts
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user