fix: correct AirFiber proprietary OID mapping and v1-only device support (#169)
Root cause: AF11X devices only support SNMPv1, IF-MIB eth0 counters return zero, and air0 32-bit counters wrap too fast for backhaul speeds. Fixes: - Use correct UBNT-AirFIBER-MIB OID indices from MIB SEQUENCE definition: .7.1 = rxOctetsOK (inbound), .6.1 = txOctetsOK (outbound) .10.1 = rxErroredFrames, .11.1 = txErroredFrames - Detect AirFiber devices by sysDescr instead of SNMP probing (v1 devices cannot return Counter64 via standard probe queries) - Force SNMPv1 for AirFiber proprietary queries - Apply proprietary counters to all real interfaces (not just eth0) Verified against live AF11X at 10.250.1.90: - IF-MIB eth0 returns zero counters - Proprietary .6.1/.7.1 show real traffic (3.75TB rx / 43TB tx) Reviewed-on: graham/towerops-web#169
This commit is contained in:
parent
de455d1cf4
commit
ce682991fe
1 changed files with 32 additions and 20 deletions
|
|
@ -1042,41 +1042,53 @@ defmodule Towerops.Workers.DevicePollerWorker do
|
|||
# because their IF-MIB counters are unreliable.
|
||||
defp detect_airfiber_counter_overrides(nil, _client_opts), do: nil
|
||||
|
||||
defp detect_airfiber_counter_overrides(snmp_device, client_opts) do
|
||||
defp detect_airfiber_counter_overrides(snmp_device, _client_opts) do
|
||||
sys_oid = snmp_device.sys_object_id || ""
|
||||
sys_descr = String.downcase(snmp_device.sys_descr || "")
|
||||
|
||||
cond do
|
||||
# Ubiquiti AirFiber (enterprise OID 41112)
|
||||
String.starts_with?(sys_oid, "1.3.6.1.4.1.41112") ->
|
||||
# Check if it's an LTU device
|
||||
case Client.get(client_opts, "1.3.6.1.4.1.41112.1.10.1.2.2.0") do
|
||||
{:ok, _} -> :airfiber_ltu
|
||||
_ ->
|
||||
# Check for regular AirFiber stats table
|
||||
case Client.get(client_opts, "1.3.6.1.4.1.41112.1.3.3.1.1.1") do
|
||||
{:ok, _} -> :airfiber
|
||||
_ -> nil
|
||||
end
|
||||
end
|
||||
# Ubiquiti AirFiber — detect by sysObjectID (enterprise 41112) or sysDescr
|
||||
# These devices need proprietary MIBs because IF-MIB eth0 counters are zero
|
||||
# and air0 32-bit counters wrap too fast on high-bandwidth links.
|
||||
# Note: detection is based on device identity, not SNMP probing, because
|
||||
# some AirFiber devices only support SNMPv1 (can't return Counter64 via probe).
|
||||
String.starts_with?(sys_oid, "1.3.6.1.4.1.41112") and String.contains?(sys_descr, "airfiber") ->
|
||||
:airfiber
|
||||
|
||||
String.starts_with?(sys_oid, "1.3.6.1.4.1.41112") and String.contains?(sys_descr, "afltu") ->
|
||||
:airfiber_ltu
|
||||
|
||||
true -> nil
|
||||
end
|
||||
end
|
||||
|
||||
# Fetch traffic stats using AirFiber proprietary MIBs (matching LibreNMS behavior)
|
||||
# Fetch traffic stats using AirFiber proprietary MIBs (matching LibreNMS behavior).
|
||||
# LibreNMS applies these counters to the eth0 interface specifically, but TowerOps
|
||||
# should apply them to whichever interface is being tracked (eth0, br0, or air0)
|
||||
# since the proprietary counters represent the radio link's actual throughput.
|
||||
# Only skip lo and sit0 (loopback/tunnel with no real traffic).
|
||||
defp get_airfiber_stats(nil, _interface, _client_opts), do: :not_airfiber
|
||||
defp get_airfiber_stats(_af_type, %{if_descr: descr}, _client_opts)
|
||||
when descr != "eth0" and descr != nil, do: :not_eth0
|
||||
when descr in ["lo", "sit0"], do: :skip_loopback
|
||||
|
||||
defp get_airfiber_stats(:airfiber, _interface, client_opts) do
|
||||
# UBNT-AirFIBER-MIB: airFiberStatistics table (1.3.6.1.4.1.41112.1.3.3.1)
|
||||
# Field order from MIB SEQUENCE: 1=index, 2=txFramesOK, 3=rxFramesOK,
|
||||
# 4=rxFrameCrcErr, 5=rxAlignErr, 6=txOctetsOK, 7=rxOctetsOK,
|
||||
# 8=txPauseFrames, 9=rxPauseFrames, 10=rxErroredFrames, 11=txErroredFrames
|
||||
#
|
||||
# These devices may only support SNMPv1 — use v1 for all queries.
|
||||
# Counter64 values returned via v1 vary by implementation; the Ubiquiti
|
||||
# firmware handles it despite the RFC saying Counter64 is v2c+ only.
|
||||
v1_opts = Keyword.put(client_opts, :version, "1")
|
||||
|
||||
oids = [
|
||||
{"1.3.6.1.4.1.41112.1.3.3.1.1.1", :if_in_octets}, # rxOctetsOK
|
||||
{"1.3.6.1.4.1.41112.1.3.3.1.2.1", :if_out_octets}, # txOctetsOK
|
||||
{"1.3.6.1.4.1.41112.1.3.3.1.5.1", :if_in_errors}, # rxErroredFrames
|
||||
{"1.3.6.1.4.1.41112.1.3.3.1.10.1", :if_out_errors} # txErroredFrames
|
||||
{"1.3.6.1.4.1.41112.1.3.3.1.7.1", :if_in_octets}, # rxOctetsOK
|
||||
{"1.3.6.1.4.1.41112.1.3.3.1.6.1", :if_out_octets}, # txOctetsOK
|
||||
{"1.3.6.1.4.1.41112.1.3.3.1.10.1", :if_in_errors}, # rxErroredFrames
|
||||
{"1.3.6.1.4.1.41112.1.3.3.1.11.1", :if_out_errors} # txErroredFrames
|
||||
]
|
||||
fetch_proprietary_stats(client_opts, oids, true)
|
||||
fetch_proprietary_stats(v1_opts, oids, true)
|
||||
end
|
||||
|
||||
defp get_airfiber_stats(:airfiber_ltu, _interface, client_opts) do
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue