From: Matteo Croce Date: Thu, 27 Feb 2025 19:10:20 +0000 (+0100) Subject: network: add log messages when a route can't be updated X-Git-Tag: v258-rc1~1131 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f06e6d19c0004c3c96691b8153d40e64e4dfba73;p=thirdparty%2Fsystemd.git 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. --- diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c index 9c579db4458..a5102521833 100644 --- a/src/network/networkd-ndisc.c +++ b/src/network/networkd-ndisc.c @@ -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; diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c index c37011079cb..11fa624d14e 100644 --- a/src/network/networkd-route.c +++ b/src/network/networkd-route.c @@ -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); diff --git a/src/network/networkd-route.h b/src/network/networkd-route.h index 46bbe2899e0..5dba22b4475 100644 --- a/src/network/networkd-route.h +++ b/src/network/networkd-route.h @@ -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) {