Changes between Initial Version and Version 1 of GENIExperimenter/Tutorials/OpenFlowOVS-Floodlight/Execute


Ignore:
Timestamp:
10/30/16 00:58:21 (7 years ago)
Author:
pjayanth@bbn.com
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • GENIExperimenter/Tutorials/OpenFlowOVS-Floodlight/Execute

    v1 v1  
     1= [wiki:GENIExperimenter/Tutorials/OpenFlowOVS Intro to OpenFlow Tutorial] =
     2{{{
     3#!html
     4
     5<div style="text-align:center; width:495px; margin-left:auto; margin-right:auto;">
     6<img id="Image-Maps_5201305222028436" src="http://groups.geni.net/geni/attachment/wiki/GENIExperimenter/Tutorials/Graphics/Execute.jpg?format=raw" usemap="#Image-Maps_5201305222028436" border="0" width="495" height="138" alt="" />
     7<map id="_Image-Maps_5201305222028436" name="Image-Maps_5201305222028436">
     8<area shape="rect" coords="18,18,135,110" href="http://groups.geni.net/geni/wiki/GENIExperimenter/Tutorials/OpenFlowOVS-Floodlight/DesignSetup" alt="" title=""    />
     9<area shape="rect" coords="180,18,297,111" href="http://groups.geni.net/geni/wiki/GENIExperimenter/Tutorials/OpenFlowOVS-Floodlight/Execute" alt="" title=""    />
     10<area shape="rect" coords="344,17,460,110" href="http://groups.geni.net/geni/wiki/GENIExperimenter/Tutorials/OpenFlowOVS-Floodlight/Finish" alt="" title=""    />
     11<area shape="rect" coords="493,136,495,138" href="http://www.image-maps.com/index.php?aff=mapped_users_5201305222028436" alt="Image Map" title="Image Map" />
     12</map>
     13<!-- Image map text links - End - -->
     14
     15</div>
     16}}}
     17[[PageOutline]]
     18== Step 3. Execute Experiment ==
     19
     20Now that the switch is up and running we are ready to start working on the controller. For this tutorial we are going to use the [http://www.noxrepo.org/pox/about-pox/ POX controller]. The software is already installed in the controller host for running POX and can also be found [http://www.gpolab.bbn.com/experiment-support/OpenFlowOVS/of-ovs.tar.gz here].
     21
     22=== 3a. Login to your hosts ===
     23
     24To start our experiment we need to ssh all of our hosts.
     25
     26To get ready for the tutorial you will need to have the following windows open:
     27  * one window with ssh into the controller
     28  * four windows with ssh into OVS
     29  * one window with ssh into host1
     30  * two windows with ssh into host2
     31  * one window with ssh into host3
     32
     33Depending on which tool and OS you are using there is a slightly different process for logging in. If you don't know how to SSH to your reserved hosts learn [wiki:HowTo/LoginToNodes how to login.] Once you have logged in follow the rest of the instructions.
     34
     35=== 3b. Use a Learning Switch Controller ===
     36
     37In this example we are going to run a very simple learning switch controller to forward traffic between `host1` and `host2`.
     38 
     39  1. First start a ping from  `host1` to `host2`, which should timeout, since there is no controller running.
     40
     41{{{
     42ping host2 -c 10
     43}}}
     44
     45  2. We have installed the POX controller under `/tmp/pox` on the controller host. POX comes with a set of example modules that you can use out of the box. One of the modules is a learning switch.  Start the learning switch controller which is already available by running the following two commands:
     46
     47
     48{{{
     49#!html
     50
     51<table id="Table_01" border="0" cellpadding="5" cellspacing="0">
     52    <tr>
     53        <td>
     54            <img src="http://trac.gpolab.bbn.com/gcf/raw-attachment/wiki/Graphics/4NotesIcon_512x512.png" width="50" height="50" alt="Note">
     55               </td>
     56<td>If you want to run your controller in a different port other than the default one (6633) then every time you invoke pox you should include: <code>openflow.of_01 --port=<custom_port> </code> e.g. pox.py  openflow.of_01 --port=443 --verbose forwarding.l2_learning
     57</td>
     58        </tr>
     59</table>
     60}}}
     61
     62{{{
     63#!html
     64
     65<table id="Table_01" border="0" cellpadding="5" cellspacing="0">
     66    <tr>
     67        <td>
     68            <img src="http://trac.gpolab.bbn.com/gcf/raw-attachment/wiki/Graphics/4NotesIcon_512x512.png" width="50" height="50" alt="Note">
     69               </td>
     70<td>"l2" below uses the letter `l` as in level and is not the number one. And you should wait for the '''INFO ... connected''' line to ensure that the switch and the controller are communicating.
     71</td>
     72        </tr>
     73</table>
     74}}}
     75 
     76{{{
     77cd /tmp/pox
     78./pox.py --verbose forwarding.l2_learning
     79}}}
     80
     81The output should look like this:
     82{{{
     83POX 0.1.0 (betta) / Copyright 2011-2013 James McCauley, et al.
     84DEBUG:core:POX 0.1.0 (betta) going up...
     85DEBUG:core:Running on CPython (2.7.3/Apr 20 2012 22:39:59)
     86DEBUG:core:Platform is Linux-3.2.0-56-generic-x86_64-with-Ubuntu-12.04-precise
     87INFO:core:POX 0.1.0 (betta) is up.
     88DEBUG:openflow.of_01:Listening on 0.0.0.0:6633
     89INFO:openflow.of_01:[9e-38-3e-8d-42-42 1] connected
     90DEBUG:forwarding.l2_learning:Connection [9e-38-3e-8d-42-42 1]
     91}}}
     92
     93
     94{{{
     95#!html
     96
     97<table id="Table_01" border="0" cellpadding="5" cellspacing="0">
     98    <tr>
     99        <td>
     100            <img src="http://trac.gpolab.bbn.com/gcf/raw-attachment/wiki/Graphics/4NotesIcon_512x512.png" width="50" height="50" alt="Note">
     101               </td>
     102<td>In the event that you need to move the port of your controller, this is the command -
     103<pre>
     104sudo ./pox.py --verbose openflow.of_01 --port=443 forwarding.l2_learning
     105</pre>
     106  Do not forget to tell the ovs switch that the controller will be listening on this new port, i.e change 6633 to 443 in Step 2c.
     107</td>
     108        </tr>
     109</table>
     110}}}
     111
     112 3. In the terminal of `host1`, ping `host2`:
     113{{{
     114[experimenter@host1 ~]$ ping host2
     115PING host2-lan1 (10.10.1.2) 56(84) bytes of data.
     116From host1-lan0 (10.10.1.1) icmp_seq=2 Destination Host Unreachable
     117From host1-lan0 (10.10.1.1) icmp_seq=3 Destination Host Unreachable
     118From host1-lan0 (10.10.1.1) icmp_seq=4 Destination Host Unreachable
     11964 bytes from host2-lan1 (10.10.1.2): icmp_req=5 ttl=64 time=23.9 ms
     12064 bytes from host2-lan1 (10.10.1.2): icmp_req=6 ttl=64 time=0.717 ms
     12164 bytes from host2-lan1 (10.10.1.2): icmp_req=7 ttl=64 time=0.654 ms
     12264 bytes from host2-lan1 (10.10.1.2): icmp_req=8 ttl=64 time=0.723 ms
     12364 bytes from host2-lan1 (10.10.1.2): icmp_req=9 ttl=64 time=0.596 ms
     124}}}
     125
     126  Now the ping should work.
     127
     128  4. Go to your controller host and take a look at the print outs. You should see that your controller installed flows based on the mac addresses of your packets. 
     129
     130{{{
     131#!html
     132
     133<table id="Table_01" border="0" cellpadding="5" cellspacing="0">
     134    <tr>
     135        <td>
     136            <img src="http://trac.gpolab.bbn.com/gcf/raw-attachment/wiki/Graphics/4NotesIcon_512x512.png" width="50" height="50" alt="Note">
     137               </td>
     138<td>There is no way to get this information from the OpenFlow-capable hardware switch.
     139</td>
     140        </tr>
     141</table>
     142}}}
     143
     144=== 3b. Look around your OVS switch  ===
     145
     146  1. If you are using OVS, to see the flow table entries on your OVS switch:
     147{{{
     148sudo ovs-ofctl dump-flows br0
     149}}}
     150    You should see at least two table entries: One for ICMP Echo (icmp_type=8) messages from host1 to host2 and one for ICMP Echo Reply (icmp_type=0) messages from host2 to host1.  You may also see flow entries for arp packets.
     151
     152  2. To see messages go between your switch and your controller, open a new ssh window to your controller node and run tcpdump on the `eth0` interface and on the tcp port that your controller is listening on usually 6633.  (You can also run `tcpdump` on the `OVS` control interface if you desire.)
     153{{{
     154sudo tcpdump -i eth0 tcp port 6633
     155}}}
     156  You will see (1) periodic keepalive messages being exchanged by the switch and the controller, (2) messages from the switch to the controller (e.g. when there is a table miss) and an ICMP Echo message in, and (3) messages from the controller to the switch (e.g. to install new flow entries).
     157
     158  3. Kill your POX controller by pressing `Ctrl-C`:
     159{{{
     160DEBUG:forwarding.l2_learning:installing flow for 02:c7:e8:a7:40:65.1 -> 02:f1:ae:bb:e3:a8.2
     161INFO:core:Going down...
     162INFO:openflow.of_01:[3a-51-a1-ab-c3-43 1] disconnected
     163INFO:core:Down.
     164}}}
     165
     166  4. Notice what happens to your ping on host1.
     167
     168  5. If you are using OVS, check the flow table entries on your switch:
     169{{{
     170sudo ovs-ofctl dump-flows br0
     171}}}
     172  Since you set your switch to "secure" mode, i.e. don't forward packets if the controller fails, you will not see flow table entries.  If you see flow table entries, try again after 10 seconds to give the entries time to expire.
     173
     174
     175==== Soft vs Hard Timeouts ====
     176
     177All rules on the switch have two different timeouts:
     178
     179  * '''Soft Timeout''': This determines for how long the flow will remain in the forwarding table of the switch if there are no packets received that match the specific flow. As long as packets from that flow are received the flow remains on the flow table.
     180  * '''Hard Timeout''': This determines the total time that a flow will remain at the forwarding table, independent of whether packets that match the flow are received; i.e. the flow will be removed after the hard timeout expires.
     181
     182Can you tell now why there were packets flowing even after you killed your controller?
     183
     184=== 3d. Download the pox apps ===
     185To help you get started with your controller writing, we will provide:
     186  * skeleton files for the controllers where you only need to complete some missing functionality
     187  * the solution: fully implemented controllers
     188  * a utility library that makes some of the pox messages easier to write
     189
     190'''In the controller terminal execute''':
     191{{{
     192  cd /tmp/pox/ext
     193  wget http://www.gpolab.bbn.com/experiment-support/NFVApps/pox-intro-ctrlapps.tar.gz
     194  tar xvfz pox-intro-ctrlapps.tar.gz
     195}}}
     196==== Useful Tips for writing your controller ====
     197
     198In order to make this first experience of writing a controller easier, we wrote some helpful functions that will abstract some of the particularities of POX away.
     199These functions are located in `/tmp/pox/ext/utils.py`, so while you write your controller consult this file for details.
     200
     201Functions that are implemented include:
     202  * packetIsIP : Test if the packet is IP
     203  * packetIsARP : Test if the packet is ARP
     204  * packetIsRequestARP : Test if this is an ARP Request packet
     205  * packetIsReplyARP : Test if this is an ARP Reply packet
     206  * packetArpDstIp : Test what is the destination IP in an ARP packet
     207  * packetArpSrcIp : Test what is the sources IP in an ARP packet
     208  * packetIsTCP : Test if a packet is TCP
     209  * packetDstIp : Test the destination IP of a packet
     210  * packetSrcIp : Test the source IP of a packet
     211  * packetDstTCPPort : Test the destination TCP port of a packet
     212  * packetSrcTCPPort : Test the source TCP port of a packet
     213  * createOFAction : Create one OpenFlow action
     214  * getFullMatch : get the full match out of a packet
     215  * createFlowMod : create a flow mod
     216  * createArpRequest : Create an Arp Request for  a different destination IP
     217  * createArpReply : Create an Arp Reply for  a different source IP
     218
     219=== 3e. Debugging your Controller ===
     220While you are developing your controller, some useful debugging tools are:
     221
     222==== i. Print messages ====
     223Run your controller in verbose mode (add --verbose) and add print messages at various places to see what your controller is seeing.
     224
     225==== ii. Check the status in the switch ====
     226If you are using an OVS switch, you can dump information from your switch.  For example, to dump the flows:
     227{{{
     228sudo ovs-ofctl dump-flows br0
     229}}}
     230Two other useful commands show you the status of your switch:
     231{{{
     232sudo ovs-vsctl show
     233sudo ovs-ofctl show br0
     234}}}
     235
     236==== iii. Use Wireshark to see the OpenFlow messages ====
     237Many times it is useful to see the OpenFlow messages being exchanged between your controller and the switch. This will tell you whether the messages that are created by your controller are correct and will allow you to see the details of any errors you might be seeing from the switch. You can use wireshark on both ends of the connection, in hardware switches you have to rely only on the controller view.
     238
     239The controller host and OVS has wireshark installed, including the openflow dissector. For more information on wireshark you can take a look at the [http://wiki.wireshark.org/ wireshark wiki].
     240
     241Here we have a simple case of how to use the OpenFlow dissector for wireshark.
     242
     243If you are on a Linux friendly machine (this includes MACs) open a terminal and ssh to your controller machine using the -Y command line argument, i.e.
     244{{{
     245ssh -Y <username>@<controller>
     246}}}
     247
     248Assuming that the public IP address on the controller is eth0, run wireshark by typing:
     249{{{
     250sudo wireshark -i eth0&
     251}}}
     252
     253When the wireshark window pops up, you might still have to choose eth0 for a live capture.  And you will want to use a filter to cut down on the chatter in the wireshark window.   One such filter might be just seeing what shows up on port 6633. To do that type ''tcp.port eq 6633'' in the filter window, assuming that 6633 is the port that the controller is
     254listening on.   And once you have lines, you can choose one of the lines and choose "Decode as ...." and choose the ''OFP protocol''.
     255
     256=== 3f. Run a traffic duplication controller ===
     257
     258In the above example we ran a very simple learning switch controller. [[BR]]
     259[[Image(GENIExperimenter/Tutorials/Graphics:4NotesIcon_512x512.png, 5%, nolink)]]
     260The power of !OpenFlow comes from the fact that you can decide to forward the packet anyway you want based on the supported !OpenFlow actions. A very simple but powerful modification you can do, is to duplicate all the traffic of the switch out a specific port. This is very useful for application and network analysis. You can imagine that at the port where you duplicate traffic you connect a device that does analysis. For this tutorial we  are going to verify the duplication by doing `tcpdump`  on two ports on the OVS switch.
     261
     262  1. '''Use the interfaces that are connected to `host2` and  `host3`. '''
     263    * Software Switch (OVS): If you have not noted them down you can use the manifest and the MAC address of the interfaces (ovs:if1 and ovs:if2) to figure this out. But you should have noted down the interfaces in Section 2 when you were configuring the software switch. Run tcpdump on these interfaces; one in each of the two ovs terminals you opened. This will allow you to see all traffic going out the interfaces.
     264    [[BR]]
     265   
     266  To see that duplication is happening, on the ovs host, run: 
     267{{{
     268sudo tcpdump -i <data_interface_name>  [data_interface to host2]
     269sudo tcpdump -i <data_interface_name>  [data_interface to host3]
     270}}}
     271
     272  You should see traffic from host1 to host2 showing up in the tcpdump window for host3.  As a comparison, you will notice that no traffic shows up in that window when the controller is running the learning switch.
     273  2. '''In the controller host directory `/tmp/pox/ext` you should see two files:'''
     274
     275       i. '''myDuplicateTraffic.py''' : This is the file that has instructions about how to complete the missing information. Go ahead and try to implement your first controller.
     276       ii. '''!DuplicateTraffic.py''' : This has the actual solution. You can just run this if you don't want to bother with writing a controller.
     277
     278  3. Run your newly written controller on the <data_interface_name> that corresponds to ''OVS:if2'' (which is connected to `host3`): 
     279{{{
     280cd /tmp/pox
     281./pox.py --verbose DuplicateTraffic --duplicate_port=?
     282}}}
     283
     284  For example, if ''OVS:if2'' corresponds to "eth1", enter
     285
     286  {{{
     287  ./pox.py --verbose myDuplicateTraffic --duplicate_port=eth1
     288  }}}
     289   
     290  4. To test it go to the terminal of host1 and try to ping host2:
     291{{{
     292ping 10.10.1.2
     293}}}
     294  If your controller is working, your packets will register in both terminals running tcpdump.
     295
     296  5. Stop the POX controller:
     297{{{
     298DEBUG:DuplicateTraffic:Got a packet : [02:f1:ae:bb:e3:a8>02:c7:e8:a7:40:65 IP]
     299DEBUG:SimpleL2Learning:installing flow for 02:f1:ae:bb:e3:a8.2 -> 02:c7:e8:a7:40:65.[1, 2]
     300
     301INFO:core:Going down...
     302INFO:openflow.of_01:[3a-51-a1-ab-c3-43 1] disconnected
     303INFO:core:Down.
     304}}}
     305
     306=== 3g. Run a port forward Controller ===
     307
     308Now let's do a slightly more complicated controller. OpenFlow gives you the power to overwrite fields of your packets at the switch, for example the TCP source or destination port and do port forwarding. You can have clients trying to contact a server at port 5000, and the OpenFlow switch can redirect your traffic to a service listening on port 6000.
     309
     310  1. Under the `/tmp/pox/ext` directory there are two files: '''!PortForwarding.py''' and '''myPortForwarding.py''' that are similar like the previous exercise. Both of these controller are configured by a configuration file at `ext/port_forward.config`. Use myPortForwarding.py to write your own port forwarding controller.
     311
     312  2. To test your controller we are going to use netcat. Go to the two terminals of host2. In one terminal run:
     313{{{
     314nc -l 5000
     315}}}
     316
     317  and in the other terminal run
     318{{{
     319nc -l 6000
     320}}}
     321
     322  3. Now, start the simple layer 2 forwarding controller. We are doing this to see what happens with a simple controller.
     323{{{
     324cd /tmp/pox
     325./pox.py --verbose forwarding.l2_learning
     326}}}
     327
     328  4. Go to the terminal of host1 and connect to host2 at port 5000:
     329{{{
     330nc 10.10.1.2 5000
     331}}}
     332   
     333  5. Type something and you should see it at the the terminal of host2 at port 5000.
     334
     335  6. Now, stop the simple layer 2 forwarding controller:
     336{{{
     337DEBUG:forwarding.l2_learning:installing flow for 02:d4:15:ed:07:4e.3 -> 02:ff:be:1d:19:ea.2
     338
     339INFO:core:Going down...
     340INFO:openflow.of_01:[36-63-8b-d7-16-4b 1] disconnected
     341INFO:core:Down.
     342}}}
     343
     344  7. And start your port forwarding controller (if you have written your controller then use myPortForwarding in the following command):
     345{{{
     346./pox.py --verbose PortForwarding
     347}}}
     348
     349  8. Repeat the netcat scenario described above. Now, your text should appear on the other terminal of host2 which is listening to port 6000.
     350
     351
     352  9. Stop your port forwarding controller:
     353{{{
     354DEBUG:myPortForwarding:Got a packet : [02:aa:a3:e8:6c:db>33:33:ff:e8:6c:db IPV6]
     355
     356INFO:core:Going down...
     357INFO:openflow.of_01:[36-63-8b-d7-16-4b 1] disconnected
     358INFO:core:Down.
     359}}}
     360
     361=== 3h. Run a Server Proxy Controller ===
     362
     363As our last exercise, instead of diverting the traffic to a different server running on the same host, we will divert the traffic to a server running on a different host and on a different port.
     364
     365  1. Under the `/tmp/pox/ext/` directory there are two files: '''Proxy.py''' and '''myProxy.py''' that are similar like the previous exercise. Both of these controllers are configured by the configuration file `proxy.config`. Use myProxy.py to write your own proxy controller.
     366
     367  2. On the terminal of `host3` run a netcat server:
     368{{{
     369nc -l 7000
     370}}}
     371
     372  3. On your controller host, open the /tmp/pox/ext/myProxy.py file, and edit it to implement a controller that will divert traffic destined for `host2` to `host3`. Before you start implementing think about what are the side effects of diverting traffic to a different host.
     373     * Is it enough to just change the IP address?
     374     * Is it enough to just modify the TCP packets?
     375
     376   If you want to see the solution, it's available in file /tmp/pox/ext/Proxy.py file. 
     377 
     378  4. To test your proxy controller run  (if you have written your controller then use myProxy in the following command)::
     379{{{
     380cd /tmp/pox
     381./pox.py --verbose Proxy
     382}}}
     383
     384
     385  5. Go back to the terminal of `host1` and try to connect netcat to `host2` port 5000
     386{{{
     387nc 10.10.1.2 5000
     388}}}
     389
     390  6. If your controller works correctly, you should see your text showing up on the terminal of `host3`.
     391
     392=== 3i. Delete your bridge ===
     393Before moving to the next step make sure you delete the bridge you have created, especially if you are using the same reservation for a different exercise:
     394{{{
     395  sudo ovs-vsctl del-br br0
     396}}}
     397
     398{{{
     399#!comment
     400== 4. Moving to a Hardware Switch ==
     401To try your controller with a GENI Hardware !OpenFlow switch:
     402       * Delete the sliver with your experiment topology.  '''Do not''' delete your controller.
     403       * Follow the instructions at [wiki:GENIExperimenter/Tutorials/OpenFlowOVS/HW/DesignSetup OpenFlow Design and Setup for Hardware Switch]
     404
     405If you do not want to do the Hardware !OpenFlow portion of the tutorial, proceed to [wiki:GENIExperimenter/Tutorials/OpenFlowOVS/Finish Finish]
     406}}}
     407----
     408
     409= [wiki:GENIExperimenter/Tutorials/OpenFlowOVS-Floodlight/DesignSetup Prev: Design and Setup for OVS] =
     410
     411{{{
     412#!comment
     413= [wiki:GENIExperimenter/Tutorials/OpenFlowOVS/NATExecute Next: Make your switch to act as a NAT server] =
     414= [wiki:GENIExperimenter/Tutorials/OpenFlowOVS/FirewallExecute Next: Make your switch to act as a Firewall] =
     415}}}
     416= [wiki:GENIExperimenter/Tutorials/OpenFlowOVS-Floodlight/Finish Next:  Finish] =