Pyretic : Routing

[Topology]

 

 

[mininet script]

#!/usr/bin/python

 

"""

Script created by VND - Visual Network Description (SDN version)

"""

from mininet.net import Mininet

from mininet.node import Controller, RemoteController, OVSKernelSwitch, 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"

    s1 = net.addSwitch( 's1', listenPort=6673, mac='00:00:00:00:00:01' )

    s2 = net.addSwitch( 's2', listenPort=6674, mac='00:00:00:00:00:02' )

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

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

    h5 = net.addHost( 'h5', mac='00:00:00:00:00:05', ip='10.0.0.5/8' )

    h6 = net.addHost( 'h6', mac='00:00:00:00:00:06', ip='10.0.0.6/8' )

    h7 = net.addHost( 'h7', mac='00:00:00:00:00:07', ip='10.0.0.7/8' )

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

 

    print "*** Creating links"

    net.addLink(s3, h7, 4, 0)

    net.addLink(s3, h6, 3, 0)

    net.addLink(h5, s1, 0, 3)

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

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

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

    net.addLink(s1, s2, 1, 1)

 

    print "*** Starting network"

    net.build()

    c8.start()

    s3.start( [c8] )

    s4.start( [c8] )

    s2.start( [c8] )

    s1.start( [c8] )

 

    print "*** Running CLI"

    CLI( net )

 

    print "*** Stopping network"

    net.stop()

 

if __name__ == '__main__':

    setLogLevel( 'info' )

    topology()

 

 

[Pyretic: Static Routing  myroute]

In this lab, I use sdnhub VM. Please put the following file under /home/ubuntu/pyretic/pyretic/tutorial

 

from pyretic.lib.corelib import*

from pyretic.lib.std import *

 

ip5 = IPAddr('10.0.0.5')

ip6 = IPAddr('10.0.0.6')

ip7 = IPAddr('10.0.0.7')

 

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

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

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

 

route2 = ((match(switch=1) >> fwd(2)) +

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

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

 

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

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

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

 

myroute = ((match(dstip=ip6) >> route1) +

           (match(dstip=ip7) >> route2) +

           (match(dstip=ip5) >> route3))

 

def main():

   return myroute

The above code is easy to understand.

 

[Execution]

1. open a terminal and run the pyretic with myroute module

 

2. open another terminal to run the mininet script

 

3. Ping Test

 

[Use Bellmanford to find a shortest path: myroute3]

from pyretic.lib.corelib import*

from pyretic.lib.std import *

from multiprocessing import Lock

from pyretic.lib.query import *

from collections import defaultdict

 

#switches

switches = []

 

#myhost[srcmac]->(switch, port)

myhost={}

 

#adjacency map [sw1][sw2]->port from sw1 to sw2

adjacency=defaultdict(lambda:defaultdict(lambda:None))

 

ip5 = IPAddr('10.0.0.5')

ip6 = IPAddr('10.0.0.6')

ip7 = IPAddr('10.0.0.7')

 

def get_path (src,dst,first_port,final_port):

  #Bellman-Ford algorithm

  print "src=",src," dst=",dst, " first_port=", first_port, " final_port=", final_port

  distance = {}

  previous = {}      

 

  for dpid in switches:

    distance[dpid] = 9999

    previous[dpid] = None

 

  distance[src]=0

 

  for m in range(len(switches)-1):

    for p in switches:

      for q in switches:

        if adjacency[p][q]!=None:

           w = 1

           if distance[p] + w < distance[q]:

             distance[q] = distance[p] + w

             previous[q] = p

  r=[]

  p=dst

  r.append(p)

  q=previous[p]

  while q is not None:

    if q == src:

      r.append(q)

      break

    p=q

    r.append(p)

    q=previous[p]

 

  r.reverse()

  if src==dst:

    path=[src]

  else:

    path=r

 

  # Now add the ports

  r = []

  in_port = first_port

  for s1,s2 in zip(path[:-1],path[1:]):

    out_port = adjacency[s1][s2]

    r.append((s1,in_port,out_port))

    in_port = adjacency[s2][s1]

  r.append((dst,in_port,final_port))

  return r

 

class find_route(DynamicPolicy):

  def __init__(self):

    super(find_route,self).__init__()

    self.flood = flood()

    self.set_initial_state()

 

  def set_initial_state(self):

    self.query = packets(1,['srcmac','dstmac', 'srcip', 'dstip'])

    self.query.register_callback(self.myroute)

    self.forward = self.flood

    self.update_policy()

 

  def set_network(self,network):

    self.set_initial_state()

 

  def update_policy(self):

    self.policy = self.forward + self.query

 

  def myroute(self,pkt):

    #print pkt['srcmac'], pkt['dstmac'], pkt['srcip'], pkt['dstip']

    if (pkt['srcmac'] not in myhost.keys()) or (pkt['dstmac'] not in myhost.keys()):

      return

    #print myhost[pkt['srcmac']][0], myhost[pkt['dstmac']][0]

    #if match(ethtype=IP_TYPE):

    #  print "ipv4 packet"

    p1 = get_path(myhost[pkt['srcmac']][0], myhost[pkt['dstmac']][0],myhost[pkt['srcmac']][1], myhost[pkt['dstmac']][1])

    print p1

 

    p2 = get_path(myhost[pkt['dstmac']][0], myhost[pkt['srcmac']][0],myhost[pkt['dstmac']][1], myhost[pkt['srcmac']][1])

    print p2

   

    r1 = parallel([(match(switch=a,srcip=pkt['srcip'],dstip=pkt['dstip']) >> fwd(c)) for a,b,c in p1])

    #print r1

 

    r2 = parallel([(match(switch=a,srcip=pkt['dstip'],dstip=pkt['srcip']) >> fwd(c)) for a,b,c in p2])

    #print r2

 

    r = r1 + r2

    print r

 

    #self.forward = r

    #modified @2015/7/2

    self.forward = if_(match(dstip=pkt['dstip'],srcip=pkt['srcip']), r, self.forward)

    self.update_policy()

 

 

def find_host():

   q = packets(1,['srcmac','switch'])

   q.register_callback(mymac_learner)

   return q

 

def mymac_learner(pkt):

   print pkt['srcmac'], pkt['dstmac'], pkt['switch'], pkt['inport']

   #if match(ethtype=ARP_TYPE):

   # print "arp packet"

  

   if pkt['srcmac'] not in myhost.keys():

      myhost[pkt['srcmac']]=( pkt['switch'], pkt['inport'])

 

   #for a in myhost.keys():

   #  print a, myhost[a][0], myhost[a][1]

  

  

class find_switch(DynamicPolicy):

    def __init__(self):

        self.last_topology = None

        self.lock = Lock()

        super(find_switch,self).__init__()

 

    def set_network(self, network):

        with self.lock:

            for x in network.switch_list():

              switches.append(x)

            for (s1,s2,data) in network.topology.edges(data=True):

              adjacency[s1][s2]=data[s1]

              adjacency[s2][s1]=data[s2]

            self.last_topology = network.topology

          

 

def arp_and_ip():

  return if_(match(ethtype=ARP_TYPE), flood(), find_route())

        

def main():

  return ( find_switch() + find_host() + arp_and_ip())

 

[Execution]

 

 

Dr. Chih-Heng

 Ke

 

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

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