--- /dev/null
+*** Settings ***
+Library SSHLibrary
+Resource ../Utils.robot
+
+*** Variables ***
+${VE_DIR} ${WORKSPACE}/GBPSFC_VE
+
+*** Keywords ***
+Connect and Login
+ [Arguments] ${ip} ${timeout}=3s
+ SSHLibrary.Open Connection ${ip} timeout=${timeout}
+ Utils.Flexible Mininet Login
+
+Execute in VE
+ [Arguments] ${cmd} ${virt_env_path}=${VE_DIR} ${timeout}=10s
+ [Documentation] Wrapper method for executing commands in python virtual environment.
+ Set Client Configuration timeout=${timeout}
+ ${stdout} ${stderr} ${rc} SSHLibrary.Execute Command source ${virt_env_path}/bin/activate;${cmd}
+ ... return_stderr=True return_stdout=True return_rc=True
+ [Return] ${stdout} ${stderr} ${rc}
+
--- /dev/null
+*** Settings ***
+Library SSHLibrary
+Resource ../Utils.robot
+
+*** Variables ***
+
+*** Keywords ***
+
+Ping from Docker
+ [Arguments] ${docker_name} ${dest_address} ${count}=1
+ [Documentation] Sends ICMP requests from docker container to remote address.
+ ${output} ${rc} SSHLibrary.Execute Command
+ ... docker exec ${docker_name} ping ${dest_address} -c ${count} >/dev/null 2>&1 && echo success
+ ... return_stdout=True return_stderr=False return_rc=True
+ Should Contain ${output} success
+ Should Be Equal As Numbers ${rc} 0
+
+Start Endless Ping from Docker
+ [Arguments] ${docker_name} ${dest_address}
+ [Documentation] Starts endless ICMP pinging from docker container to remote address.
+ Ping from Docker ${docker_name} ${dest_address}
+
+ SSHLibrary.Execute Command docker exec -d ${docker_name} ping ${dest_address}
+
+Start HTTP Service on Docker
+ [Arguments] ${docker_name} ${service_port}=80 ${timeout}=20s
+ [Documentation] Starts SimpleHTTPServer on docker container. Service port should be idle.
+ ${stdout} SSHLibrary.Execute Command docker exec ${docker_name} ps aux | grep 'SimpleHTTPServer ${service_port}'
+ ... return_stdout=True return_stderr=False return_rc=False
+ Should Be Empty ${stdout}
+ SSHLibrary.Write docker exec ${docker_name} python -m SimpleHTTPServer ${service_port} &
+ Wait Until Keyword Succeeds 2 min 5 sec Test Port On Docker ${docker_name} ${service_port}
+
+Stop HTTP Service on Docker
+ [Arguments] ${docker_name} ${service_port}=80
+ [Documentation] Stops SimpleHTTPServer on docker container. Service port should not be idle.
+ ${stdout} SSHLibrary.Execute Command
+ ... docker exec ${docker_name} ps aux | grep 'SimpleHTTPServer ${service_port}' | awk '{print $2}'
+ ... return_stdout=True return_stderr=False return_rc=False
+ Should Not Be Empty ${stdout}
+ ${stdout} SSHLibrary.Execute Command docker exec ${docker_name} kill ${stdout}
+ ... return_stdout=True return_stderr=False return_rc=False
+
+Curl from Docker
+ [Arguments] ${docker_name} ${dest_address} ${service_port}=80 ${connect_timeout}=2 ${retry}=3x ${retry_after}=1s
+ [Documentation] Sends HTTP request to remote server. Endless curl should not be running.
+ ${output} SSHLibrary.Execute Command docker exec ${docker_name} ls | grep curl_running
+ ... return_stdout=True return_stderr=False return_rc=False
+ Should Be Empty ${output}
+ Wait Until Keyword Succeeds ${retry} ${retry_after} Execute Curl ${docker_name} ${dest_address} ${service_port}
+
+Start Endless Curl from Docker
+ [Arguments] ${docker_name} ${dest_address} ${service_port} ${retry_after}=1s ${retry}=5 ${timeout}=20s ${sleep}=1
+ [Documentation] Starts endless curl from docker container. Only one endless curl can be running on docker container.
+ ${output} SSHLibrary.Execute Command docker exec ${docker_name} ls | grep curl_running
+ ... return_stdout=True return_stderr=False return_rc=False
+ Should Be Empty ${output}
+ ${output} SSHLibrary.Execute Command docker exec ${docker_name} touch curl_running && echo success
+ ... return_stdout=True return_stderr=False return_rc=False
+ Should Contain ${output} success
+ Wait Until Keyword Succeeds ${retry} ${retry_after} Execute Curl
+ ... ${docker_name} ${dest_address} ${service_port} endless="TRUE" sleep=${sleep}
+
+Stop Endless Curl from Docker
+ [Arguments] ${docker_name}
+ [Documentation] Stops endless curl from docker container. Endless curl should be running before stopping it.
+ ${output} SSHLibrary.Execute Command docker exec ${docker_name} ls | grep curl_running
+ ... return_stdout=True return_stderr=False return_rc=False
+ Should Not Be Empty ${output}
+ ${output} SSHLibrary.Execute Command docker exec ${docker_name} rm curl_running && echo success
+ ... return_stdout=True return_stderr=False return_rc=False
+ Should Contain ${output} success
+
+Stop Endless Ping from Docker to Address
+ [Arguments] ${docker_name} ${dest_address}
+ [Documentation] Stops endless ping from docker to remote address. Endless ping session should be running before stopping it.
+
+ ${output} SSHLibrary.Execute Command docker exec ${docker_name} ps aux | grep 'ping ${dest_address}' | grep -v grep | awk '{print $2}'
+ ... return_stdout=True return_stderr=False return_rc=False
+ Should Not Be Empty ${output}
+ SSHLibrary.Execute Command docker exec ${docker_name} kill ${output}
+ ${output} SSHLibrary.Execute Command docker exec ${docker_name} ps aux | grep 'ping ${dest_address}' | grep -v grep | awk '{print $2}'
+ Should Be Empty ${output}
+
+Test Port On Docker
+ [Arguments] ${docker_name} ${service_port}
+ [Documentation] Tests if a service is running on service port.
+ ${out} SSHLibrary.Execute Command docker exec ${docker_name} nc -z -w 5 127.0.0.1 ${service_port} && echo 'opened'
+ Should Not Be Empty ${out}
+
+Execute Curl
+ [Arguments] ${docker_name} ${dest_address} ${service_port} ${endless}="FALSE" ${sleep}=1
+ [Documentation] Executes curl or curl loop for caller methods based on given parameters.
+ ${output} SSHLibrary.Execute Command docker exec ${docker_name} curl ${dest_address}:${service_port} >/dev/null 2>&1 && echo success
+ Should Contain ${output} success
+ Run Keyword If ${endless} == "TRUE"
+ ... SSHLibrary.Execute Command
+ ... docker exec -d ${docker_name} /bin/sh -c "while [ -f curl_running ]; do curl ${dest_address}:${service_port} ; sleep ${sleep}; done"
+ Log ${output}
+
+
+
--- /dev/null
+*** Settings ***
+Documentation Operations on Docker containers for GBP
+Library SSHLibrary
+Library Collections
+Resource ../Utils.robot
+Resource ConnUtils.robot
+Resource DockerUtils.robot
+Variables ../../variables/Variables.py
+Library OperatingSystem
+
+*** Keywords ***
+Inspect Service Function
+ [Arguments] ${in_port} ${out_port} ${outer_src_ip} ${outer_dst_ip} ${eth_type} ${inner_src_ip}
+ ... ${inner_dst_ip} ${next_hop_ip} ${nsp} ${received_nsi} ${proto}=${EMPTY}
+ [Documentation] Inspects traffic passing through service function node.
+ @{matches} Create List
+ @{actions} Create List
+ Append In Port Check ${matches} ${in_port}
+ Append Ether-Type Check ${matches} ${eth_type}
+ Append Tunnel Set Check ${matches}
+ Append Outer IPs Check ${matches} src_ip=${outer__src_ip}/255.255.255.255 dst_ip=${outer_dst_ip}/255.255.255.255
+ Append NSI Check ${matches} ${received_nsi}
+ Append NSP Check ${matches} ${nsp}
+ Append Inner IPs Check ${matches} ${inner_src_ip}/0.0.0.0 ${inner_dst_ip}/0.0.0.0
+ Run Keyword If "${proto}" != "${EMPTY}" Append Proto Check ${matches} ${proto}
+ Append Tunnel Set Check ${actions}
+ Append Outer IPs Check ${actions} dst_ip=${next_hop_ip}
+ ${rewritten_nsi} Evaluate ${received_nsi} -1
+ Append NSI Check ${actions} ${rewritten_nsi}
+ Append NSP Check ${actions} ${nsp}
+ Append Out Port Check ${actions} ${out_port}
+ ${flow} Find Flow in DPCTL Output ${matches} ${actions}
+ [Return] ${flow}
+
+
+Inspect Service Function Forwarder
+ [Arguments] ${in_port} ${out_port} ${outer_src_ip} ${outer_dst_ip} ${eth_type} ${inner_src_ip}
+ ... ${inner_dst_ip} ${next_hop_ip} ${nsp} ${nsi} ${proto}=${EMPTY}
+ [Documentation] Inspects traffic passing through service function forwarder node.
+ @{matches} Create List
+ @{actions} Create List
+ Append In Port Check ${matches} ${in_port}
+ Append Ether-Type Check ${matches} ${eth_type}
+ Append Tunnel Set Check ${matches}
+ Append Outer IPs Check ${matches} src_ip=${outer_src_ip} dst_ip=${outer_dst_ip}
+ Append NSI Check ${matches} ${nsi}
+ Append NSP Check ${matches} ${nsp}
+ Append Inner IPs Check ${matches} ${inner_src_ip}/255.255.255.255 ${inner_dst_ip}/255.255.255.255
+ Run Keyword If "${proto}" != "${EMPTY}" Append Proto Check ${matches} ${proto}
+ Append Tunnel Set Check ${actions}
+ Append Outer IPs Check ${actions} dst_ip=${next_hop_ip}
+ Append NSI Check ${actions} ${nsi}
+ Append NSP Check ${actions} ${nsp}
+ Append Out Port Check ${actions} ${out_port}
+ ${flow} Find Flow in DPCTL Output ${matches} ${actions}
+ [Return] ${flow}
+
+Inspect Classifier Outbound
+ [Arguments] ${in_port} ${out_port} ${eth_type} ${inner_src_ip} ${inner_dst_ip}
+ ... ${next_hop_ip}=${EMPTY} ${nsi}=${EMPTY} ${proto}=${EMPTY} ${src_port}=${EMPTY} ${dst_port}=${EMPTY}
+ [Documentation] Inspects outbound traffic of a classifier. Traffic source should be located on the classifier.
+ ... If traffic destination is located on the same VM, do not specify neither of next_hop_ip and nsi.
+ ... If traffic destination is located on different VM and the traffic is not forwarded into a chain, specify
+ ... next_hop_ip and don't specify nsi.
+ ... If traffic destination is located on different VM and the traffic is forwarded into a chain, specify both
+ ... next_hop_ip and nsi.
+ @{matches} Create List
+ @{actions} Create List
+ Append In Port Check ${matches} ${in_port}
+ Append Ether-Type Check ${matches} ${eth_type}
+ Run Keyword If "${proto}" != "${EMPTY}" Append Proto Check ${matches} ${proto}
+ Run Keyword If "${src_port}"!="${EMPTY}" or "${dst_port}"!="${EMPTY}"
+ ... Append L4 Check ${matches} src_port=${src_port} dst_port=${dst_port}
+ Append Out Port Check ${actions} ${out_port}
+ Append Inner IPs Check ${actions} ${inner_src_ip} ${inner_dst_ip}
+ Run Keyword If "${next_hop_ip}"!="${EMPTY}"
+ ... Run Keywords
+ ... Append Tunnel Set Check ${actions} AND
+ ... Append Outer IPs Check ${actions} dst_ip=${next_hop_ip}
+ ... ELSE Append Tunnel Not Set Check ${actions}
+ Run Keyword If "${nsi}"!="${EMPTY}"
+ ... Append NSI Check ${actions} 255
+ ${flow} Find Flow in DPCTL Output ${matches} ${actions}
+ [Return] ${flow}
+
+Inspect Classifier Inbound
+ [Documentation] Inspects inbound traffic of a classifier. Traffic destination should be located on the classifier.
+ ... If traffic source is located on different VM and the traffic comes out of a chain, specify nsi and nsp values.
+ ... If traffic source is located on different VM and the traffic does not comes out of a chain, do not specify
+ ... neither of nsi and nsp values.
+ [Arguments] ${in_port} ${out_port} ${eth_type} ${inner_src_ip} ${inner_dst_ip}
+ ... ${outer_src_ip} ${outer_dst_ip} ${nsp}=${EMPTY} ${nsi}=${EMPTY} ${proto}=${EMPTY} ${src_port}=${EMPTY} ${dst_port}=${EMPTY}
+ @{matches} Create List
+ @{actions} Create List
+ Append In Port Check ${matches} ${in_port}
+ Append Ether-Type Check ${matches} ${eth_type}
+ Append Outer IPs Check ${matches} src_ip=${outer_src_ip} dst_ip=${outer_dst_ip}
+ Append Inner IPs Check ${matches} ${inner_src_ip} ${inner_dst_ip}
+ Run Keyword If "${src_port}"!="${EMPTY}" or "${dst_port}"!="${EMPTY}"
+ ... Append L4 Check ${matches} src_port=${src_port} dst_port=${dst_port}
+ Append Tunnel Set Check ${matches}
+ Run Keyword If "${nsi}"!="${EMPTY}" and "${nsp}"!="${EMPTY}"
+ ... Run Keywords
+ ... Append NSI Check ${matches} ${nsi} AND
+ ... Append NSP Check ${matches} ${nsp}
+ Run Keyword If "${proto}" != "${EMPTY}"
+ ... Run Keywords
+ ... Append Proto Check ${matches} ${proto} AND
+ ... Append Proto Check ${actions} ${proto}
+ Append Out Port Check ${actions} ${out_port}
+ Append Inner IPs Check ${actions} ${inner_src_ip} ${inner_dst_ip}
+ ${flow} Find Flow in DPCTL Output ${matches} ${actions}
+ [Return] ${flow}
+
+Find Flow in DPCTL Output
+ [Arguments] ${flow_match_criteria} ${flow_action_criteria}
+ [Documentation] Executes 'ovs-dpctl dump-flows' on remote system and goes through each output line.
+ ... A line is returned if all the criterias in actions part and matches part are matched. This is
+ ... done by calling 'Check Match' keyword. If no match is found for any of the flows, caller test case
+ ... will be failed.
+ ${output} SSHLibrary.Execute Command sudo ovs-dpctl dump-flows
+ Log ${output}
+ @{lines} Split To Lines ${output}
+ ${match_result} Set Variable
+ ${action_result} Set Variable
+ :FOR ${line} IN @{lines}
+ \ ${match} Get Matches Part ${line}
+ \ ${action} Get Actions Part ${line}
+ \ ${match_result} Check Match ${match} @{flow_match_criteria}
+ \ ${action_result} Check Match ${action} @{flow_action_criteria}
+ \ Run Keyword If "${match_result}" == "TRUE" and "${action_result}" == "TRUE"
+ \ ... Return From Keyword ${line}
+ Log ${flow_match_criteria}
+ Log ${flow_action_criteria}
+ Fail Flow not found!
+
+Get Matches Part
+ [Arguments] ${ovs-dpctl_flow}
+ [Documentation] Returns matches part of a flow captured with 'ovs-dpctl dump-flows'.
+ @{matches_actions} Split String ${ovs-dpctl_flow} actions
+ Log ${matches_actions[0]}
+ [Return] ${matches_actions[0]}
+
+Get Actions Part
+ [Arguments] ${ovs-dpctl_flow}
+ [Documentation] Returns actions part of a flow captured with 'ovs-dpctl dump-flows'.
+ @{matches_actions} Split String ${ovs-dpctl_flow} actions
+ [Return] ${matches_actions[1]}
+
+Check Match
+ [Arguments] ${string} @{match_criteria}
+ [Documentation] Applies 'grep' on the string argument for each criterion.
+ ${conditions} Set Variable
+ :FOR ${criterio} IN @{match_criteria}
+ \ ${grep_criterio} Catenate | grep ${criterio}
+ \ ${conditions} Catenate ${conditions} ${grep_criterio}
+ \ ${debug_output} OperatingSystem.Run echo "${string}" ${conditions}
+ \ Log ${debug_output}
+ \ Run Keyword If "${debug_output}" == "${EMPTY}" Log ${criterio}
+ ${output} OperatingSystem.Run echo "${string}" ${conditions}
+ Log ${output}
+ Run Keyword If "${output}" == "${EMPTY}"
+ ... Return From Keyword FALSE
+ ... ELSE Return From Keyword TRUE
+
+Append Proto Check
+ [Arguments] ${list} ${proto}
+ [Documentation] Returns proto part of flow can be captured with 'ovs-dpctl dump-flows'.
+ Append To List ${list} proto=${proto}
+
+Append Inner MAC Check
+ [Arguments] ${list} ${src_addr}=${EMPTY} ${dst_addr}=${EMPTY}
+ [Documentation] Returns encapsulated MAC addresses part of flow can be captured with 'ovs-dpctl dump-flows'.
+ Run Keyword If "${src_addr}" != "${EMPTY}" and "${dst_addr}" != "${EMPTY}"
+ ... Append To List ${list} "eth(src=${src_addr},dst=${dst_addr})"
+ ... ELSE IF "${src_addr}" != "${EMPTY}"
+ ... Append To List ${list} "eth(src=${src_addr},dst=.*)"
+ ... ELSE IF "${dst_addr}" != "${EMPTY}"
+ ... Append To List ${list} "eth(src=.*,dst=${dst_addr})"
+ ... ELSE Fail Specify at liest src or dest IP!
+
+Append Inner IPs Check
+ [Arguments] ${list} ${src_ip}=${EMPTY} ${dst_ip}=${EMPTY}
+ [Documentation] Returns encapsulated IP addresses part of flow can be captured with 'ovs-dpctl dump-flows'.
+ Run Keyword If "${src_ip}" != "${EMPTY}" and "${dst_ip}" != "${EMPTY}"
+ ... Append To List ${list} "ipv4(src=${src_ip},dst=${dst_ip}"
+ ... ELSE IF "${src_ip}" != "${EMPTY}"
+ ... Append To List ${list} "ipv4(src=${src_ip},dst=.*"
+ ... ELSE IF "${dst_ip}" != "${EMPTY}"
+ ... Append To List ${list} "ipv4(src=.*,dst=${dst_ip}"
+ ... ELSE Fail Specify at liest src or dest IP!
+
+Append Outer IPs Check
+ [Arguments] ${list} ${src_ip}=${EMPTY} ${dst_ip}=${EMPTY}
+ [Documentation] Returns packet IP addresses part of flow can be captured with 'ovs-dpctl dump-flows'.
+ Run Keyword If "${src_ip}" != "${EMPTY}"
+ ... Append To List ${list} src=${src_ip}
+ ... ELSE IF "${dst_ip}" != "${EMPTY}"
+ ... Append To List ${list} dst=${dst_ip}
+ ... ELSE Fail Specify at liest src or dest IP!
+
+Append In Port Check
+ [Arguments] ${list} ${in_port}
+ [Documentation] Returns ingress port part of flow can be captured with 'ovs-dpctl dump-flows'.
+ Append To List ${list} "in_port(${in_port})"
+
+Append Out Port Check
+ [Arguments] ${list} ${out_port}
+ [Documentation] Returns egress port part of flow can be captured with 'ovs-dpctl dump-flows'.
+ Append To List ${list} ,${out_port}
+
+Append L4 Check
+ [Arguments] ${list} ${src_port}=${EMPTY} ${dst_port}=${EMPTY}
+ [Documentation] Returns L4 port part of flow can be captured with 'ovs-dpctl dump-flows'.
+ Run Keyword If "${src_port}" != "${EMPTY}"
+ ... Append To List ${list} src=${src_port}
+ ... ELSE IF "${dst_port}" != "${EMPTY}"
+ ... Append To List ${list} dst=${dst_port}
+ ... ELSE Fail Specify at liest src or dest port!
+
+Append NSI Check
+ [Arguments] ${list} ${nsi}
+ [Documentation] Returns NSI part of flow can be captured with 'ovs-dpctl dump-flows'.
+ Append To List ${list} nsi=${nsi}
+
+Append NSP Check
+ [Arguments] ${list} ${nsp}
+ [Documentation] Returns NSP part of flow can be captured with 'ovs-dpctl dump-flows'.
+ Append To List ${list} nsp=${nsp}
+
+Append Ether-Type Check
+ [Arguments] ${list} ${eth_type}
+ [Documentation] Returns Ether-Type part of flow can be captured with 'ovs-dpctl dump-flows'.
+ Append To List ${list} "eth_type(${eth_type})"
+
+Append Tunnel Set Check
+ [Arguments] ${list}
+ [Documentation] Tunnel ID is locally significant to neighbouring nodes and it is not
+ ... statically determined. By checking it's presence in match ( or action) fields,
+ ... we can say whether a packet was received (or send out) via tunnel port.
+ Append To List ${list} tun_id
+
+Append Tunnel Not Set Check
+ [Arguments] ${list}
+ [Documentation] Tunnel ID is locally significant to neighbouring nodes and it is not
+ ... statically determined. By checking it's presence in match ( or action) fields,
+ ... we can say whether a packet was received (or send out) via tunnel port.
+ Append To List ${list} -v tun_id
+
+Get NSP Value From Flow
+ [Arguments] ${flow}
+ [Documentation] Reads and returns nsp value from flow captured with 'ovs-dpctl dump-flows'.
+ ${flow} Get Actions Part ${flow}
+ ${output} OperatingSystem.Run echo "\$${flow}" | sed 's/.*nsp=/nsp=/' | sed 's/,.*//' | sed 's/.*=//'
+ [Return] ${output}
+
+Manager is Connected
+ ${output} SSHLibrary.Execute Command sudo ovs-vsctl show
+ Should Contain ${output} is_connected: true
+
+Manager and Switch Connected
+ [Arguments] ${sw_name}
+ ${output} SSHLibrary.Execute Command sudo ovs-vsctl show
+ Should Contain ${output} ${sw_name}
+ Should Contain x Times ${output} is_connected: true 2
+
+Wait For Flows On Switch
+ [Arguments] ${switch_ip} ${switch_name}
+ [Documentation] Counts flows on switch, fails if 0
+ ConnUtils.Connect and Login ${switch_ip}
+ # check for OVS errors first
+ ${stdout} ${stderr} SSHLibrary.Execute Command sudo ovs-ofctl dump-flows ${switch_name} -OOpenFlow13
+ ... return_stderr=True
+ Run Keyword If "${stderr}" != "${EMPTY}" Fatal Error ${stderr}
+
+ Wait Until Keyword Succeeds 120s 20s Count Flows On Switch ${switch_name}
+ SSHLibrary.Close Connection
+
+Count Flows On Switch
+ [Arguments] ${switch_name}
+ ${out} SSHLibrary.Execute Command printf "%d" $(($(sudo ovs-ofctl dump-flows ${switch_name} -OOpenFlow13 | wc -l)-1))
+ Should Be True ${out}>0
\ No newline at end of file
--- /dev/null
+#!/usr/bin/env bash
+
+set -e
+
+sw=$(sudo ovs-vsctl show | egrep -E 'Bridge.*sw' | awk '{print $2}' | sed -e 's/^"//' -e 's/"$//')
+if [ "$sw" ]
+then
+ sudo ovs-vsctl del-br $sw
+fi
+sudo ovs-vsctl del-manager;
+
+docker stop -t=1 $(docker ps -a -q) > /dev/null 2>&1
+docker rm $(docker ps -a -q) > /dev/null 2>&1
+
+sudo /etc/init.d/openvswitch-switch stop > /dev/null
+sudo rm /etc/openvswitch/conf.db > /dev/null
+sudo /etc/init.d/openvswitch-switch start > /dev/null
\ No newline at end of file
--- /dev/null
+#!/usr/bin/python
+
+from subprocess import check_output
+
+
+def call_dpctl():
+ cmd = "ovs-dpctl dump-flows"
+ listcmd = cmd.split()
+ return check_output(listcmd)
+
+if __name__ == "__main__":
+ flows = call_dpctl().split("recirc_id")
+ for flow in flows:
+ print flow
--- /dev/null
+#!/usr/bin/env bash
+
+set -e
+hostnum=${HOSTNAME#"gbpsfc"}
+sw="sw$hostnum"
+
+TABLE=$1
+
+clear
+ovs-ofctl dump-groups $sw -OOpenFlow13
+if [ "$TABLE" ]
+then
+ ovs-ofctl dump-flows $sw -OOpenFlow13 table=$TABLE
+else
+ ovs-ofctl dump-flows $sw -OOpenFlow13
+fi
+
--- /dev/null
+#!/usr/bin/env bash
+
+: ' Returns ovs-ofctl dump-flows command output for a table
+ specified in argument by table ID and ovs-ofctl dump-groups
+ output. If no table specified in args, the sum of flows for
+ each table is returned in the output.
+'
+
+set -e
+
+sw=$(sudo ovs-vsctl show | egrep -E 'Bridge.*sw' | awk '{print $2}' | sed -e 's/"//g')
+if [ "$1" ]
+then
+ echo "GROUPS:";
+ ovs-ofctl dump-groups $sw -OOpenFlow13;
+ echo;echo "FLOWS:";ovs-ofctl dump-flows $sw -OOpenFlow13 table=$1 --rsort=priority
+ echo
+ printf "Flow count: "
+ echo $(($(ovs-ofctl dump-flows $sw -OOpenFlow13 table=$1 | wc -l)-1))
+else
+ printf "No table entered. $sw flow count: ";
+ echo $(($(ovs-ofctl dump-flows $sw -OOpenFlow13 | wc -l)-1))
+ printf "\nTable0: PortSecurity: "; echo $(($(ovs-ofctl dump-flows $sw -OOpenFlow13 table=0| wc -l)-1))
+ printf "\nTable1: IngressNat: "; echo $(($(ovs-ofctl dump-flows $sw -OOpenFlow13 table=1| wc -l)-1))
+ printf "\nTable2: SourceMapper: "; echo $(($(ovs-ofctl dump-flows $sw -OOpenFlow13 table=2| wc -l)-1))
+ printf "\nTable3: DestMapper: "; echo $(($(ovs-ofctl dump-flows $sw -OOpenFlow13 table=3| wc -l)-1))
+ printf "\nTable4: PolicyEnforcer:"; echo $(($(ovs-ofctl dump-flows $sw -OOpenFlow13 table=4| wc -l)-1))
+ printf "\nTable5: EgressNAT: "; echo $(($(ovs-ofctl dump-flows $sw -OOpenFlow13 table=5| wc -l)-1))
+ printf "\nTable6: External: "; echo $(($(ovs-ofctl dump-flows $sw -OOpenFlow13 table=6| wc -l)-1))
+fi
+
--- /dev/null
+#!/usr/bin/python
+
+"""
+Spin-up script for Opendaylight GBP and GBPSFC sample concept demonstrations.
+
+This script has to be run from the environment on which OVS switches and Docker
+containers are located. This script works together with infrastructure_config.py
+configuration script where the entire topology for specific scenario is configured. This
+file defines to which already existing switch docker containers have to be connected.
+OVS switch have to be created on the same hosting environment as this script is executed
+from. Local switch name should match one of the names specified in configuration file so that
+docker containers are created and connected to it.
+
+Updated: 22.10.2015
+
+"""
+
+import socket
+import os
+import sys
+import ipaddr
+from subprocess import call
+from subprocess import check_output
+from infrastructure_config import switches
+from infrastructure_config import hosts
+from infrastructure_config import defaultContainerImage
+
+
+def add_controller(sw, ip):
+ """Connects OVS switch to a controller. The switch is specified
+ by it's name and the controller by it's IP address.
+
+ Args:
+ :param sw: name of a switch on which controller is set
+
+ :param ip: IP address of controller
+
+ NOTE:
+ :Required controller should listen on TCP port 6653.
+ """
+
+ try:
+ socket.inet_aton(ip)
+ except socket.error:
+ print "Error: %s is not a valid IPv4 address of controller!" % ip
+ os.exit(2)
+
+ call(['sudo', 'ovs-vsctl', 'set-controller', sw, 'tcp:%s:6653' % ip])
+
+
+def add_manager(ip):
+ """Sets OVSDB manager for OVS instance.
+
+ Args:
+ :param ip: IP address of specified manager
+
+ NOTE:
+ :Required manager should listen on TCP port 6640.
+ """
+
+ try:
+ socket.inet_aton(ip)
+ except socket.error:
+ print "Error: %s is not a valid IPv4 address of manager!" % ip
+ os.exit(2)
+
+ cmd = ['sudo', 'ovs-vsctl', 'set-manager', 'tcp:%s:6640' % ip]
+ call(cmd)
+
+
+def add_switch(name, dpid=None):
+ """Adds switch to OVS instance and sets it's DataPath ID
+ if specified.
+
+ Args:
+ :param ip: name of new switch
+
+ :param dpid: DataPath ID of new switch
+ """
+
+ call(['sudo', 'ovs-vsctl', 'add-br', name]) # Add bridge
+ if dpid:
+ if len(dpid) < 16: # DPID must be 16-bytes in later versions of OVS
+ filler = '0000000000000000'
+ # prepending zeros to match 16-byt length, e.g. 123 -> 0000000000000123
+ dpid = filler[:len(filler) - len(dpid)] + dpid
+ elif len(dpid) > 16:
+ print 'DPID: %s is too long' % dpid
+ sys.exit(3)
+ call(['sudo', 'ovs-vsctl', 'set', 'bridge', name,
+ 'other-config:datapath-id=%s' % dpid])
+
+
+def set_of_version(sw, version='OpenFlow13,OpenFlow12,OpenFlow10'):
+ """Sets OpenFlow protocol versions on OVS switch
+
+ Args:
+ :param sw: name of switch
+
+ :param sw: OpenFlow versions to support on switch
+ """
+
+ call(['sudo', 'ovs-vsctl', 'set', 'bridge', sw, 'protocols={}'.format(version)])
+
+
+def add_vxlan_tunnel(sw):
+ """Adds VXLAN tunnel to OVS switch.
+
+ Args:
+ :param sw: name of switch
+
+ NOTE:
+ :Remote IP is read from flows.
+ """
+ ifaceName = '{}-vxlan-0'.format(sw)
+ cmd = ['sudo', 'ovs-vsctl', 'add-port', sw, ifaceName,
+ '--', 'set', 'Interface', ifaceName,
+ 'type=vxlan',
+ 'options:remote_ip=flow',
+ 'options:key=flow']
+ call(cmd)
+
+
+def add_gpe_tunnel(sw):
+ """Adds GPE tunnel to OVS switch.
+
+ Args:
+ :param sw: name of switch
+
+ :param dpid: DataPath ID of new switches
+
+ NOTE:
+ :Remote IP is read from flows.
+ """
+
+ ifaceName = '{}-vxlangpe-0'.format(sw)
+ cmd = ['sudo', 'ovs-vsctl', 'add-port', sw, ifaceName,
+ '--', 'set', 'Interface', ifaceName,
+ 'type=vxlan',
+ 'options:remote_ip=flow',
+ 'options:dst_port=6633',
+ 'options:nshc1=flow',
+ 'options:nshc2=flow',
+ 'options:nshc3=flow',
+ 'options:nshc4=flow',
+ 'options:nsp=flow',
+ 'options:nsi=flow',
+ 'options:key=flow']
+ call(cmd)
+
+
+def launch_container(host, containerImage):
+ # TODO use Docker.py
+ """Runs docker container in background.
+
+ Args:
+ :param host: container host name
+
+ :param dpid: DataPath ID of new switch
+
+ Returns:
+ :returns string: container ID
+
+ NOTE:
+ :No networking set.
+
+ """
+
+ containerID = check_output(['docker',
+ 'run',
+ '-d',
+ '--net=none',
+ '--name=%s' % host['name'],
+ '-h',
+ host['name'],
+ '-t',
+ '-i',
+ '--privileged=True',
+ containerImage,
+ '/bin/bash'])
+ return containerID[:-1] # Remove extraneous \n from output of above
+
+
+def connect_container_to_switch(sw, host, containerID):
+ """Connects docker to OVS switch.
+
+ Args:
+ :param sw: name of switch
+
+ :param host: host object to process.
+ Here is an example of such as object
+ {'name': 'h35_2',
+ 'mac': '00:00:00:00:35:02',
+ 'ip': '10.0.35.2/24',
+ 'switch': 'sw1'}
+ Note: 'switch' - name of OVS switch to
+ which the host will be connected
+
+ :param containerID: ID of docker container
+ """
+
+ hostIP = host['ip']
+ mac = host['mac']
+ nw = ipaddr.IPv4Network(hostIP)
+ broadcast = "{}".format(nw.broadcast)
+ router = "{}".format(nw.network + 1)
+ ovswork_path = os.path.dirname(os.path.realpath(__file__)) + '/ovswork.sh'
+ cmd = [ovswork_path,
+ sw,
+ containerID,
+ hostIP,
+ broadcast,
+ router,
+ mac,
+ host['name']]
+ if ('vlan') in host:
+ cmd.append(host['vlan'])
+ call(cmd)
+
+
+def launch(switches, hosts, odl_ip='127.0.0.1'):
+ """Connects hosts to switches. Arguments are
+ tied to underlying configuration file. Processing runs
+ for switch, that is present on local environment and
+ for hosts configured to be connected to the switch.
+
+ Args:
+ :param switches: switches to connect to
+ Example of switch object
+ {'name': 'sw1',
+ 'dpid': '1'}
+
+ :param hosts: hosts to connect
+ Example of host object
+ {'name': 'h35_2',
+ 'mac': '00:00:00:00:35:02',
+ 'ip': '10.0.35.2/24',
+ 'switch': 'sw1'}
+ Note: 'switch' - name of OVS switch to
+ which the host will be connected
+
+ :param odl_ip: IP address of ODL, acting as
+ both - manager and controller.
+ Default value is '127.0.0.1'
+ """
+
+ for sw in switches:
+ add_manager(odl_ip)
+ ports = 0
+ first_host = True
+ for host in hosts:
+ if host['switch'] == sw['name']:
+ if first_host:
+ add_switch(sw['name'], sw['dpid'])
+ set_of_version(sw['name'])
+ add_controller(sw['name'], odl_ip)
+ add_gpe_tunnel(sw['name'])
+ add_vxlan_tunnel(sw['name'])
+ first_host = False
+ containerImage = defaultContainerImage # from Config
+ if ('container_image') in host: # from Config
+ containerImage = host['container_image']
+ containerID = launch_container(host, containerImage)
+ ports += 1
+ connect_container_to_switch(
+ sw['name'], host, containerID)
+ host['port-name'] = 'vethl-' + host['name']
+ print "Created container: %s with IP: %s. Connect using docker attach %s," \
+ "disconnect with 'ctrl-p-q'." % (host['name'], host['ip'], host['name'])
+
+if __name__ == "__main__":
+ if len(sys.argv) < 2 or len(sys.argv) > 3:
+ print "Please, specify IP of ODL and switch index in arguments."
+ print "usage: ./infrastructure_launch.py ODL_IP SWITCH_INDEX"
+ sys.exit(2)
+
+ controller = sys.argv[1]
+ try:
+ socket.inet_aton(controller)
+ except socket.error:
+ print "Error: %s is not a valid IPv4 address!" % controller
+ sys.exit(2)
+
+ sw_index = int(sys.argv[2])
+ print sw_index
+ print switches[sw_index]
+ if sw_index not in range(0, len(switches) + 1):
+ print len(switches) + 1
+ print "Error: %s is not a valid switch index!" % sw_index
+ sys.exit(2)
+
+ sw_type = switches[sw_index]['type']
+ sw_name = switches[sw_index]['name']
+ if sw_type == 'gbp':
+ print "*****************************"
+ print "Configuring %s as a GBP node." % sw_name
+ print "*****************************"
+ print
+ launch([switches[sw_index]], hosts, controller)
+ print "*****************************"
+ print "OVS status:"
+ print "-----------"
+ print
+ call(['sudo', 'ovs-vsctl', 'show'])
+ print
+ print "Docker containers:"
+ print "------------------"
+ call(['docker', 'ps'])
+ print "*****************************"
+ elif sw_type == 'sff':
+ print "*****************************"
+ print "Configuring %s as an SFF." % sw_name
+ print "*****************************"
+ call(['sudo', 'ovs-vsctl', 'set-manager', 'tcp:%s:6640' % controller])
+ print
+ elif sw_type == 'sf':
+ print "*****************************"
+ print "Configuring %s as an SF." % sw_name
+ print "*****************************"
+ call(['%s/sf-config.sh' % os.path.dirname(os.path.realpath(__file__)), '%s' % sw_name])
--- /dev/null
+#!/usr/bin/env bash
+set -e
+
+BRIDGE=$1
+GUEST_ID=$2
+IPADDR=$3
+BROADCAST=$4
+GWADDR=$5
+MAC=$6
+GUESTNAME=$7
+VLANTAG=$8
+
+[ "$IPADDR" ] || {
+ echo "Syntax:"
+ echo "pipework <bridge> <guest-id> <ipaddr>/<subnet> <broadcast> <gateway> <mac> <guestname> [vlan tag]"
+ exit 1
+}
+
+# Step 1: Find the guest (for now, we only support LXC containers)
+while read dev mnt fstype options dump fsck
+do
+ [ "$fstype" != "cgroup" ] && continue
+ echo $options | grep -qw devices || continue
+ CGROUPMNT=$mnt
+done < /proc/mounts
+
+[ "$CGROUPMNT" ] || {
+ echo "Could not locate cgroup mount point."
+ exit 1
+}
+
+N=$(find "$CGROUPMNT" -name "$GUEST_ID*" | wc -l)
+case "$N" in
+ 0)
+ echo "Could not find any container matching $GUEST_ID"
+ exit 1
+ ;;
+ 1)
+ true
+ ;;
+ *)
+ echo "Found more than one container matching $GUEST_ID"
+ exit 1
+ ;;
+esac
+
+NSPID=$(head -n 1 $(find "$CGROUPMNT" -name "$GUEST_ID*" | head -n 1)/tasks)
+[ "$NSPID" ] || {
+ echo "Could not find a process inside container $GUEST_ID"
+ exit 1
+}
+
+# Step 2: Prepare the working directory
+sudo mkdir -p /var/run/netns
+sudo rm -f /var/run/netns/$NSPID
+sudo ln -s /proc/$NSPID/ns/net /var/run/netns/$NSPID
+
+# Step 3: Creating virtual interfaces
+LOCAL_IFNAME=vethl-$GUESTNAME #$NSPID
+GUEST_IFNAME=vethg-$GUESTNAME #$NSPID
+sudo ip link add name $LOCAL_IFNAME type veth peer name $GUEST_IFNAME
+sudo ip link set $LOCAL_IFNAME up
+
+# Step 4: Adding the virtual interface to the bridge
+sudo ip link set $GUEST_IFNAME netns $NSPID
+if [ "$VLANTAG" ]
+then
+ sudo ovs-vsctl add-port $BRIDGE $LOCAL_IFNAME tag=$VLANTAG
+ echo $LOCAL_IFNAME
+else
+ sudo ovs-vsctl add-port $BRIDGE $LOCAL_IFNAME
+ echo $LOCAL_IFNAME
+fi
+
+# Step 5: Configure networking within the container
+sudo ip netns exec $NSPID ip link set $GUEST_IFNAME name eth0
+sudo ip netns exec $NSPID ip addr add $IPADDR broadcast $BROADCAST dev eth0
+sudo ip netns exec $NSPID ifconfig eth0 hw ether $MAC
+sudo ip netns exec $NSPID ip addr add 127.0.0.1 dev lo
+sudo ip netns exec $NSPID ip link set eth0 up
+sudo ip netns exec $NSPID ip link set lo up
+sudo ip netns exec $NSPID ip route add default via $GWADDR
+
--- /dev/null
+#!/usr/bin/env bash
+TABLE=$1
+watch -n 1 -d "flowCount.sh $1"
+
--- /dev/null
+hostnum=${HOSTNAME#"gbpsfc"}
+sw="sw$hostnum"
+echo "Deleting controller for $sw"
+ovs-vsctl del-controller $sw;
+if [[ $? -ne 0 ]] ; then
+ exit 1
+fi
+echo "Sleeping for 6sec..."
+sleep 6
+echo "Setting controller to $ODL"
+ovs-vsctl set-controller $sw tcp:$ODL:6653
--- /dev/null
+#!/usr/bin/env bash
+
+set -e
+
+sw=$1
+
+sudo ovs-vsctl add-br $sw
+sudo ovs-vsctl add-port $sw $sw-vxlangpe-0 -- set interface $sw-vxlangpe-0 type=vxlan options:remote_ip=flow options:dst_port=6633 options:nshc1=flow options:nshc2=flow options:nshc3=flow options:nshc4=flow options:nsp=flow options:nsi=flow options:key=flow
--- /dev/null
+ovs-appctl ofproto/trace $1
--- /dev/null
+# Place the suites in run order:
+integration/test/csit/suites/groupbasedpolicy/GBP/3-node
--- /dev/null
+# Place the suites in run order:
+integration/test/csit/suites/groupbasedpolicy/GBPSFC/6-node
}
]
}
-}
+}
\ No newline at end of file
--- /dev/null
+{
+ "tenant": {
+ "id": "f5c7d344-d1c7-4208-8531-2c2693657e12",
+ "contract": [
+ {
+ "id": "22282cca-9a13-4d0c-a67e-a933ebb0b0ae",
+ "clause": [
+ {
+ "name": "allow-http-clause",
+ "subject-refs": [
+ "allow-http-subject",
+ "allow-icmp-subject"
+ ]
+ }
+ ],
+ "subject": [
+ {
+ "name": "allow-http-subject",
+ "rule": [
+ {
+ "name": "allow-http-rule",
+ "classifier-ref": [
+ {
+ "direction": "in",
+ "name": "http-dest",
+ "instance-name": "http-dest"
+ },
+ {
+ "direction": "out",
+ "name": "http-src",
+ "instance-name": "http-src"
+ }
+ ],
+ "action-ref": [
+ {
+ "name": "allow1",
+ "order": 0
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "allow-icmp-subject",
+ "rule": [
+ {
+ "name": "allow-icmp-rule",
+ "classifier-ref": [
+ {
+ "name": "icmp",
+ "instance-name": "icmp"
+ }
+ ],
+ "action-ref": [
+ {
+ "name": "allow1",
+ "order": 0
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "endpoint-group": [
+ {
+ "id": "1eaf9a67-a171-42a8-9282-71cf702f61dd",
+ "network-domain": "d2779562-ebf1-45e6-93a4-78e2362bc418",
+ "provider-named-selector": [],
+ "consumer-named-selector": [
+ {
+ "contract": [
+ "22282cca-9a13-4d0c-a67e-a933ebb0b0ae"
+ ],
+ "name": "e593f05d-96be-47ad-acd5-ba81465680d5-1eaf9a67-a171-42a8-9282-71cf702f61dd-22282cca-9a13-4d0c-a67e-a933ebb0b0ae"
+ }
+ ]
+ },
+ {
+ "consumer-named-selector": [],
+ "id": "e593f05d-96be-47ad-acd5-ba81465680d5",
+ "network-domain": "2c71d675-693e-406f-899f-12a026eb55f1",
+ "provider-named-selector": [
+ {
+ "contract": [
+ "22282cca-9a13-4d0c-a67e-a933ebb0b0ae"
+ ],
+ "name": "e593f05d-96be-47ad-acd5-ba81465680d5-1eaf9a67-a171-42a8-9282-71cf702f61dd-22282cca-9a13-4d0c-a67e-a933ebb0b0ae"
+ }
+ ]
+ }
+ ],
+ "l2-bridge-domain": [
+ {
+ "id": "7b796915-adf4-4356-b5ca-de005ac410c1",
+ "parent": "cbe0cc07-b8ff-451d-8171-9eef002a8e80"
+ }
+ ],
+ "l2-flood-domain": [
+ {
+ "id": "1ddde8d8-c2bc-48d7-8ce0-d78eb6ed4b5b",
+ "parent": "7b796915-adf4-4356-b5ca-de005ac410c1"
+ },
+ {
+ "id": "03f69af2-481c-4554-97d6-c4fedca5d126",
+ "parent": "7b796915-adf4-4356-b5ca-de005ac410c1"
+ }
+ ],
+ "l3-context": [
+ {
+ "id": "cbe0cc07-b8ff-451d-8171-9eef002a8e80"
+ }
+ ],
+ "name": "GBPPOC",
+ "subnet": [
+ {
+ "id": "d2779562-ebf1-45e6-93a4-78e2362bc418",
+ "ip-prefix": "10.0.35.1/24",
+ "parent": "1ddde8d8-c2bc-48d7-8ce0-d78eb6ed4b5b",
+ "virtual-router-ip": "10.0.35.1"
+ },
+ {
+ "id": "2c71d675-693e-406f-899f-12a026eb55f1",
+ "ip-prefix": "10.0.36.1/24",
+ "parent": "03f69af2-481c-4554-97d6-c4fedca5d126",
+ "virtual-router-ip": "10.0.36.1"
+ }
+ ],
+ "subject-feature-instances": {
+ "classifier-instance": [
+ {
+ "classifier-definition-id": "4250ab32-e8b8-445a-aebb-e1bd2cdd291f",
+ "name": "http-dest",
+ "parameter-value": [
+ {
+ "int-value": "6",
+ "name": "proto"
+ },
+ {
+ "int-value": "80",
+ "name": "destport"
+ }
+ ]
+ },
+ {
+ "classifier-definition-id": "4250ab32-e8b8-445a-aebb-e1bd2cdd291f",
+ "name": "http-src",
+ "parameter-value": [
+ {
+ "int-value": "6",
+ "name": "proto"
+ },
+ {
+ "int-value": "80",
+ "name": "sourceport"
+ }
+ ]
+ },
+ {
+ "classifier-definition-id": "79c6fdb2-1e1a-4832-af57-c65baf5c2335",
+ "name": "icmp",
+ "parameter-value": [
+ {
+ "int-value": "1",
+ "name": "proto"
+ }
+ ]
+ }
+ ],
+ "action-instance": [
+ {
+ "name": "allow1",
+ "action-definition-id": "f942e8fd-e957-42b7-bd18-f73d11266d17"
+ }
+ ]
+ }
+ }
+}
--- /dev/null
+{
+ "tenant": {
+ "id": "25c7d344-d1c7-4208-8531-2c2693657e12",
+ "contract": [
+ {
+ "id": "22282cca-9a13-4d0c-a67e-a933ebb0b0ae",
+ "clause": [
+ {
+ "name": "allow-http-clause",
+ "subject-refs": [
+ "allow-http-subject",
+ "allow-icmp-subject"
+ ]
+ }
+ ],
+ "subject": [
+ {
+ "name": "allow-http-subject",
+ "rule": [
+ {
+ "name": "allow-http-rule",
+ "classifier-ref": [
+ {
+ "direction": "in",
+ "name": "http-dest",
+ "instance-name": "http-dest"
+ },
+ {
+ "direction": "out",
+ "name": "http-src",
+ "instance-name": "http-src"
+ }
+ ],
+ "action-ref": [
+ {
+ "name": "allow1",
+ "order": 0
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "allow-icmp-subject",
+ "rule": [
+ {
+ "name": "allow-icmp-rule",
+ "classifier-ref": [
+ {
+ "name": "icmp",
+ "instance-name": "icmp"
+ }
+ ],
+ "action-ref": [
+ {
+ "name": "allow1",
+ "order": 0
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "endpoint-group": [
+ {
+ "id": "1eaf9a67-a171-42a8-9282-71cf702f61dd",
+ "network-domain": "e2779562-ebf1-45e6-93a4-78e2362bc418",
+ "provider-named-selector": [],
+ "consumer-named-selector": [
+ {
+ "contract": [
+ "22282cca-9a13-4d0c-a67e-a933ebb0b0ae"
+ ],
+ "name": "e593f05d-96be-47ad-acd5-ba81465680d5-1eaf9a67-a171-42a8-9282-71cf702f61dd-22282cca-9a13-4d0c-a67e-a933ebb0b0ae"
+ }
+ ]
+ },
+ {
+ "consumer-named-selector": [],
+ "id": "e593f05d-96be-47ad-acd5-ba81465680d5",
+ "network-domain": "3c71d675-693e-406f-899f-12a026eb55f1",
+ "provider-named-selector": [
+ {
+ "contract": [
+ "22282cca-9a13-4d0c-a67e-a933ebb0b0ae"
+ ],
+ "name": "e593f05d-96be-47ad-acd5-ba81465680d5-1eaf9a67-a171-42a8-9282-71cf702f61dd-22282cca-9a13-4d0c-a67e-a933ebb0b0ae"
+ }
+ ]
+ }
+ ],
+ "l2-bridge-domain": [
+ {
+ "id": "2b796915-adf4-4356-b5ca-de005ac410c1",
+ "parent": "2be0cc07-b8ff-451d-8171-9eef002a8e80"
+ }
+ ],
+ "l2-flood-domain": [
+ {
+ "id": "2ddde8d8-c2bc-48d7-8ce0-d78eb6ed4b5b",
+ "parent": "2b796915-adf4-4356-b5ca-de005ac410c1"
+ },
+ {
+ "id": "23f69af2-481c-4554-97d6-c4fedca5d126",
+ "parent": "2b796915-adf4-4356-b5ca-de005ac410c1"
+ }
+ ],
+ "l3-context": [
+ {
+ "id": "2be0cc07-b8ff-451d-8171-9eef002a8e80"
+ }
+ ],
+ "name": "GBPPOC2",
+ "subnet": [
+ {
+ "id": "e2779562-ebf1-45e6-93a4-78e2362bc418",
+ "ip-prefix": "10.0.35.1/24",
+ "parent": "2ddde8d8-c2bc-48d7-8ce0-d78eb6ed4b5b",
+ "virtual-router-ip": "10.0.35.1"
+ },
+ {
+ "id": "3c71d675-693e-406f-899f-12a026eb55f1",
+ "ip-prefix": "10.0.36.1/24",
+ "parent": "23f69af2-481c-4554-97d6-c4fedca5d126",
+ "virtual-router-ip": "10.0.36.1"
+ }
+ ],
+ "subject-feature-instances": {
+ "classifier-instance": [
+ {
+ "name": "icmp",
+ "classifier-definition-id": "79c6fdb2-1e1a-4832-af57-c65baf5c2335",
+ "parameter-value": [
+ {
+ "name": "proto",
+ "int-value": 1
+ }
+ ]
+ },
+ {
+ "name": "http-dest",
+ "classifier-definition-id": "4250ab32-e8b8-445a-aebb-e1bd2cdd291f",
+ "parameter-value": [
+ {
+ "int-value": "6",
+ "name": "proto"
+ },
+ {
+ "int-value": "80",
+ "name": "destport"
+ }
+ ]
+ },
+ {
+ "name": "http-src",
+ "classifier-definition-id": "4250ab32-e8b8-445a-aebb-e1bd2cdd291f",
+ "parameter-value": [
+ {
+ "int-value": "6",
+ "name": "proto"
+ },
+ {
+ "int-value": "80",
+ "name": "sourceport"
+ }
+ ]
+ }
+ ],
+ "action-instance": [
+ {
+ "name": "allow1",
+ "action-definition-id": "f942e8fd-e957-42b7-bd18-f73d11266d17"
+ }
+ ]
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "nodes": {
+ "node": [
+ {
+ "id": "openflow:1",
+ "ofoverlay:tunnel": [
+ {
+ "tunnel-type": "overlay: tunnel-type-vxlan-gpe",
+ "node-connector-id": "openflow:1:1",
+ "ip": "_CLASSIFIER1",
+ "port": 6633
+ },
+ {
+ "tunnel-type": "overlay: tunnel-type-vxlan",
+ "node-connector-id": "openflow:1:2",
+ "ip": "_CLASSIFIER1",
+ "port": 4789
+ }
+ ]
+ },
+ {
+ "id": "openflow:2",
+ "ofoverlay:tunnel": [
+ {
+ "tunnel-type": "overlay: tunnel-type-vxlan-gpe",
+ "node-connector-id": "openflow:2:1",
+ "ip": "_CLASSIFIER2",
+ "port": 6633
+ },
+ {
+ "tunnel-type": "overlay: tunnel-type-vxlan",
+ "node-connector-id": "openflow:2:2",
+ "ip": "_CLASSIFIER2",
+ "port": 4789
+ }
+ ]
+ },
+ {
+ "id": "openflow:3",
+ "ofoverlay:tunnel": [
+ {
+ "tunnel-type": "overlay: tunnel-type-vxlan-gpe",
+ "node-connector-id": "openflow:3:1",
+ "ip": "_CLASSIFIER3",
+ "port": 6633
+ },
+ {
+ "tunnel-type": "overlay: tunnel-type-vxlan",
+ "node-connector-id": "openflow:3:2",
+ "ip": "_CLASSIFIER3",
+ "port": 4789
+ }
+ ]
+ }
+ ]
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "input": {
+ "endpoint-group": "1eaf9a67-a171-42a8-9282-71cf702f61dd",
+ "network-containment": "d2779562-ebf1-45e6-93a4-78e2362bc418",
+ "l2-context": "7b796915-adf4-4356-b5ca-de005ac410c1",
+ "mac-address": "00:00:00:00:35:02",
+ "l3-address": [
+ {
+ "ip-address": "10.0.35.2",
+ "l3-context": "cbe0cc07-b8ff-451d-8171-9eef002a8e80"
+ }
+ ],
+ "port-name": "vethl-h35_2",
+ "tenant": "f5c7d344-d1c7-4208-8531-2c2693657e12"
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "input": {
+ "endpoint-group": "1eaf9a67-a171-42a8-9282-71cf702f61dd",
+ "network-containment": "d2779562-ebf1-45e6-93a4-78e2362bc418",
+ "l2-context": "7b796915-adf4-4356-b5ca-de005ac410c1",
+ "mac-address": "00:00:00:00:35:03",
+ "l3-address": [
+ {
+ "ip-address": "10.0.35.3",
+ "l3-context": "cbe0cc07-b8ff-451d-8171-9eef002a8e80"
+ }
+ ],
+ "port-name": "vethl-h35_3",
+ "tenant": "f5c7d344-d1c7-4208-8531-2c2693657e12"
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "input": {
+ "endpoint-group": "1eaf9a67-a171-42a8-9282-71cf702f61dd",
+ "network-containment": "d2779562-ebf1-45e6-93a4-78e2362bc418",
+ "l2-context": "7b796915-adf4-4356-b5ca-de005ac410c1",
+ "mac-address": "00:00:00:00:35:04",
+ "l3-address": [
+ {
+ "ip-address": "10.0.35.4",
+ "l3-context": "cbe0cc07-b8ff-451d-8171-9eef002a8e80"
+ }
+ ],
+ "port-name": "vethl-h35_4",
+ "tenant": "f5c7d344-d1c7-4208-8531-2c2693657e12"
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "input": {
+ "endpoint-group": "1eaf9a67-a171-42a8-9282-71cf702f61dd",
+ "network-containment": "d2779562-ebf1-45e6-93a4-78e2362bc418",
+ "l2-context": "7b796915-adf4-4356-b5ca-de005ac410c1",
+ "mac-address": "00:00:00:00:35:05",
+ "l3-address": [
+ {
+ "ip-address": "10.0.35.5",
+ "l3-context": "cbe0cc07-b8ff-451d-8171-9eef002a8e80"
+ }
+ ],
+ "port-name": "vethl-h35_5",
+ "tenant": "f5c7d344-d1c7-4208-8531-2c2693657e12"
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "input": {
+ "endpoint-group": "1eaf9a67-a171-42a8-9282-71cf702f61dd",
+ "network-containment": "e2779562-ebf1-45e6-93a4-78e2362bc418",
+ "l2-context": "7b796915-adf4-4356-b5ca-de005ac410c1",
+ "mac-address": "00:00:00:00:35:06",
+ "l3-address": [
+ {
+ "ip-address": "10.0.35.6",
+ "l3-context": "cbe0cc07-b8ff-451d-8171-9eef002a8e80"
+ }
+ ],
+ "port-name": "vethl-h35_6",
+ "tenant": "25c7d344-d1c7-4208-8531-2c2693657e12"
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "input": {
+ "endpoint-group": "1eaf9a67-a171-42a8-9282-71cf702f61dd",
+ "network-containment": "e2779562-ebf1-45e6-93a4-78e2362bc418",
+ "l2-context": "7b796915-adf4-4356-b5ca-de005ac410c1",
+ "mac-address": "00:00:00:00:35:07",
+ "l3-address": [
+ {
+ "ip-address": "10.0.35.7",
+ "l3-context": "cbe0cc07-b8ff-451d-8171-9eef002a8e80"
+ }
+ ],
+ "port-name": "vethl-h35_7",
+ "tenant": "25c7d344-d1c7-4208-8531-2c2693657e12"
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "input": {
+ "endpoint-group": "1eaf9a67-a171-42a8-9282-71cf702f61dd",
+ "network-containment": "e2779562-ebf1-45e6-93a4-78e2362bc418",
+ "l2-context": "7b796915-adf4-4356-b5ca-de005ac410c1",
+ "mac-address": "00:00:00:00:35:08",
+ "l3-address": [
+ {
+ "ip-address": "10.0.35.8",
+ "l3-context": "cbe0cc07-b8ff-451d-8171-9eef002a8e80"
+ }
+ ],
+ "port-name": "vethl-h35_8",
+ "tenant": "25c7d344-d1c7-4208-8531-2c2693657e12"
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "input": {
+ "endpoint-group": "1eaf9a67-a171-42a8-9282-71cf702f61dd",
+ "network-containment": "e2779562-ebf1-45e6-93a4-78e2362bc418",
+ "l2-context": "7b796915-adf4-4356-b5ca-de005ac410c1",
+ "mac-address": "00:00:00:00:35:09",
+ "l3-address": [
+ {
+ "ip-address": "10.0.35.9",
+ "l3-context": "cbe0cc07-b8ff-451d-8171-9eef002a8e80"
+ }
+ ],
+ "port-name": "vethl-h35_9",
+ "tenant": "25c7d344-d1c7-4208-8531-2c2693657e12"
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "input": {
+ "endpoint-group": "e593f05d-96be-47ad-acd5-ba81465680d5",
+ "network-containment": "2c71d675-693e-406f-899f-12a026eb55f1",
+ "l2-context": "7b796915-adf4-4356-b5ca-de005ac410c1",
+ "mac-address": "00:00:00:00:36:02",
+ "l3-address": [
+ {
+ "ip-address": "10.0.36.2",
+ "l3-context": "cbe0cc07-b8ff-451d-8171-9eef002a8e80"
+ }
+ ],
+ "port-name": "vethl-h36_2",
+ "tenant": "f5c7d344-d1c7-4208-8531-2c2693657e12"
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "input": {
+ "endpoint-group": "e593f05d-96be-47ad-acd5-ba81465680d5",
+ "network-containment": "2c71d675-693e-406f-899f-12a026eb55f1",
+ "l2-context": "7b796915-adf4-4356-b5ca-de005ac410c1",
+ "mac-address": "00:00:00:00:36:03",
+ "l3-address": [
+ {
+ "ip-address": "10.0.36.3",
+ "l3-context": "cbe0cc07-b8ff-451d-8171-9eef002a8e80"
+ }
+ ],
+ "port-name": "vethl-h36_3",
+ "tenant": "f5c7d344-d1c7-4208-8531-2c2693657e12"
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "input": {
+ "endpoint-group": "e593f05d-96be-47ad-acd5-ba81465680d5",
+ "network-containment": "2c71d675-693e-406f-899f-12a026eb55f1",
+ "l2-context": "7b796915-adf4-4356-b5ca-de005ac410c1",
+ "mac-address": "00:00:00:00:36:04",
+ "l3-address": [
+ {
+ "ip-address": "10.0.36.4",
+ "l3-context": "cbe0cc07-b8ff-451d-8171-9eef002a8e80"
+ }
+ ],
+ "port-name": "vethl-h36_4",
+ "tenant": "f5c7d344-d1c7-4208-8531-2c2693657e12"
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "input": {
+ "endpoint-group": "e593f05d-96be-47ad-acd5-ba81465680d5",
+ "network-containment": "2c71d675-693e-406f-899f-12a026eb55f1",
+ "l2-context": "7b796915-adf4-4356-b5ca-de005ac410c1",
+ "mac-address": "00:00:00:00:36:05",
+ "l3-address": [
+ {
+ "ip-address": "10.0.36.5",
+ "l3-context": "cbe0cc07-b8ff-451d-8171-9eef002a8e80"
+ }
+ ],
+ "port-name": "vethl-h36_5",
+ "tenant": "f5c7d344-d1c7-4208-8531-2c2693657e12"
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "input": {
+ "endpoint-group": "e593f05d-96be-47ad-acd5-ba81465680d5",
+ "network-containment": "3c71d675-693e-406f-899f-12a026eb55f1",
+ "l2-context": "7b796915-adf4-4356-b5ca-de005ac410c1",
+ "mac-address": "00:00:00:00:36:06",
+ "l3-address": [
+ {
+ "ip-address": "10.0.36.6",
+ "l3-context": "cbe0cc07-b8ff-451d-8171-9eef002a8e80"
+ }
+ ],
+ "port-name": "vethl-h36_6",
+ "tenant": "25c7d344-d1c7-4208-8531-2c2693657e12"
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "input": {
+ "endpoint-group": "e593f05d-96be-47ad-acd5-ba81465680d5",
+ "network-containment": "3c71d675-693e-406f-899f-12a026eb55f1",
+ "l2-context": "7b796915-adf4-4356-b5ca-de005ac410c1",
+ "mac-address": "00:00:00:00:36:07",
+ "l3-address": [
+ {
+ "ip-address": "10.0.36.7",
+ "l3-context": "cbe0cc07-b8ff-451d-8171-9eef002a8e80"
+ }
+ ],
+ "port-name": "vethl-h36_7",
+ "tenant": "25c7d344-d1c7-4208-8531-2c2693657e12"
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "input": {
+ "endpoint-group": "e593f05d-96be-47ad-acd5-ba81465680d5",
+ "network-containment": "3c71d675-693e-406f-899f-12a026eb55f1",
+ "l2-context": "7b796915-adf4-4356-b5ca-de005ac410c1",
+ "mac-address": "00:00:00:00:36:08",
+ "l3-address": [
+ {
+ "ip-address": "10.0.36.8",
+ "l3-context": "cbe0cc07-b8ff-451d-8171-9eef002a8e80"
+ }
+ ],
+ "port-name": "vethl-h36_8",
+ "tenant": "25c7d344-d1c7-4208-8531-2c2693657e12"
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "input": {
+ "endpoint-group": "e593f05d-96be-47ad-acd5-ba81465680d5",
+ "network-containment": "3c71d675-693e-406f-899f-12a026eb55f1",
+ "l2-context": "7b796915-adf4-4356-b5ca-de005ac410c1",
+ "mac-address": "00:00:00:00:36:09",
+ "l3-address": [
+ {
+ "ip-address": "10.0.36.9",
+ "l3-context": "cbe0cc07-b8ff-451d-8171-9eef002a8e80"
+ }
+ ],
+ "port-name": "vethl-h36_9",
+ "tenant": "25c7d344-d1c7-4208-8531-2c2693657e12"
+ }
+}
\ No newline at end of file