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
    def get_expected_mirror_packet(mirror_session, setup, duthost,
                                   mirror_packet, check_ttl):
        payload = mirror_packet.copy()

        # Add vendor specific padding to the packet
        if duthost.facts["asic_type"] in ["mellanox"]:
            payload = binascii.unhexlify("0" * 44) + str(payload)

        if duthost.facts["asic_type"] in ["barefoot", "cisco-8000"]:
            payload = binascii.unhexlify("0" * 24) + str(payload)

        expected_packet = testutils.simple_gre_packet(
            eth_src=setup["router_mac"],
            ip_src=mirror_session["session_src_ip"],
            ip_dst=mirror_session["session_dst_ip"],
            ip_dscp=int(mirror_session["session_dscp"]),
            ip_id=0,
            ip_ttl=int(mirror_session["session_ttl"]),
            inner_frame=payload)

        expected_packet["GRE"].proto = mirror_session["session_gre"]

        expected_packet = Mask(expected_packet)
        expected_packet.set_do_not_care_scapy(packet.Ether, "dst")
        expected_packet.set_do_not_care_scapy(packet.IP, "ihl")
        expected_packet.set_do_not_care_scapy(packet.IP, "len")
        expected_packet.set_do_not_care_scapy(packet.IP, "flags")
        expected_packet.set_do_not_care_scapy(packet.IP, "chksum")
        if duthost.facts["asic_type"] in ["cisco-8000"]:
            expected_packet.set_do_not_care_scapy(packet.GRE, "seqnum_present")
        if not check_ttl:
            expected_packet.set_do_not_care_scapy(packet.IP, "ttl")

        # The fanout switch may modify this value en route to the PTF so we should ignore it, even
        # though the session does have a DSCP specified.
        expected_packet.set_do_not_care_scapy(packet.IP, "tos")

        # Mask off the payload (we check it later)
        expected_packet.set_do_not_care(OUTER_HEADER_SIZE * 8,
                                        len(payload) * 8)

        return expected_packet
    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
Example #5
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
Example #6
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