[Ryu-devel] Dijkstra application
Brought to you by:
nz_gizmoguy
From: Gautam P. <gpa...@gm...> - 2015-07-13 05:17:46
|
Hi, Can anyone tell me what is wrong in this Dijkstra application? Why hosts are unable to ping. 1. from ryu.base import app_manager 2. from ryu.controller import ofp_event 3. from ryu.controller.handler import CONFIG_DISPATCHER, MAIN_DISPATCHER, DEAD_DISPATCHER 4. from ryu.controller.handler import set_ev_cls 5. from ryu.ofproto import ofproto_v1_3 6. from ryu.lib.packet import packet 7. from ryu.lib.packet import ethernet 8. from ryu.lib.packet import arp 9. from ryu.lib.packet import ipv4 10. from collections import defaultdict 11. from ryu.topology.api import get_switch,get_link 12. from ryu.topology import event,switches 13. 14. ARP = arp.arp.__name__ 15. ETHERNET = ethernet.ethernet.__name__ 16. ETHERNET_MULTICAST = "ff:ff:ff:ff:ff:ff" 17. 18. adjacency = defaultdict(lambda: defaultdict(lambda: None)) 19. path_map = defaultdict(lambda: defaultdict(lambda: (None, None))) 20. sws = [] 21. switches={} 22. mac_map={} 23. 24. def _get_raw_path(src, dst): 25. """ 26. Get a raw path (just a list of nodes to traverse) 27. """ 28. if len(path_map) == 0: _dijkstra_paths() 29. if src is dst: 30. # We're here! 31. return [] 32. 33. if path_map[src][dst][0] is None: 34. return None 35. intermediate = path_map[src][dst][1] 36. if intermediate is None: 37. # Directly connected 38. return [] 39. return _get_raw_path(src, intermediate) + [intermediate] + \ 40. _get_raw_path(intermediate, dst) 41. 42. def _get_path(src, dst, first_port, final_port): 43. """ 44. Gets a cooked path -- a list of (node,in_port,out_port) 45. """ 46. # Start with a raw path... 47. print src 48. print dst 49. if src == dst: 50. path = [src] 51. else: 52. path = _get_raw_path(src, dst) 53. if path is None: return None 54. path = [src] + path + [dst] 55. 56. # Now add the ports 57. r = [] 58. in_port = first_port 59. for s1, s2 in zip(path[:-1], path[1:]): 60. out_port = adjacency[s1][s2] 61. r.append((s1, in_port, out_port)) 62. in_port = adjacency[s2][s1] 63. r.append((dst, in_port, final_port)) 64. print 'R is %s' % r 65. return r 66. 67. def _dijkstra_paths(): 68. path_map.clear() 69. for k in sws: 70. for j, port in adjacency[k].iteritems(): 71. if port is None: 72. continue 73. path_map[k][j] = (1, None) 74. path_map[k][k] = (0, None) 75. print adjacency[k] 76. 77. for t in sws: 78. final_point = [] 79. final_point.append(t) 80. for i in range(len(sws) - 1): 81. min_path = 999 82. for p in sws: 83. if p not in final_point: 84. if path_map[t][p][0] is not None and path_map[t][p][0] < min_path: 85. min_path = path_map[t][p][0] 86. temp = p 87. final_point.append(temp) 88. for m in sws: 89. if m not in final_point: 90. if path_map[t][m][0] is None and path_map[t][temp][0] is not None and path_map[temp][m][ 91. 0] is not None: 92. path_map[t][m] = (path_map[t][temp][0 ] + path_map[temp][m][0], temp) 93. elif path_map[t][temp][0] is not None and path_map[temp][m][0] is not None and path_map[t][m][ 94. 0] is not None: 95. if path_map[t][temp][0] + path_map[temp][m][0 ] < path_map[t][m][0]: 96. path_map[t][m] = (path_map[t][temp][0 ] + path_map[temp][m][0], temp) 97. print path_map 98. 99. 100. class SimpleSwitch13(app_manager.RyuApp): 101. OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION] 102. 103. def __init__(self, *args, **kwargs): 104. super(SimpleSwitch13, self).__init__(*args, **kwargs) 105. self.mac_to_port = {} 106. self.arp_table = {} 107. self.sw = {} 108. self.port_tx = {} 109. self.datapaths = {} 110. self.datapath_list={} 111. self.topology_api_app=self 112. 113. @set_ev_cls (ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER) 114. def switch_features_handler(self, ev): 115. datapath = ev.msg.datapath 116. ofproto = datapath.ofproto 117. parser = datapath.ofproto_parser 118. switches[datapath.id]=datapath 119. 120. match = parser.OFPMatch() 121. actions = [parser.OFPActionOutput(ofproto.OFPP_CONTROLLER, 122. ofproto.OFPCML_NO_BUFFER)] 123. self.add_flow(datapath, 0, match, actions) 124. 125. def add_flow(self, datapath, priority, match, actions): 126. ofproto = datapath.ofproto 127. parser = datapath.ofproto_parser 128. 129. inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, 130. actions)] 131. 132. mod = parser.OFPFlowMod(datapath=datapath, priority=priority, 133. hard_timeout=20, 134. match=match, instructions=inst) 135. 136. datapath.send_msg(mod) 137. 138. @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER) 139. def _packet_in_handler(self, ev): 140. if ev.msg.msg_len < ev.msg.total_len: 141. self.logger.debug( "packet truncated: only %s of %s bytes", 142. ev.msg.msg_len, ev.msg.total_len) 143. msg = ev.msg 144. datapath = msg.datapath 145. ofproto = datapath.ofproto 146. parser = datapath.ofproto_parser 147. in_port = msg.match['in_port'] 148. 149. pkt = packet.Packet(msg.data) 150. eth = pkt.get_protocols(ethernet.ethernet)[0] 151. #avoid broadcast from LLDP 152. if eth.ethertype==35020: 153. return 154. 155. dst = eth.dst 156. src = eth.src 157. 158. loc=('00-00-00-00-00-0'+str(datapath.id),in_port) 159. oldloc=mac_map.get(src) 160. if oldloc is None: 161. mac_map[src]=loc 162. elif src not in mac_map: 163. mac_map[src]=loc 164. 165. dpid = datapath.id 166. self.mac_to_port.setdefault(dpid, {}) 167. 168. header_list = dict( 169. (p.protocol_name, p) for p in pkt.protocols if type(p) != str) 170. if ARP in header_list: 171. self.arp_table[header_list[ARP].src_ip] = src # ARP learning 172. 173. self.logger.info("packet in %s %s %s %s" , dpid, src, dst, in_port) 174. 175. # learn a mac address to avoid FLOOD next time. 176. if src not in self.mac_to_port[dpid]: #record only one in_port 177. self.mac_to_port[dpid][src] = in_port 178. 179. if dst in self.mac_to_port[dpid]: 180. out_port = self.mac_to_port[dpid][dst] 181. temp_src=mac_map[src] 182. temp_dst=mac_map[dst] 183. self.install_path(temp_src[0],temp_dst[0], temp_src[1 ], temp_dst[1], ev) 184. self.logger.info("out_port: %s", out_port) 185. else: 186. out_port = ofproto.OFPP_FLOOD 187. print"flood!" 188. 189. actions = [parser.OFPActionOutput(out_port)] 190. 191. # install a flow to avoid packet_in next time 192. if out_port != ofproto.OFPP_FLOOD: 193. match = parser.OFPMatch(in_port=in_port, eth_dst=dst) 194. 195. data = None 196. if msg.buffer_id == ofproto.OFP_NO_BUFFER: 197. data = msg.data 198. 199. out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id, 200. in_port=in_port, actions=actions, data=data) 201. datapath.send_msg(out) 202. 203. @set_ev_cls (ofp_event.EventOFPStateChange, [MAIN_DISPATCHER, DEAD_DISPATCHER]) 204. def state_change_handler(self, ev): 205. datapath = ev.datapath 206. if ev.state == MAIN_DISPATCHER: 207. if datapath.id == 1: 208. self.datapaths[datapath.id] = datapath 209. if not datapath.id in self.datapath_list: 210. self.datapath_list[datapath.id]=datapath 211. elif ev.state == DEAD_DISPATCHER: 212. if datapath.id in self.datapaths: 213. del self.datapaths[datapath.id] 214. 215. def install_path(self,src_sw, dst_sw, in_port, last_port, ev): 216. """ 217. Attempts to install a path between this switch and some destination 218. """ 219. p = _get_path(src_sw, dst_sw, in_port, last_port) 220. self._install_path(p, ev) 221. # Now reverse it and install it backwards 222. # (we'll just assume that will work) 223. p = [(sw, out_port, in_port) for sw, in_port, out_port in p] 224. self._install_path(p, ev) 225. 226. def _install_path(self, p, ev): 227. msg = ev.msg 228. datapath = msg.datapath 229. ofproto = datapath.ofproto 230. parser = datapath.ofproto_parser 231. for sw, in_port, out_port in p: 232. match = parser.OFPMatch(in_port=in_port) 233. actions = [parser.OFPActionOutput(out_port)] 234. ID=int(sw[-1:]) 235. datapath=self.datapath_list[ID] 236. self.add_flow(datapath, 1, match, actions) 237. 238. @set_ev_cls(event.EventSwitchEnter) 239. 240. def get_topology(self,ev): 241. switch_list=get_switch(self.topology_api_app,None) 242. global sws 243. # assign mac for swtich to easy read 244. sws=['00-00-00-00-00-0'+ str(switch.dp.id) for switch in switch_list] 245. links_list=get_link(self.topology_api_app,None) 246. for link in links_list: 247. sw_src='00-00-00-00-00-0'+ str(link.src.dpid) 248. sw_dst='00-00-00-00-00-0'+ str(link.dst.dpid) 249. adjacency[sw_src][sw_dst]=link.src.port_no Please suggest me if I am doing anything wrong or missing anything. Best regards, Goutam |