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)
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)
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
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)
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)
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
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'])
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)
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)
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)
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)
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)
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
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)
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)
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)
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:]
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)
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))
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))
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 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
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
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
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)
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 _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
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 _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
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 _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 _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)
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
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)
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)