Pyretic + Mininet: Change the path during packet transmission

 

[Topology]

 

First the communication path for h1 and h2 will be via h3 and h4. After 10 seconds, the path will change to via h3-h5-h6-h4. 10 seconds later, the path will change back to via h3-h4. And then so on.

 

[Mininet Script:mytopo1.py]

#!/usr/bin/python

 

from mininet.net import Mininet

from mininet.node import Controller, RemoteController, OVSKernelSwitch, OVSLegacyKernelSwitch, UserSwitch

from mininet.cli import CLI

from mininet.log import setLogLevel

from mininet.link import Link, TCLink

 

def topology():

    "Create a network."

    net = Mininet( controller=RemoteController, link=TCLink, switch=OVSKernelSwitch )

    print "*** Creating nodes"

    h1 = net.addHost( 'h1', mac='00:00:00:00:00:01', ip='10.0.0.1/8' )

    h2 = net.addHost( 'h2', mac='00:00:00:00:00:02', ip='10.0.0.2/8' )

    s3 = net.addSwitch( 's3', listenPort=6634, mac='00:00:00:00:00:03' )

    s4 = net.addSwitch( 's4', listenPort=6635, mac='00:00:00:00:00:04' )

    s5 = net.addSwitch( 's5', listenPort=6636, mac='00:00:00:00:00:05' )

    s6 = net.addSwitch( 's6', listenPort=6637, mac='00:00:00:00:00:06' )

    c7 = net.addController( 'c7', controller=RemoteController, ip='127.0.0.1', port=6633 )

 

    print "*** Creating links"

    net.addLink(s4, h2, 3, 0)

    net.addLink(s6, s4, 2, 2)

    net.addLink(s5, s6, 2, 1)

    net.addLink(s3, s5, 3, 1)

    net.addLink(s3, s4, 2, 1)

    net.addLink(h1, s3, 0, 1)

 

    print "*** Starting network"

    net.build()

    s4.start( [c7] )

    s6.start( [c7] )

    s5.start( [c7] )

    s3.start( [c7] )

    c7.start()

 

    print "*** Running CLI"

    CLI( net )

 

    print "*** Stopping network"

    net.stop()

 

if __name__ == '__main__':

    setLogLevel( 'info' )

    topology()

 

[Pyretic Script:monitor_routing.py]

from pyretic.lib.corelib import *

from pyretic.lib.std import *

from pyretic.lib.query import *

from pyretic.modules.mac_learner import *

from collections import defaultdict

 

from datetime import datetime

import time

import threading

 

ip1 = IPAddr('10.0.0.1')

ip2 = IPAddr('10.0.0.2')

 

#thr[srcip][dstip]

byte=defaultdict(lambda:None)

clock=defaultdict(lambda:None)

thr=defaultdict(lambda:None)

 

#h1-s3-s4-h2

path1=((match(switch=3) >> fwd(2)) +

       (match(switch=4) >> fwd(3)))

 

#h2-s4-s3-h1

path2=((match(switch=4) >> fwd(1)) +

       (match(switch=3) >> fwd(1)))

 

#h1-s3-s5-s6-s4-h2

path3=((match(switch=3) >> fwd(3)) +

       (match(switch=5) >> fwd(2)) +

       (match(switch=6) >> fwd(2)) +

       (match(switch=4) >> fwd(3)))

 

#h2-s4-s6-s5-s4-h1

path4=((match(switch=4) >> fwd(2)) +

       (match(switch=6) >> fwd(1)) +

       (match(switch=5) >> fwd(1)) +

       (match(switch=3) >> fwd(1)))

 

myroute1 = ((match(dstip=ip2) >> path1) +

           (match(dstip=ip1) >> path2))

myroute2 = ((match(dstip=ip2) >> path3) +

           (match(dstip=ip1) >> path4))

 

class myroute(DynamicPolicy):

  def __init__(self):

    super(myroute,self).__init__() 

    self.set_initial_state()

    self.thread = threading.Timer(10.0, self.handle_function)

    self.thread.start()

 

  def handle_function(self):

    print time.time(), " handle_function is called"

    if self.forward == myroute1:

       self.forward = myroute2

       print "change to myroute2"

    else:

       self.forward = myroute1

       print "change to myroute1"

    self.update_policy()

    self.thread = threading.Timer(10.0, self.handle_function)

    self.thread.start()

  

  def set_initial_state(self):

    self.forward = myroute1

    self.update_policy()

 

  def set_network(self,network):

    self.set_initial_state()

 

  def update_policy(self):

    self.policy = self.forward

 

def byte_count_printer(n):

  if len(n)!=0:

    print time.time()

    for i, j in n.items():

      if byte[str(i).split(" ")[2][0]]>0:

        thr[str(i).split(" ")[2][0]] = (j - byte[str(i).split(" ")[2][0]]) * 8.0 / (time.time()-clock[str(i).split(" ")[2][0]])

        print "switch ", str(i).split(" ")[2][0], " =", thr[str(i).split(" ")[2][0]], "bps"

      byte[str(i).split(" ")[2][0]]=j

      clock[str(i).split(" ")[2][0]]=time.time()

      print " ----------------------------------------------------"

 

 

def byte_counts():

  q = count_bytes(3,['switch'])

  q.register_callback(byte_count_printer)

  return q   

  

def main():

  return (myroute()  + byte_counts())

 

 

[Execution]

1. Open one window for mininet script and the other for pyretic controller

 

2. Try to use ping between h1 and h2 and then monitor the transmission path.

From the above figure, we can see that all the switches have values when the path is via h3-h5-h6-h4.

But only switches 3 and 4 have values when the path is via h3-h4.

 

 

Dr. Chih-Heng Ke

Department of Computer Science and Information Engineering, National Quemoy University, Kinmen, Taiwan

Email: smallko@gmail.com / smallko@hotmail.com