diff options
| author | Christian Breunig <christian@breunig.cc> | 2023-04-22 21:27:31 +0200 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-04-22 21:27:31 +0200 | 
| commit | 6b81f048a0cd0dd7e9d407c96426f353317ec38a (patch) | |
| tree | 26098a594daddbdc58fbe3af6cb8b0aa045f6fb6 /src | |
| parent | 459b3ab03c41f4947eb62c0f1a1db9d3f837dae5 (diff) | |
| parent | 4ab192c7c9d47180560e5d97de23dd1627c8ce11 (diff) | |
| download | vyos-1x-6b81f048a0cd0dd7e9d407c96426f353317ec38a.tar.gz vyos-1x-6b81f048a0cd0dd7e9d407c96426f353317ec38a.zip | |
Merge pull request #1966 from sever-sever/T1237
T1237: Failover route add policy for targets checking
Diffstat (limited to 'src')
| -rwxr-xr-x | src/helpers/vyos-failover.py | 41 | 
1 files changed, 29 insertions, 12 deletions
| diff --git a/src/helpers/vyos-failover.py b/src/helpers/vyos-failover.py index 03fb42f57..ce4cf8fa4 100755 --- a/src/helpers/vyos-failover.py +++ b/src/helpers/vyos-failover.py @@ -93,7 +93,12 @@ def is_port_open(ip, port):          s.close() -def is_target_alive(target_list=None, iface='', proto='icmp', port=None, debug=False): +def is_target_alive(target_list=None, +                    iface='', +                    proto='icmp', +                    port=None, +                    debug=False, +                    policy='any-available') -> bool:      """Check the availability of each target in the target_list using      the specified protocol ICMP, ARP, TCP @@ -103,17 +108,19 @@ def is_target_alive(target_list=None, iface='', proto='icmp', port=None, debug=F          proto (str): The protocol to use for the check. Options are 'icmp', 'arp', or 'tcp'.          port (int): The port number to use for the TCP check. Only applicable if proto is 'tcp'.          debug (bool): If True, print debug information during the check. +        policy (str): The policy to use for the check. Options are 'any-available' or 'all-available'.      Returns: -        bool: True if all targets are reachable, False otherwise. +        bool: True if all targets are reachable according to the policy, False otherwise.      Example: -        % is_target_alive(['192.0.2.1', '192.0.2.5'], 'eth1', proto='arp') +        % is_target_alive(['192.0.2.1', '192.0.2.5'], 'eth1', proto='arp', policy='all-available')          True      """      if iface != '':          iface = f'-I {iface}' +    num_reachable_targets = 0      for target in target_list:          match proto:              case 'icmp': @@ -121,25 +128,34 @@ def is_target_alive(target_list=None, iface='', proto='icmp', port=None, debug=F                  rc, response = rc_cmd(command)                  if debug:                      print(f'    [ CHECK-TARGET ]: [{command}] -- return-code [RC: {rc}]') -                if rc != 0: -                    return False +                if rc == 0: +                    num_reachable_targets += 1 +                    if policy == 'any-available': +                        return True              case 'arp':                  command = f'/usr/bin/arping -b -c 2 -f -w 1 -i 1 {iface} {target}'                  rc, response = rc_cmd(command)                  if debug:                      print(f'    [ CHECK-TARGET ]: [{command}] -- return-code [RC: {rc}]') -                if rc != 0: -                    return False +                if rc == 0: +                    num_reachable_targets += 1 +                    if policy == 'any-available': +                        return True              case _ if proto == 'tcp' and port is not None: -                if not is_port_open(target, port): -                    return False +                if is_port_open(target, port): +                    num_reachable_targets += 1 +                    if policy == 'any-available': +                        return True              case _:                  return False -    return True +        if policy == 'all-available' and num_reachable_targets == len(target_list): +            return True + +    return False  if __name__ == '__main__': @@ -178,6 +194,7 @@ if __name__ == '__main__':                  conf_metric = int(nexthop_config.get('metric'))                  port = nexthop_config.get('check').get('port')                  port_opt = f'port {port}' if port else '' +                policy = nexthop_config.get('check').get('policy')                  proto = nexthop_config.get('check').get('type')                  target = nexthop_config.get('check').get('target')                  timeout = nexthop_config.get('check').get('timeout') @@ -186,7 +203,7 @@ if __name__ == '__main__':                  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): +                    if is_target_alive(target, conf_iface, proto, port, debug=debug, policy=policy):                          if debug: print(f'    [ ADD ] -- ip route add {route} via {next_hop} dev {conf_iface} '                                          f'metric {conf_metric} proto failover\n###')                          rc, command = rc_cmd(f'ip route add {route} via {next_hop} dev {conf_iface} ' @@ -205,7 +222,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 \ +                if not is_target_alive(target, conf_iface, proto, port, debug=debug, policy=policy) and \                          is_route_exists(route, next_hop, conf_iface, conf_metric):                      if debug:                          print(f'Nexh_hop {next_hop} fail, target not response') | 
