diff mbox series

[2/5] gateway: Handle -ESRCH in 'unset_default_gateway_route_common'.

Message ID 20231220055613.2287074-3-gerickson@nuovations.com (mailing list archive)
State Accepted, archived
Headers show
Series Address Unhandled Gateway Route Lifecycle Events/Transitions | expand

Commit Message

Grant Erickson Dec. 20, 2023, 5:56 a.m. UTC
This maps the error '-ESRCH' in 'unset_default_gateway_route_common'
to 0 ("Success").

Generally, we mandate that gateway routes follow the documented
lifecycle and finite state machine, using events and down- and upcalls
to drive the lifecycle.

There is one exception, however. When the Linux kernel
recognizes that the next hop (that is, the "via" or RTA_GATEWAY
portion of the route) for a route becomes unreachable, it is
automatically purged from the routing table with no
RTM_DELROUTE RTNL notification. Consequently, routes so purged
will return -ESRCH when we attempt to delete them here in the
mistaken belief they are still there.

By mapping -ESRCH to 0 ("Success") we ensure that gateway
configuration for such routes is not indefinitely stuck in the
"active" or "added" states but rather is correctly advanced to the
"removed" state.
---
 src/gateway.c | 28 +++++++++++++++++++++++++---
 1 file changed, 25 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/src/gateway.c b/src/gateway.c
index 29115250d243..db8636eb20ef 100644
--- a/src/gateway.c
+++ b/src/gateway.c
@@ -221,6 +221,11 @@ 
  *        interface basis and is computed by
  *        'compute_low_priority_metric'.
  *
+ *    There is one exception to the above. When the Linux kernel
+ *    recognizes that the next hop for a route becomes unreachable, it
+ *    is automatically purged from the routing table with no
+ *    RTM_DELROUTE RTNL notification.
+ *
  *    Historically, this file started life as "connection.c". However,
  *    it was renamed to "gateway.c" since its primary focus is gateway
  *    routes and gateway route management.
@@ -1864,8 +1869,6 @@  done:
  *  @retval  -EPERM         If the current process does not have the
  *                          credentials or capabilities to unset, or
  *                          clear, routes.
- *  @retval  -ESRCH         A request was made to unset, or clear a
- *                          non-existing routing entry.
  *
  *  @sa gateway_config_state_set
  *  @sa is_gateway_config_state
@@ -1892,8 +1895,27 @@  static int unset_default_gateway_route_common(struct gateway_data *data,
 	if (is_gateway_config_state_inactive(config))
 		return -EALREADY;
 
+	/*
+	 * Generally, we mandate that gateway routes follow the documented
+	 * lifecycle and state machine, using events and down- and upcalls
+	 * to drive the lifecycle.
+	 *
+	 * There is one exception, however. When the Linux kernel
+	 * recognizes that the next hop (that is, the "via" or RTA_GATEWAY
+	 * part of the route) for a route becomes unreachable, it is
+	 * automatically purged from the routing table with no
+	 * RTM_DELROUTE RTNL notification. Consequently, routes so purged
+	 * will return -ESRCH when we attempt to delete them here in the
+	 * mistaken belief they are still there.
+	 *
+	 * Map -ESRCH to success such that gateway configuration for such
+	 * routes is not indefinitely stuck in the "active" or "added"
+	 * states.
+	 */
 	err = cb(data, config);
-	if (err < 0)
+	if (err == -ESRCH)
+		err = 0;
+	else if (err < 0)
 		goto done;
 
 	gateway_config_state_set(config,