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 verifyIdentity(self, mac_addr): """ retry authentication to check if is the same user who send packets """ mac_addr = checkMac(mac_addr) self.authenticatedToProgress(mac_addr) port = self.host_progress[mac_addr]['port'] #Ajout de 2 flux pour la gestion de 802.1x msg = of.ofp_flow_mod() msg.match = of.ofp_match() msg.match.dl_type= 0x888e msg.match.in_port = port msg.match.dl_src = mac_addr msg.priority = 200 action = of.ofp_action_output( port = of.OFPP_CONTROLLER ) msg.actions.append(action) self.connection.send(msg) self.host_progress[mac_addr]['match'].append(msg.match) msg = of.ofp_flow_mod() msg.match = of.ofp_match() msg.match.dl_type = 0x888e msg.match.in_port= of.OFPP_CONTROLLER msg.match.dl_dst = mac_addr action = of.ofp_action_output( port = port) msg.actions.append(action) msg.priority = 200 self.connection.send(msg) self.host_progress[mac_addr]['match'].append(msg.match) self.sendRequestIdentity(mac_addr, self.host_progress[mac_addr]['port'])
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 _handle_PacketIn(self,event): eth_packetRecv = event.parsed if eth_packetRecv.type == ethernet.ARP_TYPE: #checking if the payload is ARP pkt msg = of.ofp_packet_out() msg.in_port = event.port arpreq = eth_packetRecv.payload # extract arp packet - arpreq # log.debug('%s arp table',ARPTable) if arpreq.protosrc not in ARPTable.keys(): #if no srcip entry in ARP table,add a new entry for scrip, srcmac ARPTable[arpreq.protosrc] = arpreq.hwsrc # print "in 1" if arpreq.protodst not in ARPTable.keys():#if no entry in the ARPtable , then flood the ARP packet as l2 bc eth_packetSent = eth_packetRecv msg.data = eth_packetSent.pack() msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD)) #flooding on all ports of the swtch elif arpreq.protodst in ARPTable.keys(): # if dstip in ARPTable,build appropriate ARP reply arpreply = self.buildReply(arpreq)#building the arp reply , eth_packetSent = ethernet(type = ethernet.ARP_TYPE,dst = arpreply.hwdst )#setting type of ethernet packet and src and dst mac addresses eth_packetSent.set_payload(arpreply) # the payload of the eth packet is the arp packet msg.data = eth_packetSent.pack() msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT)) msg.in_port = event.port elif eth_packetRecv.type != ethernet.ARP_TYPE: # print "in switching..." msg = self.processPacket(event) # log.debug('mac addr table %s',self.macaddrtable) event.connection.send(msg)
def _handle_PacketIn(self, event): if event.dpid == 1: # s1 msg = of.ofp_flow_mod() msg.priority = 42 #msg.in_port = 1 #msg.dl_src = EthAddr("00:00:00:00:00:01") msg.match.dl_type = 0x0800 #ipv4 msg.match.nw_dst = IPAddr("10.0.0.1") msg.actions.append(of.ofp_action_output(port = 1)) msg.actions.append(of.ofp_action_dl_addr.set_dst(EthAddr("00:00:00:00:00:01"))) event.connection.send(msg) elif event.dpid == 3: # s3 msg = of.ofp_flow_mod() msg.priority = 42 #msg.in_port = 1 #msg.dl_src = EthAddr("00:00:00:00:00:01") msg.match.dl_type = 0x0800 msg.match.nw_dst = IPAddr("10.0.0.3") msg.actions.append(of.ofp_action_output(port = 1)) msg.actions.append(of.ofp_action_dl_addr.set_dst(EthAddr("00:00:00:00:00:03"))) event.connection.send(msg) elif event.dpid == 4: # s4 msg = of.ofp_flow_mod() msg.priority = 42 #msg.in_port = 1 #msg.dl_src = EthAddr("00:00:00:00:00:02") msg.match.dl_type = 0x0800 msg.match.nw_dst = IPAddr("10.0.0.2") msg.actions.append(of.ofp_action_output(port = 1)) msg.actions.append(of.ofp_action_dl_addr.set_dst(EthAddr("00:00:00:00:00:02"))) event.connection.send(msg)
def _setup_data_fwd_flows(self, switch_id, dst_mac): """ Given a switch and dst_mac address, setup two flows for data forwarding on the switch and its peer switch if the two are not the same. If the same, setup only one flow. """ (peer_switch_id, peer_fwd_port) = (self.inception. mac_to_dpid_port[dst_mac]) peer_ip = self.inception.dpid_to_ip[peer_switch_id] # two switches are different, setup a first flow at switch if switch_id != peer_switch_id: fwd_port = self.inception.dpid_ip_to_port[(switch_id, peer_ip)] core.openflow.sendToDPID(switch_id, of.ofp_flow_mod( match=of.ofp_match(dl_dst=dst_mac), action=of.ofp_action_output(port=fwd_port), priority=priority.DATA_FWD)) LOGGER.info("Setup forward flow on switch=%s for dst_mac=%s", dpid_to_str(switch_id), dst_mac) # Setup flow at the peer switch core.openflow.sendToDPID(peer_switch_id, of.ofp_flow_mod( match=of.ofp_match(dl_dst=dst_mac), action=of.ofp_action_output(port=peer_fwd_port), priority=priority.DATA_FWD)) LOGGER.info("Setup forward flow on switch=%s for dst_mac=%s", dpid_to_str(peer_switch_id), dst_mac)
def connection_up(event): msg = of.ofp_flow_mod() msg.match.priority = 50 msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.match.priority = 100 msg.match.dl_type = 0x800 msg.match.nw_proto = 1 msg.match.nw_src = IPAddr("192.168.1.2") msg.match.nw_dst = IPAddr("192.168.1.3") msg.match.tp_src = 8 msg.actions.append(of.ofp_action_dl_addr.set_dst( EthAddr("fe:fd:02:00:00:03"))) msg.actions.append(of.ofp_action_nw_addr.set_dst( IPAddr("192.168.1.4"))) msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.match.priority = 100 msg.match.dl_type = 0x800 msg.match.nw_proto = 1 msg.match.nw_src = IPAddr("192.168.1.4") msg.match.nw_dst = IPAddr("192.168.1.2") msg.match.tp_src = 0 msg.actions.append(of.ofp_action_dl_addr.set_src( EthAddr("fe:fd:02:00:00:02"))) msg.actions.append(of.ofp_action_nw_addr.set_src( IPAddr("192.168.1.3"))) msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD)) event.connection.send(msg)
def _install_path(prev_path, match): dst_sw = prev_path.dst cur_sw = prev_path.dst dst_pck = match.dl_dst msg = of.ofp_flow_mod() msg.match = match msg.idle_timeout = 10 msg.flags = of.OFPFF_SEND_FLOW_REM msg.actions.append(of.ofp_action_output(port = mac_learning[dst_pck].port)) log.debug("Installing forward from switch %s to output port %s", util.dpid_to_str(cur_sw), mac_learning[dst_pck].port) switches[dst_sw].connection.send(msg) next_sw = cur_sw cur_sw = prev_path.prev[next_sw] while cur_sw is not None: #for switch in path.keys(): msg = of.ofp_flow_mod() msg.match = match msg.idle_timeout = 10 msg.flags = of.OFPFF_SEND_FLOW_REM log.debug("Installing forward from switch %s to switch %s output port %s", util.dpid_to_str(cur_sw), util.dpid_to_str(next_sw), adj[cur_sw][next_sw]) msg.actions.append(of.ofp_action_output(port = adj[cur_sw][next_sw])) switches[cur_sw].connection.send(msg) next_sw = cur_sw cur_sw = prev_path.prev[next_sw]
def configure_icmp_proxy(connection): log.info("icmp_proxy: loading...") msg = of.ofp_flow_mod() msg.match.priority = 50 msg.actions.append(of.ofp_action_output(port = of.OFPP_NORMAL)) connection.send(msg) msg = of.ofp_flow_mod() msg.match.priority = 100 msg.match.dl_type = 0x800 msg.match.nw_proto = 1 msg.match.nw_src = IPAddr("192.168.1.2") msg.match.nw_dst = IPAddr("192.168.2.3") msg.match.tp_src = 8 msg.actions.append(of.ofp_action_dl_addr.set_dst( EthAddr("fe:fd:02:00:00:03"))) msg.actions.append(of.ofp_action_nw_addr.set_dst( IPAddr("192.168.3.4"))) msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD)) connection.send(msg) msg = of.ofp_flow_mod() msg.match.priority = 100 msg.match.dl_type = 0x800 msg.match.nw_proto = 1 msg.match.nw_src = IPAddr("192.168.3.4") msg.match.nw_dst = IPAddr("192.168.1.2") msg.match.tp_src = 0 msg.actions.append(of.ofp_action_dl_addr.set_dst( EthAddr("fe:fd:02:00:00:01"))) msg.actions.append(of.ofp_action_nw_addr.set_src(IPAddr("192.168.2.3"))) msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD)) connection.send(msg)
def AddFlowFromModel(self, flow): # add outgoing flow msg = of.ofp_flow_mod() msg.match = of.ofp_match() msg.match.dl_type = ethernet.IP_TYPE msg.match.nw_src = str(flow.internalip) msg.match.nw_dst = str(flow.externalip) msg.match.in_port = flow.internalport msg.idle_timeout = flow.idletime msg.hard_timeout = flow.hardtime msg.actions.append(of.ofp_action_output(port = flow.externalport)) log.debug("installing Manos Flow 1") self.connection.send(msg) # add incoming flow msg = of.ofp_flow_mod() msg.match = of.ofp_match() msg.match.dl_type = ethernet.IP_TYPE msg.match.nw_src = str(flow.externalip) msg.match.nw_dst = str(flow.internalip) msg.match.in_port = flow.externalport msg.idle_timeout = flow.idletime msg.hard_timeout = flow.hardtime msg.actions.append(of.ofp_action_output(port = flow.internalport)) log.debug("installing Manos Flow 2") self.connection.send(msg)
def _handle_pytap (event): # packet is an instance of class 'pox.lib.packet.ethernet.ethernet' packet = event.parsed print packet.dst, packet.src # # Learn the source srcPort = event.port if srcPort == 1 or srcPort == 2: # build the flow from port 1 to port 2 forwardFlow = of.ofp_flow_mod() forwardFlow.idle_timeout = 120 forwardFlow.hard_timeout = 120 forwardFlow.match.in_port = 1 forwardFlow.actions.append(of.ofp_action_output(port=2)) event.connection.send(forwardFlow) # build the flow from port 2 to port 1 returnFlow = of.ofp_flow_mod() returnFlow.idle_timeout = 120 returnFlow.hard_timeout = 120 returnFlow.match.in_port = 2 returnFlow.actions.append(of.ofp_action_output(port=1)) event.connection.send(returnFlow) log.debug("Installing flow from Port 1 to Port 2")
def _install (self, switch, in_port, out_port, match, buf = None): print "inside _install" print "IN PORT ********** ",in_port msg = of.ofp_flow_mod() if in_port==TRANSCODER_TO_SWITCH_PORT and switch.dpid==TRANSCODER_SERVICE_SWITCH_DPID and match.nw_dst==HOSTB_ADDR: msg1 =of.ofp_flow_mod() #msg1.match.dl_src=EthAddr("8e:f0:0d:59:7b:18") #msg1.match.dl_dst=EthAddr("ca:0b:cb:59:d8:1c") #msg1.match.nw_src=IPAddr("10.0.0.3") #msg1.match.nw_dst=IPAddr("10.0.0.2") msg1.actions.append(of.ofp_action_dl_addr.set_src("8a:3d:5a:6c:e3:fe")) #set src mac address to ip address of host A msg1.actions.append(of.ofp_action_nw_addr.set_src(HOSTA_ADDR)) #set src ip address to ip address of host A msg1.match.in_port=in_port msg1.hard_timeout = FLOW_HARD_TIMEOUT msg1.idle_timeout = FLOW_IDLE_TIMEOUT msg1.actions.append(of.ofp_action_output(port = out_port)) switch.connection.send(msg1) return elif in_port==FIREWALL_TO_SWITCH_PORT and switch.dpid==FIREWALL_SERVICE_SWITCH_DPID and match.nw_dst==HOSTB_ADDR: msg1 =of.ofp_flow_mod() #msg1.match.dl_src=EthAddr("8e:f0:0d:59:7b:18") #msg1.match.dl_dst=EthAddr("ca:0b:cb:59:d8:1c") #msg1.match.nw_src=IPAddr("10.0.0.3") #msg1.match.nw_dst=IPAddr("10.0.0.2") msg1.actions.append(of.ofp_action_dl_addr.set_src("8a:3d:5a:6c:e3:fe")) #set src mac address to ip address of host A msg1.actions.append(of.ofp_action_nw_addr.set_src(HOSTA_ADDR)) #set src ip address to ip address of host A msg1.match.in_port=in_port msg1.hard_timeout = FLOW_HARD_TIMEOUT msg1.idle_timeout = FLOW_IDLE_TIMEOUT msg1.actions.append(of.ofp_action_output(port = out_port)) switch.connection.send(msg1) return else: msg.match = match msg.match.in_port = in_port msg.idle_timeout = FLOW_IDLE_TIMEOUT msg.hard_timeout = FLOW_HARD_TIMEOUT # msg.actions.append(of.ofp_action_output(port = out_port)) msg.buffer_id = buf # switch.connection.send(msg) #print match.nw_dst #print msg.match.nw_dst #print out_port #Below lines may be needed if we want to change dst_ip address of packets towards host B to ip address of TRANSCODER VM if out_port==SWITCH_TO_TRANSCODER_PORT and switch.dpid==TRANSCODER_SERVICE_SWITCH_DPID and match.nw_dst==HOSTB_ADDR: msg.actions.append(of.ofp_action_nw_addr.set_dst(TRANSCODER_VM_IP)) msg.actions.append(of.ofp_action_dl_addr.set_dst("8e:f0:0d:59:7b:18")) if out_port==SWITCH_TO_FIREWALL_PORT and switch.dpid==FIREWALL_SERVICE_SWITCH_DPID and match.nw_dst==HOSTB_ADDR: msg.actions.append(of.ofp_action_nw_addr.set_dst(FIREWALL_VM_IP)) msg.actions.append(of.ofp_action_dl_addr.set_dst("8e:f0:0d:59:7b:18")) #set mac address of flow to mac address of FIREWALL VM msg.actions.append(of.ofp_action_output(port = out_port)) switch.connection.send(msg) print "******message sent to switch:" print switch
def _handle_ConnectionUp(self, event): # Use dpid to differentiate between switches (datapath-id) # Each switch has its own flow table. As we'll see in this # example we need to write different rules in different tables. # dpid = dpidToStr(event.dpid) log.debug("Slice for Switch %s ...", event.dpid) """ Add your logic here """ # h1 h4 if event.dpid == 1 or event.dpid == 4: msg = of.ofp_flow_mod() msg.priority = 65500 msg.match.in_port = 3 msg.actions.append(of.ofp_action_output(port=1)) event.connection.send(msg) msg.match.in_port = 1 msg.actions.append(of.ofp_action_output(port=3)) event.connection.send(msg) msg.match.in_port = 4 msg.actions.append(of.ofp_action_output(port=2)) event.connection.send(msg) msg.match.in_port = 2 msg.actions.append(of.ofp_action_output(port=4)) event.connection.send(msg) # h2 h3 if event.dpid == 2 or event.dpid == 3: msg = of.ofp_flow_mod() msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) event.connection.send(msg)
def _handle_ConnectionUp (self, event): if self._install_flow: msg = of.ofp_flow_mod() #msg.match = of.ofp_match() #msg.match.dl_type = pkt.ethernet.IP_TYPE #msg.match.dn_dst = "www.uol.com.br" msg.match.dn_dst="formiga.lecom.dcc.ufmg.br" #msg.match.dn_src = "www.uol.com" #msg.match.in_port=1 #msg.match.dl_type=0x0800 msg.idle_timeout = 65535 msg.priority = 65535 msg.actions.append(of.ofp_action_output(port = 3 )) #msg.actions.append(of.ofp_action_nw_addr.set_dst(IPAddr("150.164.0.135"))) event.connection.send(msg) print "regra inserida", msg msg = of.ofp_flow_mod() msg.match.dn_src="formiga.lecom.dcc.ufmg.br" #msg.match.dl_type=0x0800 #msg.match.in_port=3 #msg.idle_timeout = 65535 #msg.priority = 65535 #msg.actions.append(of.ofp_action_nw_addr.set_src(IPAddr("150.164.0.135"))) msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg)
def fwd(target, duration=(RULE_DURATION_SEC, RULE_DURATION_SEC)): if not isinstance(duration, tuple): duration = (duration, duration) # srcip -> dstip msg = of.ofp_flow_mod() msg.match = of.ofp_match.from_packet(packet) msg.idle_timeout = duration[0] msg.hard_timeout = duration[1] msg.actions.append(of.ofp_action_nw_addr.set_dst(target)) msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) event.connection.send(msg) # target -> srcip msg = of.ofp_flow_mod() msg.match = of.ofp_match(dl_type=0x800, nw_src=target, nw_dst=ip.srcip) msg.idle_timeout = duration[0] msg.hard_timeout = duration[1] msg.actions.append(of.ofp_action_nw_addr.set_src(ip.dstip)) msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) event.connection.send(msg) # send this pkt msg = of.ofp_packet_out() msg.actions.append(of.ofp_action_nw_addr.set_dst(target)) msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) msg.data = event.ofp msg.in_port = event.port event.connection.send(msg)
def __init__(self, connection): self.connections = {} self.replicas = deque() self.connection = connection connection.addListeners(self) # Send UDP updates to the controller. fm = of.ofp_flow_mod() fm.priority = of.OFP_DEFAULT_PRIORITY fm.match.dl_type = pkt.ethernet.IP_TYPE fm.match.nw_dst = external_nw_addr fm.match.nw_proto = pkt.ipv4.UDP_PROTOCOL fm.match.tp_dst = update_tp_addr fm.actions.append(of.ofp_action_output(port=of.OFPP_CONTROLLER)) self.connection.send(fm) # Send new connections to the controller. fm.match.nw_proto = pkt.ipv4.TCP_PROTOCOL fm.match.nw_dst = external_nw_addr fm.match.tp_dst = external_tp_addr fm.actions.append(of.ofp_action_output(port=of.OFPP_CONTROLLER)) self.connection.send(fm) # Let the non-OpenFlow stack handle everything else. fm = of.ofp_flow_mod() fm.priority = of.OFP_DEFAULT_PRIORITY - 1 fm.actions.append(of.ofp_action_output(port=of.OFPP_NORMAL)) self.connection.send(fm)
def moly_set_entries(self): if self.connection.dpid == 1: # Set ARP forwarding self.send_flow_mod(in_port=1, dl_type=ETHERTYPE_ARP, actions=[of.ofp_action_output(port=4)]) self.send_flow_mod(in_port=4, dl_type=ETHERTYPE_ARP, actions=[of.ofp_action_output(port=1)]) # Set ICMP forwarding self.send_flow_mod(in_port=1, dl_type=ETHERTYPE_IPV4, nw_proto=IPPROTO_ICMP, actions=[of.ofp_action_output(port=4)]) self.send_flow_mod(in_port=4, dl_type=ETHERTYPE_IPV4, nw_proto=IPPROTO_ICMP, actions=[of.ofp_action_output(port=1)]) # Set TCP/UDP forwarding # h1 to DPI self.send_flow_mod(in_port=1, dl_type=ETHERTYPE_IPV4, nw_proto=IPPROTO_TCP, actions=[of.ofp_action_nw_tos(nw_tos=DSCP_IMM_1), of.ofp_action_output(port=2)]) self.send_flow_mod(in_port=1, dl_type=ETHERTYPE_IPV4, nw_proto=IPPROTO_UDP, actions=[of.ofp_action_nw_tos(nw_tos=DSCP_IMM_1), of.ofp_action_output(port=2)]) # h2 to DPI self.send_flow_mod(in_port=4, dl_type=ETHERTYPE_IPV4, nw_proto=IPPROTO_TCP, actions=[of.ofp_action_nw_tos(nw_tos=DSCP_IMM_2), of.ofp_action_output(port=2)]) self.send_flow_mod(in_port=4, dl_type=ETHERTYPE_IPV4, nw_proto=IPPROTO_UDP, actions=[of.ofp_action_nw_tos(nw_tos=DSCP_IMM_2), of.ofp_action_output(port=2)]) # DPI to MBOX self.send_flow_mod(in_port=2, dl_type=ETHERTYPE_IPV4, actions=[of.ofp_action_output(port=3)]) # MBOX to h2 self.send_flow_mod(in_port=3, dl_type=ETHERTYPE_IPV4, nw_tos=DSCP_IMM_1, actions=[of.ofp_action_nw_tos(nw_tos=DSCP_BEST_EFF), of.ofp_action_output(port=4)]) # MBOX to h1 self.send_flow_mod(in_port=3, dl_type=ETHERTYPE_IPV4, nw_tos=DSCP_IMM_2, actions=[of.ofp_action_nw_tos(nw_tos=DSCP_BEST_EFF), of.ofp_action_output(port=1)]) elif self.connection.dpid == 2: # Forward everything self.send_flow_mod(in_port=1, actions=[of.ofp_action_output(port=2)]) self.send_flow_mod(in_port=2, actions=[of.ofp_action_output(port=1)]) log.debug('MoLy setup completed')
def _handle_PacketIn (event): packet = event.parsed if packet.find("arp"): # Reply to ARP a = packet.find("arp") if a.opcode == a.REQUEST: r = pkt.arp() r.hwtype = a.hwtype r.prototype = a.prototype r.hwlen = a.hwlen r.protolen = a.protolen r.opcode = r.REPLY r.hwdst = a.hwsrc r.protodst = a.protosrc r.protosrc = a.protodst r.hwsrc = EthAddr("02:00:DE:AD:BE:EF") e = pkt.ethernet(type=packet.type, src=r.hwsrc, dst=a.hwsrc) e.payload = r msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT)) msg.in_port = event.port event.connection.send(msg) log.info("%s ARPed for %s", r.protodst, r.protosrc) elif packet.find("icmp"): # Reply to pings # Make the ping reply icmp = pkt.icmp() icmp.type = pkt.TYPE_ECHO_REPLY icmp.payload = packet.find("icmp").payload # Make the IP packet around it ipp = pkt.ipv4() ipp.protocol = ipp.ICMP_PROTOCOL ipp.srcip = packet.find("ipv4").dstip ipp.dstip = packet.find("ipv4").srcip # Ethernet around that... e = pkt.ethernet() e.src = packet.dst e.dst = packet.src e.type = e.IP_TYPE # Hook them up... ipp.payload = icmp e.payload = ipp # Send it back to the input port msg = of.ofp_packet_out() msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT)) msg.data = e.pack() msg.in_port = event.port event.connection.send(msg) log.debug("%s pinged %s", ipp.dstip, ipp.srcip)
def flow_port2pacth(mn1,mn2,rm): log.debug("Sent FLOW_MOD 2 at: %s", str(datetime.now())) # all nw_dst -> patch msg0 = of.ofp_flow_mod() msg0.priority = 100 msg0.match.dl_type = 0x800 msg0.match.nw_dst = listener_ip msg0.match.nw_proto = pkt.ipv4.UDP_PROTOCOL msg0.match.tp_dst = iperf_dst_port if mn1: msg0.actions.append(of.ofp_action_output(port = patchPort_n_mn1)) dpid_0 = mn1_br0_dpid elif mn2: msg0.actions.append(of.ofp_action_output(port = patchPort_n_mn2)) dpid_0 = mn2_br0_dpid else: return if rm: # remove redirect flow from br0 msg0.actions.append(of.OFPFC_DELETE_STRICT) core.openflow.sendToDPID(dpid_0,msg0) log.info(" Ended adding flow at: %s", str(datetime.now()))
def act_like_l2switch(self, event, packet): dst_port = None self.hwadr2Port[packet.src] = event.port if packet.dst not in (ETHER_ANY, ETHER_BROADCAST) and not packet.dst.is_multicast: dst_port = self.hwadr2Port.get(packet.dst, None) if dst_port is None: packet_in = event.ofp match = of.ofp_match.from_packet(packet) msg = of.ofp_flow_mod() msg = of.ofp_packet_out() msg.data = packet_in #log.debug("match info at %s: %s"%(self.name, match)) # Add an action to send to the specified port action = of.ofp_action_output(port = of.OFPP_ALL) msg.actions.append(action) # Send message to switch self.connection.send(msg) else: msg = of.ofp_flow_mod() msg.match.dl_dst = packet.src msg.match.dl_src = packet.dst msg.actions.append(of.ofp_action_output(port = event.port)) event.connection.send(msg) # This is the packet that just came in -- we want to # install the rule and also resend the packet. msg = of.ofp_flow_mod() msg.data = event.ofp # Forward the incoming packet msg.match.dl_src = packet.src msg.match.dl_dst = packet.dst msg.actions.append(of.ofp_action_output(port = dst_port)) event.connection.send(msg)
def flow_redirect (self, packet, packet_in): if packet.src not in self.mac_to_port: log.debug("==========> adding mac_to_port_entry: src = " + str(packet.src) + "; in_port = " + str(packet_in.in_port)) self.mac_to_port[packet.src] = packet_in.in_port if packet.dst == EthAddr("00:15:17:5d:13:6c"): log.debug("packet destination is node2, redirecting to node3...") msg = of.ofp_flow_mod() msg.match = of.ofp_match.from_packet(packet) msg.idle_timeout = 1200 msg.hard_timeout = 3600 msg.buffer_id = packet_in.buffer_id msg.priority = 65535 msg.actions.append(of.ofp_action_dl_addr.set_dst(EthAddr("00:15:17:5d:33:64"))) msg.actions.append(of.ofp_action_output(port = 3)) # msg.data = event.ofp log.debug("==========> Installing flow... src = " + str(packet.src) + "; dest = " + str(packet.dst) + "; port = 3") #packet.dst = EthAddr("00:15:17:57:c6:f1") self.connection.send(msg) # self.resend_packet(packet_in, 3) elif packet.dst in self.mac_to_port: log.debug("==========> Installing flow... src = " + str(packet.src) + "; dest = " + str(packet.dst) + "; port = " + str(self.mac_to_port[packet.dst])) msg = of.ofp_flow_mod() msg.match = of.ofp_match.from_packet(packet) msg.idle_timeout = 1200 msg.hard_timeout = 3600 msg.buffer_id = packet_in.buffer_id msg.actions.append(of.ofp_action_output(port = self.mac_to_port[packet.dst])) self.connection.send(msg) else: self.resend_packet(packet_in, of.OFPP_ALL)
def _handle_ConnectionUp(self, event): fm1 = of.ofp_flow_mod() fm1.priority -= 0x1000 fm1.match.dl_type = ethernet.ARP_TYPE fm1.match.nw_src = self.ip fm1.match.dl_src = self.mac fm1.match.nw_proto = arp.REQUEST fm1.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) event.connection.send(fm1) fm2 = of.ofp_flow_mod() fm2.priority -= 0x1000 fm2.match.dl_type = ethernet.ARP_TYPE fm2.match.nw_dst = self.ip fm2.match.dl_dst = self.mac fm2.match.nw_proto = arp.REPLY fm2.actions.append(of.ofp_action_output(port=of.OFPP_CONTROLLER)) event.connection.send(fm2) fm3 = of.ofp_flow_mod() fm3.priority -= 0x1000 fm3.match.dl_type = ethernet.ARP_TYPE fm3.match.nw_proto = arp.REQUEST fm3.actions.append(of.ofp_action_output(port=of.OFPP_CONTROLLER)) event.connection.send(fm3) fm4 = of.ofp_flow_mod() fm4.priority -= 0x1000 fm4.match.dl_type = ethernet.ARP_TYPE fm4.match.nw_proto = arp.REPLY fm4.actions.append(of.ofp_action_output(port=of.OFPP_NONE)) event.connection.send(fm4)
def _install_monitoring_path(prev_path, adj): match = ofp_match_withHash() match.dl_src = struct.pack("!Q", prev_path.src)[2:] #convert dpid to EthAddr match.dl_dst = struct.pack("!Q", prev_path.dst)[2:] match.dl_type = pkt.ethernet.IP_TYPE match.nw_proto = 253 # Use for experiment and testing match.nw_dst = IPAddr("224.0.0.255") #IANA Unassigned multicast addres match.nw_src = IPAddr(prev_path.__hash__()) #path hash dst_sw = prev_path.dst cur_sw = prev_path.dst msg = of.ofp_flow_mod() msg.match = match msg.idle_timeout = 30 #msg.flags = of.OFPFF_SEND_FLOW_REM msg.actions.append(of.ofp_action_output(port = of.OFPP_CONTROLLER)) log.debug("Installing monitoring forward from switch %s to controller port", util.dpid_to_str(cur_sw)) switches[dst_sw].connection.send(msg) next_sw = cur_sw cur_sw = prev_path.prev[next_sw] while cur_sw is not None: #for switch in path.keys(): msg = of.ofp_flow_mod() msg.match = match msg.idle_timeout = 10 #msg.flags = of.OFPFF_SEND_FLOW_REM log.debug("Installing monitoring forward from switch %s to switch %s output port %s", util.dpid_to_str(cur_sw), util.dpid_to_str(next_sw), adj[cur_sw][next_sw]) msg.actions.append(of.ofp_action_output(port = adj[cur_sw][next_sw])) switches[cur_sw].connection.send(msg) next_sw = cur_sw cur_sw = prev_path.prev[next_sw]
def _handle_PacketIn (event): packet = event.parsed # Learn the source table[(event.connection,packet.src)] = event.port dst_port = table.get((event.connection,packet.dst)) if dst_port is None: # We don't know where the destination is yet. So, we'll just # send the packet out all ports (except the one it came in on!) # and hope the destination is out there somewhere. :) msg = of.ofp_packet_out(data = event.ofp) msg.actions.append(of.ofp_action_output(port = all_ports)) event.connection.send(msg) else: # Since we know the switch ports for both the source and dest # MACs, we can install rules for both directions. msg = of.ofp_flow_mod() msg.match.dl_dst = packet.src msg.match.dl_src = packet.dst msg.actions.append(of.ofp_action_output(port = event.port)) event.connection.send(msg) # This is the packet that just came in -- we want to # install the rule and also resend the packet. msg = of.ofp_flow_mod() msg.data = event.ofp # Forward the incoming packet msg.match.dl_src = packet.src msg.match.dl_dst = packet.dst msg.actions.append(of.ofp_action_output(port = dst_port)) event.connection.send(msg) log.debug("Installing %s <-> %s" % (packet.src, packet.dst))
def _install (self, switch, in_port, out_port, match, buf = None, tree = False, mod_eth = False): if tree: msg = of.ofp_flow_mod() msg.match = match if in_port != None: msg.match.in_port = in_port msg.idle_timeout = FLOW_IDLE_TIMEOUT msg.hard_timeout = FLOW_HARD_TIMEOUT #log.debug('Out ports: %s:%s', str(switch), str(out_port)) if mod_eth: msg.actions.append(of.ofp_action_dl_addr.set_dst(EthAddr('ff:ff:ff:ff:ff:ff'))) msg.actions.append(of.ofp_action_nw_addr.set_dst(IPAddr('255.255.255.255'))) for op in out_port: msg.actions.append(of.ofp_action_output(port = op)) msg.buffer_id = buf switch.connection.send(msg) else: msg = of.ofp_flow_mod() msg.match = match msg.match.in_port = in_port msg.idle_timeout = FLOW_IDLE_TIMEOUT msg.hard_timeout = FLOW_HARD_TIMEOUT msg.actions.append(of.ofp_action_output(port = out_port)) msg.buffer_id = buf switch.connection.send(msg)
def disconnect(self,addr): self.action_triggered = False if self.droplist.has_key(addr): self.droplist[addr] += 1 else: self.droplist[addr] = 1 if self.droplist[addr] != 1: return ipaddr = IPAddr(addr) msg = of.ofp_flow_mod() msg.priority = MID if self.iptable.has_key(ipaddr) and self.iptable[ipaddr] != gateway_mac: #Forbid inside machine from sending packets host_mac = self.iptable[ipaddr] switchid = self.mactable[host_mac][0] msg.match.dl_type = 0x0800 msg.match.dl_src = host_mac msg.actions.append(of.ofp_action_output(port = of.OFPP_NONE)) else: switchid = self.mactable[gateway_mac][0] msg.match.dl_type = 0x0800 msg.match.nw_src = ipaddr msg.actions.append(of.ofp_action_output(port = of.OFPP_NONE)) switch = core.openflow.getConnection(switchid) switch.send(msg) self.action_triggered = True log.info("%s being disconncted"%addr)
def _handle_PacketIn_portmod(self, event): data, eth_packet, vlan_packet, ip_packet, tcp_packet = self.parsePacket(event) # print "*** " + str(eth_packet) + " " + str(vlan_packet) + " " + str(ip_packet) # Switch the request over to 5001 if tcp_packet and tcp_packet.dstport == 5000: match_clause = of.ofp_match.from_packet(eth_packet, event.port) dst_mac = eth_packet.dst out_port = self.lookup_port_for_mac(dst_mac) if out_port: set_dst_action_clause = of.ofp_action_tp_port.set_dst(5001); output_action_clause = of.ofp_action_output(port=out_port) action_clauses = [set_dst_action_clause, output_action_clause] msg = of.ofp_flow_mod(match=match_clause, actions=action_clauses) self._connection.send(msg) # Switch to response back to 5000 elif tcp_packet and tcp_packet.srcport == 5001: match_clause = of.ofp_match.from_packet(eth_packet, event.port) dst_mac = eth_packet.dst out_port = self.lookup_port_for_mac(dst_mac) if out_port: set_dst_action_clause = of.ofp_action_tp_port.set_src(5000); output_action_clause = of.ofp_action_output(port=out_port) action_clauses = [set_dst_action_clause, output_action_clause] msg = of.ofp_flow_mod(match=match_clause, actions=action_clauses) self._connection.send(msg) # Oherwise (not part of this test), handle the packet as is else: SimpleLearningSwitch._handle_PacketIn(self, event)
def _install_rewrite_dst_mcast_flow(self,switch_id,nw_src,ports,nw_mcast_dst,new_dst): """ Creates a flow table rule that rewrites the multicast address in the packet to the IP address of a downstream host. """ msg = of.ofp_flow_mod(command=of.OFPFC_ADD) msg.match = of.ofp_match(dl_type = ethernet.IP_TYPE, nw_src=nw_src, nw_dst = nw_mcast_dst) if isinstance(new_dst,list): # this part is only executed if multiple addresses need to be rewriteen (works because OF switches execute actions in order, meaning that each copy of the packet # is output before the next destination address rewrite takes place) for dst in new_dst: action = of.ofp_action_nw_addr.set_dst(IPAddr(dst)) msg.actions.append(action) new_mac_addr = self.arpTable[switch_id][dst].mac l2_action = of.ofp_action_dl_addr.set_dst(new_mac_addr) msg.actions.append(l2_action) for prt in ports[dst]: msg.actions.append(of.ofp_action_output(port = prt)) else: action = of.ofp_action_nw_addr.set_dst(IPAddr(new_dst)) msg.actions.append(action) new_mac_addr = self.arpTable[switch_id][new_dst].mac l2_action = of.ofp_action_dl_addr.set_dst(new_mac_addr) msg.actions.append(l2_action) for prt in ports: msg.actions.append(of.ofp_action_output(port = prt)) utils.send_msg_to_switch(msg, switch_id) self._cache_flow_table_entry(switch_id, msg)
def installL2Pair(self,event,port): '''If packet reaches installL2Pair, there's no match''' packet = event.parsed eth = packet.find('ethernet') # First, install the 'packet response' entry msg = of.ofp_flow_mod() msg.idle_timeout = FLOW_TIMEOUT msg.hard_timeout = 5*FLOW_TIMEOUT msg.match.dl_type = eth.type msg.match.dl_src = eth.dst msg.match.dl_dst = eth.src msg.match.in_port = port msg.actions.append(of.ofp_action_output(port = event.port)) event.connection.send(msg) # Then install forwarding rule and send packet msg = of.ofp_flow_mod() msg.idle_timeout = FLOW_TIMEOUT msg.hard_timeout = 5*FLOW_TIMEOUT msg.data = event.ofp msg.match.dl_type = eth.type msg.match.dl_src = eth.src msg.match.dl_dst = eth.dst msg.match.in_port = event.port msg.actions.append(of.ofp_action_output(port = port)) event.connection.send(msg)
def _handle_ConnectionUp(self, event): # XXX while debugging del all flows from switches msg = of.ofp_flow_mod(command = of.OFPFC_DELETE) conn = core.openflow.getConnection(event.dpid) conn.send(msg) log.debug('DISCOVERY: Clearing all flows from %s' % event.dpid) # install flow for all LLDP packets to be forward to controller msg = of.ofp_flow_mod() # LLDP Ether type msg.match.dl_type = 0x88cc # LLDP dest addr '01:80:c2:00:00:0e' msg.match.dl_dst = '\x01\x80\xc2\x00\x00\x0e' # LLDPs to controller msg.actions.append(of.ofp_action_output(port = of.OFPP_CONTROLLER)) event.connection.send(msg) log.debug('LLDP flow-mod configuration sent. Switch: %s' % event.dpid) # if dpid no scheduled, then do it! if not event.dpid in self.scheduled_switches: Timer(self.lldp_ttl, self.send_LLDP, args = [event], recurring = True) self.scheduled_switches.append(event.dpid) # install flow for al ARP packets to be forwarded to controller msg = of.ofp_flow_mod() # ARP Ether type msg.match.dl_type = 0x0806 msg.match.dl_dst = '\xff\xff\xff\xff\xff\xff' # ARPs to controller msg.actions.append(of.ofp_action_output(port = of.OFPP_CONTROLLER)) event.connection.send(msg) log.debug('ARP flow-mod configuration sent. Switch: %s' % event.dpid)
def _handle_openflow_PacketIn(self, event): # print ("Packet in") dpid = event.connection.dpid inport = event.port packet = event.parsed if not packet.parsed: log.warning("%i %i ignoring unparsed packet", dpid, inport) return if dpid not in self.arpTable: # New switch -- create an empty table self.arpTable[dpid] = {} for fake in self.fakeways: self.arpTable[dpid][IPAddr(fake)] = Entry( of.OFPP_NONE, dpid_to_mac(dpid)) if packet.type == ethernet.LLDP_TYPE: # Ignore LLDP packets return if isinstance(packet.next, ipv4): log.debug("%i %i IP %s => %s", dpid, inport, packet.next.srcip, packet.next.dstip) # Send any waiting packets... self._send_lost_buffers(dpid, packet.next.srcip, packet.src, inport) # Learn or update port/MAC info if packet.next.srcip in self.arpTable[dpid]: if self.arpTable[dpid][packet.next.srcip] != (inport, packet.src): log.info("%i %i RE-learned %s", dpid, inport, packet.next.srcip) if self.wide: # Make sure we don't have any entries with the old info... msg = of.ofp_flow_mod( command=of.OFPFC_DELETE ) #delete all flows in flow table msg.match.nw_dst = packet.next.srcip msg.match.dl_type = ethernet.IP_TYPE event.connection.send(msg) else: log.debug("%i %i learned %s", dpid, inport, packet.next.srcip) self.arpTable[dpid][packet.next.srcip] = Entry(inport, packet.src) # Try to forward dstaddr = packet.next.dstip if dstaddr in self.arpTable[dpid]: # We have info about what port to send it out on... prt = self.arpTable[dpid][dstaddr].port mac = self.arpTable[dpid][dstaddr].mac if prt == inport: log.warning( "%i %i not sending packet for %s back out of the " "input port" % (dpid, inport, dstaddr)) else: log.debug( "%i %i installing flow for %s => %s out port %i" % (dpid, inport, packet.next.srcip, dstaddr, prt)) actions = [] actions.append(of.ofp_action_dl_addr.set_dst(mac)) actions.append(of.ofp_action_output(port=prt)) if self.wide: match = of.ofp_match(dl_type=packet.type, nw_dst=dstaddr) else: match = of.ofp_match.from_packet(packet, inport) msg = of.ofp_flow_mod(command=of.OFPFC_ADD, idle_timeout=FLOW_IDLE_TIMEOUT, hard_timeout=of.OFP_FLOW_PERMANENT, buffer_id=event.ofp.buffer_id, actions=actions, match=match) event.connection.send(msg.pack()) elif self.arp_for_unknowns: # We don't know this destination. # First, we track this buffer so that we can try to resend it later # if we learn the destination, second we ARP for the destination, # which should ultimately result in it responding and us learning # where it is # Add to tracked buffers if (dpid, dstaddr) not in self.lost_buffers: self.lost_buffers[(dpid, dstaddr)] = [] bucket = self.lost_buffers[(dpid, dstaddr)] entry = (time.time() + MAX_BUFFER_TIME, event.ofp.buffer_id, inport) bucket.append(entry) while len(bucket) > MAX_BUFFERED_PER_IP: del bucket[0] # Expire things from our outstanding ARP list... self.outstanding_arps = { k: v for k, v in self.outstanding_arps.iteritems() if v > time.time() } # Check if we've already ARPed recently if (dpid, dstaddr) in self.outstanding_arps: # Oop, we've already done this one recently. return # And ARP... self.outstanding_arps[(dpid, dstaddr)] = time.time() + 4 r = arp() r.hwtype = r.HW_TYPE_ETHERNET r.prototype = r.PROTO_TYPE_IP r.hwlen = 6 r.protolen = r.protolen r.opcode = r.REQUEST r.hwdst = ETHER_BROADCAST r.protodst = dstaddr r.hwsrc = packet.src r.protosrc = packet.next.srcip e = ethernet(type=ethernet.ARP_TYPE, src=packet.src, dst=ETHER_BROADCAST) e.set_payload(r) log.debug("%i %i ARPing for %s on behalf of %s" % (dpid, inport, r.protodst, r.protosrc)) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) msg.in_port = inport event.connection.send(msg) print("ARPing") elif isinstance(packet.next, arp): a = packet.next log.debug("%i %i ARP %s %s => %s", dpid, inport, { arp.REQUEST: "request", arp.REPLY: "reply" }.get(a.opcode, 'op:%i' % (a.opcode, )), a.protosrc, a.protodst) if a.prototype == arp.PROTO_TYPE_IP: if a.hwtype == arp.HW_TYPE_ETHERNET: if a.protosrc != 0: # Learn or update port/MAC info if a.protosrc in self.arpTable[dpid]: if self.arpTable[dpid][a.protosrc] != (inport, packet.src): log.info("%i %i RE-learned %s", dpid, inport, a.protosrc) if self.wide: # Make sure we don't have any entries with the old info... msg = of.ofp_flow_mod( command=of.OFPFC_DELETE) msg.match.dl_type = ethernet.IP_TYPE msg.match.nw_dst = a.protosrc event.connection.send(msg) else: log.debug("%i %i learned %s", dpid, inport, a.protosrc) self.arpTable[dpid][a.protosrc] = Entry( inport, packet.src) # Send any waiting packets... self._send_lost_buffers(dpid, a.protosrc, packet.src, inport) if a.opcode == arp.REQUEST: # Maybe we can answer if a.protodst in self.arpTable[dpid]: # We have an answer... if not self.arpTable[dpid][ a.protodst].isExpired(): # .. and it's relatively current, so we'll reply ourselves r = arp() r.hwtype = a.hwtype r.prototype = a.prototype r.hwlen = a.hwlen r.protolen = a.protolen r.opcode = arp.REPLY r.hwdst = a.hwsrc r.protodst = a.protosrc r.protosrc = a.protodst r.hwsrc = self.arpTable[dpid][ a.protodst].mac e = ethernet(type=packet.type, src=dpid_to_mac(dpid), dst=a.hwsrc) e.set_payload(r) log.debug("%i %i answering ARP for %s" % (dpid, inport, r.protosrc)) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append( of.ofp_action_output( port=of.OFPP_IN_PORT)) msg.in_port = inport event.connection.send(msg) print("ARP2!1") return # Didn't know how to answer or otherwise handle this ARP, so just flood it log.debug("%i %i flooding ARP %s %s => %s" % (dpid, inport, { arp.REQUEST: "request", arp.REPLY: "reply" }.get(a.opcode, 'op:%i' % (a.opcode, )), a.protosrc, a.protodst)) msg = of.ofp_packet_out( in_port=inport, data=event.ofp, action=of.ofp_action_output(port=of.OFPP_FLOOD)) event.connection.send(msg)
def _handle_ConnectionUp(event): ####################### REGRAS PRINCIPAIS ############################# #Instala a regra de ida (alterar os numeros das portas, se preciso) msg1 = of.ofp_flow_mod() msg1.match.in_port = 13 msg1.priority = 10 msg1.actions.append(of.ofp_action_output(port=21)) event.connection.send(msg1) #Instala a regra de volta (alterar os numeros das portas, se preciso) msg2 = of.ofp_flow_mod() msg2.match.in_port = 21 msg2.priority = 10 msg2.actions.append(of.ofp_action_output(port=13)) event.connection.send(msg2) #Regra de encaminhamento para o controlador msgc = of.ofp_flow_mod() msgc.match.in_port = 24 msgc.priority = 2 msgc.actions.append(of.ofp_action_output(port=of.OFPP_NORMAL)) event.connection.send(msgc) #Regra de drop para miss msg0 = of.ofp_flow_mod() msg0.priority = 1 event.connection.send(msg0) #################### REGRAS COMPLEMENTARES ################################### ''' #Permite a passagem de regras ARP (ida e volta) msg3 = of.ofp_flow_mod() msg3.match.in_port = 13 msg3.match.dl_type = 0x0806 msg3.actions.append(of.ofp_action_output(port = 21)) event.connection.send(msg3) msg3 = of.ofp_flow_mod() msg3.match.in_port = 21 msg3.match.dl_type = 0x0806 msg3.actions.append(of.ofp_action_output(port = 13)) event.connection.send(msg3) #Permite a troca de pacotes SSH (se necessario) msg3 = of.ofp_flow_mod() msg3.match.in_port = 13 msg3.match.dl_type = 0x0800 msg3.match.nw_proto = 6 # tcp = 6 e udp = 17 msg3.match.tp_dst = 22 msg3.actions.append(of.ofp_action_output(port = 21)) event.connection.send(msg3) msg3 = of.ofp_flow_mod() msg3.match.in_port = 21 msg3.match.dl_type = 0x0800 msg3.match.nw_proto = 6 # tcp = 6 e udp = 17 msg3.match.tp_src = 22 msg3.actions.append(of.ofp_action_output(port = 13)) event.connection.send(msg3) ''' log.info("Regras instaladas no switch %s.", dpidToStr(event.dpid)) event.connection.send(of.ofp_barrier_request(xid=77771))
def __init__(self, connection, transparent): # Switch we'll be adding L2 learning switch capabilities to self.connection = connection self.transparent = transparent # We want to hear PacketIn messages, so we listen # to the connection connection.addListeners(self) log.debug("Initializing LearningSwitch, transparent=%s", str(self.transparent)) #def sendCflowMsg (self): log.debug("installing flow for") msg1 = of.ofp_flow_mod() msg1.command = OFPFC_ADD msg1.idle_timeout = 11 msg1.hard_timeout = 31 msg1.actions.append(of.ofp_action_output(port=1)) #self.connection.send(msg1) msgFeature = of.ofp_features_reply() msgFeature.n_tables = 1 ports = [] port1 = ofp_phy_port() port1.port_no = 123 port1.name = "port1" port2 = ofp_phy_port() port2.port_no = 124 ports.append(port1) ports.append(port2) msgFeature.ports = ports #self.connection.send(msgFeature) msg = of.ofp_cflow_mod() msg.command = OFPFC_ADD msg.hard_timeout = 31 msg.connect.wildcards = 3840 msg.connect.num_components = 1 #msg.connect.in_port = 2001 #msg.connect.out_port = 1101 ''' msgWave = msg.connect msgWave.in_wport = 101 msgWave.out_wport = 201 msgWaveIN = ofp_wave_port() msgWaveIN.wport = 101 msgWaveIN.wavelength = 31 msgWaveOUT = ofp_wave_port msgWaveOUT.wport = 201 msgWaveOUT.wavelength = 31 ''' wport1 = [] wport2 = [] wportin1 = ofp_wave_port() wportin1.wport = 122 wportin1.wavelength = 111 wportout1 = ofp_wave_port() wportout1.wport = 123 wportout1.wavelength = 222 wport1.append(wportin1) wport2.append(wportout1) msg.connect.in_wport = wport1 msg.connect.out_wport = wport2 #log.debug("sending XC flow for", msg) self.connection.send(msg)
def install_SDN_path(): #s2收到h1的probe后 msg = of.ofp_flow_mod() msg.match = monitor.match.clone() #匹配h1 msg.match.tp_dst, msg.match.tp_src = (None,) * 2 msg.match.nw_src = IPAddr('10.0.0.1') msg.match.nw_dst = IPAddr('10.0.0.2') msg.match.in_port = monitor.switch_port #转发 for l2node in adj_path[2].keys(): msg.actions.append(of.ofp_action_output(port=adj[monitor.dpid][l2node])) # print monitor.dpid temp_path = [] temp_path.append(2) msg.actions.append(of.ofp_action_tp_port.set_src(tp_port=path_id[tuple(temp_path)])) msg.actions.append(of.ofp_action_nw_addr.set_dst(nw_addr = monitor.ip)) msg.actions.append(of.ofp_action_nw_addr.set_src(nw_addr = IPAddr('10.0.0.2'))) msg.actions.append(of.ofp_action_dl_addr.set_dst(dl_addr = monitor.hw)) msg.actions.append(of.ofp_action_dl_addr.set_src(dl_addr = EthAddr("00:00:00:00:00:02"))) msg.actions.append(of.ofp_action_output(port=of.OFPP_IN_PORT)) switches[monitor.dpid].connection.send(msg) #l2收到s2的probe后 for l2node in adj_path[2].keys(): msg = of.ofp_flow_mod(match=monitor.match.clone()) #匹配 msg.match.tp_dst, msg.match.tp_src = (None,) * 2 msg.match.nw_src = IPAddr('10.0.0.1') msg.match.nw_dst = IPAddr('10.0.0.2') msg.match.in_port = adj[l2node][monitor.dpid] #向下转发 for l3node in adj_path[2][l2node].keys(): msg.actions.append(of.ofp_action_nw_addr.set_src(nw_addr = switches_ip[l2node])) msg.actions.append(of.ofp_action_output(port=adj[l2node][l3node])) #修改udp_port,发送回s2 temp_path = [] temp_path.append(2) temp_path.append(l2node) temp_path = tuple(temp_path) msg.actions.append(of.ofp_action_tp_port.set_src(tp_port=path_id[temp_path])) msg.actions.append(of.ofp_action_output(port=of.OFPP_IN_PORT)) switches[l2node].connection.send(msg) # l3收到l2的probe以后 for l2node in adj_path[2].keys(): for l3node in adj_path[2][l2node].keys(): msg = of.ofp_flow_mod(match=monitor.match.clone()) # 匹配 msg.match.tp_dst, msg.match.tp_src = (None,) * 2 msg.match.nw_src = switches_ip[l2node] msg.match.nw_dst = IPAddr('10.0.0.2') msg.match.in_port = adj[l3node][l2node] # 向下转发 for l4node in adj_path[2][l2node][l3node]: msg.actions.append(of.ofp_action_output(port=adj[l3node][l4node])) #modify and send back temp_path = [] temp_path.append(2) temp_path.append(l2node) temp_path.append(l3node) temp_path = tuple(temp_path) msg.actions.append(of.ofp_action_tp_port.set_src(tp_port=path_id[temp_path])) msg.actions.append(of.ofp_action_output(port=of.OFPP_IN_PORT)) switches[l3node].connection.send(msg) #l4节点收到l3probe以后 for l2node in adj_path[2].keys(): for l3node in adj_path[2][l2node].keys(): for l4node in adj_path[2][l2node][l3node]: msg = of.ofp_flow_mod(match=monitor.match.clone()) # 匹配 msg.match.tp_dst, msg.match.tp_src = (None,) * 2 msg.match.nw_src = switches_ip[l2node] msg.match.nw_dst = IPAddr('10.0.0.2') msg.match.in_port = adj[l4node][l3node] # 向下转发 for l5node in adj_path[2][l2node][l3node][l4node]: msg.actions.append(of.ofp_action_output(port=adj[l4node][l5node])) #modify and send back temp_path = [] temp_path.append(2) temp_path.append(l2node) temp_path.append(l3node) temp_path.append(l4node) temp_path = tuple(temp_path) msg.actions.append(of.ofp_action_tp_port.set_src(tp_port=path_id[temp_path])) msg.actions.append(of.ofp_action_output(port=of.OFPP_IN_PORT)) switches[l4node].connection.send(msg) #l5节点收到l4probe以后 for l2node in adj_path[2].keys(): for l3node in adj_path[2][l2node].keys(): for l4node in adj_path[2][l2node][l3node]: for l5node in adj_path[2][l2node][l3node][l4node]: msg = of.ofp_flow_mod(match=monitor.match.clone()) # 匹配 msg.match.tp_dst, msg.match.tp_src = (None,) * 2 msg.match.nw_src = switches_ip[l2node] msg.match.nw_dst = IPAddr('10.0.0.2') msg.match.in_port = adj[l5node][l4node] #modify and send back temp_path = [];temp_path.append(2);temp_path.append(l2node) temp_path.append(l3node);temp_path.append(l4node) temp_path.append(l5node);temp_path = tuple(temp_path) msg.actions.append(of.ofp_action_tp_port.set_src(tp_port=path_id[temp_path])) msg.actions.append(of.ofp_action_output(port=of.OFPP_IN_PORT)) switches[l5node].connection.send(msg) #l4收到l5的probe以后 for l2node in adj_path[2].keys(): for l3node in adj_path[2][l2node].keys(): for l4node in adj_path[2][l2node][l3node]: for l5node in adj_path[2][l2node][l3node][l4node]: msg = of.ofp_flow_mod(match=monitor.match.clone()) # 匹配 msg.match.tp_dst, msg.match.tp_src = (None,) * 2 msg.match.nw_src = switches_ip[l2node] msg.match.nw_dst = IPAddr('10.0.0.2') msg.match.in_port = adj[l4node][l5node] #往上转发 msg.actions.append(of.ofp_action_output(port=adj[l4node][l3node])) switches[l4node].connection.send(msg) #l3收到l4的probe以后 for l2node in adj_path[2].keys(): for l3node in adj_path[2][l2node].keys(): for l4node in adj_path[2][l2node][l3node]: msg = of.ofp_flow_mod(match=monitor.match.clone()) # 匹配 msg.match.tp_dst, msg.match.tp_src = (None,) * 2 msg.match.nw_src = switches_ip[l2node] msg.match.nw_dst = IPAddr('10.0.0.2') msg.match.in_port = adj[l3node][l4node] #往上转发 msg.actions.append(of.ofp_action_output(port=adj[l3node][l2node])) switches[l3node].connection.send(msg) #l2节点收到l3的probe以后 for l2node in adj_path[2].keys(): for l3node in adj_path[2][l2node].keys(): msg = of.ofp_flow_mod(match=monitor.match.clone()) msg.match.tp_dst, msg.match.tp_src = (None,) * 2 msg.match.nw_src = switches_ip[l2node] msg.match.nw_dst = IPAddr('10.0.0.2') msg.match.in_port = adj[l2node][l3node] #往上转发 msg.actions.append(of.ofp_action_output(port=adj[l2node][monitor.dpid])) switches[l2node].connection.send(msg) log.debug('monitor num') #s2收到l2的probe后 for l2node in adj_path[2].keys(): msg = of.ofp_flow_mod() msg.match = monitor.match.clone() #匹配 msg.match.tp_dst, msg.match.tp_src = (None,) * 2 msg.match.nw_dst = IPAddr('10.0.0.2') msg.match.nw_src = switches_ip[l2node] msg.match.in_port = adj[monitor.dpid][l2node] #修改IP msg.actions.append(of.ofp_action_nw_addr.set_dst(nw_addr = monitor.ip)) msg.actions.append(of.ofp_action_nw_addr.set_src(nw_addr = IPAddr('10.0.0.2'))) msg.actions.append(of.ofp_action_dl_addr.set_dst(dl_addr = monitor.hw)) msg.actions.append(of.ofp_action_dl_addr.set_src(dl_addr = EthAddr("00:00:00:00:00:02"))) msg.actions.append(of.ofp_action_output(port=monitor.switch_port)) switches[monitor.dpid].connection.send(msg)
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 _handle_PacketIn(self, event): """ Handles packet in messages from the switch to implement above algorithm. """ pkt = event.parse() #code.interact(local=locals()) #log.debug("OFHandler: Got OF PacketIN!\n") if (event.port == 3 and pkt.type == ethernet.ARP_TYPE and pkt.next.opcode == arp.REQUEST): arp_req = pkt.next #log.debug("\nGot a packet request from port 3, flood it\n") arp_reply = arp() arp_reply.hwtype = arp_req.hwtype arp_reply.prototype = arp_req.prototype arp_reply.hwlen = arp_req.hwlen arp_reply.protolen = arp_req.protolen arp_reply.opcode = arp.REPLY arp_reply.protodst = arp_req.protosrc arp_reply.protosrc = arp_req.protodst arp_reply.hwsrc = EthAddr(self.sw_info["eth3"][1]) arp_reply.hwdst = arp_req.hwsrc e = ethernet(type=pkt.type, src=arp_reply.hwsrc, dst=arp_req.hwsrc) e.payload = arp_reply msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append(of.ofp_action_output(port=of.OFPP_IN_PORT)) msg.in_port = event.port event.connection.send(msg) elif (event.port == 3): #log.debug("OFHandler: raise SRPacketIn event\n") #log.debug("OFHandler: packet from outside, translate address\n") #implement an internal NAT here packet = event.parse() #print 'original packet: ', packet if (packet.type == ethernet.IP_TYPE): ip_pkt = packet.next #print INTERNAL_IP.keys() #print IP_SETTING.values() #print ip_pkt.dstip dst_ip = ip_pkt.dstip.toStr() src_ip = ip_pkt.srcip.toStr() if (dst_ip in INTERNAL_IP.keys()): #print "change IP destination\n" ip_pkt.dstip = IPAddr(IP_SETTING[INTERNAL_IP[dst_ip]]) ip_pkt.csum = ip_pkt.checksum() # ip_pkt.raw = ip_pkt.pack() ip_pkt.raw = None packet.next = ip_pkt elif (packet.type == ethernet.ARP_TYPE): if (packet.next.opcode == arp.REPLY): arp_reply = packet.next dst_ip = arp_reply.protodst.toStr() if (dst_ip in INTERNAL_IP.keys()): #print "change arp reply dst \n" arp_reply.protodst = IPAddr( IP_SETTING[INTERNAL_IP[dst_ip]]) #print arp_reply.protodst arp_reply.raw = None packet.next = arp_reply #print "modified packet: ", packet raw_packet = packet.pack() core.cs144_ofhandler.raiseEvent(SRPacketIn(raw_packet, event.port)) else: raw_packet = pkt.raw core.cs144_ofhandler.raiseEvent(SRPacketIn(raw_packet, event.port)) # Drop this packet as we won't reference it. Just trying to be # safe so that OVS's/vswitchd's buffer doesn't have stale packets. msg = of.ofp_packet_out() msg.buffer_id = event.ofp.buffer_id msg.in_port = event.port self.connection.send(msg)
def _handle_SRPacketOut(self, event): msg = of.ofp_packet_out() new_packet = event.pkt if (event.port == 3): #out going packet, need to go through NAT packet = ethernet(raw=event.pkt) if (packet.type == ethernet.IP_TYPE): #print "in SRPacketOut" #print packet ip_pkt = ipv4(raw=event.pkt[ethernet.MIN_LEN:]) if (ip_pkt.protocol == ipv4.UDP_PROTOCOL and ip_pkt.next.dstport == 53): src_ip = ip_pkt.srcip.toStr() if (src_ip in IP_SETTING.values()): ip_pkt.srcip = IPAddr( INTERNAL_NAME[NAME_SETTING[src_ip]]) ip_pkt.csum = ip_pkt.checksum() packet.next = ip_pkt #new_packet = packet.pack() #event.pkt[ethernet.MIN_LEN:ipv4.hl] = ip_pkt.tyhdr() #ipp = ip_pkt #event.pkt[ethernet.MIN_LEN:ip_pkt.hl] = struct.pack('!BBHHHBBHII', (ipp.v << 4) + ipp.hl, ipp.tos, ipp.iplen, ipp.id, (ipp.flags << 13) | ipp.frag, ipp.ttl, ipp.protocol, ipp.csum, ipp.srcip.toUnsigned(), ipp.dstip.toUnsigned()) #npkt = ipv4(raw=event.pkt[ethernet.MIN_LEN:]) #print npkt # udp_pkt= ip_pkt.next # dns_pkt = udp_pkt.next # print dns_pkt # d = dns() # u = udp() # ipp = ipv4() # ipp.protocol = ipp.UDP_PROTOCOL # ipp.srcip = IPAddr(INTERNAL_NAME[NAME_SETTING[src_ip]]) # ipp.dstip = ip_pkt.dstip # e = ethernet() # e.src = packet.src # e.dst = packet.dst # e.type = e.IP_TYPE # ipp.payload = udp_pkt # e.payload = ipp # new_packet = e.pack() else: src_ip = ip_pkt.srcip.toStr() #print ip_pkt.srcip if (src_ip in IP_SETTING.values()): # print "change IP src\n" ip_pkt.srcip = IPAddr( INTERNAL_NAME[NAME_SETTING[src_ip]]) # print ip_pkt.srcip ip_pkt.csum = ip_pkt.checksum() ip_pkt.raw = None packet.next = ip_pkt if (ip_pkt.protocol == ipv4.ICMP_PROTOCOL): icmp_pkt = ip_pkt.next icmp_pkt.raw = None if (icmp_pkt.type == 3): ip_hdr = icmp_pkt.next.next ip_hdr.dstip = IPAddr( INTERNAL_NAME[NAME_SETTING[src_ip]]) #print "Replace icmp MSG IP addr !!!!\n" #print icmp_pkt new_packet = packet.pack() elif (packet.type == ethernet.ARP_TYPE): if (packet.next.opcode == arp.REQUEST): # print "get a arp request" arp_req = packet.next src_ip = arp_req.protosrc.toStr() if (src_ip in IP_SETTING.values()): # print "change arp request src \n" arp_req.protosrc = IPAddr( INTERNAL_NAME[NAME_SETTING[src_ip]]) # print arp_req.protosrc arp_req.raw = None packet.next = arp_req new_packet = packet.pack() msg.actions.append(of.ofp_action_output(port=event.port)) msg.buffer_id = -1 msg.in_port = of.OFPP_NONE msg.data = new_packet #log.debug("SRServer catch SRPacketOut event, fwd_pkt=%r, port=%s\n" % (event.pkt, event.port)) self.connection.send(msg)
def _handle_PacketIn(self, event): #log.debug("Connection packet in %s at switch %s" % (event.connection, dpid_to_str(event.dpid))) packet = event.parsed '''if isinstance(packet.next, ipv4): log.debug("%i %i IP %s => %s", event.dpid,event.port, packet.next.srcip,packet.next.dstip) #log.debug("%i %i IP ", event.dpid, event.port) elif isinstance(packet.next, arp): log.debug("%i %i arp ", event.dpid, event.port) elif isinstance(packet.next, icmp): log.debug("%i %i icmp ", event.dpid,event.port) else: log.debug("%i %i not known protocol ", event.dpid, event.port)''' #packet is arp if isinstance(packet.next, arp): '''log.debug("ARP!!!!!!!!!!!!!!!") log.debug("destination address is %s" % packet.dst) log.debug("source address is %s" % packet.src) log.debug("dest ip address %s" %packet.next.protodst)''' outport = 0 switch = switch_dpid_name[dpid_to_str(event.dpid)] if packet.next.protodst == fake_ip_address: if packet.next.protosrc in client_ip_addresses: outport = total_client_num + 1 if dpid_to_str(event.dpid) != "00-00-00-00-00-01": print "wrong switch has arp src is client dst is fake!!!!!!!!!!!!!!!!!!!!!!!!!!!!" elif packet.next.protosrc in server_ip_addresses: server_num = server_ip_addresses.index( packet.next.protosrc) + 1 switches = servers[server_num].get_path() switch = switch_dpid_name[dpid_to_str(event.dpid)] if switches.index(switch) == 0: outport = total_client_num + 1 else: downlink_switch = switches[switches.index(switch) - 1] outport = switch_switch_adjacency[downlink_switch][ switch][2] elif packet.next.protodst in client_ip_addresses: if packet.next.protosrc in client_ip_addresses or packet.next.protosrc == fake_ip_address: client_num = client_ip_addresses.index( packet.next.protodst) + 1 outport = switch_client_port[client_num] if dpid_to_str(event.dpid) != "00-00-00-00-00-01": print "wrong switch has arp src is client dst is fake!!!!!!!!!!!!!!!!!!!!!!!!!!!!" elif packet.next.protosrc in server_ip_addresses: server_num = server_ip_addresses.index( packet.next.protosrc) + 1 switches = servers[server_num].get_path() switch = switch_dpid_name[dpid_to_str(event.dpid)] if switches.index(switch) == 0: client_num = client_ip_addresses.index( packet.next.protodst) + 1 outport = switch_client_port[client_num] else: downlink_switch = switches[switches.index(switch) - 1] outport = switch_switch_adjacency[downlink_switch][ switch][2] elif packet.next.protodst in server_ip_addresses: if packet.next.protosrc in client_ip_addresses or packet.next.protosrc == fake_ip_address: server_num = server_ip_addresses.index( packet.next.protodst) + 1 switches = servers[server_num].get_path() switch = switch_dpid_name[dpid_to_str(event.dpid)] if switches.index(switch) < len(switches) - 1: downlink_switch = switches[switches.index(switch) + 1] outport = switch_switch_adjacency[switch][ downlink_switch][1] else: outport = switch_server_port[server_num][switch] '''elif packet.next.protosrc in server_ip_addresses: log.debug("wrong arp server -> server!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ") #src server -> sw1 server_num = server_ip_addresses.index(packet.next.protosrc) + 1 switches = servers[server_num].get_path() switch = switch_dpid_name[dpid_to_str(event.dpid)] downlink_switch = switches[switches.index(switch) - 1] outport1 = switch_switch_adjacency[downlink_switch][switch][2] if switches.index(switch) < len(switches) - 1: uplink_switch = switches[switches.index(switch) + 1] inport1 = switch_switch_adjacency[switch][uplink_switch][1] else: inport1 = switch_server_port[server_num][switch] msg = of.ofp_packet_out() msg.data = event.ofp msg.match = of.ofp_match.from_packet(packet) msg.match.in_port = inport1 msg.idle_timeout = 10 #msg.in_port = event.port msg.actions.append(of.ofp_action_output(port = outport1)) core.openflow.sendToDPID(str_to_dpid(switch_name_dpid[switch]), msg) log.debug("Installing arp at %s" % switch) #sw1 -> dst server server_num = server_ip_addresses.index(packet.next.protodst) + 1 switches = servers[server_num].get_path() switch = switch_dpid_name[dpid_to_str(event.dpid)] if switches.index(switch) < len(switches) - 1: downlink_switch = switches[switches.index(switch) + 1] outport2 = switch_switch_adjacency[switch][downlink_switch][1] else: outport2 = switch_server_port[server_num][switch] msg = of.ofp_packet_out() msg.data = event.ofp msg.match = of.ofp_match.from_packet(packet) msg.idle_timeout = 10 #msg.in_port = event.port msg.actions.append(of.ofp_action_output(port = outport)) event.connection.send(msg)''' msg = of.ofp_packet_out() msg.data = event.ofp msg.match = of.ofp_match.from_packet(packet) msg.idle_timeout = 10 #msg.in_port = event.port msg.actions.append(of.ofp_action_output(port=outport)) core.openflow.sendToDPID(str_to_dpid(switch_name_dpid[switch]), msg) #log.debug("Installing arp at %s" % switch) #packet is normal ip elif isinstance(packet.next, ipv4): #log.debug("IP!!!!!!!!!") #print("packet.next.dstip is %s, pack.dst is %s" % (packet.next.dstip.toStr(), packet.dst.toStr())) #establish bi-direction flow tables on switches along the shortest path #client->server if packet.next.dstip == fake_ip_address: server_num = self._calc_server(packet) print "dst_server_num: " + str(server_num) global server_count server_count[server_num] += 1 if load_balancing_path: servers[server_num].update_path() switches = servers[server_num].get_path() switch = switch_dpid_name[dpid_to_str(event.dpid)] if switches.index(switch) < len(switches) - 1: downlink_switch = switches[switches.index(switch) + 1] outport = switch_switch_adjacency[switch][downlink_switch][ 1] else: outport = switch_server_port[server_num][switch] new_dl_dst = servers[server_num].macAddr new_nw_dst = servers[server_num].ipAddr #print ("client->server") #rewrite at gateway #print ("i is %i, outport is %i, dst is %s, src is %s" % (switches.index(switch), outport, new_dl_dst.toStr(), packet.src.toStr())) msg = of.ofp_flow_mod() msg.data = event.ofp msg.match.dl_dst = packet.dst msg.match.dl_src = packet.src msg.match.dl_type = packet.type msg.idle_timeout = 1 msg.actions.append(of.ofp_action_dl_addr.set_dst(new_dl_dst)) msg.actions.append(of.ofp_action_nw_addr.set_dst(new_nw_dst)) msg.actions.append(of.ofp_action_output(port=outport)) core.openflow.sendToDPID(str_to_dpid(switch_name_dpid[switch]), msg) #log.debug("Installing at %s" % switch) elif packet.next.dstip in server_ip_addresses: server_num = server_ip_addresses.index(packet.next.dstip) + 1 switches = servers[server_num].get_path() switch = switch_dpid_name[dpid_to_str(event.dpid)] if switches.index(switch) < len(switches) - 1: downlink_switch = switches[switches.index(switch) + 1] outport = switch_switch_adjacency[switch][downlink_switch][ 1] else: outport = switch_server_port[server_num][switch] new_dl_dst = servers[server_num].macAddr new_nw_dst = servers[server_num].ipAddr #print ("client->server") #print ("i is %i, outport is %i, dst is %s, src is %s" % (switches.index(switch), outport, new_dl_dst.toStr(), packet.src.toStr())) msg = of.ofp_flow_mod() msg.data = event.ofp msg.match.dl_dst = new_dl_dst msg.match.dl_src = packet.src msg.match.dl_type = packet.type msg.idle_timeout = 1 msg.actions.append(of.ofp_action_output(port=outport)) core.openflow.sendToDPID(str_to_dpid(switch_name_dpid[switch]), msg) #log.debug("Installing at %s" % switch) #server->client elif packet.next.srcip in server_ip_addresses: #print ("server->client") server_num = server_ip_addresses.index(packet.next.srcip) + 1 switches = servers[server_num].get_path() switch = switch_dpid_name[dpid_to_str(event.dpid)] if switches.index(switch) == 0: client_num = self._get_client_num(packet.dst) outport = switch_client_port[client_num] else: downlink_switch = switches[switches.index(switch) - 1] outport = switch_switch_adjacency[downlink_switch][switch][ 2] #print ("i is %i, outport is %i, dst is %s, src is %s" % (switches.index(switch), outport, packet.dst, packet.src)) msg = of.ofp_flow_mod() msg.data = event.ofp msg.match.dl_dst = packet.dst msg.match.dl_src = packet.src msg.match.dl_type = packet.type msg.idle_timeout = 1 #rewrite at gateway if switches.index(switch) == 0: new_dl_src = fake_mac_address new_nw_src = fake_ip_address msg.actions.append( of.ofp_action_dl_addr.set_src(new_dl_src)) msg.actions.append( of.ofp_action_nw_addr.set_src(new_nw_src)) msg.actions.append(of.ofp_action_output(port=outport)) core.openflow.sendToDPID(str_to_dpid(switch_name_dpid[switch]), msg) #log.debug("Installing at %s" % switch) #drop other packets ############## if there are other useful packets this might be wrong '''else:
def resend_packet(self, packet_in, out_port): msg = of.ofp_packet_out() msg.data = packet_in action = of.ofp_action_output(port=out_port) msg.actions.append(action) self.connection.send(msg)
def _handle_PacketIn(event): global s1_dpid, s2_dpid, s3_dpid, s4_dpid, s5_dpid packet = event.parsed #print "_handle_PacketIn is called, packet.type:", packet.type, " event.connection.dpid:", event.connection.dpid if event.connection.dpid == s1_dpid: a = packet.find('arp') if a and a.protodst == "10.0.0.4": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=4)) event.connection.send(msg) if a and a.protodst == "10.0.0.5": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=5)) event.connection.send(msg) if a and a.protodst == "10.0.0.6": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=6)) event.connection.send(msg) if a and a.protodst == "10.0.0.1": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=1)) event.connection.send(msg) if a and a.protodst == "10.0.0.2": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=2)) event.connection.send(msg) if a and a.protodst == "10.0.0.3": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=3)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.1" msg.actions.append(of.ofp_action_output(port=1)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.2" msg.actions.append(of.ofp_action_output(port=2)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.3" msg.actions.append(of.ofp_action_output(port=3)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 100 msg.idle_timeout = 0 msg.hard_timeout = 1 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.4" msg.actions.append(of.ofp_action_output(port=4)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.5" msg.actions.append(of.ofp_action_output(port=5)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.6" msg.actions.append(of.ofp_action_output(port=6)) event.connection.send(msg) elif event.connection.dpid == s2_dpid: msg = of.ofp_flow_mod() msg.priority = 10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 1 msg.match.dl_type = 0x0806 msg.actions.append(of.ofp_action_output(port=2)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 1 msg.match.dl_type = 0x0800 msg.actions.append(of.ofp_action_output(port=2)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 2 msg.match.dl_type = 0x0806 msg.actions.append(of.ofp_action_output(port=1)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 2 msg.match.dl_type = 0x0800 msg.actions.append(of.ofp_action_output(port=1)) event.connection.send(msg) elif event.connection.dpid == s3_dpid: msg = of.ofp_flow_mod() msg.priority = 10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 1 msg.match.dl_type = 0x0806 msg.actions.append(of.ofp_action_output(port=2)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 1 msg.match.dl_type = 0x0800 msg.actions.append(of.ofp_action_output(port=2)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 2 msg.match.dl_type = 0x0806 msg.actions.append(of.ofp_action_output(port=1)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 2 msg.match.dl_type = 0x0800 msg.actions.append(of.ofp_action_output(port=1)) event.connection.send(msg) elif event.connection.dpid == s4_dpid: msg = of.ofp_flow_mod() msg.priority = 10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 1 msg.match.dl_type = 0x0806 msg.actions.append(of.ofp_action_output(port=2)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 1 msg.match.dl_type = 0x0800 msg.actions.append(of.ofp_action_output(port=2)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 2 msg.match.dl_type = 0x0806 msg.actions.append(of.ofp_action_output(port=1)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 2 msg.match.dl_type = 0x0800 msg.actions.append(of.ofp_action_output(port=1)) event.connection.send(msg) elif event.connection.dpid == s5_dpid: a = packet.find('arp') if a and a.protodst == "10.0.0.4": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=4)) event.connection.send(msg) if a and a.protodst == "10.0.0.5": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=5)) event.connection.send(msg) if a and a.protodst == "10.0.0.6": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=6)) event.connection.send(msg) if a and a.protodst == "10.0.0.1": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=1)) event.connection.send(msg) if a and a.protodst == "10.0.0.2": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=2)) event.connection.send(msg) if a and a.protodst == "10.0.0.3": msg = of.ofp_packet_out(data=event.ofp) msg.actions.append(of.ofp_action_output(port=3)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.1" msg.actions.append(of.ofp_action_output(port=1)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 6 msg.actions.append(of.ofp_action_output(port=3)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.1" msg.actions.append(of.ofp_action_output(port=1)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.2" msg.actions.append(of.ofp_action_output(port=2)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.3" msg.actions.append(of.ofp_action_output(port=3)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.4" msg.actions.append(of.ofp_action_output(port=4)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.5" msg.actions.append(of.ofp_action_output(port=5)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.6" msg.actions.append(of.ofp_action_output(port=6)) event.connection.send(msg)
def s3_setup(self): #put switch 3 rules here fm = of.ofp_flow_mod() fm.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) self.connection.send(fm)
def dcs31_setup(self): #put datacenter switch rules here fm = of.ofp_flow_mod() fm.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) self.connection.send(fm)
def do_final(self, packet, packet_in, port_on_switch, switch_id): # This is where you'll put your code. The following modifications have # been made from Lab 4: # - port_on_switch represents the port that the packet was received on. # - switch_id represents the id of the switch that received the packet # (for example, s1 would have switch_id == 1, s2 would have switch_id == 2, etc...) #print "Hello, World!" h1 = '10.0.1.10' h2 = '10.0.2.20' h3 = '10.0.3.30' h4 = '10.0.4.40' h5 = '10.0.5.50' h6 = '10.0.6.60' h7 = '10.0.7.70' h8 = '10.0.8.80' serv1 = '10.0.9.10' untrustedH = '10.0.10.11' msg = of.ofp_flow_mod() msg.match = of.ofp_match.from_packet(packet) msg.idle_timeout = 30 msg.hard_timeout = 30 msg.data = packet_in ip = packet.find('ipv4') icmp = packet.find('icmp') tcp = packet.find('tcp') if ip: # any ip srcIP = ip.srcip dstIP = ip.dstip if icmp: if srcIP == untrustedH: # untrusted host sends icmp traffic self.connection.send(msg) # drop it else: if switch_id == 1: # floor 1 switch 1 if dstIP == h1: # to h1 msg.actions.append(of.ofp_action_output(port=1)) self.connection.send(msg) elif dstIP == h2: # to h2 msg.actions.append(of.ofp_action_output(port=2)) self.connection.send(msg) else: msg.actions.append( of.ofp_action_output(port=3)) # to core self.connection.send(msg) elif switch_id == 2: # floor 1 switch 2 if dstIP == h3: # to h3 msg.actions.append(of.ofp_action_output(port=1)) self.connection.send(msg) elif dstIP == h4: # to h4 msg.actions.append(of.ofp_action_output(port=2)) self.connection.send(msg) else: msg.actions.append( of.ofp_action_output(port=3)) # to core self.connection.send(msg) elif switch_id == 3: # floor 2 switch 1 if dstIP == h5: # to h5 msg.actions.append(of.ofp_action_output(port=1)) self.connection.send(msg) elif dstIP == h6: # to h6 msg.actions.append(of.ofp_action_output(port=2)) self.connection.send(msg) else: msg.actions.append( of.ofp_action_output(port=3)) # to core self.connection.send(msg) elif switch_id == 4: # floor 2 switch 2 if dstIP == h7: # to h7 msg.actions.append(of.ofp_action_output(port=1)) self.connection.send(msg) elif dstIP == h8: # to h8 msg.actions.append(of.ofp_action_output(port=2)) self.connection.send(msg) else: msg.actions.append( of.ofp_action_output(port=3)) # to core self.connection.send(msg) elif switch_id == 5: # core if dstIP == untrustedH: # to untrustedH msg.actions.append(of.ofp_action_output(port=5)) self.connection.send(msg) elif dstIP == h1: # to h10 msg.actions.append(of.ofp_action_output(port=1)) self.connection.send(msg) elif dstIP == h2: # to h20 msg.actions.append(of.ofp_action_output(port=1)) self.connection.send(msg) elif dstIP == h3: # to h30 msg.actions.append(of.ofp_action_output(port=2)) self.connection.send(msg) elif dstIP == h4: # to h40 msg.actions.append(of.ofp_action_output(port=2)) self.connection.send(msg) elif dstIP == h5: # to h50 msg.actions.append(of.ofp_action_output(port=3)) self.connection.send(msg) elif dstIP == h6: # to h60 msg.actions.append(of.ofp_action_output(port=3)) self.connection.send(msg) elif dstIP == h7: # to h70 msg.actions.append(of.ofp_action_output(port=4)) self.connection.send(msg) elif dstIP == h8: # to h80 msg.actions.append(of.ofp_action_output(port=4)) self.connection.send(msg) elif dstIP == serv1: # to serv1 msg.actions.append(of.ofp_action_output(port=6)) self.connection.send(msg) else: self.connection.send(msg) elif switch_id == 6: # data center if dstIP == serv1: # to server msg.actions.append(of.ofp_action_output(port=1)) self.connection.send(msg) else: msg.actions.append( of.ofp_action_output(port=3)) # to core self.connection.send(msg) elif tcp: if srcIP == untrustedH and dstIP == serv1: # untrustedH send tcp traffic to serv1 self.connection.send(msg) else: if switch_id == 1: # floor 1 switch 1 if dstIP == h1: # to h1 msg.actions.append(of.ofp_action_output(port=1)) self.connection.send(msg) elif dstIP == h2: # to h2 msg.actions.append(of.ofp_action_output(port=2)) self.connection.send(msg) else: msg.actions.append( of.ofp_action_output(port=3)) # to core self.connection.send(msg) elif switch_id == 2: # floor 1 switch 2 if dstIP == h3: # to h3 msg.actions.append(of.ofp_action_output(port=1)) self.connection.send(msg) elif dstIP == h4: # to h4 msg.actions.append(of.ofp_action_output(port=2)) self.connection.send(msg) else: msg.actions.append( of.ofp_action_output(port=3)) # to core self.connection.send(msg) elif switch_id == 3: # floor 2 switch 1 if dstIP == h5: # to h5 msg.actions.append(of.ofp_action_output(port=1)) self.connection.send(msg) elif dstIP == h6: # to h6 msg.actions.append(of.ofp_action_output(port=2)) self.connection.send(msg) else: msg.actions.append( of.ofp_action_output(port=3)) # to core self.connection.send(msg) elif switch_id == 4: # floor 2 switch 2 if dstIP == h7: # to h7 msg.actions.append(of.ofp_action_output(port=1)) self.connection.send(msg) elif dstIP == h8: # to h8 msg.actions.append(of.ofp_action_output(port=2)) self.connection.send(msg) else: msg.actions.append( of.ofp_action_output(port=3)) # to core self.connection.send(msg) elif switch_id == 5: # core if dstIP == untrustedH: # to untrustedH msg.actions.append(of.ofp_action_output(port=5)) self.connection.send(msg) elif dstIP == h1: # to h10 msg.actions.append(of.ofp_action_output(port=1)) self.connection.send(msg) elif dstIP == h2: # to h20 msg.actions.append(of.ofp_action_output(port=1)) self.connection.send(msg) elif dstIP == h3: # to h30 msg.actions.append(of.ofp_action_output(port=2)) self.connection.send(msg) elif dstIP == h4: # to h40 msg.actions.append(of.ofp_action_output(port=2)) self.connection.send(msg) elif dstIP == h5: # to h50 msg.actions.append(of.ofp_action_output(port=3)) self.connection.send(msg) elif dstIP == h6: # to h60 msg.actions.append(of.ofp_action_output(port=3)) self.connection.send(msg) elif dstIP == h7: # to h70 msg.actions.append(of.ofp_action_output(port=4)) self.connection.send(msg) elif dstIP == h8: # to h80 msg.actions.append(of.ofp_action_output(port=4)) self.connection.send(msg) elif dstIP == serv1: # to serv1 msg.actions.append(of.ofp_action_output(port=6)) self.connection.send(msg) else: self.connection.send(msg) elif switch_id == 6: # data center if dstIP == serv1: # to server msg.actions.append(of.ofp_action_output(port=1)) self.connection.send(msg) else: msg.actions.append( of.ofp_action_output(port=3)) # to core self.connection.send(msg) else: # otherwise msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) self.connection.send(msg)
def allow_all(self): match = of.ofp_match() fm = of.ofp_flow_mod() fm.match = match fm.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD)) self.connection.send(fm)
def _handle_PacketIn (self, event): """ Handle packet in messages from the switch to implement above algorithm. """ packet = event.parsed def flood (message = None): """ Floods the packet """ msg = of.ofp_packet_out() if time.time() - self.connection.connect_time >= _flood_delay: # Only flood if we've been connected for a little while... if self.hold_down_expired is False: # Oh yes it is! self.hold_down_expired = True log.info("%s: Flood hold-down expired -- flooding", dpid_to_str(event.dpid)) if message is not None: log.debug(message) #log.debug("%i: flood %s -> %s", event.dpid,packet.src,packet.dst) # OFPP_FLOOD is optional; on some switches you may need to change # this to OFPP_ALL. msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD)) else: pass #log.info("Holding down flood for %s", dpid_to_str(event.dpid)) msg.data = event.ofp msg.in_port = event.port self.connection.send(msg) 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) self.macToPort[packet.src] = event.port # 1 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: if packet.dst not in self.macToPort: # 4 flood("Port for %s unknown -- flooding" % (packet.dst,)) # 4a else: red = ["1","2","3","4","5","6","7"] entry_port = event.port mac_src = str(packet.src) mac_dst = str(packet.dst) # si es un msg desde fuera de la red if mac_src[-1] not in red: drop() return # si es un msg hacia fuera de la red if mac_dst[-1] not in red: drop() return print "Estoy en el switch: " , event.connection.dpid # Switch T # se implementa el firewall if entry_port == 14: if packet.find("tcp") and packet.find("tcp").dstport == 80: port = 15 else: drop() return elif entry_port == 15: port = 17 # Switch U elif entry_port in [12,24]: port = 13 # Switch V elif entry_port == 18: if mac_dst == "00:00:00:00:00:01": port = 1 elif mac_dst == "00:00:00:00:00:02": port = 2 else: port = 19 elif entry_port in [1,2]: if mac_dst == "00:00:00:00:00:07": port = 23 else: drop() return # Switch W elif entry_port in [10,26]: port = 11 # Switch X elif entry_port == 20: if mac_dst == "00:00:00:00:00:03": port = 3 elif mac_dst == "00:00:00:00:00:04": port = 4 else: port = 21 elif entry_port in [3,4]: if mac_dst == "00:00:00:00:00:07": port = 25 else: drop() return # Switch Y elif entry_port == 8: port = 9 # Switch Z elif entry_port == 22: if mac_dst == "00:00:00:00:00:05": port = 5 elif mac_dst == "00:00:00:00:00:06": port = 6 else: drop() return elif entry_port in [5,6]: if mac_dst == "00:00:00:00:00:07": port = 7 else: drop() return else: drop() return log.debug("installing flow for %s.%i -> %s.%i" % (packet.src, event.port, packet.dst, port)) msg = of.ofp_flow_mod() msg.match = of.ofp_match.from_packet(packet, event.port) msg.idle_timeout = 10 msg.hard_timeout = 30 msg.actions.append(of.ofp_action_output(port = port)) msg.data = event.ofp # 6a self.connection.send(msg)
def _handle_PacketIn (self, event): """ Handle packet in messages from the switch to implement above algorithm. """ packet = event.parsed def flood (message = None): """ Floods the packet """ msg = of.ofp_packet_out() if time.time() - self.connection.connect_time >= _flood_delay: # Only flood if we've been connected for a little while... if self.hold_down_expired is False: # Oh yes it is! self.hold_down_expired = True log.info("%s: Flood hold-down expired -- flooding", dpid_to_str(event.dpid)) if message is not None: log.debug(message) #log.debug("%i: flood %s -> %s", event.dpid,packet.src,packet.dst) # OFPP_FLOOD is optional; on some switches you may need to change # this to OFPP_ALL. msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD)) else: pass #log.info("Holding down flood for %s", dpid_to_str(event.dpid)) msg.data = event.ofp msg.in_port = event.port self.connection.send(msg) 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) self.macToPort[packet.src] = event.port # 1 # Get the DPID of the Switch Connection dpidstr = dpid_to_str(event.connection.dpid) # Check the Firewall Rules if self.CheckRule(dpidstr, packet.src) == False: drop() return 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: if packet.dst not in self.macToPort: # 4 flood("Port for %s unknown -- flooding" % (packet.dst,)) # 4a else: port = self.macToPort[packet.dst] if port == event.port: # 5 # 5a 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 # 6 log.debug("installing flow for %s.%i -> %s.%i" % (packet.src, event.port, packet.dst, port)) msg = of.ofp_flow_mod() msg.match = of.ofp_match.from_packet(packet, event.port) msg.idle_timeout = 10 msg.hard_timeout = 30 msg.actions.append(of.ofp_action_output(port = port)) msg.data = event.ofp # 6a self.connection.send(msg)
def send_packet_data(self, outport, data=None): msg = of.ofp_packet_out(in_port=of.OFPP_NONE, data=data) msg.actions.append(of.ofp_action_output(port=outport)) self.connection.send(msg)
def send_packet_bufid(self, outport, buffer_id=-1): msg = of.ofp_packet_out(in_port=of.OFPP_NONE) msg.actions.append(of.ofp_action_output(port=outport)) msg.buffer_id = buffer_id self.connection.send(msg)
def __init__(self, connection, transparent): # Switch we'll be adding L2 learning switch capabilities to self.connection = connection self.transparent = transparent # Our table self.macToPort = {} # We want to hear PacketIn messages, so we listen # to the connection connection.addListeners(self) # We just use this to know when to log a helpful message self.hold_down_expired = _flood_delay == 0 #----------------------- msg = of.ofp_flow_mod(command=of.OFPFC_DELETE) # iterate over all connected switches and delete all their flows connection.send(msg) print "INFO: Clearing all flows..." #for BCM switch only msg = of.ofp_flow_mod() msg.priority = 1000 msg.match.dl_type = 0x800 msg.match.in_port = 5 msg.match.nw_src = '10.0.0.1' msg.idle_timeout = 3000 msg.hard_timeout = 3000 #msg.actions.append(of.ofp_action_output(port = 1)) self.connection.send(msg) print 'INFO: add a default rule... (BCM only)' #------------------------- # (note that flow_mods match all flows by default) os.system('./simplesniffer eth2&') os.system('sudo bash ../pktgen/pktgen.conf.1-1-flow-dist.sh &') time.sleep(5) y = 0 print 'INFO: starting sending flow mod...' for k in xrange(1, 769): #the number of rules to install #insert first msg = of.ofp_flow_mod() #msg.match = of.ofp_match.from_packet(packet, event.port) #msg.priority = 20000 + randrange(1000) msg.priority = 2000 msg.match.dl_type = 0x800 i = int(k / 256) + 56 j = k % 256 dst = '192.168.' + str(i) + '.' + str(j) #msg.match.in_port = 1 #msg.match.nw_src = '10.0.0.1' msg.match.nw_dst = dst #print 'INFO',dst, time.time() msg.idle_timeout = 1600 msg.hard_timeout = 1600 msg.actions.append(of.ofp_action_output(port=1)) #msg.data = event.ofp # 6a self.connection.send(msg) #print 'DATA: 10.0.0.1', dst, '%f' %time.time() #print 'DATA: 10.0.0.1', dst, '%f' %time.time() burst[dst] = time.time() if k % 50 == 0: self.connection.send( of.ofp_stats_request(body=of.ofp_flow_stats_request())) #if k == 40: # self.connection.send(of.ofp_stats_request(body=of.ofp_port_stats_request())) # if k == 80: # self.connection.send(of.ofp_stats_request(body=of.ofp_queue_stats_request())) time.sleep(interval) print 'INFO: flow mod measure finished...' #write file w = open('poxout1', 'w') for d in burst: w.write('src: 10.0.0.1 dst: %s sec: %f usec: %f\n' % (d, int(burst[d]), (burst[d] - int(burst[d])) * 1000000)) w.close() os.system('sudo bash cleanpox.sh') #self destrory
def _install_hybrid_static_flows(self): t = self.t hosts = sorted(self._raw_dpids(t.layer_nodes(t.LAYER_HOST))) edge_sws = sorted(self._raw_dpids(t.layer_nodes(t.LAYER_EDGE))) agg_sws = sorted(self._raw_dpids(t.layer_nodes(t.LAYER_AGG))) core_sws = sorted(self._raw_dpids(t.layer_nodes(t.LAYER_CORE))) # For each host, add entries to that host, from each core switch. sep() #log.info("***adding down entries from each core switch") for host in hosts: host_name = self.t.id_gen(dpid=host).name_str() log.info("for host %i (%s)" % (host, host_name)) for core_sw in core_sws: core_sw_name = self.t.id_gen(dpid=core_sw).name_str() log.info("for core switch %i (%s)" % (core_sw, core_sw_name)) route = self.r.get_route(host_name, core_sw_name, None) assert route[0] == host_name assert route[-1] == core_sw_name # Form OF match match = of.ofp_match() # Highest-order four bits are host index host_id = self.t.id_gen(dpid=host) k = self.t.k host_index = host_id.pod * k + (host_id.sw * k / 2) + (host_id.host - 2) # Lowest-order two bits are core switch ID core_sw_id = self.t.id_gen(dpid=core_sw) log.info("core_sw_id: %s; sw: %i host: %i" % (core_sw, core_sw_id.sw, core_sw_id.host)) core_index = ((core_sw_id.sw - 1) * 2) + (core_sw_id.host - 1) vlan = (host_index << 2) + core_index #log.info("setting vlan to %i" % vlan) match.dl_vlan = vlan #log.info("vlan: %s" % match.dl_vlan) # Add one flow entry for each element on the path pointing down, except host for i, node in enumerate(route): # names if i == 0: pass # Don't install flow entries on hosts :-) else: # Install downward-facing entry node_dpid = self.t.id_gen(name=node).dpid node_below = route[i - 1] src_port, dst_port = self.t.port(node, node_below) log.info( "adding entry from %s to %s via VLAN %i and port %i" % (node, node_below, match.dl_vlan, src_port)) if i == 1: # Strip VLAN too actions = [ of.ofp_action_strip_vlan(), of.ofp_action_output(port=src_port) ] self.switches[node_dpid].install_multiple( actions, match, priority=PRIO_HYBRID_VLAN_DOWN) elif i > 1: self.switches[node_dpid].install( src_port, match, priority=PRIO_HYBRID_VLAN_DOWN) # # Add one flow entry for each edge switch pointing up # sep() # log.info("***adding up entries from each edge switch") # for edge_sw in edge_sws: # DPIDs # edge_sw_name = self.t.id_gen(dpid = edge_sw).name_str() # log.info("for edge sw %i (%s)" % (edge_sw, edge_sw_name)) # for core_sw in core_sws: # DPIDs # core_sw_name = self.t.id_gen(dpid = core_sw).name_str() # log.info("for core switch %i (%s)" % (core_sw, core_sw_name)) # # route = self.r.get_route(edge_sw_name, core_sw_name, None) # assert route[0] == edge_sw_name # assert route[-1] == core_sw_name # # # Form OF match # match = of.ofp_match() # # Highest-order four bits are host index # # # Lowest-order two bits are core switch ID # core_sw_id = self.t.id_gen(dpid = core_sw) # core_index = (core_sw_id.sw - 1) * 2 + (core_sw_id.host - 1) # # agg_sw_name = route[1] # agg_sw = self.t.id_gen(name = agg_sw_name).dpid # # for host_index in range((self.t.k ** 3) / 4): # match.dl_vlan = (host_index << 2) + core_index # #log.info("vlan: %s" % match.dl_vlan) # # edge_port, agg_port = self.t.port(edge_sw_name, agg_sw_name) # log.info("adding entry from %s to %s via VLAN %i and port %i" % # (edge_sw_name, agg_sw_name, match.dl_vlan, edge_port)) # self.switches[edge_sw].install(edge_port, match, # priority = PRIO_HYBRID_VLAN_UP) # Add one flow entry for each agg switch pointing up sep() log.info("***adding up entries from each agg switch") for agg_sw in agg_sws: # DPIDs agg_sw_name = self.t.id_gen(dpid=agg_sw).name_str() log.info("for agg sw %i (%s)" % (agg_sw, agg_sw_name)) for core_sw in core_sws: # DPIDs core_sw_name = self.t.id_gen(dpid=core_sw).name_str() log.info("for core switch %i (%s)" % (core_sw, core_sw_name)) if agg_sw_name in self.t.g[core_sw_name]: # If connected, add entry. agg_port, core_port = self.t.port(agg_sw_name, core_sw_name) # Form OF match match = of.ofp_match() # Highest-order four bits are host index # Lowest-order two bits are core switch ID core_sw_id = self.t.id_gen(dpid=core_sw) core_index = (core_sw_id.sw - 1) * 2 + (core_sw_id.host - 1) for host_index in range((self.t.k**3) / 4): match.dl_vlan = (host_index << 2) + core_index #log.info("vlan: %s" % match.dl_vlan) log.info( "adding entry from %s to %s via VLAN %i and port %i" % (agg_sw_name, core_sw_name, match.dl_vlan, agg_port)) self.switches[agg_sw].install( agg_port, match, priority=PRIO_HYBRID_VLAN_UP)
def _handle_PacketIn(self, event): """ Handle packet in messages from the switch to implement above algorithm. """ packet = event.parsed def flood(message=None): """ Floods the packet """ msg = of.ofp_packet_out() if time.time() - self.connection.connect_time >= _flood_delay: # Only flood if we've been connected for a little while... if self.hold_down_expired is False: # Oh yes it is! self.hold_down_expired = True log.info("%s: Flood hold-down expired -- flooding", dpid_to_str(event.dpid)) if message is not None: log.debug(message) #log.debug("%i: flood %s -> %s", event.dpid,packet.src,packet.dst) # OFPP_FLOOD is optional; on some switches you may need to change # this to OFPP_ALL. msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) else: pass #log.info("Holding down flood for %s", dpid_to_str(event.dpid)) msg.data = event.ofp msg.in_port = event.port self.connection.send(msg) 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) self.macToPort[packet.src] = event.port # 1 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: if packet.dst not in self.macToPort: # 4 flood("Port for %s unknown -- flooding" % (packet.dst, )) # 4a else: port = self.macToPort[packet.dst] whitelist = [ "00:00:00:00:00:01", "00:00:00:00:00:02", "00:00:00:00:00:03", "00:00:00:00:00:04", "00:00:00:00:00:05", "00:00:00:00:00:06", "00:00:00:00:00:07" ] if (str(packet.src) not in whitelist): log.debug( "Paquete proviene de un host externo a la red original, DROPEANDO..." ) drop() return if (str(packet.dst) not in whitelist): log.debug( "Paquete con destino a un host externo a la red original, DROPEANDO..." ) drop() return # 6 if str(packet.dst) != '00:00:00:00:00:07' and str( packet.src) != '00:00:00:00:00:07': log.debug( "Paquete no relacionado con el servidor, DROPEANDO...") drop() return """ objeto = packet.find('tcp') if objeto is None: log.debug("SE HA DETECTADO UN PAQUETE QUE NO ES HTTP, DROPEANDO...") drop() return else: if objeto.SYN or objeto.ACK or 'HTTP' in objeto.payload: log.debug("FINALMENTE, HTTP") log.debug(objeto.payload) else: log.debug("SE HA DETECTADO UN PAQUETE DE CONEXION TCP QUE NO ES HTTP, DROPEANDO...") drop() return """ if (event.port == 26): if (str(packet.dst) == "00:00:00:00:00:01" or str(packet.dst) == "00:00:00:00:00:02"): port = self.macToPort[packet.dst] else: port = 29 elif (event.port == 2 or event.port == 4): port = 13 if (event.port == 30): if (str(packet.dst) == "00:00:00:00:00:03" or str(packet.dst) == "00:00:00:00:00:04"): port = self.macToPort[packet.dst] else: port = 31 elif (event.port == 6 or event.port == 8): port = 15 if (event.port == 32): if (str(packet.dst) == "00:00:00:00:00:05" or str(packet.dst) == "00:00:00:00:00:06"): port = self.macToPort[packet.dst] else: log.debug("Ruta no permitida") drop() return elif (event.port == 10 or event.port == 12): port = 17 elif (event.port == 18): port = 19 elif (event.port == 16 or event.port == 20): port = 21 elif (event.port == 14 or event.port == 22): port = 23 elif (event.port == 24): port = 28 elif (event.port == 28): port = 25 if (port == 28 and packet.dst in self.macToPort): objeto = packet.find('tcp') if objeto is None: log.debug( "SE HA DETECTADO UN PAQUETE QUE NO ES HTTP, DROPEANDO..." ) drop(3) return else: if objeto.SYN or objeto.ACK or 'HTTP' in objeto.payload: log.debug("MENSAJE HTTP DETECTADO") log.debug(objeto.payload) else: log.debug( "SE HA DETECTADO UN PAQUETE DE CONEXION TCP QUE NO ES HTTP, DROPEANDO..." ) drop(3) return """ objeto = packet.find('ICMP') if objeto is None: log.debug("ESTO NO ES UN PING XD") else: log.debug("FINALMENTE, UN PING") if port == event.port: # 5 # 5a 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 """ log.debug( "--------------------------------------------------------") log.debug("El puerto de entrada del paquete es: %i" % (event.port)) log.debug("El puerto de salida del paquete es: %i" % (port)) log.debug( "--------------------------------------------------------") log.debug("installing flow for %s.%i -> %s.%i" % (packet.src, event.port, packet.dst, port)) msg = of.ofp_flow_mod() msg.match = of.ofp_match.from_packet(packet, event.port) msg.idle_timeout = 10 msg.hard_timeout = 30 msg.actions.append(of.ofp_action_output(port=port)) msg.data = event.ofp # 6a self.connection.send(msg)
def install_nomore(): msg = of.ofp_flow_mod() msg.match = of.ofp_match(dl_src=packet.src) msg.buffer_id = event.ofp.buffer_id msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) self.connection.send(msg)
import pox.openflow.libopenflow_01 as of from pox.lib.util import dpid_to_str, str_to_bool from pox.lib.packet.arp import arp from pox.lib.packet.ethernet import ethernet, ETHER_BROADCAST log = core.getLogger() #flow3: switch2 = 0000000000000003 flow2msg = of.ofp_flow_mod() flow2msg.cookie = 0 flow2msg.match.in_port = 2 flow2msg.match.dl_type = 0x0800 flow2msg.match.nw_src = IPAddr("192.168.1.10") # ACTIONS--------------------------------- flow2out = of.ofp_action_output (port = 1) flow2srcIP = of.ofp_action_nw_addr.set_src(IPAddr("10.0.0.2")) flow2srcMAC = of.ofp_action_dl_addr.set_src(EthAddr("00:00:00:00:00:04")) flow2dstMAC = of.ofp_action_dl_addr.set_dst(EthAddr("00:00:00:00:00:01")) flow2msg.actions = [flow2srcIP, flow2srcMAC, flow2dstMAC, flow2out] #flow4: switch3 = 0000000000000003 flow3msg = of.ofp_flow_mod() flow3msg.cookie = 0 flow3msg.match.in_port = 1 flow3msg.match.dl_type = 0x0800 flow3msg.match.nw_dst = IPAddr("10.0.0.2") # ACTIONS--------------------------------- flow3out = of.ofp_action_output (port = 2) flow3dstIP = of.ofp_action_nw_addr.set_dst(IPAddr("192.168.1.10"))
def _handle_PacketIn(self, event): """ Handle packet in messages from the switch to implement above algorithm. """ 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) packet = event.parsed switch_id = 1 host_id = 1 if packet.src.to_str() == "3e:d5:57:b2:a2:c0": switch_id = 0 host_id = 0 elif packet.src.to_str() == "06:f6:74:01:ea:fb": switch_id = 0 host_id = 1 elif packet.src.to_str() == "ee:22:79:b9:3e:11": switch_id = 1 host_id = 0 elif packet.src.to_str() == "2a:45:3f:89:0e:07": switch_id = 1 host_id = 1 elif packet.src.to_str() == "7a:28:f7:af:c0:a3": switch_id = 2 host_id = 0 elif packet.src.to_str() == "5a:77:17:1a:16:08": switch_id = 2 host_id = 1 elif packet.src.to_str() == "d6:68:86:5d:68:fa": switch_id = 3 host_id = 0 elif packet.src.to_str() == "ea:74:64:02:02:34": switch_id = 3 host_id = 1 global gamma global beta_switch global beta global t_switch global lamda_switch global start gamma[switch_id][host_id] += 1 beta_switch[switch_id] += 1 lamda_switch[switch_id] += 1 beta += 1 print("rho:", 0.8) print("omega:", w) print("Beta:", beta) print("beta_switch:", beta_switch) print("gamma:", gamma) print("alpha_switch:", alpha_switch) if beta_switch[switch_id] > alpha_switch[switch_id]: if beta > w: #dos detected print("Time to detect dos:", time.time() - start) print("Dos attack detected at switch:", switch_id) drop(3000) else: #switch thresold exceeded but not dos print("Thresolds for switch:", switch_id, "is updated from ", alpha_switch[switch_id], " to ", t_switch[switch_id]) alpha_switch[switch_id] = t_switch[switch_id] def flood(message=None): """ Floods the packet """ msg = of.ofp_packet_out() if time.time() - self.connection.connect_time >= _flood_delay: # Only flood if we've been connected for a little while... if self.hold_down_expired is False: # Oh yes it is! self.hold_down_expired = True log.info("%s: Flood hold-down expired -- flooding", dpid_to_str(event.dpid)) if message is not None: log.debug(message) #log.debug("%i: flood %s -> %s", event.dpid,packet.src,packet.dst) # OFPP_FLOOD is optional; on some switches you may need to change # this to OFPP_ALL. msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) else: pass #log.info("Holding down flood for %s", dpid_to_str(event.dpid)) msg.data = event.ofp msg.in_port = event.port self.connection.send(msg) self.macToPort[packet.src] = event.port # 1 #port = self.macToPort[packet.dst] print("packet.src,packet.dst,dpid_to_str(event.dpid), event.port", packet.src.to_str(), packet.dst, dpid_to_str(event.dpid), event.port) 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: if packet.dst not in self.macToPort: # 4 flood("Port for %s unknown -- flooding" % (packet.dst, )) # 4a else: port = self.macToPort[packet.dst] if port == event.port: # 5 # 5a 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 # 6 log.debug("installing flow for %s.%i -> %s.%i" % (packet.src, event.port, packet.dst, port)) msg = of.ofp_flow_mod() msg.match = of.ofp_match.from_packet(packet, event.port) msg.idle_timeout = 10 msg.hard_timeout = 30 msg.actions.append(of.ofp_action_output(port=port)) msg.data = event.ofp # 6a self.connection.send(msg)
def _handle_PacketIn(self, event): def flood(): """ Floods the packet """ if self.is_holding_down: log.warning("Not flooding -- holddown active") msg = of.ofp_packet_out() # OFPP_FLOOD is optional; some switches may need OFPP_ALL msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) msg.buffer_id = event.ofp.buffer_id msg.in_port = event.port self.connection.send(msg) def drop(): # Kill the buffer if event.ofp.buffer_id is not None: msg = of.ofp_packet_out() msg.buffer_id = event.ofp.buffer_id event.ofp.buffer_id = None # Mark is dead msg.in_port = event.port self.connection.send(msg) packet = event.parsed loc = (self, event.port) # Place we saw this ethaddr oldloc = mac_map.get(packet.src) # Place we last saw this ethaddr #print "We got old loc from somewhere" #print oldloc ################################################################ Handle LLDP Type ################################################################ if packet.effective_ethertype == packet.LLDP_TYPE: drop() return ################################################################################################################################################## ################################################################ Handle ARP Type ################################################################ if packet.type == ethernet.ARP_TYPE: arppack = packet.find('arp') if arppack.opcode == arp.REQUEST: mac_map[ packet. src] = loc # Learn position for ethaddr (host port eth address[dp id ,port]) #print "MAC MAP - " + str(mac_map) if swdebug: print "-----ARP REQUEST RECEIVED-----" print arppack print "loc - " + str(loc) print "Learned " + str(packet.src) + " at " + str( loc[0]) + "." + str(loc[1]) for switch in dpids: if switch is self.dpid: continue #Same Switch if swdebug: print "Sending ARP REQ to", dpidToStr(switch) action_out = [ of.ofp_action_output(port=port) for port in host_ports[switch] ] core.openflow.sendToDPID( switch, of.ofp_packet_out(data=packet.pack(), action=action_out)) return if arppack.opcode == arp.REPLY: mac_map[packet.src] = loc loc_dst = mac_map[packet.dst] # Learn position for ethaddr if swdebug: print "-----ARP REPLY RECEIVED-----" print "Send reply to DPID - ", str( loc_dst[0]), "port -", loc_dst[1] print "Type - ", type(str(loc_dst[0])) action_out = of.ofp_action_output(port=loc_dst[1]) core.openflow.sendToDPID( strToDPID(str(loc_dst[0])), of.ofp_packet_out(data=packet.pack(), action=action_out)) return ################################################################# Handle LAT Type ################################################################ if packet.effective_ethertype == LAT_TYPE: ####Get type from deeper header. """ Handle incoming latency packets """ # Latency packet is going from SWDSrc to SWDDest from Port. Left at time T port = packet.src [swdpdest, swdpsrc, port_mac, prevtime] = packet.payload.split(',') prevtime = float(prevtime) currtime = time.time() if swdebug: print "######## LATENCY Packet Received ##############" print "Packet Source" + str(swdpsrc) print "Packet Destination" + str(swdpdest) print "PrevTime = ", prevtime, " CurrTime = ", currtime dest_dpid = dpidToStr(event.dpid) if dest_dpid == swdpdest: # Latency packet travels = Controller - switchSrc - switchDest - Controller # Hence Latency = Total Time - (Controller-switch link latencies denoted by dpid_latency) latency = round((((currtime - prevtime) * 1000) - dpid_latency[strToDPID(swdpsrc)] - dpid_latency[event.dpid]), 4) latency = abs(latency) swd = ports[swdpsrc] for k in swd: if swd[k][4] == port_mac: break if latency >= 0: if k in ports[swdpsrc]: ports[swdpsrc][k][0] = latency if swdebug: print "Latency = " + str(latency) print "######## LATENCY Packet Sent ##############" return ################################################################################################################################################## if oldloc is None: if packet.src.is_multicast == False: mac_map[packet.src] = loc # Learn position for ethaddr log.debug("Learned %s at %s.%i", packet.src, loc[0], loc[1]) elif oldloc != loc: drop() return # ethaddr seen at different place! if core.openflow_discovery.is_edge_port(loc[0].dpid, loc[1]): # New place is another "plain" port (probably) log.debug("%s moved from %s.%i to %s.%i?", packet.src, dpid_to_str(oldloc[0].dpid), oldloc[1], dpid_to_str(loc[0].dpid), loc[1]) if packet.src.is_multicast == False: mac_map[packet.src] = loc # Learn position for ethaddr log.debug("Learned %s at %s.%i", packet.src, loc[0], loc[1]) elif packet.dst.is_multicast == False: # New place is a switch-to-switch port! # Hopefully, this is a packet we're flooding because we didn't # know the destination, and not because it's somehow not on a # path that we expect it to be on. # If spanning_tree is running, we might check that this port is # on the spanning tree (it should be). if packet.dst in mac_map: # Unfortunately, we know the destination. It's possible that # we learned it while it was in flight, but it's also possible # that something has gone wrong. if swdebug: print "Hit MacMap" log.warning( "Packet from %s to known destination %s arrived " "at %s.%i without flow", packet.src, packet.dst, dpid_to_str(self.dpid), event.port) if packet.dst.is_multicast: log.debug("Flood multicast from %s", packet.src) flood() else: if packet.dst not in mac_map: log.debug("%s unknown -- flooding" % (packet.dst, )) flood() else: dest = mac_map[packet.dst] if packet.type == ethernet.IP_TYPE: ipv4_packet = packet.find("ipv4") tos = ipv4_packet.tos if swdebug: if packet.find("icmp"): print "ICMP packet received" print "Received ToS = ", tos match = of.ofp_match.from_packet(packet) self.install_path(dest[0], dest[1], match, event, tos)
def _handle_PacketIn (event): #log.info("*** _handle_PacketIn... ***") dpid = event.connection.dpid inport = event.port packet = event.parsed if not packet.parsed: log.warning("%i %i ignoring unparsed packet", dpid, inport) return a = packet.find('arp') if not a: return log.info("%s ARP %s %s => %s", dpid_to_str(dpid), {arp.REQUEST:"request",arp.REPLY:"reply"}.get(a.opcode, 'op:%i' % (a.opcode,)), str(a.protosrc), str(a.protodst)) if a.prototype == arp.PROTO_TYPE_IP: if a.hwtype == arp.HW_TYPE_ETHERNET: if a.opcode == arp.REQUEST: if str(a.protodst)=="192.168.1.1": r = arp() r.hwtype = a.hwtype r.prototype = a.prototype r.hwlen = a.hwlen r.protolen = a.protolen r.opcode = arp.REPLY r.hwdst = a.hwsrc r.protodst = a.protosrc r.protosrc = a.protodst r.hwsrc = EthAddr("00:00:00:00:00:03") e = ethernet(type=packet.type, src=r.hwsrc, dst=a.hwsrc) e.payload = r log.info("%s answering ARP for %s" % (dpid_to_str(dpid), str(r.protosrc))) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT)) msg.in_port = inport event.connection.send(msg) if str(a.protodst)=="10.0.0.2": r = arp() r.hwtype = a.hwtype r.prototype = a.prototype r.hwlen = a.hwlen r.protolen = a.protolen r.opcode = arp.REPLY r.hwdst = a.hwsrc r.protodst = a.protosrc r.protosrc = a.protodst r.hwsrc = EthAddr("00:00:00:00:00:04") e = ethernet(type=packet.type, src=r.hwsrc, dst=a.hwsrc) e.payload = r log.info("%s answering ARP for %s" % (dpid_to_str(dpid), str(r.protosrc))) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT)) msg.in_port = inport event.connection.send(msg)
def _handle_PacketIn(event): global s1_dpid, s2_dpid print "PacketIn:", dpidToStr(event.connection.dpid) if event.connection.dpid == s1_dpid: msg = of.ofp_flow_mod() msg.priority = 1 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0806 msg.actions.append(of.ofp_action_output(port=of.OFPP_ALL)) event.connection.send(msg) # up: q0 for default queue.traffic from h3 to h4 # below:q1 for traffic h1 to h4 msg = of.ofp_flow_mod() msg.priority = 100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.1" msg.match.nw_dst = "10.0.0.4" msg.actions.append(of.ofp_action_enqueue(port=4, queue_id=1)) event.connection.send(msg) # below:q2 for traffic h2 to h4 msg = of.ofp_flow_mod() msg.priority = 100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.2" msg.match.nw_dst = "10.0.0.4" msg.actions.append(of.ofp_action_enqueue(port=4, queue_id=2)) event.connection.send(msg) # below:ports info msg = of.ofp_flow_mod() msg.priority = 10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.1" msg.actions.append(of.ofp_action_output(port=1)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.2" msg.actions.append(of.ofp_action_output(port=2)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.3" msg.actions.append(of.ofp_action_output(port=3)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.4" msg.actions.append(of.ofp_action_output(port=4)) event.connection.send(msg) elif event.connection.dpid == s2_dpid: 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_output(port=2)) event.connection.send(msg) 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_output(port=1)) event.connection.send(msg)
def _handle_PacketIn(self, event): inport = event.port packet = event.parsed def drop(): if event.ofp.buffer_id is not None: # Kill the buffer msg = of.ofp_packet_out(data=event.ofp) self.con.send(msg) return None tcpp = packet.find('tcp') ipp = packet.find('ipv4') udpp = packet.find('udp') if not tcpp: arpp = packet.find('arp') if arpp: # Handle replies to our server-liveness probes if arpp.opcode == arpp.REPLY: if arpp.protosrc in self.outstanding_probes: # A server is (still?) up; cool. del self.outstanding_probes[arpp.protosrc] if (self.live_servers.get(arpp.protosrc, (None, None)) == (arpp.hwsrc, inport)): # Ah, nothing new here. pass else: # Ooh, new server. self.live_servers[ arpp.protosrc] = arpp.hwsrc, inport self.log.info("Server %s up", arpp.protosrc) return if udpp and ipp: if ipp.dstip == self.service_ip and ipp.srcip in self.live_servers: self.total_connection[ipp.srcip] = float( pickle.loads(udpp.next)) # Not TCP and not ARP. Don't know what to do with this. Drop it. return drop() if ipp.srcip in self.servers: # It's FROM one of our balanced servers. # Rewrite it BACK to the client key = ipp.srcip, ipp.dstip, tcpp.srcport, tcpp.dstport entry = self.memory.get(key) if entry is None: # We either didn't install it, or we forgot about it. self.log.debug("No client for %s", key) return drop() # Refresh time timeout and reinstall. entry.refresh() # self.log.debug("Install reverse flow for %s", key) # Install reverse table entry mac, port = self.live_servers[entry.server] actions = [] actions.append(of.ofp_action_dl_addr.set_src(self.mac)) actions.append(of.ofp_action_nw_addr.set_src(self.service_ip)) actions.append(of.ofp_action_output(port=entry.client_port)) match = of.ofp_match.from_packet(packet, inport) msg = of.ofp_flow_mod(command=of.OFPFC_ADD, idle_timeout=FLOW_IDLE_TIMEOUT, hard_timeout=of.OFP_FLOW_PERMANENT, data=event.ofp, actions=actions, match=match) self.con.send(msg) elif ipp.dstip == self.service_ip: # Ah, it's for our service IP and needs to be load balanced # Do we already know this flow? key = ipp.srcip, ipp.dstip, tcpp.srcport, tcpp.dstport entry = self.memory.get(key) if entry is None or entry.server not in self.live_servers: # Don't know it (hopefully it's new!) if len(self.live_servers) == 0: self.log.warn("No servers!") return drop() # Pick a server for this flow server = self._pick_server() self.log.debug("Directing traffic from %s to %s", ipp.srcip, server) entry = MemoryEntry(server, packet, inport) self.memory[entry.key1] = entry self.memory[entry.key2] = entry self.log.debug("Total connection\n %s", self.total_connection) # Update timestamp entry.refresh() # Set up table entry towards selected server mac, port = self.live_servers[entry.server] actions = [] actions.append(of.ofp_action_dl_addr.set_dst(mac)) actions.append(of.ofp_action_nw_addr.set_dst(entry.server)) actions.append(of.ofp_action_output(port=port)) match = of.ofp_match.from_packet(packet, inport) msg = of.ofp_flow_mod(command=of.OFPFC_ADD, idle_timeout=FLOW_IDLE_TIMEOUT, hard_timeout=of.OFP_FLOW_PERMANENT, data=event.ofp, actions=actions, match=match) self.con.send(msg)
def _handle_PacketIn(self, event): """ Handle packet in messages from the switch to implement above algorithm. """ packet = event.parsed def tcpsrcport(): tcp_got = packet.find('tcp') if tcp_got: return tcp_got.srcport else: return " " def tcpdstport(): tcp_got = packet.find('tcp') if tcp_got: return tcp_got.dstport else: return " " def tcppakad(): tcp_got = packet.find('tcp') icmp_got = packet.find('icmp') if icmp_got: return "ICMP_found" exit(0) if tcp_got: if tcp_got.ACK: return "ACK_found" exit(0) if tcp_got.SYN: return "SYN_found" exit(0) if tcp_got.RST: return "RST_found" exit(0) if tcp_got.PSH: return "PSH_found" exit(0) if tcp_got.FIN: return "FIN_found" exit(0) else: return " " def getsrcip(): ip = packet.find('ipv4') if ip: return ip.srcip else: return " " def getdstip(): ip = packet.find('ipv4') if ip: return ip.dstip else: return " " #print "destination ip", ip.dstip def flood(message=None): """ Floods the packet """ msg = of.ofp_packet_out() if time.time() - self.connection.connect_time >= _flood_delay: # Only flood if we've been connected for a little while... if self.hold_down_expired is False: # Oh yes it is! self.hold_down_expired = True log.info("%s: Flood hold-down expired -- flooding", dpid_to_str(event.dpid)) if message is not None: log.debug(message) #log.debug("%i: flood %s -> %s", event.dpid,packet.src,packet.dst) # OFPP_FLOOD is optional; on some switches you may need to change # this to OFPP_ALL. msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) else: pass #log.info("Holding down flood for %s", dpid_to_str(event.dpid)) msg.data = event.ofp msg.in_port = event.port self.connection.send(msg) 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) self.macToPort[packet.src] = event.port # 1 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: if packet.dst not in self.macToPort: # 4 flood("Port for %s unknown -- flooding" % (packet.dst, )) # 4a else: port = self.macToPort[packet.dst] if port == event.port: # 5 # 5a 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 # 6 log.debug( "installing flow for %s.%i %s -> %s.%i %s ::%s" % (packet.src, event.port, getsrcip(), tcpsrcport(), packet.dst, port, getdstip(), tcpdstport(), tcppakad())) #getip() msg = of.ofp_flow_mod() msg.match = of.ofp_match.from_packet(packet, event.port) msg.idle_timeout = 10 msg.hard_timeout = 30 msg.actions.append(of.ofp_action_output(port=port)) msg.data = event.ofp # 6a self.connection.send(msg)
def _handle_PacketIn(self, event): """ Handle packet in messages from the switch to implement above algorithm. """ packet = event.parsed def flood(message=None): """ Floods the packet """ msg = of.ofp_packet_out() if time.time() - self.connection.connect_time >= _flood_delay: # Only flood if we've been connected for a little while... if self.hold_down_expired is False: # Oh yes it is! self.hold_down_expired = True log.info("%s: Flood hold-down expired -- flooding", dpid_to_str(event.dpid)) if message is not None: log.debug(message) #log.debug("%i: flood %s -> %s", event.dpid,packet.src,packet.dst) # OFPP_FLOOD is optional; on some switches you may need to change # this to OFPP_ALL. msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) else: pass #log.info("Holding down flood for %s", dpid_to_str(event.dpid)) msg.data = event.ofp msg.in_port = event.port self.connection.send(msg) 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) self.macToPort[packet.src] = event.port # 1 if not self.transparent: # 2 if packet.type == packet.LLDP_TYPE or packet.dst.isBridgeFiltered( ): drop() # 2a return if packet.dst.is_multicast: flood() #3 If destination is multicast flood the packet else: if packet.dst not in self.macToPort: #4 Checking if destination port is in the address table flood() #4a else: port = self.macToPort[packet.dst] if port == event.port: #5 if output port=input port drop(10) return #6 Installing the flow table entry into the switch msg = of.ofp_flow_mod() msg.match = of.ofp_match.from_packet(packet, event.port) msg.idle_timeout = 10 msg.hard_timeout = 30 msg.actions.append(of.ofp_action_output(port=port)) msg.data = event.ofp #6a Send the packet out to the appropriate port self.connection.send(msg)