diff options
| -rwxr-xr-x | python/vyos/ifconfig/interface.py | 8 | ||||
| -rw-r--r-- | python/vyos/ifconfig/loopback.py | 13 | ||||
| -rw-r--r-- | python/vyos/util.py | 4 | ||||
| -rwxr-xr-x | smoketest/scripts/cli/test_system_ipv6.py | 19 | ||||
| -rwxr-xr-x | smoketest/scripts/cli/test_vrf.py | 54 | ||||
| -rwxr-xr-x | src/conf_mode/vrf.py | 8 | ||||
| -rw-r--r-- | src/tests/test_util.py | 15 | 
7 files changed, 101 insertions, 20 deletions
| diff --git a/python/vyos/ifconfig/interface.py b/python/vyos/ifconfig/interface.py index 4fda1c0a9..6b9a4d03e 100755 --- a/python/vyos/ifconfig/interface.py +++ b/python/vyos/ifconfig/interface.py @@ -39,7 +39,7 @@ from vyos.util import read_file  from vyos.util import get_interface_config  from vyos.util import get_interface_namespace  from vyos.util import is_systemd_service_active -from vyos.util import sysctl_read +from vyos.util import is_ipv6_enabled  from vyos.template import is_ipv4  from vyos.template import is_ipv6  from vyos.validate import is_intf_addr_assigned @@ -1083,6 +1083,10 @@ class Interface(Control):          addr_is_v4 = is_ipv4(addr) +        # Failsave - do not add IPv6 address if IPv6 is disabled +        if is_ipv6(addr) and not is_ipv6_enabled(): +            return False +          # add to interface          if addr == 'dhcp':              self.set_dhcp(True) @@ -1498,7 +1502,7 @@ class Interface(Control):          self.set_ipv4_source_validation(value)          # Only change IPv6 parameters if IPv6 was not explicitly disabled -        if sysctl_read('net.ipv6.conf.all.disable_ipv6') == '0': +        if is_ipv6_enabled():              # Configure MSS value for IPv6 TCP connections              tmp = dict_search('ipv6.adjust_mss', config)              value = tmp if (tmp != None) else '0' diff --git a/python/vyos/ifconfig/loopback.py b/python/vyos/ifconfig/loopback.py index de554ef44..30c890fdf 100644 --- a/python/vyos/ifconfig/loopback.py +++ b/python/vyos/ifconfig/loopback.py @@ -13,9 +13,8 @@  # You should have received a copy of the GNU Lesser General Public  # License along with this library.  If not, see <http://www.gnu.org/licenses/>. -import vyos.util -  from vyos.ifconfig.interface import Interface +from vyos.util import is_ipv6_enabled  @Interface.register  class LoopbackIf(Interface): @@ -34,8 +33,6 @@ class LoopbackIf(Interface):          }      } -    name = 'loopback' -      def remove(self):          """          Loopback interface can not be deleted from operating system. We can @@ -62,11 +59,11 @@ class LoopbackIf(Interface):          on any interface. """          addr = config.get('address', []) -        # We must ensure that the loopback addresses are never deleted from the system -        addr += ['127.0.0.1/8'] -        if (vyos.util.sysctl_read('net.ipv6.conf.all.disable_ipv6') == '0'): -            addr += ['::1/128'] +        # We must ensure that the loopback addresses are never deleted from the system +        addr.append('127.0.0.1/8') +        if is_ipv6_enabled(): +            addr.append('::1/128')          # Update IP address entry in our dictionary          config.update({'address' : addr}) diff --git a/python/vyos/util.py b/python/vyos/util.py index f46775490..f3f323c34 100644 --- a/python/vyos/util.py +++ b/python/vyos/util.py @@ -1019,3 +1019,7 @@ def sysctl_write(name, value):          call(f'sysctl -wq {name}={value}')          return True      return False + +def is_ipv6_enabled() -> bool: +    """ Check if IPv6 support on the system is enabled or not """ +    return (sysctl_read('net.ipv6.conf.all.disable_ipv6') == '0') diff --git a/smoketest/scripts/cli/test_system_ipv6.py b/smoketest/scripts/cli/test_system_ipv6.py index 3112d2e46..6fe58701b 100755 --- a/smoketest/scripts/cli/test_system_ipv6.py +++ b/smoketest/scripts/cli/test_system_ipv6.py @@ -17,7 +17,11 @@  import unittest  from base_vyostest_shim import VyOSUnitTestSHIM + +from vyos.template import is_ipv4  from vyos.util import read_file +from vyos.util import is_ipv6_enabled +from vyos.validate import is_intf_addr_assigned  base_path = ['system', 'ipv6'] @@ -42,6 +46,14 @@ class TestSystemIPv6(VyOSUnitTestSHIM.TestCase):          self.assertEqual(read_file(file_forwarding), '0')      def test_system_ipv6_disable(self): +        # Verify previous "enable" state +        self.assertEqual(read_file(file_disable), '0') +        self.assertTrue(is_ipv6_enabled()) + +        loopbacks = ['127.0.0.1', '::1'] +        for addr in loopbacks: +            self.assertTrue(is_intf_addr_assigned('lo', addr)) +          # Do not assign any IPv6 address on interfaces, this requires a reboot          # which can not be tested, but we can read the config file :)          self.cli_set(base_path + ['disable']) @@ -49,6 +61,13 @@ class TestSystemIPv6(VyOSUnitTestSHIM.TestCase):          # Verify configuration file          self.assertEqual(read_file(file_disable), '1') +        self.assertFalse(is_ipv6_enabled()) + +        for addr in loopbacks: +            if is_ipv4(addr): +                self.assertTrue(is_intf_addr_assigned('lo', addr)) +            else: +                self.assertFalse(is_intf_addr_assigned('lo', addr))      def test_system_ipv6_strict_dad(self):          # This defaults to 1 diff --git a/smoketest/scripts/cli/test_vrf.py b/smoketest/scripts/cli/test_vrf.py index 5ffa9c086..5daea589c 100755 --- a/smoketest/scripts/cli/test_vrf.py +++ b/smoketest/scripts/cli/test_vrf.py @@ -1,6 +1,6 @@  #!/usr/bin/env python3  # -# Copyright (C) 2020-2021 VyOS maintainers and contributors +# Copyright (C) 2020-2022 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 @@ -25,9 +25,10 @@ from base_vyostest_shim import VyOSUnitTestSHIM  from vyos.configsession import ConfigSessionError  from vyos.ifconfig import Interface  from vyos.ifconfig import Section -from vyos.template import is_ipv6 +from vyos.template import is_ipv4  from vyos.util import cmd  from vyos.util import read_file +from vyos.util import get_interface_config  from vyos.validate import is_intf_addr_assigned  base_path = ['vrf'] @@ -105,10 +106,13 @@ class VRFTest(VyOSUnitTestSHIM.TestCase):              frrconfig = self.getFRRconfig(f'vrf {vrf}')              self.assertIn(f' vni {table}', frrconfig) +            tmp = get_interface_config(vrf) +            self.assertEqual(int(table), tmp['linkinfo']['info_data']['table']) +              # Increment table ID for the next run              table = str(int(table) + 1) -    def test_vrf_loopback_ips(self): +    def test_vrf_loopbacks_ips(self):          table = '2000'          for vrf in vrfs:              base = base_path + ['name', vrf] @@ -119,10 +123,48 @@ class VRFTest(VyOSUnitTestSHIM.TestCase):          self.cli_commit()          # Verify VRF configuration +        loopbacks = ['127.0.0.1', '::1']          for vrf in vrfs: -            self.assertTrue(vrf in interfaces()) -            self.assertTrue(is_intf_addr_assigned(vrf, '127.0.0.1')) -            self.assertTrue(is_intf_addr_assigned(vrf, '::1')) +            # Ensure VRF was created +            self.assertIn(vrf, interfaces()) +            # Test for proper loopback IP assignment +            for addr in loopbacks: +                self.assertTrue(is_intf_addr_assigned(vrf, addr)) + +    def test_vrf_loopbacks_no_ipv6(self): +        table = '2002' +        for vrf in vrfs: +            base = base_path + ['name', vrf] +            self.cli_set(base + ['table', str(table)]) +            table = str(int(table) + 1) + +        # Globally disable IPv6 - this will remove all IPv6 interface addresses +        self.cli_set(['system', 'ipv6', 'disable']) + +        # commit changes +        self.cli_commit() + +        # Verify VRF configuration +        table = '2002' +        loopbacks = ['127.0.0.1', '::1'] +        for vrf in vrfs: +            # Ensure VRF was created +            self.assertIn(vrf, interfaces()) + +            # Verify VRF table ID +            tmp = get_interface_config(vrf) +            self.assertEqual(int(table), tmp['linkinfo']['info_data']['table']) + +            # Test for proper loopback IP assignment +            for addr in loopbacks: +                if is_ipv4(addr): +                    self.assertTrue(is_intf_addr_assigned(vrf, addr)) +                else: +                    self.assertFalse(is_intf_addr_assigned(vrf, addr)) + +            table = str(int(table) + 1) + +        self.cli_delete(['system', 'ipv6'])      def test_vrf_bind_all(self):          table = '2000' diff --git a/src/conf_mode/vrf.py b/src/conf_mode/vrf.py index 6a521a0dd..c3e2d8efd 100755 --- a/src/conf_mode/vrf.py +++ b/src/conf_mode/vrf.py @@ -30,6 +30,7 @@ from vyos.util import get_interface_config  from vyos.util import popen  from vyos.util import run  from vyos.util import sysctl_write +from vyos.util import is_ipv6_enabled  from vyos import ConfigError  from vyos import frr  from vyos import airbag @@ -215,10 +216,11 @@ def apply(vrf):              # set VRF description for e.g. SNMP monitoring              vrf_if = Interface(name) -            # We also should add proper loopback IP addresses to the newly -            # created VRFs for services bound to the loopback address (SNMP, NTP) +            # We also should add proper loopback IP addresses to the newly added +            # VRF for services bound to the loopback address (SNMP, NTP)              vrf_if.add_addr('127.0.0.1/8') -            vrf_if.add_addr('::1/128') +            if is_ipv6_enabled(): +                vrf_if.add_addr('::1/128')              # add VRF description if available              vrf_if.set_alias(config.get('description', '')) diff --git a/src/tests/test_util.py b/src/tests/test_util.py index 9bd27adc0..91890262c 100644 --- a/src/tests/test_util.py +++ b/src/tests/test_util.py @@ -1,6 +1,6 @@  #!/usr/bin/env python3  # -# Copyright (C) 2020-2021 VyOS maintainers and contributors +# Copyright (C) 2020-2022 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 @@ -23,3 +23,16 @@ class TestVyOSUtil(TestCase):          expected_data = {"foo_bar": {"baz_quux": None}}          new_data = mangle_dict_keys(data, '-', '_')          self.assertEqual(new_data, expected_data) + +    def test_sysctl_read(self): +        self.assertEqual(sysctl_read('net.ipv4.conf.lo.forwarding'), '1') + +    def test_ipv6_enabled(self): +        tmp = sysctl_read('net.ipv6.conf.all.disable_ipv6') +        # We need to test for both variants as this depends on how the +        # Docker container is started (with or without IPv6 support) - so we +        # will simply check both cases to not make the users life miserable. +        if tmp == '0': +            self.assertTrue(is_ipv6_enabled()) +        else: +            self.assertFalse(is_ipv6_enabled()) | 
