示例#1
0
文件: switch.py 项目: lguohan/ptf
    def runTest(self):
        print "Sending L2 packet - port 1 -> port 2 [trunk vlan=10])"
        switch_init(self.client)
        vlan_id = 10
        port1 = port_list[1]
        port2 = port_list[2]
        mac1 = '00:11:11:11:11:11'
        mac2 = '00:22:22:22:22:22'
        mac_action = 1

        self.client.sai_thrift_create_vlan(vlan_id)
        vlan_port1 = sai_thrift_vlan_port_t(port_id=port1, tagging_mode=1)
        vlan_port2 = sai_thrift_vlan_port_t(port_id=port2, tagging_mode=0)
        self.client.sai_thrift_add_ports_to_vlan(vlan_id, [vlan_port1, vlan_port2])

        sai_thrift_create_fdb(self.client, vlan_id, mac1, port1, mac_action)
        sai_thrift_create_fdb(self.client, vlan_id, mac2, port2, mac_action)

        pkt = simple_tcp_packet(eth_dst='00:11:11:11:11:11',
                                eth_src='00:22:22:22:22:22',
                                ip_dst='10.0.0.1',
                                ip_id=102,
                                ip_ttl=64)
        exp_pkt = simple_tcp_packet(eth_dst='00:11:11:11:11:11',
                                eth_src='00:22:22:22:22:22',
                                ip_dst='10.0.0.1',
                                dl_vlan_enable=True,
                                vlan_vid=10,
                                ip_id=102,
                                ip_ttl=64,
                                pktlen=104)

        # illustrates how to use a mask even if no impact here
        m = Mask(exp_pkt)
        m.set_do_not_care_scapy(IP, 'ttl')
        try:
            send_packet(self, 2, pkt)
            verify_packets(self, m, [1])
        finally:
            sai_thrift_delete_fdb(self.client, vlan_id, mac1, port1)
            sai_thrift_delete_fdb(self.client, vlan_id, mac2, port2)

            self.client.sai_thrift_remove_ports_from_vlan(vlan_id, [vlan_port1, vlan_port2])
            self.client.sai_thrift_delete_vlan(vlan_id)
示例#2
0
    def check_ipv6_route(self, hash_key, src_port, dst_port_list):
        '''
        @summary: Check IPv6 route works.
        @param hash_key: hash key to build packet with.
        @param in_port: index of port to use for sending packet to switch
        @param dst_port_list: list of ports on which to expect packet to come back from the switch
        @return Boolean
        '''
        base_mac = self.dataplane.get_mac(0, 0)
        ip_src = self.src_ip_interval.get_random_ip(
        ) if hash_key == 'src-ip' else self.src_ip_interval.get_first_ip()
        ip_dst = self.dst_ip_interval.get_random_ip(
        ) if hash_key == 'dst-ip' else self.dst_ip_interval.get_first_ip()

        sport = random.randint(0, 65535) if hash_key == 'src-port' else 1234
        dport = random.randint(0, 65535) if hash_key == 'dst-port' else 80

        src_mac = (base_mac[:-5] + "%02x" % random.randint(0, 255) + ":" + "%02x" % random.randint(0, 255)) \
            if hash_key == 'src-mac' else base_mac
        router_mac = self.ptf_test_port_map[str(src_port)]['target_mac']
        exp_router_mac = self.router_macs[self.ptf_test_port_map[str(src_port)]
                                          ['target_dut']]

        vlan_id = random.choice(self.vlan_ids) if hash_key == 'vlan-id' else 0
        ip_proto = self._get_ip_proto(
            ipv6=True) if hash_key == "ip-proto" else None

        pkt = simple_tcpv6_packet(
            pktlen=100 if vlan_id == 0 else 104,
            eth_dst=router_mac,
            eth_src=src_mac,
            dl_vlan_enable=False if vlan_id == 0 else True,
            vlan_vid=vlan_id,
            vlan_pcp=0,
            ipv6_dst=ip_dst,
            ipv6_src=ip_src,
            tcp_sport=sport,
            tcp_dport=dport,
            ipv6_hlim=64)
        exp_pkt = simple_tcpv6_packet(eth_src=exp_router_mac,
                                      ipv6_dst=ip_dst,
                                      ipv6_src=ip_src,
                                      tcp_sport=sport,
                                      tcp_dport=dport,
                                      ipv6_hlim=63)

        if hash_key == 'ip-proto':
            pkt['IPv6'].nh = ip_proto
            exp_pkt['IPv6'].nh = ip_proto

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

        send_packet(self, src_port, pkt)
        logging.info('Sent Ether(src={}, dst={})/IPv6(src={}, dst={})/TCP(sport={}, dport={})'\
            .format(pkt.src,
                    pkt.dst,
                    pkt['IPv6'].src,
                    pkt['IPv6'].dst,
                    sport,
                    dport))
        logging.info('Expect Ether(src={}, dst={})/IPv6(src={}, dst={})/TCP(sport={}, dport={})'\
            .format(exp_router_mac,
                    'any',
                    ip_src,
                    ip_dst,
                    sport,
                    dport))

        return verify_packet_any_port(self, masked_exp_pkt, dst_port_list)
    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
示例#4
0
    def generate_from_t1(self):
        self.from_t1 = []

        vlan_ip_range = self.test_params['vlan_ip_range']

        _, mask = vlan_ip_range.split('/')
        n_hosts = min(2**(32 - int(mask)) - 3, self.max_nr_vl_pkts)

        dump = defaultdict(dict)
        counter = 0
        for i in xrange(2, n_hosts + 2):
            from_t1_src_addr = self.random_ip(
                self.test_params['default_ip_range'])
            from_t1_src_port = self.random_port(self.portchannel_ports)
            from_t1_dst_addr = self.host_ip(vlan_ip_range, i)
            from_t1_dst_port = self.vlan_ports[i % len(self.vlan_ports)]
            from_t1_if_name = "eth%d" % from_t1_dst_port
            from_t1_if_addr = "%s/%s" % (from_t1_dst_addr,
                                         vlan_ip_range.split('/')[1])
            vlan_mac_hex = '72060001%04x' % counter
            lag_mac_hex = '5c010203%04x' % counter
            mac_addr = ':'.join(lag_mac_hex[i:i + 2]
                                for i in range(0, len(lag_mac_hex), 2))
            packet = simple_tcp_packet(eth_src=mac_addr,
                                       eth_dst=self.dut_mac,
                                       ip_src=from_t1_src_addr,
                                       ip_dst=from_t1_dst_addr,
                                       ip_ttl=255,
                                       tcp_dport=5000)
            self.from_t1.append((from_t1_src_port, str(packet)))
            dump[from_t1_if_name][from_t1_dst_addr] = vlan_mac_hex
            counter += 1

        exp_packet = simple_tcp_packet(
            ip_src="0.0.0.0",
            ip_dst="0.0.0.0",
            tcp_dport=5000,
        )

        self.from_t1_exp_packet = Mask(exp_packet)
        self.from_t1_exp_packet.set_do_not_care_scapy(scapy.Ether, "src")
        self.from_t1_exp_packet.set_do_not_care_scapy(scapy.Ether, "dst")
        self.from_t1_exp_packet.set_do_not_care_scapy(scapy.IP, "src")
        self.from_t1_exp_packet.set_do_not_care_scapy(scapy.IP, "dst")
        self.from_t1_exp_packet.set_do_not_care_scapy(scapy.IP, "chksum")
        self.from_t1_exp_packet.set_do_not_care_scapy(scapy.TCP, "chksum")
        self.from_t1_exp_packet.set_do_not_care_scapy(scapy.IP, "ttl")

        # save data for arp_replay process
        with open("/tmp/from_t1.json", "w") as fp:
            json.dump(dump, fp)

        random_vlan_iface = random.choice(dump.keys())
        self.from_server_src_port = int(random_vlan_iface.replace('eth', ''))
        self.from_server_src_addr = random.choice(
            dump[random_vlan_iface].keys())
        self.from_server_dst_addr = self.random_ip(
            self.test_params['default_ip_range'])
        self.from_server_dst_ports = self.portchannel_ports

        self.nr_vl_pkts = n_hosts

        return
示例#5
0
    def verify_relayed_request_relay_forward(self):
        # Create a packet resembling a DHCPv6 RELAY-FORWARD encapsulating REQUEST packet
        request_relay_forward_packet = self.create_dhcp_request_relay_forward_packet(
        )

        # Mask off fields we don't care about matching
        masked_packet = Mask(request_relay_forward_packet)
        masked_packet.set_do_not_care_scapy(packet.Ether, "dst")
        masked_packet.set_do_not_care_scapy(IPv6, "src")
        masked_packet.set_do_not_care_scapy(IPv6, "dst")
        masked_packet.set_do_not_care_scapy(IPv6, "fl")
        masked_packet.set_do_not_care_scapy(IPv6, "tc")
        masked_packet.set_do_not_care_scapy(IPv6, "plen")
        masked_packet.set_do_not_care_scapy(IPv6, "nh")
        masked_packet.set_do_not_care_scapy(packet.UDP, "chksum")
        masked_packet.set_do_not_care_scapy(packet.UDP, "len")
        masked_packet.set_do_not_care_scapy(DHCP6OptClientLinkLayerAddr,
                                            "clladdr")
        masked_packet.set_do_not_care_scapy(
            scapy.layers.dhcp6.DHCP6_RelayForward, "linkaddr")

        # Count the number of these packets received on the ports connected to our leaves
        request_count = testutils.count_matched_packets_all_ports(
            self, masked_packet, self.server_port_indices)
        self.assertTrue(request_count >= 1,
                        "Failed: Request count of %d" % request_count)
示例#6
0
    def send_and_verify(self, dst_ip, expected_ports, src_port, triple_encap = False):
        '''
        @summary: This function builds encap packet, send and verify their arrival.
        @dst_ip: the destination ip for the inner IP header
        @expected_ports: list of ports that a packet can arrived from 
        @src_port: the physical port that the packet will be sent from 
        @triple_encap: True to send triple encapsulated packet
        '''
        #setting parameters
        src_mac =  self.dataplane.get_mac(0, 0)
        dst_mac = '00:11:22:33:44:55'
        inner_src_ip = '2.2.2.2'
        router_mac = self.test_params['router_mac']
        dscp_in = random.randint(0, 32)
        tos_in = dscp_in << 2
        dscp_out = random.randint(0, 32)
        tos_out = dscp_out << 2
        if ("pipe" == self.test_params['dscp_mode']):
            exp_tos = tos_in
        elif("uniform" == self.test_params['dscp_mode']):
            exp_tos = tos_out
        else:
            print("ERROR: no dscp is configured")
            exit()

        default_packet_len = 100
        default_packet_add_header_len = 114

        #building the packets  and the expected packets
        if (not triple_encap):
            #for the double encap packet we will use IP header with TCP header without mac    
            inner_pkt = simple_ip_only_packet(ip_dst=dst_ip, ip_src=inner_src_ip, ip_ttl=64, ip_tos=tos_in)
            #after the decap process the retuning packet will be normal tcp packet, The TTL is taked from the inner layer and redused by one
            exp_pkt = simple_tcp_packet(pktlen=default_packet_add_header_len,
                                        eth_dst=dst_mac,
                                        eth_src=router_mac,
                                        ip_dst=dst_ip,
                                        ip_src=inner_src_ip,
                                        ip_tos=exp_tos,
                                        ip_ttl=63)
        else:
            #Building triple encap packet with SCAPY, because there is no PTF function for it, I use the defualt values for the TCP header
            tcp_hdr    = scapy.TCP(sport=1234, dport=80, flags="S", chksum=0)
            inner_pkt2 = scapy.IP(src='4.4.4.4', dst='3.3.3.3', tos=0, ttl=64, id=1, ihl=None) / tcp_hdr
            inner_pkt  = scapy.IP(src=inner_src_ip, dst=dst_ip, tos=tos_in, ttl=64, id=1, ihl=None,proto=4) / inner_pkt2
            inner_pkt  = inner_pkt/("".join([chr(x) for x in xrange(default_packet_len - len(inner_pkt))]))
            #The expected packet is also built by scapy, and the TTL is taked from the inner layer and redused by one
            exp_pkt    = scapy.Ether(dst=dst_mac, src=router_mac)/inner_pkt   
            exp_pkt['IP'].tos = exp_tos #this parameter is taken by the decap rule configuration 
            exp_pkt['IP'].ttl = 63

        pkt = simple_ipv4ip_packet(
                            eth_dst=router_mac,
                            eth_src=src_mac,
                            ip_src='1.1.1.1',
                            ip_dst=self.test_params['lo_ip'],
                            ip_tos=tos_out,
                            ip_ttl=random.randint(2, 63), 
                            inner_frame=inner_pkt)
        
        #send and verify the return packets
        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.Ether, "src")
        send_packet(self, src_port, pkt)
        logging.info(".....Sending packet from port" + str(src_port) + " to " + dst_ip + ", Triple_encap: " + str(triple_encap))
        (matched, received) = verify_packet_any_port(self, masked_exp_pkt, expected_ports)
        assert received
        return (matched, received)
示例#7
0
    def runTest(self):
        """
        For SONiC
        testing ECMP uniformn distribution over 16 RIFs from 16 differnt ports
        ---- Test require 32 connected ports and SONiC up and running ----
        ---- MUST RUN WITH "--relax" option on the ptf running line   ----
        Preliminary steps
        1. Configure IPs of all of the connected ports
        (SONiC will configure neighbors)
        2. configure all routes (run add_routes.sh on SONiC)

        Test structure
        Sending Packets sequance
        1. Main loop running on 16 sources ports
        2. IP_LAST_WORD_RANGE loop running from 0-254
        3. IP_2ND_LAST_WORD_RANGE loop running 0-15
        4. Inside loop, to increase the number of packets, with differnt ports
        5. Sending and reciving packets, and counting destanation ports
        - Final counters checking for uniform distribution

        Final steps
        For cleaning configuration run remove_routes.sh from SONiC
        """
        switch_init(self.client)
        random.seed(1)
        #init vars
        sport = 0x1234
        dport = 0x50
        router_mac = self.test_params['router_mac']
        destanation_ports = range(NUMBER_OF_SRC_PORTS,NUMBER_OF_DST_PORTS+NUMBER_OF_SRC_PORTS)
        pkt_counter = [0]*32
        logging.debug("the router mac is ")
        logging.debug( router_mac)
        logging.debug("the rif macs are")
        for i in range(16): logging.debug( self.dataplane.get_mac(0, i+16))
        #send packets
        for port in xrange(NUMBER_OF_SRC_PORTS):
            for i in xrange(IP_LAST_WORD_RANGE):
                for j in xrange(IP_2ND_LAST_WORD_RANGE):
                    ip_src = '10.0.0.' + str(port * 2 + 32)
                    src_mac = self.dataplane.get_mac(0, 0)
                    ip_dst = '172.16.' + str(j) + '.' + str(i + 1)

                    pkt = simple_tcp_packet(
                                        eth_dst=router_mac,
                                        eth_src=src_mac,
                                        ip_src=ip_src,
                                        ip_dst=ip_dst,
                                        ip_id=i,
                                        tcp_sport=sport,
                                        tcp_dport=dport,
                                        ip_ttl=64)
                    exp_pkt = simple_tcp_packet(
                                        eth_dst=self.dataplane.get_mac(0, 16),
                                        eth_src=router_mac,
                                        ip_src=ip_src,
                                        ip_dst=ip_dst,
                                        ip_id=i,
                                        tcp_sport=sport,
                                        tcp_dport=dport,
                                        ip_ttl=63)
                    masked_exp_pkt = Mask(exp_pkt)
                    masked_exp_pkt.set_do_not_care_scapy(scapy.Ether,"dst")

                    send_packet(self, port, pkt)
                    (match_index,rcv_pkt) = verify_packet_any_port(self,masked_exp_pkt,destanation_ports)
                    logging.debug("found expected packet from port %d" % destanation_ports[match_index])
                    pkt_counter[match_index] += 1
                    sport = random.randint(0,0xffff)
                    dport = random.randint(0,0xffff)

        #final uniform distribution check
        for stat_port in xrange(NUMBER_OF_DST_PORTS):
            logging.debug( "PORT #"+str(hex(port_list[stat_port+NUMBER_OF_SRC_PORTS]))+":")
            logging.debug(str(pkt_counter[stat_port]))
            self.assertTrue((pkt_counter[stat_port ] >= ((IP_LAST_WORD_RANGE * IP_2ND_LAST_WORD_RANGE) * 0.9)),
                    "Not all paths are equally balanced, %s" % pkt_counter[stat_port+NUMBER_OF_SRC_PORTS])
            self.assertTrue((pkt_counter[stat_port ] <= ((IP_LAST_WORD_RANGE * IP_2ND_LAST_WORD_RANGE) * 1.1)),
                    "Not all paths are equally balanced, %s" % pkt_counter[stat_port+NUMBER_OF_SRC_PORTS])
        print "END OF TEST"
    def _get_expected_mirror_packet(self, mirror_session, setup, duthost,
                                    mirror_packet):
        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"]:
            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")

        # 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(self.OUTER_HEADER_SIZE * 8,
                                        len(payload) * 8)

        return expected_packet
示例#9
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
示例#10
0
    def check_icmp_mtu(self):
        """Check ICMP/Ping to DUT works for MAX MTU. """

        ip_src = self.src_host_ip
        ip_dst = self.src_router_ip
        src_mac = self.dataplane.get_mac(0, self.src_ptf_port_list[0])
        pktlen = self.pktlen

        if self.version == 4:
            pkt = simple_icmp_packet(pktlen=pktlen,
                                     eth_dst=self.router_mac,
                                     eth_src=src_mac,
                                     ip_src=ip_src,
                                     ip_dst=ip_dst,
                                     ip_ttl=64)

            exp_pkt = simple_icmp_packet(pktlen=pktlen,
                                         eth_src=self.router_mac,
                                         ip_src=ip_dst,
                                         ip_dst=ip_src,
                                         icmp_type=0)

            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, "id")
            masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "chksum")
            masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "ttl")
            masked_exp_pkt.set_do_not_care_scapy(scapy.ICMP, "chksum")

        else:
            pkt = simple_icmpv6_packet(pktlen=pktlen,
                                       eth_dst=self.router_mac,
                                       eth_src=src_mac,
                                       ipv6_src=ip_src,
                                       ipv6_dst=ip_dst,
                                       ipv6_hlim=64,
                                       icmp_code=0,
                                       icmp_type=128)

            exp_pkt = simple_icmpv6_packet(pktlen=pktlen,
                                           eth_src=self.router_mac,
                                           ipv6_src=ip_dst,
                                           ipv6_dst=ip_src,
                                           icmp_type=129,
                                           icmp_code=0)

            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.IPv6, "id")
            masked_exp_pkt.set_do_not_care_scapy(scapy.IPv6, "chksum")
            masked_exp_pkt.set_do_not_care_scapy(scapy.IPv6, "hlim")
            masked_exp_pkt.set_do_not_care_scapy(scapy.IPv6, "tc")
            masked_exp_pkt.set_do_not_care_scapy(scapy.IPv6, "fl")
            masked_exp_pkt.set_do_not_care_scapy(scapy.IPv6, "plen")
            masked_exp_pkt.set_do_not_care_scapy(scapy.ICMPv6Unknown, "chksum")

        src_port = self.src_ptf_port_list[0]
        send_packet(self, src_port, pkt)
        logging.info("Sending packet from port " + str(src_port) +
                     " address " + ip_src)
        logging.info("To MAC %s, dst_ip: %s", self.router_mac, ip_dst)
        dst_port_list = self.src_ptf_port_list
        logging.info(
            "Expect packet on port: %s of len %s, eth: %s, ipsrc: %s, ipdst: %s",
            str(dst_port_list), pktlen, self.router_mac, ip_dst, ip_src)

        (matched_index,
         received) = verify_packet_any_port(self, masked_exp_pkt,
                                            dst_port_list)

        assert received

        matched_port = dst_port_list[matched_index]
        logging.info("Received packet at " + str(matched_port))

        return
示例#11
0
def build_ttl0_pkts(version, dst_mac, dst_ip, vm_mac, vm_ip, dut_lb):
    """
    Builds ttl0 packet to send and ICMP TTL exceeded packet to expect back.

    Args:
        version: 4 or 6 for
        dst_mac: Destination MAC, of DUT port.
        dst_ip: Destination IP, a farend VM interface.
        vm_mac: Source MAC, of VM port that packets are sent out.
        vm_ip: Source IP, of the VM port.
        dut_lb: Loopback of DUT, source of the ICMP packets returned to the VM.

    Returns:
        3 packets, one with ttl0 to send, one as the ICMP expected packet, and one to check for TTL wrapping.

    """
    if version == 4:
        send_pkt = simple_udp_packet(
            eth_dst=dst_mac,  # mac address of dut
            eth_src=vm_mac,  # mac address of vm1
            ip_src=str(vm_ip),
            ip_dst=str(dst_ip),
            ip_ttl=0,
            pktlen=100)

        exp_pkt255 = simple_udp_packet(
            eth_dst=dst_mac,  # mac address of dut
            eth_src=vm_mac,  # mac address of vm1
            ip_src=str(vm_ip),
            ip_dst=str(dst_ip),
            ip_ttl=255,
            pktlen=100)
        v4_pktsz = 128
        exp_pkt = simple_icmp_packet(
            eth_dst=vm_mac,
            # mac address of vm1
            eth_src=dst_mac,  # mac address of dut
            ip_src=dut_lb,
            ip_dst=vm_ip,
            ip_ttl=64,
            icmp_code=0,
            icmp_type=11,
            pktlen=v4_pktsz,
        )

        masked_pkt = Mask(exp_pkt)
        masked_pkt.set_do_not_care_scapy(scapy.IP, "tos")
        masked_pkt.set_do_not_care_scapy(scapy.IP, "len")
        masked_pkt.set_do_not_care_scapy(scapy.IP, "id")
        masked_pkt.set_do_not_care_scapy(scapy.IP, "chksum")
        masked_pkt.set_do_not_care_scapy(scapy.ICMP, "chksum")
        masked_pkt.set_do_not_care(304, v4_pktsz * 8 - 304)  # ignore icmp data

    else:
        send_pkt = simple_udpv6_packet(
            eth_dst=dst_mac,  # mac address of dut
            eth_src=vm_mac,  # mac address of vm1
            ipv6_src=str(vm_ip),
            ipv6_dst=str(dst_ip),
            ipv6_hlim=0,
            pktlen=100)

        exp_pkt255 = simple_udpv6_packet(
            eth_dst=dst_mac,  # mac address of dut
            eth_src=vm_mac,  # mac address of vm1
            ipv6_src=str(vm_ip),
            ipv6_dst=str(dst_ip),
            ipv6_hlim=255,
            pktlen=100)

        v6_pktsz = 148
        exp_pkt = simple_icmpv6_packet(
            eth_dst=vm_mac,  # mac address of vm1
            eth_src=dst_mac,  # mac address of dut
            ipv6_src=str(dut_lb),
            ipv6_dst=str(vm_ip),
            ipv6_hlim=64,
            icmp_code=0,
            icmp_type=3,
            pktlen=v6_pktsz,
        )
        #
        masked_pkt = Mask(exp_pkt)
        masked_pkt.set_do_not_care_scapy(scapy.IPv6, "tc")
        masked_pkt.set_do_not_care_scapy(scapy.IPv6, "fl")
        masked_pkt.set_do_not_care_scapy(scapy.IPv6, "plen")
        masked_pkt.set_do_not_care_scapy(scapy.ICMPv6Unknown, "cksum")
        masked_pkt.set_do_not_care(456, v6_pktsz * 8 - 456)  # ignore icmp data

    return send_pkt, masked_pkt, exp_pkt255
    def generate_expected_packet(self, inner_pkt):
        """
        Generate ip_in_ip packet for verifying.
        """
        inner_pkt = inner_pkt.copy()
        inner_pkt.ttl = inner_pkt.ttl - 1
        pkt = scapy.Ether(dst=self.active_tor_mac, src=self.standby_tor_mac) / \
            scapy.IP(src=self.standby_tor_ip, dst=self.active_tor_ip) / inner_pkt['IP']
        exp_pkt = Mask(pkt)
        exp_pkt.set_do_not_care_scapy(scapy.Ether, 'dst')

        exp_pkt.set_do_not_care_scapy(scapy.IP, "ihl")
        exp_pkt.set_do_not_care_scapy(scapy.IP, "tos")
        exp_pkt.set_do_not_care_scapy(scapy.IP, "len")
        exp_pkt.set_do_not_care_scapy(scapy.IP, "id")
        exp_pkt.set_do_not_care_scapy(scapy.IP, "flags")
        exp_pkt.set_do_not_care_scapy(scapy.IP, "frag")
        exp_pkt.set_do_not_care_scapy(scapy.IP, "ttl")
        exp_pkt.set_do_not_care_scapy(scapy.IP, "proto")
        exp_pkt.set_do_not_care_scapy(scapy.IP, "chksum")

        exp_pkt.set_do_not_care_scapy(scapy.TCP, "sport")
        exp_pkt.set_do_not_care_scapy(scapy.TCP, "seq")
        exp_pkt.set_do_not_care_scapy(scapy.TCP, "ack")
        exp_pkt.set_do_not_care_scapy(scapy.TCP, "reserved")
        exp_pkt.set_do_not_care_scapy(scapy.TCP, "dataofs")
        exp_pkt.set_do_not_care_scapy(scapy.TCP, "window")
        exp_pkt.set_do_not_care_scapy(scapy.TCP, "chksum")
        exp_pkt.set_do_not_care_scapy(scapy.TCP, "urgptr")
        exp_pkt.set_ignore_extra_bytes()

        return exp_pkt
示例#13
0
    def send_and_verify(self,
                        dst_ip,
                        expected_ports,
                        src_port,
                        outer_pkt='ipv4',
                        triple_encap=False,
                        outer_ttl=None,
                        inner_ttl=None):
        '''
        @summary: This function builds encap packet, send and verify their arrival.
        @dst_ip: the destination ip for the inner IP header
        @expected_ports: list of ports that a packet can arrived from
        @src_port: the physical port that the packet will be sent from
        @triple_encap: True to send triple encapsulated packet
        @outer_ttl: TTL for the outer layer
        @inner_ttl: TTL for the inner layer
        '''

        pkt, exp_pkt = self.create_encap_packet(dst_ip, outer_pkt,
                                                triple_encap, outer_ttl,
                                                inner_ttl)
        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.Ether, "src")
        if self.ignore_ttl:
            if ipaddress.ip_address(unicode(dst_ip)).version == 4:
                masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "ttl")
                masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "chksum")
            else:
                masked_exp_pkt.set_do_not_care_scapy(scapy.IPv6, "hlim")
                masked_exp_pkt.set_do_not_care_scapy(scapy.IPv6, "chksum")

        #send and verify the return packets
        send_packet(self, src_port, pkt)
        logging.info(".....Sending packet from port" + str(src_port) + " to " +
                     dst_ip + ", Triple_encap: " + str(triple_encap))
        matched, received = verify_packet_any_port(self, masked_exp_pkt,
                                                   expected_ports)
        assert received
        return matched, received
示例#14
0
    def runTest(self):
        print
        switch_init(self.client)
        port1=port_list[0] #From where we expect encapsulated packet 
        port2=port_list[1] #From where we send normal ip packet
        mac1 = '00:05:06:00:00:00' # port1 l2 entry
        mac2 = '00:05:06:00:00:02' 
        vr_mac='00:00:08:08:08:08'
        mac_action=1                
        vlan_id=0            #expecting to use unused vlans
        addr_family_ipv4=SAI_IP_ADDR_FAMILY_IPV4
        tunnel_src_ip_addr='2.2.2.2' #src for outer ip
        encap_ip_addr='10.10.1.1'    #egress enighbhor
        ingress_ip_addr='20.20.1.1'  #ingress neighbor 
        tunnel_ip_addr_route='1.1.1.0'  #to reach tunnel nhop
        tunnel_ip_mask_route='255.255.255.0'
        ingress_nhop_ip_addr='20.20.1.1'
        egress_nhop_ip_addr='10.10.1.1'
        ip_addr_ingress_route='20.20.1.0'
        ip_mask_ingress_route='255.255.255.0'
        ip_addr_encap_route='10.10.1.0'
        ip_mask_encap_route='255.255.255.0'
        initiator_ip_addr='10.10.1.1'  #tunnel dest ip(outer header)
        neighbor_mac_ingress='00:05:06:00:00:02'
        neighbor_mac_encap='00:05:06:00:00:00' #egress side
        ip_addr_decap_src='10.10.1.1'
        ip_addr_decap_dst='2.2.2.2'
               
        ########################################################################
        #Creating Virtual router 
        #######################################################################
        vr_id=sai_thrift_create_virtual_router(self.client, 1, 1)
            
        #creating a underlay interface in loopback
        underlay_if = sai_thrift_create_router_interface(self.client, type=SAI_ROUTER_INTERFACE_TYPE_LOOPBACK, port_oid=0, vr_oid=vr_id, vlan_oid=vlan_id, v4_enabled=1, v6_enabled=1, mac='')
        #creating an overlay interface in loopback
        overlay_if = sai_thrift_create_router_interface(self.client, type=SAI_ROUTER_INTERFACE_TYPE_LOOPBACK, port_oid=0, vr_oid=vr_id, vlan_oid=vlan_id, v4_enabled=1, v6_enabled=1, mac='')
        #creating a tunnel
        tunnel_id=sai_thrift_create_tunnel(self.client, tunnel_type=SAI_TUNNEL_TYPE_IPINIP,
                                           addr_family=addr_family_ipv4, ip_addr=tunnel_src_ip_addr, underlay_if=underlay_if, overlay_if=overlay_if,
                                           encap_ttl_mode=SAI_TUNNEL_TTL_MODE_PIPE_MODEL, encap_dscp_mode=SAI_TUNNEL_DSCP_MODE_PIPE_MODEL, encap_dscp_val=50)
     
        ##############################################################################
        #  Egress configurations
        #  create router interface,
        #  create neighbor
        #  create route
        #   
        ##############################################################################
       
        #encap router interface
        encap_if_id=sai_thrift_create_router_interface(self.client, vr_oid=vr_id, type=SAI_ROUTER_INTERFACE_TYPE_PORT, port_oid=port1, vlan_oid=vlan_id, v4_enabled = 1, v6_enabled = 1, mac='')
        #egress(encap side) neighbor (ip=10.10.1.1 , mac=00:05:06:00:00:00 )
        sai_thrift_create_neighbor(self.client, addr_family=addr_family_ipv4, rif_id=encap_if_id, ip_addr=encap_ip_addr, dmac=neighbor_mac_encap)
        #egress(encap) nhop and route create
        sai_thrift_create_route(self.client, vr_id=vr_id, addr_family=addr_family_ipv4, ip_addr=ip_addr_encap_route, ip_mask=ip_mask_encap_route, nhop=encap_if_id)
        
        ###############################################################################
        #  Ingress configurations
        #  create router interface,
        #  create neighbor
        #  create nhop
        #  create route
        #   
        ##############################################################################

        #ingress router interface
        ingress_if_id=sai_thrift_create_router_interface(self.client,vr_oid=vr_id,type=SAI_ROUTER_INTERFACE_TYPE_PORT,port_oid=port2,vlan_oid=vlan_id,v4_enabled=1,v6_enabled = 1, mac='')
        #ingress neighbor neighbor (ip=20.20.1.1 , mac = 00:05:06:00:00:02)
        sai_thrift_create_neighbor(self.client, addr_family=addr_family_ipv4, rif_id=ingress_if_id, ip_addr=ingress_ip_addr, dmac=neighbor_mac_ingress)

        #adding tunnel and route
        initiator_id=sai_thrift_create_nhop(self.client, addr_family=addr_family_ipv4, ip_addr=initiator_ip_addr, rif_id=tunnel_id , is_tunnel=1)
        sai_thrift_create_route(self.client,vr_id=vr_id, addr_family=addr_family_ipv4, ip_addr=tunnel_ip_addr_route, ip_mask=tunnel_ip_mask_route, nhop=initiator_id)

        #Packet to be send 
        pkt = simple_tcp_packet(eth_dst=router_mac,
                                eth_src='00:00:00:00:00:01',
                                ip_src='20.20.1.2',
                                ip_dst='1.1.1.1',
                                ip_id=1,
                                ip_ttl=64)
        #expected packet inner IP header
        inner_hdr = simple_tcp_packet(eth_dst=router_mac,
                                eth_src='00:00:00:00:00:01',
                                ip_src='20.20.1.2',
                                ip_dst='1.1.1.1',
                                ip_id=1,
                                ip_ttl=63)
        exp_pkt = simple_ipv4ip_packet(eth_dst='00:05:06:00:00:00',
                                eth_src=router_mac,
                                ip_dst='10.10.1.1',
                                ip_src='2.2.2.2',
                                ip_id=0,#mask the indentifier during check because it differs every time.better chech with wireshark
                                ip_tos=0xc8,
                                ip_ttl=63,
                                inner_frame=inner_hdr['IP']
                                )
        #masking packet 
        m=Mask(exp_pkt)
        m.set_do_not_care_scapy(ptf.packet.IP, 'id')
        m.set_do_not_care_scapy(ptf.packet.IP, 'chksum')

        try:
            # in tuple: 0 is device number, 1 is port number
            # this tuple uniquely identifies a port
            send_packet(self, 1, pkt)
            verify_packets(self, m, [0])

        finally:
            sai_thrift_remove_route(self.client,vr_id,addr_family_ipv4,tunnel_ip_addr_route,tunnel_ip_mask_route,initiator_id) 
            self.client.sai_thrift_remove_next_hop(initiator_id)

            sai_thrift_remove_route(self.client,vr_id,addr_family_ipv4,ip_addr_encap_route,ip_mask_encap_route,encap_if_id) 

            sai_thrift_remove_neighbor(self.client,addr_family_ipv4,rif_id=ingress_if_id,ip_addr=ingress_ip_addr,dmac=neighbor_mac_ingress)
            
            sai_thrift_remove_neighbor(self.client,addr_family_ipv4,rif_id=encap_if_id,ip_addr=encap_ip_addr,dmac=neighbor_mac_encap)

            self.client.sai_thrift_remove_router_interface(ingress_if_id)

            self.client.sai_thrift_remove_router_interface(encap_if_id)

            self.client.sai_thrift_remove_tunnel(tunnel_id)

            self.client.sai_thrift_remove_router_interface(underlay_if)

            self.client.sai_thrift_remove_router_interface(overlay_if)

            self.client.sai_thrift_remove_virtual_router(vr_id)
示例#15
0
    def verify_relayed_request(self):
        # Create a packet resembling a relayed DCHPREQUEST packet
        dhcp_request_relayed = self.create_dhcp_request_relayed_packet()

        # Mask off fields we don't care about matching
        masked_request = Mask(dhcp_request_relayed)
        masked_request.set_do_not_care_scapy(scapy.Ether, "dst")

        masked_request.set_do_not_care_scapy(scapy.IP, "version")
        masked_request.set_do_not_care_scapy(scapy.IP, "ihl")
        masked_request.set_do_not_care_scapy(scapy.IP, "tos")
        masked_request.set_do_not_care_scapy(scapy.IP, "len")
        masked_request.set_do_not_care_scapy(scapy.IP, "id")
        masked_request.set_do_not_care_scapy(scapy.IP, "flags")
        masked_request.set_do_not_care_scapy(scapy.IP, "frag")
        masked_request.set_do_not_care_scapy(scapy.IP, "ttl")
        masked_request.set_do_not_care_scapy(scapy.IP, "proto")
        masked_request.set_do_not_care_scapy(scapy.IP, "chksum")
        masked_request.set_do_not_care_scapy(scapy.IP, "src")
        masked_request.set_do_not_care_scapy(scapy.IP, "dst")
        masked_request.set_do_not_care_scapy(scapy.IP, "options")

        masked_request.set_do_not_care_scapy(scapy.UDP, "chksum")
        masked_request.set_do_not_care_scapy(scapy.UDP, "len")

        masked_request.set_do_not_care_scapy(scapy.BOOTP, "sname")
        masked_request.set_do_not_care_scapy(scapy.BOOTP, "file")

        # Count the number of these packets received on the ports connected to our leaves
        num_expected_packets = self.num_dhcp_servers
        request_count = testutils.count_matched_packets_all_ports(
            self, masked_request, self.server_port_indices)
        self.assertTrue(
            request_count == num_expected_packets,
            "Failed: Request count of %d != %d" %
            (request_count, num_expected_packets))
示例#16
0
    def send_packets(self):
        random.seed(time.time())
        sport = 0x1234
        dport = 0x50
        router_mac = self.test_params['router_mac']
        destanation_ports = range(NUMBER_OF_SRC_PORTS,
                                  NUMBER_OF_DST_PORTS + NUMBER_OF_SRC_PORTS)
        self.log("the router mac is %s" % router_mac)
        self.log("the rif macs are:")
        for i in range(16):
            self.log("    %s" % self.dataplane.get_mac(0, i + 16))

        #send packets
        for port in xrange(NUMBER_OF_SRC_PORTS):
            for i in xrange(IP_LAST_WORD_RANGE):
                for j in xrange(IP_2ND_LAST_WORD_RANGE):
                    ip_src = '10.0.0.' + str(port * 2 + 32)
                    src_mac = self.dataplane.get_mac(0, 0)
                    ip_dst = '172.16.' + str(j) + '.' + str(i + 1)

                    pkt = simple_tcp_packet(eth_dst=router_mac,
                                            eth_src=src_mac,
                                            ip_src=ip_src,
                                            ip_dst=ip_dst,
                                            ip_id=i * j * port,
                                            tcp_sport=sport,
                                            tcp_dport=dport,
                                            ip_ttl=64)
                    exp_pkt = simple_tcp_packet(eth_dst=self.dataplane.get_mac(
                        0, 16),
                                                eth_src=router_mac,
                                                ip_src=ip_src,
                                                ip_dst=ip_dst,
                                                ip_id=i * j * port,
                                                tcp_sport=sport,
                                                tcp_dport=dport,
                                                ip_ttl=63)
                    masked_exp_pkt = Mask(exp_pkt)
                    masked_exp_pkt.set_do_not_care_scapy(scapy.Ether, "dst")

                    sleep_time = 1
                    repeat = 5  # Repeat the send action until we receive a packet
                    while True:
                        send_packet(self, port, pkt)
                        self.log(
                            "Sent packet src=%s dst=%s port=%s" %
                            (ip_src, ip_dst, port), True)
                        port_index = self.verify_packet_any_port(
                            masked_exp_pkt, destanation_ports)
                        if port_index is None:
                            self.log(
                                "Expected packet isn't received. Repeating",
                                True)
                            time.sleep(sleep_time)
                            sleep_time *= 2
                            repeat -= 1
                            if repeat == 0:
                                self.fail(
                                    "Can't receive packet: src=%s dst=%s port=%s"
                                    % (ip_src, ip_dst, port))
                        else:
                            break
                    self.log(
                        "Received expected packet from port %d" %
                        destanation_ports[port_index], True)

                    self.pkt_counter[port_index] += 1
                    sport = random.randint(0, 0xffff)
                    dport = random.randint(0, 0xffff)
        return
示例#17
0
文件: saimirror.py 项目: rspolyak/SAI
    def runTest(self):
        print
        switch_init(self.client)
        port1 = port_list[0]
        port2 = port_list[1]
        port3 = port_list[2]
        monitor_port=port1
        source_port=port2
        mac3='00:00:00:00:00:33'
        mac2='00:00:00:00:00:22'
        mirror_type=SAI_MIRROR_TYPE_LOCAL
        sai_thrift_create_fdb(self.client, 2, mac3, port3, 1)
        sai_thrift_create_fdb(self.client, 2, mac2, port2, 1)

        # Put ports under test in VLAN 2
        self.client.sai_thrift_create_vlan(2)
        vlan_member1 = sai_thrift_create_vlan_member(self.client, 2, port1, SAI_VLAN_PORT_TAGGED)
        vlan_member1a = sai_thrift_create_vlan_member(self.client, 1, port1, SAI_VLAN_PORT_TAGGED)
        vlan_member2 = sai_thrift_create_vlan_member(self.client, 2, port2, SAI_VLAN_PORT_TAGGED)
        vlan_member2a = sai_thrift_create_vlan_member(self.client, 1, port2, SAI_VLAN_PORT_TAGGED)
        vlan_member3 = sai_thrift_create_vlan_member(self.client, 2, port3, SAI_VLAN_PORT_TAGGED)
        vlan_member3a = sai_thrift_create_vlan_member(self.client, 1, port3, SAI_VLAN_PORT_TAGGED)

        # Remove ports from default VLAN
        self.client.sai_thrift_remove_vlan_member(vlan_member1a)
        self.client.sai_thrift_remove_vlan_member(vlan_member2a)
        self.client.sai_thrift_remove_vlan_member(vlan_member3a)

        # Set PVID
        attr_value = sai_thrift_attribute_value_t(u16=2)
        attr = sai_thrift_attribute_t(id=SAI_PORT_ATTR_PORT_VLAN_ID, value=attr_value)
        self.client.sai_thrift_set_port_attribute(port1, attr)
        self.client.sai_thrift_set_port_attribute(port2, attr)
        self.client.sai_thrift_set_port_attribute(port3, attr)

        spanid=sai_thrift_create_mirror_session(self.client,mirror_type=mirror_type,port=monitor_port,vlan=1,vlan_priority=0,vlan_tpid=0,src_mac=None,dst_mac=None,addr_family=0,src_ip=None,dst_ip=None,encap_type=0,protocol=0,ttl=0,tos=0,gre_type=0)
        attrb_value = sai_thrift_attribute_value_t(objlist=sai_thrift_object_list_t(count=1,object_id_list=[spanid]))

        attr = sai_thrift_attribute_t(id=SAI_PORT_ATTR_INGRESS_MIRROR_SESSION, value=attrb_value)
        self.client.sai_thrift_set_port_attribute(port2, attr)

        attr = sai_thrift_attribute_t(id=SAI_PORT_ATTR_EGRESS_MIRROR_SESSION, value=attrb_value)
        self.client.sai_thrift_set_port_attribute(port2, attr)
        pkt = simple_tcp_packet(eth_dst='00:00:00:00:00:33',
                                eth_src='00:22:22:22:22:22',
                                ip_dst='10.0.0.1',
                                dl_vlan_enable=True,
                                vlan_vid=2,
                                ip_id=101,
                                ip_ttl=64)

        exp_pkt = simple_tcp_packet(eth_dst='00:00:00:00:00:33',
                                eth_src='00:22:22:22:22:22',
                                ip_dst='10.0.0.1',
                                dl_vlan_enable=True,
                                vlan_vid=2,
                                ip_id=101,
                                ip_ttl=64)

        pkt2 = simple_tcp_packet(eth_dst='00:00:00:00:00:22',
                                eth_src='00:33:33:33:33:33',
                                ip_dst='10.0.0.1',
                                dl_vlan_enable=True,
                                vlan_vid=2,
                                ip_id=101,
                                ip_ttl=64,
                                pktlen=104)

        exp_pkt2 = simple_tcp_packet(eth_dst='00:00:00:00:00:22',
                                eth_src='00:33:33:33:33:33',
                                ip_dst='10.0.0.1',
                                dl_vlan_enable=True,
                                vlan_vid=2,#use vlan_vid field if packets are expected to be monitored on client side otherwise not needed 
                                ip_id=101,
                                ip_ttl=64,
                                pktlen=104)

        m=Mask(exp_pkt2)
        m.set_do_not_care_scapy(ptf.packet.IP,'id')
        m.set_do_not_care_scapy(ptf.packet.IP,'chksum')
        try:
            # in tuple: 0 is device number, 2 is port number
            # this tuple uniquely identifies a port
            # for ingress mirroring
            print "Checking INGRESS Local Mirroring"
            print "Sending packet port 2 -> port 3 (00:22:22:22:22:22 -> 00:00:00:00:00:33)"
            send_packet(self, 1, pkt)
            verify_packets(self, exp_pkt, ports=[0,2])
            # for egress mirroring
            print "Checking EGRESS Local Mirroring"
            print "Sending packet port 3 -> port 2 (00:33:33:33:33:33 -> 00:00:00:00:00:22)"
            send_packet(self, 2, pkt2)
            verify_each_packet_on_each_port(self, [m,pkt2], ports=[0,1])
        finally:
            sai_thrift_delete_fdb(self.client, 2, mac3, port3)
            sai_thrift_delete_fdb(self.client, 2, mac2, port2)

            # Remove ports from mirror destination
            attrb_value = sai_thrift_attribute_value_t(objlist=sai_thrift_object_list_t(count=0,object_id_list=[spanid]))
            attr = sai_thrift_attribute_t(id=SAI_PORT_ATTR_INGRESS_MIRROR_SESSION, value=attrb_value)
            self.client.sai_thrift_set_port_attribute(port2, attr)
            attr = sai_thrift_attribute_t(id=SAI_PORT_ATTR_EGRESS_MIRROR_SESSION, value=attrb_value)
            self.client.sai_thrift_set_port_attribute(port2, attr)

            # Now you can remove destination
            self.client.sai_thrift_remove_mirror_session(spanid)

            # Remove ports from VLAN 2
            self.client.sai_thrift_remove_vlan_member(vlan_member1)
            self.client.sai_thrift_remove_vlan_member(vlan_member2)
            self.client.sai_thrift_remove_vlan_member(vlan_member3)
            self.client.sai_thrift_delete_vlan(2)

            # Add ports back to default VLAN
            vlan_member1a = sai_thrift_create_vlan_member(self.client, 1, port1, SAI_VLAN_PORT_UNTAGGED)
            vlan_member2a = sai_thrift_create_vlan_member(self.client, 1, port2, SAI_VLAN_PORT_UNTAGGED)
            vlan_member3a = sai_thrift_create_vlan_member(self.client, 1, port3, SAI_VLAN_PORT_UNTAGGED)

            attr_value = sai_thrift_attribute_value_t(u16=1)
            attr = sai_thrift_attribute_t(id=SAI_PORT_ATTR_PORT_VLAN_ID, value=attr_value)
            self.client.sai_thrift_set_port_attribute(port1, attr)
            self.client.sai_thrift_set_port_attribute(port2, attr)
            self.client.sai_thrift_set_port_attribute(port3, attr)
示例#18
0
    def runTest(self):
        ecn = 1
        dscp = self.queue_index
        tos = dscp << 2
        tos |= ecn

        matches = re.findall('\[([\d\s]+)\]', self.port_dst)

        dst_port_list = []
        for match in matches:
            for port in match.split():
                dst_port_list.append(int(port))
        src_mac = self.dataplane.get_mac(
            *random.choice(self.dataplane.ports.keys()))

        if self.port_type == "portchannel":
            for x in range(0, self.pkt_count):
                sport = random.randint(0, 65535)
                dport = random.randint(0, 65535)
                ip_src = socket.inet_ntoa(
                    struct.pack('>I', random.randint(1, 0xffffffff)))
                ip_src = ipaddress.IPv4Address(unicode(ip_src, 'utf-8'))
                if not isinstance(self.ip_dst, unicode):
                    self.ip_dst = unicode(self.ip_dst, 'utf-8')
                ip_dst = ipaddress.IPv4Address(self.ip_dst)
                while ip_src == ip_dst or ip_src.is_multicast or ip_src.is_private or ip_src.is_global or ip_src.is_reserved:
                    ip_src = socket.inet_ntoa(
                        struct.pack('>I', random.randint(1, 0xffffffff)))
                    ip_src = ipaddress.IPv4Address(unicode(ip_src, 'utf-8'))

                ip_src = str(ip_src)
                pkt_args = {
                    'eth_dst': self.router_mac,
                    'eth_src': src_mac,
                    'ip_src': ip_src,
                    'ip_dst': self.ip_dst,
                    'ip_tos': tos,
                    'tcp_sport': sport,
                    'tcp_dport': dport,
                    'ip_ttl': 64
                }
                if self.port_src_vlan_id is not None:
                    pkt_args['dl_vlan_enable'] = True
                    pkt_args['vlan_vid'] = int(self.port_src_vlan_id)
                    pkt_args['vlan_pcp'] = self.queue_index
                pkt = simple_tcp_packet(**pkt_args)
                exp_pkt_args = {
                    'eth_src': self.router_mac,
                    'ip_src': ip_src,
                    'ip_dst': self.ip_dst,
                    'ip_tos': tos,
                    'tcp_sport': sport,
                    'tcp_dport': dport,
                    'ip_ttl': 63
                }
                if self.port_dst_vlan_id is not None:
                    exp_pkt_args['dl_vlan_enable'] = True
                    exp_pkt_args['vlan_vid'] = int(self.port_dst_vlan_id)
                    exp_pkt_args['vlan_pcp'] = self.queue_index
                exp_pkt = simple_tcp_packet(**exp_pkt_args)
                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.Ether, "src")
                masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "chksum")
                masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "ttl")
                masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "len")

                send_packet(self, self.port_src, pkt, 1)
        else:
            sport = random.randint(0, 65535)
            dport = random.randint(0, 65535)
            ip_src = "1.1.1.1"

            pkt_args = {
                'eth_dst': self.router_mac,
                'eth_src': src_mac,
                'ip_src': ip_src,
                'ip_dst': self.ip_dst,
                'ip_tos': tos,
                'tcp_sport': sport,
                'tcp_dport': dport,
                'ip_ttl': 64
            }
            if self.port_src_vlan_id is not None:
                pkt_args['dl_vlan_enable'] = True
                pkt_args['vlan_vid'] = int(self.port_src_vlan_id)
                pkt_args['vlan_pcp'] = self.queue_index
            pkt = simple_tcp_packet(**pkt_args)
            exp_pkt_args = {
                'eth_src': self.router_mac,
                'ip_src': ip_src,
                'ip_dst': self.ip_dst,
                'ip_tos': tos,
                'tcp_sport': sport,
                'tcp_dport': dport,
                'ip_ttl': 63
            }
            if self.port_dst_vlan_id is not None:
                exp_pkt_args['dl_vlan_enable'] = True
                exp_pkt_args['vlan_vid'] = int(self.port_dst_vlan_id)
                exp_pkt_args['vlan_pcp'] = self.queue_index
            exp_pkt = simple_tcp_packet(**exp_pkt_args)
            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.Ether, "src")
            masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "chksum")
            masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "ttl")
            masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "len")

            send_packet(self, self.port_src, pkt, self.pkt_count)
        if self.wd_action == 'drop':
            return verify_no_packet_any(self, masked_exp_pkt, dst_port_list)
        elif self.wd_action == 'forward':
            return verify_packet_any_port(self, masked_exp_pkt, dst_port_list)
示例#19
0
def test_vlan_tc6_tagged_untagged_unicast(
        ptfadapter, work_vlan_ports_list, vlan_intfs_dict,
        toggle_all_simulator_ports_to_rand_selected_tor_m):
    """
    Test case #6
    Send packets w/ src and dst specified over tagged port and untagged port in vlan
    Verify that bidirectional communication between tagged port and untagged port work
    """
    for test_vlan in vlan_intfs_dict:
        untagged_ports_for_test = []
        tagged_ports_for_test = []

        for vlan_port in work_vlan_ports_list:
            if test_vlan not in vlan_port['permit_vlanid']:
                continue
            if vlan_port['pvid'] == test_vlan:
                untagged_ports_for_test.append(vlan_port['port_index'])
            else:
                tagged_ports_for_test.append(vlan_port['port_index'])
        if not untagged_ports_for_test:
            continue
        if not tagged_ports_for_test:
            continue

        #take two ports for test
        src_port = untagged_ports_for_test[0]
        dst_port = tagged_ports_for_test[0]

        src_mac = ptfadapter.dataplane.get_mac(0, src_port[0])
        dst_mac = ptfadapter.dataplane.get_mac(0, dst_port[0])

        transmit_untagged_pkt = build_icmp_packet(vlan_id=0,
                                                  src_mac=src_mac,
                                                  dst_mac=dst_mac)
        exp_tagged_pkt = build_icmp_packet(vlan_id=test_vlan,
                                           src_mac=src_mac,
                                           dst_mac=dst_mac)
        exp_tagged_pkt = Mask(exp_tagged_pkt)
        exp_tagged_pkt.set_do_not_care_scapy(scapy.Dot1Q, "prio")

        return_transmit_tagged_pkt = build_icmp_packet(vlan_id=test_vlan,
                                                       src_mac=dst_mac,
                                                       dst_mac=src_mac)
        exp_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(
                test_vlan, src_port, dst_port))

        verify_unicast_packets(ptfadapter, transmit_untagged_pkt,
                               exp_tagged_pkt, src_port[0], dst_port)

        logger.info("One Way Untagged Packet Transmission Works")
        logger.info(
            "Untagged({}) packet successfully sent from port {} to port {}".
            format(test_vlan, src_port, dst_port))

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

        verify_unicast_packets(ptfadapter, return_transmit_tagged_pkt,
                               exp_untagged_pkt, dst_port[0], src_port)

        logger.info("Two Way tagged Packet Transmission Works")
        logger.info(
            "Tagged({}) packet successfully sent from port {} to port {}".
            format(test_vlan, dst_port, src_port))
示例#20
0
    def FromServer(self, test):
        rv = True
        try:
            pkt_len = self.DEFAULT_PKT_LEN
            if test['vlan'] != 0:
                tagged = True
                pkt_len += 4
            else:
                tagged = False

            vni = int(test['vni'])
            if 'dst_vni' in test:
                vni = int(test['dst_vni'])

            pkt = simple_tcp_packet(pktlen=pkt_len,
                                    eth_dst=self.dut_mac,
                                    eth_src=self.ptf_mac_addrs['eth%d' %
                                                               test['port']],
                                    dl_vlan_enable=tagged,
                                    vlan_vid=test['vlan'],
                                    ip_dst=test['dst'],
                                    ip_src=test['src'],
                                    ip_id=105,
                                    ip_ttl=64,
                                    tcp_sport=1234,
                                    tcp_dport=5000)
            exp_pkt = simple_tcp_packet(eth_dst=test['mac'],
                                        eth_src=self.dut_mac,
                                        ip_dst=test['dst'],
                                        ip_src=test['src'],
                                        ip_id=105,
                                        ip_ttl=63,
                                        tcp_sport=1234,
                                        tcp_dport=5000)
            udp_sport = 1234  # Use entropy_hash(pkt)
            udp_dport = self.vxlan_port
            if isinstance(ip_address(test['host']), ipaddress.IPv4Address):
                encap_pkt = simple_vxlan_packet(eth_src=self.dut_mac,
                                                eth_dst=self.random_mac,
                                                ip_id=0,
                                                ip_src=self.loopback_ipv4,
                                                ip_dst=test['host'],
                                                ip_ttl=128,
                                                udp_sport=udp_sport,
                                                udp_dport=udp_dport,
                                                with_udp_chksum=False,
                                                vxlan_vni=vni,
                                                inner_frame=exp_pkt)
                encap_pkt[IP].flags = 0x2
            elif isinstance(ip_address(test['host']), ipaddress.IPv6Address):
                encap_pkt = simple_vxlanv6_packet(eth_src=self.dut_mac,
                                                  eth_dst=self.random_mac,
                                                  ipv6_src=self.loopback_ipv6,
                                                  ipv6_dst=test['host'],
                                                  udp_sport=udp_sport,
                                                  udp_dport=udp_dport,
                                                  with_udp_chksum=False,
                                                  vxlan_vni=vni,
                                                  inner_frame=exp_pkt)
            else:
                raise Exception("Found invalid IP address in test")
            send_packet(self, test['port'], str(pkt))

            masked_exp_pkt = Mask(encap_pkt)
            masked_exp_pkt.set_do_not_care_scapy(scapy.Ether, "src")
            masked_exp_pkt.set_do_not_care_scapy(scapy.Ether, "dst")
            if isinstance(ip_address(test['host']), ipaddress.IPv4Address):
                masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "ttl")
            else:
                masked_exp_pkt.set_do_not_care_scapy(scapy.IPv6, "hlim")
            masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "chksum")
            masked_exp_pkt.set_do_not_care_scapy(scapy.UDP, "sport")

            log_str = "Sending packet from port " + str(
                'eth%d' % test['port']) + " to " + test['dst']
            logging.info(log_str)

            if not self.routes_removed:
                status, received_pkt = verify_packet_any_port(
                    self, masked_exp_pkt, self.net_ports)
                if self.vxlan_srcport_range_enabled:
                    scapy_pkt = Ether(received_pkt)
                    assert (
                        self.vxlan_srcport_lower_bound <= scapy_pkt.sport
                    ) and (self.vxlan_srcport_upper_bound >= scapy_pkt.sport
                           ), ("Received packet has UDP src port {} "
                               "that is not in expected range {} - {}".format(
                                   scapy_pkt.sport,
                                   self.vxlan_srcport_lower_bound,
                                   self.vxlan_srcport_upper_bound))
            else:
                verify_no_packet_any(self, masked_exp_pkt, self.net_ports)

            pkt.load = '0' * 60 + str(len(self.packets))
            self.packets.append((test['port'], str(pkt).encode("base64")))

        finally:
            print
示例#21
0
    def verify_dhcp_relay_pkt_on_server_port_with_no_padding(
            self, dst_mac=BROADCAST_MAC, src_port=DHCP_CLIENT_PORT):
        # Form and send DHCP Relay packet
        dhcp_request = self.create_dhcp_request_packet(dst_mac, src_port)
        testutils.send_packet(self, self.client_port_index, dhcp_request)

        # Mask off fields we don't care about matching
        # Create a packet resembling a relayed DCHPREQUEST packet
        dhcp_request_relayed = self.create_dhcp_request_relayed_packet()

        # Mask off fields we don't care about matching
        masked_request = Mask(dhcp_request_relayed)
        masked_request.set_do_not_care_scapy(scapy.Ether, "dst")

        masked_request.set_do_not_care_scapy(scapy.IP, "version")
        masked_request.set_do_not_care_scapy(scapy.IP, "ihl")
        masked_request.set_do_not_care_scapy(scapy.IP, "tos")
        masked_request.set_do_not_care_scapy(scapy.IP, "len")
        masked_request.set_do_not_care_scapy(scapy.IP, "id")
        masked_request.set_do_not_care_scapy(scapy.IP, "flags")
        masked_request.set_do_not_care_scapy(scapy.IP, "frag")
        masked_request.set_do_not_care_scapy(scapy.IP, "ttl")
        masked_request.set_do_not_care_scapy(scapy.IP, "proto")
        masked_request.set_do_not_care_scapy(scapy.IP, "chksum")
        masked_request.set_do_not_care_scapy(scapy.IP, "src")
        masked_request.set_do_not_care_scapy(scapy.IP, "dst")
        masked_request.set_do_not_care_scapy(scapy.IP, "options")

        masked_request.set_do_not_care_scapy(scapy.UDP, "chksum")
        masked_request.set_do_not_care_scapy(scapy.UDP, "len")

        masked_request.set_do_not_care_scapy(scapy.BOOTP, "sname")
        masked_request.set_do_not_care_scapy(scapy.BOOTP, "file")

        try:
            testutils.verify_packets_any(self, masked_request,
                                         self.server_port_indices)
        except Exception:
            self.assertTrue(
                False,
                "DHCP Relay packet not matched or Padded extra on server side")
    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)
示例#23
0
    def runTest(self):
        pass_cnt = 0
        tos = self.dscp << 2
        tos_bg = self.dscp_bg << 2
        if self.debug:
            # remove previous debug files
            files = glob.glob("/tmp/pfc_pause_{}*".format(self.dscp))
            for file in files:
                os.remove(file)
            current_time = datetime.datetime.now().strftime(
                "%Y-%m-%d_%H:%M:%S")
            log_file = open(
                "/tmp/pfc_pause_{}_{}".format(self.dscp, current_time), "w")
        """ If DUT needs to learn MAC addresses """
        if not self.dut_has_mac:
            pkt = simple_udp_packet(eth_dst=self.mac_dst,
                                    eth_src=self.mac_src,
                                    ip_src=self.ip_src,
                                    ip_dst=self.ip_dst)

            send_packet(self, self.port_src, pkt, 5)

            pkt = simple_udp_packet(eth_dst=self.mac_src,
                                    eth_src=self.mac_dst,
                                    ip_src=self.ip_dst,
                                    ip_dst=self.ip_src)

            send_packet(self, self.port_dst, pkt, 5)

        for x in range(self.pkt_count):
            sport = random.randint(0, 65535)
            dport = random.randint(0, 65535)

            pkt = simple_udp_packet(eth_dst=self.mac_dst,
                                    eth_src=self.mac_src,
                                    ip_src=self.ip_src,
                                    ip_dst=self.ip_dst,
                                    ip_tos=tos,
                                    udp_sport=sport,
                                    udp_dport=dport,
                                    ip_ttl=64)

            pkt_bg = simple_udp_packet(eth_dst=self.mac_dst,
                                       eth_src=self.mac_src,
                                       ip_src=self.ip_src,
                                       ip_dst=self.ip_dst,
                                       ip_tos=tos_bg,
                                       udp_sport=sport,
                                       udp_dport=dport,
                                       ip_ttl=64)

            exp_pkt = simple_udp_packet(ip_src=self.ip_src,
                                        ip_dst=self.ip_dst,
                                        ip_tos=tos_bg,
                                        udp_sport=sport,
                                        udp_dport=dport,
                                        ip_ttl=63)

            masked_exp_pkt = Mask(exp_pkt)
            masked_exp_pkt.set_do_not_care_scapy(scapy.Ether, "src")
            masked_exp_pkt.set_do_not_care_scapy(scapy.Ether, "dst")
            masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "ttl")
            masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "chksum")
            masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "tos")

            send_packet(self, self.port_src, pkt, 1)
            send_packet(self, self.port_src, pkt_bg, 1)

            pkts = capture_matched_packets(self, masked_exp_pkt, self.port_dst)

            if self.debug:
                for i, pkt in enumerate(pkts):
                    dump_msg = "Iteration {}:\n Pkt num {}:\n Hex dump: {}\n\n".format(
                        x, i, sc.utils.hexstr(pkt))
                    log_file.write(dump_msg)

            time.sleep(self.pkt_intvl)
            """ If the queue is paused, we should only receive the background packet """
            if self.queue_paused:
                pass_cnt += int(
                    len(pkts) == 1
                    and scapy.Ether(pkts[0])[scapy.IP].tos == tos_bg)

            else:
                pass_cnt += int(len(pkts) == 2)

        if self.debug:
            log_file.close()
        print "Passes: %d / %d" % (pass_cnt, self.pkt_count)
示例#24
0
    def runTest(self):
        ecn = 1
        dscp = self.queue_index
        tos = dscp << 2
        tos |= ecn

        matches = re.findall('\[([\d\s]+)\]', self.port_dst)

        dst_port_list = []
        for match in matches:
            for port in match.split():
                dst_port_list.append(int(port))
        src_mac = self.dataplane.get_mac(0, 0)

        if self.port_type == "portchannel":
            for x in range(0, self.pkt_count):
                sport = random.randint(0, 65535)
                dport = random.randint(0, 65535)
                ip_src = socket.inet_ntoa(struct.pack('>I', random.randint(1, 0xffffffff)))
                ip_src =ipaddress.IPv4Address(unicode(ip_src,'utf-8'))
                while ip_src == ipaddress.IPv4Address(unicode(self.ip_dst,'utf-8')) or ip_src.is_multicast or ip_src.is_private or ip_src.is_global or ip_src.is_reserved:
                    ip_src = socket.inet_ntoa(struct.pack('>I', random.randint(1, 0xffffffff)))
                    ip_src =ipaddress.IPv4Address(unicode(ip_src,'utf-8'))

                ip_src = str(ip_src)
                pkt = simple_tcp_packet(
                                    eth_dst=self.router_mac,
                                    eth_src=src_mac,
                                    ip_src=ip_src,
                                    ip_dst=self.ip_dst,
                                    ip_tos = tos,
                                    tcp_sport=sport,
                                    tcp_dport=dport,
                                    ip_ttl=64)
                exp_pkt = simple_tcp_packet(
                                    eth_src=self.router_mac,
                                    ip_src=ip_src,
                                    ip_dst=self.ip_dst,
                                    ip_tos = tos,
                                    tcp_sport=sport,
                                    tcp_dport=dport,
                                    ip_ttl=63)
                masked_exp_pkt = Mask(exp_pkt)
                masked_exp_pkt.set_do_not_care_scapy(scapy.Ether, "dst")

                send_packet(self, self.port_src, pkt, 1)
        else:
            sport = random.randint(0, 65535)
            dport = random.randint(0, 65535)
            ip_src = "1.1.1.1"

            pkt = simple_tcp_packet(
                                eth_dst=self.router_mac,
                                eth_src=src_mac,
                                ip_src=ip_src,
                                ip_dst=self.ip_dst,
                                ip_tos = tos,
                                tcp_sport=sport,
                                tcp_dport=dport,
                                ip_ttl=64)
            exp_pkt = simple_tcp_packet(
                                eth_src=self.router_mac,
                                ip_src=ip_src,
                                ip_dst=self.ip_dst,
                                ip_tos = tos,
                                tcp_sport=sport,
                                tcp_dport=dport,
                                ip_ttl=63)
            masked_exp_pkt = Mask(exp_pkt)
            masked_exp_pkt.set_do_not_care_scapy(scapy.Ether, "dst")

            send_packet(self, self.port_src, pkt, self.pkt_count)

        if self.wd_action == 'drop':
            return verify_no_packet_any(self, masked_exp_pkt, dst_port_list)
        elif self.wd_action == 'forward':
            return verify_packet_any_port(self, masked_exp_pkt, dst_port_list)
示例#25
0
class FastReloadTest(BaseTest):
    TIMEOUT = 0.5

    def __init__(self):
        BaseTest.__init__(self)
        self.fails = {}
        self.info = {}
        self.cli_info = {}
        self.logs_info = {}
        self.log_fp = open('/tmp/fast-reboot.log', 'w')
        self.test_params = testutils.test_params_get()
        self.check_param('verbose', False, required=False)
        self.check_param('dut_username', '', required=True)
        self.check_param('dut_hostname', '', required=True)
        self.check_param('fast_reboot_limit', 30, required=False)
        self.check_param('graceful_limit', 120, required=False)
        self.check_param('portchannel_ports_file', '', required=True)
        self.check_param('vlan_ports_file', '', required=True)
        self.check_param('ports_file', '', required=True)
        self.check_param('dut_mac', '', required=True)
        self.check_param('default_ip_range', '', required=True)
        self.check_param('vlan_ip_range', '', required=True)
        self.check_param('lo_prefix', '10.1.0.32/32', required=False)
        self.check_param('lo_v6_prefix', 'fc00:1::/64', required=False)
        self.check_param('arista_vms', [], required=True)
        self.check_param('min_bgp_gr_timeout', 15, required=False)

        # Default settings
        self.nr_pc_pkts = 100
        self.nr_tests = 3
        self.reboot_delay = 10
        self.task_timeout = 300  # Wait up to 5 minutes for tasks to complete
        self.max_nr_vl_pkts = 500  # FIXME: should be 1000.
        # But ptf is not fast enough + swss is slow for FDB and ARP entries insertions
        self.timeout_thr = None

        return

    def read_json(self, name):
        with open(self.test_params[name]) as fp:
            content = json.load(fp)

        return content

    def read_port_indices(self):
        self.port_indices = self.read_json('ports_file')

        return

    def read_portchannel_ports(self):
        content = self.read_json('portchannel_ports_file')
        pc_ifaces = []
        for pc in content.values():
            pc_ifaces.extend(
                [self.port_indices[member] for member in pc['members']])

        return pc_ifaces

    def read_vlan_ports(self):
        content = self.read_json('vlan_ports_file')
        if len(content) > 1:
            raise "Too many vlans"
        return [
            self.port_indices[ifname]
            for ifname in content.values()[0]['members']
        ]

    def check_param(self, param, default, required=False):
        if param not in self.test_params:
            if required:
                raise Exception("Test parameter '%s' is required" % param)
            self.test_params[param] = default

    def random_ip(self, ip):
        net_addr, mask = ip.split('/')
        n_hosts = 2**(32 - int(mask))
        random_host = random.randint(2, n_hosts - 2)
        return self.host_ip(ip, random_host)

    def host_ip(self, net_ip, host_number):
        src_addr, mask = net_ip.split('/')
        n_hosts = 2**(32 - int(mask))
        if host_number > (n_hosts - 2):
            raise Exception(
                "host number %d is greater than number of hosts %d in the network %s"
                % (host_number, n_hosts - 2, net_ip))
        src_addr_n = struct.unpack(">I", socket.inet_aton(src_addr))[0]
        net_addr_n = src_addr_n & (2**32 - n_hosts)
        host_addr_n = net_addr_n + host_number
        host_ip = socket.inet_ntoa(struct.pack(">I", host_addr_n))

        return host_ip

    def random_port(self, ports):
        return random.choice(ports)

    def log(self, message, verbose=False):
        current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        if verbose and self.test_params['verbose'] or not verbose:
            print "%s : %s" % (current_time, message)
        self.log_fp.write("%s : %s\n" % (current_time, message))

    def timeout(self, seconds, message):
        def timeout_exception(self, message):
            self.log('Timeout is reached: %s' % message)
            self.tearDown()
            os.kill(os.getpid(), signal.SIGINT)

        if self.timeout_thr is None:
            self.timeout_thr = threading.Timer(seconds,
                                               timeout_exception,
                                               args=(self, message))
            self.timeout_thr.start()
        else:
            raise Exception("Timeout already set")

    def cancel_timeout(self):
        if self.timeout_thr is not None:
            self.timeout_thr.cancel()
            self.timeout_thr = None

    def setUp(self):
        self.read_port_indices()
        self.portchannel_ports = self.read_portchannel_ports()
        vlan_ip_range = self.test_params['vlan_ip_range']
        self.vlan_ports = self.read_vlan_ports()

        self.limit = datetime.timedelta(
            seconds=self.test_params['fast_reboot_limit'])
        self.dut_ssh = self.test_params[
            'dut_username'] + '@' + self.test_params['dut_hostname']
        self.dut_mac = self.test_params['dut_mac']
        #
        self.generate_from_t1()
        self.generate_from_vlan()

        self.log("Test params:")
        self.log("DUT ssh: %s" % self.dut_ssh)
        self.log("DUT fast-reboot limit: %s" % self.limit)
        self.log("DUT mac address: %s" % self.dut_mac)

        self.log("From server src addr: %s" % self.from_server_src_addr)
        self.log("From server src port: %s" % self.from_server_src_port)
        self.log("From server dst addr: %s" % self.from_server_dst_addr)
        self.log("From server dst ports: %s" % self.from_server_dst_ports)
        self.log("From upper layer number of packets: %d" % self.nr_vl_pkts)
        self.log("VMs: %s" % str(self.test_params['arista_vms']))

        self.dataplane = ptf.dataplane_instance
        for p in self.dataplane.ports.values():
            port = p.get_packet_source()
            port.socket.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF,
                                   1000000)

        self.dataplane.flush()
        if config["log_dir"] != None:
            filename = os.path.join(config["log_dir"], str(self)) + ".pcap"
            self.dataplane.start_pcap(filename)

        self.log("Enabling arp_responder")
        self.cmd(["supervisorctl", "start", "arp_responder"])

        return

    def tearDown(self):
        self.log("Disabling arp_responder")
        self.cmd(["supervisorctl", "stop", "arp_responder"])
        if config["log_dir"] != None:
            self.dataplane.stop_pcap()
        self.log_fp.close()

    def get_if(self, iff, cmd):
        s = socket.socket()
        ifreq = ioctl(s, cmd, struct.pack("16s16x", iff))
        s.close()

        return ifreq

    def get_mac(self, iff):
        SIOCGIFHWADDR = 0x8927  # Get hardware address
        return ':'.join([
            '%02x' % ord(char)
            for char in self.get_if(iff, SIOCGIFHWADDR)[18:24]
        ])

    def generate_from_t1(self):
        self.from_t1 = []

        vlan_ip_range = self.test_params['vlan_ip_range']

        _, mask = vlan_ip_range.split('/')
        n_hosts = min(2**(32 - int(mask)) - 3, self.max_nr_vl_pkts)

        dump = defaultdict(dict)
        counter = 0
        for i in xrange(2, n_hosts + 2):
            from_t1_src_addr = self.random_ip(
                self.test_params['default_ip_range'])
            from_t1_src_port = self.random_port(self.portchannel_ports)
            from_t1_dst_addr = self.host_ip(vlan_ip_range, i)
            from_t1_dst_port = self.vlan_ports[i % len(self.vlan_ports)]
            from_t1_if_name = "eth%d" % from_t1_dst_port
            from_t1_if_addr = "%s/%s" % (from_t1_dst_addr,
                                         vlan_ip_range.split('/')[1])
            vlan_mac_hex = '72060001%04x' % counter
            lag_mac_hex = '5c010203%04x' % counter
            mac_addr = ':'.join(lag_mac_hex[i:i + 2]
                                for i in range(0, len(lag_mac_hex), 2))
            packet = simple_tcp_packet(eth_src=mac_addr,
                                       eth_dst=self.dut_mac,
                                       ip_src=from_t1_src_addr,
                                       ip_dst=from_t1_dst_addr,
                                       ip_ttl=255,
                                       tcp_dport=5000)
            self.from_t1.append((from_t1_src_port, str(packet)))
            dump[from_t1_if_name][from_t1_dst_addr] = vlan_mac_hex
            counter += 1

        exp_packet = simple_tcp_packet(
            ip_src="0.0.0.0",
            ip_dst="0.0.0.0",
            tcp_dport=5000,
        )

        self.from_t1_exp_packet = Mask(exp_packet)
        self.from_t1_exp_packet.set_do_not_care_scapy(scapy.Ether, "src")
        self.from_t1_exp_packet.set_do_not_care_scapy(scapy.Ether, "dst")
        self.from_t1_exp_packet.set_do_not_care_scapy(scapy.IP, "src")
        self.from_t1_exp_packet.set_do_not_care_scapy(scapy.IP, "dst")
        self.from_t1_exp_packet.set_do_not_care_scapy(scapy.IP, "chksum")
        self.from_t1_exp_packet.set_do_not_care_scapy(scapy.TCP, "chksum")
        self.from_t1_exp_packet.set_do_not_care_scapy(scapy.IP, "ttl")

        # save data for arp_replay process
        with open("/tmp/from_t1.json", "w") as fp:
            json.dump(dump, fp)

        random_vlan_iface = random.choice(dump.keys())
        self.from_server_src_port = int(random_vlan_iface.replace('eth', ''))
        self.from_server_src_addr = random.choice(
            dump[random_vlan_iface].keys())
        self.from_server_dst_addr = self.random_ip(
            self.test_params['default_ip_range'])
        self.from_server_dst_ports = self.portchannel_ports

        self.nr_vl_pkts = n_hosts

        return

    def generate_from_vlan(self):
        packet = simple_tcp_packet(eth_dst=self.dut_mac,
                                   ip_src=self.from_server_src_addr,
                                   ip_dst=self.from_server_dst_addr,
                                   tcp_dport=5000)
        exp_packet = simple_tcp_packet(
            ip_src=self.from_server_src_addr,
            ip_dst=self.from_server_dst_addr,
            ip_ttl=63,
            tcp_dport=5000,
        )

        self.from_vlan_exp_packet = Mask(exp_packet)
        self.from_vlan_exp_packet.set_do_not_care_scapy(scapy.Ether, "src")
        self.from_vlan_exp_packet.set_do_not_care_scapy(scapy.Ether, "dst")

        self.from_vlan_packet = str(packet)

        return

    def runTest(self):
        self.reboot_start = None
        no_routing_start = None
        no_routing_stop = None

        arista_vms = self.test_params['arista_vms'][1:-1].split(",")
        ssh_targets = []
        for vm in arista_vms:
            if (vm.startswith("'")
                    or vm.startswith('"')) and (vm.endswith("'")
                                                or vm.endswith('"')):
                ssh_targets.append(vm[1:-1])
            else:
                ssh_targets.append(vm)

        self.log("Converted addresses VMs: %s" % str(ssh_targets))

        self.ssh_jobs = []
        for addr in ssh_targets:
            q = Queue.Queue()
            thr = threading.Thread(target=self.peer_state_check,
                                   kwargs={
                                       'ip': addr,
                                       'queue': q
                                   })
            thr.setDaemon(True)
            self.ssh_jobs.append((thr, q))
            thr.start()

        thr = threading.Thread(target=self.background)
        thr.setDaemon(True)
        self.log("Check that device is alive and pinging")
        self.assertTrue(self.check_alive(), 'DUT is not stable')

        self.log("Schedule to reboot the remote switch in %s sec" %
                 self.reboot_delay)
        thr.start()

        self.log("Wait until ASIC stops")
        self.timeout(self.task_timeout,
                     "DUT hasn't stopped in %d seconds" % self.task_timeout)
        no_routing_start, upper_replies = self.check_forwarding_stop()
        self.cancel_timeout()

        self.log("ASIC was stopped, Waiting until it's up. Stop time: %s" %
                 str(no_routing_start))
        self.timeout(
            self.task_timeout,
            "DUT hasn't started to work for %d seconds" % self.task_timeout)
        no_routing_stop, _ = self.check_forwarding_resume()
        self.cancel_timeout()

        # wait until all bgp session are established
        self.log("Wait until bgp routing is up on all devices")
        for _, q in self.ssh_jobs:
            q.put('quit')

        self.timeout(
            self.task_timeout,
            "SSH threads haven't finished for %d seconds" % self.task_timeout)
        while any(thr.is_alive() for thr, _ in self.ssh_jobs):
            for _, q in self.ssh_jobs:
                q.put('go')
            time.sleep(self.TIMEOUT)

        for thr, _ in self.ssh_jobs:
            thr.join()
        self.cancel_timeout()

        self.log("ASIC works again. Start time: %s" % str(no_routing_stop))
        self.log("")

        no_cp_replies = self.extract_no_cpu_replies(upper_replies)

        self.fails['dut'] = set()
        if no_routing_stop - no_routing_start > self.limit:
            self.fails['dut'].add("Downtime must be less then %s seconds. It was %s" \
                    % (self.test_params['fast_reboot_limit'], str(no_routing_stop - no_routing_start)))
        if no_routing_stop - self.reboot_start > datetime.timedelta(
                seconds=self.test_params['graceful_limit']):
            self.fails['dut'].add(
                "Fast-reboot cycle must be less than graceful limit %s seconds"
                % self.test_params['graceful_limit'])
        if no_cp_replies < 0.95 * self.nr_vl_pkts:
            self.fails['dut'].add(
                "Dataplane didn't route to all servers, when control-plane was down: %d vs %d"
                % (no_cp_replies, self.nr_vl_pkts))

        # Generating report
        self.log("=" * 50)
        self.log("Report:")
        self.log("=" * 50)

        self.log("LACP/BGP were down for (extracted from cli):")
        self.log("-" * 50)
        for ip in sorted(self.cli_info.keys()):
            self.log("    %s - lacp: %7.3f (%d) bgp v4: %7.3f (%d) bgp v6: %7.3f (%d)" \
                     % (ip, self.cli_info[ip]['lacp'][1],   self.cli_info[ip]['lacp'][0], \
                            self.cli_info[ip]['bgp_v4'][1], self.cli_info[ip]['bgp_v4'][0],\
                            self.cli_info[ip]['bgp_v6'][1], self.cli_info[ip]['bgp_v6'][0]))

        self.log("-" * 50)
        self.log("Extracted from VM logs:")
        self.log("-" * 50)
        for ip in sorted(self.logs_info.keys()):
            self.log("Extracted log info from %s" % ip)
            for msg in sorted(self.logs_info[ip].keys()):
                if msg != 'error':
                    self.log("    %s : %d" % (msg, self.logs_info[ip][msg]))
                else:
                    self.log("    %s" % self.logs_info[ip][msg])
            self.log("-" * 50)

        self.log("Summary:")
        self.log("-" * 50)
        self.log("Downtime was %s" % str(no_routing_stop - no_routing_start))
        self.log("Reboot time was %s" %
                 str(no_routing_stop - self.reboot_start))

        self.log(
            "How many packets were received back when control plane was down: %d Expected: %d"
            % (no_cp_replies, self.nr_vl_pkts))

        has_info = any(len(info) > 0 for info in self.info.values())
        if has_info:
            self.log("-" * 50)
            self.log("Additional info:")
            self.log("-" * 50)
            for name, info in self.info.items():
                for entry in info:
                    self.log("INFO:%s:%s" % (name, entry))
            self.log("-" * 50)

        is_good = all(len(fails) == 0 for fails in self.fails.values())

        errors = ""
        if not is_good:
            self.log("-" * 50)
            self.log("Fails:")
            self.log("-" * 50)

            errors = "\n\nSomething went wrong. Please check output below:\n\n"
            for name, fails in self.fails.items():
                for fail in fails:
                    self.log("FAILED:%s:%s" % (name, fail))
                    errors += "FAILED:%s:%s\n" % (name, fail)

        self.log("=" * 50)

        self.assertTrue(is_good, errors)

    def extract_no_cpu_replies(self, arr):
        """
      This function tries to extract number of replies from dataplane, when control plane is non working
      """
        # remove all tail zero values
        non_zero = filter(lambda x: x > 0, arr)

        # check that last value is different from previos
        if len(non_zero) > 1 and non_zero[-1] < non_zero[-2]:
            return non_zero[-2]
        else:
            return non_zero[-1]

    def background(self):
        time.sleep(self.reboot_delay)

        self.log("Rebooting remote side")
        self.reboot_start = datetime.datetime.now()
        stdout, stderr, return_code = self.cmd([
            "ssh", "-oStrictHostKeyChecking=no", self.dut_ssh,
            "sudo fast-reboot"
        ])
        if stdout != []:
            self.log("stdout from fast-reboot: %s" % str(stdout))
        if stderr != []:
            self.log("stderr from fast-reboot: %s" % str(stderr))
        self.log("return code from fast-reboot: %s" % str(return_code))

        return

    def cmd(self, cmds):
        process = subprocess.Popen(cmds,
                                   shell=False,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE)
        stdout, stderr = process.communicate()
        return_code = process.returncode

        return stdout, stderr, return_code

    def peer_state_check(self, ip, queue):
        ssh = Arista(ip, queue, self.test_params)
        self.fails[ip], self.info[ip], self.cli_info[ip], self.logs_info[
            ip] = ssh.run()

    def check_forwarding_stop(self):
        return self.iteration(True)

    def check_forwarding_resume(self):
        return self.iteration(False)

    def iteration(self, is_stop):
        recorded_time = None
        counter = self.nr_tests
        nr_from_upper_array = []
        while True:
            success, nr_from_upper = self.ping_iteration()
            nr_from_upper_array.append(nr_from_upper)
            for _, q in self.ssh_jobs:
                q.put('go')
            if success and is_stop or not success and not is_stop:
                self.log("Base state", True)
                recorded_time = None
            else:
                self.log("Changed state", True)
                if recorded_time is None:
                    recorded_time = datetime.datetime.now()
                if counter == 0:
                    break
                else:
                    counter -= 1

        return recorded_time, nr_from_upper_array

    def ping_iteration(self):
        replies_from_servers = self.pingFromServers()
        if replies_from_servers > 0:
            replies_from_upper = self.pingFromUpperTier()
        else:
            replies_from_upper = 0
        return replies_from_servers > 0 and replies_from_upper > 0, replies_from_upper

    def check_alive(self):
        # This function checks that DUT routes the packets in the both directions.
        #
        # Sometimes first attempt failes because ARP responses to DUT are not so fast.
        # But after this the function expects to see steady "replies".
        # If the function sees that there is an issue with the dataplane after we saw
        # successful replies it considers that the DUT is not healthy
        #
        # Sometimes I see that DUT returns more replies then requests.
        # I think this is because of not populated FDB table
        # The function waits while it's done

        was_alive = False
        for counter in range(self.nr_tests * 2):
            success, _ = self.ping_alive()
            if success:
                was_alive = True
            else:
                if was_alive:
                    return False  # Stopped working after it working for sometime?

        # wait, until FDB entries are populated
        for _ in range(self.nr_tests * 10):  # wait for some time
            if not self.ping_alive(
            )[1]:  # until we see that there're no extra replies
                return True

        return False  # we still see extra replies

    def ping_alive(self):
        nr_from_s = self.pingFromServers()
        nr_from_l = self.pingFromUpperTier()

        is_alive = nr_from_s > self.nr_pc_pkts * 0.7 and nr_from_l > self.nr_vl_pkts * 0.7
        is_asic_weird = nr_from_s > self.nr_pc_pkts or nr_from_l > self.nr_vl_pkts
        # we receive more, then sent. not populated FDB table

        return is_alive, is_asic_weird

    def pingFromServers(self):
        for i in xrange(self.nr_pc_pkts):
            testutils.send_packet(self, self.from_server_src_port,
                                  self.from_vlan_packet)

        total_rcv_pkt_cnt = testutils.count_matched_packets_all_ports(
            self,
            self.from_vlan_exp_packet,
            self.from_server_dst_ports,
            timeout=self.TIMEOUT)

        self.log(
            "Send %5d Received %5d servers->t1" %
            (self.nr_pc_pkts, total_rcv_pkt_cnt), True)

        return total_rcv_pkt_cnt

    def pingFromUpperTier(self):
        for entry in self.from_t1:
            testutils.send_packet(self, *entry)

        total_rcv_pkt_cnt = testutils.count_matched_packets_all_ports(
            self,
            self.from_t1_exp_packet,
            self.vlan_ports,
            timeout=self.TIMEOUT)

        self.log(
            "Send %5d Received %5d t1->servers" %
            (self.nr_vl_pkts, total_rcv_pkt_cnt), True)

        return total_rcv_pkt_cnt
示例#26
0
    def check_icmp_mtu(self, ipv4=True):
        '''
        @summary: Check ICMP/Ping or ICMPv6/Ping6 to DUT works for MAX MTU.
        '''
        src_mac = self.dataplane.get_mac(0, self.src_ptf_port_list[0])
        pktlen = self.pktlen
        if ipv4:
            ip_src = self.src_host_ip
            ip_dst = self.src_router_ip

            pkt = simple_icmp_packet(pktlen=pktlen,
                                eth_dst=self.router_mac,
                                eth_src=src_mac,
                                ip_src=ip_src,
                                ip_dst=ip_dst,
                                ip_ttl=64)

            exp_pkt = simple_icmp_packet(pktlen=pktlen,
                                eth_src=self.router_mac,
                                ip_src=ip_dst,
                                ip_dst=ip_src,
                                icmp_type=0)

            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, "id")
            masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "chksum")
            masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "ttl")
            masked_exp_pkt.set_do_not_care_scapy(scapy.ICMP, "chksum")
        else:
            ip_src = self.src_host_ipv6
            ip_dst = self.src_router_ipv6

            pkt = simple_icmpv6_packet(pktlen=pktlen,
                                eth_dst=self.router_mac,
                                eth_src=src_mac,
                                ipv6_src=ip_src,
                                ipv6_dst=ip_dst,
                                icmp_type=128,
                                ipv6_hlim=64)

            exp_pkt = simple_icmpv6_packet(pktlen=pktlen,
                                eth_src=self.router_mac,
                                ipv6_src=ip_dst,
                                ipv6_dst=ip_src,
                                icmp_type=129)

            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.IPv6, "hlim")
            masked_exp_pkt.set_do_not_care_scapy(scapy.IPv6, "tc")
            masked_exp_pkt.set_do_not_care_scapy(scapy.IPv6, "fl")
            masked_exp_pkt.set_do_not_care_scapy(scapy.ICMPv6Unknown, "chksum")

        src_port = self.src_ptf_port_list[0]
        send_packet(self, src_port, pkt)
        logging.info("Sending packet from port " + str(src_port) + " to " + ip_dst)
        dst_port_list = self.src_ptf_port_list

        (matched_index, received) = verify_packet_any_port(self, masked_exp_pkt, dst_port_list)
        
        assert received

        matched_port = dst_port_list[matched_index]
        logging.info("Received packet at " + str(matched_port))

        return
示例#27
0
    def check_ipv6_route(self, hash_key, src_port, dst_port_list):
        '''
        @summary: Check IPv6 route works.
        @param hash_key: hash key to build packet with.
        @param in_port: index of port to use for sending packet to switch
        @param dst_port_list: list of ports on which to expect packet to come back from the switch
        @return Boolean
        '''
        ip_src = self.src_ip_interval.get_random_ip(
        ) if hash_key == 'src-ip' else self.src_ip_interval.get_first_ip()
        ip_dst = self.dst_ip_interval.get_random_ip(
        ) if hash_key == 'dst-ip' else self.dst_ip_interval.get_first_ip()

        sport = random.randint(0, 65535) if hash_key == 'src-port' else 1234
        dport = random.randint(0, 65535) if hash_key == 'dst-port' else 80

        src_mac = (self.base_mac[:-5] + "%02x" % random.randint(0, 255) + ":" + "%02x" % random.randint(0, 255)) \
            if hash_key == 'src-mac' else self.base_mac
        router_mac = self.ptf_test_port_map[str(src_port)]['target_mac']

        vlan_id = random.choice(self.vlan_ids) if hash_key == 'vlan-id' else 0
        ip_proto = self._get_ip_proto(
            ipv6=True) if hash_key == "ip-proto" else None

        pkt = simple_tcpv6_packet(
            pktlen=100 if vlan_id == 0 else 104,
            eth_dst=router_mac,
            eth_src=src_mac,
            dl_vlan_enable=False if vlan_id == 0 else True,
            vlan_vid=vlan_id,
            vlan_pcp=0,
            ipv6_dst=ip_dst,
            ipv6_src=ip_src,
            tcp_sport=sport,
            tcp_dport=dport,
            ipv6_hlim=64)
        exp_pkt = simple_tcpv6_packet(ipv6_dst=ip_dst,
                                      ipv6_src=ip_src,
                                      tcp_sport=sport,
                                      tcp_dport=dport,
                                      ipv6_hlim=63)

        if hash_key == 'ip-proto':
            pkt['IPv6'].nh = ip_proto
            exp_pkt['IPv6'].nh = ip_proto

        masked_exp_pkt = Mask(exp_pkt)
        masked_exp_pkt.set_do_not_care_scapy(scapy.Ether, "dst")
        # mask the chksum also if masking the ttl
        if self.ignore_ttl:
            masked_exp_pkt.set_do_not_care_scapy(scapy.IPv6, "hlim")
            masked_exp_pkt.set_do_not_care_scapy(scapy.IPv6, "chksum")
            masked_exp_pkt.set_do_not_care_scapy(scapy.TCP, "chksum")
        masked_exp_pkt.set_do_not_care_scapy(scapy.Ether, "src")

        send_packet(self, src_port, pkt)
        logging.info('Sent Ether(src={}, dst={})/IPv6(src={}, dst={})/TCP(sport={}, dport={} on port {})'\
            .format(pkt.src,
                    pkt.dst,
                    pkt['IPv6'].src,
                    pkt['IPv6'].dst,
                    sport,
                    dport,
                    src_port))
        logging.info('Expect Ether(src={}, dst={})/IPv6(src={}, dst={})/TCP(sport={}, dport={})'\
            .format('any',
                    'any',
                    ip_src,
                    ip_dst,
                    sport,
                    dport))

        rcvd_port, rcvd_pkt = verify_packet_any_port(self, masked_exp_pkt,
                                                     dst_port_list)
        exp_src_mac = self.router_macs[self.ptf_test_port_map[str(
            dst_port_list[rcvd_port])]['target_dut']]
        actual_src_mac = Ether(rcvd_pkt).src
        if exp_src_mac != actual_src_mac:
            raise Exception(
                "Pkt sent from {} to {} on port {} was rcvd pkt on {} which is one of the expected ports, "
                "but the src mac doesn't match, expected {}, got {}".format(
                    ip_src, ip_dst, src_port, dst_port_list[rcvd_port],
                    exp_src_mac, actual_src_mac))
        return (rcvd_port, rcvd_pkt)
示例#28
0
    def check_icmp_mtu(self):
        '''
        @summary: Check ICMP/Ping to DUT works for MAX MTU.
        '''
        ip_src = "10.0.0.1"
        ip_dst = "10.0.0.0"
        src_mac = self.dataplane.get_mac(0, 0)

        pktlen = (self.DEFAULT_PACKET_LEN - self.ICMP_HDR_LEN)

        pkt = simple_icmp_packet(pktlen=pktlen,
                                 eth_dst=self.router_mac,
                                 eth_src=src_mac,
                                 ip_src=ip_src,
                                 ip_dst=ip_dst,
                                 ip_ttl=64)

        exp_pkt = simple_icmp_packet(pktlen=pktlen,
                                     eth_src=self.router_mac,
                                     ip_src=ip_dst,
                                     ip_dst=ip_src,
                                     icmp_type=0)

        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, "id")
        masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "chksum")
        masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "ttl")
        masked_exp_pkt.set_do_not_care_scapy(scapy.ICMP, "chksum")

        src_port = 0
        send_packet(self, src_port, pkt)
        logging.info("Sending packet from port " + str(src_port) + " to " +
                     ip_dst)
        dst_port_list = [0, 1]

        (matched_index,
         received) = verify_packet_any_port(self, masked_exp_pkt,
                                            dst_port_list)

        assert received

        matched_port = dst_port_list[matched_index]
        logging.info("Received packet at " + str(matched_port))

        return
示例#29
0
def build_syn_pkt(local_addr, peer_addr):
    pkt = testutils.simple_tcp_packet(pktlen=54,
                                      ip_src=local_addr,
                                      ip_dst=peer_addr,
                                      tcp_dport=BGP_PORT,
                                      tcp_flags="S")
    exp_packet = Mask(pkt)
    exp_packet.set_do_not_care_scapy(scapy.Ether, "dst")
    exp_packet.set_do_not_care_scapy(scapy.Ether, "src")

    exp_packet.set_do_not_care_scapy(scapy.IP, "version")
    exp_packet.set_do_not_care_scapy(scapy.IP, "ihl")
    exp_packet.set_do_not_care_scapy(scapy.IP, "tos")
    exp_packet.set_do_not_care_scapy(scapy.IP, "len")
    exp_packet.set_do_not_care_scapy(scapy.IP, "flags")
    exp_packet.set_do_not_care_scapy(scapy.IP, "id")
    exp_packet.set_do_not_care_scapy(scapy.IP, "frag")
    exp_packet.set_do_not_care_scapy(scapy.IP, "ttl")
    exp_packet.set_do_not_care_scapy(scapy.IP, "chksum")
    exp_packet.set_do_not_care_scapy(scapy.IP, "options")

    exp_packet.set_do_not_care_scapy(scapy.TCP, "sport")
    exp_packet.set_do_not_care_scapy(scapy.TCP, "seq")
    exp_packet.set_do_not_care_scapy(scapy.TCP, "ack")
    exp_packet.set_do_not_care_scapy(scapy.TCP, "reserved")
    exp_packet.set_do_not_care_scapy(scapy.TCP, "dataofs")
    exp_packet.set_do_not_care_scapy(scapy.TCP, "window")
    exp_packet.set_do_not_care_scapy(scapy.TCP, "chksum")
    exp_packet.set_do_not_care_scapy(scapy.TCP, "urgptr")

    exp_packet.set_ignore_extra_bytes()
    return exp_packet
示例#30
0
    def check_ipv6_route(self, src_port, dst_ip_addr, dst_port_list):
        '''
        @summary: Check IPv6 route works.
        @param source_port_index: index of port to use for sending packet to switch
        @param dest_ip_addr: destination IP to build packet with.
        @param dst_port_list: list of ports on which to expect packet to come back from the switch
        @return Boolean
        '''
        sport = random.randint(0, 65535)
        dport = random.randint(0, 65535)
        ip_src = '2000:0030::1'
        ip_dst = dst_ip_addr
        src_mac = self.dataplane.get_mac(0, src_port)

        router_mac = self.ptf_test_port_map[str(src_port)]['target_mac']

        pkt = simple_tcpv6_packet(pktlen=self.pktlen,
                                  eth_dst=router_mac,
                                  eth_src=src_mac,
                                  ipv6_dst=ip_dst,
                                  ipv6_src=ip_src,
                                  tcp_sport=sport,
                                  tcp_dport=dport,
                                  ipv6_hlim=self.ttl,
                                  dl_vlan_enable=self.src_vid is not None,
                                  vlan_vid=self.src_vid or 0)
        exp_pkt = simple_tcpv6_packet(pktlen=self.pktlen,
                                      ipv6_dst=ip_dst,
                                      ipv6_src=ip_src,
                                      tcp_sport=sport,
                                      tcp_dport=dport,
                                      ipv6_hlim=max(self.ttl - 1, 0),
                                      dl_vlan_enable=self.dst_vid is not None,
                                      vlan_vid=self.dst_vid or 0)
        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.Ether, "src")

        # mask the chksum also if masking the ttl
        if self.ignore_ttl:
            masked_exp_pkt.set_do_not_care_scapy(scapy.IPv6, "hlim")
            masked_exp_pkt.set_do_not_care_scapy(scapy.IPv6, "chksum")
            masked_exp_pkt.set_do_not_care_scapy(scapy.TCP, "chksum")

        send_packet(self, src_port, pkt)
        logging.info('Sent Ether(src={}, dst={})/IPv6(src={}, dst={})/TCP(sport={}, dport={}) on port {}'\
            .format(pkt.src,
                    pkt.dst,
                    pkt['IPv6'].src,
                    pkt['IPv6'].dst,
                    sport,
                    dport,
                    src_port))
        logging.info('Expect Ether(src={}, dst={})/IPv6(src={}, dst={})/TCP(sport={}, dport={})'\
            .format('any',
                    'any',
                    ip_src,
                    ip_dst,
                    sport,
                    dport))

        if self.pkt_action == self.ACTION_FWD:
            rcvd_port, rcvd_pkt = verify_packet_any_port(
                self, masked_exp_pkt, dst_port_list)
            exp_src_mac = self.router_macs[self.ptf_test_port_map[str(
                dst_port_list[rcvd_port])]['target_dut']]
            actual_src_mac = Ether(rcvd_pkt).src
            if actual_src_mac != exp_src_mac:
                raise Exception(
                    "Pkt sent from {} to {} on port {} was rcvd pkt on {} which is one of the expected ports, "
                    "but the src mac doesn't match, expected {}, got {}".
                    format(ip_src, ip_dst, src_port, dst_port_list[rcvd_port],
                           exp_src_mac, actual_src_mac))
            return (rcvd_port, rcvd_pkt)
        elif self.pkt_action == self.ACTION_DROP:
            return verify_no_packet_any(self, masked_exp_pkt, dst_port_list)
示例#31
0
    def FromServer(self, test):
        rv = True
        try:
            pkt_len = self.DEFAULT_PKT_LEN
            if test['vlan'] != 0:
                tagged = True
                pkt_len += 4
            else:
                tagged = False

            vni = int(test['vni'])
            if 'dst_vni' in test:
                vni = int(test['dst_vni'])

            pkt = simple_tcp_packet(pktlen=pkt_len,
                                    eth_dst=self.dut_mac,
                                    eth_src=self.ptf_mac_addrs['eth%d' %
                                                               test['port']],
                                    dl_vlan_enable=tagged,
                                    vlan_vid=test['vlan'],
                                    ip_dst=test['dst'],
                                    ip_src=test['src'],
                                    ip_id=105,
                                    ip_ttl=64)
            exp_pkt = simple_tcp_packet(eth_dst=test['mac'],
                                        eth_src=self.dut_mac,
                                        ip_dst=test['dst'],
                                        ip_src=test['src'],
                                        ip_id=105,
                                        ip_ttl=63)
            udp_sport = 1234  # Use entropy_hash(pkt)
            udp_dport = self.vxlan_port
            if isinstance(ip_address(test['host']), ipaddress.IPv4Address):
                encap_pkt = simple_vxlan_packet(eth_src=self.dut_mac,
                                                eth_dst=self.random_mac,
                                                ip_id=0,
                                                ip_src=self.loopback_ipv4,
                                                ip_dst=test['host'],
                                                ip_ttl=128,
                                                udp_sport=udp_sport,
                                                udp_dport=udp_dport,
                                                with_udp_chksum=False,
                                                vxlan_vni=vni,
                                                inner_frame=exp_pkt)
                encap_pkt[IP].flags = 0x2
            elif isinstance(ip_address(test['host']), ipaddress.IPv6Address):
                encap_pkt = simple_vxlanv6_packet(eth_src=self.dut_mac,
                                                  eth_dst=self.random_mac,
                                                  ipv6_src=self.loopback_ipv6,
                                                  ipv6_dst=test['host'],
                                                  udp_sport=udp_sport,
                                                  udp_dport=udp_dport,
                                                  with_udp_chksum=False,
                                                  vxlan_vni=vni,
                                                  inner_frame=exp_pkt)
            else:
                raise Exception("Found invalid IP address in test")
            send_packet(self, test['port'], str(pkt))

            masked_exp_pkt = Mask(encap_pkt)
            masked_exp_pkt.set_do_not_care_scapy(scapy.Ether, "src")
            masked_exp_pkt.set_do_not_care_scapy(scapy.Ether, "dst")
            if isinstance(ip_address(test['host']), ipaddress.IPv4Address):
                masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "ttl")
            else:
                masked_exp_pkt.set_do_not_care_scapy(scapy.IPv6, "hlim")
            masked_exp_pkt.set_do_not_care_scapy(scapy.UDP, "sport")

            log_str = "Sending packet from port " + str(
                'eth%d' % test['port']) + " to " + test['dst']
            logging.info(log_str)

            if not self.routes_removed:
                verify_packet_any_port(self, masked_exp_pkt, self.net_ports)
            else:
                verify_no_packet_any(self, masked_exp_pkt, self.net_ports)

        finally:
            print
    def mask_off_dont_care_ra_packet_fields(self, rapkt):
        masked_rapkt = Mask(rapkt)
        masked_rapkt.set_ignore_extra_bytes()

        masked_rapkt.set_do_not_care_scapy(IPv6, "tc")
        masked_rapkt.set_do_not_care_scapy(IPv6, "fl")
        masked_rapkt.set_do_not_care_scapy(IPv6, "plen")
        masked_rapkt.set_do_not_care_scapy(IPv6, "nh")

        masked_rapkt.set_do_not_care_scapy(RA, "cksum")
        masked_rapkt.set_do_not_care_scapy(RA, "chlim")
        masked_rapkt.set_do_not_care_scapy(RA, "H")
        masked_rapkt.set_do_not_care_scapy(RA, "prf")
        masked_rapkt.set_do_not_care_scapy(RA, "P")
        masked_rapkt.set_do_not_care_scapy(RA, "res")
        masked_rapkt.set_do_not_care_scapy(RA, "routerlifetime")
        masked_rapkt.set_do_not_care_scapy(RA, "reachabletime")
        masked_rapkt.set_do_not_care_scapy(RA, "retranstimer")

        masked_rapkt.set_do_not_care_scapy(PrefixInfo, "prefixlen")
        masked_rapkt.set_do_not_care_scapy(PrefixInfo, "L")
        masked_rapkt.set_do_not_care_scapy(PrefixInfo, "A")
        masked_rapkt.set_do_not_care_scapy(PrefixInfo, "R")
        masked_rapkt.set_do_not_care_scapy(PrefixInfo, "res1")
        masked_rapkt.set_do_not_care_scapy(PrefixInfo, "validlifetime")
        masked_rapkt.set_do_not_care_scapy(PrefixInfo, "preferredlifetime")
        masked_rapkt.set_do_not_care_scapy(PrefixInfo, "res2")
        masked_rapkt.set_do_not_care_scapy(PrefixInfo, "prefix")

        return masked_rapkt
示例#33
0
    def verify_ack_received(self):
        dhcp_ack = self.create_dhcp_ack_relayed_packet()

        masked_ack = Mask(dhcp_ack)

        masked_ack.set_do_not_care_scapy(scapy.IP, "version")
        masked_ack.set_do_not_care_scapy(scapy.IP, "ihl")
        masked_ack.set_do_not_care_scapy(scapy.IP, "tos")
        masked_ack.set_do_not_care_scapy(scapy.IP, "len")
        masked_ack.set_do_not_care_scapy(scapy.IP, "id")
        masked_ack.set_do_not_care_scapy(scapy.IP, "flags")
        masked_ack.set_do_not_care_scapy(scapy.IP, "frag")
        masked_ack.set_do_not_care_scapy(scapy.IP, "ttl")
        masked_ack.set_do_not_care_scapy(scapy.IP, "proto")
        masked_ack.set_do_not_care_scapy(scapy.IP, "chksum")
        masked_ack.set_do_not_care_scapy(scapy.IP, "options")

        masked_ack.set_do_not_care_scapy(scapy.UDP, "len")
        masked_ack.set_do_not_care_scapy(scapy.UDP, "chksum")

        masked_ack.set_do_not_care_scapy(scapy.BOOTP, "sname")
        masked_ack.set_do_not_care_scapy(scapy.BOOTP, "file")

        masked_ack.set_do_not_care_scapy(scapy.DHCP, "lease_time")

        # NOTE: verify_packet() will fail for us via an assert, so no need to check a return value here
        testutils.verify_packet(self, masked_ack, self.client_port_index)
示例#34
0
文件: saimirror.py 项目: rspolyak/SAI
    def runTest(self):
        print
        switch_init(self.client)
        port1 = port_list[0]
        port2 = port_list[1]
        port3 = port_list[2]
        mac3='00:00:00:00:00:33'
        mac2='00:00:00:00:00:22'
        monitor_port=port1
        source_port=port2
        mirror_type=SAI_MIRROR_TYPE_ENHANCED_REMOTE
        vlan=0x2
        vlan_tpid=0x8100
        vlan_pri=0x6
        src_mac='00:00:00:00:11:22'
        dst_mac='00:00:00:00:11:33'
        encap_type=SAI_MIRROR_L3_GRE_TUNNEL
        ip_version=0x4
        tos=0x3c
        ttl=0xf0
        gre_type=0x88be
        src_ip='17.18.19.0'
        dst_ip='33.19.20.0'
        addr_family=0

        sai_thrift_create_fdb(self.client, 3, mac3, port3, 1)
        sai_thrift_create_fdb(self.client, 3, mac2, port2, 1)

        # Put ports under test in VLAN 3
        self.client.sai_thrift_create_vlan(3)
        vlan_member1 = sai_thrift_create_vlan_member(self.client, 3, port1, SAI_VLAN_PORT_TAGGED)
        vlan_member1a = sai_thrift_create_vlan_member(self.client, 1, port1, SAI_VLAN_PORT_TAGGED)
        vlan_member2 = sai_thrift_create_vlan_member(self.client, 3, port2, SAI_VLAN_PORT_TAGGED)
        vlan_member2a = sai_thrift_create_vlan_member(self.client, 1, port2, SAI_VLAN_PORT_TAGGED)
        vlan_member3 = sai_thrift_create_vlan_member(self.client, 3, port3, SAI_VLAN_PORT_TAGGED)
        vlan_member3a = sai_thrift_create_vlan_member(self.client, 1, port3, SAI_VLAN_PORT_TAGGED)

        # Remove ports from default VLAN
        self.client.sai_thrift_remove_vlan_member(vlan_member1a)
        self.client.sai_thrift_remove_vlan_member(vlan_member2a)
        self.client.sai_thrift_remove_vlan_member(vlan_member3a)

        # Set PVID
        attr_value = sai_thrift_attribute_value_t(u16=3)
        attr = sai_thrift_attribute_t(id=SAI_PORT_ATTR_PORT_VLAN_ID, value=attr_value)
        self.client.sai_thrift_set_port_attribute(port1, attr)
        self.client.sai_thrift_set_port_attribute(port2, attr)
        self.client.sai_thrift_set_port_attribute(port3, attr)

        erspanid=sai_thrift_create_mirror_session(self.client,mirror_type=mirror_type,port=monitor_port,vlan=vlan,vlan_priority=vlan_pri,vlan_tpid=vlan_tpid,src_mac=src_mac,dst_mac=dst_mac,addr_family=addr_family,src_ip=src_ip,dst_ip=dst_ip,encap_type=encap_type,protocol=ip_version,ttl=ttl,tos=tos,gre_type=gre_type)

        #attrb_value = sai_thrift_attribute_value_t(oid=erspanid)
        attrb_value = sai_thrift_attribute_value_t(objlist=sai_thrift_object_list_t(count=1,object_id_list=[erspanid]))

        attr = sai_thrift_attribute_t(id=SAI_PORT_ATTR_INGRESS_MIRROR_SESSION, value=attrb_value)
        self.client.sai_thrift_set_port_attribute(port2, attr)


        attr = sai_thrift_attribute_t(id=SAI_PORT_ATTR_EGRESS_MIRROR_SESSION, value=attrb_value)
        self.client.sai_thrift_set_port_attribute(port2, attr)

        pkt = simple_tcp_packet(eth_dst='00:00:00:00:00:33',
                                eth_src='00:22:22:22:22:22',
                                ip_dst='10.0.0.1',
                                dl_vlan_enable=True,
                                vlan_vid=3,
                                ip_id=101,
                                ip_ttl=64)

        pkt2 = simple_tcp_packet(eth_dst='00:00:00:00:00:22',
                                eth_src='00:33:33:33:33:33',
                                dl_vlan_enable=True,
                                vlan_vid=3,
                                ip_dst='10.0.0.1',
                                ip_id=101,
                                ip_ttl=64)

        pkt3 = simple_tcp_packet(eth_dst='00:00:00:00:00:22',
                                eth_src='00:33:33:33:33:33',
                                dl_vlan_enable=True,
                                vlan_vid=3,
                                ip_dst='10.0.0.1',
                                ip_id=101,
                                ip_ttl=64)

        exp_pkt1= simple_gre_packet(pktlen=142,
                                    eth_dst='00:00:00:00:11:33',
                                    eth_src='00:00:00:00:11:22',
                                    dl_vlan_enable=True,
                                    vlan_vid=2,
                                    ip_id=0,
                                    ip_ttl=240,
                                    ip_tos=0x3c,
                                    ip_ihl=5,
                                    ip_src='17.18.19.0',
                                    ip_dst='33.19.20.0',
                                    inner_frame=pkt
                                    )

        exp_pkt2= simple_gre_packet(pktlen=142,
                                    eth_dst='00:00:00:00:11:33',
                                    eth_src='00:00:00:00:11:22',
                                    dl_vlan_enable=True,
                                    vlan_vid=2,
                                    ip_id=0,
                                    ip_ttl=240,
                                    ip_tos=0x3c,
                                    ip_ihl=5,
                                    ip_src='17.18.19.0',
                                    ip_dst='33.19.20.0',
                                    inner_frame=pkt3
                                    )
        m1=Mask(exp_pkt1)
        m2=Mask(exp_pkt2)
        m1.set_do_not_care_scapy(ptf.packet.IP,'tos')
        m1.set_do_not_care_scapy(ptf.packet.IP,'frag')
        m1.set_do_not_care_scapy(ptf.packet.IP,'flags')
        m1.set_do_not_care_scapy(ptf.packet.IP,'chksum')
        m1.set_do_not_care_scapy(ptf.packet.GRE,'proto')
        m2.set_do_not_care_scapy(ptf.packet.IP,'tos')
        m2.set_do_not_care_scapy(ptf.packet.IP,'frag')
        m2.set_do_not_care_scapy(ptf.packet.IP,'flags')
        m2.set_do_not_care_scapy(ptf.packet.IP,'chksum')
        m2.set_do_not_care_scapy(ptf.packet.GRE,'proto')
        n=Mask(pkt2)
        n.set_do_not_care_scapy(ptf.packet.IP,'len')
        n.set_do_not_care_scapy(ptf.packet.IP,'chksum')

        try:
            # in tuple: 0 is device number, 2 is port number
            # this tuple uniquely identifies a port
            # for ingress mirroring
            print "Checking INGRESS ERSPAN Mirroring"
            print "Sending packet port 2 -> port 3 (00:22:22:22:22:22 -> 00:00:00:00:00:33)"
            send_packet(self, 1, pkt)
            verify_each_packet_on_each_port(self, [m1,pkt], ports=[0,2])#FIXME need to properly implement
            # for egress mirroring
            print "Checking EGRESS ERSPAN Mirroring"
            print "Sending packet port 3 -> port 2 (00:33:33:33:33:33 -> 00:00:00:00:00:22)"
            send_packet(self, 2, pkt2)
            verify_each_packet_on_each_port(self, [pkt2,m2], ports=[1,0])#FIXME need to properly implement
        finally:
            sai_thrift_delete_fdb(self.client, 3, mac2, port2)
            sai_thrift_delete_fdb(self.client, 3, mac3, port3)

            # Remove ports from mirror destination
            attrb_value = sai_thrift_attribute_value_t(objlist=sai_thrift_object_list_t(count=0,object_id_list=[erspanid]))
            attr = sai_thrift_attribute_t(id=SAI_PORT_ATTR_INGRESS_MIRROR_SESSION, value=attrb_value)
            self.client.sai_thrift_set_port_attribute(port2, attr)
            attr = sai_thrift_attribute_t(id=SAI_PORT_ATTR_EGRESS_MIRROR_SESSION, value=attrb_value)
            self.client.sai_thrift_set_port_attribute(port2, attr)

            # Now you can remove destination
            self.client.sai_thrift_remove_mirror_session(erspanid)

            # Remove ports from VLAN 3
            self.client.sai_thrift_remove_vlan_member(vlan_member1)
            self.client.sai_thrift_remove_vlan_member(vlan_member2)
            self.client.sai_thrift_remove_vlan_member(vlan_member3)
            self.client.sai_thrift_delete_vlan(3)

            # Add ports back to default VLAN
            vlan_member1a = sai_thrift_create_vlan_member(self.client, 1, port1, SAI_VLAN_PORT_UNTAGGED)
            vlan_member2a = sai_thrift_create_vlan_member(self.client, 1, port2, SAI_VLAN_PORT_UNTAGGED)
            vlan_member3a = sai_thrift_create_vlan_member(self.client, 1, port3, SAI_VLAN_PORT_UNTAGGED)

            attr_value = sai_thrift_attribute_value_t(u16=1)
            attr = sai_thrift_attribute_t(id=SAI_PORT_ATTR_PORT_VLAN_ID, value=attr_value)
            self.client.sai_thrift_set_port_attribute(port1, attr)
            self.client.sai_thrift_set_port_attribute(port2, attr)
            self.client.sai_thrift_set_port_attribute(port3, attr)