summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorViacheslav Hletenko <v.gletenko@vyos.io>2023-01-04 12:05:50 +0000
committerViacheslav Hletenko <v.gletenko@vyos.io>2023-01-04 12:05:50 +0000
commitb1004dcd24ba09d51eae2aaabd80b316275d8f88 (patch)
tree31973ea4698c512796d21556a3f185171dbc228f
parentf5af95be4f66380d213771b975c63361e27616ef (diff)
downloadvyos-1x-b1004dcd24ba09d51eae2aaabd80b316275d8f88.tar.gz
vyos-1x-b1004dcd24ba09d51eae2aaabd80b316275d8f88.zip
T1237: Fix failover route install route with diff metrics
If there is no route in the routing table (requires install route) it checks routing table and returns best route None But if we have 2 routes to the same dest ip but with different metrics it doesn't get None (not first route install) It cause that bast metric route cannot be installed (wrong logic) Add func "is_route_exists" and check route/gateway/metric for the required route
-rwxr-xr-xsrc/helpers/vyos-failover.py21
1 files changed, 16 insertions, 5 deletions
diff --git a/src/helpers/vyos-failover.py b/src/helpers/vyos-failover.py
index 1ac193423..0de945f20 100755
--- a/src/helpers/vyos-failover.py
+++ b/src/helpers/vyos-failover.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022 VyOS maintainers and contributors
+# Copyright (C) 2022-2023 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -28,6 +28,17 @@ from systemd import journal
my_name = Path(__file__).stem
+def is_route_exists(route, gateway, interface, metric):
+ """Check if route with expected gateway, dev and metric exists"""
+ rc, data = rc_cmd(f'sudo ip --json route show protocol failover {route} '
+ f'via {gateway} dev {interface} metric {metric}')
+ if rc == 0:
+ data = json.loads(data)
+ if len(data) > 0:
+ return True
+ return False
+
+
def get_best_route_options(route, debug=False):
"""
Return current best route ('gateway, interface, metric)
@@ -137,7 +148,7 @@ if __name__ == '__main__':
for route, route_config in config.get('route').items():
- exists_route = exists_gateway, exists_iface, exists_metric = get_best_route_options(route, debug=debug)
+ exists_gateway, exists_iface, exists_metric = get_best_route_options(route, debug=debug)
for next_hop, nexthop_config in route_config.get('next_hop').items():
conf_iface = nexthop_config.get('interface')
@@ -148,8 +159,8 @@ if __name__ == '__main__':
target = nexthop_config.get('check').get('target')
timeout = nexthop_config.get('check').get('timeout')
- # Best route not fonund in the current routing table
- if exists_route == (None, None, None):
+ # Route not found in the current routing table
+ if not is_route_exists(route, next_hop, conf_iface, conf_metric):
if debug: print(f" [NEW_ROUTE_DETECTED] route: [{route}]")
# Add route if check-target alive
if is_target_alive(target, conf_iface, proto, port, debug=debug):
@@ -172,7 +183,7 @@ if __name__ == '__main__':
# Route was added, check if the target is alive
# We should delete route if check fails only if route exists in the routing table
if not is_target_alive(target, conf_iface, proto, port, debug=debug) and \
- exists_route != (None, None, None):
+ is_route_exists(route, next_hop, conf_iface, conf_metric):
if debug:
print(f'Nexh_hop {next_hop} fail, target not response')
print(f' [ DEL ] -- ip route del {route} via {next_hop} dev {conf_iface} '