summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarius Lindvall <marius@varden.info>2026-01-01 22:42:10 +0100
committerMarius Lindvall <marius@varden.info>2026-01-01 22:42:10 +0100
commit95f40d8b30f03a47b022042ed8b3c179b0e7abdf (patch)
treecf4f451c23bbe59179d7ca01199ab3ab3ad31e97
parent76830afc8703a3f9f6be7500cb92aa9b6e255425 (diff)
downloadvyos-1x-95f40d8b30f03a47b022042ed8b3c179b0e7abdf.tar.gz
vyos-1x-95f40d8b30f03a47b022042ed8b3c179b0e7abdf.zip
nat66: T8139: add support for NAT66 source groups
Copy the support for NAT66 destination groups (commit f96733dd and commit 43554efc) over to NAT66 source groups as well. Change the existing smoketest for NAT66 groups to also cover a source group use-case example.
-rw-r--r--interface-definitions/nat66.xml.in2
-rwxr-xr-xsmoketest/scripts/cli/test_nat66.py18
-rwxr-xr-xsrc/conf_mode/nat66.py14
3 files changed, 29 insertions, 5 deletions
diff --git a/interface-definitions/nat66.xml.in b/interface-definitions/nat66.xml.in
index 2c1babd5a..3848b4c9a 100644
--- a/interface-definitions/nat66.xml.in
+++ b/interface-definitions/nat66.xml.in
@@ -79,6 +79,7 @@
</properties>
</leafNode>
#include <include/nat-port.xml.i>
+ #include <include/firewall/source-destination-group-ipv6.xml.i>
</children>
</node>
<node name="translation">
@@ -216,6 +217,7 @@
</properties>
</leafNode>
#include <include/nat-port.xml.i>
+ #include <include/firewall/source-destination-group-ipv6.xml.i>
</children>
</node>
<node name="translation">
diff --git a/smoketest/scripts/cli/test_nat66.py b/smoketest/scripts/cli/test_nat66.py
index 5e5e4829a..d5b137c70 100755
--- a/smoketest/scripts/cli/test_nat66.py
+++ b/smoketest/scripts/cli/test_nat66.py
@@ -148,10 +148,13 @@ class TestNAT66(VyOSUnitTestSHIM.TestCase):
address_group_member = 'fc00::1'
network_group = 'smoketest_net'
network_group_member = 'fc00::/64'
+ mac_group = 'smoketest_mac'
+ mac_group_member = '00:01:02:03:04:05'
translation_prefix = 'fc01::/64'
self.cli_set(['firewall', 'group', 'ipv6-address-group', address_group, 'address', address_group_member])
self.cli_set(['firewall', 'group', 'ipv6-network-group', network_group, 'network', network_group_member])
+ self.cli_set(['firewall', 'group', 'mac-group', mac_group, 'mac-address', mac_group_member])
self.cli_set(dst_path + ['rule', '1', 'destination', 'group', 'address-group', address_group])
self.cli_set(dst_path + ['rule', '1', 'translation', 'address', translation_prefix])
@@ -159,6 +162,9 @@ class TestNAT66(VyOSUnitTestSHIM.TestCase):
self.cli_set(dst_path + ['rule', '2', 'destination', 'group', 'network-group', network_group])
self.cli_set(dst_path + ['rule', '2', 'translation', 'address', translation_prefix])
+ self.cli_set(dst_path + ['rule', '3', 'source', 'group', 'mac-group', mac_group])
+ self.cli_set(dst_path + ['rule', '3', 'translation', 'address', translation_prefix])
+
self.cli_commit()
nftables_search = [
@@ -167,7 +173,8 @@ class TestNAT66(VyOSUnitTestSHIM.TestCase):
[f'set N6_{network_group}'],
[f'elements = {{ {network_group_member} }}'],
['ip6 daddr', f'@A6_{address_group}', 'dnat prefix to fc01::/64'],
- ['ip6 daddr', f'@N6_{network_group}', 'dnat prefix to fc01::/64']
+ ['ip6 daddr', f'@N6_{network_group}', 'dnat prefix to fc01::/64'],
+ ['ether saddr', f'@M_{mac_group}', 'dnat prefix to fc01::/64'],
]
self.verify_nftables(nftables_search, 'ip6 vyos_nat')
@@ -234,10 +241,13 @@ class TestNAT66(VyOSUnitTestSHIM.TestCase):
address_group_member = 'fc00::1'
network_group = 'smoketest_net'
network_group_member = 'fc00::/64'
+ mac_group = 'smoketest_mac'
+ mac_group_member = '00:01:02:03:04:05'
translation_prefix = 'fc01::/64'
self.cli_set(['firewall', 'group', 'ipv6-address-group', address_group, 'address', address_group_member])
self.cli_set(['firewall', 'group', 'ipv6-network-group', network_group, 'network', network_group_member])
+ self.cli_set(['firewall', 'group', 'mac-group', mac_group, 'mac-address', mac_group_member])
self.cli_set(src_path + ['rule', '1', 'destination', 'group', 'address-group', address_group])
self.cli_set(src_path + ['rule', '1', 'translation', 'address', translation_prefix])
@@ -245,6 +255,9 @@ class TestNAT66(VyOSUnitTestSHIM.TestCase):
self.cli_set(src_path + ['rule', '2', 'destination', 'group', 'network-group', network_group])
self.cli_set(src_path + ['rule', '2', 'translation', 'address', translation_prefix])
+ self.cli_set(src_path + ['rule', '3', 'source', 'group', 'mac-group', mac_group])
+ self.cli_set(src_path + ['rule', '3', 'translation', 'address', translation_prefix])
+
self.cli_commit()
nftables_search = [
@@ -253,7 +266,8 @@ class TestNAT66(VyOSUnitTestSHIM.TestCase):
[f'set N6_{network_group}'],
[f'elements = {{ {network_group_member} }}'],
['ip6 daddr', f'@A6_{address_group}', 'snat prefix to fc01::/64'],
- ['ip6 daddr', f'@N6_{network_group}', 'snat prefix to fc01::/64']
+ ['ip6 daddr', f'@N6_{network_group}', 'snat prefix to fc01::/64'],
+ ['ether saddr', f'@M_{mac_group}', 'snat prefix to fc01::/64'],
]
self.verify_nftables(nftables_search, 'ip6 vyos_nat')
diff --git a/src/conf_mode/nat66.py b/src/conf_mode/nat66.py
index aea187d18..c3637c6b9 100755
--- a/src/conf_mode/nat66.py
+++ b/src/conf_mode/nat66.py
@@ -92,10 +92,14 @@ def verify(nat):
if prefix != None:
if not is_ipv6(prefix):
raise ConfigError(f'{err_msg} source-prefix not specified')
-
+
+ if 'source' in config and 'group' in config['source']:
+ if len({'address_group', 'network_group', 'domain_group'} & set(config['source']['group'])) > 1:
+ raise ConfigError('Only one source address-group, network-group or domain-group can be specified')
+
if 'destination' in config and 'group' in config['destination']:
if len({'address_group', 'network_group', 'domain_group'} & set(config['destination']['group'])) > 1:
- raise ConfigError('Only one address-group, network-group or domain-group can be specified')
+ raise ConfigError('Only one destination address-group, network-group or domain-group can be specified')
if dict_search('destination.rule', nat):
for rule, config in dict_search('destination.rule', nat).items():
@@ -112,9 +116,13 @@ def verify(nat):
if not interface_exists(interface_name):
Warning(f'Interface "{interface_name}" for destination NAT66 rule "{rule}" does not exist!')
+ if 'source' in config and 'group' in config['source']:
+ if len({'address_group', 'network_group', 'domain_group'} & set(config['source']['group'])) > 1:
+ raise ConfigError('Only one source address-group, network-group or domain-group can be specified')
+
if 'destination' in config and 'group' in config['destination']:
if len({'address_group', 'network_group', 'domain_group'} & set(config['destination']['group'])) > 1:
- raise ConfigError('Only one address-group, network-group or domain-group can be specified')
+ raise ConfigError('Only one destination address-group, network-group or domain-group can be specified')
return None