NETCONF & YANG – Powerful Tools for Modern Network Management

In the previous post, we went over an introduction of Model Driven Programmability (MDP), what it means, what its basic building blocks are etc. Today’s post is a continuation of the same technology where we will look at one of the critical components of the MDP ecosystem. I am referring to NETCONF protocol. NETCONF protocol provides a mechanism for engineers to manage the configuration of network devices using data models. Some people use NETCONF and YANG synonymously with the assumption that they have always worked together, which is not incorrect but is not completely true either. NETCONF came into existence much before YANG data models had been conceived. During those times, NETCONF used to work with vendor specific data models. YANG broke that culture and brought everyone on the same page by means of standards. So, in today’s world, although it is acceptable to say that NETCONF works with YANG data models, one should also remember that this was not always the case.

So, let’s leave that small historical tidbit behind and move ahead.

Basic Flow

A standard communication on the network/web is based on an exchange of simple instructions between a client and a server.

NETCONF based communication
Fig 1 – NETCONF based communication

In simple terms,

  • The Client is the application that send requests to the server.
  • The Server is the piece of software that listens for incoming requests and responds accordingly.

We don’t need to restrict this understanding of the client/server model only in the context of web based communication. Even something as primitive as the CLI interface on network devices abides by the same principle. We issue a command and get a response in return. That’s it!! This exchange of instructions and subsequent responses can be done in multiple ways or data formats. The traditional approach has always circled around plain text in a human readable format but that is slowly & steadily changing especially in the context of large scale networks. Let’s have a detailed look at all the available options to send/receive data vis-a-vis network devices.

Payload Formats

Clear Text used with CLI

I am pretty sure that almost all of us are aware of this medium. Anyone who has ever logged into a network device and run a command, even something as simple as “show run”, must be familiar with this approach. We issue a command which is in a human readable format (clear text) and get a response which is also in a coherent text format. This is convenient, easy to remember and implement. That’s why it has worked since the beginning. However, it is an absolutely terrible method when we put it against the needs of modern programming based network management.

The only reason why the input/output is coherent & pretty is to make it understandable to us admins. But that’s not how computer systems work. They need data which follows a certain specific pattern. In other words, data which is structured. We can’t use data like the following while building solutions to programmatically manage network systems. There is a reason why we don’t see such issues plaguing API based interactions. Because the idea of “programming” is inherent to the concept of APIs. These two entities are tied together. Have we ever heard of a scenario where APIs prefer unstructured data like plain text over structured/semi-structured data formats like XML/JSON ? I don’t think so. This programming based approach is relatively new to the networking world. Therefore, it is understandable for traditional network engineers to find this new programming based approach difficult to adjust to.

CSR1000#sh ip int bri
Interface              IP-Address      OK? Method Status                Protocol
GigabitEthernet1       10.0.0.15       YES NVRAM  up                    up
GigabitEthernet2       unassigned      YES NVRAM  up                    up
GigabitEthernet3       unassigned      YES NVRAM  administratively down down
CSR1000#

XML Used with NETCONF

The following snippet is from a response that was received for a NETCONF request sent to a CSR1000 router. The NETCONF request was based on a YANG data model defined in the Openconfig standard. Alternatively, we could have also built this request as per IETF YANG model or Cisco’s native IOS XE data model. The actual link to the data model is given here

https://github.com/YangModels/yang/blob/main/vendor/cisco/xe/1761/openconfig-interfaces.yang

  <data>
    <interfaces xmlns="http://openconfig.net/yang/interfaces">
      <interface>
        <name>GigabitEthernet1</name>
        <config>
          <name>GigabitEthernet1</name>
          <type xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type">ianaift:ethernetCsmacd</type>
          <enabled>true</enabled>
        </config>
        <subinterfaces>
          <subinterface>
            <config>
              <index>0</index>
              <enabled>true</enabled>
            </config>
            <ipv4 xmlns="http://openconfig.net/yang/interfaces/ip">
              <addresses>
                <address>
                  <ip>10.0.0.15</ip>
                  <config>
                    <ip>10.0.0.15</ip>
                    <prefix-length>24</prefix-length>
                  </config>
                </address>
              </addresses>
            </ipv4>
          </subinterface>
        </subinterfaces>
      </interface>
    </interfaces>
  </data>

JSON used with RESTCONF

The following snippet is based on the same data model we reference above. But the data format is JSON

{
  "data": {
    "interfaces": {
      "interface": {
        "name": "GigabitEthernet1",
        "config": {
          "name": "GigabitEthernet1",
          "type": "ianaift:ethernetCsmacd",
          "enabled": true
        },
        "subinterfaces": {
          "subinterface": {
            "config": {
              "index": 0,
              "enabled": true
            },
            "ipv4": {
              "addresses": {
                "address": {
                  "ip": "10.0.0.15",
                  "config": {
                    "ip": "10.0.0.15",
                    "prefix-length": 24
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

Let’s reference above code with the basic building blocks of a YANG model. As I’d explained in the previous post, a YANG model based structure is primarily composed of following nodes

  • Container Nodes : A container node is used to group related nodes in a subtree. It has only child nodes and no value and may contain any number of child nodes of any type (including leafs, lists, containers, and leaf-lists).
  • List Nodes : A list defines a sequence of list entries. Each entry is like a structure or a record instance, and is uniquely identified by the values of its key leafs. A list can define multiple keys and may contain any number of child nodes of any type (including leafs, lists, containers etc.).
  • Leaf Nodes : A leaf node contains simple data like an integer or a string. It has exactly one value of a particular type, and no child nodes. Every leaf must have an associated type.
  • Leaf-list Nodes : A leaf-list is a sequence of leaf nodes with exactly one value of a particular type per leaf.

When we put above given definitions against XML/JSON code snippets, then we come to the following conclusion

  • Container Nodes
    • <interfaces> </interfaces>
  • List Nodes
    • <interface> </interface>
    • <subinterfaces> </subinterfaces>
    • <subinterface> </subinterface>
  • Leaf Nodes
    • <name> </name>
    • <type> </type>
    • <enabled> </enabled
    • <index> </index>
    • <enabled> </enabled>

I hope this post was somewhat helpful in clearing out the confusions and misconceptions that people have about NETCONF how its different from the old CLI based interactions. We will dive deeper into this whole concept of Model Driven Programmability as we go forward. So, stay tuned!!

Please feel free to provide your feedback/suggestions, if any.

Let’s connect on LinkedIn