summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Poessinger <christian@poessinger.com>2021-01-19 21:01:20 +0100
committerChristian Poessinger <christian@poessinger.com>2021-01-19 21:04:28 +0100
commit9207897983a3bfafa0ec3e436c1ad67790f09f06 (patch)
tree48d3291319fc113eda2c0effe866df154d7e8e21 /src
parent75e947ccc72d1532e1bf9c2f5011060a1043a14e (diff)
downloadvyos-1x-9207897983a3bfafa0ec3e436c1ad67790f09f06.tar.gz
vyos-1x-9207897983a3bfafa0ec3e436c1ad67790f09f06.zip
nat: T2947: add many-many translation
Support a 1:1 or 1:n prefix translation. The following configuration will NAT source addresses from the 10.2.0.0/16 range to an address from 192.0.2.0/29. For this feature to work a Linux Kernel 5.8 or higher is required! vyos@vyos# show nat source { rule 100 { outbound-interface eth1 source { address 10.2.0.0/16 } translation { address 192.0.2.0/29 } } } This results in the nftables configuration: chain POSTROUTING { type nat hook postrouting priority srcnat; policy accept; oifname "eth1" counter packets 0 bytes 0 snat ip prefix to ip saddr map { 10.2.0.0/16 : 192.0.2.0/29 } comment "SRC-NAT-100" }
Diffstat (limited to 'src')
-rwxr-xr-xsrc/conf_mode/nat.py9
-rw-r--r--src/tests/test_template.py19
2 files changed, 24 insertions, 4 deletions
diff --git a/src/conf_mode/nat.py b/src/conf_mode/nat.py
index 2d98cb11b..dae958774 100755
--- a/src/conf_mode/nat.py
+++ b/src/conf_mode/nat.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020 VyOS maintainers and contributors
+# Copyright (C) 2020-2021 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
@@ -26,6 +26,7 @@ from netifaces import interfaces
from vyos.config import Config
from vyos.configdict import dict_merge
from vyos.template import render
+from vyos.template import is_ip_network
from vyos.util import cmd
from vyos.util import check_kmod
from vyos.util import dict_search
@@ -68,9 +69,9 @@ def verify_rule(config, err_msg):
'ports can only be specified when protocol is '\
'either tcp, udp or tcp_udp!')
- if '/' in (dict_search('translation.address', config) or []):
+ if is_ip_network(dict_search('translation.address', config)):
raise ConfigError(f'{err_msg}\n' \
- 'Cannot use ports with an IPv4net type translation address as it\n' \
+ 'Cannot use ports with an IPv4 network as translation address as it\n' \
'statically maps a whole network of addresses onto another\n' \
'network of addresses')
@@ -147,7 +148,7 @@ def verify(nat):
addr = dict_search('translation.address', config)
if addr != None:
- if addr != 'masquerade':
+ if addr != 'masquerade' and not is_ip_network(addr):
for ip in addr.split('-'):
if not is_addr_assigned(ip):
print(f'WARNING: IP address {ip} does not exist on the system!')
diff --git a/src/tests/test_template.py b/src/tests/test_template.py
index 544755692..7800d007f 100644
--- a/src/tests/test_template.py
+++ b/src/tests/test_template.py
@@ -93,3 +93,22 @@ class TestVyOSTemplate(TestCase):
self.assertEqual(vyos.template.dec_ip('2001:db8::b/64', '10'), '2001:db8::1')
self.assertEqual(vyos.template.dec_ip('2001:db8::f', '5'), '2001:db8::a')
+ def test_is_network(self):
+ self.assertFalse(vyos.template.is_ip_network('192.0.2.0'))
+ self.assertFalse(vyos.template.is_ip_network('192.0.2.1/24'))
+ self.assertTrue(vyos.template.is_ip_network('192.0.2.0/24'))
+
+ self.assertFalse(vyos.template.is_ip_network('2001:db8::'))
+ self.assertFalse(vyos.template.is_ip_network('2001:db8::ffff'))
+ self.assertTrue(vyos.template.is_ip_network('2001:db8::/48'))
+ self.assertTrue(vyos.template.is_ip_network('2001:db8:1000::/64'))
+
+ def test_is_network(self):
+ self.assertTrue(vyos.template.compare_netmask('10.0.0.0/8', '20.0.0.0/8'))
+ self.assertTrue(vyos.template.compare_netmask('10.0.0.0/16', '20.0.0.0/16'))
+ self.assertFalse(vyos.template.compare_netmask('10.0.0.0/8', '20.0.0.0/16'))
+ self.assertFalse(vyos.template.compare_netmask('10.0.0.1', '20.0.0.0/16'))
+
+ self.assertTrue(vyos.template.compare_netmask('2001:db8:1000::/48', '2001:db8:2000::/48'))
+ self.assertTrue(vyos.template.compare_netmask('2001:db8:1000::/64', '2001:db8:2000::/64'))
+ self.assertFalse(vyos.template.compare_netmask('2001:db8:1000::/48', '2001:db8:2000::/64'))