Task 2: Create A Controller
In this task, the Ryu framework is introduced that allow you to create a controller. In Task 2.1, you will be creating a controller that provides Layer 2 Learning switch functionality to the OpenFlow switch. In Task 2.2, you will expand the switch controller you created, improving it both in terms of efficiency and configurability. The Skeleton code named hub.py is given.
Objectives of Task 2
▪ Learn running a Ryu controller ▪ Create your own controller
Adding a Controller
As using ovs-ofctl may have highlighted, it would be laborious and near impossible if we had to add and maintain rules by hand. This is where switching logic comes in. Under normal circumstances, switches have built-in processing which will handles this forwarding process for us. It is all done automatically to the manufacturer’s specification. With the OpenFlow switch, the logic does have to be handled by ourselves, however, programs (controllers) can make this far less laborious.
Running a Ryu Controller
Let’s look at how the data plane talks to a controller:
1. First, stop mininet, open up wireshark and select the Loopback:lo interface.
2. Next, add a filter so that you can only see the OpenFlow messages sent. Set up a filter for OpenFlow control traffic, by typing ‘openflow_v4’ in Filter box near the top of the wireshark window.
3. You then need to instantiate a topology. You can use your own custom topology, or simply run the simple topology:
$ sudo mn –topo single,3 –mac –switch ovsk –controller remote
4. From another terminal window you can run Ryu controllers using the ryu-manager program. Before that, you need to first download the file hub.py from Moodle. Then, you can navigate to the directory where hub.py lies in and run the controller:
$ ryu-manager hub.py
You should see a bunch of messages displayed in Wireshark. These show the remote controller and the OpenFlow handshake that should take place.
*Note: The hub that has been provided to you uses OpenFlow 1.3, you should
also be using this in the coursework.
5. You should now be able to ping the hosts in the network.
mininet> exit
$ sudo mn -c
$ sudo wireshark
程序代写 CS代考 加QQ: 749389476
The Skeleton code named hub.py provided on Moodle is a Hub controller that uses the Ryu framework. A hub forwards packets along all of its ports (floods) rather than just the port the destination is reachable over. This obviously is not efficient as the packet is potentially sent out on many ports in which the destination is not reachable. Also, the hub controller provided does not install entries to the flow table, meaning every packet has to be sent up to the controller. This flow-table miss can drastically increase latency. After getting yourself familiar with it, you’ll modify the provided hub code to act as an L2 learning switch.
Creating a Controller
In the above mininet tasks, you ran mininet specifying that the controller was remote. For Task 2.1, you will be creating a controller that provides layer 2 learning switch functionality to the OpenFlow switch. To do this, you will be using a Python implementation of the OpenFlow protocol called Ryu. Ryu is open source and has some example controllers here.
Layer 2 Learning Switch
A switch forwards packets between hosts. The logic behind this forwarding is often baked into the hardware through the use of Application Specific Integrated Circuits (ASICs). However, as you discovered in this practical, an SDN switch separates the physical forwarding from the logic.
For this practical, you will be creating a layer 2 learning switch. Breaking this down, you will be creating a layer 2 switch controller, enabling the forwarding of packets between hosts using layers 1 and 2 of the OSI model. Following this, you will add learning functionality to your controller. This separates the switch you will make from the hub you have been provided. A switch with learning capability will initially have to forward incoming packets to all of its ports (flood), however, it will remember the port the sending host is accessible over. It can then send future packets destined for the now known host over just the right port.
程序代写 CS代考 加微信: cstutorcs
Assuming there was a switch connected to two hosts (h1 and h2), below is a worked example of the learning capability of the switch.
1. First of all, one (or more) of the hosts will send an ARP request. The goal of this is to find the MAC address that associates to a given IP address. For example, h1 may be asked to ping 10.0.0.2, the IP address of h2, however, it might not know the MAC address of h2 yet to build the packets. h1 then sends the ARP request containing the IP 10.0.0.2 and the MAC address FF:FF:FF:FF:FF:FF (the broadcast MAC). As this is broadcast, h2 should see this. h2 can fill in the info about h1 when it sees this, and also send a message back to h1 including its MAC address: the ARP response. All the switch has to do here is simply flood the ARP packets.
2. Next, now that the MAC address for h2 is known by h1, the ping from h1 to h2 can be sent. The packet is constructed and sent by h1 and then enters the switch at port 9 (as an example). The switch can now look at where the packet came in (port 9) and also look at the source MAC of the packet (the MAC of h1). Now, the controller can store this in some form of map.
3. As the controller does not know what port h2 can be accessed via, thus it has to flood (meaning that it has to send the packet out on all ports). This is highly inefficient, however, if h2 is in the network, it will receive the packet.
4. Following the ping is the pong from h2 to h1. This is constructed using the details from the ping packet and the details from the ARP. This is then sent to the switch.
5. The switch can now inspect the packet headers. From this, it will see that the source MAC in the pong packet does not exist in the port-to-mac map. Thus, it can now add the mapping in using the details from the pong packet headers.
6. Finally, the switch can see from the pong packet information that the destination MAC is in the port-to-mac map, hence it can use the port associated with the destination MAC to forward the packet via. This means it does not need to flood the response, but simply send it via the port associated (in this example, port 9).
Getting Started with Ryu
Looking at the source code of hub.py, you will see that the controller is encapsulated within a Python class (Python can do both procedural and OO). The controller extends the app_manager.RyuApp class. Some notes on the template:
▪ In Python, the __init__ method acts in a similar way to a Constructor in Java.
▪ The self word acts in a similar way to the this keyword in Java.
▪ The *args is a list of provided arguments, often used as a form of dynamic
overloading.
▪ The **kwargs is a map, acting in a similar way to *args, however, each argument is
OpenFlow Events
Beyond the __init__ method, you have been provided 3 functions:
1. switch_features_handler that handles the OF Switch Features event, seen in the initial switch-controller handshake. This is where the controller normally has its first major interaction with each switch. The datapath in this context is each switch (1 controller can control multiple datapaths).
2. _packet_in_handler that handles the Packet In event. Every time when a packet is pushed to the controller, it is passed to this function. The event message (ev.msg) contains data and datapath. The datapath is the switch that the event came from and the data is the packet.
3. add_flow is not triggered by any OpenFlow events directly, but used by the other functions to write flow table entries onto the switch.
Packet Matching
The packet can be parsed by casting the message data from a packet-in event into a Packet type (provided in ryu.lib.packet). Then you can start parsing entries in the header. The only match field you will need that is not found in the packet header is the in_port, however, this can be found in the event message.
As a start, the ethernet header can be found the following once the packet has been parsed:
eth = pkt.protocols[0]
Task 2.1 – Create A Layer 2 Learning Switch
For this task, you should create your own Layer 2 Learning switch using the Ryu framework. You should use the hub.py controller as the base for this task. Please note that for this task, you should only create rules using match fields within layer 2. Source and destination MAC addresses are the most common fields. The Layer 2 Learning switch should learn via mapping of ingress port to source MAC, as described in the Logic part.
Note: Throughout this task you can use the logger to print information to the terminal. You should however be considerate of the logging level, be it debug, info or error etc
Part 1 – Learning
Use a single switch topology for this part.
$ sudo mn –topo single,3 –mac –switch ovsk –controller remote
1. First of all, you should aim to collect packet header information. More specifically, you should be sure to collect the source MAC address and in port of each packet that comes through the controller. To test this, you can print this information to the terminal.
2. You should then store this information in a map structure (such as a dictionary). Then, using the map, you should create the appropriate output actions (using the specific out port) where possible. You can use prints (via the logger) to test this, or you monitor the packets using wireshark.
Part 2 – Multi-Switch
Use a multi-switch topology for this: the example topology provided in topo-2sw-2host.py or the topology you created in Task 1.
1. By running your controller with multiple switches, you might notice a few issues. This is because the mappings table you will have created is currently shared with all switches. To fix this, you should implement an approach that allows each switch to have its own mappings (still using only 1 controller for the whole topology).
2. Once implemented, you can test this on any multi-switch topology.
Please note that Task 2.1 won’t be assessed. But it can serve as a basis for Task 2.2.
Improving Efficiency
Currently, the L2 switch you have implemented has to handle the Packet In OpenFlow event for every packet sent. This has major performance implications on your VM system, however, in a real-world scenario where the controller is truly remote, this can massively impact the performance of the network. Not to mention that your current topology is only built of a few hosts.
You can however write flow table entries to the datapaths (see the add_flow function in the hub.py).
First ping:
First pong (having written flow-mod):
Installing Flow-Mods
In your L2 switch implementation there should be a function named add_flow (assuming you used the base hub). Currently, this is used to add the base flow entry (the one that pushes all packets that miss other flows up to the controller). However, you can use this to push rules that apply the learned data down to the datapaths.
▪ The match parameter takes an OFPMatch type (see src here)
▪ The datapath parameter takes a datapath (such as can be found via
ev.msg.datapath)
▪ The actions parameter takes a list of OFPAction‘s (again, the src can be found here)
▪ Finally, the priority parameter is somewhat self-explanatory…
Task 2.2 – Create A Layer 4 Learning Switch
Part 1 – Adding flow mods
You should first expand your L2 learning switch by adding flow mods for packets not being flooded. You can still test your topology the same was as in Task 1, such as by using ovs- ofctl. The following commands can be useful for testing if you have successfully installed the flow mods.
You can use Ctrl + C to stop the Ryu controller.
$ sudo ovs-ofctl dump-flows s1 mininet> h1 ping -c3 h2
Programming Help
Layer 4 Functionality
Layer 2 switches are common devices, providing all the functionality to pass packets around a subnet (such as the 10.0.0.0/8 subnet you use with Mininet by default). Some organizations might however demand more from their switches. This is where Layer 4-7 switching comes in. Layer 4-7 switching provides some of the functionality often seen in routers. Organizations can then use this data to provide extra in-network features, such as QoS and security features.
Part 2 – L4 Switch
This task focuses on Layer’s 3 and 4. More specifically, you will be adding in ICMP specific match fields and IP specific fields from Layer 3. You will also be adding match fields from TCP and UDP headers from Layer 4. Expanding on your layer 2 switch, you should add layer 3 and layer 4 match fields. To check if they’re working, you can use ovs-ofctl to dump the flow-table of a given switch. You can also use some other commands that have been introduced in Task 1 to check if they are working.
Below are some useful tips for adding more match fields: OF Match Field Ordering
OpenFlow match fields are not always correctly ordered by Ryu (they can be though), so, you have to make sure you add fields layer by layer. Further to this, OpenFlow needs to know the fields it can expect for each layer. To know this, you must match on each lower layer’s header field that indicates the higher layer header. For example, if you are matching on the IPv4 (nw) source address, you should make sure you are also matching for IP in the ethertype field (in the ethernet header).
Packet Matching
In a switch, the flow table does not have infinite memory, thus, you should try and keep the number of rules to a minimum. However, this minimalism should have no impact on functionality. Although in this task you are unlikely to encounter this issue, or in fact for any part of this module, you should still consider it. The coursework assessment will consider the thought applied to your flow-mod construction.
Marking Criteria
What you will need to submit:
▪ One Python script for Task 2.2
▪ One recorded demo video with explanations; in your recorded video,
o You need to walkthrough your code for Task 2.2.
o You need to demo L4 switch functionality where ICMP, TCP and UDP packets
must be tested. Single switch topology and multiple switch topology both
should be tested.
o You need to demo the learning capability of your L4 switch.
o If you have done anything to maintain the minimal number of flow entries,
you should introduce that.
You will be awarded marks for building the functioning L4 Learning switch that meet the requirements given in the Task documentation and for your demonstration.