Exemple #1
1
  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)
Exemple #2
1
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)
Exemple #3
0
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)
Exemple #4
0
    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
Exemple #7
0
  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
Exemple #11
0
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)
Exemple #13
0
  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()
Exemple #14
0
 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)
Exemple #17
0
    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)
Exemple #18
0
    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()
Exemple #19
0
 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)
Exemple #20
0
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)
Exemple #22
0
 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
Exemple #23
0
        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)
Exemple #24
0
 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
Exemple #25
0
    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)
Exemple #31
0
  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)
Exemple #34
0
    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)
Exemple #35
0
 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)
Exemple #36
0
 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)
Exemple #37
0
 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)
Exemple #38
0
 def dropPacket(self, event):
     message = of.ofp_packet_out()
     message.data = event.data
     message.in_port = event.port
     return message
Exemple #39
0
    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
Exemple #40
0
  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)
Exemple #42
0
    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)
Exemple #45
0
 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
Exemple #46
0
 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)
Exemple #47
0
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())
Exemple #50
0
 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))
Exemple #52
0
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)
Exemple #55
0
 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
Exemple #56
0
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
Exemple #57
0
    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)
Exemple #58
0
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)
Exemple #60
0
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)