def _handle_ConnectionUp (event):
  # Set up this switch.

  # Turn on ability to specify table in flow_mods
  msg = nx.nx_flow_mod_table_id()
  event.connection.send(msg)

  # Clear second table
  msg = nx.nx_flow_mod(command=of.OFPFC_DELETE, table_id = 1)
  event.connection.send(msg)

  # Learning rule in table 0
  msg = nx.nx_flow_mod()
  msg.table_id = 0

  learn = nx.nx_action_learn(table_id=1,hard_timeout=10)
  learn.spec.chain(
      field=nx.NXM_OF_VLAN_TCI, n_bits=12).chain(
      field=nx.NXM_OF_ETH_SRC, match=nx.NXM_OF_ETH_DST).chain(
      field=nx.NXM_OF_IN_PORT, output=True)

  msg.actions.append(learn)
  msg.actions.append(nx.nx_action_resubmit.resubmit_table(1))
  event.connection.send(msg)

  # Fallthrough rule for table 1: flood
  msg = nx.nx_flow_mod()
  msg.table_id = 1
  msg.priority = 1 # Low priority
  msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD))
  event.connection.send(msg)
Exemple #2
0
def del_tables(con):
    msg = nx.nx_flow_mod(table_id = 0, command=of.OFPFC_DELETE)
    con.send(msg)
    msg = nx.nx_flow_mod(table_id = 1, command=of.OFPFC_DELETE)
    con.send(msg)
    msg = nx.nx_flow_mod(table_id = 2, command=of.OFPFC_DELETE)
    con.send(msg)
def _handle_ConnectionUp(event):
    # Set up this switch.

    # Turn on ability to specify table in flow_mods
    msg = nx.nx_flow_mod_table_id()
    event.connection.send(msg)

    # Clear second table
    msg = nx.nx_flow_mod(command=of.OFPFC_DELETE, table_id=1)
    event.connection.send(msg)

    # Learning rule in table 0
    msg = nx.nx_flow_mod()
    msg.table_id = 0

    learn = nx.nx_action_learn(table_id=1, hard_timeout=10)
    learn.spec.chain(field=nx.NXM_OF_VLAN_TCI,
                     n_bits=12).chain(field=nx.NXM_OF_ETH_SRC,
                                      match=nx.NXM_OF_ETH_DST).chain(
                                          field=nx.NXM_OF_IN_PORT, output=True)

    msg.actions.append(learn)
    msg.actions.append(nx.nx_action_resubmit.resubmit_table(1))
    event.connection.send(msg)

    # Fallthrough rule for table 1: flood
    msg = nx.nx_flow_mod()
    msg.table_id = 1
    msg.priority = 1  # Low priority
    msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD))
    event.connection.send(msg)
Exemple #4
0
def _handle_PacketIn (event):
    global inter_arrival_sum
    global flow_count
    global old_arrival
    global avg_inter_arrival_time
    global inter_arrival_time
    global avg_inter_arrival
    global process_time_sum
    global process_time_avg
    global total_flows
    
    #start timing the controller processing
    controller_start = time.time()
    #count the incoming flows within an interval. it will get re-initialized every interval
    flow_count= flow_count + 1
    #keep track of the total number of flows
    total_flows = total_flows + 1
    #get the flow arrival time
    current_arrival = time.time()
    #calculate the inter-arrival time
    inter_arrival_time = current_arrival - old_arrival
    #get the average
    inter_arrival_sum = inter_arrival_sum + inter_arrival_time
    old_arrival = current_arrival

    packet = event.parsed
 
    # reactive flow installation in table 0
    msg = nx.nx_flow_mod()
    if (actual_observe < 2):
        msg.match.of_eth_src = packet.dst
        msg.match.of_eth_dst = packet.src
        msg.idle_timeout = 4
        msg.flags = of.OFPFF_SEND_FLOW_REM
        msg.actions.append(of.ofp_action_output(port = event.port))
        core.openflow.sendToDPID(event.dpid, msg)
        
        #install entries in backup table (table 1) with long enough TTL
        msg = nx.nx_flow_mod()
        msg.match.of_eth_src = packet.dst
        msg.match.of_eth_dst = packet.src
        msg.table_id = 1
        msg.flags = of.OFPFF_SEND_FLOW_REM
        msg.actions.append(of.ofp_action_output(port = event.port))
        core.openflow.sendToDPID(event.dpid, msg)
    
    # if controller is loaded then resubmit from table 0 to table 1 (backup table)
    # Now flows will use table 1 only without communicating with the controller
    # to communicate with the controller again, we need to let the flows expire from table 1 after some time 
    # (decided based on how long time the CPU load needs to cool down)
    else:
        msg.actions.append(nx.nx_action_resubmit.resubmit_table(table = 1))
        core.openflow.sendToDPID(event.dpid, msg)
    
    # stop timing the controller processing time
    controller_end = time.time()
    process_time = controller_end - controller_start
    process_time_sum = process_time_sum + process_time
Exemple #5
0
    def flow_mod_action(self,pred,priority,action_list,cookie,command,notify,table_id):
        switch = pred['switch']
        """ Set `inport` from matching predicate """
        if 'port' in pred:
            inport = pred['port']
        else:
            inport = None
        if self.use_nx:
            match = self.build_nx_match(switch,inport,pred,table_id)
        else:
            match = self.build_of_match(switch,inport,pred)
        if self.use_nx:
            debug = False # use for debugging specific rules in build_nx_actions
            of_actions = self.build_nx_actions(inport, action_list, table_id,
                                               self.pipeline, debug=debug)
        else:
            debug = False # use for debugging specific rules in build_of_actions
            of_actions = self.build_of_actions(inport, action_list, debug=debug)

        flags = 0
        if notify:
            flags = of.OFPFF_SEND_FLOW_REM

        if 'ethtype' in pred and pred['ethtype']==0x86dd:
            msg = nx.nx_flow_mod(command=command,
                                 priority=priority,
                                 idle_timeout=of.OFP_FLOW_PERMANENT,
                                 hard_timeout=of.OFP_FLOW_PERMANENT,
                                 match=nx.nx_match(match),
                                 flags=flags,
                                 cookie=cookie,
                                 actions=of_actions)

        elif self.use_nx:
            msg = nx.nx_flow_mod(command=command,
                                 priority=priority,
                                 idle_timeout=of.OFP_FLOW_PERMANENT,
                                 hard_timeout=of.OFP_FLOW_PERMANENT,
                                 match=match,
                                 flags=flags,
                                 cookie=cookie,
                                 actions=of_actions,
                                 table_id=table_id)

        else:
            msg = of.ofp_flow_mod(command=command,
                                  priority=priority,
                                  idle_timeout=of.OFP_FLOW_PERMANENT,
                                  hard_timeout=of.OFP_FLOW_PERMANENT,
                                  match=match,
                                  flags=flags,
                                  cookie=cookie,
                                  actions=of_actions)
        try:
            self.switches[switch]['connection'].send(msg)
        except RuntimeError, e:
            print "WARNING:install_flow: %s to switch %d" % (str(e),switch)
Exemple #6
0
    def flow_mod_action(self,pred,priority,action_list,cookie,command,notify,table_id):
        switch = pred['switch']
        """ Set `inport` from matching predicate """
        if 'port' in pred:
            inport = pred['port']
        else:
            inport = None
        if self.use_nx:
            match = self.build_nx_match(switch,inport,pred,table_id)
        else:
            match = self.build_of_match(switch,inport,pred)
        if self.use_nx:
            of_actions = self.build_nx_actions(inport, action_list, table_id,
                                               self.pipeline)
        else:
            of_actions = self.build_of_actions(inport, action_list)

        flags = 0
        if notify:
            flags = of.OFPFF_SEND_FLOW_REM

        if 'ethtype' in pred and pred['ethtype']==0x86dd:
            msg = nx.nx_flow_mod(command=command,
                                 priority=priority,
                                 idle_timeout=of.OFP_FLOW_PERMANENT,
                                 hard_timeout=of.OFP_FLOW_PERMANENT,
                                 match=nx.nx_match(match),
                                 flags=flags,
                                 cookie=cookie,
                                 actions=of_actions)

        elif self.use_nx:
            msg = nx.nx_flow_mod(command=command,
                                 priority=priority,
                                 idle_timeout=of.OFP_FLOW_PERMANENT,
                                 hard_timeout=of.OFP_FLOW_PERMANENT,
                                 match=match,
                                 flags=flags,
                                 cookie=cookie,
                                 actions=of_actions,
                                 table_id=table_id)

        else:
            msg = of.ofp_flow_mod(command=command,
                                  priority=priority,
                                  idle_timeout=of.OFP_FLOW_PERMANENT,
                                  hard_timeout=of.OFP_FLOW_PERMANENT,
                                  match=match,
                                  flags=flags,
                                  cookie=cookie,
                                  actions=of_actions)
        try:
            self.switches[switch]['connection'].send(msg)
        except RuntimeError, e:
            print "WARNING:install_flow: %s to switch %d" % (str(e),switch)
Exemple #7
0
    def __init__(self, connection):

        topo = TopologyManager()
        self.connection = connection
        connection.addListeners(self)
        l = {}
        print(topo.switches)

        if (connection.eth_addr.toStr() in topo.switches):
            print("Connected")
            for k, v in topo.links.items():
                if connection.eth_addr.toStr() in v:
                    i = 1
                    for k, v in l.items():
                        print('Installing rule for link', k, 'table', i)
                        msg = nx.nx_flow_mod_table_id()
                        connection.send(msg)
                        # table 0
                        msg = nx.nx_flow_mod()
                        msg.table_id = 0
                        msg.priority = 1500
                        msg.match.of_eth_dst = "00:00:00:00:00:00"
                        msg.match.of_eth_type = 0x86dd
                        msg.match.of_in_port = v[0]
                        msg.actions.append(
                            nx.nx_action_resubmit.resubmit_table(table=0))
                        self.connection.send(msg)

                        msg = nx.nx_flow_mod()
                        msg.table_id = 0
                        msg.priority = 1000
                        msg.match.of_eth_dst = "00:00:00:00:00:00"
                        msg.match.of_eth_type = 0x86dd
                        msg.match.nx_ipv6_dst = (IPAddr6("::2"),
                                                 IPAddr6("::2"))
                        msg.actions.append(of.ofp_action_output(port=v[1]))
                        msg.actions.append(
                            nx.nx_action_resubmit.resubmit_table(table=0))
                        self.connection.send(msg)
                        if i != topo.links.__len__():
                            msg = nx.nx_flow_mod()
                            msg.table_id = 0
                            msg.priority = 500
                            msg.match.of_eth_dst = "00:00:00:00:00:00"
                            msg.match.of_eth_type = 0x86dd
                            msg.actions.append(
                                nx.nx_action_resubmit.resubmit_table(table=1))
                            self.connection.send(msg)
                            i += 1
Exemple #8
0
    def _handle_ConnectionUp(self, event):
        assert event.dpid not in self.switches
        self.switches[event.dpid] = {}
        self.switches[event.dpid]['connection'] = event.connection
        self.switches[event.dpid]['ports'] = {}

        # Turn on Nicira packet_ins
        msg = nx.nx_packet_in_format()
        event.connection.send(msg)

        msg = nx.nx_flow_mod()
        msg.actions.append(of.ofp_action_output(port=of.OFPP_CONTROLLER))
        self.switches[event.dpid]['connection'].send(msg)

        #msg = of.ofp_flow_mod(match = of.ofp_match())
        #msg.actions.append(of.ofp_action_output(port = of.OFPP_CONTROLLER))
        #self.switches[event.dpid]['connection'].send(msg)

        self.send_to_pyretic(['switch', 'join', event.dpid, 'BEGIN'])

        # port type is ofp_phy_port
        for port in event.ofp.ports:
            if port.port_no <= of.OFPP_MAX:
                self.switches[event.dpid]['ports'][port.port_no] = port.hw_addr
                CONF_UP = not 'OFPPC_PORT_DOWN' in self.active_ofp_port_config(
                    port.config)
                STAT_UP = not 'OFPPS_LINK_DOWN' in self.active_ofp_port_state(
                    port.state)
                PORT_TYPE = self.active_ofp_port_features(port.curr)
                self.send_to_pyretic([
                    'port', 'join', event.dpid, port.port_no, CONF_UP, STAT_UP,
                    PORT_TYPE
                ])

        self.send_to_pyretic(['switch', 'join', event.dpid, 'END'])
    def _handle_ConnectionUp(self, event):
        assert event.dpid not in self.switches
        self.switches[event.dpid] = {}
        self.switches[event.dpid]['connection'] = event.connection
        self.switches[event.dpid]['ports'] = {}

        # Turn on Nicira packet_ins
        msg = nx.nx_packet_in_format()
        event.connection.send(msg)

        msg = nx.nx_flow_mod()
        msg.actions.append(of.ofp_action_output(port = of.OFPP_CONTROLLER))
        self.switches[event.dpid]['connection'].send(msg)

        #msg = of.ofp_flow_mod(match = of.ofp_match())
        #msg.actions.append(of.ofp_action_output(port = of.OFPP_CONTROLLER))
        #self.switches[event.dpid]['connection'].send(msg)

        self.send_to_pyretic(['switch','join',event.dpid,'BEGIN'])

        # port type is ofp_phy_port
        for port in event.ofp.ports:
            if port.port_no <= of.OFPP_MAX:
                self.switches[event.dpid]['ports'][port.port_no] = port.hw_addr
                CONF_UP = not 'OFPPC_PORT_DOWN' in self.active_ofp_port_config(port.config)
                STAT_UP = not 'OFPPS_LINK_DOWN' in self.active_ofp_port_state(port.state)
                PORT_TYPE = self.active_ofp_port_features(port.curr)
                self.send_to_pyretic(['port','join',event.dpid, port.port_no, CONF_UP, STAT_UP, PORT_TYPE])                        
   
        self.send_to_pyretic(['switch','join',event.dpid,'END'])
Exemple #10
0
    def flow_mod_action(self,pred,priority,action_list,cookie,command,notify):
        switch = pred['switch']
        if 'inport' in pred:        
            inport = pred['inport']
        else:
            inport = None
        match = self.build_of_match(switch,inport,pred)
        of_actions = self.build_of_actions(inport,action_list)
        flags = 0
        if notify:
            flags = of.OFPFF_SEND_FLOW_REM

        if 'ethtype' in pred and pred['ethtype']==0x86dd:
            msg = nx.nx_flow_mod(command=command,
                                 priority=priority,
                                 idle_timeout=of.OFP_FLOW_PERMANENT,
                                 hard_timeout=of.OFP_FLOW_PERMANENT,
                                 match=nx.nx_match(match),
                                 flags=flags,
                                 cookie=cookie,
                                 actions=of_actions)
        else:
            msg = of.ofp_flow_mod(command=command,
                                  priority=priority,
                                  idle_timeout=of.OFP_FLOW_PERMANENT,
                                  hard_timeout=of.OFP_FLOW_PERMANENT,
                                  match=match,
                                  flags=flags,
                                  cookie=cookie,
                                  actions=of_actions)
        try:
            self.switches[switch]['connection'].send(msg)
        except RuntimeError, e:
            print "WARNING:install_flow: %s to switch %d" % (str(e),switch)
Exemple #11
0
 def add_route(self, connection, ip, mask, port, priority=100):
     msg = nx.nx_flow_mod()
     msg.priority = priority
     msg.match.append(nx.NXM_OF_ETH_TYPE(0x800))
     msg.match.append(nx.NXM_OF_IP_DST(ip, mask))
     msg.actions.append(of.ofp_action_output(port=port))
     connection.send(msg)
Exemple #12
0
 def _handle_ConnectionUp(self, event):
     msg = nx.nx_packet_in_format()
     event.connection.send(msg)
     msg = nx.nx_flow_mod_table_id()
     event.connection.send(msg)
     msg = nx.nx_flow_mod(command=of.OFPFC_DELETE)
     msg.table_id = 1
     event.connection.send(msg)
Exemple #13
0
 def _handle_ConnectionUp(self, event):
     msg = nx.nx_packet_in_format()
     event.connection.send(msg)
     msg = nx.nx_flow_mod_table_id()
     event.connection.send(msg)
     msg = nx.nx_flow_mod(command = of.OFPFC_DELETE)
     msg.table_id = 1
     event.connection.send(msg)
Exemple #14
0
    def _handle_PacketIn(self, event):
    
        packet = event.parsed
        #the flood method
        def flood(switch):      
            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
            switch.send(msg)
    
    #the drop method
        def drop(switch):
            msg = of.ofp_packet_out()
            msg.buffer_id = event.ofp.buffer_id
            msg.in_port = event.port
            switch.send(msg)
        
        ip = packet.find("ipv4")
        if ip == None:
            ip = packet.find("icmp")

        if ip:
            if not self.iptable.has_key(ip.srcip):
                self.iptable[ip.srcip] = packet.src

        if not self.mactable.has_key(packet.src):
             self.mactable[packet.src] = (event.dpid, event.port)
    
        if packet.type == packet.LLDP_TYPE or packet.dst.isBridgeFiltered():
            drop(event.connection)
            return
        if packet.dst.is_multicast:
            flood(event.connection)
        else:
            if not self.mactable.has_key(packet.dst):
	        flood(event.connection)
            else:
	        routelist = RouteApp.get_shortest_route(pox.openflow.spanning_tree._calc_spanning_tree(), event.dpid, self.mactable[packet.dst][0])
	        routelist[-1] = self.mactable[packet.dst]
	        msg = of.ofp_packet_out()
                msg.data = event.ofp
                msg.actions.append(of.ofp_action_output(port = routelist[0][1]))
                event.connection.send(msg) 
	        for switchid,out_port in routelist:
	            msg = nx.nx_flow_mod()
                    msg.table_id = 0
                    msg.priority = LOW
	            msg.match.eth_dst = packet.dst
	            msg.actions.append(of.ofp_action_output(port = out_port))
                    #msg.actions.append(nx.nx_action_resubmit.resubmit_table(table = 1))
                    msg.idle_timeout = 10
                    msg.hard_timeout = 30
	            switch = core.openflow.getConnection(switchid)
	            switch.send(msg)
Exemple #15
0
def _handle_new_host(org_mac, ip, dpid, port):
    con = core.openflow.connections[dpid]
    pmac = _assign_pmac(dpid, port - 1, org_mac)
    #i guess nothing more to do here. in multi table, the switch would have sent here and replied to the host.
    msg = nx.nx_flow_mod(table_id = 0)
    msg.priority = 5000
    msg.match.NXM_OF_IN_PORT = port
    msg.match.eth_src = org_mac
    msg.actions.append(of.ofp_action_dl_addr.set_src(adrs.EthAddr(pmac)))
    msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=1))
    con.send(msg)
    msg = nx.nx_flow_mod(table_id = 1)
    msg.priority = 5000
    msg.match.eth_dst = pmac
    msg.actions.append(of.ofp_action_dl_addr.set_dst(adrs.EthAddr(org_mac)))
    msg.actions.append(of.ofp_action_output(port = port))
    con.send(msg)
    return pmac
Exemple #16
0
def _handle_ConnectionUp (event):
    # Set up this switch.
    # After setting up, we send a barrier and wait for the response
    # before starting to listen to packet_ins for this switch -- before
    # the switch is set up, the packet_ins may not be what we expect,
    # and our responses may not work!
    
    # Turn on Nicira packet_ins
    msg = nx.nx_packet_in_format()
    event.connection.send(msg)
    
    # Turn on ability to specify table in flow_mods
    msg = nx.nx_flow_mod_table_id()
    event.connection.send(msg)
    
    # Clear second table
    msg = nx.nx_flow_mod(command=of.OFPFC_DELETE, table_id = 1)
    event.connection.send(msg)
    
    # Fallthrough rule for table 0: flood and send to controller
    msg = nx.nx_flow_mod()
    msg.priority = 1 # Low priority
    
    
    msg.actions.append(of.ofp_action_output(port = of.OFPP_CONTROLLER))
    msg.actions.append(nx.nx_action_resubmit.resubmit_table(table = 1))
    event.connection.send(msg)
    
    # Fallthrough rule for table 1: flood
    msg = nx.nx_flow_mod()
    msg.table_id = 1
    msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD))
    event.connection.send(msg)
    
    def ready (event):
        if event.ofp.xid != 0x80000000:
            # Not the right barrier
            return
        log.info("%s ready", event.connection)
        event.connection.addListenerByName("PacketIn", _handle_PacketIn)
        return EventRemove
    
    event.connection.send(of.ofp_barrier_request(xid=0x80000000))
    event.connection.addListenerByName("BarrierIn", ready)
Exemple #17
0
def _handle_ConnectionUp(event):
    # Set up this switch.
    # After setting up, we send a barrier and wait for the response
    # before starting to listen to packet_ins for this switch -- before
    # the switch is set up, the packet_ins may not be what we expect,
    # and our responses may not work!

    # Turn on Nicira packet_ins
    msg = nx.nx_packet_in_format()
    event.connection.send(msg)

    # Turn on ability to specify table in flow_mods
    msg = nx.nx_flow_mod_table_id()
    event.connection.send(msg)

    # Clear second table
    msg = nx.nx_flow_mod(command=of.OFPFC_DELETE, table_id=1)
    event.connection.send(msg)

    # Fallthrough rule for table 0: flood and send to controller
    msg = nx.nx_flow_mod()
    msg.priority = 1  # Low priority
    msg.actions.append(of.ofp_action_output(port=of.OFPP_CONTROLLER))
    msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=1))
    event.connection.send(msg)

    # Fallthrough rule for table 1: flood
    msg = nx.nx_flow_mod()
    msg.table_id = 1
    msg.priority = 1  # Low priority
    msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD))
    event.connection.send(msg)

    def ready(event):
        if event.ofp.xid != 0x80000000:
            # Not the right barrier
            return
        log.info("%s ready", event.connection)
        event.connection.addListenerByName("PacketIn", _handle_PacketIn)
        return EventRemove

    event.connection.send(of.ofp_barrier_request(xid=0x80000000))
    event.connection.addListenerByName("BarrierIn", ready)
Exemple #18
0
 def clear(self,switch=None,table_id=0):
     if switch is None:
         for switch in self.switches.keys():
             self.clear(switch)
     else:
         if self.use_nx:
             d = nx.nx_flow_mod(command = of.OFPFC_DELETE, table_id=table_id)
         else:
             d = of.ofp_flow_mod(command = of.OFPFC_DELETE)
         self.switches[switch]['connection'].send(d) 
Exemple #19
0
 def clear(self,switch=None,table_id=0):
     if switch is None:
         for switch in self.switches.keys():
             self.clear(switch)
     else:
         if self.use_nx:
             d = nx.nx_flow_mod(command = of.OFPFC_DELETE, table_id=table_id)
         else:
             d = of.ofp_flow_mod(command = of.OFPFC_DELETE)
         self.switches[switch]['connection'].send(d) 
Exemple #20
0
def _handle_migration(event):
    eth_pkt = event.parsed
    arp_pkt = event.parsed.payload
    org_mac = eth_pkt.src.toStr()
    dst_ip = arp_pkt.protodst.toStr()
    #old_pmac = arp_table[dst_ip]
    old_pmac = actual_pmac[org_mac]
    sw, port = pmac_pos(old_pmac)
    if (sw != event.dpid) or (port+1 != event.port):
        '''
        this host has migrated.
        assign new pmac.
        add trans in new switch.
        remove prev trans tabbles from old switch.
        add entry in old switch to frwrd to some agg switch replacing old pmac with new pmac
        update our internal tables
        change the assigned mac string - not assign the old pmac for the timeout period of time
        '''
        new_pmac = _handle_new_host(org_mac, dst_ip, event.dpid, event.port)
        msg = nx.nx_flow_mod(table_id = 0, command=of.OFPFC_DELETE)
        msg.priority = 5000
        msg.match.eth_src = org_mac
        event.connection.send(msg)
        msg = nx.nx_flow_mod(table_id = 1, command=of.OFPFC_DELETE)
        msg.priority = 5000
        msg.match.eth_dst = old_pmac
        event.connection.send(msg)
        
        msg = nx.nx_flow_mod(table_id = 0)
        msg.priority = 8000
        msg.hard_timeout = arp_timeout
        msg.match.eth_dst = old_pmac
        msg.actions.append(of.ofp_action_dl_addr.set_dst(adrs.EthAddr(new_pmac)))
        msg.actions.append(of.ofp_action_output(port = switch_pos(event.dpid)[1] + 1 ))#simple hashing. edge switch x sends to agg switch x
        event.connection.send(msg)
        
        arp_table[dst_ip] = new_pmac
        actual_pmac.pop(pmac_actual[old_pmac])
        pmac_actual.pop(old_pmac)
        #this nxt 2 lines should be in a fn called after the timeout. we dont want to assing old pmac to anyone until then
        vmid = int(s[-5:].replace(':',''),16)
        assigned_pmac[event.dpid][event.port] = assigned_pmac[event.dpid][event.port][:vmid] + '0' + assigned_pmac[event.dpid][event.port][vmid + 1:]
Exemple #21
0
def install_icmp_entry(event, psrc):
    # first add entries for ICMP
    # Add to destination table. This is now table 0
    msg = nx.nx_flow_mod()
    msg.match = nx.nx_match()  # pld: see pox dox "Using nx_match"
    msg.table_id = 0
    msg.match.append(nx.NXM_OF_ETH_DST(psrc))
    msg.match.append(nx.NXM_OF_ETH_TYPE(pkt.ethernet.IP_TYPE))
    msg.match.append(nx.NXM_OF_IP_PROTO(pkt.ipv4.ICMP_PROTOCOL))

    msg.actions.append(of.ofp_action_output(port=event.port))
    msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=1))
    event.connection.send(msg)

    # Now add to source table. This is now table 1
    msg = nx.nx_flow_mod()
    msg.match = nx.nx_match()  # pld: see pox dox "Using nx_match"
    msg.table_id = 1
    msg.match.append(nx.NXM_OF_ETH_SRC(psrc))
    msg.match.append(nx.NXM_OF_ETH_TYPE(pkt.ethernet.IP_TYPE))
    msg.match.append(nx.NXM_OF_IP_PROTO(pkt.ipv4.ICMP_PROTOCOL))
    # empty action list here, meaning no longer send to the controller
    event.connection.send(msg)

    # now add similar entries for ARP

    msg = nx.nx_flow_mod()
    msg.match = nx.nx_match()  # pld: see pox dox "Using nx_match"
    msg.table_id = 0
    msg.match.append(nx.NXM_OF_ETH_DST(psrc))
    msg.match.append(nx.NXM_OF_ETH_TYPE(pkt.ethernet.ARP_TYPE))
    msg.actions.append(of.ofp_action_output(port=event.port))
    msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=1))
    event.connection.send(msg)

    msg = nx.nx_flow_mod()
    msg.match = nx.nx_match()  # pld: see pox dox "Using nx_match"
    msg.table_id = 1
    msg.match.append(nx.NXM_OF_ETH_SRC(psrc))
    msg.match.append(nx.NXM_OF_ETH_TYPE(pkt.ethernet.ARP_TYPE))
    # again an empty action list
    event.connection.send(msg)
Exemple #22
0
 def __nx_switch_pipeline_init(self, dpid, p):
     """ Initialize switch `dpid` according to the input pipeline
     configuration `p`. """
     """ Clear all tables; install default actions. """
     for t in range(0, p.num_tables):
         msg = nx.nx_flow_mod(command=of.OFPFC_DELETE, table_id=t)
         self.switches[dpid]['connection'].send(msg)
         msg = nx.nx_flow_mod()
         msg.table_id = t
         msg.priority = 1
         msg.match = nx.nx_match()
         if (t+1) < p.num_tables and t in p.edges:
             """ If not last table in the pipeline, fallthrough to next. """
             dst_t = p.edges[t]
             msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=dst_t))
         else:
             """ If last table in pipeline, or no further edges, send to
             controller. """
             msg.actions.append(of.ofp_action_output(port=of.OFPP_CONTROLLER))
         self.switches[dpid]['connection'].send(msg)
Exemple #23
0
 def __nx_switch_pipeline_init(self, dpid, p):
     """ Initialize switch `dpid` according to the input pipeline
     configuration `p`. """
     """ Clear all tables; install default actions. """
     for t in range(0, p.num_tables):
         msg = nx.nx_flow_mod(command=of.OFPFC_DELETE, table_id=t)
         self.switches[dpid]['connection'].send(msg)
         msg = nx.nx_flow_mod()
         msg.table_id = t
         msg.priority = 1
         msg.match = nx.nx_match()
         if (t+1) < p.num_tables and t in p.edges:
             """ If not last table in the pipeline, fallthrough to next. """
             dst_t = p.edges[t]
             msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=dst_t))
         else:
             """ If last table in pipeline, or no further edges, send to
             controller. """
             msg.actions.append(of.ofp_action_output(port=of.OFPP_CONTROLLER))
         self.switches[dpid]['connection'].send(msg)
def _handle_PacketIn (event):
  packet = event.parsed

  if event.port > of.OFPP_MAX:
    log.debug("Ignoring special port %s", event.port)
    return

  # Add to source table
  msg = nx.nx_flow_mod()
  msg.match.of_eth_src = packet.src
  msg.actions.append(nx.nx_action_resubmit.resubmit_table(table = 1))
  event.connection.send(msg)

  # Add to destination table
  msg = nx.nx_flow_mod()
  msg.table_id = 1
  msg.match.of_eth_dst = packet.src
  msg.actions.append(of.ofp_action_output(port = event.port))
  event.connection.send(msg)

  log.info("Learning %s on port %s of %s"
           % (packet.src, event.port, event.connection))
Exemple #25
0
def _handle_PacketIn(event):
    packet = event.parsed

    if event.port > of.OFPP_MAX:
        log.debug("Ignoring special port %s", event.port)
        return

    # Add to source table
    msg = nx.nx_flow_mod()
    msg.match.of_eth_src = packet.src
    msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=1))
    event.connection.send(msg)

    # Add to destination table
    msg = nx.nx_flow_mod()
    msg.table_id = 1
    msg.match.of_eth_dst = packet.src
    msg.actions.append(of.ofp_action_output(port=event.port))
    event.connection.send(msg)

    log.info("Learning %s on port %s of %s" %
             (packet.src, event.port, event.connection))
Exemple #26
0
 def reset(self, addr):
     self.action_triggered = False
     self.monitorlist[addr] -= 1
     if self.monitorlist[addr] > 0:
         return
     self.monitorlist[addr] = 0
     log.info("resetting %s"%addr)
     msg = nx.nx_flow_mod()
     msg.command = of.OFPFC_DELETE_STRICT
     msg.table_id = 1
     ipaddr = IPAddr(addr)
     host_mac = self.iptable[ipaddr]
     msg.match.eth_src = host_mac
     switchid = self.mactable[host_mac][0]
     switch = core.openflow.getConnection(switchid)
     switch.send(msg)
     self.action_triggered = True
Exemple #27
0
 def reset(self, addr):
     self.action_triggered = False
     self.monitorlist[addr] -= 1
     if self.monitorlist[addr] > 0:
         return
     self.monitorlist[addr] = 0
     log.info("resetting %s" % addr)
     msg = nx.nx_flow_mod()
     msg.command = of.OFPFC_DELETE_STRICT
     msg.table_id = 1
     ipaddr = IPAddr(addr)
     host_mac = self.iptable[ipaddr]
     msg.match.eth_src = host_mac
     switchid = self.mactable[host_mac][0]
     switch = core.openflow.getConnection(switchid)
     switch.send(msg)
     self.action_triggered = True
	def modify_flow_table(self, **kwargs):
		"""
		The method will modify flow tables of the openflow switch as per arguments.
		It takes variable number of named arguments, these names must match with
		the names defined in static dictionaries of this class.
		"""

		match = nx_match()
		flowmod = nx_flow_mod()
		prelen = len(kwargs) + 1
		while(len(kwargs) < prelen):
			prelen = len(kwargs)
			prekey = None
			for key in kwargs.keys():
				value = kwargs[key]
				if(prekey != None):
					kwargs.pop(prekey)
					prekey = None
				try:
					if(self.match_attributes.has_key(key)):
						record = self.match_attributes[key]
						if((record[0] == None) or self._verify_attributes(match, record[0], record[1])):
							if(record[2] and (type(value) is str) and (value.find("/") != -1)):
								fields = value.split("/")
								match.__setattr__(key, record[-1](fields[0]))
								match.__setattr__(key + "_mask", record[-1](fields[1]))
							else:
								match.__setattr__(key, value)
							prekey = key
					elif(self.flowmod_attributes.has_key(key)):
						flowmod.__setattr__(key, value)
						prekey = key
					elif(self.action_attributes.has_key(key)):
						record = self.action_attributes[key]
						if(record[1]):
							flowmod.actions.append(record[0](**value))
						else:
							flowmod.actions.append(record[0]())
						prekey = key
				except Exception as e:
					return
			if(len(kwargs) == prelen):
				break
		flowmod.match = match
		print flowmod
Exemple #29
0
 def unredirect(self, addr):
     self.action_triggered = False
     self.redirectlist[addr] -= 1
     if self.redirectlist[addr] > 0:
         return
     self.redirectlist[addr] = 0
     log.info("unredirecting %s"%addr)
     msg = nx.nx_flow_mod()
     msg.command = of.OFPFC_DELETE_STRICT
     msg.table_id = 1
     serv_name = ip2serv_name[addr]
     Masterip = serv_name2ip[serv_name]
     Masteraddr = IPAddr(Masterip)
     host_mac = self.iptable[Masteraddr]
     msg.match.eth_dst = host_mac
     msg.match.of_ip_src = Masterip
     switchid = self.mactable[gateway_mac][0]
     switch = core.openflow.getConnection(switchid)
     switch.send(msg)
     self.action_triggered = True
Exemple #30
0
 def unredirect(self, addr):
     self.action_triggered = False
     self.redirectlist[addr] -= 1
     if self.redirectlist[addr] > 0:
         return
     self.redirectlist[addr] = 0
     log.info("unredirecting %s" % addr)
     msg = nx.nx_flow_mod()
     msg.command = of.OFPFC_DELETE_STRICT
     msg.table_id = 1
     serv_name = ip2serv_name[addr]
     Masterip = serv_name2ip[serv_name]
     Masteraddr = IPAddr(Masterip)
     host_mac = self.iptable[Masteraddr]
     msg.match.eth_dst = host_mac
     msg.match.of_ip_src = Masterip
     switchid = self.mactable[gateway_mac][0]
     switch = core.openflow.getConnection(switchid)
     switch.send(msg)
     self.action_triggered = True
Exemple #31
0
def addTCPrule(switch, flow, port):
    assert (port
            in switch.hmap) or (port
                                in switch.nmap), "{}: unknown port {}".format(
                                    switch, port)
    psrc = flow.ethsrc
    pdst = flow.ethdst
    msg = nx.nx_flow_mod()
    msg.match = nx.nx_match()  # pld: see pox dox "Using nx_match"
    msg.table_id = 0
    msg.idle_timeout = TCP_IDLE_TIMEOUT
    msg.match.append(nx.NXM_OF_ETH_SRC(flow.ethsrc))
    msg.match.append(nx.NXM_OF_ETH_DST(flow.ethdst))
    msg.match.append(nx.NXM_OF_ETH_TYPE(pkt.ethernet.IP_TYPE))
    msg.match.append(nx.NXM_OF_IP_PROTO(pkt.ipv4.TCP_PROTOCOL))
    msg.match.append(nx.NXM_OF_IP_SRC(flow.srcip))
    msg.match.append(nx.NXM_OF_IP_DST(flow.dstip))
    msg.match.append(nx.NXM_OF_TCP_SRC(flow.srcport))
    msg.match.append(nx.NXM_OF_TCP_DST(flow.dstport))
    msg.actions.append(of.ofp_action_output(port=port))
    switch.connection().send(msg)
Exemple #32
0
    def _handle_ConnectionUp(self, event):
        # Initialize Nicira
        msg = nx.nx_flow_mod()
        event.connection.send(msg)
        
        # Signal Table use 
        msg = nx.nx_flow_mod_table_id()
        event.connection.send(msg)

        #Table 1 -> TCP Table 2 -> ARP
        for temp_table_id in range(1, 5):  
            msg = nx.nx_flow_mod(command=of.OFPFC_DELETE, table_id = temp_table_id)
            event.connection.send(msg)
    
        #Table 0 rule: Selection of tables
        #IP Packet Handling / TCP
        msg = nx.nx_flow_mod()
        msg.table_id = 0
        msg.match.eth_type = pkt.ethernet.IP_TYPE
        msg.match.ip_proto = ipv4.TCP_PROTOCOL
        msg.priority = 65000
        msg.actions.append(nx.nx_multipath(dst = nx.NXM_NX_REG2))
        msg.actions.append(nx.nx_action_resubmit.resubmit_table(table = 1))
        event.connection.send(msg)
 
        #ARP Packet Handling
        msg = nx.nx_flow_mod()
        msg.table_id = 0
        msg.priority = 65001
        msg.match.eth_type = pkt.ethernet.ARP_TYPE
        msg.actions.append(nx.nx_action_resubmit.resubmit_table(table = 4))
        event.connection.send(msg)
        log.info("Table 0 done")
     
        #Table 1 Rules 
        # TBD: State Machine and Hash value
        # New flow function
        msg = nx.nx_flow_mod()
        msg.table_id = 1
        msg.match.eth_type = pkt.ethernet.IP_TYPE
        msg.match.ip_proto = ipv4.TCP_PROTOCOL
        msg.priority = 65004
        # Signifying New flow
        msg.actions.append(nx.nx_reg_load(dst=nx.NXM_NX_REG0, value=0x0))
        # currently learning based on eth address
        # no hash
        msg.actions.append(nx.nx_action_resubmit.resubmit_table(table = 2))
        event.connection.send(msg)
 
        #Table 2 Rules

        #1. Sync (Should be a Sync)
        msg = nx.nx_flow_mod()
        msg.table_id = 2
        msg.match.eth_type = pkt.ethernet.IP_TYPE
        msg.match.ip_proto = ipv4.TCP_PROTOCOL
        msg.match.NXM_NX_REG0 = 0
        msg.match.tcp_flags = 2
        msg.priority = 65001
        # learn function for table 1
        learn = nx.nx_action_learn(table_id=1,priority=65111)
        learn.spec = [
            nx.flow_mod_spec(src=nx.nx_learn_src_field(nx.NXM_NX_REG2),
                             dst=nx.nx_learn_dst_match(nx.NXM_NX_REG2)),
        ]
        fms = nx.flow_mod_spec.new
        learn.spec.append(fms(load=nx.NXM_NX_REG0, src=nx.nx_learn_src_immediate.u32(None, 1)))
        learn.spec.append(fms(field=nx.NXM_NX_REG0, reserved=True ))
        msg.actions.append(learn)
        msg.actions.append(nx.nx_action_resubmit.resubmit_table(table = 3))
        event.connection.send(msg)

        #2. Sync Ack (Should be after sync)
        msg = nx.nx_flow_mod()
        msg.table_id = 2
        msg.match.eth_type = pkt.ethernet.IP_TYPE
        msg.match.ip_proto = ipv4.TCP_PROTOCOL
        msg.match.tcp_flags = 0x12
        msg.priority = 65002
        msg.match.NXM_NX_REG0 = 1
        # learn function for table 1
        learn = nx.nx_action_learn(table_id=1,priority=65111)
        learn.spec = [
            nx.flow_mod_spec(src=nx.nx_learn_src_field(nx.NXM_NX_REG2),
                             dst=nx.nx_learn_dst_match(nx.NXM_NX_REG2)),
        ]
        fms = nx.flow_mod_spec.new
        learn.spec.append(fms(load=nx.NXM_NX_REG0, src=nx.nx_learn_src_immediate.u32(None, 2)))
        learn.spec.append(fms(field=nx.NXM_NX_REG0, reserved=True ))
        msg.actions.append(learn)
        msg.actions.append(nx.nx_action_resubmit.resubmit_table(table = 3))
        event.connection.send(msg)

        
        #3. Ack
        msg = nx.nx_flow_mod()
        msg.table_id = 2
        msg.match.eth_type = pkt.ethernet.IP_TYPE
        msg.match.ip_proto = ipv4.TCP_PROTOCOL
        msg.match.tcp_flags = 0x010
        msg.priority = 65003
        msg.match.NXM_NX_REG0 = 2
        # learn function for table 1
        learn = nx.nx_action_learn(table_id=1,priority=65111)
        learn.spec = [
            nx.flow_mod_spec(src=nx.nx_learn_src_field(nx.NXM_NX_REG2),
                             dst=nx.nx_learn_dst_match(nx.NXM_NX_REG2)),
        ]
        fms = nx.flow_mod_spec.new
        learn.spec.append(fms(load=nx.NXM_NX_REG0, src=nx.nx_learn_src_immediate.u32(None, 3)))
        learn.spec.append(fms(field=nx.NXM_NX_REG0, reserved=True ))
        msg.actions.append(learn)
        msg.actions.append(nx.nx_action_resubmit.resubmit_table(table = 3))
        event.connection.send(msg)

        #4. Fin
        msg = nx.nx_flow_mod()
        msg.table_id = 2
        msg.match.eth_type = pkt.ethernet.IP_TYPE
        msg.match.ip_proto = ipv4.TCP_PROTOCOL
        msg.match.tcp_flags = 0x010
        msg.priority = 65003
        msg.match.NXM_NX_REG0 = 3
        # learn function for table 1
        learn = nx.nx_action_learn(table_id=1,priority=65111)
        learn.spec = [
            nx.flow_mod_spec(src=nx.nx_learn_src_field(nx.NXM_NX_REG2),
                             dst=nx.nx_learn_dst_match(nx.NXM_NX_REG2)),
        ]
        fms = nx.flow_mod_spec.new
        learn.spec.append(fms(load=nx.NXM_NX_REG0, src=nx.nx_learn_src_immediate.u32(None, 4)))
        learn.spec.append(fms(field=nx.NXM_NX_REG0, reserved=True ))
        msg.actions.append(learn)
        msg.actions.append(nx.nx_action_resubmit.resubmit_table(table = 3))
        event.connection.send(msg)


        #5. Fin-Ack
        msg = nx.nx_flow_mod()
        msg.table_id = 2
        msg.match.eth_type = pkt.ethernet.IP_TYPE
        msg.match.ip_proto = ipv4.TCP_PROTOCOL
        msg.match.tcp_flags = 0x010
        msg.priority = 65003
        msg.match.NXM_NX_REG0 = 4
        # learn function for table 1
        learn = nx.nx_action_learn(table_id=1,priority=65111)
        learn.spec = [
            nx.flow_mod_spec(src=nx.nx_learn_src_field(nx.NXM_NX_REG2),
                             dst=nx.nx_learn_dst_match(nx.NXM_NX_REG2)),
        ]
        fms = nx.flow_mod_spec.new
        learn.spec.append(fms(load=nx.NXM_NX_REG0, src=nx.nx_learn_src_immediate.u32(None, 5)))
        learn.spec.append(fms(field=nx.NXM_NX_REG0, reserved=True ))
        msg.actions.append(learn)
        msg.actions.append(nx.nx_action_resubmit.resubmit_table(table = 3))
        event.connection.send(msg)

        #7. Ack
        msg = nx.nx_flow_mod()
        msg.table_id = 2
        msg.match.eth_type = pkt.ethernet.IP_TYPE
        msg.match.ip_proto = ipv4.TCP_PROTOCOL
        msg.match.tcp_flags = 0x010
        msg.priority = 65003
        msg.match.NXM_NX_REG0 = 5
        # learn function for table 1
        learn = nx.nx_action_learn(table_id=1,priority=65111)
        learn.spec = [
            nx.flow_mod_spec(src=nx.nx_learn_src_field(nx.NXM_NX_REG2),
                             dst=nx.nx_learn_dst_match(nx.NXM_NX_REG2)),
        ]
        fms = nx.flow_mod_spec.new
        learn.spec.append(fms(load=nx.NXM_NX_REG0, src=nx.nx_learn_src_immediate.u32(None, 6)))
        learn.spec.append(fms(field=nx.NXM_NX_REG0, reserved=True ))
        msg.actions.append(learn)
        msg.actions.append(nx.nx_action_resubmit.resubmit_table(table = 3))
        event.connection.send(msg)

        #8. RST
        msg = nx.nx_flow_mod()
        msg.table_id = 2
        msg.match.eth_type = pkt.ethernet.IP_TYPE
        msg.match.ip_proto = ipv4.TCP_PROTOCOL
        msg.match.tcp_flags = 0x14
        msg.priority = 65003
        msg.actions.append(nx.nx_action_resubmit.resubmit_table(table = 3))
        event.connection.send(msg)

        #9. PSH-Ack
        msg = nx.nx_flow_mod()
        msg.table_id = 2
        msg.match.eth_type = pkt.ethernet.IP_TYPE
        msg.match.ip_proto = ipv4.TCP_PROTOCOL
        msg.match.tcp_flags = 0x18
        msg.priority = 65003
        msg.actions.append(nx.nx_action_resubmit.resubmit_table(table = 3))
        event.connection.send(msg)

        #9. Ack
        msg = nx.nx_flow_mod()
        msg.table_id = 2
        msg.match.eth_type = pkt.ethernet.IP_TYPE
        msg.match.ip_proto = ipv4.TCP_PROTOCOL
        msg.match.tcp_flags = 0x10
        msg.priority = 65003
        msg.actions.append(nx.nx_action_resubmit.resubmit_table(table = 3))
        event.connection.send(msg)

        #send to controller  currently sending to the destination as no old state stored
        msg = nx.nx_flow_mod()
        msg.table_id = 2
        msg.priority = 64999
        msg.actions.append(nx.nx_reg_load(dst=nx.NXM_NX_REG1, value=int(1)))
        msg.actions.append(nx.nx_action_resubmit.resubmit_table(table = 3))
        event.connection.send(msg)
        log.info("Table 2 done")


        #Table 3 Rules: Forward the packet to the Destination
        msg = nx.nx_flow_mod()
        msg.table_id = 3
        msg.match.eth_type = pkt.ethernet.IP_TYPE
        msg.match.ip_dst = "10.0.0.1"
        msg.priority = 65001
        msg.actions.append(of.ofp_action_output(port = 1))
        event.connection.send(msg)

        msg = nx.nx_flow_mod()
        msg.table_id = 3
        msg.match.eth_type = pkt.ethernet.IP_TYPE
        msg.match.ip_dst = "10.0.0.2"
        msg.priority = 65001
        msg.actions.append(of.ofp_action_output(port = 2))
        event.connection.send(msg)

        msg = nx.nx_flow_mod()
        msg.table_id = 3
        msg.match.eth_type = pkt.ethernet.IP_TYPE
        msg.match.ip_dst = "10.0.0.3"
        msg.priority = 65001
        msg.actions.append(of.ofp_action_output(port = 3))
        event.connection.send(msg)
       
        #send to controller 
        msg = nx.nx_flow_mod()
        msg.table_id = 3
        msg.match.NXM_NX_REG1 = 1 
        msg.priority = 65005
        msg.actions.append(of.ofp_action_output(port = of.OFPP_CONTROLLER))
        event.connection.send(msg)
        log.info("Table 3 done")
        
        #Table 4 Rules 
        msg = nx.nx_flow_mod()
        msg.table_id = 4
        msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD))
        event.connection.send(msg)
        log.info("Table 4 done")
Exemple #33
0
def _handle_ConnectionUp(event):
    # Initialize the forwarding rules for this switch.
    # After setting up, we send a barrier and wait for the response
    # before starting to listen to packet_ins for this switch -- before
    # the switch is set up, the packet_ins may not be what we expect,
    # and our responses may not work!

    connection = event.connection
    dpid = connection.dpid
    print "handle_ConnectionUP from dpid", dpid, util.dpid_to_str(dpid)
    portlist = connection.ports.values()
    # get port_no of each item in portlist
    portlist = map(lambda x: x.port_no, portlist)
    portlist = filter(lambda x: x < of.OFPP_MAX, portlist)
    # Turn on Nicira packet_ins
    msg = nx.nx_packet_in_format()
    connection.send(msg)
    # Turn on this switch's ability to specify tables in flow_mods
    msg = nx.nx_flow_mod_table_id()
    connection.send(msg)
    # Clear first table
    msg = nx.nx_flow_mod(command=of.OFPFC_DELETE, table_id=0)
    connection.send(msg)
    # Clear second table
    msg = nx.nx_flow_mod(command=of.OFPFC_DELETE, table_id=1)
    connection.send(msg)

    # this version sets default flooding actions only for ICMP and ARP packets
    # (though there IS a rule to send unknown packets to the controller)
    # Default rule for table 0: flood (IF a flooder) and send to table 1
    # Default rule for table 1: send to controller
    # Default rule for table 0 starts here
    msgi = nx.nx_flow_mod()  # icmp msg
    msga = nx.nx_flow_mod()  # arp msg
    msgi.table_id = msga.table_id = 0
    msgi.priority = msga.priority = 1  # Low priority
    msgi.idle_timeout = msga.idle_timeout = ICMP_IDLE_TIMEOUT

    msgi.match.append(nx.NXM_OF_ETH_TYPE(pkt.ethernet.IP_TYPE))
    msgi.match.append(nx.NXM_OF_IP_PROTO(pkt.ipv4.ICMP_PROTOCOL))
    msga.match.append(nx.NXM_OF_ETH_TYPE(pkt.ethernet.ARP_TYPE))

    if flooder(dpid):
        msgi.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD))
        msga.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD))
    msgi.actions.append(nx.nx_action_resubmit.resubmit_table(table=1))
    msga.actions.append(nx.nx_action_resubmit.resubmit_table(table=1))
    connection.send(msgi)
    connection.send(msga)

    # Default rule for table 1: send to controller
    msgi = nx.nx_flow_mod()  # icmp msg
    msga = nx.nx_flow_mod()  # arp msg
    msgi.table_id = msga.table_id = 1
    msgi.priority = msga.priority = 1  # Low priority
    msgi.idle_timeout = msga.idle_timeout = ICMP_IDLE_TIMEOUT

    msgi.match.append(nx.NXM_OF_ETH_TYPE(pkt.ethernet.IP_TYPE))
    msgi.match.append(nx.NXM_OF_IP_PROTO(pkt.ipv4.ICMP_PROTOCOL))
    msga.match.append(nx.NXM_OF_ETH_TYPE(pkt.ethernet.ARP_TYPE))

    msgi.actions.append(of.ofp_action_output(port=of.OFPP_CONTROLLER))
    msga.actions.append(of.ofp_action_output(port=of.OFPP_CONTROLLER))
    connection.send(msgi)
    connection.send(msga)

    if flooder(
            dpid
    ):  # create emtpy default action (applies mostly to TCP traffic)
        msgdef = nx.nx_flow_mod()
        msgdef.table_id = 0
        msgdef.priority = 0  # pld: MUST HAVE THIS
        msgdef.actions.append(of.ofp_action_output(port=of.OFPP_CONTROLLER))
        connection.send(msgdef)

    def ready(event):  # called right below, as parameter
        if event.ofp.xid != 0x80000000:
            # Not the right barrier
            return
        log.info("%s ready", event.connection)
        event.connection.addListenerByName("PacketIn", _handle_PacketIn)
        return EventRemove

    # the following is to ensure that the switch does nothing else until it processes the actions above
    connection.send(of.ofp_barrier_request(xid=0x80000000))
    connection.addListenerByName("BarrierIn", ready)

    # now install switch
    if dpid in switchmap:
        sw = switchmap[dpid]
        if sw.connection() is None:
            sw.setConnection(connection)
    else:
        sw = SwitchNode(dpid, connection)
        switchmap[dpid] = sw
    # now add empty port list
    sw.setUnknownPorts(portlist)
    def generateRules(self,nv):
        self.networkview = nv
        hosts = self.networkview.access
        routes = self.networkview.routes
        self.hostHops = {}

        rules = []

        flowRule = nx.nx_flow_mod()
        flowRule.match.eth_dst = EthAddr("ff:ff:ff:ff:ff:ff")
        flowRule.hard_timeout = FLOW_TIMEOUT
        flowRule.actions.append(of.ofp_action_output(port = 1))
        rules.append(flowRule)

        '''
        flowRule = nx.nx_flow_mod()
        flowRule.match.eth_src = EthAddr("00:00:00:00:00:01")
        flowRule.match.eth_dst = EthAddr(self.networkview.target.eth_addr)
        flowRule.hard_timeout = FLOW_TIMEOUT
        flowRule.priority = 2
        flowRule.actions.append(of.ofp_action_output(port = 2))
        rules.append(flowRule)

        flowRule = nx.nx_flow_mod()
        flowRule.match.eth_src = EthAddr(self.networkview.target.eth_addr)
        flowRule.match.eth_dst = EthAddr("00:00:00:00:00:01")
        flowRule.hard_timeout = FLOW_TIMEOUT
        flowRule.priority = 2
        flowRule.actions.append(of.ofp_action_output(port = 1))
        rules.append(flowRule)

        #TMP for DNS test
        flowRule = nx.nx_flow_mod()
        flowRule.match.NXM_OF_ETH_TYPE = ethernet.IP_TYPE
        flowRule.match.ip_dst = IPAddr("10.168.0.10")
        flowRule.match.ip_src = IPAddr("10.168.0.11")
        flowRule.hard_timeout = FLOW_TIMEOUT
        flowRule.actions.append(of.ofp_action_output(port = 2))
        #rules.append(flowRule)

        flowRule = nx.nx_flow_mod()
        flowRule.match.NXM_OF_ETH_TYPE = ethernet.IP_TYPE
        flowRule.match.of_ip_proto = ipv4.UDP_PROTOCOL
        flowRule.match.udp_src = int(53)
        flowRule.hard_timeout = FLOW_TIMEOUT
        flowRule.priority = 999
        flowRule.actions.append(of.ofp_action_output(port = of.OFPP_CONTROLLER))
        rules.append(flowRule)
        '''


        #create rules for routes
        for r in routes:
            hopCt=0
            for hop in r.hops:
                #print("hopCt " + str(hopCt) + " isRouter " + str(hop.isRouter))
                if hopCt!=0 and hop.isRouter==True:
                    #print("Create rule " + str(r.startNode.decepted_ip_addr) + " --> " + str(r.endNode.decepted_ip_addr) + " with ttl " + str(hopCt) + " - " + str(1))
                    flowRule = nx.nx_flow_mod()
                    flowRule.match.NXM_OF_ETH_TYPE = ethernet.IP_TYPE
                    flowRule.match.NXM_NX_IP_TTL = hopCt
                    flowRule.match.eth_src = EthAddr(r.startNode.decepted_eth_addr)
                    flowRule.match.eth_dst = EthAddr(r.endNode.decepted_eth_addr)
                    flowRule.match.ip_src = IPAddr(r.startNode.decepted_ip_addr)
                    flowRule.match.ip_dst = IPAddr(r.endNode.decepted_ip_addr)
                    flowRule.hard_timeout = FLOW_TIMEOUT
                    flowRule.priority = 2
                    flowRule.actions.append(of.ofp_action_output(port = 1))
                    rules.append(flowRule)
                hopCt+=1
            hopCt-=2
            if hopCt>0 :
                self.hostHops[r.endNode.decepted_eth_addr] = hopCt

        #for key in self.hostHops.keys():
        #    print("Key " + str(key))


        #create rules for packet flow
        for h in hosts:

            #generate rule from deception server to host for ARP and DHCP
            #print("Create rule " + str("ARP from port 1") + " --> " + str(h.eth_addr) + " to port " + str(h.switchPort))
            flowRule = nx.nx_flow_mod()
            flowRule.match.of_eth_type = ethernet.ARP_TYPE
            flowRule.match.in_port = 1
            flowRule.match.eth_dst = EthAddr(h.eth_addr)
            flowRule.hard_timeout = FLOW_TIMEOUT
            flowRule.actions.append(of.ofp_action_output(port = int(h.switchPort)))
            rules.append(flowRule)

            #print("Create rule " + str("ARP from ") + str(h.eth_addr) + " to port " + str(1))
            flowRule = nx.nx_flow_mod()
            flowRule.match.of_eth_type = ethernet.ARP_TYPE
            flowRule.match.in_port = 1
            flowRule.match.eth_src = EthAddr(h.eth_addr)
            flowRule.match.in_port = int(h.switchPort)
            flowRule.hard_timeout = FLOW_TIMEOUT
            flowRule.actions.append(of.ofp_action_output(port = 1))
            rules.append(flowRule)

            #print("Create rule " + str("DHCP from port 68 ") + "to port " + str(1))
            flowRule = nx.nx_flow_mod()
            flowRule.match.of_eth_type = ethernet.IP_TYPE
            flowRule.match.of_ip_proto = ipv4.UDP_PROTOCOL
            flowRule.match.eth_src = EthAddr(str(h.eth_addr))
            flowRule.match.udp_src = int(68)
            flowRule.hard_timeout = FLOW_TIMEOUT
            flowRule.actions.append(of.ofp_action_output(port = int(1)))
            rules.append(flowRule)

            #print("Create rule " + str("DHCP from port 67 ") + " to port " + str(h.switchPort))
            flowRule = nx.nx_flow_mod()
            flowRule.match.of_eth_type = ethernet.IP_TYPE
            flowRule.match.of_ip_proto = ipv4.UDP_PROTOCOL
            flowRule.match.eth_dst = EthAddr(str(h.eth_addr))
            flowRule.match.udp_src = int(67)
            flowRule.hard_timeout = FLOW_TIMEOUT
            flowRule.actions.append(of.ofp_action_output(port = int(h.switchPort)))
            rules.append(flowRule)


            #normal node
            if h.isHoneypot==False and h.isRouter==False and h.eth_addr!=self.networkview.target.eth_addr:
                #print("Create rule " + str(h.decepted_ip_addr) + " --> " + str(h.ip_addr))

                if self.hostHops.has_key(h.decepted_eth_addr):
                    #print("a - Create rule " + str(self.networkview.target.eth_addr) + " --> " + str(h.decepted_ip_addr) + "/" + str(self.networkview.gateway.eth_addr) + " - " + str(h.switchPort))
                    maxHop = self.hostHops.get(h.decepted_eth_addr)
                    for ttl in range((maxHop+1),65):
                        flowRule = nx.nx_flow_mod()
                        flowRule.match.of_eth_type = ethernet.IP_TYPE
                        flowRule.match.eth_src = EthAddr(str(self.networkview.target.eth_addr))
                        flowRule.match.eth_dst = EthAddr(str(self.networkview.gateway.eth_addr))
                        flowRule.match.ip_dst = IPAddr(str(h.decepted_ip_addr))
                        flowRule.match.NXM_NX_IP_TTL = ttl
                        flowRule.hard_timeout = FLOW_TIMEOUT
                        flowRule.priority = 1
                        flowRule.actions.append(of.ofp_action_nw_addr.set_src(IPAddr(h.decepted_ip_addr)))
                        flowRule.actions.append(of.ofp_action_dl_addr.set_src(EthAddr(self.networkview.gateway.eth_addr)))
                        flowRule.actions.append(of.ofp_action_nw_addr.set_dst(IPAddr(h.ip_addr)))
                        flowRule.actions.append(of.ofp_action_dl_addr.set_dst(EthAddr(h.eth_addr)))
                        #print("1 - " + str(self.networkview.gateway.eth_addr) + " --> " + str(h.eth_addr))
                        flowRule.actions.append(of.ofp_action_output(port = int(h.switchPort)))
                        rules.append(flowRule)

                    #send back to user and decrease ttl
                    #print("b - Create rule " + str(self.networkview.gateway.eth_addr) + " --> " + str(h.decepted_ip_addr) + "/" + str(self.networkview.target.eth_addr) + " - " + str(self.networkview.target.switchPort))
                    hopCount = self.hostHops[h.decepted_eth_addr]
                    flowRule = nx.nx_flow_mod()
                    flowRule.match.of_eth_type = ethernet.IP_TYPE
                    flowRule.match.eth_src = EthAddr(str(h.eth_addr))
                    flowRule.match.ip_dst = IPAddr(str(h.decepted_ip_addr))
                    flowRule.match.eth_dst = EthAddr(str(self.networkview.gateway.eth_addr))
                    flowRule.hard_timeout = FLOW_TIMEOUT
                    flowRule.priority = 1
                    for hop in range(0,hopCount):
                        flowRule.actions.append(nx.nx_action_dec_ttl())
                    #print("Decrease ttl by " + str(hopCount))
                    flowRule.actions.append(of.ofp_action_nw_addr.set_src(IPAddr(h.decepted_ip_addr)))
                    flowRule.actions.append(of.ofp_action_dl_addr.set_src(EthAddr(self.networkview.gateway.eth_addr)))
                    flowRule.actions.append(of.ofp_action_nw_addr.set_dst(IPAddr(self.networkview.target.ip_addr)))
                    flowRule.actions.append(of.ofp_action_dl_addr.set_dst(EthAddr(self.networkview.target.eth_addr)))
                    flowRule.actions.append(of.ofp_action_output(port = int(self.networkview.target.switchPort)))
                    #print("2 - " + str(self.networkview.gateway.eth_addr) + " --> " + str(self.networkview.target.eth_addr))
                    rules.append(flowRule)

                else:
                    #print("a - Create rule " + str(self.networkview.target.eth_addr) + " --> " + str(h.decepted_ip_addr) + "/" + str(h.decepted_eth_addr) + " - " + str(h.switchPort))
                    flowRule = nx.nx_flow_mod()
                    flowRule.match.of_eth_type = ethernet.IP_TYPE
                    flowRule.match.eth_src = EthAddr(str(self.networkview.target.eth_addr))
                    flowRule.match.eth_dst = EthAddr(str(h.decepted_eth_addr))
                    flowRule.match.ip_dst = IPAddr(str(h.decepted_ip_addr))
                    flowRule.hard_timeout = FLOW_TIMEOUT
                    flowRule.priority = 1
                    flowRule.actions.append(of.ofp_action_nw_addr.set_src(IPAddr(h.decepted_ip_addr)))
                    #flowRule.actions.append(of.ofp_action_dl_addr.set_src(EthAddr(h.decepted_eth_addr)))
                    flowRule.actions.append(of.ofp_action_nw_addr.set_dst(IPAddr(h.ip_addr)))
                    #flowRule.actions.append(of.ofp_action_dl_addr.set_dst(EthAddr(h.eth_addr)))
                    flowRule.actions.append(of.ofp_action_output(port = int(h.switchPort)))
                    #print("3 - " + str(h.decepted_eth_addr) + " --> " + str(h.eth_addr))
                    rules.append(flowRule)

                    #print("b - Create rule " + str(h.eth_addr) + " --> " + str(h.decepted_eth_addr) + " - " + str(self.networkview.target.switchPort))
                    flowRule = nx.nx_flow_mod()
                    flowRule.match.eth_src = EthAddr(str(h.eth_addr))
                    flowRule.match.eth_dst = EthAddr(str(h.decepted_eth_addr))
                    flowRule.hard_timeout = FLOW_TIMEOUT
                    flowRule.priority = 1
                    flowRule.actions.append(of.ofp_action_nw_addr.set_src(IPAddr(h.decepted_ip_addr)))
                    flowRule.actions.append(of.ofp_action_dl_addr.set_src(EthAddr(h.decepted_eth_addr)))
                    flowRule.actions.append(of.ofp_action_nw_addr.set_dst(IPAddr(self.networkview.target.ip_addr)))
                    flowRule.actions.append(of.ofp_action_dl_addr.set_dst(EthAddr(self.networkview.target.eth_addr)))
                    flowRule.actions.append(of.ofp_action_output(port = int(self.networkview.target.switchPort)))
                    #print("4 - " + str(h.decepted_eth_addr) + " --> " + str(self.networkview.target.eth_addr))
                    rules.append(flowRule)


            #honeypot
            if h.isHoneypot==True and h.isRouter==False and h.eth_addr!=self.networkview.target.eth_addr:
                if self.hostHops.has_key(h.decepted_eth_addr):
                    #print("c - Create rule " + str(self.networkview.target.eth_addr) + " --> " + str(h.decepted_ip_addr) + "/" + str(self.networkview.gateway.eth_addr) + " - " + str(h.switchPort))
                    maxHop = self.hostHops.get(h.decepted_eth_addr)
                    for ttl in range((maxHop+1),65):
                        flowRule = nx.nx_flow_mod()
                        flowRule.match.of_eth_type = ethernet.IP_TYPE
                        flowRule.match.eth_src = EthAddr(str(self.networkview.target.eth_addr))
                        flowRule.match.eth_dst = EthAddr(str(self.networkview.gateway.eth_addr))
                        flowRule.match.ip_dst = IPAddr(str(h.decepted_ip_addr))
                        flowRule.match.NXM_NX_IP_TTL = ttl
                        flowRule.hard_timeout = FLOW_TIMEOUT
                        flowRule.priority = 1
                        flowRule.actions.append(of.ofp_action_nw_addr.set_src(IPAddr(h.decepted_ip_addr)))
                        flowRule.actions.append(of.ofp_action_dl_addr.set_src(EthAddr(self.networkview.gateway.eth_addr)))
                        flowRule.actions.append(of.ofp_action_nw_addr.set_dst(IPAddr(h.ip_addr)))
                        flowRule.actions.append(of.ofp_action_dl_addr.set_dst(EthAddr(h.eth_addr)))
                        #print("5 - " + str(self.networkview.gateway.eth_addr) + " --> " + str(h.eth_addr))
                        flowRule.actions.append(of.ofp_action_output(port = int(h.switchPort)))
                        rules.append(flowRule)

                    #send back to user and decrease ttl
                    #print("d - Create rule " + str(self.networkview.gateway.eth_addr) + " --> " + str(h.decepted_ip_addr) + "/" + str(self.networkview.target.eth_addr) + " - " + str(self.networkview.target.switchPort))
                    hopCount = self.hostHops[h.decepted_eth_addr]
                    flowRule = nx.nx_flow_mod()
                    flowRule.match.of_eth_type = ethernet.IP_TYPE
                    flowRule.match.eth_src = EthAddr(str(h.eth_addr))
                    flowRule.match.ip_dst = IPAddr(str(h.decepted_ip_addr))
                    flowRule.match.eth_dst = EthAddr(str(self.networkview.gateway.eth_addr))
                    flowRule.hard_timeout = FLOW_TIMEOUT
                    flowRule.priority = 1
                    for hop in range(0,hopCount):
                        flowRule.actions.append(nx.nx_action_dec_ttl())
                    #print("Decrease ttl by " + str(hopCount))
                    flowRule.actions.append(of.ofp_action_nw_addr.set_src(IPAddr(h.decepted_ip_addr)))
                    flowRule.actions.append(of.ofp_action_dl_addr.set_src(EthAddr(self.networkview.gateway.eth_addr)))
                    flowRule.actions.append(of.ofp_action_nw_addr.set_dst(IPAddr(self.networkview.target.ip_addr)))
                    flowRule.actions.append(of.ofp_action_dl_addr.set_dst(EthAddr(self.networkview.target.eth_addr)))
                    #print("6 - " + str(self.networkview.gateway.eth_addr) + " --> " + str(self.networkview.target.eth_addr))
                    flowRule.actions.append(of.ofp_action_output(port = int(self.networkview.target.switchPort)))
                    rules.append(flowRule)

                else:
                    #print("c - Create rule " + str(self.networkview.target.eth_addr) + " --> " + str(h.decepted_ip_addr) + "/" + str(h.decepted_eth_addr) + " - " + str(h.switchPort))
                    flowRule = nx.nx_flow_mod()
                    flowRule.match.of_eth_type = ethernet.IP_TYPE
                    flowRule.match.eth_src = EthAddr(str(self.networkview.target.eth_addr))
                    flowRule.match.eth_dst = EthAddr(str(h.decepted_eth_addr))
                    flowRule.match.ip_dst = IPAddr(str(h.decepted_ip_addr))
                    flowRule.hard_timeout = FLOW_TIMEOUT
                    flowRule.priority = 1
                    flowRule.actions.append(of.ofp_action_nw_addr.set_src(IPAddr(h.decepted_ip_addr)))
                    flowRule.actions.append(of.ofp_action_dl_addr.set_src(EthAddr(h.decepted_eth_addr)))
                    flowRule.actions.append(of.ofp_action_nw_addr.set_dst(IPAddr(h.ip_addr)))
                    flowRule.actions.append(of.ofp_action_dl_addr.set_dst(EthAddr(h.eth_addr)))
                    #print("7 - " + str(self.networkview.gateway.eth_addr) + " --> " + str(h.eth_addr))
                    flowRule.actions.append(of.ofp_action_output(port = int(h.switchPort)))
                    rules.append(flowRule)

                    #print("d - Create rule " + str(h.eth_addr) + " --> " + str(h.decepted_eth_addr) + " - " + str(self.networkview.target.switchPort))
                    flowRule = nx.nx_flow_mod()
                    flowRule.match.eth_src = EthAddr(str(h.eth_addr))
                    flowRule.match.eth_dst = EthAddr(str(h.decepted_eth_addr))
                    flowRule.hard_timeout = FLOW_TIMEOUT
                    flowRule.priority = 1
                    flowRule.actions.append(of.ofp_action_nw_addr.set_src(IPAddr(h.decepted_ip_addr)))
                    flowRule.actions.append(of.ofp_action_dl_addr.set_src(EthAddr(h.decepted_eth_addr)))
                    flowRule.actions.append(of.ofp_action_nw_addr.set_dst(IPAddr(self.networkview.target.ip_addr)))
                    flowRule.actions.append(of.ofp_action_dl_addr.set_dst(EthAddr(self.networkview.target.eth_addr)))
                    #print("8 - " + str(h.decepted_eth_addr) + " --> " + str(self.networkview.target.eth_addr))
                    flowRule.actions.append(of.ofp_action_output(port = int(self.networkview.target.switchPort)))
                    rules.append(flowRule)

                #deception server to target node
                #print("e - Create rule " + str(h.decepted_eth_addr) + " --> " + str(self.networkview.target.eth_addr) + " - " + str(self.networkview.target.switchPort))
                flowRule = nx.nx_flow_mod()
                flowRule.match.eth_src = EthAddr(str(h.decepted_eth_addr))
                flowRule.match.eth_dst = EthAddr(str(self.networkview.target.eth_addr))
                flowRule.hard_timeout = FLOW_TIMEOUT
                flowRule.priority = 1
                flowRule.actions.append(of.ofp_action_output(port = int(self.networkview.target.switchPort)))
                rules.append(flowRule)

                #deception server to honeypot
                #print("f - Create rule " + str(h.decepted_eth_addr) + " --> " + str(h.eth_addr) + " - " + str(h.switchPort))
                flowRule = nx.nx_flow_mod()
                flowRule.match.eth_src = EthAddr(str(h.decepted_eth_addr))
                flowRule.match.eth_dst = EthAddr(str(h.eth_addr))
                flowRule.hard_timeout = FLOW_TIMEOUT
                flowRule.priority = 1
                flowRule.actions.append(of.ofp_action_output(port = int(h.switchPort)))
                rules.append(flowRule)

            #honeyrouter
            if h.isHoneypot==False and h.isRouter==True and h.eth_addr!=self.networkview.target.eth_addr:
                #print("g - Create rule " + str(self.networkview.target.eth_addr) + " --> " + str(h.ip_addr) + "/" + str(h.decepted_eth_addr) + " - " + str(h.switchPort))
                #print("Create rule " + str(h.decepted_ip_addr) + " --> " + str(h.ip_addr))
                flowRule = nx.nx_flow_mod()
                flowRule.match.of_eth_type = ethernet.IP_TYPE
                flowRule.match.eth_src = EthAddr(str(self.networkview.target.eth_addr))
                flowRule.match.eth_dst = EthAddr(str(h.decepted_eth_addr))
                flowRule.match.ip_dst = IPAddr(str(h.decepted_ip_addr))
                flowRule.hard_timeout = FLOW_TIMEOUT
                flowRule.priority = 1
                flowRule.actions.append(of.ofp_action_output(port = int(h.switchPort)))
                rules.append(flowRule)

                #print("h - Create rule " + str(h.decepted_eth_addr) + " --> " + str(self.networkview.target.eth_addr) + " - " + str(self.networkview.target.switchPort))
                #print("Create rule " + str(h.ip_addr) + " --> " + str(h.decepted_ip_addr))
                flowRule = nx.nx_flow_mod()
                flowRule.match.eth_src = EthAddr(str(h.decepted_eth_addr))
                flowRule.match.eth_dst = EthAddr(str(self.networkview.target.eth_addr))
                flowRule.hard_timeout = FLOW_TIMEOUT
                flowRule.priority = 1
                flowRule.actions.append(of.ofp_action_output(port = int(self.networkview.target.switchPort)))
                rules.append(flowRule)

        return rules
Exemple #35
0
    def _handle_BarrierIn_Mig_NS(e):
        #barrier handler for new switch
        if e.xid != xid_ns:  #if its not this barrier, ignore
            return
        #log.debug( 'Barrier received for migrated pmac:{0}'.format(new_pmac) )
        e.connection.removeListener(handler_id[0])

        old_sw_con = core.openflow.connections[old_sw]
        msg = nx.nx_flow_mod(table_id=0)
        msg.priority = 8000
        msg.hard_timeout = arp_cache_timeout
        msg.match.eth_dst = old_pmac
        rewrite_action = of.ofp_action_dl_addr.set_dst(adrs.EthAddr(new_pmac))
        msg.actions.append(rewrite_action)
        #choose one up link by hashing
        up_ports = g[old_sw].keys()
        num_routes = len(up_ports)
        #msg.actions.append(of.ofp_action_output(port = up_ports[ random.randint(0, num_routes - 1) ] ))#simple hashing. edge switch x sends to agg switch x
        #old_sw_con.send(msg)

        #if more than 2 up ports are there, then hashing is req. if 1 up port, then no hashing. if 2, then the other port other than inp port
        if num_routes == 1:  #only one route
            msg.actions = [
                rewrite_action,
                of.ofp_action_output(port=of.OFPP_IN_PORT)
            ]
            old_sw_con.send(msg)
        elif num_routes == 2:
            msg.match.NXM_OF_IN_PORT = up_ports[0]
            msg.actions = [
                rewrite_action,
                of.ofp_action_output(port=up_ports[1])
            ]
            old_sw_con.send(msg)
            msg.match.NXM_OF_IN_PORT = up_ports[1]
            msg.actions = [
                rewrite_action,
                of.ofp_action_output(port=up_ports[0])
            ]
            old_sw_con.send(msg)
        else:  #3 or more ports. here need hahsing. based on src port num. also avoid the inp port. so match based on that also
            num_routes -= 1  #since we avoid each inp port
            num_bits = int(math.floor(math.log(num_routes, 2)))
            x = 2**num_bits  #Assumption:one edge switch doesn't have more than 255 direct connections to agg switches
            mask = '00:00:00:' + eth_addr_format(x - 1, 2) + ':00:00'
            prefix = '00:00:00:'
            suffix = ':00:00'
            for ii in range(num_routes + 1):
                cand_ports = list(up_ports)
                msg.match.NXM_OF_IN_PORT = cand_ports.pop(
                    ii)  #remove the inp port from the list of op ports
                for i in range(num_routes):
                    port = i % x
                    msg.match.eth_src_with_mask = (prefix +
                                                   eth_addr_format(port, 2) +
                                                   suffix, mask)
                    msg.actions = [
                        rewrite_action,
                        of.ofp_action_output(port=cand_ports[i])
                    ]
                    old_sw_con.send(msg)

        msg = nx.nx_flow_mod(table_id=0, command=of.OFPFC_DELETE)
        msg.priority = 5000
        msg.match.NXM_OF_IN_PORT = old_port
        msg.match.eth_src = old_amac
        old_sw_con.send(msg)
        msg = nx.nx_flow_mod(table_id=1, command=of.OFPFC_DELETE)
        msg.priority = 5000
        msg.match.eth_dst = old_pmac
        old_sw_con.send(msg)

        #maybe send barrier and wait? to make sure its processed so that pkts to old pmac can still reach new place?
        barrier_os = of.ofp_barrier_request()
        xid_os = barrier_os.xid

        def _handle_BarrierIn_Mig_OS(e):
            #barrier handler for old switch
            if e.xid != xid_os:  #if its not this barrier, ignore
                return
            #log.debug( 'Barrier received for diverting flows to pmac:{0}'.format(new_pmac) )
            e.connection.removeListener(handler_id[1])
            arp_table[ip] = new_pmac
            actual_pmac.pop(
                pmac_actual.pop(old_pmac)
            )  #remove old pmac to actual and vice versa since they are not valid anymore
            actual_pmac[org_mac] = new_pmac
            pmac_actual[new_pmac] = org_mac

            #this nxt 2 lines should be in a fn called after the timeout. we dont want to assing old pmac to anyone until then
            def _remove_old_pmac():
                vmid = int(old_pmac[-5:].replace(':', ''), 16)
                assigned_pmac[old_sw][old_port] = assigned_pmac[old_sw][
                    old_port][:vmid] + '0' + assigned_pmac[old_sw][old_port][
                        vmid + 1:]

            Timer(arp_cache_timeout, _remove_old_pmac)
            if event:
                _handle_arp(event)

        handler_id[1] = old_sw_con.addListenerByName("BarrierIn",
                                                     _handle_BarrierIn_Mig_OS)
        old_sw_con.send(barrier_os)
Exemple #36
0
def _check_handle_migration(event):
    '''returns 0 for no migration. returns 1 for migration'''
    eth_pkt = event.parsed
    arp_pkt = event.parsed.payload
    org_mac = eth_pkt.src.toStr(
    )  #actual mac of the current machine. same as old amac if vm mig. if vip, then diff.
    src_ip = arp_pkt.protosrc.toStr()
    old_pmac = arp_table[src_ip]
    old_amac = pmac_actual[old_pmac]  #
    sw, port = pmac_pos(old_pmac)
    #print 'In migration check. IP:{0}, old pos - {1}:{2} new pos - {3}:{4}'.format(src_ip, sw, port, event.dpid, event.port)
    if (sw != event.dpid) or (port != event.port):
        '''
        this host has migrated or virtual ip
        assign new pmac.
        add trans in new switch.
        add entry in old switch to frwrd to some agg switch replacing old pmac with new pmac
        remove prev trans tabbles from old switch.
        update our internal tables
        change the assigned mac string - not assign the old pmac for the timeout period of time
        '''
        if org_mac == old_amac:
            log.info(
                'VM migration detected. IP:{0}, old pos - {1}:{2} new pos - {3}:{4}'
                .format(src_ip, sw, port, event.dpid, event.port))
        else:
            log.info(
                'Virtual ip takeover detected. IP:{0}, old pos - {1}:{2} new pos - {3}:{4}'
                .format(src_ip, sw, port, event.dpid, event.port))

        return move_host(src_ip, event.dpid, event.port, org_mac, event)
        new_pmac = _handle_new_host(org_mac, src_ip, event.dpid, event.port)
        barrier = of.ofp_barrier_request()
        event.connection.send(barrier)

        old_switch_con = core.openflow.connections[sw]
        msg = nx.nx_flow_mod(table_id=0)
        msg.priority = 8000
        msg.hard_timeout = arp_cache_timeout
        msg.match.eth_dst = old_pmac
        rewrite_action = of.ofp_action_dl_addr.set_dst(adrs.EthAddr(new_pmac))
        msg.actions.append(rewrite_action)
        #choose one up link by hashing
        up_ports = g[event.dpid].keys()
        num_routes = len(up_ports)
        #msg.actions.append(of.ofp_action_output(port = up_ports[ random.randint(0, num_routes - 1) ] ))#simple hashing. edge switch x sends to agg switch x
        #old_switch_con.send(msg)

        #if more than 2 up ports are there, then hashing is req. if 1 up port, then no hashing. if 2, then the other port other than inp port
        if num_routes == 1:  #only one route
            msg.actions = [
                rewrite_action,
                of.ofp_action_output(port=of.OFPP_IN_PORT)
            ]
            old_switch_con.send(msg)
        elif num_routes == 2:
            msg.match.NXM_OF_IN_PORT = up_ports[0]
            msg.actions = [
                rewrite_action,
                of.ofp_action_output(port=up_ports[1])
            ]
            old_switch_con.send(msg)
            msg.match.NXM_OF_IN_PORT = up_ports[1]
            msg.actions = [
                rewrite_action,
                of.ofp_action_output(port=up_ports[0])
            ]
            old_switch_con.send(msg)
        else:  #3 or more ports. here need hahsing. based on src port num. also avoid the inp port. so match based on that also
            num_routes -= 1  #since we avoid each inp port
            num_bits = int(math.floor(math.log(num_routes, 2)))
            x = 2**num_bits  #Assumption:one edge switch doesn't have more than 255 direct connections to agg switches
            mask = '00:00:00:' + eth_addr_format(x - 1, 2) + ':00:00'
            prefix = '00:00:00:'
            suffix = ':00:00'
            for ii in range(num_routes + 1):
                cand_ports = list(up_ports)
                msg.match.NXM_OF_IN_PORT = cand_ports.pop(
                    ii)  #remove the inp port from the list of op ports
                for i in range(num_routes):
                    port = i % x
                    msg.match.eth_src_with_mask = (prefix +
                                                   eth_addr_format(port, 2) +
                                                   suffix, mask)
                    msg.actions = [
                        rewrite_action,
                        of.ofp_action_output(port=cand_ports[i])
                    ]
                    old_switch_con.send(msg)

        msg = nx.nx_flow_mod(table_id=0, command=of.OFPFC_DELETE)
        msg.priority = 5000
        msg.match.NXM_OF_IN_PORT = port
        msg.match.eth_src = old_amac
        old_switch_con.send(msg)
        msg = nx.nx_flow_mod(table_id=1, command=of.OFPFC_DELETE)
        msg.priority = 5000
        msg.match.eth_dst = old_pmac
        old_switch_con.send(msg)
        barrier = of.ofp_barrier_request()
        old_switch_con.send(barrier)

        arp_table[src_ip] = new_pmac
        actual_pmac.pop(
            pmac_actual.pop(old_pmac)
        )  #remove old pmac to actual and vice versa since they are not valid anymore
        actual_pmac[org_mac] = new_pmac
        pmac_actual[new_pmac] = org_mac

        #this nxt 2 lines should be in a fn called after the timeout. we dont want to assing old pmac to anyone until then
        def _remove_old_pmac():
            vmid = int(old_pmac[-5:].replace(':', ''), 16)
            assigned_pmac[sw][port] = assigned_pmac[sw][
                port][:vmid] + '0' + assigned_pmac[sw][port][vmid + 1:]

        Timer(arp_cache_timeout, _remove_old_pmac)
        return 1
    return 0
Exemple #37
0
def insert_routes():
    #inserting frowarding tables into all the switches
    #maybe send barrier to all switches in the end
    for core_switch in core_switches:
        #each core switch coudl be con to more than 1 ags of a pod. so hash. ASSUMEPTION : a core switch is con to all pods
        switches = [[] for i in range(num_pods)]
        links = g[core_switch]
        _port_pod = {}
        _mask_ports = {}
        con = core.openflow.connections[core_switch]
        for src_port, link in links.iteritems():
            pod = switch_pos[link[0]][0]
            switches[pod].append(src_port)  #appending src_port to pod no
            _port_pod[src_port] = pod
        pod_port[core_switch] = switches
        port_pod[core_switch] = _port_pod
        for pod_num in range(num_pods):
            num_routes = len(switches[pod_num])
            if num_routes > 1:  #need hashing. hashing is based on port num
                msg_cs = nx.nx_flow_mod(table_id=0)
                msg_cs.priority = 2000
                num_bits = int(math.floor(math.log(num_routes, 2)))
                x = 2**num_bits  #Assumption:one core switch doesn't have more than 255 direct connections to a pod
                mask = 'ff:ff:00:' + eth_addr_format(x - 1, 2) + ':00:00'
                mask_for_bcast = '00:00:00:' + eth_addr_format(x - 1,
                                                               2) + ':00:00'
                prefix = eth_addr_format(pod_num, 4) + ':00:'
                suffix = ':00:00'
                for i in range(num_routes):
                    port = i % x
                    port_mask = prefix + eth_addr_format(port, 2) + suffix
                    msg_cs.match.eth_dst_with_mask = (port_mask, mask)
                    dst_port = switches[pod_num][i]
                    msg_cs.actions = [of.ofp_action_output(port=dst_port)]
                    key = ('00:00:00:' + eth_addr_format(port, 2) + ':00:00',
                           mask_for_bcast)
                    if key not in _mask_ports:
                        _mask_ports[key] = []
                    _mask_ports[key].append(dst_port)
                    con.send(msg_cs)
            else:
                msg_cs = nx.nx_flow_mod(table_id=0)
                msg_cs.priority = 2000
                msg_cs.match.eth_dst_with_mask = (eth_addr_format(pod_num, 4) +
                                                  ":00:00:00:00",
                                                  "ff:ff:00:00:00:00")
                msg_cs.actions.append(
                    of.ofp_action_output(port=switches[pod_num][0]))
                con.send(msg_cs)
        mask_ports[core_switch] = _mask_ports

    for agg_switch in agg_switches:
        con = core.openflow.connections[agg_switch]
        up_ports = agg_up_ports[agg_switch]
        num_routes = len(up_ports)
        if num_routes > 1:  #need hashing. hashing is based on port num
            msg_as = nx.nx_flow_mod(table_id=0)
            msg_as.priority = 2000
            num_bits = int(math.floor(math.log(num_routes, 2)))
            x = 2**num_bits  #Assumption:one agg switch doesn't have more than 255 direct connections to core switches
            mask = '00:00:00:' + eth_addr_format(x - 1, 2) + ':00:00'
            prefix = '00:00:00:'
            suffix = ':00:00'
            for i in range(num_routes):
                port = i % x
                msg_as.match.eth_dst_with_mask = (prefix +
                                                  eth_addr_format(port, 2) +
                                                  suffix, mask)
                msg_as.actions = [of.ofp_action_output(port=up_ports[i])]
                con.send(msg_as)
        else:
            msg_as = nx.nx_flow_mod(table_id=0)
            msg_as.priority = 2000
            msg_as.actions.append(of.ofp_action_output(port=up_ports[0]))
            con.send(msg_as)

        down_ports = agg_down_ports[agg_switch]
        pod_num = switch_pos[agg_switch][0]
        prefix = eth_addr_format(pod_num, 4) + ':'
        suffix = ':00:00:00'
        mask = 'ff:ff:ff:00:00:00'
        msg_as = nx.nx_flow_mod(table_id=0)
        msg_as.priority = 3000

        for src_port in down_ports:
            pos = switch_pos[g[agg_switch][src_port][0]][1]
            msg_as.match.eth_dst_with_mask = (prefix +
                                              eth_addr_format(pos, 2) + suffix,
                                              mask)
            msg_as.actions = [of.ofp_action_output(port=src_port)]
            con.send(msg_as)

    for edge_switch in edge_switches:
        con = core.openflow.connections[edge_switch]
        up_ports = g[edge_switch].keys()
        num_routes = len(up_ports)
        if num_routes > 1:  #need hashing. hashing is based on port num
            msg_es = nx.nx_flow_mod(table_id=2)
            msg_es.priority = 2000
            num_bits = int(math.floor(math.log(num_routes, 2)))
            x = 2**num_bits  #Assumption:one edge switch doesn't have more than 255 direct connections to agg switches
            mask = '00:00:00:' + eth_addr_format(x - 1, 2) + ':00:00'
            prefix = '00:00:00:'
            suffix = ':00:00'
            for i in range(num_routes):
                port = i % x
                msg_es.match.eth_dst_with_mask = (prefix +
                                                  eth_addr_format(port, 2) +
                                                  suffix, mask)
                msg_es.actions = [of.ofp_action_output(port=up_ports[i])]
                con.send(msg_es)
        else:
            msg_es = nx.nx_flow_mod(table_id=2)
            msg_es.priority = 2000
            msg_es.actions.append(of.ofp_action_output(port=up_ports[0]))
            con.send(msg_es)

        down_ports = host_ports[edge_switch]
        pod_num = switch_pos[edge_switch][0]
        pos = switch_pos[edge_switch][1]
        prefix = eth_addr_format((pod_num << 8) + pos, 6) + ':'
        suffix = ':00:00'
        mask = 'ff:ff:ff:ff:00:00'
        msg_es = nx.nx_flow_mod(table_id=2)
        msg_es.priority = 3000

        for port in down_ports:
            msg_es.match.eth_dst_with_mask = (prefix +
                                              eth_addr_format(port, 2) +
                                              suffix, mask)
            msg_es.actions = [of.ofp_action_output(port=port)]
            con.send(msg_es)
Exemple #38
0
def _start():
    global started
    if started:
        return
    started = True
    print 'App initialization started'
    log.info(
        'Starting App initialization : num_switches:{0}, num_links:{1}'.format(
            num_switches, cur_num_links))
    global core_switches
    log.info('Graph : {0}'.format(g))
    for dpid, links in g.iteritems():
        if (len(links) / float(total_ports[dpid])) <= max_connected_perc:
            edge_switches.add(dpid)
            assigned_pmac[dpid] = {}
            host_ports[dpid] = list(set(ports[dpid]) - set(g[dpid].keys()))
            for port in host_ports[
                    dpid]:  #for all the edge host ports, init the assigned pmac string
                assigned_pmac[dpid][port] = init_asgn_str
    for dpid in edge_switches:  #traverse through all links of the edge switch
        links = g[dpid]
        for src_port, link in links.iteritems():
            if link[0] not in agg_switches:  #1st time we see this agg, add it and init the down ports list
                agg_switches.add(link[0])
                agg_down_ports[link[0]] = []
            agg_down_ports[link[0]].append(link[1])
    core_switches = all_switches.difference(agg_switches.union(edge_switches))
    #global cs
    #cs = list(core_switches)#not really req. in arp reply, we r sending to one core switch. maybe that itself not req. send to nearest edge switch? use pmac fn

    for dpid in agg_switches:
        agg_up_ports[dpid] = list(
            set(g[dpid].keys()) - set(agg_down_ports[dpid]))

    log.info('Edge switches : {0}'.format(edge_switches))
    log.info('Aggregate switches : {0}'.format(agg_switches))
    log.info('Core switches : {0}'.format(core_switches))
    '''
    bfs to get the pods.
    make all the dpids of core switch links in agg switch -ve. and do bfs on all agg switches
    the switch pos can used as visited or not. we can have global switch nos or sep switch nos for agg and edge. right now leaving it global. can change
    '''

    toggle_agg_core_links()  #logically remove agg to core links

    pod = 0  #make it one here. and some changes later. like egs and ags are zero index pod num. maybe in bcast semanitcs also somewhere
    for agg in agg_switches:
        if switch_pos[agg][0] == -1:  #new switch
            bfs(agg, pod)
            pod += 1
    global num_pods
    num_pods = pod

    toggle_agg_core_links()  #renable links after discovering pods using bfs

    log.info('Nume of pods : {0} \nSwitch positions : {1}'.format(
        num_pods, switch_pos))

    insert_routes()
    for es in edge_switches:  #for arp entries and wildcard resubmissions
        msg = nx.nx_flow_mod()
        msg.priority = 9000
        msg.match.eth_type = pkt.ethernet.ARP_TYPE
        msg.actions.append(of.ofp_action_output(port=of.OFPP_CONTROLLER))
        for port in host_ports[es]:
            msg.match.NXM_OF_IN_PORT = port
            core.openflow.connections[es].send(msg)
        msg = nx.nx_flow_mod(table_id=0)
        msg.priority = 10
        msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=1))
        core.openflow.connections[es].send(msg)
        msg = nx.nx_flow_mod(table_id=1)
        msg.priority = 10
        msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=2))
        core.openflow.connections[es].send(msg)

    #bcast semantics
    msg = nx.nx_flow_mod(table_id=0)
    msg.priority = 8500
    msg.match.eth_dst = 'ff:ff:ff:ff:ff:ff'
    #agg switch
    for agg in agg_switches:
        con = core.openflow.connections[agg]
        num_down_links = len(agg_down_ports[agg])
        down_actions = [
            of.ofp_action_output(port=dp) for dp in agg_down_ports[agg]
        ]
        #pkt downwards
        msg.actions = down_actions
        for in_port in agg_up_ports[agg]:
            msg.match.NXM_OF_IN_PORT = in_port
            con.send(msg)

        #for pkt upwrds
        num_up_links = len(agg_up_ports[agg])
        for i in range(num_down_links):
            msg.match.NXM_OF_IN_PORT = agg_down_ports[agg][i]
            msg.actions = list(down_actions)
            msg.actions.pop(i)
            #and add one up link here. assuming num of down links is more than or equal to num up links
            msg.actions.append(
                of.ofp_action_output(port=agg_up_ports[agg][i % num_up_links]))
            con.send(msg)

    #edge switch
    msg = nx.nx_flow_mod(table_id=2)
    msg.priority = 8500
    msg.match.eth_dst = 'ff:ff:ff:ff:ff:ff'
    for es in edge_switches:
        con = core.openflow.connections[es]
        num_down_links = len(host_ports[es])
        down_actions = [of.ofp_action_output(port=dp) for dp in host_ports[es]]
        #pkt downwards
        msg.actions = down_actions
        for in_port in g[es]:
            msg.match.NXM_OF_IN_PORT = in_port
            con.send(msg)

        #for pkt upwrds
        num_up_links = len(g[es])
        _up_ports = g[es].keys()
        for i in range(num_down_links):
            msg.match.NXM_OF_IN_PORT = host_ports[es][i]
            msg.actions = list(down_actions)
            msg.actions.pop(i)
            #and add one up link here. assuming num of down links is more than or equal to num up links. ie the perc >= 50
            msg.actions.append(
                of.ofp_action_output(port=_up_ports[i % num_up_links]))
            con.send(msg)

    #core switch
    #flood in case of portland will work. in other cases, choose one of the op link to a pod.
    #have to take care of ctlr initiated bcast too, but we are not using it. so chucking it for now
    msg_cs = nx.nx_flow_mod(table_id=0)
    msg_cs.priority = 5000  #higher priority than normal routing
    msg_cs.match.eth_dst = 'ff:ff:ff:ff:ff:ff'
    for core_switch in cs:
        con = core.openflow.connections[core_switch]
        links = g[core_switch]
        _pod_port = pod_port[core_switch]
        _mask_ports = mask_ports[core_switch]
        if not _mask_ports:  #means this core switch has no redundant links at allm then flood. we assume that each core is connct to all pods.
            msg_cs.actions = [of.ofp_action_output(port=of.OFPP_FLOOD)]
            con.send(msg_cs)
            continue
        for src_port, link in links.iteritems():
            msg_cs.match.NXM_OF_IN_PORT = src_port
            msg_cs.actions = []
            src_pod = port_pod[core_switch][src_port]
            #take care of pod with only one link. those wont have masks. so add them directly
            '''
            for pod_num in range(num_pods):#sent to all other pod except src pod
                if pod_num == src_pod:
                    continue
            '''
            for key, lports in _mask_ports.iteritems():
                msg_cs.actions = []
                dst_ports = list(lports)
                for port in _pod_port[src_pod]:
                    if port in dst_ports:
                        dst_ports.remove(
                            port)  #remove the ports leading back to src pod
                for l in _pod_port:
                    if len(l) == 1:
                        dst_ports.append(
                            l[0]
                        )  #add pods with only one link to this core switch. they wouldnt have been considered fr hashing prev
                msg_cs.match.eth_src_with_mask = key
                for _port in dst_ports:
                    msg_cs.actions.append(of.ofp_action_output(port=_port))
                con.send(msg_cs)

    #handle packet in after flow tables are installed and everything is set up
    core.openflow.addListenerByName("PacketIn", _handle_PacketIn)
    print 'App initialization done'
Exemple #39
0
    def _handle_PacketIn(self, event):

        packet = event.parsed

        #the flood method
        def flood(switch):
            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
            switch.send(msg)

    #the drop method

        def drop(switch):
            msg = of.ofp_packet_out()
            msg.buffer_id = event.ofp.buffer_id
            msg.in_port = event.port
            switch.send(msg)

        ip = packet.find("ipv4")
        if ip == None:
            ip = packet.find("icmp")

        if ip:
            if not self.iptable.has_key(ip.srcip):
                self.iptable[ip.srcip] = packet.src

        if not self.mactable.has_key(packet.src):
            self.mactable[packet.src] = (event.dpid, event.port)

        if packet.type == packet.LLDP_TYPE or packet.dst.isBridgeFiltered():
            drop(event.connection)
            return
        if packet.dst.is_multicast:
            flood(event.connection)
        else:
            if not self.mactable.has_key(packet.dst):
                flood(event.connection)
            else:
                routelist = RouteApp.get_shortest_route(
                    pox.openflow.spanning_tree._calc_spanning_tree(),
                    event.dpid, self.mactable[packet.dst][0])
                routelist[-1] = self.mactable[packet.dst]
                msg = of.ofp_packet_out()
                msg.data = event.ofp
                msg.actions.append(of.ofp_action_output(port=routelist[0][1]))
                event.connection.send(msg)
                for switchid, out_port in routelist:
                    msg = nx.nx_flow_mod()
                    msg.table_id = 0
                    msg.priority = LOW
                    msg.match.eth_dst = packet.dst
                    msg.actions.append(of.ofp_action_output(port=out_port))
                    #msg.actions.append(nx.nx_action_resubmit.resubmit_table(table = 1))
                    msg.idle_timeout = 10
                    msg.hard_timeout = 30
                    switch = core.openflow.getConnection(switchid)
                    switch.send(msg)
Exemple #40
0
def _start():
    for dpid,links in g.iteritems():
        if(links[num_pods - 1][0] == -1):#if the last port is not connected to a switch, edge port
            edge_switches.add(dpid)
            #create assigned list
            assigned_pmac[dpid] = {}
            for i in range(half_num_pods, num_pods):#for all the edge host ports, seems like a lot of mem. use something like a bit set or somehting
                assigned_pmac[dpid][i] = '1' + ('0' * 254) + '1'
    for dpid,links in g.iteritems():
        if(links[num_pods - 1][0] in edge_switches):#if the last port is not connected to an edge switch, this is an agg switch
            agg_switches.add(dpid)
    core_switches = all_switches.difference(agg_switches.union(edge_switches))
    a_core_switch = core_switches.pop()
    core_switches.add(a_core_switch)
    print edge_switches
    print agg_switches
    print core_switches

    for pod_num in range(num_pods):#each link in core switch('s' here) corresponds to one pod
        agg = g[a_core_switch][pod_num][0]
        egs.append([])
        for i in range(half_num_pods):#the links of upper half ports are edge switches
            dpid = g[agg][half_num_pods + i][0]
            egs[pod_num].append(dpid)
            switch_pos[dpid] = [pod_num, i]
        aes = egs[pod_num][0]
        ags.append([])
        for i in range(half_num_pods):
            dpid = g[aes][i][0]
            ags[pod_num].append(dpid)
            switch_pos[dpid] = [pod_num, i]
    for agg in ags[0]:
        for i in range(half_num_pods):
            dpid = g[agg][i][0]
            cs.append(g[agg][i][0])
            switch_pos[dpid] = [-1, i]
    print cs
    print ags
    print egs
    print switch_pos
    '''
    insert flows table entries
    put all frwrding in table 1 and replacing macs with pmac in table 0
    todo : replacing macs, routing, bcast semantics 
    routing : for longer matches, give higher priority. of might not do longest prefix match. so force using priority
    for all edge switches, for upward packets, sending arp req(dest is bcast) to ctlr, v high priority
        for arp reply(dest not bcast), send to ctlr and submit to table 1 whihc does routing
    
    for ags, for other pods, hash and send to a cs. for same pod, look at switch pos and send to k/2+pos    
    for all core switches, have k entries. mask is 1st 16 bits. lopp from 0 to k-1, in 1st 16 bits, send to port k. amd maybe fr bcast adrs, flood
    '''
    
    
    for pod_num in range(num_pods):
        msg_cs = nx.nx_flow_mod(table_id = 0)
        msg_cs.match.eth_dst_with_mask = ( eth_addr_format(pod_num, 4) + ":00:00:00:00", "ff:ff:00:00:00:00")
        msg_cs.actions.append(of.ofp_action_output(port = pod_num + 1))
        for core_switch in cs:
            core.openflow.connections[core_switch].send(msg_cs)
        msg_a = nx.nx_flow_mod(table_id = 0)
        msg_a.match.eth_dst_with_mask = ( eth_addr_format(pod_num, 4) + ":00:00:00:00", "ff:ff:00:00:00:00")
        msg_a.priority = 2000
        msg_a.actions.append(of.ofp_action_output(port = (pod_num/2) + 1))#simple hashing
        msg_e = nx.nx_flow_mod(table_id = 2)
        msg_e.match.eth_dst_with_mask = ( eth_addr_format(pod_num, 4) + ":00:00:00:00", "ff:ff:00:00:00:00")
        msg_e.priority = 2000
        msg_e.actions.append(of.ofp_action_output(port = (pod_num/2) + 1))#simple hashing
        #msg_e.actions.append(nx.nx_action_resubmit.resubmit_table(table=1))
        for i in range(half_num_pods):
            for pod in range(num_pods):#put the above entry into all the agg and edge switches of all pods
                #print 'pod_num:{0}, i:{1}, match:{2}, ags:{3}, egs:{4}'.format(pod_num, i, msg.match, ags[pod_num][i], egs[pod_num][i] )
                core.openflow.connections[ags[pod][i]].send(msg_a)
                core.openflow.connections[egs[pod][i]].send(msg_e)
            msg_as = nx.nx_flow_mod(table_id = 0)
            prefix = eth_addr_format((pod_num<<8) + i, 6)
            msg_as.match.eth_dst_with_mask = ( prefix + ":00:00:00", "ff:ff:ff:00:00:00")
            msg_as.priority = 3000
            msg_as.actions.append(of.ofp_action_output(port = half_num_pods + i + 1))
            for j in range(half_num_pods):
                core.openflow.connections[ags[pod_num][j]].send(msg_as)
                #check for port num
                msg_es = nx.nx_flow_mod(table_id = 2)
                msg_es.match.eth_dst_with_mask = ( prefix + ':' + eth_addr_format(half_num_pods + j, 2) + ":00:00", "ff:ff:ff:ff:00:00")
                msg_es.priority = 3000
                msg_es.actions.append(of.ofp_action_output(port = half_num_pods + j + 1))
                #msg_es.actions.append(nx.nx_action_resubmit.resubmit_table(table=1))
                core.openflow.connections[egs[pod_num][i]].send(msg_es)

    for es in edge_switches:#for arp entries and wildcard resubmissions
        msg = nx.nx_flow_mod()
        msg.priority = 9000
        msg.match.eth_type = pkt.ethernet.ARP_TYPE
        msg.actions.append(of.ofp_action_output(port = of.OFPP_CONTROLLER))
        for i in range(half_num_pods + 1, num_pods + 1):
            msg.match.NXM_OF_IN_PORT = i
            core.openflow.connections[es].send(msg)
        msg = nx.nx_flow_mod(table_id = 0)
        msg.priority = 10
        msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=1))
        core.openflow.connections[es].send(msg)
        msg = nx.nx_flow_mod(table_id = 1)
        msg.priority = 10
        msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=2))
        core.openflow.connections[es].send(msg)

    #bcast semantics
    down_flood = []
    up_flood = []
    for port in range(1, half_num_pods + 1):#flood to all host ports
        up_flood.append(of.ofp_action_output(port = port))
        down_flood.append(of.ofp_action_output(port = port + half_num_pods))

    #trickle down
    msg = nx.nx_flow_mod(table_id = 0)
    msg.priority = 8500
    msg.match.eth_dst = 'ff:ff:ff:ff:ff:ff'
    for pod_num in range(num_pods):
        for i in range(half_num_pods):
            cona = core.openflow.connections[ags[pod_num][i]]
            cone = core.openflow.connections[egs[pod_num][i]]
            for in_port in range(1, half_num_pods + 1):
                #from up link, trickle down
                msg.actions = list(down_flood)
                msg.match.NXM_OF_IN_PORT = in_port
                cona.send(msg)
                cone.send(msg)
                #from down link, flood down and choose one up
                msg.match.NXM_OF_IN_PORT = in_port + half_num_pods
                msg.actions.pop(in_port  - 1)#remove the port it came from
                msg.actions.append(of.ofp_action_output(port = i + 1))#simple hashing to pick one up link.
                cona.send(msg)
                cone.send(msg)

    msg.actions = [of.ofp_action_output(port = of.OFPP_FLOOD)]
    for core_sw in cs:
        core.openflow.connections[core_sw].send(msg)

    #handle packet in after flow tables are installed and everything is set up
    core.openflow.addListenerByName("PacketIn", _handle_PacketIn)
    def __init__(self, connection):
        self.connection = connection
        connection.addListeners(self)
        if (connection.eth_addr.toStr() == "00:00:00:00:00:01"):
            print "Preparing of rules"
            msg = nx.nx_flow_mod_table_id()
            connection.send(msg)
            #table 0
            msg = nx.nx_flow_mod()
            msg.table_id = 0
            msg.priority = 1500
            msg.match.of_eth_dst = "00:00:00:00:00:00"
            msg.match.of_eth_type = 0x86dd
            msg.match.of_in_port = 1
            msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=1))
            self.connection.send(msg)

            msg = nx.nx_flow_mod()
            msg.table_id = 0
            msg.priority = 1000
            msg.match.of_eth_dst = "00:00:00:00:00:00"
            msg.match.of_eth_type = 0x86dd
            msg.match.nx_ipv6_dst = (IPAddr6("::1"), IPAddr6("::1"))
            msg.actions.append(of.ofp_action_output(port=1))
            msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=1))
            self.connection.send(msg)

            msg = nx.nx_flow_mod()
            msg.table_id = 0
            msg.priority = 500
            msg.match.of_eth_dst = "00:00:00:00:00:00"
            msg.match.of_eth_type = 0x86dd
            msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=1))
            self.connection.send(msg)

            #table 1
            msg = nx.nx_flow_mod()
            msg.table_id = 1
            msg.priority = 1000
            msg.match.of_eth_dst = "00:00:00:00:00:00"
            msg.match.of_eth_type = 0x86dd
            msg.match.nx_ipv6_dst = (IPAddr6("::2"), IPAddr6("::2"))
            msg.actions.append(of.ofp_action_output(port=1))
            self.connection.send(msg)

            msg = nx.nx_flow_mod()
            msg.table_id = 1
            msg.priority = 1500
            msg.match.of_eth_dst = "00:00:00:00:00:00"
            msg.match.of_eth_type = 0x86dd
            msg.match.of_in_port = 2
            self.connection.send(msg)

        if (connection.eth_addr.toStr() == "00:00:00:00:00:02"):
            print "Preparing of rules"
            msg = nx.nx_flow_mod_table_id()
            connection.send(msg)
            #table 0
            msg = nx.nx_flow_mod()
            msg.table_id = 0
            msg.priority = 1500
            msg.match.of_eth_dst = "00:00:00:00:00:00"
            msg.match.of_eth_type = 0x86dd
            msg.match.of_in_port = 1
            msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=1))
            self.connection.send(msg)

            msg = nx.nx_flow_mod()
            msg.table_id = 0
            msg.priority = 1000
            msg.match.of_eth_dst = "00:00:00:00:00:00"
            msg.match.of_eth_type = 0x86dd
            msg.match.nx_ipv6_dst = (IPAddr6("::2"), IPAddr6("::2"))
            msg.actions.append(of.ofp_action_output(port=1))
            msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=1))
            self.connection.send(msg)

            msg = nx.nx_flow_mod()
            msg.table_id = 0
            msg.priority = 500
            msg.match.of_eth_dst = "00:00:00:00:00:00"
            msg.match.of_eth_type = 0x86dd
            msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=1))
            self.connection.send(msg)
            #table 1
            msg = nx.nx_flow_mod()
            msg.table_id = 1
            msg.priority = 1000
            msg.match.of_eth_dst = "00:00:00:00:00:00"
            msg.match.of_eth_type = 0x86dd
            msg.match.nx_ipv6_dst = (IPAddr6("::4"), IPAddr6("::4"))
            msg.actions.append(of.ofp_action_output(port=2))
            self.connection.send(msg)

            msg = nx.nx_flow_mod()
            msg.table_id = 1
            msg.priority = 1500
            msg.match.of_eth_dst = "00:00:00:00:00:00"
            msg.match.of_eth_type = 0x86dd
            msg.match.of_in_port = 2
            self.connection.send(msg)
def insert_routes():
    #inserting frowarding tables into all the switches
    #maybe send barrier to all switches in the end
    for core_switch in core_switches:
        #each core switch coudl be con to more than 1 ags of a pod. so hash. ASSUMEPTION : a core switch is con to all pods
        switches = [[] for i in range(num_pods)]
        links = g[core_switch]
        _port_pod = {}
        _mask_ports = {}
        con = core.openflow.connections[core_switch]
        for src_port,link in links.iteritems():
            pod = switch_pos[link[0]][0]
            switches[pod].append(src_port)#appending src_port to pod no
            _port_pod[src_port] = pod
        pod_port[core_switch] = switches
        port_pod[core_switch] = _port_pod
        for pod_num in range(num_pods):                
            num_routes = len(switches[pod_num])
            if num_routes > 1:  #need hashing. hashing is based on port num
                msg_cs = nx.nx_flow_mod(table_id = 0)
                msg_cs.priority = 2000
                num_bits  = int(math.floor(math.log(num_routes, 2)))
                x = 2 ** num_bits   #Assumption:one core switch doesn't have more than 255 direct connections to a pod
                mask = 'ff:ff:00:' + eth_addr_format(x - 1, 2) + ':00:00'
                mask_for_bcast = '00:00:00:' + eth_addr_format(x - 1, 2) + ':00:00'
                prefix = eth_addr_format(pod_num, 4) + ':00:'
                suffix = ':00:00'
                for i in range(num_routes):
                    port = i % x
                    port_mask = prefix + eth_addr_format(port, 2) + suffix
                    msg_cs.match.eth_dst_with_mask = ( port_mask, mask)
                    dst_port = switches[pod_num][i]
                    msg_cs.actions = [of.ofp_action_output(port = dst_port)]
                    key = ('00:00:00:' + eth_addr_format(port, 2) + ':00:00', mask_for_bcast)
                    if key not in _mask_ports:
                        _mask_ports[key] = []
                    _mask_ports[key].append(dst_port)
                    con.send(msg_cs)
            else:
                msg_cs = nx.nx_flow_mod(table_id = 0)
                msg_cs.priority = 2000
                msg_cs.match.eth_dst_with_mask = ( eth_addr_format(pod_num, 4) + ":00:00:00:00", "ff:ff:00:00:00:00")
                msg_cs.actions.append(of.ofp_action_output(port = switches[pod_num][0]))
                con.send(msg_cs)
        mask_ports[core_switch] = _mask_ports

    for agg_switch in agg_switches:
        con = core.openflow.connections[agg_switch]
        up_ports = agg_up_ports[agg_switch]
        num_routes = len(up_ports)
        if num_routes > 1:  #need hashing. hashing is based on port num
            msg_as = nx.nx_flow_mod(table_id = 0)
            msg_as.priority = 2000
            num_bits  = int(math.floor(math.log(num_routes, 2)))
            x = 2 ** num_bits   #Assumption:one agg switch doesn't have more than 255 direct connections to core switches
            mask = '00:00:00:' + eth_addr_format(x - 1, 2) + ':00:00'
            prefix = '00:00:00:'
            suffix = ':00:00'
            for i in range(num_routes):
                port = i % x
                msg_as.match.eth_dst_with_mask = ( prefix + eth_addr_format(port, 2) + suffix, mask)
                msg_as.actions = [ of.ofp_action_output(port = up_ports[i]) ]
                con.send(msg_as)
        else:
            msg_as = nx.nx_flow_mod(table_id = 0)
            msg_as.priority = 2000
            msg_as.actions.append(of.ofp_action_output(port = up_ports[0]))
            con.send(msg_as)
      
        down_ports = agg_down_ports[agg_switch]
        pod_num = switch_pos[agg_switch][0]
        prefix = eth_addr_format(pod_num , 4) + ':'
        suffix = ':00:00:00'
        mask = 'ff:ff:ff:00:00:00'
        msg_as = nx.nx_flow_mod(table_id = 0)
        msg_as.priority = 3000

        for src_port in down_ports:
            pos = switch_pos[g[agg_switch][src_port][0]][1]
            msg_as.match.eth_dst_with_mask = ( prefix + eth_addr_format(pos, 2) + suffix, mask)
            msg_as.actions = [ of.ofp_action_output(port = src_port) ]
            con.send(msg_as)
    
    for edge_switch in edge_switches:
        con = core.openflow.connections[edge_switch]
        up_ports = g[edge_switch].keys()
        num_routes = len(up_ports)
        if num_routes > 1:  #need hashing. hashing is based on port num
            msg_es = nx.nx_flow_mod(table_id = 2)
            msg_es.priority = 2000
            num_bits  = int(math.floor(math.log(num_routes, 2)))
            x = 2 ** num_bits   #Assumption:one edge switch doesn't have more than 255 direct connections to agg switches
            mask = '00:00:00:' + eth_addr_format(x - 1, 2) + ':00:00'
            prefix = '00:00:00:'
            suffix = ':00:00'
            for i in range(num_routes):
                port = i % x
                msg_es.match.eth_dst_with_mask = ( prefix + eth_addr_format(port, 2) + suffix, mask)
                msg_es.actions = [ of.ofp_action_output(port = up_ports[i]) ]
                con.send(msg_es)
        else:
            msg_es = nx.nx_flow_mod(table_id = 2)
            msg_es.priority = 2000
            msg_es.actions.append(of.ofp_action_output(port = up_ports[0]))
            con.send(msg_es)
      
        down_ports = host_ports[edge_switch]
        pod_num = switch_pos[edge_switch][0]
        pos = switch_pos[edge_switch][1]
        prefix = eth_addr_format((pod_num << 8) + pos, 6) + ':'
        suffix = ':00:00'
        mask = 'ff:ff:ff:ff:00:00'
        msg_es = nx.nx_flow_mod(table_id = 2)
        msg_es.priority = 3000

        for port in down_ports:
            msg_es.match.eth_dst_with_mask = ( prefix + eth_addr_format(port, 2) + suffix, mask)
            msg_es.actions = [ of.ofp_action_output(port = port) ]
            con.send(msg_es)
    def _handle_BarrierIn_Mig_NS(e):
        #barrier handler for new switch
        if e.xid != xid_ns: #if its not this barrier, ignore
            return
        #log.debug( 'Barrier received for migrated pmac:{0}'.format(new_pmac) )
        e.connection.removeListener(handler_id[0])

        old_sw_con = core.openflow.connections[old_sw]
        msg = nx.nx_flow_mod(table_id = 0)
        msg.priority = 8000
        msg.hard_timeout = arp_cache_timeout
        msg.match.eth_dst = old_pmac
        rewrite_action = of.ofp_action_dl_addr.set_dst(adrs.EthAddr(new_pmac))
        msg.actions.append(rewrite_action)
        #choose one up link by hashing
        up_ports = g[old_sw].keys()
        num_routes = len(up_ports)
        #msg.actions.append(of.ofp_action_output(port = up_ports[ random.randint(0, num_routes - 1) ] ))#simple hashing. edge switch x sends to agg switch x
        #old_sw_con.send(msg)

        #if more than 2 up ports are there, then hashing is req. if 1 up port, then no hashing. if 2, then the other port other than inp port
        if num_routes == 1: #only one route
            msg.actions = [ rewrite_action, of.ofp_action_output(port = of.OFPP_IN_PORT) ]
            old_sw_con.send(msg)
        elif num_routes == 2:
            msg.match.NXM_OF_IN_PORT = up_ports[0]
            msg.actions = [ rewrite_action, of.ofp_action_output(port = up_ports[1] ) ]
            old_sw_con.send(msg)
            msg.match.NXM_OF_IN_PORT = up_ports[1]
            msg.actions = [ rewrite_action, of.ofp_action_output(port = up_ports[0] ) ]
            old_sw_con.send(msg)
        else: #3 or more ports. here need hahsing. based on src port num. also avoid the inp port. so match based on that also
            num_routes -= 1 #since we avoid each inp port
            num_bits  = int(math.floor(math.log(num_routes, 2)))
            x = 2 ** num_bits   #Assumption:one edge switch doesn't have more than 255 direct connections to agg switches
            mask = '00:00:00:' + eth_addr_format(x - 1, 2) + ':00:00'
            prefix = '00:00:00:'
            suffix = ':00:00'
            for ii in range(num_routes + 1):
                cand_ports = list(up_ports)
                msg.match.NXM_OF_IN_PORT = cand_ports.pop(ii) #remove the inp port from the list of op ports
                for i in range(num_routes):
                    port = i % x
                    msg.match.eth_src_with_mask = ( prefix + eth_addr_format(port, 2) + suffix, mask)
                    msg.actions = [ rewrite_action, of.ofp_action_output(port = cand_ports[i]) ]
                    old_sw_con.send(msg)

        msg = nx.nx_flow_mod(table_id = 0, command=of.OFPFC_DELETE)
        msg.priority = 5000
        msg.match.NXM_OF_IN_PORT = old_port
        msg.match.eth_src = old_amac
        old_sw_con.send(msg)
        msg = nx.nx_flow_mod(table_id = 1, command=of.OFPFC_DELETE)
        msg.priority = 5000
        msg.match.eth_dst = old_pmac
        old_sw_con.send(msg)
        
        #maybe send barrier and wait? to make sure its processed so that pkts to old pmac can still reach new place?
        barrier_os = of.ofp_barrier_request()
        xid_os = barrier_os.xid
        def _handle_BarrierIn_Mig_OS(e):
            #barrier handler for old switch
            if e.xid != xid_os: #if its not this barrier, ignore
                return
            #log.debug( 'Barrier received for diverting flows to pmac:{0}'.format(new_pmac) )
            e.connection.removeListener(handler_id[1])
            arp_table[ip] = new_pmac
            actual_pmac.pop( pmac_actual.pop(old_pmac) )#remove old pmac to actual and vice versa since they are not valid anymore
            actual_pmac[org_mac] = new_pmac
            pmac_actual[new_pmac] = org_mac
            #this nxt 2 lines should be in a fn called after the timeout. we dont want to assing old pmac to anyone until then
            def _remove_old_pmac():
                vmid = int(old_pmac[-5:].replace(':',''),16)
                assigned_pmac[old_sw][old_port] = assigned_pmac[old_sw][old_port][:vmid] + '0' + assigned_pmac[old_sw][old_port][vmid + 1:]
            Timer(arp_cache_timeout, _remove_old_pmac)
            if event:
                _handle_arp(event)
        handler_id[1] = old_sw_con.addListenerByName("BarrierIn", _handle_BarrierIn_Mig_OS)
        old_sw_con.send(barrier_os)
    def constructRule(self, nv, packet, ingressPort, connection, event):
        self.networkview = nv
        hosts = self.networkview.access
        routes = self.networkview.routes
        #self.hostHops = {}
        currentOutPort = 0
        currentOutSrcIP = None
        currentOutDstIP = None
        currentOutSrcMac = None
        currentOutDstMac = None
        flowRule = None

        #check if request comes from target node or not
        if str(packet.src) == str(self.networkview.target.eth_addr) and (
                str(nv.getNodeByEth(packet.src).visible) == "v"
                or nv.getNodeByEth(packet.src).isHoneypot == True):
            if packet.type == ethernet.ARP_TYPE:
                pkt = packet.find('arp')
                if pkt != None:
                    if pkt.opcode == arp.REQUEST:
                        print("ARP packet src " + str(pkt.protosrc) + " " +
                              str(pkt.protodst) + " " +
                              str(nv.canContact(pkt.protosrc, pkt.protodst)) +
                              " " + str(ingressPort))
                        #check if request is comming from target
                        if str(pkt.hwsrc) == str(
                                self.networkview.target.eth_addr):
                            if nv.canContact(pkt.protosrc,
                                             pkt.protodst) == True:
                                flowRule = nx.nx_flow_mod()
                                flowRule.match.in_port = ingressPort
                                flowRule.match.NXM_OF_ETH_TYPE = ethernet.ARP_TYPE
                                flowRule.match.NXM_OF_ARP_OP = arp.REQUEST
                                flowRule.match.eth_src = EthAddr(pkt.hwsrc)
                                flowRule.idle_timeout = 30
                                flowRule.priority = 2
                                flowRule.actions.append(
                                    of.ofp_action_output(
                                        port=int(nv.server.switchPort)))
                                connection.send(flowRule)
                                self.logging.logRule(flowRule, "ARP")
                                currentOutPort = int(nv.server.switchPort)

                                flowRule = nx.nx_flow_mod()
                                flowRule.match.in_port = int(
                                    nv.server.switchPort)
                                flowRule.match.NXM_OF_ETH_TYPE = ethernet.ARP_TYPE
                                flowRule.match.NXM_OF_ARP_OP = arp.REPLY
                                flowRule.match.eth_dst = EthAddr(pkt.hwsrc)
                                flowRule.idle_timeout = 30
                                flowRule.priority = 2
                                flowRule.actions.append(
                                    of.ofp_action_output(port=ingressPort))
                                connection.send(flowRule)
                                self.logging.logRule(flowRule, "ARP")
                        else:
                            #if request is not from target, learn route
                            flowRule = nx.nx_flow_mod()
                            flowRule.match.in_port = ingressPort
                            flowRule.match.NXM_OF_ETH_TYPE = ethernet.ARP_TYPE
                            flowRule.match.NXM_OF_ARP_OP = arp.REQUEST
                            flowRule.match.eth_src = EthAddr(pkt.hwsrc)
                            flowRule.idle_timeout = 30
                            flowRule.priority = 2
                            flowRule.actions.append(
                                of.ofp_action_output(
                                    port=int(nv.server.switchPort)))
                            connection.send(flowRule)
                            self.logging.logRule(flowRule, "ARP")
                            currentOutPort = int(nv.server.switchPort)

                            flowRule = nx.nx_flow_mod()
                            flowRule.match.in_port = int(nv.server.switchPort)
                            flowRule.match.NXM_OF_ETH_TYPE = ethernet.ARP_TYPE
                            flowRule.match.NXM_OF_ARP_OP = arp.REPLY
                            flowRule.match.eth_dst = EthAddr(pkt.hwsrc)
                            flowRule.idle_timeout = 30
                            flowRule.priority = 2
                            flowRule.actions.append(
                                of.ofp_action_output(port=ingressPort))
                            connection.send(flowRule)
                            self.logging.logRule(flowRule, "ARP")

            elif packet.type == ethernet.IP_TYPE:
                #print("IP packet")
                #create rules for route to the specific host
                route_eth_dst = None
                route_ip_dst = None
                route_ip_src = None
                #print("Route src " + str(packet.payload.srcip) + " " + str(packet.payload.dstip) + " " + str(nv.canContact(packet.payload.srcip,packet.payload.dstip)))
                if nv.canContact(packet.payload.srcip,
                                 packet.payload.dstip) == True:
                    hopCt = 0
                    for r in routes:
                        for i in range(1, (len(r.hops) - 1)):
                            hop = r.hops[i]
                            #print("hopCt " + str(hopCt) + " isRouter " + str(hop.isRouter))
                            #print("Route src " + str(packet.payload.srcip) + " " + str(packet.payload.dstip) + " " + str(nv.canContact(packet.payload.srcip,packet.payload.dstip)))
                            if hop.isRouter == True and packet.payload.srcip == r.startNode.decepted_ip_addr and packet.payload.dstip == r.endNode.decepted_ip_addr:
                                if packet.payload.ttl <= (len(r.hops) - 2):
                                    #establish route if packet ttl matches, forward to deception server
                                    hopCt += 1
                                    flowRule = nx.nx_flow_mod()
                                    flowRule.match.NXM_OF_ETH_TYPE = ethernet.IP_TYPE
                                    flowRule.match.NXM_NX_IP_TTL = hopCt
                                    flowRule.match.eth_src = EthAddr(
                                        r.startNode.decepted_eth_addr)
                                    #flowRule.match.eth_dst = EthAddr(r.endNode.decepted_eth_addr)
                                    flowRule.match.eth_dst = EthAddr(
                                        str(self.networkview.gateway.eth_addr))
                                    flowRule.match.ip_src = IPAddr(
                                        r.startNode.decepted_ip_addr)
                                    flowRule.match.ip_dst = IPAddr(
                                        r.endNode.decepted_ip_addr)
                                    flowRule.idle_timeout = 30
                                    flowRule.priority = 2
                                    flowRule.actions.append(
                                        of.ofp_action_output(
                                            port=int(nv.server.switchPort)))
                                    connection.send(flowRule)
                                    self.logging.logRule(flowRule, "")
                                    #port for current packet on multi hop route
                                    currentOutPort = int(
                                        r.hops[packet.payload.ttl].switchPort)
                                    print("1 - Multi hop port " +
                                          str(currentOutPort))

                                    #establish route for answer packet from deception server back to target node
                                    flowRule = nx.nx_flow_mod()
                                    flowRule.match.NXM_OF_ETH_TYPE = ethernet.IP_TYPE
                                    flowRule.match.eth_src = EthAddr(
                                        r.hops[hopCt].decepted_eth_addr)
                                    #flowRule.match.eth_dst = EthAddr(r.endNode.decepted_eth_addr)
                                    flowRule.match.eth_dst = EthAddr(
                                        r.startNode.decepted_eth_addr)
                                    flowRule.match.ip_src = IPAddr(
                                        r.hops[hopCt].decepted_ip_addr)
                                    flowRule.match.ip_dst = IPAddr(
                                        r.startNode.decepted_ip_addr)
                                    for d in range(0, hopCt):
                                        flowRule.actions.append(
                                            nx.nx_action_dec_ttl())
                                    flowRule.idle_timeout = 30
                                    flowRule.priority = 2
                                    flowRule.actions.append(
                                        of.ofp_action_output(
                                            port=int(ingressPort)))
                                    connection.send(flowRule)
                                    self.logging.logRule(flowRule, "")
                                else:
                                    hopCt = (len(r.hops) - 2)

                    route_eth_dst = packet.dst
                    route_ip_dst = packet.payload.dstip
                    route_ip_src = packet.payload.srcip

                    if hopCt > 0:
                        maxHop = hopCt
                        #forward packets with TTL to destination
                        #print("IP: " + str(route_ip_dst) + " V: " + str(nv.getNodeByDecIP(route_ip_dst).visible))
                        if nv.getNodeByDecIP(
                                route_ip_dst
                        ).visible == "v" or nv.getNodeByDecIP(
                                route_ip_dst).isHoneypot == True:
                            for ttl in range((maxHop + 1), 65):
                                flowRule = nx.nx_flow_mod()
                                flowRule.match.of_eth_type = ethernet.IP_TYPE
                                flowRule.match.eth_src = EthAddr(
                                    str(self.networkview.target.eth_addr))
                                flowRule.match.eth_dst = EthAddr(
                                    str(self.networkview.gateway.eth_addr))
                                flowRule.match.ip_src = IPAddr(
                                    str(self.networkview.target.
                                        decepted_ip_addr))
                                flowRule.match.ip_dst = IPAddr(
                                    str(route_ip_dst))
                                flowRule.match.NXM_NX_IP_TTL = ttl
                                flowRule.idle_timeout = 30
                                flowRule.priority = 1
                                flowRule.actions.append(
                                    of.ofp_action_nw_addr.set_src(
                                        IPAddr(
                                            self.networkview.target.ip_addr)))
                                flowRule.actions.append(
                                    of.ofp_action_dl_addr.set_src(
                                        EthAddr(
                                            self.networkview.target.eth_addr)))
                                flowRule.actions.append(
                                    of.ofp_action_nw_addr.set_dst(
                                        IPAddr(
                                            nv.getNodeByDecIP(
                                                route_ip_dst).ip_addr)))
                                flowRule.actions.append(
                                    of.ofp_action_dl_addr.set_dst(
                                        EthAddr(
                                            nv.getNodeByDecIP(
                                                route_ip_dst).eth_addr)))
                                flowRule.actions.append(
                                    of.ofp_action_output(port=int(
                                        nv.getNodeByDecIP(
                                            route_ip_dst).switchPort)))
                                connection.send(flowRule)
                                self.logging.logRule(flowRule, "")
                                if packet.payload.ttl > hopCt:
                                    currentOutPort = int(
                                        nv.getNodeByDecIP(
                                            route_ip_dst).switchPort)
                                    currentOutSrcIP = IPAddr(
                                        self.networkview.target.ip_addr)
                                    currentOutDstIP = IPAddr(
                                        nv.getNodeByDecIP(
                                            route_ip_dst).ip_addr)
                                    currentOutSrcMac = EthAddr(
                                        self.networkview.target.eth_addr)
                                    currentOutDstMac = EthAddr(
                                        nv.getNodeByDecIP(
                                            route_ip_dst).eth_addr)

                            #send back to target and decrease ttl
                            flowRule = nx.nx_flow_mod()
                            flowRule.match.of_eth_type = ethernet.IP_TYPE
                            flowRule.match.eth_src = EthAddr(
                                str(nv.getNodeByDecIP(route_ip_dst).eth_addr))
                            flowRule.match.ip_src = IPAddr(
                                nv.getNodeByDecIP(route_ip_dst).ip_addr)
                            flowRule.match.ip_dst = IPAddr(
                                str(nv.getNodeByDecIP(route_ip_src).ip_addr))
                            flowRule.match.eth_dst = EthAddr(
                                str(nv.getNodeByDecIP(route_ip_src).eth_addr))
                            flowRule.idle_timeout = 30
                            flowRule.priority = 1
                            for hop in range(0, hopCt):
                                flowRule.actions.append(nx.nx_action_dec_ttl())
                            #print("Decrease ttl by " + str(hopCount))
                            flowRule.actions.append(
                                of.ofp_action_nw_addr.set_src(
                                    IPAddr(
                                        str(
                                            nv.getNodeByDecIP(route_ip_dst).
                                            decepted_ip_addr))))
                            flowRule.actions.append(
                                of.ofp_action_dl_addr.set_src(
                                    EthAddr(
                                        self.networkview.gateway.eth_addr)))
                            flowRule.actions.append(
                                of.ofp_action_nw_addr.set_dst(
                                    IPAddr(self.networkview.target.
                                           decepted_ip_addr)))
                            flowRule.actions.append(
                                of.ofp_action_dl_addr.set_dst(
                                    EthAddr(self.networkview.target.eth_addr)))
                            flowRule.actions.append(
                                of.ofp_action_output(port=int(
                                    self.networkview.target.switchPort)))
                            connection.send(flowRule)
                            self.logging.logRule(flowRule, "")

                    else:
                        if nv.getNodeByDecIP(
                                route_ip_dst
                        ).visible == "v" or nv.getNodeByDecIP(
                                route_ip_dst).isHoneypot == True:
                            flowRule = nx.nx_flow_mod()
                            flowRule.match.of_eth_type = ethernet.IP_TYPE
                            flowRule.match.eth_src = EthAddr(
                                str(self.networkview.target.eth_addr))
                            flowRule.match.eth_dst = EthAddr(
                                str(route_eth_dst))
                            flowRule.match.ip_src = IPAddr(
                                str(self.networkview.target.decepted_ip_addr))
                            flowRule.match.ip_dst = IPAddr(str(route_ip_dst))
                            flowRule.idle_timeout = 30
                            flowRule.priority = 1
                            flowRule.actions.append(
                                of.ofp_action_nw_addr.set_src(
                                    IPAddr(self.networkview.target.ip_addr)))
                            flowRule.actions.append(
                                of.ofp_action_dl_addr.set_src(
                                    EthAddr(self.networkview.target.eth_addr)))
                            flowRule.actions.append(
                                of.ofp_action_nw_addr.set_dst(
                                    IPAddr(
                                        nv.getNodeByDecIP(
                                            route_ip_dst).ip_addr)))
                            flowRule.actions.append(
                                of.ofp_action_dl_addr.set_dst(
                                    EthAddr(
                                        nv.getNodeByDecIP(
                                            route_ip_dst).eth_addr)))
                            flowRule.actions.append(
                                of.ofp_action_output(port=int(
                                    nv.getNodeByDecIP(
                                        route_ip_dst).switchPort)))
                            connection.send(flowRule)
                            self.logging.logRule(flowRule, "")
                            currentOutPort = int(
                                nv.getNodeByDecIP(route_ip_dst).switchPort)
                            currentOutSrcIP = IPAddr(
                                self.networkview.target.ip_addr)
                            currentOutDstIP = IPAddr(
                                nv.getNodeByDecIP(route_ip_dst).ip_addr)
                            currentOutSrcMac = EthAddr(
                                self.networkview.target.eth_addr)
                            currentOutDstMac = EthAddr(
                                nv.getNodeByDecIP(route_ip_dst).eth_addr)

                            #send back to target and decrease ttl
                            flowRule = nx.nx_flow_mod()
                            flowRule.match.of_eth_type = ethernet.IP_TYPE
                            flowRule.match.eth_src = EthAddr(
                                str(nv.getNodeByDecIP(route_ip_dst).eth_addr))
                            flowRule.match.ip_src = IPAddr(
                                nv.getNodeByDecIP(route_ip_dst).ip_addr)
                            flowRule.match.ip_dst = IPAddr(
                                self.networkview.target.ip_addr)
                            flowRule.match.eth_dst = EthAddr(
                                self.networkview.target.eth_addr)
                            flowRule.idle_timeout = 30
                            flowRule.priority = 1
                            flowRule.actions.append(
                                of.ofp_action_nw_addr.set_src(
                                    IPAddr(
                                        str(
                                            nv.getNodeByDecIP(route_ip_dst).
                                            decepted_ip_addr))))
                            flowRule.actions.append(
                                of.ofp_action_dl_addr.set_src(
                                    str(
                                        nv.getNodeByDecIP(
                                            route_ip_dst).decepted_eth_addr)))
                            flowRule.actions.append(
                                of.ofp_action_nw_addr.set_dst(
                                    IPAddr(self.networkview.target.
                                           decepted_ip_addr)))
                            flowRule.actions.append(
                                of.ofp_action_dl_addr.set_dst(
                                    EthAddr(self.networkview.target.eth_addr)))
                            flowRule.actions.append(
                                of.ofp_action_output(port=int(
                                    self.networkview.target.switchPort)))
                            connection.send(flowRule)
                            self.logging.logRule(flowRule, "")

                    #handle nested packets in icmp error by forwarding it to the deception server
                    flowRule = nx.nx_flow_mod()
                    flowRule.match.of_eth_type = ethernet.IP_TYPE
                    flowRule.match.of_ip_proto = ipv4.ICMP_PROTOCOL
                    flowRule.match.of_icmp_code = 3
                    flowRule.match.of_icmp_type = 3
                    flowRule.match.in_port = int(
                        nv.getNodeByDecIP(route_ip_dst).switchPort)
                    flowRule.match.eth_src = EthAddr(
                        str(nv.getNodeByDecIP(route_ip_dst).eth_addr))
                    flowRule.match.ip_src = IPAddr(
                        nv.getNodeByDecIP(route_ip_dst).ip_addr)
                    flowRule.match.ip_dst = IPAddr(
                        str(self.networkview.target.ip_addr))
                    flowRule.match.eth_dst = EthAddr(
                        str(self.networkview.target.eth_addr))
                    flowRule.idle_timeout = 30
                    flowRule.priority = 1000
                    for hop in range(0, hopCt):
                        flowRule.actions.append(nx.nx_action_dec_ttl())
                    flowRule.actions.append(
                        of.ofp_action_nw_addr.set_src(
                            IPAddr(
                                str(
                                    nv.getNodeByDecIP(
                                        route_ip_dst).decepted_ip_addr))))
                    if hopCt > 0:
                        flowRule.actions.append(
                            of.ofp_action_dl_addr.set_src(
                                EthAddr(self.networkview.gateway.eth_addr)))
                    else:
                        flowRule.actions.append(
                            of.ofp_action_dl_addr.set_src(
                                EthAddr(
                                    str(
                                        nv.getNodeByDecIP(
                                            route_ip_dst).decepted_eth_addr))))
                    flowRule.actions.append(
                        of.ofp_action_nw_addr.set_dst(
                            IPAddr(self.networkview.target.decepted_ip_addr)))
                    flowRule.actions.append(
                        of.ofp_action_dl_addr.set_dst(
                            EthAddr(self.networkview.target.eth_addr)))
                    flowRule.actions.append(
                        of.ofp_action_output(port=int(nv.server.switchPort)))
                    if packet.payload.protocol == ipv4.ICMP_PROTOCOL:
                        if packet.payload.payload.type == 3 and packet.payload.payload.code == 3:
                            currentOutPort = int(nv.server.switchPort)
                    connection.send(flowRule)
                    self.logging.logRule(flowRule, "")

                    #send response from deception server back to target host
                    flowRule = nx.nx_flow_mod()
                    flowRule.match.of_eth_type = ethernet.IP_TYPE
                    flowRule.match.of_ip_proto = ipv4.ICMP_PROTOCOL
                    flowRule.match.of_icmp_code = 3
                    flowRule.match.of_icmp_type = 3
                    flowRule.match.in_port = int(nv.server.switchPort)
                    if hopCt > 0:
                        flowRule.match.eth_src = EthAddr(
                            str(self.networkview.gateway.eth_addr))
                    else:
                        flowRule.match.eth_src = EthAddr(
                            str(
                                nv.getNodeByDecIP(
                                    route_ip_dst).decepted_eth_addr))
                    flowRule.match.ip_src = IPAddr(
                        nv.getNodeByDecIP(route_ip_dst).decepted_ip_addr)
                    flowRule.match.ip_dst = IPAddr(
                        str(self.networkview.target.decepted_ip_addr))
                    flowRule.match.eth_dst = EthAddr(
                        str(self.networkview.target.eth_addr))
                    flowRule.idle_timeout = 30
                    flowRule.priority = 1000
                    flowRule.actions.append(
                        of.ofp_action_output(
                            port=int(self.networkview.target.switchPort)))
                    connection.send(flowRule)
                    self.logging.logRule(flowRule, "")

                #if packet.payload.protocol == ipv4.ICMP_PROTOCOL:
                #    print("ICMP packet")
                #if packet.payload.protocol == ipv4.TCP_PROTOCOL:
                #    print("TCP packet")

                if packet.payload.protocol == ipv4.UDP_PROTOCOL:
                    print("Received UDP packet with TTL " +
                          str(packet.payload.ttl))
                    if packet.payload.payload.srcport == 68 and packet.payload.payload.dstport == 67:
                        #Handle DHCP request
                        #print("Create rule " + str("DHCP from port 68 ") + "to port " + str(1))
                        flowRule = nx.nx_flow_mod()
                        flowRule.match.of_eth_type = ethernet.IP_TYPE
                        flowRule.match.of_ip_proto = ipv4.UDP_PROTOCOL
                        flowRule.match.eth_src = packet.src
                        #flowRule.match.eth_dst = nv.server.eth_addr
                        flowRule.match.udp_src = int(68)
                        flowRule.match.udp_dst = int(67)
                        flowRule.idle_timeout = 30
                        flowRule.actions.append(
                            of.ofp_action_output(
                                port=int(nv.server.switchPort)))
                        connection.send(flowRule)
                        self.logging.logRule(flowRule, "DHCP")
                        currentOutPort = int(nv.server.switchPort)

                        #print("Create rule " + str("DHCP from port 67 ") + " to port " + str(h.switchPort))
                        flowRule = nx.nx_flow_mod()
                        flowRule.match.of_eth_type = ethernet.IP_TYPE
                        flowRule.match.of_ip_proto = ipv4.UDP_PROTOCOL
                        flowRule.match.eth_src = nv.server.eth_addr
                        flowRule.match.eth_dst = packet.src
                        flowRule.match.udp_src = int(67)
                        flowRule.match.udp_dst = int(68)
                        flowRule.idle_timeout = 30
                        flowRule.actions.append(
                            of.ofp_action_output(port=int(ingressPort)))
                        connection.send(flowRule)
                        self.logging.logRule(flowRule, "DHCP")

            #send out current packet
            if currentOutPort != 0:
                print("Sending current packet out on port " +
                      str(currentOutPort))
                outPkt = of.ofp_packet_out(data=event.ofp)
                if currentOutSrcIP != None:
                    outPkt.actions.append(
                        of.ofp_action_nw_addr.set_src(currentOutSrcIP))
                    outPkt.actions.append(
                        of.ofp_action_nw_addr.set_dst(currentOutDstIP))
                    outPkt.actions.append(
                        of.ofp_action_dl_addr.set_src(currentOutSrcMac))
                    outPkt.actions.append(
                        of.ofp_action_dl_addr.set_dst(currentOutDstMac))
                outPkt.actions.append(
                    of.ofp_action_output(port=int(currentOutPort)))
                connection.send(outPkt)

        else:
            currentOutPort == 0
            currentOutSrcIP = None
            currentOutDstIP = None
            currentOutSrcMac = None
            currentOutDstMac = None
            #print("Handle traffic of other nodes beside target nodes " + str(packet.src) + " " + str(packet.dst))
            if packet.type == ethernet.ARP_TYPE:
                pkt = packet.find('arp')
                if pkt != None:
                    if pkt.opcode == arp.REQUEST:
                        flowRule = nx.nx_flow_mod()
                        flowRule.match.in_port = ingressPort
                        flowRule.match.NXM_OF_ETH_TYPE = ethernet.ARP_TYPE
                        flowRule.match.NXM_OF_ARP_OP = arp.REQUEST
                        flowRule.match.eth_src = EthAddr(pkt.hwsrc)
                        flowRule.idle_timeout = 30
                        flowRule.priority = 2
                        flowRule.actions.append(
                            of.ofp_action_output(
                                port=int(nv.server.switchPort)))
                        connection.send(flowRule)
                        self.logging.logRule(flowRule, "ARP")

                        flowRule = nx.nx_flow_mod()
                        flowRule.match.in_port = int(nv.server.switchPort)
                        flowRule.match.NXM_OF_ETH_TYPE = ethernet.ARP_TYPE
                        flowRule.match.NXM_OF_ARP_OP = arp.REPLY
                        flowRule.match.eth_dst = EthAddr(pkt.hwsrc)
                        flowRule.idle_timeout = 30
                        flowRule.priority = 2
                        flowRule.actions.append(
                            of.ofp_action_output(port=ingressPort))
                        connection.send(flowRule)
                        self.logging.logRule(flowRule, "ARP")

            else:
                src_node = nv.getNodeByEth(packet.src)
                dst_node = nv.getNodeByEth(packet.dst)
                #print("Src node " + str(src_node) + " dst node " + str(dst_node) + " src " + str(packet.src) + " dst " + str(packet.dst))
                if src_node != None and dst_node != None:
                    #print("Route traffic from " + str(src_node.ip_addr) + " to " + str(dst_node.ip_addr))
                    if str(packet.dst) == str(
                            self.networkview.target.eth_addr):
                        flowRule = nx.nx_flow_mod()
                        flowRule.match.of_eth_type = ethernet.IP_TYPE
                        flowRule.match.eth_dst = EthAddr(
                            str(self.networkview.target.eth_addr))
                        flowRule.match.eth_src = EthAddr(str(
                            src_node.eth_addr))
                        flowRule.match.ip_dst = IPAddr(
                            str(self.networkview.target.ip_addr))
                        flowRule.match.ip_src = IPAddr(str(src_node.ip_addr))
                        flowRule.idle_timeout = 30
                        flowRule.priority = 1
                        flowRule.actions.append(
                            of.ofp_action_nw_addr.set_src(
                                IPAddr(self.networkview.target.ip_addr)))
                        #flowRule.actions.append(of.ofp_action_dl_addr.set_src(EthAddr(self.networkview.target.eth_addr)))
                        flowRule.actions.append(
                            of.ofp_action_nw_addr.set_dst(
                                IPAddr(
                                    self.networkview.target.decepted_ip_addr)))
                        #flowRule.actions.append(of.ofp_action_dl_addr.set_dst(EthAddr(self.networkview.target.decepted_eth_addr)))
                        flowRule.actions.append(
                            of.ofp_action_output(
                                port=int(self.networkview.target.switchPort)))
                        connection.send(flowRule)
                        self.logging.logRule(flowRule, "")
                        currentOutPort = int(
                            self.networkview.target.switchPort)
                        currentOutSrcIP = IPAddr(
                            self.networkview.target.ip_addr)
                        currentOutDstIP = IPAddr(
                            self.networkview.target.decepted_ip_addr)

                        flowRule = nx.nx_flow_mod()
                        flowRule.match.of_eth_type = ethernet.IP_TYPE
                        flowRule.match.eth_src = EthAddr(
                            str(self.networkview.target.decepted_eth_addr))
                        flowRule.match.eth_dst = EthAddr(
                            str(self.networkview.gateway.decepted_eth_addr))
                        flowRule.match.ip_src = IPAddr(
                            str(self.networkview.target.decepted_ip_addr))
                        flowRule.match.ip_dst = IPAddr(
                            str(self.networkview.target.ip_addr))
                        flowRule.idle_timeout = 30
                        flowRule.priority = 1
                        flowRule.actions.append(
                            of.ofp_action_nw_addr.set_src(
                                IPAddr(str(self.networkview.target.ip_addr))))
                        flowRule.actions.append(
                            of.ofp_action_dl_addr.set_src(
                                EthAddr(str(
                                    self.networkview.target.eth_addr))))
                        flowRule.actions.append(
                            of.ofp_action_nw_addr.set_dst(
                                IPAddr(src_node.ip_addr)))
                        flowRule.actions.append(
                            of.ofp_action_dl_addr.set_dst(
                                EthAddr(src_node.eth_addr)))
                        flowRule.actions.append(
                            of.ofp_action_output(
                                port=int(src_node.switchPort)))
                        connection.send(flowRule)
                        self.logging.logRule(flowRule, "")
                    else:
                        flowRule = nx.nx_flow_mod()
                        flowRule.match.of_eth_type = ethernet.IP_TYPE
                        flowRule.match.eth_dst = EthAddr(str(
                            dst_node.eth_addr))
                        flowRule.match.eth_src = EthAddr(str(
                            src_node.eth_addr))
                        flowRule.match.ip_dst = IPAddr(str(dst_node.ip_addr))
                        flowRule.match.ip_src = IPAddr(str(src_node.ip_addr))
                        flowRule.idle_timeout = 30
                        flowRule.priority = 1
                        flowRule.actions.append(
                            of.ofp_action_output(
                                port=int(dst_node.switchPort)))
                        connection.send(flowRule)
                        self.logging.logRule(flowRule, "")
                        currentOutPort = int(dst_node.switchPort)

                        flowRule = nx.nx_flow_mod()
                        flowRule.match.of_eth_type = ethernet.IP_TYPE
                        flowRule.match.eth_dst = EthAddr(str(
                            src_node.eth_addr))
                        flowRule.match.eth_src = EthAddr(str(
                            dst_node.eth_addr))
                        flowRule.match.ip_dst = IPAddr(str(src_node.ip_addr))
                        flowRule.match.ip_src = IPAddr(str(dst_node.ip_addr))
                        flowRule.idle_timeout = 30
                        flowRule.priority = 1
                        flowRule.actions.append(
                            of.ofp_action_output(
                                port=int(src_node.switchPort)))
                        connection.send(flowRule)
                        self.logging.logRule(flowRule, "")

            #send out current packet
            if currentOutPort != 0:
                print("Sending current packet out on port " +
                      str(currentOutPort))
                outPkt = of.ofp_packet_out(data=event.ofp)
                if currentOutSrcIP != None:
                    outPkt.actions.append(
                        of.ofp_action_nw_addr.set_src(currentOutSrcIP))
                    outPkt.actions.append(
                        of.ofp_action_nw_addr.set_dst(currentOutDstIP))
                outPkt.actions.append(
                    of.ofp_action_output(port=int(currentOutPort)))
                connection.send(outPkt)
def _start():
    global started
    if started:
        return
    started = True
    print 'App initialization started'
    log.info( 'Starting App initialization : num_switches:{0}, num_links:{1}'.format(num_switches, cur_num_links) )
    global core_switches
    log.info( 'Graph : {0}'.format(g))
    for dpid,links in g.iteritems():
        if ( len(links) / float(total_ports[dpid]) ) <= max_connected_perc:  
            edge_switches.add(dpid)
            assigned_pmac[dpid] = {}
            host_ports[dpid] = list( set(ports[dpid]) - set(g[dpid].keys()) )
            for port in host_ports[dpid]:#for all the edge host ports, init the assigned pmac string
                    assigned_pmac[dpid][port] = init_asgn_str
    for dpid in edge_switches:  #traverse through all links of the edge switch
        links = g[dpid]
        for src_port,link in links.iteritems():
            if link[0] not in agg_switches: #1st time we see this agg, add it and init the down ports list
                agg_switches.add(link[0])
                agg_down_ports[link[0]] = []
            agg_down_ports[link[0]].append(link[1])
    core_switches = all_switches.difference(agg_switches.union(edge_switches))
    #global cs
    #cs = list(core_switches)#not really req. in arp reply, we r sending to one core switch. maybe that itself not req. send to nearest edge switch? use pmac fn

    for dpid in agg_switches:
        agg_up_ports[dpid] = list( set(g[dpid].keys()) - set(agg_down_ports[dpid]) )

    log.info( 'Edge switches : {0}'.format(edge_switches) )
    log.info( 'Aggregate switches : {0}'.format(agg_switches) )
    log.info( 'Core switches : {0}'.format(core_switches) )

    '''
    bfs to get the pods.
    make all the dpids of core switch links in agg switch -ve. and do bfs on all agg switches
    the switch pos can used as visited or not. we can have global switch nos or sep switch nos for agg and edge. right now leaving it global. can change
    '''

    toggle_agg_core_links() #logically remove agg to core links

    pod = 0 #make it one here. and some changes later. like egs and ags are zero index pod num. maybe in bcast semanitcs also somewhere
    for agg in agg_switches:
        if switch_pos[agg][0] == -1 :   #new switch
            bfs(agg, pod)
            pod += 1
    global num_pods
    num_pods = pod

    toggle_agg_core_links() #renable links after discovering pods using bfs

    log.info( 'Nume of pods : {0} \nSwitch positions : {1}'.format( num_pods, switch_pos ) )

    insert_routes()
    for es in edge_switches:#for arp entries and wildcard resubmissions
        msg = nx.nx_flow_mod()
        msg.priority = 9000
        msg.match.eth_type = pkt.ethernet.ARP_TYPE
        msg.actions.append(of.ofp_action_output(port = of.OFPP_CONTROLLER))
        for port in host_ports[es]:
            msg.match.NXM_OF_IN_PORT = port
            core.openflow.connections[es].send(msg)
        msg = nx.nx_flow_mod(table_id = 0)
        msg.priority = 10
        msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=1))
        core.openflow.connections[es].send(msg)
        msg = nx.nx_flow_mod(table_id = 1)
        msg.priority = 10
        msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=2))
        core.openflow.connections[es].send(msg)

    #bcast semantics
    msg = nx.nx_flow_mod(table_id = 0)
    msg.priority = 8500
    msg.match.eth_dst = 'ff:ff:ff:ff:ff:ff'
    #agg switch
    for agg in agg_switches:
        con = core.openflow.connections[agg]
        num_down_links = len(agg_down_ports[agg])
        down_actions = [ of.ofp_action_output(port = dp) for dp in agg_down_ports[agg] ]
        #pkt downwards
        msg.actions = down_actions
        for in_port in agg_up_ports[agg]:
            msg.match.NXM_OF_IN_PORT = in_port
            con.send(msg)
        
        #for pkt upwrds
        num_up_links = len(agg_up_ports[agg])
        for i in range(num_down_links):
            msg.match.NXM_OF_IN_PORT = agg_down_ports[agg][i]
            msg.actions = list(down_actions)
            msg.actions.pop(i)
            #and add one up link here. assuming num of down links is more than or equal to num up links
            msg.actions.append(of.ofp_action_output(port = agg_up_ports[agg][ i % num_up_links ]))
            con.send(msg)
    
    #edge switch
    msg = nx.nx_flow_mod(table_id = 2)
    msg.priority = 8500
    msg.match.eth_dst = 'ff:ff:ff:ff:ff:ff'
    for es in edge_switches:
        con = core.openflow.connections[es]
        num_down_links = len(host_ports[es])
        down_actions = [ of.ofp_action_output(port = dp) for dp in host_ports[es] ]
        #pkt downwards
        msg.actions = down_actions
        for in_port in g[es]:
            msg.match.NXM_OF_IN_PORT = in_port
            con.send(msg)
        
        #for pkt upwrds
        num_up_links = len(g[es])
        _up_ports = g[es].keys()
        for i in range(num_down_links):
            msg.match.NXM_OF_IN_PORT = host_ports[es][i]
            msg.actions = list(down_actions)
            msg.actions.pop(i)
            #and add one up link here. assuming num of down links is more than or equal to num up links. ie the perc >= 50
            msg.actions.append(of.ofp_action_output(port = _up_ports[ i % num_up_links ]))
            con.send(msg)
    
    #core switch
    #flood in case of portland will work. in other cases, choose one of the op link to a pod.
    #have to take care of ctlr initiated bcast too, but we are not using it. so chucking it for now
    msg_cs = nx.nx_flow_mod(table_id = 0)
    msg_cs.priority = 5000 #higher priority than normal routing
    msg_cs.match.eth_dst = 'ff:ff:ff:ff:ff:ff'
    for core_switch in cs:
        con = core.openflow.connections[core_switch]
        links = g[core_switch]
        _pod_port = pod_port[core_switch]
        _mask_ports = mask_ports[core_switch]
        if not _mask_ports: #means this core switch has no redundant links at allm then flood. we assume that each core is connct to all pods.
            msg_cs.actions = [of.ofp_action_output(port = of.OFPP_FLOOD)]
            con.send(msg_cs)
            continue
        for src_port, link in links.iteritems():
            msg_cs.match.NXM_OF_IN_PORT = src_port
            msg_cs.actions = []
            src_pod = port_pod[core_switch][src_port]
#take care of pod with only one link. those wont have masks. so add them directly
            '''
            for pod_num in range(num_pods):#sent to all other pod except src pod
                if pod_num == src_pod:
                    continue
            '''
            for key,lports in _mask_ports.iteritems():
                msg_cs.actions = []
                dst_ports = list(lports)
                for port in _pod_port[src_pod]:
                    if port in dst_ports:
                        dst_ports.remove(port)#remove the ports leading back to src pod
                for l in _pod_port:
                    if len(l) == 1:
                        dst_ports.append(l[0])#add pods with only one link to this core switch. they wouldnt have been considered fr hashing prev
                msg_cs.match.eth_src_with_mask = key
                for _port in dst_ports:
                    msg_cs.actions.append(of.ofp_action_output(port = _port))
                con.send(msg_cs)

    #handle packet in after flow tables are installed and everything is set up
    core.openflow.addListenerByName("PacketIn", _handle_PacketIn)
    print 'App initialization done'
def _check_handle_migration(event):
    '''returns 0 for no migration. returns 1 for migration'''
    eth_pkt = event.parsed
    arp_pkt = event.parsed.payload
    org_mac = eth_pkt.src.toStr() #actual mac of the current machine. same as old amac if vm mig. if vip, then diff.
    src_ip = arp_pkt.protosrc.toStr()
    old_pmac = arp_table[src_ip]
    old_amac = pmac_actual[old_pmac] #
    sw, port = pmac_pos(old_pmac)
    #print 'In migration check. IP:{0}, old pos - {1}:{2} new pos - {3}:{4}'.format(src_ip, sw, port, event.dpid, event.port)
    if (sw != event.dpid) or (port != event.port):
        '''
        this host has migrated or virtual ip
        assign new pmac.
        add trans in new switch.
        add entry in old switch to frwrd to some agg switch replacing old pmac with new pmac
        remove prev trans tabbles from old switch.
        update our internal tables
        change the assigned mac string - not assign the old pmac for the timeout period of time
        '''
        if org_mac == old_amac:
            log.info( 'VM migration detected. IP:{0}, old pos - {1}:{2} new pos - {3}:{4}'.format(src_ip, sw, port, event.dpid, event.port) )
        else:
            log.info( 'Virtual ip takeover detected. IP:{0}, old pos - {1}:{2} new pos - {3}:{4}'.format(src_ip, sw, port, event.dpid, event.port) )

        return move_host(src_ip, event.dpid, event.port, org_mac, event)
        new_pmac = _handle_new_host(org_mac, src_ip, event.dpid, event.port)
        barrier = of.ofp_barrier_request()
        event.connection.send(barrier)
        
        old_switch_con = core.openflow.connections[sw]
        msg = nx.nx_flow_mod(table_id = 0)
        msg.priority = 8000
        msg.hard_timeout = arp_cache_timeout
        msg.match.eth_dst = old_pmac
        rewrite_action = of.ofp_action_dl_addr.set_dst(adrs.EthAddr(new_pmac))
        msg.actions.append(rewrite_action)
        #choose one up link by hashing
        up_ports = g[event.dpid].keys()
        num_routes = len(up_ports)
        #msg.actions.append(of.ofp_action_output(port = up_ports[ random.randint(0, num_routes - 1) ] ))#simple hashing. edge switch x sends to agg switch x
        #old_switch_con.send(msg)


        #if more than 2 up ports are there, then hashing is req. if 1 up port, then no hashing. if 2, then the other port other than inp port
        if num_routes == 1: #only one route
            msg.actions = [ rewrite_action, of.ofp_action_output(port = of.OFPP_IN_PORT) ]
            old_switch_con.send(msg)
        elif num_routes == 2:
            msg.match.NXM_OF_IN_PORT = up_ports[0]
            msg.actions = [ rewrite_action, of.ofp_action_output(port = up_ports[1] ) ]
            old_switch_con.send(msg)
            msg.match.NXM_OF_IN_PORT = up_ports[1]
            msg.actions = [ rewrite_action, of.ofp_action_output(port = up_ports[0] ) ]
            old_switch_con.send(msg)
        else: #3 or more ports. here need hahsing. based on src port num. also avoid the inp port. so match based on that also
            num_routes -= 1 #since we avoid each inp port
            num_bits  = int(math.floor(math.log(num_routes, 2)))
            x = 2 ** num_bits   #Assumption:one edge switch doesn't have more than 255 direct connections to agg switches
            mask = '00:00:00:' + eth_addr_format(x - 1, 2) + ':00:00'
            prefix = '00:00:00:'
            suffix = ':00:00'
            for ii in range(num_routes + 1):
                cand_ports = list(up_ports)
                msg.match.NXM_OF_IN_PORT = cand_ports.pop(ii) #remove the inp port from the list of op ports
                for i in range(num_routes):
                    port = i % x
                    msg.match.eth_src_with_mask = ( prefix + eth_addr_format(port, 2) + suffix, mask)
                    msg.actions = [ rewrite_action, of.ofp_action_output(port = cand_ports[i]) ]
                    old_switch_con.send(msg)

        msg = nx.nx_flow_mod(table_id = 0, command=of.OFPFC_DELETE)
        msg.priority = 5000
        msg.match.NXM_OF_IN_PORT = port
        msg.match.eth_src = old_amac
        old_switch_con.send(msg)
        msg = nx.nx_flow_mod(table_id = 1, command=of.OFPFC_DELETE)
        msg.priority = 5000
        msg.match.eth_dst = old_pmac
        old_switch_con.send(msg)
        barrier = of.ofp_barrier_request()
        old_switch_con.send(barrier)
        
        arp_table[src_ip] = new_pmac
        actual_pmac.pop( pmac_actual.pop(old_pmac) )#remove old pmac to actual and vice versa since they are not valid anymore
        actual_pmac[org_mac] = new_pmac
        pmac_actual[new_pmac] = org_mac
        #this nxt 2 lines should be in a fn called after the timeout. we dont want to assing old pmac to anyone until then
        def _remove_old_pmac():
            vmid = int(old_pmac[-5:].replace(':',''),16)
            assigned_pmac[sw][port] = assigned_pmac[sw][port][:vmid] + '0' + assigned_pmac[sw][port][vmid + 1:]
        Timer(arp_cache_timeout, _remove_old_pmac)
        return 1
    return 0
Exemple #47
0
    def _handle_ConnectionUp(self, event):
        # Initialize Nicira
        msg = nx.nx_flow_mod()
        event.connection.send(msg)

        # Signal Table use
        msg = nx.nx_flow_mod_table_id()
        event.connection.send(msg)

        #Table 1 -> TCP Table 2 -> ARP
        for temp_table_id in range(1, 5):
            msg = nx.nx_flow_mod(command=of.OFPFC_DELETE,
                                 table_id=temp_table_id)
            event.connection.send(msg)

        #Table 0 rule: Selection of tables
        #IP Packet Handling / TCP
        msg = nx.nx_flow_mod()
        msg.table_id = 0
        msg.match.eth_type = pkt.ethernet.IP_TYPE
        msg.match.ip_proto = ipv4.TCP_PROTOCOL
        msg.priority = 65000
        msg.actions.append(nx.nx_multipath(dst=nx.NXM_NX_REG2))
        msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=1))
        event.connection.send(msg)

        #ARP Packet Handling
        msg = nx.nx_flow_mod()
        msg.table_id = 0
        msg.priority = 65001
        msg.match.eth_type = pkt.ethernet.ARP_TYPE
        msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=4))
        event.connection.send(msg)
        log.info("Table 0 done")

        #Table 1 Rules
        # TBD: State Machine and Hash value
        # New flow function
        msg = nx.nx_flow_mod()
        msg.table_id = 1
        msg.match.eth_type = pkt.ethernet.IP_TYPE
        msg.match.ip_proto = ipv4.TCP_PROTOCOL
        msg.priority = 65004
        # Signifying New flow
        msg.actions.append(nx.nx_reg_load(dst=nx.NXM_NX_REG0, value=0x0))
        # currently learning based on eth address
        # no hash
        msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=2))
        event.connection.send(msg)

        #Table 2 Rules

        #1. Sync (Should be a Sync)
        msg = nx.nx_flow_mod()
        msg.table_id = 2
        msg.match.eth_type = pkt.ethernet.IP_TYPE
        msg.match.ip_proto = ipv4.TCP_PROTOCOL
        msg.match.NXM_NX_REG0 = 0
        msg.match.tcp_flags = 2
        msg.priority = 65001
        # learn function for table 1
        learn = nx.nx_action_learn(table_id=1, priority=65111)
        learn.spec = [
            nx.flow_mod_spec(src=nx.nx_learn_src_field(nx.NXM_NX_REG2),
                             dst=nx.nx_learn_dst_match(nx.NXM_NX_REG2)),
        ]
        fms = nx.flow_mod_spec.new
        learn.spec.append(
            fms(load=nx.NXM_NX_REG0,
                src=nx.nx_learn_src_immediate.u32(None, 1)))
        learn.spec.append(fms(field=nx.NXM_NX_REG0, reserved=True))
        msg.actions.append(learn)
        msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=3))
        event.connection.send(msg)

        #2. Sync Ack (Should be after sync)
        msg = nx.nx_flow_mod()
        msg.table_id = 2
        msg.match.eth_type = pkt.ethernet.IP_TYPE
        msg.match.ip_proto = ipv4.TCP_PROTOCOL
        msg.match.tcp_flags = 0x12
        msg.priority = 65002
        msg.match.NXM_NX_REG0 = 1
        # learn function for table 1
        learn = nx.nx_action_learn(table_id=1, priority=65111)
        learn.spec = [
            nx.flow_mod_spec(src=nx.nx_learn_src_field(nx.NXM_NX_REG2),
                             dst=nx.nx_learn_dst_match(nx.NXM_NX_REG2)),
        ]
        fms = nx.flow_mod_spec.new
        learn.spec.append(
            fms(load=nx.NXM_NX_REG0,
                src=nx.nx_learn_src_immediate.u32(None, 2)))
        learn.spec.append(fms(field=nx.NXM_NX_REG0, reserved=True))
        msg.actions.append(learn)
        msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=3))
        event.connection.send(msg)

        #3. Ack
        msg = nx.nx_flow_mod()
        msg.table_id = 2
        msg.match.eth_type = pkt.ethernet.IP_TYPE
        msg.match.ip_proto = ipv4.TCP_PROTOCOL
        msg.match.tcp_flags = 0x010
        msg.priority = 65003
        msg.match.NXM_NX_REG0 = 2
        # learn function for table 1
        learn = nx.nx_action_learn(table_id=1, priority=65111)
        learn.spec = [
            nx.flow_mod_spec(src=nx.nx_learn_src_field(nx.NXM_NX_REG2),
                             dst=nx.nx_learn_dst_match(nx.NXM_NX_REG2)),
        ]
        fms = nx.flow_mod_spec.new
        learn.spec.append(
            fms(load=nx.NXM_NX_REG0,
                src=nx.nx_learn_src_immediate.u32(None, 3)))
        learn.spec.append(fms(field=nx.NXM_NX_REG0, reserved=True))
        msg.actions.append(learn)
        msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=3))
        event.connection.send(msg)

        #4. Fin
        msg = nx.nx_flow_mod()
        msg.table_id = 2
        msg.match.eth_type = pkt.ethernet.IP_TYPE
        msg.match.ip_proto = ipv4.TCP_PROTOCOL
        msg.match.tcp_flags = 0x010
        msg.priority = 65003
        msg.match.NXM_NX_REG0 = 3
        # learn function for table 1
        learn = nx.nx_action_learn(table_id=1, priority=65111)
        learn.spec = [
            nx.flow_mod_spec(src=nx.nx_learn_src_field(nx.NXM_NX_REG2),
                             dst=nx.nx_learn_dst_match(nx.NXM_NX_REG2)),
        ]
        fms = nx.flow_mod_spec.new
        learn.spec.append(
            fms(load=nx.NXM_NX_REG0,
                src=nx.nx_learn_src_immediate.u32(None, 4)))
        learn.spec.append(fms(field=nx.NXM_NX_REG0, reserved=True))
        msg.actions.append(learn)
        msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=3))
        event.connection.send(msg)

        #5. Fin-Ack
        msg = nx.nx_flow_mod()
        msg.table_id = 2
        msg.match.eth_type = pkt.ethernet.IP_TYPE
        msg.match.ip_proto = ipv4.TCP_PROTOCOL
        msg.match.tcp_flags = 0x010
        msg.priority = 65003
        msg.match.NXM_NX_REG0 = 4
        # learn function for table 1
        learn = nx.nx_action_learn(table_id=1, priority=65111)
        learn.spec = [
            nx.flow_mod_spec(src=nx.nx_learn_src_field(nx.NXM_NX_REG2),
                             dst=nx.nx_learn_dst_match(nx.NXM_NX_REG2)),
        ]
        fms = nx.flow_mod_spec.new
        learn.spec.append(
            fms(load=nx.NXM_NX_REG0,
                src=nx.nx_learn_src_immediate.u32(None, 5)))
        learn.spec.append(fms(field=nx.NXM_NX_REG0, reserved=True))
        msg.actions.append(learn)
        msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=3))
        event.connection.send(msg)

        #7. Ack
        msg = nx.nx_flow_mod()
        msg.table_id = 2
        msg.match.eth_type = pkt.ethernet.IP_TYPE
        msg.match.ip_proto = ipv4.TCP_PROTOCOL
        msg.match.tcp_flags = 0x010
        msg.priority = 65003
        msg.match.NXM_NX_REG0 = 5
        # learn function for table 1
        learn = nx.nx_action_learn(table_id=1, priority=65111)
        learn.spec = [
            nx.flow_mod_spec(src=nx.nx_learn_src_field(nx.NXM_NX_REG2),
                             dst=nx.nx_learn_dst_match(nx.NXM_NX_REG2)),
        ]
        fms = nx.flow_mod_spec.new
        learn.spec.append(
            fms(load=nx.NXM_NX_REG0,
                src=nx.nx_learn_src_immediate.u32(None, 6)))
        learn.spec.append(fms(field=nx.NXM_NX_REG0, reserved=True))
        msg.actions.append(learn)
        msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=3))
        event.connection.send(msg)

        #8. RST
        msg = nx.nx_flow_mod()
        msg.table_id = 2
        msg.match.eth_type = pkt.ethernet.IP_TYPE
        msg.match.ip_proto = ipv4.TCP_PROTOCOL
        msg.match.tcp_flags = 0x14
        msg.priority = 65003
        msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=3))
        event.connection.send(msg)

        #9. PSH-Ack
        msg = nx.nx_flow_mod()
        msg.table_id = 2
        msg.match.eth_type = pkt.ethernet.IP_TYPE
        msg.match.ip_proto = ipv4.TCP_PROTOCOL
        msg.match.tcp_flags = 0x18
        msg.priority = 65003
        msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=3))
        event.connection.send(msg)

        #9. Ack
        msg = nx.nx_flow_mod()
        msg.table_id = 2
        msg.match.eth_type = pkt.ethernet.IP_TYPE
        msg.match.ip_proto = ipv4.TCP_PROTOCOL
        msg.match.tcp_flags = 0x10
        msg.priority = 65003
        msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=3))
        event.connection.send(msg)

        #send to controller  currently sending to the destination as no old state stored
        msg = nx.nx_flow_mod()
        msg.table_id = 2
        msg.priority = 64999
        msg.actions.append(nx.nx_reg_load(dst=nx.NXM_NX_REG1, value=int(1)))
        msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=3))
        event.connection.send(msg)
        log.info("Table 2 done")

        #Table 3 Rules: Forward the packet to the Destination
        msg = nx.nx_flow_mod()
        msg.table_id = 3
        msg.match.eth_type = pkt.ethernet.IP_TYPE
        msg.match.ip_dst = "10.0.0.1"
        msg.priority = 65001
        msg.actions.append(of.ofp_action_output(port=1))
        event.connection.send(msg)

        msg = nx.nx_flow_mod()
        msg.table_id = 3
        msg.match.eth_type = pkt.ethernet.IP_TYPE
        msg.match.ip_dst = "10.0.0.2"
        msg.priority = 65001
        msg.actions.append(of.ofp_action_output(port=2))
        event.connection.send(msg)

        msg = nx.nx_flow_mod()
        msg.table_id = 3
        msg.match.eth_type = pkt.ethernet.IP_TYPE
        msg.match.ip_dst = "10.0.0.3"
        msg.priority = 65001
        msg.actions.append(of.ofp_action_output(port=3))
        event.connection.send(msg)

        #send to controller
        msg = nx.nx_flow_mod()
        msg.table_id = 3
        msg.match.NXM_NX_REG1 = 1
        msg.priority = 65005
        msg.actions.append(of.ofp_action_output(port=of.OFPP_CONTROLLER))
        event.connection.send(msg)
        log.info("Table 3 done")

        #Table 4 Rules
        msg = nx.nx_flow_mod()
        msg.table_id = 4
        msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD))
        event.connection.send(msg)
        log.info("Table 4 done")
    def constructRule(self,nv,packet,ingressPort,connection,event):
        self.networkview = nv
        hosts = self.networkview.access
        routes = self.networkview.routes
        #self.hostHops = {}
        currentOutPort=0
        currentOutSrcIP=None
        currentOutDstIP=None
        currentOutSrcMac=None
        currentOutDstMac=None
        flowRule=None

        #check if request comes from target node or not
        if str(packet.src)==str(self.networkview.target.eth_addr) and (str(nv.getNodeByEth(packet.src).visible)=="v" or nv.getNodeByEth(packet.src).isHoneypot==True):
            if packet.type==ethernet.ARP_TYPE:
                pkt = packet.find('arp')
                if pkt!=None:
                    if pkt.opcode==arp.REQUEST:
                        print("ARP packet src " + str(pkt.protosrc) + " " + str(pkt.protodst) + " " + str(nv.canContact(pkt.protosrc,pkt.protodst)) + " " + str(ingressPort))
                        #check if request is comming from target
                        if str(pkt.hwsrc)==str(self.networkview.target.eth_addr):
                            if nv.canContact(pkt.protosrc,pkt.protodst)==True:
                                flowRule = nx.nx_flow_mod()
                                flowRule.match.in_port = ingressPort
                                flowRule.match.NXM_OF_ETH_TYPE = ethernet.ARP_TYPE
                                flowRule.match.NXM_OF_ARP_OP = arp.REQUEST
                                flowRule.match.eth_src = EthAddr(pkt.hwsrc)
                                flowRule.idle_timeout = 30
                                flowRule.priority = 2
                                flowRule.actions.append(of.ofp_action_output(port = int(nv.server.switchPort)))
                                connection.send(flowRule)
                                self.logging.logRule(flowRule,"ARP")
                                currentOutPort = int(nv.server.switchPort)

                                flowRule = nx.nx_flow_mod()
                                flowRule.match.in_port = int(nv.server.switchPort)
                                flowRule.match.NXM_OF_ETH_TYPE = ethernet.ARP_TYPE
                                flowRule.match.NXM_OF_ARP_OP = arp.REPLY
                                flowRule.match.eth_dst = EthAddr(pkt.hwsrc)
                                flowRule.idle_timeout = 30
                                flowRule.priority = 2
                                flowRule.actions.append(of.ofp_action_output(port = ingressPort))
                                connection.send(flowRule)
                                self.logging.logRule(flowRule,"ARP")
                        else:
                            #if request is not from target, learn route
                            flowRule = nx.nx_flow_mod()
                            flowRule.match.in_port = ingressPort
                            flowRule.match.NXM_OF_ETH_TYPE = ethernet.ARP_TYPE
                            flowRule.match.NXM_OF_ARP_OP = arp.REQUEST
                            flowRule.match.eth_src = EthAddr(pkt.hwsrc)
                            flowRule.idle_timeout = 30
                            flowRule.priority = 2
                            flowRule.actions.append(of.ofp_action_output(port = int(nv.server.switchPort)))
                            connection.send(flowRule)
                            self.logging.logRule(flowRule,"ARP")
                            currentOutPort = int(nv.server.switchPort)

                            flowRule = nx.nx_flow_mod()
                            flowRule.match.in_port = int(nv.server.switchPort)
                            flowRule.match.NXM_OF_ETH_TYPE = ethernet.ARP_TYPE
                            flowRule.match.NXM_OF_ARP_OP = arp.REPLY
                            flowRule.match.eth_dst = EthAddr(pkt.hwsrc)
                            flowRule.idle_timeout = 30
                            flowRule.priority = 2
                            flowRule.actions.append(of.ofp_action_output(port = ingressPort))
                            connection.send(flowRule)
                            self.logging.logRule(flowRule,"ARP")

            elif packet.type==ethernet.IP_TYPE:
                #print("IP packet")
                #create rules for route to the specific host
                route_eth_dst=None
                route_ip_dst=None
                route_ip_src=None
                #print("Route src " + str(packet.payload.srcip) + " " + str(packet.payload.dstip) + " " + str(nv.canContact(packet.payload.srcip,packet.payload.dstip)))
                if nv.canContact(packet.payload.srcip,packet.payload.dstip)==True:
                    hopCt=0
                    for r in routes:
                        for i in range(1,(len(r.hops)-1)):
                            hop = r.hops[i]
                            #print("hopCt " + str(hopCt) + " isRouter " + str(hop.isRouter))
                            #print("Route src " + str(packet.payload.srcip) + " " + str(packet.payload.dstip) + " " + str(nv.canContact(packet.payload.srcip,packet.payload.dstip)))
                            if hop.isRouter==True and packet.payload.srcip==r.startNode.decepted_ip_addr and packet.payload.dstip==r.endNode.decepted_ip_addr:
                                if packet.payload.ttl<=(len(r.hops)-2):
                                    #establish route if packet ttl matches, forward to deception server
                                    hopCt+=1
                                    flowRule = nx.nx_flow_mod()
                                    flowRule.match.NXM_OF_ETH_TYPE = ethernet.IP_TYPE
                                    flowRule.match.NXM_NX_IP_TTL = hopCt
                                    flowRule.match.eth_src = EthAddr(r.startNode.decepted_eth_addr)
                                    #flowRule.match.eth_dst = EthAddr(r.endNode.decepted_eth_addr)
                                    flowRule.match.eth_dst = EthAddr(str(self.networkview.gateway.eth_addr))
                                    flowRule.match.ip_src = IPAddr(r.startNode.decepted_ip_addr)
                                    flowRule.match.ip_dst = IPAddr(r.endNode.decepted_ip_addr)
                                    flowRule.idle_timeout = 30
                                    flowRule.priority = 2
                                    flowRule.actions.append(of.ofp_action_output(port = int(nv.server.switchPort)))
                                    connection.send(flowRule)
                                    self.logging.logRule(flowRule,"")
                                    #port for current packet on multi hop route
                                    currentOutPort = int(r.hops[packet.payload.ttl].switchPort)
                                    print("1 - Multi hop port " + str(currentOutPort))

                                    #establish route for answer packet from deception server back to target node
                                    flowRule = nx.nx_flow_mod()
                                    flowRule.match.NXM_OF_ETH_TYPE = ethernet.IP_TYPE
                                    flowRule.match.eth_src = EthAddr(r.hops[hopCt].decepted_eth_addr)
                                    #flowRule.match.eth_dst = EthAddr(r.endNode.decepted_eth_addr)
                                    flowRule.match.eth_dst = EthAddr(r.startNode.decepted_eth_addr)
                                    flowRule.match.ip_src = IPAddr(r.hops[hopCt].decepted_ip_addr)
                                    flowRule.match.ip_dst = IPAddr(r.startNode.decepted_ip_addr)
                                    for d in range(0,hopCt):
                                        flowRule.actions.append(nx.nx_action_dec_ttl())
                                    flowRule.idle_timeout = 30
                                    flowRule.priority = 2
                                    flowRule.actions.append(of.ofp_action_output(port = int(ingressPort)))
                                    connection.send(flowRule)
                                    self.logging.logRule(flowRule,"")
                                else:
                                    hopCt=(len(r.hops)-2)

                    route_eth_dst=packet.dst
                    route_ip_dst=packet.payload.dstip
                    route_ip_src=packet.payload.srcip

                    if hopCt>0:
                        maxHop = hopCt
                        #forward packets with TTL to destination
                        #print("IP: " + str(route_ip_dst) + " V: " + str(nv.getNodeByDecIP(route_ip_dst).visible))
                        if nv.getNodeByDecIP(route_ip_dst).visible=="v" or nv.getNodeByDecIP(route_ip_dst).isHoneypot==True:
                            for ttl in range((maxHop+1),65):
                                flowRule = nx.nx_flow_mod()
                                flowRule.match.of_eth_type = ethernet.IP_TYPE
                                flowRule.match.eth_src = EthAddr(str(self.networkview.target.eth_addr))
                                flowRule.match.eth_dst = EthAddr(str(self.networkview.gateway.eth_addr))
                                flowRule.match.ip_src = IPAddr(str(self.networkview.target.decepted_ip_addr))
                                flowRule.match.ip_dst = IPAddr(str(route_ip_dst))
                                flowRule.match.NXM_NX_IP_TTL = ttl
                                flowRule.idle_timeout = 30
                                flowRule.priority = 1
                                flowRule.actions.append(of.ofp_action_nw_addr.set_src(IPAddr(self.networkview.target.ip_addr)))
                                flowRule.actions.append(of.ofp_action_dl_addr.set_src(EthAddr(self.networkview.target.eth_addr)))
                                flowRule.actions.append(of.ofp_action_nw_addr.set_dst(IPAddr(nv.getNodeByDecIP(route_ip_dst).ip_addr)))
                                flowRule.actions.append(of.ofp_action_dl_addr.set_dst(EthAddr(nv.getNodeByDecIP(route_ip_dst).eth_addr)))
                                flowRule.actions.append(of.ofp_action_output(port = int(nv.getNodeByDecIP(route_ip_dst).switchPort)))
                                connection.send(flowRule)
                                self.logging.logRule(flowRule,"")
                                if packet.payload.ttl>hopCt:
                                    currentOutPort = int(nv.getNodeByDecIP(route_ip_dst).switchPort)
                                    currentOutSrcIP=IPAddr(self.networkview.target.ip_addr)
                                    currentOutDstIP=IPAddr(nv.getNodeByDecIP(route_ip_dst).ip_addr)
                                    currentOutSrcMac=EthAddr(self.networkview.target.eth_addr)
                                    currentOutDstMac=EthAddr(nv.getNodeByDecIP(route_ip_dst).eth_addr)

                            #send back to target and decrease ttl
                            flowRule = nx.nx_flow_mod()
                            flowRule.match.of_eth_type = ethernet.IP_TYPE
                            flowRule.match.eth_src = EthAddr(str(nv.getNodeByDecIP(route_ip_dst).eth_addr))
                            flowRule.match.ip_src = IPAddr(nv.getNodeByDecIP(route_ip_dst).ip_addr)
                            flowRule.match.ip_dst = IPAddr(str(nv.getNodeByDecIP(route_ip_src).ip_addr))
                            flowRule.match.eth_dst = EthAddr(str(nv.getNodeByDecIP(route_ip_src).eth_addr))
                            flowRule.idle_timeout = 30
                            flowRule.priority = 1
                            for hop in range(0,hopCt):
                                flowRule.actions.append(nx.nx_action_dec_ttl())
                            #print("Decrease ttl by " + str(hopCount))
                            flowRule.actions.append(of.ofp_action_nw_addr.set_src(IPAddr(str(nv.getNodeByDecIP(route_ip_dst).decepted_ip_addr))))
                            flowRule.actions.append(of.ofp_action_dl_addr.set_src(EthAddr(self.networkview.gateway.eth_addr)))
                            flowRule.actions.append(of.ofp_action_nw_addr.set_dst(IPAddr(self.networkview.target.decepted_ip_addr)))
                            flowRule.actions.append(of.ofp_action_dl_addr.set_dst(EthAddr(self.networkview.target.eth_addr)))
                            flowRule.actions.append(of.ofp_action_output(port = int(self.networkview.target.switchPort)))
                            connection.send(flowRule)
                            self.logging.logRule(flowRule,"")

                    else:
                        if nv.getNodeByDecIP(route_ip_dst).visible=="v" or nv.getNodeByDecIP(route_ip_dst).isHoneypot==True:
                            flowRule = nx.nx_flow_mod()
                            flowRule.match.of_eth_type = ethernet.IP_TYPE
                            flowRule.match.eth_src = EthAddr(str(self.networkview.target.eth_addr))
                            flowRule.match.eth_dst = EthAddr(str(route_eth_dst))
                            flowRule.match.ip_src = IPAddr(str(self.networkview.target.decepted_ip_addr))
                            flowRule.match.ip_dst = IPAddr(str(route_ip_dst))
                            flowRule.idle_timeout = 30
                            flowRule.priority = 1
                            flowRule.actions.append(of.ofp_action_nw_addr.set_src(IPAddr(self.networkview.target.ip_addr)))
                            flowRule.actions.append(of.ofp_action_dl_addr.set_src(EthAddr(self.networkview.target.eth_addr)))
                            flowRule.actions.append(of.ofp_action_nw_addr.set_dst(IPAddr(nv.getNodeByDecIP(route_ip_dst).ip_addr)))
                            flowRule.actions.append(of.ofp_action_dl_addr.set_dst(EthAddr(nv.getNodeByDecIP(route_ip_dst).eth_addr)))
                            flowRule.actions.append(of.ofp_action_output(port = int(nv.getNodeByDecIP(route_ip_dst).switchPort)))
                            connection.send(flowRule)
                            self.logging.logRule(flowRule,"")
                            currentOutPort = int(nv.getNodeByDecIP(route_ip_dst).switchPort)
                            currentOutSrcIP=IPAddr(self.networkview.target.ip_addr)
                            currentOutDstIP=IPAddr(nv.getNodeByDecIP(route_ip_dst).ip_addr)
                            currentOutSrcMac=EthAddr(self.networkview.target.eth_addr)
                            currentOutDstMac=EthAddr(nv.getNodeByDecIP(route_ip_dst).eth_addr)

                            #send back to target and decrease ttl
                            flowRule = nx.nx_flow_mod()
                            flowRule.match.of_eth_type = ethernet.IP_TYPE
                            flowRule.match.eth_src = EthAddr(str(nv.getNodeByDecIP(route_ip_dst).eth_addr))
                            flowRule.match.ip_src = IPAddr(nv.getNodeByDecIP(route_ip_dst).ip_addr)
                            flowRule.match.ip_dst = IPAddr(self.networkview.target.ip_addr)
                            flowRule.match.eth_dst = EthAddr(self.networkview.target.eth_addr)
                            flowRule.idle_timeout = 30
                            flowRule.priority = 1
                            flowRule.actions.append(of.ofp_action_nw_addr.set_src(IPAddr(str(nv.getNodeByDecIP(route_ip_dst).decepted_ip_addr))))
                            flowRule.actions.append(of.ofp_action_dl_addr.set_src(str(nv.getNodeByDecIP(route_ip_dst).decepted_eth_addr)))
                            flowRule.actions.append(of.ofp_action_nw_addr.set_dst(IPAddr(self.networkview.target.decepted_ip_addr)))
                            flowRule.actions.append(of.ofp_action_dl_addr.set_dst(EthAddr(self.networkview.target.eth_addr)))
                            flowRule.actions.append(of.ofp_action_output(port = int(self.networkview.target.switchPort)))
                            connection.send(flowRule)
                            self.logging.logRule(flowRule,"")


                    #handle nested packets in icmp error by forwarding it to the deception server
                    flowRule = nx.nx_flow_mod()
                    flowRule.match.of_eth_type = ethernet.IP_TYPE
                    flowRule.match.of_ip_proto = ipv4.ICMP_PROTOCOL
                    flowRule.match.of_icmp_code = 3
                    flowRule.match.of_icmp_type = 3
                    flowRule.match.in_port = int(nv.getNodeByDecIP(route_ip_dst).switchPort)
                    flowRule.match.eth_src = EthAddr(str(nv.getNodeByDecIP(route_ip_dst).eth_addr))
                    flowRule.match.ip_src = IPAddr(nv.getNodeByDecIP(route_ip_dst).ip_addr)
                    flowRule.match.ip_dst = IPAddr(str(self.networkview.target.ip_addr))
                    flowRule.match.eth_dst = EthAddr(str(self.networkview.target.eth_addr))
                    flowRule.idle_timeout = 30
                    flowRule.priority = 1000
                    for hop in range(0,hopCt):
                        flowRule.actions.append(nx.nx_action_dec_ttl())
                    flowRule.actions.append(of.ofp_action_nw_addr.set_src(IPAddr(str(nv.getNodeByDecIP(route_ip_dst).decepted_ip_addr))))
                    if hopCt>0:
                        flowRule.actions.append(of.ofp_action_dl_addr.set_src(EthAddr(self.networkview.gateway.eth_addr)))
                    else:
                        flowRule.actions.append(of.ofp_action_dl_addr.set_src(EthAddr(str(nv.getNodeByDecIP(route_ip_dst).decepted_eth_addr))))
                    flowRule.actions.append(of.ofp_action_nw_addr.set_dst(IPAddr(self.networkview.target.decepted_ip_addr)))
                    flowRule.actions.append(of.ofp_action_dl_addr.set_dst(EthAddr(self.networkview.target.eth_addr)))
                    flowRule.actions.append(of.ofp_action_output(port = int(nv.server.switchPort)))
                    if packet.payload.protocol == ipv4.ICMP_PROTOCOL:
                        if packet.payload.payload.type==3 and packet.payload.payload.code==3:
                            currentOutPort = int(nv.server.switchPort)
                    connection.send(flowRule)
                    self.logging.logRule(flowRule,"")

                    #send response from deception server back to target host
                    flowRule = nx.nx_flow_mod()
                    flowRule.match.of_eth_type = ethernet.IP_TYPE
                    flowRule.match.of_ip_proto = ipv4.ICMP_PROTOCOL
                    flowRule.match.of_icmp_code = 3
                    flowRule.match.of_icmp_type = 3
                    flowRule.match.in_port = int(nv.server.switchPort)
                    if hopCt>0:
                        flowRule.match.eth_src = EthAddr(str(self.networkview.gateway.eth_addr))
                    else:
                        flowRule.match.eth_src = EthAddr(str(nv.getNodeByDecIP(route_ip_dst).decepted_eth_addr))
                    flowRule.match.ip_src = IPAddr(nv.getNodeByDecIP(route_ip_dst).decepted_ip_addr)
                    flowRule.match.ip_dst = IPAddr(str(self.networkview.target.decepted_ip_addr))
                    flowRule.match.eth_dst = EthAddr(str(self.networkview.target.eth_addr))
                    flowRule.idle_timeout = 30
                    flowRule.priority = 1000
                    flowRule.actions.append(of.ofp_action_output(port = int(self.networkview.target.switchPort)))
                    connection.send(flowRule)
                    self.logging.logRule(flowRule,"")


                #if packet.payload.protocol == ipv4.ICMP_PROTOCOL:
                #    print("ICMP packet")
                #if packet.payload.protocol == ipv4.TCP_PROTOCOL:
                #    print("TCP packet")

                if packet.payload.protocol == ipv4.UDP_PROTOCOL:
                    print("Received UDP packet with TTL " + str(packet.payload.ttl))
                    if packet.payload.payload.srcport==68 and packet.payload.payload.dstport==67:
                        #Handle DHCP request
                        #print("Create rule " + str("DHCP from port 68 ") + "to port " + str(1))
                        flowRule = nx.nx_flow_mod()
                        flowRule.match.of_eth_type = ethernet.IP_TYPE
                        flowRule.match.of_ip_proto = ipv4.UDP_PROTOCOL
                        flowRule.match.eth_src = packet.src
                        #flowRule.match.eth_dst = nv.server.eth_addr
                        flowRule.match.udp_src = int(68)
                        flowRule.match.udp_dst = int(67)
                        flowRule.idle_timeout = 30
                        flowRule.actions.append(of.ofp_action_output(port = int(nv.server.switchPort)))
                        connection.send(flowRule)
                        self.logging.logRule(flowRule,"DHCP")
                        currentOutPort = int(nv.server.switchPort)

                        #print("Create rule " + str("DHCP from port 67 ") + " to port " + str(h.switchPort))
                        flowRule = nx.nx_flow_mod()
                        flowRule.match.of_eth_type = ethernet.IP_TYPE
                        flowRule.match.of_ip_proto = ipv4.UDP_PROTOCOL
                        flowRule.match.eth_src = nv.server.eth_addr
                        flowRule.match.eth_dst = packet.src
                        flowRule.match.udp_src = int(67)
                        flowRule.match.udp_dst = int(68)
                        flowRule.idle_timeout = 30
                        flowRule.actions.append(of.ofp_action_output(port = int(ingressPort)))
                        connection.send(flowRule)
                        self.logging.logRule(flowRule,"DHCP")

            #send out current packet
            if currentOutPort!=0:
                print("Sending current packet out on port " + str(currentOutPort))
                outPkt = of.ofp_packet_out(data = event.ofp)
                if currentOutSrcIP!=None:
                    outPkt.actions.append(of.ofp_action_nw_addr.set_src(currentOutSrcIP))
                    outPkt.actions.append(of.ofp_action_nw_addr.set_dst(currentOutDstIP))
                    outPkt.actions.append(of.ofp_action_dl_addr.set_src(currentOutSrcMac))
                    outPkt.actions.append(of.ofp_action_dl_addr.set_dst(currentOutDstMac))
                outPkt.actions.append(of.ofp_action_output(port = int(currentOutPort)))
                connection.send(outPkt)

        else:
            currentOutPort==0
            currentOutSrcIP=None
            currentOutDstIP=None
            currentOutSrcMac=None
            currentOutDstMac=None
            #print("Handle traffic of other nodes beside target nodes " + str(packet.src) + " " + str(packet.dst))
            if packet.type==ethernet.ARP_TYPE:
                pkt = packet.find('arp')
                if pkt!=None:
                    if pkt.opcode==arp.REQUEST:
                        flowRule = nx.nx_flow_mod()
                        flowRule.match.in_port = ingressPort
                        flowRule.match.NXM_OF_ETH_TYPE = ethernet.ARP_TYPE
                        flowRule.match.NXM_OF_ARP_OP = arp.REQUEST
                        flowRule.match.eth_src = EthAddr(pkt.hwsrc)
                        flowRule.idle_timeout = 30
                        flowRule.priority = 2
                        flowRule.actions.append(of.ofp_action_output(port = int(nv.server.switchPort)))
                        connection.send(flowRule)
                        self.logging.logRule(flowRule,"ARP")

                        flowRule = nx.nx_flow_mod()
                        flowRule.match.in_port = int(nv.server.switchPort)
                        flowRule.match.NXM_OF_ETH_TYPE = ethernet.ARP_TYPE
                        flowRule.match.NXM_OF_ARP_OP = arp.REPLY
                        flowRule.match.eth_dst = EthAddr(pkt.hwsrc)
                        flowRule.idle_timeout = 30
                        flowRule.priority = 2
                        flowRule.actions.append(of.ofp_action_output(port = ingressPort))
                        connection.send(flowRule)
                        self.logging.logRule(flowRule,"ARP")

            else:
                src_node = nv.getNodeByEth(packet.src)
                dst_node = nv.getNodeByEth(packet.dst)
                #print("Src node " + str(src_node) + " dst node " + str(dst_node) + " src " + str(packet.src) + " dst " + str(packet.dst))
                if src_node!=None and dst_node!=None:
                    #print("Route traffic from " + str(src_node.ip_addr) + " to " + str(dst_node.ip_addr))
                    if str(packet.dst)==str(self.networkview.target.eth_addr):
                        flowRule = nx.nx_flow_mod()
                        flowRule.match.of_eth_type = ethernet.IP_TYPE
                        flowRule.match.eth_dst = EthAddr(str(self.networkview.target.eth_addr))
                        flowRule.match.eth_src = EthAddr(str(src_node.eth_addr))
                        flowRule.match.ip_dst = IPAddr(str(self.networkview.target.ip_addr))
                        flowRule.match.ip_src = IPAddr(str(src_node.ip_addr))
                        flowRule.idle_timeout = 30
                        flowRule.priority = 1
                        flowRule.actions.append(of.ofp_action_nw_addr.set_src(IPAddr(self.networkview.target.ip_addr)))
                        #flowRule.actions.append(of.ofp_action_dl_addr.set_src(EthAddr(self.networkview.target.eth_addr)))
                        flowRule.actions.append(of.ofp_action_nw_addr.set_dst(IPAddr(self.networkview.target.decepted_ip_addr)))
                        #flowRule.actions.append(of.ofp_action_dl_addr.set_dst(EthAddr(self.networkview.target.decepted_eth_addr)))
                        flowRule.actions.append(of.ofp_action_output(port = int(self.networkview.target.switchPort)))
                        connection.send(flowRule)
                        self.logging.logRule(flowRule,"")
                        currentOutPort = int(self.networkview.target.switchPort)
                        currentOutSrcIP=IPAddr(self.networkview.target.ip_addr)
                        currentOutDstIP=IPAddr(self.networkview.target.decepted_ip_addr)

                        flowRule = nx.nx_flow_mod()
                        flowRule.match.of_eth_type = ethernet.IP_TYPE
                        flowRule.match.eth_src = EthAddr(str(self.networkview.target.decepted_eth_addr))
                        flowRule.match.eth_dst = EthAddr(str(self.networkview.gateway.decepted_eth_addr))
                        flowRule.match.ip_src = IPAddr(str(self.networkview.target.decepted_ip_addr))
                        flowRule.match.ip_dst = IPAddr(str(self.networkview.target.ip_addr))
                        flowRule.idle_timeout = 30
                        flowRule.priority = 1
                        flowRule.actions.append(of.ofp_action_nw_addr.set_src(IPAddr(str(self.networkview.target.ip_addr))))
                        flowRule.actions.append(of.ofp_action_dl_addr.set_src(EthAddr(str(self.networkview.target.eth_addr))))
                        flowRule.actions.append(of.ofp_action_nw_addr.set_dst(IPAddr(src_node.ip_addr)))
                        flowRule.actions.append(of.ofp_action_dl_addr.set_dst(EthAddr(src_node.eth_addr)))
                        flowRule.actions.append(of.ofp_action_output(port = int(src_node.switchPort)))
                        connection.send(flowRule)
                        self.logging.logRule(flowRule,"")
                    else:
                        flowRule = nx.nx_flow_mod()
                        flowRule.match.of_eth_type = ethernet.IP_TYPE
                        flowRule.match.eth_dst = EthAddr(str(dst_node.eth_addr))
                        flowRule.match.eth_src = EthAddr(str(src_node.eth_addr))
                        flowRule.match.ip_dst = IPAddr(str(dst_node.ip_addr))
                        flowRule.match.ip_src = IPAddr(str(src_node.ip_addr))
                        flowRule.idle_timeout = 30
                        flowRule.priority = 1
                        flowRule.actions.append(of.ofp_action_output(port = int(dst_node.switchPort)))
                        connection.send(flowRule)
                        self.logging.logRule(flowRule,"")
                        currentOutPort = int(dst_node.switchPort)

                        flowRule = nx.nx_flow_mod()
                        flowRule.match.of_eth_type = ethernet.IP_TYPE
                        flowRule.match.eth_dst = EthAddr(str(src_node.eth_addr))
                        flowRule.match.eth_src = EthAddr(str(dst_node.eth_addr))
                        flowRule.match.ip_dst = IPAddr(str(src_node.ip_addr))
                        flowRule.match.ip_src = IPAddr(str(dst_node.ip_addr))
                        flowRule.idle_timeout = 30
                        flowRule.priority = 1
                        flowRule.actions.append(of.ofp_action_output(port = int(src_node.switchPort)))
                        connection.send(flowRule)
                        self.logging.logRule(flowRule,"")

            #send out current packet
            if currentOutPort!=0:
                print("Sending current packet out on port " + str(currentOutPort))
                outPkt = of.ofp_packet_out(data = event.ofp)
                if currentOutSrcIP!=None:
                    outPkt.actions.append(of.ofp_action_nw_addr.set_src(currentOutSrcIP))
                    outPkt.actions.append(of.ofp_action_nw_addr.set_dst(currentOutDstIP))
                outPkt.actions.append(of.ofp_action_output(port = int(currentOutPort)))
                connection.send(outPkt)
Exemple #49
0
    def generateRules(self, nv):
        self.networkview = nv
        hosts = self.networkview.access
        routes = self.networkview.routes
        self.hostHops = {}

        rules = []

        flowRule = nx.nx_flow_mod()
        flowRule.match.eth_dst = EthAddr("ff:ff:ff:ff:ff:ff")
        flowRule.hard_timeout = FLOW_TIMEOUT
        flowRule.actions.append(of.ofp_action_output(port=1))
        rules.append(flowRule)
        '''
        flowRule = nx.nx_flow_mod()
        flowRule.match.eth_src = EthAddr("00:00:00:00:00:01")
        flowRule.match.eth_dst = EthAddr(self.networkview.target.eth_addr)
        flowRule.hard_timeout = FLOW_TIMEOUT
        flowRule.priority = 2
        flowRule.actions.append(of.ofp_action_output(port = 2))
        rules.append(flowRule)

        flowRule = nx.nx_flow_mod()
        flowRule.match.eth_src = EthAddr(self.networkview.target.eth_addr)
        flowRule.match.eth_dst = EthAddr("00:00:00:00:00:01")
        flowRule.hard_timeout = FLOW_TIMEOUT
        flowRule.priority = 2
        flowRule.actions.append(of.ofp_action_output(port = 1))
        rules.append(flowRule)

        #TMP for DNS test
        flowRule = nx.nx_flow_mod()
        flowRule.match.NXM_OF_ETH_TYPE = ethernet.IP_TYPE
        flowRule.match.ip_dst = IPAddr("10.168.0.10")
        flowRule.match.ip_src = IPAddr("10.168.0.11")
        flowRule.hard_timeout = FLOW_TIMEOUT
        flowRule.actions.append(of.ofp_action_output(port = 2))
        #rules.append(flowRule)

        flowRule = nx.nx_flow_mod()
        flowRule.match.NXM_OF_ETH_TYPE = ethernet.IP_TYPE
        flowRule.match.of_ip_proto = ipv4.UDP_PROTOCOL
        flowRule.match.udp_src = int(53)
        flowRule.hard_timeout = FLOW_TIMEOUT
        flowRule.priority = 999
        flowRule.actions.append(of.ofp_action_output(port = of.OFPP_CONTROLLER))
        rules.append(flowRule)
        '''

        #create rules for routes
        for r in routes:
            hopCt = 0
            for hop in r.hops:
                #print("hopCt " + str(hopCt) + " isRouter " + str(hop.isRouter))
                if hopCt != 0 and hop.isRouter == True:
                    #print("Create rule " + str(r.startNode.decepted_ip_addr) + " --> " + str(r.endNode.decepted_ip_addr) + " with ttl " + str(hopCt) + " - " + str(1))
                    flowRule = nx.nx_flow_mod()
                    flowRule.match.NXM_OF_ETH_TYPE = ethernet.IP_TYPE
                    flowRule.match.NXM_NX_IP_TTL = hopCt
                    flowRule.match.eth_src = EthAddr(
                        r.startNode.decepted_eth_addr)
                    flowRule.match.eth_dst = EthAddr(
                        r.endNode.decepted_eth_addr)
                    flowRule.match.ip_src = IPAddr(
                        r.startNode.decepted_ip_addr)
                    flowRule.match.ip_dst = IPAddr(r.endNode.decepted_ip_addr)
                    flowRule.hard_timeout = FLOW_TIMEOUT
                    flowRule.priority = 2
                    flowRule.actions.append(of.ofp_action_output(port=1))
                    rules.append(flowRule)
                hopCt += 1
            hopCt -= 2
            if hopCt > 0:
                self.hostHops[r.endNode.decepted_eth_addr] = hopCt

        #for key in self.hostHops.keys():
        #    print("Key " + str(key))

        #create rules for packet flow
        for h in hosts:

            #generate rule from deception server to host for ARP and DHCP
            #print("Create rule " + str("ARP from port 1") + " --> " + str(h.eth_addr) + " to port " + str(h.switchPort))
            flowRule = nx.nx_flow_mod()
            flowRule.match.of_eth_type = ethernet.ARP_TYPE
            flowRule.match.in_port = 1
            flowRule.match.eth_dst = EthAddr(h.eth_addr)
            flowRule.hard_timeout = FLOW_TIMEOUT
            flowRule.actions.append(
                of.ofp_action_output(port=int(h.switchPort)))
            rules.append(flowRule)

            #print("Create rule " + str("ARP from ") + str(h.eth_addr) + " to port " + str(1))
            flowRule = nx.nx_flow_mod()
            flowRule.match.of_eth_type = ethernet.ARP_TYPE
            flowRule.match.in_port = 1
            flowRule.match.eth_src = EthAddr(h.eth_addr)
            flowRule.match.in_port = int(h.switchPort)
            flowRule.hard_timeout = FLOW_TIMEOUT
            flowRule.actions.append(of.ofp_action_output(port=1))
            rules.append(flowRule)

            #print("Create rule " + str("DHCP from port 68 ") + "to port " + str(1))
            flowRule = nx.nx_flow_mod()
            flowRule.match.of_eth_type = ethernet.IP_TYPE
            flowRule.match.of_ip_proto = ipv4.UDP_PROTOCOL
            flowRule.match.eth_src = EthAddr(str(h.eth_addr))
            flowRule.match.udp_src = int(68)
            flowRule.hard_timeout = FLOW_TIMEOUT
            flowRule.actions.append(of.ofp_action_output(port=int(1)))
            rules.append(flowRule)

            #print("Create rule " + str("DHCP from port 67 ") + " to port " + str(h.switchPort))
            flowRule = nx.nx_flow_mod()
            flowRule.match.of_eth_type = ethernet.IP_TYPE
            flowRule.match.of_ip_proto = ipv4.UDP_PROTOCOL
            flowRule.match.eth_dst = EthAddr(str(h.eth_addr))
            flowRule.match.udp_src = int(67)
            flowRule.hard_timeout = FLOW_TIMEOUT
            flowRule.actions.append(
                of.ofp_action_output(port=int(h.switchPort)))
            rules.append(flowRule)

            #normal node
            if h.isHoneypot == False and h.isRouter == False and h.eth_addr != self.networkview.target.eth_addr:
                #print("Create rule " + str(h.decepted_ip_addr) + " --> " + str(h.ip_addr))

                if self.hostHops.has_key(h.decepted_eth_addr):
                    #print("a - Create rule " + str(self.networkview.target.eth_addr) + " --> " + str(h.decepted_ip_addr) + "/" + str(self.networkview.gateway.eth_addr) + " - " + str(h.switchPort))
                    maxHop = self.hostHops.get(h.decepted_eth_addr)
                    for ttl in range((maxHop + 1), 65):
                        flowRule = nx.nx_flow_mod()
                        flowRule.match.of_eth_type = ethernet.IP_TYPE
                        flowRule.match.eth_src = EthAddr(
                            str(self.networkview.target.eth_addr))
                        flowRule.match.eth_dst = EthAddr(
                            str(self.networkview.gateway.eth_addr))
                        flowRule.match.ip_dst = IPAddr(str(h.decepted_ip_addr))
                        flowRule.match.NXM_NX_IP_TTL = ttl
                        flowRule.hard_timeout = FLOW_TIMEOUT
                        flowRule.priority = 1
                        flowRule.actions.append(
                            of.ofp_action_nw_addr.set_src(
                                IPAddr(h.decepted_ip_addr)))
                        flowRule.actions.append(
                            of.ofp_action_dl_addr.set_src(
                                EthAddr(self.networkview.gateway.eth_addr)))
                        flowRule.actions.append(
                            of.ofp_action_nw_addr.set_dst(IPAddr(h.ip_addr)))
                        flowRule.actions.append(
                            of.ofp_action_dl_addr.set_dst(EthAddr(h.eth_addr)))
                        #print("1 - " + str(self.networkview.gateway.eth_addr) + " --> " + str(h.eth_addr))
                        flowRule.actions.append(
                            of.ofp_action_output(port=int(h.switchPort)))
                        rules.append(flowRule)

                    #send back to user and decrease ttl
                    #print("b - Create rule " + str(self.networkview.gateway.eth_addr) + " --> " + str(h.decepted_ip_addr) + "/" + str(self.networkview.target.eth_addr) + " - " + str(self.networkview.target.switchPort))
                    hopCount = self.hostHops[h.decepted_eth_addr]
                    flowRule = nx.nx_flow_mod()
                    flowRule.match.of_eth_type = ethernet.IP_TYPE
                    flowRule.match.eth_src = EthAddr(str(h.eth_addr))
                    flowRule.match.ip_dst = IPAddr(str(h.decepted_ip_addr))
                    flowRule.match.eth_dst = EthAddr(
                        str(self.networkview.gateway.eth_addr))
                    flowRule.hard_timeout = FLOW_TIMEOUT
                    flowRule.priority = 1
                    for hop in range(0, hopCount):
                        flowRule.actions.append(nx.nx_action_dec_ttl())
                    #print("Decrease ttl by " + str(hopCount))
                    flowRule.actions.append(
                        of.ofp_action_nw_addr.set_src(
                            IPAddr(h.decepted_ip_addr)))
                    flowRule.actions.append(
                        of.ofp_action_dl_addr.set_src(
                            EthAddr(self.networkview.gateway.eth_addr)))
                    flowRule.actions.append(
                        of.ofp_action_nw_addr.set_dst(
                            IPAddr(self.networkview.target.ip_addr)))
                    flowRule.actions.append(
                        of.ofp_action_dl_addr.set_dst(
                            EthAddr(self.networkview.target.eth_addr)))
                    flowRule.actions.append(
                        of.ofp_action_output(
                            port=int(self.networkview.target.switchPort)))
                    #print("2 - " + str(self.networkview.gateway.eth_addr) + " --> " + str(self.networkview.target.eth_addr))
                    rules.append(flowRule)

                else:
                    #print("a - Create rule " + str(self.networkview.target.eth_addr) + " --> " + str(h.decepted_ip_addr) + "/" + str(h.decepted_eth_addr) + " - " + str(h.switchPort))
                    flowRule = nx.nx_flow_mod()
                    flowRule.match.of_eth_type = ethernet.IP_TYPE
                    flowRule.match.eth_src = EthAddr(
                        str(self.networkview.target.eth_addr))
                    flowRule.match.eth_dst = EthAddr(str(h.decepted_eth_addr))
                    flowRule.match.ip_dst = IPAddr(str(h.decepted_ip_addr))
                    flowRule.hard_timeout = FLOW_TIMEOUT
                    flowRule.priority = 1
                    flowRule.actions.append(
                        of.ofp_action_nw_addr.set_src(
                            IPAddr(h.decepted_ip_addr)))
                    #flowRule.actions.append(of.ofp_action_dl_addr.set_src(EthAddr(h.decepted_eth_addr)))
                    flowRule.actions.append(
                        of.ofp_action_nw_addr.set_dst(IPAddr(h.ip_addr)))
                    #flowRule.actions.append(of.ofp_action_dl_addr.set_dst(EthAddr(h.eth_addr)))
                    flowRule.actions.append(
                        of.ofp_action_output(port=int(h.switchPort)))
                    #print("3 - " + str(h.decepted_eth_addr) + " --> " + str(h.eth_addr))
                    rules.append(flowRule)

                    #print("b - Create rule " + str(h.eth_addr) + " --> " + str(h.decepted_eth_addr) + " - " + str(self.networkview.target.switchPort))
                    flowRule = nx.nx_flow_mod()
                    flowRule.match.eth_src = EthAddr(str(h.eth_addr))
                    flowRule.match.eth_dst = EthAddr(str(h.decepted_eth_addr))
                    flowRule.hard_timeout = FLOW_TIMEOUT
                    flowRule.priority = 1
                    flowRule.actions.append(
                        of.ofp_action_nw_addr.set_src(
                            IPAddr(h.decepted_ip_addr)))
                    flowRule.actions.append(
                        of.ofp_action_dl_addr.set_src(
                            EthAddr(h.decepted_eth_addr)))
                    flowRule.actions.append(
                        of.ofp_action_nw_addr.set_dst(
                            IPAddr(self.networkview.target.ip_addr)))
                    flowRule.actions.append(
                        of.ofp_action_dl_addr.set_dst(
                            EthAddr(self.networkview.target.eth_addr)))
                    flowRule.actions.append(
                        of.ofp_action_output(
                            port=int(self.networkview.target.switchPort)))
                    #print("4 - " + str(h.decepted_eth_addr) + " --> " + str(self.networkview.target.eth_addr))
                    rules.append(flowRule)

            #honeypot
            if h.isHoneypot == True and h.isRouter == False and h.eth_addr != self.networkview.target.eth_addr:
                if self.hostHops.has_key(h.decepted_eth_addr):
                    #print("c - Create rule " + str(self.networkview.target.eth_addr) + " --> " + str(h.decepted_ip_addr) + "/" + str(self.networkview.gateway.eth_addr) + " - " + str(h.switchPort))
                    maxHop = self.hostHops.get(h.decepted_eth_addr)
                    for ttl in range((maxHop + 1), 65):
                        flowRule = nx.nx_flow_mod()
                        flowRule.match.of_eth_type = ethernet.IP_TYPE
                        flowRule.match.eth_src = EthAddr(
                            str(self.networkview.target.eth_addr))
                        flowRule.match.eth_dst = EthAddr(
                            str(self.networkview.gateway.eth_addr))
                        flowRule.match.ip_dst = IPAddr(str(h.decepted_ip_addr))
                        flowRule.match.NXM_NX_IP_TTL = ttl
                        flowRule.hard_timeout = FLOW_TIMEOUT
                        flowRule.priority = 1
                        flowRule.actions.append(
                            of.ofp_action_nw_addr.set_src(
                                IPAddr(h.decepted_ip_addr)))
                        flowRule.actions.append(
                            of.ofp_action_dl_addr.set_src(
                                EthAddr(self.networkview.gateway.eth_addr)))
                        flowRule.actions.append(
                            of.ofp_action_nw_addr.set_dst(IPAddr(h.ip_addr)))
                        flowRule.actions.append(
                            of.ofp_action_dl_addr.set_dst(EthAddr(h.eth_addr)))
                        #print("5 - " + str(self.networkview.gateway.eth_addr) + " --> " + str(h.eth_addr))
                        flowRule.actions.append(
                            of.ofp_action_output(port=int(h.switchPort)))
                        rules.append(flowRule)

                    #send back to user and decrease ttl
                    #print("d - Create rule " + str(self.networkview.gateway.eth_addr) + " --> " + str(h.decepted_ip_addr) + "/" + str(self.networkview.target.eth_addr) + " - " + str(self.networkview.target.switchPort))
                    hopCount = self.hostHops[h.decepted_eth_addr]
                    flowRule = nx.nx_flow_mod()
                    flowRule.match.of_eth_type = ethernet.IP_TYPE
                    flowRule.match.eth_src = EthAddr(str(h.eth_addr))
                    flowRule.match.ip_dst = IPAddr(str(h.decepted_ip_addr))
                    flowRule.match.eth_dst = EthAddr(
                        str(self.networkview.gateway.eth_addr))
                    flowRule.hard_timeout = FLOW_TIMEOUT
                    flowRule.priority = 1
                    for hop in range(0, hopCount):
                        flowRule.actions.append(nx.nx_action_dec_ttl())
                    #print("Decrease ttl by " + str(hopCount))
                    flowRule.actions.append(
                        of.ofp_action_nw_addr.set_src(
                            IPAddr(h.decepted_ip_addr)))
                    flowRule.actions.append(
                        of.ofp_action_dl_addr.set_src(
                            EthAddr(self.networkview.gateway.eth_addr)))
                    flowRule.actions.append(
                        of.ofp_action_nw_addr.set_dst(
                            IPAddr(self.networkview.target.ip_addr)))
                    flowRule.actions.append(
                        of.ofp_action_dl_addr.set_dst(
                            EthAddr(self.networkview.target.eth_addr)))
                    #print("6 - " + str(self.networkview.gateway.eth_addr) + " --> " + str(self.networkview.target.eth_addr))
                    flowRule.actions.append(
                        of.ofp_action_output(
                            port=int(self.networkview.target.switchPort)))
                    rules.append(flowRule)

                else:
                    #print("c - Create rule " + str(self.networkview.target.eth_addr) + " --> " + str(h.decepted_ip_addr) + "/" + str(h.decepted_eth_addr) + " - " + str(h.switchPort))
                    flowRule = nx.nx_flow_mod()
                    flowRule.match.of_eth_type = ethernet.IP_TYPE
                    flowRule.match.eth_src = EthAddr(
                        str(self.networkview.target.eth_addr))
                    flowRule.match.eth_dst = EthAddr(str(h.decepted_eth_addr))
                    flowRule.match.ip_dst = IPAddr(str(h.decepted_ip_addr))
                    flowRule.hard_timeout = FLOW_TIMEOUT
                    flowRule.priority = 1
                    flowRule.actions.append(
                        of.ofp_action_nw_addr.set_src(
                            IPAddr(h.decepted_ip_addr)))
                    flowRule.actions.append(
                        of.ofp_action_dl_addr.set_src(
                            EthAddr(h.decepted_eth_addr)))
                    flowRule.actions.append(
                        of.ofp_action_nw_addr.set_dst(IPAddr(h.ip_addr)))
                    flowRule.actions.append(
                        of.ofp_action_dl_addr.set_dst(EthAddr(h.eth_addr)))
                    #print("7 - " + str(self.networkview.gateway.eth_addr) + " --> " + str(h.eth_addr))
                    flowRule.actions.append(
                        of.ofp_action_output(port=int(h.switchPort)))
                    rules.append(flowRule)

                    #print("d - Create rule " + str(h.eth_addr) + " --> " + str(h.decepted_eth_addr) + " - " + str(self.networkview.target.switchPort))
                    flowRule = nx.nx_flow_mod()
                    flowRule.match.eth_src = EthAddr(str(h.eth_addr))
                    flowRule.match.eth_dst = EthAddr(str(h.decepted_eth_addr))
                    flowRule.hard_timeout = FLOW_TIMEOUT
                    flowRule.priority = 1
                    flowRule.actions.append(
                        of.ofp_action_nw_addr.set_src(
                            IPAddr(h.decepted_ip_addr)))
                    flowRule.actions.append(
                        of.ofp_action_dl_addr.set_src(
                            EthAddr(h.decepted_eth_addr)))
                    flowRule.actions.append(
                        of.ofp_action_nw_addr.set_dst(
                            IPAddr(self.networkview.target.ip_addr)))
                    flowRule.actions.append(
                        of.ofp_action_dl_addr.set_dst(
                            EthAddr(self.networkview.target.eth_addr)))
                    #print("8 - " + str(h.decepted_eth_addr) + " --> " + str(self.networkview.target.eth_addr))
                    flowRule.actions.append(
                        of.ofp_action_output(
                            port=int(self.networkview.target.switchPort)))
                    rules.append(flowRule)

                #deception server to target node
                #print("e - Create rule " + str(h.decepted_eth_addr) + " --> " + str(self.networkview.target.eth_addr) + " - " + str(self.networkview.target.switchPort))
                flowRule = nx.nx_flow_mod()
                flowRule.match.eth_src = EthAddr(str(h.decepted_eth_addr))
                flowRule.match.eth_dst = EthAddr(
                    str(self.networkview.target.eth_addr))
                flowRule.hard_timeout = FLOW_TIMEOUT
                flowRule.priority = 1
                flowRule.actions.append(
                    of.ofp_action_output(
                        port=int(self.networkview.target.switchPort)))
                rules.append(flowRule)

                #deception server to honeypot
                #print("f - Create rule " + str(h.decepted_eth_addr) + " --> " + str(h.eth_addr) + " - " + str(h.switchPort))
                flowRule = nx.nx_flow_mod()
                flowRule.match.eth_src = EthAddr(str(h.decepted_eth_addr))
                flowRule.match.eth_dst = EthAddr(str(h.eth_addr))
                flowRule.hard_timeout = FLOW_TIMEOUT
                flowRule.priority = 1
                flowRule.actions.append(
                    of.ofp_action_output(port=int(h.switchPort)))
                rules.append(flowRule)

            #honeyrouter
            if h.isHoneypot == False and h.isRouter == True and h.eth_addr != self.networkview.target.eth_addr:
                #print("g - Create rule " + str(self.networkview.target.eth_addr) + " --> " + str(h.ip_addr) + "/" + str(h.decepted_eth_addr) + " - " + str(h.switchPort))
                #print("Create rule " + str(h.decepted_ip_addr) + " --> " + str(h.ip_addr))
                flowRule = nx.nx_flow_mod()
                flowRule.match.of_eth_type = ethernet.IP_TYPE
                flowRule.match.eth_src = EthAddr(
                    str(self.networkview.target.eth_addr))
                flowRule.match.eth_dst = EthAddr(str(h.decepted_eth_addr))
                flowRule.match.ip_dst = IPAddr(str(h.decepted_ip_addr))
                flowRule.hard_timeout = FLOW_TIMEOUT
                flowRule.priority = 1
                flowRule.actions.append(
                    of.ofp_action_output(port=int(h.switchPort)))
                rules.append(flowRule)

                #print("h - Create rule " + str(h.decepted_eth_addr) + " --> " + str(self.networkview.target.eth_addr) + " - " + str(self.networkview.target.switchPort))
                #print("Create rule " + str(h.ip_addr) + " --> " + str(h.decepted_ip_addr))
                flowRule = nx.nx_flow_mod()
                flowRule.match.eth_src = EthAddr(str(h.decepted_eth_addr))
                flowRule.match.eth_dst = EthAddr(
                    str(self.networkview.target.eth_addr))
                flowRule.hard_timeout = FLOW_TIMEOUT
                flowRule.priority = 1
                flowRule.actions.append(
                    of.ofp_action_output(
                        port=int(self.networkview.target.switchPort)))
                rules.append(flowRule)

        return rules
    def __init__(self, connection):
        self.connection = connection
        connection.addListeners(self)
        if (connection.eth_addr.toStr() == "00:00:00:00:00:01"):
            # Rules for switch s1 !
            '''
        Table id is a number for the the table of rules for each switch.
        Priority is for overlapping matches. Higher values are higher priority.
        in_port - If using a buffer_id, this is the associated input port.
        match - An ofp_match object. By default, this matches everything,
        so you should probably set some of its fields!
        
        '''

            print "Preparing of rules"

            msg = nx.nx_flow_mod_table_id()
            connection.send(msg)
            #table 0 - Rules for IP :01
            '''
        
        Forward a packet to source if the port that is coming is the same as the input
        
        '''

            msg = nx.nx_flow_mod()
            msg.table_id = 0
            msg.priority = 1500
            msg.match.of_eth_dst = "00:00:00:00:00:00"
            msg.match.of_eth_type = 0x86dd
            msg.match.of_in_port = 1
            msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=1))
            self.connection.send(msg)
            '''
             When a message comes to the Switch if has a rule for this IPv6 
             forward it to next port 
        '''

            msg = nx.nx_flow_mod()
            msg.table_id = 0
            msg.priority = 1000
            msg.match.of_eth_dst = "00:00:00:00:00:00"
            msg.match.of_eth_type = 0x86dd
            msg.match.nx_ipv6_dst = (IPAddr6("::1"), IPAddr6("::1"))
            msg.actions.append(of.ofp_action_output(port=1))
            msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=1))
            self.connection.send(msg)
            '''
        
        If you have no rule for this IP check 
        table 1 for IP :02
        
        '''

            msg = nx.nx_flow_mod()
            msg.table_id = 0
            msg.priority = 500
            msg.match.of_eth_dst = "00:00:00:00:00:00"
            msg.match.of_eth_type = 0x86dd
            msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=1))
            self.connection.send(msg)

            #table 1 - Rules for IP :02
            msg = nx.nx_flow_mod()
            msg.table_id = 1
            msg.priority = 1000
            msg.match.of_eth_dst = "00:00:00:00:00:00"
            msg.match.of_eth_type = 0x86dd
            msg.match.nx_ipv6_dst = (IPAddr6("::2"), IPAddr6("::2"))
            msg.actions.append(of.ofp_action_output(port=1))
            self.connection.send(msg)

            msg = nx.nx_flow_mod()
            msg.table_id = 1
            msg.priority = 1500
            msg.match.of_eth_dst = "00:00:00:00:00:00"
            msg.match.of_eth_type = 0x86dd
            msg.match.of_in_port = 2
            self.connection.send(msg)

        if (connection.eth_addr.toStr() == "00:00:00:00:00:02"):
            # Rules for switch s2  !
            print "Preparing of rules"
            '''
        
        The same Rules also for Switch 2 check the above comments..
        
        '''

            msg = nx.nx_flow_mod_table_id()
            connection.send(msg)
            #table 0
            msg = nx.nx_flow_mod()
            msg.table_id = 0
            msg.priority = 1500
            msg.match.of_eth_dst = "00:00:00:00:00:00"
            msg.match.of_eth_type = 0x86dd
            msg.match.of_in_port = 1
            msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=1))
            self.connection.send(msg)

            msg = nx.nx_flow_mod()
            msg.table_id = 0
            msg.priority = 1000
            msg.match.of_eth_dst = "00:00:00:00:00:00"
            msg.match.of_eth_type = 0x86dd
            msg.match.nx_ipv6_dst = (IPAddr6("::2"), IPAddr6("::2"))
            msg.actions.append(of.ofp_action_output(port=1))
            msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=1))
            self.connection.send(msg)

            msg = nx.nx_flow_mod()
            msg.table_id = 0
            msg.priority = 500
            msg.match.of_eth_dst = "00:00:00:00:00:00"
            msg.match.of_eth_type = 0x86dd
            msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=1))
            self.connection.send(msg)
            #table 1
            msg = nx.nx_flow_mod()
            msg.table_id = 1
            msg.priority = 1000
            msg.match.of_eth_dst = "00:00:00:00:00:00"
            msg.match.of_eth_type = 0x86dd
            msg.match.nx_ipv6_dst = (IPAddr6("::4"), IPAddr6("::4"))
            msg.actions.append(of.ofp_action_output(port=2))
            self.connection.send(msg)

            msg = nx.nx_flow_mod()
            msg.table_id = 1
            msg.priority = 1500
            msg.match.of_eth_dst = "00:00:00:00:00:00"
            msg.match.of_eth_type = 0x86dd
            msg.match.of_in_port = 2
            self.connection.send(msg)