diff options
| author | zdc <zdc@users.noreply.github.com> | 2023-09-04 10:59:17 +0300 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-09-04 10:59:17 +0300 | 
| commit | 8e22a2f6f77dc2d10969d8603c59a8834164b903 (patch) | |
| tree | f2b723769df3fa6b8ea0c3c308db3e204b0b6b37 | |
| parent | bbcf94bba674e4c001d9439439b8fd405f39501a (diff) | |
| parent | 5fb77805f0fcc507c6af7b897fcf5a532bf20e42 (diff) | |
| download | vyos-1x-8e22a2f6f77dc2d10969d8603c59a8834164b903.tar.gz vyos-1x-8e22a2f6f77dc2d10969d8603c59a8834164b903.zip | |
Merge pull request #2192 from sever-sever/T5533vyos/1.5dev0
T5533: Fix VRRP IPv6 group enters in FAULT state
| -rw-r--r-- | python/vyos/utils/network.py | 31 | ||||
| -rwxr-xr-x | src/conf_mode/high-availability.py | 16 | 
2 files changed, 47 insertions, 0 deletions
| diff --git a/python/vyos/utils/network.py b/python/vyos/utils/network.py index 2f181d8d9..bc6899e45 100644 --- a/python/vyos/utils/network.py +++ b/python/vyos/utils/network.py @@ -117,6 +117,37 @@ def get_interface_namespace(iface):              if iface == tmp["ifname"]:                  return netns +def is_ipv6_tentative(iface: str, ipv6_address: str) -> bool: +    """Check if IPv6 address is in tentative state. + +    This function checks if an IPv6 address on a specific network interface is +    in the tentative state. IPv6 tentative addresses are not fully configured +    and are undergoing Duplicate Address Detection (DAD) to ensure they are +    unique on the network. + +    Args: +        iface (str): The name of the network interface. +        ipv6_address (str): The IPv6 address to check. + +    Returns: +        bool: True if the IPv6 address is tentative, False otherwise. +    """ +    import json +    from vyos.utils.process import rc_cmd + +    rc, out = rc_cmd(f'ip -6 --json address show dev {iface} scope global') +    if rc: +        return False + +    data = json.loads(out) +    for addr_info in data[0]['addr_info']: +        if ( +            addr_info.get('local') == ipv6_address and +            addr_info.get('tentative', False) +        ): +            return True +    return False +  def is_wwan_connected(interface):      """ Determine if a given WWAN interface, e.g. wwan0 is connected to the      carrier network or not """ diff --git a/src/conf_mode/high-availability.py b/src/conf_mode/high-availability.py index 626a3757e..0121df11c 100755 --- a/src/conf_mode/high-availability.py +++ b/src/conf_mode/high-availability.py @@ -15,6 +15,8 @@  # along with this program.  If not, see <http://www.gnu.org/licenses/>. +import time +  from sys import exit  from ipaddress import ip_interface  from ipaddress import IPv4Interface @@ -26,11 +28,13 @@ from vyos.ifconfig.vrrp import VRRP  from vyos.template import render  from vyos.template import is_ipv4  from vyos.template import is_ipv6 +from vyos.utils.network import is_ipv6_tentative  from vyos.utils.process import call  from vyos import ConfigError  from vyos import airbag  airbag.enable() +  def get_config(config=None):      if config:          conf = config @@ -171,6 +175,18 @@ def apply(ha):          call(f'systemctl stop {service_name}')          return None +    # Check if IPv6 address is tentative T5533 +    for group, group_config in ha['vrrp']['group'].items(): +        if 'hello_source_address' in group_config: +            if is_ipv6(group_config['hello_source_address']): +                ipv6_address = group_config['hello_source_address'] +                interface = group_config['interface'] +                checks = 20 +                interval = 0.1 +                for _ in range(checks): +                    if is_ipv6_tentative(interface, ipv6_address): +                        time.sleep(interval) +      call(f'systemctl reload-or-restart {service_name}')      return None | 
