wiki:JoeSandbox/OpenFlowOVS/Execute

Version 7 (modified by zwang@bbn.com, 10 years ago) (diff)

--

Intro to OpenFlow using OVS

Image Map

Step 2. Configure and Initialize

Although OVS is installed and initialized on the host that is meant to act as a software switch, it has not been configured yet. There 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.

In order to configure our switch, we first need to login to the host that will be used as an OpenFlow switch.

To get ready for the tutorial you will need to have the following windows open:

  • one window with ssh into the controller
  • two windows with ssh into OVS
  • one windows with ssh into host1
  • two window with ssh into host2
  • one window with ssh into host3

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 this page.

2a. (No need any more)Configure the Software Switch

Now 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:

sudo ovs-vsctl list-br

You 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.

  1. List all the interfaces of the node
    • ifconfig

    Write down the interface names that correspond to the connections to your hosts. The correspondence is:
    • Interface with IP 10.10.1.11 to host1 - ethX
    • Interface with IP 10.10.1.12 to host2 - ethY
    • Interface with IP 10.10.1.13 to host3 - ethZ

  • Be careful not to bring down eth0. This is your control interface, if you bring that interface down you won't be able to login to your host!. For all interfaces other than eth0 and l0, remove the IP from the interfaces (your interface names may vary):
    • sudo ifconfig ethX 0
    • sudo ifconfig ethY 0
    • sudo ifconfig ethZ 0
  • Add all the data interfaces to your switch (bridge):Be careful not to add interface eth0. 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.)
    • sudo ovs-vsctl add-port br0 ethX
    • sudo ovs-vsctl add-port br0 ethY
    • sudo ovs-vsctl add-port br0 ethZ
  • Login information for a VM

    Congratulations! You have configured your software switch. To verify the three ports configured run:

    sudo ovs-vsctl list-ports br0
    

    (Where is 2b?)2c. Point your switch to a controller

    Find the control interface IP of your controller, use ifconfig and note down the IP of eth0.

    An 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. (The following sentence is not true anymore)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.

    In order to point our software OpenFlow switch to the controller run:

    sudo ovs-vsctl set-controller br-switch tcp:<controller_ip>:6633
    

    (No need anymore. But maybe we should keep the instroduction)standalone vs secure mode

    The 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:

    • standalone [default]: in which case OVS will take responsibility for forwarding the packets if the controller fails
    • 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.

    In 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:

    sudo ovs-vsctl set-fail-mode br-switch secure
    

    You can verify your OVS settings by issuing the following:

    sudo ovs-vsctl show
    

    Step 3. Execute Experiment

    Now 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 Ryu controller. The software is already installed in the controller host for running Ryu and can also be found here.

    3a. Login to your hosts

    To 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 this page. Once you have logged in follow the rest of the instructions.

    3b. Use a Learning Switch Controller

    In this example we going to run a very simple learning switch controller to forward traffic between host1 and host2.

    1. First we are going to start a ping from host1 to host2, which should timeout, since there is no controller running.
      ping host2
      
    1. We have installed the Ryu controller under /tmp/ryu on the controller host. We put 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:
      cd /tmp/ryu
      PYTHONPATH=. ./bin/ryu-manager ryu/ext/simple_switch.py
      
    1. Now go to terminal of host1 and ping host2:
      [experimenter@host1 ~]$ ping host2 
      PING host2-lan1 (10.10.1.2) 56(84) bytes of data.
      From host1-lan0 (10.10.1.1) icmp_seq=2 Destination Host Unreachable
      From host1-lan0 (10.10.1.1) icmp_seq=3 Destination Host Unreachable
      From host1-lan0 (10.10.1.1) icmp_seq=4 Destination Host Unreachable
      64 bytes from host2-lan1 (10.10.1.2): icmp_req=5 ttl=64 time=23.9 ms
      64 bytes from host2-lan1 (10.10.1.2): icmp_req=6 ttl=64 time=0.717 ms
      64 bytes from host2-lan1 (10.10.1.2): icmp_req=7 ttl=64 time=0.654 ms
      64 bytes from host2-lan1 (10.10.1.2): icmp_req=8 ttl=64 time=0.723 ms
      64 bytes from host2-lan1 (10.10.1.2): icmp_req=9 ttl=64 time=0.596 ms
      

    Now the ping should work.

    1. 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.
    1. To see the flow table entries on your OVS switch:
      sudo ovs-ofctl dump-flows br-switch
      
      You should see at least two table entries: One for messages from host1 to host2 and one for messages from host2 to host1. You may also see flow entries for arp packets.
    1. 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: (This one I saw too many other packet)
      sudo tcpdump -i eth0
      
      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).
    1. Kill your Ryu controller by pressing Ctrl-C.
    1. Notice what happens to your ping on host1.
    1. Check the flow table entries on your switch:
        sudo ovs-ofctl dump-flows br-switch
      
      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.

    Soft vs Hard Timeouts

    All rules on the switch have two different timeouts:

    • 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.
    • 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.

    Can you tell now why there were packets flowing even after you killed your controller?

    Useful Tips for writing your controller

    In order to make this first experience of writing controller easier, we wrote some helpful functions that will abstract some of the particularities of Ryu away. These functions are located in /tmp/ryu/ryu/ext/utils.py, so while you write your controller consult this file for details.

    Functions that are implemented include:

    • packetIsIP : Test if the packet is IP
    • packetIsARP : Test if the packet is ARP
    • packetIsRequestARP : Test if this is an ARP Request packet
    • packetIsReplyARP : Test if this is an ARP Reply packet
    • packetArpDstIp : Test what is the destination IP in an ARP packet
    • packetArpSrcIp : Test what is the sources IP in an ARP packet
    • packetIsTCP : Test if a packet is TCP
    • packetDstIp : Test the destination IP of a packet
    • packetSrcIp : Test the source IP of a packet
    • packetDstTCPPort : Test the destination TCP port of a packet
    • packetSrcTCPPort : Test the source TCP port of a packet
    • createArpRequest : Create an Arp Request for a different destination IP
    • createArpReply : Create an Arp Reply for a different source IP

    3c. Debugging your Controller

    While you are developing your controller, some useful debugging tools are:

    i. Print messages

    Run your controller in verbose mode (add --verbose) and add print messages at various places to see what your controller is seeing.

    ii. Check the status in the switch

    If you are using an OVS switch, you can dump information from your switch. For example, to dump the flows:

    sudo ovs-ofctl dump-flows br-switch
    

    Two other useful commands show you the status of your switch:

    sudo ovs-vsctl show 
    sudo ovs-ofctl show br-switch
    

    iii. Use Wireshark to see the OpenFlow messages

    Many 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.

    The controller host and OVS has wireshark installed, including the openflow dissector. For more information on wireshark you can take a look at the wireshark wiki.

    Here we have a simple case of how to use the OpenFlow dissector for wireshark.

    If 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.

    ssh -Y <username>@<controller>
    

    We will need to capture a packet trace to feed into wireshark to analyze it. So once you are logged in run:

    sudo tcpdump -s 0 -w out.pcap tcp port 6633
    

    The 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).

    Run wireshark by typing:

    wireshark &
    

    Use 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.

    3d. Run a traffic duplication controller

    In 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.

    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.
      sudo tcpdump -i <data_interface_name>
      
    1. In the contorller host directory /tmp/ryu/ryu/ext you would see three files:
    1. (I don't have it yet)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.
    2. DuplicateTraffic.py : this has the actual solution you can just run this if you don't want to bother with writing a controller.
    3. duplicate.config : in this file, you specify which port you want to duplicate traffic to. To figure out which port maps to which interface, use "sudo ovs-ofctl show br-switch".
    1. Run your newly written controller :
      cd /tmp/ryu
      ./bin/ryu-manager ryu/ext/DuplicateTraffic.py
      

    1. To test it go to the terminal of host1 and try to ping host2:
      ping 10.10.1.2
      
      If your controller is working, your packets will register in both terminals running tcpdump.
    1. Stop the Ryu controller using Ctrl-C.

    3d. Run a port forward Controller

    Now 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.

    1. Under the /tmp/ryu/ryu/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 port_forward.config. Use myPortForwarding.py to write your own port forwarding controller.
    1. To test your controller we are going to use netcat. Go to the two terminals of host2. In one terminal run:
      nc -l 5000
      

    and in the other terminal run

    nc -l 6000
    
    1. Now, start the simple layer 2 forwarding controller. We are doing this to see what happens with a simple controller.
        cd /tmp/ryu
        ./bin/ryu-manager ryu/ext/simple_switch.py
      
    1. Go to the terminal of host1 and connect to host2 at port 5000:
      nc 10.10.1.2 5000
      

    1. Type something and you should see it at the the terminal of host2 at port 5000.
    1. Now, stop the simple layer 2 forwarding controller by Ctrl-C:
    1. And start your port forwarding controller:
      ./bin/ryu-manager ryu/ext/PortForwarding.py
      
    1. Repeat the netcat scenario described above. Now, your text should appear on the other terminal of host2 which is listening to port 6000.
    1. Stop your port forwarding controller.

    3e. Run a Server Proxy Controller

    As 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.

    1. Under the /tmp/ryu/ryu/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.
    1. On the terminal of host3 run a netcat server:
      nc -l 7000
      
    1. On your controller host open the /tmp/ryu/ryu/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.
      • Is it enough to just change the IP address?
      • Is it enough to just modify the TCP packets?

    If you want to see the solution, it's available in file /tmp/ryu/ryu/ext/Proxy.py file.

    1. To test your proxy controller run:
      cd /tmp/ryu
      ./bin/ryu-manager ryu/ext/Proxy.py
      
    1. Go back to the terminal of host1 and try to connect netcat to host2 port 5000
      nc 10.10.1.2 5000
      
    1. If your controller works correctly, you should see your text showing up on the terminal of host3.

    4. Moving to a Hardware Switch

    To try your controller with a GENI Hardware OpenFlow switch:

    • Delete resources in your slice with the compute resources. Do not delete resources in your slice with the controller.
    • Follow the instructions at GENIExperimenter/Tutorials/OpenFlowOVS/Appendix (I didn't change this part. There are a few wording changes needed.)

    If you do not want to do the Hardware OpenFlow portion of the tutorial, proceed to JoeSandbox/OpenFlowOVS/Finish


    Introduction

    Next: Finish