summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
Diffstat (limited to 'python')
-rw-r--r--python/vyos/configtree.py9
-rw-r--r--python/vyos/defaults.py10
-rw-r--r--python/vyos/firewall.py22
-rw-r--r--python/vyos/ipsec.py136
-rw-r--r--python/vyos/template.py4
5 files changed, 137 insertions, 44 deletions
diff --git a/python/vyos/configtree.py b/python/vyos/configtree.py
index 5775070e2..bd77ab899 100644
--- a/python/vyos/configtree.py
+++ b/python/vyos/configtree.py
@@ -1,5 +1,5 @@
# configtree -- a standalone VyOS config file manipulation library (Python bindings)
-# Copyright (C) 2018-2022 VyOS maintainers and contributors
+# Copyright (C) 2018-2024 VyOS maintainers and contributors
#
# This library is free software; you can redistribute it and/or modify it under the terms of
# the GNU Lesser General Public License as published by the Free Software Foundation;
@@ -290,7 +290,7 @@ class ConfigTree(object):
else:
return True
- def list_nodes(self, path):
+ def list_nodes(self, path, path_must_exist=True):
check_path(path)
path_str = " ".join(map(str, path)).encode()
@@ -298,7 +298,10 @@ class ConfigTree(object):
res = json.loads(res_json)
if res is None:
- raise ConfigTreeError("Path [{}] doesn't exist".format(path_str))
+ if path_must_exist:
+ raise ConfigTreeError("Path [{}] doesn't exist".format(path_str))
+ else:
+ return []
else:
return res
diff --git a/python/vyos/defaults.py b/python/vyos/defaults.py
index 9ccd925ce..25ee45391 100644
--- a/python/vyos/defaults.py
+++ b/python/vyos/defaults.py
@@ -50,3 +50,13 @@ commit_lock = os.path.join(directories['vyos_configdir'], '.lock')
component_version_json = os.path.join(directories['data'], 'component-versions.json')
config_default = os.path.join(directories['data'], 'config.boot.default')
+
+rt_symbolic_names = {
+ # Standard routing tables for Linux & reserved IDs for VyOS
+ 'default': 253, # Confusingly, a final fallthru, not the default.
+ 'main': 254, # The actual global table used by iproute2 unless told otherwise.
+ 'local': 255, # Special kernel loopback table.
+}
+
+rt_global_vrf = rt_symbolic_names['main']
+rt_global_table = rt_symbolic_names['main']
diff --git a/python/vyos/firewall.py b/python/vyos/firewall.py
index 664df28cc..facd498ca 100644
--- a/python/vyos/firewall.py
+++ b/python/vyos/firewall.py
@@ -30,6 +30,9 @@ 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 run
+from vyos.utils.network import get_vrf_tableid
+from vyos.defaults import rt_global_table
+from vyos.defaults import rt_global_vrf
# Conntrack
def conntrack_required(conf):
@@ -366,10 +369,14 @@ def parse_rule(rule_conf, hook, fw_name, rule_id, ip_name):
output.append(f'ip{def_suffix} dscp != {{{negated_dscp_str}}}')
if 'ipsec' in rule_conf:
- if 'match_ipsec' in rule_conf['ipsec']:
+ if 'match_ipsec_in' in rule_conf['ipsec']:
output.append('meta ipsec == 1')
- if 'match_none' in rule_conf['ipsec']:
+ if 'match_none_in' in rule_conf['ipsec']:
output.append('meta ipsec == 0')
+ if 'match_ipsec_out' in rule_conf['ipsec']:
+ output.append('rt ipsec exists')
+ if 'match_none_out' in rule_conf['ipsec']:
+ output.append('rt ipsec missing')
if 'fragment' in rule_conf:
# Checking for fragmentation after priority -400 is not possible,
@@ -469,11 +476,20 @@ def parse_rule(rule_conf, hook, fw_name, rule_id, ip_name):
if 'mark' in rule_conf['set']:
mark = rule_conf['set']['mark']
output.append(f'meta mark set {mark}')
+ if 'vrf' in rule_conf['set']:
+ set_table = True
+ vrf_name = rule_conf['set']['vrf']
+ if vrf_name == 'default':
+ table = rt_global_vrf
+ else:
+ # NOTE: VRF->table ID lookup depends on the VRF iface already existing.
+ table = get_vrf_tableid(vrf_name)
if 'table' in rule_conf['set']:
set_table = True
table = rule_conf['set']['table']
if table == 'main':
- table = '254'
+ table = rt_global_table
+ if set_table:
mark = 0x7FFFFFFF - int(table)
output.append(f'meta mark set {mark}')
if 'tcp_mss' in rule_conf['set']:
diff --git a/python/vyos/ipsec.py b/python/vyos/ipsec.py
index 4603aab22..28f77565a 100644
--- a/python/vyos/ipsec.py
+++ b/python/vyos/ipsec.py
@@ -1,4 +1,4 @@
-# Copyright 2020-2023 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright 2020-2024 VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -13,31 +13,38 @@
# You should have received a copy of the GNU Lesser General Public
# License along with this library. If not, see <http://www.gnu.org/licenses/>.
-#Package to communicate with Strongswan VICI
+# Package to communicate with Strongswan VICI
+
class ViciInitiateError(Exception):
"""
- VICI can't initiate a session.
+ VICI can't initiate a session.
"""
+
pass
+
+
class ViciCommandError(Exception):
"""
- VICI can't execute a command by any reason.
+ VICI can't execute a command by any reason.
"""
+
pass
+
def get_vici_sas():
from vici import Session as vici_session
try:
session = vici_session()
except Exception:
- raise ViciInitiateError("IPsec not initialized")
+ raise ViciInitiateError('IPsec not initialized')
try:
sas = list(session.list_sas())
return sas
except Exception:
- raise ViciCommandError(f'Failed to get SAs')
+ raise ViciCommandError('Failed to get SAs')
+
def get_vici_connections():
from vici import Session as vici_session
@@ -45,18 +52,19 @@ def get_vici_connections():
try:
session = vici_session()
except Exception:
- raise ViciInitiateError("IPsec not initialized")
+ raise ViciInitiateError('IPsec not initialized')
try:
connections = list(session.list_conns())
return connections
except Exception:
- raise ViciCommandError(f'Failed to get connections')
+ raise ViciCommandError('Failed to get connections')
+
def get_vici_sas_by_name(ike_name: str, tunnel: str) -> list:
"""
- Find sas by IKE_SA name and/or CHILD_SA name
- and return list of OrdinaryDicts with SASs info
- If tunnel is not None return value is list of OrdenaryDicts contained only
+ Find installed SAs by IKE_SA name and/or CHILD_SA name
+ and return list with SASs info.
+ If tunnel is not None return a list contained only
CHILD_SAs wich names equal tunnel value.
:param ike_name: IKE SA name
:type ike_name: str
@@ -70,7 +78,7 @@ def get_vici_sas_by_name(ike_name: str, tunnel: str) -> list:
try:
session = vici_session()
except Exception:
- raise ViciInitiateError("IPsec not initialized")
+ raise ViciInitiateError('IPsec not initialized')
vici_dict = {}
if ike_name:
vici_dict['ike'] = ike_name
@@ -80,7 +88,31 @@ def get_vici_sas_by_name(ike_name: str, tunnel: str) -> list:
sas = list(session.list_sas(vici_dict))
return sas
except Exception:
- raise ViciCommandError(f'Failed to get SAs')
+ raise ViciCommandError('Failed to get SAs')
+
+
+def get_vici_connection_by_name(ike_name: str) -> list:
+ """
+ Find loaded SAs by IKE_SA name and return list with SASs info
+ :param ike_name: IKE SA name
+ :type ike_name: str
+ :return: list of Ordinary Dicts with SASs
+ :rtype: list
+ """
+ from vici import Session as vici_session
+
+ try:
+ session = vici_session()
+ except Exception:
+ raise ViciInitiateError('IPsec is not initialized')
+ vici_dict = {}
+ if ike_name:
+ vici_dict['ike'] = ike_name
+ try:
+ sas = list(session.list_conns(vici_dict))
+ return sas
+ except Exception:
+ raise ViciCommandError('Failed to get SAs')
def terminate_vici_ikeid_list(ike_id_list: list) -> None:
@@ -94,19 +126,17 @@ def terminate_vici_ikeid_list(ike_id_list: list) -> None:
try:
session = vici_session()
except Exception:
- raise ViciInitiateError("IPsec not initialized")
+ raise ViciInitiateError('IPsec is not initialized')
try:
for ikeid in ike_id_list:
- session_generator = session.terminate(
- {'ike-id': ikeid, 'timeout': '-1'})
+ session_generator = session.terminate({'ike-id': ikeid, 'timeout': '-1'})
# a dummy `for` loop is required because of requirements
# from vici. Without a full iteration on the output, the
# command to vici may not be executed completely
for _ in session_generator:
pass
except Exception:
- raise ViciCommandError(
- f'Failed to terminate SA for IKE ids {ike_id_list}')
+ raise ViciCommandError(f'Failed to terminate SA for IKE ids {ike_id_list}')
def terminate_vici_by_name(ike_name: str, child_name: str) -> None:
@@ -123,9 +153,9 @@ def terminate_vici_by_name(ike_name: str, child_name: str) -> None:
try:
session = vici_session()
except Exception:
- raise ViciInitiateError("IPsec not initialized")
+ raise ViciInitiateError('IPsec is not initialized')
try:
- vici_dict: dict= {}
+ vici_dict: dict = {}
if ike_name:
vici_dict['ike'] = ike_name
if child_name:
@@ -138,16 +168,48 @@ def terminate_vici_by_name(ike_name: str, child_name: str) -> None:
pass
except Exception:
if child_name:
- raise ViciCommandError(
- f'Failed to terminate SA for IPSEC {child_name}')
+ raise ViciCommandError(f'Failed to terminate SA for IPSEC {child_name}')
else:
- raise ViciCommandError(
- f'Failed to terminate SA for IKE {ike_name}')
+ raise ViciCommandError(f'Failed to terminate SA for IKE {ike_name}')
+
+
+def vici_initiate_all_child_sa_by_ike(ike_sa_name: str, child_sa_list: list) -> bool:
+ """
+ Initiate IKE SA with scpecified CHILD_SAs in list
+
+ Args:
+ ike_sa_name (str): an IKE SA connection name
+ child_sa_list (list): a list of child SA names
+
+ Returns:
+ bool: a result of initiation command
+ """
+ from vici import Session as vici_session
+
+ try:
+ session = vici_session()
+ except Exception:
+ raise ViciInitiateError('IPsec is not initialized')
+
+ try:
+ for child_sa_name in child_sa_list:
+ session_generator = session.initiate(
+ {'ike': ike_sa_name, 'child': child_sa_name, 'timeout': '-1'}
+ )
+ # a dummy `for` loop is required because of requirements
+ # from vici. Without a full iteration on the output, the
+ # command to vici may not be executed completely
+ for _ in session_generator:
+ pass
+ return True
+ except Exception:
+ raise ViciCommandError(f'Failed to initiate SA for IKE {ike_sa_name}')
-def vici_initiate(ike_sa_name: str, child_sa_name: str, src_addr: str,
- dst_addr: str) -> bool:
- """Initiate IKE SA connection with specific peer
+def vici_initiate(
+ ike_sa_name: str, child_sa_name: str, src_addr: str, dst_addr: str
+) -> bool:
+ """Initiate IKE SA with one child_sa connection with specific peer
Args:
ike_sa_name (str): an IKE SA connection name
@@ -163,16 +225,18 @@ def vici_initiate(ike_sa_name: str, child_sa_name: str, src_addr: str,
try:
session = vici_session()
except Exception:
- raise ViciInitiateError("IPsec not initialized")
+ raise ViciInitiateError('IPsec is not initialized')
try:
- session_generator = session.initiate({
- 'ike': ike_sa_name,
- 'child': child_sa_name,
- 'timeout': '-1',
- 'my-host': src_addr,
- 'other-host': dst_addr
- })
+ session_generator = session.initiate(
+ {
+ 'ike': ike_sa_name,
+ 'child': child_sa_name,
+ 'timeout': '-1',
+ 'my-host': src_addr,
+ 'other-host': dst_addr,
+ }
+ )
# a dummy `for` loop is required because of requirements
# from vici. Without a full iteration on the output, the
# command to vici may not be executed completely
@@ -180,4 +244,4 @@ def vici_initiate(ike_sa_name: str, child_sa_name: str, src_addr: str,
pass
return True
except Exception:
- raise ViciCommandError(f'Failed to initiate SA for IKE {ike_sa_name}') \ No newline at end of file
+ raise ViciCommandError(f'Failed to initiate SA for IKE {ike_sa_name}')
diff --git a/python/vyos/template.py b/python/vyos/template.py
index e8d7ba669..3507e0940 100644
--- a/python/vyos/template.py
+++ b/python/vyos/template.py
@@ -556,8 +556,8 @@ def get_openvpn_cipher(cipher):
return openvpn_translate[cipher].upper()
return cipher.upper()
-@register_filter('openvpn_ncp_ciphers')
-def get_openvpn_ncp_ciphers(ciphers):
+@register_filter('openvpn_data_ciphers')
+def get_openvpn_data_ciphers(ciphers):
out = []
for cipher in ciphers:
if cipher in openvpn_translate: