Configuring Cisco IOS XE With YDK and OpenDaylight

In the previous posts about NETCONF and RESTCONF I’ve demonstrated how to interact with Cisco IOS XE device directly from the Linux shell of my development VM. This approach works fine in some cases, e.g. whenever I setup a new DC fabric, I would make calls directly to the devices I’m configuring. However, it becomes impractical in the Ops world where change is constant and involves a large number of devices. This is where centralised service orchestrators come to the fore. The prime examples of such platforms are Network Services Orchestrator from Tail-f/Cisco and open-source project OpenDaylight. In this post we’ll concentrate on ODL and how to make it work with Cisco IOS XE. Additionally, I’ll show how to use an open-source tool YDK to generate Python bindings for native YANG models and how it compares with pyangbind.

OpenDaylight primer

OpenDaylight is a swiss army knife of SDN controllers. At the moment it is comprised of dozens of projects implementing all possible sorts of SDN functionality starting from Openflow controller all the way up to L3VPN orchestrator. ODL speaks most of the modern Southbound protocols like Openflow, SNMP, NETCONF and BGP. The brain of the controller is in the Service Abstraction Layer, a framework to model all network-related characteristics and properties. All logic inside SAL is modelled in YANG which is why I called it the godfather of YANG models. Towards the end users ODL exposes Java function calls for applications running on the same host and REST API for application running remotely.

OpenDaylight has several commercial offerings from companies involved in its development. Most notable ones are from Brocade and Cisco. Here I will allow myself a bit of a rant, feel free to skip it to go straight to the technical stuff.

One thing I find interesting is that Cisco are being so secretive about their Open SDN Controller, perhaps due to the earlier market pressure to come up with a single SDN story, but still have a very large number of contributors to this open-source project. It could be the case of having an egg in each basket, but the number of Cisco’s employees involved in ODL development is substantial. I wonder if, now that the use cases for ACI and ODL have finally formed and ACI still not showing the uptake originally expected, Cisco will change their strategy and start promoting ODL more aggressively, or at least stop hiding it deep in the bowels of cisco.com. Or, perhaps, it will always stay in the shade of Tail-f’s NSC and Insieme’s ACI and will be used only for customer with unique requirements, e.g. to have both OpenStack and network devices managed through the same controller.

Environment setup

We’ll use the same environment we’ve setup in the previous posts, consisting of a CSR1K and a Linux VM connected to the same network inside my hypervisor. IOS XE device needs to have netconf-yang configured in order to enable the northbound NETCONF interface.

On the same Linux VM, I’ve downloaded and launched the latest version of ODL (Boron-SR2), and enabled NETCONF and RESTCONF plugins.

Connecting IOS XE to ODL

According to ODL NETCONF user guide, in order to connect a new device to the controller, we need to create an XML document which will include the IP, port and user credentials of the IOS XE device. Here’s the excerpt from the full XML document:

When the controller gets this information it will try to connect to the device via NETCONF and do the following three things:

Discover device capabilities advertised in the Hello message

Download all YANG models advertised by the device into the ./cache/schema directory

Go through all of the imports in each model and verify that they can be satisfied

After ODL downloads all of the 260 available models (can take up to 20 minutes) we will see the following errors in the karaf console:

Netconf device does not provide all yang models reported in hello message capabilities
Unable to build schema context, unsatisfied imports
Initialization in sal failed, disconnecting from device
No more sources for schema context

Due to inconsistencies between the advertised and the available models, ODL fails to build the full device YANG schema context, which ultimately results in inability to connect the device to the controller. However, we won’t need all of the 260 models advertised by the device. In fact, most of the configuration can be done through a single Cisco native YANG model, ned. With ODL it is possible to override the default capabilities advertised in the Hello message and “pin” only the ones that are going to be used. Assuming that ODL has downloaded most of the models at the previous step, we can simply tell it use the selected few with the following additions to the XML document:

Creates an abstraction layer to interact with southbound protocols (NETCONF or RESTCONF) in a uniform way

There’s a lot of overlap between the tools that we’ve used before and YDK. Effectively YDK combines in itself the functions of a NETCONF client, a REST client, pyangbind and pyang(the latter is used internally for model verification). Since one of the main functions of YDK is API generation I thought it’d be interesting to know how it compares to Rob Shakir’s pyangbind plugin. The following information is what I’ve managed to find on the Internet and from the comment of Santiago Alvarez below:

So it looks like YDK is a very promising alternative to pyangbind, however I, personally, would still prefer to use pyangbind due to familiarity, simplicity and the fact that I don’t need the above extra features offered by YDK right now. However, given that YDK has been able to achieve so much in just under one year of its existence, I don’t discount the possibility that I may switch to YDK as it becomes more mature and feature-rich.

Python binding generation with YDK-GEN

One of the first things we need to do is install YDK-GEN, the tools responsible for API bindings generation, and it’s core Python packages on the local machine. The following few commands are my version of the official installation procedure:

YDK-GEN generates Python bindings based on the so-called bundle profile. This is a simple JSON document which lists all YANG models to include in the output package. In our case we’d need to include a ned model along with all its imports. The sample below shows only the model specification. Refer to my Github repo for a complete bundle profile for Cisco IOS XE native YANG model.

The configuration will follow the pattern defined in the original model, which is why it’s important to understand the internal structure of a YANG model. YANG leafs are represented as simple instance attributes. All YANG containers need to be explicitly instantiated, just like the Native and Bgp classes in the example above. Presence containers (router in the above example) will be instantiated at the same time as its parent container, inside the __init__ function of the Native class. Don’t worry if this doesn’t make sense, use iPython or any IDE with autocompletion and after a few tries, you’ll get the hang of it.

Let’s see how we can set the local BGP AS number and add a new BGP peer to the neighbor list.