def _handle_PacketIn (event): packet = event.parsed if packet.effective_ethertype == LAT_TYPE: """ Handle incoming latency packets """ #print dpidToStr(event.dpid) port = packet.src [prevtime, swdpdest, swdpsrc] = packet.payload.split(',') prevtime = float(prevtime) currtime = time.time() #print "PrevTime = ", prevtime, " CurrTime = ", currtime dest_dpid = dpidToStr(event.dpid) if dest_dpid == swdpdest: #print "DPID matched" latency = round((((currtime - prevtime)*1000) - dpid_latency[strToDPID(swdpsrc)] - dpid_latency[event.dpid]), 4) #print "Latency =",latency #swd = ports[dpidToStr(self.dpid)] swd = ports[swdpsrc] #for k in swd: # if swd[k][0] == mac: # break k = 0 for p in switch_adjacency[strToDPID(swdpsrc)]: if swdebug: print swdpsrc,"\n",switch_adjacency[strToDPID(swdpsrc)] if switch_adjacency[strToDPID(swdpsrc)][p] is event.dpid: if swdebug: print "matches with",dpidToStr(event.dpid)," when p = ",p k = p if latency >=0: if k in ports[swdpsrc]: ports[swdpsrc][k][0] = latency return
def getPortInfo(self, switchid, port_name_or_number=None): "return a port object carrying port info, or by omitting the port_name_or_number the whole switch info object" req_switch_info = None for s in list_switches(): if strToDPID(s['dpid']) == switchid: req_switch_info = s break if not req_switch_info: self.log.debug("info for switch %s not found" % switchid) return None if port_name_or_number == None: return req_switch_info if type(port_name_or_number) == int: for p in req_switch_info['ports']: if p['port_no'] == port_name_or_number: return p else: for p in req_switch_info['ports']: if p['name'] == port_name_or_number: return p self.log.debug("info for port %s on switch %s not found" % (port_name_or_number, switchid)) return None
def _exec_get_switch_desc (self, dpid): dpid = strToDPID(dpid) con = core.openflow.getConnection(dpid) if con is None: return make_error("No such switch") return OFSwitchDescRequest(con).get_response()
def _exec_set_table (self, dpid, flows): dpid = strToDPID(dpid) con = core.openflow.getConnection(dpid) if con is None: return make_error("No such switch") return OFSetTableRequest(con, flows).get_response()
def _exec_cmd_get_flow_stats (self, event): try: msg = event.msg dpid = strToDPID(msg['dpid']) con = core.openflow.getConnection(dpid) if con is None: raise RuntimeError("No such switch") match = event.msg.get('match') table_id = event.msg.get('table_id', 0xff) out_port = event.msg.get('out_port', of.OFPP_NONE) sr = of.ofp_stats_request() sr.body = of.ofp_flow_stats_request() if match is None: match = of.ofp_match() else: match = dict_to_match(match) sr.body.match = match sr.body.table_id = table_id sr.body.out_port = out_port con.send(sr) self.reply(event,**{'type':'set_table','xid':sr.xid}) except: #log.exception("Exception in get_flow_stats") log.debug("Exception in get_flow_stats - %s:%s", sys.exc_info()[0].__name__, sys.exc_info()[1]) self.reply(event, exception="%s: %s" % (sys.exc_info()[0],sys.exc_info()[1]), traceback=traceback.format_exc())
def _exec_cmd_set_table(self, event): try: msg = event.msg dpid = strToDPID(msg["dpid"]) con = core.openflow.getConnection(dpid) if con is None: raise RuntimeError("No such switch") xid = of.generate_xid() fm = of.ofp_flow_mod() fm.xid = xid fm.command = of.OFPFC_DELETE con.send(fm) bar = of.ofp_barrier_request() bar.xid = xid con.send(bar) for flow in msg.get("flows", []): fm = dict_to_flow_mod(flow) fm.xid = xid con.send(fm) # con.send(of.ofp_barrier_request(xid=xid)) con.send(of.ofp_barrier_request(xid=xid)) self.reply(event, **{"type": "set_table", "xid": xid}) except: # log.exception("Exception in set_table") log.debug("Exception in set_table - %s:%s", sys.exc_info()[0].__name__, sys.exc_info()[1]) self.reply( event, exception="%s: %s" % (sys.exc_info()[0], sys.exc_info()[1]), traceback=traceback.format_exc() )
def _exec_set_table(self, dpid, flows): dpid = strToDPID(dpid) con = core.openflow.getConnection(dpid) if con is None: return make_error("No such switch") return OFSetTableRequest(con, flows).get_response()
def _exec_cmd_get_flow_stats(self, event): try: msg = event.msg dpid = strToDPID(msg['dpid']) con = core.openflow.getConnection(dpid) if con is None: raise RuntimeError("No such switch") match = event.msg.get('match') table_id = event.msg.get('table_id', 0xff) out_port = event.msg.get('out_port', of.OFPP_NONE) sr = of.ofp_stats_request() sr.body = of.ofp_flow_stats_request() if match is None: match = of.ofp_match() else: match = dict_to_match(match) sr.body.match = match sr.body.table_id = table_id sr.body.out_port = out_port con.send(sr) self.reply(event, **{'type': 'set_table', 'xid': sr.xid}) except: #log.exception("Exception in get_flow_stats") log.debug("Exception in get_flow_stats - %s:%s", sys.exc_info()[0].__name__, sys.exc_info()[1]) self.reply(event, exception="%s: %s" % (sys.exc_info()[0], sys.exc_info()[1]), traceback=traceback.format_exc())
def _exec_get_flow_stats (self, dpid, *args, **kw): dpid = strToDPID(dpid) con = core.openflow.getConnection(dpid) if con is None: return make_error("No such switch") return OFFlowStatsRequest(con, *args, **kw).get_response()
def _exec_get_switch_desc(self, dpid): dpid = strToDPID(dpid) con = core.openflow.getConnection(dpid) if con is None: return make_error("No such switch") return OFSwitchDescRequest(con).get_response()
def handle_pkt(event): """ Handle incoming latency packets """ packet = event.parsed if packet.effective_ethertype == LAT_TYPE: print dpidToStr(event.dpid) port = packet.src [prevtime, mac, swdpdest, swdpsrc] = packet.payload.split(',') prevtime = float(prevtime) currtime = time.time() #print "PrevTime = ", prevtime, " CurrTime = ", currtime dest_dpid = dpidToStr(event.dpid) if dest_dpid == swdpdest: #print "DPID matched" latency = round( (((currtime - prevtime) * 1000) - dpid_latency[strToDPID(swdpsrc)] - dpid_latency[event.dpid]), 4) #swd = ports[dpidToStr(self.dpid)] swd = ports[swdpsrc] for k in swd: if swd[k][0] == mac: break if latency >= 0: ports[swdpsrc][k][1] = latency
def _exec_get_flow_stats(self, dpid, *args, **kw): dpid = strToDPID(dpid) con = core.openflow.getConnection(dpid) if con is None: return make_error("No such switch") return OFFlowStatsRequest(con, *args, **kw).get_response()
def _exec_get_pstats (self, dpid, *args, **kw): dpid = strToDPID(dpid) con = core.openflow.getConnection(dpid) if con is None: return make_error("No such switch") params = OFPortStatsRequest(con, *args, **kw).get_response() params['ver'] = self.version return params
def _exec_get_astats (self, dpid): dpid = strToDPID(dpid) con = core.openflow.getConnection(dpid) if con is None: return make_error("No such switch") params = OFAggregateStatsRequest(con).get_response() params['ver'] = self.version return params
def fix(): msg = of.ofp_flow_mod() msg.priority = DEFAULT_PRIORITY msg.match.in_port = 5 msg.match.dl_type = ARP_DL_TYPE msg.actions.append(of.ofp_action_output(port=3)) msg.actions.append(of.ofp_action_output(port=2)) core.openflow.sendToDPID(strToDPID("62-a1-74-3c-51-43"), msg) '''
def __init__(self, ipStr, macStr, dpidStr, port): self.ipStr = ipStr self.ipAddr = IPAddr(ipStr) self.macStr = macStr self.macAddr = EthAddr(macStr) self.dpidStr = dpidStr self.dpid = strToDPID(self.dpidStr) self.port = port self._installDefaultRules()
def _handle_port_stats(event): global start_time global network port_stats = flow_stats_to_list(event.stats) #log.debug(port_stats) for node in network: if (dpidToStr( event.dpid) == network[node]["MAC"]): # find which switch for link in network[node][ "link"]: # for each link connected to this switch try: # calculate updated congestion value link["cong_value"] = MBPS * ( port_stats[link["out_port"]]["tx_bytes"] - link["prev_tx_bytes"]) # has controller just started up? if ((datetime.now() - start_time).total_seconds() > WAIT_FOR_STARTUP): #log.debug("\nBW on node %s, port %s: (Mbps): %s\n", node, link["out_port"], link["cong_value"]) if (link["cong_value"] > CONG_THRESH): # congestion detected log.debug("\nCongestion on node %s, port %s\n", node, link["out_port"]) if (network[node]["MAC"] == network["R4"]["MAC"] ): # Are we at R4? # update UDP flow rule for R8 log.debug("\nUpdate R8 flow table\n") msg = of.ofp_flow_mod() msg.priority = HIGH_PRIORITY msg.match.in_port = 3 # hardcoded msg.match.dl_type = IPV4_DL_TYPE msg.match.nw_proto = UDP_PROTO msg.match.nw_dst = IPAddr( "172.16.0.5", 30) # hardcoded for S1 msg.actions.append( of.ofp_action_output(port=1)) # hardcoded core.openflow.sendToDPID( strToDPID(network["R8"]["MAC"]), msg) # store tx_bytes for next iteration link["prev_tx_bytes"] = port_stats[ link["out_port"]]["tx_bytes"] except IndexError: pass
def _handle_PacketIn(event): packet = event.parsed if packet.effective_ethertype == LAT_TYPE: """ Handle incoming latency packets """ #print dpidToStr(event.dpid) port = packet.src [prevtime, swdpdest, swdpsrc] = packet.payload.split(',') prevtime = float(prevtime) currtime = time.time() #print "PrevTime = ", prevtime, " CurrTime = ", currtime dest_dpid = dpidToStr(event.dpid) if dest_dpid == swdpdest: #print "DPID matched" latency = round( (((currtime - prevtime) * 1000) - dpid_latency[strToDPID(swdpsrc)] - dpid_latency[event.dpid]), 4) #print "Latency =",latency #swd = ports[dpidToStr(self.dpid)] swd = ports[swdpsrc] #for k in swd: # if swd[k][0] == mac: # break k = 0 for p in switch_adjacency[strToDPID(swdpsrc)]: if swdebug: print swdpsrc, "\n", switch_adjacency[strToDPID(swdpsrc)] if switch_adjacency[strToDPID(swdpsrc)][p] is event.dpid: if swdebug: print "matches with", dpidToStr( event.dpid), " when p = ", p k = p if latency >= 0: if k in ports[swdpsrc]: ports[swdpsrc][k][0] = latency return
def _exec_cmd_packet_out (self, event): try: msg = event.msg dpid = strToDPID(msg['dpid']) con = core.openflow.getConnection(dpid) if con is None: raise RuntimeError("No such switch") po = dict_to_packet_out(msg) con.send(po) except: log.exception("Exception in packet_out") self.reply(event, exception="%s: %s" % (sys.exc_info()[0],sys.exc_info()[1]), traceback=traceback.format_exc())
def pClient(username, mac, ip=""): # permit traffic from the client to the router - i.e. auth successful connection = core.openflow.getConnection(strToDPID(dpid)) MAC = EthAddr(mac) IP = IPAddr(ip) vlan = getVLANs(ip) query = "INSERT into tbl_nac_session (username,mac_address,ip_address,start_dt) VALUES ('%s','%s','%s',now())" % ( username, mac, ip) msg = None # note: if the openflow switch supports L3 matching in addition to L2 matching # note: matching on both will result in higher security - but not all support both. # note: if we match on L3 and ARP matching is not supported (see sPortal), # note: ARPs from the client will not flow to the router but rather to the portal # note: so it does not make sense to match on L3 unless we can also match on ARPs # note: but technically you could comment out "and dp_supports_arp_match" if you don't # note: care that ARPs from clients always go to your portal which runs proxy ARP if dp_supports_l3_match and dp_supports_arp_match: msg = of.ofp_flow_mod() msg.flags = of.OFPFF_SEND_FLOW_REM msg.idle_timeout = client_idle_timeout msg.priority = 32768 msg.match.in_port = client_port_match msg.match.dl_src = MAC msg.match.dl_type = pkt.ethernet.IP_TYPE msg.match.nw_src = IP msg.actions.append(of.ofp_action_vlan_vid(vlan_vid=vlan['trusted'])) msg.actions.append(of.ofp_action_output(port=router_port_action)) else: msg = of.ofp_flow_mod() msg.flags = of.OFPFF_SEND_FLOW_REM msg.idle_timeout = client_idle_timeout msg.priority = 32768 msg.match.dl_src = MAC msg.actions.append(of.ofp_action_vlan_vid(vlan_vid=vlan['trusted'])) msg.actions.append(of.ofp_action_output(port=router_port_action)) if msg: cursor = db.cursor() cursor.execute(query) connection.send(msg)
def _exec_cmd_set_table (self, event): try: msg = event.msg dpid = strToDPID(msg['dpid']) con = core.openflow.getConnection(dpid) if con is None: raise RuntimeError("No such switch") xid = of.generate_xid() """ As modificações em um tabela de fluxo do controlador é feito com a mensagem OFPT_FLOW_MOD """ fm = of.ofp_flow_mod() fm.xid = xid "OFPFC_DELETE: Exclui todos os fluxos correspondentes .." fm.command = of.OFPFC_DELETE con.send(fm) bar = of.ofp_barrier_request() bar.xid = xid con.send(bar) for flow in msg.get('flows',[]): fm = dict_to_flow_mod(flow) fm.xid = xid con.send(fm) #con.send(of.ofp_barrier_request(xid=xid)) con.send(of.ofp_barrier_request(xid=xid)) self.reply(event,**{'type':'set_table','xid':xid}) except: #log.exception("Exception in set_table") log.debug("Exception in set_table - %s:%s", sys.exc_info()[0].__name__, sys.exc_info()[1]) self.reply(event, exception="%s: %s" % (sys.exc_info()[0],sys.exc_info()[1]), traceback=traceback.format_exc())
def pClient(username,mac,ip=""): # permit traffic from the client to the router - i.e. auth successful connection = core.openflow.getConnection(strToDPID(dpid)) MAC = EthAddr(mac) IP = IPAddr(ip) vlan = getVLANs(ip) query = "INSERT into tbl_nac_session (username,mac_address,ip_address,start_dt) VALUES ('%s','%s','%s',now())" % (username,mac,ip) msg = None # note: if the openflow switch supports L3 matching in addition to L2 matching # note: matching on both will result in higher security - but not all support both. # note: if we match on L3 and ARP matching is not supported (see sPortal), # note: ARPs from the client will not flow to the router but rather to the portal # note: so it does not make sense to match on L3 unless we can also match on ARPs # note: but technically you could comment out "and dp_supports_arp_match" if you don't # note: care that ARPs from clients always go to your portal which runs proxy ARP if dp_supports_l3_match and dp_supports_arp_match: msg = of.ofp_flow_mod() msg.flags = of.OFPFF_SEND_FLOW_REM msg.idle_timeout = client_idle_timeout msg.priority = 32768 msg.match.in_port = client_port_match msg.match.dl_src = MAC msg.match.dl_type = pkt.ethernet.IP_TYPE msg.match.nw_src = IP msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = vlan['trusted'])) msg.actions.append(of.ofp_action_output(port = router_port_action)) else: msg = of.ofp_flow_mod() msg.flags = of.OFPFF_SEND_FLOW_REM msg.idle_timeout = client_idle_timeout msg.priority = 32768 msg.match.dl_src = MAC msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = vlan['trusted'])) msg.actions.append(of.ofp_action_output(port = router_port_action)) if msg: cursor = db.cursor() cursor.execute(query) connection.send(msg)
def _exec_cmd_get_flow_stats (self, event): try: msg = event.msg dpid = strToDPID(msg['dpid']) con = core.openflow.getConnection(dpid) if con is None: raise RuntimeError("No such switch") "No such switch: sem essa mudança" match = event.msg.get('match') "Descrição dos campos" table_id = event.msg.get('table_id', 0xff) "table_id: mesa para fluxos ( padrão para todos).indica o próximo mesa no pipeline de processamento de pacotes." """ Para comandos OFPFC_DELETE * , requerem entradas correspondentes para incluir isso como uma porta de saída . Um valor de OFPP_ANY indica nenhuma restrição """ "out_port: filtro por porta de saída (padrão para todos)" out_port = event.msg.get('out_port', of.OFPP_NONE) sr = of.ofp_stats_request() sr.body = of.ofp_flow_stats_request() if match is None: match = of.ofp_match() else: match = dict_to_match(match) sr.body.match = match sr.body.table_id = table_id sr.body.out_port = out_port con.send(sr) self.reply(event,**{'type':'set_table','xid':sr.xid}) except: #log.exception("Exception in get_flow_stats") log.debug("Exception in get_flow_stats - %s:%s", sys.exc_info()[0].__name__, sys.exc_info()[1]) self.reply(event, exception="%s: %s" % (sys.exc_info()[0],sys.exc_info()[1]), traceback=traceback.format_exc())
def handle_pkt (event): """ Handle incoming latency packets """ packet = event.parsed if packet.effective_ethertype == LAT_TYPE: print dpidToStr(event.dpid) port = packet.src [prevtime, mac, swdpdest, swdpsrc] = packet.payload.split(',') prevtime = float(prevtime) currtime = time.time() #print "PrevTime = ", prevtime, " CurrTime = ", currtime dest_dpid = dpidToStr(event.dpid) if dest_dpid == swdpdest: #print "DPID matched" latency = round((((currtime - prevtime)*1000) - dpid_latency[strToDPID(swdpsrc)] - dpid_latency[event.dpid]), 4) #swd = ports[dpidToStr(self.dpid)] swd = ports[swdpsrc] for k in swd: if swd[k][0] == mac: break if latency >=0: ports[swdpsrc][k][1] = latency
def _exec_cmd_set_table(self, event): try: msg = event.msg dpid = strToDPID(msg['dpid']) con = core.openflow.getConnection(dpid) if con is None: raise RuntimeError("No such switch") xid = of.generate_xid() fm = of.ofp_flow_mod() fm.xid = xid fm.command = of.OFPFC_DELETE con.send(fm) bar = of.ofp_barrier_request() bar.xid = xid con.send(bar) for flow in msg.get('flows', []): fm = dict_to_flow_mod(flow) fm.xid = xid con.send(fm) #con.send(of.ofp_barrier_request(xid=xid)) con.send(of.ofp_barrier_request(xid=xid)) self.reply(event, **{'type': 'set_table', 'xid': xid}) except: #log.exception("Exception in set_table") log.debug("Exception in set_table - %s:%s", sys.exc_info()[0].__name__, sys.exc_info()[1]) self.reply(event, exception="%s: %s" % (sys.exc_info()[0], sys.exc_info()[1]), traceback=traceback.format_exc())
def _handle_PacketIn (self, event): def flood (): """ Floods the packet """ if self.is_holding_down: log.warning("Not flooding -- holddown active") msg = of.ofp_packet_out() # OFPP_FLOOD is optional; some switches may need OFPP_ALL msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD)) msg.buffer_id = event.ofp.buffer_id msg.in_port = event.port self.connection.send(msg) def drop (): # Kill the buffer if event.ofp.buffer_id is not None: msg = of.ofp_packet_out() msg.buffer_id = event.ofp.buffer_id event.ofp.buffer_id = None # Mark is dead msg.in_port = event.port self.connection.send(msg) packet = event.parsed loc = (self, event.port) # Place we saw this ethaddr oldloc = mac_map.get(packet.src) # Place we last saw this ethaddr ################################################################ Handle LLDP Type ################################################################ if packet.effective_ethertype == packet.LLDP_TYPE: drop() return ################################################################################################################################################## ################################################################ Handle ARP Type ################################################################ if packet.type == ethernet.ARP_TYPE: arppack = packet.find('arp') if arppack.opcode == arp.REQUEST: mac_map[packet.src] = loc # Learn position for ethaddr log.debug("Learned %s at %s.%i", packet.src, loc[0], loc[1]) for switch in dpids: if switch is self.dpid: if swdebug: print "Same switch" continue if swdebug: print "Sending ARP REQ to",dpidToStr(switch) action_out = [of.ofp_action_output(port = port) for port in host_ports[switch]] core.openflow.sendToDPID(switch, of.ofp_packet_out(data=packet.pack(),action=action_out)) return if arppack.opcode == arp.REPLY: mac_map[packet.src] = loc loc_dst = mac_map[packet.dst] # Learn position for ethaddr if swdebug: print "Send reply to DPID - ",str(loc_dst[0]),"port -",loc_dst[1] if swdebug: print "Type - ",type(str(loc_dst[0])) action_out = of.ofp_action_output(port = loc_dst[1]) core.openflow.sendToDPID(strToDPID(str(loc_dst[0])), of.ofp_packet_out(data=packet.pack(),action=action_out)) return ################################################################# Handle LAT Type ################################################################ if packet.effective_ethertype == LAT_TYPE: """ Handle incoming latency packets """ #print dpidToStr(event.dpid) port = packet.src [prevtime, port_mac, swdpdest, swdpsrc] = packet.payload.split(',') prevtime = float(prevtime) currtime = time.time() #print "PrevTime = ", prevtime, " CurrTime = ", currtime dest_dpid = dpidToStr(event.dpid) if dest_dpid == swdpdest: #print "DPID matched" latency = round((((currtime - prevtime)*1000) - dpid_latency[strToDPID(swdpsrc)] - dpid_latency[event.dpid]), 4) #print "Latency =",latency #swd = ports[dpidToStr(self.dpid)] swd = ports[swdpsrc] for k in swd: if swd[k][4] == port_mac: break if latency >=0: if k in ports[swdpsrc]: ports[swdpsrc][k][0] = latency return ################################################################################################################################################## if oldloc is None: if packet.src.is_multicast == False: mac_map[packet.src] = loc # Learn position for ethaddr log.debug("Learned %s at %s.%i", packet.src, loc[0], loc[1]) elif oldloc != loc: drop() return # ethaddr seen at different place! if core.openflow_discovery.is_edge_port(loc[0].dpid, loc[1]): # New place is another "plain" port (probably) log.debug("%s moved from %s.%i to %s.%i?", packet.src, dpid_to_str(oldloc[0].dpid), oldloc[1], dpid_to_str( loc[0].dpid), loc[1]) if packet.src.is_multicast == False: mac_map[packet.src] = loc # Learn position for ethaddr log.debug("Learned %s at %s.%i", packet.src, loc[0], loc[1]) elif packet.dst.is_multicast == False: # New place is a switch-to-switch port! # Hopefully, this is a packet we're flooding because we didn't # know the destination, and not because it's somehow not on a # path that we expect it to be on. # If spanning_tree is running, we might check that this port is # on the spanning tree (it should be). if packet.dst in mac_map: # Unfortunately, we know the destination. It's possible that # we learned it while it was in flight, but it's also possible # that something has gone wrong. if swdebug: print "Hit MacMap" log.warning("Packet from %s to known destination %s arrived " "at %s.%i without flow", packet.src, packet.dst, dpid_to_str(self.dpid), event.port) if packet.dst.is_multicast: log.debug("Flood multicast from %s", packet.src) flood() else: if packet.dst not in mac_map: log.debug("%s unknown -- flooding" % (packet.dst,)) flood() else: dest = mac_map[packet.dst] if packet.type == ethernet.IP_TYPE: ipv4_packet=packet.find("ipv4") tos = ipv4_packet.tos if packet.find("icmp"): print "ICMP packet received" print "Received ToS = ",tos match=of.ofp_match.from_packet(packet) self.install_path(dest[0], dest[1], match, event,tos)
def _handle_PacketIn(self, event): def flood(): """ Floods the packet """ if self.is_holding_down: log.warning("Not flooding -- holddown active") msg = of.ofp_packet_out() # OFPP_FLOOD is optional; some switches may need OFPP_ALL msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) msg.buffer_id = event.ofp.buffer_id msg.in_port = event.port self.connection.send(msg) def drop(): # Kill the buffer if event.ofp.buffer_id is not None: msg = of.ofp_packet_out() msg.buffer_id = event.ofp.buffer_id event.ofp.buffer_id = None # Mark is dead msg.in_port = event.port self.connection.send(msg) packet = event.parsed loc = (self, event.port) # Place we saw this ethaddr oldloc = mac_map.get(packet.src) # Place we last saw this ethaddr ################################################################ Handle LLDP Type ################################################################ if packet.effective_ethertype == packet.LLDP_TYPE: drop() return ################################################################################################################################################## ################################################################ Handle ARP Type ################################################################ if packet.type == ethernet.ARP_TYPE: arppack = packet.find('arp') if arppack.opcode == arp.REQUEST: mac_map[packet.src] = loc # Learn position for ethaddr log.debug("Learned %s at %s.%i", packet.src, loc[0], loc[1]) for switch in dpids: if switch is self.dpid: if swdebug: print "Same switch" continue if swdebug: print "Sending ARP REQ to", dpidToStr(switch) action_out = [ of.ofp_action_output(port=port) for port in host_ports[switch] ] core.openflow.sendToDPID( switch, of.ofp_packet_out(data=packet.pack(), action=action_out)) return if arppack.opcode == arp.REPLY: mac_map[packet.src] = loc loc_dst = mac_map[packet.dst] # Learn position for ethaddr if swdebug: print "Send reply to DPID - ", str( loc_dst[0]), "port -", loc_dst[1] if swdebug: print "Type - ", type(str(loc_dst[0])) action_out = of.ofp_action_output(port=loc_dst[1]) core.openflow.sendToDPID( strToDPID(str(loc_dst[0])), of.ofp_packet_out(data=packet.pack(), action=action_out)) return ################################################################# Handle LAT Type ################################################################ if packet.effective_ethertype == LAT_TYPE: """ Handle incoming latency packets """ #print dpidToStr(event.dpid) port = packet.src [prevtime, port_mac, swdpdest, swdpsrc] = packet.payload.split(',') prevtime = float(prevtime) currtime = time.time() #print "PrevTime = ", prevtime, " CurrTime = ", currtime dest_dpid = dpidToStr(event.dpid) if dest_dpid == swdpdest: #print "DPID matched" latency = round((((currtime - prevtime) * 1000) - dpid_latency[strToDPID(swdpsrc)] - dpid_latency[event.dpid]), 4) #print "Latency =",latency #swd = ports[dpidToStr(self.dpid)] swd = ports[swdpsrc] for k in swd: if swd[k][4] == port_mac: break if latency >= 0: if k in ports[swdpsrc]: ports[swdpsrc][k][0] = latency return ################################################################################################################################################## if oldloc is None: if packet.src.is_multicast == False: mac_map[packet.src] = loc # Learn position for ethaddr log.debug("Learned %s at %s.%i", packet.src, loc[0], loc[1]) elif oldloc != loc: drop() return # ethaddr seen at different place! if core.openflow_discovery.is_edge_port(loc[0].dpid, loc[1]): # New place is another "plain" port (probably) log.debug("%s moved from %s.%i to %s.%i?", packet.src, dpid_to_str(oldloc[0].dpid), oldloc[1], dpid_to_str(loc[0].dpid), loc[1]) if packet.src.is_multicast == False: mac_map[packet.src] = loc # Learn position for ethaddr log.debug("Learned %s at %s.%i", packet.src, loc[0], loc[1]) elif packet.dst.is_multicast == False: # New place is a switch-to-switch port! # Hopefully, this is a packet we're flooding because we didn't # know the destination, and not because it's somehow not on a # path that we expect it to be on. # If spanning_tree is running, we might check that this port is # on the spanning tree (it should be). if packet.dst in mac_map: # Unfortunately, we know the destination. It's possible that # we learned it while it was in flight, but it's also possible # that something has gone wrong. if swdebug: print "Hit MacMap" log.warning( "Packet from %s to known destination %s arrived " "at %s.%i without flow", packet.src, packet.dst, dpid_to_str(self.dpid), event.port) if packet.dst.is_multicast: log.debug("Flood multicast from %s", packet.src) flood() else: if packet.dst not in mac_map: log.debug("%s unknown -- flooding" % (packet.dst, )) flood() else: dest = mac_map[packet.dst] if packet.type == ethernet.IP_TYPE: ipv4_packet = packet.find("ipv4") tos = ipv4_packet.tos if packet.find("icmp"): print "ICMP packet received" print "Received ToS = ", tos match = of.ofp_match.from_packet(packet) self.install_path(dest[0], dest[1], match, event, tos)