在軟體定義網路上最佳路由之研究

關於系統

程式碼

範例影片
關於我們

靜態路由拓樸程式

#!/usr/bin/python
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()

靜態路由控制器程式

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(2))+
(match(switch = 2) >> fwd(2))+
(match(switch = 3) >> fwd(2)))

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

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

myroute = ((match(dstip = ip6) >> route1)+
(match(dstip = ip7) >> route2)+
(match(dstip = ip5) >> route3))

def main():
return myroute

 

  • 動態路由控制器程式(Dijkstra's algorithm)

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))

def minimum_distance(distance, Q):
min = float('Inf')
node = 0
for v in Q:
if distance[v] < min:
min = distance[v]
node = v
return node

  • Get_path

def get_path (src,dst,first_port,final_port):
  #Dijkstra's algorithm
print "get_path 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
Q=set(switches)
print "Q=",Q

while len(Q)>0:
u = minimum_distance(distance, Q)
print "u=",u,"Q=",Q
Q.remove(u)
print "u=",u

for p in switches:
if adjacency[u][p]!=None:
w = 1
if distance[u] + w < distance[p]:
distance[p] = distance[u] + w
previous[p] = u

r=[]
print "r=",r
p=dst
r.append(p)
print "append r=",r
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

  • Find_route

class find_route(DynamicPolicy):
#print "find_route"
def __init__(self):
#print "__init__"
super(find_route,self).__init__()
self.flood = flood()
self.set_initial_state()

def set_initial_state(self):
#print "set_initial_state"
self.query = packets(1,['srcmac','dstmac', 'srcip', 'dstip'])
self.query.register_callback(self.myroute)
self.forward = self.flood
#print "self.flood=",self.flood
self.update_policy()

def set_network(self,network):
#print "set_network"
self.set_initial_state()

def update_policy(self):
#print "update_policy"
self.policy = self.forward + self.query
#print "self.policy=",self.policy

def myroute(self,pkt):
print pkt['srcmac'], pkt['dstmac'], pkt['srcip'], pkt['dstip']
#print "myroute   pkt['srcmac']=",pkt['srcmac'],"pkt['dstmac']=", pkt['dstmac'],"pkt['srcip']=", pkt['srcip'],"pkt['dstip']=", pkt['dstip']
if (pkt['srcmac'] not in myhost.keys()) or (pkt['dstmac'] not in myhost.keys()):
return
p1 = get_path(myhost[pkt['srcmac']][0], myhost[pkt['dstmac']][0],myhost[pkt['srcmac']][1], myhost[pkt['dstmac']][1])
print "p1=",p1

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

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

  • Find_host

def find_host():
q = packets(1,['srcmac','switch'])
#print "q= ",q
q.register_callback(mymac_learner)
#print "register  q=",q
return q

def mymac_learner(pkt):
print pkt['srcmac'], pkt['dstmac'], pkt['switch'], pkt['inport']
#print "mymac_learner", 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=",a,"myhost[a][0]=", myhost[a][0],"myhost[a][1]=", myhost[a][1]

  • Find_switch

class find_switch(DynamicPolicy):
# print "find_switch"
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

  • Arp_and_ip

def arp_and_ip():
#print "arp_and_ip"
return if_(match(ethtype=ARP_TYPE), flood(), find_route())

def main():
#print "main"
return ( find_switch() + find_host() + arp_and_ip())

  • 動態路由控制器程式(Bellman-Ford algorithm)

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))

def minimum_distance(distance, Q):
min = float('Inf')
node = 0
for v in Q:
if distance[v] < min:
min = distance[v]
node = v
return node

  • Get_path

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

  • Find_route

class find_route(DynamicPolicy):
#print "find_route"
def __init__(self):
#print "__init__"
super(find_route,self).__init__()
self.flood = flood()
self.set_initial_state()

def set_initial_state(self):
#print "set_initial_state"
self.query = packets(1,['srcmac','dstmac', 'srcip', 'dstip'])
self.query.register_callback(self.myroute)
self.forward = self.flood
#print "self.flood=",self.flood
self.update_policy()

def set_network(self,network):
#print "set_network"
self.set_initial_state()

def update_policy(self):
#print "update_policy"
self.policy = self.forward + self.query
#print "self.policy=",self.policy

def myroute(self,pkt):
print pkt['srcmac'], pkt['dstmac'], pkt['srcip'], pkt['dstip']
#print "myroute   pkt['srcmac']=",pkt['srcmac'],"pkt['dstmac']=", pkt['dstmac'],"pkt['srcip']=", pkt['srcip'],"pkt['dstip']=", pkt['dstip']
if (pkt['srcmac'] not in myhost.keys()) or (pkt['dstmac'] not in myhost.keys()):
return
p1 = get_path(myhost[pkt['srcmac']][0], myhost[pkt['dstmac']][0],myhost[pkt['srcmac']][1], myhost[pkt['dstmac']][1])
print "p1=",p1

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

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

  • Find_host

def find_host():
q = packets(1,['srcmac','switch'])
#print "q= ",q
q.register_callback(mymac_learner)
#print "register  q=",q
return q

def mymac_learner(pkt):
print pkt['srcmac'], pkt['dstmac'], pkt['switch'], pkt['inport']
#print "mymac_learner", 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=",a,"myhost[a][0]=", myhost[a][0],"myhost[a][1]=", myhost[a][1]

  • Find_switch

class find_switch(DynamicPolicy):
# print "find_switch"
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

  • Arp_and_ip

def arp_and_ip():
#print "arp_and_ip"
return if_(match(ethtype=ARP_TYPE), flood(), find_route())

def main():
#print "main"
return ( find_switch() + find_host() + arp_and_ip())