summaryrefslogtreecommitdiff
path: root/smoketest
diff options
context:
space:
mode:
authorChristian Breunig <christian@breunig.cc>2023-11-16 15:46:23 +0100
committerGitHub <noreply@github.com>2023-11-16 15:46:23 +0100
commit71823db0fceee36f631484d3ff6767569e1ca825 (patch)
tree3528e9ba826be0ba71556f2393685402f44a22ec /smoketest
parentcab0d62af86ced1ded6edefb53c2e902249b160d (diff)
parentb9493ce110fb1ae2090299a5bcb5d3c7fc3dfd60 (diff)
downloadvyos-1x-71823db0fceee36f631484d3ff6767569e1ca825.tar.gz
vyos-1x-71823db0fceee36f631484d3ff6767569e1ca825.zip
Merge pull request #2489 from vyos/mergify/bp/sagitta/pr-2476
pim(6): T5733: add missing FRR related features (backport #2476)
Diffstat (limited to 'smoketest')
-rw-r--r--smoketest/config-tests/igmp-pim-small17
-rw-r--r--smoketest/configs/igmp-pim-small84
-rw-r--r--smoketest/scripts/cli/base_interfaces_test.py4
-rw-r--r--smoketest/scripts/cli/base_vyostest_shim.py5
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_pim.py192
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_pim6.py139
6 files changed, 435 insertions, 6 deletions
diff --git a/smoketest/config-tests/igmp-pim-small b/smoketest/config-tests/igmp-pim-small
new file mode 100644
index 000000000..207c17d45
--- /dev/null
+++ b/smoketest/config-tests/igmp-pim-small
@@ -0,0 +1,17 @@
+set interfaces ethernet eth1 address '100.64.0.1/24'
+set interfaces ethernet eth2 address '172.16.0.2/24'
+set protocols pim interface eth1 igmp join 224.1.0.0 source-address '1.1.1.1'
+set protocols pim interface eth1 igmp join 224.1.0.0 source-address '1.1.1.2'
+set protocols pim interface eth1 igmp query-interval '1000'
+set protocols pim interface eth1 igmp query-max-response-time '30'
+set protocols pim interface eth1 igmp version '2'
+set protocols pim interface eth2
+set protocols pim rp address 172.16.255.1 group '224.0.0.0/4'
+set service ntp server 0.pool.ntp.org
+set service ntp server 1.pool.ntp.org
+set service ntp server 2.pool.ntp.org
+set system domain-name 'vyos.io'
+set system host-name 'vyos'
+set system login user vyos authentication encrypted-password '$6$2Ta6TWHd/U$NmrX0x9kexCimeOcYK1MfhMpITF9ELxHcaBU/znBq.X2ukQOj61fVI2UYP/xBzP4QtiTcdkgs7WOQMHWsRymO/'
+set system login user vyos authentication plaintext-password ''
+set system console device ttyS0 speed '115200'
diff --git a/smoketest/configs/igmp-pim-small b/smoketest/configs/igmp-pim-small
new file mode 100644
index 000000000..f433ff8d7
--- /dev/null
+++ b/smoketest/configs/igmp-pim-small
@@ -0,0 +1,84 @@
+interfaces {
+ ethernet eth0 {
+ duplex auto
+ speed auto
+ }
+ ethernet eth1 {
+ address 100.64.0.1/24
+ duplex auto
+ speed auto
+ }
+ ethernet eth2 {
+ address 172.16.0.2/24
+ duplex auto
+ speed auto
+ }
+}
+protocols {
+ igmp {
+ interface eth1 {
+ join 224.1.0.0 {
+ source 1.1.1.1
+ source 1.1.1.2
+ }
+ query-interval 1000
+ query-max-response-time 30
+ version 2
+ }
+ }
+ pim {
+ interface eth1 {
+ }
+ interface eth2 {
+ }
+ rp {
+ address 172.16.255.1 {
+ group 224.0.0.0/4
+ }
+ }
+ }
+}
+system {
+ config-management {
+ commit-revisions 200
+ }
+ console {
+ device ttyS0 {
+ speed 115200
+ }
+ }
+ domain-name vyos.io
+ host-name vyos
+ login {
+ user vyos {
+ authentication {
+ encrypted-password $6$2Ta6TWHd/U$NmrX0x9kexCimeOcYK1MfhMpITF9ELxHcaBU/znBq.X2ukQOj61fVI2UYP/xBzP4QtiTcdkgs7WOQMHWsRymO/
+ plaintext-password ""
+ }
+ }
+ }
+ ntp {
+ server 0.pool.ntp.org {
+ }
+ server 1.pool.ntp.org {
+ }
+ server 2.pool.ntp.org {
+ }
+ }
+ syslog {
+ global {
+ facility all {
+ level info
+ }
+ facility protocols {
+ level debug
+ }
+ }
+ }
+ time-zone Europe/Berlin
+}
+
+
+// Warning: Do not remove the following line.
+// vyos-config-version: "broadcast-relay@1:cluster@1:config-management@1:conntrack@1:conntrack-sync@1:dhcp-relay@2:dhcp-server@5:dhcpv6-server@1:dns-forwarding@3:firewall@5:https@2:interfaces@18:ipoe-server@1:ipsec@5:l2tp@3:lldp@1:mdns@1:nat@5:ntp@1:pppoe-server@5:pptp@2:qos@1:quagga@7:rpki@1:salt@1:snmp@2:ssh@2:sstp@3:system@20:vrrp@2:vyos-accel-ppp@2:wanloadbalance@3:webproxy@2:zone-policy@1"
+// Release version: 1.3.0
diff --git a/smoketest/scripts/cli/base_interfaces_test.py b/smoketest/scripts/cli/base_interfaces_test.py
index 820024dc9..277f14067 100644
--- a/smoketest/scripts/cli/base_interfaces_test.py
+++ b/smoketest/scripts/cli/base_interfaces_test.py
@@ -12,9 +12,6 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-import os
-import unittest
-
from binascii import hexlify
from netifaces import AF_INET
@@ -24,7 +21,6 @@ from netifaces import interfaces
from base_vyostest_shim import VyOSUnitTestSHIM
-from vyos.configsession import ConfigSession
from vyos.configsession import ConfigSessionError
from vyos.defaults import directories
from vyos.ifconfig import Interface
diff --git a/smoketest/scripts/cli/base_vyostest_shim.py b/smoketest/scripts/cli/base_vyostest_shim.py
index f694f539d..140642806 100644
--- a/smoketest/scripts/cli/base_vyostest_shim.py
+++ b/smoketest/scripts/cli/base_vyostest_shim.py
@@ -78,9 +78,10 @@ class VyOSUnitTestSHIM:
while run(f'sudo lsof -nP {commit_lock}') == 0:
sleep(0.250)
- def getFRRconfig(self, string, end='$', endsection='^!', daemon=''):
+ def getFRRconfig(self, string=None, end='$', endsection='^!', daemon=''):
""" Retrieve current "running configuration" from FRR """
- command = f'vtysh -c "show run {daemon} no-header" | sed -n "/^{string}{end}/,/{endsection}/p"'
+ command = f'vtysh -c "show run {daemon} no-header"'
+ if string: command += f' | sed -n "/^{string}{end}/,/{endsection}/p"'
out = cmd(command)
if self.debug:
import pprint
diff --git a/smoketest/scripts/cli/test_protocols_pim.py b/smoketest/scripts/cli/test_protocols_pim.py
new file mode 100755
index 000000000..ccfced138
--- /dev/null
+++ b/smoketest/scripts/cli/test_protocols_pim.py
@@ -0,0 +1,192 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 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
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import unittest
+
+from base_vyostest_shim import VyOSUnitTestSHIM
+
+from vyos.configsession import ConfigSessionError
+from vyos.ifconfig import Section
+from vyos.utils.process import process_named_running
+
+PROCESS_NAME = 'pimd'
+base_path = ['protocols', 'pim']
+
+class TestProtocolsPIM(VyOSUnitTestSHIM.TestCase):
+ def tearDown(self):
+ # pimd process must be running
+ self.assertTrue(process_named_running(PROCESS_NAME))
+
+ self.cli_delete(base_path)
+ self.cli_commit()
+
+ # pimd process must be stopped by now
+ self.assertFalse(process_named_running(PROCESS_NAME))
+
+ def test_01_pim_basic(self):
+ rp = '127.0.0.1'
+ group = '224.0.0.0/4'
+ hello = '100'
+ dr_priority = '64'
+
+ self.cli_set(base_path + ['rp', 'address', rp, 'group', group])
+
+ interfaces = Section.interfaces('ethernet')
+ for interface in interfaces:
+ self.cli_set(base_path + ['interface', interface , 'bfd'])
+ self.cli_set(base_path + ['interface', interface , 'dr-priority', dr_priority])
+ self.cli_set(base_path + ['interface', interface , 'hello', hello])
+ self.cli_set(base_path + ['interface', interface , 'no-bsm'])
+ self.cli_set(base_path + ['interface', interface , 'no-unicast-bsm'])
+ self.cli_set(base_path + ['interface', interface , 'passive'])
+
+ # commit changes
+ self.cli_commit()
+
+ # Verify FRR pimd configuration
+ frrconfig = self.getFRRconfig(daemon=PROCESS_NAME)
+ self.assertIn(f'ip pim rp {rp} {group}', frrconfig)
+
+ for interface in interfaces:
+ frrconfig = self.getFRRconfig(f'interface {interface}', daemon=PROCESS_NAME)
+ self.assertIn(f'interface {interface}', frrconfig)
+ self.assertIn(f' ip pim', frrconfig)
+ self.assertIn(f' ip pim bfd', frrconfig)
+ self.assertIn(f' ip pim drpriority {dr_priority}', frrconfig)
+ self.assertIn(f' ip pim hello {hello}', frrconfig)
+ self.assertIn(f' no ip pim bsm', frrconfig)
+ self.assertIn(f' no ip pim unicast-bsm', frrconfig)
+ self.assertIn(f' ip pim passive', frrconfig)
+
+ self.cli_commit()
+
+ def test_02_pim_advanced(self):
+ rp = '127.0.0.2'
+ group = '224.0.0.0/4'
+ join_prune_interval = '123'
+ rp_keep_alive_timer = '190'
+ keep_alive_timer = '180'
+ packets = '10'
+ prefix_list = 'pim-test'
+ register_suppress_time = '300'
+
+ self.cli_set(base_path + ['rp', 'address', rp, 'group', group])
+ self.cli_set(base_path + ['rp', 'keep-alive-timer', rp_keep_alive_timer])
+
+ self.cli_set(base_path + ['ecmp', 'rebalance'])
+ self.cli_set(base_path + ['join-prune-interval', join_prune_interval])
+ self.cli_set(base_path + ['keep-alive-timer', keep_alive_timer])
+ self.cli_set(base_path + ['packets', packets])
+ self.cli_set(base_path + ['register-accept-list', 'prefix-list', prefix_list])
+ self.cli_set(base_path + ['register-suppress-time', register_suppress_time])
+ self.cli_set(base_path + ['no-v6-secondary'])
+ self.cli_set(base_path + ['spt-switchover', 'infinity-and-beyond', 'prefix-list', prefix_list])
+ self.cli_set(base_path + ['ssm', 'prefix-list', prefix_list])
+
+ # check validate() - PIM require defined interfaces!
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+
+ interfaces = Section.interfaces('ethernet')
+ for interface in interfaces:
+ self.cli_set(base_path + ['interface', interface])
+
+ # commit changes
+ self.cli_commit()
+
+ # Verify FRR pimd configuration
+ frrconfig = self.getFRRconfig(daemon=PROCESS_NAME)
+ self.assertIn(f'ip pim rp {rp} {group}', frrconfig)
+ self.assertIn(f'ip pim rp keep-alive-timer {rp_keep_alive_timer}', frrconfig)
+ self.assertIn(f'ip pim ecmp rebalance', frrconfig)
+ self.assertIn(f'ip pim join-prune-interval {join_prune_interval}', frrconfig)
+ self.assertIn(f'ip pim keep-alive-timer {keep_alive_timer}', frrconfig)
+ self.assertIn(f'ip pim packets {packets}', frrconfig)
+ self.assertIn(f'ip pim register-accept-list {prefix_list}', frrconfig)
+ self.assertIn(f'ip pim register-suppress-time {register_suppress_time}', frrconfig)
+ self.assertIn(f'no ip pim send-v6-secondary', frrconfig)
+ self.assertIn(f'ip pim spt-switchover infinity-and-beyond prefix-list {prefix_list}', frrconfig)
+ self.assertIn(f'ip pim ssm prefix-list {prefix_list}', frrconfig)
+
+ def test_03_pim_igmp_proxy(self):
+ igmp_proxy = ['protocols', 'igmp-proxy']
+ rp = '127.0.0.1'
+ group = '224.0.0.0/4'
+
+ self.cli_set(base_path)
+ self.cli_set(igmp_proxy)
+
+ # check validate() - can not set both IGMP proxy and PIM
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+
+ self.cli_delete(igmp_proxy)
+
+ self.cli_set(base_path + ['rp', 'address', rp, 'group', group])
+ interfaces = Section.interfaces('ethernet')
+ for interface in interfaces:
+ self.cli_set(base_path + ['interface', interface , 'bfd'])
+
+ # commit changes
+ self.cli_commit()
+
+ def test_04_igmp(self):
+ watermark_warning = '2000'
+ query_interval = '1000'
+ query_max_response_time = '200'
+ version = '2'
+
+ igmp_join = {
+ '224.1.1.1' : { 'source' : ['1.1.1.1', '2.2.2.2', '3.3.3.3'] },
+ '224.1.2.2' : { 'source' : [] },
+ '224.1.3.3' : {},
+ }
+
+ self.cli_set(base_path + ['igmp', 'watermark-warning', watermark_warning])
+ interfaces = Section.interfaces('ethernet')
+ for interface in interfaces:
+ self.cli_set(base_path + ['interface', interface , 'igmp', 'version', version])
+ self.cli_set(base_path + ['interface', interface , 'igmp', 'query-interval', query_interval])
+ self.cli_set(base_path + ['interface', interface , 'igmp', 'query-max-response-time', query_max_response_time])
+
+ for join, join_config in igmp_join.items():
+ self.cli_set(base_path + ['interface', interface , 'igmp', 'join', join])
+ if 'source' in join_config:
+ for source in join_config['source']:
+ self.cli_set(base_path + ['interface', interface , 'igmp', 'join', join, 'source-address', source])
+
+ self.cli_commit()
+
+ frrconfig = self.getFRRconfig(daemon=PROCESS_NAME)
+ self.assertIn(f'ip igmp watermark-warn {watermark_warning}', frrconfig)
+
+ for interface in interfaces:
+ frrconfig = self.getFRRconfig(f'interface {interface}', daemon=PROCESS_NAME)
+ self.assertIn(f'interface {interface}', frrconfig)
+ self.assertIn(f' ip igmp', frrconfig)
+ self.assertIn(f' ip igmp version {version}', frrconfig)
+ self.assertIn(f' ip igmp query-interval {query_interval}', frrconfig)
+ self.assertIn(f' ip igmp query-max-response-time {query_max_response_time}', frrconfig)
+
+ for join, join_config in igmp_join.items():
+ if 'source' in join_config:
+ for source in join_config['source']:
+ self.assertIn(f' ip igmp join {join} {source}', frrconfig)
+ else:
+ self.assertIn(f' ip igmp join {join}', frrconfig)
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_protocols_pim6.py b/smoketest/scripts/cli/test_protocols_pim6.py
new file mode 100755
index 000000000..e22a7c722
--- /dev/null
+++ b/smoketest/scripts/cli/test_protocols_pim6.py
@@ -0,0 +1,139 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 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
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import unittest
+
+from base_vyostest_shim import VyOSUnitTestSHIM
+from vyos.configsession import ConfigSessionError
+from vyos.ifconfig import Section
+from vyos.utils.process import process_named_running
+
+PROCESS_NAME = 'pim6d'
+base_path = ['protocols', 'pim6']
+
+class TestProtocolsPIMv6(VyOSUnitTestSHIM.TestCase):
+ def tearDown(self):
+ # Check for running process
+ self.assertTrue(process_named_running(PROCESS_NAME))
+
+ self.cli_delete(base_path)
+ self.cli_commit()
+
+ # Check for running process
+ self.assertTrue(process_named_running(PROCESS_NAME))
+
+ def test_pim6_01_mld_simple(self):
+ # commit changes
+ interfaces = Section.interfaces('ethernet')
+ for interface in interfaces:
+ self.cli_set(base_path + ['interface', interface])
+
+ self.cli_commit()
+
+ # Verify FRR pim6d configuration
+ for interface in interfaces:
+ config = self.getFRRconfig(f'interface {interface}', daemon=PROCESS_NAME)
+ self.assertIn(f'interface {interface}', config)
+ self.assertIn(f' ipv6 mld', config)
+ self.assertNotIn(f' ipv6 mld version 1', config)
+
+ # Change to MLD version 1
+ for interface in interfaces:
+ self.cli_set(base_path + ['interface', interface, 'mld', 'version', '1'])
+
+ self.cli_commit()
+
+ # Verify FRR pim6d configuration
+ for interface in interfaces:
+ config = self.getFRRconfig(f'interface {interface}', daemon=PROCESS_NAME)
+ self.assertIn(f'interface {interface}', config)
+ self.assertIn(f' ipv6 mld', config)
+ self.assertIn(f' ipv6 mld version 1', config)
+
+ def test_pim6_02_mld_join(self):
+ interfaces = Section.interfaces('ethernet')
+ # Use an invalid multicast group address
+ for interface in interfaces:
+ self.cli_set(base_path + ['interface', interface, 'mld', 'join', 'fd00::1234'])
+
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+ self.cli_delete(base_path + ['interface'])
+
+ # Use a valid multicast group address
+ for interface in interfaces:
+ self.cli_set(base_path + ['interface', interface, 'mld', 'join', 'ff18::1234'])
+
+ self.cli_commit()
+
+ # Verify FRR pim6d configuration
+ for interface in interfaces:
+ config = self.getFRRconfig(f'interface {interface}', daemon=PROCESS_NAME)
+ self.assertIn(f'interface {interface}', config)
+ self.assertIn(f' ipv6 mld join ff18::1234', config)
+
+ # Join a source-specific multicast group
+ for interface in interfaces:
+ self.cli_set(base_path + ['interface', interface, 'mld', 'join', 'ff38::5678', 'source', '2001:db8::5678'])
+
+ self.cli_commit()
+
+ # Verify FRR pim6d configuration
+ for interface in interfaces:
+ config = self.getFRRconfig(f'interface {interface}', daemon=PROCESS_NAME)
+ self.assertIn(f'interface {interface}', config)
+ self.assertIn(f' ipv6 mld join ff38::5678 2001:db8::5678', config)
+
+ def test_pim6_03_basic(self):
+ interfaces = Section.interfaces('ethernet')
+ join_prune_interval = '123'
+ keep_alive_timer = '77'
+ packets = '5'
+ register_suppress_time = '99'
+ dr_priority = '100'
+ hello = '50'
+
+ self.cli_set(base_path + ['join-prune-interval', join_prune_interval])
+ self.cli_set(base_path + ['keep-alive-timer', keep_alive_timer])
+ self.cli_set(base_path + ['packets', packets])
+ self.cli_set(base_path + ['register-suppress-time', register_suppress_time])
+
+ for interface in interfaces:
+ self.cli_set(base_path + ['interface', interface, 'dr-priority', dr_priority])
+ self.cli_set(base_path + ['interface', interface, 'hello', hello])
+ self.cli_set(base_path + ['interface', interface, 'no-bsm'])
+ self.cli_set(base_path + ['interface', interface, 'no-unicast-bsm'])
+ self.cli_set(base_path + ['interface', interface, 'passive'])
+
+ self.cli_commit()
+
+ # Verify FRR pim6d configuration
+ config = self.getFRRconfig(daemon=PROCESS_NAME)
+ self.assertIn(f'ipv6 pim join-prune-interval {join_prune_interval}', config)
+ self.assertIn(f'ipv6 pim keep-alive-timer {keep_alive_timer}', config)
+ self.assertIn(f'ipv6 pim packets {packets}', config)
+ self.assertIn(f'ipv6 pim register-suppress-time {register_suppress_time}', config)
+
+ for interface in interfaces:
+ config = self.getFRRconfig(f'interface {interface}', daemon=PROCESS_NAME)
+ self.assertIn(f' ipv6 pim drpriority {dr_priority}', config)
+ self.assertIn(f' ipv6 pim hello {hello}', config)
+ self.assertIn(f' no ipv6 pim bsm', config)
+ self.assertIn(f' no ipv6 pim unicast-bsm', config)
+ self.assertIn(f' ipv6 pim passive', config)
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2)