Merge "Use OVSDB/docs for OVSDB"
[docs.git] / docs / user-guide / service-function-chaining.rst
index abe6ba73a7f1731d859c8814c7751e2c7d6a2d12..b4e1aa6b6a407564ce5faa91da371a9889c6b831 100644 (file)
@@ -7,9 +7,9 @@ OpenDaylight Service Function Chaining (SFC) Overview
 -----------------------------------------------------
 
 OpenDaylight Service Function Chaining (SFC) provides the ability to
 -----------------------------------------------------
 
 OpenDaylight Service Function Chaining (SFC) provides the ability to
-define an ordered list of network services (e.g. firewalls, load
-balancers). These service are then "stitched" together in the network to
-create a service chain. This project provides the infrastructure
+define an ordered list of network services (e.g. firewalls, load
+balancers). These services are then "stitched" together in the network
+to create a service chain. This project provides the infrastructure
 (chaining logic, APIs) needed for ODL to provision a service chain in
 the network and an end-user application for defining such chains.
 
 (chaining logic, APIs) needed for ODL to provision a service chain in
 the network and an end-user application for defining such chains.
 
@@ -39,13 +39,16 @@ SFC User Interface
 Overview
 ~~~~~~~~
 
 Overview
 ~~~~~~~~
 
-SFC User Interface (SFC-UI) is based on Dlux project. It provides an
-easy way to create, read, update and delete configuration stored in
-datastore. Moreover, it shows the status of all SFC features (e.g
-installed, uninstalled) and Karaf log messages as well.
+The SFC User interface comes with a Command Line Interface (CLI): it provides
+several Karaf console commands to show the SFC model (SF, SFFs, etc.) provisioned
+in the datastore.
 
 
-SFC-UI Architecture
-~~~~~~~~~~~~~~~~~~~
+
+SFC Web Interface (SFC-UI)
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Architecture
+^^^^^^^^^^^^
 
 SFC-UI operates purely by using RESTCONF.
 
 
 SFC-UI operates purely by using RESTCONF.
 
@@ -54,8 +57,8 @@ SFC-UI operates purely by using RESTCONF.
 
    SFC-UI integration into ODL
 
 
    SFC-UI integration into ODL
 
-Configuring SFC-UI
-~~~~~~~~~~~~~~~~~~
+How to access
+^^^^^^^^^^^^^
 
 1. Run ODL distribution (run karaf)
 
 
 1. Run ODL distribution (run karaf)
 
@@ -63,8 +66,70 @@ Configuring SFC-UI
 
 3. Visit SFC-UI on: ``http://<odl_ip_address>:8181/sfc/index.html``
 
 
 3. Visit SFC-UI on: ``http://<odl_ip_address>:8181/sfc/index.html``
 
+
+SFC Command Line Interface (SFC-CLI)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Overview
+^^^^^^^^
+
+The Karaf Container offers a complete Unix-like console that allows managing
+the container. This console can be extended with custom commands to manage the
+features deployed on it. This feature will add some basic commands to show the
+provisioned SFC entities.
+
+How to use it
+^^^^^^^^^^^^^
+
+The SFC-CLI implements commands to show some of the provisioned SFC entities:
+Service Functions, Service Function Forwarders, Service Function
+Chains, Service Function Paths, Service Function Classifiers, Service Nodes and
+Service Function Types:
+
+* List one/all provisioned Service Functions:
+
+  .. code-block:: bash
+
+     sfc:sf-list [--name <name>]
+
+* List one/all provisioned Service Function Forwarders:
+
+  .. code-block:: bash
+
+     sfc:sff-list [--name <name>]
+
+* List one/all provisioned Service Function Chains:
+
+  .. code-block:: bash
+
+     sfc:sfc-list [--name <name>]
+
+* List one/all provisioned Service Function Paths:
+
+  .. code-block:: bash
+
+     sfc:sfp-list [--name <name>]
+
+* List one/all provisioned Service Function Classifiers:
+
+  .. code-block:: bash
+
+     sfc:sc-list [--name <name>]
+
+* List one/all provisioned Service Nodes:
+
+  .. code-block:: bash
+
+     sfc:sn-list [--name <name>]
+
+* List one/all provisioned Service Function Types:
+
+  .. code-block:: bash
+
+     sfc:sft-list [--name <name>]
+
 SFC Southbound REST Plug-in
 SFC Southbound REST Plug-in
---------------------------
+---------------------------
 
 Overview
 ~~~~~~~~
 
 Overview
 ~~~~~~~~
@@ -89,7 +154,7 @@ triggered accordingly by changes in the SFC data stores.
 -  Rendered Service Path (RSP)
 
 Southbound REST Plug-in Architecture
 -  Rendered Service Path (RSP)
 
 Southbound REST Plug-in Architecture
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 From the user perspective, the REST plug-in is another SFC Southbound
 plug-in used to communicate with network devices.
 
 From the user perspective, the REST plug-in is another SFC Southbound
 plug-in used to communicate with network devices.
@@ -115,7 +180,7 @@ Tutorial
 
 Comprehensive tutorial on how to use the Southbound REST Plug-in and how
 to control network devices with it can be found on:
 
 Comprehensive tutorial on how to use the Southbound REST Plug-in and how
 to control network devices with it can be found on:
-https://wiki.opendaylight.org/view/Service_Function_Chaining:Main#SFC_101
+https://wiki.opendaylight.org/view/Service_Function_Chaining:Main#SFC_103
 
 SFC-OVS integration
 -------------------
 
 SFC-OVS integration
 -------------------
@@ -129,10 +194,9 @@ Classifier, etc.) to OVS objects (like Bridge,
 TerminationPoint=Port/Interface). The mapping takes care of automatic
 instantiation (setup) of corresponding object whenever its counterpart
 is created. For example, when a new SFF is created, the SFC-OVS plug-in
 TerminationPoint=Port/Interface). The mapping takes care of automatic
 instantiation (setup) of corresponding object whenever its counterpart
 is created. For example, when a new SFF is created, the SFC-OVS plug-in
-will create a new OVS bridge and when a new OVS Bridge is created, the
-SFC-OVS plug-in will create a new SFF.
+will create a new OVS bridge.
 
 
-The feature is intended for SFC users willing to use Open vSwitch as
+The feature is intended for SFC users willing to use Open vSwitch as an
 underlying network infrastructure for deploying RSPs (Rendered Service
 Paths).
 
 underlying network infrastructure for deploying RSPs (Rendered Service
 Paths).
 
@@ -161,54 +225,17 @@ Configuring SFC-OVS
 Tutorials
 ~~~~~~~~~
 
 Tutorials
 ~~~~~~~~~
 
-Verifying mapping from OVS to SFF
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Overview
-''''''''
-
-This tutorial shows the usual work flow when OVS configuration is
-transformed to corresponding SFC objects (in this case SFF).
-
-Prerequisites
-''''''''''''''
-
--  Open vSwitch installed (ovs-vsctl command available in shell)
-
--  SFC-OVS feature configured as stated above
-
-Instructions
-''''''''''''
-
-1. ``ovs-vsctl set-manager tcp:<odl_ip_address>:6640``
-
-2. ``ovs-vsctl add-br br1``
-
-3. ``ovs-vsctl add-port br1 testPort``
-
-Verification
-''''''''''''
-
-a. visit SFC User Interface:
-   ``http://<odl_ip_address>:8181/sfc/index.html#/sfc/serviceforwarder``
-
-b. use pure RESTCONF and send GET request to URL:
-   ``http://<odl_ip_address>:8181/restconf/config/service-function-forwarder:service-function-forwarders``
-
-There should be SFF, which name will be ending with *br1* and the SFF
-should containt two DataPlane locators: *br1* and *testPort*.
-
 Verifying mapping from SFF to OVS
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 Overview
 ''''''''
 
 Verifying mapping from SFF to OVS
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 Overview
 ''''''''
 
-This tutorial shows the usual workflow during creation of OVS Bridge
-with use of SFC APIs.
+This tutorial shows the usual workflow during creation of an OVS
+Bridge with use of the SFC APIs.
 
 Prerequisites
 
 Prerequisites
-''''''''''''''
+'''''''''''''
 
 -  Open vSwitch installed (ovs-vsctl command available in shell)
 
 
 -  Open vSwitch installed (ovs-vsctl command available in shell)
 
@@ -217,7 +244,7 @@ Prerequisites
 Instructions
 ''''''''''''
 
 Instructions
 ''''''''''''
 
-1. In shell execute: ``ovs-vsctl set-manager tcp:<odl_ip_address>:6640``
+1. In shell execute: ``ovs-vsctl set-manager tcp:<odl_ip_address>:6640``
 
 2. Send POST request to URL:
    ``http://<odl_ip_address>:8181/restconf/operations/service-function-forwarder-ovs:create-ovs-bridge``
 
 2. Send POST request to URL:
    ``http://<odl_ip_address>:8181/restconf/operations/service-function-forwarder-ovs:create-ovs-bridge``
@@ -237,18 +264,28 @@ Instructions
         }
     }
 
         }
     }
 
-Open\_vSwitch\_ip\_address is IP address of machine, where Open vSwitch
+Open\_vSwitch\_ip\_address is the IP address of the machine where Open vSwitch
 is installed.
 
 Verification
 ''''''''''''
 
 is installed.
 
 Verification
 ''''''''''''
 
-In shell execute: ``ovs-vsctl show``. There should be Bridge with name
-*br-test* and one port/interface called *br-test*.
+In a shell execute: ``ovs-vsctl show``. There should be a Bridge with
+the name *br-test* and one port/interface called *br-test*.
+
+Also, the corresponding SFF for this OVS Bridge should be configured,
+which can be verified through the SFC User Interface or RESTCONF as
+follows.
+
+a. Visit the SFC User Interface:
+   ``http://<odl_ip_address>:8181/sfc/index.html#/sfc/serviceforwarder``
+
+b. Use pure RESTCONF and send a GET request to URL:
+   ``http://<odl_ip_address>:8181/restconf/config/service-function-forwarder:service-function-forwarders``
+
+There should be an SFF, whose name will be ending with *br1* and the
+SFF should contain two DataPlane locators: *br1* and *testPort*.
 
 
-Also, corresponding SFF for this OVS Bridge should be configured, which
-can be verified through SFC User Interface or RESTCONF as stated in
-previous tutorial.
 
 SFC Classifier User Guide
 -------------------------
 
 SFC Classifier User Guide
 -------------------------
@@ -367,9 +404,10 @@ Administering or Managing Classifier
 Classifier runs alongside sfc\_agent, therefore the command for starting
 it locally is:
 
 Classifier runs alongside sfc\_agent, therefore the command for starting
 it locally is:
 
-::
+.. code-block:: bash
 
 
-    sudo python3.4 sfc-py/sfc_agent.py --rest --odl-ip-port localhost:8181 --auto-sff-name --nfq-class
+   sudo python3.4 sfc-py/sfc_agent.py --rest --odl-ip-port localhost:8181
+   --auto-sff-name --nfq-class
 
 SFC OpenFlow Renderer User Guide
 --------------------------------
 
 SFC OpenFlow Renderer User Guide
 --------------------------------
@@ -379,9 +417,10 @@ Overview
 
 The Service Function Chaining (SFC) OpenFlow Renderer (SFC OF Renderer)
 implements Service Chaining on OpenFlow switches. It listens for the
 
 The Service Function Chaining (SFC) OpenFlow Renderer (SFC OF Renderer)
 implements Service Chaining on OpenFlow switches. It listens for the
-creation of a Rendered Service Path (RSP), and once received it programs
-Service Function Forwarders (SFF) that are hosted on OpenFlow capable
-switches to steer packets through the service chain.
+creation of a Rendered Service Path (RSP) in the operational data store,
+and once received it programs Service Function Forwarders (SFF) that
+are hosted on OpenFlow capable switches to forward packets through the
+service chain.
 
 Common acronyms used in the following sections:
 
 
 Common acronyms used in the following sections:
 
@@ -398,12 +437,13 @@ Common acronyms used in the following sections:
 SFC OpenFlow Renderer Architecture
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 SFC OpenFlow Renderer Architecture
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-The SFC OF Renderer is invoked after a RSP is created using an MD-SAL
-listener called ``SfcOfRspDataListener``. Upon SFC OF Renderer
-initialization, the ``SfcOfRspDataListener`` registers itself to listen
-for RSP changes. When invoked, the ``SfcOfRspDataListener`` processes
-the RSP and calls the ``SfcOfFlowProgrammerImpl`` to create the
-necessary flows in the Service Function Forwarders configured in the
+The SFC OF Renderer is invoked after a RSP is created in the operational
+data store using an MD-SAL listener called ``SfcOfRspDataListener``.
+Upon SFC OF Renderer initialization, the ``SfcOfRspDataListener``
+registers itself to listen for RSP changes. When invoked, the
+``SfcOfRspDataListener`` processes the RSP and calls the
+``SfcOfFlowProgrammerImpl`` to create the necessary flows in
+the Service Function Forwarders configured in the
 RSP. Refer to the following diagram for more details.
 
 .. figure:: ./images/sfc/sfcofrenderer_architecture.png
 RSP. Refer to the following diagram for more details.
 
 .. figure:: ./images/sfc/sfcofrenderer_architecture.png
@@ -629,19 +669,23 @@ features must be installed.
 
 -  odl-sfc-ui (optional)
 
 
 -  odl-sfc-ui (optional)
 
+Since OpenDaylight Karaf features internally install dependent features
+all of the above features can be installed by simply installing the
+''odl-sfc-openflow-renderer'' feature.
+
 The following command can be used to view all of the currently installed
 Karaf features:
 
 The following command can be used to view all of the currently installed
 Karaf features:
 
-::
+.. code-block:: bash
 
 
-    opendaylight-user@root>feature:list -i
+   opendaylight-user@root>feature:list -i
 
 Or, pipe the command to a grep to see a subset of the currently
 installed Karaf features:
 
 
 Or, pipe the command to a grep to see a subset of the currently
 installed Karaf features:
 
-::
+.. code-block:: bash
 
 
-    opendaylight-user@root>feature:list -i | grep sfc
+   opendaylight-user@root>feature:list -i | grep sfc
 
 To install a particular feature, use the Karaf ``feature:install``
 command.
 
 To install a particular feature, use the Karaf ``feature:install``
 command.
@@ -652,8 +696,8 @@ SFC OF Renderer Tutorial
 Overview
 ^^^^^^^^
 
 Overview
 ^^^^^^^^
 
-In this tutorial, 2 different encapsulations will be shown: MPLS and
-NSH. The following Network Topology diagram is a logical view of the
+In this tutorial, the VXLAN-GPE NSH encapsulations will be shown.
+The following Network Topology diagram is a logical view of the
 SFFs and SFs involved in creating the Service Chains.
 
 .. figure:: ./images/sfc/sfcofrenderer_nwtopo.png
 SFFs and SFs involved in creating the Service Chains.
 
 .. figure:: ./images/sfc/sfcofrenderer_nwtopo.png
@@ -668,9 +712,9 @@ To use this example, SFF OpenFlow switches must be created and connected
 as illustrated above. Additionally, the SFs must be created and
 connected.
 
 as illustrated above. Additionally, the SFs must be created and
 connected.
 
-Note that RSP symmetry depends on Service Function Path symmetric field, if present.
-If not, the RSP will be symmetric if any of the SFs involved in the chain
-has the bidirectional field set to true.
+Note that RSP symmetry depends on the Service Function Path symmetric
+field, if present. If not, the RSP will be symmetric if any of the SFs
+involved in the chain has the bidirectional field set to true.
 
 Target Environment
 ^^^^^^^^^^^^^^^^^^
 
 Target Environment
 ^^^^^^^^^^^^^^^^^^
@@ -698,15 +742,15 @@ Steps to configure the SFC OF Renderer tutorial:
 
 4. Send the ``SFP`` RESTCONF configuration
 
 
 4. Send the ``SFP`` RESTCONF configuration
 
-5. Create the ``RSP`` with a RESTCONF RPC command
+5. The ``RSP`` will be created internally when the ``SFP`` is created.
 
 Once the configuration has been successfully created, query the Rendered
 Service Paths with either the SFC UI or via RESTCONF. Notice that the
 RSP is symmetrical, so the following 2 RSPs will be created:
 
 
 Once the configuration has been successfully created, query the Rendered
 Service Paths with either the SFC UI or via RESTCONF. Notice that the
 RSP is symmetrical, so the following 2 RSPs will be created:
 
--  sfc-path1
+-  sfc-path1-Path-<RSP-ID>
 
 
--  sfc-path1-Reverse
+-  sfc-path1-Path-<RSP-ID>-Reverse
 
 At this point the Service Chains have been created, and the OpenFlow
 Switches are programmed to steer traffic through the Service Chain.
 
 At this point the Service Chains have been created, and the OpenFlow
 Switches are programmed to steer traffic through the Service Chain.
@@ -714,13 +758,13 @@ Traffic can now be injected from a client into the Service Chain. To
 debug problems, the OpenFlow tables can be dumped with the following
 commands, assuming SFF1 is called ``s1`` and SFF2 is called ``s2``.
 
 debug problems, the OpenFlow tables can be dumped with the following
 commands, assuming SFF1 is called ``s1`` and SFF2 is called ``s2``.
 
-::
+.. code-block:: bash
 
 
-    sudo ovs-ofctl -O OpenFlow13  dump-flows s1
+   sudo ovs-ofctl -O OpenFlow13  dump-flows s1
 
 
-::
+.. code-block:: bash
 
 
-    sudo ovs-ofctl -O OpenFlow13  dump-flows s2
+   sudo ovs-ofctl -O OpenFlow13  dump-flows s2
 
 In all the following configuration sections, replace the ``${JSON}``
 string with the appropriate JSON configuration. Also, change the
 
 In all the following configuration sections, replace the ``${JSON}``
 string with the appropriate JSON configuration. Also, change the
@@ -737,13 +781,15 @@ elements using NSH encapsulation.
 The Service Function configuration can be sent with the following
 command:
 
 The Service Function configuration can be sent with the following
 command:
 
-::
+.. code-block:: bash
 
 
-    curl -i -H "Content-Type: application/json" -H "Cache-Control: no-cache" --data '${JSON}' -X PUT --user admin:admin http://localhost:8181/restconf/config/service-function:service-functions/
+   curl -i -H "Content-Type: application/json" -H "Cache-Control: no-cache"
+   --data '${JSON}' -X PUT --user
+   admin:admin http://localhost:8181/restconf/config/service-function:service-functions/
 
 **SF configuration JSON.**
 
 
 **SF configuration JSON.**
 
-::
+.. code-block:: json
 
     {
      "service-functions": {
 
     {
      "service-functions": {
@@ -785,13 +831,13 @@ command:
 The Service Function Forwarder configuration can be sent with the
 following command:
 
 The Service Function Forwarder configuration can be sent with the
 following command:
 
-::
+.. code-block:: bash
 
 
-    curl -i -H "Content-Type: application/json" -H "Cache-Control: no-cache" --data '${JSON}' -X PUT --user admin:admin http://localhost:8181/restconf/config/service-function-forwarder:service-function-forwarders/
+   curl -i -H "Content-Type: application/json" -H "Cache-Control: no-cache" --data '${JSON}' -X PUT --user admin:admin http://localhost:8181/restconf/config/service-function-forwarder:service-function-forwarders/
 
 **SFF configuration JSON.**
 
 
 **SFF configuration JSON.**
 
-::
+.. code-block:: json
 
     {
      "service-function-forwarders": {
 
     {
      "service-function-forwarders": {
@@ -855,13 +901,15 @@ following command:
 The Service Function Chain configuration can be sent with the following
 command:
 
 The Service Function Chain configuration can be sent with the following
 command:
 
-::
+.. code-block:: bash
 
 
-    curl -i -H "Content-Type: application/json" -H "Cache-Control: no-cache" --data '${JSON}' -X PUT --user admin:admin http://localhost:8181/restconf/config/service-function-chain:service-function-chains/
+   curl -i -H "Content-Type: application/json" -H "Cache-Control: no-cache"
+   --data '${JSON}' -X PUT --user
+   admin:admin http://localhost:8181/restconf/config/service-function-chain:service-function-chains/
 
 **SFC configuration JSON.**
 
 
 **SFC configuration JSON.**
 
-::
+.. code-block:: json
 
     {
      "service-function-chains": {
 
     {
      "service-function-chains": {
@@ -888,13 +936,13 @@ command:
 The Service Function Path configuration can be sent with the following
 command:
 
 The Service Function Path configuration can be sent with the following
 command:
 
-::
+.. code-block:: bash
 
 
-    curl -i -H "Content-Type: application/json" -H "Cache-Control: no-cache" --data '${JSON}' -X PUT --user admin:admin http://localhost:8181/restconf/config/service-function-path:service-function-paths/
+   curl -i -H "Content-Type: application/json" -H "Cache-Control: no-cache" --data '${JSON}' -X PUT --user admin:admin http://localhost:8181/restconf/config/service-function-path:service-function-paths/
 
 **SFP configuration JSON.**
 
 
 **SFP configuration JSON.**
 
-::
+.. code-block:: json
 
     {
       "service-function-paths": {
 
     {
       "service-function-paths": {
@@ -909,40 +957,14 @@ command:
       }
     }
 
       }
     }
 
-| **NSH Rendered Service Path creation**
-
-::
-
-    curl -i -H "Content-Type: application/json" -H "Cache-Control: no-cache" --data '${JSON}' -X POST --user admin:admin http://localhost:8181/restconf/operations/rendered-service-path:create-rendered-path/
-
-**RSP creation JSON.**
-
-::
-
-    {
-     "input": {
-         "name": "sfc-path1",
-         "parent-service-function-path": "sfc-path1"
-     }
-    }
-
-| **NSH Rendered Service Path removal**
-
-The following command can be used to remove a Rendered Service Path
-called ``sfc-path1``:
-
-::
-
-    curl -i -H "Content-Type: application/json" -H "Cache-Control: no-cache" --data '{"input": {"name": "sfc-path1" } }' -X POST --user admin:admin http://localhost:8181/restconf/operations/rendered-service-path:delete-rendered-path/
-
 | **NSH Rendered Service Path Query**
 
 The following command can be used to query all of the created Rendered
 Service Paths:
 
 | **NSH Rendered Service Path Query**
 
 The following command can be used to query all of the created Rendered
 Service Paths:
 
-::
+.. code-block:: bash
 
 
-    curl -H "Content-Type: application/json" -H "Cache-Control: no-cache" -X GET --user admin:admin http://localhost:8181/restconf/operational/rendered-service-path:rendered-service-paths/
+   curl -H "Content-Type: application/json" -H "Cache-Control: no-cache" -X GET --user admin:admin http://localhost:8181/restconf/operational/rendered-service-path:rendered-service-paths/
 
 SFC OF Renderer MPLS Tutorial
 '''''''''''''''''''''''''''''
 
 SFC OF Renderer MPLS Tutorial
 '''''''''''''''''''''''''''''
@@ -955,13 +977,15 @@ elements using MPLS encapsulation.
 The Service Function configuration can be sent with the following
 command:
 
 The Service Function configuration can be sent with the following
 command:
 
-::
+.. code-block:: bash
 
 
-    curl -i -H "Content-Type: application/json" -H "Cache-Control: no-cache" --data '${JSON}' -X PUT --user admin:admin http://localhost:8181/restconf/config/service-function:service-functions/
+   curl -i -H "Content-Type: application/json" -H "Cache-Control: no-cache"
+   --data '${JSON}' -X PUT --user
+   admin:admin http://localhost:8181/restconf/config/service-function:service-functions/
 
 **SF configuration JSON.**
 
 
 **SF configuration JSON.**
 
-::
+.. code-block:: json
 
     {
      "service-functions": {
 
     {
      "service-functions": {
@@ -1003,13 +1027,13 @@ command:
 The Service Function Forwarder configuration can be sent with the
 following command:
 
 The Service Function Forwarder configuration can be sent with the
 following command:
 
-::
+.. code-block:: bash
 
 
-    curl -i -H "Content-Type: application/json" -H "Cache-Control: no-cache" --data '${JSON}' -X PUT --user admin:admin http://localhost:8181/restconf/config/service-function-forwarder:service-function-forwarders/
+   curl -i -H "Content-Type: application/json" -H "Cache-Control: no-cache" --data '${JSON}' -X PUT --user admin:admin http://localhost:8181/restconf/config/service-function-forwarder:service-function-forwarders/
 
 **SFF configuration JSON.**
 
 
 **SFF configuration JSON.**
 
-::
+.. code-block:: json
 
     {
      "service-function-forwarders": {
 
     {
      "service-function-forwarders": {
@@ -1139,13 +1163,15 @@ following command:
 The Service Function Chain configuration can be sent with the following
 command:
 
 The Service Function Chain configuration can be sent with the following
 command:
 
-::
+.. code-block:: bash
 
 
-    curl -i -H "Content-Type: application/json" -H "Cache-Control: no-cache" --data '${JSON}' -X PUT --user admin:admin http://localhost:8181/restconf/config/service-function-chain:service-function-chains/
+   curl -i -H "Content-Type: application/json" -H "Cache-Control: no-cache"
+    --data '${JSON}' -X PUT --user admin:admin
+    http://localhost:8181/restconf/config/service-function-chain:service-function-chains/
 
 **SFC configuration JSON.**
 
 
 **SFC configuration JSON.**
 
-::
+.. code-block:: json
 
     {
      "service-function-chains": {
 
     {
      "service-function-chains": {
@@ -1172,13 +1198,15 @@ command:
 The Service Function Path configuration can be sent with the following
 command:
 
 The Service Function Path configuration can be sent with the following
 command:
 
-::
+.. code-block:: bash
 
 
-    curl -i -H "Content-Type: application/json" -H "Cache-Control: no-cache" --data '${JSON}' -X PUT --user admin:admin http://localhost:8181/restconf/config/service-function-path:service-function-paths/
+   curl -i -H "Content-Type: application/json" -H "Cache-Control: no-cache"
+   --data '${JSON}' -X PUT --user admin:admin
+    http://localhost:8181/restconf/config/service-function-path:service-function-paths/
 
 **SFP configuration JSON.**
 
 
 **SFP configuration JSON.**
 
-::
+.. code-block:: json
 
     {
       "service-function-paths": {
 
     {
       "service-function-paths": {
@@ -1195,38 +1223,21 @@ command:
 
 | **MPLS Rendered Service Path creation**
 
 
 | **MPLS Rendered Service Path creation**
 
-::
-
-    curl -i -H "Content-Type: application/json" -H "Cache-Control: no-cache" --data '${JSON}' -X POST --user admin:admin http://localhost:8181/restconf/operations/rendered-service-path:create-rendered-path/
-
-**RSP creation JSON.**
+.. code-block:: bash
 
 
-::
-
-    {
-     "input": {
-         "name": "sfc-path1",
-         "parent-service-function-path": "sfc-path1"
-     }
-    }
-
-| **MPLS Rendered Service Path removal**
-
-The following command can be used to remove a Rendered Service Path
-called ``sfc-path1``:
-
-::
-
-    curl -i -H "Content-Type: application/json" -H "Cache-Control: no-cache" --data '{"input": {"name": "sfc-path1" } }' -X POST --user admin:admin http://localhost:8181/restconf/operations/rendered-service-path:delete-rendered-path/
+   curl -i -H "Content-Type: application/json" -H "Cache-Control: no-cache"
+   --data '${JSON}' -X POST --user admin:admin
+    http://localhost:8181/restconf/operations/rendered-service-path:create-rendered-path/
 
 | **MPLS Rendered Service Path Query**
 
 The following command can be used to query all of the created Rendered
 Service Paths:
 
 
 | **MPLS Rendered Service Path Query**
 
 The following command can be used to query all of the created Rendered
 Service Paths:
 
-::
+.. code-block:: bash
 
 
-    curl -H "Content-Type: application/json" -H "Cache-Control: no-cache" -X GET --user admin:admin http://localhost:8181/restconf/operational/rendered-service-path:rendered-service-paths/
+   curl -H "Content-Type: application/json" -H "Cache-Control: no-cache" -X GET
+   --user admin:admin http://localhost:8181/restconf/operational/rendered-service-path:rendered-service-paths/
 
 SFC IOS XE Renderer User Guide
 ------------------------------
 
 SFC IOS XE Renderer User Guide
 ------------------------------
@@ -1348,9 +1359,9 @@ project. These files have to be copied to the ``cache/schema``
 directory, before Karaf is started. After that, custom capabilities have
 to be sent to network-topology:
 
 directory, before Karaf is started. After that, custom capabilities have
 to be sent to network-topology:
 
-::
+*  PUT ./config/network-topology:network-topology/topology/topology-netconf/node/<device-name>
 
 
-    PUT ./config/network-topology:network-topology/topology/topology-netconf/node/<device-name>
+   .. code-block:: xml
 
     <node xmlns="urn:TBD:params:xml:ns:yang:network-topology">
       <node-id>device-name</node-id>
 
     <node xmlns="urn:TBD:params:xml:ns:yang:network-topology">
       <node-id>device-name</node-id>
@@ -1396,9 +1407,9 @@ mountpoints are cached. The first step is to create LSF on node.
 
 ``Service Function Forwarder configuration``
 
 
 ``Service Function Forwarder configuration``
 
-::
+*  PUT ./config/service-function-forwarder:service-function-forwarders
 
 
-    PUT ./config/service-function-forwarder:service-function-forwarders
+   .. code-block:: json
 
     {
         "service-function-forwarders": {
 
     {
         "service-function-forwarders": {
@@ -1425,9 +1436,9 @@ If the IOS-XE node with appropriate management IP exists, this
 configuration is mapped and LSF is created on the device. The same
 approach is used for Service Functions.
 
 configuration is mapped and LSF is created on the device. The same
 approach is used for Service Functions.
 
-::
+*  PUT ./config/service-function:service-functions
 
 
-    PUT ./config/service-function:service-functions
+   .. code-block:: json
 
     {
         "service-functions": {
 
     {
         "service-functions": {
@@ -1481,9 +1492,9 @@ approach is used for Service Functions.
 All these SFs are configured on the same device as the LSF. The next
 step is to prepare Service Function Chain.
 
 All these SFs are configured on the same device as the LSF. The next
 step is to prepare Service Function Chain.
 
-::
+*  PUT ./config/service-function-chain:service-function-chains/
 
 
-    PUT ./config/service-function-chain:service-function-chains/
+   .. code-block:: json
 
     {
         "service-function-chains": {
 
     {
         "service-function-chains": {
@@ -1511,9 +1522,9 @@ step is to prepare Service Function Chain.
 
 Service Function Path:
 
 
 Service Function Path:
 
-::
+*  PUT ./config/service-function-path:service-function-paths/
 
 
-    PUT ./config/service-function-path:service-function-paths/
+   .. code-block:: json
 
     {
         "service-function-paths": {
 
     {
         "service-function-paths": {
@@ -1530,9 +1541,9 @@ Service Function Path:
 
 Without a classifier, there is possibility to POST RSP directly.
 
 
 Without a classifier, there is possibility to POST RSP directly.
 
-::
+*  POST ./operations/rendered-service-path:create-rendered-path
 
 
-    POST ./operations/rendered-service-path:create-rendered-path
+   .. code-block:: json
 
     {
       "input": {
 
     {
       "input": {
@@ -1640,7 +1651,7 @@ selection algorithm when creating a Rendered Service Path.
    content is needed at the moment:
    Service\_function\_schudule\_type.json
 
    content is needed at the moment:
    Service\_function\_schudule\_type.json
 
-   ::
+   .. code-block:: json
 
        {
          "service-function-scheduler-types": {
 
        {
          "service-function-scheduler-types": {
@@ -1671,12 +1682,14 @@ selection algorithm when creating a Rendered Service Path.
 
    If using the Linux curl command, it could be:
 
 
    If using the Linux curl command, it could be:
 
-   ::
+   .. code-block:: bash
+
+      curl -i -H "Content-Type: application/json" -H "Cache-Control: no-cache"
+      --data '$${Service_function_schudule_type.json}' -X PUT
+      --user admin:admin http://localhost:8181/restconf/config/service-function-scheduler-type:service-function-scheduler-types/
 
 
-       curl -i -H "Content-Type: application/json" -H "Cache-Control: no-cache" --data '$${Service_function_schudule_type.json}'
-       -X PUT --user admin:admin http://localhost:8181/restconf/config/service-function-scheduler-type:service-function-scheduler-types/
 
 
-   Here is also a snapshot for using the RESTClient plugin:
+Here is also a snapshot for using the RESTClient plugin:
 
 .. figure:: ./images/sfc/RESTClient-snapshot.png
    :alt: Mozilla Firefox RESTClient
 
 .. figure:: ./images/sfc/RESTClient-snapshot.png
    :alt: Mozilla Firefox RESTClient
@@ -1809,7 +1822,7 @@ c. Get Monitoring data from NETCONF server. These monitoring data should
 
 static XML data like this:
 
 
 static XML data like this:
 
-::
+.. code-block:: xml
 
     <?xml version="1.0" encoding="UTF-8"?>
     <service-function-description-monitor-report>
 
     <?xml version="1.0" encoding="UTF-8"?>
     <service-function-description-monitor-report>
@@ -1911,7 +1924,7 @@ c. Depoly SFFs and SFs. import the service-function-forwarders.json and
 
 service-function-forwarders.json:
 
 
 service-function-forwarders.json:
 
-::
+.. code-block:: json
 
     {
       "service-function-forwarders": {
 
     {
       "service-function-forwarders": {
@@ -2051,7 +2064,7 @@ service-function-forwarders.json:
 
 service-functions.json:
 
 
 service-functions.json:
 
-::
+.. code-block:: json
 
     {
       "service-functions": {
 
     {
       "service-functions": {
@@ -2146,7 +2159,7 @@ service-functions.json:
 
 The deployed topology like this:
 
 
 The deployed topology like this:
 
-::
+.. code-block:: json
 
                   +----+           +----+          +----+
                   |sff1|+----------|sff3|---------+|sff2|
 
                   +----+           +----+          +----+
                   |sff1|+----------|sff3|---------+|sff2|
@@ -2257,7 +2270,7 @@ Create an algorithm
 POST -
 http://127.0.0.1:8181/restconf/config/service-function-group-algorithm:service-function-group-algorithms
 
 POST -
 http://127.0.0.1:8181/restconf/config/service-function-group-algorithm:service-function-group-algorithms
 
-::
+.. code-block:: json
 
     {
         "service-function-group-algorithm": [
 
     {
         "service-function-group-algorithm": [
@@ -2285,7 +2298,7 @@ Create a group
 POST -
 http://127.0.0.1:8181/restconf/config/service-function-group:service-function-groups
 
 POST -
 http://127.0.0.1:8181/restconf/config/service-function-group:service-function-groups
 
-::
+.. code-block:: json
 
     {
         "service-function-group": [
 
     {
         "service-function-group": [
@@ -2614,47 +2627,51 @@ Overview
 Rationale
 ^^^^^^^^^
 When the current SFC is deployed in a cloud environment, it is assumed that each
 Rationale
 ^^^^^^^^^
 When the current SFC is deployed in a cloud environment, it is assumed that each
-switch connected to a Service Function is configured as a Service Function Forwarder and
-each Service Function is connected to its Service Function Forwarder depending on the
-Compute Node where the Virtual Machine is located.
+switch connected to a Service Function is configured as a Service Function
+Forwarder and each Service Function is connected to its Service Function
+Forwarder depending on the Compute Node where the Virtual Machine is located.
 
 .. figure:: ./images/sfc/sfc-in-cloud.png
    :alt: Deploying SFC in Cloud Environments
 
 
 .. figure:: ./images/sfc/sfc-in-cloud.png
    :alt: Deploying SFC in Cloud Environments
 
-As shown in the picture above, this solution allows the basic cloud use cases to be fulfilled,
-as for example, the ones required in OPNFV Brahmaputra, however, some advanced use cases
-like the transparent migration of VMs can not be implemented. The Logical Service Function Forwarder
-enables the following advanced use cases:
+As shown in the picture above, this solution allows the basic cloud use cases to
+be fulfilled, as for example, the ones required in OPNFV Brahmaputra, however,
+some advanced use cases like the transparent migration of VMs can not be
+implemented. The Logical Service Function Forwarder enables the following
+advanced use cases:
 
 1. Service Function mobility without service disruption
 2. Service Functions load balancing and failover
 
 
 1. Service Function mobility without service disruption
 2. Service Functions load balancing and failover
 
-As shown in the picture below, the Logical Service Function Forwarder concept extends the current
-SFC northbound API to provide an abstraction of the underlying Data Center infrastructure.
-The Data Center underlaying network can be abstracted by a single SFF. This single SFF uses
-the logical port UUID as data plane locator to connect SFs globally and in a location-transparent manner.
+As shown in the picture below, the Logical Service Function Forwarder concept
+extends the current SFC northbound API to provide an abstraction of the
+underlying Data Center infrastructure. The Data Center underlaying network can
+be abstracted by a single SFF. This single SFF uses the logical port UUID as
+data plane locator to connect SFs globally and in a location-transparent manner.
 SFC makes use of `Genius <./genius-user-guide.html>`__ project to track the
 location of the SF's logical ports.
 
 .. figure:: ./images/sfc/single-logical-sff-concept.png
    :alt: Single Logical SFF concept
 
 SFC makes use of `Genius <./genius-user-guide.html>`__ project to track the
 location of the SF's logical ports.
 
 .. figure:: ./images/sfc/single-logical-sff-concept.png
    :alt: Single Logical SFF concept
 
-The SFC internally distributes the necessary flow state over the relevant switches based on the
-internal Data Center topology and the deployment of SFs.
+The SFC internally distributes the necessary flow state over the relevant
+switches based on the internal Data Center topology and the deployment of SFs.
 
 Changes in data model
 ~~~~~~~~~~~~~~~~~~~~~
 
 Changes in data model
 ~~~~~~~~~~~~~~~~~~~~~
-The Logical Service Function Forwarder concept extends the current SFC northbound API to provide
-an abstraction of the underlying Data Center infrastructure.
+The Logical Service Function Forwarder concept extends the current SFC
+northbound API to provide an abstraction of the underlying Data Center
+infrastructure.
 
 
-The Logical SFF simplifies the configuration of the current SFC data model by reducing the number
-of parameters to be be configured in every SFF, since the controller will discover those parameters
-by interacting with the services offered by the `Genius <./genius-user-guide.html>`__ project.
+The Logical SFF simplifies the configuration of the current SFC data model by
+reducing the number of parameters to be be configured in every SFF, since the
+controller will discover those parameters by interacting with the services
+offered by the `Genius <./genius-user-guide.html>`__ project.
 
 
-The following picture shows the Logical SFF data model. The model gets simplified as most of the
-configuration parameters of the current SFC data model are discovered in runtime. The complete
-YANG model can be found here `logical SFF model
-<https://github.com/opendaylight/sfc/blob/master/sfc-model/src/main/yang/service-function-forwarder-logical.yang>`__.
+The following picture shows the Logical SFF data model. The model gets
+simplified as most of the configuration parameters of the current SFC data model
+are discovered in runtime. The complete YANG model can be found here
+`logical SFF model <https://github.com/opendaylight/sfc/blob/master/sfc-model/src/main/yang/service-function-forwarder-logical.yang>`__.
 
 .. figure:: ./images/sfc/logical-sff-datamodel.png
    :alt: Logical SFF data model
 
 .. figure:: ./images/sfc/logical-sff-datamodel.png
    :alt: Logical SFF data model
@@ -2662,13 +2679,16 @@ YANG model can be found here `logical SFF model
 How to configure the Logical SFF
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 The following are examples to configure the Logical SFF:
 How to configure the Logical SFF
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 The following are examples to configure the Logical SFF:
-::
 
 
-    curl -i -H "Content-Type: application/json" -H "Cache-Control: no-cache" --data '${JSON}' -X PUT --user admin:admin http://localhost:8181/restconf/config/restconf/config/service-function:service-functions/
+.. code-block:: bash
+
+   curl -i -H "Content-Type: application/json" -H "Cache-Control: no-cache"
+   --data '${JSON}' -X PUT --user
+   admin:admin http://localhost:8181/restconf/config/restconf/config/service-function:service-functions/
 
 **Service Functions JSON.**
 
 
 **Service Functions JSON.**
 
-::
+.. code-block:: json
 
     {
     "service-functions": {
 
     {
     "service-functions": {
@@ -2702,13 +2722,15 @@ The following are examples to configure the Logical SFF:
     }
     }
 
     }
     }
 
-::
+.. code-block:: bash
 
 
-    curl -i -H "Content-Type: application/json" -H "Cache-Control: no-cache" --data '${JSON}' -X PUT --user admin:admin http://localhost:8181/restconf/config/service-function-forwarder:service-function-forwarders/
+   curl -i -H "Content-Type: application/json" -H "Cache-Control: no-cache"
+   --data '${JSON}' -X PUT --user
+   admin:admin http://localhost:8181/restconf/config/service-function-forwarder:service-function-forwarders/
 
 **Service Function Forwarders JSON.**
 
 
 **Service Function Forwarders JSON.**
 
-::
+.. code-block:: json
 
     {
     "service-function-forwarders": {
 
     {
     "service-function-forwarders": {
@@ -2720,13 +2742,15 @@ The following are examples to configure the Logical SFF:
     }
     }
 
     }
     }
 
-::
+.. code-block:: bash
 
 
-    curl -i -H "Content-Type: application/json" -H "Cache-Control: no-cache" --data '${JSON}' -X PUT --user admin:admin http://localhost:8181/restconf/config/service-function-chain:service-function-chains/
+   curl -i -H "Content-Type: application/json" -H "Cache-Control: no-cache"
+   --data '${JSON}' -X PUT --user
+   admin:admin http://localhost:8181/restconf/config/service-function-chain:service-function-chains/
 
 **Service Function Chains JSON.**
 
 
 **Service Function Chains JSON.**
 
-::
+.. code-block:: json
 
     {
     "service-function-chains": {
 
     {
     "service-function-chains": {
@@ -2757,13 +2781,15 @@ The following are examples to configure the Logical SFF:
     }
     }
 
     }
     }
 
-::
+.. code-block:: bash
 
 
-    curl -i -H "Content-Type: application/json" -H "Cache-Control: no-cache" --data '${JSON}' -X PUT --user admin:admin http://localhost:8182/restconf/config/service-function-chain:service-function-paths/
+   curl -i -H "Content-Type: application/json" -H "Cache-Control: no-cache"
+   --data '${JSON}' -X PUT --user
+    admin:admin http://localhost:8182/restconf/config/service-function-chain:service-function-paths/
 
 **Service Function Paths JSON.**
 
 
 **Service Function Paths JSON.**
 
-::
+.. code-block:: json
 
     {
     "service-function-paths": {
 
     {
     "service-function-paths": {
@@ -2802,15 +2828,17 @@ The following picture shows a topology and traffic flow (in green) which corresp
    Logical SFF Example
 
 
    Logical SFF Example
 
 
+The Logical SFF functionality allows OpenDaylight to find out the SFFs holding
+the SFs involved in a path. In this example the SFFs affected are Node3 and
+Node4 thus the controller renders the flows containing NSH parameters just in
+those SFFs.
 
 
-The Logical SFF functionality allows OpenDaylight to find out the SFFs holding the SFs involved in a path. In this example
-the SFFs affected are Node3 and Node4 thus the controller renders the flows containing NSH parameters just in those SFFs.
-
-Here you have the new flows rendered in Node3 and Node4 which implement the NSH protocol. Every Rendered Service Path is represented
-by an NSP value. We provisioned a symmetric RSP so we get two NSPs: 8388613 and 5. Node3 holds the first SF of NSP 8388613 and
-the last SF of NSP 5. Node 4 holds the first SF of NSP 5 and the last SF of NSP 8388613. Both Node3 and Node4 will pop the NSH header
-when the received packet has gone through the last SF of its path.
-
+Here you have the new flows rendered in Node3 and Node4 which implement the NSH
+protocol. Every Rendered Service Path is represented by an NSP value. We
+provisioned a symmetric RSP so we get two NSPs: 8388613 and 5. Node3 holds the
+first SF of NSP 8388613 and the last SF of NSP 5. Node 4 holds the first SF of
+NSP 5 and the last SF of NSP 8388613. Both Node3 and Node4 will pop the NSH
+header when the received packet has gone through the last SF of its path.
 
 **Rendered flows Node 3**
 
 
 **Rendered flows Node 3**
 
@@ -2839,8 +2867,9 @@ when the received packet has gone through the last SF of its path.
  cookie=0xba5eba1100000203, duration=68.996s, table=87, n_packets=0, n_bytes=0, priority=650,nsi=253,nsp=8388613 actions=pop_nsh,set_field:02:14:84:5e:a8:5d->eth_src,resubmit(,17)
 
 
  cookie=0xba5eba1100000203, duration=68.996s, table=87, n_packets=0, n_bytes=0, priority=650,nsi=253,nsp=8388613 actions=pop_nsh,set_field:02:14:84:5e:a8:5d->eth_src,resubmit(,17)
 
 
-An interesting scenario to show the Logical SFF strength is the migration of a SF from a compute node to another.
-The OpenDaylight will learn the new topology by itself, then it will re-render the new flows to the new SFFs affected.
+An interesting scenario to show the Logical SFF strength is the migration of a
+SF from a compute node to another. The OpenDaylight will learn the new topology
+by itself, then it will re-render the new flows to the new SFFs affected.
 
 .. figure:: ./images/sfc/single-logical-sff-example-migration.png
    :alt: Logical SFF - SF Migration Example
 
 .. figure:: ./images/sfc/single-logical-sff-example-migration.png
    :alt: Logical SFF - SF Migration Example
@@ -2850,10 +2879,11 @@ The OpenDaylight will learn the new topology by itself, then it will re-render t
    Logical SFF - SF Migration Example
 
 
    Logical SFF - SF Migration Example
 
 
-In our example, SF2 is moved from Node4 to Node2 then OpenDaylight removes NSH specific flows from Node4 and puts them in Node2.
-Check below flows showing this effect. Now Node3 keeps holding the first SF of NSP 8388613 and the last SF of NSP 5;
-but Node2 becomes the new holder of the first SF of NSP 5 and the last SF of NSP 8388613.
-
+In our example, SF2 is moved from Node4 to Node2 then OpenDaylight removes NSH
+specific flows from Node4 and puts them in Node2. Check below flows showing this
+effect. Now Node3 keeps holding the first SF of NSP 8388613 and the last SF of
+NSP 5; but Node2 becomes the new holder of the first SF of NSP 5 and the last SF
+of NSP 8388613.
 
 **Rendered Flows Node 3 After Migration**
 
 
 **Rendered Flows Node 3 After Migration**
 
@@ -2924,7 +2954,7 @@ a Logical SFF as an attachment-point:
 The following ACL enables traffic intended for port 80 within the subnetwork
 192.168.2.0/24, for RSP1 and RSP1-Reverse.
 
 The following ACL enables traffic intended for port 80 within the subnetwork
 192.168.2.0/24, for RSP1 and RSP1-Reverse.
 
-::
+.. code-block:: json
 
         {
           "access-lists": {
 
         {
           "access-lists": {
@@ -2983,9 +3013,11 @@ The following ACL enables traffic intended for port 80 within the subnetwork
           }
         }
 
           }
         }
 
-::
+.. code-block:: bash
 
 
-  curl -i -H "Content-Type: application/json" -H "Cache-Control: no-cache" --data '${JSON}' -X PUT --user admin:admin http://localhost:8181/restconf/config/ietf-access-control-list:access-lists/
+   curl -i -H "Content-Type: application/json" -H "Cache-Control: no-cache"
+   --data '${JSON}' -X PUT --user
+   admin:admin http://localhost:8181/restconf/config/ietf-access-control-list:access-lists/
 
 **Configure a classifier JSON**
 
 
 **Configure a classifier JSON**
 
@@ -2993,7 +3025,7 @@ The following JSON provisions a classifier, having a Logical SFF as an
 attachment point. The value of the field 'interface' is where you
 indicate the neutron ports of the VMs you want to classify.
 
 attachment point. The value of the field 'interface' is where you
 indicate the neutron ports of the VMs you want to classify.
 
-::
+.. code-block:: json
 
         {
           "service-function-classifiers": {
 
         {
           "service-function-classifiers": {
@@ -3015,19 +3047,23 @@ indicate the neutron ports of the VMs you want to classify.
           }
         }
 
           }
         }
 
-::
+.. code-block:: bash
 
 
-  curl -i -H "Content-Type: application/json" -H "Cache-Control: no-cache" --data '${JSON}' -X PUT --user admin:admin http://localhost:8181/restconf/config/service-function-classifier:service-function-classifiers/
+   curl -i -H "Content-Type: application/json" -H "Cache-Control: no-cache"
+   --data '${JSON}' -X PUT --user
+   admin:admin http://localhost:8181/restconf/config/service-function-classifier:service-function-classifiers/
 
 .. _sfc-user-guide-pipeline-impacts:
 
 SFC pipeline impacts
 ~~~~~~~~~~~~~~~~~~~~
 
 
 .. _sfc-user-guide-pipeline-impacts:
 
 SFC pipeline impacts
 ~~~~~~~~~~~~~~~~~~~~
 
-After binding SFC service with a particular interface by means of Genius, as explained in the :ref:`Genius User Guide <genius-user-guide-binding-services>`,
-the entry point in the SFC pipeline will be table 82 (SFC_TRANSPORT_CLASSIFIER_TABLE), and from that point, packet
-processing will be similar to the :ref:`SFC OpenFlow pipeline <sfc-user-guide-sfc-of-pipeline>`, just with another set
-of specific tables for the SFC service.
+After binding SFC service with a particular interface by means of Genius, as
+explained in the :ref:`Genius User Guide <genius-user-guide-binding-services>`,
+the entry point in the SFC pipeline will be table 82
+(SFC_TRANSPORT_CLASSIFIER_TABLE), and from that point, packet processing will be
+similar to the :ref:`SFC OpenFlow pipeline <sfc-user-guide-sfc-of-pipeline>`,
+just with another set of specific tables for the SFC service.
 
 This picture shows the SFC pipeline after service integration with Genius:
 
 
 This picture shows the SFC pipeline after service integration with Genius:
 
@@ -3035,3 +3071,387 @@ This picture shows the SFC pipeline after service integration with Genius:
    :alt: SFC Logical SFF OpenFlow pipeline
 
    SFC Logical SFF OpenFlow pipeline
    :alt: SFC Logical SFF OpenFlow pipeline
 
    SFC Logical SFF OpenFlow pipeline
+
+Directional data plane locators for symmetric paths
+---------------------------------------------------
+
+Overview
+~~~~~~~~
+
+A symmetric path results from a Service Function Path with the symmetric field
+set or when any of the constituent Service Functions is set as bidirectional.
+Such a path is defined by two Rendered Service Paths where one of them steers
+the traffic through the same Service Functions as the other but in opposite
+order. These two Rendered Service Paths are also said to be symmetric to each
+other and gives to each path a sense of direction: The Rendered Service Path
+that corresponds to the same order of Service Functions as that defined on the
+Service Function Chain is tagged as the forward or up-link path, while the
+Rendered Service Path that corresponds to the opposite order is tagged as
+reverse or down-link path.
+
+Directional data plane locators allow the use of different interfaces or
+interface details between the Service Function Forwarder and the Service
+Function in relation with the direction of the path for which they are being
+used. This function is relevant for Service Functions that would have no other
+way of discerning the direction of the traffic, like for example legacy
+bump-in-the-wire network devices.
+
+::
+
+                        +-----------------------------------------------+
+                        |                                               |
+                        |                                               |
+                        |                      SF                       |
+                        |                                               |
+                        |  sf-forward-dpl                sf-reverse-dpl |
+                        +--------+-----------------------------+--------+
+                                 |                             |
+                         ^       |      +              +       |      ^
+                         |       |      |              |       |      |
+                         |       |      |              |       |      |
+                         +       |      +              +       |      +
+                    Forward Path | Reverse Path   Forward Path | Reverse Path
+                         +       |      +              +       |      +
+                         |       |      |              |       |      |
+                         |       |      |              |       |      |
+                         |       |      |              |       |      |
+                         +       |      v              v       |      +
+                                 |                             |
+                     +-----------+-----------------------------------------+
+      Forward Path   |     sff-forward-dpl               sff-reverse-dpl   |   Forward Path
+    +--------------> |                                                     | +-------------->
+                     |                                                     |
+                     |                         SFF                         |
+                     |                                                     |
+    <--------------+ |                                                     | <--------------+
+      Reverse Path   |                                                     |   Reverse Path
+                     +-----------------------------------------------------+
+
+As shown in the previous figure, the forward path egress from the Service
+Function Forwarder towards the Service Function is defined by the
+sff-forward-dpl and sf-forward-dpl data plane locators. The forward path
+ingress from the Service Function to the Service Function Forwarder is defined
+by the sf-reverse-dpl and sff-reverse-dpl data plane locators. For the reverse
+path, it's the opposite: the sff-reverse-dpl and sf-reverse-dpl define the
+egress from the Service Function Forwarder to the Service Function, and the
+sf-forward-dpl and sff-forward-dpl define the ingress into the Service Function
+Forwarder from the Service Function.
+
+.. note:: Directional data plane locators are only supported in combination
+          with the SFC OF Renderer at this time.
+
+Configuration
+~~~~~~~~~~~~~
+
+Directional data plane locators are configured within the
+service-function-forwarder in the service-function-dictionary entity, which
+describes the association between a Service Function Forwarder and Service
+Functions:
+
+.. code-block:: service-function-forwarder.yang
+
+        list service-function-dictionary {
+            key "name";
+            leaf name {
+              type sfc-common:sf-name;
+              description
+                  "The name of the service function.";
+            }
+            container sff-sf-data-plane-locator {
+              description
+                "SFF and SF data plane locators to use when sending
+                 packets from this SFF to the associated SF";
+              leaf sf-dpl-name {
+                type sfc-common:sf-data-plane-locator-name;
+                description
+                  "The SF data plane locator to use when sending
+                   packets to the associated service function.
+                   Used both as forward and reverse locators for
+                   paths of a symmetric chain.";
+              }
+              leaf sff-dpl-name {
+                type sfc-common:sff-data-plane-locator-name;
+                description
+                  "The SFF data plane locator to use when sending
+                   packets to the associated service function.
+                   Used both as forward and reverse locators for
+                   paths of a symmetric chain.";
+              }
+              leaf sf-forward-dpl-name {
+                type sfc-common:sf-data-plane-locator-name;
+                description
+                  "The SF data plane locator to use when sending
+                   packets to the associated service function
+                   on the forward path of a symmetric chain";
+              }
+              leaf sf-reverse-dpl-name {
+                type sfc-common:sf-data-plane-locator-name;
+                description
+                  "The SF data plane locator to use when sending
+                   packets to the associated service function
+                   on the reverse path of a symmetric chain";
+              }
+              leaf sff-forward-dpl-name {
+                type sfc-common:sff-data-plane-locator-name;
+                description
+                  "The SFF data plane locator to use when sending
+                   packets to the associated service function
+                   on the forward path of a symmetric chain.";
+              }
+              leaf sff-reverse-dpl-name {
+                type sfc-common:sff-data-plane-locator-name;
+                description
+                  "The SFF data plane locator to use when sending
+                   packets to the associated service function
+                   on the reverse path of a symmetric chain.";
+              }
+            }
+        }
+
+Example
+~~~~~~~
+
+The following configuration example is based on the Logical SFF configuration
+one. Only the Service Function and Service Function Forwarder configuration
+changes with respect to that example:
+
+.. code-block:: bash
+
+   curl -i -H "Content-Type: application/json" -H "Cache-Control: no-cache"
+   --data '${JSON}' -X PUT --user
+   admin:admin http://localhost:8181/restconf/config/restconf/config/service-function:service-functions/
+
+**Service Functions JSON.**
+
+.. code-block:: json
+
+    {
+    "service-functions": {
+        "service-function": [
+            {
+                "name": "firewall-1",
+                "type": "firewall",
+                "sf-data-plane-locator": [
+                    {
+                        "name": "sf-firewall-net-A-dpl",
+                        "interface-name": "eccb57ae-5a2e-467f-823e-45d7bb2a6a9a",
+                        "transport": "service-locator:mac",
+                        "service-function-forwarder": "sfflogical1"
+
+                    },
+                    {
+                        "name": "sf-firewall-net-B-dpl",
+                        "interface-name": "7764b6f1-a5cd-46be-9201-78f917ddee1d",
+                        "transport": "service-locator:mac",
+                        "service-function-forwarder": "sfflogical1"
+
+                    }
+                ]
+            },
+            {
+                "name": "dpi-1",
+                "type": "dpi",
+                "sf-data-plane-locator": [
+                    {
+                        "name": "sf-dpi-net-A-dpl",
+                        "interface-name": "df15ac52-e8ef-4e9a-8340-ae0738aba0c0",
+                        "transport": "service-locator:mac",
+                        "service-function-forwarder": "sfflogical1"
+                    },
+                    {
+                        "name": "sf-dpi-net-B-dpl",
+                        "interface-name": "1bb09b01-422d-4ccf-8d7a-9ebf00d1a1a5",
+                        "transport": "service-locator:mac",
+                        "service-function-forwarder": "sfflogical1"
+                    }
+                ]
+            }
+        ]
+    }
+    }
+
+.. code-block:: bash
+
+   curl -i -H "Content-Type: application/json" -H "Cache-Control: no-cache"
+   --data '${JSON}' -X PUT --user
+   admin:admin http://localhost:8181/restconf/config/service-function-forwarder:service-function-forwarders/
+
+**Service Function Forwarders JSON.**
+
+.. code-block:: json
+
+    {
+    "service-function-forwarders": {
+        "service-function-forwarder": [
+            {
+                "name": "sfflogical1"
+                "sff-data-plane-locator": [
+                    {
+                        "name": "sff-firewall-net-A-dpl",
+                        "data-plane-locator": {
+                            "interface-name": "eccb57ae-5a2e-467f-823e-45d7bb2a6a9a",
+                            "transport": "service-locator:mac"
+                        }
+                    },
+                    {
+                        "name": "sff-firewall-net-B-dpl",
+                        "data-plane-locator": {
+                            "interface-name": "7764b6f1-a5cd-46be-9201-78f917ddee1d",
+                            "transport": "service-locator:mac"
+                        }
+                    },
+                    {
+                        "name": "sff-dpi-net-A-dpl",
+                        "data-plane-locator": {
+                            "interface-name": "df15ac52-e8ef-4e9a-8340-ae0738aba0c0",
+                            "transport": "service-locator:mac"
+                        }
+                    },
+                    {
+                        "name": "sff-dpi-net-B-dpl",
+                        "data-plane-locator": {
+                            "interface-name": "1bb09b01-422d-4ccf-8d7a-9ebf00d1a1a5",
+                            "transport": "service-locator:mac"
+                        }
+                    }
+                ],
+                "service-function-dictionary": [
+                    {
+                        "name": "firewall-1",
+                        "sff-sf-data-plane-locator": {
+                            "sf-forward-dpl-name": "sf-firewall-net-A-dpl",
+                            "sf-reverse-dpl-name": "sf-firewall-net-B-dpl",
+                            "sff-forward-dpl-name": "sff-firewall-net-A-dpl",
+                            "sff-reverse-dpl-name": "sff-firewall-net-B-dpl",
+                        }
+                    },
+                    {
+                        "name": "dpi-1",
+                        "sff-sf-data-plane-locator": {
+                            "sf-forward-dpl-name": "sf-dpi-net-A-dpl",
+                            "sf-reverse-dpl-name": "sf-dpi-net-B-dpl",
+                            "sff-forward-dpl-name": "sff-dpi-net-A-dpl",
+                            "sff-reverse-dpl-name": "sff-dpi-net-B-dpl",
+                        }
+                    }
+                ]
+            }
+        ]
+    }
+    }
+
+In comparison with the Logical SFF example, noticed that each Service Function
+is configured with two data plane locators instead of one so that each can be
+used in different directions of the path. To specify which locator is used on
+which direction, the Service Function Forwarder configuration is also more
+extensive compared to the previous example.
+
+When comparing this example with the Logical SFF one, that the Service Function
+Forwarder is configured with data plane locators and that they hold the same
+interface name values as the corresponding Service Function interfaces. This is
+because in the Logical SFF particular case, a single logical interface fully
+describes an attachment of a Service Function Forwarder to a Service Function
+on both the Service Function and Service Function Forwarder sides. For
+non-Logical SFF scenarios, it would be expected for the data plane locators to
+have different values as we have seen on other examples through out this user
+guide. For example, if mac addresses are to be specified in the locators, the
+Service Function would have a different mac address than the Service Function
+Forwarder.
+
+
+As a result of the overall configuration, two Rendered Service Paths are
+implemented. The forward path:
+
+::
+
+                        +------------+                +-------+
+                        | firewall-1 |                | dpi- 1 |
+                        +---+---+----+                +--+--+-+
+                            ^   |                        ^  |
+                   net-A-dpl|   |net-B-dpl      net-A-dpl|  |net-B-dpl
+                            |   |                        |  |
+  +----------+              |   |                        |  |             +----------+
+  | client A +--------------+   +------------------------+  +------------>+ server B |
+  +----------+                                                            +----------+
+
+And the reverse path:
+
+::
+
+                        +------------+                +-------+
+                        | firewall 1 |                | dpi-1 |
+                        +---+---+----+                +--+--+-+
+                            |   ^                        |  ^
+                   net-A-dpl|   |net-B-dpl      net-A-dpl|  |net-B-dpl
+                            |   |                        |  |
+  +----------+              |   |                        |  |             +----------+
+  | client A +<-------------+   +------------------------+  +-------------+ server B |
+  +----------+                                                            +----------+
+
+Consider the following notes to put the example in context:
+
+- The classification function is obviated from the illustration.
+- The forward path is up-link traffic from a client in network A to a server in
+  network B.
+- The reverse path is down-link traffic from a server in network B to a client
+  in network A.
+- The service functions might be legacy bump-in-the-wire network devices that
+  need to use different interfaces for each network.
+
+SFC Statistics User Guide
+-------------------------
+
+Statistics can be queried for Rendered Service Paths created on OVS bridges.
+Future support will be added for Service Function Forwarders and Service
+Functions. Future support will also be added for VPP and IOs-XE devices.
+
+To use SFC statistics the 'odl-sfc-statistics' Karaf feature needs to be
+installed.
+
+Statistics are queried by sending an RPC RESTconf message to ODL. For
+RSPs, its possible to either query statistics for one individual RSP
+or for all RSPs, as follows:
+
+Querying statistics for a specific RSP:
+
+.. code-block:: bash
+
+   curl -i -H "Content-Type: application/json" -H "Cache-Control: no-cache"
+   --data '{ "input": { "name" : "path1-Path-42" } }' -X POST --user admin:admin
+   http://localhost:8181/restconf/operations/sfc-statistics-operations:get-rsp-statistics
+
+
+Querying statistics for all RSPs:
+
+.. code-block:: bash
+
+   curl -i -H "Content-Type: application/json" -H "Cache-Control: no-cache"
+   --data '{ "input": { } }' -X POST --user admin:admin
+   http://localhost:8181/restconf/operations/sfc-statistics-operations:get-rsp-statistics
+
+
+The following is the sort of output that can be expected for each RSP.
+
+.. code-block:: json
+
+   {
+       "output": {
+           "statistics": [
+               {
+                   "name": "sfc-path-1sf1sff-Path-34",
+                   "statistic-by-timestamp": [
+                       {
+                           "service-statistic": {
+                               "bytes-in": 0,
+                               "bytes-out": 0,
+                               "packets-in": 0,
+                               "packets-out": 0
+                           },
+                           "timestamp": 1518561500480
+                       }
+                   ]
+               }
+           ]
+       }
+   }
+