feat: include VLAN tag in get_networks() output

Routed subnets on 802.1Q sub-interfaces now report their vlan_id so
callers can associate a subnet with the VLAN it belongs to. None for
untagged interfaces.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Christian Manivong
2026-06-12 17:17:15 +02:00
co-authored by Claude Sonnet 4.6
parent 5d5bd77b08
commit b93628ac57
+18 -5
View File
@@ -298,7 +298,11 @@ class OPNsenseDriver(FirewallDriver):
"gateway": "192.168.1.1", "gateway": "192.168.1.1",
"family": "ipv4", "family": "ipv4",
"prefix_length": 24, "prefix_length": 24,
"vlan_id": 20,
} }
``vlan_id`` is ``None`` for interfaces that are not 802.1Q VLAN
sub-interfaces (e.g. the untagged management/LAN interface).
""" """
import ipaddress import ipaddress
@@ -307,7 +311,7 @@ class OPNsenseDriver(FirewallDriver):
networks: List[Dict[str, Any]] = [] networks: List[Dict[str, Any]] = []
def _add(ifname: str, cidr: str, family: str) -> None: def _add(ifname: str, cidr: str, family: str, vlan_id: int | None) -> None:
"""Parse a CIDR string (e.g. '10.0.0.1/24') and append to networks.""" """Parse a CIDR string (e.g. '10.0.0.1/24') and append to networks."""
try: try:
iface_obj = ipaddress.ip_interface(cidr) iface_obj = ipaddress.ip_interface(cidr)
@@ -320,6 +324,7 @@ class OPNsenseDriver(FirewallDriver):
"gateway": str(iface_obj.ip), "gateway": str(iface_obj.ip),
"family": family, "family": family,
"prefix_length": net.prefixlen, "prefix_length": net.prefixlen,
"vlan_id": vlan_id,
}) })
except ValueError: except ValueError:
pass pass
@@ -329,13 +334,21 @@ class OPNsenseDriver(FirewallDriver):
if not name: if not name:
continue continue
vlan_id: int | None = None
raw_tag = iface.get("vlan_tag")
if raw_tag:
try:
vlan_id = int(raw_tag)
except (TypeError, ValueError):
vlan_id = None
# Primary format: flat CIDR strings in addr4/addr6 # Primary format: flat CIDR strings in addr4/addr6
addr4: str = iface.get("addr4", "") addr4: str = iface.get("addr4", "")
addr6: str = iface.get("addr6", "") addr6: str = iface.get("addr6", "")
if addr4: if addr4:
_add(name, addr4, "ipv4") _add(name, addr4, "ipv4", vlan_id)
if addr6: if addr6:
_add(name, addr6, "ipv6") _add(name, addr6, "ipv6", vlan_id)
# Fallback: ipv4/ipv6 arrays where ipaddr may include prefix # Fallback: ipv4/ipv6 arrays where ipaddr may include prefix
if not addr4: if not addr4:
@@ -344,14 +357,14 @@ class OPNsenseDriver(FirewallDriver):
subnet = entry.get("subnetbits") or entry.get("prefix_length") subnet = entry.get("subnetbits") or entry.get("prefix_length")
cidr = f"{ip_field}/{subnet}" if subnet and "/" not in ip_field else ip_field cidr = f"{ip_field}/{subnet}" if subnet and "/" not in ip_field else ip_field
if cidr: if cidr:
_add(name, cidr, "ipv4") _add(name, cidr, "ipv4", vlan_id)
if not addr6: if not addr6:
for entry in iface.get("ipv6") or []: for entry in iface.get("ipv6") or []:
ip_field = entry.get("ipaddr") or entry.get("ip", "") ip_field = entry.get("ipaddr") or entry.get("ip", "")
prefix = entry.get("prefixlen") or entry.get("prefix_length") prefix = entry.get("prefixlen") or entry.get("prefix_length")
cidr = f"{ip_field}/{prefix}" if prefix and "/" not in ip_field else ip_field cidr = f"{ip_field}/{prefix}" if prefix and "/" not in ip_field else ip_field
if cidr: if cidr:
_add(name, cidr, "ipv6") _add(name, cidr, "ipv6", vlan_id)
return networks return networks