summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile8
-rw-r--r--python/vyos/ifconfig/macsec.py2
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_macsec.py8
-rwxr-xr-xsrc/conf_mode/interfaces_macsec.py10
-rwxr-xr-xsrc/conf_mode/nat_cgnat.py51
5 files changed, 68 insertions, 11 deletions
diff --git a/Makefile b/Makefile
index cc382e206..509b47858 100644
--- a/Makefile
+++ b/Makefile
@@ -78,7 +78,7 @@ vyshim:
$(MAKE) -C $(SHIM_DIR)
.PHONY: all
-all: clean interface_definitions op_mode_definitions check test j2lint vyshim
+all: clean interface_definitions op_mode_definitions check test j2lint vyshim check_migration_scripts_executable
.PHONY: check
.ONESHELL:
@@ -103,6 +103,12 @@ test:
set -e; python3 -m compileall -q -x '/vmware-tools/scripts/, /ppp/' .
PYTHONPATH=python/ python3 -m "nose" --with-xunit src --with-coverage --cover-erase --cover-xml --cover-package src/conf_mode,src/op_mode,src/completion,src/helpers,src/validators,src/tests --verbose
+.PHONY: check_migration_scripts_executable
+.ONESHELL:
+check_migration_scripts_executable:
+ @echo "Checking if migration scripts have executable bit set..."
+ find src/migration-scripts -type f -not -executable -print -exec false {} + || sh -c 'echo "Found files that are not executable! Add permissions." && exit 1'
+
.PHONY: j2lint
j2lint:
ifndef J2LINT
diff --git a/python/vyos/ifconfig/macsec.py b/python/vyos/ifconfig/macsec.py
index bde1d9aec..383905814 100644
--- a/python/vyos/ifconfig/macsec.py
+++ b/python/vyos/ifconfig/macsec.py
@@ -66,7 +66,7 @@ class MACsecIf(Interface):
cmd = 'ip macsec add {ifname} rx port 1 address'.format(**self.config)
cmd += f' {peer_config["mac"]}'
self._cmd(cmd)
- # Add the rx-key to the address
+ # Add the encryption key to the address
cmd += f' sa 0 pn 1 on key 01 {peer_config["key"]}'
self._cmd(cmd)
diff --git a/smoketest/scripts/cli/test_interfaces_macsec.py b/smoketest/scripts/cli/test_interfaces_macsec.py
index a4e6840ca..d73895b7f 100755
--- a/smoketest/scripts/cli/test_interfaces_macsec.py
+++ b/smoketest/scripts/cli/test_interfaces_macsec.py
@@ -225,11 +225,11 @@ class MACsecInterfaceTest(BasicInterfaceTest.TestCase):
self.cli_commit()
self.cli_delete(self._base_path + [interface, 'security', 'mka'])
- # check validate() - tx-key required
+ # check validate() - key required
with self.assertRaises(ConfigSessionError):
self.cli_commit()
- # check validate() - tx-key length must match cipher
+ # check validate() - key length must match cipher
self.cli_set(self._base_path + [interface, 'security', 'static', 'key', tx_key_2])
with self.assertRaises(ConfigSessionError):
self.cli_commit()
@@ -239,7 +239,7 @@ class MACsecInterfaceTest(BasicInterfaceTest.TestCase):
with self.assertRaises(ConfigSessionError):
self.cli_commit()
- # check validate() - enabled peer must have both rx-key and MAC defined
+ # check validate() - enabled peer must have both key and MAC defined
self.cli_set(self._base_path + [interface, 'security', 'static', 'peer', 'TESTPEER'])
with self.assertRaises(ConfigSessionError):
self.cli_commit()
@@ -252,7 +252,7 @@ class MACsecInterfaceTest(BasicInterfaceTest.TestCase):
self.cli_commit()
self.cli_set(self._base_path + [interface, 'security', 'static', 'peer', 'TESTPEER', 'mac', peer_mac])
- # check validate() - peer rx-key length must match cipher
+ # check validate() - peer key length must match cipher
self.cli_set(self._base_path + [interface, 'security', 'cipher', cipher2])
self.cli_set(self._base_path + [interface, 'security', 'static', 'key', tx_key_2])
with self.assertRaises(ConfigSessionError):
diff --git a/src/conf_mode/interfaces_macsec.py b/src/conf_mode/interfaces_macsec.py
index eb0ca9a8b..3ede4377a 100755
--- a/src/conf_mode/interfaces_macsec.py
+++ b/src/conf_mode/interfaces_macsec.py
@@ -103,9 +103,9 @@ def verify(macsec):
# Logic to check static configuration
if dict_search('security.static', macsec) != None:
- # tx-key must be defined
+ # key must be defined
if dict_search('security.static.key', macsec) == None:
- raise ConfigError('Static MACsec tx-key must be defined.')
+ raise ConfigError('Static MACsec key must be defined.')
tx_len = len(dict_search('security.static.key', macsec))
@@ -119,12 +119,12 @@ def verify(macsec):
if 'peer' not in macsec['security']['static']:
raise ConfigError('Must have at least one peer defined for static MACsec')
- # For every enabled peer, make sure a MAC and rx-key is defined
+ # For every enabled peer, make sure a MAC and key is defined
for peer, peer_config in macsec['security']['static']['peer'].items():
if 'disable' not in peer_config and ('mac' not in peer_config or 'key' not in peer_config):
- raise ConfigError('Every enabled MACsec static peer must have a MAC address and rx-key defined.')
+ raise ConfigError('Every enabled MACsec static peer must have a MAC address and key defined!')
- # check rx-key length against cipher suite
+ # check key length against cipher suite
rx_len = len(peer_config['key'])
if dict_search('security.cipher', macsec) == 'gcm-aes-128' and rx_len != GCM_AES_128_LEN:
diff --git a/src/conf_mode/nat_cgnat.py b/src/conf_mode/nat_cgnat.py
index cb336a35c..34ec64fce 100755
--- a/src/conf_mode/nat_cgnat.py
+++ b/src/conf_mode/nat_cgnat.py
@@ -23,6 +23,7 @@ from sys import exit
from logging.handlers import SysLogHandler
from vyos.config import Config
+from vyos.configdict import is_node_changed
from vyos.template import render
from vyos.utils.process import cmd
from vyos.utils.process import run
@@ -118,6 +119,41 @@ class IPOperations:
+ [self.ip_network.broadcast_address]
]
+ def get_prefix_by_ip_range(self):
+ """Return the common prefix for the address range
+
+ Example:
+ % ip = IPOperations('100.64.0.1-100.64.0.5')
+ % ip.get_prefix_by_ip_range()
+ 100.64.0.0/29
+ """
+ if '-' in self.ip_prefix:
+ ip_start, ip_end = self.ip_prefix.split('-')
+ start_ip = ipaddress.IPv4Address(ip_start.strip())
+ end_ip = ipaddress.IPv4Address(ip_end.strip())
+
+ start_int = int(start_ip)
+ end_int = int(end_ip)
+
+ # XOR to find differing bits
+ xor = start_int ^ end_int
+
+ # Count the number of leading zeros in the XOR result to find the prefix length
+ prefix_length = 32 - xor.bit_length()
+
+ # Calculate the network address
+ network_int = start_int & (0xFFFFFFFF << (32 - prefix_length))
+ network_address = ipaddress.IPv4Address(network_int)
+
+ return f"{network_address}/{prefix_length}"
+ return self.ip_prefix
+
+
+def _delete_conntrack_entries(source_prefixes: list) -> None:
+ """Delete all conntrack entries for the list of prefixes"""
+ for source_prefix in source_prefixes:
+ run(f'conntrack -D -s {source_prefix}')
+
def generate_port_rules(
external_hosts: list,
@@ -188,6 +224,9 @@ def get_config(config=None):
with_recursive_defaults=True,
)
+ if conf.exists(base) and is_node_changed(conf, base + ['pool']):
+ config.update({'delete_conntrack_entries': {}})
+
return config
@@ -386,6 +425,18 @@ def apply(config):
# Log error message
logger.error(f"Error processing line '{allocation}': {e}")
+ # Delete conntrack entries
+ if 'delete_conntrack_entries' in config:
+ internal_pool_prefix_list = []
+ for rule, rule_config in config['rule'].items():
+ internal_pool = rule_config['source']['pool']
+ internal_ip_ranges: list = config['pool']['internal'][internal_pool]['range']
+ for internal_range in internal_ip_ranges:
+ ip_prefix = IPOperations(internal_range).get_prefix_by_ip_range()
+ internal_pool_prefix_list.append(ip_prefix)
+ # Deleta required sources for conntrack
+ _delete_conntrack_entries(internal_pool_prefix_list)
+
if __name__ == '__main__':
try: