Lab 11: Dynamically change the forwarding rules
[Topology]
|
Originally the routing rule for the H1 to H4 is via S1-S2-S5. After 1 second, the rule is changed to via s1-s3-s5. 1 second later, the rule is changed to via s1-s4-5. Then back to via s1-s2-s5. This kind of round-robin scheduling example shows how I dynamically change the forwarding rules for the switches.
[Controller Script: lab7_controller.py]
from pox.core import core import pox.openflow.libopenflow_01 as of from pox.lib.util import dpidToStr from pox.lib.addresses import IPAddr, EthAddr from pox.lib.packet.arp import arp from pox.lib.packet.ethernet import ethernet, ETHER_BROADCAST from pox.lib.packet.packet_base import packet_base from pox.lib.packet.packet_utils import * import pox.lib.packet as pkt from pox.lib.recoco import Timer import time
log = core.getLogger()
s1_dpid=0 s2_dpid=0 s3_dpid=0 s4_dpid=0 s5_dpid=0
s1_p1=0 s1_p4=0 s1_p5=0 s1_p6=0 s2_p1=0 s3_p1=0 s4_p1=0
pre_s1_p1=0 pre_s1_p4=0 pre_s1_p5=0 pre_s1_p6=0 pre_s2_p1=0 pre_s3_p1=0 pre_s4_p1=0
turn=0
def getTheTime(): #fuction to create a timestamp flock = time.localtime() then = "[%s-%s-%s" %(str(flock.tm_year),str(flock.tm_mon),str(flock.tm_mday))
if int(flock.tm_hour)<10: hrs = "0%s" % (str(flock.tm_hour)) else: hrs = str(flock.tm_hour) if int(flock.tm_min)<10: mins = "0%s" % (str(flock.tm_min)) else: mins = str(flock.tm_min)
if int(flock.tm_sec)<10: secs = "0%s" % (str(flock.tm_sec)) else: secs = str(flock.tm_sec)
then +="]%s.%s.%s" % (hrs,mins,secs) return then
def _timer_func (): global s1_dpid, s2_dpid, s3_dpid, s4_dpid, s5_dpid,turn core.openflow.getConnection(s1_dpid).send(of.ofp_stats_request(body=of.ofp_port_stats_request())) core.openflow.getConnection(s2_dpid).send(of.ofp_stats_request(body=of.ofp_port_stats_request())) core.openflow.getConnection(s3_dpid).send(of.ofp_stats_request(body=of.ofp_port_stats_request())) core.openflow.getConnection(s4_dpid).send(of.ofp_stats_request(body=of.ofp_port_stats_request())) #print getTheTime(), "sent the port stats request to s1_dpid"
if turn==0: msg = of.ofp_flow_mod() msg.command=of.OFPFC_MODIFY_STRICT msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.4" msg.actions.append(of.ofp_action_output(port = 5)) core.openflow.getConnection(s1_dpid).send(msg) turn=1 return
if turn==1: msg = of.ofp_flow_mod() msg.command=of.OFPFC_MODIFY_STRICT msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.4" msg.actions.append(of.ofp_action_output(port = 6)) core.openflow.getConnection(s1_dpid).send(msg) turn=2 return
if turn==2: msg = of.ofp_flow_mod() msg.command=of.OFPFC_MODIFY_STRICT msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.4" msg.actions.append(of.ofp_action_output(port = 4)) core.openflow.getConnection(s1_dpid).send(msg) turn=0 return
def _handle_portstats_received (event): global s1_dpid, s2_dpid, s3_dpid, s4_dpid, s5_dpid global s1_p1,s1_p4, s1_p5, s1_p6, s2_p1, s3_p1, s4_p1 global pre_s1_p1,pre_s1_p4, pre_s1_p5, pre_s1_p6, pre_s2_p1, pre_s3_p1, pre_s4_p1
if event.connection.dpid==s1_dpid: for f in event.stats: if int(f.port_no)<65534: if f.port_no==1: pre_s1_p1=s1_p1 s1_p1=f.rx_packets #print "s1_p1->","TxDrop:", f.tx_dropped,"RxDrop:",f.rx_dropped,"TxErr:",f.tx_errors,"CRC:",f.rx_crc_err,"Coll:",f.collisions,"Tx:",f.tx_packets,"Rx:",f.rx_packets if f.port_no==4: pre_s1_p4=s1_p4 s1_p4=f.tx_packets #s1_p4=f.tx_bytes #print "s1_p4->","TxDrop:", f.tx_dropped,"RxDrop:",f.rx_dropped,"TxErr:",f.tx_errors,"CRC:",f.rx_crc_err,"Coll:",f.collisions,"Tx:",f.tx_packets,"Rx:",f.rx_packets if f.port_no==5: pre_s1_p5=s1_p5 s1_p5=f.tx_packets if f.port_no==6: pre_s1_p6=s1_p6 s1_p6=f.tx_packets
if event.connection.dpid==s2_dpid: for f in event.stats: if int(f.port_no)<65534: if f.port_no==1: pre_s2_p1=s2_p1 s2_p1=f.rx_packets #s2_p1=f.rx_bytes print getTheTime(), "s1_p4(Sent):", (s1_p4-pre_s1_p4), "s2_p1(Received):", (s2_p1-pre_s2_p1)
if event.connection.dpid==s3_dpid: for f in event.stats: if int(f.port_no)<65534: if f.port_no==1: pre_s3_p1=s3_p1 s3_p1=f.rx_packets print getTheTime(), "s1_p5(Sent):", (s1_p5-pre_s1_p5), "s3_p1(Received):", (s3_p1-pre_s3_p1)
if event.connection.dpid==s4_dpid: for f in event.stats: if int(f.port_no)<65534: if f.port_no==1: pre_s4_p1=s4_p1 s4_p1=f.rx_packets print getTheTime(), "s1_p6(Sent):", (s1_p6-pre_s1_p6), "s4_p1(Received):", (s4_p1-pre_s4_p1)
def _handle_ConnectionUp (event): global s1_dpid, s2_dpid, s3_dpid, s4_dpid, s5_dpid print "ConnectionUp: ",dpidToStr(event.connection.dpid)
#remember the connection dpid for switch for m in event.connection.features.ports: if m.name == "s1-eth1": s1_dpid = event.connection.dpid print "s1_dpid=", s1_dpid elif m.name == "s2-eth1": s2_dpid = event.connection.dpid print "s2_dpid=", s2_dpid elif m.name == "s3-eth1": s3_dpid = event.connection.dpid print "s3_dpid=", s3_dpid elif m.name == "s4-eth1": s4_dpid = event.connection.dpid print "s4_dpid=", s4_dpid elif m.name == "s5-eth1": s5_dpid = event.connection.dpid print "s5_dpid=", s5_dpid
if s1_dpid<>0 and s2_dpid<>0 and s3_dpid<>0 and s4_dpid<>0: Timer(1, _timer_func, recurring=True)
def _handle_PacketIn(event): global s1_dpid, s2_dpid, s3_dpid, s4_dpid, s5_dpid
packet=event.parsed #print "_handle_PacketIn is called, packet.type:", packet.type, " event.connection.dpid:", event.connection.dpid
if event.connection.dpid==s1_dpid: a=packet.find('arp') if a and a.protodst=="10.0.0.4": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=4)) event.connection.send(msg)
if a and a.protodst=="10.0.0.5": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=5)) event.connection.send(msg)
if a and a.protodst=="10.0.0.6": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=6)) event.connection.send(msg)
if a and a.protodst=="10.0.0.1": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=1)) event.connection.send(msg)
if a and a.protodst=="10.0.0.2": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=2)) event.connection.send(msg)
if a and a.protodst=="10.0.0.3": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=3)) event.connection.send(msg)
msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.1" msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg)
msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.2" msg.actions.append(of.ofp_action_output(port = 2)) event.connection.send(msg)
msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.3" msg.actions.append(of.ofp_action_output(port = 3)) event.connection.send(msg)
msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 1 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.4" msg.actions.append(of.ofp_action_output(port = 4)) event.connection.send(msg)
msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.5" msg.actions.append(of.ofp_action_output(port = 5)) event.connection.send(msg)
msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.6" msg.actions.append(of.ofp_action_output(port = 6)) event.connection.send(msg)
elif event.connection.dpid==s2_dpid: msg = of.ofp_flow_mod() msg.priority =10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 1 msg.match.dl_type=0x0806 msg.actions.append(of.ofp_action_output(port = 2)) event.connection.send(msg)
msg = of.ofp_flow_mod() msg.priority =10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 1 msg.match.dl_type=0x0800 msg.actions.append(of.ofp_action_output(port = 2)) event.connection.send(msg)
msg = of.ofp_flow_mod() msg.priority =10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 2 msg.match.dl_type=0x0806 msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg)
msg = of.ofp_flow_mod() msg.priority =10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 2 msg.match.dl_type=0x0800 msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg)
elif event.connection.dpid==s3_dpid: msg = of.ofp_flow_mod() msg.priority =10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 1 msg.match.dl_type=0x0806 msg.actions.append(of.ofp_action_output(port = 2)) event.connection.send(msg)
msg = of.ofp_flow_mod() msg.priority =10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 1 msg.match.dl_type=0x0800 msg.actions.append(of.ofp_action_output(port = 2)) event.connection.send(msg)
msg = of.ofp_flow_mod() msg.priority =10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 2 msg.match.dl_type=0x0806 msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg)
msg = of.ofp_flow_mod() msg.priority =10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 2 msg.match.dl_type=0x0800 msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg)
elif event.connection.dpid==s4_dpid: msg = of.ofp_flow_mod() msg.priority =10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 1 msg.match.dl_type=0x0806 msg.actions.append(of.ofp_action_output(port = 2)) event.connection.send(msg)
msg = of.ofp_flow_mod() msg.priority =10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 1 msg.match.dl_type=0x0800 msg.actions.append(of.ofp_action_output(port = 2)) event.connection.send(msg)
msg = of.ofp_flow_mod() msg.priority =10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 2 msg.match.dl_type=0x0806 msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg)
msg = of.ofp_flow_mod() msg.priority =10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 2 msg.match.dl_type=0x0800 msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg)
elif event.connection.dpid==s5_dpid: a=packet.find('arp') if a and a.protodst=="10.0.0.4": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=4)) event.connection.send(msg)
if a and a.protodst=="10.0.0.5": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=5)) event.connection.send(msg)
if a and a.protodst=="10.0.0.6": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=6)) event.connection.send(msg)
if a and a.protodst=="10.0.0.1": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=1)) event.connection.send(msg)
if a and a.protodst=="10.0.0.2": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=2)) event.connection.send(msg)
if a and a.protodst=="10.0.0.3": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=3)) event.connection.send(msg)
msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.1" msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg)
msg = of.ofp_flow_mod() msg.priority =10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 6 msg.actions.append(of.ofp_action_output(port = 3)) event.connection.send(msg)
msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.1" msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg)
msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.2" msg.actions.append(of.ofp_action_output(port = 2)) event.connection.send(msg)
msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.3" msg.actions.append(of.ofp_action_output(port = 3)) event.connection.send(msg)
msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.4" msg.actions.append(of.ofp_action_output(port = 4)) event.connection.send(msg)
msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.5" msg.actions.append(of.ofp_action_output(port = 5)) event.connection.send(msg)
msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.6" msg.actions.append(of.ofp_action_output(port = 6)) event.connection.send(msg)
def launch (): global start_time core.openflow.addListenerByName("PortStatsReceived",_handle_portstats_received) core.openflow.addListenerByName("ConnectionUp", _handle_ConnectionUp) core.openflow.addListenerByName("PacketIn",_handle_PacketIn)
|
[Topology script: mymininet7.py]
#!/usr/bin/python
from mininet.topo import Topo from mininet.net import Mininet from mininet.node import CPULimitedHost from mininet.link import TCLink from mininet.util import dumpNodeConnections from mininet.log import setLogLevel from mininet.node import Controller from mininet.cli import CLI from functools import partial from mininet.node import RemoteController import os
#class POXcontroller1( Controller): # def start(self): # self.pox='%s/pox/pox.py' %os.environ['HOME'] # self.cmd(self.pox, "lab7_controller > /tmp/lab7_controller &") # def stop(self): # self.cmd('kill %' +self.pox)
#controllers = { 'poxcontroller': POXcontroller1}
class MyTopo(Topo): "Single switch connected to n hosts." def __init__(self): Topo.__init__(self) s1=self.addSwitch('s1') s2=self.addSwitch('s2') s3=self.addSwitch('s3') s4=self.addSwitch('s4') s5=self.addSwitch('s5') h1=self.addHost('h1') h2=self.addHost('h2') h3=self.addHost('h3') h4=self.addHost('h4') h5=self.addHost('h5') h6=self.addHost('h6')
self.addLink(h1, s1, bw=1, delay='10ms', loss=0, max_queue_size=1000, use_htb=True) self.addLink(h2, s1, bw=1, delay='10ms', loss=0, max_queue_size=1000, use_htb=True) self.addLink(h3, s1, bw=1, delay='10ms', loss=0, max_queue_size=1000, use_htb=True) self.addLink(s1, s2, bw=1, delay='10ms', loss=0, max_queue_size=1000, use_htb=True) self.addLink(s1, s3, bw=1, delay='10ms', loss=0, max_queue_size=1000, use_htb=True) self.addLink(s1, s4, bw=1, delay='10ms', loss=0, max_queue_size=1000, use_htb=True) self.addLink(s2, s5, bw=1, delay='10ms', loss=0, max_queue_size=1000, use_htb=True) self.addLink(s3, s5, bw=1, delay='10ms', loss=0, max_queue_size=1000, use_htb=True) self.addLink(s4, s5, bw=1, delay='10ms', loss=0, max_queue_size=1000, use_htb=True) self.addLink(s5, h4, bw=1, delay='10ms', loss=0, max_queue_size=1000, use_htb=True) self.addLink(s5, h5, bw=1, delay='10ms', loss=0, max_queue_size=1000, use_htb=True) self.addLink(s5, h6, bw=1, delay='10ms', loss=0, max_queue_size=1000, use_htb=True)
def perfTest(): "Create network and run simple performance test" topo = MyTopo() #net = Mininet(topo=topo, host=CPULimitedHost, link=TCLink, controller=POXcontroller1) net = Mininet(topo=topo, host=CPULimitedHost, link=TCLink, controller=partial(RemoteController, ip='127.0.0.1', port=6633)) net.start() print "Dumping host connections" dumpNodeConnections(net.hosts) h1,h2,h3=net.get('h1','h2','h3') h4,h5,h6=net.get('h4','h5','h6') h1.setMAC("0:0:0:0:0:1") h2.setMAC("0:0:0:0:0:2") h3.setMAC("0:0:0:0:0:3") h4.setMAC("0:0:0:0:0:4") h5.setMAC("0:0:0:0:0:5") h6.setMAC("0:0:0:0:0:6") CLI(net) net.stop()
if __name__ == '__main__': setLogLevel('info') perfTest() |
[Running the scripts]
Start the controller first.
Then run the topology script.
Use the command “h1 ping –i 0.1 h4” to send out packets to h4 from h1 for 10 packets per second. We can also see the results from the controller output that s1_p4 (switch 1, port 4) sends out 10 packets, then s1_p5, and followed by s1_p6 with this kind of round robin scheduling.
Dr. Chih-Heng Ke (smallko@gmail.com)
Department of Computer
Science and Information Engineering,
National Quemoy University, Kinmen, Taiwan.