如何解决SDN Ryu控制器
我正在使用带有 mininet 的 Ryu sdn 控制器 [并且我在 1 中得到图像中的流动错误 TypeError: '>' not supported between 'nonetype' 和 'int' 第 581 行,在 _port_stats_reply_handler 中 如果字节[dpid][p]>0: 类型错误:“nonetype”和“int”的实例之间不支持“>”
from ryu.base import app_manager
from ryu.controller import mac_to_port
from ryu.controller import ofp_event
from ryu.controller.handler import CONfig_disPATCHER,MAIN_disPATCHER
from ryu.controller.handler import set_ev_cls
from ryu.ofproto import ofproto_v1_3
from ryu.lib.mac import haddr_to_bin
from ryu.lib.packet import packet
from ryu.lib.packet import ethernet
from ryu.lib.packet import ether_types
from ryu.lib import mac
from ryu.topology.api import get_switch,get_link
from ryu.app.wsgi import ControllerBase
from ryu.topology import event,switches
from collections import defaultdict
#switches
switches = []
#mymac[srcmac]->(switch,port)
mymac={ }
#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
def get_path (src,dst,first_port,final_port):
#Dijkstra's implementation
print ("get_path is called,src=",src," dst="," first_port="," final_port=",final_port)
distance = {}
prevIoUs = {}
for dpid in switches:
distance[dpid] = float('Inf')
prevIoUs[dpid] = None
distance[src]=0
Q=set(switches)
print ("Q=",Q)
while len(Q)>0:
u = minimum_distance(distance,Q)
Q.remove(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=[]
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
# Adding 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,final_port))
return r
class ProjectController(app_manager.RyuApp):
OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]
def __init__(self,*args,**kwargs):
super(ProjectController,self).__init__(*args,**kwargs)
self.mac_to_port = {}
self.topology_api_app = self
self.datapath_list=[]
# Function that lists all attributes in the given object
def ls(self,obj):
print("\n".join([x for x in dir(obj) if x[0] != "_"]))
def add_flow(self,datapath,actions):
ofproto = datapath.ofproto
parser = datapath.ofproto_parser
match = datapath.ofproto_parser.OFPMatch(in_port=in_port,eth_dst=dst)
inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,actions)]
mod = datapath.ofproto_parser.OFPFlowMod(datapath=datapath,match=match,cookie=0,command=ofproto.OFPFC_ADD,idle_timeout=0,hard_timeout=0,priority=ofproto.OFP_DEFAULT_PRIORITY,instructions=inst)
datapath.send_msg(mod)
def install_path(self,p,ev,src_mac,dst_mac):
shortest_path_route = ""
for z in p:
shortest_path_route += str(z[0])+"-"
print (""+str(z))
#printing the shortest path route
print ("path=",shortest_path_route," src_mac="," dst_mac=",dst_mac)
msg = ev.msg
datapath = msg.datapath
ofproto = datapath.ofproto
parser = datapath.ofproto_parser
for sw,out_port in p:
#print src_mac,"->",dst_mac,"via ",sw," in_port="," out_port=",out_port
match=parser.OFPMatch(in_port=in_port,eth_src=src_mac,eth_dst=dst_mac)
actions=[parser.OFPActionOutput(out_port)]
datapath=self.datapath_list[int(sw)-1]
inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,actions)]
mod = datapath.ofproto_parser.OFPFlowMod(
datapath=datapath,priority=1,instructions=inst)
datapath.send_msg(mod)
@set_ev_cls(ofp_event.EventOFPSwitchFeatures,CONfig_disPATCHER)
def switch_features_handler(self,ev):
print ("switch_features_handler is called")
datapath = ev.msg.datapath
ofproto = datapath.ofproto
parser = datapath.ofproto_parser
match = parser.OFPmatch()
actions = [parser.OFPActionOutput(ofproto.OFPP_CONTROLLER,ofproto.OFPCML_NO_BUFFER)]
inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,actions)]
mod = datapath.ofproto_parser.OFPFlowMod(
datapath=datapath,priority=0,instructions=inst)
datapath.send_msg(mod)
@set_ev_cls(ofp_event.EventOFPPacketIn,MAIN_disPATCHER)
def _packet_in_handler(self,ev):
msg = ev.msg
datapath = msg.datapath
ofproto = datapath.ofproto
parser = datapath.ofproto_parser
in_port = msg.match['in_port']
pkt = packet.Packet(msg.data)
eth = pkt.get_protocol(ethernet.ethernet)
#print "eth.ethertype=",eth.ethertype
#avodi broadcast from LLDP
if eth.ethertype==35020:
return
dst = eth.dst
src = eth.src
dpid = datapath.id
self.mac_to_port.setdefault(dpid,{})
if src not in mymac.keys():
mymac[src]=( dpid,in_port)
#print "mymac=",mymac
if dst in mymac.keys():
p = get_path(mymac[src][0],mymac[dst][0],mymac[src][1],mymac[dst][1])
print (p)
self.install_path(p,dst)
out_port = p[0][2]
else:
out_port = ofproto.OFPP_FLOOD
actions = [parser.OFPActionOutput(out_port)]
# install a flow to avoid packet_in next time
if out_port != ofproto.OFPP_FLOOD:
match = parser.OFPMatch(in_port=in_port,eth_src=src,eth_dst=dst)
data=None
if msg.buffer_id==ofproto.OFP_NO_BUFFER:
data=msg.data
out = parser.OFPPacketout(datapath=datapath,buffer_id=msg.buffer_id,in_port=in_port,actions=actions,data=data)
datapath.send_msg(out)
# EventSwitchEnter triggers get_topology_data method
@set_ev_cls(event.EventSwitchEnter)
def get_topology_data(self,ev):
global switches
#List of switch objects from topology
switch_list = get_switch(self.topology_api_app,None)
switches=[switch.dp.id for switch in switch_list]
self.datapath_list=[switch.dp for switch in switch_list]
#print "self.datapath_list=",self.datapath_list
print ("switches=",switches)
#List of link objects from topology
links_list = get_link(self.topology_api_app,None)
mylinks=[(link.src.dpid,link.dst.dpid,link.src.port_no,link.dst.port_no) for link in links_list]
for s1,s2,port1,port2 in mylinks:
adjacency[s1][s2]=port1
adjacency[s2][s1]=port2
#print s1,port2
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。