summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Breunig <christian@breunig.cc>2023-07-26 23:14:19 +0200
committerChristian Breunig <christian@breunig.cc>2023-07-26 23:14:19 +0200
commitfa07179ae7f1dc07e6ccc1b20d2b81384b6efe07 (patch)
tree3dcfa310f073d902133412bfb177ce88a5bdf1b7
parent9e0a9b7df3d7187173feaf922fedbac8f0f0b674 (diff)
downloadvyos-1x-fa07179ae7f1dc07e6ccc1b20d2b81384b6efe07.tar.gz
vyos-1x-fa07179ae7f1dc07e6ccc1b20d2b81384b6efe07.zip
openvpn: T4974: dynamically load/unload kernel module
-rw-r--r--python/vyos/utils/kernel.py11
-rwxr-xr-xsrc/conf_mode/interfaces-openvpn.py11
2 files changed, 22 insertions, 0 deletions
diff --git a/python/vyos/utils/kernel.py b/python/vyos/utils/kernel.py
index 0eb113174..1f3bbdffe 100644
--- a/python/vyos/utils/kernel.py
+++ b/python/vyos/utils/kernel.py
@@ -25,3 +25,14 @@ def check_kmod(k_mod):
if not os.path.exists(f'/sys/module/{module}'):
if call(f'modprobe {module}') != 0:
raise ConfigError(f'Loading Kernel module {module} failed')
+
+def unload_kmod(k_mod):
+ """ Common utility function to unload required kernel modules on demand """
+ from vyos import ConfigError
+ from vyos.utils.process import call
+ if isinstance(k_mod, str):
+ k_mod = k_mod.split()
+ for module in k_mod:
+ if os.path.exists(f'/sys/module/{module}'):
+ if call(f'rmmod {module}') != 0:
+ raise ConfigError(f'Unloading Kernel module {module} failed')
diff --git a/src/conf_mode/interfaces-openvpn.py b/src/conf_mode/interfaces-openvpn.py
index 607a19385..2e4bea377 100755
--- a/src/conf_mode/interfaces-openvpn.py
+++ b/src/conf_mode/interfaces-openvpn.py
@@ -56,6 +56,8 @@ from vyos.utils.list import is_list_equal
from vyos.utils.file import makedir
from vyos.utils.file import read_file
from vyos.utils.file import write_file
+from vyos.utils.kernel import check_kmod
+from vyos.utils.kernel import unload_kmod
from vyos.utils.process import call
from vyos.utils.permission import chown
from vyos.utils.process import cmd
@@ -95,6 +97,8 @@ def get_config(config=None):
openvpn['pki'] = tmp_pki
if is_node_changed(conf, base + [ifname, 'openvpn-option']):
openvpn.update({'restart_required': {}})
+ if is_node_changed(conf, base + [ifname, 'enable-dco']):
+ openvpn.update({'restart_required': {}})
# We have to get the dict using 'get_config_dict' instead of 'get_interface_dict'
# as 'get_interface_dict' merges the defaults in, so we can not check for defaults in there.
@@ -679,6 +683,13 @@ def apply(openvpn):
if not is_addr_assigned(openvpn['local_host']):
cmd('sysctl -w net.ipv4.ip_nonlocal_bind=1')
+ # dynamically load/unload DCO Kernel extension if requested
+ dco_module = 'ovpn_dco_v2'
+ if 'enable_dco' in openvpn:
+ check_kmod(dco_module)
+ else:
+ unload_kmod(dco_module)
+
# No matching OpenVPN process running - maybe it got killed or none
# existed - nevertheless, spawn new OpenVPN process
action = 'reload-or-restart'