예제 #1
0
파일: test.py 프로젝트: unilinu/MicroP4
    def runTest(self):
        ig_ports = [swports[1], swports[2]]
        eg_ports = [swports[2], swports[1]]
        ip2 = "2001:0000:0000::0000:0000:0002"
        ip1 = "2001:0000:0000::0000:0000:0001"
        mac2 = "00:00:00:00:00:02"
        mac1 = "00:00:00:00:00:01"
        # send pkt and verify sent
        pkt = testutils.simple_tcpv6_packet(eth_dst=mac2,
                                            eth_src=mac1,
                                            ipv6_dst=ip2)
        exp_pkt = pkt
        logger.info("Sending packet on port %d", ig_ports[0])
        testutils.send_packet(self, ig_ports[0], str(pkt))

        logger.info("Expecting packet on port %d", eg_ports[0])
        testutils.verify_packets(self, exp_pkt, [eg_ports[0]])

        # send pkt and verify sent
        pkt = testutils.simple_tcpv6_packet(eth_dst=mac1,
                                            eth_src=mac2,
                                            ipv6_dst=ip1)
        exp_pkt = pkt
        logger.info("Sending packet on port %d", ig_ports[1])
        testutils.send_packet(self, ig_ports[1], str(pkt))

        logger.info("Expecting packet on port %d", eg_ports[1])
        testutils.verify_packets(self, exp_pkt, [eg_ports[1]])
예제 #2
0
    def runTest(self):
        pkt = simple_tcpv6_packet(ipv6_src='2001::1', ipv6_dst='2001::2')
        exp_pkt = simple_tcpv6_packet(ipv6_src='2001::2', ipv6_dst='2001::1')

        mask = Mask(exp_pkt)
        mask.set_do_not_care_scapy(TCP, 'chksum')

        send_packet(self, (0, 1), pkt)
        verify_packets(self, mask, device_number=0, ports=[2])
예제 #3
0
def generate_and_verify_traffic(duthost, ptfadapter, ip_dst, expected_ports, ipv6=False):
    if ipv6:
        pkt = testutils.simple_tcpv6_packet(
            eth_dst=duthost.facts["router_mac"],
            eth_src=ptfadapter.dataplane.get_mac(0, 0),
            ipv6_src='2001:db8:85a3::8a2e:370:7334',
            ipv6_dst=ip_dst,
            ipv6_hlim=64,
            tcp_sport=1234,
            tcp_dport=4321)
    else:
        pkt = testutils.simple_tcp_packet(
            eth_dst=duthost.facts["router_mac"],
            eth_src=ptfadapter.dataplane.get_mac(0, 0),
            ip_src='1.1.1.1',
            ip_dst=ip_dst,
            ip_ttl=64,
            tcp_sport=1234,
            tcp_dport=4321)

    exp_pkt = pkt.copy()
    exp_pkt = mask.Mask(exp_pkt)
    exp_pkt.set_do_not_care_scapy(packet.Ether, 'dst')
    exp_pkt.set_do_not_care_scapy(packet.Ether, 'src')
    if ipv6:
        exp_pkt.set_do_not_care_scapy(packet.IPv6, 'hlim')
        exp_pkt.set_do_not_care_scapy(packet.IPv6, 'chksum')
    else:
        exp_pkt.set_do_not_care_scapy(packet.IP, 'ttl')
        exp_pkt.set_do_not_care_scapy(packet.IP, 'chksum')

    testutils.send(ptfadapter, 5, pkt)
    testutils.verify_packet_any_port(ptfadapter, exp_pkt, ports=expected_ports)
예제 #4
0
    def _base_tcpv6_packet(self,
                           ptfadapter,
                           setup,
                           src_ip=DEFAULT_SRC_IP,
                           dst_ip=DEFAULT_DST_IP,
                           next_header=None,
                           dscp=None,
                           sport=2020,
                           dport=8080,
                           flags=0x10):
        pkt = testutils.simple_tcpv6_packet(
            eth_src=ptfadapter.dataplane.get_mac(0, 0),
            eth_dst=setup["router_mac"],
            ipv6_src=src_ip,
            ipv6_dst=dst_ip,
            ipv6_dscp=dscp,
            ipv6_hlim=64,
            tcp_sport=sport,
            tcp_dport=dport,
            tcp_flags=flags,
        )

        if next_header:
            pkt["IPv6"].nh = next_header

        return pkt
예제 #5
0
def test_src_ip_is_multicast_addr(do_test, ptfadapter, duthosts, rand_one_dut_hostname, setup, tx_dut_ports, pkt_fields, ip_addr, ports_info):
    """
    @summary: Create a packet with multicast source IP adress.
    """
    duthost = duthosts[rand_one_dut_hostname]

    ip_src = None

    if ip_addr == "ipv4":
        ip_src = "224.0.0.5"
        pkt = testutils.simple_tcp_packet(
            eth_dst=ports_info["dst_mac"],  # DUT port
            eth_src=ports_info["src_mac"],  # PTF port
            ip_src=ip_src,
            ip_dst=pkt_fields["ipv4_dst"],  # VM source
            tcp_sport=pkt_fields["tcp_sport"],
            tcp_dport=pkt_fields["tcp_dport"])
    elif ip_addr == "ipv6":
        if not pkt_fields["ipv6_dst"]:
            pytest.skip("BGP neighbour with IPv6 addr was not found")
        ip_src = "FF02:AAAA:FEE5::1:3"
        pkt = testutils.simple_tcpv6_packet(
            eth_dst=ports_info["dst_mac"],  # DUT port
            eth_src=ports_info["src_mac"],  # PTF port
            ipv6_src=ip_src,
            ipv6_dst=pkt_fields["ipv6_dst"],  # VM source
            tcp_sport=pkt_fields["tcp_sport"],
            tcp_dport=pkt_fields["tcp_dport"])
    else:
        pytest.fail("Incorrect value specified for 'ip_addr' test parameter. Supported parameters: 'ipv4' and 'ipv6'")

    log_pkt_params(ports_info["dut_iface"], ports_info["dst_mac"], ports_info["src_mac"], pkt_fields["ipv4_dst"], ip_src)

    do_test("L3", pkt, ptfadapter, duthost, ports_info, setup["neighbor_sniff_ports"], tx_dut_ports)
예제 #6
0
    def create_ipv6_inner_pkt_only(self, src_ip, dst_ip, tc, encap=False, hlim=64):
        """Creates an IPv6 only packet for the test
        @param src_ip: source ip
        @param dst_ip: destination ip
        @param tc: traffic class
        @param encap: build encapsulated packet.
                      If @encap is True the return packet would be:
                      IP(@src_ip, @dst_ip, @tc) / IP(dst_ip=4::4, src_ip=3::3) / TCP()
        """

        # no ptf function to build simple ipv6 only packet
        # so use simple_tcpv6_packet function which builds the same packet
        # with TCP header as simple_ip_only_packet but extract away Ethernet

        inner_pkt = simple_tcpv6_packet(ipv6_dst=dst_ip, ipv6_src=src_ip, ipv6_hlim=hlim, ipv6_tc=tc).getlayer(scapy.IPv6)
        if encap:
            inner_pkt2 = self.create_ipv6_inner_pkt_only(self.DEFAULT_INNER2_V6_PKT_SRC_IP,
                                                         self.DEFAULT_INNER2_V6_PKT_DST_IP,
                                                         0)
            inner_pkt = simple_ipv6ip_packet(ipv6_src=src_ip,
                                             ipv6_dst=dst_ip,
                                             ipv6_tc=tc,
                                             ipv6_hlim=hlim,
                                             inner_frame=inner_pkt2).getlayer(scapy.IPv6) # get only the IP layer

        return inner_pkt
예제 #7
0
    def tcp_packet(self, setup, direction, ptfadapter, ip_version, src_ip=None, dst_ip=None, proto=None, sport=0x4321, dport=0x51, flags=None):
        """Generate a TCP packet for testing."""
        src_ip = src_ip or DEFAULT_SRC_IP[ip_version]
        dst_ip = dst_ip or self.get_dst_ip(direction, ip_version)
        if ip_version == "ipv4":
            pkt = testutils.simple_tcp_packet(
                eth_dst=setup["destination_mac"][direction][self.src_port],
                eth_src=ptfadapter.dataplane.get_mac(0, 0),
                ip_dst=dst_ip,
                ip_src=src_ip,
                tcp_sport=sport,
                tcp_dport=dport,
                ip_ttl=64
            )

            if proto:
                pkt["IP"].proto = proto
        else:
            pkt = testutils.simple_tcpv6_packet(
                eth_dst=setup["destination_mac"][direction][self.src_port],
                eth_src=ptfadapter.dataplane.get_mac(0, 0),
                ipv6_dst=dst_ip,
                ipv6_src=src_ip,
                tcp_sport=sport,
                tcp_dport=dport,
                ipv6_hlim=64
            )

            if proto:
                pkt["IPv6"].nh = proto

        if flags:
            pkt["TCP"].flags = flags

        return pkt
예제 #8
0
def test_ip_is_zero_addr(do_test, ptfadapter, setup, tx_dut_ports, pkt_fields,
                         addr_type, addr_direction, ports_info):
    """
    @summary: Create a packet with "0.0.0.0" source or destination IP address.
    """
    zero_ipv4 = "0.0.0.0"
    zero_ipv6 = "::0"

    pkt_params = {
        "eth_dst": ports_info["dst_mac"],  # DUT port
        "eth_src": ports_info["src_mac"],  # PTF port
        "tcp_sport": pkt_fields["tcp_sport"],
        "tcp_dport": pkt_fields["tcp_dport"]
    }

    if addr_type == "ipv4":
        if addr_direction == "src":
            pkt_params["ip_src"] = zero_ipv4
            pkt_params["ip_dst"] = pkt_fields["ipv4_dst"]  # VM source
        elif addr_direction == "dst":
            pkt_params["ip_src"] = pkt_fields["ipv4_src"]  # VM source
            pkt_params["ip_dst"] = zero_ipv4
        else:
            pytest.fail(
                "Incorrect value specified for 'addr_direction'. Supported parameters: 'src' and 'dst'"
            )
        pkt = testutils.simple_tcp_packet(**pkt_params)
    elif addr_type == "ipv6":
        if not pkt_fields["ipv6_dst"]:
            pytest.skip("BGP neighbour with IPv6 addr was not found")
        if addr_direction == "src":
            pkt_params["ipv6_src"] = zero_ipv6
            pkt_params["ipv6_dst"] = pkt_fields["ipv6_dst"]  # VM source
        elif addr_direction == "dst":
            pkt_params["ipv6_src"] = pkt_fields["ipv6_src"]  # VM source
            pkt_params["ipv6_dst"] = zero_ipv6
        else:
            pytest.fail(
                "Incorrect value specified for 'addr_direction'. Supported parameters: 'src' and 'dst'"
            )
        pkt = testutils.simple_tcpv6_packet(**pkt_params)
    else:
        pytest.fail(
            "Incorrect value specified for 'addr_type' test parameter. Supported parameters: 'ipv4' or 'ipv6'"
        )

    logger.info(pkt_params)

    group = "L3"
    # DNX platform DROP counters are not there yet
    if setup.get("platform_asic") == "broadcom-dnx":
        group = "NO_DROPS"

    do_test(group, pkt, ptfadapter, ports_info,
            setup["dut_to_ptf_port_map"].values(), tx_dut_ports)
예제 #9
0
    def runTest(self):
        ip_dst_addr = '2001:0db8::3210'
        in_dmac = 'ee:30:ca:9d:1e:00'
        in_smac = 'ee:cd:00:7e:70:00'
        ig_port = 0
        eg_port = 1
        out_dmac = '00:00:00:00:00:01'

        # Add a set of table entries
        self.table_add(self.key_t2(ip_dst_addr, 128),
                       self.act_set_dmac(out_dmac))

        pkt_in = tu.simple_tcpv6_packet(eth_src=in_smac,
                                        eth_dst=in_dmac,
                                        ipv6_dst=ip_dst_addr)
        exp_pkt = tu.simple_tcpv6_packet(eth_src=in_smac,
                                         eth_dst=out_dmac,
                                         ipv6_dst=ip_dst_addr)
        tu.send_packet(self, ig_port, pkt_in)
        tu.verify_packets(self, exp_pkt, [eg_port])
예제 #10
0
def test_ip_is_zero_addr(do_test, ptfadapter, duthosts, rand_one_dut_hostname,
                         setup, tx_dut_ports, pkt_fields, addr_type,
                         addr_direction, ports_info):
    """
    @summary: Create a packet with "0.0.0.0" source or destination IP address.
    """
    duthost = duthosts[rand_one_dut_hostname]

    zero_ipv4 = "0.0.0.0"
    zero_ipv6 = "::0"

    pkt_params = {
        "eth_dst": ports_info["dst_mac"],  # DUT port
        "eth_src": ports_info["src_mac"],  # PTF port
        "tcp_sport": pkt_fields["tcp_sport"],
        "tcp_dport": pkt_fields["tcp_dport"]
    }

    if addr_type == "ipv4":
        if addr_direction == "src":
            pkt_params["ip_src"] = zero_ipv4
            pkt_params["ip_dst"] = pkt_fields["ipv4_dst"]  # VM source
        elif addr_direction == "dst":
            pkt_params["ip_src"] = pkt_fields["ipv4_src"]  # VM source
            pkt_params["ip_dst"] = zero_ipv4
        else:
            pytest.fail(
                "Incorrect value specified for 'addr_direction'. Supported parameters: 'src' and 'dst'"
            )
        pkt = testutils.simple_tcp_packet(**pkt_params)
    elif addr_type == "ipv6":
        if not pkt_fields["ipv6_dst"]:
            pytest.skip("BGP neighbour with IPv6 addr was not found")
        if addr_direction == "src":
            pkt_params["ipv6_src"] = zero_ipv6
            pkt_params["ipv6_dst"] = pkt_fields["ipv6_dst"]  # VM source
        elif addr_direction == "dst":
            pkt_params["ipv6_src"] = pkt_fields["ipv6_src"]  # VM source
            pkt_params["ipv6_dst"] = zero_ipv6
        else:
            pytest.fail(
                "Incorrect value specified for 'addr_direction'. Supported parameters: 'src' and 'dst'"
            )
        pkt = testutils.simple_tcpv6_packet(**pkt_params)
    else:
        pytest.fail(
            "Incorrect value specified for 'addr_type' test parameter. Supported parameters: 'ipv4' or 'ipv6'"
        )

    logger.info(pkt_params)

    do_test("L3", pkt, ptfadapter, duthost, ports_info,
            setup["dut_to_ptf_port_map"].values(), tx_dut_ports)
예제 #11
0
def test_src_ip_is_multicast_addr(do_test, ptfadapter, setup, tx_dut_ports,
                                  pkt_fields, ip_addr, ports_info):
    """
    @summary: Create a packet with multicast source IP adress.
    """
    ip_src = None

    if ip_addr == "ipv4":
        ip_src = "224.0.0.5"
        pkt = testutils.simple_tcp_packet(
            eth_dst=ports_info["dst_mac"],  # DUT port
            eth_src=ports_info["src_mac"],  # PTF port
            ip_src=ip_src,
            ip_dst=pkt_fields["ipv4_dst"],  # VM source
            tcp_sport=pkt_fields["tcp_sport"],
            tcp_dport=pkt_fields["tcp_dport"])
    elif ip_addr == "ipv6":
        if not pkt_fields["ipv6_dst"]:
            pytest.skip("BGP neighbour with IPv6 addr was not found")
        ip_src = "FF02:AAAA:FEE5::1:3"
        pkt = testutils.simple_tcpv6_packet(
            eth_dst=ports_info["dst_mac"],  # DUT port
            eth_src=ports_info["src_mac"],  # PTF port
            ipv6_src=ip_src,
            ipv6_dst=pkt_fields["ipv6_dst"],  # VM source
            tcp_sport=pkt_fields["tcp_sport"],
            tcp_dport=pkt_fields["tcp_dport"])
    else:
        pytest.fail(
            "Incorrect value specified for 'ip_addr' test parameter. Supported parameters: 'ipv4' and 'ipv6'"
        )

    log_pkt_params(ports_info["dut_iface"], ports_info["dst_mac"],
                   ports_info["src_mac"], pkt_fields["ipv4_dst"], ip_src)

    group = "L3"
    # DNX platform DROP counters are not there yet
    if setup.get("platform_asic") == "broadcom-dnx":
        group = "NO_DROPS"

    do_test(group, pkt, ptfadapter, ports_info, setup["neighbor_sniff_ports"],
            tx_dut_ports)
예제 #12
0
def generate_packet(src_ip, dst_ip, dst_mac):
    """
    Build ipv4 and ipv6 packets/expected_packets for testing.
    """
    if ipaddress.ip_network(unicode(src_ip), False).version == 4:
        pkt = testutils.simple_ip_packet(eth_dst=dst_mac,
                                         ip_src=src_ip,
                                         ip_dst=dst_ip)
        exp_pkt = Mask(pkt)
        exp_pkt.set_do_not_care_scapy(scapy.Ether, "dst")
        exp_pkt.set_do_not_care_scapy(scapy.Ether, "src")
        exp_pkt.set_do_not_care_scapy(scapy.IP, "ttl")
        exp_pkt.set_do_not_care_scapy(scapy.IP, "chksum")
    else:
        pkt = testutils.simple_tcpv6_packet(eth_dst=dst_mac,
                                            ipv6_src=src_ip,
                                            ipv6_dst=dst_ip)
        exp_pkt = Mask(pkt)
        exp_pkt.set_do_not_care_scapy(scapy.Ether, "dst")
        exp_pkt.set_do_not_care_scapy(scapy.Ether, "src")
        exp_pkt.set_do_not_care_scapy(scapy.IPv6, "hlim")

    return pkt, exp_pkt
예제 #13
0
def MultiSliceTestHelper(self, table_obj, exm_0_field_name, tcam_field_name,
                         lpm_field_name, exm_1_field_name, is_multi_field):
    """ @brief
    This is a helper function that 
    - Adds multiple field sliced entry in the table
    - For some runs, purposely creates discrepancies between the key fields that are already programmed and the values in 
      the sent pkts and ensures that the packet doesn't hit the entry. The way this is done is, the ipv6 address is first
      generated. Then the value of the field slice is extraced from that address. Then a bit which we expect to match on
      is flipped in the extracted value. Thus there will be a mismatch between the value present in the packet and the value
      installed in the hardware which will cause the packet to miss
    - Always scrambles the bits which are not expected to match on
    - Reads back the entry and verifies
    - Sends packets and verifies, 
      - If the installed key fields match the ones in the pkt, then the pkt should hit the entry
      - If they don't match then the pkt should miss the entry
    - Finally deletes the entry
    """
    ig_port = swports[1]
    eg_port = swports[2]

    dmac = '22:22:22:22:22:22'

    target = gc.Target(device_id=0, pipe_id=0xffff)
    num_entries = 100

    for entry_idx in range(num_entries):
        logger.info("Processing entry %d ", entry_idx)
        try:
            # Generate ipv6 dst addr and mask
            ipv6_dst_addr = generateIpv6Addr()
            ipv6_dst_addr_mask = generateIpv6Addr()
            logger.debug("Generated dst v6 addr is " + ipv6_dst_addr)
            logger.debug("Generated dst v6 mask is " + ipv6_dst_addr_mask)

            # Generate ipv6 src addr and mask
            ipv6_src_addr = generateIpv6Addr()
            ipv6_src_addr_mask = generateIpv6Addr()
            logger.debug("Generated src v6 addr is " + ipv6_src_addr)
            logger.debug("Generated src v6 mask is " + ipv6_src_addr_mask)

            # Extract all the field values from the dst addr
            tcam_v6_addr = ipv6_dst_addr
            tcam_v6_addr_mask = ipv6_dst_addr_mask
            lpm_v6_addr = ipv6_dst_addr
            exm_0_v6_addr = ipv6_dst_addr
            exm_1_v6_addr = ipv6_dst_addr

            if is_multi_field == True:
                # This indicates that the total 4 field slices are from 2 different fields, (2 slices from 1 field each)
                # Thus, the first exm field slice and tcam field slice are actually slices of a ipv6 src addr (Refer the p4
                # program for deduction). Hence set them accordingly
                tcam_v6_addr = ipv6_src_addr
                tcam_v6_addr_mask = ipv6_src_addr_mask
                exm_0_v6_addr = ipv6_src_addr

            pkt = testutils.simple_tcpv6_packet(eth_dst=dmac,
                                                ipv6_dst=ipv6_dst_addr,
                                                ipv6_src=ipv6_src_addr)
            exp_pkt = pkt

            # Start off by expecting the sent packet to match on all the fields
            should_exm_match_0 = True
            should_exm_match_1 = True
            should_tcam_match = True
            should_lpm_match = True

            # For different iterations of the test, we want to tamper with different fields individually
            if entry_idx % 5 == 1:
                should_exm_match_0 = False
            elif entry_idx % 5 == 2:
                should_exm_match_1 = False
            elif entry_idx % 5 == 3:
                should_tcam_match = False
            elif entry_idx % 5 == 4:
                should_lpm_match = False

            # We use this set to keep track of bits we want to flip/garble within a field slice
            garble_bit_index = set()

            # exm
            exm_val_0 = getIpv6AddrFieldSliceValue(exm_0_field_name,
                                                   exm_0_v6_addr)
            exm_field_byte_width_0 = getFieldSliceByteWidthFromName(
                exm_0_field_name)
            exm_field_bit_width_0 = getFieldSliceBitWidthFromName(
                exm_0_field_name)
            logger.debug("EXM_0 value before scrambling " + hex(exm_val_0))
            # Scramble bits if we want the pkt to miss in this iteration because of a mismatch on this field
            if should_exm_match_0 == False:
                # Flip any bit which we expect to match on
                index = random.randint(0, exm_field_bit_width_0 - 1)
                exm_val_0 = garbleBits(exm_val_0, [index])
            logger.debug("EXM_0 value after scrambling " + hex(exm_val_0))

            # ternary
            tcam_val = getIpv6AddrFieldSliceValue(tcam_field_name,
                                                  tcam_v6_addr)
            tcam_mask = getIpv6AddrFieldSliceValue(tcam_field_name,
                                                   tcam_v6_addr_mask)
            tcam_field_bit_width = getFieldSliceBitWidthFromName(
                tcam_field_name)
            tcam_field_byte_width = getFieldSliceByteWidthFromName(
                tcam_field_name)
            logger.debug("TCAM value before scrambling " + hex(tcam_val))
            # Scramble bits if we want the pkt to miss in this iteration because of a mismatch on this field
            if should_tcam_match == False:
                # Flip any bit which we expect to match on
                index = tcam_field_bit_width
                for i in range(tcam_field_bit_width):
                    if ((tcam_mask >> i) & 0x01) == 1:
                        index = i
                if index == tcam_field_bit_width:
                    # indicates that the generated  mask is all zeros. Thus ternary field is always going to match
                    # Hence flip the flag accordingly
                    should_tcam_match = True
                else:
                    tcam_val = garbleBits(tcam_val, [index])
            # Always scramble bits which are don't care
            garble_bit_index.clear()
            for i in range(tcam_field_bit_width):
                bit_val = (tcam_mask >> i) & 1
                if bit_val == 0:
                    garble_bit_index.add(i)
            tcam_val = garbleBits(tcam_val, garble_bit_index)
            logger.debug("TCAM value after scrambling " + hex(tcam_val))
            # We never scramble the tcam mask
            logger.debug("TCAM mask " + hex(tcam_mask))

            # lpm
            lpm_value_bit_width = getFieldSliceBitWidthFromName(lpm_field_name)
            lpm_value_byte_width = getFieldSliceByteWidthFromName(
                lpm_field_name)
            p_len = random.randint(1, lpm_value_bit_width)
            lpm_value = getIpv6AddrFieldSliceValue(lpm_field_name, lpm_v6_addr)
            logger.debug("LPM value before scrambling " + hex(lpm_value))
            logger.debug("LPM prefix width " + hex(p_len))
            # Scramble bits if we want the pkt to miss in this iteration because of a mismatch on this field
            if should_lpm_match == False:
                # Flip any bit within the prefix length so that the value in the packet
                # won't match with the value programmed. We are always flipping the bit
                # at index p_len
                lpm_value = garbleBits(lpm_value,
                                       [lpm_value_bit_width - p_len])
            if p_len != lpm_value_bit_width:
                # Always scramble the bits which are not supposed to be looked up anyway
                garble_bit_index.clear()
                for i in range(lpm_value_bit_width - 1 - p_len):
                    garble_bit_index.add(i)
                lpm_value = garbleBits(lpm_value, garble_bit_index)
            logger.debug("LPM value after scrambling " + hex(lpm_value))

            # exm
            exm_val_1 = getIpv6AddrFieldSliceValue(exm_1_field_name,
                                                   exm_1_v6_addr)
            exm_field_byte_width_1 = getFieldSliceByteWidthFromName(
                exm_1_field_name)
            exm_field_bit_width_1 = getFieldSliceBitWidthFromName(
                exm_1_field_name)
            logger.debug("EXM_1 value before scrambling " + hex(exm_val_1))
            # Scramble bits if we want the pkt to miss in this iteration because of a mismatch on this field
            if should_exm_match_1 == False:
                # Flip any bit which we expect to match on
                index = random.randint(0, exm_field_bit_width_1 - 1)
                exm_val_1 = garbleBits(exm_val_1, [index])
            logger.debug("EXM_1 value after scrambling " + hex(exm_val_1))

            logger.info("Insert the entry")
            table_key = table_obj.make_key([
                gc.KeyTuple(self.port_field_name, ig_port),
                gc.KeyTuple(exm_0_field_name, exm_val_0),
                gc.KeyTuple(tcam_field_name, tcam_val, tcam_mask),
                gc.KeyTuple(lpm_field_name, lpm_value, prefix_len=p_len),
                gc.KeyTuple(exm_1_field_name, exm_val_1),
                gc.KeyTuple("$MATCH_PRIORITY", 1)
            ])
            table_obj.entry_add(target, [table_key],
                                [getDataObj(table_obj, eg_port)])

            # Get the entry
            resp = table_obj.entry_get(target, None, {"from_hw": True})
            # for lpm and tcam, the mask is applied on the value before programming it in the hardware
            # thus get the expected lpm and tcam val to be read from hw
            lpm_val_hw = (((lpm_value) >> (lpm_value_bit_width - p_len)) <<
                          (lpm_value_bit_width - p_len))
            tcam_value_hw = tcam_val & tcam_mask
            for data, key in resp:
                data_dict = data.to_dict()
                key_dict = key.to_dict()
                assert key_dict[self.port_field_name]['value'] == ig_port
                assert key_dict[exm_0_field_name]['value'] == exm_val_0
                assert key_dict[tcam_field_name]['value'] == tcam_value_hw
                assert key_dict[tcam_field_name]['mask'] == tcam_mask
                assert key_dict[lpm_field_name]['value'] == lpm_val_hw
                assert key_dict[lpm_field_name]['prefix_len'] == p_len
                assert key_dict[exm_1_field_name]['value'] == exm_val_1

            # Send the packet
            testutils.send_packet(self, ig_port, pkt)

            logger.info("Should Exm_0 match %d", should_exm_match_0)
            logger.info("Should Tcam match %d", should_tcam_match)
            logger.info("Should Lpm match %d", should_lpm_match)
            logger.info("Should Exm_1 match %d", should_exm_match_1)
            if should_exm_match_0 == 1 and should_tcam_match == 1 and should_lpm_match == 1 and should_exm_match_1 == 1:
                # For this iteration we expect the pkt to match on all the field slices
                logger.info(
                    "Expecting packet on port %d after installing entry %d",
                    eg_port, entry_idx)
                testutils.verify_packet(self, exp_pkt, eg_port)
            else:
                # For this iteration we expect the pkt to miss on any one of the fields and hence to get dropped
                logger.info(
                    "Expecting the packet to get dropped after installing entry %d",
                    entry_idx)
                testutils.verify_no_other_packets(self)

        finally:
            # Delete the entry
            logger.info("Delete the entry")
            table_obj.entry_del(target, [table_key])

            testutils.send_packet(self, ig_port, pkt)
            logger.info("Packet is expected to get dropped.")
            testutils.verify_no_other_packets(self)
예제 #14
0
    def runTest(self):
        ig_port = swports[1]
        eg_port = swports[2]

        dmac = '22:22:22:22:22:22'
        logger.info("Range field slices are not supported yet")
        # FIXME This test fails
        return

        self.set_bfrt_info(
            self.parse_bfrt_info(self.get_bfrt_info("tna_field_slice")))
        target = self.Target(device_id=0, pipe_id=0xffff)
        num_entries = 100

        for entry_idx in range(num_entries):
            logger.info("Processing entry %d", entry_idx)
            try:
                ipv6_dst_addr = generateIpv6Addr()
                pkt = testutils.simple_tcpv6_packet(eth_dst=dmac,
                                                    ipv6_dst=ipv6_dst_addr)
                logger.debug("Ipv6 addr is " + ipv6_dst_addr)
                exp_pkt = pkt
                range_bit_width = getFieldSliceBitWidthFromName(
                    self.range_field_name)
                range_byte_width = getFieldSliceByteWidthFromName(
                    self.range_field_name)
                range_start = 1
                range_end = 0
                while range_end < range_start:
                    range_start = random.randint(0, pow(2, range_bit_width))
                    range_end = random.randint(0, pow(2, range_bit_width))
                pkt_range_value = getIpv6AddrFieldSliceValue(
                    self.range_field_name, ipv6_dst_addr)
                range_start = pkt_range_value - 1
                range_end = pkt_range_value + 1
                should_range_match = False
                if pkt_range_value >= range_start and pkt_range_value <= range_end:
                    logger.info("Entry is expected to hit")
                    should_range_match = True
                else:
                    logger.info("Entry is expected to miss")
                logger.debug("Range start is " + hex(range_start))
                logger.debug("Range end is " + hex(range_end))
                logger.debug("Pkt Range value  is " + hex(pkt_range_value))
                logger.info("Insert the entry")
                self.insert_table_entry(
                    target, self.table_name, [
                        self.KeyField('ig_intr_md.ingress_port',
                                      self.to_bytes(ig_port, 2)),
                        self.KeyField(
                            self.range_field_name,
                            low=self.to_bytes(range_start, range_byte_width),
                            high=self.to_bytes(range_end, range_byte_width)),
                        self.KeyField("$MATCH_PRIORITY", self.to_bytes(1, 4))
                    ], 'SwitchIngress.hit',
                    [self.DataField('port', self.to_bytes(eg_port, 2))])

                testutils.send_packet(self, ig_port, pkt)

                if should_range_match == True:
                    logger.info("Expecting packet on port %d", eg_port)
                    testutils.verify_packet(self, exp_pkt, eg_port)
                testutils.verify_no_other_packets(self)

                # Get key field ids
                key_port_field_id = self.get_key_field(
                    self.table_name, "ig_intr_md.ingress_port")
                key_ipv6_dst_field_id = self.get_key_field(
                    self.table_name, self.range_field_name)

                # Get all the entries
                resp = self.get_table_entry(target, self.table_name, None,
                                            {"from_hw": True})
                key_dict = {}
                entry_iter = self.parseEntryGetResponse(resp, key_dict)
                for data_dict in entry_iter:
                    assert key_dict[key_port_field_id][
                        'value'] == self.to_bytes(ig_port, 2)
                    assert key_dict[key_ipv6_dst_field_id][
                        'low'] == self.to_bytes(range_start, range_byte_width)
                    assert key_dict[key_ipv6_dst_field_id][
                        'high'] == self.to_bytes(range_end, range_byte_width)
            finally:
                logger.info("Delete the entry")
                self.delete_table_entry(target, self.table_name, [
                    self.KeyField('ig_intr_md.ingress_port',
                                  self.to_bytes(ig_port, 2)),
                    self.KeyField(
                        self.range_field_name,
                        low=self.to_bytes(range_start, range_byte_width),
                        high=self.to_bytes(range_end, range_byte_width)),
                    self.KeyField("$MATCH_PRIORITY", self.to_bytes(1, 4))
                ])

                testutils.send_packet(self, ig_port, pkt)
                logger.info("Packet is expected to get dropped.")
                testutils.verify_no_other_packets(self)
예제 #15
0
def SingleFieldSingleSliceLpmHelper(self, table_obj, lpm_field_name):
    """ @brief This is a helper function that adds a field slice entry in the table, sends packets and verifies, reads back the 
    entry and verifies and then finally deletes the entry
    """

    ig_port = swports[1]
    eg_port = swports[2]

    dmac = '22:22:22:22:22:22'
    num_entries = 100

    for entry_idx in range(num_entries):
        logger.info("Processing entry %d", entry_idx)
        try:
            # Generate ipv6 addr
            ipv6_dst_addr = generateIpv6Addr()
            logger.debug("Ipv6 addr is " + ipv6_dst_addr)

            pkt = testutils.simple_tcpv6_packet(eth_dst=dmac,
                                                ipv6_dst=ipv6_dst_addr)
            exp_pkt = pkt

            target = gc.Target(device_id=0, pipe_id=0xffff)

            # Extract the lpm val, lpm field width in bits and bytes that is going to be programmed from the
            # generated ipv6 addr
            lpm_field_val = getIpv6AddrFieldSliceValue(lpm_field_name,
                                                       ipv6_dst_addr)
            lpm_field_width_byte = getFieldSliceByteWidthFromName(
                lpm_field_name)
            lpm_value_bit_width = getFieldSliceBitWidthFromName(lpm_field_name)

            # Choose a prefix len between 1 and lpm field bit width
            p_len = random.randint(1, lpm_value_bit_width)
            logger.debug("LPM val is " + hex(lpm_field_val))
            logger.debug("LPM prefix len is " + hex(p_len))

            # Insert the entry
            logger.info("Insert the entry")
            table_key = table_obj.make_key([
                gc.KeyTuple(self.port_field_name, ig_port),
                gc.KeyTuple(lpm_field_name, lpm_field_val, prefix_len=p_len)
            ])
            table_obj.entry_add(target, [table_key],
                                [getDataObj(table_obj, eg_port)])

            testutils.send_packet(self, ig_port, pkt)

            logger.info("Expecting packet on port %d", eg_port)
            testutils.verify_packet(self, exp_pkt, eg_port)
            testutils.verify_no_other_packets(self)

            # Get the entry
            resp = table_obj.entry_get(target, None, {"from_hw": True})
            # for lpm, the mask is applied on the value before programming it in the hardware
            # thus get the expected lpm field val to be read from hw
            lpm_field_val_hw = (((lpm_field_val) >>
                                 (lpm_value_bit_width - p_len)) <<
                                (lpm_value_bit_width - p_len))
            for data, key in resp:
                data_dict = data.to_dict()
                key_dict = key.to_dict()
                assert key_dict[self.port_field_name]['value'] == ig_port
                assert key_dict[lpm_field_name]['value'] == lpm_field_val_hw
                assert key_dict[lpm_field_name]['prefix_len'] == p_len

        finally:
            # Delete the entry
            logger.info("Delete the entry")
            table_obj.entry_del(target, [table_key])

            testutils.send_packet(self, ig_port, pkt)
            logger.info("Packet is expected to get dropped.")
            testutils.verify_no_other_packets(self)
예제 #16
0
    def runTest(self):
        ig_port = swports[1]
        eg_port = swports[2]

        dmac = '22:22:22:22:22:22'

        bfrt_info = self.interface.bfrt_info_get("tna_field_slice")
        num_entries = 100

        table_obj = bfrt_info.table_get(self.table_name)
        table_key = None

        for entry_idx in range(num_entries):
            logger.info("Processing entry %d", entry_idx)
            try:
                # Generate ipv6 addr
                ipv6_dst_addr = generateIpv6Addr()
                logger.debug("Ipv6 addr is " + ipv6_dst_addr)

                pkt = testutils.simple_tcpv6_packet(eth_dst=dmac,
                                                    ipv6_dst=ipv6_dst_addr)
                exp_pkt = pkt

                target = gc.Target(device_id=0, pipe_id=0xffff)

                # Extract the exact match val that is going to be programmed from the
                # generated ipv6 addr
                exm_value = getIpv6AddrFieldSliceValue(self.exm_field_name,
                                                       ipv6_dst_addr)
                logger.debug("EXM val is " + hex(exm_value))

                # Insert the entry
                logger.info("Insert the entry")
                table_key = table_obj.make_key([
                    gc.KeyTuple(self.port_field_name, ig_port),
                    gc.KeyTuple(self.exm_field_name, exm_value)
                ])
                table_obj.entry_add(target, [table_key],
                                    [getDataObj(table_obj, eg_port)])

                testutils.send_packet(self, ig_port, pkt)

                logger.info("Expecting packet on port %d", eg_port)
                testutils.verify_packet(self, exp_pkt, eg_port)
                testutils.verify_no_other_packets(self)

                # Get the entry
                resp = table_obj.entry_get(target, None, {"from_hw": True})
                for data, key in resp:
                    data_dict = data.to_dict()
                    key_dict = key.to_dict()
                    assert key_dict[self.port_field_name]['value'] == ig_port
                    assert key_dict[self.exm_field_name]['value'] == exm_value

            finally:
                # Delete the entry
                if table_key:
                    logger.info("Delete the entry")
                    table_obj.entry_del(target, [table_key])

                testutils.send_packet(self, ig_port, pkt)
                logger.info("Packet is expected to get dropped")
                testutils.verify_no_other_packets(self)
예제 #17
0
    def runTest(self):
        ig_port = swports[1]
        eg_port = swports[2]

        dmac = '22:22:22:22:22:22'

        bfrt_info = self.interface.bfrt_info_get("tna_field_slice")
        num_entries = 100

        table_obj = bfrt_info.table_get(self.table_name)

        for entry_idx in range(num_entries):
            logger.info("Processing entry %d", entry_idx)
            try:
                # Generate ipv6 addr and mask
                ipv6_dst_addr = generateIpv6Addr()
                ipv6_dst_addr_mask = generateIpv6Addr()
                logger.debug("Ipv6 addr is : " + ipv6_dst_addr)
                logger.debug("Ipv6 addr mask is :" + ipv6_dst_addr_mask)

                pkt = testutils.simple_tcpv6_packet(eth_dst=dmac,
                                                    ipv6_dst=ipv6_dst_addr)
                exp_pkt = pkt

                target = gc.Target(device_id=0, pipe_id=0xffff)

                # Extract the tcam val and mask that is going to be programmed from the
                # generated ipv6 addr and mask
                tcam_field_val = getIpv6AddrFieldSliceValue(
                    self.tcam_field_name, ipv6_dst_addr)
                logger.debug("TCAM val is " + hex(tcam_field_val))
                tcam_field_mask = getIpv6AddrFieldSliceValue(
                    self.tcam_field_name, ipv6_dst_addr_mask)
                logger.debug("TCAM mask is " + hex(tcam_field_mask))
                tcam_field_width_byte = getFieldSliceByteWidthFromName(
                    self.tcam_field_name)

                # Insert the entry
                logger.info("Insert the entry")
                table_key = table_obj.make_key([
                    gc.KeyTuple(self.port_field_name, ig_port),
                    gc.KeyTuple(self.tcam_field_name, tcam_field_val,
                                tcam_field_mask),
                    gc.KeyTuple("$MATCH_PRIORITY", 1)
                ])
                table_obj.entry_add(target, [table_key],
                                    [getDataObj(table_obj, eg_port)])

                testutils.send_packet(self, ig_port, pkt)

                logger.info("Expecting packet on port %d", eg_port)
                testutils.verify_packet(self, exp_pkt, eg_port)
                testutils.verify_no_other_packets(self)

                # Get the entry
                resp = table_obj.entry_get(target, None, {"from_hw": True})
                # For tcam, the mask is applied on the value before programming it in the hardware
                # Thus form the expected tcam value to be read from the hw
                tcam_field_val_hw = (tcam_field_val & tcam_field_mask)
                for data, key in resp:
                    data_dict = data.to_dict()
                    key_dict = key.to_dict()
                    assert key_dict[self.port_field_name]['value'] == ig_port
                    assert key_dict[
                        self.tcam_field_name]['value'] == tcam_field_val_hw
                    assert key_dict[
                        self.tcam_field_name]['mask'] == tcam_field_mask
            finally:
                # Delete the entry
                logger.info("Delete the entry")
                table_obj.entry_del(target, [table_key])

                testutils.send_packet(self, ig_port, pkt)
                logger.info("Packet is expected to get dropped.")
                testutils.verify_no_other_packets(self)
예제 #18
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)
예제 #19
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)
예제 #20
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)
예제 #21
0
    def test_encap(self,
                   ptf_port,
                   vni,
                   ptf_addr,
                   destination,
                   nhs,
                   test_ecn=False,
                   vlan=0):
        rv = True
        try:
            pkt_len = self.DEFAULT_PKT_LEN
            if 'vlan' != 0:
                tagged = True
                pkt_len += 4
            else:
                tagged = False

            options = {'ip_ecn': 0}
            options_v6 = {'ipv6_ecn': 0}
            if test_ecn:
                ecn = random.randint(0, 3)
                options = {'ip_ecn': ecn}
                options_v6 = {'ipv6_ecn': ecn}

            # ECMP support, assume it is a string of comma seperated list of addresses.
            returned_ip_addresses = {}
            check_ecmp = False
            for host_address in nhs:
                check_ecmp = True
                # This will ensure that every nh is used atleast once.
                for i in range(self.packet_count):
                    tcp_sport = get_incremental_value('tcp_sport')
                    valid_combination = True
                    if isinstance(ip_address(destination),
                                  ipaddress.IPv4Address) and isinstance(
                                      ip_address(ptf_addr),
                                      ipaddress.IPv4Address):
                        pkt_opts = {
                            "pktlen": pkt_len,
                            "eth_dst": self.dut_mac,
                            "eth_src": self.ptf_mac_addrs['eth%d' % ptf_port],
                            "ip_dst": destination,
                            "ip_src": ptf_addr,
                            "ip_id": 105,
                            "ip_ttl": 64,
                            "tcp_sport": tcp_sport,
                            "tcp_dport": VARS['tcp_dport']
                        }
                        pkt_opts.update(options)
                        pkt = simple_tcp_packet(**pkt_opts)
                        pkt_opts['ip_ttl'] = 63
                        pkt_opts['eth_src'] = self.dut_mac
                        exp_pkt = simple_tcp_packet(**pkt_opts)
                    elif isinstance(ip_address(destination),
                                    ipaddress.IPv6Address) and isinstance(
                                        ip_address(ptf_addr),
                                        ipaddress.IPv6Address):
                        pkt_opts = {
                            "pktlen": pkt_len,
                            "eth_dst": self.dut_mac,
                            "eth_src": self.ptf_mac_addrs['eth%d' % ptf_port],
                            "ipv6_dst": destination,
                            "ipv6_src": ptf_addr,
                            "ipv6_hlim": 64,
                            "tcp_sport": tcp_sport,
                            "tcp_dport": VARS['tcp_dport']
                        }
                        pkt_opts.update(options_v6)
                        pkt = simple_tcpv6_packet(**pkt_opts)
                        pkt_opts['ipv6_hlim'] = 63
                        pkt_opts['eth_src'] = self.dut_mac
                        exp_pkt = simple_tcpv6_packet(**pkt_opts)
                    else:
                        valid_combination = False
                    udp_sport = 1234  # Use entropy_hash(pkt), it will be ignored in the test later.
                    udp_dport = self.vxlan_port
                    if isinstance(ip_address(host_address),
                                  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=host_address,
                            ip_ttl=128,
                            udp_sport=udp_sport,
                            udp_dport=udp_dport,
                            with_udp_chksum=False,
                            vxlan_vni=vni,
                            inner_frame=exp_pkt,
                            **options)
                        encap_pkt[scapy.IP].flags = 0x2
                    elif isinstance(ip_address(host_address),
                                    ipaddress.IPv6Address):
                        encap_pkt = simple_vxlanv6_packet(
                            eth_src=self.dut_mac,
                            eth_dst=self.random_mac,
                            ipv6_src=self.loopback_ipv6,
                            ipv6_dst=host_address,
                            udp_sport=udp_sport,
                            udp_dport=udp_dport,
                            with_udp_chksum=False,
                            vxlan_vni=vni,
                            inner_frame=exp_pkt,
                            **options_v6)
                    send_packet(self, ptf_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(host_address),
                                  ipaddress.IPv4Address):
                        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, "dst")
                    else:
                        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.IPv6, "dst")
                    masked_exp_pkt.set_do_not_care_scapy(scapy.UDP, "sport")
                    masked_exp_pkt.set_do_not_care_scapy(scapy.UDP, "chksum")

                    logger.info("Sending packet from port " + str(ptf_port) +
                                " to " + destination)

                    if self.expect_encap_success:
                        _, received_pkt = verify_packet_any_port(
                            self, masked_exp_pkt, self.t2_ports)
                        scapy_pkt = scapy.Ether(received_pkt)
                        # Store every destination that was received.
                        if isinstance(ip_address(host_address),
                                      ipaddress.IPv6Address):
                            dest_ip = scapy_pkt['IPv6'].dst
                        else:
                            dest_ip = scapy_pkt['IP'].dst
                        try:
                            returned_ip_addresses[
                                dest_ip] = returned_ip_addresses[dest_ip] + 1
                        except KeyError:
                            returned_ip_addresses[dest_ip] = 1

                    else:
                        check_ecmp = False
                        logger.info("Verifying no packet")
                        verify_no_packet_any(self, masked_exp_pkt,
                                             self.t2_ports)

            # Verify ECMP:
            if check_ecmp:
                self.verify_all_addresses_used_equally(nhs,
                                                       returned_ip_addresses)

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

        finally:
            logger.info("")
예제 #22
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']
        exp_router_mac = self.router_macs[self.ptf_test_port_map[str(src_port)]['target_dut']]

        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,
                                eth_src=exp_router_mac,
                                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")

        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))

        if self.pkt_action == self.ACTION_FWD:
            return verify_packet_any_port(self, masked_exp_pkt, dst_port_list)
        elif self.pkt_action == self.ACTION_DROP:
            return verify_no_packet_any(self, masked_exp_pkt, dst_port_list)
예제 #23
0
def craft_packet(src_mac,
                 dst_mac,
                 dst_ip,
                 ip_version,
                 stage,
                 tagged_mode,
                 vlan_id=10,
                 outer_vlan_id=0,
                 pkt_type=None):
    """
    Generate IPV4/IPV6 packets with single or double Vlan Header

    Args:
        src_mac: Source MAC address
        dst_mac: Dest MAC address
        dst_ip: IP address of packet
        ip_version: Ip version of packet that should be generated
        stage: ingress or egress
        tagged_mode:  TAGGED or UNTAGGED
        vlan_id: Vlan Id number
        dl_vlan_outer: Outer Vlan ID
        pkt_type: packet type to be created

    Returns:
        QinQ or TCP packet
    """
    DUMMY_IP = '8.8.8.8'
    exp_pkt_with_tag = tagged_mode in [TYPE_TAGGED, TYPE_COMBINE_TAGGED]
    if ip_version == IPV4:
        if pkt_type == 'qinq':
            pkt = testutils.simple_qinq_tcp_packet(eth_src=src_mac,
                                                   eth_dst=dst_mac,
                                                   dl_vlan_outer=outer_vlan_id,
                                                   vlan_vid=vlan_id,
                                                   ip_src=DUMMY_IP,
                                                   ip_dst=dst_ip)
            if exp_pkt_with_tag:
                exp_pkt = testutils.simple_tcp_packet(
                    pktlen=96,  # Default len (100) - Dot1Q len (4)
                    eth_src=src_mac,
                    eth_dst=dst_mac,
                    dl_vlan_enable=True,
                    vlan_vid=vlan_id,
                    ip_src=DUMMY_IP,
                    ip_dst=dst_ip)
            else:
                exp_pkt = pkt
        else:
            pkt = testutils.simple_tcp_packet(eth_src=src_mac,
                                              eth_dst=dst_mac,
                                              ip_src=DUMMY_IP,
                                              ip_dst=dst_ip)
            if exp_pkt_with_tag:
                exp_pkt = testutils.simple_tcp_packet(
                    pktlen=104,  # Default len(100) + Dot1Q len (4)
                    eth_src=src_mac,
                    eth_dst=dst_mac,
                    dl_vlan_enable=True,
                    vlan_vid=outer_vlan_id,
                    ip_src=DUMMY_IP,
                    ip_dst=dst_ip)
            else:
                exp_pkt = pkt.copy()

            exp_pkt = mask.Mask(exp_pkt)
            exp_pkt.set_do_not_care_scapy(Ether, 'src')
            exp_pkt.set_do_not_care_scapy(Ether, 'dst')
            exp_pkt.set_do_not_care_scapy(IP, 'ttl')
            exp_pkt.set_do_not_care_scapy(IP, 'chksum')

    else:
        pkt = testutils.simple_tcpv6_packet(eth_src=src_mac,
                                            eth_dst=dst_mac,
                                            dl_vlan_enable=True,
                                            vlan_vid=outer_vlan_id,
                                            ipv6_dst=dst_ip)

        if exp_pkt_with_tag:
            exp_pkt = testutils.simple_tcpv6_packet(
                pktlen=96,  # Default len (100) - Dot1Q len (4)
                eth_src=src_mac,
                eth_dst=dst_mac,
                ipv6_dst=dst_ip)
        else:
            exp_pkt = pkt

    return pkt, exp_pkt