def packet_in_handler(self, ev): """ EventHandler for PacketIn messages """ msg = ev.msg # In OpenFlow, switches are called "datapaths". Each switch gets its own datapath ID. # In the controller, we pass around datapath objects with metadata about each switch. dp = msg.datapath # Use this object to create packets for the given datapath ofctl = OfCtl.factory(dp, self.logger) in_port = msg.in_port pkt = packet.Packet(msg.data) eth = pkt.get_protocols(ethernet.ethernet)[0] if eth.ethertype == ether_types.ETH_TYPE_ARP: arp_msg = pkt.get_protocols(arp.arp)[0] if arp_msg.opcode == arp.ARP_REQUEST: self.logger.warning( "Received ARP REQUEST on switch%d/%d: Who has %s? Tell %s", dp.id, in_port, arp_msg.dst_ip, arp_msg.src_mac)
def add_forwarding_rule(self, datapath, dl_dst, port): ofctl = OfCtl.factory(datapath, self.logger) actions = [datapath.ofproto_parser.OFPActionOutput(port)] ofctl.set_flow(cookie=0, priority=0, dl_type=ether_types.ETH_TYPE_IP, dl_vlan=VLANID_NONE, dl_dst=dl_dst, actions=actions) print('forwarding_rule:\n switch:%s\n dl_dst: %s\n port: %s' % (datapath.id, dl_dst, port))
def add_forwaring_rule(self, datapath, dl_dst, port): ofctl = OfCtl.factory(datapath, self.logger) actions = [datapath.ofproto_parser.OFPActionOutput(port)] ofctl.set_flow(cookie=0, priority=100, dl_vlan=VLANID_NONE, dl_dst=dl_dst, actions=actions)
def add_forwaring_rule(self, datapath, dl_dst, port): ''' datapath: switch instance <- ofctl_api.get_datapath(self, dpid=host.port.dpid) dl_dst: dest mac addr port: out interface (1,2,3,4...) ''' ofctl = OfCtl.factory(datapath, self.logger) actions = [datapath.ofproto_parser.OFPActionOutput(port)] ofctl.set_flow(cookie=0, priority=0, dl_type=ether_types.ETH_TYPE_IP, dl_vlan=VLANID_NONE, dl_dst=dl_dst, actions=actions)
def packet_in_handler(self, ev): """ EventHandler for PacketIn messages """ msg = ev.msg # In OpenFlow, switches are called "datapaths". Each switch gets its own datapath ID. # In the controller, we pass around datapath objects with metadata about each switch. dp = msg.datapath # Use this object to create packets for the given datapath ofctl = OfCtl.factory(dp, self.logger) in_port = msg.in_port pkt = packet.Packet(msg.data) eth = pkt.get_protocols(ethernet.ethernet)[0] if eth.ethertype == ether_types.ETH_TYPE_ARP: arp_msg = pkt.get_protocols(arp.arp)[0] if arp_msg.opcode == arp.ARP_REQUEST: self.logger.warning( "Received ARP REQUEST on switch%d/%d: Who has %s? Tell %s", dp.id, in_port, arp_msg.dst_ip, arp_msg.src_mac) # TODO: Generate a *REPLY* for this request based on your switch state # Here is an example way to send an ARP packet using the ofctl utilities # ofctl.send_arp(vlan_id=VLANID_NONE, # src_port=ofctl.dp.ofproto.OFPP_CONTROLLER, # . . .) if arp_msg.dst_ip in self.mac_table: ofctl.send_arp(arp_opcode=arp.ARP_REPLY, vlan_id=VLANID_NONE, dst_mac=self.mac_table[arp_msg.src_ip], sender_mac=self.mac_table[arp_msg.dst_ip], sender_ip=arp_msg.dst_ip, target_ip=arp_msg.src_ip, target_mac=arp_msg.src_mac, src_port=ofctl.dp.ofproto.OFPP_CONTROLLER, output_port=in_port)
def rules_update(self): for i in self.tm.all_devices: if isinstance(i, TMHost): for point, num_port in i.path: point.actions = [] self.delete_forwarding_rule(point.get_dp(), "00:00:00:00:00:00") for i in self.tm.all_devices: if isinstance(i, TMHost): for point, num_port in i.path: point.flag = False self.delete_forwarding_rule(point.get_dp(), i.get_mac()) self.add_forwarding_rule(point.get_dp(), i.get_mac(), num_port) datapath = point.get_dp() point.actions += [datapath.ofproto_parser.OFPActionOutput(num_port)] #self.add_forwarding_rule(point.get_dp(), "00:00:00:00:00:00", num_port) for i in self.tm.all_devices: if isinstance(i, TMHost): for point, num_port in i.path: if not point.flag: point.flag = True ofctl = OfCtl.factory(point.get_dp(), self.logger) ofctl.set_flow(cookie=0, priority=0, dl_type=ether_types.ETH_TYPE_IP, dl_vlan=VLANID_NONE, dl_dst="00:00:00:00:00:00", actions=point.actions)
def packet_in_handler(self, ev): """ EventHandler for PacketIn messages """ msg = ev.msg # In OpenFlow, switches are called "datapaths". Each switch gets its own datapath ID. # In the controller, we pass around datapath objects with metadata about each switch. dp = msg.datapath # Use this object to create packets for the given datapath ofctl = OfCtl.factory(dp, self.logger) in_port = msg.in_port pkt = packet.Packet(msg.data) eth = pkt.get_protocols(ethernet.ethernet)[0] if eth.ethertype == ether_types.ETH_TYPE_ARP: arp_msg = pkt.get_protocols(arp.arp)[0] if arp_msg.opcode == arp.ARP_REQUEST: self.logger.warning( "Received ARP REQUEST on switch%d/%d: Who has %s? Tell %s,ip:%s,opcode:%s", dp.id, in_port, arp_msg.dst_ip, arp_msg.src_mac, arp_msg.src_ip, arp_msg.opcode) self.logger.warning(arp_msg) """ Generate an ARP packet and send it Arguments: arp_opcode -- Opcode for message vlan_id -- VLAN identifier, or VLANID_NONE dst_mac -- Destination to send the packet (not an ARP field) sender_mac -- Sender hardware address sender_ip -- Sender protocol address target_mac -- Target hardware address target_ip -- Target protocol address src_port -- Source port number for sending message (can be OFPP_CONTROLLER) output_port -- Outgoing port number to send message """# src 出发,dst收尾 reply_mac = None for i in self.tm.hostes: print(i.host.ipv4) if i.host.ipv4[0] == arp_msg.dst_ip: reply_mac = i.mac break print("reply is {}".format(reply_mac)) if reply_mac is None: return else: ofctl.send_arp( arp_opcode=2, vlan_id=VLANID_NONE, dst_mac=arp_msg.src_mac, sender_mac=reply_mac, sender_ip=arp_msg.dst_ip, target_mac=arp_msg.src_mac, target_ip=arp_msg.src_ip, src_port=ofctl.dp.ofproto.OFPP_CONTROLLER, #src_port=in_port, output_port=in_port) print("send finish") for i in self.tm.switches: for j in i.neighbors: print(i.name, j[0].name, j[1]) # for j in i.host: # print(i.name,j.name,j.host.port.port_no) self.BFS_1()
def delete_forwarding_rule(self, datapath, dl_dst): ofctl = OfCtl.factory(datapath, self.logger) match = datapath.ofproto_parser.OFPMatch(dl_dst=dl_dst) ofctl.delete_flow(cookie=0, priority=0, match=match)
def packet_in_handler(self, ev): """ EventHandler for PacketIn messages """ msg = ev.msg pkt = packet.Packet(data=msg.data) pkt_ethernet = pkt.get_protocol(ethernet.ethernet) if not pkt_ethernet: return if pkt_ethernet.ethertype == 35020: return # In OpenFlow, switches are called "datapaths". Each switch gets its own datapath ID. # In the controller, we pass around datapath objects with metadata about each switch. dp = msg.datapath # Use this object to create packets for the given datapath ofctl = OfCtl.factory(dp, self.logger) in_port = msg.in_port pkt = packet.Packet(msg.data) eth = pkt.get_protocols(ethernet.ethernet)[0] if eth.ethertype == ether_types.ETH_TYPE_ARP: # print('arp packet in!!') arp_msg = pkt.get_protocols(arp.arp)[0] if arp_msg.opcode == arp.ARP_REQUEST: self.logger.warning("Received ARP REQUEST on switch%d/%d: Who has %s? Tell %s", dp.id, in_port, arp_msg.dst_ip, arp_msg.src_mac) # Generate a *REPLY* for this request based on your switch state result_mac = self.tm.get_mac_by_ip(arp_msg.dst_ip) if result_mac is not None: # 如果mac地址存在,则返回包 print('%s to %s' % (arp_msg.dst_ip, result_mac)) ofctl.send_arp(arp_opcode=arp.ARP_REPLY, vlan_id=VLANID_NONE, dst_mac=arp_msg.src_mac, sender_mac=result_mac, sender_ip=arp_msg.dst_ip, target_mac=arp_msg.src_mac, target_ip=arp_msg.src_ip, src_port=ofctl.dp.ofproto.OFPP_CONTROLLER, output_port=msg.in_port) self.tm.print_shortest_path(arp_msg.src_mac, result_mac) else: if not self.loop_mode: print('this mac not exits.') return # 如果mac地址不存在,则泛洪 msg = ev.msg data = msg.data datapath = msg.datapath # print(dp.id) ofproto = datapath.ofproto ofp_parser = datapath.ofproto_parser if self.sp_mode: if "switch_{}".format(dp.id) in self.port_map.keys(): actions = [] for p in self.port_map["switch_{}".format(dp.id)]: if p != msg.in_port: # print(msg.in_port, p) actions.append(ofp_parser.OFPActionOutput(p)) else: actions = [ofp_parser.OFPActionOutput(ofproto.OFPP_FLOOD)] else: actions = [ofp_parser.OFPActionOutput(ofproto.OFPP_FLOOD)] out = ofp_parser.OFPPacketOut( datapath=datapath, buffer_id=msg.buffer_id, in_port=msg.in_port, actions=actions, data=data) datapath.send_msg(out)