Beispiel #1
0
def verify_packets_with_portchannel(test,
                                    pkt,
                                    ports=[],
                                    portchannel_ports=[],
                                    device_number=0,
                                    timeout=1):
    for port in ports:
        result = testutils.dp_poll(test,
                                   device_number=device_number,
                                   port_number=port,
                                   timeout=timeout,
                                   exp_pkt=pkt)
        if isinstance(result, test.dataplane.PollFailure):
            test.fail(
                "Expected packet was not received on device %d, port %r.\n%s" %
                (device_number, port, result.format()))

    for port_group in portchannel_ports:
        for port in port_group:
            result = testutils.dp_poll(test,
                                       device_number=device_number,
                                       port_number=port,
                                       timeout=timeout,
                                       exp_pkt=pkt)
            if isinstance(result, test.dataplane.PollSuccess):
                break
        else:
            test.fail(
                "Expected packet was not received on device %d, ports %s.\n" %
                (device_number, str(port_group)))
Beispiel #2
0
def test_vlan_tc5_untagged_non_broadcast(ptfadapter, vlan_ports_list, duthost):
    """
    Test case #5
    Send packets w/ src and dst specified over untagged ports in vlan
    Verify that bidirectional communication between two untagged ports work
    """
    vlan_ids = vlan_ports_list[0]['permit_vlanid'].keys()
    tagged_test_vlan = vlan_ids[0]
    untagged_test_vlan = vlan_ids[1]

    ports_for_test = []

    for vlan_port in vlan_ports_list:
        if vlan_port['pvid'] != tagged_test_vlan:
            ports_for_test.append(vlan_port['port_index'][0])

    #take two tagged ports for test
    src_port = ports_for_test[0]
    dst_port = ports_for_test[-1]

    src_mac = ptfadapter.dataplane.get_mac(0, src_port)
    dst_mac = ptfadapter.dataplane.get_mac(0, dst_port)
    
    transmit_untagged_pkt = build_icmp_packet(vlan_id=0, src_mac=src_mac, dst_mac=dst_mac)
    return_transmit_untagged_pkt = build_icmp_packet(vlan_id=0, src_mac=dst_mac, dst_mac=src_mac)

    logger.info ("Untagged packet to be sent from port {} to port {}".format(src_port, dst_port))

    testutils.send(ptfadapter, src_port, transmit_untagged_pkt)

    result_dst_if = testutils.dp_poll(ptfadapter, device_number=0, port_number=dst_port,
                                      timeout=1, exp_pkt=transmit_untagged_pkt)

    if isinstance(result_dst_if, ptfadapter.dataplane.PollSuccess):
        logger.info ("One Way Untagged Packet Transmission Works")
        logger.info ("Untagged packet successfully sent from port {} to port {}".format(src_port, dst_port))
    else:
        pytest.fail("Expected packet was not received")

    logger.info ("Untagged packet to be sent from port {} to port {}".format(dst_port, src_port))  

    testutils.send(ptfadapter, dst_port, return_transmit_untagged_pkt)

    result_src_if = testutils.dp_poll(ptfadapter, device_number=0, port_number=src_port,
                                      timeout=1, exp_pkt=return_transmit_untagged_pkt)


    if isinstance(result_src_if, ptfadapter.dataplane.PollSuccess):
        logger.info ("Two Way Untagged Packet Transmission Works")
        logger.info ("Untagged packet successfully sent from port {} to port {}".format(dst_port, src_port))
    else:
        pytest.fail("Expected packet was not received")
Beispiel #3
0
def check_macsec_pkt(macsec_attr, test, ptf_port_id, exp_pkt, timeout=3):
    device, ptf_port = testutils.port_to_tuple(ptf_port_id)
    received_packets = []
    encrypt, send_sci, xpn_en, sci, an, sak, ssci, salt = macsec_attr
    end_time = time.time() + timeout
    while True:
        cur_time = time.time()
        if cur_time > end_time:
            break
        ret = testutils.dp_poll(
            test, device_number=device, port_number=ptf_port, timeout=end_time - cur_time, exp_pkt=None)
        if isinstance(ret, test.dataplane.PollFailure):
            break
        # If the packet isn't MACsec type
        pkt = scapy.Ether(ret.packet)
        if pkt[scapy.Ether].type != 0x88e5:
            continue
        received_packets.append(pkt)
    for i in range(len(received_packets)):
        pkt = received_packets[i]
        pn = 0
        pkt = decap_macsec_pkt(pkt, sci, an, sak, encrypt,
                               send_sci, pn, xpn_en, ssci, salt)
        if not pkt:
            continue
        received_packets[i] = pkt
        if exp_pkt.pkt_match(pkt):
            return
    fail_message = "Expect pkt \n{}\n{}\nBut received \n".format(
        exp_pkt, exp_pkt.exp_pkt.show(dump=True))
    for packet in received_packets:
        fail_message += "\n{}\n".format(packet.show(dump=True))
    return fail_message
Beispiel #4
0
def count_matched_packets_all_ports_helper(test,
                                           exp_packet,
                                           exp_packet_number,
                                           ports=[],
                                           device_number=0,
                                           timeout=1):
    """
    Add exp_packet_number to original ptf interface in order to
    stop waiting when expected number of packets is received
    """
    if timeout <= 0:
        raise Exception("%s() requires positive timeout value." %
                        sys._getframe().f_code.co_name)

    last_matched_packet_time = time.time()
    total_rcv_pkt_cnt = 0
    while True:
        if (time.time() - last_matched_packet_time) > timeout:
            break

        result = dp_poll(test, device_number=device_number, timeout=timeout)
        if isinstance(result, test.dataplane.PollSuccess):
            if (result.port in ports and ptf.dataplane.match_exp_pkt(
                    exp_packet, result.packet)):
                total_rcv_pkt_cnt += 1
                if total_rcv_pkt_cnt == exp_packet_number:
                    break
                last_matched_packet_time = time.time()
        else:
            break

    return total_rcv_pkt_cnt
Beispiel #5
0
def capture_matched_packets(test,
                            exp_packet,
                            port,
                            device_number=0,
                            timeout=1):
    """
    Receive all packets on the port and return all the received packets.
    As soon as the packets stop arriving, the function waits for the timeout value and returns the received packets. Therefore, this function requires a positive timeout value.
    """
    if timeout <= 0:
        raise Exception("%s() requires positive timeout value." %
                        sys._getframe().f_code.co_name)

    pkts = list()
    while True:
        result = dp_poll(test,
                         device_number=device_number,
                         port_number=port,
                         timeout=timeout)
        if isinstance(result, test.dataplane.PollSuccess):
            if ptf.dataplane.match_exp_pkt(exp_packet, result.packet):
                pkts.append(result.packet)
        else:
            break

    return pkts
Beispiel #6
0
def count_matched_packets_helper(test,
                                 exp_packet,
                                 exp_packet_number,
                                 port,
                                 device_number=0,
                                 timeout=1):
    """
    Add exp_packet_number to original ptf interface in order to
    stop waiting when expected number of packets is received
    """
    if timeout <= 0:
        raise Exception("%s() requires positive timeout value." %
                        sys._getframe().f_code.co_name)

    total_rcv_pkt_cnt = 0
    end_time = time.time() + timeout
    while time.time() < end_time:
        result = dp_poll(test,
                         device_number=device_number,
                         port_number=port,
                         timeout=timeout,
                         exp_pkt=exp_packet)
        if isinstance(result, test.dataplane.PollSuccess):
            total_rcv_pkt_cnt += 1
            if total_rcv_pkt_cnt == exp_packet_number:
                break
        else:
            break

    return total_rcv_pkt_cnt
Beispiel #7
0
    def checkOriginalFlow(self):
        """
        @summary: Send traffic & check how many original packets are received
        @return: count: number of original packets received
        """
        exp_pkt = self.base_pkt.copy()
        exp_pkt['Ethernet'].src = self.router_mac
        exp_pkt['IP'].ttl = self.base_pkt['IP'].ttl - 1

        masked_exp_pkt = Mask(exp_pkt)
        masked_exp_pkt.set_do_not_care_scapy(scapy.Ether, "dst")

        self.dataplane.flush()

        count = 0
        for i in range(0, self.NUM_OF_TOTAL_PACKETS):
            testutils.send_packet(self, self.src_port, self.base_pkt)
            (rcv_device, rcv_port, rcv_pkt, pkt_time) = testutils.dp_poll(self, timeout=0.1, exp_pkt=masked_exp_pkt)
            if rcv_pkt is not None:
                count += 1
            elif count == 0:
                print "The first original packet is not recieved"
                assert False # Fast failure without waiting for full iteration
        print "Recieved " + str(count) + " original packets"
        return count
Beispiel #8
0
    def checkOriginalFlow(self):
        """
        @summary: Send traffic & check how many original packets are received
        @return: count: number of original packets received
        """
        exp_pkt = self.base_pkt.copy()
        exp_pkt['Ethernet'].src = self.router_mac
        exp_pkt['IP'].ttl = self.base_pkt['IP'].ttl - 1

        masked_exp_pkt = Mask(exp_pkt)
        masked_exp_pkt.set_do_not_care_scapy(scapy.Ether, "dst")

        self.dataplane.flush()

        count = 0
        testutils.send_packet(self,
                              self.src_port,
                              str(self.base_pkt),
                              count=self.NUM_OF_TOTAL_PACKETS)
        for i in range(0, self.NUM_OF_TOTAL_PACKETS):
            (rcv_device, rcv_port, rcv_pkt,
             pkt_time) = testutils.dp_poll(self,
                                           timeout=0.1,
                                           exp_pkt=masked_exp_pkt)
            if rcv_pkt is not None:
                count += 1
            elif count == 0:
                assert_str = "The first original packet is not recieved"
                assert count > 0, assert_str  # Fast failure without waiting for full iteration
            else:
                break  # No more packets available

        logger.info("Recieved {} original packets".format(count))

        return count
    def checkMirroredFlow(self):
        """
        @summary: Send traffic & check how many mirrored packets are received
        @return: count: number of mirrored packets received

        Note:
        Mellanox crafts the GRE packets with extra information:
        That is: 22 bytes extra information after the GRE header
        """
        payload = self.base_pkt
        if self.asic_type in ["mellanox"]:
            import binascii
            payload = binascii.unhexlify("0" * 44) + str(
                payload)  # Add the padding

        exp_pkt = testutils.simple_gre_packet(
            eth_src=self.router_mac,
            ip_src=self.session_src_ip,
            ip_dst=self.session_dst_ip,
            ip_dscp=self.session_dscp,
            ip_id=0,
            #ip_flags = 0x10, # need to upgrade ptf version to support it
            ip_ttl=self.session_ttl,
            inner_frame=payload)

        if self.asic_type in ["mellanox"]:
            exp_pkt['GRE'].proto = 0x8949  # Mellanox specific
        else:
            exp_pkt['GRE'].proto = 0x88be

        masked_exp_pkt = Mask(exp_pkt)
        masked_exp_pkt.set_do_not_care_scapy(scapy.Ether, "dst")
        masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "flags")
        masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "chksum")

        if self.asic_type in ["mellanox"]:
            masked_exp_pkt.set_do_not_care(
                304, 176)  # Mask the Mellanox specific inner header

        self.dataplane.flush()

        count = 0
        for i in range(0, self.NUM_OF_TOTAL_PACKETS):
            testutils.send_packet(self, self.src_port, self.base_pkt)
            (rcv_device, rcv_port, rcv_pkt,
             pkt_time) = testutils.dp_poll(self,
                                           timeout=0.1,
                                           exp_pkt=masked_exp_pkt)
            if rcv_pkt is not None:
                count += 1
            elif count == 0:
                print "The first mirrored packet is not recieved"
                assert False  # Fast failure without waiting for full iteration
        print "Received " + str(
            count) + " mirrored packets after rate limiting"
        return count
Beispiel #10
0
def check_macsec_pkt(test, ptf_port_id, exp_pkt, timeout=3):
    device, ptf_port = testutils.port_to_tuple(ptf_port_id)
    ret = testutils.dp_poll(test,
                            device_number=device,
                            port_number=ptf_port,
                            timeout=timeout,
                            exp_pkt=exp_pkt)
    if isinstance(ret, test.dataplane.PollSuccess):
        return
    else:
        return ret.format()
Beispiel #11
0
    def receivePacketOnPorts(self, ports=[], device_number=0):
        '''
        @summary Receive packet on any of specified ports
        '''
        received = False
        match_index = 0
        (rcv_device, rcv_port, rcv_pkt, pkt_time) = testutils.dp_poll(self, device_number=device_number, timeout=1)

        if rcv_port in ports:
            match_index = ports.index(rcv_port)
            received = True

        return (match_index, rcv_pkt, received)
Beispiel #12
0
        def verify_packet_count(self, pkt, port_id):
            test = self.outer.ptfadapter
            device, port = testutils.port_to_tuple(port_id)
            logging.debug("Checking for pkt on device %d, port %d", device,
                          port)
            result = testutils.dp_poll(test,
                                       device_number=device,
                                       port_number=port,
                                       exp_pkt=pkt)
            if isinstance(result, test.dataplane.PollSuccess):
                return (1, result.packet)

            return (0, None)
Beispiel #13
0
    def runTest(self):
        try:
            # expected mean and stdev from 32b unsigned uniform random
            exp_mean = (pow(2, 32) - 1) / 2.0
            exp_std = (pow(2, 32) - 1) / math.sqrt(12)

            # compute mean and std from samples
            num_samples = 1000
            rand_vals = []
            print("\nInject %s packets and get random value in srcip field." % num_samples)
            print("It may take time with model.\n")
            for i in range(num_samples):
                ipkt = testutils.simple_udp_packet(eth_dst='11:11:11:11:11:11',
                                                   eth_src='22:33:44:55:66:77',
                                                   ip_src='1.2.3.4',
                                                   ip_dst='100.99.98.97',
                                                   ip_id=101,
                                                   ip_ttl=64,
                                                   udp_sport=0x1234,
                                                   udp_dport=0xabcd)

                testutils.send_packet(self, swports[0], ipkt)
                (rcv_dev, rcv_port, rcv_pkt, pkt_time) = \
                    testutils.dp_poll(self, dev_id, swports[0], timeout=2)
                nrcv = ipkt.__class__(rcv_pkt)
                # print ("\n### Received pkt :\n")
                # nrcv.show2()
                # hexdump(nrcv)
                rand_val = ip2int(nrcv[IP].src)
                rand_vals.append(rand_val)
                # print("32b Random value written in ipv4 src ip : " + str(rand_val))

            # compare mean and std
            mean = sum(rand_vals) / float(len(rand_vals))
            std = stdev(rand_vals)
            print(("Expected Mean : " + str(exp_mean)))
            print(("Observed Mean : " + str(mean)))
            print(("Expected Stdev : " + str(exp_std)))
            print(("Observed Stdev : " + str(std)))

            assert abs(mean - exp_mean) / float(exp_mean) < 0.1
            assert abs(std - exp_std) / float(exp_std) < 0.1

        finally:
            pass
Beispiel #14
0
def count_matched_packets_all_ports(ptfadapter,
                                    exp_packet,
                                    exp_tunnel_pkt,
                                    ports=[],
                                    device_number=0,
                                    timeout=None,
                                    count=1):
    """
    Receive all packets on all specified ports and count how many expected packets were received.
    """
    if timeout is None:
        timeout = ptf.ptfutils.default_timeout
    if timeout <= 0:
        raise Exception("%s() requires positive timeout value." %
                        sys._getframe().f_code.co_name)

    start_time = time.time()
    port_packet_count = dict()
    packet_count = 0
    while True:
        if (time.time() - start_time) > timeout:
            break

        result = testutils.dp_poll(ptfadapter,
                                   device_number=device_number,
                                   timeout=timeout)
        if isinstance(result, ptfadapter.dataplane.PollSuccess):
            if ((result.port in ports) and
                (ptf.dataplane.match_exp_pkt(exp_packet, result.packet) or
                 ptf.dataplane.match_exp_pkt(exp_tunnel_pkt, result.packet))):
                port_packet_count[result.port] = port_packet_count.get(
                    result.port, 0) + 1
                packet_count += 1
                if packet_count == count:
                    return port_packet_count
        else:
            break

    return port_packet_count
    def checkMirroredFlow(self):
        """
        @summary: Send traffic & check how many mirrored packets are received
        @return: count: number of mirrored packets received
        """
        exp_pkt = testutils.simple_gre_packet(
            eth_src=self.router_mac,
            ip_src=self.session_src_ip,
            ip_dst=self.session_dst_ip,
            ip_dscp=self.session_dscp,
            ip_id=0,
            #ip_flags = 0x10, # need to upgrade ptf version to support it
            ip_ttl=self.session_ttl,
            inner_frame=self.base_pkt)

        exp_pkt['GRE'].proto = 0x88be

        masked_exp_pkt = Mask(exp_pkt)
        masked_exp_pkt.set_do_not_care_scapy(scapy.Ether, "dst")
        masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "flags")
        masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "chksum")

        self.dataplane.flush()

        count = 0
        for i in range(0, self.NUM_OF_TOTAL_PACKETS):
            testutils.send_packet(self, self.src_port, self.base_pkt)
            (rcv_device, rcv_port, rcv_pkt,
             pkt_time) = testutils.dp_poll(self,
                                           timeout=0.1,
                                           exp_pkt=masked_exp_pkt)
            if rcv_pkt is not None:
                count += 1
            elif count == 0:
                print "The first mirrored packet is not recieved"
                assert False  # Fast failure without waiting for full iteration
        print "Received " + str(
            count) + " mirrored packets after rate limiting"
        return count
    def checkMirroredFlow(self):
        """
        @summary: Send traffic & check how many mirrored packets are received
        @return: count: number of mirrored packets received

        Note:
        Mellanox crafts the GRE packets with extra information:
        That is: 22 bytes extra information after the GRE header
        """
        payload = self.base_pkt.copy()
        payload_mask = Mask(payload)

        if self.mirror_stage == "egress":
            payload['Ethernet'].src = self.router_mac
            payload['IP'].ttl -= 1
            payload_mask.set_do_not_care_scapy(scapy.Ether, "dst")
            payload_mask.set_do_not_care_scapy(scapy.IP, "chksum")

        if self.asic_type in ["mellanox"]:
            import binascii
            payload = binascii.unhexlify("0" * 44) + str(
                payload)  # Add the padding

        exp_pkt = testutils.simple_gre_packet(
            eth_src=self.router_mac,
            ip_src=self.session_src_ip,
            ip_dst=self.session_dst_ip,
            ip_dscp=self.session_dscp,
            ip_id=0,
            #ip_flags = 0x10, # need to upgrade ptf version to support it
            ip_ttl=self.session_ttl,
            inner_frame=payload)

        if self.asic_type in ["mellanox"]:
            exp_pkt['GRE'].proto = 0x8949  # Mellanox specific
        else:
            exp_pkt['GRE'].proto = 0x88be

        masked_exp_pkt = Mask(exp_pkt)
        masked_exp_pkt.set_do_not_care_scapy(scapy.Ether, "dst")
        masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "flags")
        masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "chksum")
        masked_exp_pkt.set_do_not_care(
            38 * 8,
            len(payload) * 8
        )  # don't match payload, payload will be matched by match_payload(pkt)

        def match_payload(pkt):
            pkt = scapy.Ether(pkt).load
            if self.asic_type in ["mellanox"]:
                pkt = pkt[22:]  # Mask the Mellanox specific inner header
            pkt = scapy.Ether(pkt)

            return dataplane.match_exp_pkt(payload_mask, pkt)

        self.dataplane.flush()

        count = 0
        testutils.send_packet(self,
                              self.src_port,
                              self.base_pkt,
                              count=self.NUM_OF_TOTAL_PACKETS)
        for i in range(0, self.NUM_OF_TOTAL_PACKETS):
            (rcv_device, rcv_port, rcv_pkt,
             pkt_time) = testutils.dp_poll(self,
                                           timeout=0.1,
                                           exp_pkt=masked_exp_pkt)
            if rcv_pkt is not None and match_payload(rcv_pkt):
                count += 1
            elif count == 0:
                assert_str = "The first mirrored packet is not recieved"
                assert count > 0, assert_str  # Fast failure without waiting for full iteration
            else:
                break  # No more packets available

        logger.info(
            "Received {} mirrored packets after rate limiting".format(count))

        return count
Beispiel #17
0
    def runTest(self):
        target = gc.Target(device_id=0, pipe_id=0xffff)
        # Get bfrt_info and set it as part of the test
        bfrt_info = self.interface.bfrt_info_get(p4_program_name)

        # Set default output port
        table_output_port = bfrt_info.table_get("SwitchIngress.output_port")
        action_data = table_output_port.make_data(
            action_name="SwitchIngress.set_output_port",
            data_field_list_in=[gc.DataTuple(name="port_id", val=swports[1])]
        )
        table_output_port.default_entry_set(
            target=target,
            data=action_data)

        try:
            random.seed(1)
            num_trials = 20
            logger.info(("\nInject {} packets with random values provided in the eth" +
                         " dst field.").format(num_trials))
            logger.info("Tofino computes the crc32 and crc-bzip2 hashes of the " +
                        "random value and stores them in the dst and src mac " +
                        "fields. We verify the hash value each packet.")

            # crc32 function for verification
            hash1_func = zlib.crc32
            # crc32-bzip2 function for verification
            hash2_func = crcmod.predefined.mkCrcFun('crc-32-bzip2')

            for i in range(num_trials):
                # random_value = random.randint(0, 2^32-1)
                random_value = random.randint(0, 2 ** 32 - 1)
                random_hex = "{:012x}".format(random_value)
                random_mac = ":".join(random_hex[t:t + 2] for t in range(0, 12, 2))
                ipkt = testutils.simple_udp_packet(eth_dst=str(random_mac),
                                                   eth_src=str(random_mac),
                                                   ip_src='1.2.3.4',
                                                   ip_dst='100.99.98.97',
                                                   ip_id=101,
                                                   ip_ttl=64,
                                                   udp_sport=0x1234,
                                                   udp_dport=0xabcd)

                testutils.send_packet(self, swports[0], ipkt)
                (rcv_dev, rcv_port, rcv_pkt, pkt_time) = \
                    testutils.dp_poll(self, dev_id, swports[1], timeout=2)
                nrcv = ipkt.__class__(rcv_pkt)

                hash1_p4_value = int(str(nrcv[Ether].dst).replace(":", ""), 16)
                hash2_p4_value = int(str(nrcv[Ether].src).replace(":", ""), 16)

                hash1_exp_value = hash1_func(struct.pack("!I", random_value)) & 0xffffffff
                hash2_exp_value = hash2_func(struct.pack("!I", random_value)) & 0xffffffff

                # verify the hash
                logger.info("Random value        : {:x}".format(random_value))
                logger.info("Random value mac    : {}".format(random_mac))
                logger.info("Hash1 P4 value       : {:x}".format(hash1_p4_value))
                logger.info("Hash1 expected value : {:x}".format(hash1_exp_value))
                logger.info("Hash2 P4 value       : {:x}".format(hash2_p4_value))
                logger.info("Hash2 expected value : {:x}".format(hash2_exp_value))
                assert hash1_p4_value == hash1_exp_value
                assert hash2_p4_value == hash2_exp_value

        finally:
            table_output_port.default_entry_reset(target)
Beispiel #18
0
    def runTest(self):
        target = gc.Target(device_id=0, pipe_id=0xffff)
        # Get bfrt_info and set it as part of the test
        bfrt_info = self.interface.bfrt_info_get(p4_program_name)

        # Set default output port
        table_output_port = bfrt_info.table_get("SwitchIngress.output_port")
        action_data = table_output_port.make_data(
            action_name="SwitchIngress.set_output_port",
            data_field_list_in=[gc.DataTuple(name="port_id", val=swports[1])]
        )
        table_output_port.default_entry_set(
            target=target,
            data=action_data)

        try:
            random.seed(1)
            num_trials = 20

            for i in range(num_trials):
                ip_src = int2ip(random.randint(0, 2 ** 32 - 1))
                ip_dst = int2ip(random.randint(0, 2 ** 32 - 1))
                udp_sport = random.randint(0, 2 ** 16 - 1)
                udp_dport = random.randint(0, 2 ** 16 - 1)
                print(("  Testing IPv4 and UDP port values: {}, {}, {}, {}".
                       format(ip_src, ip_dst, udp_sport, udp_dport)))
                ipkt_1 = testutils.simple_udp_packet(eth_dst="22:22:22:22:22:22",
                                                     eth_src='00:00:00:00:00:00',
                                                     ip_src=ip_src,
                                                     ip_dst=ip_dst,
                                                     ip_id=101,
                                                     ip_ttl=64,
                                                     udp_sport=udp_sport,
                                                     udp_dport=udp_dport)

                testutils.send_packet(self, swports[0], ipkt_1)
                (rcv_dev, rcv_port, rcv_pkt, pkt_time) = \
                    testutils.dp_poll(self, dev_id, swports[1], timeout=2)
                rpkt_1 = ipkt_1.__class__(rcv_pkt)

                ipkt_2 = testutils.simple_udp_packet(eth_dst="22:22:22:22:22:22",
                                                     eth_src='00:00:00:00:00:00',
                                                     ip_src=ip_dst,
                                                     ip_dst=ip_src,
                                                     ip_id=101,
                                                     ip_ttl=64,
                                                     udp_sport=udp_dport,
                                                     udp_dport=udp_sport)

                testutils.send_packet(self, swports[0], ipkt_2)
                (rcv_dev, rcv_port, rcv_pkt, pkt_time) = \
                    testutils.dp_poll(self, dev_id, swports[1], timeout=2)
                rpkt_2 = ipkt_2.__class__(rcv_pkt)

                ipkt_3 = testutils.simple_udp_packet(eth_dst="22:22:22:22:22:22",
                                                     eth_src='00:00:00:00:00:00',
                                                     ip_src=ip_src,
                                                     ip_dst=ip_dst,
                                                     ip_id=101,
                                                     ip_ttl=64,
                                                     udp_sport=udp_dport,
                                                     udp_dport=udp_sport)

                testutils.send_packet(self, swports[0], ipkt_3)
                (rcv_dev, rcv_port, rcv_pkt, pkt_time) = \
                    testutils.dp_poll(self, dev_id, swports[1], timeout=2)
                rpkt_3 = ipkt_3.__class__(rcv_pkt)

                ipkt_4 = testutils.simple_udp_packet(eth_dst="22:22:22:22:22:22",
                                                     eth_src='00:00:00:00:00:00',
                                                     ip_src=ip_src,
                                                     ip_dst=ip_dst,
                                                     ip_id=101,
                                                     ip_ttl=64,
                                                     udp_sport=udp_dport,
                                                     udp_dport=udp_sport)

                testutils.send_packet(self, swports[0], ipkt_4)
                (rcv_dev, rcv_port, rcv_pkt, pkt_time) = \
                    testutils.dp_poll(self, dev_id, swports[1], timeout=2)
                rpkt_4 = ipkt_4.__class__(rcv_pkt)

                assert rpkt_1[Ether].src != "00:00:00:00:00:00"
                assert rpkt_1[Ether].src == rpkt_2[Ether].src == rpkt_3[Ether].src == rpkt_4[Ether].src

        finally:
            table_output_port.default_entry_reset(target)
Beispiel #19
0
    def checkMirroredFlow(self):
        """
        @summary: Send traffic & check how many mirrored packets are received
        @return: count: number of mirrored packets received

        Note:
        Mellanox crafts the GRE packets with extra information:
        That is: 22 bytes extra information after the GRE header
        """
        payload = self.base_pkt.copy()
        payload_mask = Mask(payload)

        if self.mirror_stage == "egress":
            payload['Ethernet'].src = self.router_mac
            payload['IP'].ttl -= 1
            payload_mask.set_do_not_care_scapy(scapy.Ether, "dst")
            payload_mask.set_do_not_care_scapy(scapy.IP, "chksum")

        if self.asic_type in ["mellanox"]:
            import binascii
            payload = binascii.unhexlify("0"*44) + str(payload) # Add the padding

        if self.asic_type in ["barefoot"]:
            import binascii
            payload = binascii.unhexlify("0"*24) + str(payload) # Add the padding

        exp_pkt = testutils.simple_gre_packet(
                eth_src = self.router_mac,
                ip_src = self.session_src_ip,
                ip_dst = self.session_dst_ip,
                ip_dscp = self.session_dscp,
                ip_id = 0,
                #ip_flags = 0x10, # need to upgrade ptf version to support it
                ip_ttl = self.session_ttl,
                inner_frame = payload)

        if self.asic_type in ["mellanox"]:
            exp_pkt['GRE'].proto = 0x8949 # Mellanox specific
        elif self.asic_type in ["barefoot"]:
            exp_pkt['GRE'].proto = 0x22eb # Barefoot specific
        else:
            exp_pkt['GRE'].proto = 0x88be

        masked_exp_pkt = Mask(exp_pkt)
        masked_exp_pkt.set_do_not_care_scapy(scapy.Ether, "dst")
        masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "flags")
        masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "chksum")
        masked_exp_pkt.set_do_not_care(38*8, len(payload)*8)  # don't match payload, payload will be matched by match_payload(pkt)
        if self.check_ttl == 'False':
            masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "ttl")

        def match_payload(pkt):
            if self.asic_type in ["mellanox"]:
                pkt = scapy.Ether(pkt).load
                pkt = pkt[22:] # Mask the Mellanox specific inner header
                pkt = scapy.Ether(pkt)
            else:
                pkt = scapy.Ether(pkt)[scapy.GRE].payload

            return dataplane.match_exp_pkt(payload_mask, pkt)

        # send some amount to absorb CBS capacity
        testutils.send_packet(self, self.src_port, str(self.base_pkt), count=self.NUM_OF_TOTAL_PACKETS)
        self.dataplane.flush()

        end_time = datetime.datetime.now() + datetime.timedelta(seconds=self.send_time)
        tx_pkts = 0
        while datetime.datetime.now() < end_time:
            testutils.send_packet(self, self.src_port, str(self.base_pkt))
            tx_pkts += 1

        rx_pkts = 0
        while True:
            (rcv_device, rcv_port, rcv_pkt, pkt_time) = testutils.dp_poll(self, timeout=0.1, exp_pkt=masked_exp_pkt)
            if rcv_pkt is not None and match_payload(rcv_pkt):
                rx_pkts += 1
            else:
                break # No more packets available

        tx_pps = tx_pkts / self.send_time
        rx_pps = rx_pkts / self.send_time

        logger.info("Sent {} packets".format(tx_pkts))
        logger.info("Received {} mirrored packets after rate limiting".format(rx_pkts))
        logger.info("TX PPS {}".format(tx_pps))
        logger.info("RX PPS {}".format(rx_pps))

        return rx_pkts, tx_pps, rx_pps
Beispiel #20
0
    def runTest(self):
        target = gc.Target(device_id=0, pipe_id=0xffff)
        # Get bfrt_info and set it as part of the test
        bfrt_info = self.interface.bfrt_info_get(p4_program_name)

        # Set default output port
        table_output_port = bfrt_info.table_get("SwitchIngress.output_port")
        action_data = table_output_port.make_data(
            action_name="SwitchIngress.set_output_port",
            data_field_list_in=[gc.DataTuple(name="port_id", val=swports[1])])
        table_output_port.default_entry_set(target=target, data=action_data)

        try:
            ipkt_payload = struct.pack("I", 0) * 10
            ipkt = testutils.simple_udp_packet(eth_dst='11:11:11:11:11:11',
                                               eth_src='22:22:22:22:22:22',
                                               ip_src='1.2.3.4',
                                               ip_dst='100.99.98.97',
                                               ip_id=101,
                                               ip_ttl=64,
                                               udp_sport=0x1234,
                                               udp_dport=0xabcd,
                                               with_udp_chksum=False,
                                               udp_payload=ipkt_payload)

            testutils.send_packet(self, swports[0], ipkt)

            (rcv_dev, rcv_port, rcv_pkt, pkt_time) = \
                testutils.dp_poll(self, 0, swports[1], timeout=2)
            nrcv = ipkt.__class__(rcv_pkt)

            # Parse the payload and extract the timestamps
            # import pdb; pdb.set_trace()
            ts_ingress_mac, ts_ingress_global, \
                ts_enqueue, ts_dequeue_delta, \
                ts_egress_global, ts_egress_tx = \
                struct.unpack("!QQIIQQxxxxxxxxxxxxxxxxxx", nrcv.load)

            ns = 1000000000.0
            logger.info("Timestamps")
            logger.info("  raw values in ns:")
            logger.info("    ingress mac                   : {:>15}".format(
                ts_ingress_mac))
            logger.info("    ingress global                : {:>15}".format(
                ts_ingress_global))
            logger.info("    traffic manager enqueue       : {:>15}".format(
                ts_enqueue))
            logger.info("    traffic manager dequeue delta : {:>15}".format(
                ts_dequeue_delta))
            logger.info("    egress global                 : {:>15}".format(
                ts_egress_global))
            logger.info("    egress tx (no value in model) : {:>15}".format(
                ts_egress_tx))
            logger.info("  values in s:")
            logger.info("    ingress mac                   : {:>15.9f}".format(
                ts_ingress_mac / ns))
            logger.info("    ingress global                : {:>15.9f}".format(
                ts_ingress_global / ns))
            logger.info("    traffic manager enqueue       : {:>15.9f}".format(
                ts_enqueue / ns))
            logger.info("    traffic manager dequeue delta : {:>15.9f}".format(
                ts_dequeue_delta / ns))
            logger.info("    egress global                 : {:>15.9f}".format(
                ts_egress_global / ns))
            logger.info("    egress tx (no value in model) : {:>15.9f}".format(
                ts_egress_tx))
            logger.info(
                "Please note that the timestamps are using the internal time "
                +
                "of the model/chip. They are not synchronized with the global time. "
                "Furthermore, the traffic manager timestamps in the model do not "
                +
                "accurately reflect the packet processing. Correct values are shown "
                + "by the hardware implementation.")
        finally:
            table_output_port.default_entry_reset(target)
Beispiel #21
0
    def check_mirrored_packet(self, ipv6=False):
        """
        Send an ARP or ND request and verify that it is mirrored.

        NOTE: This test only verifies that the payload is correct and that the
        outermost packet headers are correct (Ether / IP / GRE). Any extra info
        or headers that an ASIC chooses to include is ignored.

        Keyword arguments:
        ipv6 -- the IP version for this test run
        """

        pkt = self.basev6_pkt if ipv6 else self.base_pkt
        payload = pkt.copy()

        if self.mirror_stage == "egress":
            payload['Ethernet'].src = self.router_mac
            payload['IP'].ttl -= 1

        exp_pkt = testutils.simple_gre_packet(
            eth_src=self.router_mac,
            ip_src=self.MIRROR_SESSION_SRC_IP,
            ip_dst=self.MIRROR_SESSION_DST_IP,
            ip_dscp=self.MIRROR_SESSION_DSCP,
            ip_id=self.IP_ID,
            ip_ttl=self.MIRROR_SESSION_TTL,
            inner_frame=payload)

        if self.asic_type in ["mellanox"]:
            exp_pkt['GRE'].proto = self.GRE_PROTO_MLNX
        else:
            exp_pkt['GRE'].proto = self.GRE_PROTO_ERSPAN

        masked_exp_pkt = Mask(exp_pkt)
        masked_exp_pkt.set_do_not_care_scapy(scapy.Ether, "dst")
        masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "ihl")
        masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "len")
        masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "flags")
        masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "chksum")

        # NOTE: The fanout modifies the tos field, so it will always be 0 even
        # if we specify a particular value in the mirror session.
        masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "tos")

        # NOTE: Later versions of PTF allow you to ignore extra bytes, which
        # would allow us to specify an expected packet to be received by
        # masking off everything but the outer headers (Ether / IP / GRE).
        #
        # For now we just trim away any extra headers and check that the packet
        # matches after it is received.

        self.dataplane.flush()

        testutils.send_packet(self, self.src_port, pkt)
        _, _, rcv_pkt, _ = testutils.dp_poll(self, timeout=0.1)

        rcv_pkt = self.trim_extra_asic_headers(rcv_pkt, len(payload))

        if rcv_pkt and masked_exp_pkt.pkt_match(rcv_pkt):
            print("{} mirroring succesful".format("ND" if ipv6 else "ARP"))
        else:
            assert False