Commit e7da4fed authored by Anurag Kumar's avatar Anurag Kumar

Upload New File

parent cba8df56
# encoding: utf-8
import networkx as nx
import random
from matplotlib import pyplot as plt
from ryu.base import app_manager
from ryu.controller import ofp_event
from ryu.controller.handler import MAIN_DISPATCHER, CONFIG_DISPATCHER
from ryu.controller.handler import set_ev_cls
from ryu.ofproto import ofproto_v1_3
from ryu.topology import api as topology
"""
Provide some public methods for operating flow tables and establishing data paths
"""
class RoutingClass(app_manager.RyuApp):
'''
Forward utilization
'''
OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]
def __init__(self, *args, **kwargs):
super(RoutingClass, self).__init__(*args, **kwargs)
self.datapaths = {}
"""
Issue table-miss flow entry, so that the switch will pass the packet-in message to the Ryu controller for data packets that will not be processed
"""
# @set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER)
# def switch_features_handler(self, ev):
# datapath = ev.msg.datapath
# ofproto = datapath.ofproto
# parser = datapath.ofproto_parser
# match = parser.OFPMatch()
# actions = [parser.OFPActionOutput(ofproto.OFPP_CONTROLLER, ofproto.OFPCML_NO_BUFFER)]
# self.add_flow(datapath, 0, match, actions)
@set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER)
def switch_features_handler(self, ev):
msg = ev.msg
dp = msg.datapath
ofp = dp.ofproto
ofp_parser = dp.ofproto_parser
match = ofp_parser.OFPMatch()
actions = [ofp_parser.OFPActionOutput(ofp.OFPP_CONTROLLER, ofp.OFPCML_NO_BUFFER)]
self.add_flow(dp, 0, match, actions)
self.logger.debug('OFPSwitchFeatures received: '
'datapath_id=0x%016x n_buffers=%d '
'n_tables=%d auxiliary_id=%d '
'capabilities=0x%08x',
msg.datapath_id, msg.n_buffers, msg.n_tables,
msg.auxiliary_id, msg.capabilities)
"""
Establish data path
"""
def set_best_path(self, from_src_dpid, to_dest_dpid, to_dest_port_number, to_dst_match, previous_actions=[]):
#-------------------------------------------------------
"""
Generate global topo diagram
"""
# nx_grapth = self.get_nx_graph()
graph = nx.DiGraph()
get_all_switches = topology.get_all_switch(self)
get_all_links = topology.get_all_link(self)
for switch in get_all_switches:
dp = switch.dp
dpid = dp.id
graph.add_node(dpid)
for link in get_all_links:
src = link.src
dest = link.dst
src_dpid = src.dpid
dest_dpid = dest.dpid
src_port = src.port_no
dest_port = dest.port_no
graph.add_edge(src_dpid, dest_dpid, src_port=src_port, dst_port=dest_port, weight=random.randrange(10, 50))
# Bug - if you create here then you have to fix the bandwidth, otherwise random function will generate random bandwidth everytime. otherwise create a function that return graph
#---------------------------------------------------------------------------------------------------------------------
"""
Calculate the shortest path
"""
# path = self.get_shortest_path(nx_grapth, from_dpid, to_dpid)
path = []
if(nx.has_path(graph, from_src_dpid, to_dest_dpid)):
path = nx.dijkstra_path(graph, from_src_dpid, to_dest_dpid)
else:
path = None
#------------------------------------------------------------------------------------------------------------------------
if path is None:
return
port_no = 0
if len(path) == 1:
dp = self.get_datapath(from_src_dpid)
actions = [dp.ofproto_parser.OFPActionOutput(to_dest_port_number)]
self.add_flow(dp, 1, to_dst_match, previous_actions+actions)
port_no = to_dest_port_number
else:
self.install_path(to_dst_match, path, graph, previous_actions)
dst_dp = self.get_datapath(to_dest_dpid)
actions = [dst_dp.ofproto_parser.OFPActionOutput(to_dest_port_number)]
self.add_flow(dst_dp, 1, to_dst_match, previous_actions+actions)
port_no = graph.adj[path[0]][path[1]]['src_port']
return port_no
"""
Calculate the shortest path
"""
# def get_shortest_path(self, nx_graph, src_dpid, dst_dpid):
# if nx.has_path(nx_graph, src_dpid, dst_dpid):
# return nx.dijkstra_path(nx_graph, src_dpid, dst_dpid)
# return None
"""
Generate global topo diagram
"""
# def get_nx_graph(self):
# graph = nx.DiGraph()
# switches = topology.get_all_switch(self)
# links = topology.get_all_link(self)
# for switch in switches:
# dpid = switch.dp.id
# graph.add_node(dpid)
# for link in links:
# src_dpid = link.src.dpid
# dst_dpid = link.dst.dpid
# src_port = link.src.port_no
# dst_port = link.dst.port_no
# graph.add_edge(src_dpid,
# dst_dpid,
# src_port=src_port,
# dst_port=dst_port, weight=random.randrange(10, 50))
# return graph
"""
Send flow table according to the best path
"""
def install_path(self, match, path, graph, previous_actions=[]):
for index, dpid in enumerate(path[:-1]):
port_no = graph.adj[path[index]][path[index + 1]]['src_port']
dp = self.get_datapath(dpid)
actions = [dp.ofproto_parser.OFPActionOutput(port_no)]
self.add_flow(dp, 1, match, previous_actions+actions)
def add_flow(self, datapath, priority, match, actions):
ofproto = datapath.ofproto
parser = datapath.ofproto_parser
inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions)]
mod = parser.OFPFlowMod(datapath=datapath, priority=priority, match=match, hard_timeout=0, instructions=inst)
datapath.send_msg(mod)
def get_datapath(self, dpid):
"""
Parameters:
self -- RyuApp instance
dpid -- Datapath ID (int type) or None to get all datapath objects
Objective:
Get datapath object by dpid.
Returns a object of datapath, a list of datapath objects when no dpid given or None when error.
"""
if dpid not in self.datapaths:
# switch = topology.get_switch(self, dpid)[0]
# self.datapaths[dpid] = switch.dp
# return switch.dp
self.datapaths[dpid] = topology.get_switch(self, dpid)[0].dp
return topology.get_switch(self, dpid)[0].dp
return self.datapaths[dpid]
def get_all_datapaths(self):
get_all_switches = topology.get_all_switch(self)
for switch in get_all_switches:
# dp = switch.dp
# dpid = dp.id
# self.datapaths[dpid] = dp
self.datapaths[switch.dp.id] = switch.dp
return self.datapaths.values()
"""
Get host information based on IP
"""
def get_host(self, ipAddr):
get_all_host = topology.get_all_host(self)
for host in get_all_host:
if ipAddr in host.ipv4:
return host
return None
"""
Send a data packet directly from a port of a switch
"""
def packet_out(self, dp, msg, out_port):
ofproto = dp.ofproto
actions = [dp.ofproto_parser.OFPActionOutput(out_port)]
# construct packet_out message and send it.
out = dp.ofproto_parser.OFPPacketOut(
datapath=dp, in_port=msg.match['in_port'],
buffer_id=ofproto.OFP_NO_BUFFER,
actions=actions, data=msg.data)
dp.send_msg(out)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment