Our previous blog posts about OpenDaylight demonstrates how to use some protocols, like OpenFlow and BGP. This post will introduce a ‘how-to’ to use another powerful protocol, the NETCONF.

Before you start:

What is NETCONF:

Network Configuration Protocol (NETCONF) provides a mechanism to install, manipulate and delete the configuration of network devices. It uses an Extensible Markup Language (XML) based data encoding for the configuration data as well as the protocol messages. The NETCONF protocol operations are realized as remote procedure calls (RPCs).

OpenDaylight uses a proper collection of YANG modules to access the device via NETCONF, however, the configuration to use different capabilities is out of scope of this blog post. In this post we will demonstrate how to configure ODL for NETCONF connections, with this configuration evaluated in two different ways: via REST API or changing a xml file (we’ll cover both).

For this example the following device and ODL version was used:

  • Juniper MX-Series — version 17.1R.8; IP address — 172.16.7.2
  • User/Password: netconf/Netconf
  • Port: 17830
  • ODL Boron SR3; Controller IP — 172.16.11.10
  • Juniper yang modules (https://github.com/Juniper/yang)

Step 1 — Start ODL and install the features:

  • odl-restconf-all
  • odl-netconf-connector-all
  • odl-netconf-clustered-topology

serro@dev ~/nic/distribution/target/assembly/bin $ ./karaf

karaf: JAVA_HOME not set; results may vary Apache Karaf starting up. Press Enter to open the shell now… 100% [=======================================================================]

Karaf started in 2s. Bundle stats: 64 active, 64 total

opendaylight-user@root>feature:install odl-restconf-all odl-netconf-connector-all odl-netconf-clustered-topology

Step 2 — Configure the ‘99-netconf-connector.xml’

Use your preferred editor (for this example we’re using Vim) to edit the file at:

serro@dev ~ $ vim /distribution-karaf-0.5.3-Boron-SR3/etc/opendaylight/karaf/99-netconf-connector.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- vi: set et smarttab sw=4 tabstop=4: -->
<!--
Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
 This program and the accompanying materials are made available under the
terms of the Eclipse Public License v1.0 which accompanies this distribution,
and is available at http://www.eclipse.org/legal/epl-v10.html
-->
<snapshot>
<configuration>
<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
<!-- Loopback connection to netconf server in controller using netconf-connector -->
<module>
<type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">prefix:sal-netconf-connector</type>
<name>controller-config</name>
<address xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">172.16.7.2</address>
<port xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">17830</port>
<username xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">netconf</username>
<password xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">Netconf</password>
<tcp-only xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">false</tcp-only>
<reconnect-on-changed-schema xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">true</reconnect-on-changed-schema>
<yang-module-capabilities xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
<capability>
http://xml.juniper.net/xnm/1.1/xnm?module=configuration&amp;revision=2015-09-11
</capability>
</yang-module-capabilities>
          <event-executor xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
<type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-event-executor</type>
<name>global-event-executor</name>
</event-executor>
<binding-registry xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
<type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">prefix:binding-broker-osgi-registry</type>
<name>binding-osgi-broker</name>
</binding-registry>
<dom-registry xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
<type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">prefix:dom-broker-osgi-registry</type>
<name>dom-broker</name>
</dom-registry>
<client-dispatcher xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
<type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:netconf">prefix:netconf-client-dispatcher</type>
<name>global-netconf-dispatcher</name>
</client-dispatcher>
<processing-executor xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
<type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool">prefix:threadpool</type>
<name>global-netconf-processing-executor</name>
</processing-executor>
<keepalive-executor xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
<type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool">prefix:scheduled-threadpool</type>
<name>global-netconf-ssh-scheduled-executor</name>
</keepalive-executor>
</module>
</modules>
</data>
</configuration>
<required-capabilities>
<capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf?module=odl-sal-netconf-connector-cfg&amp;revision=2015-08-03</capability>
</required-capabilities>
</snapshot>
  • <address>: Put here the device IP
  • <port>: Put here the port of your device used for Netconf connection
  • <username>: Put here the username used for Netconf connection
  • <password>: Put here the password used for your Netconf connection

Note: To ensure the connectivity between ODL and Juniper router, insert the highlighted tag followed by it content ‘<yang-module-capabilities> … </yang-module-capabilities>’.

The content of the tag ‘<yang-module-capabilities>’ will define the capabilities available by the device, to add a new capability, just insert a new ‘<capability>’ tag and the content with following format: <module_namespace>?module=<module_name>&amp;revision=<module_revision_date>.

Step 3 — For this example we will use the capability that ensure the connectivity between ODL and the device via NETCONF. This example uses the configuration file available at Juniper’s github (please, see link above Step 1).

Note: Make sure to create a copy of ‘configuration.yang’ downloaded from Juniper’s github with the following pattern: ‘<module_name>@<revision_date>.yang’. Also, copy all other YANG modules accordly with your Junos version (17.1R1.8 for this case) to the following folder:

serro@dev ~ $ distribution-karaf-0.5.3-Boron-SR3/cache/schema/

Step 4 — Shutdown ODL and then start again:

serro@dev ~ $ /distribution-karaf-0.5.3-Boron-SR3/stop

serro@dev ~ $ /distribution-karaf-0.5.3-Boron-SR3/start

You will see the following message at ‘karaf.log’:

2017-05-05 14:26:23,443 | INFO  | 2]-nio2-thread-1 | ClientSessionImpl                | 30 - org.apache.sshd.core - 0.14.0 | Client session created
2017-05-05 14:26:23,465 | INFO | 2]-nio2-thread-1 | ClientSessionImpl | 30 - org.apache.sshd.core - 0.14.0 | Start flagging packets as pending until key exchange is done
2017-05-05 14:26:23,489 | INFO | 2]-nio2-thread-2 | ClientSessionImpl | 30 - org.apache.sshd.core - 0.14.0 | Server version string: SSH-2.0-OpenSSH_7.1
2017-05-05 14:26:24,795 | WARN | 2]-nio2-thread-5 | AcceptAllServerKeyVerifier | 30 - org.apache.sshd.core - 0.14.0 | Server at /172.16.7.2:17830 presented unverified EC key: 2a:ab:10:85:69:71:3e:11:de:aa:76:fc:d0:40:d1:dd
2017-05-05 14:26:24,822 | INFO | 2]-nio2-thread-5 | ClientSessionImpl | 30 - org.apache.sshd.core - 0.14.0 | Dequeing pending packets
2017-05-05 14:26:24,964 | INFO | 2]-nio2-thread-7 | ClientUserAuthServiceNew | 30 - org.apache.sshd.core - 0.14.0 | Received SSH_MSG_USERAUTH_FAILURE
2017-05-05 14:26:25,000 | INFO | 2]-nio2-thread-8 | UserAuthKeyboardInteractive | 30 - org.apache.sshd.core - 0.14.0 | Received
2017-05-05 14:26:25,075 | INFO | 2]-nio2-thread-1 | UserAuthKeyboardInteractive | 30 - org.apache.sshd.core - 0.14.0 | Received
2017-05-05 14:26:25,095 | INFO | 2]-nio2-thread-2 | ClientUserAuthServiceNew | 30 - org.apache.sshd.core - 0.14.0 | Received SSH_MSG_USERAUTH_SUCCESS
2017-05-05 14:27:05,154 | INFO | sing-executor-11 | NetconfDevice | 288 - org.opendaylight.netconf.sal-netconf-connector - 1.4.3.Boron-SR3 | RemoteDevice{controller-config}: Netconf connector initialized successfully

Step 5 — Verify the connectivity with the device sending the following request:

Method: GET

URL: http://172.16.11.10:8181/restconf/operational/network-topology:network-topology/topology/topology-netconf/

Result:

"network-topology": {
    "topology": [
      {
        "topology-id": "topology-netconf",
        "node": [
          {
            "node-id": "controller-config",
            "netconf-node-topology:host": "172.16.7.2",
            "netconf-node-topology:connection-status": "connected",
            "netconf-node-topology:port": 17830,
            "netconf-node-topology:available-capabilities": {
              "available-capability": [
                "urn:ietf:params:xml:ns:netconf:capability:url:1.0?protocol=http,ftp,file",
                "urn:ietf:params:xml:ns:netconf:base:1.0",
                "urn:ietf:params:netconf:capability:url:1.0?scheme=http,ftp,file",
                "(urn:ietf:params:xml:ns:yang:ietf-inet-types?revision=2010-09-24)ietf-inet-types",
                "urn:ietf:params:xml:ns:netconf:capability:validate:1.0",
                "(http://xml.juniper.net/xnm/1.1/xnm?revision=2015-09-11)configuration",
                "urn:ietf:params:netconf:base:1.0",
                "http://xml.juniper.net/dmi/system/1.0",
                "(urn:TBD:params:xml:ns:yang:network:ted?revision=2013-10-21)ted",
                "urn:ietf:params:xml:ns:netconf:capability:candidate:1.0",
                "urn:ietf:params:netconf:capability:confirmed-commit:1.0",
                "(urn:ietf:params:xml:ns:yang:ietf-inet-types?revision=2013-07-15)ietf-inet-types",
                "http://xml.juniper.net/netconf/junos/1.0",
                "(http://yang.juniper.net/yang/1.1/je?revision=2016-11-17)junos-extension",
                "(urn:ietf:params:xml:ns:netconf:base:1.0?revision=2011-06-01)ietf-netconf",
                "urn:ietf:params:xml:ns:netconf:capability:confirmed-commit:1.0",
                "urn:ietf:params:netconf:capability:validate:1.0",
                "urn:ietf:params:netconf:capability:candidate:1.0"
              ]
            }
          }
        ]
      }
    ]
  }
}

It follows the second way to connect ODL to a NETCONF device, send the following request:

Note:Before you continue, execute Steps 01 and 03.

Method: PUT

URL: http://172.16.11.10:8181/restconf/config/network-topology:network-topology/topology/topology-netconf/node/serro-router

Content-Type: application/xml

Body:

<node xmlns="urn:TBD:params:xml:ns:yang:network-topology">
   <node-id>serro-router</node-id>
   <host xmlns="urn:opendaylight:netconf-node-topology">172.16.7.2</host>
   <port xmlns="urn:opendaylight:netconf-node-topology">17830</port>
   <username xmlns="urn:opendaylight:netconf-node-topology">netconf</username>
   <password
xmlns="urn:opendaylight:netconf-node-topology">Netconf</password>
   <tcp-only xmlns="urn:opendaylight:netconf-node-topology">false</tcp-only>
   <keepalive-delay
xmlns="urn:opendaylight:netconf-node-topology">0</keepalive-delay>
   <yang-module-capabilities xmlns="urn:opendaylight:netconf-node-topology">
    <capability>
http://xml.juniper.net/xnm/1.1/xnm?module=configuration&amp;revision=2015-09-11
</capability>
<capability>urn:ietf:params:xml:ns:netconf:base:1.0?module=ietf-netconf&amp;revision=2011-06-01</capability>
<capability>urn:ietf:params:xml:ns:yang:ietf-inet-types?module=ietf-inet-types&amp;revision=2013-07-15</capability>
<capability>urn:ietf:params:xml:ns:netconf:base:1.0?module=database-status-information&amp;revision=2017-03-07</capability>
   </yang-module-capabilities>
</node>

Now execute step 5 to ensure the connectivity.

Conclusion:

This blog post demonstrates that OpenDaylight provides a simple way to manage devices via the NETCONF protocol. With this functionality, the users can monitor and manage devices via ODL REST API and write business applications on top of ODL.

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.