Lab 11: Dynamically change the forwarding rules

[Topology]

H1,H2,H3

,S1,S2,S3,S4,S5,H4

,H5

,H6

 

 

 

 

 

 

 

 


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.