Changes between Initial Version and Version 1 of JoeSandbox/OpenFlowOVS/Execute


Ignore:
Timestamp:
08/13/14 17:02:41 (10 years ago)
Author:
zwang@bbn.com
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • JoeSandbox/OpenFlowOVS/Execute

    v1 v1  
     1= [http://groups.geni.net/geni/wiki/GENIExperimenter/Tutorials/OpenFlowOVS Intro to OpenFlow using OVS] =
     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/DesignSetup" alt="" title=""    />
     9<area shape="rect" coords="180,18,297,111" href="http://groups.geni.net/geni/wiki/GENIExperimenter/Tutorials/OpenFlowOVS/Execute" alt="" title=""    />
     10<area shape="rect" coords="344,17,460,110" href="http://groups.geni.net/geni/wiki/GENIExperimenter/Tutorials/OpenFlowOVS/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
     19== Step 2.  Configure and Initialize ==
     20
     21Although OVS is installed and initialized on the host that is meant to act as a software switch, it has not been configured yet.
     22There are two main things that need to be configured: ''(1) configure your software switch with the interfaces as ports'' and '' (2) point the switch to an !OpenFlow controller''.
     23
     24In order to configure our switch, we first need to login to the host that will be used as an !OpenFlow switch.
     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  * two windows with ssh into OVS
     29  * one windows with ssh into host1
     30  * two window 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 take a look in [wiki:HowTo/LoginToNodes this page.]
     34
     35=== 2a. Configure  the Software Switch ===
     36
     37Now that you are logged in, we need first to configure OVS. To save time in this tutorial, we have already started OVS and we have added an Ethernet bridge that will act as our software switch. Try the following to show the configure bridge:
     38{{{
     39sudo ovs-vsctl list-br
     40}}}
     41You should see only on bridge `br0`. Now we need to add the interfaces to this bridge that will act as ports of our software switch.
     42
     43{{{
     44#!html
     45<table border="0">
     46      <tr >
     47       <td width = "500">
     48         <ol>
     49           <li>List all the interfaces of the node
     50            <ul> <li> <code>ifconfig</code> </ul><br/>
     51            Write down the interface names that correspond to the connections to your hosts. The correspondence is:
     52            <ul>
     53                <li> Interface with IP 10.10.1.11 to host1  - ethX</li>
     54                <li> Interface with IP 10.10.1.12 to host2 - ethY</li>
     55                <li> Interface with IP 10.10.1.13 to host3 - ethZ</li>
     56           </ul></li>
     57           </li> <br/>
     58           <li> Be careful <b> not to bring down eth0</b>. This is your control interface, if you bring that interface down you <b> won't be able to login</b> to your host!. For all interfaces other than <code>eth0</code> and <code> l0</code>, remove the IP from the interfaces (your interface names may vary): <br/>
     59                              <ul><li> <code> sudo ifconfig ethX 0 </code> </li></ul>
     60                              <ul><li> <code> sudo ifconfig ethY 0 </code> </li></ul>
     61                              <ul><li> <code> sudo ifconfig ethZ 0 </code> </li></ul>
     62             <li> Add all the data interfaces to your switch (bridge):Be careful <b> not to add interface eth0</b>. This is your control interface. You should see three interfaces that start with VLAN, these are your data interfaces. (Use the same interfaces as you used in the previous step.)
     63                <ul><li> <code> sudo  ovs-vsctl add-port br0 ethX </code> </li></ul>
     64                <ul><li> <code> sudo  ovs-vsctl add-port br0 ethY </code> </li></ul>
     65                <ul><li> <code> sudo  ovs-vsctl add-port br0 ethZ </code> </li></ul>
     66             </li>
     67          </ol>
     68       </td>
     69        <td>
     70        <img border="0" src="http://groups.geni.net/geni/attachment/wiki/GENIExperimenter/Tutorials/OpenflowOVS/Graphics/ovs-interfaces.jpg?format=raw" alt="Login information for a VM"  height="250" title="Login information for a VM" /> </a>
     71       </td>
     72    </tr>
     73 </table>
     74}}}
     75 
     76Congratulations! You have configured your software switch. To verify the three ports configured run:
     77{{{
     78sudo ovs-vsctl list-ports br0
     79}}}
     80
     81=== 2c. Point your switch to a controller ===
     82
     83Find the control interface IP of your controller, use ifconfig and note down the IP of `eth0`.
     84
     85An !OpenFlow switch will not forward any packet, unless instructed by a controller. Basically the forwarding table is empty, until an external controller inserts forwarding rules. The !OpenFlow controller communicates with the switch over the control network and it can be anywhere in the Internet as long as it is reachable by the OVS host. For the purpose of this tutorial and in order to minimize the resources we have reserved we are going to run !OpenFlow controller at the same host as the OVS switch. This is '''merely''' for convenience reasons, the controller could have been anywhere on the Internet.
     86
     87In order to point our software !OpenFlow switch to the controller run:
     88{{{
     89sudo ovs-vsctl set-controller br0 tcp:<controller_ip>:6633
     90}}}
     91
     92==== `standalone` vs `secure` mode ====
     93
     94The !OpenFlow controller is responsible for setting up all flows on the switch, which means that when the controller is not running there should be no packet switching at all. Depending on the setup of your network, such a behavior might not be desired. It might be best that when the controller is down, the switch should default back in being a learning layer 2 switch. In other circumstances however this might be undesirable. In OVS this is a tunable parameter, called `fail-safe-mode` which can be set to the following parameters:
     95  * `standalone` [default]: in which case OVS will take responsibility for forwarding the packets if the controller fails
     96  * `secure`: in which case only the controller is responsible for forwarding packets, and if the controller is down all packets are going to be dropped.
     97
     98In OVS when the parameter is not set it falls back to the `standalone` mode. For the purpose of this tutorial we will set the `fail-safe-mode` to `secure`, since we want to be the ones controlling the forwarding. Run:
     99{{{
     100sudo ovs-vsctl set-fail-mode br0 secure
     101}}}
     102You can verify your OVS settings by issuing the following:
     103
     104{{{
     105sudo ovs-vsctl show
     106}}}
     107
     108== Step 3. Execute Experiment ==
     109
     110Now that our switch is up and running we are ready to start working on our 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].
     111
     112=== 3a. Login to your hosts ===
     113
     114To start our experiment we need to ssh all of our hosts. Depending 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 take a look in [wiki:HowTo/LoginToNodes this page.] Once you have logged in follow the rest of the instructions.
     115
     116=== 3b. Use a Learning Switch Controller ===
     117
     118In this example we going to run a very simple learning switch controller to forward traffic between host1 and host2.
     119 
     120  1. First we are going to start a ping from  `host1` to `host2`, which should timeout, since there is no controller running.
     121  {{{
     122  ping host2 -c 10
     123  }}}
     124
     125  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.  Let's start the learning switch controller which is already available:
     126  {{{
     127  cd /tmp/pox
     128  ./pox.py --verbose forwarding.l2_learning
     129  }}}
     130
     131   '' Note: "l2" above uses the letter `l` as in level and is not the number one.''
     132
     133 3. Now go to terminal of `host1` and ping `host2`:
     134  {{{
     135  [experimenter@host1 ~]$ ping host2
     136  PING host2-lan1 (10.10.1.2) 56(84) bytes of data.
     137  From host1-lan0 (10.10.1.1) icmp_seq=2 Destination Host Unreachable
     138  From host1-lan0 (10.10.1.1) icmp_seq=3 Destination Host Unreachable
     139  From host1-lan0 (10.10.1.1) icmp_seq=4 Destination Host Unreachable
     140  64 bytes from host2-lan1 (10.10.1.2): icmp_req=5 ttl=64 time=23.9 ms
     141  64 bytes from host2-lan1 (10.10.1.2): icmp_req=6 ttl=64 time=0.717 ms
     142  64 bytes from host2-lan1 (10.10.1.2): icmp_req=7 ttl=64 time=0.654 ms
     143  64 bytes from host2-lan1 (10.10.1.2): icmp_req=8 ttl=64 time=0.723 ms
     144  64 bytes from host2-lan1 (10.10.1.2): icmp_req=9 ttl=64 time=0.596 ms
     145  }}}
     146
     147  Now the ping should work.
     148
     149  4. Go back to your OVS 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.
     150
     151  5. To see the flow table entries on your OVS switch:
     152  {{{
     153  sudo ovs-ofctl dump-flows br0
     154  }}}
     155  You should see at least two table entries: One for ICMP Echo (icmp_code=8) messages from host1 to host2 and one for ICMP Echo Reply (icmp_code=0) messages from host2 to host1.  You may also see flow entries for arp packets.
     156
     157  6. To see messages go between your switch and your controller (listening on port 6633 of your localhost), run tcpdump on the `eth0` interface of your controller node:
     158  {{{
     159  sudo tcpdump -i eth0
     160  }}}
     161  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).
     162
     163  7. Kill your POX controller by pressing `Ctrl-C`:
     164  {{{
     165  DEBUG:forwarding.l2_learning:installing flow for 02:c7:e8:a7:40:65.1 -> 02:f1:ae:bb:e3:a8.2
     166  ^C
     167  INFO:core:Going down...
     168  INFO:openflow.of_01:[3a-51-a1-ab-c3-43 1] disconnected
     169  INFO:core:Down.
     170  }}}
     171
     172  8. Notice what happens to your ping on host1.
     173
     174  9. Check the flow table entries on your switch:
     175   {{{
     176  sudo ovs-ofctl dump-flows br0
     177  }}}
     178  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.
     179
     180
     181==== Soft vs Hard Timeouts ====
     182
     183All rules on the switch have two different timeouts:
     184
     185  * '''Soft Timeout''': This determines for how long the flow will remain at the forwarding table of the switch, if there no packets received that match the specific flow. As long as packets from that flow are received the flow remains on the flow table.
     186  * '''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.
     187
     188Can you tell now why there were packets flowing even after you killed your controller?
     189
     190=== Useful Tips for writing your controller ===
     191
     192In order to make this first experience of writing controller easier, we wrote some helpful functions that will abstract some of the particularities of POX away.
     193These functions are located in `/tmp/pox/ext/utils.py`, so while you write your controller consult this file for details.
     194
     195Functions that are implemented include:
     196  * packetIsIP : Test if the packet is IP
     197  * packetIsARP : Test if the packet is ARP
     198  * packetIsRequestARP : Test if this is an ARP Request packet
     199  * packetIsReplyARP : Test if this is an ARP Reply packet
     200  * packetArpDstIp : Test what is the destination IP in an ARP packet
     201  * packetArpSrcIp : Test what is the sources IP in an ARP packet
     202  * packetIsTCP : Test if a packet is TCP
     203  * packetDstIp : Test the destination IP of a packet
     204  * packetSrcIp : Test the source IP of a packet
     205  * packetDstTCPPort : Test the destination TCP port of a packet
     206  * packetSrcTCPPort : Test the source TCP port of a packet
     207  * createOFAction : Create one OpenFlow action
     208  * getFullMatch : get the full match out of a packet
     209  * createFlowMod : create a flow mod
     210  * createArpRequest : Create an Arp Request for  a different destination IP
     211  * createArpReply : Create an Arp Reply for  a different source IP
     212
     213=== 3c. Debugging your Controller ===
     214While you are developing your controller, some useful debugging tools are:
     215
     216==== i. Print messages ====
     217Run your controller in verbose mode (add --verbose) and add print messages at various places to see what your controller is seeing.
     218
     219==== ii. Check the status in the switch ====
     220If you are using an OVS switch, you can dump information from your switch.  For example, to dump the flows:
     221{{{
     222sudo ovs-ofctl dump-flows br0
     223}}}
     224Two other useful commands show you the status of your switch:
     225{{{
     226sudo ovs-vsctl show
     227sudo ovs-ofctl show br0
     228}}}
     229
     230==== iii. Use Wireshark to see the OpenFlow messages ====
     231Many 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. If you are using OVS then you can use wireshark on both ends of the connection, in hardware switches you have to rely only on the controller view.
     232
     233The 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].
     234
     235Here we have a simple case of how to use the OpenFlow dissector for wireshark.
     236
     237If 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.
     238{{{
     239ssh -Y <username>@<controller>
     240}}}
     241
     242We will need to capture a packet trace to feed into wireshark to analyze it. So once you are logged in run:
     243{{{
     244sudo tcpdump -s 0 -w out.pcap tcp port 6633
     245}}}
     246
     247The above command will run tcpdump capturing the full packets (`-s 0`), saving the capture to and out.pcap file (`-w out.pcap`) and only capturing packets with src/dst tcp port 6633 that is where our controller is running (`tcp port 6633`).
     248
     249Run wireshark by typing:
     250{{{
     251wireshark &
     252}}}
     253Use the file menu to load the pcap file. Right-click on one of the files and choose "Decode as ...." and choose the OFP protocol. Once you do that you will see the OpenFlow message types in wireshark. If you have more than openflow packets in your pcap you can type `of` in the filter box on the top and only show OpenFlow messages.
     254
     255=== 3d. Run a traffic duplication controller ===
     256
     257In the above example we ran a very simple learning switch controller. The 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 a `tcpdump`  on a port on the OVS switch.
     258
     259  1. Use the interfaces that are connected to `host2` and  `host3`. If you haven't note them down you can use the manifest and the MAC address of the interfaces (ovs:if1 and ovs:if2) to figure this out.  Run tcpdump on these interfaces; one in each of the other two terminals you opened. This will allow you to see all traffic going out the interfaces.
     260  {{{
     261  sudo tcpdump -i <data_interface_name>
     262  }}}
     263
     264  2. In the contorller host directory `/tmp/pox/ext` you would see two files:
     265
     266       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.
     267       ii. !DuplicateTraffic.py : this has the actual solution you can just run this if you don't want to bother with writing a controller.
     268
     269  3. Run your newly written controller on the <data_interface_name> that corresponds to ''OVS:if2'' (which is connected to `host3`):
     270  {{{
     271  cd /tmp/pox
     272  ./pox.py --verbose myDuplicateTraffic --duplicate_port=<data_interface_name>
     273  }}}
     274   
     275  4. To test it go to the terminal of host1 and try to ping host2:
     276  {{{
     277  ping 10.10.1.2
     278  }}}
     279  If your controller is working, your packets will register in both terminals running tcpdump.
     280
     281  5. Stop the POX controller:
     282  {{{
     283  DEBUG:myDuplicateTraffic:Got a packet : [02:f1:ae:bb:e3:a8>02:c7:e8:a7:40:65 IP]
     284  DEBUG:SimpleL2Learning:installing flow for 02:f1:ae:bb:e3:a8.2 -> 02:c7:e8:a7:40:65.[1, 2]
     285  ^C
     286  INFO:core:Going down...
     287  INFO:openflow.of_01:[3a-51-a1-ab-c3-43 1] disconnected
     288  INFO:core:Down.
     289  controller:/tmp/pox%
     290  }}}
     291
     292=== 3d. Run a port forward Controller ===
     293
     294Now 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.
     295
     296  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.
     297
     298  2. To test your controller we are going to use netcat. Go to the two terminals of host2. In one terminal run:
     299  {{{
     300  nc -l 5000
     301  }}}
     302
     303  and in the other terminal run
     304  {{{
     305  nc -l 6000
     306  }}}
     307
     308  3. Now, start the simple layer 2 forwarding controller. We are doing this to see what happens with a simple controller.
     309  {{{
     310  cd /tmp/pox
     311  ./pox.py --verbose forwarding.l2_learning
     312  }}}
     313
     314  4. Go to the terminal of host1 and connect to host2 at port 5000:
     315  {{{
     316  nc 10.10.1.2 5000
     317  }}}
     318   
     319  5. Type something and you should see it at the the terminal of host2 at port 5000.
     320
     321  6. Now, stop the simple layer 2 forwarding controller:
     322  {{{
     323  DEBUG:forwarding.l2_learning:installing flow for 02:d4:15:ed:07:4e.3 -> 02:ff:be:1d:19:ea.2
     324  ^C
     325  INFO:core:Going down...
     326  INFO:openflow.of_01:[36-63-8b-d7-16-4b 1] disconnected
     327  INFO:core:Down.
     328  controller:/tmp/pox%
     329  }}}
     330
     331  7. And start your port forwarding controller:
     332  {{{
     333  ./pox.py --verbose myPortForwarding
     334  }}}
     335
     336  8. Repeat the netcat scenario described above. Now, your text should appear on the other terminal of host2 which is listening to port 6000.
     337
     338
     339  9. Stop your port forwarding controller:
     340  {{{
     341  DEBUG:myPortForwarding:Got a packet : [02:aa:a3:e8:6c:db>33:33:ff:e8:6c:db IPV6]
     342  ^C
     343  INFO:core:Going down...
     344  INFO:openflow.of_01:[36-63-8b-d7-16-4b 1] disconnected
     345  INFO:core:Down.
     346  }}}
     347
     348=== 3e. Run a Server Proxy Controller ===
     349
     350As our last exercise, instead of diverging the traffic to a different server running on the same host, we will diverge the traffic to a server running on a different host and on a different port.
     351
     352  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.
     353
     354  2. On the terminal of `host3` run a netcat server:
     355  {{{
     356  nc -l 7000
     357  }}}
     358
     359  3. On your controller host open the /tmp/pox/ext/myProxy.py file, and edit it to implement a controller that will diverge traffic destined for `host2` to `host3`. Before you start implementing think about what are the side effects of diverging traffic to a different host.
     360     * Is it enough to just change the IP address?
     361     * Is it enough to just modify the TCP packets?
     362
     363   If you want to see the solution, it's available in file /tmp/pox/ext/Proxy.py file. 
     364 
     365  4. To test your proxy controller run:
     366  {{{
     367  cd /tmp/pox
     368  ./pox.py --verbose myProxy
     369  }}}
     370
     371  5. Go back to the terminal of `host1` and try to connect netcat to `host2` port 5000
     372  {{{
     373  nc 10.10.1.2 5000
     374  }}}
     375
     376  6. If your controller works correctly, you should see your text showing up on the terminal of `host3`.
     377
     378== 4. Moving to a Hardware Switch ==
     379To try your controller with a GENI Hardware !OpenFlow switch:
     380       * Delete resources in your slice with the compute resources.  '''Do not''' delete resources in your slice with the controller.
     381       * Follow the instructions at [wiki:GENIExperimenter/Tutorials/OpenFlowOVS/Appendix]
     382
     383If you do not want to do the Hardware !OpenFlow portion of the tutorial, proceed to [wiki:GENIExperimenter/Tutorials/OpenFlowOVS/Finish]
     384----
     385
     386= [wiki:GENIExperimenter/Tutorials/OpenFlowOVS Introduction] =
     387= [wiki:GENIExperimenter/Tutorials/OpenFlowOVS/Finish Next:  Finish] =