In this article by Jamie Goodyear, Mathieu Lemay, Rashmi Pujar, Yrineu Rodrigues, Mohamed El-Serngawy, and Alexis de Talhouët the authors of the book OpenDaylight Cookbook, we will be covering the following recipes:
(For more resources related to this topic, see here.)
OpenDaylight is a collaborative platform supported by leaders in the networking industry and hosted by the Linux Foundation. The goal of the platform is to enable the adoption of software-defined networking (SDN) and create a solid base for network functions virtualization (NFV).
OpenFlow is a vendor-neutral standard communications interface defined to enable the interaction between the control and forwarding channels of an SDN architecture. The OpenFlow plugin project intends to support implementations of the OpenFlow specification as it evolves. It currently supports OpenFlow versions 1.0 and 1.3.2. In addition, to support the core OpenFlow specification, OpenDaylight Beryllium also includes preliminary support for the Table Type Patterns and OF-CONFIG specifications.
The OpenFlow southbound plugin currently provides the following components:
Let's connect an OpenFlow switch to OpenDaylight.
This recipe requires an OpenFlow switch. If you don't have any, you can use a mininet-vm with OvS installed. You can download mininet-vm from the website:
https://github.com/mininet/mininet/wiki/Mininet-VM-Images.
Any version should work
The following recipe will be presented using a mininet-vm with OvS 2.0.2.
$ ./bin/karaf
opendaylight-user@root>feature:install odl-openflowplugin-all
It might take a minute or so to complete the installation.
mininet@mininet-vm:~$ sudo ovs-vsctl add-br br0
mininet@mininet-vm:~$ sudo ovs-vsctl set-controller br0 tcp: ${CONTROLLER_IP}:6633
mininet@mininet-vm:~$ sudo ovs-vsctl show
0b8ed0aa-67ac-4405-af13-70249a7e8a96
Bridge "br0"
Controller "tcp: ${CONTROLLER_IP}:6633"
is_connected: true
Port "br0"
Interface "br0"
type: internal
ovs_version: "2.0.2"
${CONTROLLER_IP} is the IP address of the host running OpenDaylight.
We're establishing a TCP connection.
This will list all the nodes under opendaylight-inventory subtree of MD-SAL that store OpenFlow switch information. As we connected our first switch, we should have only one node there. It will contain all the information the OpenFlow switch has, including its tables, its ports, flow statistics, and so on.
Once the feature is installed, OpenDaylight is listening to connection on port 6633 and 6640. Setting up the controller on the OpenFlow-capable switch will immediately trigger a callback on OpenDaylight. It will create the communication pipeline between the switch and OpenDaylight so they can communicate in a scalable and non-blocking way.
The OpenDaylight component responsible to connect remote NETCONF devices is called the NETCONF southbound plugin aka the netconf-connector. Creating an instance of the netconf-connector will connect a NETCONF device. The NETCONF device will be seen as a mount point in the MD-SAL, exposing the device configuration and operational datastore and its capabilities. These mount points allow applications and remote users (over RESTCONF) to interact with the mounted devices.
The netconf-connector currently supports the RFC-6241, RFC-5277 and RFC-6022.
The following recipe will explain how to connect a NETCONF device to OpenDaylight.
This recipe requires a NETCONF device. If you don't have any, you can use the NETCONF test tool provided by OpenDaylight. It can be downloaded from the OpenDaylight Nexus repository:
https://nexus.opendaylight.org/content/repositories/opendaylight.release/org/opendaylight/netconf/netconf-testtool/1.0.4-Beryllium-SR4/netconf-testtool-1.0.4-Beryllium-SR4-executable.jar
$ ./bin/karaf
opendaylight-user@root>feature:install odl-netconf-topology odl-restconf
It might take a minute or so to complete the installation.
$ java -jar netconf-testtool-1.0.1-Beryllium-SR4-executable.jar --device-count 1
This will simulate one device that will be bound to port 17830.
<node >
<node-id>new-netconf-device</node-id>
<host >127.0.0.1</host>
<port >17830</port>
<username >admin</username>
<password >admin</password>
<tcp-only >false</tcp-
only>
</node>
Let's have a closer look at this payload:
This is the default configuration of the netconf-connector; it actually has more configurable elements that will be present in a second part.
Once you have completed the request, send it. This will spawn a new netconf-connector that connects to the NETCONF device at the provided IP address and port using the provided credentials.
2016-05-07 11:37:42,470 | INFO | sing-executor-11 | NetconfDevice | 253 - org.opendaylight.netconf.sal-netconf-connector - 1.3.0.Beryllium | RemoteDevice{new-netconf-device}: Netconf connector initialized successfully
Once the new netconf-connector is created, some useful metadata are written into the MD-SAL's operational datastore under the network-topology subtree. To retrieve this information, you should send the following request:
Authorization: Basic YWRtaW46YWRtaW4=
URL: http://localhost:8181/restconf/operational/network-topology:network-topology/topology/topology-netconf/node/new-netconf-device
We're using new-netconf-device as the node-id because this is the name we assigned to the netconf-connector in a previous step.
This request will provide information about the connection status and device capabilities. The device capabilities are all the yang models the NETCONF device is providing in its hello-message that was used to create the schema context.
Using this configuration, your payload would look like this:
<node >
<node-id>new-netconf-device</node-id>
<host >127.0.0.1</host>
<port >17830</port>
<username >admin</username>
<password >admin</password>
<tcp-only >false</tcp-
only>
<schema-cache-directory >new_netconf_device_cache</schema-cache-directory>
<reconnect-on-changed-schema >false</reconnect-on-changed-schema>
<connection-timeout-millis >20000</connection-timeout-millis>
<default-request-timeout-millis >60000</default-request-timeout-millis>
<max-connection-attempts >0</max-connection-attempts>
<between-attempts-timeout-millis >2000</between-attempts-timeout-millis>
<sleep-factor >1.5</sleep-factor>
<keepalive-delay >120</keepalive-delay>
</node>
Once the request to connect a new NETCONF device is sent, OpenDaylight will setup the communication channel, used for managing, interacting with the device. At first, the remote NETCONF device will send its hello-message defining all of the capabilities it has. Based on this, the netconf-connector will download all the YANG files provided by the device. All those YANG files will define the schema context of the device.
At the end of the process, some exposed capabilities might end up as unavailable, for two possible reasons:
OpenDaylight parses YANG models as per as the RFC 6020; if a schema is not respecting the RFC, it could end up as an unavailable-capability.
If you encounter one of these situations, looking at the logs will pinpoint the reason for such a failure.
Once the NETCONF device is connected, all its capabilities are available through the mount point. View it as a pass-through directly to the NETCONF device.
To see the data contained in the device datastore, use the following request:
Adding yang-ext:mount/ to the URL will access the mount point created for new-netconf-device. This will show the configuration datastore. If you want to see the operational one, replace config by operational in the URL.
If your device defines yang model, you can access its data using the following request:
The <module> represents a schema defining the <container>. The <container> can either be a list or a container. It is not possible to access a single leaf. You can access containers/lists within containers/lists. The last part of the URL would look like this:
…/ yang-ext:mount/<module>:<container>/<sub-container>
In order to invoke an RPC on the remote device, you should use the following request:
This URL is accessing the mount point of new-netconf-device, and through this mount point we're accessing the <module> to call its <operation>. The <module> represents a schema defining the RPC and <operation> represents the RPC to call.
Removing a netconf-connector will drop the NETCONF session and all resources will be cleaned. To perform such an operation, use the following request:
By looking closer to the URL, you can see that we are removing the NETCONF node-id new-netconf-device.
Yang UI is a user interface application through which one can navigate among all yang models available in the OpenDaylight controller. Not only does it aggregate all data models, it also enables their usage. Using this interface, you can create, remove, update, and delete any part of the model-driven datastore. It provides a nice, smooth user interface making it easier to browse through the model(s).
This recipe will guide you through those functionalities.
This recipe only requires the OpenDaylight controller and a web-browser.
$ ./bin/karaf
opendaylight-user@root>feature:install odl-dlux-yangui
It might take a minute or so to complete the installation.
By default, there isn't much you can do with the provided yang models. So, let's connect an OpenFlow switch to better understand how to use this Yang UI.
Once done, refresh your web page to load newly added modules.
You could do the same request by specifying the node-id in the request. To do that you will need to expand nodes and click on node {id}, which will enable a more fine-grained search.
OpenDaylight has a model-driven architecture, which means that all of its components are modeled using YANG. While installing features, OpenDaylight loads YANG models, making them available within the MD-SAL datastore.
YangUI is a representation of this datastore. Each schema represents a subtree based on the name of the module and its revision-date. YangUI aggregates and parses all those models. It also acts as a REST client; through its web interface we can execute functions such as GET, POST, PUT, and DELETE.
The example shown previously can be improved on, as there was no user yang model loaded. For instance, if you mount a NETCONF device containing its own yang model, you could interact with it through YangUI.
You would use the config datastore to push/update some data, and you would see the operational datastore updated accordingly. In addition, accessing your data would be much easier than having to define the exact URL.
Throughout this article, we learned recipes such as connecting OpenFlow switches, mounting a NETCONF device, browsing data models with Yang UI.