Intro to YANG/NETCONF
Last updated
Last updated
Before we talk about what YANG and NETCONF are and how they work, let’s explore why they were invented in the first place.
Traditionally the CLI has been used for network automation. A script connects to network devices via SSH and performs operational and configuration commands, using screen-scraping to validate the changes. Each vendor has a different CLI, so this requires lots of different drivers which can handle the CLI syntax and screen-scraping of each OS type. This lack of standardization and lack of structred output from the CLI creates a big hurdle when developing network automation tools.
For example, when using Netmiko, you must specify the device_type for a device you are connecting to. The netmiko library needs to handle every device differently which is a huge burden. vEOS, ASA, IOS, IOS-XR, Junos, etc. are all handled differently.
A CLI can also be updated by a vendor on a whim. For example, Cisco can choose to rename a show command from show int trunk to show trunk. This makes the CLI fragile and suseptible to a version upgrade breaking an existing script. Every update requires a bug submission, like the one below, and an update to that particular device type’s library.
Here a user reports that the new WLC version has a different output on show inventory which breaks ssh_autodetect functionality.
Additionally, if you want to achieve the same type of configuration changes on different devices, you need to write different scripts that handle each device’s command syntax, or use a library that has put in the pain-staking work to handle each device type for you. However, as you saw above, these can break easily.
I find that the multi-vendor problem is much more prevalent in service provider networks, where the use of demarcation boxes from ten different vendors is commonplace. In the enterprise you are more likely to see 100% vendor lock-in with access/distribution/core switching and routing equipment.
Simply put, the CLI is not a suitable API. This prompts the need for a model-driven management framework, which is why YANG/NETCONF was developed.
SNMP uses MIBs that vendors generally adhere to (at least for the core MIBs such as interface MIBs). You might wonder why we can’t just push configuration that adheres to MIBs via SNMP to devices.
One reason is that the use of UDP is poor for bulk data transfer. Also MIBs are complex to develop and different vendors have different proprietary MIBs. There is too large of a gap between the specificity of individual MIBs and the order of operations when preforming configurations on a device. The MIBs don’t really say how and in what order to make changes to a device, and there isn’t a built-in way to do rollbacks.
Personally I recall a time where a change to AAA on routers my team inherited from another company prevented us from logging in. We realized that the local username set on the device was from the previous company and we never changed it. So we could not SSH to the devices any longer to roll back the change. I noticed that SNMP was still working, so I spent a lot of time figuring out if I could push a command from SNMP. This resulted in a few hours of attempts that were ultimately not successful.
For these reasons, SNMP is generally only used as a monitoring protocol - not as a configuration management tool.
YANG stands for Yet Another Next Generation, which is kind of a silly name similar to YAML (YAML Ain’t Markup Language). YANG is a data modeling language which was created to provide a standard way to model the configuration and operational data on a device. The idea is that YANG should be vendor neutral, and vendors should adhere to standard YANG models so that YANG/NETCONF can work across different vendors automatically.
YANG is a bit confusing at first because it is kind of a three-in-one framework/language. One, YANG is a programming language - something can be written in YANG. Two, YANG is used to write YANG data models- YANG is used to create models of data . Three, the data expressed using these YANG data models is YANG data - which is data that conforms to a YANG data model.
First let’s look at a YANG model and identify some of the components. Below is an edited version of the YANG IETF interfaces model taken from here: https://github.com/YangModels/yang/blob/main/standard/ietf/RFC/ietf-interfaces%402018-02-20.yang
As you can see above, a YANG model is a tree structure. The module is essentially the name of the model. The container groups related items or nodes together. A list intendifies like-items or like-nodes. These are stored in a sequence. In this example, you can have a list of interfaces (i.e. Gi1, Gi2, Gi3, etc.). Every attribute of a node is represented by a leaf. So an interface has attributes such as a name (GigabitEthernet1), a description (”To R2”), whether it is up or down, etc. Each of these attributes is a leaf. Each leaf has a type, such as string or boolean. A leaf can also be mandatory or optional. It may help to make the comparison that a leaf is the final "item" on a tree. For example, on a tree, you have the trunk, multiple branches, and finally the leaf at the very edge. In YANG, the module is the trunk, containers are branches, a list is another branch which only contains leafs, and the leafs are the final items which each describe one single attribute of the model.
You might think this seems more tedious than just automating the CLI command int Gi1/ip address 1.1.1.1/no shut. But hopefully you can see the power in modeling an interface in a YANG structure. The model is completely vendor neutral - any network device from any vendor can theoretically conform to this model, because all interfaces are enabled or not enabled, have a name, have a description, etc. The idea behind ths is that programmers can use these YANG models to build configuration automation tools (such as NSO) which are vendor neutral and use a single YANG model instead of individual network CLI drivers (such as Netmiko).
Let’s take a brief look at another model, this time from openconfig instead of the IETF. As a brief background, originally the IETF developed a set of industry standard YANG models, and vendors developed their own YANG models separately. For example, HSRP, being propreitary to Cisco, would have a model in Cisco’s vendor YANG model repository instead of the IETF repository. Openconfig aims to gather as many models into a single, vendor neutral repository as possible. Let’s look at an OSFPv2 model from openconfig below:
This model represents an OSPFv3 interface. It should have an ID, network type (i.e. p2p or broadcast), priority (for DR election), etc. Because OSPF is an open protocol, vendors should be able to adhere to a vendor-neutral YANG model such as the model above.
We can use pyang to print the tree in a more readable format:
The question mark means that the leaf is optional. The right-hand column next to each leaf is the data type (string, 8bit interger, boolean, etc). The leaf data must be given in the specified data type, otherwise the data is not valid.
YANG defines the format of data using YANG models. NETCONF is a transport protocol used to transport YANG data from a management server to a network device.
NETCONF uses SSH over port 830 by default. NETCONF is actually a subsystem of SSH, comparitive to the way SFTP is a subsystem of SSH. NETCONF is a transactional protocol which is RPC-based (remote procedure call). When NETCONF sends a set of configuration parameters, the data itself is modeled using YANG, but is encoded using XML. (XML is the only encoding available for NETCONF; you must use RESTCONF to use JSON which will be discussed later). NETCONF is also session-oriented and stateful. You must exchange a set of “hello” messages at the beginning of a NETCONF session. In contrast, RESTCONF is stateless.
A NETCONF transaction is “all or nothing.” If part of a configuration change fails, it is entirely rolled back on the device. This transactional aspect of NETCONF is fundamental to the protocol.
NETCONF generally uses a commit style to make configuration changes, which you are probably familiar with on IOS-XR and Junos. When using NETCONF with IOS-XE, the same two-stage commit process is used even though the IOS-XE OS itself doesn’t use a two-stage commit. A two-stage commit isn’t required to be supported by all NETCONF agents, but IOS-XE does support it. When doing a two-stage commit, the network device has multiple data stores: running, startup, and candidate. All changes are made to the candidate data store. When the changes are ready to be applied, a commit copies the candidate data store to the running data store. Only the running data store is required to be supported by a NETCONF-capable device.
NETCONF uses RPC message types. Each RPC message sent from the server has a message-id, and the RPC-reply from the network device contains this message-id.
NETCONF RPC message types
<get>
Get running config and device state information
<get-config>
Get running or startup config information
<get-schema>
Get the YANG model for a given capability
<copy-config>
Replace the entire config with another config
<edit-config>
Edits the config
<delete-config>
Deletes config
<commit>
Copy candidate data store to running data sotre
<lock> or <unlock>
Lock or unlock entire config data store so noone else can make changes
<close-session>
Graceful terminate NETCONF session
<kill-session>
Forcefully termiante NETCONF session