diff --git a/state/dynamic-vlan.yml b/state/dynamic-vlan.yml new file mode 100644 index 0000000..e89027d --- /dev/null +++ b/state/dynamic-vlan.yml @@ -0,0 +1,22 @@ +type: object +description: + This section contains the traffic counters of the logical interface. +properties: + vid: + type: number + rx_bytes: + type: number + description: + The number of bytes received. + rx_packets: + type: number + description: + The number of packets received. + tx_bytes: + type: number + description: + The number of bytes transmitted. + tx_packets: + type: number + description: + The number of packets transmitted. diff --git a/state/interface.ssid.association.yml b/state/interface.ssid.association.yml index 3702d5f..d969cb9 100644 --- a/state/interface.ssid.association.yml +++ b/state/interface.ssid.association.yml @@ -18,6 +18,10 @@ items: type: string description: The MAC address of the station. + dynamic_vlan: + type: number + description: + The VID in case the association is on a dynamic VLAN. rssi: type: number description: diff --git a/state/interface.ssid.yml b/state/interface.ssid.yml index 7107c00..8fb37a2 100644 --- a/state/interface.ssid.yml +++ b/state/interface.ssid.yml @@ -29,6 +29,14 @@ items: type: string description: The physical network device used. + vlan_ifaces: + description: + The list of dynamic vlan interfaces. + type: object + patternProperties: + ^wlan-v: + type: object + $ref: "https://ucentral.io/state/v1/interface/counter/" mode: type: string description: diff --git a/state/state.yml b/state/state.yml index 52d4209..5a415a2 100644 --- a/state/state.yml +++ b/state/state.yml @@ -35,6 +35,10 @@ properties: patternProperties: "^(eth|lan|wan)[0-9]*$": $ref: "https://ucentral.io/state/v1/lldp-peers/" + dynamic_vlans: + type: array + items: + $ref: "https://ucentral.io/state/v1/dynamic-vlan/" link-state: type: object properties: diff --git a/system/state.uc b/system/state.uc index 9a4ddc2..5d97922 100755 --- a/system/state.uc +++ b/system/state.uc @@ -286,6 +286,23 @@ function is_mesh(net, wif) { return true; } +let idx = 0; +let dyn_vlans = {}; +let dyn_vids = []; +for (let k, vlan in devices.up['bridge-vlans']) { + if (vlan.id >= 4000) + continue; + let wlan = []; + for (let port in vlan.ports) { + let dev = split(port, '-v'); + if (+dev[1] != vlan.id) + continue; + if (!dyn_vlans[dev[0]]) + dyn_vlans[dev[0]] = []; + push(dyn_vlans[dev[0]], port); + } +} + /* interfaces */ cursor.load("network"); cursor.foreach("network", "interface", function(d) { @@ -434,6 +451,9 @@ cursor.foreach("network", "interface", function(d) { let vlan = split(k, '-v'); if (vlan[0] != vap.ifname) continue; + if (vlan[1]) + for (let k, assoc in v) + assoc.dynamic_vlan = +vlan[1]; ssid.associations = [ ...(ssid.associations || []), ...v ]; } for (let assoc in ssid.associations) { @@ -461,6 +481,13 @@ cursor.foreach("network", "interface", function(d) { ssid.counters = ports['batman_mesh'].counters; ssid['mesh-path'] = mesh[vap.ifname]; } + if (dyn_vlans[vap.ifname]) { + ssid.vlan_ifaces = {}; + for (let vlan in dyn_vlans[vap.ifname]) { + push(dyn_vids, +split(vlan, '-v')[1]); + ssid.vlan_ifaces[vlan] = ports[vlan]?.counters || {} + } + } push(ssids, ssid); } counter++; @@ -486,6 +513,31 @@ cursor.foreach("network", "interface", function(d) { delete iface.ipv6; }); +dyn_vids = uniq(dyn_vids); +if (length(dyn_vids)) { + state.dynamic_vlans = []; + for (let id in dyn_vids) { + let dyn = { + vid: id, + tx_bytes: 0, + tx_packets: 0, + rx_bytes: 0, + rx_packets: 0 + }; + for (let k, dev in devstats) { + for (let k, vid in dev) { + if (vid.vid != id) + continue; + dyn.tx_bytes += vid.tx.bytes; + dyn.tx_packets += vid.tx.packets; + dyn.rx_bytes += vid.rx.bytes; + dyn.rx_packets += vid.rx.packets; + } + } + push(state.dynamic_vlans, dyn); + } +} + if (length(poe)) { state.poe = {}; state.poe.consumption = poe.consumption;