You are to write a python script to read the following 32-bit values from ifTable, and keep a running non-wrapping total for each interface of the following:
Python numbers are automatically high-precision. But when updating, you'll have to take into account the possibility of wrap-around. If the new and old values are newval and oldval, and newval > oldval, you update the total with
total += (newval - oldval)
But if there was a wrap, then newval < oldval, the amount to increment by is (232-oldval) + newval. If you were doing true 32-bit arithmetic, this would be the same as (newval-oldval) above. But, in Python, you'll have to include the 232.
The model programs for you to use are walk.py and getnext.py. Both do pretty much the same thing, actually.
One approach is to use a Python dictionary for each variable, indexed by the interface number ifIndex (or ifDescr). The ifIndex is available as an integer as lastlevels(oid,1)[0].
Do the polling every 5 minutes, but then try to keep the program running for 24 hours (write out your totals every so often, just to make sure they're not lost). Binge-watch something in the meantime to try to get ifInOctets to wrap around!
It's a nice touch to save the very first values of the attributes above, and subtract them, so that your final number represents the cumulative output since the program started running.
Turn in your Python script, the final output, and also all the intermediate output values. (The latter should show if there was an overflow.)
In the mininet virtual machine, the file /root/pox/pox/misc/of_tutorial.py implements an Ethernet hub. Change the code so that it functions as a switch. The code has been structured to make this relatively straightforward; you will have to implement act_like_switch() and then change _handle_PacketIn so that it calls this instead of act_like_hub().
(You will need to install the mininet virtual machine! My virtual-disk image is here, suitable for VirtualBox.)
Rather than use of_tutorial.py directly, I recommend using the very similar myswitch.py. I've added some variable declarations and output messages.
Copy myswitch.py to the directory /root/pox/pox/misc, before you start, and edit only the latter.
To run this, you will need two root-login windows. In the first window, invoke mininet as follows (in the directory /root/pld, where rectangle.py is defined). Make sure, though, that the self.addLink( s4, s1 ) line is commented out first.
mn --custom brectangle.py --topo recttopo --controller remote --switch ovsk --mac
Then, start up pox in the second window as follows, from /root/pox; this will run myswitch.py (note the .py extension is not entered here). Using log.level --WARNING gets rid of a lot of annoying messages; the default log.level is INFO.
./pox.py log.level --WARNING misc.myswitch
At any time you can halt Pox (with CNTL-C) and restart it, without restarting mininet. Stopping and restarting Pox will leave the openflow tables in the switches alone, also, at least for a while.
Since you're running pox in its own window, print statements will appear right there, and you won't need the logging facility.
Handy Mininet commands are:
h1 ping
h4
h1 ping -c 1 h2 # single ping
pingall
# should install all hosts into all switch forwarding tables
Information about Pox objects can be found, along with examples, in openflow.stanford.edu/display/ONL/POX+Wiki. Find misc.of_tutorial in the index and follow the link; that leads to a very detailed page on the exercise.
There are really two steps here. Step one is probably sufficient, but Step two is cool:
Step one: use self.resend_packet(packet_in, ??) to have the controller tell the switch to resend the packet out the given port.
Step two: use msg = of.ofp_flow_mod() / msg.match.dl_dst = ... / msg.actions.append(...) to install a new forwarding rule in the switch (so packets with the matching destination can be handled by the switch with no further interaction with the controller).
If working on Step two, open a third command window, again with a root
prompt, and use the command ovs-ofctl
dump-tables s1 to examine the forwarding table of a switch (here
s1).
For Step one, you need to complete the code in act_like_switch(). Once it's reasonable (that is, once you think it might compile), change _handle_PacketIn() according to this:
#
Comment out the following line and uncomment the one after
# when starting the exercise.
self.act_like_hub(packet, packet_in)
#self.act_like_switch(packet, packet_in)
For act_like_switch() itself, the Pox website has more on what's in the parameters packet and packet_in. However, I've set the important values:
psrc =
packet.src
pdst = packet.dst
inport = packet_in.in_port
# outport defined below
# switch is self.switchnum
The basic idea is that you will replace act_like_hub()'s
self.resend_packet(packet_in, of.OFPP_ALL)
by changing of.OFPP_ALL to the specific next_hop port number.
To edit on the mininet virtual machine, the simplest is to call startx to start up the X-windows environment, and then use the gedit graphical edit editor. Don't forget the key to release the mouse, if necessary: right-cntl. Alternatively, you can edit in your preferred editor on your host system, and then copy everything and paste it into the appropriate mininet-vm file. For example, you can do this:
cat > myswitch.py
paste in the contents you want
CNTL-D (eof)
Pasting into a terminal usually involves something other than CNTL-V, though.
What if the controller uses this strategy:
if (srcaddr is
NOT in the forwarding table)
add flow rule: reach srcaddr via
srcport
Demo: with 5 linear switches and a pingall:
The core problem is that it's new source addresses that
switches must inform the controller about, but the flows above match only
on the destination address. So, if a packet arrives at a switch
S with a destination known to S, then S will not contact the controller
even if the source is new.
The fix is to identify flows by a pair (destaddr,srcaddr). Doing this
means that a new srcaddr cannot -- because it is new -- be part of an
existing flow, and so will always be reported to the controller. The
controller would typically install a bidirectional flow for that
(destaddr,srcaddr) pair if it knows the port it should use to reach
destaddr. If it does not, it will record the port used to reach srcaddr
(that is, the port by which this packet arrived), flood the packet, and
wait for the destaddr node to reply.
This is done in the pox example forwarding/l2_pairs.py.