예제 #1
0
def _handle_PacketIn(event):
    global server_index
    packet = event.parsed

    # First make sure the packet is addressed using IPv4
    if (not event.parsed.find("ipv4")):
        return EventContinue

    msg = of.ofp_flow_mod()
    msg.match = of.ofp_match.from_packet(packet)

    # If the ip matches controller virtual ip then continue
    if (msg.match.nw_dst != controllerip):
        return EventContinue

    # Employing round robin algorithm here
    index = server_index % total_servers
    print index
    selected_server_ip = server[index]['ip']
    selected_server_mac = server[index]['mac']
    selected_server_outport = server[index]['outport']
    server_index += 1

    # Setup route to server
    msg.buffer_id = event.ofp.buffer_id
    msg.in_port = event.port

    msg.actions.append(
        of.ofp_action_dl_addr(of.OFPAT_SET_DL_DST, selected_server_mac))
    msg.actions.append(
        of.ofp_action_nw_addr(of.OFPAT_SET_NW_DST, selected_server_ip))
    msg.actions.append(of.ofp_action_output(port=selected_server_outport))
    event.connection.send(msg)

    # Once the last server is reached, reverse the route
    reverse_msg = of.ofp_flow_mod()
    reverse_msg.buffer_id = None
    reverse_msg.in_port = selected_server_outport

    reverse_msg.match = of.ofp_match()
    reverse_msg.match.dl_src = selected_server_mac
    reverse_msg.match.nw_src = selected_server_ip
    reverse_msg.match.tp_src = msg.match.tp_dst

    reverse_msg.match.dl_dst = msg.match.dl_src
    reverse_msg.match.nw_dst = msg.match.nw_src
    reverse_msg.match.tp_dst = msg.match.tp_src

    reverse_msg.actions.append(
        of.ofp_action_dl_addr(of.OFPAT_SET_DL_SRC, controllermac))
    reverse_msg.actions.append(
        of.ofp_action_nw_addr(of.OFPAT_SET_NW_SRC, controllerip))
    reverse_msg.actions.append(of.ofp_action_output(port=msg.in_port))
    event.connection.send(reverse_msg)

    return EventHalt
예제 #2
0
def _handle_PacketIn(event):
    global server_index
    packet = event.parsed

    # Only handle IPv4 flows
    if (not event.parsed.find("ipv4")):
        return EventContinue

    msg = of.ofp_flow_mod()
    msg.match = of.ofp_match.from_packet(packet)

    # Only handle traffic destined to virtual IP
    if (msg.match.nw_dst != virtual_ip):
        return EventContinue

    # Round robin selection of servers
    index = server_index % total_servers
    print index
    selected_server_ip = server[index]['ip']
    selected_server_mac = server[index]['mac']
    selected_server_outport = server[index]['outport']
    server_index += 1

    # Setup route to server
    msg.buffer_id = event.ofp.buffer_id
    msg.in_port = event.port

    msg.actions.append(
        of.ofp_action_dl_addr(of.OFPAT_SET_DL_DST, selected_server_mac))
    msg.actions.append(
        of.ofp_action_nw_addr(of.OFPAT_SET_NW_DST, selected_server_ip))
    msg.actions.append(of.ofp_action_output(port=selected_server_outport))
    event.connection.send(msg)

    # Setup reverse route from server
    reverse_msg = of.ofp_flow_mod()
    reverse_msg.buffer_id = None
    reverse_msg.in_port = selected_server_outport

    reverse_msg.match = of.ofp_match()
    reverse_msg.match.dl_src = selected_server_mac
    reverse_msg.match.nw_src = selected_server_ip
    reverse_msg.match.tp_src = msg.match.tp_dst

    reverse_msg.match.dl_dst = msg.match.dl_src
    reverse_msg.match.nw_dst = msg.match.nw_src
    reverse_msg.match.tp_dst = msg.match.tp_src

    reverse_msg.actions.append(
        of.ofp_action_dl_addr(of.OFPAT_SET_DL_SRC, virtual_mac))
    reverse_msg.actions.append(
        of.ofp_action_nw_addr(of.OFPAT_SET_NW_SRC, virtual_ip))
    reverse_msg.actions.append(of.ofp_action_output(port=msg.in_port))
    event.connection.send(reverse_msg)

    return EventHalt
예제 #3
0
def packet_handler(event):
    global server_no
    packet = event.parsed

    # Only handle traffic destined to virtual IP
    if (not event.parsed.find("ipv4")):
        return event_cont

    message = of.ofp_flow_mod()
    message.match = of.ofp_match.from_packet(packet)

    # Handing requests routed to the Load Balancer Ip
    if (message.match.nw_dst != load_balancer_hardcoded_ip):
        return event_cont

    # Random selection of servers
    iterator = random.randint(0, server_no - 1)
    print iterator
    serverip = topology_server[iterator]['ip']
    selected_server_mac = topology_server[iterator]['mac']
    server_output = topology_server[iterator]['outport']

    # Route followed to server
    message.buffer_id = event.ofp.buffer_id
    message.in_port = event.port

    message.actions.append(
        of.ofp_action_dl_addr(of.OFPAT_SET_DL_DST, selected_server_mac))
    message.actions.append(of.ofp_action_nw_addr(of.OFPAT_SET_NW_DST,
                                                 serverip))
    message.actions.append(of.ofp_action_output(port=server_output))
    event.connection.send(message)

    # Route from server to load balancer
    reply = of.ofp_flow_mod()
    reply.buffer_id = None
    reply.in_port = server_output

    reply.match = of.ofp_match()
    reply.match.dl_src = selected_server_mac
    reply.match.nw_src = serverip
    reply.match.tp_src = message.match.tp_dst

    reply.match.dl_dst = message.match.dl_src
    reply.match.nw_dst = message.match.nw_src
    reply.match.tp_dst = message.match.tp_src

    reply.actions.append(
        of.ofp_action_dl_addr(of.OFPAT_SET_DL_SRC, virtual_mac))
    reply.actions.append(
        of.ofp_action_nw_addr(of.OFPAT_SET_NW_SRC, load_balancer_hardcoded_ip))
    reply.actions.append(of.ofp_action_output(port=message.in_port))
    event.connection.send(reply)

    return EventHalt
예제 #4
0
def _handle_PacketIn (event):
    global server_index
    packet = event.parsed

    # Only handle IPv4 flows
    if (not event.parsed.find("ipv4")):
        return EventContinue

    msg = of.ofp_flow_mod()
    msg.match = of.ofp_match.from_packet(packet)

    # Only handle traffic destined to virtual IP
    if (msg.match.nw_dst != virtual_ip):
        return EventContinue

    # Round robin selection of servers
    index = server_index % total_servers
    print index
    selected_server_ip = server[index]['ip']
    selected_server_mac = server[index]['mac']
    selected_server_outport = server[index]['outport']
    server_index += 1

    # Setup route to server
    msg.buffer_id = event.ofp.buffer_id
    msg.in_port = event.port

    msg.actions.append(of.ofp_action_dl_addr(of.OFPAT_SET_DL_DST, selected_server_mac))
    msg.actions.append(of.ofp_action_nw_addr(of.OFPAT_SET_NW_DST, selected_server_ip))
    msg.actions.append(of.ofp_action_output(port = selected_server_outport))
    event.connection.send(msg)

    # Setup reverse route from server
    reverse_msg = of.ofp_flow_mod()
    reverse_msg.buffer_id = None
    reverse_msg.in_port = selected_server_outport

    reverse_msg.match = of.ofp_match()
    reverse_msg.match.dl_src = selected_server_mac
    reverse_msg.match.nw_src = selected_server_ip
    reverse_msg.match.tp_src = msg.match.tp_dst

    reverse_msg.match.dl_dst = msg.match.dl_src
    reverse_msg.match.nw_dst = msg.match.nw_src
    reverse_msg.match.tp_dst = msg.match.tp_src

    reverse_msg.actions.append(of.ofp_action_dl_addr(of.OFPAT_SET_DL_SRC, virtual_mac))
    reverse_msg.actions.append(of.ofp_action_nw_addr(of.OFPAT_SET_NW_SRC, virtual_ip))
    reverse_msg.actions.append(of.ofp_action_output(port = msg.in_port))
    event.connection.send(reverse_msg)

    return EventHalt
예제 #5
0
 def CreateActions(self, actions, entry, outbound):
   if outbound:
     actions.append(of.ofp_action_dl_addr(of.OFPAT_SET_DL_SRC, self.if_external))
     actions.append(of.ofp_action_nw_addr(of.OFPAT_SET_NW_SRC, NAT_IP_EXTERNAL))
     actions.append(of.ofp_action_tp_port(of.OFPAT_SET_TP_SRC, entry["natport"]))
     actions.append(of.ofp_action_dl_addr(of.OFPAT_SET_DL_DST, GetMACFromIP(entry["extip"])))
     actions.append(of.ofp_action_output(port=self.port_external))
   else:
     actions.append(of.ofp_action_dl_addr(of.OFPAT_SET_DL_SRC, self.if_external))
     actions.append(of.ofp_action_dl_addr(of.OFPAT_SET_DL_DST, entry["int"]))
     actions.append(of.ofp_action_nw_addr(of.OFPAT_SET_NW_DST, entry["intip"]))
     actions.append(of.ofp_action_tp_port(of.OFPAT_SET_TP_DST, entry["intport"]))
     actions.append(of.ofp_action_output(port=GetPortFromIP(entry["intip"])))
예제 #6
0
  def _match_action(self,msg):
    
      if len(self.actions) == 1 and self.actions[0] == "" :
          return

      for action in self.actions:
          
        action_name = action.split('=')[0]
        if action_name != "STRIP_VLAN":
            action_argu = action.split('=')[1]
        
        if(action_name == "OUTPUT"):
            msg.actions.append(of.ofp_action_output(port = int(action_argu)))
      
        elif(action_name == "ENQUEUE"):
            port = action_argu.split(':')[0]
            queue_id = action_argu.split(':')[1]
            msg.actions.append(of.ofp_action_enqueue(port = int(port) , queue_id = int(queue_id)))
    
        elif(action_name == "STRIP_VLAN"):
            msg.actions.append(of.ofp_action_strip_vlan())
    
        elif(action_name == "SET_VLAN_VID"):
            msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = int(action_argu)))
    
        elif(action_name == "SET_VLAN_PCP"):
            msg.actions.append(of.ofp_action_vlan_pcp(vlan_pcp = int(action_argu)))
    
        elif(action_name == "SET_DL_SRC"):
            msg.actions.append(of.ofp_action_dl_addr(type = 4 , dl_addr = EthAddr(action_argu)))
    
        elif(action_name == "SET_DL_DST"):
            msg.actions.append(of.ofp_action_dl_addr(type = 5 , dl_addr = EthAddr(action_argu)))
    
        elif(action_name == "SET_NW_TOS"):
            msg.actions.append(of.ofp_action_nw_tos(nw_tos = int(action_argu)))

        elif(action_name == "SET_NW_SRC"):
            msg.actions.append(of.ofp_action_nw_addr(type = 6 , nw_addr = IPAddr(action_argu)))

        elif(action_name == "SET_NW_DST"):
            msg.actions.append(of.ofp_action_nw_addr(type = 7 , nw_addr = IPAddr(action_argu)))

        elif(action_name == "SET_TP_SRC"):
            msg.actions.append(of.ofp_action_tp_port(type = 9 , tp_port = int(action_argu)))
    
        elif(action_name == "SET_TP_DST"):
            msg.actions.append(of.ofp_action_tp_port(type = 10 , tp_port = int(action_argu)))
예제 #7
0
def Round_Robin(event):
    global ServerUsed
    global server_virtual_ip
    global server_virtual_mac	
    packet = event.parsed
    msg_to_server = of.ofp_flow_mod()
    msg_to_server.match = of.ofp_match.from_packet(packet)
    if (event.parsed.find("ipv4")) and (msg_to_server.match.nw_dst == server_virtual_ip):
	    print ('Server in Service => Server :', ServerUsed)
	    server_ip =  serverList[ServerUsed] ['ip'] 
	    print ('With IP => ServerIP = :', server_ip)   
	    server_mac= serverList[ServerUsed]['mac']  
	    server_outport= serverList[ServerUsed]['port']  
	
	    # Setup route to server
        # setup_route_to_server(event,msg_to_server,server_mac,server_ip,server_outport)
	    msg_to_server.buffer_id = event.ofp.buffer_id
    	msg_to_server.in_port = event.port
    	msg_to_server.actions.append(of.ofp_action_dl_addr(of.OFPAT_SET_DL_DST, server_mac))
        msg_to_server.actions.append(of.ofp_action_nw_addr(of.OFPAT_SET_NW_DST, server_ip))
        msg_to_server.actions.append(of.ofp_action_output(port = server_outport))
    	event.connection.send(msg_to_server)
        
        # Setup reverse route from server
        # setup_route_from_server(event,msg_to_server,server_mac,server_ip,server_outport)
	    msg_from_server = of.ofp_flow_mod()
예제 #8
0
    def send_arp_request(self, connection, ip):

        log.debug("FUNCTION: send_arp_request")

        arp_req = arp()
        arp_req.hwtype = arp_req.HW_TYPE_ETHERNET
        arp_req.prototype = arp_req.PROTO_TYPE_IP
        arp_req.hwlen = 6
        arp_req.protolen = arp_req.protolen
        arp_req.opcode = arp.REQUEST
        arp_req.protodst = ip
        arp_req.hwsrc = LOADBALANCER_MAC
        arp_req.hwdst = ETHERNET_BROADCAST_ADDRESS
        arp_req.protosrc = self.LOADBALANCER_IP

        eth = ethernet() #Creating ethernet frame
        eth.type = eth.ARP_TYPE
        eth.dst = ETHERNET_BROADCAST_ADDRESS
        eth.set_payload(arp_req)

        msg = of.ofp_packet_out()
        msg.data = eth.pack()
        msg.actions.append(of.ofp_action_nw_addr(of.OFPAT_SET_NW_DST, ip))
        msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) #Appending the action to the message telling the switch to flood the package

        connection.send(msg)
def _arp(event):
    packet = event.parsed
    arp_packet = packet.find('arp')
    ip_src = str(arp_packet.protosrc)
    ip_dst = str(arp_packet.protodst)
    mac_src = ipToMac[ip_src]
    mac_dst = ipToMac[ip_dst]

    if arp_packet is not None:
        print "From  host  : ip = ", ip_src, ", mac = ", mac_src
        print "To    host  : ip = ", ip_dst, ", mac = ", mac_dst

        if arp_packet.opcode == arp.REQUEST:
            #print "arp.REQUEST"
            #create arp packet
            a = arp()
            a.opcode = arp.REPLY

            #if request from src, fake reply from dst
            if arp_packet.hwsrc == EthAddr(mac_src):
                a.hwsrc = EthAddr(mac_dst)
                a.hwdst = EthAddr(mac_src)
            elif arp_packet.hwsrc == EthAddr(mac_dst):
                a.hwsrc = EthAddr(mac_src)
                a.hwdst = EthAddr(mac_dst)

            #fake reply IP
            a.protosrc = IPAddr(ip_dst)
            a.protodst = arp_packet.protosrc
            a.hwlen = 6
            a.protolen = 4
            a.hwtype = arp.HW_TYPE_ETHERNET
            a.prototype = arp.PROTO_TYPE_IP

            #create ethernet packet
            e = ethernet()
            e.set_payload(a)
            e.type = ethernet.ARP_TYPE
            if arp_packet.hwsrc == EthAddr(mac_src):
                e.src = EthAddr(mac_dst)
                e.dst = EthAddr(mac_src)
            elif arp_packet.hwsrc == EthAddr(mac_dst):
                e.src = EthAddr(mac_src)
                e.dst = EthAddr(mac_dst)

            msg = of.ofp_packet_out()
            msg.data = e.pack()
            msg.actions.append(
                of.ofp_action_nw_addr(of.OFPAT_SET_NW_DST, IPAddr(ip_dst)))
            msg.actions.append(of.ofp_action_output(port=event.port))
            event.connection.send(msg)

            getRandomPath(mac_src,
                          mac_dst)  # choice random path from h_src to h_dst
            getRandomPath(
                mac_dst, mac_src
            )  # choice random path from h_dst to h_src (back transfer)

            print "-------------------------------------------------------\n"
            print "Random path : \t"
예제 #10
0
    def send_proxied_arp_request(self, connection, ip):
        #construct the arp packet
        ar = arp()  #type of packet
        ar.hwtype = ar.HW_TYPE_ETHERNET  #type of hardware tyr
        ar.prototype = ar.PROTO_TYPE_IP  #protocol type
        ar.hwlen = 6  #hardware addrese length 6 bytes and mac=ipv6
        ar.protolen = ar.protolen  #the ipv4 length
        ar.opcode = ar.REQUEST
        ar.hwdst = self.ethernet_broad  # broadcast to all possible  interfaces
        ar.protodst = ip  #ip dest to send
        ar.hwsrc = self.lb_mac  #fake mac address
        ar.protosrc = self.lb_real_ip  # the real ip of the address

        # packet has inside it the r packet
        e = ethernet(type=ethernet.ARP_TYPE,
                     src=self.lb_mac,
                     dst=self.ethernet_broad)
        e.set_payload(
            ar)  # take the previous packet and put it into th message data

        msg = of.ofp_packet_out(
        )  # send packet out cause we dont need an entry in the flow table
        msg.data = e.pack()
        msg.actions.append(of.ofp_action_nw_addr(of.OFPAT_SET_NW_DST,
                                                 ip))  # send to this ip
        msg.actions.append(
            of.ofp_action_output(port=of.OFPP_FLOOD))  # flood to all ports

        connection.send(msg)
예제 #11
0
    def send_arp_request(self, connection, ip):
        # Difficulties? https://en.wikipedia.org/wiki/Address_Resolution_Protocol#Example

        log.debug("FUNCTION: send_arp_request")

        arp_req = arp()
        arp_req.hwtype = arp_req.HW_TYPE_ETHERNET
        arp_req.prototype = arp_req.PROTO_TYPE_IP
        arp_req.hwlen = 6
        arp_req.protolen = arp_req.protolen
        arp_req.opcode = arp_req.REQUEST  # ADD OPCODE
        arp_req.protodst = ip  # IP the load balancer is looking for
        arp_req.hwsrc = LOADBALANCER_MAC  # Set the MAC source of the ARP REQUEST
        arp_req.hwdst = ETHERNET_BROADCAST_ADDRESS  # Set the MAC address in such a way that the packet is marked as a Broadcast
        arp_req.protosrc = self.LOADBALANCER_IP  # Set the IP source of the ARP REQUEST

        eth = ethernet(
        )  # Create an ethernet frame and set the arp_req as it's payload.
        eth.type = ethernet.ARP_TYPE  # Set packet Typee
        eth.dst = ETHERNET_BROADCAST_ADDRESS  # Set the MAC address in such a way that the packet is marked as a Broadcast
        eth.set_payload(arp_req)

        msg = of.ofp_packet_out(
        )  # create the necessary Openflow Message to make the switch send the ARP Request
        msg.data = eth.pack()
        msg.actions.append(of.ofp_action_nw_addr(of.OFPAT_SET_NW_DST, ip))

        msg.actions.append(
            of.ofp_action_output(port=of.OFPP_FLOOD)
        )  # append an action to the message which makes the switch flood the packet out

        connection.send(msg)
예제 #12
0
 def send_ofmod_modify_forward(self, _called_from, conn, nw_src, nw_dst,
                               tp_dst, new_dst, new_dl_dst, fport,
                               duration):
     msg = of.ofp_flow_mod()
     msg.priority = 0x7000
     msg.match.dl_type = 0x800  # Ethertype / length (e.g. 0x0800 = IPv4)
     msg.match.nw_src = IPAddr(nw_src)
     msg.match.nw_dst = IPAddr(nw_dst)
     msg.match.nw_proto = 17  #UDP
     if tp_dst != None:
         msg.match.tp_dst = int(tp_dst)
     msg.idle_timeout = duration[0]
     msg.hard_timeout = duration[1]
     if _called_from == 'packet_in':
         msg.buffer_id = event.ofp.buffer_id
     msg.actions.append(
         of.ofp_action_nw_addr(nw_addr=IPAddr(new_dst), type=7))
     msg.actions.append(
         of.ofp_action_dl_addr(dl_addr=EthAddr(new_dl_dst), type=5))
     msg.actions.append(of.ofp_action_output(port=fport))
     conn.send(msg)
     print '\nsend_ofmod_modify_forward to sw_dpid=%s' % conn.dpid
     print 'wcs: src_ip=%s, dst_ip=%s, tp_dst=%s' % (nw_src, nw_dst, tp_dst)
     print 'acts: new_dst=%s, new_dl_dst=%s, fport=%s\n' % (
         new_dst, new_dl_dst, fport)
예제 #13
0
  def _match_action(self,msg):
    if(self.actions == "OUTPUT"):
      msg.actions.append(of.ofp_action_output(port = int(self.actions_argu)))
      
    elif(self.actions == "enqueue"):
      port = self.actions_argu.split(':')[0]
      queue_id = self.actions_argu.split(':')[1]
      msg.actions.append(of.ofp_action_enqueue(port = int(port) , queue_id = int(queue_id)))
    
    elif(self.actions == "strip-vlan"):
      msg.actions.append(of.ofp_action_strip_vlan())
    
    elif(self.actions == "set-vlan-id"):
      msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = int(self.actions_argu)))
    
    elif(self.actions == "set-vlan-priority"):
      msg.actions.append(of.ofp_action_vlan_pcp(vlan_pcp = int(self.actions_argu)))
    
    elif(self.actions == "SET_DL_SRC"):
      msg.actions.append(of.ofp_action_dl_addr(type = 4 , dl_addr = EthAddr(self.actions_argu)))
    
    elif(self.actions == "SET_DL_DST"):
      msg.actions.append(of.ofp_action_dl_addr(type = 5 , dl_addr = EthAddr(self.actions_argu)))
    
    elif(self.actions == "SET_NW_TOS"):
      msg.actions.append(of.ofp_action_nw_tos(nw_tos = int(self.actions_argu)))

    elif(self.actions == "SET_NW_SRC"):
      msg.actions.append(of.ofp_action_nw_addr(type = 6 , nw_addr = IPAddr(self.actions_argu)))

    elif(self.actions == "SET_NW_DST"):
      msg.actions.append(of.ofp_action_nw_addr(type = 7 , nw_addr = IPAddr(self.actions_argu)))

    elif(self.actions == "SET_TP_SRC"):
      msg.actions.append(of.ofp_action_tp_port(type = 9 , tp_port = int(self.actions_argu)))
    
    elif(self.actions == "SET_TP_DST"):
      msg.actions.append(of.ofp_action_tp_port(type = 10 , tp_port = int(self.actions_argu)))
예제 #14
0
파일: NAT.py 프로젝트: hobasyd/UW-CSEP561
 def CreateActions(self, actions, entry, outbound):
     if outbound:
         actions.append(
             of.ofp_action_dl_addr(of.OFPAT_SET_DL_SRC, self.if_external))
         actions.append(
             of.ofp_action_nw_addr(of.OFPAT_SET_NW_SRC, NAT_IP_EXTERNAL))
         actions.append(
             of.ofp_action_tp_port(of.OFPAT_SET_TP_SRC, entry["natport"]))
         actions.append(
             of.ofp_action_dl_addr(of.OFPAT_SET_DL_DST,
                                   GetMACFromIP(entry["extip"])))
         actions.append(of.ofp_action_output(port=self.port_external))
     else:
         actions.append(
             of.ofp_action_dl_addr(of.OFPAT_SET_DL_SRC, self.if_external))
         actions.append(
             of.ofp_action_dl_addr(of.OFPAT_SET_DL_DST, entry["int"]))
         actions.append(
             of.ofp_action_nw_addr(of.OFPAT_SET_NW_DST, entry["intip"]))
         actions.append(
             of.ofp_action_tp_port(of.OFPAT_SET_TP_DST, entry["intport"]))
         actions.append(
             of.ofp_action_output(port=GetPortFromIP(entry["intip"])))
예제 #15
0
def send_ofmod_modify_forward (_called_from, conn, nw_src, nw_dst, tp_dst, new_dst, new_dl_dst,o_port, duration):
  msg = of.ofp_flow_mod()
  msg.priority = 0x7000
  msg.match.dl_type = 0x800 # Ethertype / length (e.g. 0x0800 = IPv4)
  msg.match.nw_src = IPAddr(nw_src)
  msg.match.nw_dst = IPAddr(nw_dst)
  msg.match.nw_proto = 17 #UDP
  if tp_dst != None:
    msg.match.tp_dst = int(tp_dst)
  msg.idle_timeout = duration[0]
  msg.hard_timeout = duration[1]
  if _called_from == 'packet_in':
    msg.buffer_id = event.ofp.buffer_id
  msg.actions.append(of.ofp_action_nw_addr(nw_addr = IPAddr(new_dst), type=7))
  msg.actions.append(of.ofp_action_dl_addr(dl_addr = EthAddr(new_dl_dst), type=5))
  msg.actions.append(of.ofp_action_output(port = o_port))
  conn.send(msg)
  print "\nFrom dpid: ", conn.dpid, "send_ofmod_modify_forward", "src_ip: ",nw_src,
  print " dst_ip: ",nw_dst," tp_dst: ",tp_dst," new_dst_ip: ",new_dst, " new_dst_mac: ", new_dl_dst, " fport: ", o_port, " is sent\n"
예제 #16
0
 def send_ofmod_modify_forward(self, _called_from, conn, nw_src, nw_dst, tp_dst, new_dst, new_dl_dst,fport, duration):
   msg = of.ofp_flow_mod()
   msg.priority = 0x7000
   msg.match.dl_type = 0x800 # Ethertype / length (e.g. 0x0800 = IPv4)
   msg.match.nw_src = IPAddr(nw_src)
   msg.match.nw_dst = IPAddr(nw_dst)
   msg.match.nw_proto = 17 #UDP
   if tp_dst != None:
     msg.match.tp_dst = int(tp_dst)
   msg.idle_timeout = duration[0]
   msg.hard_timeout = duration[1]
   if _called_from == 'packet_in':
     msg.buffer_id = event.ofp.buffer_id
   msg.actions.append(of.ofp_action_nw_addr(nw_addr = IPAddr(new_dst), type=7))
   msg.actions.append(of.ofp_action_dl_addr(dl_addr = EthAddr(new_dl_dst), type=5))
   msg.actions.append(of.ofp_action_output(port = fport))
   conn.send(msg)
   print '\nsend_ofmod_modify_forward to sw_dpid=%s' % conn.dpid
   print 'wcs: src_ip=%s, dst_ip=%s, tp_dst=%s' % (nw_src,nw_dst,tp_dst)
   print 'acts: new_dst=%s, new_dl_dst=%s, fport=%s\n' % (new_dst, new_dl_dst, fport)
예제 #17
0
 def send_ofmod_modify_forward (self, _called_from, conn, nw_src, nw_dst,
                                tp_dst, new_dst, new_dl_dst, o_port, duration):
   msg = of.ofp_flow_mod()
   msg.priority = 0x7000
   msg.match.dl_type = 0x800 # Ethertype / length (e.g. 0x0800 = IPv4)
   msg.match.nw_src = IPAddr(nw_src)
   msg.match.nw_dst = IPAddr(nw_dst)
   if tp_dst != None:
     msg.match.nw_proto = 17 #UDP
     msg.match.tp_dst = int(tp_dst)
   msg.idle_timeout = duration[0]
   msg.hard_timeout = duration[1]
   if _called_from == 'packet_in':
     msg.buffer_id = event.ofp.buffer_id
   msg.actions.append(of.ofp_action_nw_addr(nw_addr = IPAddr(new_dst), type=7))
   msg.actions.append(of.ofp_action_dl_addr(dl_addr = EthAddr(new_dl_dst), type=5))
   msg.actions.append(of.ofp_action_output(port = o_port))
   conn.send(msg)
   print "\nFrom dpid: ", conn.dpid, "send_ofmod_modify_forward", "src_ip: ", \
         nw_src," dst_ip: ",nw_dst," tp_dst: ",tp_dst," new_dst_ip: ",new_dst, \
         " new_dst_mac: ", new_dl_dst, " fport: ", o_port, " is sent\n"
예제 #18
0
  def _handle_PacketIn (self, event):
    """
    Handle packet in messages from the switch to implement above algorithm.
    """#52:54:00:79:95:26 26:6a:fb:3c:f8:fd
    cptv = server_infos(conf.captive_portal.ip,conf.captive_portal.mac,conf.captive_portal.switch_port,conf.captive_portal.tcp_port)#"130.192.225.168","52:54:00:79:95:26",5,8085)
    #cptv = server_infos("130.192.225.156","88:51:fb:42:2b:f8",5,8080)

    if self.connection.dpid not in switchs_info:
        lock.acquire()
        try:
            dpi = DPI()
            dpi.setDPI(self.connection.dpid)
            # add a new switch to our infos
            switchs_info[self.connection.dpid] = switch_infos(self.connection)
        finally:
            lock.release() # release lock, no matter what

    switch =  switchs_info[self.connection.dpid]
    if event.port not in switch.ports_info:
        lock.acquire()
        try:
            #print (dpid_to_str(self.connection.dpid))
            #print self.connection.sock.getpeername()[0]
            switch.ports_info[event.port] = port_infos(event.port)
        finally:
            lock.release() # release lock, no matter what

        #if event.port == conf.my_infos.my_default_GRE_tunnel:
        is_user_port = True
        log.info("Comparing the ports speaking " + str(event.port))
        for not_user_port in conf.my_infos.not_user_ports:
            if str(event.port) == str(not_user_port):
                is_user_port = False
                break

        if not is_user_port:
            log.info("Event port is " + str(event.port))
            log.info("First for the ethernet interface")
            # First rule: allow all traffic
            self.connection.send( of.ofp_flow_mod( action=of.ofp_action_output(port=of.OFPP_NORMAL),
                                       priority=1,
                                       match=of.ofp_match( in_port = event.port)))
        else:
            """
            Packet from user
            """
            log.info("First packet from user")
            # First rule: drop all traffic
            msg = of.ofp_flow_mod()
            msg.priority = 1
            msg.match.in_port = event.port
            msg.actions.append(of.ofp_action_output(port=of.OFPP_NONE))
            self.connection.send(msg)
            # Second rule: normal process for DNS traffic
            msg = of.ofp_flow_mod()
            msg.priority = 100
            msg.match.in_port = event.port
            msg.match.dl_type = 0x800
            msg.match.nw_proto = 17
            msg.match.tp_dst = 53
            msg.actions.append(of.ofp_action_output(port=of.OFPP_NORMAL))
            #msg.data = event.ofp
            self.connection.send(msg)
            # Third rule: normal process for ARP traffic
            msg = of.ofp_flow_mod()
            msg.priority = 100
            msg.match.in_port = event.port
            msg.match.dl_type = 0x806
            msg.actions.append(of.ofp_action_output(port=of.OFPP_NORMAL))
            #msg.data = event.ofp
            self.connection.send(msg)
            # Fourth rule: normal process for DHCPDISCOVER
            msg = of.ofp_flow_mod()
            msg.priority = 100
            msg.match.in_port = event.port
            msg.match.dl_type = 0x800
            msg.match.nw_proto = 17
            msg.match.nw_src = "0.0.0.0"
            msg.match.nw_dst = "255.255.255.255"
            msg.match.tp_src = 68
            msg.match.tp_dst = 67
            msg.actions.append(of.ofp_action_output(port=of.OFPP_NORMAL))
            #msg.data = event.ofp
            self.connection.send(msg)
            # Fifth rule: send the HTTP traffic to the controller
            msg = of.ofp_flow_mod()
            msg.priority = 1000
            msg.match.in_port = event.port
            msg.match.dl_type = 0x800
            msg.match.nw_proto = 6
            msg.match.tp_dst = 80
            msg.actions.append(of.ofp_action_output(port=of.OFPP_CONTROLLER))
            msg.data = event.ofp
            self.connection.send(msg)

    packet = event.parsed
    if not packet.parsed:
      log.info("ignoring unparsed packet")
      return

    client_list = switch.ports_info[event.port].clients_info
    log.info("LOOP Thread id: "+str(thread.get_ident() ))
    log.debug("packet.type: "+ str(packet.type) +" || pkt.ethernet.IP_TYPE: "+ str(pkt.ethernet.IP_TYPE))
    if packet.type == pkt.ethernet.IP_TYPE:
        ipv4_hdr = packet.payload
        log.debug("ipv4_hdr.protocol: "+ str(ipv4_hdr.protocol) +" || pkt.ipv4.TCP_PROTOCOL: "+ str(pkt.ipv4.TCP_PROTOCOL))
        if ipv4_hdr.protocol == pkt.ipv4.TCP_PROTOCOL:
            tcp_hdr = ipv4_hdr.payload
            log.info("tcp_hdr.dstport: "+ str(tcp_hdr.dstport) +" || DestPort: || 80")
            if tcp_hdr.dstport == 80:
                log.debug("packet.src: "+ str(packet.src))

                if str(packet.src) not in client_list:
                    log.info("packet.src is not in client_list")
                    lock.acquire()
                    try:
                        log.info("save host info: IP=" + str(ipv4_hdr.srcip) + ", MAC=" + str(packet.src) + ", INGRESS_SWITCH_PORT=" + str(switch.infos.ports[event.port].name))
                        client_list[str(packet.src)] = host_infos(ipv4_hdr.srcip,packet.src,event.port,0)
                    finally:
                        lock.release() # release lock, no matter what
                else:
                    log.debug("PACKET_IN INFOs: user MAC: "+ str(packet.src)+", user IP: "+ str(ipv4_hdr.srcip))
                    user_infos = client_list[str(packet.src)]
                    user_ip = user_infos.IP
                    log.debug("Local informations: user MAC: "+ str(packet.src)+", user IP: "+ str(user_ip))
                    if user_ip != ipv4_hdr.srcip:
                        log.debug("Updating client IP informations")
                        user_infos.IP = ipv4_hdr.srcip

                client = client_list[str(packet.src)]
                if (client.flag_auth == 0):
                    log.info("installing new flow to set destination IP to captive portal IP")
                    msg = of.ofp_flow_mod()
                    msg.priority = 10000
                    msg.idle_timeout=30
                    msg.match.dl_type = 0x800
                    msg.match.dl_src = client.MAC
                    msg.match.nw_proto = 6
                    #Adding the match on the TCP source port of the user, in order to genererate a PACKET_IN for every
                    #new TCP connection
                    msg.match.tp_src = tcp_hdr.srcport
                    msg.match.tp_dst = 80
                    msg.match.nw_dst = ipv4_hdr.dstip
                    msg.match.in_port = event.port
                    msg.actions.append(of.ofp_action_dl_addr(of.OFPAT_SET_DL_DST,cptv.MAC))
                    msg.actions.append(of.ofp_action_nw_addr(of.OFPAT_SET_NW_DST,cptv.IP))
                    msg.actions.append(of.ofp_action_tp_port(of.OFPAT_SET_TP_DST,cptv.port))
                    msg.actions.append(of.ofp_action_output(port=cptv.switch_port))
                    #msg.data = event.ofp
                    self.connection.send(msg)
                    log.info("installing new flow to set return path")
                    msg = of.ofp_flow_mod()
                    msg.priority = 10000
                    msg.idle_timeout=30
                    msg.match.dl_type = 0x800
                    msg.match.nw_proto = 6
                    msg.match.tp_dst = tcp_hdr.srcport
                    msg.match.nw_dst = ipv4_hdr.srcip
                    msg.match.nw_src = cptv.IP
                    msg.actions.append(of.ofp_action_nw_addr(of.OFPAT_SET_NW_SRC,ipv4_hdr.dstip))
                    msg.actions.append(of.ofp_action_tp_port(of.OFPAT_SET_TP_SRC,tcp_hdr.dstport))
                    msg.actions.append(of.ofp_action_output(port=event.port))
                    msg.data = event.ofp
                    self.connection.send(msg)
                '''
    def handle_IPPacket( self, event ):
        is_src_router = (event.ofp.in_port == of.OFPP_LOCAL)  # @UndefinedVariable
        if event.parsed.next.srcip.inNetwork(NON_ROUTABLE_SUBNET, NON_ROUTABLE_NETMASK):
            print "source ip is not routable"
            return
        if event.parsed.src != self.bridge_mac and not self.check_access(event.parsed.src):
            print "%s is not permmited" % (str(event.parsed.src))
            return
        if event.parsed.next.dstip.inNetwork(NON_ROUTABLE_SUBNET, NON_ROUTABLE_NETMASK):
            print "destination is not routable"
            return
        is_src_local = event.parsed.next.srcip.inNetwork(ROUTABLE_SUBNET, ROUTABLE_NETMASK) or event.parsed.next.srcip.inNetwork(INIT_SUBNET, INIT_NETMASK)
        if is_src_local and (event.parsed.next.srcip.toUnsigned(networkOrder=False) & 0x3) == 1:
            if not self.get_DHCP_mapping().is_valid_mapping(event.parsed.next.srcip, event.parsed.src) and event.parsed.src != self.bridge_mac:
                print "received packet from unrecorded mac address"
                return

        if event.parsed.next.dstip.inNetwork(MULTICAST_SUBNET, MULTICAST_NETMASK):
            print "multicast"
            if event.parsed.next.dstip in self.multicast_ip:
                action = of.ofp_action_output(port=of.OFPP_FLOOD)  # @UndefinedVariable
                command = of.OFPFC_ADD  # @UndefinedVariable
                self.send_flow_modification(event, command, [action], timeout=30)
        # check if broadcast. Change nw_dst to 10.2.255.255
        if event.parsed.next.dstip.inNetwork(ROUTABLE_SUBNET, ROUTABLE_NETMASK) and ((event.parsed.next.dstip.toUnsigned(networkOrder=False) & 0x3) == 0x3):
            print "broadcast IP"
            nw_new = of.ofp_action_nw_addr()
            nw_new.type = of.OFPAT_SET_NW_DST  # @UndefinedVariable
            nw_new.nw_addr = IPAddr("10.2.255.255")
            out = of.ofp_action_output(port=of.OFPP_IN_PORT if event.ofp.in_port == 0 else 0)  # @UndefinedVariable
            actions = [out, nw_new]
            command = of.OFPFC_ADD  # @UndefinedVariable
            self.send_flow_modification(event, command, actions, timeout=30)
        dst_port = 0
        if event.parsed.next.dstip.inNetwork(ROUTABLE_SUBNET, ROUTABLE_NETMASK) and ((event.parsed.next.dstip.toUnsigned(networkOrder=False) & 0x01) == 0x01):
            dst_port = 1
        else:
            dst_port = 0
        actions = []
        is_dst_local = event.parsed.next.dstip.inNetwork(ROUTABLE_SUBNET, ROUTABLE_NETMASK) or event.parsed.next.dstip.inNetwork(INIT_SUBNET, INIT_NETMASK)
        if is_dst_local and is_src_local and (dst_port != 0) and (not is_src_router):
            dst_mac = self.get_DHCP_mapping().get_mac(event.parsed.next.dstip)

            new_dl_src = of.ofp_action_dl_addr()
            new_dl_src.type = of.OFPAT_SET_DL_SRC  # @UndefinedVariable
            new_dl_src.set_src(self.bridge_mac)
            actions.append(new_dl_src)

            new_dl_dst = of.ofp_action_dl_addr()
            new_dl_dst.type = of.OFPAT_SET_DL_DST  # @UndefinedVariable
            new_dl_dst.set_dst(dst_mac)
            actions.append(new_dl_dst)

        out = of.ofp_action_output(port=of.OFPP_FLOOD)  # @UndefinedVariable
        actions.append(out)
        if 0 < event.ofp.in_port and event.ofp.in_port < of.OFPP_MAX:  # @UndefinedVariable
            out_of_in = of.ofp_action_output(port=of.OFPP_IN_PORT)  # @UndefinedVariable
            actions.append(out_of_in)

        command = of.OFPFC_ADD  # @UndefinedVariable
        self.send_flow_modification(event, command, actions, timeout=30)
def packet_handler(event):
    global count_server
    packet = event.parsed

    # Only handle IPv4 flows
    if (not event.parsed.find("ipv4")):
        return event_cont

    message = of.ofp_flow_mod()
    message.match = of.ofp_match.from_packet(packet)

    # Handing requests routed to the Load Balancer Ip
    if (message.match.nw_dst != virtual_ip):
        return event_cont

    # Implemented Weighted Random Server Selection
    iterator = server_no % 6
    print iterator
    if (IPAddr(message.match.nw_src) in clients):
        iterator = clients[IPAddr(message.match.nw_src)]
        serverip = topology_server[iterator]['ip']
        selected_server_mac = topology_server[iterator]['mac']
        server_output = topology_server[iterator]['outport']
    elif (iterator < topology_server[0]['weight']):
        serverip = topology_server[0]['ip']
        selected_server_mac = topology_server[0]['mac']
        server_output = topology_server[0]['outport']
        clients[IPAddr(message.match.nw_src)] = 0
        server_no += 1
    elif (iterator <
          (topology_server[0]['weight'] + topology_server[1]['weight'])):
        serverip = topology_server[1]['ip']
        selected_server_mac = topology_server[1]['mac']
        server_output = topology_server[1]['outport']
        clients[IPAddr(message.match.nw_src)] = 1
        server_no += 1
    elif (iterator <
          (topology_server[0]['weight'] + topology_server[1]['weight'] +
           topology_server[2]['weight'])):
        serverip = topology_server[2]['ip']
        selected_server_mac = topology_server[2]['mac']
        server_output = topology_server[2]['outport']
        clients[IPAddr(message.match.nw_src)] = 2
        server_no += 1

    # Route followed to server
    message.buffer_id = event.ofp.buffer_id
    message.in_port = event.port

    message.actions.append(
        of.ofp_action_dl_addr(of.OFPAT_SET_DL_DST, selected_server_mac))
    message.actions.append(of.ofp_action_nw_addr(of.OFPAT_SET_NW_DST,
                                                 serverip))
    message.actions.append(of.ofp_action_output(port=server_output))
    event.connection.send(message)

    # Route from server to load balancer
    reply = of.ofp_flow_mod()
    reply.buffer_id = None
    reply.in_port = server_output

    reply.match = of.ofp_match()
    reply.match.dl_src = selected_server_mac
    reply.match.nw_src = serverip
    reply.match.tp_src = message.match.tp_dst

    reply.match.dl_dst = message.match.dl_src
    reply.match.nw_dst = message.match.nw_src
    reply.match.tp_dst = message.match.tp_src

    reply.actions.append(
        of.ofp_action_dl_addr(of.OFPAT_SET_DL_SRC, virtual_mac))
    reply.actions.append(of.ofp_action_nw_addr(of.OFPAT_SET_NW_SRC,
                                               virtual_ip))
    reply.actions.append(of.ofp_action_output(port=message.in_port))
    event.connection.send(reply)

    return EventHalt
예제 #21
0
    def _match_action(self, msg):

        if len(self.actions) == 1 and self.actions[0] == "":
            return

        for action in self.actions:

            action_name = action.split('=')[0]
            if action_name != "STRIP_VLAN":
                action_argu = action.split('=')[1]

            if (action_name == "OUTPUT"):
                msg.actions.append(of.ofp_action_output(port=int(action_argu)))

            elif (action_name == "ENQUEUE"):
                port = action_argu.split(':')[0]
                queue_id = action_argu.split(':')[1]
                msg.actions.append(
                    of.ofp_action_enqueue(port=int(port),
                                          queue_id=int(queue_id)))

            elif (action_name == "STRIP_VLAN"):
                msg.actions.append(of.ofp_action_strip_vlan())

            elif (action_name == "SET_VLAN_VID"):
                msg.actions.append(
                    of.ofp_action_vlan_vid(vlan_vid=int(action_argu)))

            elif (action_name == "SET_VLAN_PCP"):
                msg.actions.append(
                    of.ofp_action_vlan_pcp(vlan_pcp=int(action_argu)))

            elif (action_name == "SET_DL_SRC"):
                msg.actions.append(
                    of.ofp_action_dl_addr(type=4,
                                          dl_addr=EthAddr(action_argu)))

            elif (action_name == "SET_DL_DST"):
                msg.actions.append(
                    of.ofp_action_dl_addr(type=5,
                                          dl_addr=EthAddr(action_argu)))

            elif (action_name == "SET_NW_TOS"):
                msg.actions.append(
                    of.ofp_action_nw_tos(nw_tos=int(action_argu)))

            elif (action_name == "SET_NW_SRC"):
                msg.actions.append(
                    of.ofp_action_nw_addr(type=6, nw_addr=IPAddr(action_argu)))

            elif (action_name == "SET_NW_DST"):
                msg.actions.append(
                    of.ofp_action_nw_addr(type=7, nw_addr=IPAddr(action_argu)))

            elif (action_name == "SET_TP_SRC"):
                msg.actions.append(
                    of.ofp_action_tp_port(type=9, tp_port=int(action_argu)))

            elif (action_name == "SET_TP_DST"):
                msg.actions.append(
                    of.ofp_action_tp_port(type=10, tp_port=int(action_argu)))
예제 #22
0
    def _handle_PacketIn(self, event):

        balancer_ip = IPAddr("10.0.0.99")
        balancer_eth = EthAddr("00:00:00:00:00:99")

        packet = event.parsed
        packet_in = event.ofp

        flow = of.ofp_flow_mod()
        flow.match = of.ofp_match.from_packet(packet)
        flow.match.in_port = packet_in.in_port
        if flow.match.nw_src not in self.dicts:
            self.dicts[flow.match.nw_src] = packet_in.in_port
        if flow.match.nw_dst == balancer_ip:  # if the request is to balancer
            print("[Request]: From " + str(flow.match.nw_src) + " to " +
                  str(flow.match.nw_dst))

            if flow.match.in_port == self.ind + 1:  # if the chosen server is the same as the client
                self.ind = (self.ind + 1) % self.N  # shift the server id

            ethnum = str(hex(self.ind + 1))
            if self.ind < 15:
                ethnum = "0" + ethnum[2:len(ethnum)]
            else:
                ethnum = ethnum[2:len(ethnum)]
            ipnum = str(self.ind + 1)

            server_port = self.ind + 1
            server_ip = IPAddr("10.0.0." + ipnum)
            server_eth = EthAddr("00:00:00:00:00:" + ethnum)
            print("The chosen server is " + str(server_ip))
            print(server_eth)

            flow.buffer_id = packet_in.buffer_id

            new_ip_dst = of.ofp_action_nw_addr(7, server_ip)
            new_eth_dst = of.ofp_action_dl_addr(5, server_eth)

            action = of.ofp_action_output(port=server_port)
            flow.actions.append(new_ip_dst)
            flow.actions.append(new_eth_dst)
            self.ind = (self.ind + 1) % self.N

            flow.idle_timeout = of.OFP_FLOW_PERMANENT
            flow.hard_timeout = of.OFP_FLOW_PERMANENT
            flow.priority = 65535

            flow.actions.append(action)
            event.connection.send(flow)
            flow.command = of.OFPFC_DELETE
            event.connection.send(flow)

            # indicate the current server and client info
            self.cur_client = packet_in.in_port
            self.cur_ser = server_port
            self.request = 1
        else:
            if flow.match.nw_dst in self.dicts:
                outport = self.dicts[flow.match.nw_dst]
            else:
                outport = of.OFPP_ALL
            if outport == self.cur_client and self.request == 1:
                #response message

                new_ip_src = of.ofp_action_nw_addr(6, balancer_ip)
                new_eth_src = of.ofp_action_dl_addr(4, balancer_eth)

                action = of.ofp_action_output(port=outport)

                flow.buffer_id = packet_in.buffer_id

                flow.idle_timeout = of.OFP_FLOW_PERMANENT
                flow.hard_timeout = of.OFP_FLOW_PERMANENT
                flow.priority = 65535

                flow.actions.append(new_ip_src)
                flow.actions.append(new_eth_src)
                flow.actions.append(action)
                event.connection.send(flow)
                flow.command = of.OFPFC_DELETE
                event.connection.send(flow)

                print("[Response]: Server " + str(self.cur_ser) + " response")

                self.cur_ser = -1
                self.cur_client = -1
                self.request = 0

            else:
                action = of.ofp_action_output(port=outport)
                flow.idle_timeout = of.OFP_FLOW_PERMANENT
                flow.hard_timeout = of.OFP_FLOW_PERMANENT
                flow.priority = 65535

                flow.actions.append(action)
                if event.ofp.buffer_id != -1:
                    flow.buffer_id = event.ofp.buffer_id
                event.connection.send(flow)
                print("Normal Message from " + str(flow.match.nw_src) +
                      " to " + str(flow.match.nw_dst))
                flow.command = of.OFPFC_DELETE
                event.connection.send(flow)

        return
예제 #23
0
def packet_handler (event):
    global count_server 
    packet = event.parsed

    # Only handle IPv4 flows
    if (not event.parsed.find("ipv4")):
        return event_cont

    message = of.ofp_flow_mod()
    message.match = of.ofp_match.from_packet(packet)

    # Only handle traffic destined to virtual IP
    if (message.match.nw_dst != load_balancer_hardcoded_ip):
        return event_cont

    # Implementing Weighted Round robin Server Selection 
    iterator = count_server % 6
    print iterator
    if(iterator < topology_server[0]['weight']):
        serverip = topology_server[0]['ip']
        selected_server_mac = topology_server[0]['mac']
        server_output = topology_server[0]['outport']
    elif(iterator < (topology_server[0]['weight']+topology_server[1]['weight'])):
        serverip = topology_server[1]['ip']
        selected_server_mac = topology_server[1]['mac']
        server_output = topology_server[1]['outport']
    elif(iterator < (server[0]['weight']+server[1]['weight']+server[2]['weight'])):
        serverip = server[2]['ip']
        selected_server_mac = server[2]['mac']
        server_output = server[2]['outport']
    count_server += 1
 # Route followed to server
    message.buffer_id = event.ofp.buffer_id
    message.in_port = event.port

    message.actions.append(of.ofp_action_dl_addr(of.OFPAT_SET_DL_DST, selected_server_mac))
    message.actions.append(of.ofp_action_nw_addr(of.OFPAT_SET_NW_DST, serverip))
    message.actions.append(of.ofp_action_output(port = server_output))
    event.connection.send(message)

   
    # Route from server to load balancer
    reply = of.ofp_flow_mod()
    reply.buffer_id = None
    reply.in_port = server_output

    reply.match = of.ofp_match()
    reply.match.dl_src = selected_server_mac
    reply.match.nw_src = serverip
    reply.match.tp_src = message.match.tp_dst

    reply.match.dl_dst = message.match.dl_src
    reply.match.nw_dst = message.match.nw_src
    reply.match.tp_dst = message.match.tp_src

    reply.actions.append(of.ofp_action_dl_addr(of.OFPAT_SET_DL_SRC, load_balancer_hardcoded_mac))
    reply.actions.append(of.ofp_action_nw_addr(of.OFPAT_SET_NW_SRC, load_balancer_hardcoded_ip))
    reply.actions.append(of.ofp_action_output(port = message.in_port))
    event.connection.send(reply)

    return EventHalt
예제 #24
0
    def handle_IPPacket(self, event):
        is_src_router = (event.ofp.in_port == of.OFPP_LOCAL)
        if event.parsed.next.srcip.inNetwork(NON_ROUTABLE_SUBNET,
                                             NON_ROUTABLE_NETMASK):
            print "source ip is not routable"
            return
        if event.parsed.src != self.bridge_mac and not self.check_access(
                event.parsed.src):
            print "%s is not permmited" % (str(event.parsed.src))
            return
        if event.parsed.next.dstip.inNetwork(NON_ROUTABLE_SUBNET,
                                             NON_ROUTABLE_NETMASK):
            print "destination is not routable"
            return
        is_src_local = event.parsed.next.srcip.inNetwork(
            ROUTABLE_SUBNET,
            ROUTABLE_NETMASK) or event.parsed.next.srcip.inNetwork(
                INIT_SUBNET, INIT_NETMASK)
        if is_src_local and (event.parsed.next.srcip.toUnsigned(
                networkOrder=False) & 0x3) == 1:
            if not self.get_DHCP_mapping().is_valid_mapping(
                    event.parsed.next.srcip,
                    event.parsed.src) and event.parsed.src != self.bridge_mac:
                print "received packet from unrecorded mac address"
                return

        if event.parsed.next.dstip.inNetwork(MULTICAST_SUBNET,
                                             MULTICAST_NETMASK):
            print "multicast"
            if event.parsed.next.dstip in self.multicast_ip:
                action = of.ofp_action_output(port=of.OFPP_FLOOD)
                command = of.OFPFC_ADD
                self.send_flow_modification(event,
                                            command, [action],
                                            timeout=30)
        # check if broadcast. Change nw_dst to 10.2.255.255
        if event.parsed.next.dstip.inNetwork(
                ROUTABLE_SUBNET, ROUTABLE_NETMASK) and (
                    (event.parsed.next.dstip.toUnsigned(networkOrder=False)
                     & 0x3) == 0x3):
            print "broadcast IP"
            nw_new = of.ofp_action_nw_addr()
            nw_new.type = of.OFPAT_SET_NW_DST
            nw_new.nw_addr = IPAddr("10.2.255.255")
            out = of.ofp_action_output(
                port=of.OFPP_IN_PORT if event.ofp.in_port == 0 else 0)
            actions = [out, nw_new]
            command = of.OFPFC_ADD
            self.send_flow_modification(event, command, actions, timeout=30)
        dst_port = 0
        if event.parsed.next.dstip.inNetwork(
                ROUTABLE_SUBNET, ROUTABLE_NETMASK) and (
                    (event.parsed.next.dstip.toUnsigned(networkOrder=False)
                     & 0x01) == 0x01):
            dst_port = 1
        else:
            dst_port = 0
        actions = []
        is_dst_local = event.parsed.next.dstip.inNetwork(
            ROUTABLE_SUBNET,
            ROUTABLE_NETMASK) or event.parsed.next.dstip.inNetwork(
                INIT_SUBNET, INIT_NETMASK)
        if is_dst_local and is_src_local and (dst_port !=
                                              0) and (not is_src_router):
            dst_mac = self.get_DHCP_mapping().get_mac(event.parsed.next.dstip)

            new_dl_src = of.ofp_action_dl_addr()
            new_dl_src.type = of.OFPAT_SET_DL_SRC
            new_dl_src.set_src(self.bridge_mac)
            actions.append(new_dl_src)

            new_dl_dst = of.ofp_action_dl_addr()
            new_dl_dst.type = of.OFPAT_SET_DL_DST
            new_dl_dst.set_dst(dst_mac)
            actions.append(new_dl_dst)

        out = of.ofp_action_output(port=of.OFPP_FLOOD)
        actions.append(out)
        if 0 < event.ofp.in_port and event.ofp.in_port < of.OFPP_MAX:
            out_of_in = of.ofp_action_output(port=of.OFPP_IN_PORT)
            actions.append(out_of_in)

        command = of.OFPFC_ADD
        self.send_flow_modification(event, command, actions, timeout=30)
예제 #25
0
	    # Setup route to server
        setup_route_to_server(event,msg_to_server,server_mac,server_ip,server_outport)
	
        # Setup reverse route from server
        setup_route_from_server(event,msg_to_server,server_mac,server_ip,server_outport)	
	    return EventHalt
    else:
	    return EventContinue


    
def setup_route_to_server(event,msg_to_server,server_mac,server_ip,server_outport):
	    msg_to_server.buffer_id = event.ofp.buffer_id
    	msg_to_server.in_port = event.port
    	msg_to_server.actions.append(of.ofp_action_dl_addr(of.OFPAT_SET_DL_DST, server_mac))
        msg_to_server.actions.append(of.ofp_action_nw_addr(of.OFPAT_SET_NW_DST, server_ip))
        msg_to_server.actions.append(of.ofp_action_output(port = server_outport))
    	event.connection.send(msg_to_server)

        
def setup_route_from_server(event,msg_to_server,server_mac,server_ip,server_outport):	
	    global ServerUsed    
    	msg_from_server = of.ofp_flow_mod()
    	msg_from_server.buffer_id = None
    	msg_from_server.in_port = server_outport

    	msg_from_server.match = of.ofp_match()
    	msg_from_server.match.dl_src = server_mac
    	msg_from_server.match.nw_src = server_ip
    	msg_from_server.match.tp_src = msg_to_server.match.tp_dst
예제 #26
0
    def _modify_flow(self, command_type):

        msg = of.ofp_flow_mod()
        print self.payload
        if command_type == "MOD_ST":
            msg.command = of.OFPFC_MODIFY_STRICT
        elif command_type == "MOD":
            msg.command = of.OFPFC_MODIFY

        if self.payload.has_key("wildcards"):
            msg.match.wildcards = int(self.payload['wildcards'])

        if self.payload.has_key("dstIP"):
            msg.match.nw_dst = IPAddr(self.payload['dstIP'])

        if self.payload.has_key("srcMac"):
            msg.match.dl_src = EthAddr(self.payload['srcMac'])

        if self.payload.has_key("srcIP"):
            msg.match.nw_src = IPAddr(self.payload['srcIP'])

        if self.payload.has_key("dstMac"):
            msg.match.dl_dst = EthAddr(self.payload['dstMac'])

        if self.payload.has_key("hardTimeout"):
            msg.hard_timeout = int(self.payload['hardTimeout'])

        if self.payload.has_key("srcPort"):
            msg.match.tp_src = int(self.payload['srcPort'])

        if self.payload.has_key("priority"):
            msg.priority = int(self.payload['priority'])

        if self.payload.has_key("ingressPort"):
            msg.match.in_port = int(self.payload['ingressPort'])

        if self.payload.has_key("vlan"):
            msg.match.dl_vlan = int(self.payload['vlan'])

        if self.payload.has_key("ether-type"):
            msg.match.dl_type = int(self.payload['ether-type'])

        if self.payload.has_key("duration"):
            msg.duration_sec = int(self.payload['duration'])

        if self.payload.has_key("idleTimeout"):
            msg.idle_timeout = int(self.payload['idleTimeout'])

        if self.payload.has_key("netProtocol"):
            msg.match.nw_proto = int(self.payload['netProtocol'])

        self.dpid = self.payload['switch'].replace(':', '-')[6:]
        self._parse_actions(self.payload['actions'])

        for connection in core.openflow._connections.values():

            # print dpidToStr(connection.dpid)
            conn_dpid = str(dpidToStr(connection.dpid))
            print conn_dpid
            if conn_dpid == self.dpid:
                """match actions"""
                if (self.actions == "OUTPUT"):
                    msg.actions.append(
                        of.ofp_action_output(port=int(self.actions_argu)))

                elif (self.actions == "enqueue"):
                    port = self.actions_argu.split(':')[0]
                    queue_id = self.actions_argu.split(':')[1]
                    msg.actions.append(
                        of.ofp_action_enqueue(port=int(port),
                                              queue_id=int(queue_id)))

                elif (self.actions == "strip-vlan"):
                    msg.actions.append(of.ofp_action_strip_vlan())

                elif (self.actions == "set-vlan-id"):
                    msg.actions.append(
                        of.ofp_action_vlan_vid(
                            vlan_vid=int(self.actions_argu)))

                elif (self.actions == "set-vlan-priority"):
                    msg.actions.append(
                        of.ofp_action_vlan_pcp(
                            vlan_pcp=int(self.actions_argu)))

                elif (self.actions == "SET_DL_SRC"):
                    msg.actions.append(
                        of.ofp_action_dl_addr(type=4,
                                              dl_addr=EthAddr(
                                                  self.actions_argu)))

                elif (self.actions == "SET_DL_DST"):
                    msg.actions.append(
                        of.ofp_action_dl_addr(type=5,
                                              dl_addr=EthAddr(
                                                  self.actions_argu)))

                elif (self.actions == "SET_NW_TOS"):
                    msg.actions.append(
                        of.ofp_action_nw_tos(nw_tos=int(self.actions_argu)))

                elif (self.actions == "SET_NW_SRC"):
                    msg.actions.append(
                        of.ofp_action_nw_addr(type=6,
                                              nw_addr=IPAddr(
                                                  self.actions_argu)))

                elif (self.actions == "SET_NW_DST"):
                    msg.actions.append(
                        of.ofp_action_nw_addr(type=7,
                                              nw_addr=IPAddr(
                                                  self.actions_argu)))

                elif (self.actions == "SET_TP_SRC"):
                    msg.actions.append(
                        of.ofp_action_tp_port(type=9,
                                              tp_port=int(self.actions_argu)))

                elif (self.actions == "SET_TP_DST"):
                    msg.actions.append(
                        of.ofp_action_tp_port(type=10,
                                              tp_port=int(self.actions_argu)))

                connection.send(msg)
예제 #27
0
  def _modify_flow(self,command_type):
    
    msg = of.ofp_flow_mod()
    print self.payload
    if command_type == "MOD_ST":
      msg.command = of.OFPFC_MODIFY_STRICT
    elif command_type == "MOD":
      msg.command = of.OFPFC_MODIFY

    if self.payload.has_key("wildcards"):
      msg.match.wildcards = int(self.payload['wildcards'])
    
    if self.payload.has_key("dstIP"):
      msg.match.nw_dst = IPAddr(self.payload['dstIP'])
    
    if self.payload.has_key("srcMac"):
      msg.match.dl_src = EthAddr(self.payload['srcMac'])
    
    if self.payload.has_key("srcIP"):
      msg.match.nw_src = IPAddr(self.payload['srcIP'])
    
    if self.payload.has_key("dstMac"):
      msg.match.dl_dst = EthAddr(self.payload['dstMac'])
    
    if self.payload.has_key("hardTimeout"):
      msg.hard_timeout = int(self.payload['hardTimeout'])
    
    if self.payload.has_key("srcPort"):
      msg.match.tp_src = int(self.payload['srcPort'])
    
    if self.payload.has_key("priority"):
      msg.priority = int(self.payload['priority'])
    
    if self.payload.has_key("ingressPort"):
      msg.match.in_port = int(self.payload['ingressPort'])
    
    if self.payload.has_key("vlan"):
      msg.match.dl_vlan = int(self.payload['vlan'])
    
    if self.payload.has_key("ether-type"):
      msg.match.dl_type = int(self.payload['ether-type'])
    
    if self.payload.has_key("duration"):
      msg.duration_sec = int(self.payload['duration'])
    
    if self.payload.has_key("idleTimeout"):
      msg.idle_timeout = int(self.payload['idleTimeout'])
    
    if self.payload.has_key("netProtocol"):
      msg.match.nw_proto = int(self.payload['netProtocol'])


    self.dpid = self.payload['switch'].replace(':','-')[6:]
    self._parse_actions(self.payload['actions'])

    for connection in core.openflow._connections.values() :

      # print dpidToStr(connection.dpid)
      conn_dpid = str(dpidToStr(connection.dpid))
      print conn_dpid
      if conn_dpid == self.dpid:
        """match actions"""
        if(self.actions == "OUTPUT"):
          msg.actions.append(of.ofp_action_output(port = int(self.actions_argu)))
        
        elif(self.actions == "enqueue"):
          port = self.actions_argu.split(':')[0]
          queue_id = self.actions_argu.split(':')[1]
          msg.actions.append(of.ofp_action_enqueue(port = int(port) , queue_id = int(queue_id)))
        
        elif(self.actions == "strip-vlan"):
          msg.actions.append(of.ofp_action_strip_vlan())
        
        elif(self.actions == "set-vlan-id"):
          msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = int(self.actions_argu)))
        
        elif(self.actions == "set-vlan-priority"):
          msg.actions.append(of.ofp_action_vlan_pcp(vlan_pcp = int(self.actions_argu)))
        
        elif(self.actions == "SET_DL_SRC"):
          msg.actions.append(of.ofp_action_dl_addr(type = 4 , dl_addr = EthAddr(self.actions_argu)))
        
        elif(self.actions == "SET_DL_DST"):
          msg.actions.append(of.ofp_action_dl_addr(type = 5 , dl_addr = EthAddr(self.actions_argu)))
        
        elif(self.actions == "SET_NW_TOS"):
          msg.actions.append(of.ofp_action_nw_tos(nw_tos = int(self.actions_argu)))

        elif(self.actions == "SET_NW_SRC"):
          msg.actions.append(of.ofp_action_nw_addr(type = 6 , nw_addr = IPAddr(self.actions_argu)))

        elif(self.actions == "SET_NW_DST"):
          msg.actions.append(of.ofp_action_nw_addr(type = 7 , nw_addr = IPAddr(self.actions_argu)))

        elif(self.actions == "SET_TP_SRC"):
          msg.actions.append(of.ofp_action_tp_port(type = 9 , tp_port = int(self.actions_argu)))
        
        elif(self.actions == "SET_TP_DST"):
          msg.actions.append(of.ofp_action_tp_port(type = 10 , tp_port = int(self.actions_argu)))

        connection.send(msg)
예제 #28
0
    def _handle_PacketIn(self, event):
        """
    Handle packet in messages from the switch to implement above algorithm.
    """#52:54:00:79:95:26 26:6a:fb:3c:f8:fd
        cptv = server_infos(conf.captive_portal.ip, conf.captive_portal.mac,
                            conf.captive_portal.switch_port,
                            conf.captive_portal.tcp_port
                            )  #"130.192.225.168","52:54:00:79:95:26",5,8085)
        #cptv = server_infos("130.192.225.156","88:51:fb:42:2b:f8",5,8080)

        if self.connection.dpid not in switchs_info:
            lock.acquire()
            try:
                dpi = DPI()
                dpi.setDPI(self.connection.dpid)
                # add a new switch to our infos
                switchs_info[self.connection.dpid] = switch_infos(
                    self.connection)
            finally:
                lock.release()  # release lock, no matter what

        switch = switchs_info[self.connection.dpid]
        if event.port not in switch.ports_info:
            lock.acquire()
            try:
                #print (dpid_to_str(self.connection.dpid))
                #print self.connection.sock.getpeername()[0]
                switch.ports_info[event.port] = port_infos(event.port)
            finally:
                lock.release()  # release lock, no matter what

            #if event.port == conf.my_infos.my_default_GRE_tunnel:
            is_user_port = True
            log.info("Comparing the ports speaking " + str(event.port))
            for not_user_port in conf.my_infos.not_user_ports:
                if str(event.port) == str(not_user_port):
                    is_user_port = False
                    break

            if not is_user_port:
                log.info("Event port is " + str(event.port))
                log.info("First for the ethernet interface")
                # First rule: allow all traffic
                self.connection.send(
                    of.ofp_flow_mod(
                        action=of.ofp_action_output(port=of.OFPP_NORMAL),
                        priority=1,
                        match=of.ofp_match(in_port=event.port)))
            else:
                """
            Packet from user
            """
                log.info("First packet from user")
                # First rule: drop all traffic
                msg = of.ofp_flow_mod()
                msg.priority = 1
                msg.match.in_port = event.port
                msg.actions.append(of.ofp_action_output(port=of.OFPP_NONE))
                self.connection.send(msg)
                # Second rule: normal process for DNS traffic
                msg = of.ofp_flow_mod()
                msg.priority = 100
                msg.match.in_port = event.port
                msg.match.dl_type = 0x800
                msg.match.nw_proto = 17
                msg.match.tp_dst = 53
                msg.actions.append(of.ofp_action_output(port=of.OFPP_NORMAL))
                #msg.data = event.ofp
                self.connection.send(msg)
                # Third rule: normal process for ARP traffic
                msg = of.ofp_flow_mod()
                msg.priority = 100
                msg.match.in_port = event.port
                msg.match.dl_type = 0x806
                msg.actions.append(of.ofp_action_output(port=of.OFPP_NORMAL))
                #msg.data = event.ofp
                self.connection.send(msg)
                # Fourth rule: normal process for DHCPDISCOVER
                msg = of.ofp_flow_mod()
                msg.priority = 100
                msg.match.in_port = event.port
                msg.match.dl_type = 0x800
                msg.match.nw_proto = 17
                msg.match.nw_src = "0.0.0.0"
                msg.match.nw_dst = "255.255.255.255"
                msg.match.tp_src = 68
                msg.match.tp_dst = 67
                msg.actions.append(of.ofp_action_output(port=of.OFPP_NORMAL))
                #msg.data = event.ofp
                self.connection.send(msg)
                # Fifth rule: send the HTTP traffic to the controller
                msg = of.ofp_flow_mod()
                msg.priority = 1000
                msg.match.in_port = event.port
                msg.match.dl_type = 0x800
                msg.match.nw_proto = 6
                msg.match.tp_dst = 80
                msg.actions.append(
                    of.ofp_action_output(port=of.OFPP_CONTROLLER))
                msg.data = event.ofp
                self.connection.send(msg)

        packet = event.parsed
        if not packet.parsed:
            log.info("ignoring unparsed packet")
            return

        client_list = switch.ports_info[event.port].clients_info
        log.info("LOOP Thread id: " + str(thread.get_ident()))
        log.debug("packet.type: " + str(packet.type) +
                  " || pkt.ethernet.IP_TYPE: " + str(pkt.ethernet.IP_TYPE))
        if packet.type == pkt.ethernet.IP_TYPE:
            ipv4_hdr = packet.payload
            log.debug("ipv4_hdr.protocol: " + str(ipv4_hdr.protocol) +
                      " || pkt.ipv4.TCP_PROTOCOL: " +
                      str(pkt.ipv4.TCP_PROTOCOL))
            if ipv4_hdr.protocol == pkt.ipv4.TCP_PROTOCOL:
                tcp_hdr = ipv4_hdr.payload
                log.info("tcp_hdr.dstport: " + str(tcp_hdr.dstport) +
                         " || DestPort: || 80")
                if tcp_hdr.dstport == 80:
                    log.debug("packet.src: " + str(packet.src))

                    if packet.src not in client_list:
                        log.info("packet.src is not in client_list")
                        lock.acquire()
                        try:
                            log.info("save host info: IP=" +
                                     str(ipv4_hdr.srcip) + ", MAC=" +
                                     str(packet.src) +
                                     ", INGRESS_SWITCH_PORT=" +
                                     str(switch.infos.ports[event.port].name))
                            client_list[packet.src] = host_infos(
                                ipv4_hdr.srcip, packet.src, event.port, 0)
                        finally:
                            lock.release()  # release lock, no matter what
                    else:
                        log.debug("PACKET_IN INFOs: user MAC: " +
                                  str(packet.src) + ", user IP: " +
                                  str(ipv4_hdr.srcip))
                        user_infos = client_list[packet.src]
                        user_ip = user_infos.IP
                        log.debug("Local informations: user MAC: " +
                                  str(packet.src) + ", user IP: " +
                                  str(user_ip))
                        if user_ip != ipv4_hdr.srcip:
                            log.debug("Updating client IP informations")
                            user_infos.IP = ipv4_hdr.srcip

                    client = client_list[packet.src]
                    if (client.flag_auth == 0):
                        log.info(
                            "installing new flow to set destination IP to captive portal IP"
                        )
                        msg = of.ofp_flow_mod()
                        msg.priority = 10000
                        msg.idle_timeout = 30
                        msg.match.dl_type = 0x800
                        msg.match.dl_src = client.MAC
                        msg.match.nw_proto = 6
                        #Adding the match on the TCP source port of the user, in order to genererate a PACKET_IN for every
                        #new TCP connection
                        msg.match.tp_src = tcp_hdr.srcport
                        msg.match.tp_dst = 80
                        msg.match.nw_dst = ipv4_hdr.dstip
                        msg.match.in_port = event.port
                        msg.actions.append(
                            of.ofp_action_dl_addr(of.OFPAT_SET_DL_DST,
                                                  cptv.MAC))
                        msg.actions.append(
                            of.ofp_action_nw_addr(of.OFPAT_SET_NW_DST,
                                                  cptv.IP))
                        msg.actions.append(
                            of.ofp_action_tp_port(of.OFPAT_SET_TP_DST,
                                                  cptv.port))
                        msg.actions.append(
                            of.ofp_action_output(port=cptv.switch_port))
                        #msg.data = event.ofp
                        self.connection.send(msg)
                        log.info("installing new flow to set return path")
                        msg = of.ofp_flow_mod()
                        msg.priority = 10000
                        msg.idle_timeout = 30
                        msg.match.dl_type = 0x800
                        msg.match.nw_proto = 6
                        msg.match.tp_dst = tcp_hdr.srcport
                        msg.match.nw_dst = ipv4_hdr.srcip
                        msg.match.nw_src = cptv.IP
                        msg.actions.append(
                            of.ofp_action_nw_addr(of.OFPAT_SET_NW_SRC,
                                                  ipv4_hdr.dstip))
                        msg.actions.append(
                            of.ofp_action_tp_port(of.OFPAT_SET_TP_SRC,
                                                  tcp_hdr.dstport))
                        msg.actions.append(
                            of.ofp_action_output(port=event.port))
                        msg.data = event.ofp
                        self.connection.send(msg)
                    '''
예제 #29
0
    def _handle_PacketIn(self, event):

        # parsing the input packet
        packet = event.parse()

        # If no switch has ever seen this host before, then it must be directly
        # connected to us!  Record that in our global list.
        if packet.src not in self.hostlocations or self.hostlocations[
                packet.src]["lastseen"] < (datetime.now() -
                                           timedelta(0, IDLE_TIMEOUT)):
            #log.debug("s%s takes ownership of host %s" % (self.connection.ID, packet.src))
            self.hostlocations[packet.src] = {
                "ID": self.connection.ID,
                "lastseen": datetime.now()
            }

            # Record which hosts exists on which of our ports
            ip = GetIPFromMAC(packet.src)
            if ip is not None:
                #log.debug("    on IP '%s'" % ip)
                self.hostports[event.port] = packet.src

        elif self.hostlocations[packet.src]["ID"] == self.connection.ID:
            #log.debug("s%s continues to own host %s" % (datetime.now(), self.connection.ID, packet.src))
            self.hostlocations[packet.src]["lastseen"] = datetime.now()

        # Keep a list of which MAC addresses live on which port, so we can forward
        # packets as needed
        if packet.src not in self.mactable or self.mactable[
                packet.src] != event.ofp.in_port:
            self.mactable[packet.src] = event.ofp.in_port
            #log.debug("Learned port %s connects to %s" % (event.ofp.in_port, packet.src))

        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

        # Watch for ARP packets trying to discover a load-balance target.
        packet_arp = packet.find('arp')
        if packet_arp is not None and str(
                packet_arp.protodst).startswith(LOADBALANCE_TARGET):
            # Found one!  Respond with a special MAC address, which our switches will
            # be able to identify easily for load-balancing.
            #log.debug('ARP Packet!!!! Looking for %s' % packet_arp.protodst)
            mac = GetMACForLoadBalancing()

            reply_arp = arp()
            reply_arp.hwtype = packet_arp.hwtype
            reply_arp.prototype = packet_arp.prototype
            reply_arp.hwlen = packet_arp.hwlen
            reply_arp.protolen = packet_arp.protolen
            reply_arp.opcode = arp.REPLY
            reply_arp.hwdst = packet_arp.hwsrc
            reply_arp.hwsrc = mac
            reply_arp.protodst = packet_arp.protosrc
            reply_arp.protosrc = packet_arp.protodst
            reply_eth = ethernet(type=packet.type,
                                 src=mac,
                                 dst=packet_arp.hwsrc)
            reply_eth.payload = reply_arp
            reply = of.ofp_packet_out(in_port=of.OFPP_NONE)
            reply.actions.append(of.ofp_action_output(port=event.port))
            reply.data = reply_eth.pack()
            event.connection.send(reply)
            return

        # If this packet is being delivered to a special MAC, set up some flows to
        # get the data to the right place.
        packet_ipv4 = packet.find('ipv4')
        if IsMACForLoadBalancing(packet.dst) and packet_ipv4 is not None:
            eligibleports = []
            for port in self.connection.features.ports:
                if port.port_no != event.port and not port.config & OFPPC_PORT_DOWN:
                    eligibleports.append(port.port_no)
            port_out = random.choice(eligibleports)

            # Establish bi-directional flows!
            log.debug("Establishing load-balancing flows for %s <--> %s" %
                      (packet.src, packet.dst))
            flow_in = of.ofp_flow_mod()
            flow_out = of.ofp_flow_mod()
            flow_in.idle_timeout = flow_out.idle_timeout = IDLE_TIMEOUT
            flow_in.hard_timeout = flow_out.hard_timeout = HARD_TIMEOUT
            flow_in.match = of.ofp_match(dl_dst=packet.src, dl_src=packet.dst)
            flow_out.match = of.ofp_match(dl_dst=packet.dst, dl_src=packet.src)

            if port_out in self.hostports:
                # If we're delivering to a host (instead of another switch), we need
                # to rewrite some of the packet data, so that things line up properly
                # on each end.  The sender sends to the special IP, and the receiver
                # should see the packet addressed to itself (and vice versa).
                log.debug("...which will be handled by %s" %
                          (self.hostports[port_out]))
                flow_in.actions.append(
                    of.ofp_action_dl_addr(of.OFPAT_SET_DL_SRC, packet.dst))
                flow_in.actions.append(
                    of.ofp_action_nw_addr(of.OFPAT_SET_NW_SRC,
                                          packet_ipv4.dstip))
                flow_out.actions.append(
                    of.ofp_action_dl_addr(of.OFPAT_SET_DL_DST,
                                          self.hostports[port_out]))
                flow_out.actions.append(
                    of.ofp_action_nw_addr(
                        of.OFPAT_SET_NW_DST,
                        GetIPFromMAC(self.hostports[port_out])))

                # We also need to update one of our match rules, since the packet will
                # be sent with a non-special MAC address.
                flow_in.match.dl_src = self.hostports[port_out]

            flow_in.actions.append(of.ofp_action_output(port=event.port))
            flow_out.actions.append(of.ofp_action_output(port=port_out))
            flow_in.in_port = port_out
            flow_out.in_port = event.port
            flow_out.data = event.ofp
            self.connection.send(flow_in)
            self.connection.send(flow_out)
            return

        elif packet.dst in self.mactable:
            # If we know the destination, but are being told about it, recreate the
            # flow, since this is either the initial discovery, or the flow expired.
            log.debug(
                "Establishing flow to deliver packets for %s to port %s" %
                (packet.dst, self.mactable[packet.dst]))
            fm = of.ofp_flow_mod()
            fm.idle_timeout = IDLE_TIMEOUT
            fm.hard_timeout = HARD_TIMEOUT
            fm.actions.append(
                of.ofp_action_output(port=self.mactable[packet.dst]))

            # Defining the match via from_packet will cause us to establish a flow
            # for each unique packet type per destination, instead of just per dest.
            fm.match = of.ofp_match(dl_dst=packet.dst, dl_src=packet.src)
            #fm.match = of.ofp_match.from_packet(packet)

            fm.data = event.ofp  # Deliver the packet along this flow
            self.connection.send(fm)
            return

        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)