Beispiel #1
0
    def test_mask__mask_simple_packet(self, scapy_simple_tcp_packet):
        packet = scapy_simple_tcp_packet
        mask_packet = Mask(packet)
        assert mask_packet.pkt_match(packet)

        modified_packet = packet.copy()
        modified_packet[TCP].sport = 97
        assert not mask_packet.pkt_match(modified_packet)

        # try to mask only sport (still packet will be different on chksum!)
        mask_packet.set_do_not_care_packet(TCP, "sport")
        assert not mask_packet.pkt_match(modified_packet)

        mask_packet.set_do_not_care_packet(TCP, "chksum")
        assert mask_packet.pkt_match(modified_packet)
    def send_and_check_mirror_packets(self,
                                      setup,
                                      mirror_session,
                                      ptfadapter,
                                      duthost,
                                      mirror_packet,
                                      src_port=None,
                                      dest_ports=None,
                                      expect_recv=True):
        expected_mirror_packet = self._get_expected_mirror_packet(
            mirror_session, setup, duthost, mirror_packet)

        if not src_port:
            src_port = self._get_random_src_port(setup)

        if not dest_ports:
            dest_ports = [
                self._get_monitor_port(setup, mirror_session, duthost)
            ]

        ptfadapter.dataplane.flush()
        testutils.send(ptfadapter, src_port, mirror_packet)

        if expect_recv:
            _, received_packet = testutils.verify_packet_any_port(
                ptfadapter, expected_mirror_packet, ports=dest_ports)
            logging.info("Received packet: %s",
                         packet.Ether(received_packet).summary())

            inner_packet = self._extract_mirror_payload(
                received_packet, len(mirror_packet))
            logging.info("Received inner packet: %s", inner_packet.summary())

            inner_packet = Mask(inner_packet)

            # For egress mirroring, we expect the DUT to have modified the packet
            # before forwarding it. Specifically:
            #
            # - In L2 the SMAC and DMAC will change.
            # - In L3 the TTL and checksum will change.
            #
            # We know what the TTL and SMAC should be after going through the pipeline,
            # but DMAC and checksum are trickier. For now, update the TTL and SMAC, and
            # mask off the DMAC and IP Checksum to verify the packet contents.
            if self.mirror_type() == "egress":
                mirror_packet[packet.IP].ttl -= 1
                mirror_packet[packet.Ether].src = setup["router_mac"]

                inner_packet.set_do_not_care_scapy(packet.Ether, "dst")
                inner_packet.set_do_not_care_scapy(packet.IP, "chksum")

            logging.info("Expected inner packet: %s", mirror_packet.summary())
            pytest_assert(inner_packet.pkt_match(mirror_packet),
                          "Mirror payload does not match received packet")
        else:
            testutils.verify_no_packet_any(ptfadapter, expected_mirror_packet,
                                           dest_ports)
Beispiel #3
0
    def test_mask__conditional_field__gpid_should_be_masked_correctly(
            self, scapy_simple_vxlan_packet):
        simple_vxlan = scapy_simple_vxlan_packet  # type: Packet
        simple_vxlan[VXLAN].flags = "G"
        masked_simple_vxlan = Mask(simple_vxlan)  # type: Mask
        masked_simple_vxlan.set_do_not_care_packet(VXLAN, "gpid")
        # UDP chksum will be different when we change VXLAN
        masked_simple_vxlan.set_do_not_care_packet(UDP, "chksum")

        packet_wth_custom_gpid = simple_vxlan.copy()  # type: Packet
        packet_wth_custom_gpid[VXLAN].gpid = 0x15  # 21

        assert masked_simple_vxlan.pkt_match(
            packet_wth_custom_gpid), "Packets should match"
    def send_and_check_mirror_packets(self,
                                      setup,
                                      mirror_session,
                                      ptfadapter,
                                      duthost,
                                      mirror_packet,
                                      src_port=None,
                                      dest_ports=None,
                                      expect_recv=True,
                                      valid_across_namespace=True):
        expected_mirror_packet = self._get_expected_mirror_packet(
            mirror_session, setup, duthost, mirror_packet)

        if not src_port:
            src_port = self._get_random_src_port(setup)

        if not dest_ports:
            dest_ports = [
                self._get_monitor_port(setup, mirror_session, duthost)
            ]

        # In Below logic idea is to send traffic in such a way so that mirror traffic
        # will need to go across namespaces and within namespace. If source and mirror destination
        # namespace are different then traffic mirror will go across namespace via (backend asic)
        # else via same namespace(asic)

        src_port_namespace = self._get_port_namespace(setup, int(src_port))
        dest_ports_namespace = self._get_port_namespace(
            setup, int(dest_ports[0]))

        src_port_set = set()

        # Some of test scenario are not valid across namespaces so test will explicltly pass
        # valid_across_namespace as False (default is True)
        if valid_across_namespace == True or src_port_namespace == dest_ports_namespace:
            src_port_set.add(src_port)

        # To verify same namespace mirroring we will add destination port also to the Source Port Set
        if src_port_namespace != dest_ports_namespace:
            src_port_set.add(dest_ports[0])

        # Loop through Source Port Set and send traffic on each source port of the set
        for src_port in src_port_set:
            ptfadapter.dataplane.flush()
            testutils.send(ptfadapter, src_port, mirror_packet)

            if expect_recv:
                _, received_packet = testutils.verify_packet_any_port(
                    ptfadapter, expected_mirror_packet, ports=dest_ports)
                logging.info("Received packet: %s",
                             packet.Ether(received_packet).summary())

                inner_packet = self._extract_mirror_payload(
                    received_packet, len(mirror_packet))
                logging.info("Received inner packet: %s",
                             inner_packet.summary())

                inner_packet = Mask(inner_packet)

                # For egress mirroring, we expect the DUT to have modified the packet
                # before forwarding it. Specifically:
                #
                # - In L2 the SMAC and DMAC will change.
                # - In L3 the TTL and checksum will change.
                #
                # We know what the TTL and SMAC should be after going through the pipeline,
                # but DMAC and checksum are trickier. For now, update the TTL and SMAC, and
                # mask off the DMAC and IP Checksum to verify the packet contents.
                if self.mirror_type() == "egress":
                    mirror_packet[packet.IP].ttl -= 1
                    mirror_packet[packet.Ether].src = setup["router_mac"]

                    inner_packet.set_do_not_care_scapy(packet.Ether, "dst")
                    inner_packet.set_do_not_care_scapy(packet.IP, "chksum")

                logging.info("Expected inner packet: %s",
                             mirror_packet.summary())
                pytest_assert(inner_packet.pkt_match(mirror_packet),
                              "Mirror payload does not match received packet")
            else:
                testutils.verify_no_packet_any(ptfadapter,
                                               expected_mirror_packet,
                                               dest_ports)
Beispiel #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
Beispiel #6
0
 def test_mask__set_do_not_care(self):
     expected_packet = "\x01\x02\x03\x04\x05\x06"
     packet = "\x01\x00\x00\x04\x05\x06\x07\x08"
     mask = Mask(expected_packet.encode(), ignore_extra_bytes=True)
     mask.set_do_not_care(8, 16)
     assert mask.pkt_match(packet.encode())