Development

This commit is contained in:
Matthew Grotke 2026-06-05 22:16:52 -04:00
parent 096904c723
commit cb0fb0bdaf
12 changed files with 89 additions and 8 deletions

View file

@ -845,6 +845,26 @@ def validate_config(data):
nat_check_port(f"{label} dest_port", r.get("dest_port"))
nat_check_port(f"{label} nat_port", r.get("nat_port"))
nat_check_ip(f"{label} nat_ip", r.get("nat_ip", ""))
if r.get("enabled"):
nat_ip_str = r.get("nat_ip", "")
try:
nat_addr = ipaddress.IPv4Address(nat_ip_str)
for v in _all_vlans:
if not v.get("restricted_vlan"):
continue
try:
vnet = ipaddress.IPv4Network(f"{v['subnet']}/{v['subnet_mask']}", strict=False)
except Exception:
continue
if nat_addr in vnet:
errors.append(
f"Port forwarding rule '{desc}' is enabled but its destination "
f"({nat_ip_str}) is on restricted VLAN '{v['name']}'. "
f"Disable the rule or remove the restricted_vlan flag."
)
break
except Exception:
pass
for r in data.get("inter_vlan_exceptions", []):
desc = r.get("description", "?")
@ -930,3 +950,32 @@ def validate_config(data):
errors.append(f"{lbl}: '{ip_val}' is not a valid IP, CIDR, or wildcard pattern.")
return errors
def disable_portfwd_on_restricted_vlans(data):
"""Auto-disable enabled port forwarding rules whose nat_ip falls within a restricted VLAN's subnet.
Mutates data in place. Returns list of descriptions of rules that were disabled."""
restricted_nets = []
for v in data.get('vlans', []):
if v.get('restricted_vlan'):
try:
restricted_nets.append(ipaddress.IPv4Network(f"{v['subnet']}/{v['subnet_mask']}", strict=False))
except Exception:
pass
if not restricted_nets:
return []
disabled = []
for rule in data.get('port_forwarding', []):
if not rule.get('enabled'):
continue
try:
addr = ipaddress.IPv4Address(rule.get('nat_ip', ''))
except Exception:
continue
if any(addr in net for net in restricted_nets):
rule['enabled'] = False
disabled.append(rule.get('description') or rule.get('nat_ip', '?'))
return disabled