--- /dev/null
+=== Northbound (NETCONF servers)
+OpenDaylight provides 2 types of NETCONF servers:
+
+* *NETCONF server for config-subsystem(listening by default on port
+ 1830)*
+ ** Serves as a default interface for config-subsystem and allows
+ users to spawn/reconfigure/destroy modules(or applications) in OpenDaylight
+* *NETCONF server for MD-SAL(listening by default on port 2830)*
+** Serves as an alternative interface for MD-SAL (besides RESTCONF)
+ and allows users to read/write data from MD-SAL's datastore and to
+ invoke its rpcs (NETCONF notifications are not available in the
+ Lithium release of OpenDaylight)
+
+NOTE: The reason for having 2 NETCONF servers is that config-subsystem and
+MD-SAL are 2 different components of OpenDaylight and require different
+approach for NETCONF message handling and data translation. These 2
+components will probably merge in the future.
+
+==== NETCONF server for config-subsystem
+This NETCONF server is the primary interface for config-subsystem. It
+allows the users to interact with config-subsystem in a standardized
+NETCONF manner.
+
+In terms of RFCs, these are supported:
+
+* http://tools.ietf.org/html/rfc6241[RFC-6241],
+* https://tools.ietf.org/html/rfc5277[RFC-5277],
+* https://tools.ietf.org/html/rfc6470[RFC-6470]
+** (partially, only the
+ schema-change notification is available in Lithium release)
+* https://tools.ietf.org/html/rfc6022[RFC-6022],
+
+For regular users it is recommended to use RESTCONF + the
+controller-config loopback mountpoint instead of using pure NETCONF.
+How to do that is spesific for each component/module/application
+in OpenDaylight and can be found in their dedicated user guides
+
+==== NETCONF server for MD-SAL
+This NETCONF server is just a generic interface to MD-SAL in OpenDaylight.
+It uses the stadard MD-SAL APIs and serves as an alternative to
+RESTCONF. It is
+fully model driven and supports any data and rpcs that are supported
+by MD-SAL.
+
+In terms of RFCs, these are supported:
+
+* http://tools.ietf.org/html/rfc6241[RFC-6241],
+* https://tools.ietf.org/html/rfc6022[RFC-6022],
+
+Notifications over NETCONF are not supported in the Lithium release.
+
+TIP: Install NETCONF northbound for MD-SAL by installing feature:
++odl-netconf-mdsal+ in karaf. Default binding port is *2830*.
+
+===== Configuration
+The default configuration can be found in file:
+_08-netconf-mdsal.xml_. The file contains the configuration for all
+necessary dependencies and a single SSH endpoint starting on port 2830.
+There is also a (by default disabled) TCP endpoint. It is possible
+to start multiple endpoints at the same time either in the initial
+configuration file or while OpenDaylight is running.
+
+The credentials for SSH endpoint can also be configured here, the
+defaults are admin/admin. Credentials in the SSH endpoint are not yet
+managed by the centralized AAA component and have to be configured
+separately.
+
+===== Verifying MD-SAL's NETCONF server
+After the NETCONF server is available it can be examined by e.g. a
+command line ssh tool:
+
+----
+ssh admin@localhost -p 2830 -s netconf
+----
+
+The server will respond by sending its HELLO message and can be used
+as a regular NETCONF server from now on.
+
+===== Mounting the MD-SAL's NETCONF server
+To perform this operation, just spawn a new netconf-connector as described in
+<<_spawning_additional_netconf_connectors_while_the_controller_is_running,
+Spawning netconf-connector>>.
+Just change the ip to "127.0.0.1" port to "2830" and its name to "controller-mdsal".
+
+Now the MD-SAL's datastore can be read over RESTCONF via NETCONF by invoking:
+
+GET http://localhost:8181/restconf/operational/network-topology:network-topology/topology/topology-netconf/node/controller-mdsal/yang-ext:mount
+
+NOTE: This might not seem very useful, since MD-SAL can be accessed
+directly from RESTCONF or from Application code, but the same method can be used to
+mount and control other OpenDaylight instances by the "master OpenDaylight".
--- /dev/null
+=== Southbound (netconf-connector)
+NETCONF southbound plugin is capable of connecting to remote NETCONF
+devices and expose their configuration/operational datastores, rpcs and
+notifications as MD-SAL mount points. These mount points allow
+applications and remote users (over RESTCONF) to interact with the
+mounted devices.
+
+In terms of RFCs, the connector supports:
+
+* http://tools.ietf.org/html/rfc6241[RFC-6241],
+* https://tools.ietf.org/html/rfc5277[RFC-5277],
+* https://tools.ietf.org/html/rfc6022[RFC-6022],
+
+*Netconf-connector is fully model driven (utilising YANG modeling language) so in addition to
+the above RFCs, it supports any data/RPC/notifications described by a
+YANG model that is implemented by the device.*
+
+TIP: NETCONF southbound can be activated by installing
++odl-netconf-connector-all+ Karaf feature.
+
+==== Netconf-connector configuration
+There are 2 ways for configuring netconf-connector (as is for any
+other module) NETCONF or RESTCONF. This guide focuses on using RESTCONF.
+
+===== Default configuration
+The default configuration contains all the necessary dependencies
+(file: 01-netconf.xml) and a single instance of netconf-connector
+(file: 99-netconf-connector.xml) called *controller-config* which
+connects itself to the NETCONF northbound in OpenDaylight in a loopback
+fashion. The connector mounts the NETCONF server for config-subsystem
+in order to enable RESTCONF protocol for config-subsystem. This
+RESTCONF still goes via NETCONF, but using RESTCONF is much more user
+friendly than using NETCONF.
+
+===== Spawning additional netconf-connectors while the controller is running
+Preconditions:
+
+. OpenDaylight is running
+. In Karaf, you must have the netconf-connector installed (at the
+ Karaf prompt, type: feature:install odl-netconf-connector-all); the
+ loopback NETCONF mountpoint will be automatically configured and
+ activated
+. Wait until log displays following entry:
+ RemoteDevice{controller-config}: NETCONF connector initialized
+ successfully
+
+To configure a new netconf-connector you need to send following
+request to RESTCONF:
+
+POST http://localhost:8181/restconf/config/network-topology:network-topology/topology/topology-netconf/node/controller-config/yang-ext:mount/config:modules
+
+*Headers*:
+Accept application/xml
+Content-Type application/xml
+
+----
+<module xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">prefix:sal-netconf-connector</type>
+ <name>new-netconf-device</name>
+ <address xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">127.0.0.1</address>
+ <port xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">830</port>
+ <username xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">admin</username>
+ <password xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">admin</password>
+ <tcp-only xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">false</tcp-only>
+ <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>
+----
+
+This spawns a new netconf-connector which tries to
+connect to (or mount) a NETCONF device at 127.0.0.1 and port 830. You
+can check the configuration of config-subsystem's configuration datastore.
+The new netconf-connector will now be present there. Just invoke:
+
+GET http://localhost:8181/restconf/config/network-topology:network-topology/topology/topology-netconf/node/controller-config/yang-ext:mount/config:modules
+
+The response will contain the module for new-netconf-device.
+
+Right after the new netconf-connector is created, it writes some
+useful metadata into the datastore of MD-SAL under the network-topology
+subtree. This metadata can be found at:
+
+GET http://localhost:8181/restconf/operational/network-topology:network-topology/
+
+Information about connection status, device capabilities etc. can be
+found there.
+
+===== Connecting to a device not supporting NETCONF monitoring
+The netconf-connector in OpenDaylight relies on ietf-netconf-monitoring support
+when connecting to remote NETCONF device. The ietf-netconf-monitoring
+support allows netconf-connector to list and download all YANG schemas
+that are used by the device. NETCONF connector can only communicate
+with a device if it knows the set of used schemas (or at least a
+subset). However, some devices use YANG models internally but do not
+support NETCONF monitoring. Netconf-connector can also communicate
+with these devices, but you have to side load the necessary yang
+models into OpenDaylight's YANG model cache for netconf-connector. In general
+there are 2 situations you might encounter:
+
+*1. NETCONF device does not support ietf-netconf-monitoring but it
+ does list all its YANG models as capabilities in HELLO message*
+
+This could be a device that internally uses only ietf-inet-types
+YANG model with revision 2010-09-24. In the HELLO message that is sent
+from this device there is this capability reported:
+
+----
+urn:ietf:params:xml:ns:yang:ietf-inet-types?module=ietf-inet-types&revision=2010-09-24
+----
+
+*For such devices you only need to put the schema into folder
+cache/schema inside your Karaf distribution.*
+
+IMPORTANT: The file with YANG schema for ietf-inet-types has to be
+called ietf-inet-types@2010-09-24.yang. It is the required naming format
+of the cache.
+
+*2. NETCONF device does not support ietf-netconf-monitoring and it
+ does NOT list its YANG models as capabilities in HELLO message*
+
+Compared to device that lists its YANG models in HELLO message, in
+this case there would be no capability with ietf-inet-types in the
+HELLO message. This type of device basically provides no information
+about the YANG schemas it uses so its up to the user of OpenDaylight to
+properly configure netconf-connector for this device.
+
+Netconf-connector has an optional configuration attribute called
+yang-module-capabilities and this attribute can contain a list of
+"YANG module based" capabilities. So by setting this configuration
+attribute, it is possible to override the "yang-module-based"
+capabilities reported in HELLO message of the device. To do this, we
+need to modify the configuration of netconf-connector by adding this
+xml (It needs to be added next to the address, port, username etc.
+configuration elements):
+
+----
+<yang-module-capabilities xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
+ <capability xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
+ urn:ietf:params:xml:ns:yang:ietf-inet-types?module=ietf-inet-types&revision=2010-09-24
+ </capability>
+</yang-module-capabilities>
+----
+
+*Remember to also put the YANG schemas into the cache folder.*
+
+NOTE: For putting multiple capabilities, you just need to replicate
+the capability xml element inside yang-module-capability element.
+Capability element is modeled as a leaf-list.
+With this configuration, we would make the remote device report usage
+of ietf-inet-types in the eyes of netconf-connector.
+
+===== Reconfiguring Netconf-Connector While the Controller is Running
+It is possible to change the configuration of a running module while
+the whole controller is running. This example will continue where the last left off and
+will change the configuration for the brand new netconf-connector
+after it was spawned. Using one RESTCONF request, we will change both
+username and password for the netconf-connector.
+
+To update an existing netconf-connector you need to send following
+request to RESTCONF:
+
+PUT
+http://localhost:8181/restconf/config/network-topology:network-topology/topology/topology-netconf/node/controller-config/yang-ext:mount/config:modules/module/odl-sal-netconf-connector-cfg:sal-netconf-connector/new-netconf-device
+
+----
+<module xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">prefix:sal-netconf-connector</type>
+ <name>new-netconf-device</name>
+ <username xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">bob</username>
+ <password xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">passwd</password>
+ <tcp-only xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">false</tcp-only>
+ <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>
+----
+
+Since a PUT is a replace operation, the whole configuration must be
+specified along with the new values for username and password. This
+should result in a 2xx response and the instance of netconf-connector
+called new-netconf-device will be reconfigured to use username bob and
+password passwd. New configuration can be verified by executing:
+
+GET http://localhost:8181/restconf/config/network-topology:network-topology/topology/topology-netconf/node/controller-config/yang-ext:mount/config:modules/module/odl-sal-netconf-connector-cfg:sal-netconf-connector/new-netconf-device
+
+With new configuration, the old connection will be closed and a new
+one established.
+
+===== Destroying Netconf-Connector While the Controller is Running
+Using RESTCONF one can also destroy an instance of a module. In case
+of netconf-connector, the module will be destroyed, NETCONF connection
+dropped and all resources will be cleaned. To do this, simply issue a
+request to following URL:
+
+DELETE http://localhost:8181/restconf/config/network-topology:network-topology/topology/topology-netconf/node/controller-config/yang-ext:mount/config:modules/module/odl-sal-netconf-connector-cfg:sal-netconf-connector/new-netconf-device
+
+The last element of the URL is the name of the instance and its
+predecessor is the type of that module (In our case the type is
+*sal-netconf-connector* and name *new-netconf-device*). The type and name
+are actually the keys of the module list.
+
+==== Netconf-connector utilisation
+Once the connector is up and running, users can utilize the new Mount
+point instance. By using RESTCONF or from their application code. This
+chapter deals with using RESTCONF and more information for app
+developers can be found in the developers guide or in the official
+tutorial application *ncmount* that can be found in the coretutorials project:
+
+* https://github.com/opendaylight/coretutorials/tree/stable/lithium/ncmount
+
+===== Reading data from the device
+Just invoke (no body needed):
+
+GET http://localhost:8080/restconf/operational/network-topology:network-topology/topology/topology-netconf/node/new-netconf-device/yang-ext:mount/
+
+This will return the entire content of operation datastore from the
+device. To view just the configuration datastore, change *operational* in
+this URL to *config*.
+
+===== Writing configuration data to the device
+In general, you cannot simply write any data you want to the device.
+The data have to conform to the YANG models implemented by the device.
+In this example we are adding a new interface-configuration to the
+mounted device (assuming the device supports Cisco-IOS-XR-ifmgr-cfg
+YANG model). In fact this request comes from the tutorial dedicated to
+the *ncmount* tutorial app.
+
+POST
+http://localhost:8181/restconf/config/network-topology:network-topology/topology/topology-netconf/node/new-netconf-device/yang-ext:mount/Cisco-IOS-XR-ifmgr-cfg:interface-configurations
+
+----
+<interface-configuration xmlns="http://cisco.com/ns/yang/Cisco-IOS-XR-ifmgr-cfg">
+ <active>act</active>
+ <interface-name>mpls</interface-name>
+ <description>Interface description</description>
+ <bandwidth>32</bandwidth>
+ <link-status></link-status>
+</interface-configuration>
+----
+
+Should return 200 response code with no body.
+
+TIP: This call is transformed into a couple of NETCONF RPCs. Resulting
+NETCONF RPCs that go directly to the device can be found in the OpenDaylight
+logs after invoking +log:set TRACE
+org.opendaylight.controller.sal.connect.netconf+ in the Karaf shell.
+Seeing the NETCONF RPCs might help with debugging.
+
+This request is very similar to the one where we spawned a new netconf
+device. That's because we used the loopback netconf-connector to write
+configuration data into config-subsystem datastore and config-subsystem
+picked it up from there.
+
+===== Invoking custom RPC
+Devices can implement any additional RPC and as long as it provides
+YANG models for it, it can be invoked from OpenDaylight. Following example shows how
+to invoke the get-schema RPC (get-schema is quite common among netconf
+devices). Invoke:
+
+POST
+http://localhost:8181/restconf/operations/network-topology:network-topology/topology/topology-netconf/node/new-netconf-device/yang-ext:mount/ietf-netconf-monitoring:get-schema
+
+----
+<input xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">
+ <identifier>ietf-yang-types</identifier>
+ <version>2013-07-15</version>
+</input>
+----
+
+This call should fetch the source for ietf-yang-types YANG model from
+the mounted device.
+
+==== Netconf-connector + Netopeer
+https://github.com/cesnet/netopeer[Netopeer] (an open-source NETCONF server) can be used for
+testing/exploring NETCONF southbound in OpenDaylight.
+
+===== Netopeer installation
+https://www.docker.com/[Docker] container with netopeer will be used
+in this guid. To install docker and start the
+https://index.docker.io/u/dockeruser/netopeer/[netopeer image] perform
+following steps:
+
+. Install docker http://docs.docker.com/linux/step_one/
+. Start the netopeer image:
++
+----
+docker run -rm -t -p 1831:830 dockeruser/netopeer
+----
+. Verify netopeer is running by invoking (netopeer should send its
+ HELLO message right away:
++
+----
+ssh root@localhost -p 1831 -s netconf
+(password root)
+----
+
+===== Mounting netopeer NETCONF server
+Preconditions:
+
+* OpenDaylight is started with features +odl-restconf-all+ and
+ +odl-netconf-connector-all+.
+* Netopeer is up and running in docker
+
+Now just follow the chapter:
+<<_spawning_additional_netconf_connectors_while_the_controller_is_running, Spawning netconf-connector>>. In the payload change the:
+
+* name to e.g. netopeer
+* usernam/password to your system credentials
+* ip to localhost
+* port to 1831.
+
+After netopeer is mounted successfully, its configuration can be read
+using RESTCONF by invoking:
+
+GET
+http://localhost:8181/restconf/config/network-topology:network-topology/topology/topology-netconf/node/netopeer/yang-ext:mount/