def create_discovery_packet(self, dpid, port_num, port_addr): """ Build discovery packet """ chassis_id = pkt.chassis_id(subtype=pkt.chassis_id.SUB_LOCAL) chassis_id.id = bytes('dpid:' + hex(long(dpid))[2:-1]) # Maybe this should be a MAC. But a MAC of what? Local port, maybe? port_id = pkt.port_id(subtype=pkt.port_id.SUB_PORT, id=str(port_num)) ttl = pkt.ttl(ttl=self._ttl) sysdesc = pkt.system_description() sysdesc.payload = bytes('dpid:' + hex(long(dpid))[2:-1]) discovery_packet = pkt.lldp() discovery_packet.tlvs.append(chassis_id) discovery_packet.tlvs.append(port_id) discovery_packet.tlvs.append(ttl) discovery_packet.tlvs.append(sysdesc) discovery_packet.tlvs.append(pkt.end_tlv()) eth = pkt.ethernet(type=pkt.ethernet.LLDP_TYPE) eth.src = port_addr eth.dst = pkt.ETHERNET.NDP_MULTICAST eth.payload = discovery_packet po = of.ofp_packet_out(action=of.ofp_action_output(port_id=port_num)) po.data = eth.pack() return po.pack()
def encap_sr_header_w_pktout(dpid, matchx, output_port, port_list, event, out_dpid): packetout_msg = pof.ofp_packet_out() packetout_msg.actions.append(pof.ofp_action_output(port_id=int(port_list[-1]))) packetout_msg.data = event.ofp packetout_msg.in_port = event.port core.PofManager.write_of(out_dpid, packetout_msg) return encap_sr_header(dpid, matchx, output_port, port_list)
def _handle_PacketIn(event): table_id = core.PofManager.get_flow_table_id(event.dpid, 'FirstEntryTable') # 0 match = core.PofManager.get_field("DMAC")[0] temp_matchx = core.PofManager.new_matchx(match, 'ceb7ce59253a', 'FFFFFFFFFFFF') action_1 = core.PofManager.new_action_output(0, 0, 0, 0, 0x2) # output temp_ins = core.PofManager.new_ins_apply_actions([action_1]) core.PofManager.add_flow_entry(event.dpid, table_id, [temp_matchx], [temp_ins]) packetout_msg = of.ofp_packet_out() packetout_msg.actions.append(of.ofp_action_output(port_id = 2)) packetout_msg.data = event.ofp packetout_msg.in_port = event.port event.connection.send(packetout_msg) print 'packet out' table_id = core.PofManager.get_flow_table_id(event.dpid, 'FirstEntryTable') # 0 match = core.PofManager.get_field("DMAC")[0] temp_matchx = core.PofManager.new_matchx(match, '9e28862bf766', 'FFFFFFFFFFFF') action_1 = core.PofManager.new_action_output(0, 0, 0, 0, 0x1) # output temp_ins = core.PofManager.new_ins_apply_actions([action_1]) core.PofManager.add_flow_entry(event.dpid, table_id, [temp_matchx], [temp_ins]) # msg=of.ofp_flow_mod() # msg.counter_id = 0 # msg.cookie = 0 # msg.cookie_mask = 0 # msg.table_id = 0 # msg.table_type = 0 #OF_MM_TABLE # #msg.priority = 0 # msg.index = 0 # # #matchx 1 # tempmatchx=of.ofp_matchx() # tempmatchx.field_id=0 # tempmatchx.offset=0 # tempmatchx.length=48 # tempmatchx.set_value("aaea0e50be91") #Network Center PC MAC # tempmatchx.set_mask("FFffFFffFFff") # msg.match_list.append(tempmatchx) # # tempins=of.ofp_instruction_apply_actions() # action = of.ofp_action_output() # action.port_id = 1 # tempins.action_list.append(action) # msg.instruction_list.append(tempins) # # # event.connection.send(msg) # # # # # msg1=of.ofp_flow_mod() # msg1.counter_idd = 0 # msg1.cookie = 0 # msg1.cookie_mask = 0 # msg1.table_id = 0 # msg1.table_type = 0 #OF_MM_TABLE # msg1.priority = 0 # msg1.index = 1 # # #matchx 1 # #to h2s1 # tempmatchx1=of.ofp_matchx() # tempmatchx1.fieldId=0 # tempmatchx1.offset=0 # tempmatchx1.length=48 # tempmatchx1.set_value("0ad4ca363f87") #Network Center PC MAC # tempmatchx1.set_mask("FFffFFffFFff") # msg1.match_list.append(tempmatchx1) # # tempins1=of.ofp_instruction_apply_actions() # action1 = of.ofp_action_output() # action1.port_id=2 # tempins1.action_list.append(action1) # msg1.instruction_list.append(tempins1) # # # event.connection.send(msg1) log.info("Get PacketIn")
def _handle_PacketIn(self, event): # Note: arp.hwsrc is not necessarily equal to ethernet.src # (one such example are arp replies generated by this module itself # as ethernet mac is set to switch dpid) so we should be careful # to use only arp addresses in the learning code! squelch = False dpid = event.connection.dpid inport = event.port packet = event.parsed if not packet.parsed: log.warning("%s: ignoring unparsed packet", dpid_to_str(dpid)) return a = packet.find('arp') if not a: return log.debug("%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.protosrc != 0: if _learn: # Learn or update port/MAC info if a.protosrc in _arp_table: if _arp_table[a.protosrc] != a.hwsrc: log.warn("%s RE-learned %s: %s->%s", dpid_to_str(dpid), a.protosrc, _arp_table[a.protosrc].mac, a.hwsrc) else: log.info("%s learned %s", dpid_to_str(dpid), a.protosrc) _arp_table[a.protosrc] = Entry(a.hwsrc) if a.opcode == arp.REQUEST: # Maybe we can answer if a.protodst in _arp_table: # We have an answer... 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 mac = _arp_table[a.protodst].mac if mac is True: # Special case -- use ourself mac = _dpid_to_mac(dpid) r.hwsrc = mac e = ethernet(type=packet.type, src=_dpid_to_mac(dpid), dst=a.hwsrc) e.payload = r if packet.type == ethernet.VLAN_TYPE: v_rcv = packet.find('vlan') e.payload = vlan(eth_type=e.type, payload=e.payload, id=v_rcv.id, pcp=v_rcv.pcp) e.type = ethernet.VLAN_TYPE 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) return EventHalt if _eat_packets else None else: # Keep track of failed queries squelch = a.protodst in _failed_queries _failed_queries[a.protodst] = time.time() if self._check_for_flood(dpid, a): # Didn't know how to handle this ARP, so just flood it msg = "%s flooding ARP %s %s => %s" % (dpid_to_str(dpid), { arp.REQUEST: "request", arp.REPLY: "reply" }.get(a.opcode, 'op:%i' % (a.opcode, )), a.protosrc, a.protodst) if squelch: log.debug(msg) else: log.info(msg) msg = of.ofp_packet_out() msg.actions.append(of.ofp_action_output(port_id=255)) msg.data = event.ofp event.connection.send(msg.pack()) return EventHalt if _eat_packets else None
def _handle_PacketIn(self, event): global total_entry_num global total_flow_num global reject_flow_num global total_flow_entry_num global avg_packet_overhead_pp global ipTable packet = event.parsed if isinstance(packet.next, ipv4): #dst_ip_net = check_ip_prefix(packet.next.dstip, ipTable) if packet.next.dstip in ipTable.keys(): src_ip = packet.next.srcip dst_ip = packet.next.dstip if isinstance(packet.next.next, udp): dst_port = packet.next.next.dstport src_port = packet.next.next.srcport if src_port != 5001: if (src_ip, dst_ip, src_port) not in self.has_packetin_flow_list: total_flow_num += 1 print 'Total number of handled flow: ', total_flow_num print 'Number of rejected flow: ', reject_flow_num print 'Reject rate: ', float( reject_flow_num) / total_flow_num print 'Total number of flow entry:', total_flow_entry_num print 'Average packet overhead:', avg_packet_overhead_pp print '----------' \ '---------' # print 'dst_port:', dst_port, port2hex(dst_port) self.has_packetin_flow_list.append( (src_ip, dst_ip, src_port)) dst_dpid = ipTable[packet.next.dstip][0] dst_outport = ipTable[packet.next.dstip][1] # for dpid in switch_resource.keys(): # print 'table resource:', switch_resource[dpid] if switch_resource[event.dpid] > 0: # check table resource on ingress node # for i in xrange(self.in_service_flow.qsize()): # # check the running flow entry whether it is timeout # f = self.in_service_flow.get() # if time.time() >= f[0]: # core.PofManager.delete_flow_entry(f[1].dpid, f[1].table_id, f[1].entry_id) # switch_resource[f[1].dpid] += 1 # self.has_packetin_flow_list.remove(f[1].flow_metadata) # # else: # self.in_service_flow.put(f) # break ip_addr_hex = ip2hex(packet.next.dstip.toStr()) first_hop_outport, port_list, path_list = cal_route( event.dpid, packet.next.dstip) last_hop = path_list[-1] log.info('path: %s' % path_list) # log.info('output port: %s' % port_list) entry_id = encap_sr_header_by_dip_sport_w_pktout(dpid=event.dpid, \ dip=ip_addr_hex, \ dip_mask = 'FFffFFff', \ sport = port2hex(src_port),\ sport_mask = 'FFff',\ output_port = first_hop_outport, \ port_list = port_list,\ event = event, \ out_dpid = last_hop) ctime = time.time() flow_info = InServiceFlowInfo(event.dpid, \ core.PofManager.get_flow_table_id(event.dpid, 'SRHeaderEncapTable'), \ entry_id, ctime, (src_ip, dst_ip, src_port)) # flow_info = InServiceFlowInfo4S(event.dpid, ctime, path_list) self.in_service_flow.put( (ctime + flow_info.holding_time, flow_info)) switch_resource[event.dpid] -= 1 total_flow_entry_num += 1 avg_packet_overhead_pp = (avg_packet_overhead_pp * (total_flow_num - reject_flow_num -1) \ + len(port_list) * PORT_FIELD_LEN) / (total_flow_num - reject_flow_num) else: reject_flow_num += 1 ip_addr_hex = ip2hex(packet.next.dstip.toStr()) encap_sr_header_by_dip_sport_drop( event.dpid, ip_addr_hex, 'FFffFFff', port2hex(src_port), 'FFff') else: # packetout these messages pass # self.duplicated_packetin_counter += 1 # print self.duplicated_packetin_counter dst_dpid = ipTable[packet.next.dstip][0] dst_outport = ipTable[packet.next.dstip][1] pktout_msg = pof.ofp_packet_out() output_action = pof.ofp_action_output( port_id=dst_outport) pktout_msg.actions = [output_action] pktout_msg.in_port = event.port pktout_msg.data = event.ofp core.PofManager.write_of(dst_dpid, pktout_msg) else: ip_addr_hex = ip2hex(packet.next.dstip.toStr()) first_hop_outport, port_list, path_list = cal_route( event.dpid, packet.next.dstip) last_hop = path_list[-1] entry_id = encap_sr_header_by_dip_sport_w_pktout(dpid=event.dpid, \ dip=ip_addr_hex, \ dip_mask='FFffFFff', \ sport=port2hex(5001), \ sport_mask='FFff', \ output_port=first_hop_outport, \ port_list=port_list, \ event=event, \ out_dpid=last_hop) elif isinstance(packet.next.next, tcp): src_port = packet.next.next.srcport dst_dpid = ipTable[packet.next.dstip][0] dst_outport = ipTable[packet.next.dstip][1] ip_addr_hex = ip2hex(packet.next.dstip.toStr()) first_hop_outport, port_list, path_list = cal_route( event.dpid, packet.next.dstip) last_hop = path_list[-1] log.info('path: %s' % path_list) # log.info('output port: %s' % port_list) entry_id = encap_sr_header_by_dip_sport_w_pktout(dpid=event.dpid, \ dip=ip_addr_hex, \ dip_mask='FFffFFff', \ sport=port2hex(src_port), \ sport_mask='FFff', \ output_port=first_hop_outport, \ port_list=port_list, \ event=event, \ out_dpid=last_hop) # # elif isinstance(packet.next.next, icmp): # # ipv4 but not udp # dst_dpid = ipTable[packet.next.dstip][0] # dst_outport = ipTable[packet.next.dstip][1] # # ip_addr_hex = ip2hex(packet.next.dstip.toStr()) # # first_hop_outport, port_list, path_list = cal_route(event.dpid, packet.next.dstip) # last_hop = path_list[-1] # # log.info('path: %s' % path_list) # log.info('output port: %s' % port_list) # # entry_id = encap_sr_header_by_dip_dport_w_pktout(dpid=event.dpid, \ # dip=ip_addr_hex, \ # dip_mask='FFffFFff', \ # dport='0000',\ # dport_mask='0000',\ # output_port=first_hop_outport, \ # port_list=port_list, \ # event=event, \ # out_dpid=last_hop) # else: # log.info('Dstination IP address unreachable!') elif isinstance(packet.next, arp): log.info(packet.next._to_str()) ip_addr_hex = ip2hex(packet.next.protodst.toStr()) #target_ip_net = check_ip_prefix(packet.next.protodst, ipTable) if (packet.src, packet.next.protodst) not in self.has_packetin_arp: if packet.next.protodst in ipTable.keys(): #if target_ip_net: self.has_packetin_arp.append( (packet.src, packet.next.protodst)) port_list, path_list = cal_path(event.dpid, packet.next.protodst) # print 'port list', port_list # print 'path list', path_list for dpid, port in zip(path_list, port_list): install_arp_target_ip_match_entry( dpid, ip_addr_hex, port) # reverse path flow entry port_list_rev, path_list_rev = cal_path( path_list[-1], packet.next.protosrc) ip_addr_hex_rev = ip2hex(packet.next.protosrc.toStr()) # print 'port list reverse', port_list_rev # print 'path list reverse', path_list_rev for dpid, port in zip(path_list_rev, port_list_rev): install_arp_target_ip_match_entry( dpid, ip_addr_hex_rev, port) else: log.info('Request IP address unreachable!') elif isinstance(packet.next, ipv6): drop()