added demos to the repo 19/30919/1
authorMartin Sunal <msunal@cisco.com>
Mon, 7 Dec 2015 17:10:46 +0000 (18:10 +0100)
committerMartin Sunal <msunal@cisco.com>
Mon, 7 Dec 2015 17:10:46 +0000 (18:10 +0100)
Signed-off-by: Martin Sunal <msunal@cisco.com>
74 files changed:
demos/gbp-devstack/LICENSE [new file with mode: 0644]
demos/gbp-devstack/README.rst [new file with mode: 0644]
demos/gbp-devstack/Vagrantfile [new file with mode: 0644]
demos/gbp-devstack/devstack-scripts/console.sh [new file with mode: 0644]
demos/gbp-devstack/devstack-scripts/environment [new file with mode: 0644]
demos/gbp-devstack/devstack-scripts/flowcount.sh [new file with mode: 0644]
demos/gbp-devstack/devstack-scripts/hostdump.sh [new file with mode: 0644]
demos/gbp-devstack/devstack-scripts/killrabbit.sh [new file with mode: 0644]
demos/gbp-devstack/devstack-scripts/kssh.sh [new file with mode: 0644]
demos/gbp-devstack/devstack-scripts/ndump.sh [new file with mode: 0644]
demos/gbp-devstack/devstack-scripts/novaboot-compute.sh [new file with mode: 0644]
demos/gbp-devstack/devstack-scripts/novaboot-control.sh [new file with mode: 0644]
demos/gbp-devstack/devstack-scripts/novaboot.sh [new file with mode: 0644]
demos/gbp-devstack/devstack-scripts/ovsshow.sh [new file with mode: 0644]
demos/gbp-devstack/devstack-scripts/packetCount.sh [new file with mode: 0644]
demos/gbp-devstack/devstack-scripts/pollflows.sh [new file with mode: 0644]
demos/gbp-devstack/devstack-scripts/resetcontroller.sh [new file with mode: 0644]
demos/gbp-devstack/devstack-scripts/resetmanager.sh [new file with mode: 0644]
demos/gbp-devstack/devstack-scripts/restack.sh [new file with mode: 0644]
demos/gbp-devstack/devstack-scripts/tests/testbasicIP-multirouter1.sh [new file with mode: 0644]
demos/gbp-devstack/devstack-scripts/tests/testfloatingip.sh [new file with mode: 0644]
demos/gbp-devstack/devstack-scripts/tests/testmtnet.sh [new file with mode: 0644]
demos/gbp-devstack/devstack-scripts/tutorial/exampleSecurityGroups.sh [new file with mode: 0644]
demos/gbp-devstack/devstack-scripts/tutorial/multirouter1.sh [new file with mode: 0644]
demos/gbp-devstack/devstack-scripts/tutorial/step01.sh [new file with mode: 0644]
demos/gbp-devstack/devstack-scripts/tutorial/step02.sh [new file with mode: 0644]
demos/gbp-devstack/devstack-scripts/tutorial/step03.sh [new file with mode: 0644]
demos/gbp-devstack/devstack-scripts/tutorial/step04.sh [new file with mode: 0644]
demos/gbp-devstack/devstack-scripts/unstack.sh [new file with mode: 0644]
demos/gbp-devstack/puppet/hiera.yaml [new file with mode: 0644]
demos/gbp-devstack/puppet/hieradata/hosts.json [new file with mode: 0644]
demos/gbp-devstack/puppet/manifests/base.pp [new file with mode: 0644]
demos/gbp-devstack/puppet/manifests/devstack-compute.pp [new file with mode: 0644]
demos/gbp-devstack/puppet/manifests/devstack-control.pp [new file with mode: 0644]
demos/gbp-devstack/puppet/scripts/bootstrap.sh [new file with mode: 0644]
demos/gbp-devstack/puppet/scripts/clear_ovs.sh [new file with mode: 0644]
demos/gbp-devstack/puppet/templates/compute.local.conf.erb [new file with mode: 0644]
demos/gbp-devstack/puppet/templates/control.local.conf.erb [new file with mode: 0644]
demos/gbp-devstack/puppet/templates/hosts.erb [new file with mode: 0644]
demos/gbp-devstack/wscontrol.sh [new file with mode: 0644]
demos/gbpsfc-env/README.md [new file with mode: 0644]
demos/gbpsfc-env/Vagrantfile [new file with mode: 0644]
demos/gbpsfc-env/bootstrap.sh [new file with mode: 0644]
demos/gbpsfc-env/checkdemo.sh [new file with mode: 0644]
demos/gbpsfc-env/cleandemo.sh [new file with mode: 0644]
demos/gbpsfc-env/demo-asymmetric-chain/get-nsps.py [new file with mode: 0644]
demos/gbpsfc-env/demo-asymmetric-chain/infrastructure_config.py [new file with mode: 0644]
demos/gbpsfc-env/demo-asymmetric-chain/rest.py [new file with mode: 0644]
demos/gbpsfc-env/demo-asymmetric-chain/sf-config.sh [new file with mode: 0644]
demos/gbpsfc-env/demo-gbp1/get-nsps.py [new file with mode: 0644]
demos/gbpsfc-env/demo-gbp1/infrastructure_config.py [new file with mode: 0644]
demos/gbpsfc-env/demo-gbp1/rest.py [new file with mode: 0644]
demos/gbpsfc-env/demo-symmetric-chain/get-nsps.py [new file with mode: 0644]
demos/gbpsfc-env/demo-symmetric-chain/infrastructure_config.py [new file with mode: 0644]
demos/gbpsfc-env/demo-symmetric-chain/rest.py [new file with mode: 0644]
demos/gbpsfc-env/demo-symmetric-chain/sf-config.sh [new file with mode: 0644]
demos/gbpsfc-env/dpdumpflows.py [new file with mode: 0644]
demos/gbpsfc-env/dumpflows.sh [new file with mode: 0644]
demos/gbpsfc-env/env.sh [new file with mode: 0644]
demos/gbpsfc-env/flowcount.sh [new file with mode: 0644]
demos/gbpsfc-env/infrastructure_launch.py [new file with mode: 0644]
demos/gbpsfc-env/ovsinstall.sh [new file with mode: 0644]
demos/gbpsfc-env/ovswork.sh [new file with mode: 0644]
demos/gbpsfc-env/pollflows.sh [new file with mode: 0644]
demos/gbpsfc-env/resetcontroller.sh [new file with mode: 0644]
demos/gbpsfc-env/rest-clean.py [new file with mode: 0644]
demos/gbpsfc-env/sf-config.sh [new file with mode: 0644]
demos/gbpsfc-env/startdemo.sh [new file with mode: 0644]
demos/gbpsfc-env/traceflow.sh [new file with mode: 0644]
demos/gbpsfc-env/utils/hosts [new file with mode: 0644]
demos/gbpsfc-env/utils/setuphosts.sh [new file with mode: 0644]
demos/gbpsfc-env/utils/sf-config.sh [new file with mode: 0644]
demos/gbpsfc-env/utils/sf-flows.sh [new file with mode: 0644]
demos/gbpsfc-env/vmclean.sh [new file with mode: 0644]

diff --git a/demos/gbp-devstack/LICENSE b/demos/gbp-devstack/LICENSE
new file mode 100644 (file)
index 0000000..3d967ae
--- /dev/null
@@ -0,0 +1,70 @@
+Eclipse Public License - v 1.0
+
+THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
+
+1. DEFINITIONS
+
+"Contribution" means:
+
+a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and
+b) in the case of each subsequent Contributor:
+i) changes to the Program, and
+ii) additions to the Program;
+where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program.
+"Contributor" means any person or entity that distributes the Program.
+
+"Licensed Patents" mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program.
+
+"Program" means the Contributions distributed in accordance with this Agreement.
+
+"Recipient" means anyone who receives the Program under this Agreement, including all Contributors.
+
+2. GRANT OF RIGHTS
+
+a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form.
+b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder.
+c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program.
+d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement.
+3. REQUIREMENTS
+
+A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that:
+
+a) it complies with the terms and conditions of this Agreement; and
+b) its license agreement:
+i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose;
+ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits;
+iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and
+iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange.
+When the Program is made available in source code form:
+
+a) it must be made available under this Agreement; and
+b) a copy of this Agreement must be included with each copy of the Program.
+Contributors may not remove or alter any copyright notices contained within the Program.
+
+Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution.
+
+4. COMMERCIAL DISTRIBUTION
+
+Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense.
+
+For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages.
+
+5. NO WARRANTY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement , including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations.
+
+6. DISCLAIMER OF LIABILITY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+7. GENERAL
+
+If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
+
+If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed.
+
+All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive.
+
+Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved.
+
+This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation.
\ No newline at end of file
diff --git a/demos/gbp-devstack/README.rst b/demos/gbp-devstack/README.rst
new file mode 100644 (file)
index 0000000..1f06b47
--- /dev/null
@@ -0,0 +1,109 @@
+devstack-nodes
+==============
+
+This repo provides a Vagrantfile with provisioning that one can use to easily
+get a cluster of nodes configured with DevStack.
+
+It is a fork of the wonderful work of Mr Flavio Fernandes
+
+Usage
+-----
+
+1) Run VMs::
+    
+A Vagrantfile is provided to easily create a DevStack environment to test with. To save
+performance, it is sufficient to run all the required services just on one VM. This VM
+is identified as control node. Other VMs are compute nodes. First, set number of compute
+nodes desired by setting::
+   'DEVSTACK_NUM_COMPUTE_NODES=1'
+    
+Note: Only 3 or less nodes are supported today.
+
+
+Next, execute::
+
+    vagrant up
+    
+If no VMs have been generated yet, they will be now.
+
+
+    
+2) Start devstack::
+
+    vagrant ssh [devstack-control|devstack-compute-1]
+
+    cd devstack
+    
+To make devstack-scripts visible::
+
+    sudo cp /vagrant/devstack-scripts/environment /etc/environment
+
+    source /etc/environment
+
+    sudo ovs-vsctl add-br br-int
+
+    ^ one time only.
+
+   
+This assumes that ODL is 192.168.50.1. If you need to change this, edit /etc/environment,
+change the 'export ODL=' to the right IP address, save, exit, and repeat source command above.
+After stacking for the first time, edit local.conf and:
+       
+uncomment: 'OFFLINE=True'
+
+comment out: 'RECLONE=yes'
+
+To stack safely, from $HOME/devstack directory on all the nodes execute::
+
+    restack.sh
+
+   
+Note: NOT ./restack.sh ... just restack.sh ... its in the PATH.
+To verify from control node if all the nodes are stacked successfully::
+
+    source openrc admin admin
+
+    nova hypervisor-list
+
+
+Testing
+-----
+
+1) Check the ovs bridges first::
+
+    sudo ovs-vsctl show
+
+
+2) Run scripts from ~/devstack/ directory. These scripts are in the path. If you need to modify them,
+   they are in /vagrant/devstack-scripts/tutorial::
+
+    step01.sh: client node on devstack-control, web node on devstack-compute-1
+
+    step02.sh
+
+    step03.sh
+
+
+(videos and documentation coming soon).
+
+
+3. Useful commands to verify::
+
+    flowcount.sh br-int : gives per table flow counts
+
+    flowcount.sh br-int <table#> : dumps flows from <table> in priority order
+
+
+4. You can point your browser at::
+  
+    Horizon: 192.168.50.20 (u: admin, p:admin).
+
+    This assumes you are familiar with Horizon. Ensure you look at the admin project.
+
+    ODL GBP GUI: 192.168.50.1:8181/index.html (u: admin, p: admin).
+
+    See GBP UserGuide for more information on using the GUI in Stable/Lithium.
+
+
diff --git a/demos/gbp-devstack/Vagrantfile b/demos/gbp-devstack/Vagrantfile
new file mode 100644 (file)
index 0000000..b2b6551
--- /dev/null
@@ -0,0 +1,70 @@
+# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
+VAGRANTFILE_API_VERSION = "2"
+
+Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
+
+  config.vm.provision "shell", path: "puppet/scripts/bootstrap.sh"
+  config.ssh.forward_agent = true
+  config.ssh.forward_x11 = true
+  num_compute_nodes = (ENV['DEVSTACK_NUM_COMPUTE_NODES'] || 1).to_i
+
+  # ip configuration
+  control_ip = "192.168.50.20"
+  compute_ip_base = "192.168.50."
+  neutron_ex_ip = "192.168.111.11"
+  compute_ips = num_compute_nodes.times.collect { |n| compute_ip_base + "#{n+21}" }
+
+  config.vm.provision "puppet" do |puppet|
+      puppet.hiera_config_path = "puppet/hiera.yaml"
+      puppet.working_directory = "/vagrant/puppet"
+      puppet.manifests_path = "puppet/manifests"
+      puppet.manifest_file  = "base.pp"
+  end
+
+  # Devstack Controller6
+  config.vm.define "devstack-control", primary: true do |control|
+    control.vm.box = "ubuntu/trusty64"
+    control.vm.hostname = "devstack-control"
+    control.vm.network "private_network", ip: "#{control_ip}"
+    control.vm.network "private_network", ip: "#{neutron_ex_ip}", virtualbox__intnet: "mylocalnet" 
+    control.vm.provider :virtualbox do |vb|
+      vb.memory = 4096
+    end
+    control.vm.provider "vmware_fusion" do |vf|
+      vf.vmx["memsize"] = "4096"
+    end
+    control.vm.provision "puppet" do |puppet|
+      puppet.hiera_config_path = "puppet/hiera.yaml"
+      puppet.working_directory = "/vagrant/puppet"
+      puppet.manifests_path = "puppet/manifests"
+      puppet.manifest_file  = "devstack-control.pp"
+    end
+  end
+
+  # Devstack Compute Nodes
+  num_compute_nodes.times do |n|
+    config.vm.define "devstack-compute-#{n+1}", autostart: true do |compute|
+      compute_ip = compute_ips[n]
+      compute_index = n+1
+      compute.vm.box = "ubuntu/trusty64"
+      compute.vm.provider "vmware_fusion" do |v, override|
+      end
+      compute.vm.hostname = "devstack-compute-#{compute_index}"
+      compute.vm.network "private_network", ip: "#{compute_ip}"
+      compute.vm.network "private_network", ip: "192.168.111.12", virtualbox__intnet: "mylocalnet"
+      compute.vm.provider :virtualbox do |vb|
+        vb.memory = 4096
+      end
+      compute.vm.provider "vmware_fusion" do |vf|
+        vf.vmx["memsize"] = "4096"
+      end
+      compute.vm.provision "puppet" do |puppet|
+        puppet.hiera_config_path = "puppet/hiera.yaml"
+        puppet.working_directory = "/vagrant/puppet"
+        puppet.manifests_path = "puppet/manifests"
+        puppet.manifest_file  = "devstack-compute.pp"
+      end
+    end
+  end
+
+end
diff --git a/demos/gbp-devstack/devstack-scripts/console.sh b/demos/gbp-devstack/devstack-scripts/console.sh
new file mode 100644 (file)
index 0000000..1841ebd
--- /dev/null
@@ -0,0 +1 @@
+nova get-vnc-console $1  novnc
diff --git a/demos/gbp-devstack/devstack-scripts/environment b/demos/gbp-devstack/devstack-scripts/environment
new file mode 100644 (file)
index 0000000..407eea0
--- /dev/null
@@ -0,0 +1,2 @@
+PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/vagrant/devstack-scripts:/vagrant/devstack-scripts/tutorial"
+export ODL=192.168.50.1
diff --git a/demos/gbp-devstack/devstack-scripts/flowcount.sh b/demos/gbp-devstack/devstack-scripts/flowcount.sh
new file mode 100644 (file)
index 0000000..be4d550
--- /dev/null
@@ -0,0 +1,26 @@
+[ "$1" ] || {
+    echo "Syntax:"
+    echo "flowCount <bridge> [table#]"
+    echo "Usage: flowCount <bridge>: shows flow count for entire switch."
+    echo "Usage: flowcount <bridge> <table#>: shows groups for switch and flows and flow count for particular table."
+    exit 1
+}
+
+if [ "$2" ]
+then
+       clear 
+        echo "GROUPS:";sudo ovs-ofctl dump-groups $1 -OOpenFlow13; echo;echo "FLOWS:";sudo ovs-ofctl dump-flows $1 -OOpenFlow13 table=$2 --rsort=priority
+       echo
+       printf "Flow count: "
+       sudo ovs-ofctl dump-flows $1 -OOpenFlow13 table=$2 | wc -l
+else
+        clear
+        printf "No table entered. $1 flow count: "
+        sudo ovs-ofctl dump-flows $1 -OOpenFlow13 | wc -l
+       #echo "Expected single-node: 54 double-node: 62"
+       printf "\nTable0: "; sudo ovs-ofctl dump-flows $1 -OOpenFlow13 table=0| wc -l
+        printf "\nTable1: "; sudo ovs-ofctl dump-flows $1 -OOpenFlow13 table=1| wc -l
+        printf "\nTable2: "; sudo ovs-ofctl dump-flows $1 -OOpenFlow13 table=2| wc -l
+        printf "\nTable3: "; sudo ovs-ofctl dump-flows $1 -OOpenFlow13 table=3| wc -l
+fi
+
diff --git a/demos/gbp-devstack/devstack-scripts/hostdump.sh b/demos/gbp-devstack/devstack-scripts/hostdump.sh
new file mode 100644 (file)
index 0000000..31ed392
--- /dev/null
@@ -0,0 +1,5 @@
+echo "Nova instances on compute1:"
+nova list --host devstack-compute-1
+echo "Nova instances on control:"
+nova list --host devstack-control
+
diff --git a/demos/gbp-devstack/devstack-scripts/killrabbit.sh b/demos/gbp-devstack/devstack-scripts/killrabbit.sh
new file mode 100644 (file)
index 0000000..f153d11
--- /dev/null
@@ -0,0 +1 @@
+sudo kill -9 `ps -ef | grep rabbit | grep -v grep | awk '{print $2}'`
diff --git a/demos/gbp-devstack/devstack-scripts/kssh.sh b/demos/gbp-devstack/devstack-scripts/kssh.sh
new file mode 100644 (file)
index 0000000..f5f248b
--- /dev/null
@@ -0,0 +1,10 @@
+#!/bin/sh
+ip=$1
+nnet=`neutron net-list`
+nlist=`nova list`
+uuid=`echo "$nnet" | grep $(echo "$nlist" | grep $ip | awk '{print $12}' | awk 'BEGIN {FS="="} {print $1}') | awk '{print $2}'`
+cmd="ip netns exec qdhcp-$uuid rm -rf /root/.ssh/known_hosts"
+sudo $cmd
+cmd="ip netns exec qdhcp-$uuid ssh cirros@$ip"
+sudo $cmd
+
diff --git a/demos/gbp-devstack/devstack-scripts/ndump.sh b/demos/gbp-devstack/devstack-scripts/ndump.sh
new file mode 100644 (file)
index 0000000..af3840d
--- /dev/null
@@ -0,0 +1,17 @@
+source openrc admin admin
+echo "Hypervisors:"
+nova hypervisor-list
+echo "Networks:"
+neutron net-list
+echo "Subnets: "
+neutron subnet-list
+echo "Ports: "
+neutron port-list
+echo "Security grous:"
+neutron security-group-list
+echo "Routers and router ports: "
+neutron router-list
+echo "Nova instances on compute1:"
+nova list --host devstack-compute-1
+echo "Nova instances on control:"
+nova list --host devstack-control
diff --git a/demos/gbp-devstack/devstack-scripts/novaboot-compute.sh b/demos/gbp-devstack/devstack-scripts/novaboot-compute.sh
new file mode 100644 (file)
index 0000000..96e4dc2
--- /dev/null
@@ -0,0 +1,23 @@
+NETWORK=$1
+SEC_GRP=$2
+VM=$3
+IMAGE=$4
+FLAVOR=$5
+
+if [ $# -eq 0 ]
+  then
+    echo "Usage: novaboot.sh {network} {security-group-name} {vm#} {image} {flavor}
+       ie. novaboot.sh net1 client_sg 3 lubuntu|cirros-0.3.2-x86_64-uec 6"
+    exit
+fi
+
+: ${VM:=1}
+: ${IMAGE:=cirros-0.3.4-x86_64-uec}
+: ${FLAVOR:=1}
+
+IMAGE_ID=`nova image-list | egrep $IMAGE | awk '{print $2}'`
+set -- $IMAGE_ID
+IMAGE_ID=$1
+PORT_ID=`neutron port-create $NETWORK --security-group $SEC_GRP | egrep "\sid\s" | awk '{print $4}'`
+nova boot --image $IMAGE_ID --flavor $FLAVOR --nic port-id=$PORT_ID --security-groups $SEC_GRP "$NETWORK-$SEC_GRP-$VM" --availability-zone nova:devstack-compute-1
+
diff --git a/demos/gbp-devstack/devstack-scripts/novaboot-control.sh b/demos/gbp-devstack/devstack-scripts/novaboot-control.sh
new file mode 100644 (file)
index 0000000..e99040d
--- /dev/null
@@ -0,0 +1,23 @@
+NETWORK=$1
+SEC_GRP=$2
+VM=$3
+IMAGE=$4
+FLAVOR=$5
+
+if [ $# -eq 0 ]
+  then
+    echo "Usage: novaboot.sh {network} {security-group-name} {vm#} {image} {flavor}
+       ie. novaboot.sh net1 client_sg 3 lubuntu|cirros-0.3.2-x86_64-uec 6"
+    exit
+fi
+
+: ${VM:=1}
+: ${IMAGE:=cirros-0.3.4-x86_64-uec}
+: ${FLAVOR:=1}
+
+IMAGE_ID=`nova image-list | egrep $IMAGE | awk '{print $2}'`
+set -- $IMAGE_ID
+IMAGE_ID=$1
+PORT_ID=`neutron port-create $NETWORK --security-group $SEC_GRP | egrep "\sid\s" | awk '{print $4}'`
+nova boot --image $IMAGE_ID --flavor $FLAVOR --nic port-id=$PORT_ID --security-groups $SEC_GRP "$NETWORK-$SEC_GRP-$VM" --availability-zone nova:devstack-control
+
diff --git a/demos/gbp-devstack/devstack-scripts/novaboot.sh b/demos/gbp-devstack/devstack-scripts/novaboot.sh
new file mode 100644 (file)
index 0000000..50d8552
--- /dev/null
@@ -0,0 +1,27 @@
+NETWORK=$1
+SEC_GRP=$2
+VM=$3
+IMAGE=$4
+FLAVOR=$5
+
+if [ $# -eq 0 ]
+  then
+    echo "Usage: novaboot.sh {network} {security-group-name} {vm#} {image}.
+       ie. novaboot.sh net1 client_sg 3 lubuntu|cirros-0.3.2-x86_64-uec"
+    exit
+fi
+
+: ${VM:=1}
+: ${IMAGE:=cirros-0.3.4-x86_64-uec}
+
+
+IMAGE_ID=`nova image-list | egrep $IMAGE | awk '{print $2}'`
+set -- $IMAGE_ID
+IMAGE_ID=$1
+PORT_ID=`neutron port-create $NETWORK --security-group $SEC_GRP | egrep "\sid\s" | awk '{print $4}'`
+#echo "image ",$IMAGE_ID
+#echo "flavor ", $FLAVOR
+#echo "port ",$PORT_ID
+#echo "name ", $SECGRP, $VM
+nova boot --image $IMAGE_ID --flavor $FLAVOR --nic port-id=$PORT_ID "$NETWORK-$SEC_GRP-$VM" 
+
diff --git a/demos/gbp-devstack/devstack-scripts/ovsshow.sh b/demos/gbp-devstack/devstack-scripts/ovsshow.sh
new file mode 100644 (file)
index 0000000..5e562fe
--- /dev/null
@@ -0,0 +1,2 @@
+sudo ovs-vsctl show
+
diff --git a/demos/gbp-devstack/devstack-scripts/packetCount.sh b/demos/gbp-devstack/devstack-scripts/packetCount.sh
new file mode 100644 (file)
index 0000000..bf60e4c
--- /dev/null
@@ -0,0 +1 @@
+watch -n 1 -d "sudo ovs-ofctl dump-flows br-int -OOpenFlow13 | grep -v n_packets=0"
diff --git a/demos/gbp-devstack/devstack-scripts/pollflows.sh b/demos/gbp-devstack/devstack-scripts/pollflows.sh
new file mode 100644 (file)
index 0000000..3020edd
--- /dev/null
@@ -0,0 +1,3 @@
+SWITCH=$1
+TABLE=$2
+watch -n 1 -d "flowcount.sh $1 $2"
diff --git a/demos/gbp-devstack/devstack-scripts/resetcontroller.sh b/demos/gbp-devstack/devstack-scripts/resetcontroller.sh
new file mode 100644 (file)
index 0000000..2b471c5
--- /dev/null
@@ -0,0 +1,4 @@
+sudo ovs-vsctl del-controller br-int
+sleep 6
+sudo ovs-vsctl set-controller br-int tcp:$ODL:6653
+
diff --git a/demos/gbp-devstack/devstack-scripts/resetmanager.sh b/demos/gbp-devstack/devstack-scripts/resetmanager.sh
new file mode 100644 (file)
index 0000000..3418820
--- /dev/null
@@ -0,0 +1,4 @@
+sudo ovs-vsctl del-manager
+sleep 6
+sudo ovs-vsctl set-manager tcp:$ODL:6640
+
diff --git a/demos/gbp-devstack/devstack-scripts/restack.sh b/demos/gbp-devstack/devstack-scripts/restack.sh
new file mode 100644 (file)
index 0000000..cc77330
--- /dev/null
@@ -0,0 +1,16 @@
+./unstack.sh --all
+
+ sudo service rabbitmq-server restart
+ sudo service mysql restart
+
+sudo ovs-vsctl set-manager tcp:192.168.50.1:6640
+sudo ovs-vsctl add-br br-int
+sudo ovs-vsctl set-controller tcp:192.168.50.1:6653
+
+echo "Removing all logs to save space..."
+sudo rm -rf /opt/stack/logs/*
+sudo rm -rf /home/vagrant/stack.sh.log.*
+
+time ./stack.sh
+echo "Finished stacking at: "; date
+
diff --git a/demos/gbp-devstack/devstack-scripts/tests/testbasicIP-multirouter1.sh b/demos/gbp-devstack/devstack-scripts/tests/testbasicIP-multirouter1.sh
new file mode 100644 (file)
index 0000000..300625c
--- /dev/null
@@ -0,0 +1,62 @@
+source openrc coke coke
+neutron security-group-create client_sg
+neutron security-group-rule-create client_sg --direction egress --ethertype IPv4
+neutron security-group-rule-create client_sg --direction ingress --ethertype IPv4
+
+neutron security-group-create video_sg
+neutron security-group-rule-create video_sg --direction egress --ethertype IPv4
+neutron security-group-rule-create video_sg --direction ingress --ethertype IPv4
+
+neutron security-group-create game_sg
+neutron security-group-rule-create game_sg --direction egress --ethertype IPv4
+neutron security-group-rule-create game_sg --direction ingress --ethertype IPv4
+
+
+neutron net-create net1
+neutron subnet-create net1 10.1.1.0/24 --name sub1 --gateway 10.1.1.1
+neutron net-create net2
+neutron subnet-create net2 20.1.1.0/24 --name sub2 --gateway 20.1.1.1
+#neutron net-create net3
+#neutron subnet-create net3 30.1.1.0/24 --name sub3 --gateway 30.1.1.1
+#neutron net-create net4
+#neutron subnet-create net4 40.1.1.0/24 --name sub4 --gateway 40.1.1.1
+#neutron net-create net5
+#neutron subnet-create net5 50.1.1.0/24 --name sub5 --gateway 50.1.1.1
+
+neutron router-create r1
+neutron router-interface-add r1 sub1
+neutron router-interface-add r1 sub2
+
+
+testnovaboot-control.sh net1 client_sg 1 #"bekind" 
+testnovaboot-compute.sh net2 client_sg 2
+
+
+testnovaboot-control.sh net1 video_sg 1 
+testnovaboot-compute.sh net1 game_sg 1 
+
+
+
+testnovaboot-compute.sh net2 video_sg 2 
+testnovaboot-compute.sh net2 game_sg 2 #"bekind"
+
+#neutron router-create r2
+#neutron router-interface-add r2 sub3
+#neutron router-interface-add r2 sub4
+#neutron router-interface-add r2 sub5
+
+
+#testnovaboot-control.sh net3 client_sg 3 
+#testnovaboot-compute.sh net3 client_sg 4
+
+#testnovaboot-control.sh net4 video_sg 3
+#testnovaboot-compute.sh net4 game_sg 3
+
+#testnovaboot-control.sh net5 video_sg 4 
+#testnovaboot-compute.sh net5 game_sg 4 
+
+echo "control:"
+nova list --host devstack-control
+echo "compute:"
+nova list --host devstack-compute-1
+
diff --git a/demos/gbp-devstack/devstack-scripts/tests/testfloatingip.sh b/demos/gbp-devstack/devstack-scripts/tests/testfloatingip.sh
new file mode 100644 (file)
index 0000000..889296d
--- /dev/null
@@ -0,0 +1,24 @@
+source openrc admin admin
+sudo ovs-vsctl show
+neutron security-group-create client_sg
+neutron security-group-rule-create client_sg --direction egress --ethertype IPv4
+neutron security-group-rule-create client_sg --direction ingress --ethertype IPv4
+
+neutron net-create net1
+neutron subnet-create net1 10.1.1.0/24 --name sub1 --gateway 10.1.1.1
+neutron router-create router1
+neutron router-interface-add router1 sub1
+neutron net-create drexternal --provider:network_type flat --provider:physical_network dr-external --router:external
+neutron subnet-create --name extsubnet --allocation-pool start=192.168.111.50,end=192.168.111.55  --gateway 192.168.111.100 --disable-dhcp drexternal 192.168.111.0/24
+neutron router-gateway-set router1 drexternal
+neutron floatingip-create drexternal
+neutron floatingip-create drexternal
+testnovaboot-control.sh net1 client_sg 1
+testnovaboot-compute.sh net1 client_sg 2
+neutron port-list
+neutron floatingip-list
+
+echo "neutron floatingip-associate <floatingIPID> <PORTID>
+
+neutron floatingip-associate"
+
diff --git a/demos/gbp-devstack/devstack-scripts/tests/testmtnet.sh b/demos/gbp-devstack/devstack-scripts/tests/testmtnet.sh
new file mode 100644 (file)
index 0000000..b2ed6d0
--- /dev/null
@@ -0,0 +1,41 @@
+source openrc $1 $1 ; export OS_PASSWORD=$1
+
+SG=$1"_client_sg"
+NET1=$1"_net1"
+NET2=$1"_net2"
+SUB1=$1"_sub1"
+SUB2=$1"_sub2"
+R1=$1"_r1"
+
+
+neutron security-group-create $SG 
+neutron security-group-rule-create $SG --direction egress --ethertype IPv4
+neutron security-group-rule-create $SG --direction ingress --ethertype IPv4
+
+neutron net-create $NET1 
+
+SUBNET1="10.1.2.0/24"
+GW1="10.1.2.1"
+
+if [ $1 = "coke" ]; then
+    SUBNET1="10.1.1.0/24"
+    GW1="10.1.1.1"
+fi
+
+neutron subnet-create $NET1 $SUBNET1 --name $SUB1 --gateway $GW1 
+#neutron net-create $NET2
+#neutron subnet-create $NET2 20.1.1.0/24 --name $SUB2 --gateway 20.1.1.1
+
+#neutron router-create $R1
+#neutron router-interface-add $R1 $SUB1
+#neutron router-interface-add $R1 $SUB2
+
+
+testnovaboot-control.sh $NET1 $SG 1  
+#testnovaboot-compute.sh $NET1 $SG 2
+
+echo "control:"
+nova list --host devstack-control
+echo "compute:"
+nova list --host devstack-compute-1
+
diff --git a/demos/gbp-devstack/devstack-scripts/tutorial/exampleSecurityGroups.sh b/demos/gbp-devstack/devstack-scripts/tutorial/exampleSecurityGroups.sh
new file mode 100644 (file)
index 0000000..7554226
--- /dev/null
@@ -0,0 +1,21 @@
+neutron security-group-create web_sg
+neutron security-group-rule-create web_sg --direction ingress --protocol tcp --port-range-min 80 --port-range-max 80
+neutron security-group-rule-create web_sg --direction egress --ethertype IPv4
+neutron security-group-create secured_web_sg
+neutron security-group-rule-create secured_web_sg --direction ingress --protocol tcp --port-range-min 443 --port-range-max 443
+neutron security-group-rule-create secured_web_sg --direction egress --ethertype IPv4
+neutron security-group-create client_sg
+neutron security-group-rule-create client_sg --direction egress --protocol tcp --port-range-min 80 --port-range-max 80
+neutron security-group-rule-create client_sg --direction egress --protocol tcp --port-range-min 443 --port-range-max 443
+neutron security-group-rule-create client_sg --direction ingress --ethertype IPv4
+
+
+neutron net-create net1
+neutron subnet-create net1 10.1.1.0/24 --name sub1 --gateway 10.1.1.1
+neutron net-create net2
+neutron subnet-create net2 20.1.1.0/24 --name sub2 --gateway 20.1.1.1
+
+novaboot.sh net1 client_sg
+novaboot.sh net1 web_sg
+novaboot.sh net1 secured_web_sg
+
diff --git a/demos/gbp-devstack/devstack-scripts/tutorial/multirouter1.sh b/demos/gbp-devstack/devstack-scripts/tutorial/multirouter1.sh
new file mode 100644 (file)
index 0000000..88a2fcd
--- /dev/null
@@ -0,0 +1,60 @@
+neutron security-group-create client_sg
+neutron security-group-rule-create client_sg --direction egress --protocol tcp --port-range-min 80 --port-range-max 80
+neutron security-group-rule-create client_sg --direction egress --protocol tcp --port-range-min 443 --port-range-max 443
+neutron security-group-rule-create client_sg --direction egress --protocol tcp --port-range-min 5004 --port-range-max 5004
+neutron security-group-rule-create client_sg --direction egress --protocol udp --port-range-min 5004 --port-range-max 5004
+neutron security-group-rule-create client_sg --direction ingress --ethertype IPv4
+
+neutron security-group-create video_sg
+neutron security-group-rule-create video_sg --direction ingress --protocol tcp --port-range-min 80 --port-range-max 80
+neutron security-group-rule-create video_sg --direction ingress --protocol tcp --port-range-min 443 --port-range-max 443
+neutron security-group-rule-create video_sg --direction ingress --protocol tcp --port-range-min 5004 --port-range-max 5004
+neutron security-group-rule-create video_sg --direction ingress --protocol udp --port-range-min 5004 --port-range-max 5004
+neutron security-group-rule-create video_sg --direction egress --ethertype IPv4
+
+neutron security-group-create game_sg
+neutron security-group-rule-create game_sg --direction egress --ethertype IPv4
+neutron security-group-rule-create game_sg --direction ingress --protocol tcp --port-range-min 443 --port-range-max 443
+
+neutron net-create net1
+neutron subnet-create net1 10.1.1.0/24 --name sub1 --gateway 10.1.1.1
+neutron net-create net2
+neutron subnet-create net2 20.1.1.0/24 --name sub2 --gateway 20.1.1.1
+neutron net-create net3
+neutron subnet-create net3 30.1.1.0/24 --name sub3 --gateway 30.1.1.1
+neutron net-create net4
+neutron subnet-create net4 40.1.1.0/24 --name sub4 --gateway 40.1.1.1
+neutron net-create net5
+neutron subnet-create net5 50.1.1.0/24 --name sub5 --gateway 50.1.1.1
+
+neutron router-create r1
+neutron router-interface-add r1 sub1
+neutron router-interface-add r1 sub2
+
+novaboot.sh net1 client_sg 1 #"bekind" 
+novaboot.sh net1 video_sg 1 
+novaboot.sh net1 game_sg 1 
+
+novaboot.sh net2 client_sg 2 
+novaboot.sh net2 video_sg 2 
+novaboot.sh net2 game_sg 2 #"bekind"
+
+neutron router-create r2
+neutron router-interface-add r2 sub3
+neutron router-interface-add r2 sub4
+neutron router-interface-add r2 sub5
+
+novaboot.sh net3 client_sg 3 
+novaboot.sh net3 client_sg 4
+
+novaboot.sh net4 video_sg 3
+novaboot.sh net4 game_sg 3
+
+novaboot.sh net5 video_sg 4 
+novaboot.sh net5 game_sg 4 
+
+echo "control:"
+nova list --host devstack-control
+echo "compute:"
+nova list --host devstack-compute-1
+
diff --git a/demos/gbp-devstack/devstack-scripts/tutorial/step01.sh b/demos/gbp-devstack/devstack-scripts/tutorial/step01.sh
new file mode 100644 (file)
index 0000000..86cc26a
--- /dev/null
@@ -0,0 +1,21 @@
+source openrc admin admin
+
+neutron security-group-create client_sg
+neutron security-group-rule-create client_sg --direction ingress --ethertype IPv4
+neutron security-group-rule-create client_sg --direction egress --ethertype IPv4
+
+neutron security-group-create web_sg
+neutron security-group-rule-create web_sg --direction ingress --ethertype IPv4
+neutron security-group-rule-create web_sg --direction egress --ethertype IPv4
+
+neutron net-create net1
+neutron subnet-create net1 10.1.1.0/24 --name sub1 --gateway 10.1.1.1 --dns-nameservers list=true 8.8.4.4 8.8.8.8
+
+novaboot-control.sh net1 client_sg 1 
+novaboot-compute.sh net1 web_sg 1 
+
+echo "control:"
+nova list --host devstack-control
+echo "compute:"
+nova list --host devstack-compute-1
+
diff --git a/demos/gbp-devstack/devstack-scripts/tutorial/step02.sh b/demos/gbp-devstack/devstack-scripts/tutorial/step02.sh
new file mode 100644 (file)
index 0000000..1db9713
--- /dev/null
@@ -0,0 +1,18 @@
+source openrc admin admin
+
+neutron net-create net2
+neutron subnet-create net2 20.1.1.0/24 --name sub2 --gateway 20.1.1.1 --dns-nameservers list=true 8.8.4.4 8.8.8.8
+
+neutron router-create r1
+neutron router-interface-add r1 sub1
+neutron router-interface-add r1 sub2
+
+
+novaboot-compute.sh net2 client_sg 2
+novaboot-control.sh net2 web_sg 2
+
+echo "control:"
+nova list --host devstack-control
+echo "compute:"
+nova list --host devstack-compute-1
+
diff --git a/demos/gbp-devstack/devstack-scripts/tutorial/step03.sh b/demos/gbp-devstack/devstack-scripts/tutorial/step03.sh
new file mode 100644 (file)
index 0000000..d0f67c7
--- /dev/null
@@ -0,0 +1,13 @@
+source openrc admin admin
+
+neutron net-create drexternal --provider:network_type flat --provider:physical_network dr-external --router:external
+neutron subnet-create --name extsubnet --allocation-pool start=192.168.111.50,end=192.168.111.55  --gateway 192.168.111.253 --disable-dhcp drexternal 192.168.111.0/24
+neutron router-gateway-set r1 drexternal
+neutron floatingip-create drexternal
+neutron port-list
+neutron floatingip-list
+
+echo "neutron floatingip-associate <floatingIPID> <PORTID>
+
+neutron floatingip-associate"
+
diff --git a/demos/gbp-devstack/devstack-scripts/tutorial/step04.sh b/demos/gbp-devstack/devstack-scripts/tutorial/step04.sh
new file mode 100644 (file)
index 0000000..2b59631
--- /dev/null
@@ -0,0 +1,19 @@
+source openrc admin admin
+
+neutron net-create net3
+neutron subnet-create net3 30.1.1.0/24 --name sub3 --gateway 30.1.1.1
+neutron net-create net4
+neutron subnet-create net4 40.1.1.0/24 --name sub4 --gateway 40.1.1.1
+
+neutron router-create r2
+neutron router-interface-add r2 sub3
+neutron router-interface-add r2 sub4
+
+novaboot-compute.sh net3 client_sg 3
+novaboot-compute.sh net4 web_sg 3 
+
+echo "control:"
+nova list --host devstack-control
+echo "compute:"
+nova list --host devstack-compute-1
+
diff --git a/demos/gbp-devstack/devstack-scripts/unstack.sh b/demos/gbp-devstack/devstack-scripts/unstack.sh
new file mode 100644 (file)
index 0000000..ad537a7
--- /dev/null
@@ -0,0 +1,4 @@
+echo "local.conf set to offline, please use ./myUnstack.sh or .....
+..........  IFF (IF AND ONLY IF) you have changed local.conf... 
+   ***** ./reallyunstack.sh *****    "
+
diff --git a/demos/gbp-devstack/puppet/hiera.yaml b/demos/gbp-devstack/puppet/hiera.yaml
new file mode 100644 (file)
index 0000000..a93e1d9
--- /dev/null
@@ -0,0 +1,10 @@
+---
+:backends:
+  - yaml
+  - json
+:yaml:
+  :datadir: /vagrant/puppet/hieradata
+:json:
+  :datadir: /vagrant/puppet/hieradata
+:hierarchy:
+  - hosts
diff --git a/demos/gbp-devstack/puppet/hieradata/hosts.json b/demos/gbp-devstack/puppet/hieradata/hosts.json
new file mode 100644 (file)
index 0000000..265758b
--- /dev/null
@@ -0,0 +1,24 @@
+{
+  "hosts": {
+    "opendaylight": {
+      "name": "opendaylight",
+      "ipaddress": "192.168.50.1"
+    },
+    "devstack-control": {
+      "name": "devstack-control",
+      "ipaddress": "192.168.50.20"
+    },
+    "devstack-compute-1": {
+      "name": "devstack-compute-1",
+      "ipaddress": "192.168.50.21"
+    },
+    "devstack-compute-2": {
+      "name": "devstack-compute-2",
+      "ipaddress": "192.168.50.22"
+    },
+    "devstack-compute-3": {
+      "name": "devstack-compute-3",
+      "ipaddress": "192.168.50.23"
+    }
+  }
+}
diff --git a/demos/gbp-devstack/puppet/manifests/base.pp b/demos/gbp-devstack/puppet/manifests/base.pp
new file mode 100644 (file)
index 0000000..1503186
--- /dev/null
@@ -0,0 +1,115 @@
+$deps = [
+    'autoconf',
+    'automake',
+    'bc',
+    'bridge-utils',
+    'build-essential',
+    'conntrack',
+    'curl',
+    'debhelper',
+    'dkms',
+    'dnsmasq-base',
+    'dnsmasq-utils',
+    'ebtables',
+    'euca2ools',
+    'gawk',
+    'gcc',
+    'genisoimage',
+    'git',
+    'graphviz',
+    'iptables',
+    'iputils-arping',
+    'iputils-ping',
+    'kpartx',
+    'libffi-dev',
+    'libjs-jquery-tablesorter',
+    'libssl-dev',
+    'libtool',
+    'libyaml-dev',
+    'lsof',
+    'lvm2',
+    'open-iscsi',
+    'openssh-server',
+    'openssl',
+    'parted',
+    'pm-utils',
+    'psmisc',
+    'pylint',
+    'python-all',
+    'python-boto',
+    'python-cheetah',
+    'python-dev',
+    'python-eventlet',
+    'python-feedparser',
+    'python-greenlet',
+    'python-iso8601',
+    'python-kombu',
+    'python-libxml2',
+    'python-lockfile',
+    'python-lxml',
+    'python-m2crypto',
+    'python-migrate',
+    'python-mox',
+    'python-mysql.connector',
+    'python-mysqldb',
+    'python-numpy',
+    'python-paste',
+    'python-pastedeploy',
+    'python-pyudev',
+    'python-qt4',
+    'python-routes',
+    'python-setuptools',
+    'python-sqlalchemy',
+    'python-suds',
+    'python-tempita',
+    'python-twisted-conch',
+    'python-unittest2',
+    'python-virtualenv',
+    'python-xattr',
+    'python-zopeinterface',
+    'python2.7',
+    'screen',
+    'sg3-utils',
+    'socat',
+    'sqlite3',
+    'sudo',
+    'sysfsutils',
+    'tar',
+    'tcpdump',
+    'unzip',
+    'vim',
+    'vlan',
+    'wget',
+    'xbase-clients',
+    'wireshark'
+]
+
+$hosts = hiera('hosts')
+
+file { '/etc/hosts':
+    ensure  => file,
+    owner   => 'root',
+    group   => 'root',
+    content => template('/vagrant/puppet/templates/hosts.erb')
+}
+
+package { $deps:
+    ensure   => installed,
+}
+
+exec {"Download Open vSwitch":
+    command => "wget https://raw.githubusercontent.com/pritesh/ovs/nsh-v8/third-party/start-ovs-deb.sh",
+    cwd     => "/home/vagrant",
+    creates => "/home/vagrant/start-ovs-deb.sh",
+    path    => $::path,
+    user    => 'vagrant'
+}
+
+exec { 'Extract Open vSwitch':
+    command => "bash /home/vagrant/start-ovs-deb.sh",
+    cwd     => '/home/vagrant',
+    user    => 'root',
+    path    => $::path,
+    timeout => 0,
+    require => Exec['Download Open vSwitch']
+}
diff --git a/demos/gbp-devstack/puppet/manifests/devstack-compute.pp b/demos/gbp-devstack/puppet/manifests/devstack-compute.pp
new file mode 100644 (file)
index 0000000..d85ebb0
--- /dev/null
@@ -0,0 +1,17 @@
+vcsrepo {'/home/vagrant/devstack':
+    ensure   => present,
+    provider => git,
+    user     => 'vagrant',
+    source   => 'https://github.com/openstack-dev/devstack.git',
+    revision => 'stable/kilo',
+    before   => File['/home/vagrant/devstack/local.conf'],
+}
+
+$hosts = hiera('hosts')
+
+file { '/home/vagrant/devstack/local.conf':
+    ensure  => present,
+    owner   => 'vagrant',
+    group   => 'vagrant',
+    content => template('/vagrant/puppet/templates/compute.local.conf.erb'),
+}
diff --git a/demos/gbp-devstack/puppet/manifests/devstack-control.pp b/demos/gbp-devstack/puppet/manifests/devstack-control.pp
new file mode 100644 (file)
index 0000000..473d4c4
--- /dev/null
@@ -0,0 +1,17 @@
+vcsrepo {'/home/vagrant/devstack':
+    ensure   => present,
+    provider => git,
+    user     => 'vagrant',
+    source   => 'https://github.com/openstack-dev/devstack.git',
+    revision => 'stable/kilo',
+    before   => File['/home/vagrant/devstack/local.conf'],
+}
+
+$hosts = hiera('hosts')
+
+file { '/home/vagrant/devstack/local.conf':
+    ensure  => present,
+    owner   => 'vagrant',
+    group   => 'vagrant',
+    content => template('/vagrant/puppet/templates/control.local.conf.erb'),
+}
diff --git a/demos/gbp-devstack/puppet/scripts/bootstrap.sh b/demos/gbp-devstack/puppet/scripts/bootstrap.sh
new file mode 100644 (file)
index 0000000..d717ded
--- /dev/null
@@ -0,0 +1,56 @@
+#!/usr/bin/env bash
+#
+# This bootstraps Puppet on Ubuntu 12.04 LTS.
+#
+set -e
+# Load up the release information
+
+. /etc/lsb-release
+
+REPO_DEB_URL="http://apt.puppetlabs.com/puppetlabs-release-${DISTRIB_CODENAME}.deb"
+
+#--------------------------------------------------------------------
+# NO TUNABLES BELOW THIS POINT
+#--------------------------------------------------------------------
+if [ "$(id -u)" != "0" ]; then
+  echo "This script must be run as root." >&2
+  exit 1
+fi
+
+if which puppet > /dev/null 2>&1 && apt-cache policy | grep --quiet apt.puppetlabs.com; then
+  echo "Puppet is already installed."
+  exit 0
+fi
+
+# Do the initial apt-get update
+echo "Initial apt-get update..."
+apt-get update >/dev/null
+
+# Install wget if we have to (some older Ubuntu versions)
+echo "Installing wget..."
+apt-get install -y wget >/dev/null
+
+# Install the PuppetLabs repo
+echo "Configuring PuppetLabs repo..."
+repo_deb_path=$(mktemp)
+wget --output-document="${repo_deb_path}" "${REPO_DEB_URL}" 2>/dev/null
+dpkg -i "${repo_deb_path}" >/dev/null
+apt-get update >/dev/null
+
+# Install Puppet
+echo "Installing Puppet..."
+DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" install puppet >/dev/null
+
+echo "Puppet installed!"
+
+# Install RubyGems for the provider
+echo "Installing RubyGems..."
+if [ $DISTRIB_CODENAME != "trusty" ]; then
+  apt-get install -y rubygems >/dev/null
+fi
+gem install --no-ri --no-rdoc rubygems-update
+update_rubygems >/dev/null
+
+# Installing Puppet Modules
+puppet module install puppetlabs/vcsrepo
+puppet module install puppetlabs/stdlib
diff --git a/demos/gbp-devstack/puppet/scripts/clear_ovs.sh b/demos/gbp-devstack/puppet/scripts/clear_ovs.sh
new file mode 100644 (file)
index 0000000..e48d6d6
--- /dev/null
@@ -0,0 +1,8 @@
+#!/usr/bin/env bash
+#
+
+sudo service openvswitch-switch stop
+sudo rm -rf /var/log/openvswitch/*
+sudo rm -rf /etc/openvswitch/conf.db
+sudo service openvswitch-switch start
+
diff --git a/demos/gbp-devstack/puppet/templates/compute.local.conf.erb b/demos/gbp-devstack/puppet/templates/compute.local.conf.erb
new file mode 100644 (file)
index 0000000..0c7c4e0
--- /dev/null
@@ -0,0 +1,97 @@
+[[local|localrc]]
+#enable_plugin networking-odl https://github.com/stackforge/networking-odl
+enable_plugin networking-odl https://github.com/flavio-fernandes/networking-odl lithiumkilo
+
+LOGFILE=stack.sh.log
+LOG_COLOR=False
+SCREEN_LOGDIR=/opt/stack/data/log
+#OFFLINE=True
+RECLONE=yes
+
+disable_all_services
+enable_service n-cpu n-novnc n-cauth
+
+HOST_IP=<%= @hosts[@hostname]['ipaddress'] %>
+HOST_NAME=<%= @hosts[@hostname]['name'] %>
+SERVICE_HOST=<%= @hosts['devstack-control']['ipaddress'] %>
+SERVICE_HOST_NAME=<%= @hosts['devstack-control']['name'] %>
+
+VNCSERVER_PROXYCLIENT_ADDRESS=$HOST_IP
+VNCSERVER_LISTEN=0.0.0.0
+
+ODL_MODE=compute
+ODL_MGR_IP=<%= @hosts['opendaylight']['ipaddress'] %>
+ODL_PORT=8080
+ENABLE_TENANT_TUNNELS=True
+Q_ML2_TENANT_NETWORK_TYPE=vxlan
+
+FLOATING_RANGE=192.168.111.0/24
+FIXED_RANGE="90.1.1.0/24"
+PUBLIC_NETWORK_GATEWAY=192.168.111.254
+
+PUBLIC_INTERFACE=eth2
+PUBLIC_BRIDGE=br-int
+
+## Neutron options
+Q_USE_SECGROUP=True
+ENABLE_TENANT_VLANS=True
+TENANT_VLAN_RANGE=3001:4000
+PHYSICAL_NETWORK=dr-external
+OVS_PHYSICAL_BRIDGE=br-int
+
+ODL_PROVIDER_MAPPINGS=$PHYSICAL_NETWORK:$PUBLIC_INTERFACE
+
+
+# NOTE: Set the database type
+DATABASE_TYPE=mysql
+KEYSTONE_CATALOG_BACKEND=sql
+
+Q_HOST=$SERVICE_HOST
+MYSQL_HOST=$SERVICE_HOST
+RABBIT_HOST=$SERVICE_HOST
+GLANCE_HOSTPORT=$SERVICE_HOST:9292
+KEYSTONE_AUTH_HOST=$SERVICE_HOST
+KEYSTONE_SERVICE_HOST=$SERVICE_HOST
+
+MYSQL_PASSWORD=mysql
+RABBIT_PASSWORD=rabbit
+#QPID_PASSWORD=rabbit
+SERVICE_TOKEN=service
+SERVICE_PASSWORD=admin
+ADMIN_PASSWORD=admin
+
+BRANCH=stable/kilo
+GLANCE_BRANCH=$BRANCH
+HORIZON_BRANCH=$BRANCH
+KEYSTONE_BRANCH=$BRANCH
+NOVA_BRANCH=$BRANCH
+NEUTRON_BRANCH=$BRANCH
+SWIFT_BRANCH=$BRANCH
+##CLIFF_BRANCH=$BRANCH
+##TEMPEST_BRANCH=$BRANCH
+CINDER_BRANCH=$BRANCH
+HEAT_BRANCH=$BRANCH
+TROVE_BRANCH=$BRANCH
+CEILOMETER_BRANCH=$BRANCH
+
+
+ODL_L3=True
+#Q_ML2_L3_PLUGIN=networking_odl.l3.l3_odl.OpenDaylightL3RouterPlugin
+## For L3
+[[post-config]|/etc/neutron/l3_agent.ini]]
+[DEFAULT]
+interface_driver = neutron.agent.linux.interface.NullDriver
+
+
+[[post-config|$NOVA_CONF]]
+[oslo_messaging_rabbit]
+heartbeat_timeout_threshold = 0
+
+[[post-config|$NOVA_CONF]]
+[DEFAULT]
+vnc_enabled=True
+novncproxy_base_url=http://<%= @hosts['devstack-control']['ipaddress'] %>:6080/vnc_auto.html
+vncserver_listen=0.0.0.0
+vncserver_proxyclient_address=<%= @hosts[@hostname]['ipaddress'] %>
+[oslo_messaging_rabbit]
+heartbeat_timeout_threshold = 0
diff --git a/demos/gbp-devstack/puppet/templates/control.local.conf.erb b/demos/gbp-devstack/puppet/templates/control.local.conf.erb
new file mode 100644 (file)
index 0000000..2e11d96
--- /dev/null
@@ -0,0 +1,160 @@
+[[local|localrc]]
+#enable_plugin networking-odl https://github.com/stackforge/networking-odl
+#enable_plugin networking-odl /vagrant/x/networking-odl.git plugin
+enable_plugin networking-odl https://github.com/flavio-fernandes/networking-odl lithiumkilo
+
+LOGFILE=stack.sh.log
+SCREEN_LOGDIR=/opt/stack/data/log
+LOG_COLOR=False
+#OFFLINE=True
+RECLONE=yes
+
+disable_service swift
+disable_service cinder
+disable_service n-net
+disable_service tempest
+enable_service q-svc
+enable_service q-dhcp
+enable_service q-meta
+disable_service q-vpn
+disable_service q-metering
+disable_service q-lbaas
+disable_service q-lbaasv2
+disable_service q-fwaas
+enable_service n-cauth
+
+HOST_IP=<%= @hosts['devstack-control']['ipaddress'] %>
+HOST_NAME=<%= @hosts['devstack-control']['name'] %>
+SERVICE_HOST=$HOST_IP
+SERVICE_HOST_NAME=$HOST_NAME
+
+NEUTRON_CREATE_INITIAL_NETWORKS=False
+Q_ML2_TENANT_NETWORK_TYPE=vxlan
+
+ODL_MODE=externalodl
+
+ODL_MGR_IP=<%= @hosts['opendaylight']['ipaddress'] %>
+ODL_PORT=8080
+
+ENABLE_TENANT_TUNNELS=True
+
+VNCSERVER_PROXYCLIENT_ADDRESS=${HOST_IP}
+VNCSERVER_LISTEN=0.0.0.0
+
+FLOATING_RANGE=192.168.111.0/24
+FIXED_RANGE="90.1.1.0/24"
+PUBLIC_NETWORK_GATEWAY=192.168.111.254
+PUBLIC_INTERFACE=eth2
+PUBLIC_BRIDGE=br-int
+## Neutron options
+Q_USE_SECGROUP=True
+ENABLE_TENANT_VLANS=True
+TENANT_VLAN_RANGE=3001:4000
+PHYSICAL_NETWORK=dr-external
+OVS_PHYSICAL_BRIDGE=br-int
+ODL_PROVIDER_MAPPINGS=$PHYSICAL_NETWORK:$PUBLIC_INTERFACE
+
+MYSQL_HOST=$SERVICE_HOST
+RABBIT_HOST=$SERVICE_HOST
+GLANCE_HOSTPORT=$SERVICE_HOST:9292
+KEYSTONE_AUTH_HOST=$SERVICE_HOST
+KEYSTONE_SERVICE_HOST=$SERVICE_HOST
+
+MYSQL_PASSWORD=mysql
+RABBIT_PASSWORD=rabbit
+SERVICE_TOKEN=service
+SERVICE_PASSWORD=admin
+ADMIN_PASSWORD=admin
+
+BRANCH=stable/kilo
+GLANCE_BRANCH=$BRANCH
+HORIZON_BRANCH=$BRANCH
+KEYSTONE_BRANCH=$BRANCH
+NOVA_BRANCH=$BRANCH
+NEUTRON_BRANCH=$BRANCH
+SWIFT_BRANCH=$BRANCH
+##CLIFF_BRANCH=$BRANCH
+##TEMPEST_BRANCH=$BRANCH
+CINDER_BRANCH=$BRANCH
+HEAT_BRANCH=$BRANCH
+TROVE_BRANCH=$BRANCH
+CEILOMETER_BRANCH=$BRANCH
+
+ODL_L3=True
+## For L3
+[[post-config]|/etc/neutron/l3_agent.ini]]
+[DEFAULT]
+interface_driver = neutron.agent.linux.interface.NullDriver
+[[post-config|/etc/neutron/neutron.conf]]
+[DEFAULT]
+service_plugins = networking_odl.l3.l3_odl.OpenDaylightL3RouterPlugin
+[[post-config|/etc/neutron/plugins/ml2/ml2_conf.ini]]
+[agent]
+minimize_polling=True
+[[post-config|$NOVA_CONF]]
+[DEFAULT]
+skip_isolated_core_check=true
+max_cores=128
+cpu_allocation_ratio=16.0
+quota_cores=128
+quota_instances=500
+quota_floating_ips=1000
+quota_metadata_items=300
+quota_security_group_rules=200
+quota_security_groups=200
+quota_volumes=100
+scheduler_default_filters = AllHostsFilter
+[quota]
+skip_isolated_core_check=true
+max_cores=128
+cpu_allocation_ratio=16.0
+quota_cores=128
+quota_instances=500
+quota_floating_ips=1000
+quota_metadata_items=300
+quota_security_group_rules=200
+quota_security_groups=200
+quota_volumes=100
+[oslo_messaging_rabbit]
+heartbeat_timeout_threshold = 0
+[[post-config|$CINDER_CONF]]
+[DEFAULT]
+quota_gigabytes=-1
+quota_snapshots=-1
+quota_volumes=-1
+[quota]
+quota_gigabytes=-1
+quota_snapshots=-1
+quota_volumes=-1
+[oslo_messaging_rabbit]
+heartbeat_timeout_threshold = 0
+[[post-config|$NEUTRON_CONF]]
+[DEFAULT]
+quota_network = 100
+quota_subnet = 100
+quota_port = 500
+quota_router = 100
+quota_floatingip = 5000
+quota_security_group_rules=200
+quota_security_groups=200
+[quota]
+quota_network = 100
+quota_subnet = 100
+quota_port = 500
+quota_router = 100
+quota_floatingip = 5000
+quota_security_group_rules=200
+quota_security_groups=200
+[oslo_messaging_rabbit]
+heartbeat_timeout_threshold = 0
+[[post-config|$GLANCE_API_CONF]]
+[oslo_messaging_rabbit]
+heartbeat_timeout_threshold = 0
+
diff --git a/demos/gbp-devstack/puppet/templates/hosts.erb b/demos/gbp-devstack/puppet/templates/hosts.erb
new file mode 100644 (file)
index 0000000..c23f40f
--- /dev/null
@@ -0,0 +1,8 @@
+## Do Not Edit. Created by Puppet ##
+127.0.0.1   localhost
+255.255.255.255 broadcasthost
+::1             localhost
+fe80::1%lo0 localhost
+<% @hosts.values.each do |h| %>
+<%= h["ipaddress"] %>  <%= h["name"] %>
+<% end %>
diff --git a/demos/gbp-devstack/wscontrol.sh b/demos/gbp-devstack/wscontrol.sh
new file mode 100644 (file)
index 0000000..f884dca
--- /dev/null
@@ -0,0 +1 @@
+wireshark -k -i <(vagrant ssh -c "sudo dumpcap -P -i any -w - -f 'not tcp port 22'" -- -ntt)
diff --git a/demos/gbpsfc-env/README.md b/demos/gbpsfc-env/README.md
new file mode 100644 (file)
index 0000000..3f99b06
--- /dev/null
@@ -0,0 +1,214 @@
+#SETUP
+
+This is a demonstration/development environment for show-casing OpenDaylight GroupBasedPolicy (GBP) with ServiceFunctionChaining (SFC)
+
+The initial instalation may take some time, with vagrant and docker image downloads. 
+
+After the first time it is very quick.
+
+1. Set up Vagrant. 
+  * Edit env.sh for NUM_NODES. (Keep all other vars the same for this version)
+  * Each VM takes approximately 1G RAM, 2GB used HDD (40GB)
+  * demo-gbp1: 3 VMs.
+  * demo-symmetric-chain: 6 VMs.
+  * demo-asymmetric-chain: 6 VMs.
+2. From the directory you cloned into:
+```
+source ./env.sh
+vagrant up
+```
+  * This takes quite some time initially.
+  * If the starting process fail with '/sbin/mount.vboxsf: mounting failed with the error: No such device' line
+    (usually occur after first halt) run 'vagrant plugin install vagrant-vbguest' command on host. It should solve the problem.
+
+3. Start controller.
+  * Currently it is expected that that controller runs on the host hosting the VMs.
+  * Tested using groupbasedpolicy stable/lithium.
+               If you are building stable/lithium and you get 'illegal unicode escape' error, 
+               you have to rename two yang files in 'groupbasedpolicy\ui-backend\src\main\yang'. 
+               These files have to start with a character other than 'u'. 
+               E.g. rename 'ui-backend.yang' to 'aui-backend.yang' and 'ui-backend-impl.yang' to 'aui-backend-impl.yang'.
+  * Start controller by running bin/karaf and install following features in karaf:
+
+```
+ feature:install odl-groupbasedpolicy-ofoverlay odl-groupbasedpolicy-ui odl-restconf
+```
+
+  * Run `log:tail | grep renderer` and wait until the following message appears in the log:
+```
+INFO - OFOverlayRenderer - org.opendaylight.groupbasedpolicy.ofoverlay-renderer - Initialized OFOverlay renderer
+```
+  * Now you can ^C the log:tail if you wish
+
+#Demos:
+* demo-gbp1: 
+  * 8 docker containers in 2 x EPGs (web, client)
+  * contract with ICMP and HTTP
+* demo-symmetry:
+  * 2 docker containers in 2 x EPGs (web, client)
+  * contract with ICMP (ALLOW) and HTTP (CHAIN, where Client request is chained, Web reverse path is reverse path of chain)
+* demo-asymmetry:
+  * 2 docker containers in 2 x EPGs (web, client)
+  * contract with ICMP (ALLOW) and HTTP (CHAIN, where Client request is chained, Web reverse path is ALLOW)
+
+##demo-gbp1
+
+###Setup
+
+VMs:
+* gbpsfc1: gbp
+* gbpsfc2: gbp
+* gbpsfc3: gbp
+
+Containers:
+* h35_{x} are in EPG:client
+* h36_{x} are in EPG:web
+
+To run, from host folder where Vagrantfile located do:
+
+` ./startdemo.sh demo-gbp1`
+
+After this, `infrastructure_config.py` will be copied from `/demo-gbp1`, and you are ready to start testing.
+###To test:
+
+SSH to test VM (may take some seconds):
+```bash
+vagrant ssh gbpsfc1
+```
+
+Get root rights:
+```bash
+sudo -E bash
+```
+
+Check docker containers running on your VM:
+```bash
+docker ps
+```
+
+Notice there are containers from two different endpoint groups, "h35" and "h36".
+Enter into the shell on one of "h36" (web) container (on `gbpsfc1` it will be `h36_4`, its IP is `10.0.36.4`, 
+you will need it later).
+*(You need double ENTER after `docker attach`)*
+```bash
+docker attach h36_4
+```
+
+Start a HTTP server:
+```bash
+python -m SimpleHTTPServer 80
+```
+
+Press `Ctrl-P-Q` to return to your root shell on `gbpsfc1`
+
+Enter into one of "h35" (client) container, 
+ping the container where HTTP server runs, 
+and connect to index page:
+
+*We use eternal loop here to imitate web activity. 
+After finishing your test, you might want to stop the loop with `Ctrl-C`*
+```
+docker attach h35_{x}
+ping 10.0.36.4
+while true; do curl 10.0.36.4; done
+```
+
+You may `ping` and `curl` to the web-server from any test VM.
+
+`Ctrl-P-Q` to leave back to root shell on VM.
+
+Now watch the packets flow:
+```
+ovs-dpctl dump-flows
+```
+
+Leave to main shell:
+```bash
+exit #leave root shell
+exit #close ssh session
+```
+Repeat `vagrant ssh` etc. for each of gbpsfc2, gbpsfc3.
+
+###After testing
+
+When finished from host folder where Vagrantfile located do:
+
+`./cleandemo.sh`
+
+If you like `vagrant destroy` will remove all VMs.
+
+##demo-symmetric-chain / demo-asymmetric-chain
+
+VMs:
+* gbpsfc1: gbp (client initiates transactions from here)
+* gbpsfc2: sff
+* gbpsfc3: "sf"
+* gbpsfc4: sff
+* gbpsfc5: "sf"
+* gbpsfc6: gbp (run a server here)
+
+Containers:
+* h35_2 is in EPG:client on gbpsfc1
+* h36_4 is in EPG:web on gbpsfc6
+
+To run, from host folder where Vagrantfile located do:
+
+` ./startdemo.sh demo-symmetric-chain` | `demo-asymmetric-chain`
+
+### To test by sending traffic:
+Start a test HTTP server on h36_4 in VM 6.
+
+*(don't) forget double ENTER after `docker attach`*
+```bash
+vagrant ssh gbpsfc6
+sudo -E docker ps
+sudo -E docker attach h36_4
+python -m SimpleHTTPServer 80
+```
+
+Ctrl-P-Q to detach from docker without stopping the SimpleHTTPServer, and logoff gbpsfc6.
+
+Now start client traffic, either ping or make HTTP requests to the server on h36_4.
+
+```bash
+vagrant ssh gbpsfc1
+sudo -E docker ps
+sudo -E docker attach h35_2
+ping 10.0.36.4
+curl 10.0.36.4
+while true; do curl 10.0.36.4; sleep 1; done
+```
+
+Ctrl-P-Q to detach from docker, leaving the client making HTTP requests, and logoff gbpsfc1.
+
+
+Look around: use "vagrant ssh" to the various machines 
+ * take packet captures on eth1.
+ * sudo ovs-dpctl dump-flows`
+
+### When finished from host folder where Vagrantfile located do:
+
+`./cleandemo.sh`
+
+If you like `vagrant destroy` will remove all VMs
+
+##Preparing to run another demo
+1. In the vagrant directory, run cleandemo.sh
+2. stop controller (logout of karaf)
+3. Remove journal and snapshot directories from controller directory.
+4. Restart the controller, install features, wait, as above.
+
+
+# Useful vagrant plugins
+
+You can install plugins using
+
+```bash
+vagrant plugin install <plugin>
+```
+
+Useful ones are:
+vagrant-cachier - faster build times as APT repos cached
+vagrant-vbguest - updates VirtualBox Guest Additions versions (if possible)
+
diff --git a/demos/gbpsfc-env/Vagrantfile b/demos/gbpsfc-env/Vagrantfile
new file mode 100644 (file)
index 0000000..7eab551
--- /dev/null
@@ -0,0 +1,36 @@
+
+# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
+VAGRANTFILE_API_VERSION = "2"
+
+Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
+  odl=ENV['ODL']
+  config.vm.provider "virtualbox" do |vb|
+    vb.memory = "512"
+  end
+  if Vagrant.has_plugin?("vagrant-cachier")
+    config.cache.scope = :box
+  end
+  # run our bootstrapping for the system
+  config.vm.provision 'shell', path: 'bootstrap.sh', :args => odl
+
+  num_nodes = (ENV['NUM_NODES'] || 1).to_i
+
+  # ip configuration
+  ip_base = (ENV['SUBNET'] || "192.168.50.")
+  ips = num_nodes.times.collect { |n| ip_base + "#{n+70}" }
+
+  num_nodes.times do |n|
+    config.vm.define "gbpsfc#{n+1}", autostart: true do |compute|
+      vm_ip = ips[n]
+      vm_index = n+1
+      compute.vm.box = "ubuntu/trusty64"
+      compute.vm.hostname = "gbpsfc#{vm_index}"
+      compute.vm.network "private_network", ip: "#{vm_ip}"
+      compute.vm.provider :virtualbox do |vb|
+        vb.memory = 512
+        vb.customize ["modifyvm", :id, "--ioapic", "on"]      
+        vb.cpus = 1
+      end
+    end
+  end
+end
diff --git a/demos/gbpsfc-env/bootstrap.sh b/demos/gbpsfc-env/bootstrap.sh
new file mode 100644 (file)
index 0000000..dbc43b9
--- /dev/null
@@ -0,0 +1,30 @@
+#!/bin/bash
+
+# vim: sw=4 ts=4 sts=4 et tw=72 :
+
+echo "---> Updating operating system"
+apt update -qq
+
+echo "---> Installing Group Based Policy requirements"
+apt install -y software-properties-common -qq
+apt install -y python-software-properties -qq
+apt install -y python-pip -qq
+apt install -y git-core git -qq
+apt install -y curl -qq
+# docker
+curl -sSL https://get.docker.com/ | sh
+
+cat <<EOL > /etc/default/docker
+  DOCKER_NETWORK_OPTIONS='--bip=10.250.0.254/24'
+EOL
+
+docker pull alagalah/odlpoc_ovs230
+# OVS
+curl https://raw.githubusercontent.com/pritesh/ovs/nsh-v8/third-party/start-ovs-deb.sh | bash
+
+# this part is just for local spinup DON'T copy it to releng bootstrap.sh
+pip install ipaddr
+echo "export PATH=$PATH:/vagrant" >> /home/vagrant/.profile
+echo "export ODL="$1 >> /home/vagrant/.profile
+usermod -aG docker vagrant
+
diff --git a/demos/gbpsfc-env/checkdemo.sh b/demos/gbpsfc-env/checkdemo.sh
new file mode 100644 (file)
index 0000000..b37c895
--- /dev/null
@@ -0,0 +1,16 @@
+#!/usr/bin/env bash
+
+set -e
+
+
+echo "Checking demo from $demo with vars:"
+echo "Number of nodes: " $NUM_NODES
+echo "Opendaylight Controller: " $ODL
+echo "Base subnet: " $SUBNET
+
+for i in `seq 1 $NUM_NODES`; do
+  hostname="gbpsfc"$i
+  echo $hostname "flow count: "
+  vagrant ssh $hostname -c "sudo ovs-ofctl dump-flows sw$i -OOpenFlow13 | wc -l "
+done
+
diff --git a/demos/gbpsfc-env/cleandemo.sh b/demos/gbpsfc-env/cleandemo.sh
new file mode 100644 (file)
index 0000000..64b95ec
--- /dev/null
@@ -0,0 +1,16 @@
+#!/usr/bin/env bash
+
+
+for i in `seq 1 $NUM_NODES`; do
+  hostname="gbpsfc"$i
+  switchname="sw"$i
+  echo $hostname
+  vagrant ssh $hostname -c "sudo ovs-vsctl del-br $switchname; sudo ovs-vsctl del-manager; sudo /vagrant/vmclean.sh"
+
+done
+./rest-clean.py
+
+if [ -f "demo.lock" ] ; then
+  rm demo.lock
+fi
diff --git a/demos/gbpsfc-env/demo-asymmetric-chain/get-nsps.py b/demos/gbpsfc-env/demo-asymmetric-chain/get-nsps.py
new file mode 100644 (file)
index 0000000..94650e8
--- /dev/null
@@ -0,0 +1,60 @@
+#!/usr/bin/python
+import socket
+import requests,json
+from requests.auth import HTTPBasicAuth
+import sys
+import os
+from subprocess import check_output
+from infrastructure_config import *
+
+
+DEFAULT_PORT='8181'
+USERNAME='admin'
+PASSWORD='admin'
+
+def get(host, port, uri):
+    url='http://'+host+":"+port+uri
+    #print url
+    r = requests.get(url, auth=HTTPBasicAuth(USERNAME, PASSWORD))
+    jsondata=json.loads(r.text)
+    return jsondata
+
+
+def get_rsps_uri():
+       return "/restconf/operational/rendered-service-path:rendered-service-paths"
+
+def doCmd(cmd):
+    listcmd=cmd.split()
+    print check_output(listcmd)
+
+if __name__ == "__main__":
+    # Launch main menu
+
+
+    # Some sensible defaults
+    controller=os.environ.get('ODL')
+    if controller == None:
+        sys.exit("No controller set.")
+    #else:
+       #print "Contacting controller at %s" % controller
+
+    resp=get(controller,DEFAULT_PORT,get_rsps_uri())
+    if len(resp['rendered-service-paths']) > 0:
+       paths=resp['rendered-service-paths']['rendered-service-path']
+
+       nsps=[]
+       for path in paths:
+           nsps.append(path['path-id'])
+       if len(nsps) > 0:
+           sw_index=int(socket.gethostname().split("gbpsfc",1)[1])-1
+           if sw_index in range(0,len(switches)+1):
+
+              controller=os.environ.get('ODL')
+              sw_type = switches[sw_index]['type']
+              sw_name = switches[sw_index]['name']
+              if sw_type == 'sf':
+                  print "******************************"
+                  print "Adding flows for %s as an SF." % sw_name
+                  print "******************************"
+                  doCmd('sudo /vagrant/utils/sf-flows.sh %s' % min(nsps))
+
diff --git a/demos/gbpsfc-env/demo-asymmetric-chain/infrastructure_config.py b/demos/gbpsfc-env/demo-asymmetric-chain/infrastructure_config.py
new file mode 100644 (file)
index 0000000..efdcfc9
--- /dev/null
@@ -0,0 +1,65 @@
+# Config for switches, tunnelIP is the local IP address.
+switches = [
+            {'name': 'sw1',
+             'type': 'gbp',
+             'dpid': '1'},
+            {'name': 'sw2',
+             'type': 'sff',
+             'dpid': '2'},
+            {'name': 'sw3',
+             'type': 'sf',
+             'dpid': '3'},
+            {'name': 'sw4',
+             'type': 'sff',
+             'dpid': '4'},
+            {'name': 'sw5',
+             'type': 'sf',
+             'dpid': '5'},
+            {'name': 'sw6',
+             'type': 'gbp',
+             'dpid': '6'},
+            {'name': 'sw7',
+             'type': 'none',
+             'dpid': '7'},
+            {'name': 'sw8',
+             'type': 'none',
+             'dpid': '8'}
+           ]
+
+defaultContainerImage='alagalah/odlpoc_ovs230'
+
+#Note that tenant name and endpointGroup name come from policy_config.py
+
+hosts = [{'name': 'h35_2',
+          'mac': '00:00:00:00:35:02',
+          'ip': '10.0.35.2/24',
+          'switch': 'sw1'},
+         {'name': 'h35_3',
+          'ip': '10.0.35.3/24',
+          'mac': '00:00:00:00:35:03',
+          'switch': 'sw1'},
+         {'name': 'h35_4',
+          'ip': '10.0.35.4/24',
+          'mac': '00:00:00:00:35:04',
+          'switch': 'sw6'},
+         {'name': 'h35_5',
+          'ip': '10.0.35.5/24',
+          'mac': '00:00:00:00:35:05',
+          'switch': 'sw6'},
+         {'name': 'h36_2',
+          'ip': '10.0.36.2/24',
+          'mac': '00:00:00:00:36:02',
+          'switch': 'sw1'},
+         {'name': 'h36_3',
+          'ip': '10.0.36.3/24',
+          'mac': '00:00:00:00:36:03',
+          'switch': 'sw1'},
+         {'name': 'h36_4',
+          'ip': '10.0.36.4/24',
+          'mac': '00:00:00:00:36:04',
+          'switch': 'sw6'},
+         {'name': 'h36_5',
+          'ip': '10.0.36.5/24',
+          'mac': '00:00:00:00:36:05',
+          'switch': 'sw6'}
+          ]
diff --git a/demos/gbpsfc-env/demo-asymmetric-chain/rest.py b/demos/gbpsfc-env/demo-asymmetric-chain/rest.py
new file mode 100644 (file)
index 0000000..8042637
--- /dev/null
@@ -0,0 +1,709 @@
+#!/usr/bin/python
+import argparse
+import requests,json
+from requests.auth import HTTPBasicAuth
+from subprocess import call
+import time
+import sys
+import os
+
+
+DEFAULT_PORT='8181'
+
+
+USERNAME='admin'
+PASSWORD='admin'
+
+
+CONF_TENANT='/restconf/config/policy:tenants'
+
+def get(host, port, uri):
+    url='http://'+host+":"+port+uri
+    r = requests.get(url, auth=HTTPBasicAuth(USERNAME, PASSWORD))
+    return r
+
+def put(host, port, uri, data, debug=False):
+    '''Perform a PUT rest operation, using the URL and data provided'''
+
+    url='http://'+host+":"+port+uri
+
+    headers = {'Content-type': 'application/yang.data+json',
+               'Accept': 'application/yang.data+json'}
+    if debug == True:
+        print "PUT %s" % url
+        print json.dumps(data, indent=4, sort_keys=True)
+    r = requests.put(url, data=json.dumps(data), headers=headers, auth=HTTPBasicAuth(USERNAME, PASSWORD))
+    if debug == True:
+        print r.text
+    r.raise_for_status()
+
+def post(host, port, uri, data, debug=False):
+    '''Perform a POST rest operation, using the URL and data provided'''
+
+    url='http://'+host+":"+port+uri
+    headers = {'Content-type': 'application/yang.data+json',
+               'Accept': 'application/yang.data+json'}
+    if debug == True:
+        print "POST %s" % url
+        print json.dumps(data, indent=4, sort_keys=True)
+    r = requests.post(url, data=json.dumps(data), headers=headers, auth=HTTPBasicAuth(USERNAME, PASSWORD))
+    if debug == True:
+        print r.text
+    r.raise_for_status()
+
+def wait_for_sff_in_datastore(url):
+    for i in xrange(30):
+        resp=get(controller, DEFAULT_PORT, url)
+        if ('192.168.50.71' in resp.text) and ('192.168.50.73' in resp.text):
+            break
+        time.sleep(3)
+    if ('192.168.50.71' not in resp.text):
+        print "ERROR: SFF1 has not been initialized!"
+        sys.exit(1)
+    if ('192.168.50.73' not in resp.text):
+        print "ERROR: SFF2 has not been initialized!"
+        sys.exit(1)
+
+
+
+def get_service_functions_uri():
+    return "/restconf/config/service-function:service-functions"
+
+def get_service_functions_data():
+    return {
+    "service-functions": {
+        "service-function": [
+            {
+                "name": "firewall-72",
+                "ip-mgmt-address": "192.168.50.72",
+                "type": "service-function-type:firewall",
+                "nsh-aware": "true",
+                "sf-data-plane-locator": [
+                    {
+                        "name": "2",
+                        "port": 6633,
+                        "ip": "192.168.50.72",
+                        "transport": "service-locator:vxlan-gpe",
+                        "service-function-forwarder": "SFF1"
+                    }
+                ]
+            },
+            {
+                "name": "dpi-74",
+                "ip-mgmt-address": "192.168.50.74",
+                "type": "service-function-type:dpi",
+                "nsh-aware": "true",
+                "sf-data-plane-locator": [
+                    {
+                        "name": "3",
+                        "port": 6633,
+                        "ip": "192.168.50.74",
+                        "transport": "service-locator:vxlan-gpe",
+                        "service-function-forwarder": "SFF2"
+                    }
+                ]
+            }
+        ]
+    }
+}
+
+def get_service_function_forwarders_uri():
+    return "/restconf/config/service-function-forwarder:service-function-forwarders"
+
+def get_service_function_forwarders_data():
+    return {
+    "service-function-forwarders": {
+        "service-function-forwarder": [
+            {
+                "name": "SFF1",
+                "service-node": "OVSDB2",
+                "service-function-forwarder-ovs:ovs-bridge": {
+                    "bridge-name": "sw2"
+                },
+                "service-function-dictionary": [
+                    {
+                        "name": "firewall-72",
+                        "sff-sf-data-plane-locator": {
+                            "sf-dpl-name": "2",
+                            "sff-dpl-name": "sfc-tun2"
+                        }
+                    }
+                ],
+                "sff-data-plane-locator": [
+                    {
+                        "name": "sfc-tun2",
+                        "data-plane-locator": {
+                            "transport": "service-locator:vxlan-gpe",
+                            "port": 6633,
+                            "ip": "192.168.50.71"
+                        },
+                        "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"
+                        }
+                    }
+                ]
+            },
+            {
+                "name": "SFF2",
+                "service-node": "OVSDB2",
+                "service-function-forwarder-ovs:ovs-bridge": {
+                    "bridge-name": "sw4"
+                },
+                "service-function-dictionary": [
+                    {
+                        "name": "dpi-74",
+                        "sff-sf-data-plane-locator": {
+                            "sf-dpl-name": "3",
+                            "sff-dpl-name": "sfc-tun4"
+                        }
+                    }
+                ],
+                "sff-data-plane-locator": [
+                    {
+                        "name": "sfc-tun4",
+                        "data-plane-locator": {
+                            "transport": "service-locator:vxlan-gpe",
+                            "port": 6633,
+                            "ip": "192.168.50.73"
+                        },
+                        "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"
+                        }
+                    }
+                ]
+            }
+        ]
+    }
+}
+
+def get_service_function_chains_uri():
+    return "/restconf/config/service-function-chain:service-function-chains/"
+
+def get_service_function_chains_data():
+    return {
+    "service-function-chains": {
+        "service-function-chain": [
+            {
+                "name": "SFCGBP",
+                "symmetric": "false",
+                "sfc-service-function": [
+                    {
+                        "name": "firewall-abstract1",
+                        "type": "service-function-type:firewall"
+                    },
+                    {
+                        "name": "dpi-abstract1",
+                        "type": "service-function-type:dpi"
+                    }
+                ]
+            }
+        ]
+    }
+}
+
+def get_service_function_paths_uri():
+    return "/restconf/config/service-function-path:service-function-paths/"
+
+def get_service_function_paths_data():
+    return {
+    "service-function-paths": {
+        "service-function-path": [
+            {
+                "name": "SFCGBP-Path",
+                "service-chain-name": "SFCGBP",
+                "starting-index": 255,
+                "symmetric": "false"
+
+            }
+        ]
+    }
+}
+
+def get_tenant_data():
+    return {
+    "tenant": [
+      {
+        "id": "tenant-dobre",
+        "l2-flood-domain": [
+          {
+            "id": "flood-domain-1",
+            "parent": "bridge-domain1"
+          },
+          {
+            "id": "flood-domain-2",
+            "parent": "bridge-domain1"
+          }
+        ],
+        "name": "DockerTenant",
+        "l3-context": [
+          {
+            "id": "l3-context-vrf-red"
+          }
+        ],
+        "l2-bridge-domain": [
+          {
+            "id": "bridge-domain1",
+            "parent": "l3-context-vrf-red"
+          }
+        ],
+        "subnet": [
+          {
+            "id": "subnet-10.0.36.0/24",
+            "virtual-router-ip": "10.0.36.1",
+            "parent": "flood-domain-2",
+            "ip-prefix": "10.0.36.1/24"
+          },
+          {
+            "id": "subnet-10.0.35.0/24",
+            "virtual-router-ip": "10.0.35.1",
+            "parent": "flood-domain-1",
+            "ip-prefix": "10.0.35.1/24"
+          }
+        ],
+        "endpoint-group": [
+          {
+            "id": "webservers",
+            "name" : "webservers",
+            "provider-named-selector": [
+              {
+                "name": "webservers-clients-icmp-http-contract",
+                "contract": [
+                  "icmp-http-contract"
+                ]
+              }
+            ]
+          },
+          {
+            "id": "clients",
+            "name" : "clients",
+            "consumer-named-selector": [
+              {
+                "name": "webservers-clients-icmp-http-contract",
+                "contract": [
+                  "icmp-http-contract"
+                ]
+              }
+            ]
+          }
+        ],
+        "subject-feature-instances": {
+          "classifier-instance": [
+            {
+              "name": "icmp",
+              "classifier-definition-id": "Classifier-IP-Protocol",
+              "parameter-value": [
+                {
+                  "name": "proto",
+                  "int-value": 1
+                }
+              ]
+            },
+            {
+              "name": "http-dest",
+              "classifier-definition-id": "Classifier-L4",
+              "parameter-value": [
+                {
+                  "int-value": "6",
+                  "name": "proto"
+                },
+                {
+                  "int-value": "80",
+                  "name": "destport"
+                }
+              ]
+            },
+            {
+              "name": "http-src",
+              "classifier-definition-id": "Classifier-L4",
+              "parameter-value": [
+                {
+                  "int-value": "6",
+                  "name": "proto"
+                },
+                {
+                  "int-value": "80",
+                  "name": "sourceport"
+                }
+              ]
+            }
+          ],
+          "action-instance": [
+            {
+              "name": "chain1",
+              "action-definition-id": "Action-Chain",
+              "parameter-value": [
+                {
+                  "name": "sfc-chain-name",
+                  "string-value": "SFCGBP"
+                }
+              ]
+            },
+            {
+              "name": "allow1",
+              "action-definition-id": "Action-Allow"
+            }
+          ]
+        },
+        "contract": [
+          {
+            "id": "icmp-http-contract",
+            "subject": [
+              {
+                "name": "icmp-subject",
+                "rule": [
+                  {
+                    "name": "allow-icmp-rule",
+                    "order" : 0,
+                    "classifier-ref": [
+                      {
+                        "name": "icmp",
+                       "instance-name" : "icmp"
+                      }
+                    ],
+                    "action-ref": [
+                      {
+                        "name": "allow1",
+                        "order": 0
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "name": "http-subject",
+                "rule": [
+                  {
+                    "name": "http-chain-rule",
+                    "classifier-ref": [
+                      {
+                        "name": "http-dest",
+                        "instance-name" : "http-dest",
+                        "direction": "in"
+                      }
+                    ],
+                    "action-ref": [
+                      {
+                        "name": "chain1",
+                        "order": 0
+                      }
+                    ]
+                  },
+                  {
+                    "name": "http-out-rule",
+                    "classifier-ref": [
+                      {
+                        "name": "http-src",
+                        "instance-name" : "http-src",
+                       "direction": "out"
+                      }
+                    ],
+                    "action-ref": [
+                      {
+                        "name": "allow1",
+                        "order": 0
+                      }
+                    ]
+                  }
+                ]
+              }
+            ],
+            "clause": [
+              {
+                "name": "icmp-http-clause",
+                "subject-refs": [
+                  "icmp-subject",
+                  "http-subject"
+                ]
+              }
+            ]
+          }
+        ]
+      }
+    ]
+}
+
+# Main definition - constants
+
+# =======================
+#     MENUS FUNCTIONS
+# =======================
+
+# Main menu
+
+# =======================
+#      MAIN PROGRAM
+# =======================
+
+# Main Program
+
+def get_tenant_uri():
+    return "/restconf/config/policy:tenants/policy:tenant/tenant-dobre"
+
+def get_tunnel_data_1():
+    return {
+    "node": [
+      {
+        "id": "openflow:1",
+        "ofoverlay:tunnel": [
+          {
+            "tunnel-type": "overlay:tunnel-type-vxlan-gpe",
+            "node-connector-id": "openflow:1:1",
+            "ip": "192.168.50.70",
+            "port": 6633
+          },
+          {
+            "tunnel-type": "overlay:tunnel-type-vxlan",
+            "node-connector-id": "openflow:1:2",
+            "ip": "192.168.50.70",
+            "port": 4789
+          }
+        ]
+      }
+    ]
+  }
+
+def get_tunnel_uri_1():
+    return "/restconf/config/opendaylight-inventory:nodes/node/openflow:1"
+
+def get_tunnel_data_6():
+    return {
+    "node": [
+      {
+        "id": "openflow:6",
+        "ofoverlay:tunnel": [
+          {
+            "tunnel-type": "overlay:tunnel-type-vxlan-gpe",
+            "node-connector-id": "openflow:6:1",
+            "ip": "192.168.50.75",
+            "port": 6633
+          },
+          {
+            "tunnel-type": "overlay:tunnel-type-vxlan",
+            "node-connector-id": "openflow:6:2",
+            "ip": "192.168.50.75",
+            "port": 4789
+          }
+        ]
+      }
+    ]
+  }
+
+def get_tunnel_uri_6():
+    return "/restconf/config/opendaylight-inventory:nodes/node/openflow:6"
+
+def get_endpoint_data():
+    return [
+{
+"input": {
+
+    "endpoint-group": "webservers",
+
+    "network-containment" : "subnet-10.0.36.0/24",
+
+    "l2-context": "bridge-domain1",
+    "mac-address": "00:00:00:00:36:02",
+
+    "l3-address": [
+        {
+            "ip-address": "10.0.36.2",
+            "l3-context": "l3-context-vrf-red"
+        }
+    ],
+    "port-name": "vethl-h36_2",
+    "tenant": "tenant-dobre"
+}
+},
+{
+"input": {
+    "endpoint-group": "clients",
+"network-containment" : "subnet-10.0.35.0/24",
+"l2-context": "bridge-domain1",
+"mac-address": "00:00:00:00:35:02",
+"l3-address": [
+    {
+        "ip-address": "10.0.35.2",
+        "l3-context": "l3-context-vrf-red"
+    }
+],
+"port-name": "vethl-h35_2",
+"tenant": "tenant-dobre"
+}
+},
+{
+"input": {
+
+    "endpoint-group": "clients",
+
+    "network-containment" : "subnet-10.0.35.0/24",
+
+    "l2-context": "bridge-domain1",
+    "mac-address": "00:00:00:00:35:03",
+
+    "l3-address": [
+        {
+            "ip-address": "10.0.35.3",
+            "l3-context": "l3-context-vrf-red"
+        }
+    ],
+    "port-name": "vethl-h35_3",
+    "tenant": "tenant-dobre"
+}
+},
+{
+"input": {
+
+    "endpoint-group": "webservers",
+
+    "network-containment" : "subnet-10.0.36.0/24",
+
+    "l2-context": "bridge-domain1",
+    "mac-address": "00:00:00:00:36:03",
+
+    "l3-address": [
+        {
+            "ip-address": "10.0.36.3",
+            "l3-context": "l3-context-vrf-red"
+        }
+    ],
+    "port-name": "vethl-h36_3",
+    "tenant": "tenant-dobre"
+}
+},
+{
+"input": {
+
+    "endpoint-group": "webservers",
+
+    "network-containment" : "subnet-10.0.36.0/24",
+
+    "l2-context": "bridge-domain1",
+    "mac-address": "00:00:00:00:36:04",
+
+    "l3-address": [
+        {
+            "ip-address": "10.0.36.4",
+            "l3-context": "l3-context-vrf-red"
+        }
+    ],
+    "port-name": "vethl-h36_4",
+    "tenant": "tenant-dobre"
+}
+},
+{
+"input": {
+
+    "endpoint-group": "clients",
+
+    "network-containment" : "subnet-10.0.35.0/24",
+
+    "l2-context": "bridge-domain1",
+    "mac-address": "00:00:00:00:35:04",
+
+    "l3-address": [
+        {
+            "ip-address": "10.0.35.4",
+            "l3-context": "l3-context-vrf-red"
+        }
+    ],
+    "port-name": "vethl-h35_4",
+    "tenant": "tenant-dobre"
+}
+},
+{
+"input": {
+
+    "endpoint-group": "clients",
+
+    "network-containment" : "subnet-10.0.35.0/24",
+
+    "l2-context": "bridge-domain1",
+    "mac-address": "00:00:00:00:35:05",
+
+    "l3-address": [
+        {
+            "ip-address": "10.0.35.5",
+            "l3-context": "l3-context-vrf-red"
+        }
+    ],
+    "port-name": "vethl-h35_5",
+    "tenant": "tenant-dobre"
+}
+},
+{
+"input": {
+
+    "endpoint-group": "webservers",
+
+    "network-containment" : "subnet-10.0.36.0/24",
+
+    "l2-context": "bridge-domain1",
+    "mac-address": "00:00:00:00:36:05",
+
+    "l3-address": [
+        {
+            "ip-address": "10.0.36.5",
+            "l3-context": "l3-context-vrf-red"
+        }
+    ],
+    "port-name": "vethl-h36_5",
+    "tenant": "tenant-dobre"
+}
+}]
+
+
+def get_endpoint_uri():
+    return "/restconf/operations/endpoint:register-endpoint"
+
+def get_tunnel_oper_uri():
+    return "/restconf/operational/opendaylight-inventory:nodes/"
+
+def get_topology_oper_uri():
+    return "/restconf/operational/network-topology:network-topology/topology/ovsdb:1/"
+
+if __name__ == "__main__":
+    # Launch main menu
+
+
+    # Some sensible defaults
+    controller=os.environ.get('ODL')
+    if controller == None:
+        sys.exit("No controller set.")
+
+    print "Contacting controller at %s" % controller
+    print "waiting for manager on SFFs..."
+    wait_for_sff_in_datastore(get_topology_oper_uri())
+    print "sending service functions"
+    put(controller, DEFAULT_PORT, get_service_functions_uri(), get_service_functions_data(), True)
+    print "sending service function forwarders"
+    put(controller, DEFAULT_PORT, get_service_function_forwarders_uri(), get_service_function_forwarders_data(), True)
+    print "waiting for switches on SFFs..."
+    wait_for_sff_in_datastore(get_tunnel_oper_uri())
+    print "sending service function chains"
+    put(controller, DEFAULT_PORT, get_service_function_chains_uri(), get_service_function_chains_data(), True)
+    print "sending service function paths"
+    put(controller, DEFAULT_PORT, get_service_function_paths_uri(), get_service_function_paths_data(), True)
+    print "sending tunnel"
+    put(controller, DEFAULT_PORT, get_tunnel_uri_1(), get_tunnel_data_1(), True)
+    print "sending tenant"
+    put(controller, DEFAULT_PORT, get_tunnel_uri_6(), get_tunnel_data_6(), True)
+    print "sending tenant"
+    put(controller, DEFAULT_PORT, get_tenant_uri(), get_tenant_data(),True)
+    print "registering endpoints"
+    for endpoint in get_endpoint_data():
+        post(controller, DEFAULT_PORT, get_endpoint_uri(),endpoint,True)
diff --git a/demos/gbpsfc-env/demo-asymmetric-chain/sf-config.sh b/demos/gbpsfc-env/demo-asymmetric-chain/sf-config.sh
new file mode 100644 (file)
index 0000000..b06a756
--- /dev/null
@@ -0,0 +1,17 @@
+#!/usr/bin/env bash
+
+set -e
+hostnum=${HOSTNAME#"gbpsfc"}
+sw="sw$hostnum"
+
+if [ "$hostnum" -eq "3" ]; then
+    TUNNEL=0xC0A83247
+elif [ "$hostnum" -eq "5" ]; then
+    TUNNEL=0xC0A83249
+else
+    echo "Invalid SF for this demo";
+    exit
+fi
+
+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
diff --git a/demos/gbpsfc-env/demo-gbp1/get-nsps.py b/demos/gbpsfc-env/demo-gbp1/get-nsps.py
new file mode 100644 (file)
index 0000000..c8ac97c
--- /dev/null
@@ -0,0 +1,8 @@
+#!/usr/bin/python
+
+if __name__ == "__main__":
+    # Launch main menu
+
+
+    # Some sensible defaults
+    print "Nothing"
diff --git a/demos/gbpsfc-env/demo-gbp1/infrastructure_config.py b/demos/gbpsfc-env/demo-gbp1/infrastructure_config.py
new file mode 100644 (file)
index 0000000..cc33d25
--- /dev/null
@@ -0,0 +1,67 @@
+# Config for switches, tunnelIP is the local IP address.
+switches = [
+            {'name': 'sw1',
+             'type': 'gbp',
+             'dpid': '1'},
+            {'name': 'sw2',
+             'type': 'gbp',
+             'dpid': '2'},
+            {'name': 'sw3',
+             'type': 'gbp',
+             'dpid': '3'},
+            {'name': 'sw4',
+             'type': 'none',
+             'dpid': '4'},
+            {'name': 'sw5',
+             'type': 'none',
+             'dpid': '5'},
+            {'name': 'sw6',
+             'type': 'none',
+             'dpid': '6'},
+            {'name': 'sw7',
+             'type': 'none',
+             'dpid': '7'},
+            {'name': 'sw8',
+             'type': 'none',
+             'dpid': '8'}
+           ]
+
+defaultContainerImage='alagalah/odlpoc_ovs230'
+#defaultContainerImage='ubuntu:14.04'
+
+#Note that tenant name and endpointGroup name come from policy_config.py
+
+hosts = [{'name': 'h35_2',
+          'mac': '00:00:00:00:35:02',
+          'ip': '10.0.35.2/24',
+          'switch': 'sw1'},
+         {'name': 'h35_3',
+          'ip': '10.0.35.3/24',
+          'mac': '00:00:00:00:35:03',
+          'switch': 'sw2'},
+         {'name': 'h35_4',
+          'ip': '10.0.35.4/24',
+          'mac': '00:00:00:00:35:04',
+          'switch': 'sw3'},
+         {'name': 'h35_5',
+          'ip': '10.0.35.5/24',
+          'mac': '00:00:00:00:35:05',
+          'switch': 'sw1'},
+         {'name': 'h36_2',
+          'ip': '10.0.36.2/24',
+          'mac': '00:00:00:00:36:02',
+          'switch': 'sw2'},
+         {'name': 'h36_3',
+          'ip': '10.0.36.3/24',
+          'mac': '00:00:00:00:36:03',
+          'switch': 'sw3'},
+         {'name': 'h36_4',
+          'ip': '10.0.36.4/24',
+          'mac': '00:00:00:00:36:04',
+          'switch': 'sw1'},
+         {'name': 'h36_5',
+          'ip': '10.0.36.5/24',
+          'mac': '00:00:00:00:36:05',
+          'switch': 'sw2'}
+          ]
+
diff --git a/demos/gbpsfc-env/demo-gbp1/rest.py b/demos/gbpsfc-env/demo-gbp1/rest.py
new file mode 100644 (file)
index 0000000..9b5ef32
--- /dev/null
@@ -0,0 +1,507 @@
+#!/usr/bin/python
+import argparse
+import requests,json
+from requests.auth import HTTPBasicAuth
+from subprocess import call
+import time
+import sys
+import os
+
+
+DEFAULT_PORT='8181'
+
+
+USERNAME='admin'
+PASSWORD='admin'
+
+
+OPER_NODES='/restconf/operational/opendaylight-inventory:nodes/'
+CONF_TENANT='/restconf/config/policy:tenants'
+
+def get(host, port, uri):
+    url='http://'+host+":"+port+uri
+    #print url
+    r = requests.get(url, auth=HTTPBasicAuth(USERNAME, PASSWORD))
+    jsondata=json.loads(r.text)
+    return jsondata
+
+def put(host, port, uri, data, debug=False):
+    '''Perform a PUT rest operation, using the URL and data provided'''
+
+    url='http://'+host+":"+port+uri
+
+    headers = {'Content-type': 'application/yang.data+json',
+               'Accept': 'application/yang.data+json'}
+    if debug == True:
+        print "PUT %s" % url
+        print json.dumps(data, indent=4, sort_keys=True)
+    r = requests.put(url, data=json.dumps(data), headers=headers, auth=HTTPBasicAuth(USERNAME, PASSWORD))
+    if debug == True:
+        print r.text
+    r.raise_for_status()
+
+def post(host, port, uri, data, debug=False):
+    '''Perform a POST rest operation, using the URL and data provided'''
+
+    url='http://'+host+":"+port+uri
+    headers = {'Content-type': 'application/yang.data+json',
+               'Accept': 'application/yang.data+json'}
+    if debug == True:
+        print "POST %s" % url
+        print json.dumps(data, indent=4, sort_keys=True)
+    r = requests.post(url, data=json.dumps(data), headers=headers, auth=HTTPBasicAuth(USERNAME, PASSWORD))
+    if debug == True:
+        print r.text
+    r.raise_for_status()
+    
+
+def get_tenant_data():
+    return {
+    "policy:tenant": {
+        "contract": [
+            {
+                "clause": [
+                    {
+                        "name": "allow-http-clause", 
+                        "subject-refs": [
+                            "allow-http-subject", 
+                            "allow-icmp-subject"
+                        ]
+                    }
+                ], 
+                "id": "icmp-http-contract", 
+                "subject": [
+                    {
+                        "name": "allow-http-subject", 
+                        "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-http-rule"
+                            }
+                        ]
+                    }, 
+                    {
+                        "name": "allow-icmp-subject", 
+                        "rule": [
+                            {
+                                "classifier-ref": [
+                                    {
+                                        "name": "icmp",
+                                       "instance-name" : "icmp"
+                                    }
+                                ], 
+                                                    "action-ref": [
+                      {
+                        "name": "allow1",
+                        "order": 0
+                      }
+                    ],
+
+                                "name": "allow-icmp-rule"
+                            }
+                        ]
+                    }
+                ]
+            }
+        ], 
+        "endpoint-group": [
+            {
+                "consumer-named-selector": [
+                    {
+                        "contract": [
+                            "icmp-http-contract"
+                        ], 
+                        "name": "webservers-clients-icmp-http-contract"
+                    }
+                ], 
+                "id": "clients", 
+                "provider-named-selector": []
+            }, 
+            {
+                "consumer-named-selector": [], 
+                "id": "webservers", 
+                "provider-named-selector": [
+                    {
+                        "contract": [
+                            "icmp-http-contract"
+                        ], 
+                        "name": "webservers-clients-icmp-http-contract"
+                    }
+                ]
+            }
+        ], 
+        "id": "tenant-dobre", 
+        "l2-bridge-domain": [
+            {
+                "id": "bridge-domain1", 
+                "parent": "l3-context-vrf-red"
+            }
+        ], 
+        "l2-flood-domain": [
+            {
+                "id": "flood-domain-1", 
+                "parent": "bridge-domain1"
+            }, 
+            {
+                "id": "flood-domain1", 
+                "parent": "bridge-domain1"
+            }
+        ], 
+        "l3-context": [
+            {
+                "id": "l3-context-vrf-red"
+            }
+        ], 
+        "name": "GBPPOC", 
+        "subject-feature-instances": {
+            "classifier-instance": [
+                {
+                    "classifier-definition-id": "Classifier-L4",
+                    "name": "http-dest", 
+                    "parameter-value": [
+                        {
+                            "int-value": "6", 
+                            "name": "proto"
+                        }, 
+                        {
+                            "int-value": "80", 
+                            "name": "destport"
+                        }
+                    ]
+                }, 
+                {
+                    "classifier-definition-id": "Classifier-L4",
+                    "name": "http-src", 
+                    "parameter-value": [
+                        {
+                            "int-value": "6", 
+                            "name": "proto"
+                        }, 
+                        {
+                            "int-value": "80", 
+                            "name": "sourceport"
+                        }
+                    ]
+                }, 
+                {
+                    "classifier-definition-id": "Classifier-IP-Protocol",
+                    "name": "icmp", 
+                    "parameter-value": [
+                        {
+                            "int-value": "1", 
+                            "name": "proto"
+                        }
+                    ]
+                }
+            ],
+          "action-instance": [
+            {
+              "name": "allow1",
+              "action-definition-id": "Action-Allow"
+            }
+          ]
+        }, 
+        "subnet": [
+            {
+                "id": "subnet-10.0.35.0/24", 
+                "ip-prefix": "10.0.35.1/24", 
+                "parent": "flood-domain-1", 
+                "virtual-router-ip": "10.0.35.1"
+            }, 
+            {
+                "id": "subnet-10.0.36.0/24", 
+                "ip-prefix": "10.0.36.1/24", 
+                "parent": "flood-domain1", 
+                "virtual-router-ip": "10.0.36.1"
+            }
+        ]
+    }
+            }
+
+# Main definition - constants
+# =======================
+#     MENUS FUNCTIONS
+# =======================
+# Main menu
+
+# =======================
+#      MAIN PROGRAM
+# =======================
+# Main Program
+
+def get_tenant_uri():
+    return "/restconf/config/policy:tenants/policy:tenant/tenant-dobre"
+
+def get_tunnel_data():
+    return {
+  "opendaylight-inventory:nodes": {
+    "node": [
+      {
+        "id": "openflow:1",
+        "ofoverlay:tunnel": [
+          {
+            "tunnel-type": "overlay:tunnel-type-vxlan-gpe",
+            "node-connector-id": "openflow:1:1",
+            "ip": "192.168.50.70",
+            "port": 6633
+          },
+          {
+            "tunnel-type": "overlay:tunnel-type-vxlan",
+            "node-connector-id": "openflow:1:2",
+            "ip": "192.168.50.70",
+            "port": 4789
+          }
+        ]
+      },
+      {
+        "id": "openflow:2",
+        "ofoverlay:tunnel": [
+          {
+            "tunnel-type": "overlay:tunnel-type-vxlan-gpe",
+            "node-connector-id": "openflow:2:1",
+            "ip": "192.168.50.71",
+            "port": 6633
+          },
+          {
+            "tunnel-type": "overlay:tunnel-type-vxlan",
+            "node-connector-id": "openflow:2:2",
+            "ip": "192.168.50.71",
+            "port": 4789
+          }
+        ]
+      },
+                   {
+        "id": "openflow:3",
+        "ofoverlay:tunnel": [
+          {
+            "tunnel-type": "overlay:tunnel-type-vxlan-gpe",
+            "node-connector-id": "openflow:3:1",
+            "ip": "192.168.50.72",
+            "port": 6633
+          },
+          {
+            "tunnel-type": "overlay:tunnel-type-vxlan",
+            "node-connector-id": "openflow:3:2",
+            "ip": "192.168.50.72",
+            "port": 4789
+          }
+        ]
+      },
+             
+    ]
+  }
+            }
+    
+def get_tunnel_uri():
+    return "/restconf/config/opendaylight-inventory:nodes"
+
+def get_endpoint_data():
+    return [{
+    "input": {
+
+        "endpoint-group": "clients", 
+
+        "network-containment" : "subnet-10.0.35.0/24",
+
+        "l2-context": "bridge-domain1", 
+        "mac-address": "00:00:00:00:35:02", 
+
+        "l3-address": [
+            {
+                "ip-address": "10.0.35.2", 
+                "l3-context": "l3-context-vrf-red"
+            }
+        ], 
+        "port-name": "vethl-h35_2", 
+        "tenant": "tenant-dobre"
+    }
+},
+            {
+    "input": {
+
+        "endpoint-group": "clients", 
+
+        "network-containment" : "subnet-10.0.35.0/24",
+
+        "l2-context": "bridge-domain1", 
+        "mac-address": "00:00:00:00:35:03", 
+
+        "l3-address": [
+            {
+                "ip-address": "10.0.35.3", 
+                "l3-context": "l3-context-vrf-red"
+            }
+        ], 
+        "port-name": "vethl-h35_3", 
+        "tenant": "tenant-dobre"
+    }
+},
+            {
+    "input": {
+
+        "endpoint-group": "clients", 
+
+        "network-containment" : "subnet-10.0.35.0/24",
+
+        "l2-context": "bridge-domain1", 
+        "mac-address": "00:00:00:00:35:04", 
+
+        "l3-address": [
+            {
+                "ip-address": "10.0.35.4", 
+                "l3-context": "l3-context-vrf-red"
+            }
+        ], 
+        "port-name": "vethl-h35_4", 
+        "tenant": "tenant-dobre"
+    }
+},
+            {
+    "input": {
+
+        "endpoint-group": "clients", 
+
+        "network-containment" : "subnet-10.0.35.0/24",
+
+        "l2-context": "bridge-domain1", 
+        "mac-address": "00:00:00:00:35:05", 
+
+        "l3-address": [
+            {
+                "ip-address": "10.0.35.5", 
+                "l3-context": "l3-context-vrf-red"
+            }
+        ], 
+        "port-name": "vethl-h35_5", 
+        "tenant": "tenant-dobre"
+    }
+},
+            {
+    "input": {
+
+        "endpoint-group": "webservers", 
+
+        "network-containment" : "subnet-10.0.36.0/24",
+
+        "l2-context": "bridge-domain1", 
+        "mac-address": "00:00:00:00:36:02", 
+
+        "l3-address": [
+            {
+                "ip-address": "10.0.36.2", 
+                "l3-context": "l3-context-vrf-red"
+            }
+        ], 
+        "port-name": "vethl-h36_2", 
+        "tenant": "tenant-dobre"
+    }
+},
+            {
+    "input": {
+
+        "endpoint-group": "webservers", 
+
+        "network-containment" : "subnet-10.0.36.0/24",
+
+        "l2-context": "bridge-domain1", 
+        "mac-address": "00:00:00:00:36:03", 
+
+        "l3-address": [
+            {
+                "ip-address": "10.0.36.3", 
+                "l3-context": "l3-context-vrf-red"
+            }
+        ], 
+        "port-name": "vethl-h36_3", 
+        "tenant": "tenant-dobre"
+    }
+},
+            {
+    "input": {
+
+        "endpoint-group": "webservers", 
+
+        "network-containment" : "subnet-10.0.36.0/24",
+
+        "l2-context": "bridge-domain1", 
+        "mac-address": "00:00:00:00:36:04", 
+
+        "l3-address": [
+            {
+                "ip-address": "10.0.36.4", 
+                "l3-context": "l3-context-vrf-red"
+            }
+        ], 
+        "port-name": "vethl-h36_4", 
+        "tenant": "tenant-dobre"
+    }
+},{
+    "input": {
+
+        "endpoint-group": "webservers", 
+
+        "network-containment" : "subnet-10.0.36.0/24",
+
+        "l2-context": "bridge-domain1", 
+        "mac-address": "00:00:00:00:36:05", 
+
+        "l3-address": [
+            {
+                "ip-address": "10.0.36.5", 
+                "l3-context": "l3-context-vrf-red"
+            }
+        ], 
+        "port-name": "vethl-h36_5", 
+        "tenant": "tenant-dobre"
+    }
+}]
+
+def get_endpoint_uri():
+    return "/restconf/operations/endpoint:register-endpoint"
+
+if __name__ == "__main__":
+    # Launch main menu
+
+
+    # Some sensible defaults
+    controller=os.environ.get('ODL')
+    if controller == None:
+        sys.exit("No controller set.")
+    
+
+    print "tenants"
+    tenants=get(controller,DEFAULT_PORT,CONF_TENANT)
+    print tenants
+    
+    print "sending tenant"
+    put(controller, DEFAULT_PORT, get_tenant_uri(), get_tenant_data(),True)
+    print "sending tunnel"
+    put(controller, DEFAULT_PORT, get_tunnel_uri(), get_tunnel_data(), True)
+    print "registering endpoints"
+    for endpoint in get_endpoint_data():
+        post(controller, DEFAULT_PORT, get_endpoint_uri(),endpoint,True)
+        
+        
+    
+    
diff --git a/demos/gbpsfc-env/demo-symmetric-chain/get-nsps.py b/demos/gbpsfc-env/demo-symmetric-chain/get-nsps.py
new file mode 100644 (file)
index 0000000..94650e8
--- /dev/null
@@ -0,0 +1,60 @@
+#!/usr/bin/python
+import socket
+import requests,json
+from requests.auth import HTTPBasicAuth
+import sys
+import os
+from subprocess import check_output
+from infrastructure_config import *
+
+
+DEFAULT_PORT='8181'
+USERNAME='admin'
+PASSWORD='admin'
+
+def get(host, port, uri):
+    url='http://'+host+":"+port+uri
+    #print url
+    r = requests.get(url, auth=HTTPBasicAuth(USERNAME, PASSWORD))
+    jsondata=json.loads(r.text)
+    return jsondata
+
+
+def get_rsps_uri():
+       return "/restconf/operational/rendered-service-path:rendered-service-paths"
+
+def doCmd(cmd):
+    listcmd=cmd.split()
+    print check_output(listcmd)
+
+if __name__ == "__main__":
+    # Launch main menu
+
+
+    # Some sensible defaults
+    controller=os.environ.get('ODL')
+    if controller == None:
+        sys.exit("No controller set.")
+    #else:
+       #print "Contacting controller at %s" % controller
+
+    resp=get(controller,DEFAULT_PORT,get_rsps_uri())
+    if len(resp['rendered-service-paths']) > 0:
+       paths=resp['rendered-service-paths']['rendered-service-path']
+
+       nsps=[]
+       for path in paths:
+           nsps.append(path['path-id'])
+       if len(nsps) > 0:
+           sw_index=int(socket.gethostname().split("gbpsfc",1)[1])-1
+           if sw_index in range(0,len(switches)+1):
+
+              controller=os.environ.get('ODL')
+              sw_type = switches[sw_index]['type']
+              sw_name = switches[sw_index]['name']
+              if sw_type == 'sf':
+                  print "******************************"
+                  print "Adding flows for %s as an SF." % sw_name
+                  print "******************************"
+                  doCmd('sudo /vagrant/utils/sf-flows.sh %s' % min(nsps))
+
diff --git a/demos/gbpsfc-env/demo-symmetric-chain/infrastructure_config.py b/demos/gbpsfc-env/demo-symmetric-chain/infrastructure_config.py
new file mode 100644 (file)
index 0000000..efdcfc9
--- /dev/null
@@ -0,0 +1,65 @@
+# Config for switches, tunnelIP is the local IP address.
+switches = [
+            {'name': 'sw1',
+             'type': 'gbp',
+             'dpid': '1'},
+            {'name': 'sw2',
+             'type': 'sff',
+             'dpid': '2'},
+            {'name': 'sw3',
+             'type': 'sf',
+             'dpid': '3'},
+            {'name': 'sw4',
+             'type': 'sff',
+             'dpid': '4'},
+            {'name': 'sw5',
+             'type': 'sf',
+             'dpid': '5'},
+            {'name': 'sw6',
+             'type': 'gbp',
+             'dpid': '6'},
+            {'name': 'sw7',
+             'type': 'none',
+             'dpid': '7'},
+            {'name': 'sw8',
+             'type': 'none',
+             'dpid': '8'}
+           ]
+
+defaultContainerImage='alagalah/odlpoc_ovs230'
+
+#Note that tenant name and endpointGroup name come from policy_config.py
+
+hosts = [{'name': 'h35_2',
+          'mac': '00:00:00:00:35:02',
+          'ip': '10.0.35.2/24',
+          'switch': 'sw1'},
+         {'name': 'h35_3',
+          'ip': '10.0.35.3/24',
+          'mac': '00:00:00:00:35:03',
+          'switch': 'sw1'},
+         {'name': 'h35_4',
+          'ip': '10.0.35.4/24',
+          'mac': '00:00:00:00:35:04',
+          'switch': 'sw6'},
+         {'name': 'h35_5',
+          'ip': '10.0.35.5/24',
+          'mac': '00:00:00:00:35:05',
+          'switch': 'sw6'},
+         {'name': 'h36_2',
+          'ip': '10.0.36.2/24',
+          'mac': '00:00:00:00:36:02',
+          'switch': 'sw1'},
+         {'name': 'h36_3',
+          'ip': '10.0.36.3/24',
+          'mac': '00:00:00:00:36:03',
+          'switch': 'sw1'},
+         {'name': 'h36_4',
+          'ip': '10.0.36.4/24',
+          'mac': '00:00:00:00:36:04',
+          'switch': 'sw6'},
+         {'name': 'h36_5',
+          'ip': '10.0.36.5/24',
+          'mac': '00:00:00:00:36:05',
+          'switch': 'sw6'}
+          ]
diff --git a/demos/gbpsfc-env/demo-symmetric-chain/rest.py b/demos/gbpsfc-env/demo-symmetric-chain/rest.py
new file mode 100644 (file)
index 0000000..5eb35bc
--- /dev/null
@@ -0,0 +1,711 @@
+#!/usr/bin/python
+import argparse
+import requests,json
+from requests.auth import HTTPBasicAuth
+from subprocess import call
+import time
+import sys
+import os
+
+
+DEFAULT_PORT='8181'
+
+
+USERNAME='admin'
+PASSWORD='admin'
+
+
+OPER_NODES='/restconf/operational/opendaylight-inventory:nodes/'
+CONF_TENANT='/restconf/config/policy:tenants'
+
+def get(host, port, uri):
+    url='http://'+host+":"+port+uri
+    r = requests.get(url, auth=HTTPBasicAuth(USERNAME, PASSWORD))
+    return r
+
+def put(host, port, uri, data, debug=False):
+    '''Perform a PUT rest operation, using the URL and data provided'''
+
+    url='http://'+host+":"+port+uri
+
+    headers = {'Content-type': 'application/yang.data+json',
+               'Accept': 'application/yang.data+json'}
+    if debug == True:
+        print "PUT %s" % url
+        print json.dumps(data, indent=4, sort_keys=True)
+    r = requests.put(url, data=json.dumps(data), headers=headers, auth=HTTPBasicAuth(USERNAME, PASSWORD))
+    if debug == True:
+        print r.text
+    r.raise_for_status()
+
+def post(host, port, uri, data, debug=False):
+    '''Perform a POST rest operation, using the URL and data provided'''
+
+    url='http://'+host+":"+port+uri
+    headers = {'Content-type': 'application/yang.data+json',
+               'Accept': 'application/yang.data+json'}
+    if debug == True:
+        print "POST %s" % url
+        print json.dumps(data, indent=4, sort_keys=True)
+    r = requests.post(url, data=json.dumps(data), headers=headers, auth=HTTPBasicAuth(USERNAME, PASSWORD))
+    if debug == True:
+        print r.text
+    r.raise_for_status()
+
+def wait_for_sff_in_datastore(url):
+    for i in xrange(30):
+        resp=get(controller, DEFAULT_PORT, url)
+        if ('192.168.50.71' in resp.text) and ('192.168.50.73' in resp.text):
+            break
+        time.sleep(3)
+    if ('192.168.50.71' not in resp.text):
+        print "ERROR: SFF1 has not been initialized!"
+        sys.exit(1)
+    if ('192.168.50.73' not in resp.text):
+        print "ERROR: SFF2 has not been initialized!"
+        sys.exit(1)
+
+
+
+
+def get_service_functions_uri():
+    return "/restconf/config/service-function:service-functions"
+
+def get_service_functions_data():
+    return {
+    "service-functions": {
+        "service-function": [
+            {
+                "name": "firewall-72",
+                "ip-mgmt-address": "192.168.50.72",
+                "type": "service-function-type:firewall",
+                "nsh-aware": "true",
+                "sf-data-plane-locator": [
+                    {
+                        "name": "2",
+                        "port": 6633,
+                        "ip": "192.168.50.72",
+                        "transport": "service-locator:vxlan-gpe",
+                        "service-function-forwarder": "SFF1"
+                    }
+                ]
+            },
+            {
+                "name": "dpi-74",
+                "ip-mgmt-address": "192.168.50.74",
+                "type": "service-function-type:dpi",
+                "nsh-aware": "true",
+                "sf-data-plane-locator": [
+                    {
+                        "name": "3",
+                        "port": 6633,
+                        "ip": "192.168.50.74",
+                        "transport": "service-locator:vxlan-gpe",
+                        "service-function-forwarder": "SFF2"
+                    }
+                ]
+            }
+        ]
+    }
+}
+
+def get_service_function_forwarders_uri():
+    return "/restconf/config/service-function-forwarder:service-function-forwarders"
+
+def get_service_function_forwarders_data():
+    return {
+    "service-function-forwarders": {
+        "service-function-forwarder": [
+            {
+                "name": "SFF1",
+                "service-node": "OVSDB2",
+                "service-function-forwarder-ovs:ovs-bridge": {
+                    "bridge-name": "sw2"
+                },
+                "service-function-dictionary": [
+                    {
+                        "name": "firewall-72",
+                        "sff-sf-data-plane-locator": {
+                            "sf-dpl-name": "2",
+                            "sff-dpl-name": "sfc-tun2"
+                        }
+                    }
+                ],
+                "sff-data-plane-locator": [
+                    {
+                        "name": "sfc-tun2",
+                        "data-plane-locator": {
+                            "transport": "service-locator:vxlan-gpe",
+                            "port": 6633,
+                            "ip": "192.168.50.71"
+                        },
+                        "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"
+                        }
+                    }
+                ]
+            },
+            {
+                "name": "SFF2",
+                "service-node": "OVSDB2",
+                "service-function-forwarder-ovs:ovs-bridge": {
+                    "bridge-name": "sw4"
+                },
+                "service-function-dictionary": [
+                    {
+                        "name": "dpi-74",
+                        "sff-sf-data-plane-locator": {
+                            "sf-dpl-name": "3",
+                            "sff-dpl-name": "sfc-tun4"
+                        }
+                    }
+                ],
+                "sff-data-plane-locator": [
+                    {
+                        "name": "sfc-tun4",
+                        "data-plane-locator": {
+                            "transport": "service-locator:vxlan-gpe",
+                            "port": 6633,
+                            "ip": "192.168.50.73"
+                        },
+                        "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"
+                        }
+                    }
+                ]
+            }
+        ]
+    }
+}
+
+def get_service_function_chains_uri():
+    return "/restconf/config/service-function-chain:service-function-chains/"
+
+def get_service_function_chains_data():
+    return {
+    "service-function-chains": {
+        "service-function-chain": [
+            {
+                "name": "SFCGBP",
+                "symmetric": "true",
+                "sfc-service-function": [
+                    {
+                        "name": "firewall-abstract1",
+                        "type": "service-function-type:firewall"
+                    },
+                    {
+                        "name": "dpi-abstract1",
+                        "type": "service-function-type:dpi"
+                    }
+                ]
+            }
+        ]
+    }
+}
+
+def get_service_function_paths_uri():
+    return "/restconf/config/service-function-path:service-function-paths/"
+
+def get_service_function_paths_data():
+    return {
+    "service-function-paths": {
+        "service-function-path": [
+            {
+                "name": "SFCGBP-Path",
+                "service-chain-name": "SFCGBP",
+                "starting-index": 255,
+                "symmetric": "true"
+
+            }
+        ]
+    }
+}
+
+def get_tenant_data():
+    return {
+    "tenant": [
+      {
+        "id": "tenant-dobre",
+        "l2-flood-domain": [
+          {
+            "id": "flood-domain-1",
+            "parent": "bridge-domain1"
+          },
+          {
+            "id": "flood-domain-2",
+            "parent": "bridge-domain1"
+          }
+        ],
+        "name": "DockerTenant",
+        "l3-context": [
+          {
+            "id": "l3-context-vrf-red"
+          }
+        ],
+        "l2-bridge-domain": [
+          {
+            "id": "bridge-domain1",
+            "parent": "l3-context-vrf-red"
+          }
+        ],
+        "subnet": [
+          {
+            "id": "subnet-10.0.36.0/24",
+            "virtual-router-ip": "10.0.36.1",
+            "parent": "flood-domain-2",
+            "ip-prefix": "10.0.36.1/24"
+          },
+          {
+            "id": "subnet-10.0.35.0/24",
+            "virtual-router-ip": "10.0.35.1",
+            "parent": "flood-domain-1",
+            "ip-prefix": "10.0.35.1/24"
+          }
+        ],
+        "endpoint-group": [
+          {
+            "id": "webservers",
+            "name" : "webservers",
+            "provider-named-selector": [
+              {
+                "name": "webservers-clients-icmp-http-contract",
+                "contract": [
+                  "icmp-http-contract"
+                ]
+              }
+            ]
+          },
+          {
+            "id": "clients",
+            "name" : "clients",
+            "consumer-named-selector": [
+              {
+                "name": "webservers-clients-icmp-http-contract",
+                "contract": [
+                  "icmp-http-contract"
+                ]
+              }
+            ]
+          }
+        ],
+        "subject-feature-instances": {
+          "classifier-instance": [
+            {
+              "name": "icmp",
+              "classifier-definition-id": "Classifier-IP-Protocol",
+              "parameter-value": [
+                {
+                  "name": "proto",
+                  "int-value": 1
+                }
+              ]
+            },
+            {
+              "name": "http-dest",
+              "classifier-definition-id": "Classifier-L4",
+              "parameter-value": [
+                {
+                  "int-value": "6",
+                  "name": "proto"
+                },
+                {
+                  "int-value": "80",
+                  "name": "destport"
+                }
+              ]
+            },
+            {
+              "name": "http-src",
+              "classifier-definition-id": "Classifier-L4",
+              "parameter-value": [
+                {
+                  "int-value": "6",
+                  "name": "proto"
+                },
+                {
+                  "int-value": "80",
+                  "name": "sourceport"
+                }
+              ]
+            }
+          ],
+          "action-instance": [
+            {
+              "name": "chain1",
+              "action-definition-id": "Action-Chain",
+              "parameter-value": [
+                {
+                  "name": "sfc-chain-name",
+                  "string-value": "SFCGBP"
+                }
+              ]
+            },
+            {
+              "name": "allow1",
+              "action-definition-id": "Action-Allow"
+            }
+          ]
+        },
+        "contract": [
+          {
+            "id": "icmp-http-contract",
+            "subject": [
+              {
+                "name": "icmp-subject",
+                "rule": [
+                  {
+                    "name": "allow-icmp-rule",
+                    "order" : 0,
+                    "classifier-ref": [
+                      {
+                        "name": "icmp",
+                       "instance-name" : "icmp"
+                      }
+                    ],
+                    "action-ref": [
+                      {
+                        "name": "allow1",
+                        "order": 0
+                      }
+                    ]
+                  }
+
+                ]
+              },
+              {
+                "name": "http-subject",
+                "rule": [
+                  {
+                    "name": "http-chain-rule-in",
+                    "classifier-ref": [
+                      {
+                        "name" : "http-dest",
+                       "instance-name": "http-dest",
+                        "direction": "in"
+                      }
+                    ],
+                    "action-ref": [
+                      {
+                        "name": "chain1",
+                        "order": 0
+                      }
+                    ]
+                  },
+                  {
+                    "name": "http-chain-rule-out",
+                    "classifier-ref": [
+                      {
+                        "name" : "http-src",
+                       "instance-name": "http-src",
+                        "direction": "out"
+                      }
+                    ],
+                    "action-ref": [
+                      {
+                        "name": "chain1",
+                        "order": 0
+                      }
+                    ]
+                  }
+                ]
+              }
+            ],
+            "clause": [
+              {
+                "name": "icmp-http-clause",
+                "subject-refs": [
+                  "icmp-subject",
+                  "http-subject"
+                ]
+              }
+            ]
+          }
+        ]
+      }
+    ]
+}
+
+# Main definition - constants
+
+# =======================
+#     MENUS FUNCTIONS
+# =======================
+
+# Main menu
+
+# =======================
+#      MAIN PROGRAM
+# =======================
+
+# Main Program
+
+def get_tenant_uri():
+    return "/restconf/config/policy:tenants/policy:tenant/tenant-dobre"
+
+def get_tunnel_data_1():
+    return {
+    "node": [
+      {
+        "id": "openflow:1",
+        "ofoverlay:tunnel": [
+          {
+            "tunnel-type": "overlay:tunnel-type-vxlan-gpe",
+            "node-connector-id": "openflow:1:1",
+            "ip": "192.168.50.70",
+            "port": 6633
+          },
+          {
+            "tunnel-type": "overlay:tunnel-type-vxlan",
+            "node-connector-id": "openflow:1:2",
+            "ip": "192.168.50.70",
+            "port": 4789
+          }
+        ]
+      }
+    ]
+  }
+
+def get_tunnel_uri_1():
+    return "/restconf/config/opendaylight-inventory:nodes/node/openflow:1"
+
+def get_tunnel_data_6():
+    return {
+    "node": [
+      {
+        "id": "openflow:6",
+        "ofoverlay:tunnel": [
+          {
+            "tunnel-type": "overlay:tunnel-type-vxlan-gpe",
+            "node-connector-id": "openflow:6:1",
+            "ip": "192.168.50.75",
+            "port": 6633
+          },
+          {
+            "tunnel-type": "overlay:tunnel-type-vxlan",
+            "node-connector-id": "openflow:6:2",
+            "ip": "192.168.50.75",
+            "port": 4789
+          }
+        ]
+      }
+    ]
+}
+
+def get_tunnel_uri_6():
+    return "/restconf/config/opendaylight-inventory:nodes/node/openflow:6"
+
+def get_endpoint_data():
+    return [
+{
+"input": {
+
+    "endpoint-group": "webservers",
+
+    "network-containment" : "subnet-10.0.36.0/24",
+
+    "l2-context": "bridge-domain1",
+    "mac-address": "00:00:00:00:36:02",
+
+    "l3-address": [
+        {
+            "ip-address": "10.0.36.2",
+            "l3-context": "l3-context-vrf-red"
+        }
+    ],
+    "port-name": "vethl-h36_2",
+    "tenant": "tenant-dobre"
+}
+},
+{
+"input": {
+    "endpoint-group": "clients",
+"network-containment" : "subnet-10.0.35.0/24",
+"l2-context": "bridge-domain1",
+"mac-address": "00:00:00:00:35:02",
+"l3-address": [
+    {
+        "ip-address": "10.0.35.2",
+        "l3-context": "l3-context-vrf-red"
+    }
+],
+"port-name": "vethl-h35_2",
+"tenant": "tenant-dobre"
+}
+},
+{
+"input": {
+
+    "endpoint-group": "clients",
+
+    "network-containment" : "subnet-10.0.35.0/24",
+
+    "l2-context": "bridge-domain1",
+    "mac-address": "00:00:00:00:35:03",
+
+    "l3-address": [
+        {
+            "ip-address": "10.0.35.3",
+            "l3-context": "l3-context-vrf-red"
+        }
+    ],
+    "port-name": "vethl-h35_3",
+    "tenant": "tenant-dobre"
+}
+},
+{
+"input": {
+
+    "endpoint-group": "webservers",
+
+    "network-containment" : "subnet-10.0.36.0/24",
+
+    "l2-context": "bridge-domain1",
+    "mac-address": "00:00:00:00:36:03",
+
+    "l3-address": [
+        {
+            "ip-address": "10.0.36.3",
+            "l3-context": "l3-context-vrf-red"
+        }
+    ],
+    "port-name": "vethl-h36_3",
+    "tenant": "tenant-dobre"
+}
+},
+{
+"input": {
+
+    "endpoint-group": "webservers",
+
+    "network-containment" : "subnet-10.0.36.0/24",
+
+    "l2-context": "bridge-domain1",
+    "mac-address": "00:00:00:00:36:04",
+
+    "l3-address": [
+        {
+            "ip-address": "10.0.36.4",
+            "l3-context": "l3-context-vrf-red"
+        }
+    ],
+    "port-name": "vethl-h36_4",
+    "tenant": "tenant-dobre"
+}
+},
+{
+"input": {
+
+    "endpoint-group": "clients",
+
+    "network-containment" : "subnet-10.0.35.0/24",
+
+    "l2-context": "bridge-domain1",
+    "mac-address": "00:00:00:00:35:04",
+
+    "l3-address": [
+        {
+            "ip-address": "10.0.35.4",
+            "l3-context": "l3-context-vrf-red"
+        }
+    ],
+    "port-name": "vethl-h35_4",
+    "tenant": "tenant-dobre"
+}
+},
+{
+"input": {
+
+    "endpoint-group": "clients",
+
+    "network-containment" : "subnet-10.0.35.0/24",
+
+    "l2-context": "bridge-domain1",
+    "mac-address": "00:00:00:00:35:05",
+
+    "l3-address": [
+        {
+            "ip-address": "10.0.35.5",
+            "l3-context": "l3-context-vrf-red"
+        }
+    ],
+    "port-name": "vethl-h35_5",
+    "tenant": "tenant-dobre"
+}
+},
+{
+"input": {
+
+    "endpoint-group": "webservers",
+
+    "network-containment" : "subnet-10.0.36.0/24",
+
+    "l2-context": "bridge-domain1",
+    "mac-address": "00:00:00:00:36:05",
+
+    "l3-address": [
+        {
+            "ip-address": "10.0.36.5",
+            "l3-context": "l3-context-vrf-red"
+        }
+    ],
+    "port-name": "vethl-h36_5",
+    "tenant": "tenant-dobre"
+}
+}]
+
+def get_endpoint_uri():
+    return "/restconf/operations/endpoint:register-endpoint"
+
+def get_tunnel_oper_uri():
+    return "/restconf/operational/opendaylight-inventory:nodes/"
+
+def get_topology_oper_uri():
+    return "/restconf/operational/network-topology:network-topology/topology/ovsdb:1/"
+
+if __name__ == "__main__":
+    # Launch main menu
+
+
+    # Some sensible defaults
+    controller=os.environ.get('ODL')
+    if controller == None:
+        sys.exit("No controller set.")
+
+    print "Contacting controller at %s" % controller
+    print "waiting for manager on SFFs..."
+    wait_for_sff_in_datastore(get_topology_oper_uri())
+    print "sending service functions"
+    put(controller, DEFAULT_PORT, get_service_functions_uri(), get_service_functions_data(), True)
+    print "sending service function forwarders"
+    put(controller, DEFAULT_PORT, get_service_function_forwarders_uri(), get_service_function_forwarders_data(), True)
+    print "waiting for switches on SFFs..."
+    wait_for_sff_in_datastore(get_tunnel_oper_uri())
+    print "sending service function chains"
+    put(controller, DEFAULT_PORT, get_service_function_chains_uri(), get_service_function_chains_data(), True)
+    print "sending service function paths"
+    put(controller, DEFAULT_PORT, get_service_function_paths_uri(), get_service_function_paths_data(), True)
+    print "sending tunnel"
+    put(controller, DEFAULT_PORT, get_tunnel_uri_1(), get_tunnel_data_1(), True)
+    print "sending tenant"
+    put(controller, DEFAULT_PORT, get_tunnel_uri_6(), get_tunnel_data_6(), True)
+    print "sending tenant"
+    put(controller, DEFAULT_PORT, get_tenant_uri(), get_tenant_data(),True)
+    print "registering endpoints"
+    for endpoint in get_endpoint_data():
+        post(controller, DEFAULT_PORT, get_endpoint_uri(),endpoint,True)
diff --git a/demos/gbpsfc-env/demo-symmetric-chain/sf-config.sh b/demos/gbpsfc-env/demo-symmetric-chain/sf-config.sh
new file mode 100644 (file)
index 0000000..b06a756
--- /dev/null
@@ -0,0 +1,17 @@
+#!/usr/bin/env bash
+
+set -e
+hostnum=${HOSTNAME#"gbpsfc"}
+sw="sw$hostnum"
+
+if [ "$hostnum" -eq "3" ]; then
+    TUNNEL=0xC0A83247
+elif [ "$hostnum" -eq "5" ]; then
+    TUNNEL=0xC0A83249
+else
+    echo "Invalid SF for this demo";
+    exit
+fi
+
+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
diff --git a/demos/gbpsfc-env/dpdumpflows.py b/demos/gbpsfc-env/dpdumpflows.py
new file mode 100644 (file)
index 0000000..a920344
--- /dev/null
@@ -0,0 +1,17 @@
+#!/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
+
+
+
diff --git a/demos/gbpsfc-env/dumpflows.sh b/demos/gbpsfc-env/dumpflows.sh
new file mode 100644 (file)
index 0000000..ba8f271
--- /dev/null
@@ -0,0 +1,17 @@
+#!/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
+
diff --git a/demos/gbpsfc-env/env.sh b/demos/gbpsfc-env/env.sh
new file mode 100644 (file)
index 0000000..6931e28
--- /dev/null
@@ -0,0 +1,3 @@
+export NUM_NODES=6
+export ODL="192.168.50.1"
+export SUBNET="192.168.50."
diff --git a/demos/gbpsfc-env/flowcount.sh b/demos/gbpsfc-env/flowcount.sh
new file mode 100644 (file)
index 0000000..eea8ef9
--- /dev/null
@@ -0,0 +1,25 @@
+#!/usr/bin/env bash
+
+hostnum=${HOSTNAME#"gbpsfc"}
+sw="sw$hostnum"
+set -e
+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
+
diff --git a/demos/gbpsfc-env/infrastructure_launch.py b/demos/gbpsfc-env/infrastructure_launch.py
new file mode 100644 (file)
index 0000000..713aaef
--- /dev/null
@@ -0,0 +1,150 @@
+#!/usr/bin/python
+
+import socket
+import os
+import re
+import time
+import sys
+import ipaddr
+import commands
+from subprocess import call
+from subprocess import check_output
+from infrastructure_config import *
+
+def addController(sw, ip):
+    call(['ovs-vsctl', 'set-controller', sw, 'tcp:%s:6653' % ip ])
+
+def addManager(ip):
+    cmd="ovs-vsctl set-manager tcp:%s:6640" % ip
+    listcmd=cmd.split()
+    print check_output(listcmd)
+
+def addSwitch(name, dpid=None):
+    call(['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'
+            dpid=filler[:len(filler)-len(dpid)]+dpid
+        elif len(dpid) > 16:
+            print 'DPID: %s is too long' % dpid
+            sys.exit(3)
+        call(['ovs-vsctl','set','bridge', name,'other-config:datapath-id=%s'%dpid])
+
+def addHost(net, switch, name, ip, mac):
+    containerID=launchContainer()
+
+def setOFVersion(sw, version='OpenFlow13,OpenFlow12,OpenFlow10'):
+    call(['ovs-vsctl', 'set', 'bridge', sw, 'protocols={}'.format(version)])
+
+def addTunnel(sw, sourceIp=None):
+    ifaceName = '{}-vxlan-0'.format(sw)
+    cmd = ['ovs-vsctl', 'add-port', sw, ifaceName,
+           '--', 'set', 'Interface', ifaceName,
+           'type=vxlan',
+           'options:remote_ip=flow',
+           'options:key=flow']
+#    if sourceIp is not None:
+#        cmd.append('options:source_ip={}'.format(sourceIp))
+    call(cmd)
+
+def addGpeTunnel(sw, sourceIp=None):
+    ifaceName = '{}-vxlangpe-0'.format(sw)
+    cmd = ['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']
+#    if sourceIp is not None:
+#        cmd.append('options:source_ip={}'.format(sourceIp))
+    call(cmd)
+
+def launchContainer(host,containerImage):
+    containerID= check_output(['docker','run','-d','--net=none','--name=%s'%host['name'],'-h',host['name'],'-t', '-i','--privileged=True',containerImage,'/bin/bash']) #docker run -d --net=none --name={name} -h {name} -t -i {image} /bin/bash
+    #print "created container:", containerID[:-1]
+    return containerID[:-1] #Remove extraneous \n from output of above
+
+def connectContainerToSwitch(sw,host,containerID,of_port):
+    hostIP=host['ip']
+    mac=host['mac']
+    nw = ipaddr.IPv4Network(hostIP)
+    broadcast = "{}".format(nw.broadcast)
+    router = "{}".format(nw.network + 1)
+    cmd=['/vagrant/ovswork.sh',sw,containerID,hostIP,broadcast,router,mac,of_port,host['name']]
+    if host.has_key('vlan'):
+        cmd.append(host['vlan'])
+    call(cmd)
+
+def doCmd(cmd):
+    listcmd=cmd.split()
+    print check_output(listcmd)
+
+def launch(switches, hosts, contIP='127.0.0.1'):
+
+    for sw in switches:
+        addManager(contIP)
+        ports=0
+        first_host=True
+        for host in hosts:
+            if host['switch'] == sw['name']:
+                if first_host:
+                    dpid=sw['dpid']
+                    addSwitch(sw['name'],sw['dpid'])
+                    setOFVersion(sw['name'])
+                    addController(sw['name'], contIP)
+                    addGpeTunnel(sw['name'])
+                    addTunnel(sw['name'])
+                first_host=False
+                containerImage=defaultContainerImage #from Config
+                if host.has_key('container_image'): #from Config
+                    containerImage=host['container_image']
+                containerID=launchContainer(host,containerImage)
+                ports+=1
+                connectContainerToSwitch(sw['name'],host,containerID,str(ports))
+                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__" :
+#    print "Cleaning environment..."
+#    doCmd('/vagrant/clean.sh')
+    sw_index=int(socket.gethostname().split("gbpsfc",1)[1])-1
+    if sw_index in range(0,len(switches)+1):
+
+       controller=os.environ.get('ODL')
+       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
+           doCmd('ovs-vsctl show')
+           print
+           print "Docker containers:"
+           print "------------------"
+           doCmd('docker ps')
+           print "*****************************"
+       elif sw_type == 'sff':
+           print "*****************************"
+           print "Configuring %s as an SFF." % sw_name
+           print "*****************************"
+           doCmd('sudo ovs-vsctl set-manager tcp:%s:6640' % controller)
+           print
+       elif sw_type == 'sf':
+           print "*****************************"
+           print "Configuring %s as an SF." % sw_name
+           print "*****************************"
+           doCmd('sudo /vagrant/sf-config.sh')
+           #addGpeTunnel(switches[sw_index]['name'])
+
diff --git a/demos/gbpsfc-env/ovsinstall.sh b/demos/gbpsfc-env/ovsinstall.sh
new file mode 100644 (file)
index 0000000..472fceb
--- /dev/null
@@ -0,0 +1 @@
+curl https://raw.githubusercontent.com/pritesh/ovs/nsh-v8/third-party/start-ovs-deb.sh | bash
diff --git a/demos/gbpsfc-env/ovswork.sh b/demos/gbpsfc-env/ovswork.sh
new file mode 100644 (file)
index 0000000..b19835b
--- /dev/null
@@ -0,0 +1,84 @@
+#!/usr/bin/env bash
+set -e
+
+BRIDGE=$1
+GUEST_ID=$2
+IPADDR=$3
+BROADCAST=$4
+GWADDR=$5
+MAC=$6
+OF_PORT=$7
+GUESTNAME=$8
+VLANTAG=$9
+
+[ "$IPADDR" ] || {
+    echo "Syntax:"
+    echo "pipework <hostinterface> <guest> <ipaddr>/<subnet> <broadcast> <gateway> [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
+mkdir -p /var/run/netns
+rm -f /var/run/netns/$NSPID
+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
+ip link add name $LOCAL_IFNAME type veth peer name $GUEST_IFNAME
+ip link set $LOCAL_IFNAME up
+
+# Step 4: Adding the virtual interface to the bridge
+ip link set $GUEST_IFNAME netns $NSPID
+if [ "$VLANTAG" ]
+then
+       ovs-vsctl add-port $BRIDGE $LOCAL_IFNAME tag=$VLANTAG 
+       echo $LOCAL_IFNAME 
+else
+       ovs-vsctl add-port $BRIDGE $LOCAL_IFNAME 
+       echo $LOCAL_IFNAME
+fi
+
+# Step 5: Configure netwroking within the container
+ip netns exec $NSPID ip link set $GUEST_IFNAME name eth0
+ip netns exec $NSPID ip addr add $IPADDR broadcast $BROADCAST dev eth0
+ip netns exec $NSPID ifconfig eth0 hw ether $MAC 
+ip netns exec $NSPID ip addr add 127.0.0.1 dev lo
+ip netns exec $NSPID ip link set eth0 up
+ip netns exec $NSPID ip link set lo up
+ip netns exec $NSPID ip route add default via $GWADDR 
+
diff --git a/demos/gbpsfc-env/pollflows.sh b/demos/gbpsfc-env/pollflows.sh
new file mode 100644 (file)
index 0000000..108cf0e
--- /dev/null
@@ -0,0 +1,4 @@
+#!/usr/bin/env bash
+TABLE=$1
+watch -n 1 -d "flowCount.sh $1"
+
diff --git a/demos/gbpsfc-env/resetcontroller.sh b/demos/gbpsfc-env/resetcontroller.sh
new file mode 100644 (file)
index 0000000..ac72564
--- /dev/null
@@ -0,0 +1,11 @@
+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
diff --git a/demos/gbpsfc-env/rest-clean.py b/demos/gbpsfc-env/rest-clean.py
new file mode 100644 (file)
index 0000000..7481066
--- /dev/null
@@ -0,0 +1,124 @@
+#!/usr/bin/python
+import argparse
+import requests,json
+from requests.auth import HTTPBasicAuth
+from subprocess import call
+import time
+import sys
+import os
+
+
+DEFAULT_PORT='8181'
+
+
+USERNAME='admin'
+PASSWORD='admin'
+
+
+OPER_NODES='/restconf/operational/opendaylight-inventory:nodes/'
+CONF_TENANT='/restconf/config/policy:tenants'
+
+def get(host, port, uri):
+    url='http://'+host+":"+port+uri
+    r = requests.get(url, auth=HTTPBasicAuth(USERNAME, PASSWORD))
+    return r
+
+def rest_delete(host, port, uri, debug=False):
+    '''Perform a DELETE rest operation, using the URL and data provided'''
+    url='http://'+host+":"+port+uri
+    headers = {'Content-type': 'application/yang.data+json',
+               'Accept': 'application/yang.data+json'}
+    if debug == True:
+        print "DELETE %s" % url
+    r = requests.delete(url, headers=headers, auth=HTTPBasicAuth(USERNAME, PASSWORD))
+    if debug == True:
+        print r.text
+    r.raise_for_status()
+
+def post(host, port, uri, data, debug=False):
+    '''Perform a POST rest operation, using the URL and data provided'''
+    url='http://'+host+":"+port+uri
+    headers = {'Content-type': 'application/yang.data+json',
+               'Accept': 'application/yang.data+json'}
+    if debug == True:
+        print "POST %s" % url
+        print json.dumps(data, indent=4, sort_keys=True)
+    r = requests.post(url, data=json.dumps(data), headers=headers, auth=HTTPBasicAuth(USERNAME, PASSWORD))
+    if debug == True:
+        print r.text
+    r.raise_for_status()
+
+def get_service_functions_uri():
+    return "/restconf/config/service-function:service-functions"
+
+def get_service_function_forwarders_uri():
+    return "/restconf/config/service-function-forwarder:service-function-forwarders"
+
+def get_service_function_chains_uri():
+    return "/restconf/config/service-function-chain:service-function-chains/"
+
+def get_service_function_paths_uri():
+    return "/restconf/config/service-function-path:service-function-paths/"
+
+def get_tenant_uri():
+    return "/restconf/config/policy:tenants/policy:tenant/f5c7d344-d1c7-4208-8531-2c2693657e12"
+
+def get_tunnel_uri():
+    return "/restconf/config/opendaylight-inventory:nodes"
+
+def get_endpoint_uri():
+    return "/restconf/operations/endpoint:unregister-endpoint"
+
+def get_topology_uri():
+    return "/restconf/config/network-topology:network-topology/topology/ovsdb:1"
+
+if __name__ == "__main__":
+    # Launch main menu
+
+
+    # Some sensible defaults
+    controller=os.environ.get('ODL')
+    if controller == None:
+        sys.exit("No controller set.")
+    else:
+       print "Contacting controller at %s" % controller
+
+    resp=get(controller,DEFAULT_PORT,'/restconf/operational/endpoint:endpoints')
+    resp_json=json.loads(resp.text)
+    l2_eps=resp_json['endpoints']['endpoint']
+    l3_eps=resp_json['endpoints']['endpoint-l3']
+
+    print "deleting service function paths"
+    rest_delete(controller, DEFAULT_PORT, get_service_function_paths_uri(), True)
+
+    print "deleting service function chains"
+    rest_delete(controller, DEFAULT_PORT, get_service_function_chains_uri(), True)
+
+    print "deleting service functions"
+    rest_delete(controller, DEFAULT_PORT, get_service_functions_uri(), True)
+
+    print "deleting service function forwarders"
+    rest_delete(controller, DEFAULT_PORT, get_service_function_forwarders_uri(), True)
+
+    print "deleting tunnel"
+    rest_delete(controller, DEFAULT_PORT, get_tunnel_uri(), True)
+
+    print "deleting tenant"
+    rest_delete(controller, DEFAULT_PORT, get_tenant_uri(), True)
+
+    print "unregistering L2 endpoints"
+    for endpoint in l2_eps:
+       data={ "input": { "l2": [ { "l2-context": endpoint['l2-context'] ,"mac-address": endpoint['mac-address'] } ] } }
+        post(controller, DEFAULT_PORT, get_endpoint_uri(),data,True)
+
+    print "unregistering L3 endpoints"
+    for endpoint in l3_eps:
+       data={ "input": { "l3": [ { "l3-context": endpoint['l3-context'] ,"ip-address": endpoint['ip-address'] } ] } }
+        post(controller, DEFAULT_PORT, get_endpoint_uri(),data,True)
+
+    print "topology removed check"
+    resp=get(controller, DEFAULT_PORT, get_topology_uri())
+    topology_json=json.loads(resp.text)
+    if resp.status_code == requests.codes.ok:
+        print "WARNING: Topology %s has not been removed! Removing now..." % get_topology_uri()
+        rest_delete(controller, DEFAULT_PORT, get_topology_uri(), True)
diff --git a/demos/gbpsfc-env/sf-config.sh b/demos/gbpsfc-env/sf-config.sh
new file mode 100644 (file)
index 0000000..b06a756
--- /dev/null
@@ -0,0 +1,17 @@
+#!/usr/bin/env bash
+
+set -e
+hostnum=${HOSTNAME#"gbpsfc"}
+sw="sw$hostnum"
+
+if [ "$hostnum" -eq "3" ]; then
+    TUNNEL=0xC0A83247
+elif [ "$hostnum" -eq "5" ]; then
+    TUNNEL=0xC0A83249
+else
+    echo "Invalid SF for this demo";
+    exit
+fi
+
+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
diff --git a/demos/gbpsfc-env/startdemo.sh b/demos/gbpsfc-env/startdemo.sh
new file mode 100644 (file)
index 0000000..382b8df
--- /dev/null
@@ -0,0 +1,43 @@
+#!/usr/bin/env bash
+
+set -e
+
+demo=${1%/}
+
+echo $demo
+
+if [ -f "demo.lock" ]; then
+    echo "There is already a demo running:"
+    cat demo.lock
+    exit
+fi
+
+cp $demo/infrastructure_config.py .
+
+if [ -f $demo/sf-config.sh ]; then
+    cp $demo/sf-config.sh .
+fi
+
+echo "Starting demo from $demo with vars:"
+echo "Number of nodes: " $NUM_NODES
+echo "Opendaylight Controller: " $ODL
+echo "Base subnet: " $SUBNET
+
+for i in `seq 1 $NUM_NODES`; do
+  hostname="gbpsfc"$i
+  echo $hostname
+  vagrant ssh $hostname -c "sudo -E /vagrant/infrastructure_launch.py"
+done
+
+echo "Configuring controller..."
+./$demo/rest.py
+
+echo "Post-controller configuration..."
+for i in `seq 1 $NUM_NODES`; do
+  hostname="gbpsfc"$i
+  echo $hostname
+  cp $demo/get-nsps.py .
+  vagrant ssh $hostname -c "sudo -E /vagrant/get-nsps.py"
+done
+echo "$demo" > demo.lock
+
diff --git a/demos/gbpsfc-env/traceflow.sh b/demos/gbpsfc-env/traceflow.sh
new file mode 100644 (file)
index 0000000..ca2426e
--- /dev/null
@@ -0,0 +1 @@
+ovs-appctl ofproto/trace $1
diff --git a/demos/gbpsfc-env/utils/hosts b/demos/gbpsfc-env/utils/hosts
new file mode 100644 (file)
index 0000000..bfc4bfd
--- /dev/null
@@ -0,0 +1,12 @@
+127.0.0.1      localhost
+192.168.50.70  gbpsfc1
+192.168.50.71  gbpsfc2
+192.168.50.72  gbpsfc3
+192.168.50.73   gbpsfc4
+192.168.50.74   gbpsfc5
+192.168.50.75   gbpsfc6
+
+# The following lines are desirable for IPv6 capable hosts
+::1     localhost ip6-localhost ip6-loopback
+ff02::1 ip6-allnodes
+ff02::2 ip6-allrouters
diff --git a/demos/gbpsfc-env/utils/setuphosts.sh b/demos/gbpsfc-env/utils/setuphosts.sh
new file mode 100644 (file)
index 0000000..2a73259
--- /dev/null
@@ -0,0 +1,11 @@
+#!/usr/bin/env bash
+
+set -e
+
+for i in `seq 1 $NUM_NODES`; do
+  hostname="gbpsfc"$i
+  echo $hostname
+  vagrant ssh $hostname -c "sudo cp /vagrant/utils/hosts /etc/hosts"
+done
+
diff --git a/demos/gbpsfc-env/utils/sf-config.sh b/demos/gbpsfc-env/utils/sf-config.sh
new file mode 100644 (file)
index 0000000..7f86790
--- /dev/null
@@ -0,0 +1,13 @@
+#!/usr/bin/env bash
+
+set -e
+hostnum=${HOSTNAME#"gbpsfc"}
+sw="sw$hostnum"
+sudo ovs-vsctl add-br $sw
+ovs-vsctl add-port $sw sfc-tun$hostnum -- set interface sfc-tun$hostnum type=vxlan options:remote_ip=flow options:dst_port=6633 options:key=flow options:nsi=flow options:nsp=flow options:"nshc1"=flow options:"nshc2"=flow options:"nshc3"=flow options:"nshc4"=flow
+
+sudo ovs-ofctl add-flow $sw "priority=1000,nsp=1,nsi=255 actions=move:NXM_NX_NSH_C1[]->NXM_NX_NSH_C1[],move:NXM_NX_NSH_C2[]->NXM_NX_NSH_C2[],move:NXM_NX_TUN_ID[0..31]->NXM_NX_TUN_ID[0..31],load:0xC0A83247->NXM_NX_TUN_IPV4_DST[],set_nsi:254,set_nsp:1,IN_PORT" -OOpenFlow13
+sudo ovs-ofctl add-flow $sw "priority=1000,nsp=1,nsi=254 actions=move:NXM_NX_NSH_C1[]->NXM_NX_NSH_C1[],move:NXM_NX_NSH_C2[]->NXM_NX_NSH_C2[],move:NXM_NX_TUN_ID[0..31]->NXM_NX_TUN_ID[0..31],load:0xC0A83249->NXM_NX_TUN_IPV4_DST[],set_nsi:253,set_nsp:1,IN_PORT" -OOpenFlow13
+
+sudo ovs-ofctl add-flow $sw "priority=1000,nsp=2,nsi=255 actions=move:NXM_NX_NSH_C1[]->NXM_NX_NSH_C1[],move:NXM_NX_NSH_C2[]->NXM_NX_NSH_C2[],move:NXM_NX_TUN_ID[0..31]->NXM_NX_TUN_ID[0..31],load:0xC0A83249->NXM_NX_TUN_IPV4_DST[],set_nsi:254,set_nsp:2,IN_PORT" -OOpenFlow13
+sudo ovs-ofctl add-flow $sw "priority=1000,nsp=2,nsi=254 actions=move:NXM_NX_NSH_C1[]->NXM_NX_NSH_C1[],move:NXM_NX_NSH_C2[]->NXM_NX_NSH_C2[],move:NXM_NX_TUN_ID[0..31]->NXM_NX_TUN_ID[0..31],load:0xC0A83247->NXM_NX_TUN_IPV4_DST[],set_nsi:253,set_nsp:2,IN_PORT" -OOpenFlow13
diff --git a/demos/gbpsfc-env/utils/sf-flows.sh b/demos/gbpsfc-env/utils/sf-flows.sh
new file mode 100644 (file)
index 0000000..f4ee649
--- /dev/null
@@ -0,0 +1,20 @@
+#!/usr/bin/env bash
+
+set -e
+hostnum=${HOSTNAME#"gbpsfc"}
+sw="sw$hostnum"
+nsp=$1
+
+if [ "$hostnum" -eq "3" ]; then
+    TUNNEL=0xC0A83247
+elif [ "$hostnum" -eq "5" ]; then
+    TUNNEL=0xC0A83249
+else
+    echo "Invalid SF for this demo";
+    exit
+fi
+# delete NORMAL, if present
+nsphex=`printf "%x\n" $nsp`
+sudo ovs-ofctl --strict del-flows $sw priority=0
+sudo ovs-ofctl add-flow $sw "priority=1000,nsi=255 actions=move:NXM_NX_NSH_C1[]->NXM_NX_NSH_C1[],move:NXM_NX_NSH_C2[]->NXM_NX_NSH_C2[],move:NXM_NX_TUN_ID[0..31]->NXM_NX_TUN_ID[0..31],load:$TUNNEL->NXM_NX_TUN_IPV4_DST[],set_nsi:254,IN_PORT" -OOpenFlow13
+sudo ovs-ofctl add-flow $sw "priority=1000,nsi=254 actions=move:NXM_NX_NSH_C1[]->NXM_NX_NSH_C1[],move:NXM_NX_NSH_C2[]->NXM_NX_NSH_C2[],move:NXM_NX_TUN_ID[0..31]->NXM_NX_TUN_ID[0..31],load:$TUNNEL->NXM_NX_TUN_IPV4_DST[],set_nsi:253,IN_PORT" -OOpenFlow13
diff --git a/demos/gbpsfc-env/vmclean.sh b/demos/gbpsfc-env/vmclean.sh
new file mode 100644 (file)
index 0000000..3974b38
--- /dev/null
@@ -0,0 +1,12 @@
+#!/usr/bin/env bash
+
+docker stop -t=1 $(docker ps -a -q) > /dev/null 2>&1
+docker rm $(docker ps -a -q) > /dev/null 2>&1
+
+/etc/init.d/openvswitch-switch stop > /dev/null
+rm /etc/openvswitch/conf.db > /dev/null
+/etc/init.d/openvswitch-switch start > /dev/null
+
+
+ovs-vsctl show
+