summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/templates/frr/static_mcast.frr.j29
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_static_multicast.py49
-rwxr-xr-xsrc/conf_mode/interfaces_l2tpv3.py3
-rwxr-xr-xsrc/conf_mode/interfaces_wireguard.py6
-rwxr-xr-xsrc/conf_mode/interfaces_wireless.py3
-rwxr-xr-xsrc/conf_mode/nat.py3
-rwxr-xr-xsrc/conf_mode/nat64.py18
-rwxr-xr-xsrc/conf_mode/nat66.py3
-rwxr-xr-xsrc/conf_mode/protocols_static_multicast.py27
-rwxr-xr-xsrc/conf_mode/system_acceleration.py3
-rwxr-xr-xsrc/conf_mode/system_console.py1
-rwxr-xr-xsrc/op_mode/generate_ovpn_client_file.py6
-rw-r--r--src/tests/test_configd_inspect.py3
13 files changed, 102 insertions, 32 deletions
diff --git a/data/templates/frr/static_mcast.frr.j2 b/data/templates/frr/static_mcast.frr.j2
index 491d4b54a..54b2790b0 100644
--- a/data/templates/frr/static_mcast.frr.j2
+++ b/data/templates/frr/static_mcast.frr.j2
@@ -1,13 +1,4 @@
!
-{% for route_gr in old_mroute %}
-{% for nh in old_mroute[route_gr] %}
-{% if old_mroute[route_gr][nh] %}
-no ip mroute {{ route_gr }} {{ nh }} {{ old_mroute[route_gr][nh] }}
-{% else %}
-no ip mroute {{ route_gr }} {{ nh }}
-{% endif %}
-{% endfor %}
-{% endfor %}
{% for route_gr in mroute %}
{% for nh in mroute[route_gr] %}
{% if mroute[route_gr][nh] %}
diff --git a/smoketest/scripts/cli/test_protocols_static_multicast.py b/smoketest/scripts/cli/test_protocols_static_multicast.py
new file mode 100755
index 000000000..9fdda236f
--- /dev/null
+++ b/smoketest/scripts/cli/test_protocols_static_multicast.py
@@ -0,0 +1,49 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2024 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
+
+
+base_path = ['protocols', 'static', 'multicast']
+
+
+class TestProtocolsStaticMulticast(VyOSUnitTestSHIM.TestCase):
+
+ def tearDown(self):
+ self.cli_delete(base_path)
+ self.cli_commit()
+
+ mroute = self.getFRRconfig('ip mroute', end='')
+ self.assertFalse(mroute)
+
+ def test_01_static_multicast(self):
+
+ self.cli_set(base_path + ['route', '224.202.0.0/24', 'next-hop', '224.203.0.1'])
+ self.cli_set(base_path + ['interface-route', '224.203.0.0/24', 'next-hop-interface', 'eth0'])
+
+ self.cli_commit()
+
+ # Verify FRR bgpd configuration
+ frrconfig = self.getFRRconfig('ip mroute', end='')
+
+ self.assertIn('ip mroute 224.202.0.0/24 224.203.0.1', frrconfig)
+ self.assertIn('ip mroute 224.203.0.0/24 eth0', frrconfig)
+
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2)
diff --git a/src/conf_mode/interfaces_l2tpv3.py b/src/conf_mode/interfaces_l2tpv3.py
index b9f827bee..f0a70436e 100755
--- a/src/conf_mode/interfaces_l2tpv3.py
+++ b/src/conf_mode/interfaces_l2tpv3.py
@@ -86,6 +86,8 @@ def generate(l2tpv3):
return None
def apply(l2tpv3):
+ check_kmod(k_mod)
+
# Check if L2TPv3 interface already exists
if interface_exists(l2tpv3['ifname']):
# L2TPv3 is picky when changing tunnels/sessions, thus we can simply
@@ -102,7 +104,6 @@ def apply(l2tpv3):
if __name__ == '__main__':
try:
- check_kmod(k_mod)
c = get_config()
verify(c)
generate(c)
diff --git a/src/conf_mode/interfaces_wireguard.py b/src/conf_mode/interfaces_wireguard.py
index 0e0b77877..7abdfdbfa 100755
--- a/src/conf_mode/interfaces_wireguard.py
+++ b/src/conf_mode/interfaces_wireguard.py
@@ -103,7 +103,12 @@ def verify(wireguard):
public_keys.append(peer['public_key'])
+def generate(wireguard):
+ return None
+
def apply(wireguard):
+ check_kmod('wireguard')
+
if 'rebuild_required' in wireguard or 'deleted' in wireguard:
wg = WireGuardIf(**wireguard)
# WireGuard only supports peer removal based on the configured public-key,
@@ -123,7 +128,6 @@ def apply(wireguard):
if __name__ == '__main__':
try:
- check_kmod('wireguard')
c = get_config()
verify(c)
apply(c)
diff --git a/src/conf_mode/interfaces_wireless.py b/src/conf_mode/interfaces_wireless.py
index f35a250cb..d24675ee6 100755
--- a/src/conf_mode/interfaces_wireless.py
+++ b/src/conf_mode/interfaces_wireless.py
@@ -239,6 +239,8 @@ def verify(wifi):
return None
def generate(wifi):
+ check_kmod('mac80211')
+
interface = wifi['ifname']
# Delete config files if interface is removed
@@ -333,7 +335,6 @@ def apply(wifi):
if __name__ == '__main__':
try:
- check_kmod('mac80211')
c = get_config()
verify(c)
generate(c)
diff --git a/src/conf_mode/nat.py b/src/conf_mode/nat.py
index f74bb217e..39803fa02 100755
--- a/src/conf_mode/nat.py
+++ b/src/conf_mode/nat.py
@@ -240,6 +240,8 @@ def generate(nat):
return None
def apply(nat):
+ check_kmod(k_mod)
+
cmd(f'nft --file {nftables_nat_config}')
cmd(f'nft --file {nftables_static_nat_conf}')
@@ -253,7 +255,6 @@ def apply(nat):
if __name__ == '__main__':
try:
- check_kmod(k_mod)
c = get_config()
verify(c)
generate(c)
diff --git a/src/conf_mode/nat64.py b/src/conf_mode/nat64.py
index 32a1c47d1..df501ce7f 100755
--- a/src/conf_mode/nat64.py
+++ b/src/conf_mode/nat64.py
@@ -46,7 +46,12 @@ def get_config(config: Config | None = None) -> None:
base = ["nat64"]
nat64 = config.get_config_dict(base, key_mangling=("-", "_"), get_first_key=True)
- base_src = base + ["source", "rule"]
+ return nat64
+
+
+def verify(nat64) -> None:
+ check_kmod(["jool"])
+ base_src = ["nat64", "source", "rule"]
# Load in existing instances so we can destroy any unknown
lines = cmd("jool instance display --csv").splitlines()
@@ -76,12 +81,8 @@ def get_config(config: Config | None = None) -> None:
):
rules[num]["recreate"] = True
- return nat64
-
-
-def verify(nat64) -> None:
if not nat64:
- # no need to verify the CLI as nat64 is going to be deactivated
+ # nothing left to do
return
if dict_search("source.rule", nat64):
@@ -128,6 +129,9 @@ def verify(nat64) -> None:
def generate(nat64) -> None:
+ if not nat64:
+ return
+
os.makedirs(JOOL_CONFIG_DIR, exist_ok=True)
if dict_search("source.rule", nat64):
@@ -184,6 +188,7 @@ def generate(nat64) -> None:
def apply(nat64) -> None:
if not nat64:
+ unload_kmod(['jool'])
return
if dict_search("source.rule", nat64):
@@ -211,7 +216,6 @@ def apply(nat64) -> None:
if __name__ == "__main__":
try:
- check_kmod(["jool"])
c = get_config()
verify(c)
generate(c)
diff --git a/src/conf_mode/nat66.py b/src/conf_mode/nat66.py
index 075738dad..c44320f36 100755
--- a/src/conf_mode/nat66.py
+++ b/src/conf_mode/nat66.py
@@ -112,6 +112,8 @@ def apply(nat):
if not nat:
return None
+ check_kmod(k_mod)
+
cmd(f'nft --file {nftables_nat66_config}')
call_dependents()
@@ -119,7 +121,6 @@ def apply(nat):
if __name__ == '__main__':
try:
- check_kmod(k_mod)
c = get_config()
verify(c)
generate(c)
diff --git a/src/conf_mode/protocols_static_multicast.py b/src/conf_mode/protocols_static_multicast.py
index 7f6ae3680..2bf794042 100755
--- a/src/conf_mode/protocols_static_multicast.py
+++ b/src/conf_mode/protocols_static_multicast.py
@@ -20,9 +20,10 @@ from ipaddress import IPv4Address
from sys import exit
from vyos import ConfigError
+from vyos import frr
from vyos.config import Config
from vyos.utils.process import call
-from vyos.template import render
+from vyos.template import render, render_to_string
from vyos import airbag
airbag.enable()
@@ -92,23 +93,39 @@ def verify(mroute):
if IPv4Address(route[0]) < IPv4Address('224.0.0.0'):
raise ConfigError(route + " not a multicast network")
+
def generate(mroute):
if mroute is None:
return None
- render(config_file, 'frr/static_mcast.frr.j2', mroute)
+ mroute['new_frr_config'] = render_to_string('frr/static_mcast.frr.j2', mroute)
return None
+
def apply(mroute):
if mroute is None:
return None
+ static_daemon = 'staticd'
+
+ frr_cfg = frr.FRRConfig()
+ frr_cfg.load_configuration(static_daemon)
- if os.path.exists(config_file):
- call(f'vtysh -d staticd -f {config_file}')
- os.remove(config_file)
+ if 'old_mroute' in mroute:
+ for route_gr in mroute['old_mroute']:
+ for nh in mroute['old_mroute'][route_gr]:
+ if mroute['old_mroute'][route_gr][nh]:
+ frr_cfg.modify_section(f'^ip mroute {route_gr} {nh} {mroute["old_mroute"][route_gr][nh]}')
+ else:
+ frr_cfg.modify_section(f'^ip mroute {route_gr} {nh}')
+
+ if 'new_frr_config' in mroute:
+ frr_cfg.add_before(frr.default_add_before, mroute['new_frr_config'])
+
+ frr_cfg.commit_configuration(static_daemon)
return None
+
if __name__ == '__main__':
try:
c = get_config()
diff --git a/src/conf_mode/system_acceleration.py b/src/conf_mode/system_acceleration.py
index e4b248675..d2cf44ff0 100755
--- a/src/conf_mode/system_acceleration.py
+++ b/src/conf_mode/system_acceleration.py
@@ -79,6 +79,9 @@ def verify(qat):
if not data:
raise ConfigError('No QAT acceleration device found')
+def generate(qat):
+ return
+
def apply(qat):
# Shutdown VPN service which can use QAT
if 'ipsec' in qat:
diff --git a/src/conf_mode/system_console.py b/src/conf_mode/system_console.py
index 27bf92e0b..b380e0521 100755
--- a/src/conf_mode/system_console.py
+++ b/src/conf_mode/system_console.py
@@ -22,7 +22,6 @@ from vyos.utils.process import call
from vyos.utils.serial import restart_login_consoles
from vyos.system import grub_util
from vyos.template import render
-from vyos.defaults import directories
from vyos import ConfigError
from vyos import airbag
airbag.enable()
diff --git a/src/op_mode/generate_ovpn_client_file.py b/src/op_mode/generate_ovpn_client_file.py
index 974f7d9b6..1d2f1067a 100755
--- a/src/op_mode/generate_ovpn_client_file.py
+++ b/src/op_mode/generate_ovpn_client_file.py
@@ -51,12 +51,12 @@ verb 3
} %}
{% if encryption is defined and encryption is not none %}
-{% if encryption.ncp_ciphers is defined and encryption.ncp_ciphers is not none %}
-cipher {% for algo in encryption.ncp_ciphers %}
+{% if encryption.data_ciphers is defined and encryption.data_ciphers is not none %}
+cipher {% for algo in encryption.data_ciphers %}
{{ encryption_map[algo] if algo in encryption_map.keys() else algo }}{% if not loop.last %}:{% endif %}
{% endfor %}
-data-ciphers {% for algo in encryption.ncp_ciphers %}
+data-ciphers {% for algo in encryption.data_ciphers %}
{{ encryption_map[algo] if algo in encryption_map.keys() else algo }}{% if not loop.last %}:{% endif %}
{% endfor %}
{% endif %}
diff --git a/src/tests/test_configd_inspect.py b/src/tests/test_configd_inspect.py
index 98552c8f3..ccd631893 100644
--- a/src/tests/test_configd_inspect.py
+++ b/src/tests/test_configd_inspect.py
@@ -56,8 +56,7 @@ class TestConfigdInspect(TestCase):
m = import_script(s)
for i in f_list:
f = getattr(m, i, None)
- if not f:
- continue
+ self.assertIsNotNone(f, f"'{s}': missing function '{i}'")
sig = signature(f)
par = sig.parameters
l = len(par)