summaryrefslogtreecommitdiff
path: root/smoketest
diff options
context:
space:
mode:
Diffstat (limited to 'smoketest')
-rwxr-xr-xsmoketest/bin/vyos-configtest23
-rw-r--r--smoketest/config-tests/basic-vyos62
-rw-r--r--smoketest/config-tests/dialup-router-medium-vpn321
-rw-r--r--smoketest/configs/basic-vyos12
-rw-r--r--smoketest/scripts/cli/base_interfaces_test.py8
-rwxr-xr-xsmoketest/scripts/cli/test_component_version.py50
-rwxr-xr-xsmoketest/scripts/cli/test_dependency_graph.py54
-rwxr-xr-xsmoketest/scripts/cli/test_firewall.py137
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_openvpn.py76
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_pppoe.py9
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_vxlan.py50
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_wireless.py3
-rwxr-xr-xsmoketest/scripts/cli/test_load_balancing_reverse_proxy.py2
-rwxr-xr-xsmoketest/scripts/cli/test_load_balancing_wan.py7
-rwxr-xr-xsmoketest/scripts/cli/test_nat.py5
-rwxr-xr-xsmoketest/scripts/cli/test_netns.py (renamed from smoketest/scripts/cli/test_interfaces_netns.py)52
-rwxr-xr-xsmoketest/scripts/cli/test_policy.py58
-rwxr-xr-xsmoketest/scripts/cli/test_policy_route.py16
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_bgp.py16
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_isis.py4
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_pim6.py110
-rwxr-xr-xsmoketest/scripts/cli/test_service_dns_dynamic.py192
-rwxr-xr-xsmoketest/scripts/cli/test_service_mdns-repeater.py74
-rwxr-xr-xsmoketest/scripts/cli/test_system_conntrack.py99
-rwxr-xr-xsmoketest/scripts/cli/test_system_flow-accounting.py2
-rwxr-xr-xsmoketest/scripts/cli/test_vpn_ipsec.py120
-rwxr-xr-xsmoketest/scripts/system/test_kernel_options.py6
27 files changed, 1170 insertions, 398 deletions
diff --git a/smoketest/bin/vyos-configtest b/smoketest/bin/vyos-configtest
index 3e42b0380..c1b602737 100755
--- a/smoketest/bin/vyos-configtest
+++ b/smoketest/bin/vyos-configtest
@@ -24,6 +24,7 @@ from vyos.configsession import ConfigSession, ConfigSessionError
from vyos import ConfigError
config_dir = '/usr/libexec/vyos/tests/config'
+config_test_dir = '/usr/libexec/vyos/tests/config-tests'
save_config = '/tmp/vyos-configtest-save'
class DynamicClassBase(unittest.TestCase):
@@ -42,7 +43,7 @@ class DynamicClassBase(unittest.TestCase):
except OSError:
pass
-def make_test_function(filename):
+def make_test_function(filename, test_path=None):
def test_config_load(self):
config_path = os.path.join(config_dir, filename)
self.session.migrate_and_load_config(config_path)
@@ -51,6 +52,16 @@ def make_test_function(filename):
except (ConfigError, ConfigSessionError):
self.session.discard()
self.fail()
+
+ if test_path:
+ config_commands = self.session.show(['configuration', 'commands'])
+
+ with open(test_path, 'r') as f:
+ for line in f.readlines():
+ if not line or line.startswith("#"):
+ continue
+
+ self.assertIn(line, config_commands)
return test_config_load
def class_name_from_func_name(s):
@@ -69,10 +80,18 @@ if __name__ == '__main__':
config_list.sort()
for config in config_list:
- test_func = make_test_function(config)
+ test_path = os.path.join(config_test_dir, config)
+
+ if not os.path.exists(test_path):
+ test_path = None
+ else:
+ log.info(f'Loaded migration result test for config "{config}"')
+
+ test_func = make_test_function(config, test_path)
func_name = config.replace('-', '_')
klassname = f'TestConfig{class_name_from_func_name(func_name)}'
+
globals()[klassname] = type(klassname,
(DynamicClassBase,),
{f'test_{func_name}': test_func})
diff --git a/smoketest/config-tests/basic-vyos b/smoketest/config-tests/basic-vyos
new file mode 100644
index 000000000..ef8bf374a
--- /dev/null
+++ b/smoketest/config-tests/basic-vyos
@@ -0,0 +1,62 @@
+set interfaces ethernet eth0 address '192.168.0.1/24'
+set interfaces ethernet eth0 duplex 'auto'
+set interfaces ethernet eth0 speed 'auto'
+set interfaces ethernet eth1 duplex 'auto'
+set interfaces ethernet eth1 speed 'auto'
+set interfaces ethernet eth2 duplex 'auto'
+set interfaces ethernet eth2 speed 'auto'
+set interfaces ethernet eth2 vif 100 address '100.100.0.1/24'
+set interfaces ethernet eth2 vif-s 200 address '100.64.200.254/24'
+set interfaces ethernet eth2 vif-s 200 vif-c 201 address '100.64.201.254/24'
+set interfaces ethernet eth2 vif-s 200 vif-c 202 address '100.64.202.254/24'
+set interfaces loopback lo
+set protocols static arp interface eth0 address 192.168.0.20 mac '00:50:00:00:00:20'
+set protocols static arp interface eth0 address 192.168.0.30 mac '00:50:00:00:00:30'
+set protocols static arp interface eth0 address 192.168.0.40 mac '00:50:00:00:00:40'
+set protocols static arp interface eth2.100 address 100.100.0.2 mac '00:50:00:00:02:02'
+set protocols static arp interface eth2.100 address 100.100.0.3 mac '00:50:00:00:02:03'
+set protocols static arp interface eth2.100 address 100.100.0.4 mac '00:50:00:00:02:04'
+set protocols static arp interface eth2.200 address 100.64.200.1 mac '00:50:00:00:00:01'
+set protocols static arp interface eth2.200 address 100.64.200.2 mac '00:50:00:00:00:02'
+set protocols static arp interface eth2.200.201 address 100.64.201.10 mac '00:50:00:00:00:10'
+set protocols static arp interface eth2.200.201 address 100.64.201.20 mac '00:50:00:00:00:20'
+set protocols static arp interface eth2.200.202 address 100.64.202.30 mac '00:50:00:00:00:30'
+set protocols static arp interface eth2.200.202 address 100.64.202.40 mac '00:50:00:00:00:40'
+set protocols static route 0.0.0.0/0 next-hop 100.64.0.1
+set service dhcp-server shared-network-name LAN authoritative
+set service dhcp-server shared-network-name LAN subnet 192.168.0.0/24 default-router '192.168.0.1'
+set service dhcp-server shared-network-name LAN subnet 192.168.0.0/24 domain-name 'vyos.net'
+set service dhcp-server shared-network-name LAN subnet 192.168.0.0/24 domain-search 'vyos.net'
+set service dhcp-server shared-network-name LAN subnet 192.168.0.0/24 name-server '192.168.0.1'
+set service dhcp-server shared-network-name LAN subnet 192.168.0.0/24 range LANDynamic start '192.168.0.20'
+set service dhcp-server shared-network-name LAN subnet 192.168.0.0/24 range LANDynamic stop '192.168.0.240'
+set service dns forwarding allow-from '192.168.0.0/16'
+set service dns forwarding cache-size '10000'
+set service dns forwarding dnssec 'off'
+set service dns forwarding listen-address '192.168.0.1'
+set service ssh ciphers 'aes128-ctr'
+set service ssh ciphers 'aes192-ctr'
+set service ssh ciphers 'aes256-ctr'
+set service ssh ciphers 'chacha20-poly1305@openssh.com'
+set service ssh ciphers 'rijndael-cbc@lysator.liu.se'
+set service ssh key-exchange 'curve25519-sha256@libssh.org'
+set service ssh key-exchange 'diffie-hellman-group1-sha1'
+set service ssh key-exchange 'diffie-hellman-group-exchange-sha1'
+set service ssh key-exchange 'diffie-hellman-group-exchange-sha256'
+set service ssh listen-address '192.168.0.1'
+set service ssh port '22'
+set system config-management commit-revisions '100'
+set system console device ttyS0 speed '115200'
+set system host-name 'vyos'
+set system name-server '192.168.0.1'
+set system syslog console facility all level 'emerg'
+set system syslog console facility mail level 'info'
+set system syslog global facility all level 'info'
+set system syslog global facility auth level 'info'
+set system syslog global facility local7 level 'debug'
+set system syslog global preserve-fqdn
+set system syslog host syslog.vyos.net facility auth level 'warning'
+set system syslog host syslog.vyos.net facility local7 level 'notice'
+set system syslog host syslog.vyos.net format octet-counted
+set system syslog host syslog.vyos.net port '8000'
+set system time-zone 'Europe/Berlin'
diff --git a/smoketest/config-tests/dialup-router-medium-vpn b/smoketest/config-tests/dialup-router-medium-vpn
new file mode 100644
index 000000000..37baee0fd
--- /dev/null
+++ b/smoketest/config-tests/dialup-router-medium-vpn
@@ -0,0 +1,321 @@
+set firewall global-options all-ping 'enable'
+set firewall global-options broadcast-ping 'disable'
+set firewall global-options ip-src-route 'disable'
+set firewall global-options ipv6-receive-redirects 'disable'
+set firewall global-options ipv6-src-route 'disable'
+set firewall global-options log-martians 'enable'
+set firewall global-options receive-redirects 'disable'
+set firewall global-options send-redirects 'enable'
+set firewall global-options source-validation 'disable'
+set firewall global-options syn-cookies 'disable'
+set firewall global-options twa-hazards-protection 'enable'
+set firewall ipv4 name test_tcp_flags rule 1 action 'drop'
+set firewall ipv4 name test_tcp_flags rule 1 protocol 'tcp'
+set firewall ipv4 name test_tcp_flags rule 1 tcp flags ack
+set firewall ipv4 name test_tcp_flags rule 1 tcp flags not fin
+set firewall ipv4 name test_tcp_flags rule 1 tcp flags not rst
+set firewall ipv4 name test_tcp_flags rule 1 tcp flags syn
+set high-availability vrrp group LAN address 192.168.0.1/24
+set high-availability vrrp group LAN hello-source-address '192.168.0.250'
+set high-availability vrrp group LAN interface 'eth1'
+set high-availability vrrp group LAN peer-address '192.168.0.251'
+set high-availability vrrp group LAN priority '200'
+set high-availability vrrp group LAN vrid '1'
+set high-availability vrrp sync-group failover-group member 'LAN'
+set interfaces ethernet eth0 duplex 'auto'
+set interfaces ethernet eth0 mtu '9000'
+set interfaces ethernet eth0 offload gro
+set interfaces ethernet eth0 offload gso
+set interfaces ethernet eth0 offload sg
+set interfaces ethernet eth0 offload tso
+set interfaces ethernet eth0 speed 'auto'
+set interfaces ethernet eth1 address '192.168.0.250/24'
+set interfaces ethernet eth1 duplex 'auto'
+set interfaces ethernet eth1 ip source-validation 'strict'
+set interfaces ethernet eth1 mtu '9000'
+set interfaces ethernet eth1 offload gro
+set interfaces ethernet eth1 offload gso
+set interfaces ethernet eth1 offload sg
+set interfaces ethernet eth1 offload tso
+set interfaces ethernet eth1 speed 'auto'
+set interfaces loopback lo
+set interfaces openvpn vtun0 encryption cipher 'aes256'
+set interfaces openvpn vtun0 hash 'sha512'
+set interfaces openvpn vtun0 ip adjust-mss '1380'
+set interfaces openvpn vtun0 ip source-validation 'strict'
+set interfaces openvpn vtun0 keep-alive failure-count '3'
+set interfaces openvpn vtun0 keep-alive interval '30'
+set interfaces openvpn vtun0 mode 'client'
+set interfaces openvpn vtun0 openvpn-option 'comp-lzo adaptive'
+set interfaces openvpn vtun0 openvpn-option 'fast-io'
+set interfaces openvpn vtun0 openvpn-option 'persist-key'
+set interfaces openvpn vtun0 openvpn-option 'reneg-sec 86400'
+set interfaces openvpn vtun0 persistent-tunnel
+set interfaces openvpn vtun0 remote-host '192.0.2.10'
+set interfaces openvpn vtun0 tls auth-key 'openvpn_vtun0_auth'
+set interfaces openvpn vtun0 tls ca-certificate 'openvpn_vtun0_1'
+set interfaces openvpn vtun0 tls ca-certificate 'openvpn_vtun0_2'
+set interfaces openvpn vtun0 tls certificate 'openvpn_vtun0'
+set interfaces openvpn vtun1 authentication password 'vyos1'
+set interfaces openvpn vtun1 authentication username 'vyos1'
+set interfaces openvpn vtun1 encryption cipher 'aes256'
+set interfaces openvpn vtun1 hash 'sha1'
+set interfaces openvpn vtun1 ip adjust-mss '1380'
+set interfaces openvpn vtun1 keep-alive failure-count '3'
+set interfaces openvpn vtun1 keep-alive interval '30'
+set interfaces openvpn vtun1 mode 'client'
+set interfaces openvpn vtun1 openvpn-option 'comp-lzo adaptive'
+set interfaces openvpn vtun1 openvpn-option 'tun-mtu 1500'
+set interfaces openvpn vtun1 openvpn-option 'tun-mtu-extra 32'
+set interfaces openvpn vtun1 openvpn-option 'mssfix 1300'
+set interfaces openvpn vtun1 openvpn-option 'persist-key'
+set interfaces openvpn vtun1 openvpn-option 'mute 10'
+set interfaces openvpn vtun1 openvpn-option 'route-nopull'
+set interfaces openvpn vtun1 openvpn-option 'fast-io'
+set interfaces openvpn vtun1 openvpn-option 'reneg-sec 86400'
+set interfaces openvpn vtun1 persistent-tunnel
+set interfaces openvpn vtun1 protocol 'udp'
+set interfaces openvpn vtun1 remote-host '01.foo.com'
+set interfaces openvpn vtun1 remote-port '1194'
+set interfaces openvpn vtun1 tls auth-key 'openvpn_vtun1_auth'
+set interfaces openvpn vtun1 tls ca-certificate 'openvpn_vtun1_1'
+set interfaces openvpn vtun1 tls ca-certificate 'openvpn_vtun1_2'
+set interfaces openvpn vtun2 authentication password 'vyos2'
+set interfaces openvpn vtun2 authentication username 'vyos2'
+set interfaces openvpn vtun2 disable
+set interfaces openvpn vtun2 encryption cipher 'aes256'
+set interfaces openvpn vtun2 hash 'sha512'
+set interfaces openvpn vtun2 ip adjust-mss '1380'
+set interfaces openvpn vtun2 keep-alive failure-count '3'
+set interfaces openvpn vtun2 keep-alive interval '30'
+set interfaces openvpn vtun2 mode 'client'
+set interfaces openvpn vtun2 openvpn-option 'tun-mtu 1500'
+set interfaces openvpn vtun2 openvpn-option 'tun-mtu-extra 32'
+set interfaces openvpn vtun2 openvpn-option 'mssfix 1300'
+set interfaces openvpn vtun2 openvpn-option 'persist-key'
+set interfaces openvpn vtun2 openvpn-option 'mute 10'
+set interfaces openvpn vtun2 openvpn-option 'route-nopull'
+set interfaces openvpn vtun2 openvpn-option 'fast-io'
+set interfaces openvpn vtun2 openvpn-option 'remote-random'
+set interfaces openvpn vtun2 openvpn-option 'reneg-sec 86400'
+set interfaces openvpn vtun2 persistent-tunnel
+set interfaces openvpn vtun2 protocol 'udp'
+set interfaces openvpn vtun2 remote-host '01.myvpn.com'
+set interfaces openvpn vtun2 remote-host '02.myvpn.com'
+set interfaces openvpn vtun2 remote-host '03.myvpn.com'
+set interfaces openvpn vtun2 remote-port '1194'
+set interfaces openvpn vtun2 tls auth-key 'openvpn_vtun2_auth'
+set interfaces openvpn vtun2 tls ca-certificate 'openvpn_vtun2_1'
+set interfaces pppoe pppoe0 authentication password 'password'
+set interfaces pppoe pppoe0 authentication username 'vyos'
+set interfaces pppoe pppoe0 mtu '1500'
+set interfaces pppoe pppoe0 source-interface 'eth0'
+set interfaces wireguard wg0 address '192.168.10.1/24'
+set interfaces wireguard wg0 ip adjust-mss '1380'
+set interfaces wireguard wg0 peer blue allowed-ips '192.168.10.3/32'
+set interfaces wireguard wg0 peer blue persistent-keepalive '20'
+set interfaces wireguard wg0 peer blue preshared-key 'ztFDOY9UyaDvn8N3X97SFMDwIfv7EEfuUIPP2yab6UI='
+set interfaces wireguard wg0 peer blue public-key 'G4pZishpMRrLmd96Kr6V7LIuNGdcUb81gWaYZ+FWkG0='
+set interfaces wireguard wg0 peer green allowed-ips '192.168.10.21/32'
+set interfaces wireguard wg0 peer green persistent-keepalive '25'
+set interfaces wireguard wg0 peer green preshared-key 'LQ9qmlTh9G4nZu4UgElxRUwg7JB/qoV799aADJOijnY='
+set interfaces wireguard wg0 peer green public-key '5iQUD3VoCDBTPXAPHOwUJ0p7xzKGHEY/wQmgvBVmaFI='
+set interfaces wireguard wg0 peer pink allowed-ips '192.168.10.14/32'
+set interfaces wireguard wg0 peer pink allowed-ips '192.168.10.16/32'
+set interfaces wireguard wg0 peer pink persistent-keepalive '25'
+set interfaces wireguard wg0 peer pink preshared-key 'Qi9Odyx0/5itLPN5C5bEy3uMX+tmdl15QbakxpKlWqQ='
+set interfaces wireguard wg0 peer pink public-key 'i4qNPmxyy9EETL4tIoZOLKJF4p7IlVmpAE15gglnAk4='
+set interfaces wireguard wg0 peer red allowed-ips '192.168.10.4/32'
+set interfaces wireguard wg0 peer red persistent-keepalive '20'
+set interfaces wireguard wg0 peer red preshared-key 'CumyXX7osvUT9AwnS+m2TEfCaL0Ptc2LfuZ78Sujuk8='
+set interfaces wireguard wg0 peer red public-key 'ALGWvMJCKpHF2tVH3hEIHqUe9iFfAmZATUUok/WQzks='
+set interfaces wireguard wg0 port '7777'
+set interfaces wireguard wg1 address '10.89.90.2/30'
+set interfaces wireguard wg1 ip adjust-mss '1380'
+set interfaces wireguard wg1 peer sam address '192.0.2.45'
+set interfaces wireguard wg1 peer sam allowed-ips '10.1.1.0/24'
+set interfaces wireguard wg1 peer sam allowed-ips '10.89.90.1/32'
+set interfaces wireguard wg1 peer sam persistent-keepalive '20'
+set interfaces wireguard wg1 peer sam port '1200'
+set interfaces wireguard wg1 peer sam preshared-key 'XpFtzx2Z+nR8pBv9/sSf7I94OkZkVYTz0AeU5Q/QQUE='
+set interfaces wireguard wg1 peer sam public-key 'v5zfKGvH6W/lfDXJ0en96lvKo1gfFxMUWxe02+Fj5BU='
+set interfaces wireguard wg1 port '7778'
+set nat destination rule 50 destination port '49371'
+set nat destination rule 50 inbound-interface 'pppoe0'
+set nat destination rule 50 protocol 'tcp_udp'
+set nat destination rule 50 translation address '192.168.0.5'
+set nat destination rule 51 destination port '58050-58051'
+set nat destination rule 51 inbound-interface 'pppoe0'
+set nat destination rule 51 protocol 'tcp'
+set nat destination rule 51 translation address '192.168.0.5'
+set nat destination rule 52 destination port '22067-22070'
+set nat destination rule 52 inbound-interface 'pppoe0'
+set nat destination rule 52 protocol 'tcp'
+set nat destination rule 52 translation address '192.168.0.5'
+set nat destination rule 53 destination port '34342'
+set nat destination rule 53 inbound-interface 'pppoe0'
+set nat destination rule 53 protocol 'tcp_udp'
+set nat destination rule 53 translation address '192.168.0.121'
+set nat destination rule 54 destination port '45459'
+set nat destination rule 54 inbound-interface 'pppoe0'
+set nat destination rule 54 protocol 'tcp_udp'
+set nat destination rule 54 translation address '192.168.0.120'
+set nat destination rule 55 destination port '22'
+set nat destination rule 55 inbound-interface 'pppoe0'
+set nat destination rule 55 protocol 'tcp'
+set nat destination rule 55 translation address '192.168.0.5'
+set nat destination rule 56 destination port '8920'
+set nat destination rule 56 inbound-interface 'pppoe0'
+set nat destination rule 56 protocol 'tcp'
+set nat destination rule 56 translation address '192.168.0.5'
+set nat destination rule 60 destination port '80,443'
+set nat destination rule 60 inbound-interface 'pppoe0'
+set nat destination rule 60 protocol 'tcp'
+set nat destination rule 60 translation address '192.168.0.5'
+set nat destination rule 70 destination port '5001'
+set nat destination rule 70 inbound-interface 'pppoe0'
+set nat destination rule 70 protocol 'tcp'
+set nat destination rule 70 translation address '192.168.0.5'
+set nat destination rule 80 destination port '25'
+set nat destination rule 80 inbound-interface 'pppoe0'
+set nat destination rule 80 protocol 'tcp'
+set nat destination rule 80 translation address '192.168.0.5'
+set nat destination rule 90 destination port '8123'
+set nat destination rule 90 inbound-interface 'pppoe0'
+set nat destination rule 90 protocol 'tcp'
+set nat destination rule 90 translation address '192.168.0.7'
+set nat destination rule 91 destination port '1880'
+set nat destination rule 91 inbound-interface 'pppoe0'
+set nat destination rule 91 protocol 'tcp'
+set nat destination rule 91 translation address '192.168.0.7'
+set nat destination rule 500 destination address '!192.168.0.0/24'
+set nat destination rule 500 destination port '53'
+set nat destination rule 500 inbound-interface 'eth1'
+set nat destination rule 500 protocol 'tcp_udp'
+set nat destination rule 500 source address '!192.168.0.1-192.168.0.5'
+set nat destination rule 500 translation address '192.168.0.1'
+set nat source rule 1000 outbound-interface 'pppoe0'
+set nat source rule 1000 translation address 'masquerade'
+set nat source rule 2000 outbound-interface 'vtun0'
+set nat source rule 2000 source address '192.168.0.0/16'
+set nat source rule 2000 translation address 'masquerade'
+set nat source rule 3000 outbound-interface 'vtun1'
+set nat source rule 3000 translation address 'masquerade'
+set policy prefix-list user1-routes rule 1 action 'permit'
+set policy prefix-list user1-routes rule 1 prefix '192.168.0.0/24'
+set policy prefix-list user2-routes rule 1 action 'permit'
+set policy prefix-list user2-routes rule 1 prefix '10.1.1.0/24'
+set policy route LAN-POLICY-BASED-ROUTING interface 'eth1'
+set policy route LAN-POLICY-BASED-ROUTING rule 10 destination
+set policy route LAN-POLICY-BASED-ROUTING rule 10 disable
+set policy route LAN-POLICY-BASED-ROUTING rule 10 set table '10'
+set policy route LAN-POLICY-BASED-ROUTING rule 10 source address '192.168.0.119/32'
+set policy route LAN-POLICY-BASED-ROUTING rule 20 destination
+set policy route LAN-POLICY-BASED-ROUTING rule 20 set table '100'
+set policy route LAN-POLICY-BASED-ROUTING rule 20 source address '192.168.0.240'
+set policy route-map rm-static-to-bgp rule 10 action 'permit'
+set policy route-map rm-static-to-bgp rule 10 match ip address prefix-list 'user1-routes'
+set policy route-map rm-static-to-bgp rule 100 action 'deny'
+set policy route6 LAN6-POLICY-BASED-ROUTING interface 'eth1'
+set policy route6 LAN6-POLICY-BASED-ROUTING rule 10 destination
+set policy route6 LAN6-POLICY-BASED-ROUTING rule 10 disable
+set policy route6 LAN6-POLICY-BASED-ROUTING rule 10 set table '10'
+set policy route6 LAN6-POLICY-BASED-ROUTING rule 10 source address '2002::1'
+set policy route6 LAN6-POLICY-BASED-ROUTING rule 20 destination
+set policy route6 LAN6-POLICY-BASED-ROUTING rule 20 set table '100'
+set policy route6 LAN6-POLICY-BASED-ROUTING rule 20 source address '2008::f'
+set protocols bgp address-family ipv4-unicast redistribute connected route-map 'rm-static-to-bgp'
+set protocols bgp neighbor 10.89.90.1 address-family ipv4-unicast nexthop-self
+set protocols bgp neighbor 10.89.90.1 address-family ipv4-unicast prefix-list export 'user1-routes'
+set protocols bgp neighbor 10.89.90.1 address-family ipv4-unicast prefix-list import 'user2-routes'
+set protocols bgp neighbor 10.89.90.1 address-family ipv4-unicast soft-reconfiguration inbound
+set protocols bgp neighbor 10.89.90.1 password 'ericandre2020'
+set protocols bgp neighbor 10.89.90.1 remote-as '64589'
+set protocols bgp parameters log-neighbor-changes
+set protocols bgp parameters router-id '10.89.90.2'
+set protocols bgp system-as '64590'
+set protocols static route 100.64.160.23/32 interface pppoe0
+set protocols static route 100.64.165.25/32 interface pppoe0
+set protocols static route 100.64.165.26/32 interface pppoe0
+set protocols static route 100.64.198.0/24 interface vtun0
+set protocols static table 10 route 0.0.0.0/0 interface vtun1
+set protocols static table 100 route 0.0.0.0/0 next-hop 192.168.10.5
+set service conntrack-sync accept-protocol 'tcp'
+set service conntrack-sync accept-protocol 'udp'
+set service conntrack-sync accept-protocol 'icmp'
+set service conntrack-sync disable-external-cache
+set service conntrack-sync event-listen-queue-size '8'
+set service conntrack-sync expect-sync 'all'
+set service conntrack-sync failover-mechanism vrrp sync-group 'failover-group'
+set service conntrack-sync interface eth1 peer '192.168.0.251'
+set service conntrack-sync sync-queue-size '8'
+set service dhcp-server failover name 'DHCP02'
+set service dhcp-server failover remote '192.168.0.251'
+set service dhcp-server failover source-address '192.168.0.250'
+set service dhcp-server failover status 'primary'
+set service dhcp-server shared-network-name LAN authoritative
+set service dhcp-server shared-network-name LAN subnet 192.168.0.0/24 default-router '192.168.0.1'
+set service dhcp-server shared-network-name LAN subnet 192.168.0.0/24 domain-name 'vyos.net'
+set service dhcp-server shared-network-name LAN subnet 192.168.0.0/24 domain-search 'vyos.net'
+set service dhcp-server shared-network-name LAN subnet 192.168.0.0/24 enable-failover
+set service dhcp-server shared-network-name LAN subnet 192.168.0.0/24 lease '86400'
+set service dhcp-server shared-network-name LAN subnet 192.168.0.0/24 name-server '192.168.0.1'
+set service dhcp-server shared-network-name LAN subnet 192.168.0.0/24 range LANDynamic start '192.168.0.200'
+set service dhcp-server shared-network-name LAN subnet 192.168.0.0/24 range LANDynamic stop '192.168.0.240'
+set service dhcp-server shared-network-name LAN subnet 192.168.0.0/24 static-mapping Audio ip-address '192.168.0.107'
+set service dhcp-server shared-network-name LAN subnet 192.168.0.0/24 static-mapping Audio mac-address '00:50:01:dc:91:14'
+set service dhcp-server shared-network-name LAN subnet 192.168.0.0/24 static-mapping IPTV ip-address '192.168.0.104'
+set service dhcp-server shared-network-name LAN subnet 192.168.0.0/24 static-mapping IPTV mac-address '00:50:01:31:b5:f6'
+set service dhcp-server shared-network-name LAN subnet 192.168.0.0/24 static-mapping McPrintus ip-address '192.168.0.60'
+set service dhcp-server shared-network-name LAN subnet 192.168.0.0/24 static-mapping McPrintus mac-address '00:50:01:58:ac:95'
+set service dhcp-server shared-network-name LAN subnet 192.168.0.0/24 static-mapping McPrintus static-mapping-parameters 'option domain-name-servers 192.168.0.6,192.168.0.17;'
+set service dhcp-server shared-network-name LAN subnet 192.168.0.0/24 static-mapping Mobile01 ip-address '192.168.0.109'
+set service dhcp-server shared-network-name LAN subnet 192.168.0.0/24 static-mapping Mobile01 mac-address '00:50:01:bc:ac:51'
+set service dhcp-server shared-network-name LAN subnet 192.168.0.0/24 static-mapping Mobile01 static-mapping-parameters 'option domain-name-servers 192.168.0.6,192.168.0.17;'
+set service dhcp-server shared-network-name LAN subnet 192.168.0.0/24 static-mapping camera1 ip-address '192.168.0.11'
+set service dhcp-server shared-network-name LAN subnet 192.168.0.0/24 static-mapping camera1 mac-address '00:50:01:70:b9:4d'
+set service dhcp-server shared-network-name LAN subnet 192.168.0.0/24 static-mapping camera1 static-mapping-parameters 'option domain-name-servers 192.168.0.6,192.168.0.17;'
+set service dhcp-server shared-network-name LAN subnet 192.168.0.0/24 static-mapping camera2 ip-address '192.168.0.12'
+set service dhcp-server shared-network-name LAN subnet 192.168.0.0/24 static-mapping camera2 mac-address '00:50:01:70:b7:4f'
+set service dhcp-server shared-network-name LAN subnet 192.168.0.0/24 static-mapping camera2 static-mapping-parameters 'option domain-name-servers 192.168.0.6,192.168.0.17;'
+set service dhcp-server shared-network-name LAN subnet 192.168.0.0/24 static-mapping pearTV ip-address '192.168.0.101'
+set service dhcp-server shared-network-name LAN subnet 192.168.0.0/24 static-mapping pearTV mac-address '00:50:01:ba:62:79'
+set service dhcp-server shared-network-name LAN subnet 192.168.0.0/24 static-mapping sand ip-address '192.168.0.110'
+set service dhcp-server shared-network-name LAN subnet 192.168.0.0/24 static-mapping sand mac-address '00:50:01:af:c5:d2'
+set service dns forwarding allow-from '192.168.0.0/16'
+set service dns forwarding cache-size '8192'
+set service dns forwarding dnssec 'off'
+set service dns forwarding listen-address '192.168.0.1'
+set service dns forwarding name-server 100.64.0.1
+set service dns forwarding name-server 100.64.0.2
+set service ntp allow-client address '192.168.0.0/16'
+set service ntp server nz.pool.ntp.org prefer
+set service snmp community AwesomeCommunity authorization 'ro'
+set service snmp community AwesomeCommunity client '127.0.0.1'
+set service snmp community AwesomeCommunity network '192.168.0.0/24'
+set service ssh access-control allow user 'vyos'
+set service ssh client-keepalive-interval '60'
+set service ssh listen-address '192.168.0.1'
+set service ssh listen-address '192.168.10.1'
+set service ssh listen-address '192.168.0.250'
+set system config-management commit-revisions '100'
+set system console device ttyS0 speed '115200'
+set system host-name 'vyos'
+set system ip arp table-size '1024'
+set system name-server '192.168.0.1'
+set system name-server 'pppoe0'
+set system option ctrl-alt-delete 'ignore'
+set system option reboot-on-panic
+set system option startup-beep
+set system static-host-mapping host-name host60.vyos.net inet '192.168.0.60'
+set system static-host-mapping host-name host104.vyos.net inet '192.168.0.104'
+set system static-host-mapping host-name host107.vyos.net inet '192.168.0.107'
+set system static-host-mapping host-name host109.vyos.net inet '192.168.0.109'
+set system sysctl parameter net.core.default_qdisc value 'fq'
+set system sysctl parameter net.ipv4.tcp_congestion_control value 'bbr'
+set system syslog global facility all level 'info'
+set system syslog host 192.168.0.252 facility all level 'debug'
+set system syslog host 192.168.0.252 protocol 'udp'
+set system task-scheduler task Update-Blacklists executable path '/config/scripts/vyos-foo-update.script'
+set system task-scheduler task Update-Blacklists interval '3h'
+set system time-zone 'Pacific/Auckland'
diff --git a/smoketest/configs/basic-vyos b/smoketest/configs/basic-vyos
index 033c1a518..78dba3ee2 100644
--- a/smoketest/configs/basic-vyos
+++ b/smoketest/configs/basic-vyos
@@ -116,6 +116,18 @@ system {
speed 115200
}
}
+ conntrack {
+ ignore {
+ rule 1 {
+ destination {
+ address 192.0.2.2
+ }
+ source {
+ address 192.0.2.1
+ }
+ }
+ }
+ }
host-name vyos
login {
user vyos {
diff --git a/smoketest/scripts/cli/base_interfaces_test.py b/smoketest/scripts/cli/base_interfaces_test.py
index 820024dc9..51ccbc9e6 100644
--- a/smoketest/scripts/cli/base_interfaces_test.py
+++ b/smoketest/scripts/cli/base_interfaces_test.py
@@ -834,8 +834,12 @@ class BasicInterfaceTest:
self.assertEqual('1', tmp)
if cli_defined(self._base_path + ['ip'], 'source-validation'):
- tmp = read_file(f'{proc_base}/rp_filter')
- self.assertEqual('2', tmp)
+ base_options = f'iifname "{interface}"'
+ out = cmd('sudo nft list chain ip raw vyos_rpfilter')
+ for line in out.splitlines():
+ if line.startswith(base_options):
+ self.assertIn('fib saddr oif 0', line)
+ self.assertIn('drop', line)
def test_interface_ipv6_options(self):
if not self._test_ipv6:
diff --git a/smoketest/scripts/cli/test_component_version.py b/smoketest/scripts/cli/test_component_version.py
deleted file mode 100755
index 7b1b12c53..000000000
--- a/smoketest/scripts/cli/test_component_version.py
+++ /dev/null
@@ -1,50 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright (C) 2022 VyOS maintainers and contributors
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 or later as
-# 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 vyos.component_version as component_version
-
-# After T3474, component versions should be updated in the files in
-# vyos-1x/interface-definitions/include/version/
-# This test verifies that the legacy version in curver_DATA does not exceed
-# that in the xml cache.
-class TestComponentVersion(unittest.TestCase):
- def setUp(self):
- self.legacy_d = component_version.legacy_from_system()
- self.xml_d = component_version.from_system()
- self.set_legacy_d = set(self.legacy_d)
- self.set_xml_d = set(self.xml_d)
-
- def test_component_version(self):
- bool_issubset = (self.set_legacy_d.issubset(self.set_xml_d))
- if not bool_issubset:
- missing = self.set_legacy_d.difference(self.set_xml_d)
- print(f'\n\ncomponents in legacy but not in XML: {missing}')
- print('new components must be listed in xml-component-version.xml.in')
- self.assertTrue(bool_issubset)
-
- bad_component_version = False
- for k, v in self.legacy_d.items():
- bool_inequality = (v <= self.xml_d[k])
- if not bool_inequality:
- print(f'\n\n{k} has not been updated in XML component versions:')
- print(f'legacy version {v}; XML version {self.xml_d[k]}')
- bad_component_version = True
- self.assertFalse(bad_component_version)
-
-if __name__ == '__main__':
- unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_dependency_graph.py b/smoketest/scripts/cli/test_dependency_graph.py
deleted file mode 100755
index 45a40acc4..000000000
--- a/smoketest/scripts/cli/test_dependency_graph.py
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright (C) 2022 VyOS maintainers and contributors
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 or later as
-# 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 json
-import unittest
-from graphlib import TopologicalSorter, CycleError
-
-DEP_FILE = '/usr/share/vyos/config-mode-dependencies.json'
-
-def graph_from_dict(d):
- g = {}
- for k in list(d):
- g[k] = set()
- # add the dependencies for every sub-case; should there be cases
- # that are mutally exclusive in the future, the graphs will be
- # distinguished
- for el in list(d[k]):
- g[k] |= set(d[k][el])
- return g
-
-class TestDependencyGraph(unittest.TestCase):
- def setUp(self):
- with open(DEP_FILE) as f:
- dd = json.load(f)
- self.dependency_graph = graph_from_dict(dd)
-
- def test_cycles(self):
- ts = TopologicalSorter(self.dependency_graph)
- out = None
- try:
- # get node iterator
- order = ts.static_order()
- # try iteration
- _ = [*order]
- except CycleError as e:
- out = e.args
-
- self.assertIsNone(out)
-
-if __name__ == '__main__':
- unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_firewall.py b/smoketest/scripts/cli/test_firewall.py
index ee6ccb710..7b4ba11d0 100755
--- a/smoketest/scripts/cli/test_firewall.py
+++ b/smoketest/scripts/cli/test_firewall.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2022 VyOS maintainers and contributors
+# Copyright (C) 2021-2023 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -274,8 +274,8 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):
['meta l4proto gre', f'oifname != "{interface}"', 'drop'],
['meta l4proto icmp', f'ct mark {mark_hex}', 'return'],
['chain NAME_smoketest'],
- ['saddr 172.16.20.10', 'daddr 172.16.10.10', 'log prefix "[smoketest-1-A]" log level debug', 'ip ttl 15', 'accept'],
- ['tcp flags syn / syn,ack', 'tcp dport 8888', 'log prefix "[smoketest-2-R]" log level err', 'ip ttl > 102', 'reject'],
+ ['saddr 172.16.20.10', 'daddr 172.16.10.10', 'log prefix "[ipv4-NAM-smoketest-1-A]" log level debug', 'ip ttl 15', 'accept'],
+ ['tcp flags syn / syn,ack', 'tcp dport 8888', 'log prefix "[ipv4-NAM-smoketest-2-R]" log level err', 'ip ttl > 102', 'reject'],
['log prefix "[smoketest-default-D]"','smoketest default-action', 'drop']
]
@@ -308,10 +308,12 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):
self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'default-action', 'drop'])
self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '1', 'source', 'address', '198.51.100.1'])
+ self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '1', 'mark', '1010'])
self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '1', 'action', 'jump'])
self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '1', 'jump-target', name])
self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '2', 'protocol', 'tcp'])
+ self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '2', 'mark', '!98765'])
self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '2', 'action', 'queue'])
self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '2', 'queue', '3'])
self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '3', 'protocol', 'udp'])
@@ -325,19 +327,44 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):
nftables_search = [
['chain VYOS_FORWARD_filter'],
['type filter hook forward priority filter; policy drop;'],
- ['ip saddr 198.51.100.1', f'jump NAME_{name}'],
+ ['ip saddr 198.51.100.1', 'meta mark 0x000003f2', f'jump NAME_{name}'],
['chain VYOS_INPUT_filter'],
['type filter hook input priority filter; policy accept;'],
- [f'meta l4proto tcp','queue to 3'],
- [f'meta l4proto udp','queue flags bypass,fanout to 0-15'],
+ ['meta mark != 0x000181cd', 'meta l4proto tcp','queue to 3'],
+ ['meta l4proto udp','queue flags bypass,fanout to 0-15'],
[f'chain NAME_{name}'],
- ['ip length { 64, 512, 1024 }', 'ip dscp { 0x11, 0x34 }', f'log prefix "[{name}-6-A]" log group 66 snaplen 6666 queue-threshold 32000', 'accept'],
+ ['ip length { 64, 512, 1024 }', 'ip dscp { 0x11, 0x34 }', f'log prefix "[ipv4-NAM-{name}-6-A]" log group 66 snaplen 6666 queue-threshold 32000', 'accept'],
['ip length 1-30000', 'ip length != 60000-65535', 'ip dscp 0x03-0x0b', 'ip dscp != 0x15-0x19', 'accept'],
[f'log prefix "[{name}-default-D]"', 'drop']
]
self.verify_nftables(nftables_search, 'ip vyos_filter')
+ def test_ipv4_synproxy(self):
+ tcp_mss = '1460'
+ tcp_wscale = '7'
+ dport = '22'
+
+ self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '10', 'action', 'drop'])
+ self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '10', 'protocol', 'tcp'])
+ self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '10', 'destination', 'port', dport])
+ self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '10', 'synproxy', 'tcp', 'mss', tcp_mss])
+ self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '10', 'synproxy', 'tcp', 'window-scale', tcp_wscale])
+
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+
+ self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '10', 'action', 'synproxy'])
+
+ self.cli_commit()
+
+ nftables_search = [
+ [f'tcp dport {dport} ct state invalid,untracked', f'synproxy mss {tcp_mss} wscale {tcp_wscale} timestamp sack-perm']
+ ]
+
+ self.verify_nftables(nftables_search, 'ip vyos_filter')
+
+
def test_ipv4_mask(self):
name = 'smoketest-mask'
interface = 'eth0'
@@ -412,7 +439,7 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):
['type filter hook output priority filter; policy drop;'],
['meta l4proto gre', f'oifname "{interface}"', 'return'],
[f'chain NAME6_{name}'],
- ['saddr 2002::1', 'daddr 2002::1:1', 'log prefix "[v6-smoketest-1-A]" log level crit', 'accept'],
+ ['saddr 2002::1', 'daddr 2002::1:1', 'log prefix "[ipv6-NAM-v6-smoketest-1-A]" log level crit', 'accept'],
[f'"{name} default-action drop"', f'log prefix "[{name}-default-D]"', 'drop']
]
@@ -441,6 +468,7 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):
self.cli_set(['firewall', 'ipv6', 'input', 'filter', 'default-action', 'accept'])
self.cli_set(['firewall', 'ipv6', 'input', 'filter', 'rule', '1', 'source', 'address', '2001:db8::/64'])
+ self.cli_set(['firewall', 'ipv6', 'input', 'filter', 'rule', '1', 'mark', '!6655-7766'])
self.cli_set(['firewall', 'ipv6', 'input', 'filter', 'rule', '1', 'action', 'jump'])
self.cli_set(['firewall', 'ipv6', 'input', 'filter', 'rule', '1', 'jump-target', name])
@@ -452,7 +480,7 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):
['ip6 length 1-1999', 'ip6 length != 60000-65535', 'ip6 dscp 0x04-0x0e', 'ip6 dscp != 0x1f-0x23', 'accept'],
['chain VYOS_IPV6_INPUT_filter'],
['type filter hook input priority filter; policy accept;'],
- ['ip6 saddr 2001:db8::/64', f'jump NAME6_{name}'],
+ ['ip6 saddr 2001:db8::/64', 'meta mark != 0x000019ff-0x00001e56', f'jump NAME6_{name}'],
[f'chain NAME6_{name}'],
['ip6 length { 65, 513, 1025 }', 'ip6 dscp { af21, 0x35 }', 'accept'],
[f'log prefix "[{name}-default-D]"', 'drop']
@@ -503,12 +531,15 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):
self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '2', 'state', 'invalid', 'enable'])
self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '3', 'action', 'accept'])
self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '3', 'state', 'new', 'enable'])
-
self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '3', 'connection-status', 'nat', 'destination'])
self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '4', 'action', 'accept'])
self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '4', 'state', 'new', 'enable'])
self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '4', 'state', 'established', 'enable'])
self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '4', 'connection-status', 'nat', 'source'])
+ self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '5', 'action', 'accept'])
+ self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '5', 'state', 'related', 'enable'])
+ self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '5', 'conntrack-helper', 'ftp'])
+ self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '5', 'conntrack-helper', 'pptp'])
self.cli_commit()
@@ -517,35 +548,75 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):
['ct state invalid', 'reject'],
['ct state new', 'ct status dnat', 'accept'],
['ct state { established, new }', 'ct status snat', 'accept'],
+ ['ct state related', 'ct helper { "ftp", "pptp" }', 'accept'],
['drop', f'comment "{name} default-action drop"']
]
self.verify_nftables(nftables_search, 'ip vyos_filter')
# Check conntrack
- self.verify_nftables_chain([['accept']], 'raw', 'FW_CONNTRACK')
- self.verify_nftables_chain([['return']], 'ip6 raw', 'FW_CONNTRACK')
+ self.verify_nftables_chain([['accept']], 'ip vyos_conntrack', 'FW_CONNTRACK')
+ self.verify_nftables_chain([['return']], 'ip6 vyos_conntrack', 'FW_CONNTRACK')
+
+ def test_bridge_basic_rules(self):
+ name = 'smoketest'
+ interface_in = 'eth0'
+ mac_address = '00:53:00:00:00:01'
+ vlan_id = '12'
+ vlan_prior = '3'
+
+ self.cli_set(['firewall', 'bridge', 'name', name, 'default-action', 'accept'])
+ self.cli_set(['firewall', 'bridge', 'name', name, 'enable-default-log'])
+ self.cli_set(['firewall', 'bridge', 'name', name, 'rule', '1', 'action', 'accept'])
+ self.cli_set(['firewall', 'bridge', 'name', name, 'rule', '1', 'source', 'mac-address', mac_address])
+ self.cli_set(['firewall', 'bridge', 'name', name, 'rule', '1', 'inbound-interface', 'interface-name', interface_in])
+ self.cli_set(['firewall', 'bridge', 'name', name, 'rule', '1', 'log', 'enable'])
+ self.cli_set(['firewall', 'bridge', 'name', name, 'rule', '1', 'log-options', 'level', 'crit'])
+
+ self.cli_set(['firewall', 'bridge', 'forward', 'filter', 'default-action', 'drop'])
+ self.cli_set(['firewall', 'bridge', 'forward', 'filter', 'rule', '1', 'action', 'accept'])
+ self.cli_set(['firewall', 'bridge', 'forward', 'filter', 'rule', '1', 'vlan', 'id', vlan_id])
+ self.cli_set(['firewall', 'bridge', 'forward', 'filter', 'rule', '2', 'action', 'jump'])
+ self.cli_set(['firewall', 'bridge', 'forward', 'filter', 'rule', '2', 'jump-target', name])
+ self.cli_set(['firewall', 'bridge', 'forward', 'filter', 'rule', '2', 'vlan', 'priority', vlan_prior])
+
+ self.cli_commit()
+
+ nftables_search = [
+ ['chain VYOS_FORWARD_filter'],
+ ['type filter hook forward priority filter; policy drop;'],
+ [f'vlan id {vlan_id}', 'accept'],
+ [f'vlan pcp {vlan_prior}', f'jump NAME_{name}'],
+ [f'chain NAME_{name}'],
+ [f'ether saddr {mac_address}', f'iifname "{interface_in}"', f'log prefix "[bri-NAM-{name}-1-A]" log level crit', 'accept']
+ ]
+
+ self.verify_nftables(nftables_search, 'bridge vyos_filter')
def test_source_validation(self):
# Strict
self.cli_set(['firewall', 'global-options', 'source-validation', 'strict'])
+ self.cli_set(['firewall', 'global-options', 'ipv6-source-validation', 'strict'])
self.cli_commit()
nftables_strict_search = [
['fib saddr . iif oif 0', 'drop']
]
- self.verify_nftables(nftables_strict_search, 'inet vyos_global_rpfilter')
+ self.verify_nftables_chain(nftables_strict_search, 'ip raw', 'vyos_global_rpfilter')
+ self.verify_nftables_chain(nftables_strict_search, 'ip6 raw', 'vyos_global_rpfilter')
# Loose
self.cli_set(['firewall', 'global-options', 'source-validation', 'loose'])
+ self.cli_set(['firewall', 'global-options', 'ipv6-source-validation', 'loose'])
self.cli_commit()
nftables_loose_search = [
['fib saddr oif 0', 'drop']
]
- self.verify_nftables(nftables_loose_search, 'inet vyos_global_rpfilter')
+ self.verify_nftables_chain(nftables_loose_search, 'ip raw', 'vyos_global_rpfilter')
+ self.verify_nftables_chain(nftables_loose_search, 'ip6 raw', 'vyos_global_rpfilter')
def test_sysfs(self):
for name, conf in sysfs_config.items():
@@ -564,5 +635,43 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):
with open(path, 'r') as f:
self.assertNotEqual(f.read().strip(), conf['default'], msg=path)
+ def test_flow_offload(self):
+ self.cli_set(['firewall', 'flowtable', 'smoketest', 'interface', 'eth0'])
+ self.cli_set(['firewall', 'flowtable', 'smoketest', 'offload', 'hardware'])
+
+ # QEMU virtual NIC does not support hw-tc-offload
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+
+ self.cli_set(['firewall', 'flowtable', 'smoketest', 'offload', 'software'])
+
+ self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '1', 'action', 'offload'])
+ self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '1', 'offload-target', 'smoketest'])
+ self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '1', 'protocol', 'tcp_udp'])
+ self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '1', 'state', 'established', 'enable'])
+ self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '1', 'state', 'related', 'enable'])
+
+ self.cli_set(['firewall', 'ipv6', 'forward', 'filter', 'rule', '1', 'action', 'offload'])
+ self.cli_set(['firewall', 'ipv6', 'forward', 'filter', 'rule', '1', 'offload-target', 'smoketest'])
+ self.cli_set(['firewall', 'ipv6', 'forward', 'filter', 'rule', '1', 'protocol', 'tcp_udp'])
+ self.cli_set(['firewall', 'ipv6', 'forward', 'filter', 'rule', '1', 'state', 'established', 'enable'])
+ self.cli_set(['firewall', 'ipv6', 'forward', 'filter', 'rule', '1', 'state', 'related', 'enable'])
+
+ self.cli_commit()
+
+ nftables_search = [
+ ['flowtable VYOS_FLOWTABLE_smoketest'],
+ ['hook ingress priority filter'],
+ ['devices = { eth0 }'],
+ ['ct state { established, related }', 'meta l4proto { tcp, udp }', 'flow add @VYOS_FLOWTABLE_smoketest'],
+ ]
+
+ self.verify_nftables(nftables_search, 'ip vyos_filter')
+ self.verify_nftables(nftables_search, 'ip6 vyos_filter')
+
+ # Check conntrack
+ self.verify_nftables_chain([['accept']], 'ip vyos_conntrack', 'FW_CONNTRACK')
+ self.verify_nftables_chain([['accept']], 'ip6 vyos_conntrack', 'FW_CONNTRACK')
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_interfaces_openvpn.py b/smoketest/scripts/cli/test_interfaces_openvpn.py
index d1ece84d6..4a7e2418c 100755
--- a/smoketest/scripts/cli/test_interfaces_openvpn.py
+++ b/smoketest/scripts/cli/test_interfaces_openvpn.py
@@ -421,7 +421,7 @@ class TestInterfacesOpenVPN(VyOSUnitTestSHIM.TestCase):
# IP pool configuration
netmask = IPv4Network(subnet).netmask
network = IPv4Network(subnet).network_address
- self.assertIn(f'server {network} {netmask} nopool', config)
+ self.assertIn(f'server {network} {netmask}', config)
# Verify client
client_config = read_file(client_config_file)
@@ -442,80 +442,6 @@ class TestInterfacesOpenVPN(VyOSUnitTestSHIM.TestCase):
interface = f'vtun{ii}'
self.assertNotIn(interface, interfaces())
- def test_openvpn_server_net30_topology(self):
- # Create OpenVPN server interfaces (net30) using different client
- # subnets. Validate configuration afterwards.
- auth_hash = 'sha256'
- num_range = range(20, 25)
- port = ''
- for ii in num_range:
- interface = f'vtun{ii}'
- subnet = f'192.0.{ii}.0/24'
- path = base_path + [interface]
- port = str(2000 + ii)
-
- self.cli_set(path + ['device-type', 'tun'])
- self.cli_set(path + ['encryption', 'cipher', 'aes192'])
- self.cli_set(path + ['hash', auth_hash])
- self.cli_set(path + ['mode', 'server'])
- self.cli_set(path + ['local-port', port])
- self.cli_set(path + ['server', 'subnet', subnet])
- self.cli_set(path + ['server', 'topology', 'net30'])
- self.cli_set(path + ['replace-default-route'])
- self.cli_set(path + ['keep-alive', 'failure-count', '10'])
- self.cli_set(path + ['keep-alive', 'interval', '5'])
- self.cli_set(path + ['tls', 'ca-certificate', 'ovpn_test'])
- self.cli_set(path + ['tls', 'certificate', 'ovpn_test'])
- self.cli_set(path + ['tls', 'dh-params', 'ovpn_test'])
- self.cli_set(path + ['vrf', vrf_name])
-
- self.cli_commit()
-
- for ii in num_range:
- interface = f'vtun{ii}'
- subnet = f'192.0.{ii}.0/24'
- start_addr = inc_ip(subnet, '4')
- stop_addr = dec_ip(last_host_address(subnet), '1')
- port = str(2000 + ii)
-
- config_file = f'/run/openvpn/{interface}.conf'
- config = read_file(config_file)
-
- self.assertIn(f'dev {interface}', config)
- self.assertIn(f'dev-type tun', config)
- self.assertIn(f'persist-key', config)
- self.assertIn(f'proto udp', config) # default protocol
- self.assertIn(f'auth {auth_hash}', config)
- self.assertIn(f'cipher AES-192-CBC', config)
- self.assertIn(f'topology net30', config)
- self.assertIn(f'lport {port}', config)
- self.assertIn(f'push "redirect-gateway def1"', config)
- self.assertIn(f'keepalive 5 50', config)
-
- # TLS options
- self.assertIn(f'ca /run/openvpn/{interface}_ca.pem', config)
- self.assertIn(f'cert /run/openvpn/{interface}_cert.pem', config)
- self.assertIn(f'key /run/openvpn/{interface}_cert.key', config)
- self.assertIn(f'dh /run/openvpn/{interface}_dh.pem', config)
-
- # IP pool configuration
- netmask = IPv4Network(subnet).netmask
- network = IPv4Network(subnet).network_address
- self.assertIn(f'server {network} {netmask} nopool', config)
- self.assertIn(f'ifconfig-pool {start_addr} {stop_addr}', config)
-
- self.assertTrue(process_named_running(PROCESS_NAME))
- self.assertEqual(get_vrf(interface), vrf_name)
- self.assertIn(interface, interfaces())
-
- # check that no interface remained after deleting them
- self.cli_delete(base_path)
- self.cli_commit()
-
- for ii in num_range:
- interface = f'vtun{ii}'
- self.assertNotIn(interface, interfaces())
-
def test_openvpn_site2site_verify(self):
# Create one OpenVPN site2site interface and check required
# verify() stages
diff --git a/smoketest/scripts/cli/test_interfaces_pppoe.py b/smoketest/scripts/cli/test_interfaces_pppoe.py
index 0ce5e2fe0..7b702759f 100755
--- a/smoketest/scripts/cli/test_interfaces_pppoe.py
+++ b/smoketest/scripts/cli/test_interfaces_pppoe.py
@@ -59,10 +59,12 @@ class PPPoEInterfaceTest(VyOSUnitTestSHIM.TestCase):
user = f'VyOS-user-{interface}'
passwd = f'VyOS-passwd-{interface}'
mtu = '1400'
+ mru = '1300'
self.cli_set(base_path + [interface, 'authentication', 'username', user])
self.cli_set(base_path + [interface, 'authentication', 'password', passwd])
self.cli_set(base_path + [interface, 'mtu', mtu])
+ self.cli_set(base_path + [interface, 'mru', '9000'])
self.cli_set(base_path + [interface, 'no-peer-dns'])
# check validate() - a source-interface is required
@@ -70,6 +72,11 @@ class PPPoEInterfaceTest(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
self.cli_set(base_path + [interface, 'source-interface', self._source_interface])
+ # check validate() - MRU needs to be less or equal then MTU
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+ self.cli_set(base_path + [interface, 'mru', mru])
+
# commit changes
self.cli_commit()
@@ -80,6 +87,8 @@ class PPPoEInterfaceTest(VyOSUnitTestSHIM.TestCase):
tmp = get_config_value(interface, 'mtu')[1]
self.assertEqual(tmp, mtu)
+ tmp = get_config_value(interface, 'mru')[1]
+ self.assertEqual(tmp, mru)
tmp = get_config_value(interface, 'user')[1].replace('"', '')
self.assertEqual(tmp, user)
tmp = get_config_value(interface, 'password')[1].replace('"', '')
diff --git a/smoketest/scripts/cli/test_interfaces_vxlan.py b/smoketest/scripts/cli/test_interfaces_vxlan.py
index f6b203de4..e9c9e68fd 100755
--- a/smoketest/scripts/cli/test_interfaces_vxlan.py
+++ b/smoketest/scripts/cli/test_interfaces_vxlan.py
@@ -20,6 +20,8 @@ from vyos.configsession import ConfigSessionError
from vyos.ifconfig import Interface
from vyos.utils.network import get_bridge_fdb
from vyos.utils.network import get_interface_config
+from vyos.utils.network import interface_exists
+from vyos.utils.network import get_vxlan_vlan_tunnels
from vyos.template import is_ipv6
from base_interfaces_test import BasicInterfaceTest
@@ -133,5 +135,53 @@ class VXLANInterfaceTest(BasicInterfaceTest.TestCase):
self.assertTrue(options['linkinfo']['info_data']['external'])
self.assertEqual('vxlan', options['linkinfo']['info_kind'])
+ def test_vxlan_vlan_vni_mapping(self):
+ bridge = 'br0'
+ interface = 'vxlan0'
+ source_interface = 'eth0'
+
+ vlan_to_vni = {
+ '10': '10010',
+ '11': '10011',
+ '12': '10012',
+ '13': '10013',
+ '20': '10020',
+ '30': '10030',
+ '31': '10031',
+ }
+
+ self.cli_set(self._base_path + [interface, 'external'])
+ self.cli_set(self._base_path + [interface, 'source-interface', source_interface])
+
+ for vlan, vni in vlan_to_vni.items():
+ self.cli_set(self._base_path + [interface, 'vlan-to-vni', vlan, 'vni', vni])
+
+ # This must fail as this VXLAN interface is not associated with any bridge
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+ self.cli_set(['interfaces', 'bridge', bridge, 'member', 'interface', interface])
+
+ # It is not allowed to use duplicate VNIs
+ self.cli_set(self._base_path + [interface, 'vlan-to-vni', '11', 'vni', vlan_to_vni['10']])
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+ # restore VLAN - VNI mappings
+ for vlan, vni in vlan_to_vni.items():
+ self.cli_set(self._base_path + [interface, 'vlan-to-vni', vlan, 'vni', vni])
+
+ # commit configuration
+ self.cli_commit()
+
+ self.assertTrue(interface_exists(bridge))
+ self.assertTrue(interface_exists(interface))
+
+ tmp = get_interface_config(interface)
+ self.assertEqual(tmp['master'], bridge)
+
+ tmp = get_vxlan_vlan_tunnels('vxlan0')
+ self.assertEqual(tmp, list(vlan_to_vni))
+
+ self.cli_delete(['interfaces', 'bridge', bridge])
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_interfaces_wireless.py b/smoketest/scripts/cli/test_interfaces_wireless.py
index f8686edd8..95246a7b9 100755
--- a/smoketest/scripts/cli/test_interfaces_wireless.py
+++ b/smoketest/scripts/cli/test_interfaces_wireless.py
@@ -97,6 +97,7 @@ class WirelessInterfaceTest(BasicInterfaceTest.TestCase):
vht_opt = {
# VyOS CLI option hostapd - ht_capab setting
+ 'channel-set-width 3' : '[VHT160-80PLUS80]',
'stbc tx' : '[TX-STBC-2BY1]',
'stbc rx 12' : '[RX-STBC-12]',
'ldpc' : '[RXLDPC]',
@@ -104,7 +105,7 @@ class WirelessInterfaceTest(BasicInterfaceTest.TestCase):
'vht-cf' : '[HTC-VHT]',
'antenna-pattern-fixed' : '[RX-ANTENNA-PATTERN][TX-ANTENNA-PATTERN]',
'max-mpdu 11454' : '[MAX-MPDU-11454]',
- 'max-mpdu-exp 2' : '[MAX-A-MPDU-LEN-EXP-2][VHT160]',
+ 'max-mpdu-exp 2' : '[MAX-A-MPDU-LEN-EXP-2]',
'link-adaptation both' : '[VHT-LINK-ADAPT3]',
'short-gi 80' : '[SHORT-GI-80]',
'short-gi 160' : '[SHORT-GI-160]',
diff --git a/smoketest/scripts/cli/test_load_balancing_reverse_proxy.py b/smoketest/scripts/cli/test_load_balancing_reverse_proxy.py
index a33fd5c18..274b97f22 100755
--- a/smoketest/scripts/cli/test_load_balancing_reverse_proxy.py
+++ b/smoketest/scripts/cli/test_load_balancing_reverse_proxy.py
@@ -74,6 +74,7 @@ class TestLoadBalancingReverseProxy(VyOSUnitTestSHIM.TestCase):
self.cli_set(back_base + [bk_second_name, 'mode', mode])
self.cli_set(back_base + [bk_second_name, 'server', bk_second_name, 'address', bk_server_second])
self.cli_set(back_base + [bk_second_name, 'server', bk_second_name, 'port', bk_server_port])
+ self.cli_set(back_base + [bk_second_name, 'server', bk_second_name, 'backup'])
self.cli_set(base_path + ['global-parameters', 'max-connections', max_connections])
@@ -106,6 +107,7 @@ class TestLoadBalancingReverseProxy(VyOSUnitTestSHIM.TestCase):
self.assertIn(f'backend {bk_second_name}', config)
self.assertIn(f'mode {mode}', config)
self.assertIn(f'server {bk_second_name} {bk_server_second}:{bk_server_port}', config)
+ self.assertIn(f'server {bk_second_name} {bk_server_second}:{bk_server_port} backup', config)
if __name__ == '__main__':
diff --git a/smoketest/scripts/cli/test_load_balancing_wan.py b/smoketest/scripts/cli/test_load_balancing_wan.py
index 9b2cb0fac..47ca19b27 100755
--- a/smoketest/scripts/cli/test_load_balancing_wan.py
+++ b/smoketest/scripts/cli/test_load_balancing_wan.py
@@ -124,11 +124,12 @@ class TestLoadBalancingWan(VyOSUnitTestSHIM.TestCase):
self.assertEqual(tmp, original)
# Delete veth interfaces and netns
- for iface in [iface1, iface2, iface3, container_iface1, container_iface2, container_iface3]:
+ for iface in [iface1, iface2, iface3]:
call(f'sudo ip link del dev {iface}')
delete_netns(ns1)
delete_netns(ns2)
+ delete_netns(ns3)
def test_check_chains(self):
@@ -246,11 +247,13 @@ class TestLoadBalancingWan(VyOSUnitTestSHIM.TestCase):
self.assertEqual(tmp, nat_vyos_pre_snat_hook)
# Delete veth interfaces and netns
- for iface in [iface1, iface2, iface3, container_iface1, container_iface2, container_iface3]:
+ for iface in [iface1, iface2, iface3]:
call(f'sudo ip link del dev {iface}')
delete_netns(ns1)
delete_netns(ns2)
+ delete_netns(ns3)
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_nat.py b/smoketest/scripts/cli/test_nat.py
index 31dfcef87..703e5ab28 100755
--- a/smoketest/scripts/cli/test_nat.py
+++ b/smoketest/scripts/cli/test_nat.py
@@ -155,11 +155,6 @@ class TestNAT(VyOSUnitTestSHIM.TestCase):
rule = '5'
self.cli_set(src_path + ['rule', rule, 'source', 'address', '192.0.2.0/24'])
- # check validate() - outbound-interface must be defined
- with self.assertRaises(ConfigSessionError):
- self.cli_commit()
- self.cli_set(src_path + ['rule', rule, 'outbound-interface', 'eth0'])
-
# check validate() - translation address not specified
with self.assertRaises(ConfigSessionError):
self.cli_commit()
diff --git a/smoketest/scripts/cli/test_interfaces_netns.py b/smoketest/scripts/cli/test_netns.py
index b8bebb221..fd04dd520 100755
--- a/smoketest/scripts/cli/test_interfaces_netns.py
+++ b/smoketest/scripts/cli/test_netns.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright (C) 2021-2023 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -16,7 +16,6 @@
import unittest
-from netifaces import interfaces
from base_vyostest_shim import VyOSUnitTestSHIM
from vyos.configsession import ConfigSession
@@ -24,56 +23,61 @@ from vyos.configsession import ConfigSessionError
from vyos.ifconfig import Interface
from vyos.ifconfig import Section
from vyos.utils.process import cmd
+from vyos.utils.network import is_netns_interface
+from vyos.utils.network import get_netns_all
base_path = ['netns']
-namespaces = ['mgmt', 'front', 'back', 'ams-ix']
+interfaces = ['dum10', 'dum12', 'dum50']
-class NETNSTest(VyOSUnitTestSHIM.TestCase):
- def setUp(self):
- self._interfaces = ['dum10', 'dum12', 'dum50']
+class NetNSTest(VyOSUnitTestSHIM.TestCase):
+ def tearDown(self):
+ self.cli_delete(base_path)
+ # commit changes
+ self.cli_commit()
+
+ # There should be no network namespace remaining
+ tmp = cmd('ip netns ls')
+ self.assertFalse(tmp)
+
+ super(NetNSTest, self).tearDown()
- def test_create_netns(self):
+ def test_netns_create(self):
+ namespaces = ['mgmt', 'front', 'back']
for netns in namespaces:
- base = base_path + ['name', netns]
- self.cli_set(base)
+ self.cli_set(base_path + ['name', netns])
# commit changes
self.cli_commit()
- netns_list = cmd('ip netns ls')
-
# Verify NETNS configuration
for netns in namespaces:
- self.assertTrue(netns in netns_list)
-
+ self.assertIn(netns, get_netns_all())
- def test_netns_assign_interface(self):
+ def test_netns_interface(self):
netns = 'foo'
- self.cli_set(['netns', 'name', netns])
+ self.cli_set(base_path + ['name', netns])
# Set
- for iface in self._interfaces:
+ for iface in interfaces:
self.cli_set(['interfaces', 'dummy', iface, 'netns', netns])
# commit changes
self.cli_commit()
- netns_iface_list = cmd(f'sudo ip netns exec {netns} ip link show')
-
- for iface in self._interfaces:
- self.assertTrue(iface in netns_iface_list)
+ for interface in interfaces:
+ self.assertTrue(is_netns_interface(interface, netns))
# Delete
- for iface in self._interfaces:
- self.cli_delete(['interfaces', 'dummy', iface, 'netns', netns])
+ for interface in interfaces:
+ self.cli_delete(['interfaces', 'dummy', interface])
# commit changes
self.cli_commit()
netns_iface_list = cmd(f'sudo ip netns exec {netns} ip link show')
- for iface in self._interfaces:
- self.assertNotIn(iface, netns_iface_list)
+ for interface in interfaces:
+ self.assertFalse(is_netns_interface(interface, netns))
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_policy.py b/smoketest/scripts/cli/test_policy.py
index 354f791bd..4ac422d5f 100755
--- a/smoketest/scripts/cli/test_policy.py
+++ b/smoketest/scripts/cli/test_policy.py
@@ -1467,7 +1467,7 @@ class TestPolicy(VyOSUnitTestSHIM.TestCase):
table = '23'
for src in sources:
self.cli_set(path + ['rule', rule, 'set', 'table', table])
- self.cli_set(path + ['rule', rule, 'source', src])
+ self.cli_set(path + ['rule', rule, 'source', 'address', src])
self.cli_commit()
@@ -1508,7 +1508,7 @@ class TestPolicy(VyOSUnitTestSHIM.TestCase):
table = '154'
self.cli_set(path + ['rule', rule, 'set', 'table', table])
- self.cli_set(path + ['rule', rule, 'destination', dst])
+ self.cli_set(path + ['rule', rule, 'destination', 'address', dst])
self.cli_commit()
@@ -1519,6 +1519,28 @@ class TestPolicy(VyOSUnitTestSHIM.TestCase):
self.assertEqual(sort_ip(tmp), sort_ip(original))
+ # Test set table for destination and protocol
+ def test_protocol_destination_table_id(self):
+ path = base_path + ['local-route']
+
+ dst = '203.0.113.12'
+ rule = '85'
+ table = '104'
+ proto = 'tcp'
+
+ self.cli_set(path + ['rule', rule, 'set', 'table', table])
+ self.cli_set(path + ['rule', rule, 'destination', 'address', dst])
+ self.cli_set(path + ['rule', rule, 'protocol', proto])
+
+ self.cli_commit()
+
+ original = """
+ 85: from all to 203.0.113.12 ipproto tcp lookup 104
+ """
+ tmp = cmd('ip rule show prio 85')
+
+ self.assertEqual(sort_ip(tmp), sort_ip(original))
+
# Test set table for sources with fwmark
def test_fwmark_sources_table_id(self):
path = base_path + ['local-route']
@@ -1529,7 +1551,7 @@ class TestPolicy(VyOSUnitTestSHIM.TestCase):
table = '150'
for src in sources:
self.cli_set(path + ['rule', rule, 'set', 'table', table])
- self.cli_set(path + ['rule', rule, 'source', src])
+ self.cli_set(path + ['rule', rule, 'source', 'address', src])
self.cli_set(path + ['rule', rule, 'fwmark', fwmk])
self.cli_commit()
@@ -1554,7 +1576,7 @@ class TestPolicy(VyOSUnitTestSHIM.TestCase):
self.cli_set(path + ['rule', rule, 'set', 'table', table])
self.cli_set(path + ['rule', rule, 'inbound-interface', iif])
for src in sources:
- self.cli_set(path + ['rule', rule, 'source', src])
+ self.cli_set(path + ['rule', rule, 'source', 'address', src])
self.cli_commit()
@@ -1580,8 +1602,8 @@ class TestPolicy(VyOSUnitTestSHIM.TestCase):
for src in sources:
for dst in destinations:
self.cli_set(path + ['rule', rule, 'set', 'table', table])
- self.cli_set(path + ['rule', rule, 'source', src])
- self.cli_set(path + ['rule', rule, 'destination', dst])
+ self.cli_set(path + ['rule', rule, 'source', 'address', src])
+ self.cli_set(path + ['rule', rule, 'destination', 'address', dst])
self.cli_set(path + ['rule', rule, 'fwmark', fwmk])
self.cli_commit()
@@ -1605,7 +1627,7 @@ class TestPolicy(VyOSUnitTestSHIM.TestCase):
table = '23'
for src in sources:
self.cli_set(path + ['rule', rule, 'set', 'table', table])
- self.cli_set(path + ['rule', rule, 'source', src])
+ self.cli_set(path + ['rule', rule, 'source', 'address', src])
self.cli_commit()
@@ -1646,7 +1668,7 @@ class TestPolicy(VyOSUnitTestSHIM.TestCase):
table = '154'
self.cli_set(path + ['rule', rule, 'set', 'table', table])
- self.cli_set(path + ['rule', rule, 'destination', dst])
+ self.cli_set(path + ['rule', rule, 'destination', 'address', dst])
self.cli_commit()
@@ -1667,7 +1689,7 @@ class TestPolicy(VyOSUnitTestSHIM.TestCase):
table = '150'
for src in sources:
self.cli_set(path + ['rule', rule, 'set', 'table', table])
- self.cli_set(path + ['rule', rule, 'source', src])
+ self.cli_set(path + ['rule', rule, 'source', 'address', src])
self.cli_set(path + ['rule', rule, 'fwmark', fwmk])
self.cli_commit()
@@ -1690,7 +1712,7 @@ class TestPolicy(VyOSUnitTestSHIM.TestCase):
table = '150'
for src in sources:
self.cli_set(path + ['rule', rule, 'set', 'table', table])
- self.cli_set(path + ['rule', rule, 'source', src])
+ self.cli_set(path + ['rule', rule, 'source', 'address', src])
self.cli_set(path + ['rule', rule, 'inbound-interface', iif])
self.cli_commit()
@@ -1717,8 +1739,8 @@ class TestPolicy(VyOSUnitTestSHIM.TestCase):
for src in sources:
for dst in destinations:
self.cli_set(path + ['rule', rule, 'set', 'table', table])
- self.cli_set(path + ['rule', rule, 'source', src])
- self.cli_set(path + ['rule', rule, 'destination', dst])
+ self.cli_set(path + ['rule', rule, 'source', 'address', src])
+ self.cli_set(path + ['rule', rule, 'destination', 'address', dst])
self.cli_set(path + ['rule', rule, 'fwmark', fwmk])
self.cli_commit()
@@ -1748,15 +1770,15 @@ class TestPolicy(VyOSUnitTestSHIM.TestCase):
for src in sources:
for dst in destinations:
self.cli_set(path + ['rule', rule, 'set', 'table', table])
- self.cli_set(path + ['rule', rule, 'source', src])
- self.cli_set(path + ['rule', rule, 'destination', dst])
+ self.cli_set(path + ['rule', rule, 'source', 'address', src])
+ self.cli_set(path + ['rule', rule, 'destination', 'address', dst])
self.cli_set(path + ['rule', rule, 'fwmark', fwmk])
for src in sources_v6:
for dst in destinations_v6:
self.cli_set(path_v6 + ['rule', rule, 'set', 'table', table])
- self.cli_set(path_v6 + ['rule', rule, 'source', src])
- self.cli_set(path_v6 + ['rule', rule, 'destination', dst])
+ self.cli_set(path_v6 + ['rule', rule, 'source', 'address', src])
+ self.cli_set(path_v6 + ['rule', rule, 'destination', 'address', dst])
self.cli_set(path_v6 + ['rule', rule, 'fwmark', fwmk])
self.cli_commit()
@@ -1799,7 +1821,7 @@ class TestPolicy(VyOSUnitTestSHIM.TestCase):
table = '151'
self.cli_set(path + ['rule', rule, 'set', 'table', table])
for src in sources:
- self.cli_set(path + ['rule', rule, 'source', src])
+ self.cli_set(path + ['rule', rule, 'source', 'address', src])
self.cli_commit()
@@ -1812,7 +1834,7 @@ class TestPolicy(VyOSUnitTestSHIM.TestCase):
self.assertEqual(sort_ip(tmp), sort_ip(original_first))
# Create second commit with added destination
- self.cli_set(path + ['rule', rule, 'destination', destination])
+ self.cli_set(path + ['rule', rule, 'destination', 'address', destination])
self.cli_commit()
original_second = """
diff --git a/smoketest/scripts/cli/test_policy_route.py b/smoketest/scripts/cli/test_policy_route.py
index d9b64544a..72192fb98 100755
--- a/smoketest/scripts/cli/test_policy_route.py
+++ b/smoketest/scripts/cli/test_policy_route.py
@@ -191,15 +191,18 @@ class TestPolicyRoute(VyOSUnitTestSHIM.TestCase):
def test_pbr_matching_criteria(self):
self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'protocol', 'udp'])
self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'action', 'drop'])
+ self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'mark', '2020'])
self.cli_set(['policy', 'route', 'smoketest', 'rule', '2', 'protocol', 'tcp'])
self.cli_set(['policy', 'route', 'smoketest', 'rule', '2', 'tcp', 'flags', 'syn'])
self.cli_set(['policy', 'route', 'smoketest', 'rule', '2', 'tcp', 'flags', 'not', 'ack'])
+ self.cli_set(['policy', 'route', 'smoketest', 'rule', '2', 'mark', '2-3000'])
self.cli_set(['policy', 'route', 'smoketest', 'rule', '2', 'set', 'table', table_id])
self.cli_set(['policy', 'route', 'smoketest', 'rule', '3', 'source', 'address', '198.51.100.0/24'])
self.cli_set(['policy', 'route', 'smoketest', 'rule', '3', 'protocol', 'tcp'])
self.cli_set(['policy', 'route', 'smoketest', 'rule', '3', 'destination', 'port', '22'])
self.cli_set(['policy', 'route', 'smoketest', 'rule', '3', 'state', 'new', 'enable'])
self.cli_set(['policy', 'route', 'smoketest', 'rule', '3', 'ttl', 'gt', '2'])
+ self.cli_set(['policy', 'route', 'smoketest', 'rule', '3', 'mark', '!456'])
self.cli_set(['policy', 'route', 'smoketest', 'rule', '3', 'set', 'table', table_id])
self.cli_set(['policy', 'route', 'smoketest', 'rule', '4', 'protocol', 'icmp'])
self.cli_set(['policy', 'route', 'smoketest', 'rule', '4', 'icmp', 'type-name', 'echo-request'])
@@ -210,6 +213,7 @@ class TestPolicyRoute(VyOSUnitTestSHIM.TestCase):
self.cli_set(['policy', 'route', 'smoketest', 'rule', '4', 'set', 'table', table_id])
self.cli_set(['policy', 'route', 'smoketest', 'rule', '5', 'dscp', '41'])
self.cli_set(['policy', 'route', 'smoketest', 'rule', '5', 'dscp', '57-59'])
+ self.cli_set(['policy', 'route', 'smoketest', 'rule', '5', 'mark', '!456-500'])
self.cli_set(['policy', 'route', 'smoketest', 'rule', '5', 'set', 'table', table_id])
self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '1', 'protocol', 'udp'])
@@ -247,11 +251,11 @@ class TestPolicyRoute(VyOSUnitTestSHIM.TestCase):
# IPv4
nftables_search = [
['iifname { "' + interface + '", "' + interface_wc + '" }', 'jump VYOS_PBR_UD_smoketest'],
- ['meta l4proto udp', 'drop'],
- ['tcp flags syn / syn,ack', 'meta mark set ' + mark_hex],
- ['ct state new', 'tcp dport 22', 'ip saddr 198.51.100.0/24', 'ip ttl > 2', 'meta mark set ' + mark_hex],
- ['meta l4proto icmp', 'log prefix "[smoketest-4-A]"', 'icmp type echo-request', 'ip length { 128, 1024-2048 }', 'meta pkttype other', 'meta mark set ' + mark_hex],
- ['ip dscp { 0x29, 0x39-0x3b }', 'meta mark set ' + mark_hex]
+ ['meta l4proto udp', 'meta mark 0x000007e4', 'drop'],
+ ['tcp flags syn / syn,ack', 'meta mark 0x00000002-0x00000bb8', 'meta mark set ' + mark_hex],
+ ['ct state new', 'tcp dport 22', 'ip saddr 198.51.100.0/24', 'ip ttl > 2', 'meta mark != 0x000001c8', 'meta mark set ' + mark_hex],
+ ['log prefix "[ipv4-route-smoketest-4-A]"', 'icmp type echo-request', 'ip length { 128, 1024-2048 }', 'meta pkttype other', 'meta mark set ' + mark_hex],
+ ['ip dscp { 0x29, 0x39-0x3b }', 'meta mark != 0x000001c8-0x000001f4', 'meta mark set ' + mark_hex]
]
self.verify_nftables(nftables_search, 'ip vyos_mangle')
@@ -262,7 +266,7 @@ class TestPolicyRoute(VyOSUnitTestSHIM.TestCase):
['meta l4proto udp', 'drop'],
['tcp flags syn / syn,ack', 'meta mark set ' + mark_hex],
['ct state new', 'tcp dport 22', 'ip6 saddr 2001:db8::/64', 'ip6 hoplimit > 2', 'meta mark set ' + mark_hex],
- ['meta l4proto ipv6-icmp', 'log prefix "[smoketest6-4-A]"', 'icmpv6 type echo-request', 'ip6 length != { 128, 1024-2048 }', 'meta pkttype multicast', 'meta mark set ' + mark_hex],
+ ['log prefix "[ipv6-route6-smoketest6-4-A]"', 'icmpv6 type echo-request', 'ip6 length != { 128, 1024-2048 }', 'meta pkttype multicast', 'meta mark set ' + mark_hex],
['ip6 dscp != { 0x0e-0x13, 0x3d }', 'meta mark set ' + mark_hex]
]
diff --git a/smoketest/scripts/cli/test_protocols_bgp.py b/smoketest/scripts/cli/test_protocols_bgp.py
index 77952d8d9..967958cab 100755
--- a/smoketest/scripts/cli/test_protocols_bgp.py
+++ b/smoketest/scripts/cli/test_protocols_bgp.py
@@ -44,6 +44,7 @@ neighbor_config = {
'bfd' : '',
'cap_dynamic' : '',
'cap_ext_next' : '',
+ 'cap_ext_sver' : '',
'remote_as' : '100',
'adv_interv' : '400',
'passive' : '',
@@ -71,6 +72,7 @@ neighbor_config = {
'pfx_list_out' : prefix_list_out,
'no_send_comm_std' : '',
'local_role' : 'rs-client',
+ 'p_attr_taw' : '200',
},
'192.0.2.3' : {
'advertise_map' : route_map_in,
@@ -87,6 +89,7 @@ neighbor_config = {
'exist_map' : route_map_out,
'cap_dynamic' : '',
'cap_ext_next' : '',
+ 'cap_ext_sver' : '',
'remote_as' : '123',
'adv_interv' : '400',
'passive' : '',
@@ -137,6 +140,7 @@ peer_group_config = {
'remote_as' : '111',
'graceful_rst_no' : '',
'port' : '667',
+ 'p_attr_taw' : '126',
},
'foo-bar' : {
'advertise_map' : route_map_in,
@@ -217,6 +221,8 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase):
self.assertIn(f' neighbor {peer} capability dynamic', frrconfig)
if 'cap_ext_next' in peer_config:
self.assertIn(f' neighbor {peer} capability extended-nexthop', frrconfig)
+ if 'cap_ext_sver' in peer_config:
+ self.assertIn(f' neighbor {peer} capability software-version', frrconfig)
if 'description' in peer_config:
self.assertIn(f' neighbor {peer} description {peer_config["description"]}', frrconfig)
if 'no_cap_nego' in peer_config:
@@ -264,6 +270,8 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase):
self.assertIn(f' neighbor {peer} addpath-tx-all-paths', frrconfig)
if 'p_attr_discard' in peer_config:
self.assertIn(f' neighbor {peer} path-attribute discard {peer_config["p_attr_discard"]}', frrconfig)
+ if 'p_attr_taw' in peer_config:
+ self.assertIn(f' neighbor {peer} path-attribute treat-as-withdraw {peer_config["p_attr_taw"]}', frrconfig)
if 'addpath_per_as' in peer_config:
self.assertIn(f' neighbor {peer} addpath-tx-bestpath-per-AS', frrconfig)
if 'advertise_map' in peer_config:
@@ -390,6 +398,8 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase):
self.cli_set(base_path + ['neighbor', peer, 'capability', 'dynamic'])
if 'cap_ext_next' in peer_config:
self.cli_set(base_path + ['neighbor', peer, 'capability', 'extended-nexthop'])
+ if 'cap_ext_sver' in peer_config:
+ self.cli_set(base_path + ['neighbor', peer, 'capability', 'software-version'])
if 'description' in peer_config:
self.cli_set(base_path + ['neighbor', peer, 'description', peer_config["description"]])
if 'no_cap_nego' in peer_config:
@@ -424,6 +434,8 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase):
self.cli_set(base_path + ['neighbor', peer, 'update-source', peer_config["update_src"]])
if 'p_attr_discard' in peer_config:
self.cli_set(base_path + ['neighbor', peer, 'path-attribute', 'discard', peer_config["p_attr_discard"]])
+ if 'p_attr_taw' in peer_config:
+ self.cli_set(base_path + ['neighbor', peer, 'path-attribute', 'treat-as-withdraw', peer_config["p_attr_taw"]])
if 'route_map_in' in peer_config:
self.cli_set(base_path + ['neighbor', peer, 'address-family', afi, 'route-map', 'import', peer_config["route_map_in"]])
if 'route_map_out' in peer_config:
@@ -490,6 +502,8 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase):
self.cli_set(base_path + ['peer-group', peer_group, 'capability', 'dynamic'])
if 'cap_ext_next' in config:
self.cli_set(base_path + ['peer-group', peer_group, 'capability', 'extended-nexthop'])
+ if 'cap_ext_sver' in config:
+ self.cli_set(base_path + ['peer-group', peer_group, 'capability', 'software-version'])
if 'description' in config:
self.cli_set(base_path + ['peer-group', peer_group, 'description', config["description"]])
if 'no_cap_nego' in config:
@@ -544,6 +558,8 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase):
self.cli_set(base_path + ['peer-group', peer_group, 'disable-connected-check'])
if 'p_attr_discard' in config:
self.cli_set(base_path + ['peer-group', peer_group, 'path-attribute', 'discard', config["p_attr_discard"]])
+ if 'p_attr_taw' in config:
+ self.cli_set(base_path + ['peer-group', peer_group, 'path-attribute', 'treat-as-withdraw', config["p_attr_taw"]])
# Conditional advertisement
if 'advertise_map' in config:
diff --git a/smoketest/scripts/cli/test_protocols_isis.py b/smoketest/scripts/cli/test_protocols_isis.py
index af171c8b2..8b423dbea 100755
--- a/smoketest/scripts/cli/test_protocols_isis.py
+++ b/smoketest/scripts/cli/test_protocols_isis.py
@@ -100,6 +100,8 @@ class TestProtocolsISIS(VyOSUnitTestSHIM.TestCase):
self.cli_set(vrf_base + ['table', table])
self.cli_set(vrf_base + ['protocols', 'isis', 'net', net])
self.cli_set(vrf_base + ['protocols', 'isis', 'interface', vrf_iface])
+ self.cli_set(vrf_base + ['protocols', 'isis', 'advertise-high-metrics'])
+ self.cli_set(vrf_base + ['protocols', 'isis', 'advertise-passive-only'])
self.cli_set(['interfaces', 'ethernet', vrf_iface, 'vrf', vrf])
# Also set a default VRF IS-IS config
@@ -115,6 +117,8 @@ class TestProtocolsISIS(VyOSUnitTestSHIM.TestCase):
tmp = self.getFRRconfig(f'router isis {domain} vrf {vrf}', daemon='isisd')
self.assertIn(f'router isis {domain} vrf {vrf}', tmp)
self.assertIn(f' net {net}', tmp)
+ self.assertIn(f' advertise-high-metrics', tmp)
+ self.assertIn(f' advertise-passive-only', tmp)
self.cli_delete(['vrf', 'name', vrf])
self.cli_delete(['interfaces', 'ethernet', vrf_iface, 'vrf'])
diff --git a/smoketest/scripts/cli/test_protocols_pim6.py b/smoketest/scripts/cli/test_protocols_pim6.py
new file mode 100755
index 000000000..1be12836d
--- /dev/null
+++ b/smoketest/scripts/cli/test_protocols_pim6.py
@@ -0,0 +1,110 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2023 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import unittest
+
+from base_vyostest_shim import VyOSUnitTestSHIM
+from vyos.configsession import ConfigSessionError
+from vyos.ifconfig import Section
+from vyos.utils.process import process_named_running
+
+PROCESS_NAME = 'pim6d'
+base_path = ['protocols', 'pim6']
+
+
+class TestProtocolsPIMv6(VyOSUnitTestSHIM.TestCase):
+ def tearDown(self):
+ # Check for running process
+ self.assertTrue(process_named_running(PROCESS_NAME))
+ self.cli_delete(base_path)
+ self.cli_commit()
+
+ def test_pim6_01_mld_simple(self):
+ # commit changes
+ interfaces = Section.interfaces('ethernet')
+
+ for interface in interfaces:
+ self.cli_set(base_path + ['interface', interface])
+
+ self.cli_commit()
+
+ # Verify FRR pim6d configuration
+ for interface in interfaces:
+ config = self.getFRRconfig(
+ f'interface {interface}', daemon=PROCESS_NAME)
+ self.assertIn(f'interface {interface}', config)
+ self.assertIn(f' ipv6 mld', config)
+ self.assertNotIn(f' ipv6 mld version 1', config)
+
+ # Change to MLD version 1
+ for interface in interfaces:
+ self.cli_set(base_path + ['interface',
+ interface, 'mld', 'version', '1'])
+
+ self.cli_commit()
+
+ # Verify FRR pim6d configuration
+ for interface in interfaces:
+ config = self.getFRRconfig(
+ f'interface {interface}', daemon=PROCESS_NAME)
+ self.assertIn(f'interface {interface}', config)
+ self.assertIn(f' ipv6 mld', config)
+ self.assertIn(f' ipv6 mld version 1', config)
+
+ def test_pim6_02_mld_join(self):
+ # commit changes
+ interfaces = Section.interfaces('ethernet')
+
+ # Use an invalid multiple group address
+ for interface in interfaces:
+ self.cli_set(base_path + ['interface',
+ interface, 'mld', 'join', 'fd00::1234'])
+
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+ self.cli_delete(base_path + ['interface'])
+
+ # Use a valid multiple group address
+ for interface in interfaces:
+ self.cli_set(base_path + ['interface',
+ interface, 'mld', 'join', 'ff18::1234'])
+
+ self.cli_commit()
+
+ # Verify FRR pim6d configuration
+ for interface in interfaces:
+ config = self.getFRRconfig(
+ f'interface {interface}', daemon=PROCESS_NAME)
+ self.assertIn(f'interface {interface}', config)
+ self.assertIn(f' ipv6 mld join ff18::1234', config)
+
+ # Join a source-specific multicast group
+ for interface in interfaces:
+ self.cli_set(base_path + ['interface', interface,
+ 'mld', 'join', 'ff38::5678', 'source', '2001:db8::5678'])
+
+ self.cli_commit()
+
+ # Verify FRR pim6d configuration
+ for interface in interfaces:
+ config = self.getFRRconfig(
+ f'interface {interface}', daemon=PROCESS_NAME)
+ self.assertIn(f'interface {interface}', config)
+ self.assertIn(f' ipv6 mld join ff38::5678 2001:db8::5678', config)
+
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_service_dns_dynamic.py b/smoketest/scripts/cli/test_service_dns_dynamic.py
index ee8a07b37..acabc0070 100755
--- a/smoketest/scripts/cli/test_service_dns_dynamic.py
+++ b/smoketest/scripts/cli/test_service_dns_dynamic.py
@@ -17,6 +17,8 @@
import os
import unittest
import tempfile
+import random
+import string
from base_vyostest_shim import VyOSUnitTestSHIM
@@ -24,16 +26,25 @@ from vyos.configsession import ConfigSessionError
from vyos.utils.process import cmd
from vyos.utils.process import process_running
+DDCLIENT_SYSTEMD_UNIT = '/run/systemd/system/ddclient.service.d/override.conf'
DDCLIENT_CONF = '/run/ddclient/ddclient.conf'
DDCLIENT_PID = '/run/ddclient/ddclient.pid'
+DDCLIENT_PNAME = 'ddclient'
base_path = ['service', 'dns', 'dynamic']
+server = 'ddns.vyos.io'
hostname = 'test.ddns.vyos.io'
zone = 'vyos.io'
+username = 'vyos_user'
password = 'paSS_@4ord'
+ttl = '300'
interface = 'eth0'
class TestServiceDDNS(VyOSUnitTestSHIM.TestCase):
+ def setUp(self):
+ # Always start with a clean CLI instance
+ self.cli_delete(base_path)
+
def tearDown(self):
# Check for running process
self.assertTrue(process_running(DDCLIENT_PID))
@@ -47,30 +58,38 @@ class TestServiceDDNS(VyOSUnitTestSHIM.TestCase):
# IPv4 standard DDNS service configuration
def test_01_dyndns_service_standard(self):
- ddns = ['address', interface, 'service']
+ svc_path = ['address', interface, 'service']
services = {'cloudflare': {'protocol': 'cloudflare'},
- 'freedns': {'protocol': 'freedns', 'username': 'vyos_user'},
- 'zoneedit': {'protocol': 'zoneedit1', 'username': 'vyos_user'}}
+ 'freedns': {'protocol': 'freedns', 'username': username},
+ 'zoneedit': {'protocol': 'zoneedit1', 'username': username}}
for svc, details in services.items():
- # Always start with a clean CLI instance
- self.cli_delete(base_path)
-
- self.cli_set(base_path + ddns + [svc, 'host-name', hostname])
- self.cli_set(base_path + ddns + [svc, 'password', password])
- self.cli_set(base_path + ddns + [svc, 'zone', zone])
+ self.cli_set(base_path + svc_path + [svc, 'host-name', hostname])
+ self.cli_set(base_path + svc_path + [svc, 'password', password])
+ self.cli_set(base_path + svc_path + [svc, 'zone', zone])
+ self.cli_set(base_path + svc_path + [svc, 'ttl', ttl])
for opt, value in details.items():
- self.cli_set(base_path + ddns + [svc, opt, value])
+ self.cli_set(base_path + svc_path + [svc, opt, value])
- # commit changes
+ # 'zone' option is supported and required by 'cloudfare', but not 'freedns' and 'zoneedit'
+ self.cli_set(base_path + svc_path + [svc, 'zone', zone])
if details['protocol'] == 'cloudflare':
pass
else:
- # zone option does not work on all protocols, an exception is
- # raised for all others
+ # exception is raised for unsupported ones
with self.assertRaises(ConfigSessionError):
self.cli_commit()
- self.cli_delete(base_path + ddns + [svc, 'zone', zone])
+ self.cli_delete(base_path + svc_path + [svc, 'zone'])
+
+ # 'ttl' option is supported by 'cloudfare', but not 'freedns' and 'zoneedit'
+ self.cli_set(base_path + svc_path + [svc, 'ttl', ttl])
+ if details['protocol'] == 'cloudflare':
+ pass
+ else:
+ # exception is raised for unsupported ones
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+ self.cli_delete(base_path + svc_path + [svc, 'ttl'])
# commit changes
self.cli_commit()
@@ -79,8 +98,8 @@ class TestServiceDDNS(VyOSUnitTestSHIM.TestCase):
ddclient_conf = cmd(f'sudo cat {DDCLIENT_CONF}')
# default value 300 seconds
self.assertIn(f'daemon=300', ddclient_conf)
- self.assertIn(f'use=if', ddclient_conf)
- self.assertIn(f'if={interface}', ddclient_conf)
+ self.assertIn(f'usev4=ifv4', ddclient_conf)
+ self.assertIn(f'ifv4={interface}', ddclient_conf)
self.assertIn(f'password={password}', ddclient_conf)
for opt in details.keys():
@@ -94,20 +113,27 @@ class TestServiceDDNS(VyOSUnitTestSHIM.TestCase):
# IPv6 only DDNS service configuration
def test_02_dyndns_service_ipv6(self):
timeout = '60'
- ddns = ['address', interface, 'service', 'dynv6']
+ svc_path = ['address', interface, 'service', 'dynv6']
proto = 'dyndns2'
- user = 'none'
- password = 'paSS_4ord'
- srv = 'ddns.vyos.io'
ip_version = 'ipv6'
+ wait_time = '600'
+ expiry_time_good = '3600'
+ expiry_time_bad = '360'
self.cli_set(base_path + ['timeout', timeout])
- self.cli_set(base_path + ddns + ['ip-version', ip_version])
- self.cli_set(base_path + ddns + ['protocol', proto])
- self.cli_set(base_path + ddns + ['server', srv])
- self.cli_set(base_path + ddns + ['username', user])
- self.cli_set(base_path + ddns + ['password', password])
- self.cli_set(base_path + ddns + ['host-name', hostname])
+ self.cli_set(base_path + svc_path + ['ip-version', ip_version])
+ self.cli_set(base_path + svc_path + ['protocol', proto])
+ self.cli_set(base_path + svc_path + ['server', server])
+ self.cli_set(base_path + svc_path + ['username', username])
+ self.cli_set(base_path + svc_path + ['password', password])
+ self.cli_set(base_path + svc_path + ['host-name', hostname])
+ self.cli_set(base_path + svc_path + ['wait-time', wait_time])
+
+ # expiry-time must be greater than wait-time, exception is raised otherwise
+ self.cli_set(base_path + svc_path + ['expiry-time', expiry_time_bad])
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+ self.cli_set(base_path + svc_path + ['expiry-time', expiry_time_good])
# commit changes
self.cli_commit()
@@ -118,37 +144,47 @@ class TestServiceDDNS(VyOSUnitTestSHIM.TestCase):
self.assertIn(f'usev6=ifv6', ddclient_conf)
self.assertIn(f'ifv6={interface}', ddclient_conf)
self.assertIn(f'protocol={proto}', ddclient_conf)
- self.assertIn(f'server={srv}', ddclient_conf)
- self.assertIn(f'login={user}', ddclient_conf)
+ self.assertIn(f'server={server}', ddclient_conf)
+ self.assertIn(f'login={username}', ddclient_conf)
self.assertIn(f'password={password}', ddclient_conf)
+ self.assertIn(f'min-interval={wait_time}', ddclient_conf)
+ self.assertIn(f'max-interval={expiry_time_good}', ddclient_conf)
# IPv4+IPv6 dual DDNS service configuration
def test_03_dyndns_service_dual_stack(self):
- ddns = ['address', interface, 'service']
- services = {'cloudflare': {'protocol': 'cloudflare', 'zone': 'vyos.io'},
- 'freedns': {'protocol': 'freedns', 'username': 'vyos_user'}}
- password = 'vyos_pass'
+ svc_path = ['address', interface, 'service']
+ services = {'cloudflare': {'protocol': 'cloudflare', 'zone': zone},
+ 'freedns': {'protocol': 'freedns', 'username': username},
+ 'google': {'protocol': 'googledomains', 'username': username}}
ip_version = 'both'
- for svc, details in services.items():
- # Always start with a clean CLI instance
- self.cli_delete(base_path)
-
- self.cli_set(base_path + ddns + [svc, 'host-name', hostname])
- self.cli_set(base_path + ddns + [svc, 'password', password])
- self.cli_set(base_path + ddns + [svc, 'ip-version', ip_version])
+ for name, details in services.items():
+ self.cli_set(base_path + svc_path + [name, 'host-name', hostname])
+ self.cli_set(base_path + svc_path + [name, 'password', password])
for opt, value in details.items():
- self.cli_set(base_path + ddns + [svc, opt, value])
+ self.cli_set(base_path + svc_path + [name, opt, value])
+
+ # Dual stack is supported by 'cloudfare' and 'freedns' but not 'googledomains'
+ # exception is raised for unsupported ones
+ self.cli_set(base_path + svc_path + [name, 'ip-version', ip_version])
+ if details['protocol'] not in ['cloudflare', 'freedns']:
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+ self.cli_delete(base_path + svc_path + [name, 'ip-version'])
# commit changes
self.cli_commit()
# Check the generating config parameters
ddclient_conf = cmd(f'sudo cat {DDCLIENT_CONF}')
- self.assertIn(f'usev4=ifv4', ddclient_conf)
- self.assertIn(f'usev6=ifv6', ddclient_conf)
- self.assertIn(f'ifv4={interface}', ddclient_conf)
- self.assertIn(f'ifv6={interface}', ddclient_conf)
+ if details['protocol'] not in ['cloudflare', 'freedns']:
+ self.assertIn(f'usev4=ifv4', ddclient_conf)
+ self.assertIn(f'ifv4={interface}', ddclient_conf)
+ else:
+ self.assertIn(f'usev4=ifv4', ddclient_conf)
+ self.assertIn(f'usev6=ifv6', ddclient_conf)
+ self.assertIn(f'ifv4={interface}', ddclient_conf)
+ self.assertIn(f'ifv6={interface}', ddclient_conf)
self.assertIn(f'password={password}', ddclient_conf)
for opt in details.keys():
@@ -161,19 +197,16 @@ class TestServiceDDNS(VyOSUnitTestSHIM.TestCase):
def test_04_dyndns_rfc2136(self):
# Check if DDNS service can be configured and runs
- ddns = ['address', interface, 'rfc2136', 'vyos']
- srv = 'ns1.vyos.io'
- zone = 'vyos.io'
- ttl = '300'
+ svc_path = ['address', interface, 'rfc2136', 'vyos']
with tempfile.NamedTemporaryFile(prefix='/config/auth/') as key_file:
key_file.write(b'S3cretKey')
- self.cli_set(base_path + ddns + ['server', srv])
- self.cli_set(base_path + ddns + ['zone', zone])
- self.cli_set(base_path + ddns + ['key', key_file.name])
- self.cli_set(base_path + ddns + ['ttl', ttl])
- self.cli_set(base_path + ddns + ['host-name', hostname])
+ self.cli_set(base_path + svc_path + ['server', server])
+ self.cli_set(base_path + svc_path + ['zone', zone])
+ self.cli_set(base_path + svc_path + ['key', key_file.name])
+ self.cli_set(base_path + svc_path + ['ttl', ttl])
+ self.cli_set(base_path + svc_path + ['host-name', hostname])
# commit changes
self.cli_commit()
@@ -183,10 +216,61 @@ class TestServiceDDNS(VyOSUnitTestSHIM.TestCase):
self.assertIn(f'use=if', ddclient_conf)
self.assertIn(f'if={interface}', ddclient_conf)
self.assertIn(f'protocol=nsupdate', ddclient_conf)
- self.assertIn(f'server={srv}', ddclient_conf)
+ self.assertIn(f'server={server}', ddclient_conf)
self.assertIn(f'zone={zone}', ddclient_conf)
self.assertIn(f'password={key_file.name}', ddclient_conf)
self.assertIn(f'ttl={ttl}', ddclient_conf)
+ def test_05_dyndns_hostname(self):
+ # Check if DDNS service can be configured and runs
+ svc_path = ['address', interface, 'service', 'namecheap']
+ proto = 'namecheap'
+ hostnames = ['@', 'www', hostname, f'@.{hostname}']
+
+ for name in hostnames:
+ self.cli_set(base_path + svc_path + ['protocol', proto])
+ self.cli_set(base_path + svc_path + ['server', server])
+ self.cli_set(base_path + svc_path + ['username', username])
+ self.cli_set(base_path + svc_path + ['password', password])
+ self.cli_set(base_path + svc_path + ['host-name', name])
+
+ # commit changes
+ self.cli_commit()
+
+ # Check the generating config parameters
+ ddclient_conf = cmd(f'sudo cat {DDCLIENT_CONF}')
+ self.assertIn(f'protocol={proto}', ddclient_conf)
+ self.assertIn(f'server={server}', ddclient_conf)
+ self.assertIn(f'login={username}', ddclient_conf)
+ self.assertIn(f'password={password}', ddclient_conf)
+ self.assertIn(f'{name}', ddclient_conf)
+
+ def test_06_dyndns_vrf(self):
+ vrf_name = f'vyos-test-{"".join(random.choices(string.ascii_letters + string.digits, k=5))}'
+ svc_path = ['address', interface, 'service', 'cloudflare']
+
+ self.cli_set(['vrf', 'name', vrf_name, 'table', '12345'])
+ self.cli_set(base_path + ['vrf', vrf_name])
+
+ self.cli_set(base_path + svc_path + ['protocol', 'cloudflare'])
+ self.cli_set(base_path + svc_path + ['host-name', hostname])
+ self.cli_set(base_path + svc_path + ['zone', zone])
+ self.cli_set(base_path + svc_path + ['password', password])
+
+ # commit changes
+ self.cli_commit()
+
+ # Check for process in VRF
+ systemd_override = cmd(f'cat {DDCLIENT_SYSTEMD_UNIT}')
+ self.assertIn(f'ExecStart=ip vrf exec {vrf_name} /usr/bin/ddclient -file {DDCLIENT_CONF}',
+ systemd_override)
+
+ # Check for process in VRF
+ proc = cmd(f'ip vrf pids {vrf_name}')
+ self.assertIn(DDCLIENT_PNAME, proc)
+
+ # Cleanup VRF
+ self.cli_delete(['vrf', 'name', vrf_name])
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_service_mdns-repeater.py b/smoketest/scripts/cli/test_service_mdns-repeater.py
index 9a9839025..f2fb3b509 100755
--- a/smoketest/scripts/cli/test_service_mdns-repeater.py
+++ b/smoketest/scripts/cli/test_service_mdns-repeater.py
@@ -19,6 +19,7 @@ import unittest
from base_vyostest_shim import VyOSUnitTestSHIM
from configparser import ConfigParser
+from vyos.configsession import ConfigSessionError
from vyos.utils.process import process_named_running
base_path = ['service', 'mdns', 'repeater']
@@ -27,6 +28,20 @@ config_file = '/run/avahi-daemon/avahi-daemon.conf'
class TestServiceMDNSrepeater(VyOSUnitTestSHIM.TestCase):
+ def setUp(self):
+ # Start with a clean CLI instance
+ self.cli_delete(base_path)
+
+ # Service required a configured IP address on the interface
+ self.cli_set(intf_base + ['dum10', 'address', '192.0.2.1/30'])
+ self.cli_set(intf_base + ['dum10', 'ipv6', 'address', 'no-default-link-local'])
+ self.cli_set(intf_base + ['dum20', 'address', '192.0.2.5/30'])
+ self.cli_set(intf_base + ['dum20', 'address', '2001:db8:0:2::5/64'])
+ self.cli_set(intf_base + ['dum30', 'address', '192.0.2.9/30'])
+ self.cli_set(intf_base + ['dum30', 'address', '2001:db8:0:2::9/64'])
+ self.cli_set(intf_base + ['dum40', 'address', '2001:db8:0:2::11/64'])
+ self.cli_commit()
+
def tearDown(self):
# Check for running process
self.assertTrue(process_named_running('avahi-daemon'))
@@ -34,24 +49,23 @@ class TestServiceMDNSrepeater(VyOSUnitTestSHIM.TestCase):
self.cli_delete(base_path)
self.cli_delete(intf_base + ['dum10'])
self.cli_delete(intf_base + ['dum20'])
+ self.cli_delete(intf_base + ['dum30'])
+ self.cli_delete(intf_base + ['dum40'])
self.cli_commit()
# Check that there is no longer a running process
self.assertFalse(process_named_running('avahi-daemon'))
- def test_service(self):
+ def test_service_dual_stack(self):
# mDNS browsing domains in addition to the default one (local)
domains = ['dom1.home.arpa', 'dom2.home.arpa']
# mDNS services to be repeated
services = ['_ipp._tcp', '_smb._tcp', '_ssh._tcp']
- # Service required a configured IP address on the interface
- self.cli_set(intf_base + ['dum10', 'address', '192.0.2.1/30'])
- self.cli_set(intf_base + ['dum20', 'address', '192.0.2.5/30'])
-
- self.cli_set(base_path + ['interface', 'dum10'])
+ self.cli_set(base_path + ['ip-version', 'both'])
self.cli_set(base_path + ['interface', 'dum20'])
+ self.cli_set(base_path + ['interface', 'dum30'])
for domain in domains:
self.cli_set(base_path + ['browse-domain', domain])
@@ -65,10 +79,56 @@ class TestServiceMDNSrepeater(VyOSUnitTestSHIM.TestCase):
conf = ConfigParser(delimiters='=')
conf.read(config_file)
- self.assertEqual(conf['server']['allow-interfaces'], 'dum10, dum20')
+ self.assertEqual(conf['server']['use-ipv4'], 'yes')
+ self.assertEqual(conf['server']['use-ipv6'], 'yes')
+ self.assertEqual(conf['server']['allow-interfaces'], 'dum20, dum30')
self.assertEqual(conf['server']['browse-domains'], ', '.join(domains))
self.assertEqual(conf['reflector']['enable-reflector'], 'yes')
self.assertEqual(conf['reflector']['reflect-filters'], ', '.join(services))
+ def test_service_ipv4(self):
+ # partcipating interfaces should have IPv4 addresses
+ self.cli_set(base_path + ['ip-version', 'ipv4'])
+ self.cli_set(base_path + ['interface', 'dum10'])
+ self.cli_set(base_path + ['interface', 'dum40'])
+
+ # exception is raised if partcipating interfaces do not have IPv4 address
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+ self.cli_delete(base_path + ['interface', 'dum40'])
+ self.cli_set(base_path + ['interface', 'dum20'])
+ self.cli_commit()
+
+ # Validate configuration values
+ conf = ConfigParser(delimiters='=')
+ conf.read(config_file)
+
+ self.assertEqual(conf['server']['use-ipv4'], 'yes')
+ self.assertEqual(conf['server']['use-ipv6'], 'no')
+ self.assertEqual(conf['server']['allow-interfaces'], 'dum10, dum20')
+ self.assertEqual(conf['reflector']['enable-reflector'], 'yes')
+
+ def test_service_ipv6(self):
+ # partcipating interfaces should have IPv6 addresses
+ self.cli_set(base_path + ['ip-version', 'ipv6'])
+ self.cli_set(base_path + ['interface', 'dum10'])
+ self.cli_set(base_path + ['interface', 'dum30'])
+
+ # exception is raised if partcipating interfaces do not have IPv4 address
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+ self.cli_delete(base_path + ['interface', 'dum10'])
+ self.cli_set(base_path + ['interface', 'dum40'])
+ self.cli_commit()
+
+ # Validate configuration values
+ conf = ConfigParser(delimiters='=')
+ conf.read(config_file)
+
+ self.assertEqual(conf['server']['use-ipv4'], 'no')
+ self.assertEqual(conf['server']['use-ipv6'], 'yes')
+ self.assertEqual(conf['server']['allow-interfaces'], 'dum30, dum40')
+ self.assertEqual(conf['reflector']['enable-reflector'], 'yes')
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_system_conntrack.py b/smoketest/scripts/cli/test_system_conntrack.py
index 2a89aa98b..7657ab724 100755
--- a/smoketest/scripts/cli/test_system_conntrack.py
+++ b/smoketest/scripts/cli/test_system_conntrack.py
@@ -35,6 +35,17 @@ class TestSystemConntrack(VyOSUnitTestSHIM.TestCase):
self.cli_delete(base_path)
self.cli_commit()
+ def verify_nftables(self, nftables_search, table, inverse=False, args=''):
+ nftables_output = cmd(f'sudo nft {args} list table {table}')
+
+ for search in nftables_search:
+ matched = False
+ for line in nftables_output.split("\n"):
+ if all(item in line for item in search):
+ matched = True
+ break
+ self.assertTrue(not matched if inverse else matched, msg=search)
+
def test_conntrack_options(self):
conntrack_config = {
'net.netfilter.nf_conntrack_expect_max' : {
@@ -151,27 +162,34 @@ class TestSystemConntrack(VyOSUnitTestSHIM.TestCase):
def test_conntrack_module_enable(self):
# conntrack helper modules are disabled by default
modules = {
- 'ftp' : {
- 'driver' : ['nf_nat_ftp', 'nf_conntrack_ftp'],
+ 'ftp': {
+ 'driver': ['nf_nat_ftp', 'nf_conntrack_ftp'],
+ 'nftables': ['ct helper set "ftp_tcp"']
},
- 'h323' : {
- 'driver' : ['nf_nat_h323', 'nf_conntrack_h323'],
+ 'h323': {
+ 'driver': ['nf_nat_h323', 'nf_conntrack_h323'],
+ 'nftables': ['ct helper set "ras_udp"',
+ 'ct helper set "q931_tcp"']
},
- 'nfs' : {
- 'nftables' : ['ct helper set "rpc_tcp"',
- 'ct helper set "rpc_udp"']
+ 'nfs': {
+ 'nftables': ['ct helper set "rpc_tcp"',
+ 'ct helper set "rpc_udp"']
},
- 'pptp' : {
- 'driver' : ['nf_nat_pptp', 'nf_conntrack_pptp'],
+ 'pptp': {
+ 'driver': ['nf_nat_pptp', 'nf_conntrack_pptp'],
+ 'nftables': ['ct helper set "pptp_tcp"']
},
- 'sip' : {
- 'driver' : ['nf_nat_sip', 'nf_conntrack_sip'],
+ 'sip': {
+ 'driver': ['nf_nat_sip', 'nf_conntrack_sip'],
+ 'nftables': ['ct helper set "sip_tcp"',
+ 'ct helper set "sip_udp"']
},
- 'sqlnet' : {
- 'nftables' : ['ct helper set "tns_tcp"']
+ 'sqlnet': {
+ 'nftables': ['ct helper set "tns_tcp"']
},
- 'tftp' : {
- 'driver' : ['nf_nat_tftp', 'nf_conntrack_tftp'],
+ 'tftp': {
+ 'driver': ['nf_nat_tftp', 'nf_conntrack_tftp'],
+ 'nftables': ['ct helper set "tftp_udp"']
},
}
@@ -189,7 +207,7 @@ class TestSystemConntrack(VyOSUnitTestSHIM.TestCase):
self.assertTrue(os.path.isdir(f'/sys/module/{driver}'))
if 'nftables' in module_options:
for rule in module_options['nftables']:
- self.assertTrue(find_nftables_rule('raw', 'VYOS_CT_HELPER', [rule]) != None)
+ self.assertTrue(find_nftables_rule('ip vyos_conntrack', 'VYOS_CT_HELPER', [rule]) != None)
# unload modules
for module in modules:
@@ -205,7 +223,7 @@ class TestSystemConntrack(VyOSUnitTestSHIM.TestCase):
self.assertFalse(os.path.isdir(f'/sys/module/{driver}'))
if 'nftables' in module_options:
for rule in module_options['nftables']:
- self.assertTrue(find_nftables_rule('raw', 'VYOS_CT_HELPER', [rule]) == None)
+ self.assertTrue(find_nftables_rule('ip vyos_conntrack', 'VYOS_CT_HELPER', [rule]) == None)
def test_conntrack_hash_size(self):
hash_size = '65536'
@@ -232,5 +250,52 @@ class TestSystemConntrack(VyOSUnitTestSHIM.TestCase):
tmp = read_file('/etc/modprobe.d/vyatta_nf_conntrack.conf')
self.assertIn(hash_size_default, tmp)
+ def test_conntrack_ignore(self):
+ address_group = 'conntracktest'
+ address_group_member = '192.168.0.1'
+ ipv6_address_group = 'conntracktest6'
+ ipv6_address_group_member = 'dead:beef::1'
+
+ self.cli_set(['firewall', 'group', 'address-group', address_group, 'address', address_group_member])
+ self.cli_set(['firewall', 'group', 'ipv6-address-group', ipv6_address_group, 'address', ipv6_address_group_member])
+
+ self.cli_set(base_path + ['ignore', 'ipv4', 'rule', '1', 'source', 'address', '192.0.2.1'])
+ self.cli_set(base_path + ['ignore', 'ipv4', 'rule', '1', 'destination', 'address', '192.0.2.2'])
+ self.cli_set(base_path + ['ignore', 'ipv4', 'rule', '1', 'destination', 'port', '22'])
+ self.cli_set(base_path + ['ignore', 'ipv4', 'rule', '1', 'protocol', 'tcp'])
+ self.cli_set(base_path + ['ignore', 'ipv4', 'rule', '1', 'tcp', 'flags', 'syn'])
+
+ self.cli_set(base_path + ['ignore', 'ipv4', 'rule', '2', 'source', 'address', '192.0.2.1'])
+ self.cli_set(base_path + ['ignore', 'ipv4', 'rule', '2', 'destination', 'group', 'address-group', address_group])
+
+ self.cli_set(base_path + ['ignore', 'ipv6', 'rule', '11', 'source', 'address', 'fe80::1'])
+ self.cli_set(base_path + ['ignore', 'ipv6', 'rule', '11', 'destination', 'address', 'fe80::2'])
+ self.cli_set(base_path + ['ignore', 'ipv6', 'rule', '11', 'destination', 'port', '22'])
+ self.cli_set(base_path + ['ignore', 'ipv6', 'rule', '11', 'protocol', 'tcp'])
+
+ self.cli_set(base_path + ['ignore', 'ipv6', 'rule', '12', 'source', 'address', 'fe80::1'])
+ self.cli_set(base_path + ['ignore', 'ipv6', 'rule', '12', 'destination', 'group', 'address-group', ipv6_address_group])
+
+ self.cli_set(base_path + ['ignore', 'ipv6', 'rule', '13', 'source', 'address', 'fe80::1'])
+ self.cli_set(base_path + ['ignore', 'ipv6', 'rule', '13', 'destination', 'address', '!fe80::3'])
+
+ self.cli_commit()
+
+ nftables_search = [
+ ['ip saddr 192.0.2.1', 'ip daddr 192.0.2.2', 'tcp dport 22', 'tcp flags & syn == syn', 'notrack'],
+ ['ip saddr 192.0.2.1', 'ip daddr @A_conntracktest', 'notrack']
+ ]
+
+ nftables6_search = [
+ ['ip6 saddr fe80::1', 'ip6 daddr fe80::2', 'tcp dport 22', 'notrack'],
+ ['ip6 saddr fe80::1', 'ip6 daddr @A6_conntracktest6', 'notrack'],
+ ['ip6 saddr fe80::1', 'ip6 daddr != fe80::3', 'notrack']
+ ]
+
+ self.verify_nftables(nftables_search, 'ip vyos_conntrack')
+ self.verify_nftables(nftables6_search, 'ip6 vyos_conntrack')
+
+ self.cli_delete(['firewall'])
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_system_flow-accounting.py b/smoketest/scripts/cli/test_system_flow-accounting.py
index d55ea616e..6c761579b 100755
--- a/smoketest/scripts/cli/test_system_flow-accounting.py
+++ b/smoketest/scripts/cli/test_system_flow-accounting.py
@@ -67,7 +67,7 @@ class TestSystemFlowAccounting(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
# verify configuration
- nftables_output = cmd('sudo nft list chain raw VYOS_CT_PREROUTING_HOOK').splitlines()
+ nftables_output = cmd('sudo nft list chain raw VYOS_PREROUTING_HOOK').splitlines()
for interface in Section.interfaces('ethernet'):
rule_found = False
ifname_search = f'iifname "{interface}"'
diff --git a/smoketest/scripts/cli/test_vpn_ipsec.py b/smoketest/scripts/cli/test_vpn_ipsec.py
index 01b0406bf..17b1b395c 100755
--- a/smoketest/scripts/cli/test_vpn_ipsec.py
+++ b/smoketest/scripts/cli/test_vpn_ipsec.py
@@ -45,77 +45,62 @@ PROCESS_NAME = 'charon-systemd'
regex_uuid4 = '[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}'
ca_pem = """
-MIIDSzCCAjOgAwIBAgIUQHK+ZgTUYZksvXY2/MyW+Jiels4wDQYJKoZIhvcNAQEL
-BQAwFjEUMBIGA1UEAwwLRWFzeS1SU0EgQ0EwHhcNMjEwNjE0MTk0NTI3WhcNMzEw
-NjEyMTk0NTI3WjAWMRQwEgYDVQQDDAtFYXN5LVJTQSBDQTCCASIwDQYJKoZIhvcN
-AQEBBQADggEPADCCAQoCggEBAKCAzpatA8yywXhGunWD//6Qg9EMJMb+7didNr10
-DuYPPGyTOXwG4Xicbr0FJ6cNkWg4wj3ZXEqqBzgS1Z9u78yuYPt5LE9eM8Wtawp7
-qIUCMTlSu4uD3/4A3c1xfHDpTOEl1BDvxMtQxQZcMNQVUG5ZMdcWQvqvQG6F7Nak
-+jgkaQ+Gyhwq++KVTEHJsA6+POuD0uaqAJv3tLGrRf4y4zdOn4thuTQ9swIBjKW6
-ci78Dk0F4u24YYV2BHKsPEPIyCQxKSRrMvqVWWljX9HmNsGawyEhLvW34aphj0aD
-JL/n1kWm+DnGyM+Rp6pXQz5y3xAnmKeYziaQNnvHoQi+gY0CAwEAAaOBkDCBjTAd
-BgNVHQ4EFgQUy43jkjE+CORrxeddqofQztZ9UxYwUQYDVR0jBEowSIAUy43jkjE+
-CORrxeddqofQztZ9UxahGqQYMBYxFDASBgNVBAMMC0Vhc3ktUlNBIENBghRAcr5m
-BNRhmSy9djb8zJb4mJ6WzjAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkq
-hkiG9w0BAQsFAAOCAQEALHdd1JXq6EUF9dSUijPLEiDVwn2TTIBIxvQqFzpWDDHg
-EWLzRJESyNUbIiwuUGwvqcVki0TmQcFR9XwmcDFDotlXz9OQISBlCW+Twuf4/XAL
-11njH8qXSaWF/wPbF35NOPhV5xOOCZ6K7Vilp3tK6LeOWvz2AUtwiVE1prNV3cIA
-B2ham0JASS0HIkfrcjpZNcx4NlSBaFf4MK5A11p13zPqMqzdEqn6n8fbYEADfVzy
-TfdqX1dPVc9zaM8uwyh5VyYBMDV7DoL384ZHJZYLENK/pT4kbl+sM/Cnhvyu0UCe
-RVqJGQtCdChZpDAVkzJRQYw3/FR8Mj+M+8GrgOrJ0w==
+MIICMDCCAdegAwIBAgIUBCzIjYvD7SPbx5oU18IYg7NVxQ0wCgYIKoZIzj0EAwIw
+ZzELMAkGA1UEBhMCR0IxEzARBgNVBAgMClNvbWUtU3RhdGUxEjAQBgNVBAcMCVNv
+bWUtQ2l0eTENMAsGA1UECgwEVnlPUzEgMB4GA1UEAwwXSVBTZWMgU21va2V0ZXN0
+IFJvb3QgQ0EwHhcNMjMwOTI0MTIwMzQxWhcNMzMwOTIxMTIwMzQxWjBnMQswCQYD
+VQQGEwJHQjETMBEGA1UECAwKU29tZS1TdGF0ZTESMBAGA1UEBwwJU29tZS1DaXR5
+MQ0wCwYDVQQKDARWeU9TMSAwHgYDVQQDDBdJUFNlYyBTbW9rZXRlc3QgUm9vdCBD
+QTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABEh8/yU572B3zmFxrGgHk+H7grYt
+EHUJodY3gXNWMHz0gySrbGhsGtECDfP/G+T4Suk7cuVzB1wnLocSafD8TcqjYTBf
+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsG
+AQUFBwMCBggrBgEFBQcDATAdBgNVHQ4EFgQUTYoQJNlk7X87/gRegHnCnPef39Aw
+CgYIKoZIzj0EAwIDRwAwRAIgX1spXjrUc10r3g/Zm4O31LU5O08J2vVqFo94zHE5
+0VgCIG4JK9Zg5O/yn4mYksZux7efiHRUzL2y2TXQ9IqrqM8W
+"""
+
+int_ca_pem = """
+MIICYDCCAgWgAwIBAgIUcFx2BVYErHI+SneyPYHijxXt1cgwCgYIKoZIzj0EAwIw
+ZzELMAkGA1UEBhMCR0IxEzARBgNVBAgMClNvbWUtU3RhdGUxEjAQBgNVBAcMCVNv
+bWUtQ2l0eTENMAsGA1UECgwEVnlPUzEgMB4GA1UEAwwXSVBTZWMgU21va2V0ZXN0
+IFJvb3QgQ0EwHhcNMjMwOTI0MTIwNTE5WhcNMzMwOTIwMTIwNTE5WjBvMQswCQYD
+VQQGEwJHQjETMBEGA1UECAwKU29tZS1TdGF0ZTESMBAGA1UEBwwJU29tZS1DaXR5
+MQ0wCwYDVQQKDARWeU9TMSgwJgYDVQQDDB9JUFNlYyBTbW9rZXRlc3QgSW50ZXJt
+ZWRpYXRlIENBMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIHw2G5dq3c715AcA
+tzR++dYu1fLRFmHzRGTZOT7hLrh2Fg4hnKFPLOeUA5Qi50xCvjJ9JnonTyy2RfRH
+axYizKOBhjCBgzASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjAd
+BgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwHQYDVR0OBBYEFC9KrFYtA+hO
+l7vdMbWxTMAyLB7BMB8GA1UdIwQYMBaAFE2KECTZZO1/O/4EXoB5wpz3n9/QMAoG
+CCqGSM49BAMCA0kAMEYCIQCnqWbElgOL9dGO3iLxasFNq/hM7vM/DzaiHi4BowxW
+0gIhAMohefNj+QgLfPhvyODHIPE9LMyfp7lJEaCC2K8PCSFD
"""
peer_cert = """
-MIIDZjCCAk6gAwIBAgIRAKHpoE0rTcB/YXhnFpeckngwDQYJKoZIhvcNAQELBQAw
-FjEUMBIGA1UEAwwLRWFzeS1SU0EgQ0EwHhcNMjEwNjE0MjAwNDQ3WhcNMjQwNTI5
-MjAwNDQ3WjAQMQ4wDAYDVQQDDAVwZWVyMTCCASIwDQYJKoZIhvcNAQEBBQADggEP
-ADCCAQoCggEBALNwjDC1Lj2ojfCi1TESsyD0MLuqUVLTBZaXCXFtQdB/Aw3b3eBc
-J8+FUYQ6xMplmklXcjJEyXSMvqENpLX6xEDNWWvqTf22eEWt36QTfBeyFyDKtXnm
-4Y+ufXAHl3sLtyZN/7q+Xl4ubYvtAHVRLYzkXAtj1tVdaYEZQy8x/F3ZFFUsCfxR
-RqJBKTxcENP8STpIz9X8dS9iif9SBA42C0eHqMWv1tYW1IHO9gQxYFS3cvoPDPlD
-AJ3ihu5x3fO892S7FtZLVN/GsN1TKRKL217eVPyW0+QcnUwbrXWc7fnmm1btXVmh
-9YKPdtX8WnEeOtMCVZGKqdydnI3iAqvPmd0CAwEAAaOBtDCBsTAJBgNVHRMEAjAA
-MB0GA1UdDgQWBBQGsAPY4cHnTNUv7l+l8OYRSqcX8jBRBgNVHSMESjBIgBTLjeOS
-MT4I5GvF512qh9DO1n1TFqEapBgwFjEUMBIGA1UEAwwLRWFzeS1SU0EgQ0GCFEBy
-vmYE1GGZLL12NvzMlviYnpbOMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAsGA1UdDwQE
-AwIFoDAQBgNVHREECTAHggVwZWVyMTANBgkqhkiG9w0BAQsFAAOCAQEAdJr+11eG
-FvChxu/LkwsXe2V+OZzGRq+hmQlaK3kG/AyI5hVA/IVHJkDe281wbBNKBWYxeSMn
-lAKbwuhPluO99oldzY9ZVkSiRmLh3r27wy/y+1plvoNxyTN7644Hvtk/8P/LV67R
-amXvVgkhpvIQSBfgifXzqUs+BV/x7TSeN3isxNOB8FP6imODsw8lF0Ir1Ze34emr
-TMNo5wNR5xp2dUa9OkzjRpgpifh20zM3UeVOixIPoq78IDjT0aZP8Lve2/g4Ccc6
-RHNF31r/2UL8rZfQRUAMijVdAvIINCk0kRBhNcr9MCi3czmmgiXXMGwLWLvSkfnE
-W06wKX1lpPSptg==
+MIICSTCCAfCgAwIBAgIUPxYleUgCo/glVVePze3QmAFgi6MwCgYIKoZIzj0EAwIw
+bzELMAkGA1UEBhMCR0IxEzARBgNVBAgMClNvbWUtU3RhdGUxEjAQBgNVBAcMCVNv
+bWUtQ2l0eTENMAsGA1UECgwEVnlPUzEoMCYGA1UEAwwfSVBTZWMgU21va2V0ZXN0
+IEludGVybWVkaWF0ZSBDQTAeFw0yMzA5MjQxMjA2NDJaFw0yODA5MjIxMjA2NDJa
+MGQxCzAJBgNVBAYTAkdCMRMwEQYDVQQIDApTb21lLVN0YXRlMRIwEAYDVQQHDAlT
+b21lLUNpdHkxDTALBgNVBAoMBFZ5T1MxHTAbBgNVBAMMFElQU2VjIFNtb2tldGVz
+dCBQZWVyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEZJtuTDu84uy++GMwRNLl
+10JAXZxXQSDl+CdTWwjbQZURcdY+ia7BoaoYX/0VKPel3Se64rIUQQLQoY/9MJb9
+UKN1MHMwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
+KwYBBQUHAwEwHQYDVR0OBBYEFNJCdnkm3cAmf04UwOKL7IqMJ6OXMB8GA1UdIwQY
+MBaAFC9KrFYtA+hOl7vdMbWxTMAyLB7BMAoGCCqGSM49BAMCA0cAMEQCIGVnDRUy
+UJ0U/deDvrBo1+AakZndkNAMN/XNo5a5GzhEAiBCY7E/3b0BIO8FiIbVB3iDcaxg
+g7ET2RgWxvhEoN3ZRw==
"""
peer_key = """
-MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCzcIwwtS49qI3w
-otUxErMg9DC7qlFS0wWWlwlxbUHQfwMN293gXCfPhVGEOsTKZZpJV3IyRMl0jL6h
-DaS1+sRAzVlr6k39tnhFrd+kE3wXshcgyrV55uGPrn1wB5d7C7cmTf+6vl5eLm2L
-7QB1US2M5FwLY9bVXWmBGUMvMfxd2RRVLAn8UUaiQSk8XBDT/Ek6SM/V/HUvYon/
-UgQONgtHh6jFr9bWFtSBzvYEMWBUt3L6Dwz5QwCd4obucd3zvPdkuxbWS1TfxrDd
-UykSi9te3lT8ltPkHJ1MG611nO355ptW7V1ZofWCj3bV/FpxHjrTAlWRiqncnZyN
-4gKrz5ndAgMBAAECggEACvAya4mv3uxWcrPKYSptpvWbvuTb/juE3LAqUDLDz0ze
-x8p+VP3pI1pSJMhcVKYq6IufF3df/G3T9Qda4gj+S6D48X4f8PZdkInP1zWk2+Ds
-TgBtXZf4agTN+rVLw6FsMbaRfzW5lO4pmV0CKSSgrTUCc2NLpkgCdW8vzEG0y5ek
-15uBOyvuydWM4CFgZT/cUvnu4UtPFL1vaTdD4Lw0FfZq4iS8SWsGbbMoTPKkJRlS
-k9oMEOvhA1WIfSgiG0FyaidoNEormB6J1SKVo27P8SOYu2etiFdF9SJUYg9cBzM3
-z3HcAsXeSh2kpc8Fc2yOS6zI5AsC0Len2SQmKQD8YQKBgQDlgg5cZV5AY2Ji6b+T
-nTHjna7dg/kzUOYs0AmK9DHHziZJ2SKucJlB9smynPLjY/MQbKcNWQ1Cad+olDNP
-Ts4lLhs4kbITkmgPQME3it1fGstHy/sGcF0m+YRsSxfwt5bxLXH86+d067C0XMhg
-URMgGv9ZBTe/P1LuhIUTEjYzlQKBgQDIJvl7sSXHRRB0k7NU/uV3Tut3NTqIzXiz
-pq9hMyF+3aIqaA7kdjIIJczv1grVYz+RUdX3Gu1FyHMl8ynoEz5NNWsbe+Ay/moa
-ztijak3UH3M+d6WsxSRehdYl6DaMstHwWfKZvWNJCGyl7ckz9gGjc3DY/qYqZDrx
-p3LlZsY7KQKBgQCj3ur2GgLkIpI7Yf9CHPlkNlCHJhYnB9pxoNFPf/CTY6R/EiTr
-PMaRDO8TM3FR3ynMTmgw5abMBuCFc9v3AqO6dGNHTvBBfUYDrg7H48UQhQckaocA
-H/bDP2HIGQ4s+Ek0R2ieWKpZF3iCL8V60CjBwcUVAN6/FS3X1JNX/KbqyQKBgQDA
-8dlk5PN/MlPXnZ6t2/7G0bxpsVVZFYI65P+CGvE6RFuUt7VLhalbc10pAtR0unVI
-GHTD/iAnOkHOnqeSQiK3+TvkRbluTxVn/GiYt9yJFTxaRqrebzlNKYW0CzOy1JtP
-MNaOYCS6/bUHC7//KDKSJ7HsbScwDGlKFVrMTBPiaQKBgQCjkIJDZ4pC3er7QiC3
-RXWPyxIG5iTjn4fizphaBt6+pkBAlBh0V6inmleAWa5DJSpgU4jQv4mZsAQs6ctq
-usmoy47ke8pTXPHgQ8ZUwsfM4IztqOm+w0X6mSZi6HdJCnMdxCZBBpO225UvonSR
-rgiyCHemtMepq57Pl1Nmj49eEA==
+MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgVDEZDK7q/T+tiJUV
+WLKS3ZYDfZ4lZv0C1gJpYq0gWP2hRANCAARkm25MO7zi7L74YzBE0uXXQkBdnFdB
+IOX4J1NbCNtBlRFx1j6JrsGhqhhf/RUo96XdJ7rishRBAtChj/0wlv1Q
"""
+swanctl_dir = '/etc/swanctl'
+CERT_PATH = f'{swanctl_dir}/x509/'
+CA_PATH = f'{swanctl_dir}/x509ca/'
+
class TestVPNIPsec(VyOSUnitTestSHIM.TestCase):
skip_process_check = False
@@ -400,7 +385,9 @@ class TestVPNIPsec(VyOSUnitTestSHIM.TestCase):
# Enable PKI
peer_name = 'peer1'
ca_name = 'MyVyOS-CA'
+ int_ca_name = 'MyVyOS-IntCA'
self.cli_set(['pki', 'ca', ca_name, 'certificate', ca_pem.replace('\n','')])
+ self.cli_set(['pki', 'ca', int_ca_name, 'certificate', int_ca_pem.replace('\n','')])
self.cli_set(['pki', 'certificate', peer_name, 'certificate', peer_cert.replace('\n','')])
self.cli_set(['pki', 'certificate', peer_name, 'private', 'key', peer_key.replace('\n','')])
@@ -415,7 +402,7 @@ class TestVPNIPsec(VyOSUnitTestSHIM.TestCase):
self.cli_set(peer_base_path + ['authentication', 'local-id', peer_name])
self.cli_set(peer_base_path + ['authentication', 'mode', 'x509'])
self.cli_set(peer_base_path + ['authentication', 'remote-id', 'peer2'])
- self.cli_set(peer_base_path + ['authentication', 'x509', 'ca-certificate', ca_name])
+ self.cli_set(peer_base_path + ['authentication', 'x509', 'ca-certificate', int_ca_name])
self.cli_set(peer_base_path + ['authentication', 'x509', 'certificate', peer_name])
self.cli_set(peer_base_path + ['connection-type', 'initiate'])
self.cli_set(peer_base_path + ['ike-group', ike_group])
@@ -466,6 +453,11 @@ class TestVPNIPsec(VyOSUnitTestSHIM.TestCase):
for line in swanctl_secrets_lines:
self.assertIn(line, swanctl_conf)
+ # Check Root CA, Intermediate CA and Peer cert/key pair is present
+ self.assertTrue(os.path.exists(os.path.join(CA_PATH, f'{int_ca_name}_1.pem')))
+ self.assertTrue(os.path.exists(os.path.join(CA_PATH, f'{int_ca_name}_2.pem')))
+ self.assertTrue(os.path.exists(os.path.join(CERT_PATH, f'{peer_name}.pem')))
+
# There is only one VTI test so no need to delete this globally in tearDown()
self.cli_delete(vti_path)
diff --git a/smoketest/scripts/system/test_kernel_options.py b/smoketest/scripts/system/test_kernel_options.py
index a39ae50bc..0e3cbd0ed 100755
--- a/smoketest/scripts/system/test_kernel_options.py
+++ b/smoketest/scripts/system/test_kernel_options.py
@@ -76,7 +76,6 @@ class TestKernelModules(unittest.TestCase):
self.assertTrue(tmp)
def test_qemu_support(self):
- # The bond/lacp interface must be enabled in the OS Kernel
for option in ['CONFIG_VIRTIO_BLK', 'CONFIG_SCSI_VIRTIO',
'CONFIG_VIRTIO_NET', 'CONFIG_VIRTIO_CONSOLE',
'CONFIG_VIRTIO', 'CONFIG_VIRTIO_PCI',
@@ -86,11 +85,14 @@ class TestKernelModules(unittest.TestCase):
self.assertTrue(tmp)
def test_vmware_support(self):
- # The bond/lacp interface must be enabled in the OS Kernel
for option in ['CONFIG_VMXNET3']:
tmp = re.findall(f'{option}=(y|m)', config)
self.assertTrue(tmp)
+ def test_container_cgroup_support(self):
+ for option in ['CONFIG_CGROUPS', 'CONFIG_MEMCG', 'CONFIG_CGROUP_PIDS', 'CONFIG_CGROUP_BPF']:
+ tmp = re.findall(f'{option}=(y|m)', config)
+ self.assertTrue(tmp)
if __name__ == '__main__':
unittest.main(verbosity=2)