def check_no_cpu_packets(duthost, port, packet_fingerprint): start_pcap = "tcpdump -i %s -w %s" % (port, PACKET_SAVE_PATH) stop_pcap = "pkill -f '%s'" % start_pcap start_pcap = "nohup %s &" % start_pcap duthost.shell(start_pcap) try: yield finally: time.sleep(1.0) duthost.shell(stop_pcap, module_ignore_errors=True) with tempfile.NamedTemporaryFile() as tmp_pcap: duthost.fetch(src=PACKET_SAVE_PATH, dest=tmp_pcap.name, flat=True) received_packets = sniff(offline=tmp_pcap.name) logging.debug("Packets received from port %s:", port) for i, pkt in enumerate(received_packets): logging.debug("%d: %s" % (i, utilities.dump_scapy_packet_show_output(pkt))) packets_with_fingerprint = [ _ for _ in received_packets if packet_fingerprint in str(_) ] pytest_assert( len(packets_with_fingerprint) == 0, "Received packets with fingerprint %s" % packet_fingerprint)
def test_decap_active_tor(apply_active_state_to_orchagent, build_encapsulated_packet, rand_selected_interface, ptfadapter, tbinfo, rand_selected_dut, tunnel_traffic_monitor): tor = rand_selected_dut encapsulated_packet = build_encapsulated_packet iface, _ = rand_selected_interface exp_ptf_port_index = get_ptf_server_intf_index(tor, tbinfo, iface) exp_pkt = build_expected_packet_to_server(encapsulated_packet) ptfadapter.dataplane.flush() ptf_t1_intf = random.choice(get_t1_ptf_ports(tor, tbinfo)) logging.info("send encapsulated packet from ptf t1 interface %s", ptf_t1_intf) testutils.send(ptfadapter, int(ptf_t1_intf.strip("eth")), encapsulated_packet, count=10) _, rec_pkt = testutils.verify_packet_any_port(ptfadapter, exp_pkt, ports=[exp_ptf_port_index]) rec_pkt = Ether(rec_pkt) logging.info("received decap packet:\n%s", dump_scapy_packet_show_output(rec_pkt)) exp_ttl = encapsulated_packet[IP].payload[IP].ttl - 1 exp_tos = encapsulated_packet[IP].payload[IP].tos if rec_pkt[IP].ttl != exp_ttl: pytest.fail("the expected ttl should be %s" % exp_ttl) if rec_pkt[IP].tos != exp_tos: pytest.fail("the expected tos should be %s" % exp_tos)
def __exit__(self, *exc_info): if exc_info[0]: return try: port_index, rec_pkt = testutils.verify_packet_any_port( ptfadapter, self.exp_pkt, ports=self.listen_ports) except AssertionError as detail: logging.debug("Error occurred in polling for tunnel traffic", exc_info=True) if "Did not receive expected packet on any of ports" in str( detail): if self.existing: raise detail else: raise detail else: self.rec_pkt = Ether(rec_pkt) rec_port = self.listen_ports[port_index] logging.debug("Receive encap packet from PTF interface %s", "eth%s" % rec_port) logging.debug("Encapsulated packet:\n%s", dump_scapy_packet_show_output(self.rec_pkt)) if not self.existing: raise RuntimeError( "Detected tunnel traffic from host %s." % self.standby_tor.hostname) ttl_check_res = self._check_ttl(self.rec_pkt) tos_check_res = self._check_tos(self.rec_pkt) check_res = [] if ttl_check_res: check_res.append(ttl_check_res) if tos_check_res: check_res.append(tos_check_res) if check_res: raise ValueError(", ".join(check_res) + ".")
def test_dscp_to_queue_during_decap_on_active( ptfhost, setup_dualtor_tor_active, build_encapsulated_ip_packet, request, rand_selected_interface, ptfadapter, tbinfo, rand_selected_dut, tunnel_traffic_monitor, duthosts, rand_one_dut_hostname): """ Test if DSCP to Q mapping for inner header is matching with outer header during decap on active """ tor = rand_selected_dut encapsulated_packet = build_encapsulated_ip_packet iface, _ = rand_selected_interface exp_ptf_port_index = get_ptf_server_intf_index(tor, tbinfo, iface) exp_pkt = build_expected_packet_to_server(encapsulated_packet) # Clear queue counters duthost = duthosts[rand_one_dut_hostname] duthost.shell('sonic-clear queuecounters') logging.info("Clearing queue counters before starting traffic") with stop_garp(ptfhost): ptfadapter.dataplane.flush() ptf_t1_intf = random.choice(get_t1_ptf_ports(tor, tbinfo)) logging.info("send encapsulated packet from ptf t1 interface %s", ptf_t1_intf) testutils.send(ptfadapter, int(ptf_t1_intf.strip("eth")), encapsulated_packet, count=10) exp_tos = encapsulated_packet[IP].payload[IP].tos exp_dscp = exp_tos >> 2 exp_queue = derive_queue_id_from_dscp(exp_dscp) _, rec_pkt = testutils.verify_packet_any_port( ptfadapter, exp_pkt, ports=[exp_ptf_port_index], timeout=10) rec_pkt = Ether(rec_pkt) logging.info("received decap packet:\n%s", dump_scapy_packet_show_output(rec_pkt)) time.sleep(10) rec_queue = get_queue_id_of_received_packet(duthosts, rand_one_dut_hostname, rand_selected_interface) if rec_queue == None or rec_queue != exp_queue: pytest.fail( "the expected Queue : {} not matching with received Queue : {}" .format(exp_queue, rec_queue)) else: logging.info( "the expected Queue : {} matching with received Queue : {}". format(exp_queue, rec_queue))
def build_encapsulated_ip_packet( rand_selected_interface, ptfadapter, rand_selected_dut, tunnel_traffic_monitor ): """ Build the encapsulated packet to be sent from T1 to ToR. """ tor = rand_selected_dut _, server_ips = rand_selected_interface server_ipv4 = server_ips["server_ipv4"].split("/")[0] config_facts = tor.get_running_config_facts() try: peer_ipv4_address = [dut_name["address_ipv4"] for dut_name in config_facts["PEER_SWITCH"].values()][0] except IndexError: raise ValueError("Failed to get peer ToR address from CONFIG_DB") tor_ipv4_address = [addr for addr in config_facts["LOOPBACK_INTERFACE"]["Loopback0"] if is_ipv4_address(addr.split("/")[0])][0] tor_ipv4_address = tor_ipv4_address.split("/")[0] inner_dscp = random.choice(range(0, 33)) inner_ttl = random.choice(range(3, 65)) inner_ecn = random.choice(range(0,3)) inner_packet = testutils.simple_ip_packet( ip_src="1.1.1.1", ip_dst=server_ipv4, ip_dscp=inner_dscp, ip_ttl=inner_ttl, ip_ecn=inner_ecn )[IP] packet = testutils.simple_ipv4ip_packet( eth_dst=tor.facts["router_mac"], eth_src=ptfadapter.dataplane.get_mac(0, 0), ip_src=peer_ipv4_address, ip_dst=tor_ipv4_address, ip_dscp=inner_dscp, ip_ttl=255, ip_ecn=inner_ecn, inner_frame=inner_packet ) logging.info("the encapsulated packet to send:\n%s", dump_scapy_packet_show_output(packet)) return packet
def verify_ecn_on_received_packet( ptfadapter, exp_pkt, exp_ptf_port_index, exp_ecn ): """ Verify ECN value on the received packet w.r.t expected packet """ _, rec_pkt = testutils.verify_packet_any_port(ptfadapter, exp_pkt, ports=[exp_ptf_port_index]) rec_pkt = Ether(rec_pkt) logging.info("received packet:\n%s", dump_scapy_packet_show_output(rec_pkt)) rec_dscp = rec_pkt[IP].tos >> 2 rec_ecn = rec_pkt[IP].tos & 3 if rec_ecn != exp_ecn: pytest.fail("the expected ECN: {0:02b} not matching with received ECN: {0:02b}".format(exp_ecn, rec_ecn)) else: logging.info("the expected ECN: {0:02b} matching with received ECN: {0:02b}".format(exp_ecn, rec_ecn))
def _announce_new_neighbor_gen(): """Generator to announce the neighbor to a different interface at each iteration.""" for dut_iface in dut_ifaces: update_iface_func = yield dut_iface if callable(update_iface_func): update_iface_func(dut_iface) ptf_iface = dut_to_ptf_intf_map[dut_iface] garp_packet = testutils.simple_arp_packet( eth_src=NEW_NEIGHBOR_HWADDR, hw_snd=NEW_NEIGHBOR_HWADDR, ip_snd=NEW_NEIGHBOR_IPV4_ADDR, ip_tgt=NEW_NEIGHBOR_IPV4_ADDR, arp_op=2) logging.info( "GARP packet to announce new neighbor %s to mux interface %s:\n%s", NEW_NEIGHBOR_IPV4_ADDR, dut_iface, dump_scapy_packet_show_output(garp_packet)) testutils.send(ptfadapter, int(ptf_iface), garp_packet, count=5) # let the generator stops here to allow the caller to execute testings yield
def build_packet_to_server(duthost, ptfadapter, target_server_ip): """Build packet and expected mask packet destinated to server.""" pkt_dscp = random.choice(range(0, 33)) pkt_ttl = random.choice(range(3, 65)) pkt = testutils.simple_ip_packet(eth_dst=duthost.facts["router_mac"], eth_src=ptfadapter.dataplane.get_mac( 0, 0), ip_src="1.1.1.1", ip_dst=target_server_ip, ip_dscp=pkt_dscp, ip_ttl=pkt_ttl) logging.info("the packet destinated to server %s:\n%s", target_server_ip, dump_scapy_packet_show_output(pkt)) exp_pkt = mask.Mask(pkt) exp_pkt.set_do_not_care_scapy(scapyall.Ether, "dst") exp_pkt.set_do_not_care_scapy(scapyall.Ether, "src") exp_pkt.set_do_not_care_scapy(scapyall.IP, "tos") exp_pkt.set_do_not_care_scapy(scapyall.IP, "ttl") exp_pkt.set_do_not_care_scapy(scapyall.IP, "chksum") return pkt, exp_pkt