NETCONF
NETCONF protocol sessions, RPC operations, and YANG model-driven configuration management.
Enable NETCONF on IOS-XE
Switch(config)# netconf-yang
Switch(config)# netconf-yang feature candidate-datastore
candidate-datastore enables the candidate config — edit without affecting running until you commit. Without it, edit-config writes directly to running (which is the default IOS-XE behavior).
Switch# show netconf-yang sessions
Switch# show netconf-yang sessions detail
Switch# show platform software yang-management process
YANG Models
NETCONF is the transport. YANG is the data model that defines the structure. IOS-XE supports three model families:
-
IETF models —
ietf-interfaces,ietf-ip,ietf-routing. Standards-based, multi-vendor. -
OpenConfig models —
openconfig-interfaces,openconfig-bgp. Vendor-neutral, opinionated. -
Cisco native models —
Cisco-IOS-XE-native,Cisco-IOS-XE-interfaces-oper. Full device coverage, IOS-XE specific.
Switch# show netconf-yang datastores
Or retrieve capabilities via a NETCONF session (the server sends them in the <hello> message).
ncclient — Python NETCONF Client
from ncclient import manager
import xmltodict
m = manager.connect(
host="10.50.1.10",
port=830,
username="admin",
password="<PASSWORD>",
hostkey_verify=False
)
# Get full running config
config = m.get_config(source="running")
print(config)
filter_xml = """
<filter xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"/>
</filter>
"""
result = m.get_config(source="running", filter=filter_xml)
print(result)
edit_xml = """
<config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
<interface>
<name>GigabitEthernet1</name>
<description>Uplink to Core</description>
</interface>
</interfaces>
</config>
"""
m.edit_config(target="running", config=edit_xml)
Candidate Datastore Workflow
If candidate-datastore is enabled, use the lock-edit-validate-commit pattern:
with manager.connect(...) as m:
# Lock candidate to prevent concurrent edits
m.lock(target="candidate")
# Edit candidate (not running)
m.edit_config(target="candidate", config=edit_xml)
# Validate before committing
m.validate(source="candidate")
# Commit candidate to running
m.commit()
# Unlock
m.unlock(target="candidate")
This is the same workflow as Junos or any NETCONF device with candidate support. The advantage: you can build up multiple changes, validate them together, and commit atomically.
XPath Filters vs Subtree Filters
# Get only Loopback interfaces
filter_xml = """
<filter>
<interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
<interface>
<type xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type">
ianaift:softwareLoopback
</type>
</interface>
</interfaces>
</filter>
"""
filter_xpath = "/interfaces/interface[type='ianaift:softwareLoopback']"
result = m.get_config(source="running", filter=("xpath", filter_xpath))
Not all IOS-XE versions support XPath filters. Subtree filters always work.
Raw NETCONF via SSH
ssh -p 830 admin@10.50.1.10 -s netconf
The device sends its <hello> with capabilities. Send your <hello> back, then issue RPC operations. Each message ends with ]]>]]> (NETCONF 1.0) or chunked framing (1.1).
Operational Data (get vs get-config)
-
get-config— retrieves configuration data only (what you configured). -
get— retrieves configuration AND operational/state data (counters, status, neighbors).
# Get operational interface data -- counters, oper-status
oper_filter = """
<filter>
<interfaces-state xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"/>
</filter>
"""
result = m.get(filter=oper_filter)
Verification and Troubleshooting
Switch# show netconf-yang sessions (1)
Switch# show netconf-yang statistics (2)
Switch# debug netconf-yang level debug (3)
| 1 | Active NETCONF sessions with session ID and user |
| 2 | RPC counts — in/out, errors, notifications |
| 3 | Full NETCONF message trace — very verbose, lab only |