def build_of_actions(self,inport,action_list): ### BUILD OF ACTIONS of_actions = [] for actions in action_list: outport = actions['outport'] del actions['outport'] if 'srcmac' in actions: of_actions.append(of.ofp_action_dl_addr.set_src(actions['srcmac'])) if 'dstmac' in actions: of_actions.append(of.ofp_action_dl_addr.set_dst(actions['dstmac'])) if 'srcip' in actions: of_actions.append(of.ofp_action_nw_addr.set_src(actions['srcip'])) if 'dstip' in actions: of_actions.append(of.ofp_action_nw_addr.set_dst(actions['dstip'])) if 'srcport' in actions: of_actions.append(of.ofp_action_tp_port.set_src(actions['srcport'])) if 'dstport' in actions: of_actions.append(of.ofp_action_tp_port.set_dst(actions['dstport'])) if 'vlan_id' in actions: if actions['vlan_id'] is None: of_actions.append(of.ofp_action_strip_vlan()) else: of_actions.append(of.ofp_action_vlan_vid(vlan_vid=actions['vlan_id'])) if 'vlan_pcp' in actions: if actions['vlan_pcp'] is None: if not actions['vlan_id'] is None: raise RuntimeError("vlan_id and vlan_pcp must be set together!") pass else: of_actions.append(of.ofp_action_vlan_pcp(vlan_pcp=actions['vlan_pcp'])) if (not inport is None) and (outport == inport): of_actions.append(of.ofp_action_output(port=of.OFPP_IN_PORT)) else: of_actions.append(of.ofp_action_output(port=outport)) return of_actions
def build_of_actions(self,inport,action_list): ### BUILD OF ACTIONS of_actions = [] for actions in action_list: outport = actions['port'] del actions['port'] if 'srcmac' in actions: of_actions.append(of.ofp_action_dl_addr.set_src(actions['srcmac'])) if 'dstmac' in actions: of_actions.append(of.ofp_action_dl_addr.set_dst(actions['dstmac'])) if 'srcip' in actions: of_actions.append(of.ofp_action_nw_addr.set_src(actions['srcip'])) if 'dstip' in actions: of_actions.append(of.ofp_action_nw_addr.set_dst(actions['dstip'])) if 'srcport' in actions: of_actions.append(of.ofp_action_tp_port.set_src(actions['srcport'])) if 'dstport' in actions: of_actions.append(of.ofp_action_tp_port.set_dst(actions['dstport'])) if 'vlan_id' in actions: if actions['vlan_id'] is None: of_actions.append(of.ofp_action_strip_vlan()) else: of_actions.append(of.ofp_action_vlan_vid(vlan_vid=actions['vlan_id'])) if 'vlan_pcp' in actions: if actions['vlan_pcp'] is None: if not actions['vlan_id'] is None: raise RuntimeError("vlan_id and vlan_pcp must be set together!") pass else: of_actions.append(of.ofp_action_vlan_pcp(vlan_pcp=actions['vlan_pcp'])) if (not inport is None) and (outport == inport): of_actions.append(of.ofp_action_output(port=of.OFPP_IN_PORT)) else: of_actions.append(of.ofp_action_output(port=outport)) return of_actions
def resend_packet (self, packet_in, out_ports): """ Instructs the switch to resend a packet that it had sent to us. "packet_in" is the ofp_packet_in object the switch had sent to the controller due to a table-miss. """ log.debug( "Sending out: %s" % out_ports ) msg = of.ofp_packet_out() msg.data = packet_in # Add actions for each out port for out_port in out_ports: # If port is dot1q put on vlan tag if self.vlan_to_port[out_port] == 1: action = of.ofp_action_vlan_vid(vlan_vid = self.vlan_to_port[packet_in.in_port]) # Else strip vlan tag else: action = of.ofp_action_strip_vlan() msg.actions.append(action) # Send the packet out of the specified port action = of.ofp_action_output(port = out_port) msg.actions.append(action) # Send message to switch self.connection.send(msg) log.debug("Packet sent out: %s" % out_ports )
def install_push_rule(self, info, label, ip, raddr, dstaddr): ''' Install a flow rule on an edge switch to push a label onto a flow. ''' # message for switch msg = of.ofp_flow_mod() # match on MAC dst and IP dst msg.match.dl_src = None # wildcard source MAC msg.match.dl_dst = dstaddr msg.match.dl_type = ethernet.IP_TYPE msg.match.nw_src = None # wildcard source IP msg.match.nw_dst = ip # actions - rewrite MAC dst and push label actions = [] actions.append(of.ofp_action_dl_addr.set_dst(raddr)) actions.append(of.ofp_action_vlan_vid(vlan_vid=label)) # set output port action port = self.topology_tracker.get_link_port(info.dpid1, info.dpid2) if port is None: log.warn("No port connecting {0} --> {1}".format( info.dpid1, info.dpid2)) return actions.append(of.ofp_action_output(port=port)) msg.actions = actions # set a timeout and send msg.idle_timeout = self.idle_timeout self.topology_tracker.graph.node[info.dpid1]['connection'].send(msg) return actions
def knownSend(self, buffer_id, raw_data, out_port, in_port): """ Sends packet to known host """ msg = of.ofp_packet_out() msg.in_port = in_port if buffer_id != -1 and buffer_id is not None: # We got a buffer ID from the switch; use that msg.buffer_id = buffer_id else: # No buffer ID from switch -- we got the raw data if raw_data is None: # No raw_data specified -- nothing to send! return msg.data = raw_data # Add an action to send to the specified port action1 = of.ofp_action_vlan_vid(vlan_vid=VLAN_SPECIAL) action2 = of.ofp_action_output(port=out_port) msg.actions.append(action1) msg.actions.append(action2) # Send message to switch self.connection.send(msg)
def install_path_rule(self, info, inlabel, outlabel): ''' Install a flow rule on a core switch to route based on label. ''' # message for switch msg = of.ofp_flow_mod() # match on MAC dst and IP dst msg.match.dl_src = None # wildcard MACs msg.match.dl_dst = None msg.match.dl_vlan = inlabel # actions - rewrite MAC dst and push label msg.actions.append(of.ofp_action_vlan_vid(vlan_vid=outlabel)) # set output port action port = self.topology_tracker.get_link_port(info.dpid1, info.dpid2) if port is None: log.warn("No port connecting {0} --> {1}".format( info.dpid1, info.dpid2)) return msg.actions.append(of.ofp_action_output(port=port)) # set a timeout and send #msg.idle_timeout = None # these flows are static self.topology_tracker.graph.node[info.dpid1]['connection'].send(msg)
def flow_3f(inport, input_ip, trans_port, original_port, vlan=0, out_port=2): # flow1: flow3fmsg.cookie = 0 flow3fmsg.match.in_port = inport flow3fmsg.match.dl_type = 0x0800 flow3fmsg.match.nw_src = IPAddr(input_ip) flow3fmsg.match.nw_proto = 6 flow3fmsg.match.tp_src = original_port # ACTIONS--------------------------------- flow3ftrans = of.ofp_action_tp_port.set_src(trans_port) flow3fout = of.ofp_action_output(port=out_port) flow3fsrcIP = of.ofp_action_nw_addr.set_src(IPAddr("10.0.0.2")) flow3fsrcMAC = of.ofp_action_dl_addr.set_src(EthAddr("00:00:00:00:00:05")) flow3fdstMAC = of.ofp_action_dl_addr.set_dst(EthAddr("00:00:00:00:00:06")) flow3fvlanid = of.ofp_action_vlan_vid(vlan_vid=vlan) flow3fmsg.actions = [ flow3ftrans, flow3fsrcIP, flow3fsrcMAC, flow3fdstMAC, flow3fvlanid, flow3fout ] return flow3fmsg
def installPolicyDoneRule(switch): """ Installs rules for packets that were successfully """ if int(switch) in range(100, 200): fm = of.ofp_flow_mod() fm.match.dl_vlan = VLAN_DONE action = of.ofp_action_output(port=of.OFPP_FLOOD) fm.actions.append(action) RulesTable.addRule(switch, "core flood to all ports", VLAN_DONE, "flood ports") switchesConn[switch].send(fm) else: fm = of.ofp_flow_mod() fm.match.dl_vlan = VLAN_DONE allPorts = [ int(p) for p in Discovery.graph.nodes[int(switch)].connection.ports ] corePorts = Discovery.getPorts(int(switch)) hostPorts = list(set(allPorts) - set(corePorts)) RulesTable.addRule(switch, " TOR flood to all hosts ", VLAN_DONE, "all hosts ports") action = of.ofp_action_vlan_vid() fm.actions.append(action) for p in hostPorts: if p < of.OFPP_MAX: action = of.ofp_action_output(port=p) fm.actions.append(action) switchesConn[switch].send(fm)
def _update_step(self): if self.update_step > len(self.config.config) - 1: self.update_timer.cancel() log.warning("Updating Ends.") return self.config.change_step(self.update_step) self.update_timer._next = time.time() + self.config.next_time # redistribute flows based on new configuration self.config.reset_real_config() self.reset_flowdist_tables() # Compute for each port in all source destination pair for src in self.sd_path_table: for dst in self.sd_path_table[src]: id_list = self.sd_path_table[src][dst] for srcport in self.sd_srcport_table[src][dst]: pid = self.get_pid_by_srcport(id_list, srcport) # should be None if pid is None: # Not existed port, choose the last one as default pid = id_list[len(id_list) - 1] for k in id_list: now_split = self.config.now_config real_split = self.config.real_config if now_split[k-1] > real_split[k-1] or now_split[k-1] == 1: pid = k break # update flow_dist_table and real_config_table self.flow_dist_table[pid-1].append(srcport) self.config.compute_real_config(id_list, self.flow_dist_table) log.warning("pid %s", pid) srcip = self.srcip_table[src] dstip = self.dstip_table[dst] msg = of.ofp_flow_mod( command = of.OFPFC_MODIFY ) msg.match.dl_type = 0x800 msg.match.nw_src = IPAddr(srcip) msg.match.nw_dst = IPAddr(dstip) msg.match.nw_proto = 17 msg.match.tp_src = srcport path = self.path_id_table[pid] if len(path) > 3: # It is not the last sw, tag it and send into the network if USE_VLAN_TAG: msg.actions.append( of.ofp_action_vlan_vid( vlan_vid = pid ) ) if USE_ETHERNET_SRC_TAG: msg.actions.append( of.ofp_action_dl_addr.set_src( EthAddr( self._int_to_MAC( pid ) ) ) ) msg.actions.append( of.ofp_action_output( port = self.ports[path[1]][path[2]] ) ) elif len(path) == 3: # last sw, forward to the host # msg.actions.append( of.ofp_action_output( port = of.OFPP_FLOOD ) ) msg.actions.append( of.ofp_action_output( port = self.hadj[path[2]][path[1]] ) ) sw = path[1] core.openflow.sendToDPID(sw, msg) # print msg # log.warning("SD pair %i, pid %i", self.sd_pair[src][dst], pid) log.warning("Update Step %i ...", self.update_step) self.update_step += 1
def dropping (duration=None): msg.priority=65535 msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = 831)) # modify the vlan id from the 830 to 831 print "dropping packets from ", IP_attack for connection in self.myconnections: connection.send(msg) #send the msg to the switch connection.send(of.ofp_stats_request(body=of.ofp_flow_stats_request())) #getting the flux stats print "MSG sent"
def _handle_PacketIn(event): global s1_dpid # print "PacketIn: ", dpidToStr(event.connection.dpid) if event.connection.dpid==s1_dpid: # Flujo entrante por el puerto 3 con dl_vlan = 50 msg = of.ofp_flow_mod() msg.priority = 100 # A numero mas alto mayor prioridad msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 3 msg.match.dl_vlan = 50 msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg) # Flujo entrante por el puerto 3 con dl_vlan = 60 msg = of.ofp_flow_mod() msg.priority = 1 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 3 msg.match.dl_vlan = 60 msg.actions.append(of.ofp_action_output(port = 2)) event.connection.send(msg) # Flujo entrante por el puerto 1 msg = of.ofp_flow_mod() msg.priority = 1 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 1 msg.actions.append([of.ofp_action_vlan_vid(vlan_vid = 50),of.ofp_action_output(port = 3)]) event.connection.send(msg) # Flujo entrante por el puerto 2 msg = of.ofp_flow_mod() msg.priority = 1 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 2 msg.actions.append([of.ofp_action_vlan_vid(vlan_vid = 60),of.ofp_action_output(port = 1)]) event.connection.send(msg)
def honeypot(): print "Honeypot" msg.actions.append(of.ofp_action_dl_addr.set_dst(mac_honey)) # honeypot MAC address msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = 831)) # modify the vlan id from the 830 to 831 msg.actions.append(of.ofp_action_nw_addr.set_dst(ip_honeypot)) # action to send the flux to the honey_pot msg.actions.append(of.ofp_action_output(port = 6)) # which port the honeypot is connected # see how i can get this port by python for connection in self.myconnections: connection.send(msg) #send the msg to the switch connection.send(of.ofp_stats_request(body=of.ofp_flow_stats_request())) #getting the flux stats print "MSG sent"
def _install_hybrid_dynamic_flows(self, event, out_dpid, final_out_port, packet): "Install entry at ingress switch." in_name = self.t.id_gen(dpid=event.dpid).name_str() #log.info("in_name: %s" % in_name) out_name = self.t.id_gen(dpid=out_dpid).name_str() #log.info("out_name: %s" % out_name) hash_ = self._ecmp_hash(packet) src_dst_route = self.r.get_route(in_name, out_name, hash_) # Choose a random core switch. core_sws = sorted( self._raw_dpids(self.t.layer_nodes(self.t.LAYER_CORE))) core_sw = random.choice(core_sws) core_sw_id = self.t.id_gen(dpid=core_sw) core_sw_name = self.t.id_gen(dpid=core_sw).name_str() route = self.r.get_route(in_name, core_sw_name, None) assert len(route) == 3 log.info("route: %s" % route) match = of.ofp_match.from_packet(packet) assert core_sw_id.pod == self.t.k core_sw_index = ((core_sw_id.sw - 1) * 2) + (core_sw_id.host - 1) #log.info("core_sw_index: %s" % core_sw_index) dst_host_index = self.dpid_port_to_host_index(out_dpid, final_out_port) #log.info("dst_host_index: %s" % dst_host_index) vlan = (dst_host_index << 2) + core_sw_index log.info("vlan: %s" % vlan) log.info("len(src_dst_route): %i" % len(src_dst_route)) if len(src_dst_route) == 1: # Don't bother with VLAN append; directly send to out port. log.info("adding edge-only entry from %s to %s on sw %s" % (match.dl_src, match.dl_dst, in_name)) self.switches[event.dpid].install(final_out_port, match, idle_timeout=HYBRID_IDLE_TIMEOUT, priority=PRIO_HYBRID_FLOW_DOWN) else: # Write VLAN and send up src_port, dst_port = self.t.port(route[0], route[1]) actions = [ of.ofp_action_vlan_vid(vlan_vid=vlan), of.ofp_action_output(port=src_port) ] self.switches[event.dpid].install_multiple( actions, match, idle_timeout=HYBRID_IDLE_TIMEOUT, priority=PRIO_HYBRID_FLOW_UP)
def pClient(username, mac, ip=""): # permit traffic from the client to the router - i.e. auth successful connection = core.openflow.getConnection(strToDPID(dpid)) MAC = EthAddr(mac) IP = IPAddr(ip) vlan = getVLANs(ip) query = "INSERT into tbl_nac_session (username,mac_address,ip_address,start_dt) VALUES ('%s','%s','%s',now())" % ( username, mac, ip) msg = None # note: if the openflow switch supports L3 matching in addition to L2 matching # note: matching on both will result in higher security - but not all support both. # note: if we match on L3 and ARP matching is not supported (see sPortal), # note: ARPs from the client will not flow to the router but rather to the portal # note: so it does not make sense to match on L3 unless we can also match on ARPs # note: but technically you could comment out "and dp_supports_arp_match" if you don't # note: care that ARPs from clients always go to your portal which runs proxy ARP if dp_supports_l3_match and dp_supports_arp_match: msg = of.ofp_flow_mod() msg.flags = of.OFPFF_SEND_FLOW_REM msg.idle_timeout = client_idle_timeout msg.priority = 32768 msg.match.in_port = client_port_match msg.match.dl_src = MAC msg.match.dl_type = pkt.ethernet.IP_TYPE msg.match.nw_src = IP msg.actions.append(of.ofp_action_vlan_vid(vlan_vid=vlan['trusted'])) msg.actions.append(of.ofp_action_output(port=router_port_action)) else: msg = of.ofp_flow_mod() msg.flags = of.OFPFF_SEND_FLOW_REM msg.idle_timeout = client_idle_timeout msg.priority = 32768 msg.match.dl_src = MAC msg.actions.append(of.ofp_action_vlan_vid(vlan_vid=vlan['trusted'])) msg.actions.append(of.ofp_action_output(port=router_port_action)) if msg: cursor = db.cursor() cursor.execute(query) connection.send(msg)
def pClient(username,mac,ip=""): # permit traffic from the client to the router - i.e. auth successful connection = core.openflow.getConnection(strToDPID(dpid)) MAC = EthAddr(mac) IP = IPAddr(ip) vlan = getVLANs(ip) query = "INSERT into tbl_nac_session (username,mac_address,ip_address,start_dt) VALUES ('%s','%s','%s',now())" % (username,mac,ip) msg = None # note: if the openflow switch supports L3 matching in addition to L2 matching # note: matching on both will result in higher security - but not all support both. # note: if we match on L3 and ARP matching is not supported (see sPortal), # note: ARPs from the client will not flow to the router but rather to the portal # note: so it does not make sense to match on L3 unless we can also match on ARPs # note: but technically you could comment out "and dp_supports_arp_match" if you don't # note: care that ARPs from clients always go to your portal which runs proxy ARP if dp_supports_l3_match and dp_supports_arp_match: msg = of.ofp_flow_mod() msg.flags = of.OFPFF_SEND_FLOW_REM msg.idle_timeout = client_idle_timeout msg.priority = 32768 msg.match.in_port = client_port_match msg.match.dl_src = MAC msg.match.dl_type = pkt.ethernet.IP_TYPE msg.match.nw_src = IP msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = vlan['trusted'])) msg.actions.append(of.ofp_action_output(port = router_port_action)) else: msg = of.ofp_flow_mod() msg.flags = of.OFPFF_SEND_FLOW_REM msg.idle_timeout = client_idle_timeout msg.priority = 32768 msg.match.dl_src = MAC msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = vlan['trusted'])) msg.actions.append(of.ofp_action_output(port = router_port_action)) if msg: cursor = db.cursor() cursor.execute(query) connection.send(msg)
def honeypot(): print "Honeypot" msg.actions.append(of.ofp_action_dl_addr.set_dst(mac_honey)) # honeypot MAC address msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = 831)) # modify the vlan id from the 830 to 831 msg.actions.append(of.ofp_action_nw_addr.set_dst(ip_honeypot)) # action to send the flux to the honey_pot msg.actions.append(of.ofp_action_output(port = 6)) # which port the honeypot is connected ts = time.time() st = datetime.datetime.fromtimestamp(ts).strftime('%H:%M:%S %d-%m-%Y') outputLog.write("Flow Deviated "+ IP_attack +"-->" + IP_dst +' '+ str(st) +'\n') # see how i can get this port by python for connection in self.myconnections: connection.send(msg) #send the msg to the switch connection.send(of.ofp_stats_request(body=of.ofp_flow_stats_request())) #getting the flux stats print "MSG sent to switchs"
def unknownSend(self, buffer_id, raw_data, out_port, in_port, switch): """ Sends packet to unknown host """ msg = of.ofp_packet_out() msg.in_port = in_port if buffer_id != -1 and buffer_id is not None: # We got a buffer ID from the switch; use that msg.buffer_id = buffer_id else: # No buffer ID from switch -- we got the raw data if raw_data is None: # No raw_data specified -- nothing to send! return msg.data = raw_data # Add an action to send to the specified port action1 = of.ofp_action_vlan_vid(vlan_vid=VLAN_DONE) action2 = of.ofp_action_output(port=out_port) msg.actions.append(action1) msg.actions.append(action2) allPorts = [ int(p) for p in Discovery.graph.nodes[int(switch)].connection.ports ] corePorts = Discovery.getPorts(int(switch)) hostPorts = list(set(allPorts) - set(corePorts)) for p in hostPorts: if p < of.OFPP_MAX: action3 = of.ofp_action_vlan_vid() action4 = of.ofp_action_output(port=p) msg.actions.append(action3) msg.actions.append(action4) # Send message to switch self.connection.send(msg)
def _match_action(self,msg): if len(self.actions) == 1 and self.actions[0] == "" : return for action in self.actions: action_name = action.split('=')[0] if action_name != "STRIP_VLAN": action_argu = action.split('=')[1] if(action_name == "OUTPUT"): msg.actions.append(of.ofp_action_output(port = int(action_argu))) elif(action_name == "ENQUEUE"): port = action_argu.split(':')[0] queue_id = action_argu.split(':')[1] msg.actions.append(of.ofp_action_enqueue(port = int(port) , queue_id = int(queue_id))) elif(action_name == "STRIP_VLAN"): msg.actions.append(of.ofp_action_strip_vlan()) elif(action_name == "SET_VLAN_VID"): msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = int(action_argu))) elif(action_name == "SET_VLAN_PCP"): msg.actions.append(of.ofp_action_vlan_pcp(vlan_pcp = int(action_argu))) elif(action_name == "SET_DL_SRC"): msg.actions.append(of.ofp_action_dl_addr(type = 4 , dl_addr = EthAddr(action_argu))) elif(action_name == "SET_DL_DST"): msg.actions.append(of.ofp_action_dl_addr(type = 5 , dl_addr = EthAddr(action_argu))) elif(action_name == "SET_NW_TOS"): msg.actions.append(of.ofp_action_nw_tos(nw_tos = int(action_argu))) elif(action_name == "SET_NW_SRC"): msg.actions.append(of.ofp_action_nw_addr(type = 6 , nw_addr = IPAddr(action_argu))) elif(action_name == "SET_NW_DST"): msg.actions.append(of.ofp_action_nw_addr(type = 7 , nw_addr = IPAddr(action_argu))) elif(action_name == "SET_TP_SRC"): msg.actions.append(of.ofp_action_tp_port(type = 9 , tp_port = int(action_argu))) elif(action_name == "SET_TP_DST"): msg.actions.append(of.ofp_action_tp_port(type = 10 , tp_port = int(action_argu)))
def dropping (duration=duration_block): #this is the time that mflow will be blocked in seconds msg.priority=65535 msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = 831)) # modify the vlan id from the 830 to 831 if duration is not None: if not isinstance(duration, tuple): duration = (duration,duration) msg.idle_timeout = duration[0] #this made the flow go back after the specified time msg.hard_timeout = duration[1] print "dropping packets from ", IP_attack ts = time.time() #create time stamp st = datetime.datetime.fromtimestamp(ts).strftime('%d-%m-%Y %H:%M:%S') #human format time stamp outputLog.write("Flow Blocked "+ IP_attack +"-->" + IP_dst +' '+ str(st) +" detected by "+self.addressSensor[0]+'\n')# creating the log #see how to create a log style for connection in self.myconnections: connection.send(msg) #send the msg to the switch connection.send(of.ofp_stats_request(body=of.ofp_flow_stats_request())) #getting the flux stats print "MSG sent to switches!"
def _install_hybrid_dynamic_flows(self, event, out_dpid, final_out_port, packet): "Install entry at ingress switch." in_name = self.t.id_gen(dpid = event.dpid).name_str() #log.info("in_name: %s" % in_name) out_name = self.t.id_gen(dpid = out_dpid).name_str() #log.info("out_name: %s" % out_name) hash_ = self._ecmp_hash(packet) src_dst_route = self.r.get_route(in_name, out_name, hash_, False) # Choose a random core switch. core_sws = sorted(self._raw_dpids(self.t.layer_nodes(self.t.LAYER_CORE))) core_sw = random.choice(core_sws) core_sw_id = self.t.id_gen(dpid = core_sw) core_sw_name = self.t.id_gen(dpid = core_sw).name_str() route = self.r.get_route(in_name, core_sw_name, None, False) assert len(route) == 3 log.info("route: %s" % route) match = of.ofp_match.from_packet(packet) assert core_sw_id.pod == self.t.k core_sw_index = ((core_sw_id.sw - 1) * 2) + (core_sw_id.host - 1) #log.info("core_sw_index: %s" % core_sw_index) dst_host_index = self.dpid_port_to_host_index(out_dpid, final_out_port) #log.info("dst_host_index: %s" % dst_host_index) vlan = (dst_host_index << 2) + core_sw_index log.info("vlan: %s" % vlan) log.info("len(src_dst_route): %i" % len(src_dst_route)) if len(src_dst_route) == 1: # Don't bother with VLAN append; directly send to out port. log.info("adding edge-only entry from %s to %s on sw %s" % (match.dl_src, match.dl_dst, in_name)) self.switches[event.dpid].install(final_out_port, match, idle_timeout = HYBRID_IDLE_TIMEOUT, priority = PRIO_HYBRID_FLOW_DOWN) else: # Write VLAN and send up src_port, dst_port = self.t.port(route[0], route[1]) actions = [of.ofp_action_vlan_vid(vlan_vid = vlan), of.ofp_action_output(port = src_port)] self.switches[event.dpid].install_multiple(actions, match, idle_timeout = HYBRID_IDLE_TIMEOUT, priority = PRIO_HYBRID_FLOW_UP)
def install_fwdrule(event,srcip,dstip,outport,vlan=0): msg = of.ofp_flow_mod() #Match msg.match = of.ofp_match() msg.match.dl_type = ethernet.IP_TYPE msg.match.set_nw_src(IPAddr(srcip, 32), 32) msg.match.set_nw_dst(IPAddr(dstip, 32), 32) if not vlan == 0 : # Need to set VLAN Tag for isolation of tenant traffic. msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = vlan)) msg.actions.append(of.ofp_action_output(port = outport)) msg.data = event.ofp msg.in_port = event.port event.connection.send(msg)
def send_packet(self, buffer_id, raw_data, out_port, in_port, vlan_clear=False): """ Sends a packet out of the specified switch port. If buffer_id is a valid buffer on the switch, use that. Otherwise, send the raw data in raw_data. The "in_port" is the port number that packet arrived on. Use OFPP_NONE if you're generating this packet. """ # We tell the switch to take the packet with id buffer_if from in_port # and send it to out_port # If the switch did not specify a buffer_id, it must have specified # the raw data of the packet, so in this case we tell it to send # the raw data msg = of.ofp_packet_out() msg.in_port = in_port if buffer_id != -1 and buffer_id is not None: # We got a buffer ID from the switch; use that msg.buffer_id = buffer_id else: # No buffer ID from switch -- we got the raw data if raw_data is None: # No raw_data specified -- nothing to send! return msg.data = raw_data # Add an action to send to the specified port if vlan_clear: action = of.ofp_action_vlan_vid() msg.actions.append(action) action = of.ofp_action_output(port=out_port) msg.actions.append(action) # Send message to switch self.connection.send(msg)
def flow_4f(vlanid): ip = ip_vlan_reverse_dict[vlanid] #print "flow4f ip - {0}".format(ip) flow4fmsg = of.ofp_flow_mod() flow4fmsg.cookie = 0 flow4fmsg.match.in_port = 1 #flow4fmsg.match.dl_type = 0x8100 flow4fmsg.match.dl_vlan = vlanid flow4fmsg.hard_timeout = 60 print blocked_ips # Clear blocked_ips # READ FROM FILE AND UPDATE blocked_ips with open("/home/mininet/pox/pox/misc/blocked_ips.txt", "r") as f: b_l = [] for i in f: b_l.append(i.strip()) global blocked_ips blocked_ips = b_l if str(ip) not in blocked_ips: #if True: #flow4fmsg.match.nw_src = IPAddr("10.0.0.2") # ACTIONS--------------------------------- flow4fout = of.ofp_action_output(port=2) # flow4fsrcIP = of.ofp_action_nw_addr.set_src(IPAddr("10.0.0.2")) flow4fsrcMAC = of.ofp_action_dl_addr.set_src( EthAddr("00:00:00:00:00:03")) flow4fdstMAC = of.ofp_action_dl_addr.set_dst( EthAddr("00:00:00:00:00:01")) flow4fvlanid = of.ofp_action_vlan_vid(vlan_vid=0) flow4fmsg.actions = [ flow4fsrcMAC, flow4fdstMAC, flow4fvlanid, flow4fout ] else: print "IP is blocked" return flow4fmsg
def two_phase_update(self, config): #read all the flow mods for dpid,flow_mod_list in config.flowmods.iteritems(): for flow_mod in flow_mod_list: flow_mod.match.dl_vlan = self.vlan core.openflow.getConnection(dpid).send(flow_mod) #for all external ports, install vlan mod rules for id,sw in core.openflow_topology.topology._entities.iteritems(): for portid in sw.ports.iterkeys(): if self.is_external(id,portid) == 1 and portid < 10: match = of.ofp_match(in_port = portid) flow = of.ofp_flow_mod(match = match) flow.command = of.OFPFC_MODIFY_STRICT action = of.ofp_action_vlan_vid(vlan_vid = self.vlan) flow.actions.append(action) core.openflow.getConnection(id).send(flow) # Delete the old vlan rules after a certain interval Timer(self.delete_interval, self.delete_old_rules, recurring = False) return
def _match_action(self,msg): if(self.actions == "OUTPUT"): msg.actions.append(of.ofp_action_output(port = int(self.actions_argu))) elif(self.actions == "enqueue"): port = self.actions_argu.split(':')[0] queue_id = self.actions_argu.split(':')[1] msg.actions.append(of.ofp_action_enqueue(port = int(port) , queue_id = int(queue_id))) elif(self.actions == "strip-vlan"): msg.actions.append(of.ofp_action_strip_vlan()) elif(self.actions == "set-vlan-id"): msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = int(self.actions_argu))) elif(self.actions == "set-vlan-priority"): msg.actions.append(of.ofp_action_vlan_pcp(vlan_pcp = int(self.actions_argu))) elif(self.actions == "SET_DL_SRC"): msg.actions.append(of.ofp_action_dl_addr(type = 4 , dl_addr = EthAddr(self.actions_argu))) elif(self.actions == "SET_DL_DST"): msg.actions.append(of.ofp_action_dl_addr(type = 5 , dl_addr = EthAddr(self.actions_argu))) elif(self.actions == "SET_NW_TOS"): msg.actions.append(of.ofp_action_nw_tos(nw_tos = int(self.actions_argu))) elif(self.actions == "SET_NW_SRC"): msg.actions.append(of.ofp_action_nw_addr(type = 6 , nw_addr = IPAddr(self.actions_argu))) elif(self.actions == "SET_NW_DST"): msg.actions.append(of.ofp_action_nw_addr(type = 7 , nw_addr = IPAddr(self.actions_argu))) elif(self.actions == "SET_TP_SRC"): msg.actions.append(of.ofp_action_tp_port(type = 9 , tp_port = int(self.actions_argu))) elif(self.actions == "SET_TP_DST"): msg.actions.append(of.ofp_action_tp_port(type = 10 , tp_port = int(self.actions_argu)))
def flood (): """ Floods the packet """ if event.ofp.buffer_id == -1: log.warning("Not flooding unbuffered packet on %s", dpidToStr(event.dpid)) return msg = of.ofp_packet_out() if time.time() - self.connection.connect_time > FLOOD_DELAY: # Only flood if we've been connected for a little while... log.debug("%i: flood %s -> %s", event.dpid, packet.src, packet.dst) if packet.dst.toInt() < 5 and packet.dst.toInt() < 5 and event.dpid != packet.dst.toInt() and packet.type != ethernet.VLAN_TYPE: log.debug("No vlan tag, pushing") msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = event.dpid)) elif packet.src.toInt() < 5 and packet.dst.toInt() < 5 and event.dpid == packet.dst.toInt() and packet.type == ethernet.VLAN_TYPE: log.debug("VLAN tag found, popping") msg.actions.append(of.ofp_action_header(type=of.ofp_action_type_rev_map['OFPAT_STRIP_VLAN'])) msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD)) else: pass log.info("Holding down flood for %s", dpidToStr(event.dpid)) msg.buffer_id = event.ofp.buffer_id msg.in_port = event.port self.connection.send(msg)
def coding_switch(self,packet,packet_in): #Assign source mac to forwarding table. src_mac = packet.src dst_mac = packet.dst self.fwd_table[src_mac] = packet_in.in_port #log.debug("%s \n" % self.fwd_table) if dst_mac in self.fwd_table: #Add flow mod msg = of.ofp_flow_mod() msg.match = of.ofp_match.from_packet(packet) #Contruct exact match based on incoming packet. msg.data = packet_in if self.check_vlan(packet): #Send VLAN packets back to the same host socket msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT)) msg.actions.append(of.ofp_action_tp_port(type=of.OFPAT_SET_TP_DST,tp_port=666)) print("Has VLAN") else: msg.actions.append(of.ofp_action_output(port = self.fwd_table[dst_mac])) #Normal learning switch (No Flow Mods). Used for comparison #msg = of.ofp_packet_out() #Instructs switch to send packet out. #msg.data = packet_in #msg.actions.append(of.ofp_action_output(port = self.fwd_table[dst_mac])) else: #Act like a hub and forward to all output ports. msg = of.ofp_packet_out() #Instructs switch to send packet out. msg.data = packet_in msg.actions.append(of.ofp_action_output(port = of.OFPP_ALL)) #Send message to switch msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = 2135)) self.connection.send(msg)
def configureRules (self, event, lruleset): """ Configure initial rules """ print "Ready for configure init rules in SW: " + dpidToStr(event.dpid) + " " + str(event.dpid) of_fib = parse_of_file(lruleset) #print of_fib of_list = [] try: of_list = of_fib[dpidToStr(event.dpid)] except KeyError: print "Oops! There is no information about the Sw " + dpidToStr(event.dpid) + " in the configuration file" #f = open('/tmp/' + dpidToStr(event.dpid), 'wa') #f.write( dpidToStr(event.dpid) + " begin " + str(time.time())) #of_entry = of_list[0] #print of_entry for of_entry in of_list: msg = of.ofp_flow_mod() #print "writing OpenFlow entry:", of_entry #msg.priority = 42 if "dl_type" in of_entry.keys(): msg.match.dl_type = int(of_entry["dl_type"], 16) if "nw_proto" in of_entry.keys(): msg.match.nw_proto = int(of_entry["nw_proto"], 10) #ETH if "dl_src" in of_entry.keys(): msg.match.dl_src = EthAddr(of_entry["dl_src"]) if "dl_dst" in of_entry.keys(): msg.match.dl_dst = EthAddr(of_entry["dl_dst"]) #IP if "nw_src" in of_entry.keys(): msg.match.nw_src = IPAddr(of_entry["nw_src"]) if "nw_dst" in of_entry.keys(): msg.match.nw_dst = IPAddr(of_entry["nw_dst"]) if "nw_tos" in of_entry.keys(): msg.match.nw_tos = int(of_entry["nw_tos"],10) #UDP if "tp_dst" in of_entry.keys(): msg.match.tp_dst = int(of_entry["tp_dst"],10) if "tp_src" in of_entry.keys(): msg.match.tp_src = int(of_entry["tp_src"],10) #OTHERS if "in_port" in of_entry.keys(): msg.match.in_port = int(of_entry["in_port"],10) if "dl_vlan" in of_entry.keys(): msg.match.dl_vlan = int(of_entry["dl_vlan"],16) if "vlan_tci" in of_entry.keys(): msg.match.vlan_tci = int(of_entry["vlan_tci"],16) #msg.match.tp_dst = 80 # iterate list of actions #output #vlan if "mod_nw_tos" in of_entry["actions"].keys(): msg.actions.append(of.ofp_action_nw_tos(nw_tos = int(of_entry["actions"]["mod_nw_tos"],10))) if "mod_vlan_vid" in of_entry["actions"].keys(): msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = int(of_entry["actions"]["mod_vlan_vid"],16))) if "mod_dl_src" in of_entry["actions"].keys(): msg.actions.append(of.ofp_action_dl_addr.set_src(EthAddr(of_entry["actions"]["mod_dl_src"]))) if "mod_dl_dst" in of_entry["actions"].keys(): print "mod_dl_dst: %s " % of_entry["actions"]["mod_dl_dst"] msg.actions.append(of.ofp_action_dl_addr.set_dst(EthAddr(of_entry["actions"]["mod_dl_dst"]))) if "output" in of_entry["actions"].keys(): msg.actions.append(of.ofp_action_output(port = int(of_entry["actions"]["output"],10))) #print "set the output port" self.connection.send(msg) #f.write(" ending " + str(time.time()) + "\n") #f.close() print "Init rules configured, allow traffic for " + dpidToStr(event.dpid)
def reply_request(self, success, request_id, event, title_aggr=None, w=None): # Build the response resp_msg = dts_pb2.ControlResponse() resp_msg.status = resp_msg.SUCCESS if success else resp_msg.FAILURE if request_id != None: resp_msg.request_id = request_id if self.aggr and w: # reply for the second workspace attachment print 'title_aggr', title_aggr, 'flow', self.flow # Send FLOW_MOD to the swith that is ataching an entity title = w.title if title_aggr in workspaces_aggr: w2 = workspaces_aggr[title_aggr] else: log.info('Unknown aggregated workspace title') title_hash = hashlib.sha256(title).digest()[:12] title_hash_aggr = hashlib.sha256(title_aggr).digest()[:12] recvRule = of.ofp_flow_mod() recvRule.command = of.OFPFC_MODIFY_STRICT #recvRule.match.dl_type = 0x0880 # Causes conflicts with user-space switches recvRule.match.dl_dst = title_hash_aggr[:6] recvRule.match.dl_src = title_hash_aggr[6:] recvRule.match.dl_vlan = self.flow recvRule.actions.append( of.ofp_action_dl_addr.set_dst(title_hash[:6])) recvRule.actions.append( of.ofp_action_dl_addr.set_src(title_hash[6:])) recvRule.actions.append( of.ofp_action_enqueue(port=event.port, queue_id=1)) core.openflow.sendToDPID(event.dpid, recvRule) try: s = w.switches[event.dpid] except KeyError: s = w.WPSwitch(event.dpid) w.switches[s.dpid] = s if event.dpid == w2.path[-1]: s.used_ports.add( graph[w2.path[-1]][w2.path[w2.path.index(w2.path[-1]) - 1]]['ports'][w2.path[-1]]) else: s.used_ports.add( graph[w2.path[0]][w2.path[w2.path.index(w2.path[0]) + 1]]['ports'][w2.path[0]]) sendRule = of.ofp_flow_mod() sendRule.command = of.OFPFC_MODIFY_STRICT #sendRule.match.dl_type = 0x0880 # Causes conflicts with user-space switches sendRule.match.dl_dst = title_hash[:6] sendRule.match.dl_src = title_hash[6:] sendRule.actions.append( of.ofp_action_dl_addr.set_dst(title_hash_aggr[:6])) sendRule.actions.append( of.ofp_action_dl_addr.set_src(title_hash_aggr[6:])) sendRule.actions.append(of.ofp_action_vlan_vid(vlan_vid=self.flow)) for p in s.used_ports: sendRule.actions.append( of.ofp_action_enqueue(port=p, queue_id=1)) core.openflow.sendToDPID(event.dpid, sendRule) # Send FLOW_MOD to the switch that created the workspace switch1 = wks[w.title] print 'OZUUUUUU1', switch1.dpid, switch1.port, try: s = w.switches[switch1.dpid] except KeyError: s = w.WPSwitch(switch1.dpid) w.switches[s.dpid] = s if switch1.dpid == w2.path[0]: s.used_ports.add( graph[w2.path[0]][w2.path[w2.path.index(w2.path[0]) + 1]]['ports'][w2.path[0]]) else: s.used_ports.add( graph[w2.path[-1]][w2.path[w2.path.index(w2.path[-1]) - 1]]['ports'][w2.path[-1]]) sendRule = of.ofp_flow_mod() sendRule.command = of.OFPFC_MODIFY_STRICT #sendRule.match.dl_type = 0x0880 # Causes conflicts with user-space switches sendRule.match.dl_dst = title_hash[:6] sendRule.match.dl_src = title_hash[6:] sendRule.actions.append( of.ofp_action_dl_addr.set_dst(title_hash_aggr[:6])) sendRule.actions.append( of.ofp_action_dl_addr.set_src(title_hash_aggr[6:])) sendRule.actions.append(of.ofp_action_vlan_vid(vlan_vid=self.flow)) for p in s.used_ports: sendRule.actions.append( of.ofp_action_enqueue(port=p, queue_id=1)) core.openflow.sendToDPID(switch1.dpid, sendRule) recvRule = of.ofp_flow_mod() recvRule.command = of.OFPFC_MODIFY_STRICT #recvRule.match.dl_type = 0x0880 # Causes conflicts with user-space switches recvRule.match.dl_dst = title_hash_aggr[:6] recvRule.match.dl_src = title_hash_aggr[6:] recvRule.match.dl_vlan = self.flow recvRule.actions.append( of.ofp_action_dl_addr.set_dst(title_hash[:6])) recvRule.actions.append( of.ofp_action_dl_addr.set_src(title_hash[6:])) recvRule.actions.append( of.ofp_action_enqueue(port=event.port, queue_id=1)) core.openflow.sendToDPID(switch1.dpid, recvRule) resp_msg = resp_msg.SerializeToString() # Send response back to the entity resp = of.ofp_packet_out() if not self.wifi: # not wifi resp.data = ''.join( (DTSA.HEADER, struct.pack("<H", len(resp_msg)), resp_msg)) else: resp.data = ''.join( (self.addrResp, struct.pack("<H", len(resp_msg)), resp_msg)) resp.actions.append(of.ofp_action_output(port=event.port)) event.connection.send(resp)
def install_flow(self, pred, action_list): switch = pred['switch'] ### BUILD OF MATCH inport = pred['inport'] match = of.ofp_match() match.in_port = pred['inport'] match.dl_src = pred['srcmac'] match.dl_dst = pred['dstmac'] match.dl_type = pred['ethtype'] if 'vlan_id' in pred: match.dl_vlan = pred['vlan_id'] else: match.dl_vlan = 0xffff if 'vlan_pcp' in pred: match.dl_vlan_pcp = pred['vlan_pcp'] else: match.dl_vlan_pcp = 0 match.nw_proto = pred['protocol'] if 'srcip' in pred: match.nw_src = pred['srcip'] if 'dstip' in pred: match.nw_dst = pred['dstip'] if 'tos' in pred: match.nw_tos = pred['tos'] if 'srcport' in pred: match.tp_src = pred['srcport'] if 'dstport' in pred: match.tp_dst = pred['dstport'] ### BUILD OF ACTIONS of_actions = [] for actions in action_list: outport = actions['outport'] del actions['outport'] if 'srcmac' in actions: of_actions.append( of.ofp_action_dl_addr.set_src(actions['srcmac'])) if 'dstmac' in actions: of_actions.append( of.ofp_action_dl_addr.set_dst(actions['dstmac'])) if 'srcip' in actions: of_actions.append( of.ofp_action_nw_addr.set_src(actions['srcip'])) if 'dstip' in actions: of_actions.append( of.ofp_action_nw_addr.set_dst(actions['dstip'])) if 'vlan_id' in actions: if actions['vlan_id'] is None: of_actions.append(of.ofp_action_strip_vlan()) else: of_actions.append( of.ofp_action_vlan_vid(vlan_vid=actions['vlan_id'])) if 'vlan_pcp' in actions: if actions['vlan_pcp'] is None: if not actions['vlan_id'] is None: raise RuntimeError( "vlan_id and vlan_pcp must be set together!") pass else: of_actions.append( of.ofp_action_vlan_pcp(vlan_pcp=actions['vlan_pcp'])) if outport == inport: of_actions.append(of.ofp_action_output(port=of.OFPP_IN_PORT)) else: of_actions.append(of.ofp_action_output(port=outport)) msg = of.ofp_flow_mod(command=of.OFPFC_ADD, idle_timeout=of.OFP_FLOW_PERMANENT, hard_timeout=of.OFP_FLOW_PERMANENT, match=match, actions=of_actions) try: self.switches[switch]['connection'].send(msg) except RuntimeError, e: print "ERROR:install_flow: %s to switch %d" % (str(e), switch)
def install_flowrule(self, id, match, action): """ Install a flowrule in an OpenFlow switch. :param id: ID of the infra element stored in the NFFG :type id: str :param match: match part of the rule (keys: in_port, vlan_id) :type match: dict :param action: action part of the rule (keys: out, vlan_push, vlan_pop) :type action: dict :return: None """ conn = self.openflow.getConnection(dpid=self.infra_to_dpid[id]) if not conn: log.warning( "Missing connection for node element: %s! Skip flowrule " "installation..." % id) return msg = of.ofp_flow_mod() msg.match.in_port = match['in_port'] if 'vlan_id' in match: try: vlan_id = int(match['vlan_id']) except ValueError: log.warning( "VLAN_ID: %s in match field is not a valid number! " "Skip flowrule installation..." % match['vlan_id']) return msg.match.dl_vlan = vlan_id # Append explicit matching parameters to OF flowrule if 'flowclass' in match: for ovs_match_entry in match['flowclass'].split(','): kv = ovs_match_entry.split('=') # kv = [field, value] ~ ['dl_src', '00:0A:E4:25:6B:B6'] # msg.match.dl_src = "00:00:00:00:00:01" if kv[0] in ('dl_src', 'dl_dst'): setattr(msg.match, kv[0], EthAddr(kv[1])) elif kv[0] in ('in_port', 'dl_vlan', 'dl_type', 'ip_proto', 'nw_proto', 'nw_tos', 'nw_ttl', 'tp_src', 'tp_dst'): setattr(msg.match, kv[0], int(kv[1], 0)) elif kv[0] in ('nw_src', 'nw_dst'): setattr(msg.match, kv[0], IPAddr(kv[1])) else: setattr(msg.match, kv[0], kv[1]) if 'vlan_push' in action: try: vlan_push = int(action['vlan_push']) except ValueError: log.warning( "VLAN_PUSH: %s in action field is not a valid number! " "Skip flowrule installation..." % action['vlan_push']) return msg.actions.append(of.ofp_action_vlan_vid(vlan_vid=vlan_push)) # msg.actions.append(of.ofp_action_vlan_vid()) out = action['out'] # If out is in the detected saps --> always remove the VLAN tags if 'vlan_pop' in action: msg.actions.append(of.ofp_action_strip_vlan()) else: try: # If next node is a SAP we need to setup the MAC addresses and # strip VLAN from the frame explicitly if out in self.saps[id]: msg.actions.append(of.ofp_action_strip_vlan()) except KeyError: pass try: if out in self.saps[id]: dl_dst = self.saps[id][str(out)]['dl_dst'] dl_src = self.saps[id][str(out)]['dl_src'] msg.actions.append( of.ofp_action_dl_addr.set_dst(EthAddr(dl_dst))) msg.actions.append( of.ofp_action_dl_addr.set_src(EthAddr(dl_src))) except KeyError: pass try: out_port = int(action['out']) except ValueError: log.warning( "Output port: %s is not a valid port in flowrule action: %s! " "Skip flowrule installation..." % (action['out'], action)) return msg.actions.append(of.ofp_action_output(port=out_port)) log.debug("Install flow entry into INFRA: %s on connection: %s ..." % (id, conn)) conn.send(msg) log.log(VERBOSE, "Sent raw OpenFlow flowrule:\n%s" % msg)
def configureRules(connection, lruleset): """ Configure initial rules """ #print "Ready for configure init rules in SW: " + dpidToStr(connection.dpid) + " " + str(connection.dpid) of_fib = parse_of_file(lruleset) #print of_fib of_list = [] try: of_list = of_fib[dpidToStr(connection.dpid)] except KeyError: print "Oops! There are no for the Sw " + dpidToStr(connection.dpid) #f = open('/tmp/' + dpidToStr(event.dpid), 'wa') #f.write( dpidToStr(event.dpid) + " begin " + str(time.time())) #of_entry = of_list[0] #print of_entry for of_entry in of_list: msg = of.ofp_flow_mod() #print "writing OpenFlow entry:", of_entry #msg.priority = 42 if "dl_type" in of_entry.keys(): msg.match.dl_type = int(of_entry["dl_type"], 16) if "nw_proto" in of_entry.keys(): msg.match.nw_proto = int(of_entry["nw_proto"], 10) #ETH if "dl_src" in of_entry.keys(): msg.match.dl_src = EthAddr(of_entry["dl_src"]) if "dl_dst" in of_entry.keys(): msg.match.dl_dst = EthAddr(of_entry["dl_dst"]) #IP if "nw_src" in of_entry.keys(): msg.match.nw_src = of_entry["nw_src"] #msg.match.nw_src = IPAddr(of_entry["nw_src"]) if "nw_dst" in of_entry.keys(): msg.match.nw_dst = of_entry["nw_dst"] #msg.match.nw_dst = IPAddr(of_entry["nw_dst"]) if "nw_tos" in of_entry.keys(): msg.match.nw_tos = int(of_entry["nw_tos"], 10) #UDP if "tp_dst" in of_entry.keys(): msg.match.tp_dst = int(of_entry["tp_dst"], 10) if "tp_src" in of_entry.keys(): msg.match.tp_src = int(of_entry["tp_src"], 10) #OTHERS if "in_port" in of_entry.keys(): msg.match.in_port = int(of_entry["in_port"], 10) if "dl_vlan" in of_entry.keys(): msg.match.dl_vlan = int(of_entry["dl_vlan"], 10) if "dl_vlan_pcp" in of_entry.keys(): msg.match.dl_vlan_pcp = int(of_entry["dl_vlan_pcp"], 10) #msg.match.tp_dst = 80 # iterate list of actions #output #vlan if "mod_nw_tos" in of_entry["actions"].keys(): msg.actions.append( of.ofp_action_nw_tos( nw_tos=int(of_entry["actions"]["mod_nw_tos"], 10))) if "mod_vlan_vid" in of_entry["actions"].keys(): msg.actions.append( of.ofp_action_vlan_vid( vlan_vid=int(of_entry["actions"]["mod_vlan_vid"], 10))) if "mod_vlan_pcp" in of_entry["actions"].keys(): msg.actions.append( of.ofp_action_vlan_pcp( vlan_pcp=int(of_entry["actions"]["mod_vlan_pcp"], 10))) if "mod_dl_src" in of_entry["actions"].keys(): msg.actions.append( of.ofp_action_dl_addr.set_src( EthAddr(of_entry["actions"]["mod_dl_src"]))) if "mod_dl_dst" in of_entry["actions"].keys(): msg.actions.append( of.ofp_action_dl_addr.set_dst( EthAddr(of_entry["actions"]["mod_dl_dst"]))) if "output" in of_entry["actions"].keys(): msg.actions.append( of.ofp_action_output( port=int(of_entry["actions"]["output"], 10))) #print "set the output port" connection.send(msg) #f.write(" ending " + str(time.time()) + "\n") #f.close() print "Rules configured, allow traffic for " + dpidToStr(connection.dpid)
def send_table (self): if self.connection is None: self.log.debug("Can't send table: disconnected") return clear = of.ofp_flow_mod(command=of.OFPFC_DELETE) self.connection.send(clear) self.connection.send(of.ofp_barrier_request()) # From DHCPD msg = of.ofp_flow_mod() msg.match = of.ofp_match() msg.match.dl_type = pkt.ethernet.IP_TYPE msg.match.nw_proto = pkt.ipv4.UDP_PROTOCOL #msg.match.nw_dst = IP_BROADCAST msg.match.tp_src = pkt.dhcp.CLIENT_PORT msg.match.tp_dst = pkt.dhcp.SERVER_PORT msg.actions.append(of.ofp_action_output(port = of.OFPP_CONTROLLER)) #msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD)) self.connection.send(msg) core.openflow_discovery.install_flow(self.connection) ''' self.mac_to_vid = { 00.00.00.00.00.00 = 1 } ''' self.edge_ports = [] for port in self.ports: pn = port.port_no if pn < 0 or pn >= of.OFPP_MAX: continue if core.openflow_discovery.is_edge_port(self.dpid, pn): self.edge_ports.append(pn) src = self for dst in switches_by_dpid.itervalues(): if dst is src: continue p = _get_path(src, dst) if p is None: continue msg = of.ofp_flow_mod() msg.priority += 1 msg.match = of.ofp_match() msg.match.dl_type = pkt.ethernet.IP_TYPE #msg.match.nw_dst = "%s/%s" % (dst.network, dst.subnet) msg.match.in_port = pn msg.match.nw_src = "10.%s.%s.0/255.255.255.0" % (self._id,pn) msg.match.nw_dst = "%s/%s" % (dst.network, "255.255.0.0") msg.actions.append(of.ofp_action_vlan_vid(vlan_vid=self.vid_by_port(pn))) msg.actions.append(of.ofp_action_output(port=p[0][1])) self.connection.send(msg) src = self for dst in switches_by_dpid.itervalues(): if dst is src: continue p = _get_path(src, dst) if p is None: continue msg = of.ofp_flow_mod() msg.match = of.ofp_match() msg.match.dl_type = pkt.ethernet.IP_TYPE #msg.match.nw_dst = "%s/%s" % (dst.network, dst.subnet) msg.match.nw_dst = "%s/%s" % (dst.network, "255.255.0.0") msg.actions.append(of.ofp_action_output(port=p[0][1])) self.connection.send(msg) """ # Can just do this instead of MAC learning if you run arp_responder... for port in self.ports: p = port.port_no if p < 0 or p >= of.OFPP_MAX: continue msg = of.ofp_flow_mod() msg.match = of.ofp_match() msg.match.dl_type = pkt.ethernet.IP_TYPE msg.match.nw_dst = "10.%s.%s.0/255.255.255.0" % (self._id,p) msg.actions.append(of.ofp_action_output(port=p)) self.connection.send(msg) """ for ip,mac in self.ip_to_mac.iteritems(): self._send_rewrite_rule(ip, mac) flood_ports = [] for port in self.ports: p = port.port_no if p < 0 or p >= of.OFPP_MAX: continue if core.openflow_discovery.is_edge_port(self.dpid, p): flood_ports.append(p) msg = of.ofp_flow_mod() msg.priority -= 1 msg.match = of.ofp_match() msg.match.dl_type = pkt.ethernet.IP_TYPE msg.match.nw_dst = "10.%s.%s.0/255.255.255.0" % (self._id,p) msg.actions.append(of.ofp_action_output(port=of.OFPP_CONTROLLER)) self.connection.send(msg) msg = of.ofp_flow_mod() msg.priority -= 1 msg.match = of.ofp_match() msg.match.dl_type = pkt.ethernet.IP_TYPE msg.match.nw_dst = "255.255.255.255" for p in flood_ports: msg.actions.append(of.ofp_action_output(port=p)) self.connection.send(msg)
def act_like_switch (self, packet, packet_in): """ Implement switch-like behavior. """ # Here's some psuedocode to start you off implementing a learning # switch. You'll need to rewrite it as real Python code. log.debug("DPID: %s" % self.connection.dpid) # Learn source vlan of the packet if packet.type == ethernet.VLAN_TYPE: src_vlan = packet.find('vlan').id else: src_vlan = self.vlan_to_port[packet_in.in_port] log.debug("Source VLAN: %s" % src_vlan) # Learn the port for the source MAC self.mac_to_port[packet.src] = packet_in.in_port # add or update mac table entry # Ports to send out the packet out_ports = [] #if the port associated with the destination MAC of the packet is known if packet.dst in self.mac_to_port: log.debug("Mac is in table") dst_vlan = self.vlan_to_port[self.mac_to_port[packet.dst]] #if the port is in the same vlan as sending port if src_vlan == dst_vlan or dst_vlan == 1: # Send packet out the associated port out_ports.append(self.mac_to_port[packet.dst]) self.resend_packet(packet_in, out_ports) log.debug("Installing flow. Source port: %s. Destination port: %s.", packet_in.in_port, self.mac_to_port[packet.dst]) # Install the flow table entry msg = of.ofp_flow_mod() ## Set fields to match received packet msg.match = of.ofp_match(dl_dst = packet.dst) #< Set other fields of flow_mod (timeouts? buffer_id?) > msg.idle_timeout = 60 # Add action to add vlan tag or strip it if dst_vlan == 1: action = of.ofp_action_vlan_vid(vlan_vid = src_vlan) else: action = of.ofp_action_strip_vlan() msg.actions.append(action) # Add action to resend packet out of the specified port msg.actions.append(of.ofp_action_output(port = self.mac_to_port[packet.dst])) self.connection.send(msg) else: # Sending to all ports in same vlan as the input port or dot1q port, ignore port connected to controller log.debug("Adress is not in table, flooding: ") for port in self.connection.ports: if port != packet_in.in_port and (self.vlan_to_port[port] == src_vlan or self.vlan_to_port[port] == 1): out_ports.append(port) log.debug(out_ports) if len(out_ports) > 0: self.resend_packet(packet_in, out_ports)
def install_flow(self,pred,action_list): switch = pred['switch'] ### BUILD OF MATCH inport = pred['inport'] match = of.ofp_match() match.in_port = pred['inport'] match.dl_src = pred['srcmac'] match.dl_dst = pred['dstmac'] match.dl_type = pred['ethtype'] if 'vlan_id' in pred: match.dl_vlan = pred['vlan_id'] else: match.dl_vlan = 0xffff if 'vlan_pcp' in pred: match.dl_vlan_pcp = pred['vlan_pcp'] else: match.dl_vlan_pcp = 0 match.nw_proto = pred['protocol'] if 'srcip' in pred: match.nw_src = pred['srcip'] if 'dstip' in pred: match.nw_dst = pred['dstip'] if 'tos' in pred: match.nw_tos = pred['tos'] if 'srcport' in pred: match.tp_src = pred['srcport'] if 'dstport' in pred: match.tp_dst = pred['dstport'] ### BUILD OF ACTIONS of_actions = [] for actions in action_list: outport = actions['outport'] del actions['outport'] if 'srcmac' in actions: of_actions.append(of.ofp_action_dl_addr.set_src(actions['srcmac'])) if 'dstmac' in actions: of_actions.append(of.ofp_action_dl_addr.set_dst(actions['dstmac'])) if 'srcip' in actions: of_actions.append(of.ofp_action_nw_addr.set_src(actions['srcip'])) if 'dstip' in actions: of_actions.append(of.ofp_action_nw_addr.set_dst(actions['dstip'])) if 'vlan_id' in actions: if actions['vlan_id'] is None: of_actions.append(of.ofp_action_strip_vlan()) else: of_actions.append(of.ofp_action_vlan_vid(vlan_vid=actions['vlan_id'])) if 'vlan_pcp' in actions: if actions['vlan_pcp'] is None: if not actions['vlan_id'] is None: raise RuntimeError("vlan_id and vlan_pcp must be set together!") pass else: of_actions.append(of.ofp_action_vlan_pcp(vlan_pcp=actions['vlan_pcp'])) if outport == inport: of_actions.append(of.ofp_action_output(port=of.OFPP_IN_PORT)) else: of_actions.append(of.ofp_action_output(port=outport)) msg = of.ofp_flow_mod(command=of.OFPFC_ADD, idle_timeout=of.OFP_FLOW_PERMANENT, hard_timeout=of.OFP_FLOW_PERMANENT, match=match, actions=of_actions) try: self.switches[switch]['connection'].send(msg) except RuntimeError, e: print "ERROR:install_flow: %s to switch %d" % (str(e),switch)
def reply_request(self, success, request_id, event, title_aggr=None, w = None): # Build the response resp_msg = dts_pb2.ControlResponse() resp_msg.status = resp_msg.SUCCESS if success else resp_msg.FAILURE if request_id != None: resp_msg.request_id = request_id if self.aggr and w: # reply for the second workspace attachment print 'title_aggr', title_aggr, 'flow', self.flow # Send FLOW_MOD to the swith that is ataching an entity title = w.title if title_aggr in workspaces_aggr: w2 = workspaces_aggr[title_aggr] else: log.info('Unknown aggregated workspace title') title_hash = hashlib.sha256(title).digest()[:12] title_hash_aggr = hashlib.sha256(title_aggr).digest()[:12] recvRule = of.ofp_flow_mod() recvRule.command = of.OFPFC_MODIFY_STRICT #recvRule.match.dl_type = 0x0880 # Causes conflicts with user-space switches recvRule.match.dl_dst = title_hash_aggr[:6] recvRule.match.dl_src = title_hash_aggr[6:] recvRule.match.dl_vlan = self.flow recvRule.actions.append(of.ofp_action_dl_addr.set_dst(title_hash[:6])) recvRule.actions.append(of.ofp_action_dl_addr.set_src(title_hash[6:])) recvRule.actions.append(of.ofp_action_enqueue(port=event.port, queue_id=1)) core.openflow.sendToDPID(event.dpid, recvRule) try: s = w.switches[event.dpid] except KeyError: s = w.WPSwitch(event.dpid) w.switches[s.dpid] = s if event.dpid == w2.path[-1]: s.used_ports.add(graph[w2.path[-1]][w2.path[w2.path.index(w2.path[-1])-1]]['ports'][w2.path[-1]]) else: s.used_ports.add(graph[w2.path[0]][w2.path[w2.path.index(w2.path[0])+1]]['ports'][w2.path[0]]) sendRule = of.ofp_flow_mod() sendRule.command = of.OFPFC_MODIFY_STRICT #sendRule.match.dl_type = 0x0880 # Causes conflicts with user-space switches sendRule.match.dl_dst = title_hash[:6] sendRule.match.dl_src = title_hash[6:] sendRule.actions.append(of.ofp_action_dl_addr.set_dst(title_hash_aggr[:6])) sendRule.actions.append(of.ofp_action_dl_addr.set_src(title_hash_aggr[6:])) sendRule.actions.append(of.ofp_action_vlan_vid(vlan_vid=self.flow)) for p in s.used_ports: sendRule.actions.append(of.ofp_action_enqueue(port=p, queue_id=1)) core.openflow.sendToDPID(event.dpid, sendRule) # Send FLOW_MOD to the switch that created the workspace switch1 = wks[w.title] print 'OZUUUUUU1', switch1.dpid, switch1.port, try: s = w.switches[switch1.dpid] except KeyError: s = w.WPSwitch(switch1.dpid) w.switches[s.dpid] = s if switch1.dpid == w2.path[0]: s.used_ports.add(graph[w2.path[0]][w2.path[w2.path.index(w2.path[0])+1]]['ports'][w2.path[0]]) else: s.used_ports.add(graph[w2.path[-1]][w2.path[w2.path.index(w2.path[-1])-1]]['ports'][w2.path[-1]]) sendRule = of.ofp_flow_mod() sendRule.command = of.OFPFC_MODIFY_STRICT #sendRule.match.dl_type = 0x0880 # Causes conflicts with user-space switches sendRule.match.dl_dst = title_hash[:6] sendRule.match.dl_src = title_hash[6:] sendRule.actions.append(of.ofp_action_dl_addr.set_dst(title_hash_aggr[:6])) sendRule.actions.append(of.ofp_action_dl_addr.set_src(title_hash_aggr[6:])) sendRule.actions.append(of.ofp_action_vlan_vid(vlan_vid=self.flow)) for p in s.used_ports: sendRule.actions.append(of.ofp_action_enqueue(port=p, queue_id=1)) core.openflow.sendToDPID(switch1.dpid, sendRule) recvRule = of.ofp_flow_mod() recvRule.command = of.OFPFC_MODIFY_STRICT #recvRule.match.dl_type = 0x0880 # Causes conflicts with user-space switches recvRule.match.dl_dst = title_hash_aggr[:6] recvRule.match.dl_src = title_hash_aggr[6:] recvRule.match.dl_vlan = self.flow recvRule.actions.append(of.ofp_action_dl_addr.set_dst(title_hash[:6])) recvRule.actions.append(of.ofp_action_dl_addr.set_src(title_hash[6:])) recvRule.actions.append(of.ofp_action_enqueue(port=event.port, queue_id=1)) core.openflow.sendToDPID(switch1.dpid, recvRule) resp_msg = resp_msg.SerializeToString() # Send response back to the entity resp = of.ofp_packet_out() if not self.wifi: # not wifi resp.data = ''.join((DTSA.HEADER, struct.pack("<H", len(resp_msg)), resp_msg)) else: resp.data = ''.join((self.addrResp, struct.pack("<H", len(resp_msg)), resp_msg)) resp.actions.append(of.ofp_action_output(port = event.port)) event.connection.send(resp)
def sPortal(connection): for network, vlan in networks.iteritems(): # permit DNS to flow from clients to router msg = of.ofp_flow_mod() msg.priority = 20 msg.match.in_port = client_port_match msg.match.dl_vlan = vlan['untrusted'] msg.match.dl_type = 0x0800 msg.match.nw_proto = 17 msg.match.tp_dst = 53 msg.actions.append(of.ofp_action_vlan_vid(vlan_vid=vlan['trusted'])) msg.actions.append(of.ofp_action_output(port=router_port_action)) connection.send(msg) # permit DHCP to flow from clients to router msg = of.ofp_flow_mod() msg.priority = 20 msg.match.in_port = client_port_match msg.match.dl_vlan = vlan['untrusted'] msg.match.dl_type = 0x0800 msg.match.nw_proto = 17 msg.match.tp_src = 68 msg.match.tp_dst = 67 msg.actions.append(of.ofp_action_vlan_vid(vlan_vid=vlan['trusted'])) msg.actions.append(of.ofp_action_output(port=router_port_action)) connection.send(msg) # permit ARP to flow from clients to router (if supported) # otherwise, pre-authenticated clients will ARP to captive portal # which should be running proxy-arp so there should still be no problem if dp_supports_arp_match: msg = of.ofp_flow_mod() msg.priority = 20 msg.match.in_port = client_port_match msg.match.dl_vlan = vlan['untrusted'] msg.match.dl_type = pkt.ethernet.ARP_TYPE msg.actions.append( of.ofp_action_vlan_vid(vlan_vid=vlan['trusted'])) msg.actions.append(of.ofp_action_output(port=router_port_action)) connection.send(msg) # send traffic from the client to the portal msg = of.ofp_flow_mod() msg.priority = 10 msg.match.in_port = client_port_match msg.match.dl_vlan = vlan['untrusted'] msg.actions.append(of.ofp_action_dl_addr.set_dst(portal)) msg.actions.append(of.ofp_action_vlan_vid(vlan_vid=vlan['portal'])) msg.actions.append(of.ofp_action_output(port=portal_port_action)) connection.send(msg) # send IP traffic from the portal back to the client msg = of.ofp_flow_mod() msg.priority = 10 msg.match.in_port = portal_port_match msg.match.dl_vlan = vlan['portal'] msg.match.dl_src = portal # note - commented out because the switch under test can't match IP networks yet # note - this means for now that the "networks" array can only contain one network # note - we would have to also match ARP which is also not supported via the device under test #msg.match.dl_type = pkt.ethernet.IP_TYPE #msg.match.nw_dst = network msg.actions.append(of.ofp_action_vlan_vid(vlan_vid=vlan['untrusted'])) msg.actions.append(of.ofp_action_output(port=client_port_action)) connection.send(msg) # send IP traffic from the router back to the client msg = of.ofp_flow_mod() msg.priority = 10 msg.match.in_port = router_port_match msg.match.dl_vlan = vlan['trusted'] msg.match.dl_src = router # note - commented out because the switch under test can't match IP networks yet # note - this means for now that teh "networks" array can only contain one network # note - we would have to also match ARP which is also not supported via the device under test #msg.match.dl_type = pkt.ethernet.IP_TYPE #msg.match.nw_dst = network msg.actions.append(of.ofp_action_vlan_vid(vlan_vid=vlan['untrusted'])) msg.actions.append(of.ofp_action_output(port=client_port_action)) connection.send(msg)
from pox.core import core from pox.lib.addresses import IPAddr from pox.lib.addresses import EthAddr import pox.openflow.libopenflow_01 as of log = core.getLogger() #1: switch0 = 0000000000000005 flow0msg = of.ofp_flow_mod() flow0msg.cookie = 0 flow0msg.priority = 32768 flow0msg.match.in_port = 1 flow0msg.match.nw_proto = 6 # ACTIONS--------------------------------- flow0vlan_id = of.ofp_action_vlan_vid (vlan_vid = 10) flow0out = of.ofp_action_output (port = 3) flow0msg.actions = [flow0vlan_id, flow0out] #2: switch1 = 0000000000000005 flow1msg = of.ofp_flow_mod() flow1msg.cookie = 0 flow1msg.priority = 32768 flow1msg.match.in_port = 2 flow1msg.match.nw_proto = 6 # ACTIONS--------------------------------- flow1vlan_id = of.ofp_action_vlan_vid (vlan_vid = 20) flow1out = of.ofp_action_output (port = 3) flow1msg.actions = [flow1vlan_id, flow1out]
def __handle_PacketIn(self, event): packet = event.parsed src = packet.src.toStr() dst = packet.dst.toStr() if self.lat_test: if packet.type != 0x5566: # not test packet, drop it return src = self._MAC_to_int(src) dst = self._MAC_to_int(dst) timeinit, = struct.unpack('!I', packet.find('ethernet').payload) timediff = time.time()*1000 - self.system_time - timeinit if src in self.adj_test: if dst in self.adj_test[src]: self.adj[src][dst] = timediff del self.adj_test[src][dst] if dst in self.sw_test: self.sw_lat[dst] = timediff self.sw_test.remove(dst) return pid = 0 if src in self.hosts: for d in self.sd_path_table[src]: # FIXME: Pick one as default # Maybe we should apply flood function to broadcasting for sd_path_id in self.sd_path_table[src][d]: pid = sd_path_id # log.warning("Packet Vid = %i", pid) if dst in self.hosts: if self.config.config_set: id_list = self.sd_path_table[src][dst] # last one, in case not found pid = len(id_list) - 1 sum_of_all = 0 for x in id_list: sum_of_all += self.config.now_config[x-1] rand_num = sum_of_all * random.random() for x in id_list: rand_num -= self.config.now_config[x-1] # Since the path ID starts from 1, which is different from the index if rand_num < 0: # path_id should start from 1 pid = x break log.warning("SD pair %i, pid %i", self.sd_pair[src][dst], pid) else: # FIXME: path selection for sd_path_id in self.sd_path_table[src][dst]: # There exists a path pid = sd_path_id # log.warning("Packet Vid = %i", pid) msg = of.ofp_packet_out( data = event.ofp ) if pid != 0: # There exists a path path = self.path_id_table[pid] if len(path) > 3: # It is not the last sw, tag it and send into the network if USE_VLAN_TAG: msg.actions.append( of.ofp_action_vlan_vid( vlan_vid = pid ) ) if USE_ETHERNET_SRC_TAG: msg.actions.append( of.ofp_action_dl_addr.set_src( EthAddr( self._int_to_MAC( pid ) ) ) ) msg.actions.append( of.ofp_action_output( port = self.ports[path[1]][path[2]] ) ) elif len(path) == 3: # last sw, forward to the host # msg.actions.append( of.ofp_action_output( port = of.OFPP_FLOOD ) ) msg.actions.append( of.ofp_action_output( port = self.hadj[path[2]][path[1]] ) ) event.connection.send(msg)
def _handle_PacketIn (self, event): """ Handles packet in messages from the switch to implement above algorithm. """ packet = event.parse() def flood (): """ Floods the packet """ if event.ofp.buffer_id == -1: log.warning("Not flooding unbuffered packet on %s", dpidToStr(event.dpid)) return msg = of.ofp_packet_out() if time.time() - self.connection.connect_time > FLOOD_DELAY: # Only flood if we've been connected for a little while... #log.debug("%i: flood %s -> %s", event.dpid, packet.src, packet.dst) msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD)) else: pass #log.info("Holding down flood for %s", dpidToStr(event.dpid)) msg.buffer_id = event.ofp.buffer_id msg.in_port = event.port self.connection.send(msg) def drop (duration = None): """ Drops this packet and optionally installs a flow to continue dropping similar ones for a while """ if duration is not None: if not isinstance(duration, tuple): duration = (duration,duration) msg = of.ofp_flow_mod() msg.match = of.ofp_match.from_packet(packet) msg.idle_timeout = duration[0] msg.hard_timeout = duration[1] msg.buffer_id = event.ofp.buffer_id self.connection.send(msg) elif event.ofp.buffer_id != -1: msg = of.ofp_packet_out() msg.buffer_id = event.ofp.buffer_id msg.in_port = event.port self.connection.send(msg) self.macToPort[packet.src] = event.port # 1 if not self.transparent: if packet.type == packet.LLDP_TYPE or packet.dst.isBridgeFiltered(): # 2 drop() return if packet.dst.isMulticast(): flood() # 3a else: if packet.dst not in self.macToPort: # 4 log.debug("Port for %s unknown -- flooding" % (packet.dst,)) flood() # 4a else: port = self.macToPort[packet.dst] if port == event.port: # 5 # 5a log.warning("Same port for packet from %s -> %s on %s. Drop." % (packet.src, packet.dst, port), dpidToStr(event.dpid)) drop(10) return # 6 log.debug("installing flow for %s.%i -> %s.%i" % (packet.src, event.port, packet.dst, port)) log.debug("\nDPG: test code to include rule to install VLAN tag\n") # DPG CODE IS IN THIS AREA ************************************************************************************************************ msg = of.ofp_flow_mod() msg.match = of.ofp_match.from_packet(packet) msg.idle_timeout = 100000 msg.hard_timeout = 300000 msg.actions.append(of.ofp_action_output(port = port)) vlan_vid = self._get_next_vlad_id() msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = vlan_vid)) #msg.actions.append(of.ofp_action_vlan_vid()) #msg.actions.append(of.ofp_action_vlan_vid(self._get_next_vlad_id())) msg.buffer_id = event.ofp.buffer_id # 6a self.connection.send(msg) log.debug("\n ---------------------------------------------------") log.debug("DPG: here is the flow") log.debug(msg) log.debug(" --------------------------------------------------- \n")
def _match_action(self, msg): if len(self.actions) == 1 and self.actions[0] == "": return for action in self.actions: action_name = action.split('=')[0] if action_name != "STRIP_VLAN": action_argu = action.split('=')[1] if (action_name == "OUTPUT"): msg.actions.append(of.ofp_action_output(port=int(action_argu))) elif (action_name == "ENQUEUE"): port = action_argu.split(':')[0] queue_id = action_argu.split(':')[1] msg.actions.append( of.ofp_action_enqueue(port=int(port), queue_id=int(queue_id))) elif (action_name == "STRIP_VLAN"): msg.actions.append(of.ofp_action_strip_vlan()) elif (action_name == "SET_VLAN_VID"): msg.actions.append( of.ofp_action_vlan_vid(vlan_vid=int(action_argu))) elif (action_name == "SET_VLAN_PCP"): msg.actions.append( of.ofp_action_vlan_pcp(vlan_pcp=int(action_argu))) elif (action_name == "SET_DL_SRC"): msg.actions.append( of.ofp_action_dl_addr(type=4, dl_addr=EthAddr(action_argu))) elif (action_name == "SET_DL_DST"): msg.actions.append( of.ofp_action_dl_addr(type=5, dl_addr=EthAddr(action_argu))) elif (action_name == "SET_NW_TOS"): msg.actions.append( of.ofp_action_nw_tos(nw_tos=int(action_argu))) elif (action_name == "SET_NW_SRC"): msg.actions.append( of.ofp_action_nw_addr(type=6, nw_addr=IPAddr(action_argu))) elif (action_name == "SET_NW_DST"): msg.actions.append( of.ofp_action_nw_addr(type=7, nw_addr=IPAddr(action_argu))) elif (action_name == "SET_TP_SRC"): msg.actions.append( of.ofp_action_tp_port(type=9, tp_port=int(action_argu))) elif (action_name == "SET_TP_DST"): msg.actions.append( of.ofp_action_tp_port(type=10, tp_port=int(action_argu)))
def _handle_PacketIn(self, event): packet = event.parsed def getVlan(port, id_): res = None if (id_ != None): res = id_ else: tabla = importData() for i in tabla: for j in i.get('ports'): if (j.get('port') == port): res = i.get('vlan') return res def tagType(portname, vlanname): tabla = importData() for i in tabla: if i.get('vlan') == str(vlanname): for j in i.get('ports'): if (j.get('port') == str(portname)): ttype = j.get('type') return ttype def flood(message=None): srcPort = str(event.port) if (packet.find('vlan') is not None): vlanId = getVlan(srcPort, packet.find('vlan').id) else: vlanId = getVlan(srcPort, None) put = True for i in self.macToPort: if ((i.get('mac') == packet.src) and (i.get('port') == int(srcPort)) and (i.get('vlan') == vlanId)): put = False if (put): self.macToPort.append({ 'mac': packet.src, 'port': int(srcPort), 'vlan': vlanId }) taggedPorts = [] untaggedPorts = [] tabla = importData() for i in tabla: if i.get('vlan') == str(vlanId): for j in i.get('ports'): if (j.get('port') != srcPort and j.get('type') == "tagged"): taggedPorts.append(j.get('port')) if (j.get('port') != srcPort and j.get('type') == "untagged"): untaggedPorts.append(j.get('port')) tag = tagType(srcPort, vlanId) msg = of.ofp_flow_mod() msg.match.in_port = int(srcPort) # Tagged if tag == "tagged": # print ("FLOOD from T-port {0}").format(srcPort) # T a T for i in taggedPorts: msg.actions.append(of.ofp_action_output(port=int(i))) # T a U if untaggedPorts != []: msg.actions.append(of.ofp_action_strip_vlan()) for i in untaggedPorts: msg.actions.append(of.ofp_action_output(port=int(i))) # Untagged if tag == "untagged": # print ("FLOOD from U-port {0}").format(srcPort) # U a U for i in untaggedPorts: msg.actions.append(of.ofp_action_output(port=int(i))) # U a T if taggedPorts != []: msg.actions.append( of.ofp_action_vlan_vid(vlan_vid=int(vlanId))) for i in taggedPorts: msg.actions.append(of.ofp_action_output(port=int(i))) self.connection.send(msg) return def drop(duration=None): """ Drops this packet and optionally installs a flow to continue dropping similar ones for a while """ if duration is not None: if not isinstance(duration, tuple): duration = (duration, duration) msg = of.ofp_flow_mod() msg.match = of.ofp_match.from_packet(packet) msg.idle_timeout = duration[0] msg.hard_timeout = duration[1] msg.buffer_id = event.ofp.buffer_id self.connection.send(msg) elif event.ofp.buffer_id is not None: msg = of.ofp_packet_out() msg.buffer_id = event.ofp.buffer_id msg.in_port = event.port self.connection.send(msg) if not self.transparent: # 2 if packet.type == packet.LLDP_TYPE or packet.dst.isBridgeFiltered( ): drop() # 2a return if packet.dst.is_multicast: flood() # 3a else: vlan = None if (packet.find('vlan') is not None): vlan = packet.find('vlan').id else: vlan = None found = False if vlan != None: for i in self.macToPort: if (i.get('mac') == packet.dst and i.get('vlan') == vlan): port = int(i.get('port')) found = True if vlan == None: tabla = importData() for j in tabla: for k in j.get('ports'): if (str(event.port) == str(k.get('port')) and k.get('type') == "untagged"): # port = k.get('port') vlan = j.get('vlan') if (vlan != None): for i in self.macToPort: if (str(i.get('mac')) == str(packet.dst) and str(i.get('vlan')) == str(vlan)): port = i.get('port') found = True if not found: # 4 flood("Port for %s unknown -- flooding" % (packet.dst, )) # 4a else: vlanId = vlan put = True for i in self.macToPort: if ((i.get('mac') == packet.src) and (i.get('port') == int(event.port)) and (i.get('vlan') == vlanId)): put = False if (put): self.macToPort.append({ 'mac': packet.src, 'port': int(event.port), 'vlan': vlanId }) if port == event.port: # 5 log.warning( "Same port for packet from %s -> %s on %s.%s. Drop." % (packet.src, packet.dst, dpid_to_str( event.dpid), port)) drop(10) return tag1 = tagType(str(event.port), str(vlanId)) tag2 = tagType(str(port), str(vlanId)) msg = of.ofp_flow_mod() msg.match = of.ofp_match.from_packet(packet, event.port) msg.idle_timeout = 10 msg.hard_timeout = 30 msg.data = event.ofp # 6a # Tagged if tag1 == "tagged": if tag2 == "tagged": msg.actions.append( of.ofp_action_output(port=int(port))) if tag2 == "untagged": msg.actions.append(of.ofp_action_strip_vlan()) msg.actions.append( of.ofp_action_output(port=int(port))) # Untagged if tag1 == "untagged": if tag2 == "untagged": msg.actions.append( of.ofp_action_output(port=int(port))) if tag2 == "tagged": msg.actions.append( of.ofp_action_vlan_vid(vlan_vid=int(vlanId))) msg.actions.append( of.ofp_action_output(port=int(port))) self.connection.send(msg) return
def _modify_flow(self,command_type): msg = of.ofp_flow_mod() print self.payload if command_type == "MOD_ST": msg.command = of.OFPFC_MODIFY_STRICT elif command_type == "MOD": msg.command = of.OFPFC_MODIFY if self.payload.has_key("wildcards"): msg.match.wildcards = int(self.payload['wildcards']) if self.payload.has_key("dstIP"): msg.match.nw_dst = IPAddr(self.payload['dstIP']) if self.payload.has_key("srcMac"): msg.match.dl_src = EthAddr(self.payload['srcMac']) if self.payload.has_key("srcIP"): msg.match.nw_src = IPAddr(self.payload['srcIP']) if self.payload.has_key("dstMac"): msg.match.dl_dst = EthAddr(self.payload['dstMac']) if self.payload.has_key("hardTimeout"): msg.hard_timeout = int(self.payload['hardTimeout']) if self.payload.has_key("srcPort"): msg.match.tp_src = int(self.payload['srcPort']) if self.payload.has_key("priority"): msg.priority = int(self.payload['priority']) if self.payload.has_key("ingressPort"): msg.match.in_port = int(self.payload['ingressPort']) if self.payload.has_key("vlan"): msg.match.dl_vlan = int(self.payload['vlan']) if self.payload.has_key("ether-type"): msg.match.dl_type = int(self.payload['ether-type']) if self.payload.has_key("duration"): msg.duration_sec = int(self.payload['duration']) if self.payload.has_key("idleTimeout"): msg.idle_timeout = int(self.payload['idleTimeout']) if self.payload.has_key("netProtocol"): msg.match.nw_proto = int(self.payload['netProtocol']) self.dpid = self.payload['switch'].replace(':','-')[6:] self._parse_actions(self.payload['actions']) for connection in core.openflow._connections.values() : # print dpidToStr(connection.dpid) conn_dpid = str(dpidToStr(connection.dpid)) print conn_dpid if conn_dpid == self.dpid: """match actions""" if(self.actions == "OUTPUT"): msg.actions.append(of.ofp_action_output(port = int(self.actions_argu))) elif(self.actions == "enqueue"): port = self.actions_argu.split(':')[0] queue_id = self.actions_argu.split(':')[1] msg.actions.append(of.ofp_action_enqueue(port = int(port) , queue_id = int(queue_id))) elif(self.actions == "strip-vlan"): msg.actions.append(of.ofp_action_strip_vlan()) elif(self.actions == "set-vlan-id"): msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = int(self.actions_argu))) elif(self.actions == "set-vlan-priority"): msg.actions.append(of.ofp_action_vlan_pcp(vlan_pcp = int(self.actions_argu))) elif(self.actions == "SET_DL_SRC"): msg.actions.append(of.ofp_action_dl_addr(type = 4 , dl_addr = EthAddr(self.actions_argu))) elif(self.actions == "SET_DL_DST"): msg.actions.append(of.ofp_action_dl_addr(type = 5 , dl_addr = EthAddr(self.actions_argu))) elif(self.actions == "SET_NW_TOS"): msg.actions.append(of.ofp_action_nw_tos(nw_tos = int(self.actions_argu))) elif(self.actions == "SET_NW_SRC"): msg.actions.append(of.ofp_action_nw_addr(type = 6 , nw_addr = IPAddr(self.actions_argu))) elif(self.actions == "SET_NW_DST"): msg.actions.append(of.ofp_action_nw_addr(type = 7 , nw_addr = IPAddr(self.actions_argu))) elif(self.actions == "SET_TP_SRC"): msg.actions.append(of.ofp_action_tp_port(type = 9 , tp_port = int(self.actions_argu))) elif(self.actions == "SET_TP_DST"): msg.actions.append(of.ofp_action_tp_port(type = 10 , tp_port = int(self.actions_argu))) connection.send(msg)
def _modify_flow(self, command_type): msg = of.ofp_flow_mod() print self.payload if command_type == "MOD_ST": msg.command = of.OFPFC_MODIFY_STRICT elif command_type == "MOD": msg.command = of.OFPFC_MODIFY if self.payload.has_key("wildcards"): msg.match.wildcards = int(self.payload['wildcards']) if self.payload.has_key("dstIP"): msg.match.nw_dst = IPAddr(self.payload['dstIP']) if self.payload.has_key("srcMac"): msg.match.dl_src = EthAddr(self.payload['srcMac']) if self.payload.has_key("srcIP"): msg.match.nw_src = IPAddr(self.payload['srcIP']) if self.payload.has_key("dstMac"): msg.match.dl_dst = EthAddr(self.payload['dstMac']) if self.payload.has_key("hardTimeout"): msg.hard_timeout = int(self.payload['hardTimeout']) if self.payload.has_key("srcPort"): msg.match.tp_src = int(self.payload['srcPort']) if self.payload.has_key("priority"): msg.priority = int(self.payload['priority']) if self.payload.has_key("ingressPort"): msg.match.in_port = int(self.payload['ingressPort']) if self.payload.has_key("vlan"): msg.match.dl_vlan = int(self.payload['vlan']) if self.payload.has_key("ether-type"): msg.match.dl_type = int(self.payload['ether-type']) if self.payload.has_key("duration"): msg.duration_sec = int(self.payload['duration']) if self.payload.has_key("idleTimeout"): msg.idle_timeout = int(self.payload['idleTimeout']) if self.payload.has_key("netProtocol"): msg.match.nw_proto = int(self.payload['netProtocol']) self.dpid = self.payload['switch'].replace(':', '-')[6:] self._parse_actions(self.payload['actions']) for connection in core.openflow._connections.values(): # print dpidToStr(connection.dpid) conn_dpid = str(dpidToStr(connection.dpid)) print conn_dpid if conn_dpid == self.dpid: """match actions""" if (self.actions == "OUTPUT"): msg.actions.append( of.ofp_action_output(port=int(self.actions_argu))) elif (self.actions == "enqueue"): port = self.actions_argu.split(':')[0] queue_id = self.actions_argu.split(':')[1] msg.actions.append( of.ofp_action_enqueue(port=int(port), queue_id=int(queue_id))) elif (self.actions == "strip-vlan"): msg.actions.append(of.ofp_action_strip_vlan()) elif (self.actions == "set-vlan-id"): msg.actions.append( of.ofp_action_vlan_vid( vlan_vid=int(self.actions_argu))) elif (self.actions == "set-vlan-priority"): msg.actions.append( of.ofp_action_vlan_pcp( vlan_pcp=int(self.actions_argu))) elif (self.actions == "SET_DL_SRC"): msg.actions.append( of.ofp_action_dl_addr(type=4, dl_addr=EthAddr( self.actions_argu))) elif (self.actions == "SET_DL_DST"): msg.actions.append( of.ofp_action_dl_addr(type=5, dl_addr=EthAddr( self.actions_argu))) elif (self.actions == "SET_NW_TOS"): msg.actions.append( of.ofp_action_nw_tos(nw_tos=int(self.actions_argu))) elif (self.actions == "SET_NW_SRC"): msg.actions.append( of.ofp_action_nw_addr(type=6, nw_addr=IPAddr( self.actions_argu))) elif (self.actions == "SET_NW_DST"): msg.actions.append( of.ofp_action_nw_addr(type=7, nw_addr=IPAddr( self.actions_argu))) elif (self.actions == "SET_TP_SRC"): msg.actions.append( of.ofp_action_tp_port(type=9, tp_port=int(self.actions_argu))) elif (self.actions == "SET_TP_DST"): msg.actions.append( of.ofp_action_tp_port(type=10, tp_port=int(self.actions_argu))) connection.send(msg)
def _handle_PacketIn(event): global s1_dpid, s2_dpid # print "PacketIn: ", dpidToStr(event.connection.dpid) # switch s1 if event.connection.dpid==s1_dpid: # Flujos para la tabla de flujos del switch flow_s1_0 = of.ofp_flow_mod() flow_s1_0.priority = 32768 # A mayor valor mas prioridad flow_s1_0.match.in_port = 1 flow_s1_0vlan_id = of.ofp_action_vlan_vid(vlan_vid = 10) flow_s1_queue1 = of.ofp_action_enqueue(port = 3, queue_id = 1) flow_s1_0.actions = [flow_s1_0vlan_id,flow_s1_queue1] flow_s1_1 = of.ofp_flow_mod() flow_s1_1.priority = 32768 # A mayor valor mas prioridad flow_s1_1.match.in_port = 2 flow_s1_1vlan_id = of.ofp_action_vlan_vid(vlan_vid = 20) flow_s1_queue2 = of.ofp_action_enqueue(port = 3, queue_id = 2) flow_s1_1.actions = [flow_s1_1vlan_id,flow_s1_queue2] flow_s1_2 = of.ofp_flow_mod() flow_s1_2.priority = 32768 # A mayor valor mas prioridad flow_s1_2.match.dl_vlan = 10 flow_s1_2stripvlan = of.ofp_action_strip_vlan() flow_s1_2out = of.ofp_action_output(port = 1) flow_s1_2.actions = [flow_s1_2stripvlan,flow_s1_2out] flow_s1_3 = of.ofp_flow_mod() flow_s1_3.priority = 32768 # A mayor valor mas prioridad flow_s1_3.match.dl_vlan = 20 flow_s1_3stripvlan = of.ofp_action_strip_vlan() flow_s1_3out = of.ofp_action_output(port = 2) flow_s1_3.actions = [flow_s1_3stripvlan,flow_s1_3out] # Instalacion de los flujos previamente definidos core.openflow.sendToDPID(s1_dpid,flow_s1_0) core.openflow.sendToDPID(s1_dpid,flow_s1_1) core.openflow.sendToDPID(s1_dpid,flow_s1_2) core.openflow.sendToDPID(s1_dpid,flow_s1_3) # switch s2 if event.connection.dpid==s2_dpid: # Flujos para la tabla de flujos del switch flow_s2_0 = of.ofp_flow_mod() flow_s2_0.priority = 32768 # A mayor valor mas prioridad flow_s2_0.match.in_port = 2 flow_s2_0vlan_id = of.ofp_action_vlan_vid(vlan_vid = 20) flow_s2_queue2 = of.ofp_action_enqueue(port = 1, queue_id = 2) flow_s2_0.actions = [flow_s2_0vlan_id,flow_s2_queue2] flow_s2_1 = of.ofp_flow_mod() flow_s2_1.priority = 32768 # A mayor valor mas prioridad flow_s2_1.match.in_port = 3 flow_s2_1vlan_id = of.ofp_action_vlan_vid(vlan_vid = 10) flow_s2_queue1 = of.ofp_action_enqueue(port = 1, queue_id = 1) flow_s2_1.actions = [flow_s2_1vlan_id,flow_s2_queue1] flow_s2_2 = of.ofp_flow_mod() flow_s2_2.priority = 32768 # A mayor valor mas prioridad flow_s2_2.match.dl_vlan = 10 flow_s2_2stripvlan = of.ofp_action_strip_vlan() flow_s2_2out = of.ofp_action_output(port = 3) flow_s2_2.actions = [flow_s2_2stripvlan,flow_s2_2out] flow_s2_3 = of.ofp_flow_mod() flow_s2_3.priority = 32768 # A mayor valor mas prioridad flow_s2_3.match.dl_vlan = 20 flow_s2_3stripvlan = of.ofp_action_strip_vlan() flow_s2_3out = of.ofp_action_output(port = 2) flow_s2_3.actions = [flow_s2_3stripvlan,flow_s2_3out] # Instalacion de los flujos previamente definidos core.openflow.sendToDPID(s2_dpid,flow_s2_0) core.openflow.sendToDPID(s2_dpid,flow_s2_1) core.openflow.sendToDPID(s2_dpid,flow_s2_2) core.openflow.sendToDPID(s2_dpid,flow_s2_3)
def sPortal(connection): for network,vlan in networks.iteritems(): # permit DNS to flow from clients to router msg = of.ofp_flow_mod() msg.priority = 20 msg.match.in_port = client_port_match msg.match.dl_vlan = vlan['untrusted'] msg.match.dl_type = 0x0800 msg.match.nw_proto = 17 msg.match.tp_dst = 53 msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = vlan['trusted'])) msg.actions.append(of.ofp_action_output(port = router_port_action)) connection.send(msg) # permit DHCP to flow from clients to router msg = of.ofp_flow_mod() msg.priority = 20 msg.match.in_port = client_port_match msg.match.dl_vlan = vlan['untrusted'] msg.match.dl_type = 0x0800 msg.match.nw_proto = 17 msg.match.tp_src = 68 msg.match.tp_dst = 67 msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = vlan['trusted'])) msg.actions.append(of.ofp_action_output(port = router_port_action)) connection.send(msg) # permit ARP to flow from clients to router (if supported) # otherwise, pre-authenticated clients will ARP to captive portal # which should be running proxy-arp so there should still be no problem if dp_supports_arp_match: msg = of.ofp_flow_mod() msg.priority = 20 msg.match.in_port = client_port_match msg.match.dl_vlan = vlan['untrusted'] msg.match.dl_type = pkt.ethernet.ARP_TYPE msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = vlan['trusted'])) msg.actions.append(of.ofp_action_output(port = router_port_action)) connection.send(msg) # send traffic from the client to the portal msg = of.ofp_flow_mod() msg.priority = 10 msg.match.in_port = client_port_match msg.match.dl_vlan = vlan['untrusted'] msg.actions.append(of.ofp_action_dl_addr.set_dst(portal)) msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = vlan['portal'])) msg.actions.append(of.ofp_action_output(port = portal_port_action)) connection.send(msg) # send IP traffic from the portal back to the client msg = of.ofp_flow_mod() msg.priority = 10 msg.match.in_port = portal_port_match msg.match.dl_vlan = vlan['portal'] msg.match.dl_src = portal # note - commented out because the switch under test can't match IP networks yet # note - this means for now that the "networks" array can only contain one network # note - we would have to also match ARP which is also not supported via the device under test #msg.match.dl_type = pkt.ethernet.IP_TYPE #msg.match.nw_dst = network msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = vlan['untrusted'])) msg.actions.append(of.ofp_action_output(port = client_port_action)) connection.send(msg) # send IP traffic from the router back to the client msg = of.ofp_flow_mod() msg.priority = 10 msg.match.in_port = router_port_match msg.match.dl_vlan = vlan['trusted'] msg.match.dl_src = router # note - commented out because the switch under test can't match IP networks yet # note - this means for now that teh "networks" array can only contain one network # note - we would have to also match ARP which is also not supported via the device under test #msg.match.dl_type = pkt.ethernet.IP_TYPE #msg.match.nw_dst = network msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = vlan['untrusted'])) msg.actions.append(of.ofp_action_output(port = client_port_action)) connection.send(msg)
def installNFToRRules(switch): """ Installs rules to ToR switches that have one or more NF connected to them """ for pol in policies: mList = pol.match cList = pol.chain lastNFSwitch = services[cList[(len(cList) - 1)]][NF_DPID] if lastNFSwitch == switch: fm = Tutorial.matchBuilder(mList) fm.match.in_port = int(services[cList[(len(cList) - 1)]][NF_PORT]) action = of.ofp_action_output(port=of.OFPP_CONTROLLER) fm.actions.append(action) RulesTable.addRule(switch, mList, "null", "controller port", services[cList[(len(cList) - 1)]][NF_PORT]) switchesConn[switch].send(fm) if len(cList) >= 2: for i in range(len(cList) - 1): nfSwitch = services[cList[i]][NF_DPID] if nfSwitch == switch: nf2Switch = services[cList[(i + 1)]][NF_DPID] if nf2Switch == switch: fm = Tutorial.matchBuilder(mList) nfPort = services[cList[i]][NF_PORT] nfTag = services[cList[i]][NF_VLAN] nf2Port = services[cList[(i + 1)]][NF_PORT] fm.match.in_port = int(nfPort) action = of.ofp_action_output(port=int(nf2Port)) fm.actions.append(action) RulesTable.addRule(switch, mList, "null", nf2Port, nfPort) switchesConn[switch].send(fm) else: fm = Tutorial.matchBuilder(mList) nfPort = services[cList[i]][NF_PORT] # corePort = str(coreSwitches[randint(0, (len(coreSwitches) - 1))]) coreSwitch = coreSwitches[0] corePort = Discovery.getPort( int(switch), int(coreSwitch)) if corePort is None: configHelper[2] = False return nfTag = services[cList[i]][NF_VLAN] fm.match.in_port = int(nfPort) action1 = of.ofp_action_vlan_vid( vlan_vid=int(nfTag)) action2 = of.ofp_action_output(port=int(corePort)) fm.actions.append(action1) fm.actions.append(action2) RulesTable.addRule(switch, mList, "null", corePort, nfPort, nfTag) switchesConn[switch].send(fm) for pol2 in policies: mList = pol2.match cList = pol2.chain fm = Tutorial.matchBuilder(mList) # corePort = str(coreSwitches[randint(0, (len(coreSwitches) - 1))]) if services[cList[0]][NF_DPID] != switch: coreSwitch = coreSwitches[0] corePort = Discovery.getPort(int(switch), int(coreSwitch)) if corePort is None: configHelper[2] = False return fm.match.dl_vlan = of.OFP_VLAN_NONE action = of.ofp_action_output(port=int(corePort)) fm.actions.append(action) RulesTable.addRule(switch, mList, None, corePort) switchesConn[switch].send(fm) for c in cList: nfSwitch = services[c][NF_DPID] cIndx = cList.index(c) if nfSwitch == switch: if cIndx == 0 or (cIndx > 0 and services[cList[ (cIndx - 1)]][NF_DPID] != switch): if cIndx == 0: allPorts = [ int(p) for p in Discovery.graph.nodes[int( switch)].connection.ports ] else: allPorts = Discovery.getPorts(int(switch)) for p in allPorts: if p < of.OFPP_MAX and p != int( services[c][NF_PORT]): fm = Tutorial.matchBuilder(mList) fm.match.in_port = int(p) nfPort = services[c][NF_PORT] if cIndx == 0: fm.match.dl_vlan = of.OFP_VLAN_NONE RulesTable.addRule(switch, mList, None, nfPort, p) else: fm.match.dl_vlan = services[cList[( cIndx - 1)]][NF_VLAN] RulesTable.addRule( switch, mList, services[cList[(cIndx - 1)]][NF_VLAN], nfPort, p) action1 = of.ofp_action_vlan_vid() action2 = of.ofp_action_output( port=int(nfPort)) fm.actions.append(action1) fm.actions.append(action2) switchesConn[switch].send(fm)
def __handle_PacketIn(self, event): packet = event.parsed src = packet.src.toStr() dst = packet.dst.toStr() # Extract IP information ip = packet.find('ipv4') udpp = packet.find('udp') if ip: # it is not a good way to define a variable, anyway srcip = ip.srcip dstip = ip.dstip self.srcip_table[src] = srcip self.dstip_table[dst] = dstip if udpp: srcport = udpp.srcport # Each src-dst pair has several ports if srcport not in self.sd_srcport_table[src][dst]: # New port discovered self.sd_srcport_table[src][dst].append(srcport) # Latency test packets handling if self.lat_test: if packet.type != 0x5566: # not test packet, drop it return src = self._MAC_to_int(src) dst = self._MAC_to_int(dst) timeinit, = struct.unpack('!I', packet.find('ethernet').payload) timediff = time.time()*1000 - self.system_time - timeinit if src in self.adj_test: if dst in self.adj_test[src]: self.adj[src][dst] = timediff del self.adj_test[src][dst] if dst in self.sw_test: self.sw_lat[dst] = timediff self.sw_test.remove(dst) return # assign path id pid = 0 if src in self.hosts: for d in self.sd_path_table[src]: # FIXME: Pick one as default # Maybe we should apply flood function to broadcasting for sd_path_id in self.sd_path_table[src][d]: pid = sd_path_id # log.warning("Packet Vid = %i", pid) if dst in self.hosts: if self.config.config_set: if ip and udpp: # If the packet is an IP/UDP packet id_list = self.sd_path_table[src][dst] # last one, in case not found pid = self.get_pid_by_srcport(id_list, srcport) if pid is None: # Not existed port, choose the last one as default pid = id_list[len(id_list) - 1] for k in id_list: now_split = self.config.now_config real_split = self.config.real_config # log.warning("now %s real %s", now_split, real_split ) if now_split[k-1] > real_split[k-1] or now_split[k-1] == 1: pid = k break # update flow_dist_table and real_config_table self.flow_dist_table[pid-1].append(srcport) self.config.compute_real_config(id_list, self.flow_dist_table) else: id_list = self.sd_path_table[src][dst] # last one, in case not found pid = id_list[len(id_list) - 1] sum_of_all = 0 for x in id_list: sum_of_all += self.config.now_config[x-1] rand_num = sum_of_all * random.random() for x in id_list: rand_num -= self.config.now_config[x-1] # Since the path ID starts from 1, which is different from the index if rand_num < 0: # path_id should start from 1 pid = x break # log.warning("SD pair %i, pid %i", self.sd_pair[src][dst], pid) else: # FIXME: path selection for sd_path_id in self.sd_path_table[src][dst]: # There exists a path pid = sd_path_id # log.warning("Packet Vid = %i", pid) if ip and udpp: # FIXME: Do we need to modify the flow whenever the packet in? msg = of.ofp_flow_mod() msg.match.dl_type = 0x800 msg.match.nw_src = IPAddr(srcip) msg.match.nw_dst = IPAddr(dstip) msg.match.nw_proto = 17 msg.match.tp_src = srcport # slog.warning("Add rule for port %s", srcport) else: msg = of.ofp_packet_out(data = event.ofp) if pid != 0: # There exists a path path = self.path_id_table[pid] if len(path) > 3: # It is not the last sw, tag it and send into the network if USE_VLAN_TAG: msg.actions.append( of.ofp_action_vlan_vid( vlan_vid = pid ) ) if USE_ETHERNET_SRC_TAG: msg.actions.append( of.ofp_action_dl_addr.set_src( EthAddr( self._int_to_MAC( pid ) ) ) ) msg.actions.append( of.ofp_action_output( port = self.ports[path[1]][path[2]] ) ) elif len(path) == 3: # last sw, forward to the host #msg.actions.append( of.ofp_action_output( port = of.OFPP_FLOOD ) ) msg.actions.append( of.ofp_action_output( port = self.hadj[path[2]][path[1]] ) ) event.connection.send(msg) """
def _update_step(self): if self.update_step > len(self.config.config) - 1: self.update_timer.cancel() log.warning("Updating Ends.") return self.update_timer._interval = 10 self.config.change_step(self.update_step) #redistribute flows based on new configuration for i in self.config.real_config: for j in self.config.real_config[i]: self.config.real_config[i][j] = 0.0 for sd_id in self.flow_dist_table: for path in self.flow_dist_table[sd_id]: self.flow_dist_table[sd_id][path] = [] for src in self.sd_srcport_table: for dst in self.sd_srcport_table[src]: sd_id = self.sd_pair[src][dst] id_list = self.config.now_config[sd_id] real_split = self.config.real_config[sd_id] cur_dist = self.flow_dist_table[sd_id] for srcport in self.sd_srcport_table[src][dst]: # last one, in case not found pid = len(id_list) - 1 for k,x in enumerate(id_list): if x > real_split[k] or x == 1: pid = k + 1 # update flow_dist_table and real_config_table cur_dist[k].append(srcport) num_flow = len(self.sd_srcport_table[src][dst]) self.config.compute_real_config(sd_id, num_flow, cur_dist) #print 'compute_real_config', self.config.real_config[sd_id][k] break srcip = self.srcip_table[src] dstip = self.dstip_table[dst] msg = of.ofp_flow_mod(command = of.OFPFC_MODIFY_STRICT) msg.match.dl_type = 0x800 msg.match.nw_src = IPAddr(srcip) msg.match.nw_dst = IPAddr(dstip) msg.match.nw_proto = 17 msg.match.tp_src = srcport path = self.path_id_table[pid] if len(path) > 3: # It is not the last sw, tag it and send into the network if USE_VLAN_TAG: msg.actions.append( of.ofp_action_vlan_vid( vlan_vid = pid ) ) if USE_ETHERNET_SRC_TAG: msg.actions.append( of.ofp_action_dl_addr.set_src( EthAddr( self._int_to_MAC( pid ) ) ) ) msg.actions.append( of.ofp_action_output( port = self.ports[path[1]][path[2]] ) ) elif len(path) == 3: # last sw, forward to the host # msg.actions.append( of.ofp_action_output( port = of.OFPP_FLOOD ) ) msg.actions.append( of.ofp_action_output( port = self.hadj[path[2]][path[1]] ) ) sw = path[1] core.openflow.sendToDPID(sw, msg) #print msg log.warning("SD pair %i, pid %i", self.sd_pair[src][dst], pid) log.warning("Update Step %i ...", self.update_step) self.update_step += 1
def flood(message=None): srcPort = str(event.port) if (packet.find('vlan') is not None): vlanId = getVlan(srcPort, packet.find('vlan').id) else: vlanId = getVlan(srcPort, None) put = True for i in self.macToPort: if ((i.get('mac') == packet.src) and (i.get('port') == int(srcPort)) and (i.get('vlan') == vlanId)): put = False if (put): self.macToPort.append({ 'mac': packet.src, 'port': int(srcPort), 'vlan': vlanId }) taggedPorts = [] untaggedPorts = [] tabla = importData() for i in tabla: if i.get('vlan') == str(vlanId): for j in i.get('ports'): if (j.get('port') != srcPort and j.get('type') == "tagged"): taggedPorts.append(j.get('port')) if (j.get('port') != srcPort and j.get('type') == "untagged"): untaggedPorts.append(j.get('port')) tag = tagType(srcPort, vlanId) msg = of.ofp_flow_mod() msg.match.in_port = int(srcPort) # Tagged if tag == "tagged": # print ("FLOOD from T-port {0}").format(srcPort) # T a T for i in taggedPorts: msg.actions.append(of.ofp_action_output(port=int(i))) # T a U if untaggedPorts != []: msg.actions.append(of.ofp_action_strip_vlan()) for i in untaggedPorts: msg.actions.append(of.ofp_action_output(port=int(i))) # Untagged if tag == "untagged": # print ("FLOOD from U-port {0}").format(srcPort) # U a U for i in untaggedPorts: msg.actions.append(of.ofp_action_output(port=int(i))) # U a T if taggedPorts != []: msg.actions.append( of.ofp_action_vlan_vid(vlan_vid=int(vlanId))) for i in taggedPorts: msg.actions.append(of.ofp_action_output(port=int(i))) self.connection.send(msg) return
def build_nx_actions(self,inport,action_list,table_id,pipeline): ### BUILD NX ACTIONS of_actions = [] ctlr_outport = False # there is a controller outport action phys_outports = list() # list of physical outports to forward out of possibly_resubmit_next_table = False # should packet be passed on to next table? atleast_one_action = False for actions in action_list: atleast_one_action = True if 'srcmac' in actions: of_actions.append(of.ofp_action_dl_addr.set_src(actions['srcmac'])) if 'dstmac' in actions: of_actions.append(of.ofp_action_dl_addr.set_dst(actions['dstmac'])) if 'srcip' in actions: of_actions.append(of.ofp_action_nw_addr.set_src(actions['srcip'])) if 'dstip' in actions: of_actions.append(of.ofp_action_nw_addr.set_dst(actions['dstip'])) if 'srcport' in actions: of_actions.append(of.ofp_action_tp_port.set_src(actions['srcport'])) if 'dstport' in actions: of_actions.append(of.ofp_action_tp_port.set_dst(actions['dstport'])) if 'vlan_id' in actions: if actions['vlan_id'] is None: of_actions.append(of.ofp_action_strip_vlan()) else: of_actions.append(of.ofp_action_vlan_vid(vlan_vid=actions['vlan_id'])) if 'vlan_pcp' in actions: if actions['vlan_pcp'] is None: if not actions['vlan_id'] is None: raise RuntimeError("vlan_id and vlan_pcp must be set together!") pass else: of_actions.append(of.ofp_action_vlan_pcp(vlan_pcp=actions['vlan_pcp'])) assert 'port' in actions outport = actions['port'] if outport == of.OFPP_CONTROLLER: ctlr_outport = True else: """ There is either a physical output action (i.e., on a non-controller port), or a "send to next table" action.""" possibly_resubmit_next_table = True if outport != CUSTOM_NEXT_TABLE_PORT: phys_outports.append(outport) """ Otherwise there are no physical outports; just a possibility of resubmitting to the next table. Pass. """ """In general, actual packet forwarding may have to wait until the final table in the pipeline. This means we must determine if there is a "next" table that processes the packet from here, or if this is the last one. But first, the easy part. There are exactly three cases where a forwarding table *will* in fact "immediately forward" a packet according to the current rule (and all previous table stages that processed the packet), without waiting for any other further processing: (1) if the packet is dropped by the current rule, (2) if the packet is forwarded to the controller port, or (3) if this is the last stage of the pipeline. In the case of (1) and (2), packet forwarding may happen immediately and only depend on the current rule. But in (3), the forwarding decision must take the current rule as well as previous port changes into account, as follows: (a) if the current rule specifies an output port, forward the packet out of that port. (b) if the current rule does not specify an outport, then forward the packet out of the port using the value stored in the dedicated per-packet port register. If neither of (1)-(3) above is true, then we take the following approach: (a) if there is an outport set by this rule, write that value into the dedicated per-packet register that contains the current port the packet is in. (b) if there is no outport set by this rule, and if this is table id 0, move the value of the inport into the dedicated per-packet port register. This denotes that the packet is currently still on its inport. (c) resubmit the packet to the "next" table (according to the pipeline). """ exists_next_table = table_id in pipeline.edges # Decide first on "immediate forwarding" conditions: immediately_fwd = True if not atleast_one_action: # (1) drop of_actions = [] elif ctlr_outport: # (2) controller of_actions = [] of_actions.append(of.ofp_action_output(port=of.OFPP_CONTROLLER)) elif possibly_resubmit_next_table and (not exists_next_table): # (3) last stage of pipeline if len(phys_outports) > 0: # fwd out of latest assigned ports for p in phys_outports: of_actions.append(of.ofp_action_output(port=p)) else: # fwd out of stored port value of_actions.append(nx.nx_output_reg(reg=nx.NXM_NX_REG2, nbits=16)) elif (not exists_next_table) and (not possibly_resubmit_next_table): raise RuntimeError("Unexpected condition in multi-stage processing") else: # must resubmit packet to subsequent tables for processing immediately_fwd = False if immediately_fwd: return of_actions # Act on packet with knowledge that subsequent tables must process it assert (possibly_resubmit_next_table and exists_next_table and (not immediately_fwd)) next_table = pipeline.edges[table_id] if len(phys_outports) > 0: # move port register to latest assigned port values for p in phys_outports: of_actions.append(nx.nx_reg_load(dst=nx.NXM_NX_REG2, value=p, nbits=16)) of_actions.append(nx.nx_action_resubmit.resubmit_table( table=next_table)) elif table_id == 0: # move the inport value to reg2. of_actions.append(nx.nx_reg_move(src=nx.NXM_OF_IN_PORT, dst=nx.NXM_NX_REG2, nbits=16)) of_actions.append(nx.nx_action_resubmit.resubmit_table( table=next_table)) else: of_actions.append(nx.nx_action_resubmit.resubmit_table( table=next_table)) return of_actions
def __handle_PacketIn(self, event): packet = event.parsed src = packet.src.toStr() dst = packet.dst.toStr() ip = packet.find('ipv4') udpp = packet.find('udp') if ip: srcip = ip.srcip dstip = ip.dstip self.srcip_table[src] = srcip self.dstip_table[dst] = dstip if udpp: srcport = udpp.srcport if srcport not in self.sd_srcport_table[src][dst]: self.sd_srcport_table[src][dst].append(srcport) #print(self.sd_srcport_table[src][dst]) if self.lat_test: if packet.type != 0x5566: # not test packet, drop it return src = self._MAC_to_int(src) dst = self._MAC_to_int(dst) timeinit, = struct.unpack('!I', packet.find('ethernet').payload) timediff = time.time()*1000 - self.system_time - timeinit if src in self.adj_test: if dst in self.adj_test[src]: self.adj[src][dst] = timediff del self.adj_test[src][dst] if dst in self.sw_test: self.sw_lat[dst] = timediff self.sw_test.remove(dst) return pid = 0 if src in self.hosts: for d in self.sd_path_table[src]: # FIXME: Pick one as default # Maybe we should apply flood function to broadcasting for sd_path_id in self.sd_path_table[src][d]: pid = sd_path_id # log.warning("Packet Vid = %i", pid) if dst in self.hosts: if ip and udpp and self.config.config_set: sd_id = self.sd_pair[src][dst] id_list = self.config.now_config[sd_id] real_split = self.config.real_config[sd_id] cur_dist = self.flow_dist_table[sd_id] # last one, in case not found pid = len(id_list) - 1 if scrport in cur_dist.values: pid = self.get_pid_by_scrport(sd_id, scrport) else: for k,x in enumerate(id_list): if x > real_split[k] or x == 1: pid = k + 1 # update flow_dist_table and real_config_table self.flow_dist_table[sd_id][k].append(srcport) num_flow = len(self.sd_srcport_table[src][dst]) self.config.compute_real_config(sd_id, num_flow, cur_dist) break log.warning("SD pair %i, pid %i", self.sd_pair[src][dst], pid) elif self.config.config_set: id_list = self.config.now_config[self.sd_pair[src][dst]] # last one, in case not found pid = len(id_list) - 1 rand_num = random.random() for k,x in enumerate(id_list): rand_num -= x if rand_num < 0: # path_id should start from 1 pid = k + 1 break log.warning("SD pair %i, pid %i", self.sd_pair[src][dst], pid) else: # FIXME: path selection for sd_path_id in self.sd_path_table[src][dst]: # There exists a path pid = sd_path_id # log.warning("Packet Vid = %i", pid) if ip and udpp: msg = of.ofp_flow_mod() msg.match.dl_type = 0x800 msg.match.nw_src = IPAddr(srcip) msg.match.nw_dst = IPAddr(dstip) msg.match.nw_proto = 17 msg.match.tp_src = srcport else: msg = of.ofp_packet_out(data = event.ofp) if pid != 0: # There exists a path path = self.path_id_table[pid] if len(path) > 3: # It is not the last sw, tag it and send into the network if USE_VLAN_TAG: msg.actions.append( of.ofp_action_vlan_vid( vlan_vid = pid ) ) if USE_ETHERNET_SRC_TAG: msg.actions.append( of.ofp_action_dl_addr.set_src( EthAddr( self._int_to_MAC( pid ) ) ) ) msg.actions.append( of.ofp_action_output( port = self.ports[path[1]][path[2]] ) ) elif len(path) == 3: # last sw, forward to the host #msg.actions.append( of.ofp_action_output( port = of.OFPP_FLOOD ) ) msg.actions.append( of.ofp_action_output( port = self.hadj[path[2]][path[1]] ) ) """ msg = of.ofp_packet_out( data = event.ofp ) if pid != 0: # There exists a path path = self.path_id_table[pid] if len(path) > 3: # It is not the last sw, tag it and send into the network if USE_VLAN_TAG: msg.actions.append( of.ofp_action_vlan_vid( vlan_vid = pid ) ) if USE_ETHERNET_SRC_TAG: msg.actions.append( of.ofp_action_dl_addr.set_src( EthAddr( self._int_to_MAC( pid ) ) ) ) msg.actions.append( of.ofp_action_output( port = self.ports[path[1]][path[2]] ) ) elif len(path) == 3: # last sw, forward to the host # msg.actions.append( of.ofp_action_output( port = of.OFPP_FLOOD ) ) msg.actions.append( of.ofp_action_output( port = self.hadj[path[2]][path[1]] ) ) """ event.connection.send(msg)