--- /dev/null
+*** Settings ***
+Library SSHLibrary
+
+*** Variables ***
+
+*** Keywords ***
+Docker Ovs Start
+ [Arguments] ${nodes} ${guests} ${tunnel} ${odl_ip} ${log_file}=myFile2.log
+ [Documentation] Run the docker-ovs.sh script with specific input arguments. Run ./docker-ovs.sh --help for more info.
+ ${result} SSHLibrary.Execute Command ./docker-ovs.sh spawn --nodes=${nodes} --guests=${guests} --tun=${tunnel} --odl=${odl_ip} > >(tee ${log_file}) 2> >(tee ${log_file}) return_stderr=True return_stdout=True return_rc=True
+ log ${result}
+ Should be equal as integers ${result[2]} 0
+
+Docker Ovs Clean
+ [Arguments] ${log_file}=myFile3.log
+ [Documentation] Run the docker-ovs.sh script with --clean option to clean up all containers deployment. Run ./docker-ovs.sh --help for more info.
+ ${result} SSHLibrary.Execute Command ./docker-ovs.sh clean > >(tee ${log_file}) 2> >(tee ${log_file}) return_stderr=True return_stdout=True return_rc=True
+ log ${result}
+ Should be equal as integers ${result[2]} 0
+
+Get Docker Ids
+ [Documentation] Execute command docker ps and retrieve the existing containers ids
+ ${output} ${rc} SSHLibrary.Execute Command sudo docker ps -q -a return_stdout=True return_stderr=False return_rc=True
+ Should Be Equal As Numbers ${rc} 0
+ [Return] ${output}
+
+Get Docker Ids Formatted
+ [Arguments] ${format}
+ [Documentation] Execute command docker ps with --format argument and retrieve the existing containers names
+ ${output} ${rc} SSHLibrary.Execute Command sudo docker ps -a --format ${format} return_stdout=True return_stderr=False return_rc=True
+ Should Be Equal As Numbers ${rc} 0
+ [Return] ${output}
+
+Get Docker Names As List
+ [Documentation] Returns a list with the names of all running containers inside the tools system
+ ${docker_ps}= DockerSfc.Get Docker Ids Formatted "{{.Names}}" -f status=running
+ ${docker_name_list}= Split String ${docker_ps} \n
+ [Return] ${docker_name_list}
+
+Get Docker IP
+ [Arguments] ${docker_name}
+ [Documentation] Obtain the IP address from a given container
+ ${output} ${rc} SSHLibrary.Execute Command sudo docker inspect -f '{{.NetworkSettings.IPAddress }}' ${docker_name} return_stdout=True return_stderr=False return_rc=True
+ Should Be Equal As Numbers ${rc} 0
+ [Return] ${output}
+
+Docker Exec
+ [Arguments] ${docker_name} ${command} ${return_contains}=${EMPTY} ${result_code}=0
+ [Documentation] Execute a command into a docker container.
+ ${output} ${rc} SSHLibrary.Execute Command sudo docker exec ${docker_name} ${command} return_stdout=True return_stderr=False return_rc=True
+ Run Keyword If '${return_contains}'!='${EMPTY}' Should Contain ${output} ${return_contains}
+ Should Be Equal As Numbers ${rc} ${result_code}
+ [Return] ${output}
+
+Multiple Docker Exec
+ [Arguments] ${docker_name_list} ${command} ${return_contains}=${EMPTY} ${result_code}=0
+ [Documentation] Execute a command in a list of dockers and return all the outputs in a list
+ @{list_output}= Create List
+ : FOR ${docker_id} IN @{docker_name_list}
+ \ ${exec_output}= Docker Exec ${docker_id} ${command} ${return_contains} ${result_code}
+ \ Append To List ${list_output} ${exec_output}
+ [Return] ${list_output}
+
+Get Flows In Docker Containers
+ ${docker_list}= DockerSfc.Get Docker Names As List
+ ${docker_flows} DockerSfc.Multiple Docker Exec ${docker_list} ovs-ofctl dump-flows -OOpenflow13 br-int OFPST_FLOW
+ [Return] ${docker_flows}
+
+Get Docker Bridge Subnet
+ [Documentation] Obtain the subnet used by docker bridge using the docker inspect tool
+ ${output} ${rc} SSHLibrary.Execute Command sudo docker network inspect bridge --format {{.IPAM.Config}} | grep -E -o "([0-9]{1,3}[\.]){3}[0-9]{1,3}[\/][0-9]{1,2}" return_stdout=True return_stderr=False return_rc=True
+ Should Be Equal As Numbers ${rc} 0
+ [Return] ${output}
--- /dev/null
+import ipaddr
+
+__author__ = "Jose Luis Franco Arza"
+__copyright__ = "Copyright(c) 2016, Ericsson."
+__license__ = "New-style BSD"
+__email__ = "jose.luis.franco.arza@ericsson.com"
+
+
+def get_network_from_cidr(cidr):
+ '''
+ Returns the subnetwork part from a given subnet in CIDR format,
+ like 192.168.1.0/24. Returning 192.168.1.0.
+ '''
+ o = ipaddr.IPv4Network(cidr)
+ return str(o.network)
+
+
+def get_mask_from_cidr(cidr):
+ '''
+ Returns a subnet mask from a given subnet in CIDR format,
+ like 192.168.1.0/24. Returning 255.255.255.0.
+ '''
+ o = ipaddr.IPv4Network(cidr)
+ return str(o.netmask)
+
+
+def get_ip_address_first_octets(ip, n_octets):
+ '''
+ Given an IP address, this function returns the number
+ of octets determined as argument. If 4 are specified, then the output
+ is the whole IP
+ '''
+
+ return ".".join(ip.split(".")[:int(n_octets)])
*** Settings ***
Documentation Test suite for SFC Service Functions, Operates functions from Restconf APIs.
Suite Setup Init Suite
-Suite Teardown Delete All Sessions
+Suite Teardown Cleanup Suite
Library SSHLibrary
Library Collections
Library OperatingSystem
Library RequestsLibrary
+Library ../../../libraries/SFC/SfcUtils.py
Variables ../../../variables/Variables.py
Resource ../../../variables/sfc/Variables.robot
Resource ../../../libraries/Utils.robot
Resource ../../../libraries/TemplatedRequests.robot
+Resource ../../../libraries/KarafKeywords.robot
+Resource ../../../libraries/SFC/DockerSfc.robot
*** Variables ***
-${CREATE_RSP1_INPUT} {"input":{"parent-service-function-path":"SFP-1","name":"SFP-1-Path-1"}}
-${CREATE_RSP_FAILURE_INPUT} {"input":{"parent-service-function-path":"SFC1-empty","name":"SFC1-empty-Path-1"}}
+${CREATE_RSP1_INPUT} {"input":{"parent-service-function-path":"SFP1","name":"RSP1"}}
+${CREATE_RSP_FAILURE_INPUT} {"input":{"parent-service-function-path":"SFC1-empty","name":"RSP1-empty-Path-1"}}
*** Test Cases ***
Basic Environment Setup Tests
Add Elements To URI From File ${SERVICE_NODES_URI} ${SERVICE_NODES_FILE}
Add Elements To URI From File ${SERVICE_FUNCTIONS_URI} ${SERVICE_FUNCTIONS_FILE}
Add Elements To URI From File ${SERVICE_CHAINS_URI} ${SERVICE_CHAINS_FILE}
+ Add Elements To URI From File ${SERVICE_METADATA_URI} ${SERVICE_METADATA_FILE}
Add Elements To URI From File ${SERVICE_FUNCTION_PATHS_URI} ${SERVICE_FUNCTION_PATHS_FILE}
+ Add Elements To URI From File ${SERVICE_FUNCTION_ACLS_URI} ${SERVICE_FUNCTION_ACLS_FILE}
Create and Get Rendered Service Path
[Documentation] Create and Get Rendered Service Path Through RESTConf APIs
Post Elements To URI As JSON ${OPERATIONS_CREATE_RSP_URI} ${CREATE_RSP1_INPUT}
${resp} RequestsLibrary.Get Request session ${OPERATIONAL_RSPS_URI}
Should Contain ${ALLOWED_STATUS_CODES} ${resp.status_code}
- ${elements}= Create List SFP-1-Path-1 "parent-service-function-path":"SFP-1" "hop-number":0 "service-index":255 "hop-number":1
+ ${elements}= Create List RSP1 "parent-service-function-path":"SFP1" "hop-number":0 "service-index":255 "hop-number":1
... "service-index":254
Check For Elements At URI ${OPERATIONAL_RSPS_URI} ${elements}
-Clean Datastore After Tests
- [Documentation] Clean All Items In Datastore After Tests
- Sleep 1
- Remove All Elements At URI ${SERVICE_FUNCTIONS_URI}
- Remove All Elements At URI ${SERVICE_FORWARDERS_URI}
- Remove All Elements At URI ${SERVICE_NODES_URI}
- Remove All Elements At URI ${SERVICE_CHAINS_URI}
- Remove All Elements At URI ${SERVICE_FUNCTION_PATHS_URI}
+Create and Get Classifiers
+ [Documentation] Apply json file descriptions of ACLs and Classifiers
+ Add Elements To URI From File ${SERVICE_CLASSIFIERS_URI} ${SERVICE_CLASSIFIERS_FILE}
+ ${classifiers}= Create List "service-function-classifiers" "service-function-classifier" "type":"ietf-access-control-list:ipv4-acl" "scl-service-function-forwarder"
+ Append To List ${classifiers} "name":"Classifier2" "name":"ACL2"
+ Append To List ${classifiers} "name":"Classifier1" "name":"ACL1"
+ Check For Elements At URI ${SERVICE_CLASSIFIERS_URI} ${classifiers}
+ Wait Until Keyword Succeeds 60s 2s Check Classifier Flows
*** Keywords ***
Post Elements To URI As JSON
${value} To Json ${resp.content}
[Return] ${value}
+Check Classifier Flows
+ ${flowList}= DockerSfc.Get Flows In Docker Containers
+ log ${flowList}
+ Should Contain Match ${flowList} *actions=pop_nsh*
+ Should Contain Match ${flowList} *actions=push_nsh*
+
+Switch Ips In Json Files
+ [Arguments] ${json_dir} ${container_names}
+ ${normalized_dir}= OperatingSystem.Normalize Path ${json_dir}/*.json
+ : FOR ${cont_name} IN @{container_names}
+ \ ${cont_ip}= Get Docker IP ${cont_name}
+ \ OperatingSystem.Run sudo sed -i 's/${cont_name}/${cont_ip}/g' ${normalized_dir}
+
Init Suite
[Documentation] Connect Create session and initialize ODL version specific variables
SSHLibrary.Open Connection ${TOOLS_SYSTEM_IP} timeout=3s
Utils.Flexible Mininet Login
+ ${docker_cidr}= DockerSfc.Get Docker Bridge Subnet
+ ${docker_nw}= SfcUtils.Get Network From Cidr ${docker_cidr}
+ ${docker_mask}= SfcUtils.Get Mask From Cidr ${docker_cidr}
+ ${route_to_docker_net}= Set Variable sudo route add -net ${docker_nw} netmask ${docker_mask} gw ${TOOLS_SYSTEM_IP}
+ Run Command On Remote System ${ODL_SYSTEM_IP} ${route_to_docker_net} ${ODL_SYSTEM_USER} prompt=${ODL_SYSTEM_PROMPT}
SSHLibrary.Put File ${CURDIR}/docker-ovs.sh . mode=0755
SSHLibrary.Put File ${CURDIR}/Dockerfile . mode=0755
SSHLibrary.Put File ${CURDIR}/setup-docker-image.sh . mode=0755
${result} SSHLibrary.Execute Command ./setup-docker-image.sh > >(tee myFile.log) 2> >(tee myFile.log) return_stderr=True return_stdout=True return_rc=True
log ${result}
Should be equal as integers ${result[2]} 0
- ${result} SSHLibrary.Execute Command ./docker-ovs.sh spawn --nodes=6 --guests=1 --tun=vxlan-gpe --odl=${ODL_SYSTEM_IP} > >(tee myFile2.log) 2> >(tee myFile2.log) return_stderr=True return_stdout=True return_rc=True
- log ${result}
- Should be equal as integers ${result[2]} 0
- SSHLibrary.Close Connection
+ DockerSfc.Docker Ovs Start nodes=6 guests=1 tunnel=vxlan-gpe odl_ip=${ODL_SYSTEM_IP}
+ ${docker_name_list}= DockerSfc.Get Docker Names As List
+ Set Suite Variable ${DOCKER_NAMES_LIST} ${docker_name_list}
Create Session session http://${ODL_SYSTEM_IP}:${RESTCONFPORT} auth=${AUTH} headers=${HEADERS}
log ${ODL_STREAM}
- Run Keyword If '${ODL_STREAM}' == 'stable-lithium' Set Suite Variable ${VERSION_DIR} lithium
- ... ELSE Set Suite Variable ${VERSION_DIR} master
- Set Suite Variable ${SERVICE_FUNCTIONS_FILE} ${CURDIR}/../../../variables/sfc/${VERSION_DIR}/full-deploy/service-functions.json
- Set Suite Variable ${SERVICE_FORWARDERS_FILE} ${CURDIR}/../../../variables/sfc/${VERSION_DIR}/full-deploy/service-function-forwarders.json
- Set Suite Variable ${SERVICE_NODES_FILE} ${CURDIR}/../../../variables/sfc/${VERSION_DIR}/full-deploy/service-nodes.json
- Set Suite Variable ${SERVICE_CHAINS_FILE} ${CURDIR}/../../../variables/sfc/${VERSION_DIR}/full-deploy/service-function-chains.json
- Set Suite Variable ${SERVICE_FUNCTION_PATHS_FILE} ${CURDIR}/../../../variables/sfc/${VERSION_DIR}/full-deploy/service-function-paths.json
- Set Suite Variable ${SERVICE_RANDOM_SCHED_TYPE_FILE} ${CURDIR}/../../../variables/sfc/${VERSION_DIR}/full-deploy/service-random-schedule-type.json
- Set Suite Variable ${SERVICE_ROUNDROBIN_SCHED_TYPE_FILE} ${CURDIR}/../../../variables/sfc/${VERSION_DIR}/full-deploy/service-roundrobin-schedule-type.json
+ Set Suite Variable ${CONFIG_DIR} ${CURDIR}/../../../variables/sfc/master/full-deploy
+ Set Suite Variable ${SERVICE_FUNCTIONS_FILE} ${CONFIG_DIR}/service-functions.json
+ Set Suite Variable ${SERVICE_FORWARDERS_FILE} ${CONFIG_DIR}/service-function-forwarders.json
+ Set Suite Variable ${SERVICE_NODES_FILE} ${CONFIG_DIR}/service-nodes.json
+ Set Suite Variable ${SERVICE_CHAINS_FILE} ${CONFIG_DIR}/service-function-chains.json
+ Set Suite Variable ${SERVICE_FUNCTION_PATHS_FILE} ${CONFIG_DIR}/service-function-paths.json
+ Set Suite Variable ${SERVICE_METADATA_FILE} ${CONFIG_DIR}/service-function-metadata.json
+ Set Suite Variable ${SERVICE_FUNCTION_ACLS_FILE} ${CONFIG_DIR}/service-function-acls.json
+ Set Suite Variable ${SERVICE_CLASSIFIERS_FILE} ${CONFIG_DIR}/service-function-classifiers.json
+ Switch Ips In Json Files ${CONFIG_DIR} ${DOCKER_NAMES_LIST}
+
+Cleanup Suite
+ [Documentation] Clean up all docker containers created and delete sessions
+ Remove All Elements At URI ${SERVICE_CLASSIFIERS_URI}
+ Remove All Elements At URI ${SERVICE_FUNCTION_ACLS_URI}
+ Remove All Elements At URI ${SERVICE_FUNCTIONS_URI}
+ Remove All Elements At URI ${SERVICE_FORWARDERS_URI}
+ Remove All Elements At URI ${SERVICE_NODES_URI}
+ Remove All Elements At URI ${SERVICE_CHAINS_URI}
+ Remove All Elements At URI ${SERVICE_FUNCTION_PATHS_URI}
+ Remove All Elements At URI ${SERVICE_METADATA_URI}
+ DockerSfc.Docker Ovs Clean log_file=myFile4.log
+ Delete All Sessions
+ SSHLibrary.Close Connection
exit 1
}
+clean_iptables () {
+ sudo iptables -F
+ sudo iptables -t nat -F
+}
+
ovs_vsctl () {
sudo ovs-vsctl --timeout=60 "$@"
}
if [ -z "$ODL" ]; then :; else
d_ovs_vsctl "$CONTAINER" set-manager "tcp:${ODL}:6640"
- d_ovs_vsctl "$CONTAINER" set-controller br-tun "tcp:${ODL}:6633"
- d_ovs_vsctl "$CONTAINER" set-controller br-int "tcp:${ODL}:6633"
fi
DO_GUEST="$GUESTS"
UTIL=$(basename $0)
search_path ovs-vsctl
search_path docker
+clean_iptables
#if [[ $EUID -ne 0 ]]; then
# echo "This script must be run as root" 1>&2
[Documentation] Initialize session and ODL version specific variables
Create Session session http://${ODL_SYSTEM_IP}:${RESTCONFPORT} auth=${AUTH} headers=${HEADERS}
log ${ODL_STREAM}
- Run Keyword If '${ODL_STREAM}' == 'stable-lithium' Set Suite Variable ${VERSION_DIR} lithium
- ... ELSE Set Suite Variable ${VERSION_DIR} master
+ Set Suite Variable ${VERSION_DIR} master
Set Suite Variable ${SERVICE_FUNCTIONS_URI} /restconf/config/service-function:service-functions/
Set Suite Variable ${SERVICE_FUNCTIONS_FILE} ${CURDIR}/../../../variables/sfc/${VERSION_DIR}/service-functions.json
Set Suite Variable ${SF_DPI102100_URI} /restconf/config/service-function:service-functions/service-function/dpi-102-100/
[Documentation] Initialize session and ODL version specific variables
Create Session session http://${ODL_SYSTEM_IP}:${RESTCONFPORT} auth=${AUTH} headers=${HEADERS}
log ${ODL_STREAM}
- Run Keyword If '${ODL_STREAM}' == 'stable-lithium' Set Suite Variable ${VERSION_DIR} lithium
- ... ELSE Set Suite Variable ${VERSION_DIR} master
+ Set Suite Variable ${VERSION_DIR} master
Set Suite Variable ${SERVICE_FORWARDERS_URI} /restconf/config/service-function-forwarder:service-function-forwarders/
Set Suite Variable ${SERVICE_FORWARDERS_FILE} ${CURDIR}/../../../variables/sfc/${VERSION_DIR}/service-function-forwarders.json
Set Suite Variable ${SFF_OVS100_URI} /restconf/config/service-function-forwarder:service-function-forwarders/service-function-forwarder/ovs-100/
[Documentation] Initialize session and ODL version specific variables
Create Session session http://${ODL_SYSTEM_IP}:${RESTCONFPORT} auth=${AUTH} headers=${HEADERS}
log ${ODL_STREAM}
- Run Keyword If '${ODL_STREAM}' == 'stable-lithium' Set Suite Variable ${VERSION_DIR} lithium
- ... ELSE Set Suite Variable ${VERSION_DIR} master
+ Set Suite Variable ${VERSION_DIR} master
Set Suite Variable ${SERVICE_NODES_URI} /restconf/config/service-node:service-nodes/
Set Suite Variable ${SERVICE_NODES_FILE} ${CURDIR}/../../../variables/sfc/${VERSION_DIR}/service-nodes.json
Set Suite Variable ${SN_NODE100_URI} /restconf/config/service-node:service-nodes/service-node/node-100
[Documentation] Initialize session and ODL version specific variables
Create Session session http://${ODL_SYSTEM_IP}:${RESTCONFPORT} auth=${AUTH} headers=${HEADERS}
log ${ODL_STREAM}
- Run Keyword If '${ODL_STREAM}' == 'stable-lithium' Set Suite Variable ${VERSION_DIR} lithium
- ... ELSE Set Suite Variable ${VERSION_DIR} master
+ Set Suite Variable ${VERSION_DIR} master
Set Suite Variable ${SERVICE_CHAINS_URI} /restconf/config/service-function-chain:service-function-chains/
Set Suite Variable ${SERVICE_CHAINS_FILE} ${CURDIR}/../../../variables/sfc/${VERSION_DIR}/service-function-chains.json
Set Suite Variable ${SERVICE_CHAIN100_URI} /restconf/config/service-function-chain:service-function-chains/service-function-chain/SFC100
[Documentation] Initialize session and ODL version specific variables
Create Session session http://${ODL_SYSTEM_IP}:${RESTCONFPORT} auth=${AUTH} headers=${HEADERS}
log ${ODL_STREAM}
- Run Keyword If '${ODL_STREAM}' == 'stable-lithium' Set Suite Variable ${VERSION_DIR} lithium
- ... ELSE Set Suite Variable ${VERSION_DIR} master
+ Set Suite Variable ${VERSION_DIR} master
Set Suite Variable ${SERVICE_SCHED_TYPES_URI} /restconf/config/service-function-scheduler-type:service-function-scheduler-types/
Set Suite Variable ${SERVICE_SCHED_TYPES_FILE} ${CURDIR}/../../../variables/sfc/${VERSION_DIR}/service-schedule-types.json
Set Suite Variable ${SERVICE_WSP_SCHED_TYPE_URI} /restconf/config/service-function-scheduler-type:service-function-scheduler-types/service-function-scheduler-type/service-function-scheduler-type:weighted-shortest-path
[Documentation] Initialize session and ODL version specific variables
Create Session session http://${ODL_SYSTEM_IP}:${RESTCONFPORT} auth=${AUTH} headers=${HEADERS}
log ${ODL_STREAM}
- Run Keyword If '${ODL_STREAM}' == 'stable-lithium' Set Suite Variable ${VERSION_DIR} lithium
- ... ELSE Set Suite Variable ${VERSION_DIR} master
+ Set Suite Variable ${VERSION_DIR} master
Set Suite Variable ${SERVICE_FUNCTION_PATHS_URI} /restconf/config/service-function-path:service-function-paths/
Set Suite Variable ${SERVICE_FUNCTION_PATHS_FILE} ${CURDIR}/../../../variables/sfc/${VERSION_DIR}/service-function-paths.json
Set Suite Variable ${SERVICE_FUNCTION_PATH400_URI} /restconf/config/service-function-path:service-function-paths/service-function-path/SFC1-400
[Documentation] Create session and initialize ODL version specific variables
Create Session session http://${ODL_SYSTEM_IP}:${RESTCONFPORT} auth=${AUTH} headers=${HEADERS}
log ${ODL_STREAM}
- Run Keyword If '${ODL_STREAM}' == 'stable-lithium' Set Suite Variable ${VERSION_DIR} lithium
- ... ELSE Set Suite Variable ${VERSION_DIR} master
+ Set Suite Variable ${VERSION_DIR} master
Set Suite Variable ${SERVICE_FUNCTIONS_URI} /restconf/config/service-function:service-functions/
Set Suite Variable ${SERVICE_FUNCTIONS_FILE} ${CURDIR}/../../../variables/sfc/${VERSION_DIR}/service-functions.json
Set Suite Variable ${SERVICE_FORWARDERS_URI} /restconf/config/service-function-forwarder:service-function-forwarders/
Init Suite
[Documentation] Initialize ODL version specific variables
log ${ODL_STREAM}
- Run Keyword If '${ODL_STREAM}' == 'stable-lithium' Set Suite Variable ${VERSION_DIR} lithium
- ... ELSE Set Suite Variable ${VERSION_DIR} master
+ Set Suite Variable ${VERSION_DIR} master
Set Suite Variable ${SFC_FUNCTIONS_FILE} ${CURDIR}/../../../variables/sfc/${VERSION_DIR}/service-functions.json
*** Variables ***
# Generic Service Chains and Function URIs
${SERVICE_FUNCTIONS_URI} /restconf/config/service-function:service-functions/
+${SERVICE_FUNCTION_ACLS_URI} /restconf/config/ietf-access-control-list:access-lists/
+${SERVICE_CLASSIFIERS_URI} /restconf/config/service-function-classifier:service-function-classifiers/
${SERVICE_FORWARDERS_URI} /restconf/config/service-function-forwarder:service-function-forwarders/
${SERVICE_NODES_URI} /restconf/config/service-node:service-nodes/
${SERVICE_CHAINS_URI} /restconf/config/service-function-chain:service-function-chains/
${SERVICE_SCHED_TYPE_URI_BASE} SERVICE_SCHED_TYPES_URI+'service-function-scheduler-type/service-function-scheduler-type:'
${SERVICE_RANDOM_SCHED_TYPE_URI} SERVICE_SCHED_TYPE_URI_BASE+'random'
${SERVICE_ROUNDROBIN_SCHED_TYPE_URI} SERVICE_SCHED_TYPE_URI_BASE+'round-robin'
+${SERVICE_METADATA_URI} /restconf/config/service-function-path-metadata:service-function-metadata/
${OPERATIONAL_RSPS_URI} /restconf/operational/rendered-service-path:rendered-service-paths/
${OPERATIONS_CREATE_RSP_URI} /restconf/operations/rendered-service-path:create-rendered-path/
${OPERATIONS_DELETE_RSP_URI} /restconf/operations/rendered-service-path:delete-rendered-path/
+++ /dev/null
-{
- "service-function-chains": {
- "service-function-chain": [
- {
- "name": "SFC1",
- "sfc-service-function": [
- {
- "name": "dpi-abstract1",
- "type": "service-function-type:dpi",
- "order" : 0
- },
- {
- "name": "napt44-abstract1",
- "type": "service-function-type:napt44",
- "order" : 1
- },
- {
- "name": "firewall-abstract1",
- "type": "service-function-type:firewall",
- "order" : 2
- }
- ]
- },
- {
- "name": "SFC2",
- "sfc-service-function": [
- {
- "name": "firewall-abstract2",
- "type": "service-function-type:firewall",
- "order" : 0
- },
- {
- "name": "napt44-abstract2",
- "type": "service-function-type:napt44",
- "order" : 1
- }
- ]
- }
- ]
- }
-}
+++ /dev/null
-{
- "service-function-forwarders": {
- "service-function-forwarder": [
- {
- "name": "SFF-bootstrap",
- "service-node": "OVSDB1",
- "rest-uri": "http://localhost:5000",
- "sff-data-plane-locator": [
- {
- "name": "eth0",
- "data-plane-locator": {
- "port": 5000,
- "ip": "192.168.1.1",
- "transport": "service-locator:vxlan-gpe"
- }
- }
- ],
- "service-function-dictionary": [
- {
- "sff-sf-data-plane-locator": {
- "port": 5000,
- "ip": "10.1.1.1"
- },
- "name": "SF1",
- "type": "service-function-type:dpi"
- },
- {
- "sff-sf-data-plane-locator": {
- "port": 5000,
- "ip": "10.1.1.2"
- },
- "name": "SF2",
- "type": "service-function-type:firewall"
- }
- ],
- "connected-sff-dictionary": [
- {
- "sff-sff-data-plane-locator": {
- "port": 5000,
- "ip": "192.168.1.2"
- },
- "name": "br-int-ovs-2"
- }
- ]
- },
- {
- "name": "br-int-ovs-2",
- "service-node": "OVSDB2",
- "rest-uri": "http://localhost:5000",
- "sff-data-plane-locator": [
- {
- "name": "eth0",
- "data-plane-locator": {
- "port": 5000,
- "ip": "192.168.1.2",
- "transport": "service-locator:vxlan-gpe"
- }
- }
- ],
- "service-function-dictionary": [
- {
- "sff-sf-data-plane-locator": {
- "port": 5000,
- "ip": "10.1.1.5"
- },
- "name": "SF5",
- "type": "service-function-type:dpi"
- },
- {
- "sff-sf-data-plane-locator": {
- "port": 5000,
- "ip": "10.1.1.6"
- },
- "name": "SF6",
- "type": "service-function-type:napt44"
- }
- ],
- "connected-sff-dictionary": [
- {
- "sff-sff-data-plane-locator": {
- "port": 5000,
- "ip": "10.1.1.2"
- },
- "name": "SFF-bootstrap"
- }
- ]
- }
- ]
- }
-}
+++ /dev/null
-{
- "service-function-paths": {
- "service-function-path": [
- {
- "name": "SFC1-100",
- "service-chain-name": "SFC1"
- },
- {
- "name": "SFC1-200",
- "service-chain-name": "SFC1"
- },
- {
- "name": "SFC1-300",
- "service-chain-name": "SFC1"
- },
- {
- "name": "SFC2-100",
- "service-chain-name": "SFC2"
- },
- {
- "name": "SFC2-200",
- "service-chain-name": "SFC2"
- }
- ]
- }
-}
+++ /dev/null
-{
- "service-functions": {
- "service-function": [
- {
- "rest-uri": "http://localhost:10002",
- "ip-mgmt-address": "10.3.1.103",
- "sf-data-plane-locator": [
- {
- "name": "preferred",
- "port": 10002,
- "ip": "10.3.1.103",
- "service-function-forwarder": "SFF-bootstrap"
- }
- ],
- "name": "napt44-103-2",
- "type": "service-function-type:napt44",
- "nsh-aware": true
- },
- {
- "rest-uri": "http://localhost:10001",
- "ip-mgmt-address": "10.3.1.103",
- "sf-data-plane-locator": [
- {
- "name": "master",
- "port": 10001,
- "ip": "10.3.1.103",
- "service-function-forwarder": "SFF-bootstrap"
- }
- ],
- "name": "napt44-103-1",
- "type": "service-function-type:napt44",
- "nsh-aware": true
- },
- {
- "rest-uri": "http://localhost:10002",
- "ip-mgmt-address": "10.3.1.102",
- "sf-data-plane-locator": [
- {
- "name": "1",
- "port": 10002,
- "ip": "10.3.1.102",
- "service-function-forwarder": "SFF-bootstrap"
- }
- ],
- "name": "dpi-102-2",
- "type": "service-function-type:dpi",
- "nsh-aware": true
- },
- {
- "rest-uri": "http://localhost:10002",
- "ip-mgmt-address": "10.3.1.101",
- "sf-data-plane-locator": [
- {
- "name": "2",
- "port": 10002,
- "ip": "10.3.1.101",
- "service-function-forwarder": "SFF-bootstrap"
- }
- ],
- "name": "firewall-101-2",
- "type": "service-function-type:firewall",
- "nsh-aware": true
- },
- {
- "rest-uri": "http://localhost:10002",
- "ip-mgmt-address": "10.3.1.104",
- "sf-data-plane-locator": [
- {
- "name": "3",
- "port": 10020,
- "ip": "10.3.1.104",
- "service-function-forwarder": "SFF-bootstrap"
- }
- ],
- "name": "napt44-104",
- "type": "service-function-type:napt44",
- "nsh-aware": true
- },
- {
- "rest-uri": "http://localhost:10001",
- "ip-mgmt-address": "10.3.1.102",
- "sf-data-plane-locator": [
- {
- "name": "4",
- "port": 10001,
- "ip": "10.3.1.102",
- "service-function-forwarder": "SFF-bootstrap"
- }
- ],
- "name": "dpi-102-1",
- "type": "service-function-type:dpi",
- "nsh-aware": true
- },
- {
- "rest-uri": "http://localhost:10001",
- "ip-mgmt-address": "10.3.1.104",
- "sf-data-plane-locator": [
- {
- "name": "my-locator",
- "port": 10001,
- "ip": "10.3.1.104",
- "service-function-forwarder": "SFF-bootstrap"
- }
- ],
- "name": "firewall-104",
- "type": "service-function-type:firewall",
- "nsh-aware": true
- },
- {
- "rest-uri": "http://localhost:10003",
- "ip-mgmt-address": "10.3.1.102",
- "sf-data-plane-locator": [
- {
- "name": "101",
- "port": 10003,
- "ip": "10.3.1.102",
- "service-function-forwarder": "SFF-bootstrap"
- }
- ],
- "name": "dpi-102-3",
- "type": "service-function-type:dpi",
- "nsh-aware": true
- },
- {
- "rest-uri": "http://localhost:10001",
- "ip-mgmt-address": "10.3.1.101",
- "sf-data-plane-locator": [
- {
- "name": "007",
- "port": 10001,
- "ip": "10.3.1.101",
- "service-function-forwarder": "SFF-bootstrap"
- }
- ],
- "name": "firewall-101-1",
- "type": "service-function-type:firewall",
- "nsh-aware": true
- }
- ]
- }
-}
+++ /dev/null
-{
- "service-function-scheduler-type": [
- {
- "type": "service-function-scheduler-type:load-balance",
- "enabled": true,
- "name": "load-balance"
- }
- ]
-}
+++ /dev/null
-{
- "service-nodes": {
- "service-node": [
- {
- "name": "node-101",
- "service-function": [
- "firewall-101-2",
- "firewall-101-1"
- ],
- "ip-mgmt-address": "10.3.1.101"
- },
- {
- "name": "node-102",
- "service-function": [
- "dpi-102-1",
- "dpi-102-2",
- "dpi-102-3"
- ],
- "ip-mgmt-address": "10.3.1.102"
- },
- {
- "name": "node-103",
- "service-function": [
- "napt44-103-1",
- "napt44-103-2"
- ],
- "ip-mgmt-address": "10.3.1.103"
- },
- {
- "name": "node-104",
- "service-function": [
- "firewall-104",
- "napt44-104"
- ],
- "ip-mgmt-address": "10.3.1.104"
- }
- ]
- }
-}
\ No newline at end of file
+++ /dev/null
-{
- "service-function-scheduler-type": [
- {
- "type": "service-function-scheduler-type:random",
- "enabled": true,
- "name": "random"
- }
- ]
-}
+++ /dev/null
-{
- "service-function-scheduler-type": [
- {
- "type": "service-function-scheduler-type:round-robin",
- "enabled": true,
- "name": "round-robin"
- }
- ]
-}
+++ /dev/null
-{
- "service-function-scheduler-types": {
- "service-function-scheduler-type": [
- {
- "name": "random",
- "type": "service-function-scheduler-type:random",
- "enabled": false
- },
- {
- "name": "round-robin",
- "type": "service-function-scheduler-type:round-robin",
- "enabled": true
- },
- {
- "name": "load-balance",
- "type": "service-function-scheduler-type:load-balance",
- "enabled": false
- },
- {
- "name": "shortest-path",
- "type": "service-function-scheduler-type:shortest-path",
- "enabled": false
- }
- ]
- }
-}
-
+++ /dev/null
-{
- "service-function-scheduler-type": [
- {
- "type": "service-function-scheduler-type:shortest-path",
- "enabled": true,
- "name": "shortest-path"
- }
- ]
-}
+++ /dev/null
-{
- "service-function-scheduler-type": [
- {
- "type": "service-function-scheduler-type:weighted-shortest-path",
- "enabled": false,
- "name": "weighted-shortest-path"
- }
- ]
-}
+++ /dev/null
-{
- "service-function": [
- {
- "name": "dpi-102-100",
- "type": "service-function-type:dpi",
- "nsh-aware": true,
- "sf-data-plane-locator": [
- {
- "name": "dpl-100",
- "port": 10100,
- "ip": "10.3.1.102",
- "service-function-forwarder": "SFF-bootstrap"
- }
- ],
- "ip-mgmt-address": "10.3.1.102",
- "rest-uri": "http://localhost:10100"
- }
- ]
-}
+++ /dev/null
-{
- "sf-data-plane-locator": [
- {
- "name": "dpl-101",
- "port": 10101,
- "ip": "10.3.1.102",
- "service-function-forwarder": "SFF-bootstrap"
- }
- ]
-}
+++ /dev/null
-{
- "service-function-chain": [
- {
- "name": "SFC100",
- "sfc-service-function": [
- {
- "name": "dpi-abstract100",
- "order": 0,
- "type": "service-function-type:firewall"
- },
- {
- "name": "napt44-abstract100",
- "order": 1,
- "type": "service-function-type:dpi"
- },
- {
- "name": "firewall-abstract100",
- "order": 2,
- "type": "service-function-type:napt44"
- }
- ]
- }
- ]
-}
+++ /dev/null
-{
- "sfc-service-function": [
- {
- "name": "ids-abstract100",
- "order": 3,
- "type": "service-function-type:ids"
- }
- ]
-}
+++ /dev/null
-{
- "sff-sff-data-plane-locator": {
- "ip": "10.1.1.1",
- "port": 6000
- }
-}
+++ /dev/null
-{
- "connected-sff-dictionary": [
- {
- "name": "SFF100",
- "sff-interfaces": [
- {
- "sff-interface": "dpl-100"
- }
- ],
- "sff-sff-data-plane-locator": {
- "port": 6000,
- "ip": "10.1.1.2"
- },
- "failmode": "service-function-forwarder:open"
- }
- ]
-}
+++ /dev/null
-{
- "sff-data-plane-locator": [
- {
- "name": "dpl-101",
- "data-plane-locator": {
- "ip": "192.168.1.1",
- "port": 6101,
- "transport": "service-locator:vxlan-gpe"
- }
- }
- ]
-}
+++ /dev/null
-{
- "data-plane-locator": {
- "ip": "192.168.1.1",
- "port": 5000,
- "transport": "service-locator:vxlan-gpe"
- }
-}
+++ /dev/null
-{
- "service-function-forwarder": [
- {
- "name": "ovs-100",
- "service-node": "OVSDB2",
- "rest-uri": "http://localhost:6000",
- "sff-data-plane-locator": [
- {
- "name": "eth0",
- "data-plane-locator": {
- "port": 6000,
- "ip": "192.168.1.2",
- "transport": "service-locator:vxlan-gpe"
- }
- }
- ],
- "service-function-dictionary": [
- {
- "sff-sf-data-plane-locator": {
- "port": 6000,
- "ip": "10.1.1.7"
- },
- "name": "SF7",
- "type": "service-function-type:dpi"
- }
- ]
- }
- ]
-}
+++ /dev/null
-{
- "sff-sf-data-plane-locator": {
- "port": 6000,
- "ip": "10.1.1.1"
- }
-}
+++ /dev/null
-{
- "service-function-dictionary": [
- {
- "name": "SF100",
- "sff-sf-data-plane-locator": {
- "port": 5100,
- "ip": "10.1.1.1"
- },
- "type": "service-function-type:napt44"
- }
- ]
-}
+++ /dev/null
-{
- "service-function-path": [
- {
- "name": "SFC1-400",
- "service-chain-name": "SFC1"
- }
- ]
-}
+++ /dev/null
-{
- "service-node": [
- {
- "name": "node-100",
- "ip-mgmt-address": "10.3.1.100",
- "service-function": [
- "dpi-100-1",
- "firewall-102-1"
- ]
- }
- ]
-}
--- /dev/null
+{
+ "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
+ }
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+}
"sfc-service-function": [
{
"name": "dpi-abstract1",
- "type": "dpi",
- "order" : 0
+ "type": "dpi"
},
{
- "name": "napt44-abstract1",
- "type": "napt44",
- "order" : 1
+ "name": "firewall-abstract1",
+ "type": "firewall"
}
]
+ },
+ {
+ "name": "SFC2",
+ "symmetric": "true",
+ "sfc-service-function": [
+ {
+ "name": "dpi-abstract1",
+ "type": "dpi"
+ }
+ ]
}
]
}
--- /dev/null
+{
+ "service-function-classifiers": {
+ "service-function-classifier": [
+ {
+ "name": "Classifier1",
+ "scl-service-function-forwarder": [
+ {
+ "name": "Classifier1",
+ "interface": "v-ovsnsn6g1"
+ }
+ ],
+ "acl": {
+ "name": "ACL1",
+ "type": "ietf-access-control-list:ipv4-acl"
+ }
+ },
+ {
+ "name": "Classifier2",
+ "scl-service-function-forwarder": [
+ {
+ "name": "Classifier2",
+ "interface": "v-ovsnsn1g1"
+ }
+ ],
+ "acl": {
+ "name": "ACL2",
+ "type": "ietf-access-control-list:ipv4-acl"
+ }
+ }
+ ]
+ }
+}
"service-function-forwarders": {
"service-function-forwarder": [
{
- "name": "SFF-1",
- "service-node": "SFF-1",
- "rest-uri": "http://localhost:5000",
+ "name": "Classifier1",
+ "service-node": "classifier1",
"service-function-forwarder-ovs:ovs-bridge": {
- "bridge-name": "br-sfc"
+ "bridge-name": "br-int"
},
"sff-data-plane-locator": [
{
- "name": "SFF-1-DPL",
+ "name": "sff0-dpl",
"data-plane-locator": {
- "port": 5000,
- "ip": "172.17.0.3",
+ "port": 6633,
+ "ip": "ovs-node-6",
"transport": "service-locator:vxlan-gpe"
},
"service-function-forwarder-ovs:ovs-options": {
"nshc4": "flow"
}
}
- ],
- "service-function-dictionary": [
+ ]
+ },
+ {
+ "name": "SFF1",
+ "service-node": "sff1",
+ "service-function-forwarder-ovs:ovs-bridge": {
+ "bridge-name": "br-int"
+ },
+ "sff-data-plane-locator": [
{
- "sff-sf-data-plane-locator": {
- "sf-dpl-name": "SF-1-DPL",
- "sff-dpl-name": "SFF-1-DPL"
+ "name": "sff1-dpl",
+ "data-plane-locator": {
+ "port": 6633,
+ "ip": "ovs-node-5",
+ "transport": "service-locator:vxlan-gpe"
},
- "name": "SF1"
+ "service-function-forwarder-ovs:ovs-options": {
+ "remote-ip": "flow",
+ "dst-port": "6633",
+ "key": "flow",
+ "nsp": "flow",
+ "nsi": "flow",
+ "nshc1": "flow",
+ "nshc2": "flow",
+ "nshc3": "flow",
+ "nshc4": "flow"
+ }
}
],
- "connected-sff-dictionary": [
+ "service-function-dictionary": [
{
- "sff-sff-data-plane-locator": {
- "port": 5000,
- "ip": "172.17.0.5"
- },
- "name": "SFF-2"
+ "name": "dpi-1",
+ "sff-sf-data-plane-locator": {
+ "sf-dpl-name": "dpi-1-dpl",
+ "sff-dpl-name": "sff1-dpl"
+ }
}
]
},
{
- "name": "SFF-2",
- "service-node": "SFF-2",
+ "name": "SFF2",
+ "service-node": "sff2",
"service-function-forwarder-ovs:ovs-bridge": {
- "bridge-name": "br-sfc"
+ "bridge-name": "br-int"
},
- "rest-uri": "http://localhost:5000",
"sff-data-plane-locator": [
{
- "name": "SFF-2-DPL",
+ "name": "sff2-dpl",
"data-plane-locator": {
- "port": 5000,
- "ip": "172.17.0.5",
+ "port": 6633,
+ "ip": "ovs-node-3",
"transport": "service-locator:vxlan-gpe"
},
"service-function-forwarder-ovs:ovs-options": {
],
"service-function-dictionary": [
{
+ "name": "firewall-1",
"sff-sf-data-plane-locator": {
- "sf-dpl-name": "SF-2-DPL",
- "sff-dpl-name": "SFF-2-DPL"
- },
- "name": "SF2"
+ "sf-dpl-name": "firewall-1-dpl",
+ "sff-dpl-name": "sff2-dpl"
+ }
}
- ],
- "connected-sff-dictionary": [
+ ]
+ },
+ {
+ "name": "Classifier2",
+ "service-node": "classifier2",
+ "service-function-forwarder-ovs:ovs-bridge": {
+ "bridge-name": "br-int"
+ },
+ "sff-data-plane-locator": [
{
- "sff-sff-data-plane-locator": {
- "port": 5000,
- "ip": "172.17.0.3"
+ "name": "sff3-dpl",
+ "data-plane-locator": {
+ "port": 6633,
+ "ip": "ovs-node-1",
+ "transport": "service-locator:vxlan-gpe"
},
- "name": "SFF-1"
+ "service-function-forwarder-ovs:ovs-options": {
+ "remote-ip": "flow",
+ "dst-port": "6633",
+ "key": "flow",
+ "nsp": "flow",
+ "nsi": "flow",
+ "nshc1": "flow",
+ "nshc2": "flow",
+ "nshc3": "flow",
+ "nshc4": "flow"
+ }
}
]
}
--- /dev/null
+{
+ "service-function-metadata": {
+ "context-metadata": [
+ {
+ "name": "NSH1",
+ "context-header1": "1",
+ "context-header2": "2",
+ "context-header3": "3",
+ "context-header4": "4"
+ }
+ ]
+ }
+}
"service-function-paths": {
"service-function-path": [
{
- "name": "SFP-1",
- "service-chain-name": "SFC1"
+ "name": "SFP1",
+ "service-chain-name": "SFC1",
+ "starting-index": 255,
+ "symmetric": "true",
+ "context-metadata": "NSH1",
+ "service-path-hop": [
+ {
+ "hop-number": 0,
+ "service-function-name": "dpi-1"
+ }
+ ]
}
]
}
"service-functions": {
"service-function": [
{
- "rest-uri": "http://localhost:10002",
- "ip-mgmt-address": "172.17.0.4",
+ "ip-mgmt-address": "ovs-node-4",
"sf-data-plane-locator": [
{
- "name": "SF-1-DPL",
- "port": 10002,
- "ip": "172.17.0.4",
- "service-function-forwarder": "SFF-1"
+ "name": "dpi-1-dpl",
+ "port": 6633,
+ "ip": "ovs-node-4",
+ "transport": "service-locator:vxlan-gpe",
+ "service-function-forwarder": "SFF1"
}
],
- "name": "dpi-102-2",
+ "name": "dpi-1",
"type": "dpi",
- "nsh-aware": true
+ "nsh-aware": true,
+ "rest-uri": "http://ovs-node-4:5000"
},
{
- "rest-uri": "http://localhost:10001",
- "ip-mgmt-address": "172.17.0.6",
+ "ip-mgmt-address": "ovs-node-2",
"sf-data-plane-locator": [
{
- "name": "SF-2-DPL",
- "port": 10001,
- "ip": "172.17.0.6",
- "service-function-forwarder": "SFF-2"
+ "name": "firewall-1-dpl",
+ "port": 6633,
+ "ip": "ovs-node-2",
+ "transport": "service-locator:vxlan-gpe",
+ "service-function-forwarder": "SFF2"
}
],
- "name": "napt44-103-2",
- "type": "napt44",
- "nsh-aware": true
+ "name": "firewall-1",
+ "type": "firewall",
+ "nsh-aware": true,
+ "rest-uri": "http://ovs-node-2:5000"
}
]
}
"service-nodes": {
"service-node": [
{
- "name": "SF-1",
+ "name": "sf1",
"service-function": [
- "dpi-102-2"
+ "dpi-1"
],
- "ip-mgmt-address": "172.17.0.4"
+ "ip-mgmt-address": "ovs-node-4"
},
{
- "name": "SF-2",
+ "name": "sf2",
"service-function": [
- "napt-44-103-2"
+ "firewall-1"
],
- "ip-mgmt-address": "172.17.0.6"
+ "ip-mgmt-address": "ovs-node-2"
},
{
- "name": "SFF-1",
- "service-function": [
- ],
- "ip-mgmt-address": "172.17.0.3"
+ "name": "sff1",
+ "ip-mgmt-address": "ovs-node-5"
},
{
- "name": "SFF-2",
- "service-function": [
- ],
- "ip-mgmt-address": "172.17.0.5"
+ "name": "sff2",
+ "ip-mgmt-address": "ovs-node-3"
},
{
- "name": "classifier-1",
- "service-function": [
- ],
- "ip-mgmt-address": "172.17.0.2"
+ "name": "classifier1",
+ "ip-mgmt-address": "ovs-node-6"
},
{
- "name": "classifier-2",
- "service-function": [
- ],
- "ip-mgmt-address": "172.17.0.7"
+ "name": "classifier2",
+ "ip-mgmt-address": "ovs-node-1"
}
]
}