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.actions.append(of.ofp_action_output(port = port)) msg.buffer_id = event.ofp.buffer_id msg.cookie = current_cookie #Set the flow identifier #GT #Sent flow to switch #GT self.connection.send(msg) l_scriptName = inspect.getfile(inspect.currentframe())# Script name #GT l_lineNumber = inspect.currentframe().f_back.f_lineno # Get line number #GT l_timestamp = datetime.datetime.now()# Timestamp #GT #Add flow entry to switch ---> key: FlowID | Field | Value #GT header = of.ofp_header()#GT self.dbHandler.addFlowEntry(msg, header, event.dpid, l_scriptName, l_lineNumber, l_timestamp)#GT #Set flow active --> SwitchID | FlowId | Value = 1 #GT self.dbHandler.modifySwichEntry(event.dpid, msg.cookie)#GT #Increase the flow identifier (cookie) #GT current_cookie = current_cookie + 1 #GT elif event.ofp.buffer_id != -1: msg = of.ofp_packet_out() msg.buffer_id = event.ofp.buffer_id msg.in_port = event.port self.connection.send(msg)
def check_socket(self): pkt_count = 0 while True: pkt_count += 1 buff = self.s.recv(100) pkt = of.ofp_header() pkt.unpack(buff) #print('[{}][check_socket]recved: ', len(buff)) print('\n[{0}] received [{1}]byte data.'.format(pkt_count, len(buff))) print(pkt.show()) if pkt.header_type == gini_of.OFPT_HELLO: # OFPT_HELLO print("OFPT_HELLO msg: ") pkt = of.ofp_hello() pkt.unpack(buff) self.process_hello(pkt) elif pkt.header_type == gini_of.OFPT_ECHO_REQUEST: print("OFPT_ECHO_REPLY msg: ") pkt = of.ofp_echo_request() pkt.unpack(buff) self.process_echo_request(pkt) elif pkt.header_type == gini_of.OFPT_FEATURES_REQUEST: print("OFPT_FEATURES_REQUEST msg: ") pkt = of.ofp_features_request() pkt.unpack(buff) self.process_features_request(pkt) elif pkt.header_type == gini_of.OFPT_SET_CONFIG: print("OFPT_SET_CONFIG msg: ") pkt = of.ofp_set_config() pkt.unpack(buff) self.process_set_config(pkt) elif pkt.header_type == gini_of.OFPT_FLOW_MOD: print("OFPT_FLOW_MOD msg: ") pkt = giniclass_flow_mod() pkt.unpack(buff) self.process_flow_mod(pkt) elif pkt.header_type == gini_of.OFPT_BARRIER_REQUEST: print("OFPT_BARRIER_REQUEST msg: ") pkt = of.ofp_barrier_request() pkt.unpack(buff) self.process_barrier_request(pkt) else: print("Unknown type!: ", pkt.header_type, "details: ") print(pkt.show())
def _handle_PacketIn (self, event): global current_cookie #GT 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] = {} if packet.type == ethernet.LLDP_TYPE: # Ignore LLDP packets return if isinstance(packet.next, ipv4): log.debug("%i %i IP %s => %s", dpid,inport,str(packet.next.srcip),str(packet.next.dstip)) # 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,str(packet.next.srcip)) else: log.debug("%i %i learned %s", dpid,inport,str(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 if prt == inport: log.warning("%i %i not sending packet for %s back out of the input port" % ( dpid, inport, str(dstaddr))) else: log.debug("%i %i installing flow for %s => %s out port %i" % (dpid, inport, str(packet.next.srcip), str(dstaddr), prt)) 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, action=of.ofp_action_output(port = prt), match=of.ofp_match.from_packet(packet, inport)) msg.cookie = current_cookie #Set the flow identifier #GT #Sent flow to switch #GT event.connection.send(msg.pack()) l_scriptName = inspect.getfile(inspect.currentframe())# Script name #GT l_lineNumber = inspect.currentframe().f_back.f_lineno # Get line number #GT l_timestamp = datetime.datetime.now()# Timestamp #GT #Add flow entry to switch ---> key: FlowID | Field | Value #GT header = of.ofp_header()#GT self.dbHandler.addFlowEntry(msg, header, event.dpid, l_scriptName, l_lineNumber, l_timestamp)#GT #Set flow active --> SwitchID | FlowId | Value = 1 #GT self.dbHandler.modifySwichEntry(event.dpid, msg.cookie)#GT #Increase the flow identifier (cookie) #GT current_cookie = current_cookie + 1 #GT 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,)), str(a.protosrc), str(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,str(a.protosrc)) else: log.debug("%i %i learned %s", dpid,inport,str(a.protosrc)) self.arpTable[dpid][a.protosrc] = Entry(inport, packet.src) 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=r.hwsrc, dst=a.hwsrc) e.set_payload(r) log.debug("%i %i answering ARP for %s" % (dpid, inport, 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) 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,)), str(a.protosrc), str(a.protodst))) msg = of.ofp_packet_out(in_port = inport, action = of.ofp_action_output(port = of.OFPP_FLOOD)) if event.ofp.buffer_id is of.NO_BUFFER: # Try sending the (probably incomplete) raw data msg.data = event.data else: msg.buffer_id = event.ofp.buffer_id event.connection.send(msg.pack()) return
def flowlet_arrival(self, flowlet, prevnode, destnode, input_intf=None): '''Incoming flowlet: determine whether it's a data plane flowlet or whether it's an OF message coming back from the controller''' if input_intf is None: input_intf = self.trafgen_ip if self.tracePkt: self.packetInDebugger(flowlet, prevnode, destnode, input_intf) if isinstance(flowlet, OpenflowMessage): self.logger.debug("Received from controller: {}".format(flowlet.ofmsg)) ofmsg = None if isinstance(flowlet.ofmsg, oflib.ofp_base): ofmsg = flowlet.ofmsg elif isinstance(flowlet.ofmsg, str): ofhdr = oflib.ofp_header() ofhdr.unpack(flowlet.ofmsg) ofmsg = oflib._message_type_to_class[ofhdr.header_type]() ofmsg.unpack(flowlet.ofmsg) else: raise UnhandledPoxPacketFlowletTranslation("Not an openflow message from controller: {}".format(flowlet.ofmsg)) self.pox_switch.rx_message(self, ofmsg) if self.trace: for i,entry in enumerate(self.pox_switch.table.entries): actions = '::'.join([oflib.ofp_action_type_map[a.type] + ' ' + repr(a) for a in entry.actions]) self.logger.info("Flow table entry {}: {} (actions: {})".format(i+1, str(entry), actions)) elif isinstance(flowlet, PoxFlowlet): self.logger.debug("Received PoxFlowlet: {}".format(str(flowlet.origpkt))) input_port = self.interface_to_port_map[input_intf] self.process_packet(flowlet.origpkt, input_port) if self.trace: self.__traceit(flowlet, flowlet.origpkt, input_port) self.pox_switch.rx_packet(flowlet.origpkt, input_port) elif isinstance(flowlet, Flowlet): input_port = self.interface_to_port_map[input_intf] portinfo = self.ports[input_port] # self.logger.info("Received flowlet in {} intf{} dstmac{} plocal{} -- {}".format(self.name, input_intf, flowlet.dstmac, portinfo.localmac, type(flowlet))) if portinfo.link is NullLink: flowlet.srcmac = portinfo.remotemac dstmac = self.dstmac_cache.get(destnode, None) if dstmac is None: self.dstmac_cache[destnode] = dstmac = fscore().topology.node(destnode).remote_macaddr flowlet.dstmac = dstmac # self.logger.debug("Local flowlet: setting MAC addrs as {}->{}".format(flowlet.srcmac, flowlet.dstmac)) #else: # # self.logger.debug("Non-local flowlet: MAC addrs {}->{}".format(flowlet.srcmac, flowlet.dstmac)) self.measure_flow(flowlet, prevnode, input_intf) # assume this is an incoming flowlet on the dataplane. # reformat it and inject it into the POX switch # self.logger.debug("Flowlet arrival in OF switch {} {} {} {} {}".format(self.name, flowlet.dstaddr, prevnode, destnode, input_intf)) pkt = flowlet_to_packet(flowlet) pkt.flowlet = None if self.trace: self.__traceit(flowlet, pkt, input_port) self.pox_switch.rx_packet(pkt, input_port) if self.ipdests.get(flowlet.dstaddr, None): self.logger.debug("Flowlet arrived at destination {}".format(self.name)) if self.autoack and not flowlet.ackflow: self.send_ack_flow(flowlet, input_intf) else: raise UnhandledPoxPacketFlowletTranslation("Unexpected message in OF switch: {}".format(type(flowlet)))
def _handle_PacketIn (self, event): """ Handles packet in messages from the switch to implement above algorithm. """ global current_cookie #GT packet = event.parse() def flood (): """ Floods the packet """ if event.ofp.buffer_id == -1: log.warning("Not flooding unbuffered packet on %s", dpidToStr(event.dpid)) return msg = of.ofp_packet_out() if time.time() - self.connection.connect_time > FLOOD_DELAY: # Only flood if we've been connected for a little while... #log.debug("%i: flood %s -> %s", event.dpid, packet.src, packet.dst) msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD)) else: pass #log.info("Holding down flood for %s", dpidToStr(event.dpid)) msg.buffer_id = event.ofp.buffer_id msg.in_port = event.port self.connection.send(msg) def drop (duration = None): """ Drops this packet and optionally installs a flow to continue dropping similar ones for a while """ if duration is not None: if not isinstance(duration, tuple): duration = (duration,duration) msg = of.ofp_flow_mod() msg.match = of.ofp_match.from_packet(packet) msg.idle_timeout = duration[0] msg.hard_timeout = duration[1] msg.actions.append(of.ofp_action_output(port = port)) msg.buffer_id = event.ofp.buffer_id msg.cookie = current_cookie #Set the flow identifier #GT #Sent flow to switch #GT self.connection.send(msg) l_scriptName = inspect.getfile(inspect.currentframe())# Script name #GT l_lineNumber = inspect.currentframe().f_back.f_lineno # Get line number #GT l_timestamp = datetime.datetime.now()# Timestamp #GT #Add flow entry to switch ---> key: FlowID | Field | Value #GT header = of.ofp_header()#GT self.dbHandler.addFlowEntry(msg, header, event.dpid, l_scriptName, l_lineNumber, l_timestamp)#GT #Set flow active --> SwitchID | FlowId | Value = 1 #GT self.dbHandler.modifySwichEntry(event.dpid, msg.cookie)#GT #Increase the flow identifier (cookie) #GT current_cookie = current_cookie + 1 #GT elif event.ofp.buffer_id != -1: msg = of.ofp_packet_out() msg.buffer_id = event.ofp.buffer_id msg.in_port = event.port self.connection.send(msg) self.macToPort[packet.src] = event.port # 1 if not self.transparent: if packet.type == packet.LLDP_TYPE or packet.dst.isBridgeFiltered(): # 2 drop() return if packet.dst.isMulticast(): flood() # 3a else: if packet.dst not in self.macToPort: # 4 log.debug("Port for %s unknown -- flooding" % (packet.dst,)) flood() # 4a else: port = self.macToPort[packet.dst] if port == event.port: # 5 # 5a log.warning("Same port for packet from %s -> %s on %s. Drop." % (packet.src, packet.dst, port), dpidToStr(event.dpid)) drop(10) return # 6 log.debug("installing flow for %s.%i -> %s.%i" % (packet.src, event.port, packet.dst, port)) msg = of.ofp_flow_mod() msg.match = of.ofp_match.from_packet(packet) msg.idle_timeout = 10 msg.hard_timeout = 30 msg.actions.append(of.ofp_action_output(port = port)) msg.buffer_id = event.ofp.buffer_id # 6a msg.cookie = current_cookie #Set the flow identifier #GT #Sent flow to switch #GT self.connection.send(msg) l_scriptName = inspect.getfile(inspect.currentframe())# Script name #GT l_lineNumber = inspect.currentframe().f_back.f_lineno # Get line number #GT l_timestamp = datetime.datetime.now()# Timestamp #GT #Add flow entry to switch ---> key: FlowID | Field | Value #GT header = of.ofp_header()#GT self.dbHandler.addFlowEntry(msg, header, event.dpid, l_scriptName, l_lineNumber, l_timestamp)#GT #Set flow active --> SwitchID | FlowId | Value = 1 #GT self.dbHandler.modifySwichEntry(event.dpid, msg.cookie)#GT #Increase the flow identifier (cookie) #GT current_cookie = current_cookie + 1 #GT
def flowlet_arrival(self, flowlet, prevnode, destnode, input_intf=None): '''Incoming flowlet: determine whether it's a data plane flowlet or whether it's an OF message coming back from the controller''' if input_intf is None: input_intf = self.trafgen_ip if isinstance(flowlet, OpenflowMessage): self.logger.debug("Received from controller: {}".format(flowlet.ofmsg)) ofmsg = None if isinstance(flowlet.ofmsg, oflib.ofp_base): ofmsg = flowlet.ofmsg elif isinstance(flowlet.ofmsg, str): ofhdr = oflib.ofp_header() ofhdr.unpack(flowlet.ofmsg) ofmsg = oflib._message_type_to_class[ofhdr.header_type]() ofmsg.unpack(flowlet.ofmsg) else: raise UnhandledPoxPacketFlowletTranslation("Not an openflow message from controller: {}".format(flowlet.ofmsg)) self.pox_switch.rx_message(self, ofmsg) if self.trace: for i,entry in enumerate(self.pox_switch.table.entries): actions = '::'.join([oflib.ofp_action_type_map[a.type] + ' ' + repr(a) for a in entry.actions]) self.logger.info("Flow table entry {}: {} (actions: {})".format(i+1, str(entry), actions)) elif isinstance(flowlet, PoxFlowlet): self.logger.debug("Received PoxFlowlet: {}".format(str(flowlet.origpkt))) input_port = self.interface_to_port_map[input_intf] self.process_packet(flowlet.origpkt, input_port) if self.trace: self.__traceit(flowlet, flowlet.origpkt, input_port) self.pox_switch.rx_packet(flowlet.origpkt, input_port) elif isinstance(flowlet, Flowlet): input_port = self.interface_to_port_map[input_intf] portinfo = self.ports[input_port] # self.logger.info("Received flowlet in {} intf{} dstmac{} plocal{} -- {}".format(self.name, input_intf, flowlet.dstmac, portinfo.localmac, type(flowlet))) if portinfo.link is NullLink: flowlet.srcmac = portinfo.remotemac dstmac = self.dstmac_cache.get(destnode, None) if dstmac is None: self.dstmac_cache[destnode] = dstmac = fscore().topology.node(destnode).remote_macaddr flowlet.dstmac = dstmac # self.logger.debug("Local flowlet: setting MAC addrs as {}->{}".format(flowlet.srcmac, flowlet.dstmac)) #else: # # self.logger.debug("Non-local flowlet: MAC addrs {}->{}".format(flowlet.srcmac, flowlet.dstmac)) self.measure_flow(flowlet, prevnode, input_intf) # assume this is an incoming flowlet on the dataplane. # reformat it and inject it into the POX switch # self.logger.debug("Flowlet arrival in OF switch {} {} {} {} {}".format(self.name, flowlet.dstaddr, prevnode, destnode, input_intf)) pkt = flowlet_to_packet(flowlet) pkt.flowlet = None if self.trace: self.__traceit(flowlet, pkt, input_port) self.pox_switch.rx_packet(pkt, input_port) if self.ipdests.get(flowlet.dstaddr, None): self.logger.debug("Flowlet arrived at destination {}".format(self.name)) if self.autoack and not flowlet.ackflow: self.send_ack_flow(flowlet, input_intf) else: raise UnhandledPoxPacketFlowletTranslation("Unexpected message in OF switch: {}".format(type(flowlet)))