X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=docs%2Fuser-guide%2Fservice-function-chaining.rst;h=1679ff4597b754c4a57c36a251654adf27ef6857;hb=6c238d135292ac3aba6e8cc762eaaaa65d622502;hp=5fc94e69704c91b3f77123e69b432b507aadc442;hpb=62610ead50f93869d84919e53b88e1e11c2ff082;p=docs.git diff --git a/docs/user-guide/service-function-chaining.rst b/docs/user-guide/service-function-chaining.rst index 5fc94e697..1679ff459 100644 --- a/docs/user-guide/service-function-chaining.rst +++ b/docs/user-guide/service-function-chaining.rst @@ -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 a 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,22 @@ 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 in two flavors: -SFC-UI Architecture -~~~~~~~~~~~~~~~~~~~ +- Web Interface (SFC-UI): is based on Dlux project. It provides an easy way to + create, read, update and delete configuration stored in the datastore. + Moreover, it shows the status of all SFC features (e.g installed, + uninstalled) and Karaf log messages as well. + +- Command Line Interface (CLI): it provides several Karaf console commands to + show the SFC model (SF, SFFs, etc.) provisioned in the datastore. + + +SFC Web Interface (SFC-UI) +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Architecture +^^^^^^^^^^^^ SFC-UI operates purely by using RESTCONF. @@ -52,22 +63,84 @@ SFC-UI operates purely by using RESTCONF. SFC-UI integration into ODL -Configuring SFC-UI -~~~~~~~~~~~~~~~~~~ +How to access +^^^^^^^^^^^^^ 1. Run ODL distribution (run karaf) -2. In karaf console execute: ``feature:install odl-sfc-ui`` +2. In Karaf console execute: ``feature:install odl-sfc-ui`` 3. Visit SFC-UI on: ``http://:8181/sfc/index.html`` -SFC Southbound REST Plugin --------------------------- + +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 ] + +* List one/all provisioned Service Function Forwarders: + + .. code-block:: bash + + sfc:sff-list [--name ] + +* List one/all provisioned Service Function Chains: + + .. code-block:: bash + + sfc:sfc-list [--name ] + +* List one/all provisioned Service Function Paths: + + .. code-block:: bash + + sfc:sfp-list [--name ] + +* List one/all provisioned Service Function Classifiers: + + .. code-block:: bash + + sfc:sc-list [--name ] + +* List one/all provisioned Service Nodes: + + .. code-block:: bash + + sfc:sn-list [--name ] + +* List one/all provisioned Service Function Types: + + .. code-block:: bash + + sfc:sft-list [--name ] + +SFC Southbound REST Plug-in +--------------------------- Overview ~~~~~~~~ -The Southbound REST Plugin is used to send configuration from DataStore +The Southbound REST Plug-in is used to send configuration from datastore down to network devices supporting a REST API (i.e. they have a configured REST URI). It supports POST/PUT/DELETE operations, which are triggered accordingly by changes in the SFC data stores. @@ -82,27 +155,27 @@ triggered accordingly by changes in the SFC data stores. - Service Function Schedule Type (SFST) -- Service Function Forwader (SFF) +- Service Function Forwarder (SFF) - Rendered Service Path (RSP) -Southbound REST Plugin Architecture -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Southbound REST Plug-in Architecture +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -From the user perspective, the REST plugin is another SFC Southbound -plugin 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. .. figure:: ./images/sfc/sb-rest-architecture-user.png - :alt: Soutbound REST Plugin integration into ODL + :alt: Southbound REST Plug-in integration into ODL - Soutbound REST Plugin integration into ODL + Southbound REST Plug-in integration into ODL Configuring Southbound REST Plugin ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1. Run ODL distribution (run karaf) -2. In karaf console execute: ``feature:install odl-sfc-sb-rest`` +2. In Karaf console execute: ``feature:install odl-sfc-sb-rest`` 3. Configure REST URIs for SF/SFF through SFC User Interface or RESTCONF (required configuration steps can be found in the tutorial stated @@ -111,9 +184,9 @@ Configuring Southbound REST Plugin Tutorial ~~~~~~~~ -Comprehensive tutorial on how to use the Southbound REST Plugin and how +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 ------------------- @@ -126,11 +199,10 @@ Integration is realized through mapping of SFC objects (like SF, SFF, 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 plugin -will create a new OVS bridge and when a new OVS Bridge is created, the -SFC-OVS plugin will create a new SFF. +is created. For example, when a new SFF is created, the SFC-OVS plug-in +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). @@ -139,7 +211,7 @@ SFC-OVS Architecture SFC-OVS uses the OVSDB MD-SAL Southbound API for getting/writing information from/to OVS devices. From the user perspective SFC-OVS acts -as a layer between SFC DataStore and OVSDB. +as a layer between SFC datastore and OVSDB. .. figure:: ./images/sfc/sfc-ovs-architecture-user.png :alt: SFC-OVS integration into ODL @@ -151,7 +223,7 @@ Configuring SFC-OVS 1. Run ODL distribution (run karaf) -2. In karaf console execute: ``feature:install odl-sfc-ovs`` +2. In Karaf console execute: ``feature:install odl-sfc-ovs`` 3. Configure Open vSwitch to use ODL as a manager, using following command: ``ovs-vsctl set-manager tcp::6640`` @@ -159,54 +231,17 @@ Configuring SFC-OVS Tutorials ~~~~~~~~~ -Verifying mapping from OVS to SFF -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Overview -'''''''' - -This tutorial shows the usual workflow when OVS configuration is -transformed to corresponding SFC objects (in this case SFF). - -Prerequisities -'''''''''''''' - -- Open vSwitch installed (ovs-vsctl command available in shell) - -- SFC-OVS feature configured as stated above - -Instructions -'''''''''''' - -1. ``ovs-vsctl set-manager tcp::6640`` - -2. ``ovs-vsctl add-br br1`` - -3. ``ovs-vsctl add-port br1 testPort`` - -Verification -'''''''''''' - -a. visit SFC User Interface: - ``http://:8181/sfc/index.html#/sfc/serviceforwarder`` - -b. use pure RESTCONF and send GET request to URL: - ``http://: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. -Prerequisities -'''''''''''''' +Prerequisites +''''''''''''' - Open vSwitch installed (ovs-vsctl command available in shell) @@ -215,7 +250,7 @@ Prerequisities Instructions '''''''''''' -1. In shell execute: ``ovs-vsctl set-manager tcp::6640`` +1. In a shell execute: ``ovs-vsctl set-manager tcp::6640`` 2. Send POST request to URL: ``http://:8181/restconf/operations/service-function-forwarder-ovs:create-ovs-bridge`` @@ -235,18 +270,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://:8181/sfc/index.html#/sfc/serviceforwarder`` + +b. Use pure RESTCONF and send a GET request to URL: + ``http://: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 ------------------------- @@ -298,7 +343,7 @@ Configuring Classifier 2. SFF data plane locator must be configured -3. Classifier interface must be mannually added to SFF bridge. +3. Classifier interface must be manually added to SFF bridge. Administering or Managing Classifier ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -345,7 +390,7 @@ and forwarded to a related SFF, which knows how to traverse the RSP. Rules are created using appropriate iptables command. If the Access Control Entry (ACE) rule is MAC address related both iptables and -ip6tabeles rules re issued. If ACE rule is IPv4 address related, only +IPv6 tables rules re issued. If ACE rule is IPv4 address related, only iptables rules are issued, same for IPv6. .. note:: @@ -362,12 +407,13 @@ Configuring Classifier Administering or Managing Classifier ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Classfier runs alongside sfc\_agent, therefore the commad for starting +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 +423,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 +443,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 +457,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 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -579,7 +629,7 @@ the packets out. Here are two examples on SFF1. RSP Paths 1 and 2 are symmetric MPLS paths that use VLAN for the SFF-SF. RSP Paths 3 and 4 are symmetric NSH paths. Since it is assumed that switches used for NSH will only have one -VXLANport, the NSH packets are just sent back where they came from. +VXLAN port, the NSH packets are just sent back where they came from. +----------+--------------------------------+--------------------------------+ | Priority | Match | Action | @@ -625,19 +675,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 +702,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 +718,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 +748,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- -- sfc-path1-Reverse +- sfc-path1-Path--Reverse At this point the Service Chains have been created, and the OpenFlow Switches are programmed to steer traffic through the Service Chain. @@ -706,17 +764,17 @@ 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 -``localhost`` desintation in the URL accordingly. +``localhost`` destination in the URL accordingly. SFC OF Renderer NSH Tutorial '''''''''''''''''''''''''''' @@ -729,13 +787,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 +803,6 @@ command: { "name": "sf1", "type": "http-header-enrichment", - "nsh-aware": true, "ip-mgmt-address": "10.0.0.2", "sf-data-plane-locator": [ { @@ -758,7 +817,6 @@ command: { "name": "sf2", "type": "firewall", - "nsh-aware": true, "ip-mgmt-address": "10.0.0.3", "sf-data-plane-locator": [ { @@ -779,13 +837,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 +907,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 +942,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 +963,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 +983,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 +999,6 @@ command: { "name": "sf1", "type": "http-header-enrichment", - "nsh-aware": false, "ip-mgmt-address": "10.0.0.2", "sf-data-plane-locator": [ { @@ -980,7 +1013,6 @@ command: { "name": "sf2", "type": "firewall", - "nsh-aware": false, "ip-mgmt-address": "10.0.0.3", "sf-data-plane-locator": [ { @@ -1001,13 +1033,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 +1169,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 +1204,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 +1229,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 - } - } - -| **MPLS Rendered Service Path removal** +.. code-block:: bash -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 +1365,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/ - PUT ./config/network-topology:network-topology/topology/topology-netconf/node/ + .. code-block:: xml device-name @@ -1396,9 +1413,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 +1442,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 +1452,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 +1466,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 +1480,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 +1496,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 +1528,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 +1547,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 +1657,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 +1688,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 +1828,7 @@ c. Get Monitoring data from NETCONF server. These monitoring data should static XML data like this: -:: +.. code-block:: xml @@ -1897,7 +1911,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 +1930,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 +1956,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 +1998,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 +2040,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 +2070,7 @@ service-function-forwarders.json: service-functions.json: -:: +.. code-block:: json { "service-functions": { @@ -2073,8 +2087,7 @@ service-functions.json: } ], "name": "napt44-1", - "type": "service-function-type:napt44", - "nsh-aware": true + "type": "napt44" }, { "rest-uri": "http://localhost:10002", @@ -2088,8 +2101,7 @@ service-functions.json: } ], "name": "napt44-2", - "type": "service-function-type:napt44", - "nsh-aware": true + "type": "napt44" }, { "rest-uri": "http://localhost:10003", @@ -2103,8 +2115,7 @@ service-functions.json: } ], "name": "firewall-1", - "type": "service-function-type:firewall", - "nsh-aware": true + "type": "firewall" }, { "rest-uri": "http://localhost:10004", @@ -2118,8 +2129,7 @@ service-functions.json: } ], "name": "firewall-2", - "type": "service-function-type:firewall", - "nsh-aware": true + "type": "firewall" }, { "rest-uri": "http://localhost:10005", @@ -2133,8 +2143,7 @@ service-functions.json: } ], "name": "test-server", - "type": "service-function-type:dpi", - "nsh-aware": true + "type": "dpi" }, { "rest-uri": "http://localhost:10006", @@ -2148,16 +2157,15 @@ service-functions.json: } ], "name": "test-client", - "type": "service-function-type:dpi", - "nsh-aware": true + "type": "dpi" } ] } } -The depolyed topology like this: +The deployed topology like this: -:: +.. code-block:: json +----+ +----+ +----+ |sff1|+----------|sff3|---------+|sff2| @@ -2268,7 +2276,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 +2304,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 +2313,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 +2338,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 +2398,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 +2428,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 +2453,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 +2470,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,37 +2484,980 @@ 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 avaiable it is used to send a POST RPC to the +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/ + +.. code-block:: json + + { + "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. + +.. 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: + +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. +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. + +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 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 `__. + +.. figure:: ./images/sfc/logical-sff-datamodel.png + :alt: Logical SFF data model + +How to configure the Logical SFF +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +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/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": "firewall-dpl", + "interface-name": "eccb57ae-5a2e-467f-823e-45d7bb2a6a9a", + "transport": "service-locator:eth-nsh", + "service-function-forwarder": "sfflogical1" + + } + ] + }, + { + "name": "dpi-1", + "type": "dpi", + "sf-data-plane-locator": [ + { + "name": "dpi-dpl", + "interface-name": "df15ac52-e8ef-4e9a-8340-ae0738aba0c0", + "transport": "service-locator:eth-nsh", + "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" + } + ] + } + } + +.. 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/ + +**Service Function Chains JSON.** + +.. code-block:: json + + { + "service-function-chains": { + "service-function-chain": [ + { + "name": "SFC1", + "sfc-service-function": [ + { + "name": "dpi-abstract1", + "type": "dpi" + }, + { + "name": "firewall-abstract1", + "type": "firewall" + } + ] + }, + { + "name": "SFC2", + "sfc-service-function": [ + { + "name": "dpi-abstract1", + "type": "dpi" + } + ] + } + ] + } + } + +.. 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/ + +**Service Function Paths JSON.** + +.. code-block:: json + + { + "service-function-paths": { + "service-function-path": [ + { + "name": "SFP1", + "service-chain-name": "SFC1", + "starting-index": 255, + "symmetric": "true", + "context-metadata": "NSH1", + "transport-type": "service-locator:vxlan-gpe" + + } + ] + } + } + +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** :: - POST ./restconf/operations/sfc-ioam-nb-pot:disable-sfc-ioam-pot-rendered-path + 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 +`, 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 `, +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 `, +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 { - "input": { - "sfc-ioam-pot-rsp-name": "rsp1" - } + "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 + } + ] + } + ] + } + } +