Merge "Use OVSDB/docs for OVSDB"
[docs.git] / docs / user-guide / service-function-chaining.rst
index d602f0e5fac5fbd493e04d4707eede1b7e9a42d7..b4e1aa6b6a407564ce5faa91da371a9889c6b831 100644 (file)
@@ -1,3 +1,5 @@
+.. _sfc-user-guide:
+
 Service Function Chaining
 =========================
 
@@ -5,9 +7,9 @@ OpenDaylight Service Function Chaining (SFC) Overview
 -----------------------------------------------------
 
 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.
 
@@ -37,13 +39,16 @@ SFC User Interface
 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.
 
@@ -52,8 +57,8 @@ SFC-UI operates purely by using RESTCONF.
 
    SFC-UI integration into ODL
 
-Configuring SFC-UI
-~~~~~~~~~~~~~~~~~~
+How to access
+^^^^^^^^^^^^^
 
 1. Run ODL distribution (run karaf)
 
@@ -61,8 +66,70 @@ Configuring SFC-UI
 
 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
---------------------------
+---------------------------
 
 Overview
 ~~~~~~~~
@@ -87,7 +154,7 @@ triggered accordingly by changes in the SFC data stores.
 -  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.
@@ -113,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:
-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
 -------------------
@@ -127,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
-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).
 
@@ -159,54 +225,17 @@ Configuring SFC-OVS
 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
 ''''''''
 
-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
-''''''''''''''
+'''''''''''''
 
 -  Open vSwitch installed (ovs-vsctl command available in shell)
 
@@ -215,7 +244,7 @@ Prerequisites
 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``
@@ -235,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
 ''''''''''''
 
-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
 -------------------------
@@ -365,9 +404,10 @@ Administering or Managing Classifier
 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
 --------------------------------
@@ -377,9 +417,10 @@ Overview
 
 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:
 
@@ -396,12 +437,13 @@ Common acronyms used in the following sections:
 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
@@ -409,6 +451,8 @@ RSP. Refer to the following diagram for more details.
 
    SFC OpenFlow Renderer High Level Architecture
 
+.. _sfc-user-guide-sfc-of-pipeline:
+
 SFC OpenFlow Switch Flow pipeline
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -625,19 +669,23 @@ features must be installed.
 
 -  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:
 
-::
+.. 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:
 
-::
+.. 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.
@@ -648,8 +696,8 @@ SFC OF Renderer Tutorial
 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
@@ -664,6 +712,10 @@ To use this example, SFF OpenFlow switches must be created and connected
 as illustrated above. Additionally, the SFs must be created and
 connected.
 
+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
 ^^^^^^^^^^^^^^^^^^
 
@@ -690,15 +742,15 @@ Steps to configure the SFC OF Renderer tutorial:
 
 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:
 
--  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.
@@ -706,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``.
 
-::
+.. 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
@@ -729,13 +781,15 @@ elements using NSH encapsulation.
 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.**
 
-::
+.. code-block:: json
 
     {
      "service-functions": {
@@ -743,7 +797,6 @@ command:
          {
            "name": "sf1",
            "type": "http-header-enrichment",
-           "nsh-aware": true,
            "ip-mgmt-address": "10.0.0.2",
            "sf-data-plane-locator": [
              {
@@ -758,7 +811,6 @@ command:
          {
            "name": "sf2",
            "type": "firewall",
-           "nsh-aware": true,
            "ip-mgmt-address": "10.0.0.3",
            "sf-data-plane-locator": [
              {
@@ -779,13 +831,13 @@ 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.**
 
-::
+.. code-block:: json
 
     {
      "service-function-forwarders": {
@@ -849,20 +901,21 @@ 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.**
 
-::
+.. code-block:: json
 
     {
      "service-function-chains": {
        "service-function-chain": [
          {
            "name": "sfc-chain1",
-           "symmetric": true,
            "sfc-service-function": [
              {
                "name": "hdr-enrich-abstract1",
@@ -883,13 +936,13 @@ 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.**
 
-::
+.. code-block:: json
 
     {
       "service-function-paths": {
@@ -904,41 +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",
-         "symmetric": true
-     }
-    }
-
-| **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:
 
-::
+.. 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
 '''''''''''''''''''''''''''''
@@ -951,13 +977,15 @@ elements using MPLS encapsulation.
 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.**
 
-::
+.. code-block:: json
 
     {
      "service-functions": {
@@ -965,7 +993,6 @@ command:
          {
            "name": "sf1",
            "type": "http-header-enrichment",
-           "nsh-aware": false,
            "ip-mgmt-address": "10.0.0.2",
            "sf-data-plane-locator": [
              {
@@ -980,7 +1007,6 @@ command:
          {
            "name": "sf2",
            "type": "firewall",
-           "nsh-aware": false,
            "ip-mgmt-address": "10.0.0.3",
            "sf-data-plane-locator": [
              {
@@ -1001,13 +1027,13 @@ 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.**
 
-::
+.. code-block:: json
 
     {
      "service-function-forwarders": {
@@ -1137,20 +1163,21 @@ 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.**
 
-::
+.. code-block:: json
 
     {
      "service-function-chains": {
        "service-function-chain": [
          {
            "name": "sfc-chain1",
-           "symmetric": true,
            "sfc-service-function": [
              {
                "name": "hdr-enrich-abstract1",
@@ -1171,13 +1198,15 @@ 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.**
 
-::
+.. code-block:: json
 
     {
       "service-function-paths": {
@@ -1194,39 +1223,21 @@ command:
 
 | **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.**
-
-::
-
-    {
-     "input": {
-         "name": "sfc-path1",
-         "parent-service-function-path": "sfc-path1",
-         "symmetric": true
-     }
-    }
+.. code-block:: bash
 
-| **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:
 
-::
+.. 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
 ------------------------------
@@ -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:
 
-::
+*  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>
@@ -1396,9 +1407,9 @@ mountpoints are cached. The first step is to create LSF on node.
 
 ``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": {
@@ -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.
 
-::
+*  PUT ./config/service-function:service-functions
 
-    PUT ./config/service-function:service-functions
+   .. code-block:: json
 
     {
         "service-functions": {
@@ -1435,8 +1446,7 @@ approach is used for Service Functions.
                 {
                     "name": "Firewall",
                     "ip-mgmt-address": "172.25.73.23",
-                    "type": "service-function-type: firewall",
-                    "nsh-aware": true,
+                    "type": "firewall",
                     "sf-data-plane-locator": [
                         {
                             "name": "firewall-dpl",
@@ -1450,8 +1460,7 @@ approach is used for Service Functions.
                 {
                     "name": "Dpi",
                     "ip-mgmt-address": "172.25.73.23",
-                    "type":"service-function-type: dpi",
-                    "nsh-aware": true,
+                    "type":"dpi",
                     "sf-data-plane-locator": [
                         {
                             "name": "dpi-dpl",
@@ -1465,8 +1474,7 @@ approach is used for Service Functions.
                 {
                     "name": "Qos",
                     "ip-mgmt-address": "172.25.73.23",
-                    "type":"service-function-type: qos",
-                    "nsh-aware": true,
+                    "type":"qos",
                     "sf-data-plane-locator": [
                         {
                             "name": "qos-dpl",
@@ -1482,30 +1490,29 @@ 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. SFC is symmetric.
+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-chain": [
                 {
                     "name": "CSR3XSF",
-                    "symmetric": "true",
                     "sfc-service-function": [
                         {
                             "name": "Firewall",
-                            "type": "service-function-type: firewall"
+                            "type": "firewall"
                         },
                         {
                             "name": "Dpi",
-                            "type": "service-function-type: dpi"
+                            "type": "dpi"
                         },
                         {
                             "name": "Qos",
-                            "type": "service-function-type: qos"
+                            "type": "qos"
                         }
                     ]
                 }
@@ -1515,9 +1522,9 @@ step is to prepare Service Function Chain. SFC is symmetric.
 
 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": {
@@ -1534,15 +1541,14 @@ Service Function Path:
 
 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": {
           "name": "CSR3XSF-Path-RSP",
-          "parent-service-function-path": "CSR3XSF-Path",
-          "symmetric": true
+          "parent-service-function-path": "CSR3XSF-Path"
       }
     }
 
@@ -1645,7 +1651,7 @@ selection algorithm when creating a Rendered Service Path.
    content is needed at the moment:
    Service\_function\_schudule\_type.json
 
-   ::
+   .. code-block:: json
 
        {
          "service-function-scheduler-types": {
@@ -1676,12 +1682,14 @@ selection algorithm when creating a Rendered Service Path.
 
    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
@@ -1814,7 +1822,7 @@ c. Get Monitoring data from NETCONF server. These monitoring data should
 
 static XML data like this:
 
-::
+.. code-block:: xml
 
     <?xml version="1.0" encoding="UTF-8"?>
     <service-function-description-monitor-report>
@@ -1897,7 +1905,7 @@ Function by actual topology.
 Prerequisites
 '''''''''''''
 
--  Depolyed topology (include SFFs, SFs and their links).
+-  Deployed topology (include SFFs, SFs and their links).
 
 -  Dijkstra’s algorithm. More information on Dijkstra’s algorithm can be
    found on the wiki here:
@@ -1916,7 +1924,7 @@ c. Depoly SFFs and SFs. import the service-function-forwarders.json and
 
 service-function-forwarders.json:
 
-::
+.. code-block:: json
 
     {
       "service-function-forwarders": {
@@ -1942,19 +1950,19 @@ service-function-forwarders.json:
             "service-function-dictionary": [
               {
                 "sff-sf-data-plane-locator": {
-                  "port": 10001,
-                  "ip": "10.3.1.103"
+                   "sf-dpl-name": "sf1dpl",
+                   "sff-dpl-name": "sff1dpl"
                 },
                 "name": "napt44-1",
-                "type": "service-function-type:napt44"
+                "type": "napt44"
               },
               {
                 "sff-sf-data-plane-locator": {
-                  "port": 10003,
-                  "ip": "10.3.1.102"
+                   "sf-dpl-name": "sf2dpl",
+                   "sff-dpl-name": "sff2dpl"
                 },
                 "name": "firewall-1",
-                "type": "service-function-type:firewall"
+                "type": "firewall"
               }
             ],
             "connected-sff-dictionary": [
@@ -1984,19 +1992,19 @@ service-function-forwarders.json:
             "service-function-dictionary": [
               {
                 "sff-sf-data-plane-locator": {
-                  "port": 10002,
-                  "ip": "10.3.1.103"
+                   "sf-dpl-name": "sf1dpl",
+                   "sff-dpl-name": "sff1dpl"
                 },
                 "name": "napt44-2",
-                "type": "service-function-type:napt44"
+                "type": "napt44"
               },
               {
                 "sff-sf-data-plane-locator": {
-                  "port": 10004,
-                  "ip": "10.3.1.101"
+                   "sf-dpl-name": "sf2dpl",
+                   "sff-dpl-name": "sff2dpl"
                 },
                 "name": "firewall-2",
-                "type": "service-function-type:firewall"
+                "type": "firewall"
               }
             ],
             "connected-sff-dictionary": [
@@ -2026,19 +2034,19 @@ service-function-forwarders.json:
             "service-function-dictionary": [
               {
                 "sff-sf-data-plane-locator": {
-                  "port": 10005,
-                  "ip": "10.3.1.104"
+                   "sf-dpl-name": "sf1dpl",
+                   "sff-dpl-name": "sff1dpl"
                 },
                 "name": "test-server",
-                "type": "service-function-type:dpi"
+                "type": "dpi"
               },
               {
                 "sff-sf-data-plane-locator": {
-                  "port": 10006,
-                  "ip": "10.3.1.102"
+                   "sf-dpl-name": "sf2dpl",
+                   "sff-dpl-name": "sff2dpl"
                 },
                 "name": "test-client",
-                "type": "service-function-type:dpi"
+                "type": "dpi"
               }
             ],
             "connected-sff-dictionary": [
@@ -2056,7 +2064,7 @@ service-function-forwarders.json:
 
 service-functions.json:
 
-::
+.. code-block:: json
 
     {
       "service-functions": {
@@ -2073,8 +2081,7 @@ service-functions.json:
               }
             ],
             "name": "napt44-1",
-            "type": "service-function-type:napt44",
-            "nsh-aware": true
+            "type": "napt44"
           },
           {
             "rest-uri": "http://localhost:10002",
@@ -2088,8 +2095,7 @@ service-functions.json:
               }
             ],
             "name": "napt44-2",
-            "type": "service-function-type:napt44",
-            "nsh-aware": true
+            "type": "napt44"
           },
           {
             "rest-uri": "http://localhost:10003",
@@ -2103,8 +2109,7 @@ service-functions.json:
               }
             ],
             "name": "firewall-1",
-            "type": "service-function-type:firewall",
-            "nsh-aware": true
+            "type": "firewall"
           },
           {
             "rest-uri": "http://localhost:10004",
@@ -2118,8 +2123,7 @@ service-functions.json:
               }
             ],
             "name": "firewall-2",
-            "type": "service-function-type:firewall",
-            "nsh-aware": true
+            "type": "firewall"
           },
           {
             "rest-uri": "http://localhost:10005",
@@ -2133,8 +2137,7 @@ service-functions.json:
               }
             ],
             "name": "test-server",
-            "type": "service-function-type:dpi",
-            "nsh-aware": true
+            "type": "dpi"
           },
           {
             "rest-uri": "http://localhost:10006",
@@ -2148,8 +2151,7 @@ service-functions.json:
               }
             ],
             "name": "test-client",
-            "type": "service-function-type:dpi",
-            "nsh-aware": true
+            "type": "dpi"
           }
         ]
       }
@@ -2157,7 +2159,7 @@ service-functions.json:
 
 The deployed topology like this:
 
-::
+.. code-block:: json
 
                   +----+           +----+          +----+
                   |sff1|+----------|sff3|---------+|sff2|
@@ -2268,7 +2270,7 @@ Create an algorithm
 POST -
 http://127.0.0.1:8181/restconf/config/service-function-group-algorithm:service-function-group-algorithms
 
-::
+.. code-block:: json
 
     {
         "service-function-group-algorithm": [
@@ -2296,7 +2298,7 @@ Create a group
 POST -
 http://127.0.0.1:8181/restconf/config/service-function-group:service-function-groups
 
-::
+.. code-block:: json
 
     {
         "service-function-group": [
@@ -2305,7 +2307,7 @@ http://127.0.0.1:8181/restconf/config/service-function-group:service-function-gr
             "ip-mgmt-address": "10.3.1.103",
             "algorithm": "alg1",
             "name": "SFG1",
-            "type": "service-function-type:napt44",
+            "type": "napt44",
             "sfc-service-function": [
                 {
                     "name":"napt44-104"
@@ -2330,11 +2332,53 @@ SFC Proof of Transit User Guide
 Overview
 ~~~~~~~~
 
-Early Service Function Chaining (SFC) Proof of Transit (SFC Proof of
-Transit) implements Service Chaining Proof of Transit functionality on
-capable switches. After the creation of an Rendered Service Path (RSP),
-a user can configure to enable SFC proof of transit on the selected RSP
-to effect the proof of transit.
+Several deployments use traffic engineering, policy routing, segment
+routing or service function chaining (SFC) to steer packets through a
+specific set of nodes. In certain cases regulatory obligations or a
+compliance policy require to prove that all packets that are supposed to
+follow a specific path are indeed being forwarded across the exact set
+of nodes specified. I.e. if a packet flow is supposed to go through a
+series of service functions or network nodes, it has to be proven that
+all packets of the flow actually went through the service chain or
+collection of nodes specified by the policy. In case the packets of a
+flow weren’t appropriately processed, a proof of transit egress device
+would be required to identify the policy violation and take
+corresponding actions (e.g. drop or redirect the packet, send an alert
+etc.) corresponding to the policy.
+
+Service Function Chaining (SFC) Proof of Transit (SFC PoT)
+implements Service Chaining Proof of Transit functionality on capable
+network devices.  Proof of Transit defines mechanisms to securely
+prove that traffic transited the defined path.  After the creation of an
+Rendered Service Path (RSP), a user can configure to enable SFC proof
+of transit on the selected RSP to effect the proof of transit.
+
+To ensure that the data traffic follows a specified path or a function
+chain, meta-data is added to user traffic in the form of a header.  The
+meta-data is based on a 'share of a secret' and provisioned by the SFC
+PoT configuration from ODL over a secure channel to each of the nodes
+in the SFC.  This meta-data is updated at each of the service-hop while
+a designated node called the verifier checks whether the collected
+meta-data allows the retrieval of the secret.
+
+The following diagram shows the overview and essentially utilizes Shamir's
+secret sharing algorithm, where each service is given a point on the
+curve and when the packet travels through each service, it collects these
+points (meta-data) and a verifier node tries to re-construct the curve
+using the collected points, thus verifying that the packet traversed
+through all the service functions along the chain.
+
+.. figure:: ./images/sfc/sfc-pot-intro.png
+   :alt: SFC Proof of Transit overview
+
+   SFC Proof of Transit overview
+
+Transport options for different protocols includes a new TLV in SR header
+for Segment Routing, NSH Type-2 meta-data, IPv6 extension headers, IPv4
+variants and for VXLAN-GPE.  More details are captured in the following
+link.
+
+In-situ OAM: https://github.com/CiscoDevNet/iOAM
 
 Common acronyms used in the following sections:
 
@@ -2348,54 +2392,26 @@ Common acronyms used in the following sections:
 
 -  RSP - Rendered Service Path
 
--  SFCPOT - Service Function Chain Proof of Transit
+-  SFC PoT - Service Function Chain Proof of Transit
+
 
 SFC Proof of Transit Architecture
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-When SFC Proof of Transit is initialized, all required listeners are
-registered to handle incoming data. It involves ``SfcPotNodeListener``
-which stores data about all node devices including their mountpoints
-(used here as databrokers), ``SfcPotRSPDataListener``,
-``RenderedPathListener``. ``RenderedPathListener`` is used to listen for
-RSP changes. ``SfcPotRSPDataListener`` implements RPC services to enable
-or disable SFC Proof of Transit on a particular RSP. When the SFC Proof
-of Transit is invoked, RSP listeners and service implementations are
-setup to receive SFCPOT configurations. When a user configures via a
-POST RPC call to enable SFCPOT on a particular RSP, the configuration
-drives the creation of necessary augmentations to the RSP to effect the
-SFCPOT configurations.
-
-SFC Proof of Transit details
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+SFC PoT feature is implemented as a two-part implementation with a
+north-bound handler that augments the RSP while a south-bound renderer
+auto-generates the required parameters and passes it on to the nodes
+that belong to the SFC.
 
-Several deployments use traffic engineering, policy routing, segment
-routing or service function chaining (SFC) to steer packets through a
-specific set of nodes. In certain cases regulatory obligations or a
-compliance policy require to prove that all packets that are supposed to
-follow a specific path are indeed being forwarded across the exact set
-of nodes specified. I.e. if a packet flow is supposed to go through a
-series of service functions or network nodes, it has to be proven that
-all packets of the flow actually went through the service chain or
-collection of nodes specified by the policy. In case the packets of a
-flow weren’t appropriately processed, a proof of transit egress device
-would be required to identify the policy violation and take
-corresponding actions (e.g. drop or redirect the packet, send an alert
-etc.) corresponding to the policy.
+The north-bound feature is enabled via odl-sfc-pot feature while the
+south-bound renderer is enabled via the odl-sfc-pot-netconf-renderer
+feature.  For the purposes of SFC PoT handling, both features must be
+installed.
+
+RPC handlers to augment the RSP are part of ``SfcPotRpc`` while the
+RSP augmentation to enable or disable SFC PoT feature is done via
+``SfcPotRspProcessor``.
 
-The SFCPOT approach is based on meta-data which is added to every
-packet. The meta data is updated at every hop and is used to verify
-whether a packet traversed all required nodes. A particular path is
-either described by a set of secret keys, or a set of shares of a single
-secret. Nodes on the path retrieve their individual keys or shares of a
-key (using for e.g. Shamir’s Shared Sharing Secret scheme) from a
-central controller. The complete key set is only known to the verifier-
-which is typically the ultimate node on a path that requires proof of
-transit. Each node in the path uses its secret or share of the secret to
-update the meta-data of the packets as the packets pass through the
-node. When the verifier receives a packet, it can use its key(s) along
-with the meta-data to validate whether the packet traversed the service
-chain correctly.
 
 SFC Proof of Transit entities
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -2406,15 +2422,10 @@ Proof of Transit for a particular RSP is enabled by an RPC request to
 the controller along with necessary parameters to control some of the
 aspects of the SFC Proof of Transit process.
 
-The RPC handler identifies the RSP and generates SFC Proof of Transit
-parameters like secret share, secret etc., and adds the generated SFCPOT
-configuration parameters to SFC main as well as the various SFC hops.
-The last node in the SFC is configured as a verifier node to allow
-SFCPOT Proof of Transit process to be completed.
-
-The SFCPOT configuration generators and related handling are done by
-``SfcPotAPI``, ``SfcPotConfigGenerator``, ``SfcPotListener``,
-``SfcPotPolyAPI``, ``SfcPotPolyClassAPI`` and ``SfcPotPolyClass``.
+The RPC handler identifies the RSP and adds PoT feature meta-data like
+enable/disable, number of PoT profiles, profiles refresh parameters etc.,
+that directs the south-bound renderer appropriately when RSP changes
+are noticed via call-backs in the renderer handlers.
 
 Administering SFC Proof of Transit
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -2436,6 +2447,10 @@ features must be installed:
 
 -  odl-sfc-pot
 
+Please note that the odl-sfc-pot-netconf-renderer or other renderers in future
+must be installed for the feature to take full-effect.  The details of the renderer
+features are described in other parts of this document.
+
 SFC Proof of Transit Tutorial
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -2449,10 +2464,13 @@ Preconditions
 ^^^^^^^^^^^^^
 
 To enable a device to handle SFC Proof of Transit, it is expected that
-the netconf server device advertise capability as under ioam-scv.yang
-present under src/main/yang folder of sfc-pot feature. It is also
-expected that netconf notifications be enabled and its support
-capability advertised as capabilities.
+the NETCONF node device advertise capability as under ioam-sb-pot.yang
+present under sfc-model/src/main/yang folder. It is also expected that base
+NETCONF support be enabled and its support capability advertised as capabilities.
+
+NETCONF support:``urn:ietf:params:netconf:base:1.0``
+
+PoT support: ``(urn:cisco:params:xml:ns:yang:sfc-ioam-sb-pot?revision=2017-01-12)sfc-ioam-sb-pot``
 
 It is also expected that the devices are netconf mounted and available
 in the topology-netconf store.
@@ -2460,91 +2478,200 @@ in the topology-netconf store.
 Instructions
 ^^^^^^^^^^^^
 
-When SFC Proof of Transit is installed, all netconf nodes in
-topology-netconf are processed and all capable nodes with accessible
-mountpoints are cached.
+When SFC Proof of Transit is installed, all netconf nodes in topology-netconf
+are processed and all capable nodes with accessible mountpoints are cached.
 
-First step is to create the required RSP as usually done.
+First step is to create the required RSP as is usually done using RSP creation
+steps in SFC main.
 
 Once RSP name is available it is used to send a POST RPC to the
 controller similar to below:
 
-::
+POST -
+http://ODL-IP:8181/restconf/operations/sfc-ioam-nb-pot:enable-sfc-ioam-pot-rendered-path/
 
-    POST ./restconf/operations/sfc-ioam-nb-pot:enable-sfc-ioam-pot-rendered-path
+.. code-block:: json
 
     {
-      "input": {
-        "sfc-ioam-pot-rsp-name": "rsp1"
-      }
+        "input":
+        {
+            "sfc-ioam-pot-rsp-name": "sfc-path-3sf3sff",
+            "ioam-pot-enable":true,
+            "ioam-pot-num-profiles":2,
+            "ioam-pot-bit-mask":"bits32",
+            "refresh-period-time-units":"milliseconds",
+            "refresh-period-value":5000
+        }
     }
 
 The following can be used to disable the SFC Proof of Transit on an RSP
-which removes the augmentations and stores back the RSP without the
-SFCPOT enabled features and also sending down a delete configuration to
-the SFCPOT configuration sub-tree in the nodes.
+which disables the PoT feature.
 
-::
+POST -
+http://ODL-IP:8181/restconf/operations/sfc-ioam-nb-pot:disable-sfc-ioam-pot-rendered-path/
 
-    POST ./restconf/operations/sfc-ioam-nb-pot:disable-sfc-ioam-pot-rendered-path
+.. code-block:: json
 
     {
-      "input": {
-        "sfc-ioam-pot-rsp-name": "rsp1"
-      }
+        "input":
+        {
+            "sfc-ioam-pot-rsp-name": "sfc-path-3sf3sff",
+        }
     }
 
+SFC PoT NETCONF Renderer User Guide
+-----------------------------------
+
+Overview
+~~~~~~~~
+
+The SFC Proof of Transit (PoT) NETCONF renderer implements SFC Proof of
+Transit functionality on NETCONF-capable devices, that have advertised
+support for in-situ OAM (iOAM) support.
+
+It listens for an update to an existing RSP with enable or disable proof of
+transit support and adds the auto-generated SFC PoT configuration parameters
+to all the SFC hop nodes.  The last node in the SFC is configured as a
+verifier node to allow SFC PoT process to be completed.
+
+Common acronyms are used as below:
+
+- SF - Service Function
+
+- SFC - Service Function Chain
+
+- RSP - Rendered Service Path
+
+- SFF - Service Function Forwarder
+
+
+Mapping to SFC entities
+~~~~~~~~~~~~~~~~~~~~~~~
+
+The renderer module listens to RSP updates in ``SfcPotNetconfRSPListener``
+and triggers configuration generation in ``SfcPotNetconfIoam`` class.  Node
+arrival and leaving are managed via ``SfcPotNetconfNodeManager`` and
+``SfcPotNetconfNodeListener``.  In addition there is a timer thread that
+runs to generate configuration periodically to refresh the profiles in the
+nodes that are part of the SFC.
+
+
+Administering SFC PoT NETCONF Renderer
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To use the SFC Proof of Transit Karaf, the following Karaf features must
+be installed:
+
+-  odl-sfc-model
+
+-  odl-sfc-provider
+
+-  odl-sfc-netconf
+
+-  odl-restconf-all
+
+-  odl-netconf-topology
+
+-  odl-netconf-connector-all
+
+-  odl-sfc-pot
+
+-  odl-sfc-pot-netconf-renderer
+
+
+SFC PoT NETCONF Renderer Tutorial
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Overview
+^^^^^^^^
+
+This tutorial is a simple example how to enable SFC PoT on NETCONF-capable
+devices.
+
+Preconditions
+^^^^^^^^^^^^^
+
+The NETCONF-capable device will have to support sfc-ioam-sb-pot.yang file.
+
+It is expected that a NETCONF-capable VPP device has Honeycomb (Hc2vpp)
+Java-based agent that helps to translate between NETCONF and VPP internal
+APIs.
+
+More details are here:
+In-situ OAM: https://github.com/CiscoDevNet/iOAM
+
+Steps
+^^^^^
+When the SFC PoT NETCONF renderer module is installed, all NETCONF nodes in
+topology-netconf are processed and all sfc-ioam-sb-pot yang capable nodes
+with accessible mountpoints are cached.
+
+The first step is to create RSP for the SFC as per SFC guidelines above.
+
+Enable SFC PoT is done on the RSP via RESTCONF to the ODL as outlined above.
+
+Internally, the NETCONF renderer will act on the callback to a modified RSP
+that has PoT enabled.
+
+In-situ OAM algorithms for auto-generation of SFC PoT parameters are
+generated automatically and sent to these nodes via NETCONF.
+
 Logical Service Function Forwarder
 ----------------------------------
 
 Overview
 ~~~~~~~~
 
+.. _sfc-user-guide-logical-sff-motivation:
+
 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
 
-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
 
-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
 
-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
 ~~~~~~~~~~~~~~~~~~~~~
-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
@@ -2552,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:
-::
 
-    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.**
 
-::
+.. code-block:: json
 
     {
     "service-functions": {
@@ -2566,7 +2696,6 @@ The following are examples to configure the Logical SFF:
             {
                 "name": "firewall-1",
                 "type": "firewall",
-                "nsh-aware": "true",
                 "sf-data-plane-locator": [
                     {
                         "name": "firewall-dpl",
@@ -2580,7 +2709,6 @@ The following are examples to configure the Logical SFF:
             {
                 "name": "dpi-1",
                 "type": "dpi",
-                "nsh-aware": "true",
                 "sf-data-plane-locator": [
                     {
                         "name": "dpi-dpl",
@@ -2594,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.**
 
-::
+.. code-block:: json
 
     {
     "service-function-forwarders": {
@@ -2612,20 +2742,21 @@ 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.**
 
-::
+.. code-block:: json
 
     {
     "service-function-chains": {
         "service-function-chain": [
             {
                 "name": "SFC1",
-                "symmetric": "true",
                 "sfc-service-function": [
                     {
                         "name": "dpi-abstract1",
@@ -2639,7 +2770,6 @@ The following are examples to configure the Logical SFF:
             },
             {
                 "name": "SFC2",
-                "symmetric": "true",
                 "sfc-service-function": [
                     {
                         "name": "dpi-abstract1",
@@ -2651,14 +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.**
 
-::
+.. code-block:: json
 
     {
     "service-function-paths": {
@@ -2676,3 +2807,651 @@ The following are examples to configure the Logical SFF:
     }
     }
 
+As a result of above configuration, OpenDaylight renders the needed flows in all involved SFFs. Those flows implement:
+
+- Two Rendered Service Paths:
+
+  - dpi-1 (SF1), firewall-1 (SF2)
+  - firewall-1 (SF2), dpi-1 (SF1)
+
+- The communication between SFFs and SFs based on eth-nsh
+
+- The communication between SFFs based on vxlan-gpe
+
+The following picture shows a topology and traffic flow (in green) which corresponds to the above configuration.
+
+.. figure:: ./images/sfc/single-logical-sff-example.png
+   :alt: Logical SFF Example
+   :width: 800px
+   :height: 600px
+
+   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.
+
+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**
+
+::
+
+ cookie=0x14, duration=59.264s, table=83, n_packets=0, n_bytes=0, priority=250,nsp=5 actions=goto_table:86
+ cookie=0x14, duration=59.194s, table=83, n_packets=0, n_bytes=0, priority=250,nsp=8388613 actions=goto_table:86
+ cookie=0x14, duration=59.257s, table=86, n_packets=0, n_bytes=0, priority=550,nsi=254,nsp=5 actions=load:0x8e0a37cc9094->NXM_NX_ENCAP_ETH_SRC[],load:0x6ee006b4c51e->NXM_NX_ENCAP_ETH_DST[],goto_table:87
+ cookie=0x14, duration=59.189s, table=86, n_packets=0, n_bytes=0, priority=550,nsi=255,nsp=8388613 actions=load:0x8e0a37cc9094->NXM_NX_ENCAP_ETH_SRC[],load:0x6ee006b4c51e->NXM_NX_ENCAP_ETH_DST[],goto_table:87
+ cookie=0xba5eba1100000203, duration=59.213s, table=87, n_packets=0, n_bytes=0, priority=650,nsi=253,nsp=5 actions=pop_nsh,set_field:6e:e0:06:b4:c5:1e->eth_src,resubmit(,17)
+ cookie=0xba5eba1100000201, duration=59.213s, table=87, n_packets=0, n_bytes=0, priority=650,nsi=254,nsp=5 actions=load:0x800->NXM_NX_REG6[],resubmit(,220)
+ cookie=0xba5eba1100000201, duration=59.188s, table=87, n_packets=0, n_bytes=0, priority=650,nsi=255,nsp=8388613 actions=load:0x800->NXM_NX_REG6[],resubmit(,220)
+ cookie=0xba5eba1100000201, duration=59.182s, table=87, n_packets=0, n_bytes=0, priority=650,nsi=254,nsp=8388613 actions=set_field:0->tun_id,output:6
+
+**Rendered Flows Node 4**
+
+::
+
+ cookie=0x14, duration=69.040s, table=83, n_packets=0, n_bytes=0, priority=250,nsp=5 actions=goto_table:86
+ cookie=0x14, duration=69.008s, table=83, n_packets=0, n_bytes=0, priority=250,nsp=8388613 actions=goto_table:86
+ cookie=0x14, duration=69.040s, table=86, n_packets=0, n_bytes=0, priority=550,nsi=255,nsp=5 actions=load:0xbea93873f4fa->NXM_NX_ENCAP_ETH_SRC[],load:0x214845ea85d->NXM_NX_ENCAP_ETH_DST[],goto_table:87
+ cookie=0x14, duration=69.005s, table=86, n_packets=0, n_bytes=0, priority=550,nsi=254,nsp=8388613 actions=load:0xbea93873f4fa->NXM_NX_ENCAP_ETH_SRC[],load:0x214845ea85d->NXM_NX_ENCAP_ETH_DST[],goto_table:87
+ cookie=0xba5eba1100000201, duration=69.029s, table=87, n_packets=0, n_bytes=0, priority=650,nsi=255,nsp=5 actions=load:0x1100->NXM_NX_REG6[],resubmit(,220)
+ cookie=0xba5eba1100000201, duration=69.029s, table=87, n_packets=0, n_bytes=0, priority=650,nsi=254,nsp=5 actions=set_field:0->tun_id,output:1
+ cookie=0xba5eba1100000201, duration=68.999s, table=87, n_packets=0, n_bytes=0, priority=650,nsi=254,nsp=8388613 actions=load:0x1100->NXM_NX_REG6[],resubmit(,220)
+ 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.
+
+.. figure:: ./images/sfc/single-logical-sff-example-migration.png
+   :alt: Logical SFF - SF Migration Example
+   :width: 800px
+   :height: 600px
+
+   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.
+
+**Rendered Flows Node 3 After Migration**
+
+::
+
+ cookie=0x14, duration=64.044s, table=83, n_packets=0, n_bytes=0, priority=250,nsp=5 actions=goto_table:86
+ cookie=0x14, duration=63.947s, table=83, n_packets=0, n_bytes=0, priority=250,nsp=8388613 actions=goto_table:86
+ cookie=0x14, duration=64.044s, table=86, n_packets=0, n_bytes=0, priority=550,nsi=254,nsp=5 actions=load:0x8e0a37cc9094->NXM_NX_ENCAP_ETH_SRC[],load:0x6ee006b4c51e->NXM_NX_ENCAP_ETH_DST[],goto_table:87
+ cookie=0x14, duration=63.947s, table=86, n_packets=0, n_bytes=0, priority=550,nsi=255,nsp=8388613 actions=load:0x8e0a37cc9094->NXM_NX_ENCAP_ETH_SRC[],load:0x6ee006b4c51e->NXM_NX_ENCAP_ETH_DST[],goto_table:87
+ cookie=0xba5eba1100000201, duration=64.034s, table=87, n_packets=0, n_bytes=0, priority=650,nsi=254,nsp=5 actions=load:0x800->NXM_NX_REG6[],resubmit(,220)
+ cookie=0xba5eba1100000203, duration=64.034s, table=87, n_packets=0, n_bytes=0, priority=650,nsi=253,nsp=5 actions=pop_nsh,set_field:6e:e0:06:b4:c5:1e->eth_src,resubmit(,17)
+ cookie=0xba5eba1100000201, duration=63.947s, table=87, n_packets=0, n_bytes=0, priority=650,nsi=255,nsp=8388613 actions=load:0x800->NXM_NX_REG6[],resubmit(,220)
+ cookie=0xba5eba1100000201, duration=63.942s, table=87, n_packets=0, n_bytes=0, priority=650,nsi=254,nsp=8388613 actions=set_field:0->tun_id,output:2
+
+**Rendered Flows Node 2 After Migration**
+
+::
+
+ cookie=0x14, duration=56.856s, table=83, n_packets=0, n_bytes=0, priority=250,nsp=5 actions=goto_table:86
+ cookie=0x14, duration=56.755s, table=83, n_packets=0, n_bytes=0, priority=250,nsp=8388613 actions=goto_table:86
+ cookie=0x14, duration=56.847s, table=86, n_packets=0, n_bytes=0, priority=550,nsi=255,nsp=5 actions=load:0xbea93873f4fa->NXM_NX_ENCAP_ETH_SRC[],load:0x214845ea85d->NXM_NX_ENCAP_ETH_DST[],goto_table:87
+ cookie=0x14, duration=56.755s, table=86, n_packets=0, n_bytes=0, priority=550,nsi=254,nsp=8388613 actions=load:0xbea93873f4fa->NXM_NX_ENCAP_ETH_SRC[],load:0x214845ea85d->NXM_NX_ENCAP_ETH_DST[],goto_table:87
+ cookie=0xba5eba1100000201, duration=56.823s, table=87, n_packets=0, n_bytes=0, priority=650,nsi=255,nsp=5 actions=load:0x1100->NXM_NX_REG6[],resubmit(,220)
+ cookie=0xba5eba1100000201, duration=56.823s, table=87, n_packets=0, n_bytes=0, priority=650,nsi=254,nsp=5 actions=set_field:0->tun_id,output:4
+ cookie=0xba5eba1100000201, duration=56.755s, table=87, n_packets=0, n_bytes=0, priority=650,nsi=254,nsp=8388613 actions=load:0x1100->NXM_NX_REG6[],resubmit(,220)
+ cookie=0xba5eba1100000203, duration=56.750s, 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)
+
+**Rendered Flows Node 4 After Migration**
+
+::
+
+ -- No flows for NSH processing --
+
+.. _sfc-user-guide-classifier-impacts:
+
+Classifier impacts
+~~~~~~~~~~~~~~~~~~
+
+As previously mentioned, in the :ref:`Logical SFF rationale
+<sfc-user-guide-logical-sff-motivation>`, the Logical SFF feature relies on
+Genius to get the dataplane IDs of the OpenFlow switches, in order to properly
+steer the traffic through the chain.
+
+Since one of the classifier's objectives is to steer the packets *into* the
+SFC domain, the classifier has to be aware of where the first Service
+Function is located - if it migrates somewhere else, the classifier table
+has to be updated accordingly, thus enabling the seemless migration of Service
+Functions.
+
+For this feature, mobility of the client VM is out of scope, and should be
+managed by its high-availability module, or VNF manager.
+
+Keep in mind that classification *always* occur in the compute-node where
+the client VM (i.e. traffic origin) is running.
+
+How to attach the classifier to a Logical SFF
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In order to leverage this functionality, the classifier has to be configured
+using a Logical SFF as an attachment-point, specifying within it the neutron
+port to classify.
+
+The following examples show how to configure an ACL, and a classifier having
+a Logical SFF as an attachment-point:
+
+**Configure an ACL**
+
+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": {
+            "acl": [
+              {
+                "acl-name": "ACL1",
+                "acl-type": "ietf-access-control-list:ipv4-acl",
+                "access-list-entries": {
+                  "ace": [
+                    {
+                      "rule-name": "ACE1",
+                      "actions": {
+                        "service-function-acl:rendered-service-path": "RSP1"
+                      },
+                      "matches": {
+                        "destination-ipv4-network": "192.168.2.0/24",
+                        "source-ipv4-network": "192.168.2.0/24",
+                        "protocol": "6",
+                        "source-port-range": {
+                            "lower-port": 0
+                        },
+                        "destination-port-range": {
+                            "lower-port": 80
+                        }
+                      }
+                    }
+                  ]
+                }
+              },
+              {
+                "acl-name": "ACL2",
+                "acl-type": "ietf-access-control-list:ipv4-acl",
+                "access-list-entries": {
+                  "ace": [
+                    {
+                      "rule-name": "ACE2",
+                      "actions": {
+                        "service-function-acl:rendered-service-path": "RSP1-Reverse"
+                      },
+                      "matches": {
+                        "destination-ipv4-network": "192.168.2.0/24",
+                        "source-ipv4-network": "192.168.2.0/24",
+                        "protocol": "6",
+                        "source-port-range": {
+                            "lower-port": 80
+                        },
+                        "destination-port-range": {
+                            "lower-port": 0
+                        }
+                      }
+                    }
+                  ]
+                }
+              }
+            ]
+          }
+        }
+
+.. 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/
+
+**Configure a classifier JSON**
+
+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.
+
+.. code-block:: json
+
+        {
+          "service-function-classifiers": {
+            "service-function-classifier": [
+              {
+                "name": "Classifier1",
+                "scl-service-function-forwarder": [
+                  {
+                    "name": "sfflogical1",
+                    "interface": "09a78ba3-78ba-40f5-a3ea-1ce708367f2b"
+                  }
+                ],
+                "acl": {
+                    "name": "ACL1",
+                    "type": "ietf-access-control-list:ipv4-acl"
+                 }
+              }
+            ]
+          }
+        }
+
+.. 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/
+
+.. _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.
+
+This picture shows the SFC pipeline after service integration with Genius:
+
+.. figure:: ./images/sfc/LSFF_pipeline.png
+   :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
+                       }
+                   ]
+               }
+           ]
+       }
+   }
+