/* default to accept RA if ip_forward is disabled and ignore RA if ip_forward is enabled */
network->ipv6_accept_ra = !FLAGS_SET(network->ip_forward, ADDRESS_FAMILY_IPV6);
- /* When PrefixAllowList= or RouteAllowList= are specified, then PrefixDenyList= or RouteDenyList= are ignored. */
+ /* When RouterAllowList=, PrefixAllowList= or RouteAllowList= are specified, then
+ * RouterDenyList=, PrefixDenyList= or RouteDenyList= are ignored, respectively. */
+ if (!set_isempty(network->ndisc_allow_listed_router))
+ network->ndisc_deny_listed_router = set_free_free(network->ndisc_deny_listed_router);
if (!set_isempty(network->ndisc_allow_listed_prefix))
network->ndisc_deny_listed_prefix = set_free_free(network->ndisc_deny_listed_prefix);
if (!set_isempty(network->ndisc_allow_listed_route_prefix))
break;
}
- if (IN6_IS_ADDR_UNSPECIFIED(&router)) {
+ if (in6_addr_is_null(&router)) {
_cleanup_free_ char *buf = NULL;
(void) in_addr_to_string(address->family, &address->in_addr, &buf);
NDiscDNSSL *dnssl;
NDiscRDNSS *rdnss;
int k, r = 0;
+ bool updated = false;
assert(link);
assert(router);
log_link_debug(link, "Removing old NDisc information obtained from %s.", strna(buf));
}
- link_dirty(link);
-
SET_FOREACH(na, link->ndisc_addresses)
if (na->marked && IN6_ARE_ADDR_EQUAL(&na->router, router)) {
k = address_remove(na->address, link, NULL);
}
SET_FOREACH(rdnss, link->ndisc_rdnss)
- if (rdnss->marked && IN6_ARE_ADDR_EQUAL(&rdnss->router, router))
+ if (rdnss->marked && IN6_ARE_ADDR_EQUAL(&rdnss->router, router)) {
free(set_remove(link->ndisc_rdnss, rdnss));
+ updated = true;
+ }
SET_FOREACH(dnssl, link->ndisc_dnssl)
- if (dnssl->marked && IN6_ARE_ADDR_EQUAL(&dnssl->router, router))
+ if (dnssl->marked && IN6_ARE_ADDR_EQUAL(&dnssl->router, router)) {
free(set_remove(link->ndisc_dnssl, dnssl));
+ updated = true;
+ }
+
+ if (updated)
+ link_dirty(link);
return r;
}
r = route_configure(route, link, ndisc_route_handler, &ret);
if (r < 0)
return log_link_error_errno(link, r, "Failed to set NDisc route: %m");
+ if (r > 0)
+ link->ndisc_routes_configured = false;
link->ndisc_routes_messages++;
link_enter_failed(link);
return 1;
}
-
- r = link_set_routes(link);
- if (r < 0) {
- link_enter_failed(link);
- return 1;
- }
}
return 1;
assert(link);
assert(rt);
- r = address_configure(address, link, ndisc_address_handler, true, &ret);
+ r = address_configure(address, link, ndisc_address_handler, &ret);
if (r < 0)
return log_link_error_errno(link, r, "Failed to set NDisc SLAAC address: %m");
+ if (r > 0)
+ link->ndisc_addresses_configured = false;
link->ndisc_addresses_messages++;
_cleanup_free_ struct in6_addr *new_address = NULL;
if (j->address_generation_type == IPV6_TOKEN_ADDRESS_GENERATION_PREFIXSTABLE
- && (IN6_IS_ADDR_UNSPECIFIED(&j->prefix) || IN6_ARE_ADDR_EQUAL(&j->prefix, address))) {
+ && (in6_addr_is_null(&j->prefix) || IN6_ARE_ADDR_EQUAL(&j->prefix, address))) {
/* While this loop uses dad_counter and a retry limit as specified in RFC 7217, the loop
- does not actually attempt Duplicate Address Detection; the counter will be incremented
- only when the address generation algorithm produces an invalid address, and the loop
- may exit with an address which ends up being unusable due to duplication on the link.
- */
+ * does not actually attempt Duplicate Address Detection; the counter will be incremented
+ * only when the address generation algorithm produces an invalid address, and the loop
+ * may exit with an address which ends up being unusable due to duplication on the link. */
for (; j->dad_counter < DAD_CONFLICTS_IDGEN_RETRIES_RFC7217; j->dad_counter++) {
r = make_stableprivate_address(link, address, prefixlen, j->dad_counter, &new_address);
if (r < 0)
struct in6_addr router;
NDiscRDNSS *rdnss;
usec_t time_now;
+ bool updated = false;
int n, r;
assert(link);
if (r < 0)
return log_oom();
assert(r > 0);
+
+ updated = true;
}
+ if (updated)
+ link_dirty(link);
+
return 0;
}
uint32_t lifetime;
usec_t time_now;
NDiscDNSSL *dnssl;
+ bool updated = false;
char **j;
int r;
if (r < 0)
return log_oom();
assert(r > 0);
+
+ updated = true;
}
+ if (updated)
+ link_dirty(link);
+
return 0;
}
}
static int ndisc_router_handler(Link *link, sd_ndisc_router *rt) {
- struct in6_addr router;
+ union in_addr_union router;
uint64_t flags;
NDiscAddress *na;
NDiscRoute *nr;
assert(link->manager);
assert(rt);
- link->ndisc_addresses_configured = false;
- link->ndisc_routes_configured = false;
-
- link_dirty(link);
-
- r = sd_ndisc_router_get_address(rt, &router);
+ r = sd_ndisc_router_get_address(rt, &router.in6);
if (r < 0)
return log_link_error_errno(link, r, "Failed to get router address from RA: %m");
+ if ((!set_isempty(link->network->ndisc_allow_listed_router) &&
+ !set_contains(link->network->ndisc_allow_listed_router, &router.in6)) ||
+ set_contains(link->network->ndisc_deny_listed_router, &router.in6)) {
+ if (DEBUG_LOGGING) {
+ _cleanup_free_ char *buf = NULL;
+
+ (void) in_addr_to_string(AF_INET6, &router, &buf);
+ if (!set_isempty(link->network->ndisc_allow_listed_router))
+ log_link_debug(link, "Router '%s' is not in allow list, ignoring", strna(buf));
+ else
+ log_link_debug(link, "Router '%s' is in deny list, ignoring", strna(buf));
+ }
+ return 0;
+ }
+
SET_FOREACH(na, link->ndisc_addresses)
- if (IN6_ARE_ADDR_EQUAL(&na->router, &router))
+ if (IN6_ARE_ADDR_EQUAL(&na->router, &router.in6))
na->marked = true;
SET_FOREACH(nr, link->ndisc_routes)
- if (IN6_ARE_ADDR_EQUAL(&nr->router, &router))
+ if (IN6_ARE_ADDR_EQUAL(&nr->router, &router.in6))
nr->marked = true;
r = sd_ndisc_router_get_flags(rt, &flags);
if (link->ndisc_addresses_messages == 0)
link->ndisc_addresses_configured = true;
- else {
+ else
log_link_debug(link, "Setting SLAAC addresses.");
- /* address_handler calls link_set_routes() and link_set_nexthop(). Before they are
- * called, the related flags must be cleared. Otherwise, the link becomes configured
- * state before routes are configured. */
- link->static_routes_configured = false;
- link->static_nexthops_configured = false;
- }
-
if (link->ndisc_routes_messages == 0)
link->ndisc_routes_configured = true;
else
NDiscRDNSS *r;
NDiscDNSSL *d;
usec_t time_now;
- bool updated = false;
assert(link);
time_now = now(clock_boottime_or_monotonic());
SET_FOREACH(r, link->ndisc_rdnss)
- if (r->valid_until < time_now) {
+ if (r->valid_until < time_now)
free(set_remove(link->ndisc_rdnss, r));
- updated = true;
- }
SET_FOREACH(d, link->ndisc_dnssl)
- if (d->valid_until < time_now) {
+ if (d->valid_until < time_now)
free(set_remove(link->ndisc_dnssl, d));
- updated = true;
- }
-
- if (updated)
- link_dirty(link);
}
void ndisc_flush(Link *link) {
token->prefix = buffer.in6;
}
- r = ordered_set_ensure_allocated(&network->ipv6_tokens, &ipv6_token_hash_ops);
- if (r < 0)
+ r = ordered_set_ensure_put(&network->ipv6_tokens, &ipv6_token_hash_ops, token);
+ if (r == -ENOMEM)
return log_oom();
-
- r = ordered_set_put(network->ipv6_tokens, token);
if (r == -EEXIST)
log_syntax(unit, LOG_DEBUG, filename, line, r,
"IPv6 token '%s' is duplicated, ignoring: %m", rvalue);