C9800 Model-Driven Telemetry: Streaming Wireless Data with YANG and gRPC
You're managing a large Cisco Catalyst 9800 wireless deployment. Everything runs smoothly, but you need deeper operational insights. You want to monitor client join times, track access point performance metrics in real-time, and correlate wireless KPIs with your network infrastructure. Traditional polling methods consume bandwidth and introduce latency. Model-driven telemetry (MDT) solves this problem by enabling continuous streaming of operational data from your C9800 controller directly to a collector, using standardized protocols and YANG data models. This article explains how MDT works on the C9800, how to configure it, and how to build dashboards that give you actionable wireless insights.
Why Model-Driven Telemetry Matters
Traditional management approaches rely on polling (such as SNMP). You ask the device for data at regular intervals, wait for a response, and hope nothing important happens between polls. With large wireless networks generating millions of metrics per second, polling introduces three critical challenges:
- Polling creates unnecessary network overhead, forcing you to balance data freshness against bandwidth consumption.
- You miss rapid state changes that occur between poll intervals (imagine an AP joining and leaving during a 60-second polling cycle).
- The C9800 must process many requests simultaneously, consuming CPU cycles that could go toward managing clients.
Model-driven telemetry flips this model. Instead of asking the device for data, the C9800 publishes operational data asynchronously, pushing updates to a collector only when data changes (on-change) or at regular, predictable intervals (periodic). This approach reduces overhead, improves data freshness, and provides a natural stream of events that tell the story of your wireless network in real-time.
The key phrase in MDT is "model-driven." Unlike unstructured logs, MDT uses YANG data models to organize telemetry. YANG (defined in RFC 6020 and RFC 7950) is a standardized data modeling language. When you combine YANG models with standard protocols like NETCONF, RESTCONF, and gRPC, you get a management framework that scales across heterogeneous networks.
Understanding the MDT Roles and Architecture
Model-driven telemetry involves three key players. Understanding these roles helps you design a telemetry pipeline that meets your operational needs.
| Role | Description | Responsibility |
|---|---|---|
| Management Agent | External system that initiates subscriptions | Sends subscription requests to the C9800, specifying what data to stream and how often. Often a management platform or orchestration system. |
| Publisher | The C9800 Wireless Controller | Collects operational data (client counts, AP metrics, VLAN status) and publishes it to subscribers using configured protocols (NETCONF, RESTCONF, gRPC). |
| Collector | Data collection system receiving streams | Accepts telemetry data from the C9800, processes it, and stores it in a database or visualization tool (Telegraf, InfluxDB, Grafana, etc.). |
The subscription flow is straightforward: a management agent connects to the C9800, requests telemetry for specific operational data (using a YANG path), and specifies the transport protocol and frequency. The C9800 then streams data either immediately for on-change events or at periodic intervals. If the collector disconnects, the subscription ends, and the C9800 stops sending data (important for dial-out subscriptions, which remain static on the controller).
Protocol Choices for Telemetry: NETCONF, RESTCONF, and gRPC
The C9800 supports three transport protocols for MDT. Your choice depends on your existing infrastructure and performance requirements.
| Protocol | Transport | Encoding | Best For | Considerations |
|---|---|---|---|---|
| NETCONF | SSH (port 830) | XML | Structured config changes and operational queries | Higher overhead due to XML; requires SSH key management; well-established standard (RFC 6020). |
| RESTCONF | HTTPS (port 443) | XML or JSON | RESTful integrations and HTTP-based collectors | More flexible encoding; leverages standard HTTPS; good for web-based tools. |
| gRPC | TCP (custom port, typically 57344) | Protocol Buffers (kvGPB) | High-volume telemetry and real-time streaming | Most efficient encoding and transport; lowest latency; modern streaming standard; requires gRPC client library. |
For high-frequency telemetry (multiple updates per second), gRPC with Protocol Buffers is recommended. For lighter loads and existing NETCONF-based workflows, NETCONF or RESTCONF are appropriate.
Enabling Model-Driven Telemetry on the C9800
Before streaming telemetry, you must enable the transport protocols on your C9800. Here's the configuration sequence for each protocol.
Enabling NETCONF
NETCONF requires AAA authentication. Configure a local user or RADIUS backend, then enable NETCONF:
C9800-telemetry(config)# aaa new-model
C9800-telemetry(config)# aaa authentication login default local
C9800-telemetry(config)# aaa authorization exec default local
C9800-telemetry(config)# username netconfuser privilege 15 secret netconfpass
C9800-telemetry(config)# netconf-yangNETCONF uses port 830 by default. Verify with show platform software yang-management process, which displays running YANG-related daemons (confd, ncclient, ncsshd, etc.).
Enabling RESTCONF
RESTCONF requires the HTTP server. Enable it and RESTCONF:
C9800-telemetry(config)# restconf
C9800-telemetry(config)# ip http secure-serverVerify RESTCONF status with show platform software yang-management process. RESTCONF listens on HTTPS port 443.
Enabling gRPC Network Management Interface (gNMI)
For production use, gNMI should run in secure mode with TLS. First, enable it in insecure mode for testing:
C9800-telemetry(config)# gnmi
C9800-telemetry(config)# gnmi serverFor secure mode, install certificates and configure TLS:
C9800-telemetry(config)# gnmi
C9800-telemetry(config)# gnmi server
C9800-telemetry(config)# gnmi secure-server
C9800-telemetry(config)# gnmi secure-trustpoint trustpoint_name
C9800-telemetry(config)# gnmi secure-client-authBy default, secure gNMI uses port 9339 and insecure gNMI uses port 50052. You can override these if needed. Verify status with show gnxi state.
YANG Models: Configuration vs. Operational Data
The C9800 exposes operational data through YANG models. Unlike configuration data (which you can write), operational data is read-only. This distinction is critical for telemetry.
| Data Type | Access | Purpose | Examples |
|---|---|---|---|
| Configuration | Read-write | Persistent settings stored on the controller | WLAN names, security policies, interface configs |
| Operational | Read-only | Real-time state that changes dynamically | Connected clients, AP status, traffic counters, client join events |
For telemetry, you subscribe to operational data. The C9800 YANG models follow a standard structure. For example, the operational model for clients is located in the ietf-interfaces container under interfaces-state. Configuration models use a separate interfaces container.
To find available operational paths, use YANG Suite (a Cisco development tool) or search GitHub for the specific C9800 release. For release 17.6.1, models are available at https://github.com/YangModels/yang/tree/master/vendor/cisco/se/1761.
Polling vs. Subscribing: Which Strategy?
MDT supports two subscription models. Choosing between them shapes how your telemetry pipeline operates.
Periodic Subscriptions
You specify an interval (in milliseconds), and the C9800 sends the same data at regular periods. For example, every 5 seconds, send the count of connected clients. Periodic subscriptions are hierarchical: if you subscribe to a parent path, you receive all leaves under that path. This is efficient for metrics that change gradually.
On-Change Subscriptions
The C9800 sends data only when the value changes. For example, subscribe to VLAN status and receive a notification only when a VLAN transitions to active or inactive. On-change subscriptions are not hierarchical: you receive data for the exact leaf you subscribed to, not parent containers.
On-change can trigger floods of updates if many changes occur rapidly (imagine 100 APs joining simultaneously). To prevent this, use a dampening period: the controller waits a specified interval before sending the next update, even if the value has changed. Only dampening period 0 (no dampening) is supported as of release 17.6.1.
Choose periodic for stable metrics (client counts, throughput) and on-change for state transitions (AP join/leave, client authentication events).
Dial-Out vs. Dial-In: Who Initiates the Connection?
MDT subscriptions can be created in two ways, and the direction of initiation matters.
Dial-Out Subscriptions
You configure subscriptions directly on the C9800 using CLI or NETCONF. The controller initiates connections to a remote collector. These subscriptions are static, stored in the running configuration, and survive a reload. The C9800 continuously tries to connect to the receiver IP address you specify.
Example configuration:
telemetry ietf subscription 1
encoding encode-kvgb
filter xpath /wireless-ap-global-oper:ap-global-oper-data/ap-join-stats/ap-join-info/ap-name
source-address 192.168.20.150
stream yang-push
update-policy periodic 500
receiver ip address 192.168.30.188 57000 protocol grpc-tcpThis configuration creates a periodic subscription that sends AP join statistics every 500 milliseconds using gRPC to a collector at 192.168.30.188:57000. If the connection drops due to reload or network issues, the C9800 automatically reestablishes it.
Dial-In Subscriptions
An external management agent (running NETCONF, RESTCONF, or gNMI) connects to the C9800 and creates a subscription on-the-fly. These are dynamic, tied to the session, and disappear when the session ends. If you stop your Python script or collector, the subscription is removed.
Dial-in is useful for temporary monitoring, testing, and scenarios where you want the collector to control what data it receives. Dial-out is better for production, persistent monitoring.
| Aspect | Dial-Out | Dial-In |
|---|---|---|
| Configuration Location | Static on C9800 | Dynamic, defined by external agent |
| Initiation | C9800 connects to collector | Collector connects to C9800 |
| Persistence | Survives reload; automatically reconnects | Dies when session ends; must be recreated |
| Best Use Case | Production monitoring, permanent metrics | Testing, development, temporary subscriptions |
Building Subscriptions with XPath Filters
When you subscribe to operational data, you specify which data you want using an XPath filter. XPath (XML Path Language) is a notation for selecting nodes in an XML tree. Understanding XPath is essential for targeting the right telemetry.
YANG modules define a module prefix and namespace. For example, the wireless operational model uses the prefix wireless-ap-global-oper. To subscribe to AP join statistics, you construct the path:
/wireless-ap-global-oper:ap-global-oper-data/ap-join-stats/ap-join-info/ap-nameThe module prefix (before the colon) matches the namespace in the YANG file. The rest is the path through the data hierarchy. You can use wildcards or predicates to filter further:
/wireless-ap-global-oper:ap-global-oper-data/ap-join-stats/ap-join-info— Subscribe to all AP join info entries./wireless-client-global-oper:client-global-oper-data/client-live-stats— Subscribe to all client statistics.
YANG Suite provides a graphical interface to browse modules and construct XPaths, making this process easier than manually reading YANG files.
Real-World Example: Building a Dial-In Telemetry Subscription
Let's create a dial-in subscription using Python and the ncclient library to receive AP join statistics every 5 seconds:
from ncclient import manager
# Connect to C9800
mgr = manager.connect(
host='192.168.1.1',
port=830,
username='admin',
password='admin',
hostkey_verify=False
)
# Define subscription XML (NETCONF)
subscription_xml = """
<establish-subscription xmlns="urn:ietf:params:xml:ns:yang:ietf-event-notifications">
<stream>yang-push</stream>
<xpath-filter>
/wireless-ap-global-oper:ap-global-oper-data/ap-join-stats/ap-join-info
</xpath-filter>
<update-policy>
<periodic>
<period>5000</period>
</periodic>
</update-policy>
</establish-subscription>
"""
# Send subscription request
rpc = mgr.dispatch(subscription_xml)
# Listen for notifications
print("Waiting for telemetry updates...")
while True:
notification = mgr.take_notification()
print(notification)
When you run this script, the C9800 streams AP join statistics as XML notifications. Each notification contains the AP name, join time, MAC address, and other metrics. You can parse these notifications and insert them into a database.
Common Telemetry Paths for Wireless Operations
Here are frequently-used operational paths for C9800 telemetry:
| Metric | YANG Path | Typical Use Case |
|---|---|---|
| Client Join Events | /wireless-ap-global-oper:ap-global-oper-data/ap-join-stats/ap-join-info | Monitor client onboarding, track join failures |
| Client Live Statistics | /wireless-client-global-oper:client-global-oper-data/client-live-stats | Real-time client count, throughput, RSSI per band |
| AP Statistics | /wireless-ap-global-oper:ap-global-oper-data/ap-global-info | AP uptime, client count per AP, model info |
| VLAN Status | /ietf-interfaces:interfaces-state/interface | Track VLAN state changes, uptime |
| Interface Counters | /ietf-interfaces:interfaces-state/interface/statistics | Monitor traffic, errors, and discards |
Verify paths exist by checking the YANG models for your C9800 release. Not all paths support on-change subscriptions; test periodically first if unsure.
Building a Telemetry Pipeline with Telegraf, InfluxDB, and Grafana
Once you have subscriptions configured, the next step is collecting, storing, and visualizing the data. A typical stack uses Telegraf (collector), InfluxDB (time-series database), and Grafana (visualization).
Step 1: Configure a Dial-Out Subscription on the C9800
telemetry ietf subscription 23
encoding encode-kvgb
filter xpath /wireless-client-global-oper:client-global-oper-data/client-live-stats
stream yang-push
update-policy periodic 1000
receiver ip address 192.168.30.188 57000 protocol grpc-tcp
This sends client statistics every 1 second via gRPC to Telegraf listening on 192.168.30.188:57000.
Step 2: Configure Telegraf to Accept gRPC Telemetry
Telegraf includes a Cisco gRPC telemetry input plugin. Configure it:
[[inputs.cisco_telemetry_mdt]]
transport = "grpc"
service_address = ":57000"
Telegraf decodes gRPC telemetry, tags it with metadata, and writes it to InfluxDB. The gRPC payload is automatically decoded from Protocol Buffers into readable metrics.
Step 3: Query and Visualize in Grafana
In Grafana, query InfluxDB for client statistics:
SELECT COUNT(field_value) FROM "wireless_client_global_oper"
WHERE time > now() - 1h GROUP BY time(5m)
Create panels for client count, client state distribution (RUN vs. AUTH), and per-AP metrics. Use alerts to notify you when client counts drop unexpectedly or when specific APs go offline.
Troubleshooting Telemetry Issues
When telemetry doesn't flow as expected, check these points:
Verify protocol is running: Use show gnxi state for gRPC, show platform software yang-management process for all protocols. Services should show "Running" status.
Check subscription status: View configured subscriptions with show telemetry ietf subscription all or show telemetry ietf subscription detail. Verify state is "Valid" and the receiver IP is reachable.
Verify receiver connectivity: Ping the receiver IP from the C9800. If using gRPC, ensure the port is open and the receiver is listening (check with netstat or ss on the collector host).
Test with on-change subscriptions first: If you only need periodic data, start with a short periodic interval (500 ms) to verify the path works before adding complexity.
Common errors: If you see "XPATH_NOT_SUPPORTED" in logs, the specified path doesn't support the subscription type (on-change vs. periodic). If you see "NOT_SUPPORTED," the path doesn't exist in the YANG model for your release.
Key Takeaways
Model-driven telemetry on the Cisco Catalyst 9800 replaces inefficient polling with continuous, efficient data streaming:
- MDT uses YANG data models, standard protocols (NETCONF, RESTCONF, gRPC), and subscription-based streaming to deliver operational data to external collectors with minimal overhead.
- Choose gRPC with Protocol Buffers for high-volume telemetry; use NETCONF or RESTCONF for lighter loads or existing REST-based workflows.
- Configure dial-out subscriptions on the C9800 for production persistent monitoring; use dial-in subscriptions for temporary testing and development.
- Understand XPath filters and YANG paths so you can target the exact data you need (client join events, AP statistics, VLAN state, etc.).
- Build a collector pipeline using Telegraf, InfluxDB, and Grafana to aggregate telemetry from your entire wireless deployment and create actionable dashboards.
- Always verify that the protocol is enabled, subscriptions are valid, and the receiver is reachable before assuming telemetry is broken.
By implementing model-driven telemetry, you gain visibility into wireless network behavior at the granularity and speed required for modern operations. You move from reactive troubleshooting (something broke, now let me investigate) to proactive management (continuous data tells me exactly what's happening right now).