summaryrefslogtreecommitdiff
path: root/src/conf_mode
diff options
context:
space:
mode:
Diffstat (limited to 'src/conf_mode')
-rwxr-xr-xsrc/conf_mode/firewall.py9
-rwxr-xr-xsrc/conf_mode/interfaces_ethernet.py20
-rwxr-xr-xsrc/conf_mode/load-balancing_reverse-proxy.py38
-rwxr-xr-xsrc/conf_mode/nat.py8
-rwxr-xr-xsrc/conf_mode/nat66.py6
-rwxr-xr-xsrc/conf_mode/policy_route.py4
-rwxr-xr-xsrc/conf_mode/protocols_nhrp.py4
-rwxr-xr-xsrc/conf_mode/service_https.py39
-rwxr-xr-xsrc/conf_mode/system_conntrack.py7
-rwxr-xr-xsrc/conf_mode/vpn_openconnect.py52
-rwxr-xr-xsrc/conf_mode/vpn_sstp.py65
-rwxr-xr-xsrc/conf_mode/vrf.py11
12 files changed, 92 insertions, 171 deletions
diff --git a/src/conf_mode/firewall.py b/src/conf_mode/firewall.py
index 810437dda..3cf618363 100755
--- a/src/conf_mode/firewall.py
+++ b/src/conf_mode/firewall.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2023 VyOS maintainers and contributors
+# Copyright (C) 2021-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
@@ -18,7 +18,6 @@ import os
import re
from glob import glob
-from json import loads
from sys import exit
from vyos.base import Warning
@@ -31,11 +30,9 @@ from vyos.ethtool import Ethtool
from vyos.firewall import fqdn_config_parse
from vyos.firewall import geoip_update
from vyos.template import render
-from vyos.utils.process import call
-from vyos.utils.process import cmd
from vyos.utils.dict import dict_search_args
from vyos.utils.dict import dict_search_recursive
-from vyos.utils.process import process_named_running
+from vyos.utils.process import call
from vyos.utils.process import rc_cmd
from vyos import ConfigError
from vyos import airbag
@@ -491,7 +488,7 @@ def apply_sysfs(firewall):
f.write(value)
def apply(firewall):
- install_result, output = rc_cmd(f'nft -f {nftables_conf}')
+ install_result, output = rc_cmd(f'nft --file {nftables_conf}')
if install_result == 1:
raise ConfigError(f'Failed to apply firewall: {output}')
diff --git a/src/conf_mode/interfaces_ethernet.py b/src/conf_mode/interfaces_ethernet.py
index 2c0f846c3..504d48f89 100755
--- a/src/conf_mode/interfaces_ethernet.py
+++ b/src/conf_mode/interfaces_ethernet.py
@@ -15,7 +15,6 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
-import pprint
from glob import glob
from sys import exit
@@ -26,7 +25,6 @@ from vyos.configdict import get_interface_dict
from vyos.configdict import is_node_changed
from vyos.configverify import verify_address
from vyos.configverify import verify_dhcpv6
-from vyos.configverify import verify_eapol
from vyos.configverify import verify_interface_exists
from vyos.configverify import verify_mirror_redirect
from vyos.configverify import verify_mtu
@@ -34,6 +32,8 @@ from vyos.configverify import verify_mtu_ipv6
from vyos.configverify import verify_vlan_config
from vyos.configverify import verify_vrf
from vyos.configverify import verify_bond_bridge_member
+from vyos.configverify import verify_pki_certificate
+from vyos.configverify import verify_pki_ca_certificate
from vyos.ethtool import Ethtool
from vyos.ifconfig import EthernetIf
from vyos.ifconfig import BondIf
@@ -263,6 +263,22 @@ def verify_allowedbond_changes(ethernet: dict):
f' on interface "{ethernet["ifname"]}".' \
f' Interface is a bond member')
+def verify_eapol(ethernet: dict):
+ """
+ Common helper function used by interface implementations to perform
+ recurring validation of EAPoL configuration.
+ """
+ if 'eapol' not in ethernet:
+ return
+
+ if 'certificate' not in ethernet['eapol']:
+ raise ConfigError('Certificate must be specified when using EAPoL!')
+
+ verify_pki_certificate(ethernet, ethernet['eapol']['certificate'], no_password_protected=True)
+
+ if 'ca_certificate' in ethernet['eapol']:
+ for ca_cert in ethernet['eapol']['ca_certificate']:
+ verify_pki_ca_certificate(ethernet, ca_cert)
def verify(ethernet):
if 'deleted' in ethernet:
diff --git a/src/conf_mode/load-balancing_reverse-proxy.py b/src/conf_mode/load-balancing_reverse-proxy.py
index 2a0acd84a..694a4e1ea 100755
--- a/src/conf_mode/load-balancing_reverse-proxy.py
+++ b/src/conf_mode/load-balancing_reverse-proxy.py
@@ -20,6 +20,9 @@ from sys import exit
from shutil import rmtree
from vyos.config import Config
+from vyos.configverify import verify_pki_certificate
+from vyos.configverify import verify_pki_ca_certificate
+from vyos.utils.dict import dict_search
from vyos.utils.process import call
from vyos.utils.network import check_port_availability
from vyos.utils.network import is_listen_port_bind_service
@@ -33,8 +36,7 @@ airbag.enable()
load_balancing_dir = '/run/haproxy'
load_balancing_conf_file = f'{load_balancing_dir}/haproxy.cfg'
systemd_service = 'haproxy.service'
-systemd_override = r'/run/systemd/system/haproxy.service.d/10-override.conf'
-
+systemd_override = '/run/systemd/system/haproxy.service.d/10-override.conf'
def get_config(config=None):
if config:
@@ -54,30 +56,6 @@ def get_config(config=None):
return lb
-
-def _verify_cert(lb: dict, config: dict) -> None:
- if 'ca_certificate' in config['ssl']:
- ca_name = config['ssl']['ca_certificate']
- pki_ca = lb['pki'].get('ca')
- if pki_ca is None:
- raise ConfigError(f'CA certificates does not exist in PKI')
- else:
- ca = pki_ca.get(ca_name)
- if ca is None:
- raise ConfigError(f'CA certificate "{ca_name}" does not exist')
-
- elif 'certificate' in config['ssl']:
- cert_names = config['ssl']['certificate']
- pki_certs = lb['pki'].get('certificate')
- if pki_certs is None:
- raise ConfigError(f'Certificates does not exist in PKI')
-
- for cert_name in cert_names:
- pki_cert = pki_certs.get(cert_name)
- if pki_cert is None:
- raise ConfigError(f'Certificate "{cert_name}" does not exist')
-
-
def verify(lb):
if not lb:
return None
@@ -107,12 +85,12 @@ def verify(lb):
raise ConfigError(f'Cannot use both "send-proxy" and "send-proxy-v2" for server "{bk_server}"')
for front, front_config in lb['service'].items():
- if 'ssl' in front_config:
- _verify_cert(lb, front_config)
+ for cert in dict_search('ssl.certificate', front_config) or []:
+ verify_pki_certificate(lb, cert)
for back, back_config in lb['backend'].items():
- if 'ssl' in back_config:
- _verify_cert(lb, back_config)
+ tmp = dict_search('ssl.ca_certificate', front_config)
+ if tmp: verify_pki_ca_certificate(lb, tmp)
def generate(lb):
diff --git a/src/conf_mode/nat.py b/src/conf_mode/nat.py
index b3f38c04a..76c07a9ec 100755
--- a/src/conf_mode/nat.py
+++ b/src/conf_mode/nat.py
@@ -223,19 +223,19 @@ def generate(nat):
render(nftables_static_nat_conf, 'firewall/nftables-static-nat.j2', nat)
# dry-run newly generated configuration
- tmp = run(f'nft -c -f {nftables_nat_config}')
+ tmp = run(f'nft --check --file {nftables_nat_config}')
if tmp > 0:
raise ConfigError('Configuration file errors encountered!')
- tmp = run(f'nft -c -f {nftables_static_nat_conf}')
+ tmp = run(f'nft --check --file {nftables_static_nat_conf}')
if tmp > 0:
raise ConfigError('Configuration file errors encountered!')
return None
def apply(nat):
- cmd(f'nft -f {nftables_nat_config}')
- cmd(f'nft -f {nftables_static_nat_conf}')
+ cmd(f'nft --file {nftables_nat_config}')
+ cmd(f'nft --file {nftables_static_nat_conf}')
if not nat or 'deleted' in nat:
os.unlink(nftables_nat_config)
diff --git a/src/conf_mode/nat66.py b/src/conf_mode/nat66.py
index 4c1ead258..fe017527d 100755
--- a/src/conf_mode/nat66.py
+++ b/src/conf_mode/nat66.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2023 VyOS maintainers and contributors
+# Copyright (C) 2020-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
@@ -14,8 +14,6 @@
# 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 jmespath
-import json
import os
from sys import exit
@@ -106,7 +104,7 @@ def apply(nat):
if not nat:
return None
- cmd(f'nft -f {nftables_nat66_config}')
+ cmd(f'nft --file {nftables_nat66_config}')
call_dependents()
return None
diff --git a/src/conf_mode/policy_route.py b/src/conf_mode/policy_route.py
index 6d7a06714..c58fe1bce 100755
--- a/src/conf_mode/policy_route.py
+++ b/src/conf_mode/policy_route.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2023 VyOS maintainers and contributors
+# Copyright (C) 2021-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
@@ -177,7 +177,7 @@ def cleanup_table_marks():
cmd(f'{cmd_str} rule del fwmark {fwmark} table {table}')
def apply(policy):
- install_result = run(f'nft -f {nftables_conf}')
+ install_result = run(f'nft --file {nftables_conf}')
if install_result == 1:
raise ConfigError('Failed to apply policy based routing')
diff --git a/src/conf_mode/protocols_nhrp.py b/src/conf_mode/protocols_nhrp.py
index c339c6391..9f66407f2 100755
--- a/src/conf_mode/protocols_nhrp.py
+++ b/src/conf_mode/protocols_nhrp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2023 VyOS maintainers and contributors
+# Copyright (C) 2021-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
@@ -93,7 +93,7 @@ def generate(nhrp):
return None
def apply(nhrp):
- nft_rc = run(f'nft -f {nhrp_nftables_conf}')
+ nft_rc = run(f'nft --file {nhrp_nftables_conf}')
if nft_rc != 0:
raise ConfigError('Failed to apply NHRP tunnel firewall rules')
diff --git a/src/conf_mode/service_https.py b/src/conf_mode/service_https.py
index 46efc3c93..9e58b4c72 100755
--- a/src/conf_mode/service_https.py
+++ b/src/conf_mode/service_https.py
@@ -24,13 +24,14 @@ from time import sleep
from vyos.base import Warning
from vyos.config import Config
from vyos.config import config_dict_merge
-from vyos.configdiff import get_config_diff
from vyos.configverify import verify_vrf
+from vyos.configverify import verify_pki_certificate
+from vyos.configverify import verify_pki_ca_certificate
+from vyos.configverify import verify_pki_dh_parameters
from vyos.defaults import api_config_state
from vyos.pki import wrap_certificate
from vyos.pki import wrap_private_key
from vyos.pki import wrap_dh_parameters
-from vyos.pki import load_dh_parameters
from vyos.template import render
from vyos.utils.dict import dict_search
from vyos.utils.process import call
@@ -84,33 +85,14 @@ def verify(https):
if https is None:
return None
- if 'certificates' in https and 'certificate' in https['certificates']:
- cert_name = https['certificates']['certificate']
- if 'pki' not in https:
- raise ConfigError('PKI is not configured!')
-
- if cert_name not in https['pki']['certificate']:
- raise ConfigError('Invalid certificate in configuration!')
+ if dict_search('certificates.certificate', https) != None:
+ verify_pki_certificate(https, https['certificates']['certificate'])
- pki_cert = https['pki']['certificate'][cert_name]
-
- if 'certificate' not in pki_cert:
- raise ConfigError('Missing certificate in configuration!')
+ tmp = dict_search('certificates.ca_certificate', https)
+ if tmp != None: verify_pki_ca_certificate(https, tmp)
- if 'private' not in pki_cert or 'key' not in pki_cert['private']:
- raise ConfigError('Missing certificate private key in configuration!')
-
- if 'dh_params' in https['certificates']:
- dh_name = https['certificates']['dh_params']
- if dh_name not in https['pki']['dh']:
- raise ConfigError('Invalid DH parameter in configuration!')
-
- pki_dh = https['pki']['dh'][dh_name]
- dh_params = load_dh_parameters(pki_dh['parameters'])
- dh_numbers = dh_params.parameter_numbers()
- dh_bits = dh_numbers.p.bit_length()
- if dh_bits < 2048:
- raise ConfigError(f'Minimum DH key-size is 2048 bits')
+ tmp = dict_search('certificates.dh_params', https)
+ if tmp != None: verify_pki_dh_parameters(https, tmp, 2048)
else:
Warning('No certificate specified, using build-in self-signed certificates. '\
@@ -214,7 +196,8 @@ def apply(https):
https_service_name = 'nginx.service'
if https is None:
- call(f'systemctl stop {http_api_service_name}')
+ if is_systemd_service_active(http_api_service_name):
+ call(f'systemctl stop {http_api_service_name}')
call(f'systemctl stop {https_service_name}')
return
diff --git a/src/conf_mode/system_conntrack.py b/src/conf_mode/system_conntrack.py
index 4bea31bbb..56d798e43 100755
--- a/src/conf_mode/system_conntrack.py
+++ b/src/conf_mode/system_conntrack.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2023 VyOS maintainers and contributors
+# Copyright (C) 2021-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
@@ -15,19 +15,16 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
-import re
from sys import exit
from vyos.config import Config
from vyos.configdep import set_dependents, call_dependents
-from vyos.utils.process import process_named_running
from vyos.utils.dict import dict_search
from vyos.utils.dict import dict_search_args
from vyos.utils.dict import dict_search_recursive
from vyos.utils.process import cmd
from vyos.utils.process import rc_cmd
-from vyos.utils.process import run
from vyos.template import render
from vyos import ConfigError
from vyos import airbag
@@ -218,7 +215,7 @@ def apply(conntrack):
cmd(f'modprobe -a {module_str}')
# Load new nftables ruleset
- install_result, output = rc_cmd(f'nft -f {nftables_ct_file}')
+ install_result, output = rc_cmd(f'nft --file {nftables_ct_file}')
if install_result == 1:
raise ConfigError(f'Failed to apply configuration: {output}')
diff --git a/src/conf_mode/vpn_openconnect.py b/src/conf_mode/vpn_openconnect.py
index 08e4fc6db..8159fedea 100755
--- a/src/conf_mode/vpn_openconnect.py
+++ b/src/conf_mode/vpn_openconnect.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2023 VyOS maintainers and contributors
+# Copyright (C) 2018-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
@@ -19,6 +19,8 @@ from sys import exit
from vyos.base import Warning
from vyos.config import Config
+from vyos.configverify import verify_pki_certificate
+from vyos.configverify import verify_pki_ca_certificate
from vyos.pki import wrap_certificate
from vyos.pki import wrap_private_key
from vyos.template import render
@@ -75,7 +77,7 @@ def verify(ocserv):
if "accounting" in ocserv:
if "mode" in ocserv["accounting"] and "radius" in ocserv["accounting"]["mode"]:
if not origin["accounting"]['radius']['server']:
- raise ConfigError('Openconnect accounting mode radius requires at least one RADIUS server')
+ raise ConfigError('OpenConnect accounting mode radius requires at least one RADIUS server')
if "authentication" not in ocserv or "mode" not in ocserv["authentication"]:
raise ConfigError('Accounting depends on OpenConnect authentication configuration')
elif "radius" not in ocserv["authentication"]["mode"]:
@@ -89,12 +91,12 @@ def verify(ocserv):
raise ConfigError('OpenConnect authentication modes are mutually-exclusive, remove either local or radius from your configuration')
if "radius" in ocserv["authentication"]["mode"]:
if not ocserv["authentication"]['radius']['server']:
- raise ConfigError('Openconnect authentication mode radius requires at least one RADIUS server')
+ raise ConfigError('OpenConnect authentication mode radius requires at least one RADIUS server')
if "local" in ocserv["authentication"]["mode"]:
if not ocserv.get("authentication", {}).get("local_users"):
- raise ConfigError('openconnect mode local required at least one user')
+ raise ConfigError('OpenConnect mode local required at least one user')
if not ocserv["authentication"]["local_users"]["username"]:
- raise ConfigError('openconnect mode local required at least one user')
+ raise ConfigError('OpenConnect mode local required at least one user')
else:
# For OTP mode: verify that each local user has an OTP key
if "otp" in ocserv["authentication"]["mode"]["local"]:
@@ -127,40 +129,20 @@ def verify(ocserv):
if 'default_config' not in ocserv["authentication"]["identity_based_config"]:
raise ConfigError('OpenConnect identity-based-config enabled but default-config not set')
else:
- raise ConfigError('openconnect authentication mode required')
+ raise ConfigError('OpenConnect authentication mode required')
else:
- raise ConfigError('openconnect authentication credentials required')
+ raise ConfigError('OpenConnect authentication credentials required')
# Check ssl
if 'ssl' not in ocserv:
- raise ConfigError('openconnect ssl required')
+ raise ConfigError('SSL missing on OpenConnect config!')
- if not ocserv['pki'] or 'certificate' not in ocserv['pki']:
- raise ConfigError('PKI not configured')
+ if 'certificate' not in ocserv['ssl']:
+ raise ConfigError('SSL certificate missing on OpenConnect config!')
+ verify_pki_certificate(ocserv, ocserv['ssl']['certificate'])
- ssl = ocserv['ssl']
- if 'certificate' not in ssl:
- raise ConfigError('openconnect ssl certificate required')
-
- cert_name = ssl['certificate']
-
- if cert_name not in ocserv['pki']['certificate']:
- raise ConfigError('Invalid openconnect ssl certificate')
-
- cert = ocserv['pki']['certificate'][cert_name]
-
- if 'certificate' not in cert:
- raise ConfigError('Missing certificate in PKI')
-
- if 'private' not in cert or 'key' not in cert['private']:
- raise ConfigError('Missing private key in PKI')
-
- if 'ca_certificate' in ssl:
- if 'ca' not in ocserv['pki']:
- raise ConfigError('PKI not configured')
-
- if ssl['ca_certificate'] not in ocserv['pki']['ca']:
- raise ConfigError('Invalid openconnect ssl CA certificate')
+ if 'ca_certificate' in ocserv['ssl']:
+ verify_pki_ca_certificate(ocserv, ocserv['ssl']['ca_certificate'])
# Check network settings
if "network_settings" in ocserv:
@@ -172,7 +154,7 @@ def verify(ocserv):
else:
ocserv["network_settings"]["push_route"] = ["default"]
else:
- raise ConfigError('openconnect network settings required')
+ raise ConfigError('OpenConnect network settings required!')
def generate(ocserv):
if not ocserv:
@@ -276,7 +258,7 @@ def apply(ocserv):
break
sleep(0.250)
if counter > 5:
- raise ConfigError('openconnect failed to start, check the logs for details')
+ raise ConfigError('OpenConnect failed to start, check the logs for details')
break
counter += 1
diff --git a/src/conf_mode/vpn_sstp.py b/src/conf_mode/vpn_sstp.py
index 8661a8aff..7490fd0e0 100755
--- a/src/conf_mode/vpn_sstp.py
+++ b/src/conf_mode/vpn_sstp.py
@@ -20,6 +20,8 @@ from sys import exit
from vyos.config import Config
from vyos.configdict import get_accel_dict
+from vyos.configverify import verify_pki_certificate
+from vyos.configverify import verify_pki_ca_certificate
from vyos.pki import wrap_certificate
from vyos.pki import wrap_private_key
from vyos.template import render
@@ -46,51 +48,6 @@ cert_key_path = os.path.join(cfg_dir, 'sstp-cert.key')
ca_cert_file_path = os.path.join(cfg_dir, 'sstp-ca.pem')
-def verify_certificate(config):
- #
- # SSL certificate checks
- #
- if not config['pki']:
- raise ConfigError('PKI is not configured')
-
- if 'ssl' not in config:
- raise ConfigError('SSL missing on SSTP config')
-
- ssl = config['ssl']
-
- # CA
- if 'ca_certificate' not in ssl:
- raise ConfigError('SSL CA certificate missing on SSTP config')
-
- ca_name = ssl['ca_certificate']
-
- if ca_name not in config['pki']['ca']:
- raise ConfigError('Invalid CA certificate on SSTP config')
-
- if 'certificate' not in config['pki']['ca'][ca_name]:
- raise ConfigError('Missing certificate data for CA certificate on SSTP config')
-
- # Certificate
- if 'certificate' not in ssl:
- raise ConfigError('SSL certificate missing on SSTP config')
-
- cert_name = ssl['certificate']
-
- if cert_name not in config['pki']['certificate']:
- raise ConfigError('Invalid certificate on SSTP config')
-
- pki_cert = config['pki']['certificate'][cert_name]
-
- if 'certificate' not in pki_cert:
- raise ConfigError('Missing certificate data for certificate on SSTP config')
-
- if 'private' not in pki_cert or 'key' not in pki_cert['private']:
- raise ConfigError('Missing private key for certificate on SSTP config')
-
- if 'password_protected' in pki_cert['private']:
- raise ConfigError('Encrypted private key is not supported on SSTP config')
-
-
def get_config(config=None):
if config:
conf = config
@@ -124,7 +81,17 @@ def verify(sstp):
verify_accel_ppp_ip_pool(sstp)
verify_accel_ppp_name_servers(sstp)
verify_accel_ppp_wins_servers(sstp)
- verify_certificate(sstp)
+
+ if 'ssl' not in sstp:
+ raise ConfigError('SSL missing on SSTP config!')
+
+ if 'certificate' not in sstp['ssl']:
+ raise ConfigError('SSL certificate missing on SSTP config!')
+ verify_pki_certificate(sstp, sstp['ssl']['certificate'])
+
+ if 'ca_certificate' not in sstp['ssl']:
+ raise ConfigError('SSL CA certificate missing on SSTP config!')
+ verify_pki_ca_certificate(sstp, sstp['ssl']['ca_certificate'])
def generate(sstp):
@@ -154,15 +121,15 @@ def generate(sstp):
def apply(sstp):
+ systemd_service = 'accel-ppp@sstp.service'
if not sstp:
- call('systemctl stop accel-ppp@sstp.service')
+ call(f'systemctl stop {systemd_service}')
for file in [sstp_chap_secrets, sstp_conf]:
if os.path.exists(file):
os.unlink(file)
-
return None
- call('systemctl restart accel-ppp@sstp.service')
+ call(f'systemctl reload-or-restart {systemd_service}')
if __name__ == '__main__':
diff --git a/src/conf_mode/vrf.py b/src/conf_mode/vrf.py
index 16908100f..1fc813189 100755
--- a/src/conf_mode/vrf.py
+++ b/src/conf_mode/vrf.py
@@ -14,8 +14,6 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-import os
-
from sys import exit
from json import loads
@@ -33,6 +31,7 @@ from vyos.utils.network import get_vrf_members
from vyos.utils.network import interface_exists
from vyos.utils.process import call
from vyos.utils.process import cmd
+from vyos.utils.process import popen
from vyos.utils.system import sysctl_write
from vyos import ConfigError
from vyos import frr
@@ -227,7 +226,11 @@ def apply(vrf):
# Remove nftables conntrack zone map item
nft_del_element = f'delete element inet vrf_zones ct_iface_map {{ "{tmp}" }}'
- cmd(f'nft {nft_del_element}')
+ # Check if deleting is possible first to avoid raising errors
+ _, err = popen(f'nft --check {nft_del_element}')
+ if not err:
+ # Remove map element
+ cmd(f'nft {nft_del_element}')
# Delete the VRF Kernel interface
call(f'ip link delete dev {tmp}')
@@ -307,7 +310,7 @@ def apply(vrf):
if vrf['conntrack']:
for chain, rule in nftables_rules.items():
cmd(f'nft add rule inet vrf_zones {chain} {rule}')
-
+
if 'name' not in vrf or not vrf['conntrack']:
for chain, rule in nftables_rules.items():
cmd(f'nft flush chain inet vrf_zones {chain}')