diff options
| author | Daniil Baturin <daniil@vyos.io> | 2026-04-07 13:50:06 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-04-07 13:50:06 +0100 |
| commit | b7d191cd3053a736fa14ebfefe7a95093b0fcacd (patch) | |
| tree | f9279c0bda74b578e58140f3e90b184613139790 /src/migration-scripts | |
| parent | 229cd51b7dda3fed93dd7da2aa1b131221e9aa75 (diff) | |
| parent | 227699e62146c71c3a0d3923650edd247b20ef16 (diff) | |
| download | vyos-1x-b7d191cd3053a736fa14ebfefe7a95093b0fcacd.tar.gz vyos-1x-b7d191cd3053a736fa14ebfefe7a95093b0fcacd.zip | |
Merge pull request #5103 from alexandr-san4ez/T8281-current
firewall: T8281: Normalize network prefixes in rule configuration
Diffstat (limited to 'src/migration-scripts')
| -rw-r--r-- | src/migration-scripts/firewall/10-to-11 | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/src/migration-scripts/firewall/10-to-11 b/src/migration-scripts/firewall/10-to-11 index 50d3eb89b..f608c200d 100644 --- a/src/migration-scripts/firewall/10-to-11 +++ b/src/migration-scripts/firewall/10-to-11 @@ -36,10 +36,57 @@ # set firewall [ipv4 | ipv6] input filter rule <5,10,15,...> action jump # set firewall [ipv4 | ipv6] input filter rule <5,10,15,...> jump-target <name> +# T8281: Normalize firewall rule network prefixes for source and destination address +# +# Fixes invalid/non-canonical prefixes like: +# 10.10.10.1/30 -> 10.10.10.0/30 +# 2001:db8::1/64 -> 2001:db8::/64 +# +# Only "source address" and "destination address" are rewritten. + +from ipaddress import ip_network from vyos.configtree import ConfigTree base = ['firewall'] + +def normalize_address(config: ConfigTree, path: list[str]): + if not config.exists(path): + return + + def normalize(value: str) -> str | None: + if '/' not in value: + return None + + is_except = value.startswith('!') + if is_except: + value = value.lstrip('!') + + try: + new_value = str(ip_network(value, strict=False)) + except ValueError: + return None + + return f'!{new_value}' if is_except else new_value + + value = config.return_value(path) + if value: + normalized = normalize(value) + if normalized and normalized != value: + config.set(path, value=normalized) + + +def migrate_ruleset(config: ConfigTree, ruleset_base: list[str]): + if not config.exists(ruleset_base + ['rule']): + return + + for rule_id in config.list_nodes(ruleset_base + ['rule']): + rule_base = ruleset_base + ['rule', rule_id] + + for direction in ['source', 'destination']: + normalize_address(config, rule_base + [direction, 'address']) + + def migrate(config: ConfigTree) -> None: if not config.exists(base): # Nothing to do @@ -185,3 +232,25 @@ def migrate(config: ConfigTree) -> None: inp_ipv6_rule = inp_ipv6_rule + 5 config.delete(base + ['interface']) + + ### Normalize/fix firewall rule network prefixes for source and destination address (T8281) + for family in ['ipv4', 'ipv6', 'bridge']: + # 1) Named rulesets: + # set firewall ipv4|ipv6|bridge name <ruleset> rule <id> ... + ruleset_base = base + [family, 'name'] + if config.exists(ruleset_base): + for ruleset in config.list_nodes(ruleset_base): + migrate_ruleset(config, ruleset_base + [ruleset]) + + # 2) Hook-based rulesets: + # set firewall ipv4|ipv6|bridge input|output|forward filter|raw rule <id> ... + # set firewall ipv4|ipv6 prerouting raw rule <id> ... + hook_rulesets = { + 'input': ['filter', 'raw'], + 'output': ['filter', 'raw'], + 'forward': ['filter', 'raw'], + 'prerouting': ['raw'], + } + for hook, rulesets in hook_rulesets.items(): + for ruleset in rulesets: + migrate_ruleset(config, base + [family, hook, ruleset]) |
