summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
authorChristian Breunig <christian@breunig.cc>2026-10-17 21:53:37 +0200
committerChristian Breunig <christian@breunig.cc>2026-10-17 21:53:37 +0200
commita0ea6ec9012350d6bda47d86f9f6f7b928acd0d0 (patch)
tree955be424fb58b333ea7a42a66036c2b5b2792e6c /python
parentc01cf102163c93891b17a663790db6c2b8433301 (diff)
downloadvyos-1x-a0ea6ec9012350d6bda47d86f9f6f7b928acd0d0.tar.gz
vyos-1x-a0ea6ec9012350d6bda47d86f9f6f7b928acd0d0.zip
nat: T9475: load-balance rules with a translation port failed to commit
With load-balance backends, the translation port and any translation options were placed between "to" and the hash expression, e.g. "dnat to:80 numgen random ...". nft rejects that and the commit failed. The port is now part of every backend in the map and the options follow the map, so load-balanced port forwarding works.
Diffstat (limited to 'python')
-rw-r--r--python/vyos/nat.py12
1 files changed, 9 insertions, 3 deletions
diff --git a/python/vyos/nat.py b/python/vyos/nat.py
index e70c6b846..9eeb62db6 100644
--- a/python/vyos/nat.py
+++ b/python/vyos/nat.py
@@ -124,19 +124,23 @@ def parse_nat_rule(rule_conf, rule_id, nat_type, ipv6=False):
else:
translation_str = " ".join(translation_output)
- if options:
- translation_str += f' {",".join(options)}'
+ options_str = f' {",".join(options)}' if options else ''
if not ipv6 and 'backend' in rule_conf['load_balance']:
hash_input_items = []
current_prob = 0
nat_map = []
+ # the port has to be part of every map value, nft rejects a port
+ # or options between "to" and the hash expression
+ translation_str = f'{nat_type[:1]}nat {ip_prefix} to' if port else f'{nat_type[:1]}nat to'
+ backend_suffix = f' . {port}' if port else ''
+
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)
- element = hash_val + " : " + trans_addr
+ element = hash_val + " : " + trans_addr + backend_suffix
nat_map.append(element)
current_prob = current_prob + item_prob
@@ -163,6 +167,8 @@ def parse_nat_rule(rule_conf, rule_id, nat_type, ipv6=False):
hash_input = ' . '.join(hash_input_items)
translation_str += f' jhash ' + f'{hash_input}' + f' mod {modulus} map ' + '{ ' + f'{elements}' + ' }'
+ translation_str += options_str
+
for target in ['source', 'destination']:
if target not in rule_conf:
continue