首页 > 代码库 > [转]Openflow Lab
[转]Openflow Lab
GETTING STARTED OPENFLOW OPENVSWITCH TUTORIAL LAB : SETUP
For a more up to date tutorial as anything more then 6 months old is outdated in the world of SDN Please see:
OpenDaylight OpenStack Integration with DevStack on Fedora 20
I wrote a Python OpenFlow installation app to automate an OpenFlow KVM and Open vSwitch setup found at:
OpenFlow, OpenvSwitch and KVM SDN Lab Installation App →
GETTING STARTED OPENFLOW OPENVSWITCH TUTORIAL LAB – SETUP:
Getting Started OpenFlow OpenvSwitch Tutorial Lab : This is an OpenFlow Tutorial using OpenvSwitch and Floodlight controller but any other controller or switch can be used. I have had some requests on some scenarios so I put this together. Adding a few more flexible components. Getting to know all of these packages like KVM, OpenvSwitch are going to be pretty big in the future ecosystem orchestrations.
The video doesn’t have any sound, I am tight on time, sorry. I think it should be pretty straightforward and the video may help if you get stuck. Probably a couple typos here and there I will try and catch over the weekend. We are lacking good lab material on these topics right now so maybe this will save a couple folks some time.
PREREQUISITES
The KVM requires an x86 machine with either Intel VT or AMD w/AMD-V support. Anything fairly new will have that support in the processor. There are a few older HW builds that support hardware assisted virtualization by enabling it in the bios. Pretty much Googling your machine for hardware virtualization will let you know. Qemu can be run on non VT HW but the machines will probably get brutalized by a few host VMs. When you are setting up the vSwitch either have an out of band or be on it physically. Be careful when you are adding multiple interfaces to bridges since you can spin up a bridging loop pretty quickly unless you have STP on. I recommend a test/dev network or mom’s basement network. If not BPDUguard is your friend This is done on a fresh install of 64-bit Ubuntu 12.04 (Precise).
Quick screencast. I highly recommend considering using a small Linux Kernel named linux-0.2.img.bz2 from Qemu if using a laptop or nested hypervisor.
Shell
$nano /etc/network/interfaces
Add in your configuration to the file to your physical interface and save the file.
Restart networking. If the configuration is off this will cut you off.
$/etc/init.d/networking restart
$route -n will display your default route if you are having connectivity issues.
$apt-get update
$apt-get dist-upgrade
INSTALL OPENVSWITCH
Shell
$ apt-get install openvswitch-datapath-source bridge-utils
$ module-assistant auto-install openvswitch-datapath
$ apt-get install openvswitch-common
Verify install
$ovs-vsctl show
ovs_version: “1.4.0+build0″
Processes should look something like this
$ps -ea | grep ovs
26464 ? 00:00:00 ovsdb-server
26465 ? 00:00:00 ovsdb-server
26473 ? 00:00:00 ovs-vswitchd
26474 ? 00:00:00 ovs-vswitchd
26637 ? 00:00:00 ovs-controller
$ /etc/init.d/openvswitch-switch restart
Add your bridge, think of this as a subnet if you aren’t familiar with the term.
Add a physical interface to your virtual bridge for connectivity off box. If you don’t script this part you will probably clip your connection as you zero out eth0 and apply it to br-int. You can pop the commands into a text file and make it executable with
chmod +x script.sh
Shell
$ ovs-vsctl add-br br-int
$ ovs-vsctl add-port br-int eth0
$ ifconfig eth0 0
#Zero out your eth0 interface and slap it on the bridge interface
#(warning will clip you unless you script it)
$ifconfig br-int 192.168.1.208 netmask 255.255.255.0
#Change your default route
$route add default gw 192.168.1.1 br-int and $route del default gw 192.168.1.1 eth0
INSTALL FLOODLIGHT OPENFLOW CONTROLLER AND ATTACH OPENVSWITCH
Install dependencies, apt-get for UB and yum for RH:
Shell
apt-get install build-essential default-jdk ant python-dev eclipse git
Clone the Github project and build the jar and start the controller:
Shell
$git clone git://github.com/floodlight/floodlight.git
cd into the floodlight directory created.
$cd floodlight
Run ant to build a jar. It will be in the ~/floodlight/target directory.
$ant
Run the controller :
$java -jar target/floodlight.jar
By default it will binds to port 6633 and all ports e.g. 0.0.0.0/0.0.0.0:6633
ATTACH OPENVSWITCH TO THE CONTROLLER
Shell
$ovs-vsctl set-controller br-int tcp:192.168.1.208:6633
In the FloodLight console you will see something like this:
Shell
[New I/O server worker #1-1] INFO n.f.core.internal.Controller - Switch handshake successful: OFSwitchImpl [/192.168.1.208:49519 DPID[00:00:ba:66:35:e8:38:48]]
The output of OVS ‘ovs-vsctl show’ looks something like this:
Shell
# ovs-vsctl show
70a40219-8725-46a8-b808-af75c642cac8
Bridge "br-int"
Controller "tcp:192.168.1.208:6633"
is_connected: true
Port "eth0"
Interface "eth0"
Port "br-int"
Interface "br-int"
type: internal
ovs_version: "1.4.0+build0"
INSTALL KVM AND INTEGRATE INTO OVS
Shell
$apt-get install kvm uml-utilities
These two scripts bring up the KVM Tap interfaces into your bridge from the CLI. If you copy and paste below make sure the (‘) does not get formatted improperly. It should be yellow in nano. “switch=br-int” br-int is the name of your bridge in OVS.
$nano /etc/ovs-ifup (open and paste what is below)
Shell
#!/bin/sh
switch=‘br-int‘
/sbin/ifconfig $1 0.0.0.0 up
ovs-vsctl add-port ${switch} $1
$nano /etc/ovs-ifdown (open and paste what is below)
Shell
#!/bin/sh
switch=‘br-int‘
/sbin/ifconfig $1 0.0.0.0 down
ovs-vsctl del-port ${switch} $1
Make both files executable
chmod +x /etc/ovs-ifup /etc/ovs-ifdown
BOOT THE GUEST VIRTUAL MACHINES
- Host1
Shell
kvm -m 512 -net nic,macaddr=00:00:00:00:cc:10 -net tap,script=/etc/ovs-ifup,downscript=/etc/ovs-ifdown -cdrom ubuntu-12.04-desktop-amd64.iso
- Host2
Shell
kvm -m 512 -net nic,macaddr=00:11:22:CC:CC:10 -net tap,script=/etc/ovs-ifup,downscript=/etc/ovs-ifdown -cdrom ubuntu-12.04-desktop-amd64.iso
- Host3
Shell
kvm -m 512 -net nic,macaddr=22:22:22:00:cc:10 -net tap,script=/etc/ovs-ifup,downscript=/etc/ovs-ifdown -cdrom ubuntu-12.04-desktop-amd64.iso
Each one of those will begin loading from the ISO. I just click “Try Ubuntu” when they are booting and just run them from disk since really all we need are nodes that can test connectivity as we push static flows. If it is a more permanent test lab it would make since to install them to disk.
While those are spinning up let’s install curl.
Shell
$apt-get install curl
Figure 1. OVS Taps
One they are up assign IP addresses to them by clicking in the top left of the Ubuntu window and type in ‘terminal’ no parentheses. Then give them IPs if you want to statically assign them with ifconfig.
Shell
sudo ifconfig eth0 192.168.1.x netmask 255.255.255.0
OPENFLOW STARTER TUTORIAL LAB #1
For a more up to date tutorial as anything more then 6 months old is outdated in the world of SDN Please see:
OpenDaylight OpenStack Integration with DevStack on Fedora 20
- Lab 1: Add static destination MAC addresses to each node. Match: DstMac: , Action:DstPortX
- Lab 2: Add static flow with src mac address match with the associated action to an output port e.g. Match:SrcMac Action:DstPortY.
- Lab 3: Add a bad static flow for one of the hosts and watch ICMP replies from the gateway on the board port come back through tcpdump. Match:DstMac, Action:PortZ
Figure 1. The topology for the lab simulates in software the same capabilities you can get in hardware thanks to OpenvSwitch.[/crayon]
This setup allows you to add and remove as many matches into the API calls and tinker with them to get a feel once you nail down the basics. Then you can write the next “killer app” get rich and make it rain, but first lets figure out what is going on here.
RESTFUL/JSON API
The API is documented very well (that is huge and differentiating IMO) @
Shell
<a href=http://www.mamicode.com/"http://www.openflowhub.org/display/floodlightcontroller/Proposed+New+API">http://www.openflowhub.org/display/floodlightcontroller/Proposed+New+API
RESTful APIs are very important in my opinion if there is to be a transition of any kind to make it human readable for at the least troubleshooting or easy field parsing programmaticlaly for those of us who are only willing to muck our way through interpreted languages. Huge fan of what they have done here with their API and I expect the industry to follow this.
FORWARDING TABLE IN OPENVSWITCH
Based on ‘ovs-appctl fdb/show br-int’ build your cheat sheet so see what port your host VMs are on inside of OpenvSwitch. If you do not see your entry it has like timed out ~300 seconds or so, refresh the entry by simply pinging the host VM from the vSwitch. These tables are the same as your CAM tables doing key/value exact matches for L2 mac address lookups and LPM (Longest Prefix Match) in todays network systems only in software.
Shell
$ovs-appctl fdb/show br-int
port VLAN MAC Age
1 0 00:23:69:62:26:09 58
6 0 00:11:22:cc:cc:10 7
5 0 00:00:00:00:cc:10 4
0 0 5c:26:0a:5a:c8:b2 3
7 0 22:22:22:00:cc:10 3
MAC tables for this lab are as follows. Yours will likely be different based on the assignment by the vSwitch. The mac addresses are specifed by the KVM boot but anything can be used as long they are unique.
The DPID datapath ID is required to send the API calls. You need to find the one on your vSwitch. Lots of ways to find it either through the Floodlight console or APIs or from the ovs-ofctl show <bridge name> listed below. It is basically a few bytes prepended on your Nics MAC address).
Shell
$ ovs-ofctl show br-int
OFPT_FEATURES_REPLY (xid=0x1): ver:0x1, dpid:00005c260a5ac8b2 (that is your DPID)
Replace the curl commands with your DPID curl -d ‘{“switch”: “00:00:5c:26:0a:5a:c8:b2″, (that longer than usual mac looking ID)
“ovs-dpctl dump-flows br-int” will display the datapaths being instantiated into the OpenvSwitch and handy for debugging and tshooting.
Figure2. MAC to Port mapping or forwarding table for the labs. Build this from “ovs-appctl fdb/show br-int” output.
Throughout the lab I have my VM hosts pinging the gateway so I can watch what happens as I instantiate static flows into the OpenvSwitch (OVS) flow table.
OPENFLOW WEBUI GUI
Through the lab for starters it might be easier for some to watch the web page. This is a nice Django front end put together by Wes Felter and some of his guys at IBM. There are some bugs which I’m sure the Floodlight guys would like anyone to clean up. If you leave the page open it continues to refresh until it consumes the planet as it polls the controller. Just close and reopen every now and then.
The WebUI loads be default with the jar binary:
Shell
java -jar floodlight.jar
Shell
http://<yourIP>:8080/ui/index.html
Figure 3. WebUI starts automatically and binds to port 8080
It might be more comfortable for some to use the WebUI / GUI. It is a nice clean web front at that!
All three labs are in this screencast.
LAB 1 STATIC MAC ENTRIES FOR OUR 3 HOSTS
Figure 3. Three hosts with static mac entries for each port.
STATIC FLOW PUSH INTO THE OPENFLOW PIPELINE
Before we run we crawl, before we dynamically forward we statically forward! It seems natural that most of the time we start with static entries when teaching the mechanics of routing with network IGPs. Here we are defining static data paths. We match (or don’t) a rule and have an associated action to it that will eventually kick off a fairly complex sets of flow tables in a pipeline in v1.1 and up.
The fairly close command for a data path in a tradiational instruction set on today’s switches would be this ‘”mac-address-table static 0000.0000.cc10 vlan 100 interface GigabitEthernet0/1″. We are not setting a vlan id but would be as easy as adding “dataLayerVirtualLan”:x to the flow push. That is obviously not scalable but I think it is important to understand how datapaths get pushed to the OF enabled switch. Normally even in the SDN world those mac address are learned through flooding to all ports FFFF.FFFF.FFFF on the broadcast domain. The controller than learns of it starts a mac address timer to begin to age it out if no more traffic is received so as not to exhaust the it’s tables but cache it if it continues talking by restarting the timer each time a frame is received from the MAC source.
Push static flows for each destination mac address in the switch to an assigned port. We have a match and action explicitly defined. All we are doing is adding static mac address entries instead of them being defined dynamically through flooding. Not each name is unique. If copying and pasting make sure to strip formatting.
As you add the flows keep in mind each curl you do will overwrite the previous one their with the same name in the table. Notice each flow pushed has a unique name. It’s almost ACLs but not quite.
- Install curl
Shell
$apt-get install curl
With OVS and the OF controller run each of these from your command line.
Remember to replace the DPID “switch”: “00:00:5c:26:0a:5a:c8:b2″ & the IP addr 192.168.1.208 with your lab addresses. Each curl command is one line.
INSTANTIATE THE OPENFLOW FORWARDING RULES
- Host 1
Shell
$ curl -d ‘{"switch": "00:00:5c:26:0a:5a:c8:b2", "name":"static-flow1", "cookie":"0", "priority":"32768", "dst-mac":"00:00:00:00:cc:10","active":"true", "actions":"output=5"}‘ http://192.168.1.208:8080/wm/staticflowentrypusher/json
- Host 2
Shell
$ curl -d ‘{"switch": "00:00:5c:26:0a:5a:c8:b2", "name":"static-flow2", "cookie":"0", "priority":"32768", "dst-mac":"00:11:22:cc:cc:10","active":"true", "actions":"output=6"}‘ http://192.168.1.208:8080/wm/staticflowentrypusher/json
- Host 3
Shell
$ curl -d ‘{"switch": "00:00:5c:26:0a:5a:c8:b2", "name":"static-flow3", "cookie":"0", "priority":"32768", "dst-mac":"22:22:22:00:cc:10","active":"true", "actions":"output=7"}‘ http://192.168.1.208:8080/wm/staticflowentrypusher/json
LIST THE FLOWS
Now through the API we can pull all static flows that have been pushed with this API call. Notice all of the Tuples (header fields e.g. SrcMac, Dest,IP etc) being listed. Look for the “match” and “action” you pushed.
Shell
$ curl http://192.168.1.208:8080/wm/staticflowentrypusher /list/00:00:5c:26:0a:5a:c8:b2/json
CLEAR OR DELETE THE STATIC FLOWS
To clear all of the static flows the API call looks like this. Clear all flows the API also has a delete function documented:
Shell
$ curl http://192.168.1.208:8080/wm/staticflowentrypusher /clear/00:00:5c:26:0a:5a:c8:b2/json
OPENFLOW STARTER TUTORIAL LAB #2
For a more up to date tutorial as anything more then 6 months old is outdated in the world of SDN Please see:
OpenDaylight OpenStack Integration with DevStack on Fedora 20
OpenFlow Starter Tutorial Lab #2 :This lab is to restrict two hosts to only talk to each other with source based forwarding using the static flow pusher RESTful API. You can add any field you want to make the forwarding decisions on. Remember to name the flows with unique names or else you will overwrite previously instantiated flows. Previous posts in the series have setup included. Links to those at the bottom of this post.
Figure 1. OpenFlow Starter Tutorial Lab #2 Topology
Based on source MAC address we can lock two ports into only talking to each other. This is used for security reasons today in sensitive areas. This allows for very granular port to port mapping. We are adding two flows, just as a host needs a flow setup to talk to another host it also needs a return flow to put established.
Delete old static Flows from Lab 1.
Shell
curl http://192.168.1.208:8080/wm/staticflowentrypusher/clear/00:00:5c:26:0a:5a:c8:b2/json
PUSH THE TWO STATIC OPENFLOW RESTFUL API CALLS TO CREATE YOUR FLOWMOD
Shell
#To ping from port 1 to 6
$curl -d ‘{"switch": "00:00:5c:26:0a:5a:c8:b2", "name":"static-flow1", "cookie":"0", "priority":"32768", "src-mac":"00:11:22:cc:cc:10","active":"true", "actions":"output=6"}‘ http://192.168.1.208:8080/wm/staticflowentrypusher/json
#To ping from port 6 to 1
$curl -d ‘{"switch": "00:00:5c:26:0a:5a:c8:b2", "name":"static-flow2", "cookie":"0", "priority":"32768", "src-mac":"22:22:22:00:cc:10","active":"true", "actions":"output=1"}‘ http://192.168.1.208:8080/wm/staticflowentrypusher/json
Ping the hosts from those two ports. They should only be able to ping each other not your gateway or anything else since the closets match is the static one pushed.
Once I add these may gateway no longer pings becuase the only place those to source mac addresses explicitly match on are eachothers ports. So while they can talk to each other they can not talk anywhere else.
While this is clearly not managable at scale, it should get the your wheels going on the possiblities this opens when you start thinking about how powerful this granularity can become in the security world if done programmatically from policy.
OPENFLOW STARTER TUTORIAL LAB #3
For a more up to date tutorial as anything more then 6 months old is outdated in the world of SDN Please see:
OpenDaylight OpenStack Integration with DevStack on Fedora 20
OpenFlow Starter Tutorial Lab #3 : Move individual flows
Pre-requisites install and the beginning of the lab can be found here.
Figure 1. OpenFlow starter tutorial Lab #3 topology. Add an entry to the wrong port and watch it break.
Let’s clear all of our flows and get everything pinging the gateway again.
Shell
$curl http://192.168.1.208:8080/wm/staticflowentrypusher /clear/00:00:5c:26:0a:5a:c8:b2/json
Add our three earlier entries from Lab1
Shell
$curl -d ‘{"switch": "00:00:5c:26:0a:5a:c8:b2", "name":"static-flow1", "cookie":"0", "priority":"32768", "dst-mac":"00:00:00:00:cc:10","active":"true", "actions":"output=5"}‘ http://192.168.1.208:8080/wm/staticflowentrypusher/json
Shell
curl -d ‘{"switch": "00:00:5c:26:0a:5a:c8:b2", "name":"static-flow2", "cookie":"0", "priority":"32768", "dst-mac":"00:11:22:cc:cc:10","active":"true", "actions":"output=6"}‘ http://192.168.1.208:8080/wm/staticflowentrypusher/json
Shell
$curl -d ‘{"switch": "00:00:5c:26:0a:5a:c8:b2", "name":"static-flow3", "cookie":"0", "priority":"32768", "dst-mac":"22:22:22:00:cc:10","active":"true", "actions":"output=7"}‘ http://192.168.1.208:8080/wm/staticflowentrypusher/json
TCPDUMP ANALYSIS
Start tcpdump on the host you will send Host3′s traffic to. In my case I am starting tcpdump on Host1 where I am going to send Host3′s traffic to.
Shell
$ sudo tcpdump -i eth0 host <IP of host 3>
The filter “host <ip>”says only capture traffic to or from that host. We should never see unicast traffic from one host to another under proper condictions on a packet switched network.
INSTANTIATE BAD FLOWS
Now lets push a mac to a bad port and watch it break. This will overwrite ‘static-flow3′. This will break Host 3.
Shell
$curl -d ‘{"switch": "00:00:5c:26:0a:5a:c8:b2", "name":"wrong-port", "cookie":"0", "priority":"32768", "dst-mac":"22:22:22:00:cc:10","active":"true", "actions":"output=5"}‘ http://192.168.1.208:8080/wm/staticflowentrypusher/json
Figure 2. TCPdump output when I push host 3′s forwarding datapath to host 1.
As soon as you added the “wrong-port” static flow you began getting ICMP replies from the gateway until that times out. This has many more security type implications. Why not have your action be forward to two ports instead of just one. The 2nd port could be an IDS monitoring traffic and instead of trying to process the firehose of traffic in a typical port mirror you can get as granular you want and watch only particular matching traffic as defined by the tuple matching in the header fields (src_mac,dst_ip,VID etc.). No you can use a fraction of the hardware and only process what is important to your use case. Load balancing is another obvious one. Policy routing that may be scalable if managed programmatically by northbound API’s.
Figure 3. The API is the end game IMO
CONCLUSION
Thats it hope this maybe demystifies a bit of OpenFlow for you. I still have lots to learn as it is never-ending cycle, but going through a couple of labs seems to help nail some of this down and show that with complexity or more accuraltely abstraction, will bring more simplicity to the operators(some day so very very very far away theoretically). This lab setup can scale out to a wide range of different scenarios then just the couple little guys here. Would love to hear what others are doing.
From an end user perspective, it is the same ideas we have had in best matching of prefixes all along but we are adding more ways to match and fields to match upon. The API is what is going to be very important in my opinion and will open up the value over the next coulple of years as the northbound apps begin to surface. Sorry there is not any commentary on the videos, swamped but I think its fairly straightforward. I only added the video in case someone gets stuck. Feel free to contact with assistance or jump on irc.freenode.net on #openflow.
MISCELLANEOUS API CALLS
Find all flows
Shell
$curl http://192.168.1.208:8080/wm/core/switch/ 00:00:5c:26:0a:5a:c8:b2/flow/json
List all static
Shell
$curl http://192.168.1.208:8080/wm/staticflowentrypusher/list/00:00:5c:26:0a:5a:c8:b2/json
Clear all flows
Shell
$curl http://192.168.1.208:8080/wm/staticflowentrypusher/clear/00:00:5c:26:0a:5a:c8:b2/json
ADDITIONAL OPENFLOW AND SDN LINKS AND RESOURCES
http://openvswitch.org/ Martin Casado’s group have put an amazing vSwitch out there. I doubt there will be many vSwitches that are not munging his work in some form or fashion over the next few years.
http://floodlight.openflowhub.org/ Thanks to Nick Bastin for answering my question on the #openflow channel. He is a great asset to the community.
http://www.noxrepo.org/ Another nice OpenFlow Controller is POX a Python based platform agnostic project the Murphy McCauley is doing a great job with. As soon as I dig into the API I am going to do a similar tutorial with that. I need the API docs if anyone has them hook me up.
I am typically always /nick networkstatic on irc.freenode.net in #openvswitch #openflow #openstack and #packetpushers if anyone has any questions.