Skip to main content
RunBook Academy

VyOSXLIX · Monitoring and Observability IntegrationMonitoring

Interface metrics — SNMP, NETCONF, gNMI, and the Prometheus exporter

Advanced⏱ ~28 minconfigureshow service snmpshow interfacessnmpwalksnmpgetnet-snmpprometheusnode_exportercurlcommit-confirmrollback

What you'll learn

  • Identify the canonical interface counters (ifInOctets, ifOutOctets, ifInErrors, ifInDiscards, 64-bit vs 32-bit)
  • Configure SNMPv2c and SNMPv3 on VyOS 1.5 LTS with the right view and the right community model
  • Explain the difference between SNMP polling, NETCONF/YANG, gNMI telemetry streams, and the Prometheus pull model
  • Configure the Prometheus node_exporter textfile collector for derived metrics
  • Validate the metrics pipeline end-to-end before alerting on it

Prerequisites

Verified against VyOS 1.5.x LTS (circinus) · VyOS 1.4.x (sagitta) — legacy · FRRouting 10.x (VyOS 1.5) · Linux kernel 6.6 LTS (VyOS 1.5 base) · strongSwan 5.9.x (IPsec) · WireGuard 1.0.x (kernel module + userspace tooling) · 2026-08-15

Not yet marked complete on this device.

A “router is dropping packets” report is not a router problem until the operator has counter evidence. The IF-MIB counters (ifInOctets, ifOutOctets, ifInErrors, ifInDiscards, ifOutErrors, ifOutDiscards) and the per-queue drops in /sys/class/net/<nic>/statistics/ are the canonical evidence. The operator who cannot read those counters in five minutes will spend an hour guessing whether the network is slow, the application is slow, or the report is wrong.

This lesson is the production reference for interface metrics on VyOS 1.5 LTS: the four transport options (SNMP, NETCONF, gNMI, Prometheus), what each one gives the operator, what each one costs, and the validation discipline that prevents the metrics layer from becoming the next source of incidents.

The four transports

flowchart LR
  subgraph ROUTER["VyOS 1.5 router (data plane)"]
    K["Linux kernel<br/>/sys/class/net"]
    F["FRR zebra<br/>interface state"]
  end
  subgraph COLLECT["Collection plane"]
    S["SNMP agent<br/>(snmpd)"]
    N["NETCONF server<br/>(netconfd)"]
    G["gNMI server<br/>(gnmi)"]
    P["Prometheus<br/>node_exporter"]
  end
  subgraph CONSUME["Consumption plane"]
    Z["Zabbix<br/>LibreNMS<br/>Prometheus"]
  end
  K --> S
  K --> N
  F --> N
  K --> G
  K --> P
  S --> Z
  N --> Z
  G --> Z
  P --> Z

SNMP is the most common operational interface. It has existed since 1988, every NMS understands it, and the IF-MIB / IF-MIB-II / EtherLike-MIB provide the canonical counters. The cost: SNMP is a poll model, so the operator must build a polling cadence, and SNMPv2c sends the community string in cleartext (use SNMPv3 for any modern deployment).

NETCONF/YANG is the structured-data alternative. It gives the operator the full configuration tree and operational state, and it is the long-term direction for vendor-neutral network management. The cost: the operator must model the data in YANG, and the tooling is less mature than SNMP.

gNMI (gRPC Network Management Interface) is the streaming-evidence alternative. gNMI supports telemetry subscriptions that push counter deltas to the collector, so the operator sees near-real-time state without polling. The cost: gNMI is the most recent transport, the tooling is still maturing, and VyOS 1.5 LTS has gNMI support via the vyos-gnmi package (optional, not enabled by default).

Prometheus node_exporter is the modern pull-model alternative. The exporter runs on the router, exposes a /metrics endpoint, and the Prometheus server pulls it on a configurable cadence. The cost: the operator must run the exporter (it is not part of the base VyOS image), and the data is in Prometheus format, not the IF-MIB format that NMS tooling expects.

The canonical counters

The IF-MIB defines the canonical interface counters. The operator must know which counters are 32-bit, which are 64-bit, and which are unavailable on virtual interfaces.

flowchart TD
  subgraph IF["IF-MIB (RFC 2863)"]
    O32["ifInOctets (32-bit)"]
    O64["ifHCInOctets (64-bit)"]
    P32["ifInUcastPkts (32-bit)"]
    P64["ifHCInUcastPkts (64-bit)"]
    E["ifInErrors"]
    D["ifInDiscards"]
    U["ifInUnknownProtos"]
  end
  subgraph ETH["EtherLike-MIB (RFC 3635)"]
    EE["dot3StatsFCSErrors"]
    ES["dot3StatsSymbolErrors"]
    EL["dot3StatsExcessiveCollisions"]
  end
  subgraph QS["Linux per-queue /sys/class/net"]
    QD["rx_queue_N.dropped"]
    TF["tx_queue_N.dropped"]
  end

The 32-bit counters wrap at 4 GB; on a 10 Gbps interface, the wrap happens every 3.4 seconds. The 64-bit counters (ifHCInOctets, ifHCOutOctets) wrap at 18 EB and are the only safe choice for high-rate interfaces. The IF-MIB exposes the 32-bit counters via ifInOctets / ifOutOctets and the 64-bit counters via ifXTable (ifHCInOctets, ifHCOutOctets). Every modern NMS polls the 64-bit table.

The Linux per-queue drops (rx_queue_N.dropped, tx_queue_N.dropped) are visible in /sys/class/net/<nic>/statistics/ and are not part of the IF-MIB. The operator correlates interface-level drops (ifInDiscards) with per-queue drops to identify whether the drops are at the driver ring, the qdisc, or the upper layers.

Step 1 — Configure SNMPv3

The operator configures SNMPv3 with authentication and privacy. SNMPv3 with auth (SHA) and priv (AES) is the only acceptable configuration for any network that crosses a trust boundary.

configure
set service snmp v3 engineid '0x80004f7e9c3a1b2c'
set service snmp v3 group default mode 'ro'
set service snmp v3 group default view 'full'
set service snmp v3 view full oid '1' include
set service snmp v3 user monitoring-auth group default auth plaintext-key 'AuthPass-2026-Q3'
set service snmp v3 user monitoring-auth group default auth type 'sha'
set service snmp v3 user monitoring-auth group default privacy plaintext-key 'PrivPass-2026-Q3'
set service snmp v3 user monitoring-auth group default privacy type 'aes'
set service snmp listen-address '10.0.0.1'
commit

The engine ID must be unique per device. The view 1 (the entire MIB tree) is the safe default; restrict the view to ifTable and ifXTable if the NMS only needs interface counters. The ro mode is read-only; the operator does not give SNMP write access to the monitoring system.

After the commit, the operator validates:

$ snmpwalk -v3 -u monitoring-auth -l authPriv -a SHA -A 'AuthPass-2026-Q3' -x AES -X 'PrivPass-2026-Q3' 10.0.0.1 ifHCInOctets
IF-MIB::ifHCInOctets.1 = Counter64: 12345678901234
IF-MIB::ifHCInOctets.2 = Counter64: 98765432109876
IF-MIB::ifHCInOctets.3 = Counter64: 0
IF-MIB::ifHCInOctets.4 = Counter64: 456123789456123

The ifHCInOctets values are present and changing — the metric is live. If the operator sees NULL or noSuchObject, the SNMPv3 handshake failed and the operator must check the engine ID, the user, the password, and the view.

Step 2 — Configure Prometheus node_exporter

The Prometheus pull model is the most common modern alternative. The operator installs the node_exporter binary on the router (via the prometheus-node-exporter package or a manual install) and exposes the metrics on a local port.

configure
# Expose the Prometheus port on the management VRF
set service prometheus node-exporter listen-address '10.0.0.1'
set service prometheus node-exporter port '9100'
set service prometheus node-exporter collectors 'network'
commit

After the commit, the operator curls the metrics endpoint:

$ curl -s http://10.0.0.1:9100/metrics | grep node_network_
node_network_receive_bytes_total{device="eth0"} 1.234e+10
node_network_transmit_bytes_total{device="eth0"} 9.876e+09
node_network_mtu_bytes{device="eth0"} 1500
node_network_up{device="eth0"} 1

The counter is named node_network_receive_bytes_total (the _total suffix is the Prometheus convention for monotonic counters). The Prometheus server records this counter and computes the rate via rate(node_network_receive_bytes_total[5m]) in PromQL.

Step 3 — Configure NETCONF

NETCONF is the structured-data alternative. The operator enables the NETCONF server and the YANG models:

configure
set service netconf listen-address '10.0.0.1'
set service netconf port '830'
set service netconf authentication username 'netconf-user'
set service netconf authentication password 'NetC0nf-2026-Q3'
commit

The operator then uses a NETCONF client (e.g., ncclient in Python) to subscribe to interface state:

$ python3 -c "
from ncclient import manager
with manager.connect_ssh('10.0.0.1', port=830, username='netconf-user', password='NetC0nf-2026-Q3', hostkey_verify=False) as m:
    state = m.get(filter=('xpath', '/ietf-interfaces:interfaces-state')).data_xml
    print(state)
"

The output is structured XML. The operator can parse it with xmlstarlet or lxml and feed it into a time-series database. The cost: the operator must understand YANG, and the tooling is heavier than SNMP.

Step 4 — Configure gNMI telemetry

gNMI is the streaming-evidence alternative. The operator enables the gNMI server and subscribes to a telemetry stream:

configure
set service gnmi listen-address '10.0.0.1'
set service gnmi port '57400'
set service gnmi authentication username 'gnmi-user'
set service gnmi authentication password 'GNm1-2026-Q3'
commit

The operator then uses a gNMI client (e.g., gnmic from Nokia) to subscribe:

$ gnmic -a 10.0.0.1:57400 -u gnmi-user -p 'GNm1-2026-Q3' \
  subscribe --path '/interfaces/interface[name=eth0]/state/counters' \
  --stream-mode sample --sample-interval 10s

The stream produces counter updates every 10 seconds. The operator feeds the stream into a time-series database (e.g., Prometheus remote-write, InfluxDB, or a Kafka pipeline for downstream processing). The cost: gNMI requires the vyos-gnmi package (often not present in the default image), and the tooling is less mature than SNMP.

Validation discipline

Every metric must be validated before it becomes an alert. The validation discipline:

  1. Confirm the metric is present. The operator runs the collection command (snmpwalk, curl /metrics, gNMI subscribe) and confirms the metric is returned.
  2. Confirm the metric is changing. A metric that is present but constant is stale. The operator runs the collection command twice, 5 seconds apart, and confirms the counter has incremented.
  3. Confirm the rate is sensible. The operator computes the rate (octets / delta-time) and compares it to the expected rate. A 10 Gbps interface at 1% utilisation should show ~100 Mbps; if the rate is 100 Gbps, the metric is wrong.
  4. Confirm the metric survives a router reload. The operator reloads the router, waits for it to come back, and confirms the metric is still present and changing. If the metric is missing after a reload, the configuration has not been saved.
  5. Confirm the metric is in the alerting pipeline. The operator runs the alert query (PromQL, NMS rule) and confirms the alert fires under the expected condition.

Production failure modes

The interface-metrics failure modes the operator encounters:

  • SNMPv2c in production. The community string is sent in cleartext; every host on the management network can read the IF-MIB. Fix: migrate to SNMPv3 with auth and priv.
  • Polling the 32-bit counters on a 10 Gbps interface. The counter wraps every 3.4 seconds; the NMS misinterprets the wrap as a negative rate. Fix: poll the 64-bit counters (ifHCInOctets, ifHCOutOctets).
  • Prometheus scraping a router that is not using NTP. The Prometheus server’s timestamps are correct but the router’s /metrics is not; the rate computation is wrong. Fix: configure NTP on the router.
  • Telemetry flooding from gNMI. A subscription with a 1-second sample interval on 1000 paths produces 1,000,000 counter updates per second. The collector cannot keep up. Fix: increase the sample interval, or use on-change subscriptions instead of sample subscriptions.
  • Metrics saved in the configuration but not in the persistent image. The set service snmp ... command is lost on reboot if the operator did not save. Fix: save after every configuration change.
  • Counters reset on routing daemon reload. FRR’s reload re-initialises the zebra RIB counters; the IF-MIB counters are unaffected (they are kernel counters), but the operator must not confuse the two. Fix: correlate IF-MIB counters with /sys/class/net/<nic>/statistics/.

Rollback

Interface-metrics changes are typically configuration-only, but the impact can be cross-cutting. The rollback discipline:

  • SNMP, NETCONF, gNMI, Prometheus — all are in the VyOS tree. The rollback is rollback N and commit.
  • The node_exporter binary — installed outside the VyOS tree. The rollback is to uninstall the package or kill the process.
  • The textfile collector script — installed in /usr/local/bin or /var/lib/node_exporter. The rollback is to remove the script and the cron entry.
  • NMS configuration — the NMS (Zabbix, Prometheus, LibreNMS) is a separate system. The rollback is to revert the NMS configuration, not the router.

For every change, use commit-confirm:

configure
# ... make the change ...
commit-confirm 5
# If the change has unintended consequences, the auto-rollback
# fires after 5 minutes and the previous configuration is restored.

Production discipline

Cross-course references

  • Part VII (XLIX-VyOS-Monitoring / vii-05-interface-diagnostics) covers the operational commands (show interfaces, monitor interfaces) that the metrics layer is built on.
  • The Observability course covers the consumer side: Prometheus, Grafana, alerting on counter deviation.
  • The Ansible course’s XLII-Ansible-BeyondLinux covers the automation hand-off (rolling out SNMPv3 to a fleet via a single playbook).
  • The Linux course’s V-Linux-NetConfig covers the underlying counter primitives (/sys/class/net/<nic>/statistics/) at the host level.
  • The Observability course’s III-Observability-MetricsTypes covers the counter vs gauge distinction and the rate computation that Prometheus performs.

Quiz

Knowledge check · 4 questions

  1. Q1. An operator is polling interface counters on a 10 Gbps link. The counter should be the 64-bit IF-MIB counter, not the 32-bit one. Which OID is the 64-bit input octet counter?

  2. Q2. Configuring SNMPv2c with a community string on a router reachable from the management network is acceptable if the management network is private.

  3. Q3. An operator configures SNMPv3 on VyOS 1.5 LTS and runs `snmpwalk -v3 -u monitoring-auth -l authPriv -a SHA -A 'AuthPass-2026-Q3' -x AES -X 'PrivPass-2026-Q3' 10.0.0.1 ifHCInOctets`. The output is `Timeout: No Response from 10.0.0.1`. The router is reachable on the management interface. What is the first thing to check?

    R1 is a VyOS 1.5 LTS edge router. The operator has configured SNMPv3 with a user named `monitoring-auth`, SHA authentication, AES privacy. The operator runs `snmpwalk` from the NMS server (10.0.1.50) against the router (10.0.0.1). The router is reachable on the management interface (ping succeeds). The `snmpwalk` command returns `Timeout: No Response from 10.0.0.1`. The operator has not yet validated the SNMPv3 configuration.

  4. Q4. An operator needs to expose the per-VRF route count from VyOS 1.5 LTS as a Prometheus metric. The built-in node_exporter does not have a 'per-VRF route count' collector. The operator decides to use the textfile collector. What is the canonical pattern?

    R1 has three VRFs: `default`, `mgmt`, and `customer-a`. The NMS polls the route count for each VRF every 5 minutes and alerts if any VRF grows by more than 10% in a 24-hour window. The built-in `node_network_*` metrics cover the interface counters but not the per-VRF route count. The operator must build a derived metric.

Passing score: 75%. Answers are checked in this browser.