Welcome back. We are continuing our discussion of the control plane, and in this lesson we will look at how to use an SDN controller to customize the control plane behavior. We will use the POX Controller that we discussed in the last lesson for the examples that we will explore in this lesson. We'll review the basic operation of a hub and a switch, then we'll use Mininet to set up a simple topology and we will use the POX Controller to control the behavior of the switch that we set up in that topology. We will then use the POX Controller to implement two different types of control in the network topology. A hub which simply forwards all traffic out all of the output ports and a learning switch which learns forwarding table entries based on the ports on which incoming packets arrive. For both examples we will look at the flow table entries using dpctl and in particular we will explore how the flow table entries differ and we'll also walk through the code for each of these two control examples. Let's first use Mininet to set up an example topology as we've done before. We'll use a simple three node topology with a single Open vSwitch to connect those three nodes. Even without a controller, we can use dpctl to communicate with that switch to perform operations such as examining the current flow table entries that exist in the switch. Using Mininet, we set up our single three node topology with an Open vSwitch and the option that specifies we want to use a remote controller. At this point, we have three hosts connected by a single Open vSwitch, but we have not yet instantiated a controller. Therefore, if we try to ping between the host and the topology we see that the hosts can not actually reach one another. This is also corroborated by looking at dpctl. If we dump the flow table entries and the switch, we will see that the switch actually has no flow table entries, which is why the hosts are unable to reach one another. Before we attach a controller that behaves like a hubber switch, let's first review what a hub does. In a hub, no forwarding information is actually stored at the switch that connects the hosts and the network. Therefore, when an input packet arrives on a particular port, the switch simply forwards that packet out all of the output ports. To see how this works with POX, let's look at the POX Hub application. The place to start looking at the code is in hub.py, which contains two functions. One is a method called launch, which just adds a listener that listens for OpenFlow switches to connect to it. In this case, when we launch the Hub, the Open vSwitch that we created with the Mininet topology, will attempt to connect to our hub. Let's now take a quick look at what happens when we start the POX Controller using the hub functionality. What we see here when we start POX is a little bit of information including information about the OpenFlow switch that has connected to this hub. That switch in particular is the Open vSwitch that we've created in the Mininet topology. If we look at our new Mininet topology we can see that we now have a controller designated as C0. That is the POX Controller running the Hub functionality that we will now look into in a little bit more detail. Going back to the code in hub.py, we can now see what happens when the POX Controller receives a connection attempt from an OpenFlow switch. What's shown here on the slide is the entire POX code for implementing a hub controller. The handle connection up method simply creates a flow modification message that we will send back to the Open vSwitch, telling the switch to modify its flow table entries. So we first create the message, and in that message, we append a specific action which simply is to send the packets on all of the output ports. Once we've created that OpenFlow flow table modification method, we simply send that message to the switch on the connection that we have from the Open vSwitch. If we now try to ping all of the nodes in topology, we see that all of the nodes can reach one another, and if we use dpctl to look at the flows that are stored in the Open vSwitch, we can now see that there's a flow table entry whose action is to flood. So to review what we just did, we took our Mininet topology and we started a POX Controller running hub.py, which simply executed the functionality that we showed on a previous slide. Now, what we're going to do is change the control methods that are running at the POX Controller so that the controller can cause the switch to implement a learning switch rather than just a simple hub. Let's first review what a learning switch does and how it differs from a hub. So if you recall, when a packet arrives on an input port at a hub, the hub simply forwards that packet on all of the output ports. A learning switch, on the other hand, behaves a little differently because when that input packet arrives, the switch learns how to reach the particular destination that sent the packet to the switch. For example, in the figure here, we see that a packet arrives from A. At that point, the switch can examine the source MAC address for that packet and then determine that packets that are destined for that source MAC address for A should be sent on the output port on the left side of the switch here. In other words, each incoming frame causes the switch to create a new flow table entry. To cause the POX Controller to induce that behavior on the Open vSwitch, we attach the POX Controller as before, but instead of running the hub code that we just looked at we are going to run a different set of methods which is in the l2_learning.py file in the POX distribution. Let's jump in and take a quick look at the learning switch algorithm that is implemented in that Python file. [BLANK_AUDIO]. The algorithm has several steps. The first step is to use the source address of the packet and the switch port to update the address and port table that the controller itself maintains as a hash table. The second is to drop certain types of packets. The third is to check whether the destination for the packet is a multicast destination. If it is, the controller instructs the switch to flood the packet on all output ports. If the destination address for the packet is not already contained in the hash table that's being maintained at the controller for mapping addresses to ports then the controller instructs the switch to behave like a hub by flooding the traffic out all output ports. If the output port is the same as the input port, the controller instructs the switch to drop the packet to avoid loops. Otherwise, the controller sends a flow table modification entry to the switch. That flow table modification entry is similar to the one we looked at in the hub example, but the difference is that the flow table entry is specific to the port on which the packet arrived and that address that's contained in the source address field of the incoming packet. What the controller does is take that source address for the packet and the incoming port on which the packet arrived and inserts a flow table entry in the switch that instructs all future packets destined for that address to be forwarded only out that output port rather than being flooded out all output ports. Let's clean up the Mininet topology that we had before and start it again. Now, instead of attaching the POX Controller with the Hub control logic, let's instead attach a POX Controller that runs the learning switch algorithm that we just went through. So once we start the controller we see that, as before, our Open vSwitch has connected to the controller and if we try to ping all of the hosts we can once again see that the hosts can communicate with one another. Now that behavior looks the same as before, but the difference arises when we look at dpctl to dump the floats. What we see now in the switch are a bunch of different flow table entries. What we can see is that each flow table entry has a particular destination address and the output port on which packets for that destination are to be forwarded. Let's take a very quick look at the Python code that is running at the POX Controller. Now, as before we have a launch method which registers the l2 learning object with the core POX Controller. Upon being instantiated that object adds a listener to ensure that it can handle connection up events from OpenFlow switches that try to connect to this controller. Upon a connection attempt from an OpenFlow switch, this object then instantiates the learning switch object and passes the connection event to that object. When we dig into that particular object, we can see that upon instantiation we create that hash table mapping the addresses to ports. We add a listener for packet in messages and then we implement the packet in handler. I will not go into all of the details of the implementation of the packet in handler, but let's just jump down to the portion of the code that implements the learning switch algorithm. So, if we jump to this particular line, we can see the beginning of the algorithm. The first step being to assign an entry in the MAC to port table that maps that packet's source MAC address to the port on which the packet arrived. To drop certain types of packets, to flood if the packet's destination is a multicast packet, to flood if the packet's destination is not already in the MAC address to output port mapping, to check whether the designated output port, if it exists, is the same as the port on which the packet arrived and to drop the packet if the input port and the output port are the same. And finally, installing a flow table entry in the Open vSwitch that matches on the particular packet properties and sends the packet out the output port corresponding to the port that it just learned that it should send future packets out on based on the port on which the packet arrived. Finally, once that flow modification message is created, the controller sends it to the switch. In summary, we reviewed the basic operations of a hub and a switch. We set up a simple Mininet topology and used the POX Controller to implement hub and switch functions, and we explored how to implement these two types of control inside the POX control framework. We looked at how the behaviors differed in terms of the flow table entries and the switch using dpctl, and we also walked through the code itself.