summaryrefslogtreecommitdiff
path: root/scripts/cli/base_interfaces_test.py
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/cli/base_interfaces_test.py')
-rw-r--r--scripts/cli/base_interfaces_test.py177
1 files changed, 158 insertions, 19 deletions
diff --git a/scripts/cli/base_interfaces_test.py b/scripts/cli/base_interfaces_test.py
index 53fe553bc..14ec7e137 100644
--- a/scripts/cli/base_interfaces_test.py
+++ b/scripts/cli/base_interfaces_test.py
@@ -15,17 +15,28 @@
import os
import unittest
-from vyos.configsession import ConfigSession
from netifaces import ifaddresses, AF_INET, AF_INET6
-from vyos.validate import is_intf_addr_assigned, is_ipv6_link_local
+
+from vyos.configsession import ConfigSession
from vyos.ifconfig import Interface
+from vyos.util import read_file
+from vyos.validate import is_intf_addr_assigned, is_ipv6_link_local
class BasicInterfaceTest:
class BaseTest(unittest.TestCase):
+ _test_ip = False
_test_mtu = False
+ _test_vlan = False
+ _test_qinq = False
+ _test_ipv6 = False
_base_path = []
+
_options = {}
_interfaces = []
+ _qinq_range = ['10', '20', '30']
+ _vlan_range = ['100', '200', '300', '2000']
+ # choose IPv6 minimum MTU value for tests - this must always work
+ _mtu = '1280'
def setUp(self):
self.session = ConfigSession(os.getpid())
@@ -38,9 +49,14 @@ class BasicInterfaceTest:
def tearDown(self):
# we should not remove ethernet from the overall CLI
if 'ethernet' in self._base_path:
- self.session.delete(self._base_path)
- for intf in self._interfaces:
- self.session.set(self._base_path + [intf])
+ for interface in self._interfaces:
+ # when using a dedicated interface to test via TEST_ETH environment
+ # variable only this one will be cleared in the end - usable to test
+ # ethernet interfaces via SSH
+ self.session.delete(self._base_path + [interface])
+ self.session.set(self._base_path + [interface, 'duplex', 'auto'])
+ self.session.set(self._base_path + [interface, 'speed', 'auto'])
+ self.session.set(self._base_path + [interface, 'smp-affinity', 'auto'])
else:
self.session.delete(self._base_path)
@@ -105,26 +121,149 @@ class BasicInterfaceTest:
self.assertTrue(is_intf_addr_assigned(intf, addr['addr']))
+ def test_ipv6_link_local(self):
+ """ Common function for IPv6 link-local address assignemnts """
+ if not self._test_ipv6:
+ return None
+
+ for interface in self._interfaces:
+ base = self._base_path + [interface]
+ for option in self._options.get(interface, []):
+ self.session.set(base + option.split())
+
+ # after commit we must have an IPv6 link-local address
+ self.session.commit()
+
+ for interface in self._interfaces:
+ for addr in ifaddresses(interface)[AF_INET6]:
+ self.assertTrue(is_ipv6_link_local(addr['addr']))
+
+ # disable IPv6 link-local address assignment
+ for interface in self._interfaces:
+ base = self._base_path + [interface]
+ self.session.set(base + ['ipv6', 'address', 'no-default-link-local'])
+
+ # after commit we must have no IPv6 link-local address
+ self.session.commit()
+
+ for interface in self._interfaces:
+ self.assertTrue(AF_INET6 not in ifaddresses(interface))
+
+ def _mtu_test(self, intf):
+ """ helper function to verify MTU size """
+ with open('/sys/class/net/{}/mtu'.format(intf), 'r') as f:
+ tmp = f.read().rstrip()
+ self.assertEqual(tmp, self._mtu)
def test_change_mtu(self):
- """
- Check if MTU can be changed on interface.
- Test MTU size will be 1400 bytes.
- """
- if self._test_mtu is False:
+ """ Testcase if MTU can be changed on interface """
+ if not self._test_mtu:
return None
-
- # choose a MTU which works on every interface
- mtu = '1400'
for intf in self._interfaces:
- self.session.set(self._base_path + [intf, 'mtu', mtu])
+ base = self._base_path + [intf]
+ self.session.set(base + ['mtu', self._mtu])
for option in self._options.get(intf, []):
- self.session.set(self._base_path + [intf] + option.split())
+ self.session.set(base + option.split())
self.session.commit()
+ for intf in self._interfaces:
+ self._mtu_test(intf)
- # Validate interface description
+ def test_8021q_vlan(self):
+ """ Testcase for 802.1q VLAN interfaces """
+ if not self._test_vlan:
+ return None
+
+ for interface in self._interfaces:
+ base = self._base_path + [interface]
+ for option in self._options.get(interface, []):
+ self.session.set(base + option.split())
+
+ for vlan in self._vlan_range:
+ base = self._base_path + [interface, 'vif', vlan]
+ self.session.set(base + ['mtu', self._mtu])
+ for address in self._test_addr:
+ self.session.set(base + ['address', address])
+
+ self.session.commit()
for intf in self._interfaces:
- with open('/sys/class/net/{}/mtu'.format(intf), 'r') as f:
- tmp = f.read().rstrip()
- self.assertTrue(tmp == mtu)
+ for vlan in self._vlan_range:
+ vif = f'{intf}.{vlan}'
+ for address in self._test_addr:
+ self.assertTrue(is_intf_addr_assigned(vif, address))
+ self._mtu_test(vif)
+
+
+ def test_8021ad_qinq_vlan(self):
+ """ Testcase for 802.1ad Q-in-Q VLAN interfaces """
+ if not self._test_qinq:
+ return None
+
+ for interface in self._interfaces:
+ base = self._base_path + [interface]
+ for option in self._options.get(interface, []):
+ self.session.set(base + option.split())
+
+ for vif_s in self._qinq_range:
+ for vif_c in self._vlan_range:
+ base = self._base_path + [interface, 'vif-s', vif_s, 'vif-c', vif_c]
+ self.session.set(base + ['mtu', self._mtu])
+ for address in self._test_addr:
+ self.session.set(base + ['address', address])
+
+ self.session.commit()
+ for interface in self._interfaces:
+ for vif_s in self._qinq_range:
+ for vif_c in self._vlan_range:
+ vif = f'{interface}.{vif_s}.{vif_c}'
+ for address in self._test_addr:
+ self.assertTrue(is_intf_addr_assigned(vif, address))
+ self._mtu_test(vif)
+
+ def test_ip_options(self):
+ """ test IP options like arp """
+ if not self._test_ip:
+ return None
+
+ for interface in self._interfaces:
+ arp_tmo = '300'
+ path = self._base_path + [interface]
+ for option in self._options.get(interface, []):
+ self.session.set(path + option.split())
+
+ # Options
+ self.session.set(path + ['ip', 'arp-cache-timeout', arp_tmo])
+ self.session.set(path + ['ip', 'disable-arp-filter'])
+ self.session.set(path + ['ip', 'enable-arp-accept'])
+ self.session.set(path + ['ip', 'enable-arp-announce'])
+ self.session.set(path + ['ip', 'enable-arp-ignore'])
+ self.session.set(path + ['ip', 'enable-proxy-arp'])
+ self.session.set(path + ['ip', 'proxy-arp-pvlan'])
+ self.session.set(path + ['ip', 'source-validation', 'loose'])
+
+ self.session.commit()
+
+ for interface in self._interfaces:
+ tmp = read_file(f'/proc/sys/net/ipv4/neigh/{interface}/base_reachable_time_ms')
+ self.assertEqual(tmp, str((int(arp_tmo) * 1000))) # tmo value is in milli seconds
+
+ tmp = read_file(f'/proc/sys/net/ipv4/conf/{interface}/arp_filter')
+ self.assertEqual('0', tmp)
+
+ tmp = read_file(f'/proc/sys/net/ipv4/conf/{interface}/arp_accept')
+ self.assertEqual('1', tmp)
+
+ tmp = read_file(f'/proc/sys/net/ipv4/conf/{interface}/arp_announce')
+ self.assertEqual('1', tmp)
+
+ tmp = read_file(f'/proc/sys/net/ipv4/conf/{interface}/arp_ignore')
+ self.assertEqual('1', tmp)
+
+ tmp = read_file(f'/proc/sys/net/ipv4/conf/{interface}/proxy_arp')
+ self.assertEqual('1', tmp)
+
+ tmp = read_file(f'/proc/sys/net/ipv4/conf/{interface}/proxy_arp_pvlan')
+ self.assertEqual('1', tmp)
+
+ tmp = read_file(f'/proc/sys/net/ipv4/conf/{interface}/rp_filter')
+ self.assertEqual('2', tmp)