summaryrefslogtreecommitdiff
path: root/smoketest
diff options
context:
space:
mode:
Diffstat (limited to 'smoketest')
-rw-r--r--smoketest/configs/dmz-guest-lan-nat-pppoe-router3
-rw-r--r--smoketest/configs/ospf-config120
-rw-r--r--smoketest/configs/small-as-bgp-vrrp683
-rwxr-xr-xsmoketest/scripts/cli/test_nat66.py156
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_bgp.py122
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_ospf.py277
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_ospfv3.py123
7 files changed, 1445 insertions, 39 deletions
diff --git a/smoketest/configs/dmz-guest-lan-nat-pppoe-router b/smoketest/configs/dmz-guest-lan-nat-pppoe-router
index 075f18b9e..e671126a6 100644
--- a/smoketest/configs/dmz-guest-lan-nat-pppoe-router
+++ b/smoketest/configs/dmz-guest-lan-nat-pppoe-router
@@ -1393,9 +1393,6 @@ service {
}
system {
config-management {
- commit-archive {
- location tftp://172.16.20.200/CONFIGS/vyos
- }
commit-revisions 200
}
conntrack {
diff --git a/smoketest/configs/ospf-config b/smoketest/configs/ospf-config
new file mode 100644
index 000000000..fe313e4b0
--- /dev/null
+++ b/smoketest/configs/ospf-config
@@ -0,0 +1,120 @@
+interfaces {
+ dummy dum0 {
+ address 172.18.254.201/32
+ }
+ ethernet eth0 {
+ duplex auto
+ smp-affinity auto
+ speed auto
+ vif 201 {
+ address 172.18.201.10/24
+ ip {
+ ospf {
+ authentication {
+ md5 {
+ key-id 10 {
+ md5-key OSPFVyOSNET
+ }
+ }
+ }
+ dead-interval 40
+ hello-interval 10
+ priority 1
+ retransmit-interval 5
+ transmit-delay 1
+ }
+ }
+ }
+ }
+ ethernet eth1 {
+ duplex auto
+ smp-affinity auto
+ speed auto
+ }
+}
+protocols {
+ ospf {
+ area 0 {
+ network 172.18.201.0/24
+ network 172.18.254.201/32
+ }
+ log-adjacency-changes {
+ }
+ parameters {
+ abr-type cisco
+ router-id 172.18.254.201
+ }
+ passive-interface default
+ passive-interface-exclude eth0.201
+ }
+ static {
+ route 0.0.0.0/0 {
+ next-hop 172.18.201.254 {
+ distance 10
+ }
+ }
+ }
+}
+service {
+ lldp {
+ interface all {
+ }
+ }
+ snmp {
+ community public {
+ authorization ro
+ network 172.16.100.0/24
+ }
+ contact "VyOS maintainers and contributors <maintainers@vyos.io>"
+ location "Jenkins"
+ }
+ ssh {
+ disable-host-validation
+ port 22
+ }
+}
+system {
+ config-management {
+ commit-revisions 200
+ }
+ console {
+ device ttyS0 {
+ speed 115200
+ }
+ }
+ domain-name vyos.net
+ host-name vyos
+ login {
+ user vyos {
+ authentication {
+ encrypted-password $6$2Ta6TWHd/U$NmrX0x9kexCimeOcYK1MfhMpITF9ELxHcaBU/znBq.X2ukQOj61fVI2UYP/xBzP4QtiTcdkgs7WOQMHWsRymO/
+ plaintext-password ""
+ }
+ level admin
+ }
+ }
+ name-server 172.16.254.30
+ 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. */
+/* === vyatta-config-version: "broadcast-relay@1:cluster@1:config-management@1:conntrack-sync@1:conntrack@1:dhcp-relay@2:dhcp-server@5:dns-forwarding@1:firewall@5:ipsec@5:l2tp@1:mdns@1:nat@4:ntp@1:pptp@1:qos@1:quagga@6:snmp@1:ssh@1:system@9:vrrp@2:wanloadbalance@3:webgui@1:webproxy@1:webproxy@2:zone-policy@1" === */
+/* Release version: 1.2.6 */
diff --git a/smoketest/configs/small-as-bgp-vrrp b/smoketest/configs/small-as-bgp-vrrp
new file mode 100644
index 000000000..61286c324
--- /dev/null
+++ b/smoketest/configs/small-as-bgp-vrrp
@@ -0,0 +1,683 @@
+firewall {
+ all-ping enable
+ broadcast-ping disable
+ config-trap disable
+ group {
+ address-group NET-VYOS-HTTPS-4 {
+ address 10.0.150.73
+ }
+ ipv6-network-group NET-VYOS-6 {
+ network 2001:db8:200::/40
+ }
+ network-group NET-VYOS-4 {
+ network 10.0.150.0/23
+ network 192.168.189.0/24
+ }
+ port-group MY-NAS-PORTS {
+ port 80
+ port 5000
+ port 5001
+ port 6022
+ port 9443
+ }
+ }
+ ipv6-name WAN-TO-VLAN15-6 {
+ default-action drop
+ enable-default-log
+ rule 1 {
+ action accept
+ state {
+ established enable
+ related enable
+ }
+ }
+ rule 2 {
+ action drop
+ log enable
+ state {
+ invalid enable
+ }
+ }
+ rule 100 {
+ action accept
+ source {
+ group {
+ network-group NET-VYOS-6
+ }
+ }
+ }
+ rule 1010 {
+ action accept
+ destination {
+ address 2001:db8:200:15::a
+ group {
+ port-group MY-NAS-PORTS
+ }
+ }
+ protocol tcp
+ }
+ }
+ ipv6-receive-redirects disable
+ ipv6-src-route disable
+ ip-src-route disable
+ log-martians enable
+ name WAN-TO-VLAN15-4 {
+ default-action drop
+ enable-default-log
+ rule 1 {
+ action accept
+ state {
+ established enable
+ related enable
+ }
+ }
+ rule 2 {
+ action drop
+ log enable
+ state {
+ invalid enable
+ }
+ }
+ rule 100 {
+ action accept
+ source {
+ group {
+ network-group NET-VYOS-4
+ }
+ }
+ }
+ rule 1000 {
+ action accept
+ destination {
+ group {
+ address-group NET-VYOS-HTTPS-4
+ }
+ port 80,443
+ }
+ protocol tcp
+ }
+ rule 1010 {
+ action accept
+ destination {
+ address 10.0.150.74
+ group {
+ port-group MY-NAS-PORTS
+ }
+ }
+ protocol tcp
+ }
+ }
+ receive-redirects disable
+ send-redirects enable
+ source-validation disable
+ syn-cookies enable
+ twa-hazards-protection disable
+}
+high-availability {
+ vrrp {
+ group VLAN5-IPv4 {
+ interface eth0.5
+ preempt-delay 180
+ priority 250
+ virtual-address 10.0.150.120/28
+ vrid 5
+ }
+ group VLAN5-IPv6 {
+ interface eth0.5
+ preempt-delay 180
+ priority 250
+ virtual-address 2001:db8:200:f0::ffff/64
+ vrid 6
+ }
+ group VLAN10-IPv4 {
+ interface eth0.10
+ preempt-delay 180
+ priority 250
+ virtual-address 10.0.150.62/26
+ vrid 10
+ }
+ group VLAN10-IPv6 {
+ interface eth0.10
+ preempt-delay 180
+ priority 250
+ virtual-address 2001:db8:200:10::ffff/64
+ virtual-address 2001:db8:200::ffff/64
+ vrid 11
+ }
+ group VLAN15-IPv4 {
+ interface eth0.15
+ preempt-delay 180
+ priority 250
+ virtual-address 10.0.150.78/28
+ vrid 15
+ }
+ group VLAN15-IPv6 {
+ interface eth0.15
+ preempt-delay 180
+ priority 250
+ virtual-address 2001:db8:200:15::ffff/64
+ vrid 16
+ }
+ group VLAN500-IPv4 {
+ interface eth0.500
+ preempt-delay 180
+ priority 250
+ virtual-address 10.0.151.238/28
+ vrid 238
+ }
+ group VLAN500-IPv6 {
+ interface eth0.500
+ preempt-delay 180
+ priority 250
+ virtual-address 2001:db8:200:50::ffff/64
+ vrid 239
+ }
+ group VLAN520-IPv4 {
+ interface eth0.520
+ preempt-delay 180
+ priority 250
+ virtual-address 10.0.150.190/28
+ vrid 52
+ }
+ group VLAN520-IPv6 {
+ interface eth0.520
+ preempt-delay 180
+ priority 250
+ virtual-address 2001:db8:200:520::ffff/64
+ vrid 53
+ }
+ group VLAN810-IPv4 {
+ interface eth0.810
+ preempt-delay 180
+ priority 250
+ virtual-address 10.0.151.30/27
+ vrid 80
+ }
+ group VLAN810-IPv6 {
+ interface eth0.810
+ preempt-delay 180
+ priority 250
+ virtual-address 2001:db8:200:102::ffff/64
+ vrid 81
+ }
+ sync-group VYOS {
+ member VLAN5-IPv4
+ member VLAN5-IPv6
+ member VLAN10-IPv4
+ member VLAN10-IPv6
+ member VLAN500-IPv4
+ member VLAN500-IPv6
+ member VLAN15-IPv4
+ member VLAN15-IPv6
+ member VLAN810-IPv6
+ member VLAN810-IPv4
+ member VLAN520-IPv4
+ member VLAN520-IPv6
+ }
+ }
+}
+interfaces {
+ dummy dum0 {
+ address 2001:db8:200:ffff::2/128
+ address 10.0.151.251/32
+ }
+ ethernet eth0 {
+ vif 5 {
+ address 10.0.150.121/28
+ address 2001:db8:200:f0::4/64
+ ip {
+ ospf {
+ authentication {
+ md5 {
+ key-id 10 {
+ md5-key vyosospfkey
+ }
+ }
+ }
+ cost 10
+ dead-interval 40
+ hello-interval 10
+ network broadcast
+ priority 200
+ retransmit-interval 5
+ transmit-delay 5
+ }
+ }
+ }
+ vif 10 {
+ address 2001:db8:200:10::1:ffff/64
+ address 2001:db8:200::1:ffff/64
+ address 10.0.150.60/26
+ }
+ vif 15 {
+ address 10.0.150.76/28
+ address 2001:db8:200:15::1:ffff/64
+ firewall {
+ out {
+ ipv6-name WAN-TO-VLAN15-6
+ name WAN-TO-VLAN15-4
+ }
+ }
+ }
+ vif 50 {
+ address 192.168.189.2/24
+ }
+ vif 110 {
+ address 2001:db8:200:101::ffff/64
+ address 10.0.151.190/27
+ address 10.0.151.158/28
+ }
+ vif 410 {
+ address 10.0.151.206/28
+ address 2001:db8:200:104::ffff/64
+ }
+ vif 450 {
+ address 2001:db8:200:103::ffff/64
+ address 10.0.151.142/29
+ disable
+ }
+ vif 500 {
+ address 10.0.151.236/28
+ address 2001:db8:200:50::1:ffff/64
+ }
+ vif 520 {
+ address 10.0.150.188/26
+ address 2001:db8:200:520::1:ffff/64
+ }
+ vif 800 {
+ address 2001:db8:200:ff::104:1/112
+ address 10.0.151.212/31
+ }
+ vif 810 {
+ address 10.0.151.28/27
+ address 2001:db8:200:102::1:ffff/64
+ }
+ }
+ ethernet eth1 {
+ }
+ loopback lo {
+ }
+}
+policy {
+ prefix-list as65000-origin-v4 {
+ rule 10 {
+ action permit
+ prefix 10.0.150.0/23
+ }
+ rule 100 {
+ action permit
+ prefix 0.0.0.0/0
+ }
+ }
+ prefix-list6 as65000-origin-v6 {
+ rule 10 {
+ action permit
+ prefix 2001:db8:200::/40
+ }
+ }
+ route-map as65010-in {
+ rule 10 {
+ action permit
+ set {
+ local-preference 30
+ }
+ }
+ }
+ route-map as65010-out {
+ rule 10 {
+ action permit
+ set {
+ as-path-prepend "65000 65000"
+ }
+ }
+ }
+}
+protocols {
+ bgp 65000 {
+ address-family {
+ ipv4-unicast {
+ network 10.0.150.0/23 {
+ }
+ }
+ ipv6-unicast {
+ network 2001:db8:200::/40 {
+ }
+ }
+ }
+ neighbor 10.0.151.222 {
+ address-family {
+ ipv4-unicast {
+ default-originate {
+ }
+ prefix-list {
+ export as65000-origin-v4
+ }
+ route-map {
+ export as65010-out
+ import as65010-in
+ }
+ soft-reconfiguration {
+ inbound
+ }
+ }
+ }
+ capability {
+ dynamic
+ }
+ remote-as 65010
+ }
+ neighbor 10.0.151.252 {
+ peer-group VYOSv4
+ }
+ neighbor 10.0.151.254 {
+ peer-group VYOSv4
+ }
+ neighbor 2001:db8:200:ffff::3 {
+ peer-group VYOSv6
+ }
+ neighbor 2001:db8:200:ffff::a {
+ peer-group VYOSv6
+ }
+ neighbor 2001:db8:200:ff::101:2 {
+ address-family {
+ ipv6-unicast {
+ capability {
+ dynamic
+ }
+ prefix-list {
+ export as65000-origin-v6
+ }
+ route-map {
+ import as65010-in
+ }
+ soft-reconfiguration {
+ inbound
+ }
+ }
+ }
+ remote-as 65010
+ }
+ parameters {
+ default {
+ no-ipv4-unicast
+ }
+ log-neighbor-changes
+ router-id 10.0.151.251
+ }
+ peer-group VYOSv4 {
+ address-family {
+ ipv4-unicast {
+ nexthop-self {
+ }
+ }
+ }
+ capability {
+ dynamic
+ }
+ remote-as 65000
+ update-source dum0
+ }
+ peer-group VYOSv6 {
+ address-family {
+ ipv6-unicast {
+ nexthop-self {
+ }
+ }
+ }
+ capability {
+ dynamic
+ }
+ remote-as 65000
+ update-source dum0
+ }
+ timers {
+ holdtime 30
+ keepalive 10
+ }
+ }
+ ospf {
+ area 0 {
+ area-type {
+ normal
+ }
+ authentication md5
+ network 10.0.151.251/32
+ network 10.0.151.208/31
+ network 10.0.150.112/28
+ }
+ parameters {
+ abr-type cisco
+ router-id 10.0.151.251
+ }
+ passive-interface default
+ passive-interface-exclude dum0
+ passive-interface-exclude eth0.5
+ redistribute {
+ connected {
+ metric-type 2
+ }
+ static {
+ metric-type 2
+ }
+ }
+ }
+ ospfv3 {
+ area 0.0.0.0 {
+ interface dum0
+ interface eth0.5
+ }
+ parameters {
+ router-id 10.0.151.251
+ }
+ redistribute {
+ connected {
+ }
+ static {
+ }
+ }
+ }
+ static {
+ route 10.0.0.0/8 {
+ MY-NAS {
+ distance 254
+ }
+ }
+ route 172.16.0.0/12 {
+ MY-NAS {
+ distance 254
+ }
+ }
+ route 192.168.0.0/16 {
+ MY-NAS {
+ distance 254
+ }
+ }
+ route 193.148.249.144/32 {
+ next-hop 192.168.189.1 {
+ }
+ }
+ route 10.0.150.0/23 {
+ MY-NAS {
+ distance 254
+ }
+ }
+ route 10.0.151.32/27 {
+ next-hop 10.0.151.5 {
+ }
+ }
+ route6 2001:db8:2fe:ffff::/64 {
+ next-hop 2001:db8:200:102::4 {
+ }
+ }
+ route6 2001:db8:2ff::/48 {
+ next-hop 2001:db8:200:101::1 {
+ }
+ }
+ route6 2001:db8:200::/40 {
+ MY-NAS {
+ distance 254
+ }
+ }
+ }
+}
+service {
+ dhcp-server {
+ shared-network-name NET-VYOS-DHCP-1 {
+ subnet 10.0.151.224/28 {
+ default-router 10.0.151.238
+ dns-server 10.0.150.2
+ dns-server 10.0.150.1
+ domain-name vyos.net
+ failover {
+ local-address 10.0.151.236
+ name NET-VYOS-DHCP-1
+ peer-address 10.0.151.237
+ status primary
+ }
+ lease 1800
+ range 0 {
+ start 10.0.151.225
+ stop 10.0.151.237
+ }
+ }
+ }
+ shared-network-name NET-VYOS-HOSTING-1 {
+ subnet 10.0.150.128/26 {
+ default-router 10.0.150.190
+ dns-server 10.0.150.2
+ dns-server 10.0.150.1
+ domain-name vyos.net
+ failover {
+ local-address 10.0.150.188
+ name NET-VYOS-HOSTING-1
+ peer-address 10.0.150.189
+ status primary
+ }
+ lease 604800
+ range 0 {
+ start 10.0.150.129
+ stop 10.0.150.187
+ }
+ }
+ }
+ }
+ lldp {
+ interface all {
+ }
+ management-address 10.0.151.251
+ snmp {
+ enable
+ }
+ }
+ router-advert {
+ interface eth4.500 {
+ default-preference high
+ name-server 2001:db8:200::1
+ name-server 2001:db8:200::2
+ prefix 2001:db8:200:50::/64 {
+ valid-lifetime infinity
+ }
+ }
+ interface eth4.520 {
+ default-preference high
+ name-server 2001:db8:200::1
+ name-server 2001:db8:200::2
+ prefix 2001:db8:200:520::/64 {
+ valid-lifetime infinity
+ }
+ }
+ }
+ snmp {
+ community public {
+ network 10.0.150.0/26
+ network 2001:db8:200:10::/64
+ }
+ contact noc@vyos.net
+ listen-address 10.0.151.251 {
+ }
+ listen-address 2001:db8:200:ffff::2 {
+ }
+ location "Jenkins"
+ }
+ ssh {
+ disable-host-validation
+ listen-address 10.0.151.251
+ listen-address 2001:db8:200:ffff::2
+ listen-address 192.168.189.2
+ loglevel fatal
+ port 22
+ }
+}
+system {
+ config-management {
+ commit-revisions 200
+ }
+ console {
+ device ttyS0 {
+ speed 115200
+ }
+ }
+ domain-name vyos.net
+ host-name vyos
+ login {
+ banner {
+ pre-login "VyOS - Network\n"
+ }
+ radius {
+ server 192.0.2.1 {
+ key SuperS3cretRADIUSkey
+ timeout 1
+ }
+ server 192.0.2.2 {
+ key SuperS3cretRADIUSkey
+ timeout 1
+ }
+ source-address 192.0.2.254
+ }
+ user vyos {
+ authentication {
+ encrypted-password $6$O5gJRlDYQpj$MtrCV9lxMnZPMbcxlU7.FI793MImNHznxGoMFgm3Q6QP3vfKJyOSRCt3Ka/GzFQyW1yZS4NS616NLHaIPPFHc0
+ plaintext-password ""
+ }
+ }
+ }
+ name-server 192.0.2.1
+ name-server 192.0.2.2
+ name-server 2001:db8:200::1
+ name-server 2001:db8:200::2
+ ntp {
+ allow-clients {
+ address 10.0.150.0/23
+ address 2001:db8:200::/40
+ }
+ listen-address 10.0.151.251
+ listen-address 2001:db8:200:ffff::2
+ server 0.de.pool.ntp.org {
+ }
+ server 1.de.pool.ntp.org {
+ }
+ server 2.de.pool.ntp.org {
+ }
+ }
+ syslog {
+ global {
+ facility all {
+ level notice
+ }
+ facility protocols {
+ level debug
+ }
+ }
+ host 10.0.150.26 {
+ facility all {
+ level all
+ }
+ }
+ }
+ 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@6: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-beta-202101151942
diff --git a/smoketest/scripts/cli/test_nat66.py b/smoketest/scripts/cli/test_nat66.py
new file mode 100755
index 000000000..ccc4196e0
--- /dev/null
+++ b/smoketest/scripts/cli/test_nat66.py
@@ -0,0 +1,156 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2020 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 os
+import jmespath
+import json
+import unittest
+
+from vyos.configsession import ConfigSession
+from vyos.configsession import ConfigSessionError
+from vyos.util import cmd
+from vyos.util import dict_search
+
+base_path = ['nat66']
+src_path = base_path + ['source']
+dst_path = base_path + ['destination']
+
+class TestNAT66(unittest.TestCase):
+ def setUp(self):
+ # ensure we can also run this test on a live system - so lets clean
+ # out the current configuration :)
+ self.session = ConfigSession(os.getpid())
+ self.session.delete(base_path)
+
+ def tearDown(self):
+ self.session.delete(base_path)
+ self.session.commit()
+
+ def test_source_nat66(self):
+ source_prefix = 'fc00::/64'
+ translation_prefix = 'fc01::/64'
+ self.session.set(src_path + ['rule', '1', 'outbound-interface', 'eth1'])
+ self.session.set(src_path + ['rule', '1', 'source', 'prefix', source_prefix])
+ self.session.set(src_path + ['rule', '1', 'translation', 'prefix', translation_prefix])
+
+ # check validate() - outbound-interface must be defined
+ self.session.commit()
+
+ tmp = cmd('sudo nft -j list table ip6 nat')
+ data_json = jmespath.search('nftables[?rule].rule[?chain]', json.loads(tmp))
+
+ for idx in range(0, len(data_json)):
+ data = data_json[idx]
+
+ self.assertEqual(data['chain'], 'POSTROUTING')
+ self.assertEqual(data['family'], 'ip6')
+ self.assertEqual(data['table'], 'nat')
+
+ iface = dict_search('match.right', data['expr'][0])
+ address = dict_search('match.right.prefix.addr', data['expr'][2])
+ mask = dict_search('match.right.prefix.len', data['expr'][2])
+ translation_address = dict_search('snat.addr.prefix.addr', data['expr'][3])
+ translation_mask = dict_search('snat.addr.prefix.len', data['expr'][3])
+
+ self.assertEqual(iface, 'eth1')
+ # check for translation address
+ self.assertEqual(f'{translation_address}/{translation_mask}', translation_prefix)
+ self.assertEqual(f'{address}/{mask}', source_prefix)
+
+ def test_destination_nat66(self):
+ destination_address = 'fc00::1'
+ translation_address = 'fc01::1'
+ self.session.set(dst_path + ['rule', '1', 'inbound-interface', 'eth1'])
+ self.session.set(dst_path + ['rule', '1', 'destination', 'address', destination_address])
+ self.session.set(dst_path + ['rule', '1', 'translation', 'address', translation_address])
+
+ # check validate() - outbound-interface must be defined
+ self.session.commit()
+
+ tmp = cmd('sudo nft -j list table ip6 nat')
+ data_json = jmespath.search('nftables[?rule].rule[?chain]', json.loads(tmp))
+
+ for idx in range(0, len(data_json)):
+ data = data_json[idx]
+
+ self.assertEqual(data['chain'], 'PREROUTING')
+ self.assertEqual(data['family'], 'ip6')
+ self.assertEqual(data['table'], 'nat')
+
+ iface = dict_search('match.right', data['expr'][0])
+ dnat_addr = dict_search('dnat.addr', data['expr'][3])
+
+ self.assertEqual(dnat_addr, translation_address)
+ self.assertEqual(iface, 'eth1')
+
+ def test_destination_nat66_prefix(self):
+ destination_prefix = 'fc00::/64'
+ translation_prefix = 'fc01::/64'
+ self.session.set(dst_path + ['rule', '1', 'inbound-interface', 'eth1'])
+ self.session.set(dst_path + ['rule', '1', 'destination', 'address', destination_prefix])
+ self.session.set(dst_path + ['rule', '1', 'translation', 'address', translation_prefix])
+
+ # check validate() - outbound-interface must be defined
+ self.session.commit()
+
+ tmp = cmd('sudo nft -j list table ip6 nat')
+ data_json = jmespath.search('nftables[?rule].rule[?chain]', json.loads(tmp))
+
+ for idx in range(0, len(data_json)):
+ data = data_json[idx]
+
+ self.assertEqual(data['chain'], 'PREROUTING')
+ self.assertEqual(data['family'], 'ip6')
+ self.assertEqual(data['table'], 'nat')
+
+ iface = dict_search('match.right', data['expr'][0])
+ translation_address = dict_search('dnat.addr.prefix.addr', data['expr'][3])
+ translation_mask = dict_search('dnat.addr.prefix.len', data['expr'][3])
+
+ self.assertEqual(f'{translation_address}/{translation_mask}', translation_prefix)
+ self.assertEqual(iface, 'eth1')
+
+ def test_source_nat66_required_translation_prefix(self):
+ # T2813: Ensure translation address is specified
+ rule = '5'
+ source_prefix = 'fc00::/64'
+ translation_prefix = 'fc00:2::/64'
+ self.session.set(src_path + ['rule', rule, 'source', 'prefix', source_prefix])
+
+ # check validate() - outbound-interface must be defined
+ with self.assertRaises(ConfigSessionError):
+ self.session.commit()
+ self.session.set(src_path + ['rule', rule, 'outbound-interface', 'eth0'])
+
+ # check validate() - translation address not specified
+ with self.assertRaises(ConfigSessionError):
+ self.session.commit()
+
+ self.session.set(src_path + ['rule', rule, 'translation', 'prefix', translation_prefix])
+ self.session.commit()
+
+ def test_nat66_no_rules(self):
+ # T3206: deleting all rules but keep the direction 'destination' or
+ # 'source' resulteds in KeyError: 'rule'.
+ #
+ # Test that both 'nat destination' and 'nat source' nodes can exist
+ # without any rule
+ self.session.set(src_path)
+ self.session.set(dst_path)
+ self.session.commit()
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_protocols_bgp.py b/smoketest/scripts/cli/test_protocols_bgp.py
index fef32741e..66ca3cdd7 100755
--- a/smoketest/scripts/cli/test_protocols_bgp.py
+++ b/smoketest/scripts/cli/test_protocols_bgp.py
@@ -26,59 +26,72 @@ PROCESS_NAME = 'bgpd'
ASN = '64512'
base_path = ['protocols', 'bgp', ASN]
+route_map_in = 'foo-map-in'
+route_map_out = 'foo-map-out'
+prefix_list_in = 'pfx-foo-in'
+prefix_list_out = 'pfx-foo-out'
+
neighbor_config = {
'192.0.2.1' : {
- 'cap_dynamic' : '',
- 'cap_ext_next': '',
- 'remote_as' : '100',
- 'adv_interv' : '400',
- 'passive' : '',
- 'password' : 'VyOS-Secure123',
- 'shutdown' : '',
- 'cap_over' : '',
- 'ttl_security': '5',
- 'local_as' : '300',
+ 'cap_dynamic' : '',
+ 'cap_ext_next' : '',
+ 'remote_as' : '100',
+ 'adv_interv' : '400',
+ 'passive' : '',
+ 'password' : 'VyOS-Secure123',
+ 'shutdown' : '',
+ 'cap_over' : '',
+ 'ttl_security' : '5',
+ 'local_as' : '300',
+ 'route_map_in' : route_map_in,
+ 'route_map_out': route_map_out,
},
'192.0.2.2' : {
- 'remote_as' : '200',
- 'shutdown' : '',
- 'no_cap_nego' : '',
- 'port' : '667',
- 'cap_strict' : '',
+ 'remote_as' : '200',
+ 'shutdown' : '',
+ 'no_cap_nego' : '',
+ 'port' : '667',
+ 'cap_strict' : '',
+ 'pfx_list_in' : prefix_list_in,
+ 'pfx_list_out' : prefix_list_out,
},
'192.0.2.3' : {
- 'description' : 'foo bar baz',
- 'remote_as' : '200',
- 'passive' : '',
- 'multi_hop' : '5',
- 'update_src' : 'lo',
+ 'description' : 'foo bar baz',
+ 'remote_as' : '200',
+ 'passive' : '',
+ 'multi_hop' : '5',
+ 'update_src' : 'lo',
},
}
peer_group_config = {
'foo' : {
- 'remote_as' : '100',
- 'passive' : '',
- 'password' : 'VyOS-Secure123',
- 'shutdown' : '',
- 'cap_over' : '',
+ 'remote_as' : '100',
+ 'passive' : '',
+ 'password' : 'VyOS-Secure123',
+ 'shutdown' : '',
+ 'cap_over' : '',
# XXX: not available in current Perl backend
# 'ttl_security': '5',
},
'bar' : {
- 'description' : 'foo peer bar group',
- 'remote_as' : '200',
- 'shutdown' : '',
- 'no_cap_nego' : '',
- 'local_as' : '300',
+ 'description' : 'foo peer bar group',
+ 'remote_as' : '200',
+ 'shutdown' : '',
+ 'no_cap_nego' : '',
+ 'local_as' : '300',
+ 'pfx_list_in' : prefix_list_in,
+ 'pfx_list_out' : prefix_list_out,
},
'baz' : {
- 'cap_dynamic' : '',
- 'cap_ext_next': '',
- 'remote_as' : '200',
- 'passive' : '',
- 'multi_hop' : '5',
- 'update_src' : 'lo',
+ 'cap_dynamic' : '',
+ 'cap_ext_next' : '',
+ 'remote_as' : '200',
+ 'passive' : '',
+ 'multi_hop' : '5',
+ 'update_src' : 'lo',
+ 'route_map_in' : route_map_in,
+ 'route_map_out': route_map_out,
},
}
@@ -89,7 +102,19 @@ class TestProtocolsBGP(unittest.TestCase):
def setUp(self):
self.session = ConfigSession(os.getpid())
+ self.session.set(['policy', 'route-map', route_map_in, 'rule', '10', 'action', 'permit'])
+ self.session.set(['policy', 'route-map', route_map_out, 'rule', '10', 'action', 'permit'])
+ self.session.set(['policy', 'prefix-list', prefix_list_in, 'rule', '10', 'action', 'permit'])
+ self.session.set(['policy', 'prefix-list', prefix_list_in, 'rule', '10', 'prefix', '192.0.2.0/25'])
+ self.session.set(['policy', 'prefix-list', prefix_list_out, 'rule', '10', 'action', 'permit'])
+ self.session.set(['policy', 'prefix-list', prefix_list_out, 'rule', '10', 'prefix', '192.0.2.128/25'])
+
def tearDown(self):
+ self.session.delete(['policy', 'route-map', route_map_in])
+ self.session.delete(['policy', 'route-map', route_map_out])
+ self.session.delete(['policy', 'prefix-list', prefix_list_in])
+ self.session.delete(['policy', 'prefix-list', prefix_list_out])
+
self.session.delete(base_path)
self.session.commit()
del self.session
@@ -122,6 +147,15 @@ class TestProtocolsBGP(unittest.TestCase):
self.assertIn(f' neighbor {peer} ttl-security hops {peer_config["ttl_security"]}', frrconfig)
if 'update_src' in peer_config:
self.assertIn(f' neighbor {peer} update-source {peer_config["update_src"]}', frrconfig)
+ if 'route_map_in' in peer_config:
+ self.assertIn(f' neighbor {peer} route-map {peer_config["route_map_in"]} in', frrconfig)
+ if 'route_map_out' in peer_config:
+ self.assertIn(f' neighbor {peer} route-map {peer_config["route_map_out"]} out', frrconfig)
+ if 'pfx_list_in' in peer_config:
+ self.assertIn(f' neighbor {peer} prefix-list {peer_config["pfx_list_in"]} in', frrconfig)
+ if 'pfx_list_out' in peer_config:
+ self.assertIn(f' neighbor {peer} prefix-list {peer_config["pfx_list_out"]} out', frrconfig)
+
def test_bgp_01_simple(self):
router_id = '127.0.0.1'
@@ -184,6 +218,14 @@ class TestProtocolsBGP(unittest.TestCase):
self.session.set(base_path + ['neighbor', neighbor, 'ttl-security', 'hops', config["ttl_security"]])
if 'update_src' in config:
self.session.set(base_path + ['neighbor', neighbor, 'update-source', config["update_src"]])
+ if 'route_map_in' in config:
+ self.session.set(base_path + ['neighbor', neighbor, 'address-family', 'ipv4-unicast', 'route-map', 'import', config["route_map_in"]])
+ if 'route_map_out' in config:
+ self.session.set(base_path + ['neighbor', neighbor, 'address-family', 'ipv4-unicast', 'route-map', 'export', config["route_map_out"]])
+ if 'pfx_list_in' in config:
+ self.session.set(base_path + ['neighbor', neighbor, 'address-family', 'ipv4-unicast', 'prefix-list', 'import', config["pfx_list_in"]])
+ if 'pfx_list_out' in config:
+ self.session.set(base_path + ['neighbor', neighbor, 'address-family', 'ipv4-unicast', 'prefix-list', 'export', config["pfx_list_out"]])
# commit changes
self.session.commit()
@@ -231,6 +273,14 @@ class TestProtocolsBGP(unittest.TestCase):
self.session.set(base_path + ['peer-group', peer_group, 'ttl-security', 'hops', config["ttl_security"]])
if 'update_src' in config:
self.session.set(base_path + ['peer-group', peer_group, 'update-source', config["update_src"]])
+ if 'route_map_in' in config:
+ self.session.set(base_path + ['peer-group', peer_group, 'address-family', 'ipv4-unicast', 'route-map', 'import', config["route_map_in"]])
+ if 'route_map_out' in config:
+ self.session.set(base_path + ['peer-group', peer_group, 'address-family', 'ipv4-unicast', 'route-map', 'export', config["route_map_out"]])
+ if 'pfx_list_in' in config:
+ self.session.set(base_path + ['peer-group', peer_group, 'address-family', 'ipv4-unicast', 'prefix-list', 'import', config["pfx_list_in"]])
+ if 'pfx_list_out' in config:
+ self.session.set(base_path + ['peer-group', peer_group, 'address-family', 'ipv4-unicast', 'prefix-list', 'export', config["pfx_list_out"]])
# commit changes
self.session.commit()
diff --git a/smoketest/scripts/cli/test_protocols_ospf.py b/smoketest/scripts/cli/test_protocols_ospf.py
new file mode 100755
index 000000000..d47838d8c
--- /dev/null
+++ b/smoketest/scripts/cli/test_protocols_ospf.py
@@ -0,0 +1,277 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2021 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 os
+import unittest
+
+from vyos.configsession import ConfigSession
+from vyos.ifconfig import Section
+from vyos.util import cmd
+from vyos.util import process_named_running
+
+PROCESS_NAME = 'ospfd'
+base_path = ['protocols', 'ospf']
+
+route_map = 'foo-bar-baz10'
+
+def getFRROSPFconfig():
+ return cmd('vtysh -c "show run" | sed -n "/router ospf/,/^!/p"')
+
+class TestProtocolsOSPF(unittest.TestCase):
+ def setUp(self):
+ self.session = ConfigSession(os.getpid())
+ self.session.set(['policy', 'route-map', route_map, 'rule', '10', 'action', 'permit'])
+ self.session.set(['policy', 'route-map', route_map, 'rule', '20', 'action', 'permit'])
+
+ def tearDown(self):
+ # Check for running process
+ self.assertTrue(process_named_running(PROCESS_NAME))
+
+ self.session.delete(['policy', 'route-map', route_map])
+ self.session.delete(base_path)
+ self.session.commit()
+ del self.session
+
+ def test_ospf_01_defaults(self):
+ # commit changes
+ self.session.set(base_path)
+ self.session.commit()
+
+ # Verify FRR ospfd configuration
+ frrconfig = getFRROSPFconfig()
+ self.assertIn(f'router ospf', frrconfig)
+ self.assertIn(f' auto-cost reference-bandwidth 100', frrconfig)
+ self.assertIn(f' timers throttle spf 200 1000 10000', frrconfig) # defaults
+
+
+ def test_ospf_02_simple(self):
+ router_id = '127.0.0.1'
+ abr_type = 'ibm'
+ bandwidth = '1000'
+ metric = '123'
+
+ self.session.set(base_path + ['auto-cost', 'reference-bandwidth', bandwidth])
+ self.session.set(base_path + ['parameters', 'router-id', router_id])
+ self.session.set(base_path + ['parameters', 'abr-type', abr_type])
+ self.session.set(base_path + ['log-adjacency-changes', 'detail'])
+ self.session.set(base_path + ['default-metric', metric])
+
+ # commit changes
+ self.session.commit()
+
+ # Verify FRR ospfd configuration
+ frrconfig = getFRROSPFconfig()
+ self.assertIn(f'router ospf', frrconfig)
+ self.assertIn(f' auto-cost reference-bandwidth {bandwidth}', frrconfig)
+ self.assertIn(f' ospf router-id {router_id}', frrconfig)
+ self.assertIn(f' ospf abr-type {abr_type}', frrconfig)
+ self.assertIn(f' timers throttle spf 200 1000 10000', frrconfig) # defaults
+ self.assertIn(f' default-metric {metric}', frrconfig)
+
+
+ def test_ospf_03_access_list(self):
+ acl = '100'
+ seq = '10'
+ protocols = ['bgp', 'connected', 'kernel', 'rip', 'static']
+
+ self.session.set(['policy', 'access-list', acl, 'rule', seq, 'action', 'permit'])
+ self.session.set(['policy', 'access-list', acl, 'rule', seq, 'source', 'any'])
+ self.session.set(['policy', 'access-list', acl, 'rule', seq, 'destination', 'any'])
+ for ptotocol in protocols:
+ self.session.set(base_path + ['access-list', acl, 'export', ptotocol])
+
+ # commit changes
+ self.session.commit()
+
+ # Verify FRR ospfd configuration
+ frrconfig = getFRROSPFconfig()
+ self.assertIn(f'router ospf', frrconfig)
+ self.assertIn(f' timers throttle spf 200 1000 10000', frrconfig) # defaults
+ for ptotocol in protocols:
+ self.assertIn(f' distribute-list {acl} out {ptotocol}', frrconfig) # defaults
+ self.session.delete(['policy', 'access-list', acl])
+
+
+ def test_ospf_04_default_originate(self):
+ seq = '100'
+ metric = '50'
+ metric_type = '1'
+
+ self.session.set(base_path + ['default-information', 'originate', 'metric', metric])
+ self.session.set(base_path + ['default-information', 'originate', 'metric-type', metric_type])
+ self.session.set(base_path + ['default-information', 'originate', 'route-map', route_map])
+
+ # commit changes
+ self.session.commit()
+
+ # Verify FRR ospfd configuration
+ frrconfig = getFRROSPFconfig()
+ self.assertIn(f'router ospf', frrconfig)
+ self.assertIn(f' timers throttle spf 200 1000 10000', frrconfig) # defaults
+ self.assertIn(f' default-information originate metric {metric} metric-type {metric_type} route-map {route_map}', frrconfig)
+
+ # Now set 'always'
+ self.session.set(base_path + ['default-information', 'originate', 'always'])
+ self.session.commit()
+
+ # Verify FRR ospfd configuration
+ frrconfig = getFRROSPFconfig()
+ self.assertIn(f' default-information originate always metric {metric} metric-type {metric_type} route-map {route_map}', frrconfig)
+
+
+ def test_ospf_05_options(self):
+ global_distance = '128'
+ intra_area = '100'
+ inter_area = '110'
+ external = '120'
+ on_startup = '30'
+ on_shutdown = '60'
+ refresh = '50'
+
+ self.session.set(base_path + ['distance', 'global', global_distance])
+ self.session.set(base_path + ['distance', 'ospf', 'external', external])
+ self.session.set(base_path + ['distance', 'ospf', 'intra-area', intra_area])
+
+ self.session.set(base_path + ['max-metric', 'router-lsa', 'on-startup', on_startup])
+ self.session.set(base_path + ['max-metric', 'router-lsa', 'on-shutdown', on_shutdown])
+
+ self.session.set(base_path + ['mpls-te', 'enable'])
+ self.session.set(base_path + ['refresh', 'timers', refresh])
+
+ # commit changes
+ self.session.commit()
+
+ # Verify FRR ospfd configuration
+ frrconfig = getFRROSPFconfig()
+ self.assertIn(f'router ospf', frrconfig)
+ self.assertIn(f' mpls-te on', frrconfig)
+ self.assertIn(f' mpls-te router-address 0.0.0.0', frrconfig) # default
+ self.assertIn(f' distance {global_distance}', frrconfig)
+ self.assertIn(f' distance ospf intra-area {intra_area} external {external}', frrconfig)
+ self.assertIn(f' max-metric router-lsa on-startup {on_startup}', frrconfig)
+ self.assertIn(f' max-metric router-lsa on-shutdown {on_shutdown}', frrconfig)
+ self.assertIn(f' refresh timer {refresh}', frrconfig)
+
+
+ # enable inter-area
+ self.session.set(base_path + ['distance', 'ospf', 'inter-area', inter_area])
+ self.session.commit()
+
+ frrconfig = getFRROSPFconfig()
+ self.assertIn(f' distance ospf intra-area {intra_area} inter-area {inter_area} external {external}', frrconfig)
+
+
+ def test_ospf_06_neighbor(self):
+ priority = '10'
+ poll_interval = '20'
+ neighbors = ['1.1.1.1', '2.2.2.2', '3.3.3.3']
+ for neighbor in neighbors:
+ self.session.set(base_path + ['neighbor', neighbor, 'priority', priority])
+ self.session.set(base_path + ['neighbor', neighbor, 'poll-interval', poll_interval])
+
+ # commit changes
+ self.session.commit()
+
+ # Verify FRR ospfd configuration
+ frrconfig = getFRROSPFconfig()
+ self.assertIn(f'router ospf', frrconfig)
+ for neighbor in neighbors:
+ self.assertIn(f' neighbor {neighbor} priority {priority} poll-interval {poll_interval}', frrconfig) # default
+
+
+ def test_ospf_07_passive_interface(self):
+ self.session.set(base_path + ['passive-interface', 'default'])
+ interfaces = Section.interfaces('ethernet')
+ for interface in interfaces:
+ self.session.set(base_path + ['passive-interface-exclude', interface])
+
+ # commit changes
+ self.session.commit()
+
+ # Verify FRR ospfd configuration
+ frrconfig = getFRROSPFconfig()
+ self.assertIn(f'router ospf', frrconfig)
+ self.assertIn(f' passive-interface default', frrconfig) # default
+ for interface in interfaces:
+ self.assertIn(f' no passive-interface {interface}', frrconfig) # default
+
+
+ def test_ospf_08_redistribute(self):
+ metric = '15'
+ metric_type = '1'
+ redistribute = ['bgp', 'connected', 'kernel', 'rip', 'static']
+
+ for protocol in redistribute:
+ self.session.set(base_path + ['redistribute', protocol, 'metric', metric])
+ self.session.set(base_path + ['redistribute', protocol, 'route-map', route_map])
+ if protocol not in ['kernel', 'static']:
+ self.session.set(base_path + ['redistribute', protocol, 'metric-type', metric_type])
+
+ # commit changes
+ self.session.commit()
+
+ # Verify FRR ospfd configuration
+ frrconfig = getFRROSPFconfig()
+ self.assertIn(f'router ospf', frrconfig)
+ for protocol in redistribute:
+ if protocol in ['kernel', 'static']:
+ self.assertIn(f' redistribute {protocol} metric {metric} route-map {route_map}', frrconfig)
+ else:
+ self.assertIn(f' redistribute {protocol} metric {metric} metric-type {metric_type} route-map {route_map}', frrconfig)
+
+
+ def test_ospf_09_area(self):
+ area = '0'
+ networks = ['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16']
+ for network in networks:
+ self.session.set(base_path + ['area', area, 'network', network])
+
+ # commit changes
+ self.session.commit()
+
+ # Verify FRR ospfd configuration
+ frrconfig = getFRROSPFconfig()
+ self.assertIn(f'router ospf', frrconfig)
+ for network in networks:
+ self.assertIn(f' network {network} area {area}', frrconfig)
+
+
+ def test_ospf_10_virtual_link(self):
+ area = '10'
+ shortcut = 'enable'
+ virtual_link = '192.0.2.1'
+ hello = '6'
+ retransmit = '5'
+ transmit = '5'
+ dead = '40'
+
+ self.session.set(base_path + ['area', area, 'shortcut', shortcut])
+ self.session.set(base_path + ['area', area, 'virtual-link', virtual_link, 'hello-interval', hello])
+ self.session.set(base_path + ['area', area, 'virtual-link', virtual_link, 'retransmit-interval', retransmit])
+ self.session.set(base_path + ['area', area, 'virtual-link', virtual_link, 'transmit-delay', transmit])
+ self.session.set(base_path + ['area', area, 'virtual-link', virtual_link, 'dead-interval', dead])
+
+ # commit changes
+ self.session.commit()
+
+ # Verify FRR ospfd configuration
+ frrconfig = getFRROSPFconfig()
+ self.assertIn(f'router ospf', frrconfig)
+ self.assertIn(f' area {area} shortcut {shortcut}', frrconfig)
+ self.assertIn(f' area {area} virtual-link {virtual_link} hello-interval {hello} retransmit-interval {retransmit} transmit-delay {transmit} dead-interval {dead}', frrconfig)
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_protocols_ospfv3.py b/smoketest/scripts/cli/test_protocols_ospfv3.py
new file mode 100755
index 000000000..297d5d996
--- /dev/null
+++ b/smoketest/scripts/cli/test_protocols_ospfv3.py
@@ -0,0 +1,123 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2021 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 os
+import unittest
+
+from vyos.configsession import ConfigSession
+from vyos.ifconfig import Section
+from vyos.util import cmd
+from vyos.util import process_named_running
+
+PROCESS_NAME = 'ospf6d'
+base_path = ['protocols', 'ospfv3']
+
+
+def getFRROSPFconfig():
+ return cmd('vtysh -c "show run" | sed -n "/router ospf6/,/^!/p"')
+
+class TestProtocolsOSPFv3(unittest.TestCase):
+ def setUp(self):
+ self.session = ConfigSession(os.getpid())
+
+ def tearDown(self):
+ # Check for running process
+ self.assertTrue(process_named_running(PROCESS_NAME))
+
+ self.session.delete(base_path)
+ self.session.commit()
+ del self.session
+
+
+ def test_ospfv3_01_basic(self):
+ area = '0'
+ seq = '10'
+ prefix = '2001:db8::/32'
+ acl_name = 'foo-acl-100'
+ router_id = '192.0.2.1'
+
+ self.session.set(['policy', 'access-list6', acl_name, 'rule', seq, 'action', 'permit'])
+ self.session.set(['policy', 'access-list6', acl_name, 'rule', seq, 'source', 'any'])
+
+ self.session.set(base_path + ['parameters', 'router-id', router_id])
+ self.session.set(base_path + ['area', area, 'range', prefix, 'advertise'])
+ self.session.set(base_path + ['area', area, 'export-list', acl_name])
+ self.session.set(base_path + ['area', area, 'import-list', acl_name])
+
+ interfaces = Section.interfaces('ethernet')
+ for interface in interfaces:
+ self.session.set(base_path + ['area', area, 'interface', interface])
+
+ # commit changes
+ self.session.commit()
+
+ # Verify FRR ospfd configuration
+ frrconfig = getFRROSPFconfig()
+ self.assertIn(f'router ospf6', frrconfig)
+ self.assertIn(f' area {area} range {prefix}', frrconfig)
+ self.assertIn(f' ospf6 router-id {router_id}', frrconfig)
+ self.assertIn(f' area {area} import-list {acl_name}', frrconfig)
+ self.assertIn(f' area {area} export-list {acl_name}', frrconfig)
+
+ for interface in interfaces:
+ self.assertIn(f' interface {interface} area {area}', frrconfig)
+
+ self.session.delete(['policy', 'access-list6', acl_name])
+
+
+ def test_ospfv3_02_distance(self):
+ dist_global = '200'
+ dist_external = '110'
+ dist_inter_area = '120'
+ dist_intra_area = '130'
+
+ self.session.set(base_path + ['distance', 'global', dist_global])
+ self.session.set(base_path + ['distance', 'ospfv3', 'external', dist_external])
+ self.session.set(base_path + ['distance', 'ospfv3', 'inter-area', dist_inter_area])
+ self.session.set(base_path + ['distance', 'ospfv3', 'intra-area', dist_intra_area])
+
+ # commit changes
+ self.session.commit()
+
+ # Verify FRR ospfd configuration
+ frrconfig = getFRROSPFconfig()
+ self.assertIn(f'router ospf6', frrconfig)
+ self.assertIn(f' distance {dist_global}', frrconfig)
+ self.assertIn(f' distance ospf6 intra-area {dist_intra_area} inter-area {dist_inter_area} external {dist_external}', frrconfig)
+
+
+ def test_ospfv3_03_redistribute(self):
+ route_map = 'foo-bar'
+ route_map_seq = '10'
+ redistribute = ['bgp', 'connected', 'kernel', 'ripng', 'static']
+
+ self.session.set(['policy', 'route-map', route_map, 'rule', route_map_seq, 'action', 'permit'])
+
+ for protocol in redistribute:
+ self.session.set(base_path + ['redistribute', protocol, 'route-map', route_map])
+
+ # commit changes
+ self.session.commit()
+
+ # Verify FRR ospfd configuration
+ frrconfig = getFRROSPFconfig()
+ self.assertIn(f'router ospf6', frrconfig)
+ for protocol in redistribute:
+ self.assertIn(f' redistribute {protocol} route-map {route_map}', frrconfig)
+
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2)