diff options
Diffstat (limited to 'smoketest')
38 files changed, 5312 insertions, 331 deletions
diff --git a/smoketest/configs/bgp-bfd-communities b/smoketest/configs/bgp-bfd-communities new file mode 100644 index 000000000..3b3056a51 --- /dev/null +++ b/smoketest/configs/bgp-bfd-communities @@ -0,0 +1,533 @@ +interfaces { + ethernet eth0 { + address 192.0.2.100/25 + address 2001:db8::ffff/64 + } + loopback lo { + } +} +policy { + large-community-list ANYCAST_ALL { + rule 10 { + action permit + description "Allow all anycast from anywhere" + regex "4242420696:100:.*" + } + } + large-community-list ANYCAST_INT { + rule 10 { + action permit + description "Allow all anycast from int" + regex 4242420696:100:1 + } + } + prefix-list BGP-BACKBONE-IN { + description "Inbound backbone routes from other sites" + rule 10 { + action deny + description "Block default route" + prefix 0.0.0.0/0 + } + rule 20 { + action deny + description "Block int primary" + ge 21 + prefix 192.168.0.0/20 + } + rule 30 { + action deny + description "Block loopbacks" + ge 25 + prefix 192.168.253.0/24 + } + rule 40 { + action deny + description "Block backbone peering" + ge 25 + prefix 192.168.254.0/24 + } + rule 999 { + action permit + description "Allow everything else" + ge 1 + prefix 0.0.0.0/0 + } + } + prefix-list BGP-BACKBONE-OUT { + description "Outbound backbone routes to other sites" + rule 10 { + action permit + description "Int primary" + ge 23 + prefix 192.168.0.0/20 + } + } + prefix-list GLOBAL { + description "Globally redistributed routes" + rule 10 { + action permit + prefix 192.168.100.1/32 + } + rule 20 { + action permit + prefix 192.168.7.128/25 + } + } + prefix-list6 BGP-BACKBONE-IN-V6 { + description "Inbound backbone routes from other sites" + rule 10 { + action deny + description "Block default route" + prefix ::/0 + } + rule 20 { + action deny + description "Block int primary" + ge 53 + prefix fd52:d62e:8011::/52 + } + rule 30 { + action deny + description "Block peering and stuff" + ge 53 + prefix fd52:d62e:8011:f000::/52 + } + rule 999 { + action permit + description "Allow everything else" + ge 1 + prefix ::/0 + } + } + prefix-list6 BGP-BACKBONE-OUT-V6 { + description "Outbound backbone routes to other sites" + rule 10 { + action permit + ge 64 + prefix fd52:d62e:8011::/52 + } + } + prefix-list6 GLOBAL-V6 { + description "Globally redistributed routes" + rule 10 { + action permit + ge 64 + prefix fd52:d62e:8011:2::/63 + } + } + route-map BGP-REDISTRIBUTE { + rule 10 { + action permit + description "Prepend AS and allow VPN and modem" + match { + ip { + address { + prefix-list GLOBAL + } + } + } + set { + as-path-prepend 4242420666 + } + } + rule 20 { + action permit + description "Allow VPN" + match { + ipv6 { + address { + prefix-list GLOBAL-V6 + } + } + } + } + } + route-map BGP-BACKBONE-IN { + rule 10 { + action permit + match { + ip { + address { + prefix-list BGP-BACKBONE-IN + } + } + } + } + rule 20 { + action permit + match { + ipv6 { + address { + prefix-list BGP-BACKBONE-IN-V6 + } + } + } + } + rule 30 { + action permit + match { + large-community { + large-community-list ANYCAST_ALL + } + } + } + } + route-map BGP-BACKBONE-OUT { + rule 10 { + action permit + match { + ip { + address { + prefix-list BGP-BACKBONE-OUT + } + } + } + } + rule 20 { + action permit + match { + ipv6 { + address { + prefix-list BGP-BACKBONE-OUT-V6 + } + } + } + } + rule 30 { + action permit + match { + large-community { + large-community-list ANYCAST_INT + } + } + set { + as-path-prepend 4242420666 + } + } + } +} +protocols { + bfd { + peer 192.168.253.1 { + interval { + receive 50 + transmit 50 + } + multihop + source { + address 192.168.253.3 + } + } + peer 192.168.253.2 { + interval { + receive 50 + transmit 50 + } + multihop + source { + address 192.168.253.3 + } + } + peer 192.168.253.6 { + interval { + receive 50 + transmit 50 + } + multihop + source { + address 192.168.253.3 + } + } + peer 192.168.253.7 { + interval { + receive 50 + transmit 50 + } + multihop + source { + address 192.168.253.3 + } + } + peer 192.168.253.12 { + interval { + receive 100 + transmit 100 + } + multihop + source { + address 192.168.253.3 + } + } + peer fd52:d62e:8011:fffe:192:168:253:1 { + interval { + receive 50 + transmit 50 + } + multihop + source { + address fd52:d62e:8011:fffe:192:168:253:3 + } + } + peer fd52:d62e:8011:fffe:192:168:253:2 { + interval { + receive 50 + transmit 50 + } + multihop + source { + address fd52:d62e:8011:fffe:192:168:253:3 + } + } + peer fd52:d62e:8011:fffe:192:168:253:6 { + interval { + receive 50 + transmit 50 + } + multihop + source { + address fd52:d62e:8011:fffe:192:168:253:3 + } + } + peer fd52:d62e:8011:fffe:192:168:253:7 { + interval { + receive 50 + transmit 50 + } + multihop + source { + address fd52:d62e:8011:fffe:192:168:253:3 + } + } + peer fd52:d62e:8011:fffe:192:168:253:12 { + interval { + receive 100 + transmit 100 + } + multihop + source { + address fd52:d62e:8011:fffe:192:168:253:3 + } + } + } + bgp 4242420666 { + address-family { + ipv4-unicast { + redistribute { + connected { + route-map BGP-REDISTRIBUTE + } + static { + route-map BGP-REDISTRIBUTE + } + } + } + ipv6-unicast { + redistribute { + connected { + route-map BGP-REDISTRIBUTE + } + } + } + } + neighbor 192.168.253.1 { + peer-group INT + } + neighbor 192.168.253.2 { + peer-group INT + } + neighbor 192.168.253.6 { + peer-group DAL13 + } + neighbor 192.168.253.7 { + peer-group DAL13 + } + neighbor 192.168.253.12 { + address-family { + ipv4-unicast { + route-map { + export BGP-BACKBONE-OUT + import BGP-BACKBONE-IN + } + soft-reconfiguration { + inbound + } + } + } + bfd { + } + ebgp-multihop 2 + remote-as 4242420669 + update-source dum0 + } + neighbor fd52:d62e:8011:fffe:192:168:253:1 { + address-family { + ipv6-unicast { + peer-group INTv6 + } + } + } + neighbor fd52:d62e:8011:fffe:192:168:253:2 { + address-family { + ipv6-unicast { + peer-group INTv6 + } + } + } + neighbor fd52:d62e:8011:fffe:192:168:253:6 { + address-family { + ipv6-unicast { + peer-group DAL13v6 + } + } + } + neighbor fd52:d62e:8011:fffe:192:168:253:7 { + address-family { + ipv6-unicast { + peer-group DAL13v6 + } + } + } + neighbor fd52:d62e:8011:fffe:192:168:253:12 { + address-family { + ipv6-unicast { + route-map { + export BGP-BACKBONE-OUT + import BGP-BACKBONE-IN + } + soft-reconfiguration { + inbound + } + } + } + bfd { + } + ebgp-multihop 2 + remote-as 4242420669 + update-source dum0 + } + parameters { + confederation { + identifier 4242420696 + peers 4242420668 + peers 4242420669 + } + default { + no-ipv4-unicast + } + distance { + global { + external 220 + internal 220 + local 220 + } + } + graceful-restart { + } + } + peer-group DAL13 { + address-family { + ipv4-unicast { + route-map { + export BGP-BACKBONE-OUT + import BGP-BACKBONE-IN + } + soft-reconfiguration { + inbound + } + } + } + bfd + ebgp-multihop 2 + remote-as 4242420668 + update-source dum0 + } + peer-group DAL13v6 { + address-family { + ipv6-unicast { + route-map { + export BGP-BACKBONE-OUT + import BGP-BACKBONE-IN + } + soft-reconfiguration { + inbound + } + } + } + bfd + ebgp-multihop 2 + remote-as 4242420668 + update-source dum0 + } + peer-group INT { + address-family { + ipv4-unicast { + default-originate { + } + soft-reconfiguration { + inbound + } + } + } + bfd + remote-as 4242420666 + update-source dum0 + } + peer-group INTv6 { + address-family { + ipv6-unicast { + default-originate { + } + soft-reconfiguration { + inbound + } + } + } + bfd + remote-as 4242420666 + update-source dum0 + } + } +} +system { + config-management { + commit-revisions 200 + } + console { + device ttyS0 { + speed 115200 + } + } + host-name vyos + login { + user vyos { + authentication { + encrypted-password $6$2Ta6TWHd/U$NmrX0x9kexCimeOcYK1MfhMpITF9ELxHcaBU/znBq.X2ukQOj61fVI2UYP/xBzP4QtiTcdkgs7WOQMHWsRymO/ + plaintext-password "" + } + level admin + } + } + 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@10:vrrp@2:wanloadbalance@3:webgui@1:webproxy@1:webproxy@2:zone-policy@1" === */ +/* Release version: 1.2.6-S1 */ diff --git a/smoketest/configs/bgp-big-as-cloud b/smoketest/configs/bgp-big-as-cloud new file mode 100644 index 000000000..df3ae015c --- /dev/null +++ b/smoketest/configs/bgp-big-as-cloud @@ -0,0 +1,1952 @@ +firewall { + all-ping enable + broadcast-ping disable + config-trap disable + group { + address-group bgp-peers-4 { + address 192.0.68.3 + address 192.0.68.2 + address 192.0.176.193 + address 192.0.52.0-192.0.52.255 + address 192.0.53.0-192.0.53.255 + address 192.0.16.209 + address 192.0.192.0-192.0.192.255 + address 192.0.193.0-192.0.193.255 + address 192.0.194.0-192.0.194.255 + address 192.0.195.0-192.0.195.255 + address 192.0.196.0-192.0.196.255 + address 192.0.197.0-192.0.197.255 + address 192.0.198.0-192.0.198.255 + address 192.0.199.0-192.0.199.255 + } + address-group vrrp-peers-4 { + address 192.0.68.3 + address 192.0.160.3 + address 192.0.98.3 + address 192.0.71.131 + address 192.0.84.67 + address 192.0.71.195 + address 192.0.71.115 + address 192.0.70.195 + address 192.0.70.179 + address 192.0.70.163 + address 192.0.70.147 + address 192.0.70.131 + address 192.0.70.19 + address 192.0.70.3 + address 192.0.71.99 + address 192.0.68.67 + address 192.0.71.67 + address 192.0.71.3 + address 192.0.68.35 + address 192.0.68.131 + address 192.0.69.2 + address 192.0.70.35 + address 192.0.70.67 + } + ipv6-address-group bgp-peers-6 { + address 2001:db8:c::3 + address 2001:db8:1000::2e9 + address 2001:db8:24::fb + address 2001:db8:24::fc + address 2001:db8:24::fd + address 2001:db8:24::2e + address 2001:db8:24::3d + address 2001:db8:24::4a + address 2001:db8:24::5e + address 2001:db8:24::7 + address 2001:db8:24::11 + address 2001:db8:24::18 + address 2001:db8:24::20 + address 2001:db8:24::22 + address 2001:db8:24::31 + address 2001:db8:24::58 + address 2001:db8:24::64 + address 2001:db8:24::a5 + address 2001:db8:24::aa + address 2001:db8:24::ab + address 2001:db8:24::b0 + address 2001:db8:24::b3 + address 2001:db8:24::bd + address 2001:db8:24::c + address 2001:db8:24::d2 + address 2001:db8:24::d3 + address 2001:db8:838::1 + address 2001:db8::1a27:5051:c09d + address 2001:db8::1a27:5051:c19d + address 2001:db8::20ad:0:1 + address 2001:db8::2306:0:1 + address 2001:db8::2ca:0:1 + address 2001:db8::2ca:0:2 + address 2001:db8::2ca:0:3 + address 2001:db8::2ca:0:4 + } + ipv6-address-group vrrp-peers-6 { + address fe80::fe89:15cf + } + ipv6-network-group AS64512-6 { + network 2001::/29 + } + network-group AS64512-4 { + network 192.0.68.0/22 + network 192.0.98.0/24 + network 192.0.160.0/24 + network 192.0.84.0/22 + } + } + ipv6-name management-to-local-6 { + default-action reject + enable-default-log + } + ipv6-name management-to-peers-6 { + default-action reject + enable-default-log + } + ipv6-name management-to-servers-6 { + default-action reject + enable-default-log + } + ipv6-name peers-to-local-6 { + default-action reject + enable-default-log + rule 500 { + action accept + protocol icmpv6 + } + rule 501 { + action accept + protocol vrrp + source { + group { + address-group vrrp-peers-6 + } + } + } + rule 502 { + action accept + destination { + port bgp + } + protocol tcp + source { + group { + address-group bgp-peers-6 + } + } + } + rule 503 { + action accept + protocol tcp + source { + group { + address-group bgp-peers-6 + } + port bgp + } + } + } + ipv6-name peers-to-management-6 { + default-action reject + enable-default-log + } + ipv6-name peers-to-servers-6 { + default-action reject + enable-default-log + rule 9990 { + action reject + source { + group { + network-group AS64512-6 + } + } + } + rule 9999 { + action accept + destination { + group { + network-group AS64512-6 + } + } + } + } + ipv6-name servers-to-local-6 { + default-action reject + enable-default-log + rule 500 { + action accept + protocol icmpv6 + } + rule 501 { + action accept + protocol vrrp + source { + group { + address-group vrrp-peers-6 + } + } + } + rule 511 { + action accept + protocol tcp_udp + source { + port 53 + } + } + } + ipv6-name servers-to-management-6 { + default-action reject + enable-default-log + } + ipv6-name servers-to-peers-6 { + default-action reject + enable-default-log + rule 51 { + action accept + source { + group { + network-group AS64512-6 + } + } + } + } + ipv6-receive-redirects disable + ipv6-src-route disable + ip-src-route disable + log-martians enable + name management-to-local-4 { + default-action reject + enable-default-log + rule 500 { + action accept + protocol icmp + } + rule 501 { + action accept + destination { + port 22 + } + protocol tcp + } + rule 502 { + action accept + destination { + port snmp + } + protocol udp + } + } + name management-to-peers-4 { + default-action reject + enable-default-log + } + name management-to-servers-4 { + default-action reject + enable-default-log + } + name peers-to-local-4 { + default-action reject + enable-default-log + rule 500 { + action accept + protocol icmp + } + rule 501 { + action accept + protocol vrrp + source { + group { + address-group vrrp-peers-4 + } + } + } + rule 502 { + action accept + destination { + port bgp + } + protocol tcp + source { + group { + address-group bgp-peers-4 + } + } + } + rule 503 { + action accept + protocol tcp + source { + group { + address-group bgp-peers-4 + } + port bgp + } + } + } + name peers-to-management-4 { + default-action reject + enable-default-log + } + name peers-to-servers-4 { + default-action reject + enable-default-log + rule 9990 { + action reject + source { + group { + network-group AS64512-4 + } + } + } + rule 9999 { + action accept + destination { + group { + network-group AS64512-4 + } + } + } + } + name servers-to-local-4 { + default-action reject + enable-default-log + rule 500 { + action accept + protocol icmp + } + rule 501 { + action accept + protocol vrrp + source { + group { + address-group vrrp-peers-4 + } + } + } + rule 511 { + action accept + protocol tcp_udp + source { + port 53 + } + } + } + name servers-to-management-4 { + default-action reject + enable-default-log + } + name servers-to-peers-4 { + default-action reject + enable-default-log + rule 51 { + action accept + source { + group { + network-group AS64512-4 + } + } + } + } + receive-redirects disable + send-redirects enable + source-validation disable + syn-cookies enable + twa-hazards-protection disable +} +high-availability { + vrrp { + group 11-4 { + interface eth0.11 + priority 200 + virtual-address 192.0.68.1/27 + vrid 4 + } + group 11-6 { + interface eth0.11 + priority 200 + virtual-address 2001:db8:c::1/64 + vrid 6 + } + group 102-4 { + interface eth0.102 + priority 200 + virtual-address 192.0.98.1/24 + vrid 4 + } + group 102-6 { + interface eth0.102 + priority 200 + virtual-address 2001:db8:0:102::1/64 + vrid 6 + } + group 105-4 { + interface eth0.105 + priority 200 + virtual-address 192.0.160.1/24 + vrid 4 + } + group 105-6 { + interface eth0.105 + priority 200 + virtual-address 2001:db8:0:105::1/64 + vrid 6 + } + group 1001-4 { + interface eth0.1001 + priority 200 + virtual-address 192.0.68.33/27 + vrid 4 + } + group 1001-6 { + interface eth0.1001 + priority 200 + virtual-address 2001:db8:0:1001::1/64 + vrid 6 + } + group 1002-4 { + interface eth0.1002 + priority 200 + virtual-address 192.0.68.65/26 + vrid 4 + } + group 1002-6 { + interface eth0.1002 + priority 200 + virtual-address 2001:db8:0:1002::1/64 + vrid 6 + } + group 1003-4 { + interface eth0.1003 + priority 200 + virtual-address 192.0.68.129/25 + vrid 4 + } + group 1003-6 { + interface eth0.1003 + priority 200 + virtual-address 2001:db8:0:1003::1/64 + vrid 6 + } + group 1004-4 { + interface eth0.1004 + priority 200 + virtual-address 192.0.69.1/24 + vrid 4 + } + group 1004-6 { + interface eth0.1004 + priority 200 + virtual-address 2001:db8:0:1004::1/64 + vrid 6 + } + group 1005-4 { + interface eth0.1005 + priority 200 + virtual-address 192.0.70.1/28 + vrid 4 + } + group 1005-6 { + interface eth0.1005 + priority 200 + virtual-address 2001:db8:0:1005::1/64 + vrid 6 + } + group 1006-4 { + interface eth0.1006 + priority 200 + virtual-address 192.0.70.17/28 + vrid 4 + } + group 1006-6 { + interface eth0.1006 + priority 200 + virtual-address 2001:db8:0:1006::1/64 + vrid 6 + } + group 1007-4 { + interface eth0.1007 + priority 200 + virtual-address 192.0.70.33/27 + vrid 4 + } + group 1007-6 { + interface eth0.1007 + priority 200 + virtual-address 2001:db8:0:1007::1/64 + vrid 6 + } + group 1008-4 { + interface eth0.1008 + priority 200 + virtual-address 192.0.70.65/26 + vrid 4 + } + group 1008-6 { + interface eth0.1008 + priority 200 + virtual-address 2001:db8:0:1008::1/64 + vrid 6 + } + group 1009-4 { + interface eth0.1009 + priority 200 + virtual-address 192.0.70.129/28 + vrid 4 + } + group 1009-6 { + interface eth0.1009 + priority 200 + virtual-address 2001:db8:0:1009::1/64 + vrid 6 + } + group 1010-4 { + interface eth0.1010 + priority 200 + virtual-address 192.0.70.145/28 + vrid 4 + } + group 1010-6 { + interface eth0.1010 + priority 200 + virtual-address 2001:db8:0:1010::1/64 + vrid 6 + } + group 1011-4 { + interface eth0.1011 + priority 200 + virtual-address 192.0.70.161/28 + vrid 4 + } + group 1011-6 { + interface eth0.1011 + priority 200 + virtual-address 2001:db8:0:1011::1/64 + vrid 6 + } + group 1012-4 { + interface eth0.1012 + priority 200 + virtual-address 192.0.70.177/28 + vrid 4 + } + group 1012-6 { + interface eth0.1012 + priority 200 + virtual-address 2001:db8:0:1012::1/64 + vrid 6 + } + group 1013-4 { + interface eth0.1013 + priority 200 + virtual-address 192.0.70.193/27 + vrid 4 + } + group 1013-6 { + interface eth0.1013 + priority 200 + virtual-address 2001:db8:0:1013::1/64 + vrid 6 + } + group 1014-4 { + interface eth0.1014 + priority 200 + virtual-address 192.0.84.65/26 + vrid 4 + } + group 1014-6 { + interface eth0.1014 + priority 200 + virtual-address 2001:db8:0:1014::1/64 + vrid 6 + } + group 1015-4 { + interface eth0.1015 + priority 200 + virtual-address 192.0.71.1/26 + vrid 4 + } + group 1015-6 { + interface eth0.1015 + priority 200 + virtual-address 2001:db8:0:1015::1/64 + vrid 6 + } + group 1016-4 { + interface eth0.1016 + priority 200 + virtual-address 192.0.71.65/27 + vrid 4 + } + group 1016-6 { + interface eth0.1016 + priority 200 + virtual-address 2001:db8:0:1016::1/64 + vrid 6 + } + group 1017-4 { + interface eth0.1017 + priority 200 + virtual-address 192.0.71.97/28 + vrid 4 + } + group 1017-6 { + interface eth0.1017 + priority 200 + virtual-address 2001:db8:0:1017::1/64 + vrid 6 + } + group 1018-4 { + interface eth0.1018 + priority 200 + virtual-address 192.0.71.113/28 + vrid 4 + } + group 1018-6 { + interface eth0.1018 + priority 200 + virtual-address 2001:db8:0:1018::1/64 + vrid 6 + } + group 1019-4 { + interface eth0.1019 + priority 200 + virtual-address 192.0.71.129/26 + vrid 4 + } + group 1019-6 { + interface eth0.1019 + priority 200 + virtual-address 2001:db8:0:1019::1/64 + vrid 6 + } + group 1020-4 { + interface eth0.1020 + priority 200 + virtual-address 192.0.71.193/26 + vrid 4 + } + group 1020-6 { + interface eth0.1020 + priority 200 + virtual-address 2001:db8:0:1020::1/64 + vrid 6 + } + } +} +interfaces { + ethernet eth0 { + address 192.0.0.11/16 + duplex auto + smp-affinity auto + speed auto + vif 11 { + address 192.0.68.2/27 + address 2001:db8:c::2/64 + } + vif 102 { + address 192.0.98.2/24 + address 2001:db8:0:102::2/64 + } + vif 105 { + address 192.0.160.2/24 + address 2001:db8:0:105::2/64 + } + vif 838 { + address 192.0.16.210/30 + address 2001:db8:838::2/64 + } + vif 886 { + address 192.0.193.224/21 + address 2001:db8::3:669:0:1/64 + } + vif 1001 { + address 192.0.68.34/27 + address 2001:db8:0:1001::2/64 + } + vif 1002 { + address 192.0.68.66/26 + address 2001:db8:0:1002::2/64 + } + vif 1003 { + address 192.0.68.130/25 + address 2001:db8:0:1003::2/64 + } + vif 1004 { + address 192.0.69.2/24 + address 2001:db8:0:1004::2/64 + } + vif 1005 { + address 192.0.70.2/28 + address 2001:db8:0:1005::2/64 + } + vif 1006 { + address 192.0.70.18/28 + address 2001:db8:0:1006::2/64 + } + vif 1007 { + address 192.0.70.34/27 + address 2001:db8:0:1007::2/64 + } + vif 1008 { + address 192.0.70.66/26 + address 2001:db8:0:1008::2/64 + } + vif 1009 { + address 192.0.70.130/28 + address 2001:db8:0:1009::2/64 + } + vif 1010 { + address 192.0.70.146/28 + address 2001:db8:0:1010::2/64 + } + vif 1011 { + address 192.0.70.162/28 + address 2001:db8:0:1011::2/64 + } + vif 1012 { + address 192.0.70.178/28 + address 2001:db8:0:1012::2/64 + } + vif 1013 { + address 192.0.70.194/27 + address 2001:db8:0:1013::3/64 + } + vif 1014 { + address 192.0.84.66/26 + address 2001:db8:0:1014::2/64 + } + vif 1015 { + address 192.0.71.2/26 + address 2001:db8:0:1015::2/64 + } + vif 1016 { + address 192.0.71.66/27 + address 2001:db8:0:1016::2/64 + } + vif 1017 { + address 192.0.71.98/28 + address 2001:db8:0:1017::2/64 + } + vif 1018 { + address 192.0.71.114/28 + address 2001:db8:0:1018::2/64 + } + vif 1019 { + address 192.0.71.130/26 + address 2001:db8:0:1019::2/64 + } + vif 1020 { + address 192.0.71.194/26 + address 2001:db8:0:1020::2/64 + } + vif 4088 { + address 2001:db8:24::c7/64 + address 192.0.52.199/23 + } + vif 4089 { + address 192.0.176.194/30 + address 2001:db8:1000::2ea/126 + } + } + loopback lo { + } +} +policy { + as-path-list AS64513-AS64514 { + rule 10 { + action permit + regex "^64513 64514$" + } + } + as-path-list AS64512 { + rule 10 { + action permit + regex ^$ + } + } + prefix-list defaultV4 { + rule 10 { + action permit + prefix 0.0.0.0/0 + } + } + prefix-list hostrouteV4 { + rule 10 { + action permit + ge 32 + prefix 192.0.160.0/24 + } + rule 20 { + action permit + ge 32 + prefix 192.0.98.0/24 + } + rule 30 { + action permit + ge 32 + prefix 192.0.68.0/22 + } + rule 40 { + action permit + ge 32 + prefix 192.0.84.0/22 + } + } + prefix-list vyosV4 { + rule 10 { + action permit + prefix 192.0.160.0/24 + } + rule 20 { + action permit + prefix 192.0.98.0/24 + } + rule 30 { + action permit + prefix 192.0.68.0/22 + } + rule 40 { + action permit + prefix 192.0.84.0/22 + } + } + prefix-list privateV4 { + rule 10 { + action permit + le 32 + prefix 192.0.0.0/8 + } + rule 20 { + action permit + le 32 + prefix 192.0.0.0/12 + } + rule 30 { + action permit + le 32 + prefix 192.0.0.0/16 + } + } + prefix-list6 all6 { + rule 10 { + action permit + ge 4 + prefix 2000::/3 + } + } + prefix-list6 hostrouteV6 { + rule 20 { + action permit + ge 128 + prefix 2001:db8::/29 + } + } + prefix-list6 vyosV6 { + rule 20 { + action permit + prefix 2001:db8::/29 + } + } + prefix-list6 privateV6 { + rule 10 { + action permit + prefix fc00::/7 + } + } + route-map ExportRouteMap { + rule 5 { + action permit + match { + as-path AS64512 + ip { + address { + prefix-list hostrouteV4 + } + } + } + set { + community 65000:666 + } + } + rule 10 { + action permit + match { + as-path AS64512 + ip { + address { + prefix-list vyosV4 + } + } + } + } + rule 15 { + action permit + match { + as-path AS64512 + ipv6 { + address { + prefix-list hostrouteV6 + } + } + } + set { + community 65000:666 + } + } + rule 20 { + action permit + match { + as-path AS64512 + ipv6 { + address { + prefix-list vyosV6 + } + } + } + } + rule 100 { + action deny + } + } + route-map ExportRouteMapAS64515 { + rule 10 { + action permit + match { + ipv6 { + address { + prefix-list all6 + } + } + } + } + rule 20 { + action deny + match { + ip { + address { + prefix-list defaultV4 + } + } + } + } + rule 100 { + action deny + } + } + route-map ExportRouteMapAS64516 { + rule 5 { + action permit + match { + as-path AS64512 + ip { + address { + prefix-list hostrouteV4 + } + } + } + set { + community 65000:666 + } + } + rule 10 { + action permit + match { + as-path AS64512 + ip { + address { + prefix-list vyosV4 + } + } + } + } + rule 15 { + action permit + match { + as-path AS64512 + ipv6 { + address { + prefix-list hostrouteV6 + } + } + } + set { + community 65000:666 + } + } + rule 20 { + action permit + match { + as-path AS64512 + ipv6 { + address { + prefix-list vyosV6 + } + } + } + } + rule 100 { + action deny + } + } + route-map ExportRouteMapAS64517 { + rule 5 { + action permit + match { + as-path AS64512 + ip { + address { + prefix-list hostrouteV4 + } + } + } + set { + community 64517:666 + } + } + rule 10 { + action permit + match { + as-path AS64512 + ip { + address { + prefix-list vyosV4 + } + } + } + } + rule 15 { + action permit + match { + as-path AS64512 + ipv6 { + address { + prefix-list hostrouteV6 + } + } + } + set { + community 64517:666 + } + } + rule 20 { + action permit + match { + as-path AS64512 + ipv6 { + address { + prefix-list vyosV6 + } + } + } + } + rule 100 { + action deny + } + } + route-map ExportRouteMapAS64513 { + rule 5 { + action permit + match { + as-path AS64512 + ip { + address { + prefix-list hostrouteV4 + } + } + } + set { + community 64513:666 + } + } + rule 10 { + action permit + match { + as-path AS64512 + ip { + address { + prefix-list vyosV4 + } + } + } + } + rule 15 { + action permit + match { + as-path AS64512 + ipv6 { + address { + prefix-list hostrouteV6 + } + } + } + set { + community 64513:666 + } + } + rule 20 { + action permit + match { + as-path AS64512 + ipv6 { + address { + prefix-list vyosV6 + } + } + } + } + rule 100 { + action deny + } + } + route-map ImportRouteMap { + rule 10 { + action deny + match { + ip { + address { + prefix-list privateV4 + } + } + } + } + rule 15 { + action deny + match { + ipv6 { + address { + prefix-list privateV6 + } + } + } + } + rule 20 { + action deny + match { + ip { + address { + prefix-list vyosV4 + } + } + } + } + rule 30 { + action deny + match { + ipv6 { + address { + prefix-list vyosV6 + } + } + } + } + rule 40 { + action deny + match { + as-path AS64512 + } + } + rule 50 { + action permit + match { + as-path AS64513-AS64514 + } + set { + weight 10001 + } + } + rule 65535 { + action permit + } + } +} +protocols { + bgp 64500 { + address-family { + ipv4-unicast { + network 192.0.98.0/24 { + } + network 192.0.160.0/24 { + } + network 192.0.68.0/22 { + } + network 192.0.84.0/22 { + } + redistribute { + static { + route-map ExportRouteMap + } + } + } + ipv6-unicast { + network 2001:db8::/29 { + } + redistribute { + static { + route-map ExportRouteMap + } + } + } + } + neighbor 192.0.16.209 { + address-family { + ipv4-unicast { + route-map { + export ExportRouteMapAS64516 + import ImportRouteMap + } + } + } + remote-as 64501 + } + neighbor 192.0.192.6 { + address-family { + ipv4-unicast { + maximum-prefix 100 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64502 + } + neighbor 192.0.192.157 { + address-family { + ipv4-unicast { + maximum-prefix 350000 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64503 + } + neighbor 192.0.192.228 { + address-family { + ipv4-unicast { + maximum-prefix 10000 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64504 + } + neighbor 192.0.193.157 { + address-family { + ipv4-unicast { + maximum-prefix 350000 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64505 + } + neighbor 192.0.193.202 { + address-family { + ipv4-unicast { + maximum-prefix 10000 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64506 + } + neighbor 192.0.193.223 { + address-family { + ipv4-unicast { + maximum-prefix 10000 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64507 + } + neighbor 192.0.194.161 { + address-family { + ipv4-unicast { + maximum-prefix 10000 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64508 + } + neighbor 192.0.194.171 { + address-family { + ipv4-unicast { + maximum-prefix 10000 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64509 + } + neighbor 192.0.176.193 { + address-family { + ipv4-unicast { + route-map { + export ExportRouteMapAS64516 + import ImportRouteMap + } + } + } + remote-as 64510 + } + neighbor 192.0.52.12 { + address-family { + ipv4-unicast { + maximum-prefix 300 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64511 + } + neighbor 192.0.52.17 { + address-family { + ipv4-unicast { + maximum-prefix 75 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + password vyosvyos + remote-as 64512 + } + neighbor 192.0.52.24 { + address-family { + ipv4-unicast { + maximum-prefix 300 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64513 + } + neighbor 192.0.52.32 { + address-family { + ipv4-unicast { + maximum-prefix 50 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + password vyosfoooo + remote-as 64514 + } + neighbor 192.0.52.34 { + address-family { + ipv4-unicast { + maximum-prefix 10 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64515 + } + neighbor 192.0.52.46 { + address-family { + ipv4-unicast { + maximum-prefix 10 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64516 + } + neighbor 192.0.52.49 { + address-family { + ipv4-unicast { + maximum-prefix 75 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + password secret + remote-as 64517 + } + neighbor 192.0.52.74 { + address-family { + ipv4-unicast { + maximum-prefix 15000 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + password secretvyos + remote-as 64518 + } + neighbor 192.0.52.94 { + address-family { + ipv4-unicast { + maximum-prefix 250 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64519 + } + neighbor 192.0.52.100 { + address-family { + ipv4-unicast { + maximum-prefix 50 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64520 + } + neighbor 192.0.52.119 { + address-family { + ipv4-unicast { + maximum-prefix 30 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64521 + } + neighbor 192.0.52.165 { + address-family { + ipv4-unicast { + maximum-prefix 50 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64522 + } + neighbor 192.0.52.170 { + address-family { + ipv4-unicast { + maximum-prefix 150000 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64523 + } + neighbor 192.0.52.171 { + address-family { + ipv4-unicast { + maximum-prefix 10000 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64524 + } + neighbor 192.0.52.179 { + address-family { + ipv4-unicast { + maximum-prefix 20 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64525 + } + neighbor 192.0.52.189 { + address-family { + ipv4-unicast { + maximum-prefix 1000 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64526 + } + neighbor 192.0.52.210 { + address-family { + ipv4-unicast { + maximum-prefix 15 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64527 + } + neighbor 192.0.52.211 { + address-family { + ipv4-unicast { + maximum-prefix 15 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64528 + } + neighbor 192.0.52.251 { + address-family { + ipv4-unicast { + route-map { + export ExportRouteMap + import ImportRouteMap + } + weight 1010 + } + } + remote-as 64529 + } + neighbor 192.0.52.252 { + address-family { + ipv4-unicast { + route-map { + export ExportRouteMap + } + weight 1010 + } + } + remote-as 64530 + } + neighbor 192.0.52.253 { + address-family { + ipv4-unicast { + route-map { + export ExportRouteMapAS64515 + import ImportRouteMap + } + } + } + passive + remote-as 64531 + } + neighbor 192.0.68.3 { + address-family { + ipv4-unicast { + nexthop-self + soft-reconfiguration { + inbound + } + } + } + remote-as 64532 + update-source 192.0.68.2 + } + neighbor 2001:db8:838::1 { + address-family { + ipv6-unicast { + route-map { + export ExportRouteMapAS64516 + import ImportRouteMap + } + } + } + remote-as 64533 + } + neighbor 2001:db8:c::3 { + address-family { + ipv6-unicast { + nexthop-self + soft-reconfiguration { + inbound + } + } + } + remote-as 64534 + update-source 2001:db8:c::2 + } + neighbor 2001:db8:24::2e { + address-family { + ipv6-unicast { + maximum-prefix 5 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + password vyossecret + remote-as 64535 + } + neighbor 2001:db8:24::4a { + address-family { + ipv6-unicast { + maximum-prefix 1000 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64536 + } + neighbor 2001:db8:24::5e { + address-family { + ipv6-unicast { + maximum-prefix 200 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64537 + } + neighbor 2001:db8:24::11 { + address-family { + ipv6-unicast { + maximum-prefix 20 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64538 + } + neighbor 2001:db8:24::18 { + address-family { + ipv6-unicast { + maximum-prefix 300 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64539 + } + neighbor 2001:db8:24::20 { + address-family { + ipv6-unicast { + maximum-prefix 10 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64540 + } + neighbor 2001:db8:24::22 { + address-family { + ipv6-unicast { + maximum-prefix 5 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64541 + } + neighbor 2001:db8:24::31 { + address-family { + ipv6-unicast { + maximum-prefix 20 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64542 + } + neighbor 2001:db8:24::58 { + address-family { + ipv6-unicast { + maximum-prefix 15 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64543 + } + neighbor 2001:db8:24::64 { + address-family { + ipv6-unicast { + maximum-prefix 10 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + password geheim + remote-as 64544 + } + neighbor 2001:db8:24::a5 { + address-family { + ipv6-unicast { + maximum-prefix 10 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64545 + } + neighbor 2001:db8:24::aa { + address-family { + ipv6-unicast { + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64546 + } + neighbor 2001:db8:24::ab { + address-family { + ipv6-unicast { + maximum-prefix 1800 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + remote-as 64547 + } + neighbor 2001:db8:24::b0 { + address-family { + ipv6-unicast { + maximum-prefix 5 + route-map { + export ExportRouteMap + import ImportRouteMap + } + } + } + password secret123 + remote-as 64548 + } + parameters { + default { + no-ipv4-unicast + } + log-neighbor-changes + router-id 192.0.68.2 + } + } + static { + route 192.0.98.0/24 { + blackhole { + } + } + route 192.0.160.0/24 { + blackhole { + } + } + route 192.0.68.0/22 { + blackhole { + } + } + route 192.0.84.0/22 { + blackhole { + } + } + route6 2001:db8::/29 { + blackhole { + } + } + } +} +system { + config-management { + commit-revisions 100 + } + console { + device ttyS0 { + speed 115200 + } + } + flow-accounting { + disable-imt + interface eth0.4088 + interface eth0.4089 + netflow { + engine-id 1 + server 192.0.2.55 { + port 2055 + } + version 9 + } + syslog-facility daemon + } + host-name vyos + login { + user vyos { + authentication { + encrypted-password $6$2Ta6TWHd/U$NmrX0x9kexCimeOcYK1MfhMpITF9ELxHcaBU/znBq.X2ukQOj61fVI2UYP/xBzP4QtiTcdkgs7WOQMHWsRymO/ + plaintext-password "" + } + } + } + name-server 2001:db8::1 + name-server 2001:db8::2 + name-server 192.0.2.1 + name-server 192.0.2.2 + ntp { + server 0.pool.ntp.org { + } + server 1.pool.ntp.org { + } + server 2.pool.ntp.org { + } + } + syslog { + global { + facility all { + level all + } + preserve-fqdn + } + } + time-zone Europe/Zurich +} +zone-policy { + zone local { + default-action drop + from management { + firewall { + ipv6-name management-to-local-6 + name management-to-local-4 + } + } + from peers { + firewall { + ipv6-name peers-to-local-6 + name peers-to-local-4 + } + } + from servers { + firewall { + ipv6-name servers-to-local-6 + name servers-to-local-4 + } + } + local-zone + } + zone management { + default-action reject + from peers { + firewall { + ipv6-name peers-to-management-6 + name peers-to-management-4 + } + } + from servers { + firewall { + ipv6-name servers-to-management-6 + name servers-to-management-4 + } + } + interface eth0 + } + zone peers { + default-action reject + from management { + firewall { + ipv6-name management-to-peers-6 + name management-to-peers-4 + } + } + from servers { + firewall { + ipv6-name servers-to-peers-6 + name servers-to-peers-4 + } + } + interface eth0.4088 + interface eth0.4089 + interface eth0.11 + interface eth0.838 + interface eth0.886 + } + zone servers { + default-action reject + from management { + firewall { + ipv6-name management-to-servers-6 + name management-to-servers-4 + } + } + from peers { + firewall { + ipv6-name peers-to-servers-6 + name peers-to-servers-4 + } + } + interface eth0.1001 + interface eth0.105 + interface eth0.102 + interface eth0.1019 + interface eth0.1014 + interface eth0.1020 + interface eth0.1018 + interface eth0.1013 + interface eth0.1012 + interface eth0.1011 + interface eth0.1010 + interface eth0.1009 + interface eth0.1006 + interface eth0.1005 + interface eth0.1017 + interface eth0.1016 + interface eth0.1002 + interface eth0.1015 + interface eth0.1003 + interface eth0.1004 + interface eth0.1007 + interface eth0.1008 + } +} + + +/* 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.5 */ diff --git a/smoketest/configs/small-as-bgp-vrrp b/smoketest/configs/bgp-small-as index 61286c324..6b953a3f6 100644 --- a/smoketest/configs/small-as-bgp-vrrp +++ b/smoketest/configs/bgp-small-as @@ -345,6 +345,10 @@ protocols { } } neighbor 10.0.151.222 { + disable-send-community { + extended + standard + } address-family { ipv4-unicast { default-originate { diff --git a/smoketest/configs/bgp-ixp b/smoketest/configs/bgp-small-internet-exchange index de6213b50..de6213b50 100644 --- a/smoketest/configs/bgp-ixp +++ b/smoketest/configs/bgp-small-internet-exchange diff --git a/smoketest/configs/dmz-guest-lan-nat-pppoe-router b/smoketest/configs/dialup-router-complex index e671126a6..fef79ea56 100644 --- a/smoketest/configs/dmz-guest-lan-nat-pppoe-router +++ b/smoketest/configs/dialup-router-complex @@ -1660,4 +1660,3 @@ zone-policy { // 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-202101091250 - diff --git a/smoketest/configs/dialup-router-medium-vpn b/smoketest/configs/dialup-router-medium-vpn new file mode 100644 index 000000000..dfb3d9621 --- /dev/null +++ b/smoketest/configs/dialup-router-medium-vpn @@ -0,0 +1,707 @@ +firewall { + all-ping enable + broadcast-ping disable + config-trap disable + ipv6-receive-redirects disable + ipv6-src-route disable + ip-src-route disable + log-martians enable + options { + interface vtun0 { + adjust-mss 1380 + } + interface vtun1 { + adjust-mss 1380 + } + interface vtun2 { + adjust-mss 1380 + } + interface wg0 { + adjust-mss 1380 + } + interface wg1 { + adjust-mss 1380 + } + } + receive-redirects disable + send-redirects enable + source-validation disable + syn-cookies disable + twa-hazards-protection enable +} +high-availability { + vrrp { + group LAN { + hello-source-address 192.168.0.250 + interface eth1 + peer-address 192.168.0.251 + priority 200 + virtual-address 192.168.0.1/24 + vrid 1 + } + sync-group failover-group { + member LAN + } + } +} +interfaces { + ethernet eth0 { + duplex auto + mtu 9000 + offload-options { + generic-receive on + generic-segmentation on + scatter-gather on + tcp-segmentation on + } + pppoe 0 { + default-route auto + mtu 1500 + name-server auto + password password + traffic-policy { + out shape-17mbit + } + user-id vyos + password vyos + } + smp-affinity auto + speed auto + } + ethernet eth1 { + address 192.168.0.250/24 + duplex auto + ip { + source-validation strict + } + mtu 9000 + offload-options { + generic-receive on + generic-segmentation on + scatter-gather on + tcp-segmentation on + } + policy { + route LAN-POLICY-BASED-ROUTING + } + smp-affinity auto + speed auto + traffic-policy { + out shape-94mbit + } + } + loopback lo { + } + openvpn vtun0 { + encryption aes256 + hash sha512 + ip { + source-validation strict + } + keep-alive { + failure-count 3 + interval 30 + } + mode client + openvpn-option "comp-lzo adaptive" + openvpn-option fast-io + openvpn-option persist-key + openvpn-option "reneg-sec 86400" + persistent-tunnel + remote-host 192.0.2.10 + tls { + ca-cert-file /config/auth/ovpn_test_ca.pem + cert-file /config/auth/ovpn_test_server.pem + key-file /config/auth/ovpn_test_server.key + auth-file /config/auth/ovpn_test_tls_auth.key + } + } + openvpn vtun1 { + authentication { + password vyos1 + username vyos1 + } + encryption aes256 + hash sha1 + keep-alive { + failure-count 3 + interval 30 + } + mode client + openvpn-option "comp-lzo adaptive" + openvpn-option "tun-mtu 1500" + openvpn-option "tun-mtu-extra 32" + openvpn-option "mssfix 1300" + openvpn-option persist-key + openvpn-option "mute 10" + openvpn-option route-nopull + openvpn-option fast-io + openvpn-option "reneg-sec 86400" + persistent-tunnel + protocol udp + remote-host 01.foo.com + remote-port 1194 + tls { + ca-cert-file /config/auth/ovpn_test_ca.pem + auth-file /config/auth/ovpn_test_tls_auth.key + } + } + openvpn vtun2 { + authentication { + password vyos2 + username vyos2 + } + disable + encryption aes256 + hash sha512 + keep-alive { + failure-count 3 + interval 30 + } + mode client + openvpn-option "tun-mtu 1500" + openvpn-option "tun-mtu-extra 32" + openvpn-option "mssfix 1300" + openvpn-option persist-key + openvpn-option "mute 10" + openvpn-option route-nopull + openvpn-option fast-io + openvpn-option remote-random + openvpn-option "reneg-sec 86400" + persistent-tunnel + protocol udp + remote-host 01.myvpn.com + remote-host 02.myvpn.com + remote-host 03.myvpn.com + remote-port 1194 + tls { + ca-cert-file /config/auth/ovpn_test_ca.pem + auth-file /config/auth/ovpn_test_tls_auth.key + } + } + wireguard wg0 { + address 192.168.10.1/24 + peer red { + allowed-ips 192.168.10.4/32 + persistent-keepalive 20 + preshared-key CumyXX7osvUT9AwnS+m2TEfCaL0Ptc2LfuZ78Sujuk8= + pubkey ALGWvMJCKpHF2tVH3hEIHqUe9iFfAmZATUUok/WQzks= + } + peer green { + allowed-ips 192.168.10.21/32 + persistent-keepalive 25 + preshared-key LQ9qmlTh9G4nZu4UgElxRUwg7JB/qoV799aADJOijnY= + pubkey 5iQUD3VoCDBTPXAPHOwUJ0p7xzKGHEY/wQmgvBVmaFI= + } + peer blue { + allowed-ips 192.168.10.3/32 + persistent-keepalive 20 + preshared-key ztFDOY9UyaDvn8N3X97SFMDwIfv7EEfuUIPP2yab6UI= + pubkey G4pZishpMRrLmd96Kr6V7LIuNGdcUb81gWaYZ+FWkG0= + } + peer pink { + allowed-ips 192.168.10.14/32 + allowed-ips 192.168.10.16/32 + persistent-keepalive 25 + preshared-key Qi9Odyx0/5itLPN5C5bEy3uMX+tmdl15QbakxpKlWqQ= + pubkey i4qNPmxyy9EETL4tIoZOLKJF4p7IlVmpAE15gglnAk4= + } + port 7777 + } + wireguard wg1 { + address 10.89.90.2/30 + peer sam { + allowed-ips 10.1.1.0/24 + allowed-ips 10.89.90.1/32 + endpoint 192.0.2.45:1200 + persistent-keepalive 20 + preshared-key XpFtzx2Z+nR8pBv9/sSf7I94OkZkVYTz0AeU5Q/QQUE= + pubkey v5zfKGvH6W/lfDXJ0en96lvKo1gfFxMUWxe02+Fj5BU= + } + port 7778 + } +} +nat { + destination { + rule 50 { + destination { + port 49371 + } + inbound-interface pppoe0 + protocol tcp_udp + translation { + address 192.168.0.5 + } + } + rule 51 { + destination { + port 58050-58051 + } + inbound-interface pppoe0 + protocol tcp + translation { + address 192.168.0.5 + } + } + rule 52 { + destination { + port 22067-22070 + } + inbound-interface pppoe0 + protocol tcp + translation { + address 192.168.0.5 + } + } + rule 53 { + destination { + port 34342 + } + inbound-interface pppoe0 + protocol tcp_udp + translation { + address 192.168.0.121 + } + } + rule 54 { + destination { + port 45459 + } + inbound-interface pppoe0 + protocol tcp_udp + translation { + address 192.168.0.120 + } + } + rule 55 { + destination { + port 22 + } + inbound-interface pppoe0 + protocol tcp + translation { + address 192.168.0.5 + } + } + rule 56 { + destination { + port 8920 + } + inbound-interface pppoe0 + protocol tcp + translation { + address 192.168.0.5 + } + } + rule 60 { + destination { + port 80,443 + } + inbound-interface pppoe0 + protocol tcp + translation { + address 192.168.0.5 + } + } + rule 70 { + destination { + port 5001 + } + inbound-interface pppoe0 + protocol tcp + translation { + address 192.168.0.5 + } + } + rule 80 { + destination { + port 25 + } + inbound-interface pppoe0 + protocol tcp + translation { + address 192.168.0.5 + } + } + rule 90 { + destination { + port 8123 + } + inbound-interface pppoe0 + protocol tcp + translation { + address 192.168.0.7 + } + } + rule 91 { + destination { + port 1880 + } + inbound-interface pppoe0 + protocol tcp + translation { + address 192.168.0.7 + } + } + rule 500 { + destination { + address !192.168.0.0/24 + port 53 + } + inbound-interface eth1 + protocol tcp_udp + source { + address !192.168.0.1-192.168.0.5 + } + translation { + address 192.168.0.1 + } + } + } + source { + rule 1000 { + outbound-interface pppoe0 + translation { + address masquerade + } + } + rule 2000 { + outbound-interface vtun0 + source { + address 192.168.0.0/16 + } + translation { + address masquerade + } + } + rule 3000 { + outbound-interface vtun1 + translation { + address masquerade + } + } + } +} +policy { + prefix-list user2-routes { + rule 1 { + action permit + prefix 10.1.1.0/24 + } + } + prefix-list user1-routes { + rule 1 { + action permit + prefix 192.168.0.0/24 + } + } + route LAN-POLICY-BASED-ROUTING { + rule 10 { + destination { + } + disable + set { + table 10 + } + source { + address 192.168.0.119/32 + } + } + rule 20 { + destination { + } + set { + table 100 + } + source { + address 192.168.0.240 + } + } + } + route-map rm-static-to-bgp { + rule 10 { + action permit + match { + ip { + address { + prefix-list user1-routes + } + } + } + } + rule 100 { + action deny + } + } +} +protocols { + bgp 64590 { + address-family { + ipv4-unicast { + redistribute { + connected { + route-map rm-static-to-bgp + } + } + } + } + neighbor 10.89.90.1 { + address-family { + ipv4-unicast { + nexthop-self + prefix-list { + export user1-routes + import user2-routes + } + soft-reconfiguration { + inbound + } + } + } + password ericandre2020 + remote-as 64589 + } + parameters { + log-neighbor-changes + router-id 10.89.90.2 + } + } + static { + interface-route 100.64.160.23/32 { + next-hop-interface pppoe0 { + } + } + interface-route 100.64.165.25/32 { + next-hop-interface pppoe0 { + } + } + interface-route 100.64.165.26/32 { + next-hop-interface pppoe0 { + } + } + interface-route 100.64.198.0/24 { + next-hop-interface vtun0 { + } + } + table 10 { + interface-route 0.0.0.0/0 { + next-hop-interface vtun1 { + } + } + } + table 100 { + route 0.0.0.0/0 { + next-hop 192.168.10.5 { + } + } + } + } +} +service { + conntrack-sync { + accept-protocol tcp,udp,icmp + disable-external-cache + event-listen-queue-size 8 + expect-sync all + failover-mechanism { + vrrp { + sync-group failover-group + } + } + interface eth1 { + peer 192.168.0.251 + } + sync-queue-size 8 + } + dhcp-server { + shared-network-name LAN { + authoritative + subnet 192.168.0.0/24 { + default-router 192.168.0.1 + dns-server 192.168.0.1 + domain-name vyos.net + domain-search vyos.net + failover { + local-address 192.168.0.250 + name DHCP02 + peer-address 192.168.0.251 + status primary + } + lease 86400 + range LANDynamic { + start 192.168.0.200 + stop 192.168.0.240 + } + static-mapping IPTV { + ip-address 192.168.0.104 + mac-address 00:50:01:31:b5:f6 + } + static-mapping McPrintus { + ip-address 192.168.0.60 + mac-address 00:50:01:58:ac:95 + static-mapping-parameters "option domain-name-servers 192.168.0.6,192.168.0.17;" + } + static-mapping Audio { + ip-address 192.168.0.107 + mac-address 00:50:01:dc:91:14 + } + static-mapping Mobile01 { + ip-address 192.168.0.109 + mac-address 00:50:01:bc:ac:51 + static-mapping-parameters "option domain-name-servers 192.168.0.6,192.168.0.17;" + } + static-mapping sand { + ip-address 192.168.0.110 + mac-address 00:50:01:af:c5:d2 + } + static-mapping pearTV { + ip-address 192.168.0.101 + mac-address 00:50:01:ba:62:79 + } + static-mapping camera1 { + ip-address 192.168.0.11 + mac-address 00:50:01:70:b9:4d + static-mapping-parameters "option domain-name-servers 192.168.0.6,192.168.0.17;" + } + static-mapping camera2 { + ip-address 192.168.0.12 + mac-address 00:50:01:70:b7:4f + static-mapping-parameters "option domain-name-servers 192.168.0.6,192.168.0.17;" + } + } + } + } + dns { + forwarding { + allow-from 192.168.0.0/16 + cache-size 8192 + dnssec off + listen-address 192.168.0.1 + name-server 100.64.0.1 + name-server 100.64.0.2 + } + } + snmp { + community AwesomeCommunity { + authorization ro + client 127.0.0.1 + network 192.168.0.0/24 + } + } + ssh { + access-control { + allow { + user vyos + } + } + client-keepalive-interval 60 + listen-address 192.168.0.1 + listen-address 192.168.10.1 + listen-address 192.168.0.250 + } +} +system { + config-management { + commit-revisions 100 + } + console { + device ttyS0 { + speed 115200 + } + } + host-name vyos + ip { + arp { + table-size 1024 + } + } + login { + user vyos { + authentication { + encrypted-password $6$O5gJRlDYQpj$MtrCV9lxMnZPMbcxlU7.FI793MImNHznxGoMFgm3Q6QP3vfKJyOSRCt3Ka/GzFQyW1yZS4NS616NLHaIPPFHc0 + plaintext-password "" + } + } + } + name-server 192.168.0.1 + ntp { + allow-clients { + address 192.168.0.0/16 + } + listen-address 192.168.0.1 + listen-address 192.168.0.250 + server nz.pool.ntp.org { + prefer + } + } + options { + beep-if-fully-booted + ctrl-alt-del-action ignore + reboot-on-panic true + } + static-host-mapping { + host-name host104.vyos.net { + inet 192.168.0.104 + } + host-name host60.vyos.net { + inet 192.168.0.60 + } + host-name host107.vyos.net { + inet 192.168.0.107 + } + host-name host109.vyos.net { + inet 192.168.0.109 + } + } + sysctl { + custom net.core.default_qdisc { + value fq + } + custom net.ipv4.tcp_congestion_control { + value bbr + } + } + syslog { + global { + facility all { + level info + } + } + host 192.168.0.252 { + facility all { + level debug + protocol udp + } + } + } + task-scheduler { + task Update-Blacklists { + executable { + path /config/scripts/vyos-foo-update.script + } + interval 3h + } + } + time-zone Pacific/Auckland +} +traffic-policy { + shaper shape-17mbit { + bandwidth 17mbit + default { + bandwidth 100% + burst 15k + queue-type fq-codel + } + } + shaper shape-94mbit { + bandwidth 94mbit + default { + bandwidth 100% + burst 15k + queue-type fq-codel + } + } +} +/* 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/ospf-config b/smoketest/configs/ospf-small index fe313e4b0..d95ba4ea4 100644 --- a/smoketest/configs/ospf-config +++ b/smoketest/configs/ospf-small @@ -24,12 +24,27 @@ interfaces { transmit-delay 1 } } + ipv6 { + ospfv3 { + bfd + cost 40 + } + } } } ethernet eth1 { duplex auto smp-affinity auto speed auto + ipv6 { + ospfv3 { + bfd + cost 60 + mtu-ignore + network broadcast + priority 20 + } + } } } protocols { @@ -47,6 +62,13 @@ protocols { passive-interface default passive-interface-exclude eth0.201 } + ospfv3 { + area 0.0.0.0 { + interface eth0 + interface eth1 + interface eth2 + } + } static { route 0.0.0.0/0 { next-hop 172.18.201.254 { diff --git a/smoketest/configs/pppoe-client b/smoketest/configs/pppoe-client deleted file mode 100644 index ef6a26423..000000000 --- a/smoketest/configs/pppoe-client +++ /dev/null @@ -1,62 +0,0 @@ -interfaces { - ethernet eth0 { - } - loopback lo { - } - pppoe pppoe0 { - authentication { - password bar - user foo - } - connect-on-demand - default-route auto - mtu 1492 - source-interface eth0 - } -} -service { - ssh { - } -} -system { - config-management { - commit-revisions 100 - } - console { - device ttyS0 { - speed 115200 - } - } - 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 - } - } - } -} - - -// 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@13: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@19:vrrp@2:vyos-accel-ppp@2:wanloadbalance@3:webgui@1:webproxy@2:zone-policy@1" -// Release version: 1.3-rolling-202010241631 diff --git a/smoketest/configs/rip-router b/smoketest/configs/rip-router new file mode 100644 index 000000000..09cb11a45 --- /dev/null +++ b/smoketest/configs/rip-router @@ -0,0 +1,267 @@ +interfaces { + dummy dum0 { + address 192.0.2.0/32 + } + ethernet eth0 { + duplex auto + ip { + rip { + authentication { + md5 1 { + password VyOSsecure + } + } + split-horizon { + poison-reverse + } + } + } + ipv6 { + ripng { + split-horizon { + poison-reverse + } + } + } + smp-affinity auto + speed auto + address 172.18.202.10/24 + } + ethernet eth1 { + duplex auto + smp-affinity auto + speed auto + vif 20 { + ip { + rip { + authentication { + plaintext-password VyOSsecure + } + split-horizon { + poison-reverse + } + } + } + ipv6 { + ripng { + split-horizon { + disable + } + } + } + } + vif-s 200 { + ip { + rip { + authentication { + md5 1 { + password VyOSsecure + } + } + split-horizon { + disable + } + } + } + ipv6 { + ripng { + split-horizon { + poison-reverse + } + } + } + vif-c 2000 { + ip { + rip { + authentication { + md5 1 { + password VyOSsecure + } + } + } + } + } + vif-c 3000 { + ip { + rip { + split-horizon { + disable + } + } + } + ipv6 { + ripng { + split-horizon { + poison-reverse + } + } + } + } + } + } +} +policy { + access-list6 198 { + rule 10 { + action permit + source { + any + } + } + } + access-list6 199 { + rule 20 { + action deny + source { + any + } + } + } + prefix-list6 bar-prefix { + rule 200 { + action deny + prefix 2001:db8::/32 + } + } + prefix-list6 foo-prefix { + rule 100 { + action permit + prefix 2001:db8::/32 + } + } + route-map FooBar123 { + rule 10 { + action permit + } + } +} +protocols { + rip { + default-distance 20 + default-information { + originate + } + interface eth0 + interface eth1.20 + interface eth1.200 + interface eth1.200.2000 + interface eth1.200.3000 + network 192.168.0.0/24 + redistribute { + connected { + } + } + } + ripng { + aggregate-address 2001:db8:1000::/48 + default-information { + originate + } + default-metric 8 + distribute-list { + access-list { + in 198 + out 199 + } + interface eth0 { + access-list { + in 198 + out 199 + } + prefix-list { + in foo-prefix + out bar-prefix + } + } + interface eth1 { + access-list { + in 198 + out 199 + } + prefix-list { + in foo-prefix + out bar-prefix + } + } + interface eth2 { + access-list { + in 198 + out 199 + } + prefix-list { + in foo-prefix + out bar-prefix + } + } + prefix-list { + in foo-prefix + out bar-prefix + } + } + interface eth0 + interface eth1 + interface eth2 + network 2001:db8:1000::/64 + network 2001:db8:1001::/64 + network 2001:db8:2000::/64 + network 2001:db8:2001::/64 + passive-interface default + redistribute { + connected { + metric 8 + route-map FooBar123 + } + static { + metric 8 + route-map FooBar123 + } + } + route 2001:db8:1000::/64 + } +} +service { + ssh { + port 22 + } +} +system { + config-management { + commit-revisions 100 + } + console { + device ttyS0 { + speed 115200 + } + } + host-name vyos + login { + user vyos { + authentication { + encrypted-password $6$O5gJRlDYQpj$MtrCV9lxMnZPMbcxlU7.FI793MImNHznxGoMFgm3Q6QP3vfKJyOSRCt3Ka/GzFQyW1yZS4NS616NLHaIPPFHc0 + 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 + } + } + } +} + +/* 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@10:vrrp@2:wanloadbalance@3:webgui@1:webproxy@1:webproxy@2:zone-policy@1" === */ +/* Release version: 1.2.6-S1 */ diff --git a/smoketest/configs/vrf-basic b/smoketest/configs/vrf-basic new file mode 100644 index 000000000..ded33f683 --- /dev/null +++ b/smoketest/configs/vrf-basic @@ -0,0 +1,231 @@ +interfaces { + ethernet eth0 { + address 192.0.2.1/24 + } + ethernet eth1 { + duplex auto + speed auto + vrf green + } + ethernet eth2 { + vrf red + } +} +protocols { + static { + route 0.0.0.0/0 { + next-hop 192.0.2.254 { + distance 10 + } + } + table 10 { + interface-route 1.0.0.0/8 { + next-hop-interface eth0 { + distance 20 + } + } + interface-route 2.0.0.0/8 { + next-hop-interface eth0 { + distance 20 + } + } + interface-route 3.0.0.0/8 { + next-hop-interface eth0 { + distance 20 + } + } + } + table 20 { + interface-route 4.0.0.0/8 { + next-hop-interface eth0 { + distance 20 + } + } + interface-route 5.0.0.0/8 { + next-hop-interface eth0 { + distance 50 + } + } + interface-route 6.0.0.0/8 { + next-hop-interface eth0 { + distance 60 + } + } + interface-route6 2001:db8:100::/40 { + next-hop-interface eth1 { + distance 20 + } + } + interface-route6 2001:db8::/40 { + next-hop-interface eth1 { + distance 10 + } + } + route 11.0.0.0/8 { + next-hop 1.1.1.1 { + next-hop-interface eth0 + } + } + route 12.0.0.0/8 { + next-hop 1.1.1.1 { + next-hop-interface eth0 + } + } + route 13.0.0.0/8 { + next-hop 1.1.1.1 { + next-hop-interface eth0 + } + } + } + table 30 { + interface-route6 2001:db8:200::/40 { + next-hop-interface eth1 { + distance 20 + } + } + route 14.0.0.0/8 { + next-hop 2.2.1.1 { + next-hop-interface eth1 + } + } + route 15.0.0.0/8 { + next-hop 2.2.1.1 { + next-hop-interface eth1 + } + } + } + } + vrf green { + static { + interface-route 100.0.0.0/8 { + next-hop-interface eth0 { + distance 200 + next-hop-vrf default + } + } + interface-route 101.0.0.0/8 { + next-hop-interface eth0 { + next-hop-vrf default + } + next-hop-interface eth1 { + } + } + interface-route6 2001:db8:300::/40 { + next-hop-interface eth1 { + distance 20 + next-hop-vrf default + } + } + route 20.0.0.0/8 { + next-hop 1.1.1.1 { + next-hop-interface eth1 + next-hop-vrf default + } + } + route 21.0.0.0/8 { + next-hop 2.2.1.1 { + next-hop-interface eth1 + next-hop-vrf default + } + } + route6 2001:db8:100::/40 { + next-hop fe80::1 { + interface eth0 + next-hop-vrf default + } + } + } + } + vrf red { + static { + interface-route 103.0.0.0/8 { + next-hop-interface eth0 { + distance 201 + next-hop-vrf default + } + } + interface-route 104.0.0.0/8 { + next-hop-interface eth0 { + next-hop-vrf default + } + next-hop-interface eth1 { + next-hop-vrf default + } + } + interface-route6 2001:db8:400::/40 { + next-hop-interface eth1 { + distance 24 + next-hop-vrf default + } + } + route 30.0.0.0/8 { + next-hop 1.1.1.1 { + next-hop-interface eth1 + } + } + route 40.0.0.0/8 { + next-hop 2.2.1.1 { + next-hop-interface eth1 + next-hop-vrf default + } + } + route6 2001:db8:100::/40 { + next-hop fe80::1 { + interface eth0 + next-hop-vrf default + } + } + } + } +} +system { + config-management { + commit-revisions 100 + } + console { + device ttyS0 { + speed 115200 + } + } + host-name vyos + login { + user vyos { + authentication { + encrypted-password $6$O5gJRlDYQpj$MtrCV9lxMnZPMbcxlU7.FI793MImNHznxGoMFgm3Q6QP3vfKJyOSRCt3Ka/GzFQyW1yZS4NS616NLHaIPPFHc0 + plaintext-password "" + } + } + } + nt + 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 +} +vrf { + name green { + table 1000 + } + name red { + table 2000 + } +} + +// 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-202101231023 diff --git a/smoketest/scripts/cli/base_interfaces_test.py b/smoketest/scripts/cli/base_interfaces_test.py index 8f21ec70e..1426e80c2 100644 --- a/smoketest/scripts/cli/base_interfaces_test.py +++ b/smoketest/scripts/cli/base_interfaces_test.py @@ -402,12 +402,13 @@ class BasicInterfaceTest: tmp = read_file(f'/proc/sys/net/ipv6/conf/{interface}/dad_transmits') self.assertEqual(dad_transmits, tmp) - def test_dhcpv6_client_options(self): + def test_dhcpv6_clinet_options(self): if not self._test_ipv6_dhcpc6: self.skipTest('not supported') - duid = '00:01:00:01:27:71:db:f0:00:50:00:00:00:10' + duid_base = 10 for interface in self._interfaces: + duid = '00:01:00:01:27:71:db:f0:00:50:00:00:00:{}'.format(duid_base) path = self._base_path + [interface] for option in self._options.get(interface, []): self.session.set(path + option.split()) @@ -417,10 +418,13 @@ class BasicInterfaceTest: self.session.set(path + ['dhcpv6-options', 'rapid-commit']) self.session.set(path + ['dhcpv6-options', 'parameters-only']) self.session.set(path + ['dhcpv6-options', 'duid', duid]) + duid_base += 1 self.session.commit() + duid_base = 10 for interface in self._interfaces: + duid = '00:01:00:01:27:71:db:f0:00:50:00:00:00:{}'.format(duid_base) dhcpc6_config = read_file(f'/run/dhcp6c/dhcp6c.{interface}.conf') self.assertIn(f'interface {interface} ' + '{', dhcpc6_config) self.assertIn(f' request domain-name-servers;', dhcpc6_config) @@ -430,6 +434,7 @@ class BasicInterfaceTest: self.assertIn(f' send rapid-commit;', dhcpc6_config) self.assertIn(f' send client-id {duid};', dhcpc6_config) self.assertIn('};', dhcpc6_config) + duid_base += 1 # Check for running process self.assertTrue(process_named_running('dhcp6c')) diff --git a/smoketest/scripts/cli/test_interfaces_bonding.py b/smoketest/scripts/cli/test_interfaces_bonding.py index 882d38760..b65d97d30 100755 --- a/smoketest/scripts/cli/test_interfaces_bonding.py +++ b/smoketest/scripts/cli/test_interfaces_bonding.py @@ -25,34 +25,32 @@ from vyos.configsession import ConfigSessionError from vyos.util import read_file class BondingInterfaceTest(BasicInterfaceTest.BaseTest): - def setUp(self): - self._test_ip = True - self._test_ipv6 = True - self._test_ipv6_pd = True - self._test_ipv6_dhcpc6 = True - self._test_mtu = True - self._test_vlan = True - self._test_qinq = True - self._base_path = ['interfaces', 'bonding'] - self._interfaces = ['bond0'] - self._mirror_interfaces = ['dum21354'] - self._members = [] + @classmethod + def setUpClass(cls): + cls._test_ip = True + cls._test_ipv6 = True + cls._test_ipv6_pd = True + cls._test_ipv6_dhcpc6 = True + cls._test_mtu = True + cls._test_vlan = True + cls._test_qinq = True + cls._base_path = ['interfaces', 'bonding'] + cls._interfaces = ['bond0'] + cls._mirror_interfaces = ['dum21354'] + cls._members = [] # we need to filter out VLAN interfaces identified by a dot (.) # in their name - just in case! if 'TEST_ETH' in os.environ: - self._members = os.environ['TEST_ETH'].split() + cls._members = os.environ['TEST_ETH'].split() else: - for tmp in Section.interfaces("ethernet"): + for tmp in Section.interfaces('ethernet'): if not '.' in tmp: - self._members.append(tmp) - - self._options['bond0'] = [] - for member in self._members: - self._options['bond0'].append(f'member interface {member}') - - super().setUp() + cls._members.append(tmp) + cls._options['bond0'] = [] + for member in cls._members: + cls._options['bond0'].append(f'member interface {member}') def test_add_single_ip_address(self): super().test_add_single_ip_address() diff --git a/smoketest/scripts/cli/test_interfaces_bridge.py b/smoketest/scripts/cli/test_interfaces_bridge.py index 33c2e7dad..f64b527b3 100755 --- a/smoketest/scripts/cli/test_interfaces_bridge.py +++ b/smoketest/scripts/cli/test_interfaces_bridge.py @@ -28,31 +28,30 @@ from vyos.util import read_file from vyos.validate import is_intf_addr_assigned class BridgeInterfaceTest(BasicInterfaceTest.BaseTest): - def setUp(self): - self._test_ip = True - self._test_ipv6 = True - self._test_ipv6_pd = True - self._test_ipv6_dhcpc6 = True - self._test_vlan = True - self._base_path = ['interfaces', 'bridge'] - self._mirror_interfaces = ['dum21354'] - self._members = [] + @classmethod + def setUpClass(cls): + cls._test_ip = True + cls._test_ipv6 = True + cls._test_ipv6_pd = True + cls._test_ipv6_dhcpc6 = True + cls._test_vlan = True + cls._base_path = ['interfaces', 'bridge'] + cls._mirror_interfaces = ['dum21354'] + cls._members = [] # we need to filter out VLAN interfaces identified by a dot (.) # in their name - just in case! if 'TEST_ETH' in os.environ: - self._members = os.environ['TEST_ETH'].split() + cls._members = os.environ['TEST_ETH'].split() else: - for tmp in Section.interfaces("ethernet"): + for tmp in Section.interfaces('ethernet'): if not '.' in tmp: - self._members.append(tmp) + cls._members.append(tmp) - self._options['br0'] = [] - for member in self._members: - self._options['br0'].append(f'member interface {member}') - self._interfaces = list(self._options) - - super().setUp() + cls._options['br0'] = [] + for member in cls._members: + cls._options['br0'].append(f'member interface {member}') + cls._interfaces = list(cls._options) def tearDown(self): for intf in self._interfaces: diff --git a/smoketest/scripts/cli/test_interfaces_dummy.py b/smoketest/scripts/cli/test_interfaces_dummy.py index 60465a1d5..6e462bccf 100755 --- a/smoketest/scripts/cli/test_interfaces_dummy.py +++ b/smoketest/scripts/cli/test_interfaces_dummy.py @@ -19,10 +19,10 @@ import unittest from base_interfaces_test import BasicInterfaceTest class DummyInterfaceTest(BasicInterfaceTest.BaseTest): - def setUp(self): - self._base_path = ['interfaces', 'dummy'] - self._interfaces = ['dum435', 'dum8677', 'dum0931', 'dum089'] - super().setUp() + @classmethod + def setUpClass(cls): + cls._base_path = ['interfaces', 'dummy'] + cls._interfaces = ['dum435', 'dum8677', 'dum0931', 'dum089'] if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/smoketest/scripts/cli/test_interfaces_erspan.py b/smoketest/scripts/cli/test_interfaces_erspan.py new file mode 100755 index 000000000..c180f0a34 --- /dev/null +++ b/smoketest/scripts/cli/test_interfaces_erspan.py @@ -0,0 +1,135 @@ +#!/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 unittest +import json + +from vyos.configsession import ConfigSession +from vyos.configsession import ConfigSessionError +from vyos.util import cmd + +from base_interfaces_test import BasicInterfaceTest + +mtu = 1500 + +def erspan_conf(interface): + tmp = cmd(f'ip -d -j link show {interface}') + ''' + [ + { + "ifindex": 17, + "link": null, + "ifname": "ersp0", + "flags": [ + "BROADCAST", + "MULTICAST" + ], + "mtu": 1450, + "qdisc": "noop", + "operstate": "DOWN", + "linkmode": "DEFAULT", + "group": "default", + "txqlen": 1000, + "link_type": "ether", + "address": "22:27:14:7b:0d:79", + "broadcast": "ff:ff:ff:ff:ff:ff", + "promiscuity": 0, + "min_mtu": 68, + "max_mtu": 0, + "linkinfo": { + "info_kind": "erspan", + "info_data": { + "remote": "10.2.2.2", + "local": "10.1.1.1", + "ttl": 0, + "pmtudisc": true, + "ikey": "0.0.0.123", + "okey": "0.0.0.123", + "iseq": true, + "oseq": true, + "erspan_index": 0, + "erspan_ver": 1 + } + }, + "inet6_addr_gen_mode": "eui64", + "num_tx_queues": 1, + "num_rx_queues": 1, + "gso_max_size": 65536, + "gso_max_segs": 65535 + } + ] + ''' + return json.loads(tmp)[0] + +class ERSPanTunnelInterfaceTest(BasicInterfaceTest.BaseTest): + def setUp(self): + super().setUp() + + self._base_path = ['interfaces', 'erspan'] + self._test_mtu = True + + self.local_v4 = '10.1.1.1' + self.local_v6 = '2001:db8::1' + self.remote_v4 = '10.2.2.2' + self.remote_v6 = '2001:db9::1' + + def tearDown(self): + self.session.delete(['interfaces', 'erspan']) + super().tearDown() + + def test_erspan_ipv4(self): + interface = 'ersp100' + encapsulation = 'erspan' + key = 123 + + self.session.set(self._base_path + [interface, 'encapsulation', encapsulation]) + self.session.set(self._base_path + [interface, 'local-ip', self.local_v4]) + self.session.set(self._base_path + [interface, 'remote-ip', self.remote_v4]) + self.session.set(self._base_path + [interface, 'parameters', 'ip' , 'key', str(key)]) + + self.session.commit() + + conf = erspan_conf(interface) + self.assertEqual(interface, conf['ifname']) + self.assertEqual(encapsulation, conf['linkinfo']['info_kind']) + self.assertEqual(mtu, conf['mtu']) + + self.assertEqual(self.local_v4, conf['linkinfo']['info_data']['local']) + self.assertEqual(self.remote_v4, conf['linkinfo']['info_data']['remote']) + + + def test_erspan_ipv6(self): + interface = 'ersp1000' + encapsulation = 'ip6erspan' + key = 123 + + self.session.set(self._base_path + [interface, 'encapsulation', encapsulation]) + self.session.set(self._base_path + [interface, 'local-ip', self.local_v6]) + self.session.set(self._base_path + [interface, 'remote-ip', self.remote_v6]) + self.session.set(self._base_path + [interface, 'parameters', 'ip' , 'key', str(key)]) + + self.session.commit() + + conf = erspan_conf(interface) + self.assertEqual(interface, conf['ifname']) + self.assertEqual(encapsulation, conf['linkinfo']['info_kind']) + self.assertEqual(mtu, conf['mtu']) + + self.assertEqual(self.local_v6, conf['linkinfo']['info_data']['local']) + self.assertEqual(self.remote_v6, conf['linkinfo']['info_data']['remote']) + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/smoketest/scripts/cli/test_interfaces_ethernet.py b/smoketest/scripts/cli/test_interfaces_ethernet.py index 6c6e66008..772ff248f 100755 --- a/smoketest/scripts/cli/test_interfaces_ethernet.py +++ b/smoketest/scripts/cli/test_interfaces_ethernet.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2020 VyOS maintainers and contributors +# Copyright (C) 2020-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 @@ -35,38 +35,31 @@ def get_wpa_supplicant_value(interface, key): return tmp[0] class EthernetInterfaceTest(BasicInterfaceTest.BaseTest): - def setUp(self): - self._test_ip = True - self._test_ipv6 = True - self._test_ipv6_pd = True - self._test_ipv6_dhcpc6 = True - self._test_mtu = True - self._test_vlan = True - self._test_qinq = True - self._base_path = ['interfaces', 'ethernet'] - self._mirror_interfaces = ['dum21354'] + @classmethod + def setUpClass(cls): + cls._test_ip = True + cls._test_ipv6 = True + cls._test_ipv6_pd = True + cls._test_ipv6_dhcpc6 = True + cls._test_mtu = True + cls._test_vlan = True + cls._test_qinq = True + cls._base_path = ['interfaces', 'ethernet'] + cls._mirror_interfaces = ['dum21354'] # we need to filter out VLAN interfaces identified by a dot (.) # in their name - just in case! if 'TEST_ETH' in os.environ: tmp = os.environ['TEST_ETH'].split() - self._interfaces = tmp + cls._interfaces = tmp else: - for tmp in Section.interfaces("ethernet"): + for tmp in Section.interfaces('ethernet'): if not '.' in tmp: - self._interfaces.append(tmp) + cls._interfaces.append(tmp) - self._macs = {} - for interface in self._interfaces: - try: - mac = self.session.show_config(self._base_path + - [interface, 'hw-id']).split()[1] - except: - # during initial system startup there is no hw-id node - mac = read_file(f'/sys/class/net/{interface}/address') - self._macs[interface] = mac - - super().setUp() + cls._macs = {} + for interface in cls._interfaces: + cls._macs[interface] = read_file(f'/sys/class/net/{interface}/address') def tearDown(self): @@ -102,8 +95,7 @@ class EthernetInterfaceTest(BasicInterfaceTest.BaseTest): # Validate interface state for interface in self._interfaces: - with open(f'/sys/class/net/{interface}/flags', 'r') as f: - flags = f.read() + flags = read_file(f'/sys/class/net/{interface}/flags') self.assertEqual(int(flags, 16) & 1, 0) def test_offloading_rps(self): diff --git a/smoketest/scripts/cli/test_interfaces_geneve.py b/smoketest/scripts/cli/test_interfaces_geneve.py index 12cded400..b708b5437 100755 --- a/smoketest/scripts/cli/test_interfaces_geneve.py +++ b/smoketest/scripts/cli/test_interfaces_geneve.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2020 VyOS maintainers and contributors +# Copyright (C) 2020-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 @@ -20,16 +20,16 @@ from vyos.configsession import ConfigSession from base_interfaces_test import BasicInterfaceTest class GeneveInterfaceTest(BasicInterfaceTest.BaseTest): - def setUp(self): - self._test_ip = True - self._test_ipv6 = True - self._base_path = ['interfaces', 'geneve'] - self._options = { + @classmethod + def setUpClass(cls): + cls._test_ip = True + cls._test_ipv6 = True + cls._base_path = ['interfaces', 'geneve'] + cls._options = { 'gnv0': ['vni 10', 'remote 127.0.1.1'], 'gnv1': ['vni 20', 'remote 127.0.1.2'], } - self._interfaces = list(self._options) - super().setUp() + cls._interfaces = list(cls._options) if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/smoketest/scripts/cli/test_interfaces_l2tpv3.py b/smoketest/scripts/cli/test_interfaces_l2tpv3.py index 81af6d7f4..a89895b92 100755 --- a/smoketest/scripts/cli/test_interfaces_l2tpv3.py +++ b/smoketest/scripts/cli/test_interfaces_l2tpv3.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2020 VyOS maintainers and contributors +# Copyright (C) 2020-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 @@ -21,11 +21,12 @@ from base_interfaces_test import BasicInterfaceTest from vyos.util import cmd class GeneveInterfaceTest(BasicInterfaceTest.BaseTest): - def setUp(self): - self._test_ip = True - self._test_ipv6 = True - self._base_path = ['interfaces', 'l2tpv3'] - self._options = { + @classmethod + def setUpClass(cls): + cls._test_ip = True + cls._test_ipv6 = True + cls._base_path = ['interfaces', 'l2tpv3'] + cls._options = { 'l2tpeth10': ['local-ip 127.0.0.1', 'remote-ip 127.10.10.10', 'tunnel-id 100', 'peer-tunnel-id 10', 'session-id 100', 'peer-session-id 10', @@ -35,8 +36,7 @@ class GeneveInterfaceTest(BasicInterfaceTest.BaseTest): 'session-id 20', 'tunnel-id 200', 'source-port 2020', 'destination-port 20202'], } - self._interfaces = list(self._options) - super().setUp() + cls._interfaces = list(cls._options) def test_add_single_ip_address(self): super().test_add_single_ip_address() diff --git a/smoketest/scripts/cli/test_interfaces_loopback.py b/smoketest/scripts/cli/test_interfaces_loopback.py index 36000c3ff..77dd4c1b5 100755 --- a/smoketest/scripts/cli/test_interfaces_loopback.py +++ b/smoketest/scripts/cli/test_interfaces_loopback.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2020 VyOS maintainers and contributors +# Copyright (C) 2020-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 @@ -21,13 +21,13 @@ from netifaces import interfaces from vyos.validate import is_intf_addr_assigned +loopbacks = ['127.0.0.1', '::1'] + class LoopbackInterfaceTest(BasicInterfaceTest.BaseTest): - def setUp(self): - super().setUp() - # these addresses are never allowed to be removed from the system - self._loopback_addresses = ['127.0.0.1', '::1'] - self._base_path = ['interfaces', 'loopback'] - self._interfaces = ['lo'] + @classmethod + def setUpClass(cls): + cls._base_path = ['interfaces', 'loopback'] + cls._interfaces = ['lo'] def tearDown(self): self.session.delete(self._base_path) @@ -40,12 +40,12 @@ class LoopbackInterfaceTest(BasicInterfaceTest.BaseTest): def test_add_single_ip_address(self): super().test_add_single_ip_address() - for addr in self._loopback_addresses: + for addr in loopbacks: self.assertTrue(is_intf_addr_assigned('lo', addr)) def test_add_multiple_ip_addresses(self): super().test_add_multiple_ip_addresses() - for addr in self._loopback_addresses: + for addr in loopbacks: self.assertTrue(is_intf_addr_assigned('lo', addr)) def test_interface_disable(self): diff --git a/smoketest/scripts/cli/test_interfaces_macsec.py b/smoketest/scripts/cli/test_interfaces_macsec.py index 89743e5fd..3a3e7bff3 100755 --- a/smoketest/scripts/cli/test_interfaces_macsec.py +++ b/smoketest/scripts/cli/test_interfaces_macsec.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2020 VyOS maintainers and contributors +# Copyright (C) 2020-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 @@ -31,19 +31,19 @@ def get_config_value(interface, key): return tmp[0] class MACsecInterfaceTest(BasicInterfaceTest.BaseTest): - def setUp(self): - super().setUp() - self._test_ip = True - self._test_ipv6 = True - self._base_path = ['interfaces', 'macsec'] - self._options = { 'macsec0': ['source-interface eth0', 'security cipher gcm-aes-128'] } + @classmethod + def setUpClass(cls): + cls._test_ip = True + cls._test_ipv6 = True + cls._base_path = ['interfaces', 'macsec'] + cls._options = { 'macsec0': ['source-interface eth0', 'security cipher gcm-aes-128'] } # if we have a physical eth1 interface, add a second macsec instance - if 'eth1' in Section.interfaces("ethernet"): + if 'eth1' in Section.interfaces('ethernet'): macsec = { 'macsec1': [f'source-interface eth1', 'security cipher gcm-aes-128'] } - self._options.update(macsec) + cls._options.update(macsec) - self._interfaces = list(self._options) + cls._interfaces = list(cls._options) def test_macsec_encryption(self): # MACsec can be operating in authentication and encryption mode - both diff --git a/smoketest/scripts/cli/test_interfaces_openvpn.py b/smoketest/scripts/cli/test_interfaces_openvpn.py index 00db3f667..a2a1a85ec 100755 --- a/smoketest/scripts/cli/test_interfaces_openvpn.py +++ b/smoketest/scripts/cli/test_interfaces_openvpn.py @@ -625,27 +625,27 @@ if __name__ == '__main__': # Generate mandatory SSL certificate tmp = f'openssl req -newkey rsa:4096 -new -nodes -x509 -days 3650 '\ f'-keyout {ssl_key} -out {ssl_cert} -subj {subject}' - print(cmd(tmp)) + cmd(tmp) if not os.path.isfile(ca_cert): # Generate "CA" tmp = f'openssl req -new -x509 -key {ssl_key} -out {ca_cert} -subj {subject}' - print(cmd(tmp)) + cmd(tmp) if not os.path.isfile(dh_pem): # Generate "DH" key tmp = f'openssl dhparam -out {dh_pem} 2048' - print(cmd(tmp)) + cmd(tmp) if not os.path.isfile(s2s_key): # Generate site-2-site key tmp = f'openvpn --genkey --secret {s2s_key}' - print(cmd(tmp)) + cmd(tmp) if not os.path.isfile(auth_key): # Generate TLS auth key tmp = f'openvpn --genkey --secret {auth_key}' - print(cmd(tmp)) + cmd(tmp) for file in [ca_cert, ssl_cert, ssl_key, dh_pem, s2s_key, auth_key]: cmd(f'sudo chown openvpn:openvpn {file}') diff --git a/smoketest/scripts/cli/test_interfaces_pppoe.py b/smoketest/scripts/cli/test_interfaces_pppoe.py index 6bfe35d86..285c756e2 100755 --- a/smoketest/scripts/cli/test_interfaces_pppoe.py +++ b/smoketest/scripts/cli/test_interfaces_pppoe.py @@ -97,6 +97,27 @@ class PPPoEInterfaceTest(unittest.TestCase): self.assertTrue(running) + + def test_pppoe_clent_disabled_interface(self): + # Check if PPPoE Client can be disabled + for interface in self._interfaces: + self.session.set(base_path + [interface, 'authentication', 'user', 'vyos']) + self.session.set(base_path + [interface, 'authentication', 'password', 'vyos']) + self.session.set(base_path + [interface, 'source-interface', self._source_interface]) + self.session.set(base_path + [interface, 'disable']) + + self.session.commit() + + # Validate PPPoE client process + running = False + for interface in self._interfaces: + for proc in process_iter(): + if interface in proc.cmdline(): + running = True + + self.assertFalse(running) + + def test_pppoe_dhcpv6pd(self): # Check if PPPoE dialer can be configured with DHCPv6-PD address = '1' diff --git a/smoketest/scripts/cli/test_interfaces_pseudo_ethernet.py b/smoketest/scripts/cli/test_interfaces_pseudo_ethernet.py index 1a5debb79..f4cb4cdc9 100755 --- a/smoketest/scripts/cli/test_interfaces_pseudo_ethernet.py +++ b/smoketest/scripts/cli/test_interfaces_pseudo_ethernet.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2020 VyOS maintainers and contributors +# Copyright (C) 2020-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 @@ -19,21 +19,21 @@ import unittest from base_interfaces_test import BasicInterfaceTest class PEthInterfaceTest(BasicInterfaceTest.BaseTest): - def setUp(self): - self._test_ip = True - self._test_ipv6 = True - self._test_ipv6_pd = True - self._test_ipv6_dhcpc6 = True - self._test_mtu = True - self._test_vlan = True - self._test_qinq = True - self._base_path = ['interfaces', 'pseudo-ethernet'] - self._options = { + @classmethod + def setUpClass(cls): + cls._test_ip = True + cls._test_ipv6 = True + cls._test_ipv6_pd = True + cls._test_ipv6_dhcpc6 = True + cls._test_mtu = True + cls._test_vlan = True + cls._test_qinq = True + cls._base_path = ['interfaces', 'pseudo-ethernet'] + cls._options = { 'peth0': ['source-interface eth1'], 'peth1': ['source-interface eth1'], } - self._interfaces = list(self._options) - super().setUp() + cls._interfaces = list(cls._options) if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/smoketest/scripts/cli/test_interfaces_tunnel.py b/smoketest/scripts/cli/test_interfaces_tunnel.py index 8405fc7d0..a9250e3e5 100755 --- a/smoketest/scripts/cli/test_interfaces_tunnel.py +++ b/smoketest/scripts/cli/test_interfaces_tunnel.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2020 VyOS maintainers and contributors +# Copyright (C) 2020-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 @@ -61,22 +61,22 @@ def tunnel_conf(interface): return json.loads(tmp)[0] class TunnelInterfaceTest(BasicInterfaceTest.BaseTest): - def setUp(self): - self._test_ip = True - self._test_ipv6 = True - self._test_mtu = True - self._base_path = ['interfaces', 'tunnel'] - self.local_v4 = '192.0.2.1' - self.local_v6 = '2001:db8::1' - - self._options = { - 'tun10': ['encapsulation ipip', 'remote-ip 192.0.2.10', 'local-ip ' + self.local_v4], - 'tun20': ['encapsulation gre', 'remote-ip 192.0.2.20', 'local-ip ' + self.local_v4], + @classmethod + def setUpClass(cls): + cls._test_ip = True + cls._test_ipv6 = True + cls._test_mtu = True + cls._base_path = ['interfaces', 'tunnel'] + cls.local_v4 = '192.0.2.1' + cls.local_v6 = '2001:db8::1' + cls._options = { + 'tun10': ['encapsulation ipip', 'remote-ip 192.0.2.10', 'local-ip ' + cls.local_v4], + 'tun20': ['encapsulation gre', 'remote-ip 192.0.2.20', 'local-ip ' + cls.local_v4], } + cls._interfaces = list(cls._options) - self._interfaces = list(self._options) + def setUp(self): super().setUp() - self.session.set(['interfaces', 'dummy', source_if, 'address', self.local_v4 + '/32']) self.session.set(['interfaces', 'dummy', source_if, 'address', self.local_v6 + '/128']) diff --git a/smoketest/scripts/cli/test_interfaces_vxlan.py b/smoketest/scripts/cli/test_interfaces_vxlan.py index a726aa610..fcc1b15ce 100755 --- a/smoketest/scripts/cli/test_interfaces_vxlan.py +++ b/smoketest/scripts/cli/test_interfaces_vxlan.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2020 VyOS maintainers and contributors +# Copyright (C) 2020-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 @@ -20,17 +20,17 @@ from vyos.configsession import ConfigSession, ConfigSessionError from base_interfaces_test import BasicInterfaceTest class VXLANInterfaceTest(BasicInterfaceTest.BaseTest): - def setUp(self): - self._test_ip = True - self._test_ipv6 = True - self._test_mtu = True - self._base_path = ['interfaces', 'vxlan'] - self._options = { + @classmethod + def setUpClass(cls): + cls._test_ip = True + cls._test_ipv6 = True + cls._test_mtu = True + cls._base_path = ['interfaces', 'vxlan'] + cls._options = { 'vxlan0': ['vni 10', 'remote 127.0.0.2'], 'vxlan1': ['vni 20', 'group 239.1.1.1', 'source-interface eth0'], } - self._interfaces = list(self._options) - super().setUp() + cls._interfaces = list(cls._options) if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/smoketest/scripts/cli/test_interfaces_wireguard.py b/smoketest/scripts/cli/test_interfaces_wireguard.py index d9a51b146..e70324f96 100755 --- a/smoketest/scripts/cli/test_interfaces_wireguard.py +++ b/smoketest/scripts/cli/test_interfaces_wireguard.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2020 VyOS maintainers and contributors +# Copyright (C) 2020-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 diff --git a/smoketest/scripts/cli/test_interfaces_wireless.py b/smoketest/scripts/cli/test_interfaces_wireless.py index 51d97f032..39e8cd5b8 100755 --- a/smoketest/scripts/cli/test_interfaces_wireless.py +++ b/smoketest/scripts/cli/test_interfaces_wireless.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2020 VyOS maintainers and contributors +# Copyright (C) 2020-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 @@ -32,10 +32,11 @@ def get_config_value(interface, key): return tmp[0] class WirelessInterfaceTest(BasicInterfaceTest.BaseTest): - def setUp(self): - self._test_ip = True - self._base_path = ['interfaces', 'wireless'] - self._options = { + @classmethod + def setUpClass(cls): + cls._test_ip = True + cls._base_path = ['interfaces', 'wireless'] + cls._options = { 'wlan0': ['physical-device phy0', 'ssid VyOS-WIFI-0', 'type station', 'address 192.0.2.1/30'], 'wlan1': ['physical-device phy0', 'ssid VyOS-WIFI-1', 'country-code se', @@ -45,8 +46,7 @@ class WirelessInterfaceTest(BasicInterfaceTest.BaseTest): 'wlan11': ['physical-device phy1', 'ssid VyOS-WIFI-3', 'country-code se', 'type access-point', 'address 192.0.2.13/30', 'channel 0'], } - self._interfaces = list(self._options) - super().setUp() + cls._interfaces = list(cls._options) def test_wireless_add_single_ip_address(self): # derived method to check if member interfaces are enslaved properly diff --git a/smoketest/scripts/cli/test_interfaces_wirelessmodem.py b/smoketest/scripts/cli/test_interfaces_wirelessmodem.py index 696a6946b..023f57305 100755 --- a/smoketest/scripts/cli/test_interfaces_wirelessmodem.py +++ b/smoketest/scripts/cli/test_interfaces_wirelessmodem.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2020 VyOS maintainers and contributors +# Copyright (C) 2020-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 diff --git a/smoketest/scripts/cli/test_protocols_bfd.py b/smoketest/scripts/cli/test_protocols_bfd.py new file mode 100755 index 000000000..80e5daa7c --- /dev/null +++ b/smoketest/scripts/cli/test_protocols_bfd.py @@ -0,0 +1,181 @@ +#!/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.configsession import ConfigSessionError +from vyos.util import cmd +from vyos.util import process_named_running + +PROCESS_NAME = 'bfdd' +base_path = ['protocols', 'bfd'] + +dum_if = 'dum1001' +peers = { + '192.0.2.10' : { + 'intv_rx' : '500', + 'intv_tx' : '600', + 'multihop' : '', + 'source_addr': '192.0.2.254', + }, + '192.0.2.20' : { + 'echo_mode' : '', + 'intv_echo' : '100', + 'intv_mult' : '100', + 'intv_rx' : '222', + 'intv_tx' : '333', + 'shutdown' : '', + 'source_intf': dum_if, + }, + '2001:db8::a' : { + 'source_addr': '2001:db8::1', + 'source_intf': dum_if, + }, + '2001:db8::b' : { + 'source_addr': '2001:db8::1', + 'multihop' : '', + }, +} + +profiles = { + 'foo' : { + 'echo_mode' : '', + 'intv_echo' : '100', + 'intv_mult' : '101', + 'intv_rx' : '222', + 'intv_tx' : '333', + 'shutdown' : '', + }, + 'bar' : { + 'intv_mult' : '102', + 'intv_rx' : '444', + }, +} + +def getFRRconfig(): + return cmd('vtysh -c "show run" | sed -n "/^bfd/,/^!/p"') + +def getBFDPeerconfig(peer): + return cmd(f'vtysh -c "show run" | sed -n "/^ {peer}/,/^!/p"') + +def getBFDProfileconfig(profile): + return cmd(f'vtysh -c "show run" | sed -n "/^ {profile}/,/^!/p"') + +class TestProtocolsBFD(unittest.TestCase): + def setUp(self): + self.session = ConfigSession(os.getpid()) + + def tearDown(self): + self.session.delete(base_path) + self.session.commit() + del self.session + + # Check for running process + self.assertTrue(process_named_running(PROCESS_NAME)) + + def test_bfd_peer(self): + for peer, peer_config in peers.items(): + if 'echo_mode' in peer_config: + self.session.set(base_path + ['peer', peer, 'echo-mode']) + if 'intv_echo' in peer_config: + self.session.set(base_path + ['peer', peer, 'interval', 'echo-interval', peer_config["intv_echo"]]) + if 'intv_mult' in peer_config: + self.session.set(base_path + ['peer', peer, 'interval', 'multiplier', peer_config["intv_mult"]]) + if 'intv_rx' in peer_config: + self.session.set(base_path + ['peer', peer, 'interval', 'receive', peer_config["intv_rx"]]) + if 'intv_tx' in peer_config: + self.session.set(base_path + ['peer', peer, 'interval', 'transmit', peer_config["intv_tx"]]) + if 'multihop' in peer_config: + self.session.set(base_path + ['peer', peer, 'multihop']) + if 'shutdown' in peer_config: + self.session.set(base_path + ['peer', peer, 'shutdown']) + if 'source_addr' in peer_config: + self.session.set(base_path + ['peer', peer, 'source', 'address', peer_config["source_addr"]]) + if 'source_intf' in peer_config: + self.session.set(base_path + ['peer', peer, 'source', 'interface', peer_config["source_intf"]]) + + # commit changes + self.session.commit() + + # Verify FRR bgpd configuration + frrconfig = getFRRconfig() + for peer, peer_config in peers.items(): + tmp = f'peer {peer}' + if 'multihop' in peer_config: + tmp += f' multihop' + if 'source_addr' in peer_config: + tmp += f' local-address {peer_config["source_addr"]}' + if 'source_intf' in peer_config: + tmp += f' interface {peer_config["source_intf"]}' + + self.assertIn(tmp, frrconfig) + peerconfig = getBFDPeerconfig(tmp) + + if 'echo_mode' in peer_config: + self.assertIn(f' echo-mode', peerconfig) + if 'intv_echo' in peer_config: + self.assertIn(f' echo-interval {peer_config["intv_echo"]}', peerconfig) + if 'intv_mult' in peer_config: + self.assertIn(f' detect-multiplier {peer_config["intv_mult"]}', peerconfig) + if 'intv_rx' in peer_config: + self.assertIn(f' receive-interval {peer_config["intv_rx"]}', peerconfig) + if 'intv_tx' in peer_config: + self.assertIn(f' transmit-interval {peer_config["intv_tx"]}', peerconfig) + if 'shutdown' not in peer_config: + self.assertIn(f' no shutdown', peerconfig) + + def test_bfd_profile(self): + peer = '192.0.2.10' + + for profile, profile_config in profiles.items(): + if 'echo_mode' in profile_config: + self.session.set(base_path + ['profile', profile, 'echo-mode']) + if 'intv_echo' in profile_config: + self.session.set(base_path + ['profile', profile, 'interval', 'echo-interval', profile_config["intv_echo"]]) + if 'intv_mult' in profile_config: + self.session.set(base_path + ['profile', profile, 'interval', 'multiplier', profile_config["intv_mult"]]) + if 'intv_rx' in profile_config: + self.session.set(base_path + ['profile', profile, 'interval', 'receive', profile_config["intv_rx"]]) + if 'intv_tx' in profile_config: + self.session.set(base_path + ['profile', profile, 'interval', 'transmit', profile_config["intv_tx"]]) + if 'shutdown' in profile_config: + self.session.set(base_path + ['profile', profile, 'shutdown']) + + self.session.set(base_path + ['peer', peer, 'profile', list(profiles)[0]]) + + # commit changes + self.session.commit() + + # Verify FRR bgpd configuration + for profile, profile_config in profiles.items(): + config = getBFDProfileconfig(f'profile {profile}') + if 'echo_mode' in profile_config: + self.assertIn(f' echo-mode', config) + if 'intv_echo' in profile_config: + self.assertIn(f' echo-interval {profile_config["intv_echo"]}', config) + if 'intv_mult' in profile_config: + self.assertIn(f' detect-multiplier {profile_config["intv_mult"]}', config) + if 'intv_rx' in profile_config: + self.assertIn(f' receive-interval {profile_config["intv_rx"]}', config) + if 'intv_tx' in profile_config: + self.assertIn(f' transmit-interval {profile_config["intv_tx"]}', config) + if 'shutdown' not in profile_config: + self.assertIn(f' no shutdown', config) + +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 87d10eb85..b6a6a493c 100755 --- a/smoketest/scripts/cli/test_protocols_bgp.py +++ b/smoketest/scripts/cli/test_protocols_bgp.py @@ -19,6 +19,7 @@ import unittest from vyos.configsession import ConfigSession from vyos.configsession import ConfigSessionError +from vyos.template import is_ipv6 from vyos.util import cmd from vyos.util import process_named_running @@ -30,6 +31,8 @@ route_map_in = 'foo-map-in' route_map_out = 'foo-map-out' prefix_list_in = 'pfx-foo-in' prefix_list_out = 'pfx-foo-out' +prefix_list_in6 = 'pfx-foo-in6' +prefix_list_out6 = 'pfx-foo-out6' neighbor_config = { '192.0.2.1' : { @@ -45,6 +48,8 @@ neighbor_config = { 'local_as' : '300', 'route_map_in' : route_map_in, 'route_map_out': route_map_out, + 'no_send_comm_ext' : '', + 'addpath_all' : '', }, '192.0.2.2' : { 'remote_as' : '200', @@ -54,6 +59,7 @@ neighbor_config = { 'cap_strict' : '', 'pfx_list_in' : prefix_list_in, 'pfx_list_out' : prefix_list_out, + 'no_send_comm_std' : '', }, '192.0.2.3' : { 'description' : 'foo bar baz', @@ -62,6 +68,32 @@ neighbor_config = { 'multi_hop' : '5', 'update_src' : 'lo', }, + '2001:db8::1' : { + 'cap_dynamic' : '', + 'cap_ext_next' : '', + 'remote_as' : '123', + '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, + 'no_send_comm_std' : '', + 'addpath_per_as' : '', + }, + '2001:db8::2' : { + 'remote_as' : '456', + 'shutdown' : '', + 'no_cap_nego' : '', + 'port' : '667', + 'cap_strict' : '', + 'pfx_list_in' : prefix_list_in6, + 'pfx_list_out' : prefix_list_out6, + 'no_send_comm_ext' : '', + }, } peer_group_config = { @@ -82,6 +114,7 @@ peer_group_config = { 'local_as' : '300', 'pfx_list_in' : prefix_list_in, 'pfx_list_out' : prefix_list_out, + 'no_send_comm_ext' : '', }, 'baz' : { 'cap_dynamic' : '', @@ -96,10 +129,13 @@ peer_group_config = { } def getFRRBGPconfig(): - return cmd(f'vtysh -c "show run" | sed -n "/router bgp {ASN}/,/^!/p"') + return cmd(f'vtysh -c "show run" | sed -n "/^router bgp {ASN}/,/^!/p"') + +def getFRRBGPVNIconfig(vni): + return cmd(f'vtysh -c "show run" | sed -n "/^ vni {vni}/,/^!/p"') def getFRRRPKIconfig(): - return cmd(f'vtysh -c "show run" | sed -n "/rpki/,/^!/p"') + return cmd(f'vtysh -c "show run" | sed -n "/^rpki/,/^!/p"') class TestProtocolsBGP(unittest.TestCase): def setUp(self): @@ -112,16 +148,26 @@ class TestProtocolsBGP(unittest.TestCase): 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']) + self.session.set(['policy', 'prefix-list6', prefix_list_in6, 'rule', '10', 'action', 'permit']) + self.session.set(['policy', 'prefix-list6', prefix_list_in6, 'rule', '10', 'prefix', '2001:db8:1000::/64']) + self.session.set(['policy', 'prefix-list6', prefix_list_out6, 'rule', '10', 'action', 'deny']) + self.session.set(['policy', 'prefix-list6', prefix_list_out6, 'rule', '10', 'prefix', '2001:db8:2000::/64']) + 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(['policy', 'prefix-list6', prefix_list_in6]) + self.session.delete(['policy', 'prefix-list6', prefix_list_out6]) self.session.delete(base_path) self.session.commit() del self.session + # Check for running process + self.assertTrue(process_named_running(PROCESS_NAME)) + def verify_frr_config(self, peer, peer_config, frrconfig): # recurring patterns to verify for both a simple neighbor and a peer-group if 'cap_dynamic' in peer_config: @@ -158,11 +204,20 @@ class TestProtocolsBGP(unittest.TestCase): 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) + if 'no_send_comm_std' in peer_config: + self.assertIn(f' no neighbor {peer} send-community', frrconfig) + if 'no_send_comm_ext' in peer_config: + self.assertIn(f' no neighbor {peer} send-community extended', frrconfig) + if 'addpath_all' in peer_config: + self.assertIn(f' neighbor {peer} addpath-tx-all-paths', frrconfig) + if 'addpath_per_as' in peer_config: + self.assertIn(f' neighbor {peer} addpath-tx-bestpath-per-AS', frrconfig) def test_bgp_01_simple(self): router_id = '127.0.0.1' local_pref = '500' + stalepath_time = '60' self.session.set(base_path + ['parameters', 'router-id', router_id]) self.session.set(base_path + ['parameters', 'log-neighbor-changes']) @@ -170,6 +225,8 @@ class TestProtocolsBGP(unittest.TestCase): self.session.set(base_path + ['parameters', 'default', 'local-pref', local_pref]) # Deactivate IPv4 unicast for a peer by default self.session.set(base_path + ['parameters', 'default', 'no-ipv4-unicast']) + self.session.set(base_path + ['parameters', 'graceful-restart', 'stalepath-time', stalepath_time]) + self.session.set(base_path + ['parameters', 'graceful-shutdown']) # commit changes self.session.commit() @@ -181,54 +238,66 @@ class TestProtocolsBGP(unittest.TestCase): self.assertIn(f' bgp log-neighbor-changes', frrconfig) self.assertIn(f' bgp default local-preference {local_pref}', frrconfig) self.assertIn(f' no bgp default ipv4-unicast', frrconfig) + self.assertIn(f' bgp graceful-restart stalepath-time {stalepath_time}', frrconfig) + self.assertIn(f' bgp graceful-shutdown', frrconfig) - # Check for running process - self.assertTrue(process_named_running(PROCESS_NAME)) def test_bgp_02_neighbors(self): # Test out individual neighbor configuration items, not all of them are # also available to a peer-group! - for neighbor, config in neighbor_config.items(): - if 'adv_interv' in config: - self.session.set(base_path + ['neighbor', neighbor, 'advertisement-interval', config["adv_interv"]]) - if 'cap_dynamic' in config: - self.session.set(base_path + ['neighbor', neighbor, 'capability', 'dynamic']) - if 'cap_ext_next' in config: - self.session.set(base_path + ['neighbor', neighbor, 'capability', 'extended-nexthop']) - if 'description' in config: - self.session.set(base_path + ['neighbor', neighbor, 'description', config["description"]]) - if 'no_cap_nego' in config: - self.session.set(base_path + ['neighbor', neighbor, 'disable-capability-negotiation']) - if 'multi_hop' in config: - self.session.set(base_path + ['neighbor', neighbor, 'ebgp-multihop', config["multi_hop"]]) - if 'local_as' in config: - self.session.set(base_path + ['neighbor', neighbor, 'local-as', config["local_as"]]) - if 'cap_over' in config: - self.session.set(base_path + ['neighbor', neighbor, 'override-capability']) - if 'passive' in config: - self.session.set(base_path + ['neighbor', neighbor, 'passive']) - if 'password' in config: - self.session.set(base_path + ['neighbor', neighbor, 'password', config["password"]]) - if 'port' in config: - self.session.set(base_path + ['neighbor', neighbor, 'port', config["port"]]) - if 'remote_as' in config: - self.session.set(base_path + ['neighbor', neighbor, 'remote-as', config["remote_as"]]) - if 'cap_strict' in config: - self.session.set(base_path + ['neighbor', neighbor, 'strict-capability-match']) - if 'shutdown' in config: - self.session.set(base_path + ['neighbor', neighbor, 'shutdown']) - if 'ttl_security' in config: - 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"]]) + for peer, peer_config in neighbor_config.items(): + afi = 'ipv4-unicast' + if is_ipv6(peer): + afi = 'ipv6-unicast' + + if 'adv_interv' in peer_config: + self.session.set(base_path + ['neighbor', peer, 'advertisement-interval', peer_config["adv_interv"]]) + if 'cap_dynamic' in peer_config: + self.session.set(base_path + ['neighbor', peer, 'capability', 'dynamic']) + if 'cap_ext_next' in peer_config: + self.session.set(base_path + ['neighbor', peer, 'capability', 'extended-nexthop']) + if 'description' in peer_config: + self.session.set(base_path + ['neighbor', peer, 'description', peer_config["description"]]) + if 'no_cap_nego' in peer_config: + self.session.set(base_path + ['neighbor', peer, 'disable-capability-negotiation']) + if 'multi_hop' in peer_config: + self.session.set(base_path + ['neighbor', peer, 'ebgp-multihop', peer_config["multi_hop"]]) + if 'local_as' in peer_config: + self.session.set(base_path + ['neighbor', peer, 'local-as', peer_config["local_as"]]) + if 'cap_over' in peer_config: + self.session.set(base_path + ['neighbor', peer, 'override-capability']) + if 'passive' in peer_config: + self.session.set(base_path + ['neighbor', peer, 'passive']) + if 'password' in peer_config: + self.session.set(base_path + ['neighbor', peer, 'password', peer_config["password"]]) + if 'port' in peer_config: + self.session.set(base_path + ['neighbor', peer, 'port', peer_config["port"]]) + if 'remote_as' in peer_config: + self.session.set(base_path + ['neighbor', peer, 'remote-as', peer_config["remote_as"]]) + if 'cap_strict' in peer_config: + self.session.set(base_path + ['neighbor', peer, 'strict-capability-match']) + if 'shutdown' in peer_config: + self.session.set(base_path + ['neighbor', peer, 'shutdown']) + if 'ttl_security' in peer_config: + self.session.set(base_path + ['neighbor', peer, 'ttl-security', 'hops', peer_config["ttl_security"]]) + if 'update_src' in peer_config: + self.session.set(base_path + ['neighbor', peer, 'update-source', peer_config["update_src"]]) + if 'route_map_in' in peer_config: + self.session.set(base_path + ['neighbor', peer, 'address-family', afi, 'route-map', 'import', peer_config["route_map_in"]]) + if 'route_map_out' in peer_config: + self.session.set(base_path + ['neighbor', peer, 'address-family', afi, 'route-map', 'export', peer_config["route_map_out"]]) + if 'pfx_list_in' in peer_config: + self.session.set(base_path + ['neighbor', peer, 'address-family', afi, 'prefix-list', 'import', peer_config["pfx_list_in"]]) + if 'pfx_list_out' in peer_config: + self.session.set(base_path + ['neighbor', peer, 'address-family', afi, 'prefix-list', 'export', peer_config["pfx_list_out"]]) + if 'no_send_comm_std' in peer_config: + self.session.set(base_path + ['neighbor', peer, 'address-family', afi, 'disable-send-community', 'standard']) + if 'no_send_comm_ext' in peer_config: + self.session.set(base_path + ['neighbor', peer, 'address-family', afi, 'disable-send-community', 'extended']) + if 'addpath_all' in peer_config: + self.session.set(base_path + ['neighbor', peer, 'address-family', afi, 'addpath-tx-all']) + if 'addpath_per_as' in peer_config: + self.session.set(base_path + ['neighbor', peer, 'address-family', afi, 'addpath-tx-per-as']) # commit changes self.session.commit() @@ -238,11 +307,11 @@ class TestProtocolsBGP(unittest.TestCase): self.assertIn(f'router bgp {ASN}', frrconfig) for peer, peer_config in neighbor_config.items(): - if 'adv_interv' in config: + if 'adv_interv' in peer_config: self.assertIn(f' neighbor {peer} advertisement-interval {peer_config["adv_interv"]}', frrconfig) - if 'port' in config: + if 'port' in peer_config: self.assertIn(f' neighbor {peer} port {peer_config["port"]}', frrconfig) - if 'cap_strict' in config: + if 'cap_strict' in peer_config: self.assertIn(f' neighbor {peer} strict-capability-match', frrconfig) self.verify_frr_config(peer, peer_config, frrconfig) @@ -284,6 +353,14 @@ class TestProtocolsBGP(unittest.TestCase): 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"]]) + if 'no_send_comm_std' in config: + self.session.set(base_path + ['peer-group', peer_group, 'address-family', 'ipv4-unicast', 'disable-send-community', 'standard']) + if 'no_send_comm_ext' in config: + self.session.set(base_path + ['peer-group', peer_group, 'address-family', 'ipv4-unicast', 'disable-send-community', 'extended']) + if 'addpath_all' in config: + self.session.set(base_path + ['peer-group', peer_group, 'address-family', 'ipv4-unicast', 'addpath-tx-all']) + if 'addpath_per_as' in config: + self.session.set(base_path + ['peer-group', peer_group, 'address-family', 'ipv4-unicast', 'addpath-tx-per-as']) # commit changes self.session.commit() @@ -311,7 +388,7 @@ class TestProtocolsBGP(unittest.TestCase): } # We want to redistribute ... - redistributes = ['connected', 'kernel', 'ospf', 'rip', 'static'] + redistributes = ['connected', 'isis', 'kernel', 'ospf', 'rip', 'static'] for redistribute in redistributes: self.session.set(base_path + ['address-family', 'ipv4-unicast', 'redistribute', redistribute]) @@ -348,12 +425,12 @@ class TestProtocolsBGP(unittest.TestCase): def test_bgp_05_afi_ipv6(self): networks = { '2001:db8:100::/48' : { - }, + }, '2001:db8:200::/48' : { - }, + }, '2001:db8:300::/48' : { 'summary_only' : '', - }, + }, } # We want to redistribute ... @@ -420,38 +497,33 @@ class TestProtocolsBGP(unittest.TestCase): self.assertIn(f' bgp listen range {prefix} peer-group {peer_group}', frrconfig) - def test_bgp_07_rpki(self): - rpki_path = ['protocols', 'rpki'] - init_tmo = '50' - polling = '400' - preference = '100' - timeout = '900' - - cache = { - 'foo' : { 'address' : '1.1.1.1', 'port' : '8080' }, -# T3253 only one peer supported -# 'bar' : { 'address' : '2.2.2.2', 'port' : '9090' }, - } - - self.session.set(rpki_path + ['polling-period', polling]) - self.session.set(rpki_path + ['preference', preference]) - - for name, config in cache.items(): - self.session.set(rpki_path + ['cache', name, 'address', config['address']]) - self.session.set(rpki_path + ['cache', name, 'port', config['port']]) + def test_bgp_07_l2vpn_evpn(self): + vnis = ['10010', '10020', '10030'] + neighbors = ['192.0.2.10', '192.0.2.20', '192.0.2.30'] + self.session.set(base_path + ['address-family', 'l2vpn-evpn', 'advertise-all-vni']) + self.session.set(base_path + ['address-family', 'l2vpn-evpn', 'advertise-default-gw']) + self.session.set(base_path + ['address-family', 'l2vpn-evpn', 'advertise-svi-ip']) + self.session.set(base_path + ['address-family', 'l2vpn-evpn', 'flooding', 'disable']) + for vni in vnis: + self.session.set(base_path + ['address-family', 'l2vpn-evpn', 'vni', vni, 'advertise-default-gw']) + self.session.set(base_path + ['address-family', 'l2vpn-evpn', 'vni', vni, 'advertise-svi-ip']) # commit changes self.session.commit() # Verify FRR bgpd configuration - frrconfig = getFRRRPKIconfig() - self.assertIn(f'rpki polling_period {polling}', frrconfig) - - for name, config in cache.items(): - self.assertIn('rpki cache {address} {port} preference 1'.format(**config), frrconfig) - - self.session.delete(rpki_path) - + frrconfig = getFRRBGPconfig() + self.assertIn(f'router bgp {ASN}', frrconfig) + self.assertIn(f' address-family l2vpn evpn', frrconfig) + self.assertIn(f' advertise-all-vni', frrconfig) + self.assertIn(f' advertise-default-gw', frrconfig) + self.assertIn(f' advertise-svi-ip', frrconfig) + self.assertIn(f' flooding disable', frrconfig) + for vni in vnis: + vniconfig = getFRRBGPVNIconfig(vni) + self.assertIn(f'vni {vni}', vniconfig) + self.assertIn(f' advertise-default-gw', vniconfig) + self.assertIn(f' advertise-svi-ip', vniconfig) if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/smoketest/scripts/cli/test_protocols_ospf.py b/smoketest/scripts/cli/test_protocols_ospf.py index d47838d8c..0ca8bb3bd 100755 --- a/smoketest/scripts/cli/test_protocols_ospf.py +++ b/smoketest/scripts/cli/test_protocols_ospf.py @@ -30,6 +30,9 @@ route_map = 'foo-bar-baz10' def getFRROSPFconfig(): return cmd('vtysh -c "show run" | sed -n "/router ospf/,/^!/p"') +def getFRRInterfaceConfig(interface): + return cmd(f'vtysh -c "show run" | sed -n "/^interface {interface}$/,/^!/p"') + class TestProtocolsOSPF(unittest.TestCase): def setUp(self): self.session = ConfigSession(os.getpid()) @@ -85,7 +88,7 @@ class TestProtocolsOSPF(unittest.TestCase): def test_ospf_03_access_list(self): acl = '100' seq = '10' - protocols = ['bgp', 'connected', 'kernel', 'rip', 'static'] + protocols = ['bgp', 'connected', 'isis', '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']) @@ -212,7 +215,7 @@ class TestProtocolsOSPF(unittest.TestCase): def test_ospf_08_redistribute(self): metric = '15' metric_type = '1' - redistribute = ['bgp', 'connected', 'kernel', 'rip', 'static'] + redistribute = ['bgp', 'connected', 'isis', 'kernel', 'rip', 'static'] for protocol in redistribute: self.session.set(base_path + ['redistribute', protocol, 'metric', metric]) @@ -232,24 +235,8 @@ class TestProtocolsOSPF(unittest.TestCase): 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' + def test_ospf_09_virtual_link(self): 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' @@ -263,6 +250,8 @@ class TestProtocolsOSPF(unittest.TestCase): 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]) + for network in networks: + self.session.set(base_path + ['area', area, 'network', network]) # commit changes self.session.commit() @@ -272,6 +261,39 @@ class TestProtocolsOSPF(unittest.TestCase): 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) + for network in networks: + self.assertIn(f' network {network} area {area}', frrconfig) + + def test_ospf_10_interface_configureation(self): + interfaces = Section.interfaces('ethernet') + password = 'vyos1234' + bandwidth = '10000' + cost = '150' + network = 'point-to-point' + priority = '200' + + for interface in interfaces: + self.session.set(base_path + ['interface', interface, 'authentication', 'plaintext-password', password]) + self.session.set(base_path + ['interface', interface, 'bandwidth', bandwidth]) + self.session.set(base_path + ['interface', interface, 'bfd']) + self.session.set(base_path + ['interface', interface, 'cost', cost]) + self.session.set(base_path + ['interface', interface, 'mtu-ignore']) + self.session.set(base_path + ['interface', interface, 'network', network]) + self.session.set(base_path + ['interface', interface, 'priority', priority]) + + # commit changes + self.session.commit() + + for interface in interfaces: + config = getFRRInterfaceConfig(interface) + self.assertIn(f'interface {interface}', config) + self.assertIn(f' ip ospf authentication-key {password}', config) + self.assertIn(f' ip ospf bfd', config) + self.assertIn(f' ip ospf cost {cost}', config) + self.assertIn(f' ip ospf mtu-ignore', config) + self.assertIn(f' ip ospf network {network}', config) + self.assertIn(f' ip ospf priority {priority}', config) + self.assertIn(f' bandwidth {bandwidth}', config) 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 index 297d5d996..754c4488f 100755 --- a/smoketest/scripts/cli/test_protocols_ospfv3.py +++ b/smoketest/scripts/cli/test_protocols_ospfv3.py @@ -25,10 +25,15 @@ from vyos.util import process_named_running PROCESS_NAME = 'ospf6d' base_path = ['protocols', 'ospfv3'] +router_id = '192.0.2.1' +default_area = '0' def getFRROSPFconfig(): return cmd('vtysh -c "show run" | sed -n "/router ospf6/,/^!/p"') +def getFRRIFconfig(iface): + return cmd(f'vtysh -c "show run" | sed -n "/^interface {iface}/,/^!/p"') + class TestProtocolsOSPFv3(unittest.TestCase): def setUp(self): self.session = ConfigSession(os.getpid()) @@ -43,23 +48,21 @@ class TestProtocolsOSPFv3(unittest.TestCase): 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]) + self.session.set(base_path + ['area', default_area, 'range', prefix, 'advertise']) + self.session.set(base_path + ['area', default_area, 'export-list', acl_name]) + self.session.set(base_path + ['area', default_area, 'import-list', acl_name]) interfaces = Section.interfaces('ethernet') for interface in interfaces: - self.session.set(base_path + ['area', area, 'interface', interface]) + self.session.set(base_path + ['area', default_area, 'interface', interface]) # commit changes self.session.commit() @@ -67,13 +70,13 @@ class TestProtocolsOSPFv3(unittest.TestCase): # Verify FRR ospfd configuration frrconfig = getFRROSPFconfig() self.assertIn(f'router ospf6', frrconfig) - self.assertIn(f' area {area} range {prefix}', frrconfig) + self.assertIn(f' area {default_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) + self.assertIn(f' area {default_area} import-list {acl_name}', frrconfig) + self.assertIn(f' area {default_area} export-list {acl_name}', frrconfig) for interface in interfaces: - self.assertIn(f' interface {interface} area {area}', frrconfig) + self.assertIn(f' interface {interface} area {default_area}', frrconfig) self.session.delete(['policy', 'access-list6', acl_name]) @@ -118,6 +121,46 @@ class TestProtocolsOSPFv3(unittest.TestCase): for protocol in redistribute: self.assertIn(f' redistribute {protocol} route-map {route_map}', frrconfig) + def test_ospfv3_0104_interfaces(self): + + self.session.set(base_path + ['parameters', 'router-id', router_id]) + self.session.set(base_path + ['area', default_area]) + + cost = '100' + priority = '10' + interfaces = Section.interfaces('ethernet') + for interface in interfaces: + if_base = base_path + ['interface', interface] + self.session.set(if_base + ['bfd']) + self.session.set(if_base + ['cost', cost]) + self.session.set(if_base + ['instance-id', '0']) + self.session.set(if_base + ['mtu-ignore']) + self.session.set(if_base + ['network', 'point-to-point']) + self.session.set(if_base + ['passive']) + self.session.set(if_base + ['priority', priority]) + cost = str(int(cost) + 10) + priority = str(int(priority) + 5) + + # commit changes + self.session.commit() + + # Verify FRR ospfd configuration + frrconfig = getFRROSPFconfig() + self.assertIn(f'router ospf6', frrconfig) + + cost = '100' + priority = '10' + for interface in interfaces: + if_config = getFRRIFconfig(interface) + self.assertIn(f'interface {interface}', if_config) + self.assertIn(f' ipv6 ospf6 bfd', if_config) + self.assertIn(f' ipv6 ospf6 cost {cost}', if_config) + self.assertIn(f' ipv6 ospf6 mtu-ignore', if_config) + self.assertIn(f' ipv6 ospf6 network point-to-point', if_config) + self.assertIn(f' ipv6 ospf6 passive', if_config) + self.assertIn(f' ipv6 ospf6 priority {priority}', if_config) + cost = str(int(cost) + 10) + priority = str(int(priority) + 5) if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/smoketest/scripts/cli/test_protocols_rip.py b/smoketest/scripts/cli/test_protocols_rip.py new file mode 100755 index 000000000..f42ea0c0a --- /dev/null +++ b/smoketest/scripts/cli/test_protocols_rip.py @@ -0,0 +1,138 @@ +#!/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 = 'ripd' +acl_in = '198' +acl_out = '199' +prefix_list_in = 'foo-prefix' +prefix_list_out = 'bar-prefix' +route_map = 'FooBar123' + +base_path = ['protocols', 'rip'] + +def getFRRconfig(): + return cmd('vtysh -c "show run" | sed -n "/router rip/,/^!/p"') + +class TestProtocolsRIP(unittest.TestCase): + def setUp(self): + self.session = ConfigSession(os.getpid()) + + self.session.set(['policy', 'access-list', acl_in, 'rule', '10', 'action', 'permit']) + self.session.set(['policy', 'access-list', acl_in, 'rule', '10', 'source', 'any']) + self.session.set(['policy', 'access-list', acl_in, 'rule', '10', 'destination', 'any']) + self.session.set(['policy', 'access-list', acl_out, 'rule', '20', 'action', 'deny']) + self.session.set(['policy', 'access-list', acl_out, 'rule', '20', 'source', 'any']) + self.session.set(['policy', 'access-list', acl_out, 'rule', '20', 'destination', 'any']) + self.session.set(['policy', 'prefix-list', prefix_list_in, 'rule', '100', 'action', 'permit']) + self.session.set(['policy', 'prefix-list', prefix_list_in, 'rule', '100', 'prefix', '192.0.2.0/24']) + self.session.set(['policy', 'prefix-list', prefix_list_out, 'rule', '200', 'action', 'deny']) + self.session.set(['policy', 'prefix-list', prefix_list_out, 'rule', '200', 'prefix', '192.0.2.0/24']) + self.session.set(['policy', 'route-map', route_map, 'rule', '10', 'action', 'permit']) + + def tearDown(self): + self.session.delete(base_path) + self.session.delete(['policy', 'access-list', acl_in]) + self.session.delete(['policy', 'access-list', acl_out]) + self.session.delete(['policy', 'prefix-list', prefix_list_in]) + self.session.delete(['policy', 'prefix-list', prefix_list_out]) + self.session.delete(['policy', 'route-map', route_map]) + + self.session.commit() + del self.session + + # Check for running process + self.assertTrue(process_named_running(PROCESS_NAME)) + + def test_rip(self): + distance = '40' + network_distance = '66' + metric = '8' + interfaces = Section.interfaces('ethernet') + neighbors = ['1.2.3.4', '1.2.3.5', '1.2.3.6'] + networks = ['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16'] + redistribute = ['bgp', 'connected', 'isis', 'kernel', 'ospf', 'static'] + timer_garbage = '888' + timer_timeout = '1000' + timer_update = '90' + + self.session.set(base_path + ['default-distance', distance]) + self.session.set(base_path + ['default-information', 'originate']) + self.session.set(base_path + ['default-metric', metric]) + self.session.set(base_path + ['distribute-list', 'access-list', 'in', acl_in]) + self.session.set(base_path + ['distribute-list', 'access-list', 'out', acl_out]) + self.session.set(base_path + ['distribute-list', 'prefix-list', 'in', prefix_list_in]) + self.session.set(base_path + ['distribute-list', 'prefix-list', 'out', prefix_list_out]) + self.session.set(base_path + ['passive-interface', 'default']) + self.session.set(base_path + ['timers', 'garbage-collection', timer_garbage]) + self.session.set(base_path + ['timers', 'timeout', timer_timeout]) + self.session.set(base_path + ['timers', 'update', timer_update]) + for interface in interfaces: + self.session.set(base_path + ['interface', interface]) + self.session.set(base_path + ['distribute-list', 'interface', interface, 'access-list', 'in', acl_in]) + self.session.set(base_path + ['distribute-list', 'interface', interface, 'access-list', 'out', acl_out]) + self.session.set(base_path + ['distribute-list', 'interface', interface, 'prefix-list', 'in', prefix_list_in]) + self.session.set(base_path + ['distribute-list', 'interface', interface, 'prefix-list', 'out', prefix_list_out]) + for neighbor in neighbors: + self.session.set(base_path + ['neighbor', neighbor]) + for network in networks: + self.session.set(base_path + ['network', network]) + self.session.set(base_path + ['network-distance', network, 'distance', network_distance]) + self.session.set(base_path + ['route', network]) + for proto in redistribute: + self.session.set(base_path + ['redistribute', proto, 'metric', metric]) + self.session.set(base_path + ['redistribute', proto, 'route-map', route_map]) + + + # commit changes + self.session.commit() + + # Verify FRR ospfd configuration + frrconfig = getFRRconfig() + self.assertIn(f'router rip', frrconfig) + self.assertIn(f' distance {distance}', frrconfig) + self.assertIn(f' default-information originate', frrconfig) + self.assertIn(f' default-metric {metric}', frrconfig) + self.assertIn(f' distribute-list {acl_in} in', frrconfig) + self.assertIn(f' distribute-list {acl_out} out', frrconfig) + self.assertIn(f' distribute-list prefix {prefix_list_in} in', frrconfig) + self.assertIn(f' distribute-list prefix {prefix_list_out} out', frrconfig) + self.assertIn(f' passive-interface default', frrconfig) + self.assertIn(f' timers basic {timer_update} {timer_timeout} {timer_garbage}', frrconfig) + for interface in interfaces: + self.assertIn(f' network {interface}', frrconfig) + self.assertIn(f' distribute-list {acl_in} in {interface}', frrconfig) + self.assertIn(f' distribute-list {acl_out} out {interface}', frrconfig) + self.assertIn(f' distribute-list prefix {prefix_list_in} in {interface}', frrconfig) + self.assertIn(f' distribute-list prefix {prefix_list_out} out {interface}', frrconfig) + for neighbor in neighbors: + self.assertIn(f' neighbor {neighbor}', frrconfig) + for network in networks: + self.assertIn(f' network {network}', frrconfig) + self.assertIn(f' distance {network_distance} {network}', frrconfig) + self.assertIn(f' route {network}', frrconfig) + for proto in redistribute: + self.assertIn(f' redistribute {proto} metric {metric} route-map {route_map}', frrconfig) + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/smoketest/scripts/cli/test_protocols_ripng.py b/smoketest/scripts/cli/test_protocols_ripng.py new file mode 100755 index 000000000..6850b60d3 --- /dev/null +++ b/smoketest/scripts/cli/test_protocols_ripng.py @@ -0,0 +1,133 @@ +#!/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 = 'ripngd' +acl_in = '198' +acl_out = '199' +prefix_list_in = 'foo-prefix' +prefix_list_out = 'bar-prefix' +route_map = 'FooBar123' + +base_path = ['protocols', 'ripng'] + +def getFRRconfig(): + return cmd('vtysh -c "show run" | sed -n "/router ripng/,/^!/p"') + +class TestProtocolsRIPng(unittest.TestCase): + def setUp(self): + self.session = ConfigSession(os.getpid()) + + self.session.set(['policy', 'access-list6', acl_in, 'rule', '10', 'action', 'permit']) + self.session.set(['policy', 'access-list6', acl_in, 'rule', '10', 'source', 'any']) + self.session.set(['policy', 'access-list6', acl_out, 'rule', '20', 'action', 'deny']) + self.session.set(['policy', 'access-list6', acl_out, 'rule', '20', 'source', 'any']) + self.session.set(['policy', 'prefix-list6', prefix_list_in, 'rule', '100', 'action', 'permit']) + self.session.set(['policy', 'prefix-list6', prefix_list_in, 'rule', '100', 'prefix', '2001:db8::/32']) + self.session.set(['policy', 'prefix-list6', prefix_list_out, 'rule', '200', 'action', 'deny']) + self.session.set(['policy', 'prefix-list6', prefix_list_out, 'rule', '200', 'prefix', '2001:db8::/32']) + self.session.set(['policy', 'route-map', route_map, 'rule', '10', 'action', 'permit']) + + def tearDown(self): + self.session.delete(base_path) + self.session.delete(['policy', 'access-list6', acl_in]) + self.session.delete(['policy', 'access-list6', acl_out]) + self.session.delete(['policy', 'prefix-list6', prefix_list_in]) + self.session.delete(['policy', 'prefix-list6', prefix_list_out]) + self.session.delete(['policy', 'route-map', route_map]) + + self.session.commit() + del self.session + + # Check for running process + self.assertTrue(process_named_running(PROCESS_NAME)) + + def test_ripng(self): + metric = '8' + interfaces = Section.interfaces('ethernet') + aggregates = ['2001:db8:1000::/48', '2001:db8:2000::/48', '2001:db8:3000::/48'] + networks = ['2001:db8:1000::/64', '2001:db8:1001::/64', '2001:db8:2000::/64', '2001:db8:2001::/64'] + redistribute = ['bgp', 'connected', 'kernel', 'ospfv3', 'static'] + timer_garbage = '888' + timer_timeout = '1000' + timer_update = '90' + + self.session.set(base_path + ['default-information', 'originate']) + self.session.set(base_path + ['default-metric', metric]) + self.session.set(base_path + ['distribute-list', 'access-list', 'in', acl_in]) + self.session.set(base_path + ['distribute-list', 'access-list', 'out', acl_out]) + self.session.set(base_path + ['distribute-list', 'prefix-list', 'in', prefix_list_in]) + self.session.set(base_path + ['distribute-list', 'prefix-list', 'out', prefix_list_out]) + self.session.set(base_path + ['passive-interface', 'default']) + self.session.set(base_path + ['timers', 'garbage-collection', timer_garbage]) + self.session.set(base_path + ['timers', 'timeout', timer_timeout]) + self.session.set(base_path + ['timers', 'update', timer_update]) + for aggregate in aggregates: + self.session.set(base_path + ['aggregate-address', aggregate]) + + for interface in interfaces: + self.session.set(base_path + ['interface', interface]) + self.session.set(base_path + ['distribute-list', 'interface', interface, 'access-list', 'in', acl_in]) + self.session.set(base_path + ['distribute-list', 'interface', interface, 'access-list', 'out', acl_out]) + self.session.set(base_path + ['distribute-list', 'interface', interface, 'prefix-list', 'in', prefix_list_in]) + self.session.set(base_path + ['distribute-list', 'interface', interface, 'prefix-list', 'out', prefix_list_out]) + for network in networks: + self.session.set(base_path + ['network', network]) + self.session.set(base_path + ['route', network]) + for proto in redistribute: + self.session.set(base_path + ['redistribute', proto, 'metric', metric]) + self.session.set(base_path + ['redistribute', proto, 'route-map', route_map]) + + + # commit changes + self.session.commit() + + # Verify FRR ospfd configuration + frrconfig = getFRRconfig() + self.assertIn(f'router ripng', frrconfig) + self.assertIn(f' default-information originate', frrconfig) + self.assertIn(f' default-metric {metric}', frrconfig) + self.assertIn(f' ipv6 distribute-list {acl_in} in', frrconfig) + self.assertIn(f' ipv6 distribute-list {acl_out} out', frrconfig) + self.assertIn(f' ipv6 distribute-list prefix {prefix_list_in} in', frrconfig) + self.assertIn(f' ipv6 distribute-list prefix {prefix_list_out} out', frrconfig) + self.assertIn(f' passive-interface default', frrconfig) + self.assertIn(f' timers basic {timer_update} {timer_timeout} {timer_garbage}', frrconfig) + for aggregate in aggregates: + self.assertIn(f' aggregate-address {aggregate}', frrconfig) + for interface in interfaces: + self.assertIn(f' network {interface}', frrconfig) + self.assertIn(f' ipv6 distribute-list {acl_in} in {interface}', frrconfig) + self.assertIn(f' ipv6 distribute-list {acl_out} out {interface}', frrconfig) + self.assertIn(f' ipv6 distribute-list prefix {prefix_list_in} in {interface}', frrconfig) + self.assertIn(f' ipv6 distribute-list prefix {prefix_list_out} out {interface}', frrconfig) + for network in networks: + self.assertIn(f' network {network}', frrconfig) + self.assertIn(f' route {network}', frrconfig) + for proto in redistribute: + if proto == 'ospfv3': + proto = 'ospf6' + self.assertIn(f' redistribute {proto} metric {metric} route-map {route_map}', frrconfig) + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/smoketest/scripts/cli/test_protocols_rpki.py b/smoketest/scripts/cli/test_protocols_rpki.py new file mode 100755 index 000000000..bec4ef76f --- /dev/null +++ b/smoketest/scripts/cli/test_protocols_rpki.py @@ -0,0 +1,159 @@ +#!/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.configsession import ConfigSessionError +from vyos.util import cmd +from vyos.util import process_named_running + +base_path = ['protocols', 'rpki'] +PROCESS_NAME = 'bgpd' + +rpki_known_hosts = '/config/auth/known_hosts' +rpki_ssh_key = '/config/auth/id_rsa_rpki' +rpki_ssh_pub = f'{rpki_ssh_key}.pub' + +def getFRRRPKIconfig(): + return cmd(f'vtysh -c "show run" | sed -n "/rpki/,/^!/p"') + +class TestProtocolsRPKI(unittest.TestCase): + def setUp(self): + self.session = ConfigSession(os.getpid()) + + def tearDown(self): + self.session.delete(base_path) + self.session.commit() + del self.session + + # Nothing RPKI specific should be left over in the config + # + # Disabled until T3266 is resolved + # frrconfig = getFRRRPKIconfig() + # self.assertNotIn('rpki', frrconfig) + + # Check for running process + self.assertTrue(process_named_running(PROCESS_NAME)) + + def test_rpki(self): + polling = '7200' + cache = { + '192.0.2.1' : { + 'port' : '8080', + 'preference' : '1' + }, + '192.0.2.2' : { + 'port' : '9090', + 'preference' : '2' + }, + '2001:db8::1' : { + 'port' : '1234', + 'preference' : '3' + }, + '2001:db8::2' : { + 'port' : '5678', + 'preference' : '4' + }, + } + + self.session.set(base_path + ['polling-period', polling]) + for peer, peer_config in cache.items(): + self.session.set(base_path + ['cache', peer, 'port', peer_config['port']]) + self.session.set(base_path + ['cache', peer, 'preference', peer_config['preference']]) + + # commit changes + self.session.commit() + + # Verify FRR configuration + frrconfig = getFRRRPKIconfig() + self.assertIn(f'rpki polling_period {polling}', frrconfig) + + for peer, peer_config in cache.items(): + port = peer_config['port'] + preference = peer_config['preference'] + self.assertIn(f'rpki cache {peer} {port} preference {preference}', frrconfig) + + def test_rpki_ssh(self): + polling = '7200' + cache = { + '192.0.2.3' : { + 'port' : '1234', + 'username' : 'foo', + 'preference' : '10' + }, + '192.0.2.4' : { + 'port' : '5678', + 'username' : 'bar', + 'preference' : '20' + }, + } + + self.session.set(base_path + ['polling-period', polling]) + + for peer, peer_config in cache.items(): + self.session.set(base_path + ['cache', peer, 'port', peer_config['port']]) + self.session.set(base_path + ['cache', peer, 'preference', peer_config['preference']]) + self.session.set(base_path + ['cache', peer, 'ssh', 'username', peer_config['username']]) + self.session.set(base_path + ['cache', peer, 'ssh', 'public-key-file', rpki_ssh_pub]) + self.session.set(base_path + ['cache', peer, 'ssh', 'private-key-file', rpki_ssh_key]) + self.session.set(base_path + ['cache', peer, 'ssh', 'known-hosts-file', rpki_known_hosts]) + + # commit changes + self.session.commit() + + # Verify FRR configuration + frrconfig = getFRRRPKIconfig() + self.assertIn(f'rpki polling_period {polling}', frrconfig) + + for peer, peer_config in cache.items(): + port = peer_config['port'] + preference = peer_config['preference'] + username = peer_config['username'] + self.assertIn(f'rpki cache {peer} {port} {username} {rpki_ssh_key} {rpki_known_hosts} preference {preference}', frrconfig) + + + def test_rpki_verify_preference(self): + cache = { + '192.0.2.1' : { + 'port' : '8080', + 'preference' : '1' + }, + '192.0.2.2' : { + 'port' : '9090', + 'preference' : '1' + }, + } + + for peer, peer_config in cache.items(): + self.session.set(base_path + ['cache', peer, 'port', peer_config['port']]) + self.session.set(base_path + ['cache', peer, 'preference', peer_config['preference']]) + + # check validate() - preferences must be unique + with self.assertRaises(ConfigSessionError): + self.session.commit() + + +if __name__ == '__main__': + # Create OpenSSH keypair used in RPKI tests + if not os.path.isfile(rpki_ssh_key): + cmd(f'ssh-keygen -t rsa -f {rpki_ssh_key} -N ""') + + if not os.path.isfile(rpki_known_hosts): + cmd(f'touch {rpki_known_hosts}') + + unittest.main(verbosity=2) diff --git a/smoketest/scripts/cli/test_protocols_static.py b/smoketest/scripts/cli/test_protocols_static.py new file mode 100755 index 000000000..cf591f060 --- /dev/null +++ b/smoketest/scripts/cli/test_protocols_static.py @@ -0,0 +1,385 @@ +#!/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.configsession import ConfigSessionError +from vyos.template import is_ipv6 +from vyos.util import cmd + +base_path = ['protocols', 'static'] +vrf_path = ['protocols', 'vrf'] + +def getFRRCconfig(vrf=None): + if vrf: + return cmd(f'vtysh -c "show run" | sed -n "/^vrf {vrf}/,/^!/p"') + else: + return cmd(f'vtysh -c "show run" | sed -n "/^ip route/,/^!/p"') + +routes = { + '10.0.0.0/8' : { + 'next_hop' : { + '192.0.2.100' : { 'distance' : '100' }, + '192.0.2.110' : { 'distance' : '110', 'interface' : 'eth0' }, + '192.0.2.120' : { 'distance' : '120', 'disable' : '' }, + }, + 'interface' : { + 'eth0' : { 'distance' : '130' }, + 'eth1' : { 'distance' : '140' }, + }, + 'blackhole' : { 'distance' : '250', 'tag' : '500' }, + }, + '172.16.0.0/12' : { + 'interface' : { + 'eth0' : { 'distance' : '50', 'vrf' : 'black' }, + 'eth1' : { 'distance' : '60', 'vrf' : 'black' }, + }, + 'blackhole' : { 'distance' : '90' }, + }, + '192.0.2.0/24' : { + 'interface' : { + 'eth0' : { 'distance' : '50', 'vrf' : 'black' }, + 'eth1' : { 'disable' : '' }, + }, + 'blackhole' : { 'distance' : '90' }, + }, + '100.64.0.0/10' : { + 'blackhole' : { }, + }, + '2001:db8:100::/40' : { + 'next_hop' : { + '2001:db8::1' : { 'distance' : '10' }, + '2001:db8::2' : { 'distance' : '20', 'interface' : 'eth0' }, + '2001:db8::3' : { 'distance' : '30', 'disable' : '' }, + }, + 'interface' : { + 'eth0' : { 'distance' : '40', 'vrf' : 'black' }, + 'eth1' : { 'distance' : '50', 'disable' : '' }, + }, + 'blackhole' : { 'distance' : '250', 'tag' : '500' }, + }, + '2001:db8:200::/40' : { + 'interface' : { + 'eth0' : { 'distance' : '40' }, + 'eth1' : { 'distance' : '50', 'disable' : '' }, + }, + 'blackhole' : { 'distance' : '250', 'tag' : '500' }, + }, + '2001:db8::/32' : { + 'blackhole' : { 'distance' : '200', 'tag' : '600' }, + }, +} + +vrfs = ['red', 'green', 'blue'] +tables = ['80', '81', '82'] + +class StaticRouteTest(unittest.TestCase): + def setUp(self): + self.session = ConfigSession(os.getpid()) + + def tearDown(self): + for route, route_config in routes.items(): + route_type = 'route' + if is_ipv6(route): + route_type = 'route6' + self.session.delete(base_path + [route_type, route]) + + for vrf in vrfs: + self.session.delete(vrf_path + [vrf]) + + for table in tables: + self.session.delete(base_path + ['table', table]) + + self.session.commit() + del self.session + + def test_protocols_static(self): + for route, route_config in routes.items(): + route_type = 'route' + if is_ipv6(route): + route_type = 'route6' + base = base_path + [route_type, route] + if 'next_hop' in route_config: + for next_hop, next_hop_config in route_config['next_hop'].items(): + self.session.set(base + ['next-hop', next_hop]) + if 'disable' in next_hop_config: + self.session.set(base + ['next-hop', next_hop, 'disable']) + if 'distance' in next_hop_config: + self.session.set(base + ['next-hop', next_hop, 'distance', next_hop_config['distance']]) + if 'interface' in next_hop_config: + self.session.set(base + ['next-hop', next_hop, 'interface', next_hop_config['interface']]) + if 'vrf' in next_hop_config: + self.session.set(base + ['next-hop', next_hop, 'vrf', next_hop_config['vrf']]) + + + if 'interface' in route_config: + for interface, interface_config in route_config['interface'].items(): + self.session.set(base + ['interface', interface]) + if 'disable' in interface_config: + self.session.set(base + ['interface', interface, 'disable']) + if 'distance' in interface_config: + self.session.set(base + ['interface', interface, 'distance', interface_config['distance']]) + if 'vrf' in interface_config: + self.session.set(base + ['interface', interface, 'vrf', interface_config['vrf']]) + + if 'blackhole' in route_config: + self.session.set(base + ['blackhole']) + if 'distance' in route_config['blackhole']: + self.session.set(base + ['blackhole', 'distance', route_config['blackhole']['distance']]) + if 'tag' in route_config['blackhole']: + self.session.set(base + ['blackhole', 'tag', route_config['blackhole']['tag']]) + + # commit changes + self.session.commit() + + # Verify FRR bgpd configuration + frrconfig = getFRRCconfig() + + # Verify routes + for route, route_config in routes.items(): + ip_ipv6 = 'ip' + if is_ipv6(route): + ip_ipv6 = 'ipv6' + + if 'next_hop' in route_config: + for next_hop, next_hop_config in route_config['next_hop'].items(): + tmp = f'{ip_ipv6} route {route} {next_hop}' + if 'interface' in next_hop_config: + tmp += ' ' + next_hop_config['interface'] + if 'distance' in next_hop_config: + tmp += ' ' + next_hop_config['distance'] + if 'vrf' in next_hop_config: + tmp += ' nexthop-vrf ' + next_hop_config['vrf'] + + if 'disable' in next_hop_config: + self.assertNotIn(tmp, frrconfig) + else: + self.assertIn(tmp, frrconfig) + + if 'interface' in route_config: + for interface, interface_config in route_config['interface'].items(): + tmp = f'{ip_ipv6} route {route} {interface}' + if 'interface' in interface_config: + tmp += ' ' + interface_config['interface'] + if 'distance' in interface_config: + tmp += ' ' + interface_config['distance'] + if 'vrf' in interface_config: + tmp += ' nexthop-vrf ' + interface_config['vrf'] + + if 'disable' in interface_config: + self.assertNotIn(tmp, frrconfig) + else: + self.assertIn(tmp, frrconfig) + + if 'blackhole' in route_config: + tmp = f'{ip_ipv6} route {route} blackhole' + if 'tag' in route_config['blackhole']: + tmp += ' tag ' + route_config['blackhole']['tag'] + if 'distance' in route_config['blackhole']: + tmp += ' ' + route_config['blackhole']['distance'] + + self.assertIn(tmp, frrconfig) + + def test_protocols_static_table(self): + for table in tables: + for route, route_config in routes.items(): + route_type = 'route' + if is_ipv6(route): + route_type = 'route6' + base = base_path + ['table', table, route_type, route] + + if 'next_hop' in route_config: + for next_hop, next_hop_config in route_config['next_hop'].items(): + self.session.set(base + ['next-hop', next_hop]) + if 'disable' in next_hop_config: + self.session.set(base + ['next-hop', next_hop, 'disable']) + if 'distance' in next_hop_config: + self.session.set(base + ['next-hop', next_hop, 'distance', next_hop_config['distance']]) + if 'interface' in next_hop_config: + self.session.set(base + ['next-hop', next_hop, 'interface', next_hop_config['interface']]) + if 'vrf' in next_hop_config: + self.session.set(base + ['next-hop', next_hop, 'vrf', next_hop_config['vrf']]) + + + if 'interface' in route_config: + for interface, interface_config in route_config['interface'].items(): + self.session.set(base + ['interface', interface]) + if 'disable' in interface_config: + self.session.set(base + ['interface', interface, 'disable']) + if 'distance' in interface_config: + self.session.set(base + ['interface', interface, 'distance', interface_config['distance']]) + if 'vrf' in interface_config: + self.session.set(base + ['interface', interface, 'vrf', interface_config['vrf']]) + + if 'blackhole' in route_config: + self.session.set(base + ['blackhole']) + if 'distance' in route_config['blackhole']: + self.session.set(base + ['blackhole', 'distance', route_config['blackhole']['distance']]) + if 'tag' in route_config['blackhole']: + self.session.set(base + ['blackhole', 'tag', route_config['blackhole']['tag']]) + + # commit changes + self.session.commit() + + # Verify FRR bgpd configuration + frrconfig = getFRRCconfig() + + for table in tables: + # Verify routes + for route, route_config in routes.items(): + ip_ipv6 = 'ip' + if is_ipv6(route): + ip_ipv6 = 'ipv6' + + if 'next_hop' in route_config: + for next_hop, next_hop_config in route_config['next_hop'].items(): + tmp = f'{ip_ipv6} route {route} {next_hop}' + if 'interface' in next_hop_config: + tmp += ' ' + next_hop_config['interface'] + if 'distance' in next_hop_config: + tmp += ' ' + next_hop_config['distance'] + if 'vrf' in next_hop_config: + tmp += ' nexthop-vrf ' + next_hop_config['vrf'] + + tmp += ' table ' + table + if 'disable' in next_hop_config: + self.assertNotIn(tmp, frrconfig) + else: + self.assertIn(tmp, frrconfig) + + if 'interface' in route_config: + for interface, interface_config in route_config['interface'].items(): + tmp = f'{ip_ipv6} route {route} {interface}' + if 'interface' in interface_config: + tmp += ' ' + interface_config['interface'] + if 'distance' in interface_config: + tmp += ' ' + interface_config['distance'] + if 'vrf' in interface_config: + tmp += ' nexthop-vrf ' + interface_config['vrf'] + + tmp += ' table ' + table + if 'disable' in interface_config: + self.assertNotIn(tmp, frrconfig) + else: + self.assertIn(tmp, frrconfig) + + if 'blackhole' in route_config: + tmp = f'{ip_ipv6} route {route} blackhole' + if 'tag' in route_config['blackhole']: + tmp += ' tag ' + route_config['blackhole']['tag'] + if 'distance' in route_config['blackhole']: + tmp += ' ' + route_config['blackhole']['distance'] + + tmp += ' table ' + table + self.assertIn(tmp, frrconfig) + + + def test_protocols_vrf_static(self): + for vrf in vrfs: + for route, route_config in routes.items(): + route_type = 'route' + if is_ipv6(route): + route_type = 'route6' + base = vrf_path + [vrf, 'static', route_type, route] + + if 'next_hop' in route_config: + for next_hop, next_hop_config in route_config['next_hop'].items(): + self.session.set(base + ['next-hop', next_hop]) + if 'disable' in next_hop_config: + self.session.set(base + ['next-hop', next_hop, 'disable']) + if 'distance' in next_hop_config: + self.session.set(base + ['next-hop', next_hop, 'distance', next_hop_config['distance']]) + if 'interface' in next_hop_config: + self.session.set(base + ['next-hop', next_hop, 'interface', next_hop_config['interface']]) + if 'vrf' in next_hop_config: + self.session.set(base + ['next-hop', next_hop, 'vrf', next_hop_config['vrf']]) + + + if 'interface' in route_config: + for interface, interface_config in route_config['interface'].items(): + self.session.set(base + ['interface', interface]) + if 'disable' in interface_config: + self.session.set(base + ['interface', interface, 'disable']) + if 'distance' in interface_config: + self.session.set(base + ['interface', interface, 'distance', interface_config['distance']]) + if 'vrf' in interface_config: + self.session.set(base + ['interface', interface, 'vrf', interface_config['vrf']]) + + if 'blackhole' in route_config: + self.session.set(base + ['blackhole']) + if 'distance' in route_config['blackhole']: + self.session.set(base + ['blackhole', 'distance', route_config['blackhole']['distance']]) + if 'tag' in route_config['blackhole']: + self.session.set(base + ['blackhole', 'tag', route_config['blackhole']['tag']]) + + # commit changes + self.session.commit() + + for vrf in vrfs: + # Verify FRR bgpd configuration + frrconfig = getFRRCconfig(vrf) + self.assertIn(f'vrf {vrf}', frrconfig) + + # Verify routes + for route, route_config in routes.items(): + ip_ipv6 = 'ip' + if is_ipv6(route): + ip_ipv6 = 'ipv6' + + if 'next_hop' in route_config: + for next_hop, next_hop_config in route_config['next_hop'].items(): + tmp = f'{ip_ipv6} route {route} {next_hop}' + if 'interface' in next_hop_config: + tmp += ' ' + next_hop_config['interface'] + if 'distance' in next_hop_config: + tmp += ' ' + next_hop_config['distance'] + if 'vrf' in next_hop_config: + tmp += ' nexthop-vrf ' + next_hop_config['vrf'] + + if 'disable' in next_hop_config: + self.assertNotIn(tmp, frrconfig) + else: + self.assertIn(tmp, frrconfig) + + if 'interface' in route_config: + for interface, interface_config in route_config['interface'].items(): + tmp = f'{ip_ipv6} route {route} {interface}' + if 'interface' in interface_config: + tmp += ' ' + interface_config['interface'] + if 'distance' in interface_config: + tmp += ' ' + interface_config['distance'] + if 'vrf' in interface_config: + tmp += ' nexthop-vrf ' + interface_config['vrf'] + + if 'disable' in interface_config: + self.assertNotIn(tmp, frrconfig) + else: + self.assertIn(tmp, frrconfig) + + if 'blackhole' in route_config: + tmp = f'{ip_ipv6} route {route} blackhole' + if 'tag' in route_config['blackhole']: + tmp += ' tag ' + route_config['blackhole']['tag'] + if 'distance' in route_config['blackhole']: + tmp += ' ' + route_config['blackhole']['distance'] + + self.assertIn(tmp, frrconfig) + + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/smoketest/scripts/cli/test_service_bcast-relay.py b/smoketest/scripts/cli/test_service_bcast-relay.py index c28509714..00d7750aa 100755 --- a/smoketest/scripts/cli/test_service_bcast-relay.py +++ b/smoketest/scripts/cli/test_service_bcast-relay.py @@ -30,7 +30,6 @@ class TestServiceBroadcastRelay(unittest.TestCase): self.session = ConfigSession(os.getpid()) self.session.set(['interfaces', 'dummy', 'dum1001', 'address', self._address1]) self.session.set(['interfaces', 'dummy', 'dum1002', 'address', self._address2]) - self.session.commit() def tearDown(self): self.session.delete(['interfaces', 'dummy', 'dum1001']) diff --git a/smoketest/scripts/cli/test_vrf.py b/smoketest/scripts/cli/test_vrf.py index 5270e758a..8e977d407 100755 --- a/smoketest/scripts/cli/test_vrf.py +++ b/smoketest/scripts/cli/test_vrf.py @@ -16,19 +16,44 @@ import re import os +import json import unittest + from netifaces import interfaces from vyos.configsession import ConfigSession from vyos.configsession import ConfigSessionError +from vyos.ifconfig import Interface +from vyos.ifconfig import Section +from vyos.template import is_ipv6 +from vyos.util import cmd from vyos.util import read_file from vyos.validate import is_intf_addr_assigned -from vyos.ifconfig import Interface base_path = ['vrf'] vrfs = ['red', 'green', 'blue', 'foo-bar', 'baz_foo'] +def get_vrf_ipv4_routes(vrf): + return json.loads(cmd(f'ip -4 -j route show vrf {vrf}')) + +def get_vrf_ipv6_routes(vrf): + return json.loads(cmd(f'ip -6 -j route show vrf {vrf}')) + class VRFTest(unittest.TestCase): + _interfaces = [] + + @classmethod + def setUpClass(cls): + # we need to filter out VLAN interfaces identified by a dot (.) + # in their name - just in case! + if 'TEST_ETH' in os.environ: + tmp = os.environ['TEST_ETH'].split() + cls._interfaces = tmp + else: + for tmp in Section.interfaces('ethernet'): + if not '.' in tmp: + cls._interfaces.append(tmp) + def setUp(self): self.session = ConfigSession(os.getpid()) @@ -120,5 +145,26 @@ class VRFTest(unittest.TestCase): with self.assertRaises(ConfigSessionError): self.session.commit() + def test_vrf_assign_interface(self): + vrf = vrfs[0] + table = '5000' + self.session.set(['vrf', 'name', vrf, 'table', table]) + + for interface in self._interfaces: + section = Section.section(interface) + self.session.set(['interfaces', section, interface, 'vrf', vrf]) + + # commit changes + self.session.commit() + + # Verify & cleanup + for interface in self._interfaces: + # os.readlink resolves to: '../../../../../virtual/net/foovrf' + tmp = os.readlink(f'/sys/class/net/{interface}/master').split('/')[-1] + self.assertEqual(tmp, vrf) + # cleanup + section = Section.section(interface) + self.session.delete(['interfaces', section, interface, 'vrf']) + if __name__ == '__main__': - unittest.main(verbosity=2, failfast=True) + unittest.main(verbosity=2) |