wiki:GENIExperimenter/Tutorials/GREESC13/OpenFlowWiMAX/Execute

Version 1 (modified by Ryan Izard, 11 years ago) (diff)

--

Vertical Handoff with OpenFlow

Image Map

4. Configure and Initialize

  1. In the Root Terminal, execute the system_setup.sh script:
    $ cd /root/06-03-13
    $ ./system_setup.sh
    
    Please be patient; the script can take a minute to complete. It is bringing up the tap interface, starting OVS and

creating the topology coded in the script, and configuring network access on each OVS bridge.

  1. In the Root Terminal, execute the delete_route.sh script:
       $ cd eth_control
       $ ./delete_route.sh
       Verify the new routing table has a default route via the br_tap interface no routes via the br_wimax and br_wifi 
    
    interfaces.
       3.  In Eclipse, run Floodlight by browsing to '''Run-->Run'''. Note the console output shown toward the bottom of the 
    
    Eclipse window. Since OVS is running, and the '''system_setup.sh''' script pointed each OVS bridge to the Floodlight 
    
    controller, you should see where each switch DPID connects to Floodlight.
       4.  In the Root Terminal, open an new tab (File-->Open Tab) or switch to an unused tab. Browse to the '''/root/06-03-
    
    13/eth_control''' directory.
       5.  In this directory are some Python scripts to manually add and remove flows in the OVS bridges. These scripts 
    
    leverage the Static Flow Pusher REST API present in the Floodlight controller. Since we have previously disabled 
    
    Forwarding, flows added by the Static Flow Pusher will be the only flows present on the switches, and thus only traffic 
    
    permitted by these flows will traverse the OVS network. These flows essentially take packets from a particular ingress 
    
    port and send them out a destination port. To do this, we need to determine the port numbers Floodlight has associated 
    
    with the ports of our OVS bridges. The Floodlight REST API is a means of obtaining data from the Floodlight controller. We 
    
    need to send a query to Floodlight asking for what it knows about any connected switches.
       {{{
       $ curl http://localhost:8080/wm/core/controller/switches/json | python -mjson.tool
       
       % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
       100  3397    0  3397    0     0   5900      0 --:--:-- --:--:-- --:--:--  6055
       [
        {
            "actions": 4095, 
            "attributes": {
                "DescriptionData": {
                    "datapathDescription": "None", 
                    "hardwareDescription": "Open vSwitch", 
                    "length": 1056, 
                    "manufacturerDescription": "Nicira, Inc.", 
                    "serialNumber": "None", 
                    "softwareDescription": "1.7.1"
                }, 
                "FastWildcards": 4194303, 
                "supportsOfppFlood": true, 
                "supportsOfppTable": true
            }, 
            "buffers": 256, 
            "capabilities": 199, 
            "connectedSince": 1372098663566, 
            "dpid": "00:00:00:00:00:00:00:05", 
            "featuresReplyFromSwitch": {
                "cancelled": false, 
                "done": true, 
                "transactionId": 2
            }, 
            "inetAddress": "/127.0.0.1:34846", 
            "ports": [
                {
                    "advertisedFeatures": 0, 
                    "config": 0, 
                    "currentFeatures": 0, 
                    "hardwareAddress": "12:51:16:90:8f:ee", 
                    "name": "br_tap", 
                    "peerFeatures": 0, 
                    "portNumber": 65534, 
                    "state": 0, 
                    "supportedFeatures": 0
                }, 
                {
                    "advertisedFeatures": 0, 
                    "config": 0, 
                    "currentFeatures": 0, 
                    "hardwareAddress": "00:00:00:00:00:05", 
                    "name": "tap-wlan0", 
                    "peerFeatures": 0, 
                    "portNumber": 7, 
                    "state": 0, 
                    "supportedFeatures": 0
                }, 
                {
                    "advertisedFeatures": 0, 
                    "config": 0, 
                    "currentFeatures": 0, 
                    "hardwareAddress": "00:00:00:00:00:05", 
                    "name": "tap-wimax", 
                    "peerFeatures": 0, 
                    "portNumber": 10, 
                    "state": 0, 
                    "supportedFeatures": 0
                }, 
                {
                    "advertisedFeatures": 0, 
                    "config": 1, 
                    "currentFeatures": 130, 
                    "hardwareAddress": "12:51:16:90:8f:ee", 
                    "name": "tap0", 
                    "peerFeatures": 0, 
                    "portNumber": 1, 
                    "state": 1, 
                    "supportedFeatures": 0
                }
            ], 
            "role": null, 
            "tables": -1
        }, 
        {
            "actions": 4095, 
            "attributes": {
                "DescriptionData": {
                    "datapathDescription": "None", 
                    "hardwareDescription": "Open vSwitch", 
                    "length": 1056, 
                    "manufacturerDescription": "Nicira, Inc.", 
                    "serialNumber": "None", 
                    "softwareDescription": "1.7.1"
                }, 
                "FastWildcards": 4194303, 
                "supportsOfppFlood": true, 
                "supportsOfppTable": true
            }, 
            "buffers": 256, 
            "capabilities": 199, 
            "connectedSince": 1372098663511, 
            "dpid": "00:00:00:00:00:00:00:02", 
            "featuresReplyFromSwitch": {
                "cancelled": false, 
                "done": true, 
                "transactionId": 2
            }, 
            "inetAddress": "/127.0.0.1:34844", 
            "ports": [
                {
                    "advertisedFeatures": 0, 
                    "config": 0, 
                    "currentFeatures": 0, 
                    "hardwareAddress": "00:00:00:00:00:02", 
                    "name": "wlan0-tap", 
                    "peerFeatures": 0, 
                    "portNumber": 12, 
                    "state": 0, 
                    "supportedFeatures": 0
                }, 
                {
                    "advertisedFeatures": 0, 
                    "config": 0, 
                    "currentFeatures": 0, 
                    "hardwareAddress": "00:0c:29:04:5c:4b", 
                    "name": "br_wifi0", 
                    "peerFeatures": 0, 
                    "portNumber": 65534, 
                    "state": 0, 
                    "supportedFeatures": 0
                }, 
                {
                    "advertisedFeatures": 128, 
                    "config": 0, 
                    "currentFeatures": 160, 
                    "hardwareAddress": "00:00:00:00:00:02", 
                    "name": "eth1", 
                    "peerFeatures": 0, 
                    "portNumber": 1, 
                    "state": 0, 
                    "supportedFeatures": 160
                }
            ], 
            "role": null, 
            "tables": -1
        }, 
        {
            "actions": 4095, 
            "attributes": {
                "DescriptionData": {
                    "datapathDescription": "None", 
                    "hardwareDescription": "Open vSwitch", 
                    "length": 1056, 
                    "manufacturerDescription": "Nicira, Inc.", 
                    "serialNumber": "None", 
                    "softwareDescription": "1.7.1"
                }, 
                "FastWildcards": 4194303, 
                "supportsOfppFlood": true, 
                "supportsOfppTable": true
            }, 
            "buffers": 256, 
            "capabilities": 199, 
            "connectedSince": 1372098663540, 
            "dpid": "00:00:00:00:00:00:00:04", 
            "featuresReplyFromSwitch": {
                "cancelled": false, 
                "done": true, 
                "transactionId": 2
            }, 
            "inetAddress": "/127.0.0.1:34845", 
            "ports": [
                {
                    "advertisedFeatures": 0, 
                    "config": 0, 
                    "currentFeatures": 0, 
                    "hardwareAddress": "00:00:00:00:00:04", 
                    "name": "wimax-tap", 
                    "peerFeatures": 0, 
                    "portNumber": 13, 
                    "state": 0, 
                    "supportedFeatures": 0
                }, 
                {
                    "advertisedFeatures": 0, 
                    "config": 0, 
                    "currentFeatures": 0, 
                    "hardwareAddress": "00:0c:29:04:5c:55", 
                    "name": "br_wimax", 
                    "peerFeatures": 0, 
                    "portNumber": 65534, 
                    "state": 0, 
                    "supportedFeatures": 0
                }, 
                {
                    "advertisedFeatures": 128, 
                    "config": 0, 
                    "currentFeatures": 160, 
                    "hardwareAddress": "00:00:00:00:00:04", 
                    "name": "eth2", 
                    "peerFeatures": 0, 
                    "portNumber": 1, 
                    "state": 0, 
                    "supportedFeatures": 160
                }
            ], 
            "role": null, 
            "tables": -1
        }
       ]
       }}}
       Above is sample output from the query issued. The output is organized by switch -- there should be three -- br_tap, 
    
    br_wifi, and br_wimax. On each of these switches, you can see the ports and the names of the ports as they were given in 
    
    '''system_setup.sh'''. Take note of the port numbers for the patch ports on each switch, as well as the port numbers for 
    
    the interface port on each switch.
       6.  Armed with this information, we can now create the flows we want to insert on each switch. Namely, we can specify 
    
    and ingress and output port on br_tap, br_wifi, and br_wimax for packets traveling in each direction. In the Root 
    
    Terminal, open the Python script '''gree13_switchWiFi.py''' with your favorite text editor. This script is designed to 
    
    switch to the WiFi interface.
       {{{
       $ gedit gree13_switchWiFi.py
    
    import httplib
    import json
    
    class StaticFlowPusher(object):
    
        def __init__(self, server):
            self.server = server
    
        def get(self, data):
            ret = self.rest_call({}, 'GET')
            return json.loads(ret[2])
    
        def set(self, data):
            ret = self.rest_call(data, 'POST')
            return ret[0] == 200
    
        def remove(self, objtype, data):
            ret = self.rest_call(data, 'DELETE')
            return ret[0] == 200
    
        def rest_call(self, data, action):
            path = '/wm/staticflowentrypusher/json'
            headers = {
                'Content-type': 'application/json',
                'Accept': 'application/json',
                }
            body = json.dumps(data)
            conn = httplib.HTTPConnection(self.server, 8080)
            conn.request(action, path, body, headers)
            response = conn.getresponse()
            ret = (response.status, response.reason, response.read())
            print ret
            conn.close()
            return ret
    
    pusher = StaticFlowPusher('127.0.0.1')
    
    flow1 = {
        'switch':"00:00:00:00:00:00:00:05",
        "name":"src-dst-ether-tap",
        "priority":"32768",
        "active":"true",
        "ether-type":"0x800",
        "ingress-port":"65534",
        "actions":"output=10"
        }
        
    flow2 = {
        'switch':"00:00:00:00:00:00:00:05",
        "name":"dst-src-ether-tap",
        "priority":"32768",
        "active":"true",
        "ether-type":"0x800",
        "ingress-port":"10",
        "actions":"output=65534"
        }
    
    flow3 = {
        'switch':"00:00:00:00:00:00:00:05",
        "name":"src-dst-arp-tap",
        "priority":"32768",
        "active":"true",
        "ether-type":"0x806",
        "ingress-port":"65534",
        "actions":"output=10"
        }
        
    flow4 = {
        'switch':"00:00:00:00:00:00:00:05",
        "name":"dst-src-arp-tap",
        "priority":"32768",
        "active":"true",
        "ether-type":"0x806",
        "ingress-port":"10",
        "actions":"output=65534"
        }
        
    flow5 = {
        'switch':"00:00:00:00:00:00:00:04",
        "name":"src-dst-ether-eth",
        "priority":"32768",
        "active":"true",
        "ether-type":"0x800",
        "ingress-port":"13",
        "actions":"output=1"
        }
        
    flow6 = {
        'switch':"00:00:00:00:00:00:00:04",
        "name":"dst-src-ether-eth",
        "priority":"32768",
        "active":"true",
        "ether-type":"0x800",
        "ingress-port":"1",
        "actions":"output=13"
        }
    
    flow7 = {
        'switch':"00:00:00:00:00:00:00:04",
        "name":"src-dst-arp-eth",
        "priority":"32768",
        "active":"true",
        "ether-type":"0x806",
        "ingress-port":"13",
        "actions":"output=1"
        }
        
    flow8 = {
        'switch':"00:00:00:00:00:00:00:04",
        "name":"dst-src-arp-eth",
        "priority":"32768",
        "active":"true",
        "ether-type":"0x806",
        "ingress-port":"1",
        "actions":"output=13"
        }        
        
    pusher.set(flow1)
    pusher.set(flow2)
    pusher.set(flow3)
    pusher.set(flow4)
    pusher.set(flow5)
    pusher.set(flow6)
    pusher.set(flow7)
    pusher.set(flow8)
       }}}
       In this script, there are four flows for each OVS bridge -- two for outgoing packets and two for incoming packets. Why 
    
    two? OpenFlow filters packets by not only data like MAC and IP addresses, but also by the type of packet (its 
    
    '''ethertype'''). We need to forward all IP (ethertype=0x800) and all ARP (ethertype=0x806) packets in each direction in 
    
    order to achieve IP connectivity between the tap interface and the outside world. What we want to do is look for packets 
    
    from the port br_tap is assigned to, then send them out the tap-wifi port number (the patch port connected to the br_wifi 
    
    OVS bridge), then when they arrive at br_wifi, look for them on the wifi-tap port number and send them out the br_wifi 
    
    port number. Then we want to implement the same for the opposite direction. Examine the script and modify it as necessary 
    
    to allow packets to travel from the br_tap interface, to the br_wifi interface, and out to the host-only network.
       7.  Save the '''gree13_switchWiFi.py''' script.
       8.  Repeat and save for '''gree13_switchWiMAX.py'''. Use the port numbers noted in the json output to complete the 
    
    flows needed to send packets from the br_tap interface out the br_wimax interface.
    
    
    == 5.  Execute Experiment ==
       1.  Run the WiFi switching script:
       {{{
       $ python gree13_switchWiFi.py
       (200, 'OK', '{"status" : "Entry pushed"}')
    (200, 'OK', '{"status" : "Entry pushed"}')
    (200, 'OK', '{"status" : "Entry pushed"}')
    (200, 'OK', '{"status" : "Entry pushed"}')
    (200, 'OK', '{"status" : "Entry pushed"}')
    (200, 'OK', '{"status" : "Entry pushed"}')
    (200, 'OK', '{"status" : "Entry pushed"}')
    (200, 'OK', '{"status" : "Entry pushed"}')
       }}}
       2.  In another unused tab in the Root Terminal, run ping to the gateway IP. The default route is set to br_tap and IP 
    
    forwarding is disabled -- this forces all packets into the OVS network, where the interface switching is handled by 
    
    Floodlight and the Static Flow Pusher.
       {{{
       $ ping 192.168.193.1
       }}}
       3.  Leave ping running and run the WiMAX switching script in another Root Terminal tab: 
       {{{
       $ python gree13_switchWiMAX.py
       (200, 'OK', '{"status" : "Entry pushed"}')
    (200, 'OK', '{"status" : "Entry pushed"}')
    (200, 'OK', '{"status" : "Entry pushed"}')
    (200, 'OK', '{"status" : "Entry pushed"}')
    (200, 'OK', '{"status" : "Entry pushed"}')
    (200, 'OK', '{"status" : "Entry pushed"}')
    (200, 'OK', '{"status" : "Entry pushed"}')
    (200, 'OK', '{"status" : "Entry pushed"}')
       }}}
       
    == 6.  Analyze Experiment ==
    
       1.  Notice the delay introduced in the ping responses. When we configured and ran the '''system_setup.sh''' script, we 
    
    introduced a simulated delay to the "WiMAX" interface. This confirms the switch is occuring. Before and after the switch, 
    
    the source IP remains the br_tap IP, and the destination IP remains the gateway IP.
       2.  Congratuations! You have just completed a simulated vertical Layer-2 handoff! This project is being developed and 
    
    tested using actual GENI WiFi and WiMAX testbed at Clemson University. You can give it a try yourself outside the VM using 
    
    whatever physical interfaces you have available.
    
    
    ----
    
    = [wiki:GENIExperimenter/Tutorials/GREESC13/OpenFlowWiMAX Introduction] =
    = [wiki:GENIExperimenter/Tutorials/GREESC13/OpenFlowWiMAX/Finish Next:  Finish] =