def _handle_inbound_nat(self, event, ether_pkt, ip_pkt, tcp_pkt): nat_conn = self._nat_table.get_connection(ip_pkt.srcip, tcp_pkt.srcport, tcp_pkt.dstport) if nat_conn is None: self._drop_packet(event, 'Inbound TCP packet for unmapped port') return local_mac = self._arp_table.lookup(nat_conn.local_ip) if local_mac is None: self._queue_and_arp(event, nat_conn.local_ip) return # Update the NAT connection state from the outbound packet. nat_conn.update(ether_pkt, ip_pkt, tcp_pkt) msg = of.ofp_packet_out(data = event.ofp) out_port = self.get_port_for_mac(local_mac) if nat_conn.is_established() and out_port is not None: # The connection is now ESTABLISHED and we know where to find the # destination NAT host, so hand control over to flow table rules. self._install_nat_rules(nat_conn, out_port, local_mac, ether_pkt.src) # Send the current packet according to the new flow table rules. msg.actions.append(of.ofp_action_output(port = of.OFPP_TABLE)) self._packet_logger.action('Apply Flow Table') return elif out_port is None: out_port = of.OFPP_FLOOD self._packet_logger.action('Translate and Forward', [ ('Out Port', out_port) ]) msg = of.ofp_packet_out(data = event.ofp) msg.actions = self._get_inbound_nat_actions(nat_conn, local_mac, out_port) self.connection.send(msg)
def _handle_PacketIn (event): packet = event.parsed mac_table[packet.src] = event.port if packet.dst not in mac_table.keys(): msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD)) event.connection.send(msg) if packet.dst in mac_table.keys(): msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port = mac_table.get(packet.dst))) event.connection.send(msg)
def _handle_PacketIn (event): packet = event.parsed if packet.find("arp"): # Reply to ARP a = packet.find("arp") if a.opcode == a.REQUEST: r = pkt.arp() r.hwtype = a.hwtype r.prototype = a.prototype r.hwlen = a.hwlen r.protolen = a.protolen r.opcode = r.REPLY r.hwdst = a.hwsrc r.protodst = a.protosrc r.protosrc = a.protodst r.hwsrc = EthAddr("02:00:DE:AD:BE:EF") e = pkt.ethernet(type=packet.type, src=r.hwsrc, dst=a.hwsrc) e.payload = r msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT)) msg.in_port = event.port event.connection.send(msg) log.info("%s ARPed for %s", r.protodst, r.protosrc) elif packet.find("icmp"): # Reply to pings # Make the ping reply icmp = pkt.icmp() icmp.type = pkt.TYPE_ECHO_REPLY icmp.payload = packet.find("icmp").payload # Make the IP packet around it ipp = pkt.ipv4() ipp.protocol = ipp.ICMP_PROTOCOL ipp.srcip = packet.find("ipv4").dstip ipp.dstip = packet.find("ipv4").srcip # Ethernet around that... e = pkt.ethernet() e.src = packet.dst e.dst = packet.src e.type = e.IP_TYPE # Hook them up... ipp.payload = icmp e.payload = ipp # Send it back to the input port msg = of.ofp_packet_out() msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT)) msg.data = e.pack() msg.in_port = event.port event.connection.send(msg) log.debug("%s pinged %s", ipp.dstip, ipp.srcip)
def _handle_IPv4In(self,event): dst_ip = event.ipv4p.dstip dpid = dpid_to_str(event.connection.dpid) inport = event.inport #判断是否是Core收到了IPv4In事件 if dpid in core.SRPConfig.core_list: return #判断目的网段是否在对应DPID连接的网段中 if not same_network(dst_ip,core.SRPConfig.get_tor_lan_addr(dpid)): return if dst_ip in self.arp_table[dpid]: #判断之前是否已经获得目的IP地址的MAC地址 table = self.arp_table[dpid][dst_ip] log.debug("[%s] Send out the ipv4 packet: %s =>%s",dpid,event.ipv4p.srcip,dst_ip) msg = of.ofp_packet_out(buffer_id = event.ofp.buffer_id, in_port = inport) msg.actions.append(of.ofp_action_dl_addr.set_dst(table.mac)) msg.actions.append(of.ofp_action_output(port = table.port)) event.connection.send(msg) log.debug("[%s] Set up the Flow for destination: %s",dpid,dst_ip) actions = list() actions.append(of.ofp_action_dl_addr.set_dst(table.mac)) actions.append(of.ofp_action_output(port = table.port)) match = of.ofp_match() match.dl_type = pkt.ethernet.IP_TYPE match.nw_dst = dst_ip msg = of.ofp_flow_mod(command = of.OFPFC_MODIFY, actions = actions, match = match, idle_timeout = FLOW_IDLE_TIMEOUT, hard_timeout = of.OFP_FLOW_PERMANENT) event.connection.send(msg) else: #缓存IPv4报文,并广播ARPRequest报文请求目的IP地址的MAC地址 log.debug("[%s] Buffer unsent IPv4 packet point to %s",dpid,dst_ip) if (dpid,dst_ip) not in self.ipv4_buffers: self.ipv4_buffers[(dpid,dst_ip)] = [] buffers = self.ipv4_buffers[(dpid,dst_ip)] entry = (time.time()+MAX_BUFFER_TIME,event.ofp.buffer_id,inport) buffers.append(entry) while len(buffers)>MAX_BUFFERED_PER_IP: msg = of.ofp_packet_out(buffer_id=buffers[0][1],in_port=buffers[0][2]) event.connection.send(msg) del buffers[0] #触发SendARPRequest事件,请求该IPv4报文的目的IP地址对应的MAC地址 src_ip = parse_cidr(core.SRPConfig.get_tor_lan_addr(dpid))[0] src_mac = _dpid_to_mac(event.connection.dpid) log.debug("[%s] Raise SendARPRequest Event %s | %s => %s | %s", dpid,src_ip,src_mac,dst_ip,ETHER_BROADCAST) ev = SendARPRequest(event.connection,src_ip,src_mac,dst_ip,ETHER_BROADCAST,flood=True) self.raiseEvent(ev)
def _handle_PacketIn (self, event): """ Handles packet in messages from the switch. """ packet = event.parsed # This is the parsed packet data. if not packet.parsed: log.warning("Ignoring incomplete packet") return packet_in = event.ofp # The actual ofp_packet_in message. # handle static routing if packet.type == myPkt.ethernet.IP_TYPE: if packet.payload.protocol != myPkt.ipv4.ICMP_PROTOCOL: src_ip = packet.payload.srcip dst_ip = packet.payload.dstip log.debug("Receive a parket from " + str(src_ip) + " to " + str(dst_ip)) if str(packet.dst) == "12:12:12:12:12:12": if self.ip_to_port1.get(dst_ip): #log.debug("sending parket to " + str(dst_ip)) log.debug(str(packet.src) + " " + str(packet.dst)) packet.src = packet.dst if str(dst_ip) == "10.0.1.100" or str(dst_ip) == "10.0.2.100": packet.dst = myAddr.EthAddr(self.arp_cache1[str(dst_ip)]) else: packet.dst = myAddr.EthAddr("34:34:34:34:34:34") log.debug(str(packet.src) + " " + str(packet.dst)) msg = of.ofp_packet_out() msg.actions.append(of.ofp_action_output(port = self.ip_to_port1[str(dst_ip)])) msg.data = packet.pack() msg.in_port = event.port event.connection.send(msg) else: log.debug("Don't know this packet destination IP address") if str(packet.dst) == "34:34:34:34:34:34": if self.ip_to_port2.get(dst_ip): #log.debug("sending parket to " + str(dst_ip)) log.debug(str(packet.src) + " " + str(packet.dst)) packet.src = packet.dst if str(dst_ip) == "10.0.3.100" or str(dst_ip) == "10.0.4.100": packet.dst = myAddr.EthAddr(self.arp_cache2[str(dst_ip)]) else: packet.dst = myAddr.EthAddr("12:12:12:12:12:12") log.debug(str(packet.src) + " " + str(packet.dst)) msg = of.ofp_packet_out() msg.actions.append(of.ofp_action_output(port = self.ip_to_port2[str(dst_ip)])) msg.data = packet.pack() msg.in_port = event.port event.connection.send(msg) else: log.debug("Don't know this packet destination IP address") # Comment out the following line and uncomment the one after # when starting the exercise. #self.act_like_hub(packet, packet_in) self.act_like_switch(event, packet, packet_in)
def _handle_PacketIn(self,event): packet = event.parsed Switch_Output[event.dpid][packet.src]=event.port if packet.find("arp"): arp_packet=packet.find("arp") IP_To_MAC[arp_packet.protosrc]=packet.src if arp_packet.opcode==arp.REQUEST: if arp_packet.protodst in IP_To_MAC: #reply #construct arp reply packet arp_reply=arp() arp_reply.hwsrc=IP_To_MAC[arp_packet.protodst] arp_reply.hwdst=packet.src arp_reply.opcode=arp.REPLY arp_reply.protosrc=arp_packet.protodst arp_reply.protodst=arp_packet.protosrc ether=ethernet() ether.type=ethernet.ARP_TYPE ether.dst=packet.src ether.src=IP_To_MAC[arp_packet.protodst] ether.payload=arp_reply # send the created arp reply back to switch msg=of.ofp_packet_out() msg.data=ether.pack() msg.actions.append(of.ofp_action_output(port=of.OFPP_IN_PORT)) msg.in_port=event.port event.connection.send(msg) elif (arp_packet.protosrc,arp_packet.protodst) not in Switch_AntiFlood[event.dpid]: #flood msg=of.ofp_packet_out(data=event.data) msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) msg.in_port=event.port event.connection.send(msg) # Switch_AntiFlood[event.dpid].append((arp_reply.protosrc,arp_packet.protodst) ) # if packet.find('ipv4'): # ip_packet=packet.find('ipv4') # IP_To_MAC[ip_packet.dstip]=packet.dst # IP_To_MAC[ip_packet.srcip]=packet.src if packet.dst in Switch_Output[event.dpid] : msg=of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=Switch_Output[event.dpid][packet.dst])) msg.in_port=event.port event.connection.send(msg) Install_Flow(event,packet.src,packet.dst,Switch_Output[event.dpid][packet.dst]) Install_Flow(event,packet.dst,packet.src,Switch_Output[event.dpid][packet.src]) print event.dpid,'packet_in:',packet print 'out_put:',Switch_Output print 'IP_MAC',IP_To_MAC print 'Anti',Switch_AntiFlood print
def push_flows (self, con, buffer_reverse = False, buffer_id = None, data = None): if con.action.defer: return count = 0 #assert con.sig.is_reverse is False #assert con.sig_r.is_reverse is True mon_any = con.action.monitor_forward or con.action.monitor_backward msg = of.ofp_flow_mod() msg.cookie = con.cookie msg.flags = of.OFPFF_SEND_FLOW_REM msg.match = con.sig_r.match msg.match.in_port = OUTSIDE_PORT msg.idle_timeout = 10 msg.hard_timeout = 60 * 2 if con.action.forward or con.action.monitor_backward: if con.action.monitor_backward: count += 1 msg.actions.append(of.ofp_action_output(port = of.OFPP_CONTROLLER)) else: count += 1 msg.actions.append(of.ofp_action_output(port = INSIDE_PORT)) if buffer_id is not None and buffer_reverse: msg.buffer_id = buffer_id if (data is not None) and (buffer_reverse) and (buffer_id == -1): self.gateway.switch.send(of.ofp_packet_out( action = of.ofp_action_output(port = INSIDE_PORT), data = data)) self.gateway.switch.send(msg) msg = of.ofp_flow_mod() msg.cookie = con.cookie msg.flags = of.OFPFF_SEND_FLOW_REM msg.match = con.sig.match msg.match.in_port = INSIDE_PORT msg.idle_timeout = 10 msg.hard_timeout = 60 * 2 if con.action.forward or con.action.monitor_forward: if con.action.monitor_forward: count += 1 msg.actions.append(of.ofp_action_output(port = of.OFPP_CONTROLLER)) else: #if True: count += 1 msg.actions.append(of.ofp_action_output(port = OUTSIDE_PORT)) if buffer_id is not None and not buffer_reverse: msg.buffer_id = buffer_id if (data is not None) and (not buffer_reverse) and (buffer_id == -1): self.gateway.switch.send(of.ofp_packet_out( action = of.ofp_action_output(port = OUTSIDE_PORT), data = data)) self.gateway.switch.send(msg) log.debug("Pushed %i rules for %s", count, str(con)) con.fully_installed = True
def handle_arp(self, event, packet): ''' handle arp replies ''' arp_req = packet.next if arp_req.prototype == arp.PROTO_TYPE_IP and arp_req.hwtype == arp.HW_TYPE_ETHERNET and arp_req.protosrc != 0: log.debug("ARP proto source..." + str(arp_req.protosrc) + str(arp_req.protodst)) if arp_req.opcode == arp.REPLY and arp_req.hwdst == self.outmac: log.debug("updating arp table for %s" % arp_req.protosrc) self.arp_table[arp_req.protosrc] = (packet.src, event.port, time.time() * ARP_TIMEOUT) return # update the arp table self.arp_table[arp_req.protosrc] = (packet.src, event.port, time.time() * ARP_TIMEOUT) # see if we can handle the arp request (we know the dst and it hasn't expired) if arp_req.opcode == arp.REQUEST: if arp_req.protodst in self.arp_table and self.arp_table[arp_req.protodst][2] > time.time(): # we can respond to the ARP request log.debug("responding to ARP request...") self.send_arpResponse(arp_req, event, packet, self.arp_table[arp_req.protodst][0]) return elif arp_req.protodst == IPAddr('10.0.1.1'): # handle client side # create the arp response packet self.send_arpResponse(arp_req, event, packet, self.connection.ports[event.port].hw_addr) return elif arp_req.protodst == IPAddr('172.64.3.1'): # handle server side log.debug("repsonding to arp for server ip, %s" % event.port) self.send_arpResponse(arp_req, event, packet, self.connection.ports[event.port].hw_addr) return # we don't know where this mac is, flood the packet if event.port == 4: log.debug("flooding ARP packet!" + str(self.arp_table)) msg = of.ofp_packet_out() msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT)) msg.buffer_id = event.ofp.buffer_id msg.in_port = event.port self.connection.send(msg) else: log.debug("flooding client arp packet") msg = of.ofp_packet_out() for i in range(4): msg.actions.append(of.ofp_action_output(port = i )) msg.buffer_id = event.ofp.buffer_id msg.in_port = event.port self.connection.send(msg) return
def _handle_arp(event): eth_pkt = event.parsed arp_pkt = event.parsed.payload org_mac = eth_pkt.src.toStr() pmac_src = adrs.EthAddr(actual_pmac[org_mac]) #gratituos arp is when the src and dst ip in arp are same. check it and update tables in case of new host. or else return if arp_pkt.opcode == arp_pkt.REQUEST: dst_ip = arp_pkt.protodst.toStr() #print 'ARP request : ip:{0}'.format(dst_ip) if dst_ip in arp_table: #we know the mapping. respond back to inp port OFPP_IN_PORT. arp_reply = pkt.arp() arp_reply.hwsrc = adrs.EthAddr(arp_table[dst_ip]) arp_reply.hwdst = eth_pkt.src arp_reply.opcode = pkt.arp.REPLY arp_reply.protosrc = arp_pkt.protodst arp_reply.protodst = arp_pkt.protosrc ether = pkt.ethernet() ether.type = pkt.ethernet.ARP_TYPE ether.dst = eth_pkt.src ether.src = arp_reply.hwsrc ether.payload = arp_reply msg = of.ofp_packet_out() #msg.in_port = event.port #msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT)) msg.actions.append(of.ofp_action_output(port = event.port)) msg.data = ether.pack() event.connection.send(msg) else: #bcast with src changed to sources pmac. also if its this switch, put inport as the it came from, so that it wont go to it #print 'Broadcasting since we dont have ARP mapping' arp_pkt.hwsrc = pmac_src eth_pkt.src = pmac_src #edge bcast: msg = of.ofp_packet_out() for i in range(half_num_pods + 1, num_pods + 1):#pkt out to host ports msg.actions.append(of.ofp_action_output(port = i)) msg.data = eth_pkt.pack() other_switches = edge_switches - set([event.dpid]) for es in other_switches: core.openflow.connections[es].send(msg) msg.actions.pop(event.port - half_num_pods - 1) event.connection.send(msg) elif arp_pkt.opcode == arp_pkt.REPLY: #print 'ARP reply : src ip:{0}, dst ip:{1}'.format(arp_pkt.protosrc.toStr(), arp_pkt.protodst.toStr()) arp_pkt.hwdst = adrs.EthAddr(pmac_actual[arp_pkt.hwdst.toStr()]) arp_pkt.hwsrc = pmac_src eth_pkt.src = pmac_src msg = of.ofp_packet_out() msg.actions.append(of.ofp_action_output(port = of.OFPP_TABLE)) msg.data = eth_pkt.pack() core.openflow.connections[cs[0]].send(msg)
def handle_arp (self, packet, in_port): print "ARP Packet Arrived at Router R"+str(self.connection.dpid)+" at Interface"+str(in_port) if packet.payload.opcode == arp.REQUEST: arp_req = packet.next # Create ARP reply arp_rep = arp() arp_rep.opcode = arp.REPLY # Show the client that it's actually the me arp_rep.hwsrc = self.EthAddr arp_rep.hwdst = arp_req.hwsrc arp_rep.protosrc = self.IPAddr arp_rep.protodst = arp_req.protosrc # Create the Ethernet packet eth = ethernet() eth.type = ethernet.ARP_TYPE eth.dst = packet.src eth.src = self.EthAddr eth.set_payload(arp_rep) # Send the ARP reply to client # msg is the "packet out" message. Now giving this packet special properties msg = of.ofp_packet_out() msg.data = eth.pack() msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT)) msg.in_port = in_port self.connection.send(msg) print "arp reply DONE" if packet.payload.opcode == arp.REPLY: self.arp_table[packet.next.protosrc]=packet.src que1=[] for tpl in self.que: eth=tpl[0] Interface=tpl[1] prt=tpl[2] if eth.payload.dstip==packet.next.protosrc: eth.dst=packet.src msg = of.ofp_packet_out() msg.data = eth.pack() # print "inport",of.OFPP_IN_PORT # print "outport",int(Interface) msg.actions.append(of.ofp_action_output(port = int(Interface))) msg.in_port = prt self.connection.send(msg) else: que1.append(tpl) self.que=que1
def _handle_PacketIn (event): # after receive the PacketIn message, handle it. get the information about the packet, get the #Learn the desintation IP address and fill up routing table, according to my store of edge list, get the port number #I need to handle the ARP request from each subnet first. packet = event.parsed #print packet.src if packet.type == ethernet.IPV6_TYPE: return srcSwitch = "s" + str(event.dpid) print srcSwitch print packet.type,event.port #match = of.ofp_match.from_packet(packet) if isinstance(packet.next, arp): #This solves the problem of turning every ARP into IP packets a = packet.next #destinationIP = a.protodst #dstIPtest = getKey(destinationIP) #test = network1.GetPortNumAndMacAddr(srcSwitch, dstIPtest) if a.prototype == arp.PROTO_TYPE_IP: if a.hwtype == arp.HW_TYPE_ETHERNET: if a.protosrc != 0: arpTable[str(a.protosrc)] = packet.src print arpTable _send_paused_traffic(event.dpid,str(a.protosrc),event.port) if a.opcode == a.REQUEST: if str(a.protodst) in arpTable: r = pkt.arp() r.hwtype = a.hwtype r.prototype = a.prototype r.hwlen = a.hwlen r.protolen = a.protolen r.opcode = a.REPLY r.hwdst = a.hwsrc #r.hwsrc = switchMac[a.protodst] r.hwsrc = arpTable[str(a.protodst)] r.protodst = a.protosrc #print a.protodst.toRaw #print (r.protodst.toStr == "192.168.70.2") #if(r.protodst == IPAddr("192.168.70.2")): #if(r.protodst == IPAddr("192.168.10.1")): #r.hwsrc = EthAddr("52:fa:e1:4c:d1:6c") r.protosrc = a.protodst #a.protodst is the destination IP addresses e = pkt.ethernet(type=packet.type, src=r.hwsrc, dst=a.hwsrc) e.payload = r msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT)) msg.in_port = event.port event.connection.send(msg) else: msg = of.ofp_packet_out(in_port = event.port, action = of.ofp_action_output(port = of.OFPP_IN_PORT)) event.connection.send(msg)
def _handle_PacketIn(self, event): # parsing the input packet packet = event.parse() # updating out mac to port mapping if packet.type == packet.LLDP_TYPE or packet.type == 0x86DD: # Drop LLDP packets # Drop IPv6 packets # send of command without actions msg = of.ofp_packet_out() msg.buffer_id = event.ofp.buffer_id msg.in_port = event.port self.connection.send(msg) return # Add the mac to our list self.macDictionary[packet.src] = event.port # if we know the dest, then set a flow and forwad the packet if packet.dst in self.macDictionary.keys(): ## Code in this block takes inspiration (or outright borrowed) from ## l2_learning.py that comes with pox. # Add a flow to the switch port = self.macDictionary[packet.dst] log.debug("installing flow for *.* -> %s.%i" % (packet.dst, port)) msg = of.ofp_flow_mod() msg.match = of.ofp_match.from_packet(packet) msg.match.dl_src = None # wilcard for src msg.match.in_port = None msg.match.nw_src = None msg.idle_timeout = 10 msg.hard_timeout = 30 msg.actions.append(of.ofp_action_output(port=port)) msg.data = event.ofp # Send packet to port self.connection.send(msg) return # Flood the packet log.debug("Port for %s unknown -- flooding" % (packet.dst,)) msg = of.ofp_packet_out() 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 create_discovery_packet (self, dpid, port_num, port_addr): """ Build discovery packet """ chassis_id = pkt.chassis_id(subtype=pkt.chassis_id.SUB_LOCAL) chassis_id.id = bytes('dpid:' + hex(long(dpid))[2:-1]) # Maybe this should be a MAC. But a MAC of what? Local port, maybe? port_id = pkt.port_id(subtype=pkt.port_id.SUB_PORT, id=str(port_num)) ttl = pkt.ttl(ttl = self._ttl) sysdesc = pkt.system_description() sysdesc.payload = bytes('dpid:' + hex(long(dpid))[2:-1]) discovery_packet = pkt.lldp() discovery_packet.tlvs.append(chassis_id) discovery_packet.tlvs.append(port_id) discovery_packet.tlvs.append(ttl) discovery_packet.tlvs.append(sysdesc) discovery_packet.tlvs.append(pkt.end_tlv()) eth = pkt.ethernet(type=pkt.ethernet.LLDP_TYPE) eth.src = port_addr eth.dst = pkt.ETHERNET.NDP_MULTICAST eth.payload = discovery_packet po = of.ofp_packet_out(action = of.ofp_action_output(port=port_num)) po.data = eth.pack() return po.pack()
def drop (): # Kill buffer(缓冲区) on switch if event.ofp.buffer_id is not None: msg = of.ofp_packet_out() msg.buffer_id = event.ofp.buffer_id msg.in_port = event.port event.connection.send(msg)
def resend_packet (self, packet_in, out_ports): """ Instructs the switch to resend a packet that it had sent to us. "packet_in" is the ofp_packet_in object the switch had sent to the controller due to a table-miss. """ log.debug( "Sending out: %s" % out_ports ) msg = of.ofp_packet_out() msg.data = packet_in # Add actions for each out port for out_port in out_ports: # If port is dot1q put on vlan tag if self.vlan_to_port[out_port] == 1: action = of.ofp_action_vlan_vid(vlan_vid = self.vlan_to_port[packet_in.in_port]) # Else strip vlan tag else: action = of.ofp_action_strip_vlan() msg.actions.append(action) # Send the packet out of the specified port action = of.ofp_action_output(port = out_port) msg.actions.append(action) # Send message to switch self.connection.send(msg) log.debug("Packet sent out: %s" % out_ports )
def _do_probe (self): """ Send an ARP to a server to see if it's still up """ self._do_expire() server = self.servers.pop(0) self.servers.append(server) r = arp() r.hwtype = r.HW_TYPE_ETHERNET r.prototype = r.PROTO_TYPE_IP r.opcode = r.REQUEST r.hwdst = ETHER_BROADCAST r.protodst = server r.hwsrc = self.mac r.protosrc = self.service_ip e = ethernet(type=ethernet.ARP_TYPE, src=self.mac, dst=ETHER_BROADCAST) e.set_payload(r) #self.log.debug("ARPing for %s", server) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD)) msg.in_port = of.OFPP_NONE self.con.send(msg) self.outstanding_probes[server] = time.time() + self.arp_timeout core.callDelayed(self._probe_wait_time, self._do_probe)
def send_to_switch(self,packet): switch = packet["switch"] outport = packet["outport"] try: inport = packet["inport"] if inport == -1 or inport == outport: inport = inport_value_hack(outport) except KeyError: inport = inport_value_hack(outport) msg = of.ofp_packet_out() msg.in_port = inport msg.data = self.packet_to_network(packet) msg.actions.append(of.ofp_action_output(port = outport)) if self.show_traces: print "========= POX/OF SEND ================" print msg print packetlib.ethernet(msg._get_data()) print ## HANDLE PACKETS SEND ON LINKS THAT HAVE TIMED OUT try: self.switches[switch]['connection'].send(msg) except Runtimerror, e: print "ERROR:send_to_switch: %s to switch %d" % (str(e),switch)
def create_discovery_packet(self, dpid, portNum, portAddr): """ Create LLDP packet """ discovery_packet = lldp() cid = chassis_id() # Maybe this should be a MAC. But a MAC of what? Local port, maybe? cid.fill(cid.SUB_LOCAL, bytes("dpid:" + hex(long(dpid))[2:-1])) discovery_packet.add_tlv(cid) pid = port_id() pid.fill(pid.SUB_PORT, str(portNum)) discovery_packet.add_tlv(pid) ttlv = ttl() ttlv.fill(LLDP_TTL) discovery_packet.add_tlv(ttlv) sysdesc = system_description() sysdesc.fill(bytes("dpid:" + hex(long(dpid))[2:-1])) discovery_packet.add_tlv(sysdesc) discovery_packet.add_tlv(end_tlv()) eth = ethernet() eth.src = portAddr eth.dst = NDP_MULTICAST eth.set_payload(discovery_packet) eth.type = ethernet.LLDP_TYPE po = of.ofp_packet_out(action=of.ofp_action_output(port=portNum), data=eth.pack()) return po.pack()
def send_packet (self, buffer_id, raw_data, out_port, in_port): """ Sends a packet out of the specified switch port. If buffer_id is a valid buffer on the switch, use that. Otherwise, send the raw data in raw_data. The "in_port" is the port number that packet arrived on. Use OFPP_NONE if you're generating this packet. """ # We tell the switch to take the packet with id buffer_if from in_port # and send it to out_port # If the switch did not specify a buffer_id, it must have specified # the raw data of the packet, so in this case we tell it to send # the raw data msg = of.ofp_packet_out() msg.in_port = in_port if buffer_id != -1 and buffer_id is not None: # We got a buffer ID from the switch; use that msg.buffer_id = buffer_id else: # No buffer ID from switch -- we got the raw data if raw_data is None: # No raw_data specified -- nothing to send! return msg.data = raw_data # Add an action to send to the specified port action = of.ofp_action_output(port = out_port) msg.actions.append(action) # Send message to switch self.connection.send(msg)
def flood(event): connection = event.connection msg = of.ofp_packet_out() msg.data = event.ofp msg.in_port = event.port msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) connection.send(msg)
def send_arpResponse(self, arp_req, event, packet, mac): ''' Send out an ARP response ''' # create the arp response packet arp_res = arp() arp_res.hwtype = arp_req.hwtype arp_res.prototype = arp_req.prototype arp_res.hwlen = arp_req.hwlen arp_res.protolen = arp_req.protolen arp_res.opcode = arp.REPLY arp_res.hwdst = arp_req.hwsrc arp_res.protodst = arp_req.protosrc arp_res.protosrc = arp_req.protodst arp_res.hwsrc = mac # create an ethernet package that contains the arp response we created above e = ethernet(type=packet.type, src=mac, dst=arp_req.hwsrc) e.set_payload(arp_res) log.debug("%i %i answering ARP for %s" % (event.connection.dpid, event.port, str(arp_res.protosrc))) # send the ARP response msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT)) msg.in_port = event.port event.connection.send(msg)
def sendPing (self, macEntry, ipAddr): """ Builds an ETH/IP any-to-any ARP packet (an "ARP ping") """ r = arp() r.opcode = arp.REQUEST r.hwdst = macEntry.macaddr r.hwsrc = self.ping_src_mac r.protodst = ipAddr # src is IP_ANY e = ethernet(type=ethernet.ARP_TYPE, src=r.hwsrc, dst=r.hwdst) e.payload = r log.debug("%i %i sending ARP REQ to %s %s", macEntry.dpid, macEntry.port, str(r.hwdst), str(r.protodst)) msg = of.ofp_packet_out(data = e.pack(), action = of.ofp_action_output(port=macEntry.port)) if core.openflow.sendToDPID(macEntry.dpid, msg.pack()): ipEntry = macEntry.ipAddrs[ipAddr] ipEntry.pings.sent() else: # macEntry is stale, remove it. log.debug("%i %i ERROR sending ARP REQ to %s %s", macEntry.dpid, macEntry.port, str(r.hwdst), str(r.protodst)) del macEntry.ipAddrs[ipAddr] return
def _handle_PacketIn(self,event): eth_packetRecv = event.parsed if eth_packetRecv.type == ethernet.ARP_TYPE: #checking if the payload is ARP pkt msg = of.ofp_packet_out() msg.in_port = event.port arpreq = eth_packetRecv.payload # extract arp packet - arpreq # log.debug('%s arp table',ARPTable) if arpreq.protosrc not in ARPTable.keys(): #if no srcip entry in ARP table,add a new entry for scrip, srcmac ARPTable[arpreq.protosrc] = arpreq.hwsrc # print "in 1" if arpreq.protodst not in ARPTable.keys():#if no entry in the ARPtable , then flood the ARP packet as l2 bc eth_packetSent = eth_packetRecv msg.data = eth_packetSent.pack() msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD)) #flooding on all ports of the swtch elif arpreq.protodst in ARPTable.keys(): # if dstip in ARPTable,build appropriate ARP reply arpreply = self.buildReply(arpreq)#building the arp reply , eth_packetSent = ethernet(type = ethernet.ARP_TYPE,dst = arpreply.hwdst )#setting type of ethernet packet and src and dst mac addresses eth_packetSent.set_payload(arpreply) # the payload of the eth packet is the arp packet msg.data = eth_packetSent.pack() msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT)) msg.in_port = event.port elif eth_packetRecv.type != ethernet.ARP_TYPE: # print "in switching..." msg = self.processPacket(event) # log.debug('mac addr table %s',self.macaddrtable) event.connection.send(msg)
def kill_buffer (): if event.ofp.buffer_id == -1: return msg = of.ofp_packet_out() msg.buffer_id = event.ofp.buffer_id msg.in_port = event.port self.switch.send(msg) return
def send_to_switch(self,packet): switch = packet["switch"] outport = packet["outport"] try: inport = packet["inport"] if inport == -1 or inport == outport: inport = inport_value_hack(outport) except KeyError: inport = inport_value_hack(outport) msg = of.ofp_packet_out() msg.in_port = inport msg.data = self.packet_to_network(packet) msg.actions.append(of.ofp_action_output(port = outport)) thisConnection = self.switches[switch]['connection'] #if self.show_traces: if self.trace != None: self.trace("========= POX/OF SEND ================", timeStamped=True) self.trace(msg) # If the following line is un-commented, 'pingall' fails # Tested with BADIP2IP and BADIP3IP # self.trace(packetlib.ethernet(msg._get_data())) self.trace("thisConnection=%s\n" % thisConnection) self.trace("") ## HANDLE PACKETS SEND ON LINKS THAT HAVE TIMED OUT try: # self.switches[switch]['connection'].send(msg) thisConnection.send(msg) except Runtimerror, e: print "ERROR:send_to_switch: %s to switch %d" % (str(e),switch)
def _handle_ConnectionUp(self, event): # fake mac id for service ip self.lb_mac = EthAddr("0A:00:00:00:00:01") self.connection = event.connection # pre emptively collecting the mac and port number of server IPs # by sending ARP request packets for ip in self.serverIp: # constructing ARP packet arpPacket = arp() arpPacket.opcode = arpPacket.REQUEST arpPacket.hwsrc = self.lb_mac arpPacket.hwdst = ETHER_BROADCAST arpPacket.protosrc = self.serviceIp arpPacket.protodst = ip # constructing ethernet packet with ARP as payload e = ethernet(type = ethernet.ARP_TYPE, src = self.connection.eth_addr, dst = ETHER_BROADCAST) e.set_payload(arpPacket) # constructing openflow out message msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD)) msg.in_port = of.OFPP_NONE # sending message self.connection.send(msg)
def drop (): 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 msg.in_port = event.port self.connection.send(msg)
def flood (message = None): """ Floods the packet """ msg = of.ofp_packet_out() msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD)) msg.data = event.ofp msg.in_port = event.port event.connection.send(msg)
def _flood(self, packet_in): ports=self.connection.features.ports buffer_id = packet_in.buffer_id raw_data = packet_in.data in_port=packet_in.in_port msg=of.ofp_packet_out() if buffer_id != -1 and buffer_id is not None: # We got a buffer ID from the switch; use that msg.buffer_id = buffer_id else: # No buffer ID from switch -- we got the raw data if raw_data is None: # No raw_data specified -- nothing to send! return msg.data = raw_data for port in ports: port_no=port.port_no # do not flood backwards, do not flood the controller and do not flood over links that are not part of the spanning tree if (port_no < of.OFPP_MAX) and (port_no != in_port) and (port_no not in self.forbidden_ports): #print '[switch %i] (flooding) adding action from in_port=%i to out_port=%i' % (self.connection.dpid, in_port,port_no) action = of.ofp_action_output(port = port_no) msg.actions.append(action) self.connection.send(msg)
def flood(message=None): """ Floods the packet """ msg = of.ofp_packet_out() if time.time() - self.connection.connect_time >= _flood_delay: # Only flood if we've been connected for a little while... if self.hold_down_expired is False: # Oh yes it is! self.hold_down_expired = True log.info("%s: Flood hold-down expired -- flooding", dpid_to_str(event.dpid)) if message is not None: log.debug(message) #log.debug("%i: flood %s -> %s", event.dpid,packet.src,packet.dst) # OFPP_FLOOD is optional; on some switches you may need to change # this to OFPP_ALL. msg.actions.append( of.ofp_action_output(port=of.OFPP_FLOOD)) else: pass #log.info("Holding down flood for %s", dpid_to_str(event.dpid)) msg.data = event.ofp msg.in_port = event.port self.connection.send(msg)
def _handle_PacketIn (self, event): dpid = event.connection.dpid inport = event.port packet = event.parsed if not packet.parsed: log.warning("%i %i ignoring unparsed packet", dpid, inport) return if dpid not in self.arpTable: # New switch -- create an empty table self.arpTable[dpid] = {} for fake in self.fakeways: self.arpTable[dpid][IPAddr(fake)] = Entry(of.OFPP_NONE, dpid_to_mac(dpid)) if packet.type == ethernet.LLDP_TYPE: # Ignore LLDP packets return if isinstance(packet.next, ipv4): log.debug("%i %i IP %s => %s", dpid,inport, packet.next.srcip,packet.next.dstip) # Send any waiting packets... self._send_lost_buffers(dpid, packet.next.srcip, packet.src, inport) # Learn or update port/MAC info if packet.next.srcip in self.arpTable[dpid]: if self.arpTable[dpid][packet.next.srcip] != (inport, packet.src): log.info("%i %i RE-learned %s", dpid,inport,packet.next.srcip) else: log.debug("%i %i learned %s", dpid,inport,str(packet.next.srcip)) self.arpTable[dpid][packet.next.srcip] = Entry(inport, packet.src) # Try to forward dstaddr = packet.next.dstip if dstaddr in self.arpTable[dpid]: # We have info about what port to send it out on... prt = self.arpTable[dpid][dstaddr].port mac = self.arpTable[dpid][dstaddr].mac if prt == inport: log.warning("%i %i not sending packet for %s back out of the " + "input port" % (dpid, inport, str(dstaddr))) else: log.debug("%i %i installing flow for %s => %s out port %i" % (dpid, inport, packet.next.srcip, dstaddr, prt)) actions = [] actions.append(of.ofp_action_dl_addr.set_dst(mac)) actions.append(of.ofp_action_output(port = prt)) match = of.ofp_match.from_packet(packet, inport) match.dl_src = None # Wildcard source MAC msg = of.ofp_flow_mod(command=of.OFPFC_ADD, idle_timeout=FLOW_IDLE_TIMEOUT, hard_timeout=of.OFP_FLOW_PERMANENT, buffer_id=event.ofp.buffer_id, actions=actions, match=of.ofp_match.from_packet(packet, inport)) event.connection.send(msg.pack()) elif self.arp_for_unknowns: # We don't know this destination. # First, we track this buffer so that we can try to resend it later # if we learn the destination, second we ARP for the destination, # which should ultimately result in it responding and us learning # where it is # Add to tracked buffers if (dpid,dstaddr) not in self.lost_buffers: self.lost_buffers[(dpid,dstaddr)] = [] bucket = self.lost_buffers[(dpid,dstaddr)] entry = (time.time() + MAX_BUFFER_TIME,event.ofp.buffer_id,inport) bucket.append(entry) while len(bucket) > MAX_BUFFERED_PER_IP: del bucket[0] # Expire things from our outstanding ARP list... self.outstanding_arps = {k:v for k,v in self.outstanding_arps.iteritems() if v > time.time()} # Check if we've already ARPed recently if (dpid,dstaddr) in self.outstanding_arps: # Oop, we've already done this one recently. return # And ARP... self.outstanding_arps[(dpid,dstaddr)] = time.time() + 4 r = arp() r.hwtype = r.HW_TYPE_ETHERNET r.prototype = r.PROTO_TYPE_IP r.hwlen = 6 r.protolen = r.protolen r.opcode = r.REQUEST r.hwdst = ETHER_BROADCAST r.protodst = dstaddr r.hwsrc = packet.src r.protosrc = packet.next.srcip e = ethernet(type=ethernet.ARP_TYPE, src=packet.src, dst=ETHER_BROADCAST) e.set_payload(r) log.debug("%i %i ARPing for %s on behalf of %s" % (dpid, inport, str(r.protodst), str(r.protosrc))) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD)) msg.in_port = inport event.connection.send(msg) elif isinstance(packet.next, arp): a = packet.next log.debug("%i %i ARP %s %s => %s", dpid, inport, {arp.REQUEST:"request",arp.REPLY:"reply"}.get(a.opcode, 'op:%i' % (a.opcode,)), str(a.protosrc), str(a.protodst)) if a.prototype == arp.PROTO_TYPE_IP: if a.hwtype == arp.HW_TYPE_ETHERNET: if a.protosrc != 0: # Learn or update port/MAC info if a.protosrc in self.arpTable[dpid]: if self.arpTable[dpid][a.protosrc] != (inport, packet.src): log.info("%i %i RE-learned %s", dpid,inport,str(a.protosrc)) else: log.debug("%i %i learned %s", dpid,inport,str(a.protosrc)) self.arpTable[dpid][a.protosrc] = Entry(inport, packet.src) # Send any waiting packets... self._send_lost_buffers(dpid, a.protosrc, packet.src, inport) if a.opcode == arp.REQUEST: # Maybe we can answer if a.protodst in self.arpTable[dpid]: # We have an answer... if not self.arpTable[dpid][a.protodst].isExpired(): # .. and it's relatively current, so we'll reply ourselves r = arp() r.hwtype = a.hwtype r.prototype = a.prototype r.hwlen = a.hwlen r.protolen = a.protolen r.opcode = arp.REPLY r.hwdst = a.hwsrc r.protodst = a.protosrc r.protosrc = a.protodst r.hwsrc = self.arpTable[dpid][a.protodst].mac e = ethernet(type=packet.type, src=dpid_to_mac(dpid), dst=a.hwsrc) e.set_payload(r) log.debug("%i %i answering ARP for %s" % (dpid, inport, str(r.protosrc))) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT)) msg.in_port = inport event.connection.send(msg) return srcdpid = -1 srcport = -1 dstdpid = -1 dstport = -1 if self.cached_link.has_key((a.protosrc, a.protodst)): pass else:#此时src与dst尚未建立相应的链路,试图从host_tracker中找到ip地址对应的交换机dpid和port for k, v in core.host_tracker.entryByMAC.items(): for ip in v.ipAddrs: if ip == a.protosrc: srcdpid = v.dpid srcport = v.port if ip == a.protodst: dstdpid = v.dpid dstport = v.port if srcdpid >= 0 and srcport >= 0 and dstdpid >= 0 and dstport >= 0:#如果所有的host对应的dpid和port均已找到的话,开始寻路 path = None while path == None: moo1 = MOO(srcdpid, dstdpid)#MOO算法寻路 path = moo1.calc_path() if path != None:#找到了一条链路 self.cached_link[(a.protosrc, a.protodst)] = (path[:], srcdpid, srcport, dstdpid, dstport) path.reverse() self.cached_link[(a.protodst, a.protosrc)] = (path[:], dstdpid, dstport, srcdpid, srcport) if self.cached_link.has_key((a.protosrc, a.protodst)):#此时系统中存在缓存的链路 srcdpid = self.cached_link.get((a.protosrc, a.protodst))[1] srcport = self.cached_link.get((a.protosrc, a.protodst))[2] dstdpid = self.cached_link.get((a.protosrc, a.protodst))[3] dstport = self.cached_link.get((a.protosrc, a.protodst))[4] log.info("%i %i flow answering for %s to %s" % (dpid, inport, str(a.protosrc), str(a.protodst))) def findport(srcdpid, dstdpid):#在core.openflow_discovery.adjacency中寻找两个中间交换机的物理端口连接 for k, v in core.openflow_discovery.adjacency.items(): if k.dpid1 == srcdpid and k.dpid2 == dstdpid: return k.port1, k.port2 actions = [] #actions.append(of.ofp_action_dl_addr.set_dst(EthAddr('00:00:00:00:00:02'))) if dpid == dstdpid:#当前交换机即为目的地交换机时,直接从dstport中出去即可,无需通过core.openflow_discovery.adjacency计算 actions.append(of.ofp_action_output(port = dstport)) else:#当前交换机不是目的地交换机 linkpath = self.cached_link.get((a.protosrc, a.protodst))[0]#取得当前已计算好的链路信息 nextdpid = -1#初始化下一跳交换机 for i in range(len(linkpath)):#在已计算好的链路信息中寻找当前交换机的下一跳交换机,此时,当前交换机肯定不为最后一跳交换机 if linkpath[i] == dpid: nextdpid = linkpath[i + 1] log.info("%i to %i found a hop" %(dpid, nextdpid)) break port1, port2 = findport(dpid,nextdpid)#在core.openflow_discovery.adjacency中寻找两个中间交换机的物理端口连接 actions.append(of.ofp_action_output(port = port1)) match = of.ofp_match.from_packet(packet, 1) match.dl_src = None # Wildcard source MAC msg = of.ofp_flow_mod(command=of.OFPFC_ADD, idle_timeout=FLOW_IDLE_TIMEOUT, hard_timeout=of.OFP_FLOW_PERMANENT, buffer_id=event.ofp.buffer_id, actions=actions, match=of.ofp_match.from_packet(packet, inport)) event.connection.send(msg.pack()) return else: log.info("%i %i unable to find a path from %s to %s" % (dpid, inport, str(a.protosrc), str(a.protodst))) return
def _handle_openflow_PacketIn (self, event): global cache, cacheCnt, dstCacheDict, nwHosts, cache1checker, cache2checker, cache1Down, cache2Down, cache1checkerCount, cache2checkerCount dpid = event.connection.dpid inport = event.port packet = event.parsed if not packet.parsed: log.warning("%i %i ignoring unparsed packet", dpid, inport) return if dpid not in self.arpTable: # New switch -- create an empty table self.arpTable[dpid] = {} for fake in self.fakeways: self.arpTable[dpid][IPAddr(fake)] = Entry(of.OFPP_NONE, dpid_to_mac(dpid)) if packet.type == ethernet.LLDP_TYPE: # Ignore LLDP packets return if isinstance(packet.next, ipv4): log.debug("%i %i IP %s => %s", dpid,inport, packet.next.srcip,packet.next.dstip) # Send any waiting packets... self._send_lost_buffers(dpid, packet.next.srcip, packet.src, inport) # Learn or update port/MAC info if packet.next.srcip in self.arpTable[dpid]: if self.arpTable[dpid][packet.next.srcip] != (inport, packet.src): log.debug("%i %i RE-learned %s", dpid,inport,packet.next.srcip) if self.wide: # Make sure we don't have any entries with the old info... msg = of.ofp_flow_mod(command=of.OFPFC_DELETE) msg.match.nw_dst = packet.next.srcip msg.match.dl_type = ethernet.IP_TYPE event.connection.send(msg) else: log.debug("%i %i learned %s", dpid,inport,packet.next.srcip) self.arpTable[dpid][packet.next.srcip] = Entry(inport, packet.src) # Try to forward dstaddr = packet.next.dstip #print nwHosts #print dstCacheDict #print dstaddr #print type(dstaddr) #for p in nwHosts: log.info("Hosts - %s",p) # print hosts #for p in dstCacheDict: log.info("Cache entries - %s",p) # print map keys #HackAlert if dstaddr not in nwHosts: if dstaddr not in dstCacheDict: dstCacheDict[dstaddr] = IPAddr(cache[cacheCnt]) log.info("assigning new cache for a new dstaddr: cache assigned :%s for dest addr:%s", dstCacheDict[dstaddr], packet.next.dstip) cacheCnt=1-cacheCnt dstaddr = IPAddr(dstCacheDict[dstaddr]) if packet.next.dstip not in nwHosts: if dstaddr == IPAddr('192.168.1.4') and cache1Down: dstCacheDict[packet.next.dstip] = IPAddr('192.168.1.5') dstaddr = IPAddr('192.168.1.5') log.info("**********************cache 1 is down**********************") msg = of.ofp_flow_mod(command=of.OFPFC_DELETE) msg.match.nw_dst = packet.next.dstip msg.match.dl_type = ethernet.IP_TYPE #event.connection.send(msg) if dstaddr == IPAddr('192.168.1.5') and cache2Down: dstCacheDict[packet.next.dstip] = IPAddr('192.168.1.4') dstaddr = IPAddr('192.168.1.4') log.info("**********************cache 2 is down**********************") msg = of.ofp_flow_mod(command=of.OFPFC_DELETE) msg.match.nw_dst = packet.next.dstip msg.match.dl_type = ethernet.IP_TYPE #event.connection.send(msg) if cache1Down and cache2Down: log.info("**********************cache 1 & 2 are down => reroute to router **********************") dstaddr = IPAddr('192.168.1.2') msg = of.ofp_flow_mod(command=of.OFPFC_DELETE) msg.match.nw_dst = packet.next.dstip msg.match.dl_type = ethernet.IP_TYPE #event.connection.send(msg) log.info("changing actual destination IP : %s to cache ip : %s", packet.next.dstip, dstaddr) # if dstaddr in dstCacheDict: # dstaddr = dstCacheDict[dstaddr] # elif dstaddr not in nwHosts: # dstCacheDict[dstaddr] = cache[cacheCnt] # cacheCnt=1-cacheCnt # dstaddr = dstCacheDict[dstaddr] if dstaddr in self.arpTable[dpid]: # We have info about what port to send it out on... prt = self.arpTable[dpid][dstaddr].port mac = self.arpTable[dpid][dstaddr].mac if prt == inport: log.warning("%i %i not sending packet for %s back out of the " "input port" % (dpid, inport, dstaddr)) else: log.info("For packet in on switch %i via port %i installing flow for source %s => destination %s to go on out port %i in the switch %i" % (dpid, inport, packet.next.srcip, packet.next.dstip, prt, dpid)) actions = [] actions.append(of.ofp_action_dl_addr.set_dst(mac)) actions.append(of.ofp_action_nw_addr.set_dst(dstaddr)) #actions.append(of.ofp_action_tp_port.set_dst(80)) actions.append(of.ofp_action_output(port = prt)) #if self.wide: match = of.ofp_match(dl_type = ethernet.IP_TYPE, in_port=inport, nw_src=packet.next.srcip, nw_dst = packet.next.dstip) #mention the actual destination IP #else: # match = of.ofp_match.from_packet(packet, inport) msg = of.ofp_flow_mod(command=of.OFPFC_ADD, idle_timeout=FLOW_IDLE_TIMEOUT, hard_timeout=of.OFP_FLOW_PERMANENT, buffer_id=event.ofp.buffer_id, actions=actions, match=match) event.connection.send(msg.pack()) ########################################################################################## actions = [] #actions.append(of.ofp_action_dl_addr.set_dst(mac)) actions.append(of.ofp_action_nw_addr.set_src(packet.next.dstip)) #actions.append(of.ofp_action_tp_port.set_dst(8080)) actions.append(of.ofp_action_output(port = inport)) #if self.wide: match = of.ofp_match(dl_type = ethernet.IP_TYPE, in_port=prt, nw_src=dstaddr, nw_dst = packet.next.srcip) #mention the actual destination IP #else: # match = of.ofp_match.from_packet(packet, inport) msg = of.ofp_flow_mod(command=of.OFPFC_ADD, idle_timeout=FLOW_IDLE_TIMEOUT, hard_timeout=of.OFP_FLOW_PERMANENT, buffer_id=of.NO_BUFFER, actions=actions, match=match) event.connection.send(msg.pack()) elif self.arp_for_unknowns: # We don't know this destination. # First, we track this buffer so that we can try to resend it later # if we learn the destination, second we ARP for the destination, # which should ultimately result in it responding and us learning # where it is # Add to tracked buffers if (dpid,dstaddr) not in self.lost_buffers: self.lost_buffers[(dpid,dstaddr)] = [] bucket = self.lost_buffers[(dpid,dstaddr)] entry = (time.time() + MAX_BUFFER_TIME,event.ofp.buffer_id,inport) bucket.append(entry) while len(bucket) > MAX_BUFFERED_PER_IP: del bucket[0] # Expire things from our outstanding ARP list... self.outstanding_arps = {k:v for k,v in self.outstanding_arps.iteritems() if v > time.time()} # Check if we've already ARPed recently if (dpid,dstaddr) in self.outstanding_arps: # Oop, we've already done this one recently. return # And ARP... self.outstanding_arps[(dpid,dstaddr)] = time.time() + 4 r = arp() r.hwtype = r.HW_TYPE_ETHERNET r.prototype = r.PROTO_TYPE_IP r.hwlen = 6 r.protolen = r.protolen r.opcode = r.REQUEST r.hwdst = ETHER_BROADCAST r.protodst = dstaddr r.hwsrc = packet.src r.protosrc = packet.next.srcip e = ethernet(type=ethernet.ARP_TYPE, src=packet.src, dst=ETHER_BROADCAST) e.set_payload(r) log.debug("%i %i ARPing for %s on behalf of %s" % (dpid, inport, r.protodst, r.protosrc)) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD)) msg.in_port = inport event.connection.send(msg) elif isinstance(packet.next, arp): a = packet.next log.debug("%i %i ARP %s %s => %s", dpid, inport, {arp.REQUEST:"request",arp.REPLY:"reply"}.get(a.opcode, 'op:%i' % (a.opcode,)), a.protosrc, a.protodst) dstaddr = a.protodst# dest IP spoofingmac = False #HackAlert if dstaddr not in nwHosts: if dstaddr not in dstCacheDict: dstCacheDict[dstaddr] = IPAddr(cache[cacheCnt]) log.info("assigning cache for a new dstaddr in ARP: cache:%s, dstaddr:%s", dstCacheDict[dstaddr], a.protodst) cacheCnt=1-cacheCnt dstaddr = IPAddr(dstCacheDict[dstaddr]) #check cache status if a.protodst not in nwHosts: if dstaddr == IPAddr('192.168.1.4') and cache1Down: dstCacheDict[a.protodst] = IPAddr('192.168.1.5') dstaddr = IPAddr('192.168.1.5') log.debug("********************** cache 1 is down **********************") msg = of.ofp_flow_mod(command=of.OFPFC_DELETE) msg.match.nw_dst = a.protodst msg.match.nw_src = a.protosrc msg.match.dl_type = ethernet.IP_TYPE #event.connection.send(msg) if dstaddr == IPAddr('192.168.1.5') and cache2Down: dstCacheDict[a.protodst] = IPAddr('192.168.1.4') dstaddr = IPAddr('192.168.1.4') msg = of.ofp_flow_mod(command=of.OFPFC_DELETE) msg.match.nw_dst = a.protodst msg.match.nw_src = a.protosrc msg.match.dl_type = ethernet.IP_TYPE #event.connection.send(msg) log.debug("********************** cache 2 is down **********************") if cache1Down and cache2Down: log.debug("********************** cache 1 & 2 are down => reroute to router **********************") dstaddr = IPAddr('192.168.1.2') # redirect to router msg = of.ofp_flow_mod(command=of.OFPFC_DELETE) msg.match.nw_dst = a.protodst msg.match.nw_src = a.protosrc msg.match.dl_type = ethernet.IP_TYPE #event.connection.send(msg) log.info("changing destination IP to cache ip in ARP: cache:%s, dstaddr:%s", dstaddr, a.protodst) if dstaddr != a.protodst: spoofingmac = True if a.prototype == arp.PROTO_TYPE_IP: if a.hwtype == arp.HW_TYPE_ETHERNET: if a.protosrc != 0: if str(a.protosrc) == '192.168.1.4': cache1checker = False cache1Down = False cache1checkerCount = 10 if str(a.protosrc) == '192.168.1.5': cache2checker = False cache2Down = False cache2checkerCount = 10 # Learn or update port/MAC info if a.protosrc in self.arpTable[dpid]: if self.arpTable[dpid][a.protosrc] != (inport, packet.src): log.debug("%i %i RE-learned %s", dpid,inport,a.protosrc) if self.wide: # Make sure we don't have any entries with the old info... msg = of.ofp_flow_mod(command=of.OFPFC_DELETE) msg.match.dl_type = ethernet.IP_TYPE msg.match.nw_dst = a.protosrc event.connection.send(msg) else: log.debug("%i %i learned %s", dpid,inport,a.protosrc) self.arpTable[dpid][a.protosrc] = Entry(inport, packet.src) # Send any waiting packets... self._send_lost_buffers(dpid, a.protosrc, packet.src, inport) # start evaluating ARP requests if a.opcode == arp.REQUEST: # Maybe we can answer if dstaddr in self.arpTable[dpid]: # We have an answer... if not self.arpTable[dpid][dstaddr].isExpired(): # .. and it's relatively current, so we'll reply ourselves if str(dstaddr) in cache and str(dstaddr) == '192.168.1.4': cache1checker = False cache1Down = False cache1checkerCount = 10 if str(dstaddr) in cache and str(dstaddr) == '192.168.1.5': cache2checker = False cache2Down = False cache2checkerCount = 10 r = arp() r.hwtype = a.hwtype r.prototype = a.prototype r.hwlen = a.hwlen r.protolen = a.protolen r.opcode = arp.REPLY r.hwdst = a.hwsrc r.protodst = a.protosrc r.protosrc = a.protodst #The guy who is supposed to reply r.hwsrc = self.arpTable[dpid][dstaddr].mac # mac of guy who is supposed to reply e = ethernet(type=packet.type, src=dpid_to_mac(dpid), dst=a.hwsrc) e.set_payload(r) ###################################################################################################################### if spoofingmac: log.info("Switch %i on port %i answering ARP for %s to %s with the mac of the cache %s switch %s" % (dpid, inport,a.protodst,a.protosrc, r.hwsrc, dpid_to_mac(dpid))) else: log.info("Switch %i on port %i answering ARP for %s to %s with the mac %s switch %s" % (dpid, inport,a.protodst,a.protosrc, r.hwsrc, dpid_to_mac(dpid))) ###################################################################################################################### msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT)) msg.in_port = inport event.connection.send(msg) return else: if str(dstaddr) in cache and str(dstaddr) == '192.168.1.4': #entry is expired -set checker is true if cache1checker: cache1Down = True log.debug("################# Cache1 is down #################") else: if cache1checkerCount == 0: cache1checker = True else: cache1checkerCount=cache1checkerCount-1 if str(dstaddr) in cache and str(dstaddr) == '192.168.1.5': if cache2checker: cache2Down = True log.debug("################# Cache2 is down #################") else: if cache2checkerCount == 0: cache2checker = True else: cache2checkerCount=cache2checkerCount-1 # Didn't know how to answer or otherwise handle this ARP, so just flood it #log.debug("%i %i flooding ARP %s %s => %s" % (dpid, inport, {arp.REQUEST:"request",arp.REPLY:"reply"}.get(a.opcode, 'op:%i' % (a.opcode,)), a.protosrc, a.protodst)) if a.opcode == arp.REQUEST: r = arp() r.hwtype = a.hwtype r.prototype = a.prototype r.hwlen = a.hwlen r.protolen = a.protolen r.opcode = a.opcode r.hwdst = ETHER_BROADCAST r.protodst = dstaddr r.hwsrc = a.hwsrc r.protosrc = a.protosrc e = ethernet(type=packet.type, src=packet.src, dst=ETHER_BROADCAST) e.set_payload(r) log.info("Switch %i %i Flooding ARP for %s on behalf of %s" % (dpid, inport, r.protodst, r.protosrc)) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD)) msg.in_port = inport event.connection.send(msg) if cache1Down and dstaddr != IPAddr('192.168.1.4'): r = arp() r.hwtype = a.hwtype r.prototype = a.prototype r.hwlen = a.hwlen r.protolen = a.protolen r.opcode = a.opcode r.hwdst = ETHER_BROADCAST r.protodst = IPAddr('192.168.1.4') r.hwsrc = a.hwsrc r.protosrc = a.protosrc e = ethernet(type=packet.type, src=packet.src, dst=ETHER_BROADCAST) e.set_payload(r) log.debug("Checking if cache up Switch %i %i Flooding ARP for %s on behalf of %s" % (dpid, inport, r.protodst, r.protosrc)) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD)) msg.in_port = inport event.connection.send(msg) if cache2Down and dstaddr != IPAddr('192.168.1.5'): r = arp() r.hwtype = a.hwtype r.prototype = a.prototype r.hwlen = a.hwlen r.protolen = a.protolen r.opcode = a.opcode r.hwdst = ETHER_BROADCAST r.protodst = IPAddr('192.168.1.5') r.hwsrc = a.hwsrc r.protosrc = a.protosrc e = ethernet(type=packet.type, src=packet.src, dst=ETHER_BROADCAST) e.set_payload(r) log.debug("Checking if cache up Switch %i %i Flooding ARP for %s on behalf of %s" % (dpid, inport, r.protodst, r.protosrc)) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD)) msg.in_port = inport event.connection.send(msg) else: msg = of.ofp_packet_out(in_port = inport, data = event.ofp, action = of.ofp_action_output(port = of.OFPP_FLOOD)) event.connection.send(msg)
def resend_packet(self, packet_in, out_port): msg = of.ofp_packet_out() msg.data = packet_in action = of.ofp_action_output(port=out_port) msg.actions.append(action) self.connection.send(msg)
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: print "Same switch" continue 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 print "Send reply to DPID - ", str( loc_dst[0]), "port -", loc_dst[1] 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, 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 switch_adjacency[strToDPID(swdpsrc)][p] is event.dpid: k = p 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. 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 flood(message=None): log.debug("\nFlooding for packet of source h{}".format(src_mac)) msg = of.ofp_packet_out() msg.data = ofMsg msg.actions.append(of.ofp_action_output(port=of.OFPP_ALL)) event.connection.send(msg)
def drop(message=None): """ Drop the packet """ msg = of.ofp_packet_out() msg.data = event.ofp msg.in_port = event.port event.connection.send(msg)
def outputPacket(self, packetInfo, outputPorts): outputMsg = of.ofp_packet_out() outputMsg.data = packetInfo outputMsg.actions.append(of.ofp_action_output(port=outputPorts)) self.connection.send(outputMsg)
def dropPacket(self, event): message = of.ofp_packet_out() message.data = event.data message.in_port = event.port return message
def _handle_PacketIn(self, event): # Note: arp.hwsrc is not necessarily equal to ethernet.src # (one such example are arp replies generated by this module itself # as ethernet mac is set to switch dpid) so we should be careful # to use only arp addresses in the learning code! squelch = False dpid = event.connection.dpid inport = event.port packet = event.parsed if not packet.parsed: log.warning("%s: ignoring unparsed packet", dpid_to_str(dpid)) return a = packet.find('arp') if not a: return log.debug("%s ARP %s %s => %s", dpid_to_str(dpid), { arp.REQUEST: "request", arp.REPLY: "reply" }.get(a.opcode, 'op:%i' % (a.opcode, )), str(a.protosrc), str(a.protodst)) if a.prototype == arp.PROTO_TYPE_IP: if a.hwtype == arp.HW_TYPE_ETHERNET: if a.protosrc != 0: if _learn: # Learn or update port/MAC info old_entry = _arp_table.get(a.protosrc) if old_entry is None: log.info("%s learned %s", dpid_to_str(dpid), a.protosrc) _arp_table[a.protosrc] = Entry(a.hwsrc) else: if old_entry.mac is True: # We never replace these special cases. # Might want to warn on conflict? pass elif old_entry.mac != a.hwsrc: if old_entry.static: log.warn( "%s static entry conflict %s: %s->%s", dpid_to_str(dpid), a.protosrc, old_entry.mac, a.hwsrc) else: log.warn("%s RE-learned %s: %s->%s", dpid_to_str(dpid), a.protosrc, old_entry.mac, a.hwsrc) _arp_table[a.protosrc] = Entry(a.hwsrc) else: # Update timestamp _arp_table[a.protosrc] = Entry(a.hwsrc) if a.opcode == arp.REQUEST: # Maybe we can answer if a.protodst in _arp_table: # We have an answer... r = arp() r.hwtype = a.hwtype r.prototype = a.prototype r.hwlen = a.hwlen r.protolen = a.protolen r.opcode = arp.REPLY r.hwdst = a.hwsrc r.protodst = a.protosrc r.protosrc = a.protodst mac = _arp_table[a.protodst].mac if mac is True: # Special case -- use ourself mac = event.connection.eth_addr r.hwsrc = mac e = ethernet(type=packet.type, src=event.connection.eth_addr, dst=a.hwsrc) e.payload = r if packet.type == ethernet.VLAN_TYPE: v_rcv = packet.find('vlan') e.payload = vlan(eth_type=e.type, payload=e.payload, id=v_rcv.id, pcp=v_rcv.pcp) e.type = ethernet.VLAN_TYPE log.info("%s answering ARP for %s" % (dpid_to_str(dpid), str(r.protosrc))) log.info("The corresponding MAC is %s" % str(r.hwsrc)) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append( of.ofp_action_output(port=of.OFPP_IN_PORT)) msg.in_port = inport event.connection.send(msg) return EventHalt if _eat_packets else None else: # Keep track of failed queries squelch = a.protodst in _failed_queries _failed_queries[a.protodst] = time.time() if self._check_for_flood(dpid, a): # Didn't know how to handle this ARP, so just flood it msg = "%s flooding ARP %s %s => %s" % (dpid_to_str(dpid), { arp.REQUEST: "request", arp.REPLY: "reply" }.get(a.opcode, 'op:%i' % (a.opcode, )), a.protosrc, a.protodst) if squelch: log.debug(msg) else: log.info(msg) msg = of.ofp_packet_out() msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) msg.data = event.ofp event.connection.send(msg.pack()) return EventHalt if _eat_packets else None
def _handle_PacketIn (self, event): # Note: arp.hwsrc is not necessarily equal to ethernet.src # (one such example are arp replies generated by this module itself # as ethernet mac is set to switch dpid) so we should be careful # to use only arp addresses in the learning code! squelch = False # print _arp_table # core.openflow.addListeners(self, priority=3) dpid = event.connection.dpid inport = event.port packet = event.parsed if not packet.parsed: log.warning("%s: ignoring unparsed packet", dpid_to_str(dpid)) return a = packet.find('arp') if not a: return log.debug("%s ARP %s %s => %s", dpid_to_str(dpid), {arp.REQUEST:"request",arp.REPLY:"reply"}.get(a.opcode, 'op:%i' % (a.opcode,)), str(a.protosrc), str(a.protodst)) if a.prototype == arp.PROTO_TYPE_IP: if a.hwtype == arp.HW_TYPE_ETHERNET: if a.protosrc != 0: # if _learn: # # Learn or update port/MAC info # if a.protosrc in _arp_table: # if _arp_table[a.protosrc] != a.hwsrc: # log.warn("%s RE-learned %s: %s->%s", dpid_to_str(dpid), # a.protosrc, _arp_table[a.protosrc].mac, a.hwsrc) # else: # log.info("%s learned %s", dpid_to_str(dpid), a.protosrc) # _arp_table[a.protosrc] = Entry(a.hwsrc) # print "PacketIn" # print _arp_table if a.opcode == arp.REQUEST: # Maybe we can answer if a.protodst in _arp_table: # We have an answer... r = arp() r.hwtype = a.hwtype r.prototype = a.prototype r.hwlen = a.hwlen r.protolen = a.protolen r.opcode = arp.REPLY r.hwdst = a.hwsrc r.protodst = a.protosrc r.protosrc = a.protodst mac = _arp_table[a.protodst].mac if mac is True: # Special case -- use ourself mac = _dpid_to_mac(dpid) r.hwsrc = mac e = ethernet(type=packet.type, src=_dpid_to_mac(dpid), dst=a.hwsrc) e.payload = r if packet.type == ethernet.VLAN_TYPE: v_rcv = packet.find('vlan') e.payload = vlan(eth_type = e.type, payload = e.payload, id = v_rcv.id, pcp = v_rcv.pcp) e.type = ethernet.VLAN_TYPE log.info("%s answering ARP for %s" % (dpid_to_str(dpid), str(r.protosrc))) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT)) msg.in_port = inport event.connection.send(msg) # print "SUCCESS" return EventHalt if _eat_packets else None else: # Keep track of failed queries squelch = a.protodst in _failed_queries _failed_queries[a.protodst] = time.time()
def _handle_openflow_PacketIn(self, event): log.info("Entrei aqui!!") log.info(str(self.arpTable)) dpid = event.connection.dpid inport = event.port packet = event.parsed if not packet.parsed: log.warning("%i %i ignoring unparsed packet", dpid, inport) return if dpid not in self.arpTable: # New switch -- create an empty table self.arpTable[dpid] = {} for fake in self.fakeways: self.arpTable[dpid][IPAddr(fake)] = Entry( of.OFPP_NONE, dpid_to_mac(dpid)) if packet.type == ethernet.LLDP_TYPE: # Ignore LLDP packets return if isinstance(packet.next, ipv4): log.debug("%i %i IP %s => %s", dpid, inport, packet.next.srcip, packet.next.dstip) # Send any waiting packets... self._send_lost_buffers(dpid, packet.next.srcip, packet.src, inport) # Learn or update port/MAC info if packet.next.srcip in self.arpTable[dpid]: if self.arpTable[dpid][packet.next.srcip] != (inport, packet.src): log.info("%i %i RE-learned %s", dpid, inport, packet.next.srcip) if self.wide: # Make sure we don't have any entries with the old info... msg = of.ofp_flow_mod(command=of.OFPFC_DELETE) msg.match.nw_dst = packet.next.srcip msg.match.dl_type = ethernet.IP_TYPE event.connection.send(msg) else: log.debug("%i %i learned %s", dpid, inport, packet.next.srcip) self.arpTable[dpid][packet.next.srcip] = Entry(inport, packet.src) # Try to forward dstaddr = packet.next.dstip if dstaddr in self.arpTable[dpid]: # We have info about what port to send it out on... prt = self.arpTable[dpid][dstaddr].port mac = self.arpTable[dpid][dstaddr].mac if prt == inport: log.warning( "%i %i not sending packet for %s back out of the " "input port" % (dpid, inport, dstaddr)) else: log.debug( "%i %i installing flow for %s => %s out port %i" % (dpid, inport, packet.next.srcip, dstaddr, prt)) actions = [] actions.append(of.ofp_action_dl_addr.set_dst(mac)) actions.append(of.ofp_action_output(port=prt)) if self.wide: match = of.ofp_match(dl_type=packet.type, nw_dst=dstaddr) else: match = of.ofp_match.from_packet(packet, inport) msg = of.ofp_flow_mod(command=of.OFPFC_ADD, idle_timeout=FLOW_IDLE_TIMEOUT, hard_timeout=of.OFP_FLOW_PERMANENT, buffer_id=event.ofp.buffer_id, actions=actions, match=match) event.connection.send(msg.pack()) elif self.arp_for_unknowns: # We don't know this destination. # First, we track this buffer so that we can try to resend it later # if we learn the destination, second we ARP for the destination, # which should ultimately result in it responding and us learning # where it is # Add to tracked buffers if (dpid, dstaddr) not in self.lost_buffers: self.lost_buffers[(dpid, dstaddr)] = [] bucket = self.lost_buffers[(dpid, dstaddr)] entry = (time.time() + MAX_BUFFER_TIME, event.ofp.buffer_id, inport) bucket.append(entry) while len(bucket) > MAX_BUFFERED_PER_IP: del bucket[0] # Expire things from our outstanding ARP list... self.outstanding_arps = { k: v for k, v in self.outstanding_arps.iteritems() if v > time.time() } # Check if we've already ARPed recently if (dpid, dstaddr) in self.outstanding_arps: # Oop, we've already done this one recently. return # And ARP... self.outstanding_arps[(dpid, dstaddr)] = time.time() + 4 r = arp() r.hwtype = r.HW_TYPE_ETHERNET r.prototype = r.PROTO_TYPE_IP r.hwlen = 6 r.protolen = r.protolen r.opcode = r.REQUEST r.hwdst = ETHER_BROADCAST r.protodst = dstaddr r.hwsrc = packet.src r.protosrc = packet.next.srcip e = ethernet(type=ethernet.ARP_TYPE, src=packet.src, dst=ETHER_BROADCAST) e.set_payload(r) log.debug("%i %i ARPing for %s on behalf of %s" % (dpid, inport, r.protodst, r.protosrc)) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) msg.in_port = inport event.connection.send(msg) elif isinstance(packet.next, arp): a = packet.next log.debug("%i %i ARP %s %s => %s", dpid, inport, { arp.REQUEST: "request", arp.REPLY: "reply" }.get(a.opcode, 'op:%i' % (a.opcode, )), a.protosrc, a.protodst) if a.prototype == arp.PROTO_TYPE_IP: if a.hwtype == arp.HW_TYPE_ETHERNET: if a.protosrc != 0: # Learn or update port/MAC info if a.protosrc in self.arpTable[dpid]: if self.arpTable[dpid][a.protosrc] != (inport, packet.src): log.info("%i %i RE-learned %s", dpid, inport, a.protosrc) if self.wide: # Make sure we don't have any entries with the old info... msg = of.ofp_flow_mod( command=of.OFPFC_DELETE) msg.match.dl_type = ethernet.IP_TYPE msg.match.nw_dst = a.protosrc event.connection.send(msg) else: log.debug("%i %i learned %s", dpid, inport, a.protosrc) self.arpTable[dpid][a.protosrc] = Entry( inport, packet.src) # Send any waiting packets... self._send_lost_buffers(dpid, a.protosrc, packet.src, inport) if a.opcode == arp.REQUEST: # Maybe we can answer if a.protodst in self.arpTable[dpid]: # We have an answer... if not self.arpTable[dpid][ a.protodst].isExpired(): # .. and it's relatively current, so we'll reply ourselves r = arp() r.hwtype = a.hwtype r.prototype = a.prototype r.hwlen = a.hwlen r.protolen = a.protolen r.opcode = arp.REPLY r.hwdst = a.hwsrc r.protodst = a.protosrc r.protosrc = a.protodst r.hwsrc = self.arpTable[dpid][ a.protodst].mac e = ethernet(type=packet.type, src=dpid_to_mac(dpid), dst=a.hwsrc) e.set_payload(r) log.debug("%i %i answering ARP for %s" % (dpid, inport, r.protosrc)) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append( of.ofp_action_output( port=of.OFPP_IN_PORT)) msg.in_port = inport event.connection.send(msg) return # Didn't know how to answer or otherwise handle this ARP, so just flood it log.debug("%i %i flooding ARP %s %s => %s" % (dpid, inport, { arp.REQUEST: "request", arp.REPLY: "reply" }.get(a.opcode, 'op:%i' % (a.opcode, )), a.protosrc, a.protodst)) msg = of.ofp_packet_out( in_port=inport, data=event.ofp, action=of.ofp_action_output(port=of.OFPP_FLOOD)) event.connection.send(msg)
def reply_request(self, success, request_id, event, title_aggr=None, w=None): # Build the response resp_msg = dts_pb2.ControlResponse() resp_msg.status = resp_msg.SUCCESS if success else resp_msg.FAILURE if request_id != None: resp_msg.request_id = request_id if self.aggr and w: # reply for the second workspace attachment print 'title_aggr', title_aggr, 'flow', self.flow # Send FLOW_MOD to the swith that is ataching an entity title = w.title if title_aggr in workspaces_aggr: w2 = workspaces_aggr[title_aggr] else: log.info('Unknown aggregated workspace title') title_hash = hashlib.sha256(title).digest()[:12] title_hash_aggr = hashlib.sha256(title_aggr).digest()[:12] recvRule = of.ofp_flow_mod() recvRule.command = of.OFPFC_MODIFY_STRICT #recvRule.match.dl_type = 0x0880 # Causes conflicts with user-space switches recvRule.match.dl_dst = title_hash_aggr[:6] recvRule.match.dl_src = title_hash_aggr[6:] recvRule.match.dl_vlan = self.flow recvRule.actions.append( of.ofp_action_dl_addr.set_dst(title_hash[:6])) recvRule.actions.append( of.ofp_action_dl_addr.set_src(title_hash[6:])) recvRule.actions.append( of.ofp_action_enqueue(port=event.port, queue_id=1)) core.openflow.sendToDPID(event.dpid, recvRule) try: s = w.switches[event.dpid] except KeyError: s = w.WPSwitch(event.dpid) w.switches[s.dpid] = s if event.dpid == w2.path[-1]: s.used_ports.add( graph[w2.path[-1]][w2.path[w2.path.index(w2.path[-1]) - 1]]['ports'][w2.path[-1]]) else: s.used_ports.add( graph[w2.path[0]][w2.path[w2.path.index(w2.path[0]) + 1]]['ports'][w2.path[0]]) sendRule = of.ofp_flow_mod() sendRule.command = of.OFPFC_MODIFY_STRICT #sendRule.match.dl_type = 0x0880 # Causes conflicts with user-space switches sendRule.match.dl_dst = title_hash[:6] sendRule.match.dl_src = title_hash[6:] sendRule.actions.append( of.ofp_action_dl_addr.set_dst(title_hash_aggr[:6])) sendRule.actions.append( of.ofp_action_dl_addr.set_src(title_hash_aggr[6:])) sendRule.actions.append(of.ofp_action_vlan_vid(vlan_vid=self.flow)) for p in s.used_ports: sendRule.actions.append( of.ofp_action_enqueue(port=p, queue_id=1)) core.openflow.sendToDPID(event.dpid, sendRule) # Send FLOW_MOD to the switch that created the workspace switch1 = wks[w.title] print 'OZUUUUUU1', switch1.dpid, switch1.port, try: s = w.switches[switch1.dpid] except KeyError: s = w.WPSwitch(switch1.dpid) w.switches[s.dpid] = s if switch1.dpid == w2.path[0]: s.used_ports.add( graph[w2.path[0]][w2.path[w2.path.index(w2.path[0]) + 1]]['ports'][w2.path[0]]) else: s.used_ports.add( graph[w2.path[-1]][w2.path[w2.path.index(w2.path[-1]) - 1]]['ports'][w2.path[-1]]) sendRule = of.ofp_flow_mod() sendRule.command = of.OFPFC_MODIFY_STRICT #sendRule.match.dl_type = 0x0880 # Causes conflicts with user-space switches sendRule.match.dl_dst = title_hash[:6] sendRule.match.dl_src = title_hash[6:] sendRule.actions.append( of.ofp_action_dl_addr.set_dst(title_hash_aggr[:6])) sendRule.actions.append( of.ofp_action_dl_addr.set_src(title_hash_aggr[6:])) sendRule.actions.append(of.ofp_action_vlan_vid(vlan_vid=self.flow)) for p in s.used_ports: sendRule.actions.append( of.ofp_action_enqueue(port=p, queue_id=1)) core.openflow.sendToDPID(switch1.dpid, sendRule) recvRule = of.ofp_flow_mod() recvRule.command = of.OFPFC_MODIFY_STRICT #recvRule.match.dl_type = 0x0880 # Causes conflicts with user-space switches recvRule.match.dl_dst = title_hash_aggr[:6] recvRule.match.dl_src = title_hash_aggr[6:] recvRule.match.dl_vlan = self.flow recvRule.actions.append( of.ofp_action_dl_addr.set_dst(title_hash[:6])) recvRule.actions.append( of.ofp_action_dl_addr.set_src(title_hash[6:])) recvRule.actions.append( of.ofp_action_enqueue(port=event.port, queue_id=1)) core.openflow.sendToDPID(switch1.dpid, recvRule) resp_msg = resp_msg.SerializeToString() # Send response back to the entity resp = of.ofp_packet_out() if not self.wifi: # not wifi resp.data = ''.join( (DTSA.HEADER, struct.pack("<H", len(resp_msg)), resp_msg)) else: resp.data = ''.join( (self.addrResp, struct.pack("<H", len(resp_msg)), resp_msg)) resp.actions.append(of.ofp_action_output(port=event.port)) event.connection.send(resp)
def _handle_PacketIn(self, event): dpid = event.connection.dpid inport = event.port packet = event.parsed if not packet.parsed: log.warning("%i %i ignoring unparsed packet", dpid, inport) return if dpid not in self.arpTable: # New switch -- create an empty table self.arpTable[dpid] = {} for fake in self.fakeways: self.arpTable[dpid][IPAddr(fake)] = Entry( of.OFPP_NONE, dpid_to_mac(dpid)) if dpid not in self.routing: # New switch -- create an empty table self.routing[dpid] = {} self.routing[dpid][IPAddr('10.0.%d.1' % (3 - dpid))] = 1 if packet.type == ethernet.LLDP_TYPE: # Ignore LLDP packets return if isinstance(packet.next, ipv4): log.debug("%i %i IP %s => %s", dpid, inport, packet.next.srcip, packet.next.dstip) # Send any waiting packets... self._send_lost_buffers(dpid, packet.next.srcip, packet.src, inport) # Learn or update port/MAC info if packet.next.srcip in self.arpTable[dpid]: if self.arpTable[dpid][packet.next.srcip] != (inport, packet.src): log.info("%i %i RE-learned %s", dpid, inport, packet.next.srcip) else: log.debug("%i %i learned %s ", dpid, inport, str(packet.next.srcip)) self.arpTable[dpid][packet.next.srcip] = Entry( inport, packet.src) if packet.next.srcip not in self.routing[dpid]: self.routing[dpid][packet.next.srcip] = inport dstaddr = packet.next.dstip srcaddr = packet.next.srcip n = str(dstaddr).split('.') l = str(srcaddr).split('.') if n[0] != '10': self.icmp_message(dpid, packet, packet.next.srcip, packet.next.dstip, pkt.TYPE_DEST_UNREACH, event) return if n[1] != '0': self.icmp_message(dpid, packet, packet.next.srcip, packet.next.dstip, pkt.TYPE_DEST_UNREACH, event) return if n[2] != '1' and n[2] != '2': self.icmp_message(dpid, packet, packet.next.srcip, packet.next.dstip, pkt.TYPE_DEST_UNREACH, event) return if n[2] == '1': if n[3] != '2' and n[3] != '3' and n[3] != '1': self.icmp_message(dpid, packet, packet.next.srcip, packet.next.dstip, pkt.TYPE_DEST_UNREACH, event) return if n[2] == '2': if n[3] != '2' and n[3] != '1': self.icmp_message(dpid, packet, packet.next.srcip, packet.next.dstip, pkt.TYPE_DEST_UNREACH, event) return # Try to forward if dstaddr in self.fakeways and int(n[2]) == dpid: if isinstance(packet.next.next, icmp): if packet.next.next.type == pkt.TYPE_ECHO_REQUEST: self.icmp_message(dpid, packet, packet.next.srcip, packet.next.dstip, pkt.TYPE_ECHO_REPLY, event) elif n[2] == l[2]: if dstaddr not in self.routing[ dpid] or dstaddr not in self.arpTable[dpid]: if (dpid, dstaddr) not in self.lost_buffers: self.lost_buffers[(dpid, dstaddr)] = [] bucket = self.lost_buffers[(dpid, dstaddr)] entry = (time.time() + MAX_BUFFER_TIME, event.ofp.buffer_id, inport) bucket.append(entry) while len(bucket) > MAX_BUFFERED_PER_IP: del bucket[0] # Expire things from our outstanding ARP list... self.outstanding_arps = { k: v for k, v in self.outstanding_arps.iteritems() if v > time.time() } # Check if we've already ARPed recently if (dpid, dstaddr) in self.outstanding_arps: # Oop, we've already done this one recently. return r = arp() r.hwtype = r.HW_TYPE_ETHERNET r.prototype = r.PROTO_TYPE_IP r.hwlen = 6 r.protolen = r.protolen r.opcode = r.REQUEST r.hwdst = ETHER_BROADCAST r.protodst = dstaddr r.hwsrc = packet.src r.protosrc = packet.next.srcip e = ethernet(type=ethernet.ARP_TYPE, src=packet.src, dst=ETHER_BROADCAST) e.set_payload(r) log.debug("%i %i ARPing for %s on behalf of %s" % (dpid, inport, str(r.protodst), str(r.protosrc))) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append( of.ofp_action_output(port=of.OFPP_FLOOD)) msg.in_port = inport event.connection.send(msg) if dstaddr in self.arpTable[dpid]: # We have info about what port to send it out on... prt = self.arpTable[dpid][dstaddr].port mac = self.arpTable[dpid][dstaddr].mac log.debug( "%i %i installing flow for %s => %s out port %i" % (dpid, inport, packet.next.srcip, dstaddr, prt)) actions = [] actions.append(of.ofp_action_dl_addr.set_dst(mac)) actions.append(of.ofp_action_output(port=prt)) match = of.ofp_match.from_packet(packet, inport) match.dl_src = None # Wildcard source MAC msg = of.ofp_flow_mod(command=of.OFPFC_ADD, idle_timeout=FLOW_IDLE_TIMEOUT, hard_timeout=of.OFP_FLOW_PERMANENT, buffer_id=event.ofp.buffer_id, actions=actions, match=of.ofp_match.from_packet( packet, inport)) event.connection.send(msg.pack()) else: if dstaddr in self.arpTable[dpid]: n_addr = IPAddr('10.0.%d.1' % (3 - dpid)) mac = self.arpTable[dpid][dstaddr].mac prt = self.routing[dpid][dstaddr] actions = [] actions.append(of.ofp_action_dl_addr.set_dst(mac)) actions.append(of.ofp_action_output(port=prt)) match = of.ofp_match.from_packet(packet, inport) match.dl_src = None # Wildcard source MAC msg = of.ofp_flow_mod(command=of.OFPFC_ADD, idle_timeout=FLOW_IDLE_TIMEOUT, hard_timeout=of.OFP_FLOW_PERMANENT, buffer_id=event.ofp.buffer_id, actions=actions, match=of.ofp_match.from_packet( packet, inport)) event.connection.send(msg.pack()) elif self.arp_for_unknowns: if dstaddr not in self.routing[ dpid] or dstaddr not in self.arpTable[dpid]: if (dpid, dstaddr) not in self.lost_buffers: self.lost_buffers[(dpid, dstaddr)] = [] bucket = self.lost_buffers[(dpid, dstaddr)] entry = (time.time() + MAX_BUFFER_TIME, event.ofp.buffer_id, inport) bucket.append(entry) while len(bucket) > MAX_BUFFERED_PER_IP: del bucket[0] # Expire things from our outstanding ARP list... self.outstanding_arps = { k: v for k, v in self.outstanding_arps.iteritems() if v > time.time() } # Check if we've already ARPed recently if (dpid, dstaddr) in self.outstanding_arps: # Oop, we've already done this one recently. return r = arp() r.hwtype = r.HW_TYPE_ETHERNET r.prototype = r.PROTO_TYPE_IP r.hwlen = 6 r.protolen = r.protolen r.opcode = r.REQUEST r.hwdst = ETHER_BROADCAST r.protodst = dstaddr r.hwsrc = packet.src r.protosrc = packet.next.srcip e = ethernet(type=ethernet.ARP_TYPE, src=packet.src, dst=ETHER_BROADCAST) e.set_payload(r) log.debug( "%i %i ARPing for %s on behalf of %s" % (dpid, inport, str(r.protodst), str(r.protosrc))) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append( of.ofp_action_output(port=of.OFPP_FLOOD)) msg.in_port = inport event.connection.send(msg) elif isinstance(packet.next, arp): a = packet.next n = str(packet.next.protodst).split('.') l = str(packet.next.protosrc).split('.') flag = 0 if a.prototype == arp.PROTO_TYPE_IP: if a.hwtype == arp.HW_TYPE_ETHERNET: if a.protosrc != 0: # Learn or update port/MAC info if a.protosrc in self.arpTable[dpid]: if self.arpTable[dpid][a.protosrc] != (inport, packet.src): log.info("%i %i RE-learned %s", dpid, inport, str(a.protosrc)) else: log.debug("%i %i learned %s", dpid, inport, str(a.protosrc)) self.arpTable[dpid][a.protosrc] = Entry( inport, packet.src) if packet.next.protosrc not in self.routing[dpid]: self.routing[dpid][packet.next.protosrc] = inport # Send any waiting packets.. self._send_lost_buffers(dpid, a.protosrc, packet.src, inport) if a.opcode == arp.REQUEST: # Maybe we can answer if a.protodst in self.arpTable[dpid]: # We have an answer... if self.arpTable[dpid][ a.protodst] or self.fakeways: # .. and it's relatively current, so we'll reply ourselves r = arp() r.hwtype = a.hwtype r.prototype = a.prototype r.hwlen = a.hwlen r.protolen = a.protolen r.opcode = arp.REPLY r.hwdst = a.hwsrc r.protodst = a.protosrc r.protosrc = a.protodst r.hwsrc = self.arpTable[dpid][ a.protodst].mac e = ethernet(type=packet.type, src=dpid_to_mac(dpid), dst=a.hwsrc) e.set_payload(r) log.debug("%i %i answering ARP for %s" % (dpid, inport, str(r.protosrc))) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append( of.ofp_action_output( port=of.OFPP_IN_PORT)) msg.in_port = inport event.connection.send(msg) return else: n_addr = IPAddr('10.0.%d.1' % (3 - dpid)) mac = self.arpTable[dpid][n_addr].mac r = arp() r.hwtype = a.hwtype r.prototype = a.prototype r.hwlen = a.hwlen r.protolen = a.protolen r.opcode = arp.REPLY r.hwdst = mac r.protodst = a.protosrc r.protosrc = a.protodst r.hwsrc = self.arpTable[dpid][ a.protodst].mac e = ethernet(type=packet.type, src=dpid_to_mac(dpid), dst=a.hwdst) e.set_payload(r) log.debug("%i %i answering ARP for %s" % (dpid, inport, str(r.protosrc))) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append( of.ofp_action_output(port=1)) msg.in_port = inport event.connection.send(msg) return elif a.opcode == arp.REPLY and a.protodst != IPAddr( '10.0.%d.1' % (dpid)): if a.protodst in self.routing[ dpid] and n[2] != l[2] and inport != 1: flag = 1 msg = of.ofp_packet_out() msg.data = event.ofp action = of.ofp_action_output(port=1) msg.actions.append(action) event.connection.send(msg) else: flag = 1 msg = of.ofp_packet_out( in_port=inport, data=event.ofp, action=of.ofp_action_output( port=of.OFPP_FLOOD)) event.connection.send(msg) if flag == 0: # Didn't know how to answer or otherwise handle this ARP, so just flood it log.debug( "%i %i flooding ARP %s %s => %s" % (dpid, inport, { arp.REQUEST: "request", arp.REPLY: "reply" }.get(a.opcode, 'op:%i' % (a.opcode, )), str(a.protosrc), str(a.protodst))) msg = of.ofp_packet_out( in_port=inport, data=event.ofp, action=of.ofp_action_output(port=of.OFPP_FLOOD)) event.connection.send(msg)
def _handle_openflow_PacketIn (self, event): dpid = event.connection.dpid inport = event.port packet = event.parsed if not packet.parsed: log.warning("S: %d P: %d - Ignorando pacote mal-formado", dpid, inport) return # Switch nao esta na tabela. Aloca Espaco. if dpid not in self.arpTable: self.arpTable[dpid] = {} #Ignora pacotes nivel 2 - LLDP if packet.type == ethernet.LLDP_TYPE: return # Pacotes IPv4 if isinstance(packet.next, ipv4): log.debug("S: %i P: %i - IP %s => %s", dpid,inport,packet.next.srcip,packet.next.dstip) if inport!= 4: self.arpTable[dpid][packet.next.srcip] = Entry(inport, packet.src) log.debug("DPID: %d %s ------ Gate %s",dpid, TRIGGER, self.gateways) # SE chegar tarefa no switch if dpid in self.gateways and TRIGGER == True: log.warning("Trafego chegando em S %d", dpid) # Portas externas do gateway -> 2 e 3 if inport == 2 or inport == 3: log.debug("Trafego chegando em S:%d P: %d", dpid, inport) actions = [] if dpid == 1: actions.append(of.ofp_action_dl_addr.set_dst("00:00:00:00:00:11")) if dpid == 2: actions.append(of.ofp_action_dl_addr.set_dst("00:00:00:00:00:12")) actions.append(of.ofp_action_output(port = 4)) match = of.ofp_match.from_packet(packet, inport) msg = of.ofp_flow_mod(command=of.OFPFC_ADD, #idle_timeout=FLOW_IDLE_TIMEOUT, #hard_timeout=of.OFP_FLOW_PERMANENT, buffer_id=event.ofp.buffer_id, actions=actions, match=match) event.connection.send(msg.pack()) # Portas do filtro do gateway -> 4 elif inport == 4: log.debug("Trafego chegando em S: %d P: %d",dpid,inport) prt = 1 mac = "00:00:00:00:00:02" actions = [] actions.append(of.ofp_action_dl_addr.set_dst(mac)) actions.append(of.ofp_action_output(port = prt)) match = of.ofp_match.from_packet(packet, inport) msg = of.ofp_flow_mod(command=of.OFPFC_ADD, #idle_timeout=FLOW_IDLE_TIMEOUT, #hard_timeout=of.OFP_FLOW_PERMANENT, buffer_id=event.ofp.buffer_id, actions=actions, match=match) event.connection.send(msg.pack()) # Porta interna do Gateway -> 1 elif inport == 1: dstaddr = packet.next.dstip prt = self.arpTable[dpid][dstaddr].port mac = self.arpTable[dpid][dstaddr].mac log.debug("Trafego chegando em S:%d P: %d para ou %d ", dpid, inport, prt) actions = [] actions.append(of.ofp_action_dl_addr.set_dst(mac)) actions.append(of.ofp_action_output(port = prt)) match = of.ofp_match.from_packet(packet, inport) msg = of.ofp_flow_mod(command=of.OFPFC_ADD, #idle_timeout=FLOW_IDLE_TIMEOUT, #hard_timeout=of.OFP_FLOW_PERMANENT, buffer_id=event.ofp.buffer_id, actions=actions, match=match) event.connection.send(msg.pack()) else: dstaddr = packet.next.dstip # Sei pra que porta vai mandar. if dstaddr in self.arpTable[dpid]: prt = self.arpTable[dpid][dstaddr].port mac = self.arpTable[dpid][dstaddr].mac if prt == inport: log.warning("S: %i P: %i - Porta de entrada e a mesma de saida - %s" % (dpid, inport,str(dstaddr))) else: log.debug("S: %i P: %i - Instalando Flow para %s => %s out porta %i" % (dpid, inport, packet.next.srcip, dstaddr, prt)) actions = [] actions.append(of.ofp_action_dl_addr.set_dst(mac)) actions.append(of.ofp_action_output(port = prt)) match = of.ofp_match.from_packet(packet, inport) msg = of.ofp_flow_mod(command=of.OFPFC_ADD, #idle_timeout=FLOW_IDLE_TIMEOUT, #hard_timeout=of.OFP_FLOW_PERMANENT, buffer_id=event.ofp.buffer_id, actions=actions, match=match) event.connection.send(msg.pack()) # Pacotes ARP elif isinstance(packet.next, arp): a = packet.next log.debug("S: %i P: %i - ARP %s %s => %s", dpid, inport, {arp.REQUEST:"request",arp.REPLY:"reply"}.get(a.opcode, 'op:%i' % (a.opcode,)), a.protosrc, a.protodst) self.arpTable[dpid][a.protosrc] = Entry(inport, packet.src) if a.prototype == arp.PROTO_TYPE_IP: if a.hwtype == arp.HW_TYPE_ETHERNET: if a.protosrc != 0: if a.opcode == arp.REQUEST: # Maybe we can answer if a.protodst in self.arpTable[dpid]: # Tem Resposta local r = arp() r.hwtype = a.hwtype r.prototype = a.prototype r.hwlen = a.hwlen r.protolen = a.protolen r.opcode = arp.REPLY r.hwdst = a.hwsrc r.protodst = a.protosrc r.protosrc = a.protodst r.hwsrc = self.arpTable[dpid][a.protodst].mac e = ethernet(type=packet.type, src=dpid_to_mac(dpid), dst=a.hwsrc) e.set_payload(r) log.debug("%i %i answering ARP for %s" % (dpid, inport, r.protosrc)) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT)) msg.in_port = inport event.connection.send(msg) return # Nao sabe ent'ao inunda log.debug("%i %i flooding ARP %s %s => %s" % (dpid, inport, {arp.REQUEST:"request",arp.REPLY:"reply"}.get(a.opcode, 'op:%i' % (a.opcode,)), a.protosrc, a.protodst)) msg = of.ofp_packet_out(in_port = inport, data = event.ofp, action = of.ofp_action_output(port = of.OFPP_FLOOD)) event.connection.send(msg)
def floodPacket(self, event): message = of.ofp_packet_out() message.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) message.data = event.data message.in_port = event.port return message
def send_packet_bufid(self, outport, buffer_id=-1): msg = of.ofp_packet_out(in_port=of.OFPP_NONE) msg.actions.append(of.ofp_action_output(port=outport)) msg.buffer_id = buffer_id self.connection.send(msg)
def _handle_PacketIn(event): global updated, G, Forest packet = event.parsed if not updated: cal_SPT() #update_SPT() #update_Table() updated = True print( " 0000 000 000 00", event.connection) print( " 0000 000 000 dpid 00", event.dpid) ''' table[(event.connection,packet.src)] = event.port print (" ------------------- distnation ", packet.dst.toStr(), type(event), type(packet)) sw_host[packet.src.toStr()] = (event.dpid, event.port) print (" ************** *") print (" ************** *") print (" ************** *") print (" * * ",packet.src.toStr(), (event.dpid, event.port) ) print (" ************** *") print (" ************** *") print (" ************** *") ''' print( " ------------------- distnation ", event.connection) if packet.dst.toStr() in sw_host.keys( ) and packet.dst.toStr() <> 'ff:ff:ff:ff:ff:ff': print( " packet.dst.toStr() ******************* ************* *", packet.dst.toStr()) targetSW_PT = sw_host[packet.dst.toStr()] target_port = targetSW_PT[1] target_sw = targetSW_PT[0] #print "-------------- TTTTTTTTTTTTTTTTTTT TTT ",type(pt) pt = Forest[event.dpid - 1].treeList[target_sw - 1].port print "-------------- TTTTTTTTTTTTTTTTTTT TTT ", pt, type( pt) if not pt: pt = target_port msg = of.ofp_flow_mod() msg.match.dl_dst = packet.src msg.match.dl_src = packet.dst msg.actions.append(of.ofp_action_output(port=pt)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.data = event.ofp # Forward the incoming packet msg.match.dl_src = packet.src msg.match.dl_dst = packet.dst msg.actions.append(of.ofp_action_output(port=pt)) event.connection.send(msg) print "-------------- TTTTTTTTTTTTTTTTTTT pt, dst TTT ", pt, packet.dst print( " 000000000000000000000000000000000000000000000000000000000000000 " ) print( " 000000000000000000000000000000000000000000000000000000000000000 ", event.dpid, pt) print( " 000000000000000000000000000000000000000000000000000000000000000 " ) #end #print(" packet.dst.toStr() ***********************************", packet.dst.toStr(), packet.dst, type( packet.dst)) # Learn the source else: #if True: print "************* 00 ************************ SKIP *" table[(event.connection, packet.src)] = event.port dst_port = table.get((event.connection, packet.dst)) print "************* 00 ************************ SKIP *", type( dst_port) if dst_port is None: # We don't know where the destination is yet. So, we'll just # send the packet out all ports (except the one it came in on!) # and hope the destination is out there somewhere. :) msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=all_ports)) event.connection.send(msg) else: # Since we know the switch ports for both the source and dest # MACs, we can install rules for both directions. msg = of.ofp_flow_mod() msg.match.dl_dst = packet.src msg.match.dl_src = packet.dst msg.actions.append(of.ofp_action_output(port=event.port)) event.connection.send(msg) # This is the packet that just came in -- we want to # install the rule and also resend the packet. msg = of.ofp_flow_mod() msg.data = event.ofp # Forward the incoming packet msg.match.dl_src = packet.src msg.match.dl_dst = packet.dst msg.actions.append(of.ofp_action_output(port=dst_port)) event.connection.send(msg) log.debug("Installing %s <-> %s" % (packet.src, packet.dst))
def _handle_PacketIn(self, event): ''' Callback function that receives packet_in events and responds to them. Packet in events are sent from the device and carry a data packet that the device does not know what to do with ''' # Extract the data packet from the packet in event data = event.parsed # Update the MAC table. The MAC address that is the source of # the frame is served from the port where this packet originated # We should store (or update) this relation self.mac_table[data.src] = event.port # We extract the destination MAC address from the data dst = data.dst if dst.is_multicast: # If the destination MAC is a multicast address, send the # frame out of all ports, like a hub log.info("Received multicast from %s" % (self.connection, )) # Create a new flow_mod message msg = of.ofp_flow_mod() # Set the hard and idle timeouts to sane values msg.idle_timeout = IDLE_TIMOUT msg.hard_timeout = HARD_TIMEOUT # Match the destination mac address that triggered this packet_in event msg.match = of.ofp_match(dl_dst=dst) # Flood the packet to all ports (but the incoming) msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) # Set the buffer of the message that triggered the packet in event # This way that message will be treated by the new flow and will # not be lost msg.buffer_id = event.ofp.buffer_id # Send the message to the switch self.connection.send(msg) else: if dst in self.mac_table: # If the destination MAC address exists in the MAC table # we will send the packet out from the port the MAC # table has stored, unless it is the same as the # incoming port if event.port == self.mac_table[dst]: # If the source port is the same as the destination # port do nothing (efectively drop the packet) pass else: # If the source port is different than the destinationport # create a new flow matching the port-mac_src-mac_dst and # push it to the device log.info( "Received unicast from %s with known destination %s" % (self.connection, dst)) # Create a new flow_mod message msg = of.ofp_flow_mod() # Match the destination MAC address with the one received in the message carried by the packet_in msg.match = of.ofp_match(dl_dst=data.dst) # Set timeouts to sane values msg.idle_timeout = IDLE_TIMOUT msg.hard_timeout = HARD_TIMEOUT # Send this message to the port indicated by the MAC table msg.actions.append( of.ofp_action_output(port=self.mac_table[dst])) # Set the buffer of the message that triggered the packet in event # This way that message will be treated by the new flow and will # not be lost msg.buffer_id = event.ofp.buffer_id # Send the message to the switch self.connection.send(msg) else: # If the destination MAC address is not in the MAC table # Flood the message to all ports excpet the incoming one # Hopefully the destination will answer and eventually his # port will become known log.info( "Received unicast from %s with uknown destination %s" % (self.connection, dst)) # Create a new packet_out message msg = of.ofp_packet_out() # Indicate the port this packet came from msg.in_port = event.port # Set the action to flood the packet msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) # Set the data to flood msg.data = event.ofp # Send the message to the switch self.connection.send(msg)
def f_send_arp_openflow_flood(self): msg = of.ofp_packet_out() msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) msg.data = self.packet_event.ofp self.packet_event.connection.send(msg.pack())
def send_packet_data(self, outport, data=None): msg = of.ofp_packet_out(in_port=of.OFPP_NONE, data=data) msg.actions.append(of.ofp_action_output(port=outport)) self.connection.send(msg)
def _handle_PacketIn(self, event): def forward(port): """Tell the switch to drop the packet""" msg = of.ofp_packet_out() msg.actions.append(of.ofp_action_output(port=port)) if event.ofp.buffer_id is not None: msg.buffer_id = event.ofp.buffer_id else: msg.data = event.ofp.data msg.in_port = event.port self.connection.send(msg) def flood(): """Tell all switches to flood the packet, remember that we disable inter-switch flooding at startup""" #forward(of.OFPP_FLOOD) for (dpid, switch) in switches.iteritems(): msg = of.ofp_packet_out() if switch == self: if event.ofp.buffer_id is not None: msg.buffer_id = event.ofp.buffer_id else: msg.data = event.ofp.data msg.in_port = event.port else: msg.data = event.ofp.data ports = [ p for p in switch.connection.ports if (dpid, p) not in switch_ports ] if len(ports) > 0: for p in ports: msg.actions.append(of.ofp_action_output(port=p)) switches[dpid].connection.send(msg) def drop(): """Tell the switch to drop the packet""" if event.ofp.buffer_id is not None: #nothing to drop because the packet is not in the Switch buffer msg = of.ofp_packet_out() msg.buffer_id = event.ofp.buffer_id event.ofp.buffer_id = None # Mark as dead, copied from James McCauley, not sure what it does but it does not work otherwise msg.in_port = event.port self.connection.send(msg) log.debug("Received PacketIn") packet = event.parsed SwitchPort = namedtuple('SwitchPoint', 'dpid port') if ( event.dpid, event.port ) not in switch_ports: # only relearn locations if they arrived from non-interswitch links mac_learning[packet.src] = SwitchPort( event.dpid, event.port) #relearn the location of the mac-address if packet.effective_ethertype == packet.LLDP_TYPE: drop() log.debug("Switch %s dropped LLDP packet", self) elif packet.dst.is_multicast: flood() log.debug("Switch %s flooded multicast 0x%0.4X type packet", self, packet.effective_ethertype) elif packet.dst not in mac_learning: flood( ) #Let's first learn the location of the recipient before generating and installing any rules for this. We might flood this but that leads to further complications if half way the flood through the network the path has been learned. log.debug( "Switch %s flooded unicast 0x%0.4X type packet, due to unlearned MAC address", self, packet.effective_ethertype) elif packet.effective_ethertype == packet.ARP_TYPE: #These packets are sent so not-often that they don't deserve a flow #Instead of flooding them, we drop it at the current switch and have it resend by the switch to which the recipient is connected. #flood() drop() dst = mac_learning[packet.dst] msg = of.ofp_packet_out() msg.data = event.ofp.data msg.actions.append(of.ofp_action_output(port=dst.port)) switches[dst.dpid].connection.send(msg) log.debug( "Switch %s processed unicast ARP (0x0806) packet, send to recipient by switch %s", self, util.dpid_to_str(dst.dpid)) else: log.debug( "Switch %s received PacketIn of type 0x%0.4X, received from %s.%s", self, packet.effective_ethertype, util.dpid_to_str(event.dpid), event.port) dst = mac_learning[packet.dst] prev_path = _get_path(self.connection.dpid, dst.dpid) if prev_path is None: flood() return log.debug("Path from %s to %s over path %s", packet.src, packet.dst, prev_path) if self.l3_matching == True: #only match on l2-properties, useful when doing experiments with UDP streams as you can insert a flow using ping and then start sending udp. match = ofp_match_withHash() match.dl_src = packet.src match.dl_dst = packet.dst match.dl_type = packet.type p = packet.next if isinstance(p, vlan): match.dl_type = p.eth_type match.dl_vlan = p.id match.dl_vlan_pcp = p.pcp p = p.next if isinstance(p, ipv4): match.nw_src = p.srcip match.nw_dst = p.dstip match.nw_proto = p.protocol match.nw_tos = p.tos p = p.next else: match.dl_vlan = of.OFP_VLAN_NONE match.dl_vlan_pcp = 0 else: match = ofp_match_withHash.from_packet(packet) _install_path(prev_path, match) #forward the packet directly from the last switch, there is no need to have the packet run through the complete network. drop() dst = mac_learning[packet.dst] msg = of.ofp_packet_out() msg.data = event.ofp.data msg.actions.append(of.ofp_action_output(port=dst.port)) switches[dst.dpid].connection.send(msg) self.raiseEvent(NewFlow(prev_path, match, adj)) log.debug( "Switch %s processed unicast 0x%0.4x type packet, send to recipient by switch %s", self, packet.effective_ethertype, util.dpid_to_str(dst.dpid))
def _handle_PacketIn(event): """ PacketIn message is sent by the switch when its flow table contains no rule to route an incoming packet. core.openflow.miss_send_len controls the max number of Bytes to be sent to the Controller in each PacketIn payload default payload size is 128 B pox matching conventions: dt_xxx = datalink (MAC) nw_xxx = network (IP) tp_xxx = transmission port (TCP) xxx can be src and dst physical ports are specified by int while virtual port are specified by symbolic name (eg: of.OFPP_FLOOD) you can use event.ofp PacketIn payload as PacketOut payload """ event_info(event) ALL_PORTS = of.OFPP_FLOOD # 65531 # log.debug("OFPP_FLOOD: %r" % ALL_PORTS) # parsed contains the openflow payload that usually is # the first part of the packet sent from host to s3 packet = event.parsed # table is indexed by a tuple (connection, mac_address) src_key = (event.connection, packet.src) table[src_key] = event.port # log.debug("controller add new table entry: %r: %r" % ( # src_key, table[src_key])) # built key given the MAC destination # and search the table for destination port dst_key = (event.connection, packet.dst) dst_port = table.get(dst_key) # tell the switch to flood -> send a packet_out pkt if dst_port is None: packet_out = of.ofp_packet_out() packet_out.data = event.ofp # reuse PacketIn payload as PacketOut payload # create a flood action action = of.ofp_action_output(port=ALL_PORTS) packet_out.actions.append(action) # send the packet_out event.connection.send(packet_out) # tell the switch two new rules -> send two flow_mod pkts else: flow_mod = of.ofp_flow_mod() # flow_mod contains a match object that can be used to send # rules to the switch flow_mod.match.dl_src = packet.dst # if packet comes from destination MAC flow_mod.match.dl_dst = packet.src # if packet destination is source MAC # define an action object to be appended to the actions list # the action tell the switch to use event.port as output port # event.port was the port on which the switch received the packet # that generates the PackeIn action = of.ofp_action_output( port=event.port) # then forward packet to event.port # flow mod contains a actions list that can be used # to tell the switch what it shuld do in case of # the rule is matched flow_mod.actions.append(action) event.connection.send(flow_mod) flow_mod = of.ofp_flow_mod() flow_mod.match.dl_src = packet.src # if pacekt comes from source MAC flow_mod.match.dl_dst = packet.dst # if pacekt destination is destination MAC action = of.ofp_action_output( port=dst_port) # then forward packet to dst_port flow_mod.actions.append(action) event.connection.send(flow_mod) log.info("Sent to switch rules for %s <-> %s" % (packet.src, packet.dst))
def _handle_PacketIn(self, event): dpid = event.connection.dpid inport = event.port packet = event.parse() if not packet.parsed: log.warning("%i %i ignoring unparsed packet", dpid, inport) return if dpid not in self.arpTable: # New switch -- create an empty table self.arpTable[dpid] = {} if packet.type == ethernet.LLDP_TYPE: # Ignore LLDP packets return if isinstance(packet.next, ipv4): log.debug("%i %i IP %s => %s", dpid, inport, str(packet.next.srcip), str(packet.next.dstip)) # Learn or update port/MAC info if packet.next.srcip in self.arpTable[dpid]: if self.arpTable[dpid][packet.next.srcip] != (inport, packet.src): log.info("%i %i RE-learned %s", dpid, inport, str(packet.next.srcip)) else: log.debug("%i %i learned %s", dpid, inport, str(packet.next.srcip)) self.arpTable[dpid][packet.next.srcip] = Entry(inport, packet.src) # Try to forward dstaddr = packet.next.dstip if dstaddr in self.arpTable[dpid]: # We have info about what port to send it out on... prt = self.arpTable[dpid][dstaddr].port if prt == inport: log.warning( "%i %i not sending packet for %s back out of the input port" % (dpid, inport, str(dstaddr))) else: log.debug( "%i %i installing flow for %s => %s out port %i" % (dpid, inport, str( packet.next.srcip), str(dstaddr), prt)) msg = of.ofp_flow_mod( command=of.OFPFC_ADD, idle_timeout=FLOW_IDLE_TIMEOUT, hard_timeout=of.OFP_FLOW_PERMANENT, buffer_id=event.ofp.buffer_id, action=of.ofp_action_output(port=prt), match=of.ofp_match.from_packet(packet, inport)) event.connection.send(msg.pack()) elif isinstance(packet.next, arp): a = packet.next log.debug("%i %i ARP %s %s => %s", dpid, inport, { arp.REQUEST: "request", arp.REPLY: "reply" }.get(a.opcode, 'op:%i' % (a.opcode, )), str(a.protosrc), str(a.protodst)) if a.prototype == arp.PROTO_TYPE_IP: if a.hwtype == arp.HW_TYPE_ETHERNET: if a.protosrc != 0: # Learn or update port/MAC info if a.protosrc in self.arpTable[dpid]: if self.arpTable[dpid][a.protosrc] != (inport, packet.src): log.info("%i %i RE-learned %s", dpid, inport, str(a.protosrc)) else: log.debug("%i %i learned %s", dpid, inport, str(a.protosrc)) self.arpTable[dpid][a.protosrc] = Entry( inport, packet.src) if a.opcode == arp.REQUEST: # Maybe we can answer if a.protodst in self.arpTable[dpid]: # We have an answer... if not self.arpTable[dpid][ a.protodst].isExpired(): # .. and it's relatively current, so we'll reply ourselves r = arp() r.hwtype = a.hwtype r.prototype = a.prototype r.hwlen = a.hwlen r.protolen = a.protolen r.opcode = arp.REPLY r.hwdst = a.hwsrc r.protodst = a.protosrc r.protosrc = a.protodst r.hwsrc = self.arpTable[dpid][ a.protodst].mac e = ethernet(type=packet.type, src=r.hwsrc, dst=a.hwsrc) e.set_payload(r) log.debug("%i %i answering ARP for %s" % (dpid, inport, str(r.protosrc))) msg = of.ofp_packet_out( data=e.pack(), action=of.ofp_action_output( port=inport)) event.connection.send(msg.pack()) return # Didn't know how to answer or otherwise handle this ARP, so just flood it log.debug("%i %i flooding ARP %s %s => %s" % (dpid, inport, { arp.REQUEST: "request", arp.REPLY: "reply" }.get(a.opcode, 'op:%i' % (a.opcode, )), str(a.protosrc), str(a.protodst))) msg = of.ofp_packet_out( in_port=inport, action=of.ofp_action_output(port=of.OFPP_FLOOD)) if event.ofp.buffer_id is of.NO_BUFFER: # Try sending the (probably incomplete) raw data msg.data = packet.arr else: msg.buffer_id = event.ofp.buffer_id event.connection.send(msg.pack()) return
def f_send_arp_reply_pkt(self, arp_ether, outport): msg = of.ofp_packet_out(in_port=of.OFPP_NONE) msg.data = arp_ether.pack() msg.actions.append(of.ofp_action_output(port=outport)) #msg.buffer_id = <some buffer id, if any> self.connection.send(msg)
def drop(): if event.ofp.buffer_id is not None: # Kill the buffer msg = of.ofp_packet_out(data=event.ofp) self.con.send(msg) return None
def ifReach(dstip, event, self): dpid = self.connection.dpid for subRouteTable in self.routeTable: dstnetwork = subRouteTable[DST_Network] if dstip.inNetwork(dstnetwork): log.debug('------ip dst %s is in the routeTable-----' % dstip) nextPort = subRouteTable[NEXTHOP_PORT] log.debug('------ip dst port %s is in the routeTable-----' % nextPort) if nextPort == event.ofp.in_port: continue nextHopIp = IPAddr(subRouteTable[NETX_HOP_IP]) nextPortIp = IPAddr(subRouteTable[NEXT_PORT_IP]) srcMac = arpCache[dpid][nextPort][nextPortIp] if nextHopIp in arpCache[dpid][nextPort]: log.debug('------I know the next dst %s mac-----' % nextHopIp) nextHopMac = arpCache[dpid][nextPort][nextHopIp] msg = of.ofp_flow_mod() msg.match = of.ofp_match() msg.match.dl_type = ethernet.IP_TYPE msg.match.nw_dst = dstip msg.command = 0 msg.idle_timeout = 10 msg.hard_timeout = 30 msg.buffer_id = event.ofp.buffer_id msg.actions.append(of.ofp_action_dl_addr.set_src(srcMac)) msg.actions.append(of.ofp_action_dl_addr.set_dst(nextHopMac)) msg.actions.append(of.ofp_action_output(port=nextPort)) self.connection.send(msg) log.debug('-----install a flow-----') else: log.debug( '------I do not know the next dst %s mac,make an arp request-----' % IPAddr(subRouteTable[NETX_HOP_IP])) ARPrequest = arp() ARPrequest.opcode = arp.REQUEST ARPrequest.protosrc = nextPortIp ARPrequest.hwsrc = srcMac ARPrequest.protodst = nextHopIp arpPacket = ethernet(type=ethernet.ARP_TYPE, src=ARPrequest.hwsrc, dst=ETHER_BROADCAST) arpPacket.set_payload(ARPrequest) msg = of.ofp_packet_out() msg.data = arpPacket.pack() msg.actions.append(of.ofp_action_output(port=nextPort)) msg.in_port = event.ofp.in_port event.connection.send(msg) log.debug('------Arp request has been snet-----') nextHopMac = ETHER_BROADCAST msg = of.ofp_packet_out() msg.in_port = event.port msg.buffer_id = event.ofp.buffer_id msg.actions.append(of.ofp_action_dl_addr.set_src(srcMac)) msg.actions.append(of.ofp_action_dl_addr.set_dst(nextHopMac)) msg.actions.append(of.ofp_action_output(port=nextPort)) self.connection.send(msg) return True return False
def _handle_PacketIn(self, event): packet = event.parsed connection = event.connection if packet.type != 0x86DD: # IPV6 packet type pass if packet.type == packet.ARP_TYPE: arp_packet = packet.find('arp') if arp_packet is not None: if arp_packet.opcode == arp.REQUEST: arp_reply = arp() arp_reply.opcode = arp.REPLY arp_reply.hwsrc = EthAddr(self.arpTable[IPAddr( arp_packet.protodst)][0]) arp_reply.hwdst = arp_packet.hwsrc arp_reply.hwtype = arp.HW_TYPE_ETHERNET arp_reply.prototype = arp.PROTO_TYPE_IP arp_reply.hwlen = 6 arp_reply.protolen = 4 arp_reply.protosrc = arp_packet.protodst arp_reply.protodst = arp_packet.protosrc e = ethernet() e.set_payload(arp_reply) e.type = ethernet.ARP_TYPE e.src = EthAddr(self.arpTable[IPAddr( arp_packet.protodst)][0]) e.dst = arp_packet.hwsrc msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append(of.ofp_action_output(port=event.port)) connection.send(msg) if packet.type == packet.IP_TYPE: ip_packet = packet.payload ipsrc = ip_packet.srcip ipdst = ip_packet.dstip print 'Installing path for ' + str(ipsrc) + ' -> ' + str(ipdst) route = select_route( ipsrc, ipdst) # Chooses shortest route from the dictionary. for i in range(0, len(route) - 1): match1 = of.ofp_match() match1.nw_src = ipsrc match1.nw_dst = ipdst match1.dl_src = self.arpTable[IPAddr(ipsrc)][ 0] # MAC of source host. match1.dl_dst = self.arpTable[IPAddr(ipdst)][ 0] # MAC of destination host. fm = of.ofp_flow_mod() fm.match = match1 fm.hard_timeout = 30 fm.idle_timeout = 30 fm.actions.append(of.ofp_action_nw_addr.set_dst(ipdst)) outport = ports[(graph[str(route[i])]['id'], graph[str(route[i + 1])]['id'])][0] fm.actions.append(of.ofp_action_output(port=outport)) connections[graph[str(route[i])]['id']].send(fm)
def _handle_PacketIn(event): global s1_dpid, s2_dpid, s3_dpid, s4_dpid, s5_dpid, s6_dpid packet=event.parsed print "_handle_PacketIn is called, packet.type:", packet.type, " event.connection.dpid:", event.connection.dpid ################################### if event.connection.dpid==s1_dpid: a=packet.find('arp') if a and a.protodst=="10.0.0.1": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=1)) event.connection.send(msg) if a and a.protodst=="10.0.0.2": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=2)) event.connection.send(msg) if a and a.protodst=="10.0.0.6": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=3)) event.connection.send(msg) if a and a.protodst=="10.0.0.3": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=2)) event.connection.send(msg) if a and a.protodst=="10.0.0.4": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=2)) event.connection.send(msg) if a and a.protodst=="10.0.0.5": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=3)) event.connection.send(msg) #AddFlows s1 msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.1" msg.match.nw_dst = "10.0.0.2" msg.actions.append(of.ofp_action_output(port = 2)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.1" msg.match.nw_dst = "10.0.0.3" msg.actions.append(of.ofp_action_output(port = 2)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.1" msg.match.nw_dst = "10.0.0.4" msg.actions.append(of.ofp_action_output(port = 2)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.1" msg.match.nw_dst = "10.0.0.5" msg.actions.append(of.ofp_action_output(port = 3)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.1" msg.match.nw_dst = "10.0.0.6" msg.actions.append(of.ofp_action_output(port = 3)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.2" msg.match.nw_dst = "10.0.0.1" msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.2" msg.match.nw_dst = "10.0.0.6" msg.actions.append(of.ofp_action_output(port = 3)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.3" msg.match.nw_dst = "10.0.0.1" msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.3" msg.match.nw_dst = "10.0.0.6" msg.actions.append(of.ofp_action_output(port = 3)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.4" msg.match.nw_dst = "10.0.0.1" msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.5" msg.match.nw_dst = "10.0.0.1" msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.6" msg.match.nw_dst = "10.0.0.1" msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.6" msg.match.nw_dst = "10.0.0.2" msg.actions.append(of.ofp_action_output(port = 2)) event.connection.send(msg) #################################### if event.connection.dpid==s2_dpid: a=packet.find('arp') if a and a.protodst=="10.0.0.2": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=1)) event.connection.send(msg) if a and a.protodst=="10.0.0.1": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=2)) event.connection.send(msg) if a and a.protodst=="10.0.0.3": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=3)) event.connection.send(msg) if a and a.protodst=="10.0.0.5": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=4)) event.connection.send(msg) if a and a.protodst=="10.0.0.4": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=3)) event.connection.send(msg) if a and a.protodst=="10.0.0.6": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=2)) event.connection.send(msg) #Add flows s2 msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.1" msg.match.nw_dst = "10.0.0.2" msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.1" msg.match.nw_dst = "10.0.0.3" msg.actions.append(of.ofp_action_output(port = 3)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.1" msg.match.nw_dst = "10.0.0.4" msg.actions.append(of.ofp_action_output(port = 3)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.2" msg.match.nw_dst = "10.0.0.1" msg.actions.append(of.ofp_action_output(port = 2)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.2" msg.match.nw_dst = "10.0.0.3" msg.actions.append(of.ofp_action_output(port = 3)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.2" msg.match.nw_dst = "10.0.0.4" msg.actions.append(of.ofp_action_output(port = 3)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.2" msg.match.nw_dst = "10.0.0.5" msg.actions.append(of.ofp_action_output(port = 4)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.2" msg.match.nw_dst = "10.0.0.6" msg.actions.append(of.ofp_action_output(port = 2)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.3" msg.match.nw_dst = "10.0.0.1" msg.actions.append(of.ofp_action_output(port = 2)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.3" msg.match.nw_dst = "10.0.0.2" msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.3" msg.match.nw_dst = "10.0.0.6" msg.actions.append(of.ofp_action_output(port = 2)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.4" msg.match.nw_dst = "10.0.0.2" msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.5" msg.match.nw_dst = "10.0.0.2" msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.6" msg.match.nw_dst = "10.0.0.2" msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg) #################################### if event.connection.dpid==s3_dpid: a=packet.find('arp') if a and a.protodst=="10.0.0.3": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=1)) event.connection.send(msg) if a and a.protodst=="10.0.0.2": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=2)) event.connection.send(msg) if a and a.protodst=="10.0.0.6": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=2)) event.connection.send(msg) if a and a.protodst=="10.0.0.4": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=3)) event.connection.send(msg) if a and a.protodst=="10.0.0.5": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=3)) event.connection.send(msg) if a and a.protodst=="10.0.0.1": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=2)) event.connection.send(msg) #Add flows s3 msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.1" msg.match.nw_dst = "10.0.0.3" msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.1" msg.match.nw_dst = "10.0.0.4" msg.actions.append(of.ofp_action_output(port = 3)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.2" msg.match.nw_dst = "10.0.0.3" msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.2" msg.match.nw_dst = "10.0.0.4" msg.actions.append(of.ofp_action_output(port = 3)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.3" msg.match.nw_dst = "10.0.0.1" msg.actions.append(of.ofp_action_output(port = 2)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.3" msg.match.nw_dst = "10.0.0.2" msg.actions.append(of.ofp_action_output(port = 2)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.3" msg.match.nw_dst = "10.0.0.4" msg.actions.append(of.ofp_action_output(port = 3)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.3" msg.match.nw_dst = "10.0.0.5" msg.actions.append(of.ofp_action_output(port = 3)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.3" msg.match.nw_dst = "10.0.0.6" msg.actions.append(of.ofp_action_output(port = 2)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.4" msg.match.nw_dst = "10.0.0.2" msg.actions.append(of.ofp_action_output(port = 2)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.4" msg.match.nw_dst = "10.0.0.3" msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.5" msg.match.nw_dst = "10.0.0.3" msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.6" msg.match.nw_dst = "10.0.0.3" msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg) #################################### if event.connection.dpid==s4_dpid: a=packet.find('arp') if a and a.protodst=="10.0.0.4": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=1)) event.connection.send(msg) if a and a.protodst=="10.0.0.3": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=2)) event.connection.send(msg) if a and a.protodst=="10.0.0.1": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=2)) event.connection.send(msg) if a and a.protodst=="10.0.0.2": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=2)) event.connection.send(msg) if a and a.protodst=="10.0.0.5": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=3)) event.connection.send(msg) if a and a.protodst=="10.0.0.6": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=3)) event.connection.send(msg) #Add flows s4 msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.1" msg.match.nw_dst = "10.0.0.4" msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.2" msg.match.nw_dst = "10.0.0.4" msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.3" msg.match.nw_dst = "10.0.0.4" msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.3" msg.match.nw_dst = "10.0.0.5" msg.actions.append(of.ofp_action_output(port = 3)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.4" msg.match.nw_dst = "10.0.0.1" msg.actions.append(of.ofp_action_output(port = 3)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.4" msg.match.nw_dst = "10.0.0.2" msg.actions.append(of.ofp_action_output(port = 2)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.4" msg.match.nw_dst = "10.0.0.3" msg.actions.append(of.ofp_action_output(port = 2)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.4" msg.match.nw_dst = "10.0.0.5" msg.actions.append(of.ofp_action_output(port = 3)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.4" msg.match.nw_dst = "10.0.0.6" msg.actions.append(of.ofp_action_output(port = 3)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.5" msg.match.nw_dst = "10.0.0.3" msg.actions.append(of.ofp_action_output(port = 2)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.5" msg.match.nw_dst = "10.0.0.4" msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.6" msg.match.nw_dst = "10.0.0.3" msg.actions.append(of.ofp_action_output(port = 2)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.6" msg.match.nw_dst = "10.0.0.4" msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg) #################################### if event.connection.dpid==s5_dpid: a=packet.find('arp') if a and a.protodst=="10.0.0.5": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=1)) event.connection.send(msg) if a and a.protodst=="10.0.0.2": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=2)) event.connection.send(msg) if a and a.protodst=="10.0.0.3": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=3)) event.connection.send(msg) if a and a.protodst=="10.0.0.1": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=4)) event.connection.send(msg) if a and a.protodst=="10.0.0.4": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=3)) event.connection.send(msg) if a and a.protodst=="10.0.0.6": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=4)) event.connection.send(msg) #Add flows s5 msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.1" msg.match.nw_dst = "10.0.0.5" msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.2" msg.match.nw_dst = "10.0.0.5" msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.3" msg.match.nw_dst = "10.0.0.5" msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.4" msg.match.nw_dst = "10.0.0.1" msg.actions.append(of.ofp_action_output(port = 4)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.4" msg.match.nw_dst = "10.0.0.5" msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.4" msg.match.nw_dst = "10.0.0.6" msg.actions.append(of.ofp_action_output(port = 4)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.5" msg.match.nw_dst = "10.0.0.1" msg.actions.append(of.ofp_action_output(port = 4)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.5" msg.match.nw_dst = "10.0.0.2" msg.actions.append(of.ofp_action_output(port = 2)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.5" msg.match.nw_dst = "10.0.0.3" msg.actions.append(of.ofp_action_output(port = 3)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.5" msg.match.nw_dst = "10.0.0.4" msg.actions.append(of.ofp_action_output(port = 3)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.5" msg.match.nw_dst = "10.0.0.6" msg.actions.append(of.ofp_action_output(port = 4)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.6" msg.match.nw_dst = "10.0.0.3" msg.actions.append(of.ofp_action_output(port = 3)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.6" msg.match.nw_dst = "10.0.0.4" msg.actions.append(of.ofp_action_output(port = 3)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.6" msg.match.nw_dst = "10.0.0.5" msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg) #################################### if event.connection.dpid==s6_dpid: a=packet.find('arp') if a and a.protodst=="10.0.0.6": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=1)) event.connection.send(msg) if a and a.protodst=="10.0.0.1": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=2)) event.connection.send(msg) if a and a.protodst=="10.0.0.2": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=2)) event.connection.send(msg) if a and a.protodst=="10.0.0.3": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=3)) event.connection.send(msg) if a and a.protodst=="10.0.0.5": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=3)) event.connection.send(msg) if a and a.protodst=="10.0.0.4": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=3)) event.connection.send(msg) #Add flows s6 msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.1" msg.match.nw_dst = "10.0.0.5" msg.actions.append(of.ofp_action_output(port = 3)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.1" msg.match.nw_dst = "10.0.0.6" msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.2" msg.match.nw_dst = "10.0.0.6" msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.3" msg.match.nw_dst = "10.0.0.6" msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.4" msg.match.nw_dst = "10.0.0.1" msg.actions.append(of.ofp_action_output(port = 2)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.4" msg.match.nw_dst = "10.0.0.6" msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.5" msg.match.nw_dst = "10.0.0.1" msg.actions.append(of.ofp_action_output(port = 2)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.5" msg.match.nw_dst = "10.0.0.6" msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.6" msg.match.nw_dst = "10.0.0.1" msg.actions.append(of.ofp_action_output(port = 2)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.6" msg.match.nw_dst = "10.0.0.2" msg.actions.append(of.ofp_action_output(port = 2)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.6" msg.match.nw_dst = "10.0.0.3" msg.actions.append(of.ofp_action_output(port = 3)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.6" msg.match.nw_dst = "10.0.0.4" msg.actions.append(of.ofp_action_output(port = 3)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.6" msg.match.nw_dst = "10.0.0.5" msg.actions.append(of.ofp_action_output(port = 3)) event.connection.send(msg)
def _handle_PacketIn(self, event): """ Packet processing """ packet = event.parsed dpid = event.connection.dpid eth_packet = packet.find(pkt.ethernet) ip_packet = packet.find(pkt.ipv4) icmp_packet = packet.find(pkt.icmp) tcp_packet = packet.find(pkt.tcp) udp_packet = packet.find(pkt.udp) if icmp_packet is None and tcp_packet is None and udp_packet is None: return def flood(): #Flood incoming packet if dst is not known yet #Do not update flow table log.info("Flooding packet in switch: " + dpidToStr(event.connection.dpid) + " --- dst=" + str(eth_packet.dst)) msg = of.ofp_packet_out() msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD)) msg.data = event.ofp msg.in_port = event.port event.connection.send(msg) dstEntry = core.host_tracker.getMacEntry(eth_packet.dst) if dstEntry is None: return flood() log.info("Calculating packet path in switch: " + dpidToStr(event.connection.dpid) + " --- dst=" + str(eth_packet.dst)) dst = dstEntry.dpid port = None if (dst == dpid): #current switch is destination swith port = dstEntry.port else: #calculate all possible minnimum paths paths = [[neighbour] for neighbour in self.getNeighbours(dpid)] dsts = self.getPathsToDst(paths, dst) while not dsts: #for each iteration, calculates all paths from src which has length n #if any of those paths end in dst, finish while oldPaths = paths paths = [] for path in oldPaths: neighbours = self.getNeighbours(path[-1].dpid2) for neighbour in neighbours: paths.append(path + [neighbour]) dsts = self.getPathsToDst(paths, dst) if len(dsts) == 0: return else: #dsts has all possible minimum paths to dst ports = [dstPath[0].port1 for dstPath in dsts] port = self.getLeastUsedPort(ports, dpid) text = "Making rule for sending packet in switch: " + dpidToStr(dpid) + '\n' text += "Ethernet: " + str(eth_packet.src) + " -> " + str(eth_packet.dst) + '\n' alert = "Possible attack detected: {}\n\tEthernet: {} -> {}".format(eth_packet.payload, eth_packet.src, eth_packet.dst) #update flow table msg = of.ofp_flow_mod() msg.match.dl_type = eth_packet.type msg.match.nw_src = ip_packet.srcip msg.match.nw_dst = ip_packet.dstip msg.match.nw_proto = ip_packet.protocol text += "IPv4: " + str(ip_packet.srcip) + " -> " + str(ip_packet.dstip) alert += "\n\tIPv4: {} -> {}".format(ip_packet.srcip, ip_packet.dstip) if tcp_packet is not None: msg.match.tp_src = tcp_packet.srcport msg.match.tp_dst = tcp_packet.dstport text += "\nTCP: " + str(tcp_packet.srcport) + " -> " + str(tcp_packet.dstport) alert += "\n\tTCP: {} -> {}".format(tcp_packet.srcport, tcp_packet.dstport) if udp_packet is not None: msg.match.tp_src = udp_packet.srcport msg.match.tp_dst = udp_packet.dstport text += "\nUDP: " + str(udp_packet.srcport) + " -> " + str(udp_packet.dstport) alert += "\n\tUDP: {} -> {}\n\t".format(udp_packet.srcport, udp_packet.dstport) if icmp_packet is not None: alert += "\n\tICMP: {}".format(icmp_packet) msg.actions.append(of.ofp_action_output(port = port)) event.connection.send(msg) print text # Log the alert log.error(alert) ports_used[dpid][port] += 1 #send packet msg = of.ofp_packet_out() msg.actions.append(of.ofp_action_output(port = port)) msg.data = event.ofp msg.in_port = event.port event.connection.send(msg)
def _handle_PacketIn(event): global s1_dpid, s2_dpid, s3_dpid, s4_dpid packet = event.parsed if event.connection.dpid == s1_dpid: a = packet.find('arp') if a and a.protodst == "10.0.0.1": msg = of.ofp_packet_out(data = event.ofp) msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg) if a and a.protodst == "10.0.0.3": msg = of.ofp_packet_out(data = event.ofp) msg.actions.append(of.ofp_action_output(port = 4)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.1" msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.3" msg.actions.append(of.ofp_action_output(port = 4)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.3" msg.match.nw_dst = "10.0.0.2" msg.actions.append(of.ofp_action_output(port = 3)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0806 msg.match.nw_src = "10.0.0.3" msg.match.nw_dst = "10.0.0.2" msg.actions.append(of.ofp_action_output(port = 3)) event.connection.send(msg) elif event.connection.dpid == s2_dpid: msg = of.ofp_flow_mod() msg.priority = 10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.in_port = 1 msg.actions.append(of.ofp_action_output(port = 2)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0806 msg.match.in_port = 1 msg.actions.append(of.ofp_action_output(port = 2)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.in_port = 3 msg.actions.append(of.ofp_action_output(port = 2)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0806 msg.match.in_port = 3 msg.actions.append(of.ofp_action_output(port = 2)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 2 msg.match.dl_type = 0x0800 msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 2 msg.match.dl_type = 0x0806 msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg) elif event.connection.dpid == s3_dpid: msg = of.ofp_flow_mod() msg.priority = 10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 2 msg.match.dl_type = 0x0800 msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 2 msg.match.dl_type = 0x0806 msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 1 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.1" msg.actions.append(of.ofp_action_output(port = 3)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 1 msg.match.dl_type = 0x0806 msg.match.nw_src = "10.0.0.1" msg.actions.append(of.ofp_action_output(port = 3)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 1 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.3" msg.actions.append(of.ofp_action_output(port = 2)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 1 msg.match.dl_type = 0x0806 msg.match.nw_src = "10.0.0.3" msg.actions.append(of.ofp_action_output(port = 2)) event.connection.send(msg) elif event.connection.dpid == s4_dpid: a = packet.find('arp') if a and a.protodst == "10.0.0.2": msg = of.ofp_packet_out(data = event.ofp) msg.actions.append(of.ofp_action_output(port = 3)) event.connection.send(msg) if a and a.protodst == "10.0.0.1": msg = of.ofp_packet_out(data = event.ofp) msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg) if a and a.protodst == "10.0.0.3": msg = of.ofp_packet_out(data = event.ofp) msg.actions.append(of.ofp_action_output(port = 2)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.1" msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.3" msg.actions.append(of.ofp_action_output(port = 2)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.2" msg.actions.append(of.ofp_action_output(port = 3)) event.connection.send(msg)