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