]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: add log messages when a route can't be updated
authorMatteo Croce <teknoraver@meta.com>
Thu, 27 Feb 2025 19:10:20 +0000 (20:10 +0100)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 9 Mar 2025 20:39:49 +0000 (05:39 +0900)
Sometimes networkd removes a route, based on route_can_update() verdict.
Add some debug messages to better understand whi this decision has been made.

src/network/networkd-ndisc.c
src/network/networkd-route.c
src/network/networkd-route.h

index 9c579db44589b5fa614f75e2c30d111328a8fb80..a5102521833429b5e706d89587028389afd9c669 100644 (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;
index c37011079cb598ce63e6840cb5d7bf871fbed2cf..11fa624d14ee44a69a3fdf0678ac5c1d827b32b8 100644 (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);
index 46bbe2899e025d98ec4a2f710ced882897065aa2..5dba22b44759f11ce0760f5d1d7cbecfa66333ba 100644 (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) {