def _rcv_frame(self, frame): pkt = Ether(frame) self.log.info('received packet', pkt=pkt) if pkt.haslayer(Dot1Q): if pkt.haslayer(Dot1AD): outer_shim = pkt.getlayer(Dot1AD) else: outer_shim = pkt.getlayer(Dot1Q) if pkt.haslayer(IP) or outer_shim.type == EAP_ETH_TYPE: # We don't have any context about the packet at this point. # Assume that only downstream traffic is double-tagged. if isinstance(outer_shim.payload, Dot1Q): logical_port = int(self.nni_port.port_no) else: cvid = outer_shim.vlan logical_port = self.get_subscriber_uni_port(cvid) popped_frame = ( Ether(src=pkt.src, dst=pkt.dst, type=outer_shim.type) / outer_shim.payload ) kw = dict( logical_device_id=self.logical_device_id, logical_port_no=logical_port, ) self.log.info('sending-packet-in', **kw) self.adapter_agent.send_packet_in( packet=str(popped_frame), **kw) elif pkt.haslayer(Raw): raw_data = json.loads(pkt.getlayer(Raw).load) self.alarms.send_alarm(self, raw_data)
def main(p4info_file_path, bmv2_file_path): p4info_helper = p4runtime_lib.helper.P4InfoHelper(p4info_file_path) pk = PortKnocking() pk.load() switches_conf = load_switches_conf() firewall_rules = load_firewall_rules() forward_rules = load_forward_rules() pk_packet_in_rules = load_pk_packet_in_rules() try: switches = connect_to_switches(switches_conf["switches"]) send_master_arbitration_updates(switches) set_pipelines(switches, p4info_helper, bmv2_file_path) install_direct_forwarding_rules(p4info_helper, switches) install_firewall_rules(p4info_helper, switches, switches_conf["switches"], firewall_rules["switches"]) install_port_knock_in_rules(p4info_helper, switches, switches_conf["switches"], pk_packet_in_rules["switches"]) install_forwarding_rules(p4info_helper, switches, switches_conf["switches"], forward_rules["switches"]) switch_2 = switches[1] while True: packet_in = switch_2.PacketIn() print("Recibido paquete: "+str(packet_in)) if packet_in.WhichOneof('update') == 'packet': pkt = Ether(_pkt=packet_in.packet.payload) src_ip = pkt.getlayer(IP).src dst_ip = pkt.getlayer(IP).dst tcp_dPort = pkt.getlayer(TCP).dport print("SRC IP: " + str(src_ip)) print("DST IP: " + str(dst_ip)) print("TCP DPORT: " + str(tcp_dPort)) if pkt.getlayer(TCP): pk.check(src_ip, dst_ip, tcp_dPort) if pk.has_authed(src_ip, dst_ip): install_allowance_rules(p4info_helper, switch_2, src_ip, dst_ip, pk.config["hidden_services"][dst_ip]) except KeyboardInterrupt: print(" Shutting down.") except grpc.RpcError as e: printGrpcError(e) ShutdownAllSwitchConnections()
def on_pkt_rx(self, pkt, start_ts): scapy_pkt = Ether(pkt['binary']) if scapy_pkt.haslayer('ICMPv6EchoReply'): node_ip = scapy_pkt.getlayer(IPv6).src hlim = scapy_pkt.getlayer(IPv6).hlim dst_ip = scapy_pkt.getlayer(IPv6).dst if dst_ip != self.src_ip: # not our ping return dt = pkt['ts'] - start_ts self.result['formatted_string'] = 'Reply from {0}: bytes={1}, time={2:.2f}ms, hlim={3}'.format(node_ip, len(pkt['binary']), dt * 1000, hlim) self.result['src_ip'] = node_ip self.result['rtt'] = dt * 1000 self.result['ttl'] = hlim self.result['status'] = 'success' return self.port.ok(self.result) if scapy_pkt.haslayer('ICMPv6ND_NS') and scapy_pkt.haslayer('ICMPv6NDOptSrcLLAddr'): node_mac = scapy_pkt.getlayer(ICMPv6NDOptSrcLLAddr).lladdr node_ip = scapy_pkt.getlayer(IPv6).src dst_ip = scapy_pkt.getlayer(IPv6).dst if dst_ip != self.src_ip: # not our ping return self.send_intermediate(self.generate_ns_na(node_mac, node_ip)) if scapy_pkt.haslayer('ICMPv6DestUnreach'): node_ip = scapy_pkt.getlayer(IPv6).src dst_ip = scapy_pkt.getlayer(IPv6).dst if dst_ip != self.src_ip: # not our ping return self.result['formatted_string'] = 'Reply from {0}: Destination host unreachable'.format(node_ip) self.result['status'] = 'unreachable' return self.port.ok(self.result)
def packet_out(self, egress_port, msg): pkt = Ether(msg) self.log.debug('packet out', egress_port=egress_port, device_id=self.device_id, logical_device_id=self.logical_device_id, packet=str(pkt).encode("HEX")) # Find port type egress_port_type = self.platform.intf_id_to_port_type_name(egress_port) if egress_port_type == Port.ETHERNET_UNI: if pkt.haslayer(Dot1Q): outer_shim = pkt.getlayer(Dot1Q) if isinstance(outer_shim.payload, Dot1Q): # If double tag, remove the outer tag payload = ( Ether(src=pkt.src, dst=pkt.dst, type=outer_shim.type) / outer_shim.payload) else: payload = pkt else: payload = pkt send_pkt = binascii.unhexlify(str(payload).encode("HEX")) self.log.debug( 'sending-packet-to-ONU', egress_port=egress_port, intf_id=self.platform.intf_id_from_uni_port_num(egress_port), onu_id=self.platform.onu_id_from_port_num(egress_port), uni_id=self.platform.uni_id_from_port_num(egress_port), port_no=egress_port, packet=str(payload).encode("HEX")) onu_pkt = openolt_pb2.OnuPacket( intf_id=self.platform.intf_id_from_uni_port_num(egress_port), onu_id=self.platform.onu_id_from_port_num(egress_port), port_no=egress_port, pkt=send_pkt) self.stub.OnuPacketOut(onu_pkt) elif egress_port_type == Port.ETHERNET_NNI: self.log.debug('sending-packet-to-uplink', egress_port=egress_port, packet=str(pkt).encode("HEX")) send_pkt = binascii.unhexlify(str(pkt).encode("HEX")) uplink_pkt = openolt_pb2.UplinkPacket( intf_id=self.platform.intf_id_from_nni_port_num(egress_port), pkt=send_pkt) self.stub.UplinkPacketOut(uplink_pkt) else: self.log.warn('Packet-out-to-this-interface-type-not-implemented', egress_port=egress_port, port_type=egress_port_type)
def packet_out(self, egress_port, msg): pkt = Ether(msg) self.log.info('packet out', egress_port=egress_port, packet=str(pkt).encode("HEX")) if pkt.haslayer(Dot1Q): outer_shim = pkt.getlayer(Dot1Q) if isinstance(outer_shim.payload, Dot1Q): payload = ( Ether(src=pkt.src, dst=pkt.dst, type=outer_shim.type) / outer_shim.payload ) else: payload = pkt else: payload = pkt self.log.info('sending-packet-to-device', egress_port=egress_port, packet=str(payload).encode("HEX")) send_pkt = binascii.unhexlify(str(payload).encode("HEX")) onu_pkt = openolt_pb2.OnuPacket(intf_id=intf_id_from_port_num(egress_port), onu_id=onu_id_from_port_num(egress_port), pkt=send_pkt) self.stub.OnuPacketOut(onu_packet)
def process_actions(flow, frame): egress_port = None for action in get_actions(flow): if action.type == OUTPUT: egress_port = action.output.port elif action.type == POP_VLAN: if frame.haslayer(Dot1Q): shim = frame.getlayer(Dot1Q) frame = Ether( src=frame.src, dst=frame.dst, type=shim.type) / shim.payload elif action.type == PUSH_VLAN: frame = ( Ether(src=frame.src, dst=frame.dst, type=action.push.ethertype) / Dot1Q(type=frame.type) / frame.payload ) elif action.type == SET_FIELD: assert (action.set_field.field.oxm_class == ofp.OFPXMC_OPENFLOW_BASIC) field = action.set_field.field.ofb_field if field.type == VLAN_VID: shim = frame.getlayer(Dot1Q) shim.vlan = field.vlan_vid & 4095 elif field.type == VLAN_PCP: shim = frame.getlayer(Dot1Q) shim.prio = field.vlan_pcp else: raise NotImplementedError('set_field.field.type=%d' % field.type) else: raise NotImplementedError('action.type=%d' % action.type) return egress_port, frame
def main(p4info_file_path, bmv2_file_path): # Instantiate a P4Runtime helper from the p4info file ip2id_l = {} id_manager = IdManager(2**16 - 1) p4info_helper = p4runtime_lib.helper.P4InfoHelper(p4info_file_path) switches_conf = load_switches_conf() pr_rules = load_pr_rules() sdnc_pi_rules = load_sdnc_pkt_in_rules() fwd_rules = load_fwd_rules() pk_rules = load_pk_rules() try: switches = connect_to_switches(switches_conf["switches"]) send_master_arbitration_updates(switches) set_pipelines(switches, p4info_helper, bmv2_file_path) install_direct_forwarding_rules(p4info_helper, switches) install_rules_protected_services(p4info_helper, switches, switches_conf, pr_rules["switches"]) install_port_knock_in_rules(p4info_helper, switches, switches_conf, sdnc_pi_rules["switches"]) install_forwarding_rules(p4info_helper, switches, switches_conf, fwd_rules["switches"]) switch_2 = switches[1] while True: packet_in = switch_2.PacketIn() if packet_in.WhichOneof('update') == 'packet': pkt = Ether(_pkt=packet_in.packet.payload) src_ip = pkt.getlayer(IP).src print("SRC IP: " + str(src_ip)) new_id = id_manager.get_id() print("New ID: " + str(new_id)) ip2id_l[str(src_ip)] = new_id install_pip2id_rules(p4info_helper, switches, src_ip, new_id) install_pk_rules(p4info_helper, switches, switches_conf, pk_rules["switches"]) except KeyboardInterrupt: print(" Shutting down.") except grpc.RpcError as e: printGrpcError(e) ShutdownAllSwitchConnections()
def packet_out(self, egress_port, msg): self.log.debug('sending-packet-out', egress_port=egress_port, msg_hex=hexify(msg)) pkt = Ether(msg) out_pkt = pkt self.log.debug("packet_out: incoming: %s" % pkt.summary()) if egress_port != self.nni_port.port_no: # don't do the vlan manipulation for the NNI port, vlans are already correct if pkt.haslayer(Dot1Q): if pkt.haslayer(Dot1AD): outer_shim = pkt.getlayer(Dot1AD) else: outer_shim = pkt.getlayer(Dot1Q) if isinstance(outer_shim.payload, Dot1Q): # If double tag, remove the outer tag out_pkt = ( Ether(src=pkt.src, dst=pkt.dst, type=outer_shim.type) / outer_shim.payload ) else: out_pkt = pkt else: # Add egress port as VLAN tag out_pkt = ( Ether(src=pkt.src, dst=pkt.dst) / Dot1Q(vlan=egress_port, type=pkt.type) / pkt.payload ) self.log.debug("packet_out: outgoing: %s" % out_pkt.summary()) # TODO need better way of mapping logical ports to PON ports out_port = self.nni_port.port_no if egress_port == self.nni_port.port_no else 1 if self.ponsim_comm == 'grpc': # send over grpc stream stub = ponsim_pb2_grpc.PonSimStub(self.get_channel()) frame = PonSimFrame(id=self.device_id, payload=str(out_pkt), out_port=out_port) stub.SendFrame(frame) else: # send over frameio self.io_port.send(str(out_pkt))
def _rcv_frame(self, frame): pkt = Ether(frame) if pkt.haslayer(Dot1Q): outer_shim = pkt.getlayer(Dot1Q) if isinstance(outer_shim.payload, Dot1Q): inner_shim = outer_shim.payload cvid = inner_shim.vlan popped_frame = ( Ether(src=pkt.src, dst=pkt.dst, type=inner_shim.type) / inner_shim.payload) self.log.info('sending-packet-in', device_id=self.device_id, port=cvid) yield self.core_proxy.send_packet_in(device_id=self.device_id, port=cvid, packet=str(popped_frame)) elif pkt.haslayer(Raw): raw_data = json.loads(pkt.getlayer(Raw).load) self.alarms.send_alarm(self, raw_data)
def on_pkt_rx(self, pkt, start_ts): # convert to scapy scapy_pkt = Ether(pkt['binary']) if scapy_pkt.haslayer('ICMPv6ND_NS') and scapy_pkt.haslayer('ICMPv6NDOptSrcLLAddr'): node_mac = scapy_pkt.getlayer(ICMPv6NDOptSrcLLAddr).lladdr node_ip = scapy_pkt.getlayer(IPv6).src if node_ip not in self.responses: self.send_intermediate(self.generate_ns_na(node_mac, node_ip)) elif scapy_pkt.haslayer('ICMPv6ND_NA'): is_router = scapy_pkt.getlayer(ICMPv6ND_NA).R node_ip = scapy_pkt.getlayer(ICMPv6ND_NA).tgt dst_ip = scapy_pkt.getlayer(IPv6).dst node_mac = scapy_pkt.src if node_ip not in self.responses and dst_ip == self.src_ip: self.responses[node_ip] = {'type': 'Router' if is_router else 'Host', 'mac': node_mac} elif scapy_pkt.haslayer('ICMPv6EchoReply'): node_mac = scapy_pkt.src node_ip = scapy_pkt.getlayer(IPv6).src if node_ip == self.dst_ip and node_ip != 'ff02::1': # for ping ipv6 return self.port.ok([{'type': 'N/A', 'ipv6': node_ip, 'mac': node_mac}]) if node_ip not in self.responses: self.send_intermediate(self.generate_ns_na(node_mac, node_ip))
def _rcv_frame(self, frame): pkt = Ether(frame) if pkt.haslayer(Dot1Q): outer_shim = pkt.getlayer(Dot1Q) if isinstance(outer_shim.payload, Dot1Q): inner_shim = outer_shim.payload cvid = inner_shim.vlan logical_port = cvid popped_frame = ( Ether(src=pkt.src, dst=pkt.dst, type=inner_shim.type) / inner_shim.payload) kw = dict( logical_device_id=self.logical_device_id, logical_port_no=logical_port, ) self.log.info('sending-packet-in', **kw) self.adapter_agent.send_packet_in(packet=str(popped_frame), **kw) elif pkt.haslayer(Raw): raw_data = json.loads(pkt.getlayer(Raw).load) self.alarms.send_alarm(self, raw_data)
def run(self): """ Infinite loop that receives from the host's interface, checks if the message is a control message or a normal packet and treats it accordingly. Calls the general control packet handler if the message was a control message. Filters the received traffic for packet belonging to an active handover. :return: """ try: while True: buf = self.sock.recv(1500) eth_type = struct.unpack_from('!H', buf, 12)[0] # logging.info(repr(pkt)) if eth_type == CONTROL_MESSAGE_ETHER_TYPE: pkt = Ether(buf) # control message # logging.info("CONTROL MESSAGE RECEIVED") msg, length = HandoverMessage.parser( bytearray(pkt.getlayer(Raw).load)) if msg.cmd == HandoverMessage.CMD_TRANSPORT_PKT: # wrapped queued message from controller. queue it locally self.queue_msg(self.handovers[msg.handover_id], msg.tlvs[0].payload, True) # logging.info("queue from controller {}".format(self.port_id)) else: self.control_msg_handler(self.port_id, msg) else: matching_handover = False with self.handovers_lock: if self.handovers: for id, handover in self.handovers.items(): if handover.matches_packet(self.port_id, buf): # this packet belongs to this handover. lets queue it # logging.info('found matching handover at {}'.format(['ingress', 'egress'][self.id])) self.queue_msg(handover, buf, False) matching_handover = True break if not matching_handover: self.send(buf) except: logging.error(traceback.format_exc())
def rcv_io(self, port, frame): self.log.info('received', iface_name=port.iface_name, frame_len=len(frame)) pkt = Ether(frame) if pkt.haslayer(Dot1Q): outer_shim = pkt.getlayer(Dot1Q) if isinstance(outer_shim.payload, Dot1Q): inner_shim = outer_shim.payload cvid = inner_shim.vlan logical_port = cvid popped_frame = ( Ether(src=pkt.src, dst=pkt.dst, type=inner_shim.type) / inner_shim.payload) kw = dict( logical_device_id=self.logical_device_id, logical_port_no=logical_port, ) self.log.info('sending-packet-in', **kw) self.adapter_agent.send_packet_in(packet=str(popped_frame), **kw)
def process_pcap(pcap_file_name): func_name = "process_pcap - " print(func_name + "opening file:" + pcap_file_name) count = 0 interesting_packet_count = 0 for ( pkt_data, pkt_metadata, ) in RawPcapReader(pcap_file_name): count += 1 ether_pkt = Ether(pkt_data) ''' if 'type' not in ether_pkt.fields: # LLC frames will have 'len' instead of 'type'. # We disregard those continue ''' print(func_name + "packet[" + str(count) + "] content:\n") #print(ether_pkt.show()) isis_common_header = "ISIS Common Header" for key, val in ether_pkt.fields.items(): print(str(key) + ":" + str(val)) if not ether_pkt.haslayer(isis_common_header): print(func_name + "packet[" + str(count) + "] is NOT an ISIS packet, ignore it") continue isis_hello_pdu_type_num = 17 isis_common_header_feilds = ether_pkt.getlayer( isis_common_header).fields for key, val in isis_common_header_feilds.items(): print(str(key) + ":" + str(val)) if val == isis_hello_pdu_type_num: print(func_name + "packet[" + str(count) + "] is ISIS Hello PDU") '''
def handle_packet_in(self, ind_info): self.log.info('Received Packet-In', ind_info=ind_info) pkt = Ether(ind_info['packet']) if pkt.haslayer(Dot1Q): outer_shim = pkt.getlayer(Dot1Q) if isinstance(outer_shim.payload, Dot1Q): inner_shim = outer_shim.payload cvid = inner_shim.vlan logical_port = cvid popped_frame = ( Ether(src=pkt.src, dst=pkt.dst, type=inner_shim.type) / inner_shim.payload) kw = dict( logical_device_id=self.logical_device_id, logical_port_no=logical_port, ) self.log.info('sending-packet-in', **kw) self.adapter_agent.send_packet_in(packet=str(popped_frame), **kw) reactor.callLater(1, self.process_packet_in)
def extract_one_packet(buf): """Extract one packet from the incoming buf buffer. Takes string as input and looks for first whole packet in it. If it finds one, it returns substring from the buf parameter. :param buf: String representation of incoming packet buffer. :type buf: str :returns: String representation of first packet in buf. :rtype: str """ pkt_len = 0 if len(buf) < 60: return None try: ether_type = Ether(buf[0:14]).type except AttributeError: raise RuntimeError(f"No EtherType in packet {buf!r}") if ether_type == ETH_P_IP: # 14 is Ethernet fame header size. # 4 bytes is just enough to look for length in ip header. # ip total length contains just the IP packet length so add the Ether # header. pkt_len = Ether(buf[0:14 + 4]).len + 14 if len(buf) < 60: return None elif ether_type == ETH_P_IPV6: if not Ether(buf[0:14 + 6]).haslayer(IPv6): raise RuntimeError(f"Invalid IPv6 packet {buf!r}") # ... to add to the above, 40 bytes is the length of IPV6 header. # The ipv6.len only contains length of the payload and not the header pkt_len = Ether(buf)[u"IPv6"].plen + 14 + 40 if len(buf) < 60: return None elif ether_type == ETH_P_ARP: pkt = Ether(buf[:20]) if not pkt.haslayer(ARP): raise RuntimeError(u"Incomplete ARP packet") # len(eth) + arp(2 hw addr type + 2 proto addr type # + 1b len + 1b len + 2b operation) pkt_len = 14 + 8 pkt_len += 2 * pkt.getlayer(ARP).hwlen pkt_len += 2 * pkt.getlayer(ARP).plen del pkt elif ether_type == 32821: # RARP (Reverse ARP) pkt = Ether(buf[:20]) pkt.type = ETH_P_ARP # Change to ARP so it works with scapy pkt = Ether(pkt) if not pkt.haslayer(ARP): pkt.show() raise RuntimeError(u"Incomplete RARP packet") # len(eth) + arp(2 hw addr type + 2 proto addr type # + 1b len + 1b len + 2b operation) pkt_len = 14 + 8 pkt_len += 2 * pkt.getlayer(ARP).hwlen pkt_len += 2 * pkt.getlayer(ARP).plen del pkt else: raise RuntimeError(f"Unknown protocol {ether_type}") if pkt_len < 60: pkt_len = 60 if len(buf) < pkt_len: return None return buf[0:pkt_len]
def _rcv_io(self, port, frame): log.info('frame-received', frame=hexify(frame)) # make into frame to extract source mac response = Ether(frame) if response.haslayer(Dot1Q): # All OAM responses from the OLT should have a TIBIT_MGMT_VLAN. # Responses from the ONUs should have a TIBIT_MGMT_VLAN followed by a ONU CTAG # All packet-in frames will have the TIBIT_PACKET_IN_VLAN. if response.getlayer(Dot1Q).type == 0x8100: if response.getlayer(Dot1Q).vlan == TIBIT_PACKET_IN_VLAN: inner_tag_and_rest = response.payload.payload if isinstance(inner_tag_and_rest, Dot1Q): cvid = inner_tag_and_rest.vlan frame = Ether(src=response.src, dst=response.dst, type=inner_tag_and_rest.type) /\ inner_tag_and_rest.payload _, logical_device_id = self.vlan_to_device_ids.get(cvid) if logical_device_id is None: log.error('invalid-cvid', cvid=cvid) else: self.adapter_agent.send_packet_in( logical_device_id=logical_device_id, logical_port_no=cvid, # C-VID encodes port no packet=str(frame)) else: log.error('packet-in-single-tagged', frame=hexify(response)) else: ## Mgmt responses received from the ONU ## Since the type of the first layer is 0x8100, ## then the frame must have an inner tag layer olt_mac = response.src device_id = self.device_ids[olt_mac] channel_id = response[Dot1Q:2].vlan log.info('received_channel_id', channel_id=channel_id, device_id=device_id) proxy_address=Device.ProxyAddress( device_id=device_id, channel_id=channel_id ) # pop dot1q header(s) msg = response.payload.payload self.adapter_agent.receive_proxied_message(proxy_address, msg) else: ## Mgmt responses received from the OLT ## enqueue incoming parsed frame to right device log.info('received-dot1q-not-8100') self.incoming_queues[response.src].put(response)
def main(p4info_file_path, bmv2_file_path): # Instantiate a P4Runtime helper from the p4info file mac_to_port = defaultdict(dict) p4info_helper = helper.P4InfoHelper(p4info_file_path) try: # Create a switch connection object for s1 and s2; # this is backed by a P4Runtime gRPC connection. # Also, dump all P4Runtime messages sent to switch to given txt files. s1 = bmv2.Bmv2SwitchConnection( name='s0', address='127.0.0.1:50051', device_id=1) # Send master arbitration update message to establish this controller as # master (required by P4Runtime before performing any other write operation) s1.MasterArbitrationUpdate() # Install the P4 program on the switches s1.SetForwardingPipelineConfig(p4info=p4info_helper.p4info, bmv2_json_file_path=bmv2_file_path) print "Installed P4 Program using SetForwardingPipelineConfig on s1" # Write the rules that tunnel traffic from h1-h2 to s1 # writeIpv4Rules(p4info_helper, sw_id=s1, dst_ip_addr="10.10.10.1", port = 1) # writeIpv4Rules(p4info_helper, sw_id=s1, dst_ip_addr="10.10.10.2", port = 2) # writeIpv4Rules(p4info_helper, sw_id=s1, dst_ip_addr="10.10.3.3", port = 3) # readTableRules(p4info_helper, s1) mc_group_entry = p4info_helper.buildMulticastGroupEntry(1, replicas=[ {'egress_port': 1, 'instance': 1}, {'egress_port': 2, 'instance': 2}, {'egress_port': 3, 'instance': 3}, {'egress_port': 4, 'instance': 4}, {'egress_port': 5, 'instance': 5}, {'egress_port': 64, 'instance': 64} ]) s1.WritePREEntry(mc_group_entry) print "Installed mgrp on s1." writeBroadcastRules(p4info_helper, s1) readTableRules(p4info_helper, s1) lldp_thread = LLDP_Thread(s1) # lldp_thread.run() # lldp_thread.start() # counter = 0 while True: packetin = s1.PacketIn() # counter += 1 payload = packetin.packet.payload pkt = Ether(_pkt=payload[12:]) # metadata = packetin.packet.metadata[0] # metadata_id = metadata.metadata_id # port = metadata.value # pkt_type = packetin.packet.metadata[1].value zeros = struct.unpack(">q", payload[:8])[0] port = struct.unpack(">H", payload[8:10])[0] type = struct.unpack(">H", payload[10:12])[0] if zeros == 0: pkt_eth_src = pkt.getlayer(Ether).src pkt_eth_dst = pkt.getlayer(Ether).dst ether_type = pkt.getlayer(Ether).type # self send lldp if type == 5: pass elif type == 4: pass else: lldp_thread.run() # if pkt_eth_src in mac_to_port[s1.name]: # writeIpv4Rules(p4info_helper,s1,pkt_eth_src,mac_to_port[s1.name][pkt_eth_src]) # if ether_type == 2048 or ether_type == 2054: # writeIpv4Rules(p4info_helper, s1, pkt_eth_src, port) mac_to_port[s1.name][pkt_eth_src] = port if pkt_eth_dst not in mac_to_port[s1.name]: writeFloodingRules(p4info_helper, s1, pkt_eth_src, pkt_eth_dst) else: writeIpv4Rules(p4info_helper, s1, pkt_eth_src, pkt_eth_dst, mac_to_port[s1.name][pkt_eth_dst]) writeIpv4Rules(p4info_helper, s1, pkt_eth_dst, pkt_eth_src, mac_to_port[s1.name][pkt_eth_src]) readTableRules(p4info_helper, s1) packet_out = p4runtime_pb2.PacketOut() packet_out.payload = payload[12:] # def packet_Out(s1,packetout): # s1.PacketOut(packetout) # thread.start_new_thread(packet_Out,(s1,packet_out)) # packet_out.metadata = metadata s1.PacketOut(packet_out) # if counter % 10 == 0: else: pass except KeyboardInterrupt: print " Shutting down." except grpc.RpcError as e: printGrpcError(e) ShutdownAllSwitchConnections()
def packet_out_process(self, topic, msg): def get_port_out(opo): for action in opo.actions: if action.type == OUTPUT: return action.output.port pb = Parse(loads(msg), ofp.PacketOut(), ignore_unknown_fields=True) logical_device_id = pb.id ofp_packet_out = pb.packet_out self.log.debug("received packet-out form kafka", logical_device_id=logical_device_id, ofp_packet_out=ofp_packet_out) egress_port = get_port_out(ofp_packet_out) msg = ofp_packet_out.data self.log.debug('rcv-packet-out', logical_device_id=logical_device_id, egress_port=egress_port, # adapter_name=self.adapter_name, data=hexify(msg)) pkt = Ether(msg) self.log.debug('packet out', egress_port=egress_port, packet=str(pkt).encode("HEX")) # Find port type egress_port_type = self.device.platform \ .intf_id_to_port_type_name(egress_port) if egress_port_type == Port.ETHERNET_UNI: if pkt.haslayer(Dot1Q): outer_shim = pkt.getlayer(Dot1Q) if isinstance(outer_shim.payload, Dot1Q): # If double tag, remove the outer tag payload = ( Ether(src=pkt.src, dst=pkt.dst, type=outer_shim.type) / outer_shim.payload ) else: payload = pkt else: payload = pkt send_pkt = binascii.unhexlify(str(payload).encode("HEX")) self.log.debug( 'sending-packet-to-ONU', egress_port=egress_port, intf_id=self.device.platform.intf_id_from_uni_port_num( egress_port), onu_id=self.device.platform.onu_id_from_port_num(egress_port), uni_id=self.device.platform.uni_id_from_port_num(egress_port), port_no=egress_port, packet=str(payload).encode("HEX")) onu_pkt = openolt_pb2.OnuPacket( intf_id=self.device.platform.intf_id_from_uni_port_num( egress_port), onu_id=self.device.platform.onu_id_from_port_num(egress_port), port_no=egress_port, pkt=send_pkt) self.device.stub.OnuPacketOut(onu_pkt) elif egress_port_type == Port.ETHERNET_NNI: self.log.debug('sending-packet-to-uplink', egress_port=egress_port, packet=str(pkt).encode("HEX")) send_pkt = binascii.unhexlify(str(pkt).encode("HEX")) uplink_pkt = openolt_pb2.UplinkPacket( intf_id=self.device.platform.intf_id_from_nni_port_num( egress_port), pkt=send_pkt) self.device.stub.UplinkPacketOut(uplink_pkt) else: self.log.warn('Packet-out-to-this-interface-type-not-implemented', egress_port=egress_port, port_type=egress_port_type)