Skip to content

Commit

Permalink
Merge pull request #3680 from sever-sever/T6497
Browse files Browse the repository at this point in the history
T6497: CGNAT delete conntrack entries if a pool is modified
  • Loading branch information
c-po authored Jun 19, 2024
2 parents da5d29a + 93cac8a commit 4763437
Showing 1 changed file with 51 additions and 0 deletions.
51 changes: 51 additions & 0 deletions src/conf_mode/nat_cgnat.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
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
Expand Down Expand Up @@ -118,6 +119,41 @@ def convert_prefix_to_list_ips(self) -> list:
+ [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,
Expand Down Expand Up @@ -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


Expand Down Expand Up @@ -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:
Expand Down

0 comments on commit 4763437

Please sign in to comment.