network: add log messages when a route can't be updated

Sometimes networkd removes a route, based on route_can_update() verdict.
Add some debug messages to better understand whi this decision has been made.
This commit is contained in:
Matteo Croce
2025-03-10 05:39:49 +09:00
committed by Yu Watanabe
parent 8d04b8198d
commit f06e6d19c0
3 changed files with 76 additions and 15 deletions
+2 -2
View File
@@ -515,7 +515,7 @@ static int ndisc_request_route(Route *route, Link *link) {
ndisc_set_route_priority(link, route);
existing = ASSERT_PTR(req->userdata);
if (!route_can_update(existing, route)) {
if (!route_can_update(link->manager, existing, route)) {
if (existing->source == NETWORK_CONFIG_SOURCE_STATIC) {
log_link_debug(link, "Found a pending route request that conflicts with new request based on a received RA, ignoring request.");
return 0;
@@ -536,7 +536,7 @@ static int ndisc_request_route(Route *route, Link *link) {
route->pref = pref_original;
ndisc_set_route_priority(link, route);
if (!route_can_update(existing, route)) {
if (!route_can_update(link->manager, existing, route)) {
if (existing->source == NETWORK_CONFIG_SOURCE_STATIC) {
log_link_debug(link, "Found an existing route that conflicts with new route based on a received RA, ignoring request.");
return 0;
+73 -12
View File
@@ -1393,36 +1393,97 @@ static bool route_by_kernel(const Route *route) {
return false;
}
bool route_can_update(const Route *existing, const Route *requesting) {
bool route_can_update(Manager *manager, const Route *existing, const Route *requesting) {
int r;
assert(manager);
assert(existing);
assert(requesting);
if (route_compare_func(existing, requesting) != 0)
if (route_compare_func(existing, requesting) != 0) {
log_route_debug(existing, "Cannot update route, as the existing route is different", manager);
return false;
}
switch (existing->family) {
case AF_INET:
if (existing->nexthop.weight != requesting->nexthop.weight)
if (existing->nexthop.weight != requesting->nexthop.weight) {
log_debug("Cannot update route: existing weight: %u, requesting weight: %u",
existing->nexthop.weight, requesting->nexthop.weight);
return false;
}
return true;
case AF_INET6:
if (existing->protocol != requesting->protocol)
if (existing->protocol != requesting->protocol) {
if (DEBUG_LOGGING) {
_cleanup_free_ char *ex = NULL, *req = NULL;
r = route_protocol_to_string_alloc(existing->protocol, &ex);
if (r < 0)
return false;
r = route_protocol_to_string_alloc(requesting->protocol, &req);
if (r < 0)
return false;
log_debug("Cannot update route: existing protocol: %s, requesting protocol: %s", ex, req);
}
return false;
if (existing->type != requesting->type)
}
if (existing->type != requesting->type) {
log_debug("Cannot update route: existing type: %s, requesting type: %s",
route_type_to_string(existing->type),
route_type_to_string(requesting->type));
return false;
if ((existing->flags & ~RTNH_COMPARE_MASK) != (requesting->flags & ~RTNH_COMPARE_MASK))
}
if ((existing->flags & ~RTNH_COMPARE_MASK) != (requesting->flags & ~RTNH_COMPARE_MASK)) {
if (DEBUG_LOGGING) {
_cleanup_free_ char *ex = NULL, *req = NULL;
r = route_flags_to_string_alloc(existing->flags, &ex);
if (r < 0)
return false;
r = route_flags_to_string_alloc(requesting->flags, &req);
if (r < 0)
return false;
log_debug("Cannot update route: existing flags: %s, requesting flags: %s", ex, req);
}
return false;
if (!in6_addr_equal(&existing->prefsrc.in6, &requesting->prefsrc.in6))
}
if (!in6_addr_equal(&existing->prefsrc.in6, &requesting->prefsrc.in6)) {
log_debug("Cannot update route: existing preferred source: %s, requesting preferred source: %s",
IN6_ADDR_TO_STRING(&existing->prefsrc.in6),
IN6_ADDR_TO_STRING(&requesting->prefsrc.in6));
return false;
if (existing->pref != requesting->pref)
}
if (existing->pref != requesting->pref) {
log_debug("Cannot update route: existing preference: %u, requesting preference: %u",
existing->pref, requesting->pref);
return false;
if (existing->expiration_managed_by_kernel && requesting->lifetime_usec == USEC_INFINITY)
}
if (existing->expiration_managed_by_kernel && requesting->lifetime_usec == USEC_INFINITY) {
log_route_debug(existing,
"Cannot update route: the expiration is managed by the kernel and requested lifetime is infinite",
manager);
return false; /* We cannot disable expiration timer in the kernel. */
if (!route_metric_can_update(&existing->metric, &requesting->metric, existing->expiration_managed_by_kernel))
}
if (!route_metric_can_update(&existing->metric, &requesting->metric, existing->expiration_managed_by_kernel)) {
log_route_debug(existing,
"Cannot update route: expiration is managed by the kernel or metrics differ",
manager);
return false;
if (existing->nexthop.weight != requesting->nexthop.weight)
}
if (existing->nexthop.weight != requesting->nexthop.weight) {
log_debug("Cannot update route: existing weight: %u, requesting weight: %u",
existing->nexthop.weight, requesting->nexthop.weight);
return false;
}
return true;
default:
@@ -1449,7 +1510,7 @@ static int link_unmark_route(Link *link, const Route *route, const RouteNextHop
if (route_get(link->manager, tmp, &existing) < 0)
return 0;
if (!route_can_update(existing, tmp))
if (!route_can_update(link->manager, existing, tmp))
return 0;
route_unmark(existing);
+1 -1
View File
@@ -104,7 +104,7 @@ int route_get(Manager *manager, const Route *route, Route **ret);
bool route_is_bound_to_link(const Route *route, Link *link);
int route_get_request(Manager *manager, const Route *route, Request **ret);
bool route_can_update(const Route *existing, const Route *requesting);
bool route_can_update(Manager *manager, const Route *existing, const Route *requesting);
int link_drop_routes(Link *link, bool only_static);
static inline int link_drop_static_routes(Link *link) {