[MUSIC]
In the last assignment we implemented a traffic monitor to collect statistics
about each host bandwidth usage.
We saw in our dashboard how one tenant consumed almost all of the available
bandwidth in the network.
As a result, the video quality in another tenants application suffered.
This is partly due with the nature of our applications.
Our video stream is adaptive, so when it competes with other flows,
the quality is scaled down.
It's also a result of the protocol of these applications you're using.
All our iperf flows are using UDP, so
they don't compete fairly with the video stream.
Remember from our previous assignments,
our naive routing policy will send all traffic through one core switch.
As a result, the switch s104 becomes a bottleneck in our network.
In this assignment, we'll improve this policy by using all core switches.
We'll keep it simple by pre-assigning tenants to each core switch.
So you won't need to worry about having to figure out how to balance tenants across
the core switches.
Specifically, we'll write a small amount of code to generate rules for
the edge switches.
These rules will route traffic to the core switch based on the packet's
destination host and which tenant that host belongs to.
We use the same topology as before.
Switches will be named the same and ports will be numbered the same.
We'll statically assign each core switch to handle the different tenant.
Here, we've assigned core switch s104 to handle all traffic for
VLAN 0, which is our video streaming tenant and
s105 will handle traffic for VLAN 1, which is our iperf tenant.
So our routing policy will look like this, switch s102 and s103 will forward
all packets to s104 or that are destined for the video streaming hosts.
And switches s101, s102, and s103,
before all traffic to s105 for iperf traffic.
So the global policy will look like this.
This will be done programmatically, but
you'll only need to write a very small amount of code to do this.
So let's look exactly at what you'll need to write.
So I'll start by walking through you through the relevant code, and
then show you how the system should behave if your code works properly.
So our setup will be exactly the same as a previous assignment, so
let's look at the code you'll need to write.
So we'll edit the file policy under the directory /cloudnetmooc/minidc/controller.
So if we open file policy.py.
So we'll edit the file policy.py.
If you look at the top of this file, you'll see a description
of useful classes and functions that you might need for this assignment.
So the first is CoreSwitch class which stores information about the core
switches.
Specifically the name, it's dpid and
a list of the pre-assigned VLANs that that switch will handle.
In the edge class, we have the name and the dpid properties and
we also have a list called neighbors which is the host attached to that switch.
In the host class we have mame which is it's name like h6,
the MACaddress, switch which is which switch the host is connected to.
And VLANs which is a list of the VLANs which with that host is associated.
And finally, we have a topology class.
So this has a list of hosts, switches,
core switches and edge switches, and
a dictionary of VLANs with the key VLAN number and
what hosts are part of that VLAN.
The ports dictionary, we saw it in the last assignment which
takes a switch name as the first key and a number as a second key.
And returns the host or switch connected to the port on that switch.
For this assignment you might also find the function getVlanCore useful.
Which takes a vlanId and returns the pre-assigned core switch for that VLAN.
In this assignment, you'll edit the class static policy.
Specifically the build function, but first let's look at the current
policy that our system is using which is the class default policy.
You can use this class
as a rough template for
your solution.
So let's look specifically at the function build,
which builds the routingTable for our policy.
So remember with this policy,
all traffic from edge switches is sent through one core switch.
So we can see we start by creating an empty routing table which is a dictionary.
And a routing table is structured as a dictionary where each key is a switch,
either a core switch or an edge switch and the value is a list of rules.
So we can see here that we then take one core switch from
the list of core switches in out topology and it's dpid.
Then we initialize our routing table.
With an entry for only that coreSwitch using its dpid.
The first block of code creates rules for
core switches to send packets from a core switch down to an edge switch.
So in each core switch, we install a rule that says,
if a pack's destination matches some host MAC address forwarded out some part.
So which port do we forward it out?
We forwarded out the part connected to the edge switch for that destination host.
So let's look at a quick example before further exploring this code.
So suppose we're creating a rule for the core switch s104,
if we see a packet destined for host h1, we want to forward it closer to host h1.
We do this by sending it out a port that connects the core switch
to h1s edge switch which is s102.
So with our destination h1 we'll send it out the port
connected to switch s102 which we can see is port two.
Now let's look at the second block of code which installs rules in the edge switches.
There'll be two types of rules in an edge switch.
The first, says that if a destination is a host connected to that switch,
it forwards it out the port for that host.
So this is what we call a neighboring host.
Otherwise we send it out a port to a core switch.
Now in our [INAUDIBLE] policy remember we send all traffic to one core switch.
So here in the else block we can see that we determine the outport for
non neighboring host using the topo.ports dictionary again.
We pass it the name of the edge switch where the packet is currently located.
And the core name, which remember earlier was
the single core that we're using in our policy.
And the ordering matters in this topo.ports object.
So if we want to look up the outport on switch s104 for switch s102,
we'd type something like topo.ports s104 and then s102.
If we wanted the output on switch s102 we reverse it.
So s102 would be first and s104 would be second.
So now your solution will be to implement a block of code
just like this second block.
But we want to use all core switches.
So if we look at the comment for the block that you need to add in the class
static policy, we have given you a hint to use the function debt VLAN core.
So this will return the core switch.
Stack be assigned to a given vlanId.
And remember,
the documentation at the top of a file will describe how to find a host's vlanId.
Now, to verify your routing policy works.
Let's start up our system.
To start two terminals, one for
the network emulator and one for the controller.
And we'll use the vid parameter, just as before.
And remember the pseudo password is lower case M-O-O-C.