summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--interface-definitions/include/firewall/nat-balance.xml.i2
-rw-r--r--interface-definitions/include/nat-rule.xml.i4
-rw-r--r--python/vyos/nat.py8
-rwxr-xr-xsmoketest/scripts/cli/test_nat.py39
-rwxr-xr-xsrc/conf_mode/nat.py19
5 files changed, 46 insertions, 26 deletions
diff --git a/interface-definitions/include/firewall/nat-balance.xml.i b/interface-definitions/include/firewall/nat-balance.xml.i
index ac60a2545..01793f06b 100644
--- a/interface-definitions/include/firewall/nat-balance.xml.i
+++ b/interface-definitions/include/firewall/nat-balance.xml.i
@@ -1,5 +1,5 @@
<!-- include start from firewall/nat-balance.xml.i -->
-<tagNode name="member">
+<tagNode name="backend">
<properties>
<help>Translated IP address</help>
<valueHelp>
diff --git a/interface-definitions/include/nat-rule.xml.i b/interface-definitions/include/nat-rule.xml.i
index fa7625c7d..6234e6195 100644
--- a/interface-definitions/include/nat-rule.xml.i
+++ b/interface-definitions/include/nat-rule.xml.i
@@ -25,9 +25,9 @@
</node>
#include <include/generic-disable-node.xml.i>
#include <include/nat-exclude.xml.i>
- <node name="balance">
+ <node name="load-balance">
<properties>
- <help>Apply NAT balance</help>
+ <help>Apply NAT load balance</help>
</properties>
<children>
#include <include/firewall/firewall-hashing-parameters.xml.i>
diff --git a/python/vyos/nat.py b/python/vyos/nat.py
index 9978993a7..a56ca1ff3 100644
--- a/python/vyos/nat.py
+++ b/python/vyos/nat.py
@@ -90,12 +90,12 @@ def parse_nat_rule(rule_conf, rule_id, nat_type, ipv6=False):
if options:
translation_str += f' {",".join(options)}'
- if 'member' in rule_conf['balance']:
+ if 'backend' in rule_conf['load_balance']:
hash_input_items = []
current_prob = 0
nat_map = []
- for trans_addr, addr in rule_conf['balance']['member'].items():
+ for trans_addr, addr in rule_conf['load_balance']['backend'].items():
item_prob = int(addr['weight'])
upper_limit = current_prob + item_prob - 1
hash_val = str(current_prob) + '-' + str(upper_limit)
@@ -105,10 +105,10 @@ def parse_nat_rule(rule_conf, rule_id, nat_type, ipv6=False):
elements = ' , '.join(nat_map)
- if 'hash' in rule_conf['balance'] and 'random' in rule_conf['balance']['hash']:
+ if 'hash' in rule_conf['load_balance'] and 'random' in rule_conf['load_balance']['hash']:
translation_str += ' numgen random mod 100 map ' + '{ ' + f'{elements}' + ' }'
else:
- for input_param in rule_conf['balance']['hash']:
+ for input_param in rule_conf['load_balance']['hash']:
if input_param == 'source-address':
param = 'ip saddr'
elif input_param == 'destination-address':
diff --git a/smoketest/scripts/cli/test_nat.py b/smoketest/scripts/cli/test_nat.py
index 673be9905..f0c4fef2e 100755
--- a/smoketest/scripts/cli/test_nat.py
+++ b/smoketest/scripts/cli/test_nat.py
@@ -231,6 +231,27 @@ class TestNAT(VyOSUnitTestSHIM.TestCase):
self.verify_nftables(nftables_search, 'ip vyos_static_nat')
+ def test_dnat_redirect(self):
+ dst_addr_1 = '10.0.1.1'
+ dest_port = '5122'
+ protocol = 'tcp'
+ redirected_port = '22'
+ ifname = 'eth0'
+
+ self.cli_set(dst_path + ['rule', '10', 'destination', 'address', dst_addr_1])
+ self.cli_set(dst_path + ['rule', '10', 'destination', 'port', dest_port])
+ self.cli_set(dst_path + ['rule', '10', 'protocol', protocol])
+ self.cli_set(dst_path + ['rule', '10', 'inbound-interface', ifname])
+ self.cli_set(dst_path + ['rule', '10', 'translation', 'redirect', 'port', redirected_port])
+
+ self.cli_commit()
+
+ nftables_search = [
+ [f'iifname "{ifname}"', f'ip daddr {dst_addr_1}', f'{protocol} dport {dest_port}', f'redirect to :{redirected_port}']
+ ]
+
+ self.verify_nftables(nftables_search, 'ip vyos_nat')
+
def test_nat_balance(self):
ifname = 'eth0'
member_1 = '198.51.100.1'
@@ -246,17 +267,17 @@ class TestNAT(VyOSUnitTestSHIM.TestCase):
self.cli_set(dst_path + ['rule', '1', 'inbound-interface', ifname])
self.cli_set(dst_path + ['rule', '1', 'protocol', 'tcp'])
self.cli_set(dst_path + ['rule', '1', 'destination', 'port', dst_port])
- self.cli_set(dst_path + ['rule', '1', 'balance', 'hash', 'source-address'])
- self.cli_set(dst_path + ['rule', '1', 'balance', 'hash', 'source-port'])
- self.cli_set(dst_path + ['rule', '1', 'balance', 'hash', 'destination-address'])
- self.cli_set(dst_path + ['rule', '1', 'balance', 'hash', 'destination-port'])
- self.cli_set(dst_path + ['rule', '1', 'balance', 'member', member_1, 'weight', weight_1])
- self.cli_set(dst_path + ['rule', '1', 'balance', 'member', member_2, 'weight', weight_2])
+ self.cli_set(dst_path + ['rule', '1', 'load-balance', 'hash', 'source-address'])
+ self.cli_set(dst_path + ['rule', '1', 'load-balance', 'hash', 'source-port'])
+ self.cli_set(dst_path + ['rule', '1', 'load-balance', 'hash', 'destination-address'])
+ self.cli_set(dst_path + ['rule', '1', 'load-balance', 'hash', 'destination-port'])
+ self.cli_set(dst_path + ['rule', '1', 'load-balance', 'backend', member_1, 'weight', weight_1])
+ self.cli_set(dst_path + ['rule', '1', 'load-balance', 'backend', member_2, 'weight', weight_2])
self.cli_set(src_path + ['rule', '1', 'outbound-interface', ifname])
- self.cli_set(src_path + ['rule', '1', 'balance', 'hash', 'random'])
- self.cli_set(src_path + ['rule', '1', 'balance', 'member', member_3, 'weight', weight_3])
- self.cli_set(src_path + ['rule', '1', 'balance', 'member', member_4, 'weight', weight_4])
+ self.cli_set(src_path + ['rule', '1', 'load-balance', 'hash', 'random'])
+ self.cli_set(src_path + ['rule', '1', 'load-balance', 'backend', member_3, 'weight', weight_3])
+ self.cli_set(src_path + ['rule', '1', 'load-balance', 'backend', member_4, 'weight', weight_4])
self.cli_commit()
diff --git a/src/conf_mode/nat.py b/src/conf_mode/nat.py
index dea833cf1..fa6fe9bb6 100755
--- a/src/conf_mode/nat.py
+++ b/src/conf_mode/nat.py
@@ -125,17 +125,17 @@ def verify_rule(config, err_msg, groups_dict):
if config['protocol'] not in ['tcp', 'udp', 'tcp_udp']:
raise ConfigError('Protocol must be tcp, udp, or tcp_udp when specifying a port-group')
- if 'balance' in config:
+ if 'load_balance' in config:
for item in ['source-port', 'destination-port']:
- if item in config['balance']['hash'] and config['protocol'] not in ['tcp', 'udp']:
+ if item in config['load_balance']['hash'] and config['protocol'] not in ['tcp', 'udp']:
raise ConfigError('Protocol must be tcp or udp when specifying hash ports')
count = 0
- if 'member' in config['balance']:
- for member in config['balance']['member']:
- weight = config['balance']['member'][member]['weight']
+ if 'backend' in config['load_balance']:
+ for member in config['load_balance']['backend']:
+ weight = config['load_balance']['backend'][member]['weight']
count = count + int(weight)
if count != 100:
- Warning(f'Sum of weight for nat balance rule is not 100. You may get unexpected behaviour')
+ Warning(f'Sum of weight for nat load balance rule is not 100. You may get unexpected behaviour')
def get_config(config=None):
if config:
@@ -210,7 +210,7 @@ def verify(nat):
Warning(f'rule "{rule}" interface "{config["outbound_interface"]}" does not exist on this system')
if not dict_search('translation.address', config) and not dict_search('translation.port', config):
- if 'exclude' not in config and 'member' not in config['balance']:
+ if 'exclude' not in config and 'backend' not in config['load_balance']:
raise ConfigError(f'{err_msg} translation requires address and/or port')
addr = dict_search('translation.address', config)
@@ -222,7 +222,6 @@ def verify(nat):
# common rule verification
verify_rule(config, err_msg, nat['firewall_group'])
-
if dict_search('destination.rule', nat):
for rule, config in dict_search('destination.rule', nat).items():
err_msg = f'Destination NAT configuration error in rule {rule}:'
@@ -233,8 +232,8 @@ def verify(nat):
elif config['inbound_interface'] not in 'any' and config['inbound_interface'] not in interfaces():
Warning(f'rule "{rule}" interface "{config["inbound_interface"]}" does not exist on this system')
- if not dict_search('translation.address', config) and not dict_search('translation.port', config):
- if 'exclude' not in config and 'member' not in config['balance']:
+ if not dict_search('translation.address', config) and not dict_search('translation.port', config) and not dict_search('translation.redirect.port', config):
+ if 'exclude' not in config and 'backend' not in config['load_balance']:
raise ConfigError(f'{err_msg} translation requires address and/or port')
# common rule verification