From a0ea6ec9012350d6bda47d86f9f6f7b928acd0d0 Mon Sep 17 00:00:00 2001 From: Christian Breunig Date: Sat, 17 Oct 2026 21:53:37 +0200 Subject: 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. --- python/vyos/nat.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'python') 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 -- cgit v1.2.3