Ejemplo n.º 1
0
    def updateConfig(self):
        '''
        Performs a SetForwardingPipelineConfig on the device with provided
        P4Info and binary device config.

        Prerequisite: setUp() method has been called first to create
        the channel.
        '''
        request = p4runtime_pb2.SetForwardingPipelineConfigRequest()
        request.device_id = self.device_id
        config = request.config
        # TBD: It seems like there should be a way to do this without
        # reading the P4info file again, instead getting the data from
        # self.p4info as saved when executing the setUp() method
        # above.  The following commented-out assignment does not work.
        #config.p4info = self.p4info
        proto_txt_path = testutils.test_param_get("p4info")
        with open(proto_txt_path, 'r') as fin:
            google.protobuf.text_format.Merge(fin.read(), config.p4info)
        config_path = testutils.test_param_get("config")
        logging.info(
            "Reading config (compiled P4 program) from {}".format(config_path))
        with open(config_path, 'rb') as config_f:
            config.p4_device_config = config_f.read()
        request.action = p4runtime_pb2.SetForwardingPipelineConfigRequest.VERIFY_AND_COMMIT
        try:
            response = self.stub.SetForwardingPipelineConfig(request)
        except Exception as e:
            logging.error("Error during SetForwardingPipelineConfig",
                          file=sys.stderr)
            logging.error(str(e), file=sys.stderr)
            return False
        return True
Ejemplo n.º 2
0
    def setUp(self):
        BaseTest.setUp(self)
        self.device_id = 0

        # Setting up PTF dataplane
        self.dataplane = ptf.dataplane_instance
        self.dataplane.flush()

        self._swports = []
        for device, port, ifname in config["interfaces"]:
            self._swports.append(port)

        grpc_addr = testutils.test_param_get("grpcaddr")
        if grpc_addr is None:
            grpc_addr = 'localhost:50051'

        self.channel = grpc.insecure_channel(grpc_addr)
        self.stub = p4runtime_pb2.P4RuntimeStub(self.channel)

        proto_txt_path = testutils.test_param_get("p4info")
        print "Importing p4info proto from", proto_txt_path
        self.p4info = p4info_pb2.P4Info()
        with open(proto_txt_path, "rb") as fin:
            google.protobuf.text_format.Merge(fin.read(), self.p4info)

        self.import_p4info_names()

        # used to store write requests sent to the P4Runtime server, useful for
        # autocleanup of tests (see definition of autocleanup decorator below)
        self._reqs = []

        self.set_up_stream()
Ejemplo n.º 3
0
def make_phase0_data(field1, field2, field3, field4):
    """@brief Pack all fields into one pahse0_data. For tofino 2, it is
    left shifted 64 more because the field is a 128 bit value
    """
    phase0data = (field1 << 48) | (field2 << 24) | (field3 << 8) | field4
    if testutils.test_param_get("arch") == "tofino":
        pass
    elif testutils.test_param_get("arch") == "tofino2":
        phase0data = phase0data << 64
    return phase0data
Ejemplo n.º 4
0
    def runTest(self):
        eg_port = swports[2]
        dmac = '22:22:22:22:22:22'
        dkey = '22:22:22:22:22:23'
        dmask = 'ff:ff:ff:ff:ff:f0'
        port_mask = 0
        pkt = testutils.simple_tcp_packet(eth_dst=dmac)
        pkt2 = testutils.simple_tcp_packet(eth_dst=dkey)
        exp_pkt = pkt
        exp_pkt2 = pkt2

        # Get bfrt_info and set it as part of the test
        bfrt_info = self.interface.bfrt_info_get("tna_dkm")

        # Set the scope of the table to ALL_PIPES
        logger.info("=============== Testing Dyn Key Mask ===============")
        target = gc.Target(device_id=0, pipe_id=0xffff)
        logger.info("set dyn key mask")
        forward_table = bfrt_info.table_get("SwitchIngress.forward")
        forward_table.info.key_field_annotation_add("hdr.ethernet.dst_addr",
                                                    "mac")
        key_mask = forward_table.make_key(
            [gc.KeyTuple('hdr.ethernet.dst_addr', dmask),
             gc.KeyTuple('ig_intr_md.ingress_port', port_mask)])
        forward_table.attribute_dyn_key_mask_set(target, key_mask)
        resp = forward_table.attribute_get(target, "DynamicKeyMask")
        for d in resp:
            assert d["fields"].to_dict()["ig_intr_md.ingress_port"]["value"] == port_mask
            assert d["fields"].to_dict()["hdr.ethernet.dst_addr"]["value"] == dmask

        logger.info("Add entry")
        key_list = [forward_table.make_key(
            [gc.KeyTuple('hdr.ethernet.dst_addr', dmac),
             gc.KeyTuple('ig_intr_md.ingress_port', swports_0[0])])]
        data_list = [forward_table.make_data([gc.DataTuple('port', eg_port)],
                                             "SwitchIngress.hit")]
        forward_table.entry_add(target, key_list, data_list)

        self.send_and_verify_packet(swports_0[0], eg_port, pkt2, exp_pkt2)
        self.send_and_verify_packet(swports_1[0], eg_port, pkt2, exp_pkt2)
        if int(testutils.test_param_get('num_pipes')) > 2:
            self.send_and_verify_packet(swports_2[0], eg_port, pkt2, exp_pkt2)
        if int(testutils.test_param_get('num_pipes')) > 3:
            self.send_and_verify_packet(swports_3[0], eg_port, pkt2, exp_pkt2)
        self.send_and_verify_packet(swports_0[0], eg_port, pkt, exp_pkt)
        self.send_and_verify_packet(swports_1[0], eg_port, pkt, exp_pkt)
        if int(testutils.test_param_get('num_pipes')) > 2:
            self.send_and_verify_packet(swports_2[0], eg_port, pkt, exp_pkt)
        if int(testutils.test_param_get('num_pipes')) > 3:
            self.send_and_verify_packet(swports_3[0], eg_port, pkt, exp_pkt)
        testutils.verify_no_other_packets(self, timeout=2)
        logger.info("Delete the entry")
        forward_table.entry_del(target, key_list)
Ejemplo n.º 5
0
    def setUp(self):
        BaseTest.setUp(self)

        # Setting up PTF dataplane
        self.dataplane = ptf.dataplane_instance
        self.dataplane.flush()

        self._swports = []
        for device, port, ifname in config["interfaces"]:
            self._swports.append(port)

        self.port1 = self.swports(1)
        self.port2 = self.swports(2)
        self.port3 = self.swports(3)

        grpc_addr = testutils.test_param_get("grpcaddr")
        if grpc_addr is None:
            grpc_addr = 'localhost:50051'

        self.device_id = int(testutils.test_param_get("device_id"))
        if self.device_id is None:
            self.fail("Device ID is not set")

        self.cpu_port = int(testutils.test_param_get("cpu_port"))
        if self.cpu_port is None:
            self.fail("CPU port is not set")

        pltfm = testutils.test_param_get("pltfm")
        if pltfm is not None and pltfm == 'hw' and getattr(
                self, "_skip_on_hw", False):
            raise SkipTest("Skipping test in HW")

        self.channel = grpc.insecure_channel(grpc_addr)
        self.stub = p4runtime_pb2.P4RuntimeStub(self.channel)

        proto_txt_path = testutils.test_param_get("p4info")
        # print "Importing p4info proto from", proto_txt_path
        self.p4info = p4info_pb2.P4Info()
        with open(proto_txt_path, "rb") as fin:
            google.protobuf.text_format.Merge(fin.read(), self.p4info)

        self.helper = P4InfoHelper(proto_txt_path)

        # used to store write requests sent to the P4Runtime server, useful for
        # autocleanup of tests (see definition of autocleanup decorator below)
        self.reqs = []

        self.election_id = 1
        self.set_up_stream()
Ejemplo n.º 6
0
    def runTest(self):
        target = client.Target(device_id=0, pipe_id=0xffff)

        bfrt_info = self.interface.bfrt_info_get("tna_meter_lpf_wred")
        table = bfrt_info.table_get("SwitchIngress.direct_meter_color")
        table.info.key_field_annotation_add("hdr.ethernet.src_addr", "mac")

        entry_key = table.make_key(
            [client.KeyTuple('hdr.ethernet.src_addr', '00:11:22:33:44:55')])
        entry_data = table.make_data([], "SwitchIngress.set_color_direct")
        table.entry_add(target, [entry_key], [entry_data])

        for data, key in table.entry_get(target, [entry_key],
                                         {"from_hw": False}):
            data_dict = data.to_dict()
            if g_is_tofino and testutils.test_param_get("target") is not "hw":
                self.assertEqual(data_dict["$METER_SPEC_CIR_KBPS"], 5195848221)
                self.assertEqual(data_dict["$METER_SPEC_PIR_KBPS"], 5195848221)
            elif g_is_tofino2:
                self.assertEqual(data_dict["$METER_SPEC_CIR_KBPS"], 4087999890)
                self.assertEqual(data_dict["$METER_SPEC_PIR_KBPS"], 4087999890)
            self.assertEqual(data_dict["$METER_SPEC_CBS_KBITS"], 4380866642)
            self.assertEqual(data_dict["$METER_SPEC_PBS_KBITS"], 4380866642)

        table.entry_del(target, [entry_key])
Ejemplo n.º 7
0
 def runTest(self):
     if testutils.test_param_get('target') != "hw":
         return
     seed = random.randint(1, 65535)
     logger.info("Seed used for Ports with p4program Test is %d", seed)
     random.seed(seed)
     # Get bfrt_info and set it as part of the test
     bfrt_info = self.interface.bfrt_info_get("tna_ports")
     # Initializing all tables
     self.forward_table = bfrt_info.table_get("SwitchIngress.forward")
     self.forward_table.info.key_field_annotation_add(
         "hdr.ethernet.dst_addr", "mac")
     self.port_table = bfrt_info.table_get("$PORT")
     self.port_stat_table = bfrt_info.table_get("$PORT_STAT")
     self.port_hdl_info_table = bfrt_info.table_get("$PORT_HDL_INFO")
     self.port_fp_idx_info_table = bfrt_info.table_get("$PORT_FP_IDX_INFO")
     self.port_str_info_table = bfrt_info.table_get("$PORT_STR_INFO")
     # Setting up PTF dataplane
     self.dataplane = ptf.dataplane_instance
     self.dataplane.flush()
     PortCfgTest(self, 16, 20)
     PortStatTest(self, 12, 8)
     # model 3/0, hw 18/0
     PortHdlInfoTest(self, 8, 18, "18/0")
     PortStatusCbTest(self, 12)
Ejemplo n.º 8
0
    def setUp(self):
        super(P4EbpfTest, self).setUp()

        if self.skip:
            self.skipTest(self.skip_reason)

        if not os.path.exists(self.p4_file_path):
            self.fail("P4 program not found, no such file.")

        if not os.path.exists("ptf_out"):
            os.makedirs("ptf_out")

        head, tail = os.path.split(self.p4_file_path)
        filename = tail.split(".")[0]
        self.test_prog_image = os.path.join("ptf_out", filename + ".o")

        p4args = "--Wdisable=unused --max-ternary-masks 3"
        if self.is_trace_logs_enabled():
            p4args += " --trace"

        if "xdp2tc" in testutils.test_params_get():
            p4args += " --xdp2tc=" + self.xdp2tc_mode()

        logger.info("P4ARGS=" + p4args)
        self.exec_cmd(
            "make -f ../runtime/kernel.mk BPFOBJ={output} P4FILE={p4file} "
            "ARGS=\"{cargs}\" P4C=p4c-ebpf P4ARGS=\"{p4args}\" psa".format(
                output=self.test_prog_image,
                p4file=self.p4_file_path,
                cargs="-DPSA_PORT_RECIRCULATE=2",
                p4args=p4args), "Compilation error")

        self.dataplane = ptf.dataplane_instance
        self.dataplane.flush()
        logger.info("\nUsing test params: %s", testutils.test_params_get())
        if "namespace" in testutils.test_params_get():
            self.switch_ns = testutils.test_param_get("namespace")
        self.interfaces = testutils.test_param_get("interfaces").split(",")

        self.exec_ns_cmd(
            "psabpf-ctl pipeline load id {} {}".format(TEST_PIPELINE_ID,
                                                       self.test_prog_image),
            "Can't load programs into eBPF subsystem")

        for intf in self.interfaces:
            self.add_port(dev=intf)
Ejemplo n.º 9
0
    def setUp(self):
        self.pdrs = []
        self.fars = []
        self.appQers = []
        self.sessionQers = []

        # activate grpc connection to bess
        bess_server_addr = testutils.test_param_get("bess_upf_addr")
        self.channel = grpc.insecure_channel(target=bess_server_addr)
        self.bess_client = pb.BESSControlStub(self.channel)
Ejemplo n.º 10
0
 def setUp(self):
     super(TrexTest, self).setUp()
     trex_server_addr = testutils.test_param_get("trex_server_addr")
     self.trex_client = STLClient(server=trex_server_addr)
     self.trex_client.connect()
     self.trex_client.acquire()
     self.trex_client.reset()  # Resets configs from all ports
     self.trex_client.clear_stats()  # Clear status from all ports
     # Put all ports to promiscuous mode, otherwise they will drop all
     # incoming packets if the destination mac is not the port mac address.
     self.trex_client.set_port_attr(self.trex_client.get_all_ports(),
                                    promiscuous=True)
Ejemplo n.º 11
0
    def verifyRegisterValue(self, resp, register_value):
        # Since the table exists in all pipes and 1 stage per pipe, we expect
        # to get back a number of register values equal to the number of pipes
        # (one each per pipe and stage).
        num_pipes = int(testutils.test_param_get('num_pipes'))
        num_register_values = num_pipes

        data_dict = next(resp)[0].to_dict()

        for i in range(num_register_values):
            read_value = data_dict["SwitchIngress.bool_register_table.f1"][i]
            logger.info("Register Expected Value (%s) : Read value (%s)",
                        str(register_value[i]), str(read_value))
            if read_value != register_value[i]:
                logger.error("Register field didn't match with the read value")
                assert (0)
Ejemplo n.º 12
0
    def runTest(self):
        seed = random.randint(1, 65535)
        logger.info("Seed used for RegisterTest is %d", seed)
        random.seed(seed)

        # Get bfrt_info and set it as part of the test
        bfrt_info = self.interface.bfrt_info_get("tna_register")

        register_idx = random.randint(0, 500)
        register_value_hi = random.randint(0, 1000)
        register_value_lo = random.randint(0, 1000)
        logger.info("Register value hi %s", str(register_value_hi))
        logger.info("Register value lo %s", str(register_value_lo))
        register_value_hi_arr = {}
        register_value_lo_arr = {}
        num_pipes = int(testutils.test_param_get('num_pipes'))

        for i in range(num_pipes):
            register_value_hi_arr[i] = register_value_hi
            register_value_lo_arr[i] = register_value_lo

        target = gc.Target(device_id=0, pipe_id=0xffff)
        register_table = bfrt_info.table_get("SwitchIngress.test_reg")
        register_table.entry_add(target, [
            register_table.make_key(
                [gc.KeyTuple('$REGISTER_INDEX', register_idx)])
        ], [
            register_table.make_data([
                gc.DataTuple('SwitchIngress.test_reg.first',
                             register_value_lo),
                gc.DataTuple('SwitchIngress.test_reg.second',
                             register_value_hi)
            ])
        ])

        resp = register_table.entry_get(target, [
            register_table.make_key(
                [gc.KeyTuple('$REGISTER_INDEX', register_idx)])
        ], {"from_hw": True})

        data, _ = next(resp)
        data_dict = data.to_dict()
        VerifyReadRegisters(self, "SwitchIngress.test_reg.first",
                            "SwitchIngress.test_reg.second",
                            register_value_lo_arr, register_value_hi_arr,
                            data_dict)
Ejemplo n.º 13
0
def VerifyReadRegisters(self, register_name_lo, register_name_hi, resp, register_value_lo, register_value_hi,
                        data_dict):
    # since the table is symmetric and exists only in stage 0, we know that the response data is going to have
    # 8 data fields (2 (hi and lo) * 4 (num pipes) * 1 (num_stages)). bfrt_server returns all (4) register values
    # corresponding to one field id followed by all (4) register values corresponding to the other field id

    num_pipes = int(testutils.test_param_get('num_pipes'))
    for i in range(num_pipes):
        value_lo = data_dict[register_name_lo][i]
        value_hi = data_dict[register_name_hi][i]
        logger.info("Register Lo Expected Value (%s) : Read value (%s)", str(register_value_lo[i]), str(value_lo))
        logger.info("Register Hi Expected Value (%s) : Read value (%s)", str(register_value_hi[i]), str(value_hi))
        if data_dict[register_name_lo][i] != register_value_lo[i]:
            logger.info("Register field lo didn't match with the read value")
            assert (0)
        if data_dict[register_name_hi][i] != register_value_hi[i]:
            logger.info("Register field hi didn't match with the read value")
            assert (0)
Ejemplo n.º 14
0
    def setUp(self, proto_bin_path):
        BaseTest.setUp(self)

        self.target = testutils.test_param_get('target')
        if not self.target:
            self.target = "bmv2"
        elif self.target not in {"bmv2"}:
            print "Unsupported target", self.target
            sys.exit(1)

        self.device_id = 0

        # Setting up PTF dataplane
        self.dataplane = ptf.dataplane_instance
        self.dataplane.flush()

        self.device_id = 0

        self.channel = grpc.insecure_channel('localhost:50051')
        self.stub = p4runtime_pb2.P4RuntimeStub(self.channel)

        ConfigRequest = p4runtime_pb2.SetForwardingPipelineConfigRequest
        req = ConfigRequest()

        print "Connecting to device"
        req.action = ConfigRequest().VERIFY_AND_COMMIT
        config = req.configs.add()
        config.device_id = self.device_id

        print "Importing p4info proto from", proto_bin_path
        with open(proto_bin_path, "rb") as fin:
            config.p4info.ParseFromString(fin.read())

        # we save p4info for name -> id lookups
        self.p4info = config.p4info

        if self.target == "bmv2":
            device_config = p4config_pb2.P4DeviceConfig()
            extras = device_config.extras
            extras.kv["port"] = "9090"
            extras.kv["notifications"] = "ipc:///tmp/bmv2-0-notifications.ipc"
            config.p4_device_config = device_config.SerializeToString()

        rep = self.stub.SetForwardingPipelineConfig(req)
Ejemplo n.º 15
0
    def runTest(self):
        if testutils.test_param_get('target') != "hw":
            return
        seed = random.randint(1, 65535)
        logger.info("Seed used for Ports Test is %d", seed)
        random.seed(seed)
        # Get bfrt_info and set it as part of the test
        bfrt_info = self.interface.bfrt_info_get()
        # Initializing all tables
        self.port_table = bfrt_info.table_get("$PORT")
        self.port_hdl_info_table = bfrt_info.table_get("$PORT_HDL_INFO")
        self.port_fp_idx_info_table = bfrt_info.table_get("$PORT_FP_IDX_INFO")
        self.port_str_info_table = bfrt_info.table_get("$PORT_STR_INFO")

        # Setting up PTF dataplane
        self.dataplane = ptf.dataplane_instance
        self.dataplane.flush()
        CfgPortTableClearTest(self, 32)
        PortCfgTest(self, 32, 36)
        # model 4/0, hw 19/0
        PortHdlInfoTest(self, 8, 18, "18/0")
Ejemplo n.º 16
0
Archivo: common.py Proyecto: tatry/p4c
 def is_trace_logs_enabled(self):
     return testutils.test_param_get('trace') == 'True'
Ejemplo n.º 17
0
Archivo: common.py Proyecto: tatry/p4c
 def xdp2tc_mode(self):
     return testutils.test_param_get('xdp2tc')
Ejemplo n.º 18
0
def port_to_local_port(port):
    """ Given a port return its ID within a pipe. """
    local_port = port & 0x7F
    assert (local_port < 72)
    return local_port


def port_to_pipe(port):
    """ Given a port return the pipe it belongs to. """
    local_port = port_to_local_port(port)
    pipe = (port >> 7) & 0x3
    assert (port == make_port(pipe, local_port))
    return pipe


num_pipes = int(testutils.test_param_get('num_pipes'))
pipes = list(range(num_pipes))

swports = []
swports_by_pipe = {p: list() for p in pipes}
for device, port, ifname in config["interfaces"]:
    swports.append(port)
swports.sort()
for port in swports:
    pipe = port_to_pipe(port)
    swports_by_pipe[pipe].append(port)

# Tofino-1 uses pipes 0 and 2 as the external pipes while 1 and 3 are
# the internal pipes.
# Tofino-2 uses pipes 0 and 1 as the external pipes while 2 and 3 are
# the internal pipes.
Ejemplo n.º 19
0
#

import logging

from ptf import config
import ptf.testutils as testutils
from bfruntime_client_base_tests import BfRuntimeTest
import bfrt_grpc.bfruntime_pb2 as bfruntime_pb2
import bfrt_grpc.client as gc
import random

logger = logging.getLogger('Test')
if not len(logger.handlers):
    logger.addHandler(logging.StreamHandler())

num_pipes = int(testutils.test_param_get('num_pipes'))
pipes = list(range(num_pipes))

swports = []
for device, port, ifname in config["interfaces"]:
    pipe = port >> 7
    if pipe in pipes:
        swports.append(port)
swports.sort()


def VerifyReadRegisters(self, register_name_lo, register_name_hi,
                        register_value_lo, register_value_hi, data_dict):
    # since the table is symmetric and exists only in stage 0, we know that the response data is going to have
    # 8 data fields (2 (hi and lo) * 4 (num pipes) * 1 (num_stages)). bfrt_server returns all (4) register values
    # corresponding to one field id followed by all (4) register values corresponding to the other field id
Ejemplo n.º 20
0
    def runTest(self):
        if testutils.test_param_get('target') != "hw":
            logger.info(
                "This test is meant to be run only on hardware. Thus simply returning"
            )
            return

        eg_port = 50
        init_bytes_val = 123456
        init_pkts_val = 654321
        # Get bfrt_info and set it as part of the test
        bfrt_info = self.interface.bfrt_info_get("tna_counter")

        self.counter_table = bfrt_info.table_get(
            "SwitchIngress.indirect_counter")
        target = gc.Target(device_id=0, pipe_id=0xffff)
        # insert entry in the indirect counter table
        self.counter_table.entry_add(target, [
            self.counter_table.make_key(
                [gc.KeyTuple('$COUNTER_INDEX', eg_port)])
        ], [
            self.counter_table.make_data([
                gc.DataTuple('$COUNTER_SPEC_BYTES', init_bytes_val),
                gc.DataTuple('$COUNTER_SPEC_PKTS', init_pkts_val)
            ])
        ])

        num_read = 10
        logger.info("Reading Indirect Counter Table Entry for %d times",
                    num_read)
        self.readEntryHelper(target, eg_port, num_read, True, init_pkts_val,
                             init_bytes_val)

        # Change the lrt dr timeout to 10 milliseconds
        self.fixedObject.devport_mgr.devport_mgr_lrt_dr_timeout_set(
            target.device_id_, 10)
        hw_timeout = self.fixedObject.devport_mgr.devport_mgr_lrt_dr_timeout_get(
            target.device_id_)
        if hw_timeout != 10:
            logger.info(
                "Read timeout value %d doesn't match up with the expected %d",
                hw_timeout, 10)
            assert (0)
        time_req = self.readEntryHelper(target, eg_port, 1, True,
                                        init_pkts_val, init_bytes_val)
        logger.info("Reading Indirect Counter Table Entry for %d times",
                    num_read)
        time_req = self.readEntryHelper(target, eg_port, num_read, True,
                                        init_pkts_val, init_bytes_val)
        assert (time_req <= 15)

        # Change the lrt dr timeout back to the default value of 50 milliseconds
        self.fixedObject.devport_mgr.devport_mgr_lrt_dr_timeout_set(
            target.device_id_, 50)
        hw_timeout = self.fixedObject.devport_mgr.devport_mgr_lrt_dr_timeout_get(
            target.device_id_)
        if hw_timeout != 50:
            logger.info(
                "Read timeout value %d doesn't match up with the expected %d",
                hw_timeout, 50)
            assert (0)
        time_req = self.readEntryHelper(target, eg_port, 1, True,
                                        init_pkts_val, init_bytes_val)
        logger.info("Reading Indirect Counter Table Entry for %d times",
                    num_read)
        time_req = self.readEntryHelper(target, eg_port, num_read, True,
                                        init_pkts_val, init_bytes_val)
        assert (time_req > 15)
        assert (time_req <= 55)
Ejemplo n.º 21
0
    def runTest(self):
        ig_port = swports[1]
        num_pipes = int(testutils.test_param_get('num_pipes'))

        logger.info("[INFO-Switch] Adding TCAM Ranges for cardinality...")
        bfrt_info = self.interface.bfrt_info_get("fcm")
        card_range_tcam = bfrt_info.table_get(
            "SwitchIngress.fcmsketch.tb_fcm_cardinality")
        target = gc.Target(device_id=0, pipe_id=0xffff)

        NUM_FLOWS = 1000  # number of sample flows
        MAX_FLOW_SIZE = 10  # max size of flows
        num_packets = 0  # PTF generates 40 packets per second
        seed = 30669  # random seed
        random.seed(seed)
        logger.info("Seed used %d" % seed)

        # info of sample packet
        dmac = "00:11:22:33:44:55"
        ip_src = None  # random flow ID
        ip_dst = "192.168.1.1"
        ip_src_list = []

        # # Make sure the table starts off empty
        resp_empty = card_range_tcam.entry_get(target, None,
                                               {"from_hw": FROM_HW})
        for data, key in resp_empty:
            assert 0, "Shouldn't have hit here since table is supposed to be empty"

        # Insert TCAM Range Entries
        for i in range(1, n_entry - 1):
            if DEBUGGING:
                logger.info(
                    "Rule %d : Card %d <- range (%d, %d)", i,
                    int(lc_cardinality(float(range_table[i][0]),
                                       float(n_leaf))), range_table[i][0],
                    range_table[i][1])
            # add entry
            card_range_tcam.entry_add(target, [
                card_range_tcam.make_key([
                    gc.KeyTuple('$MATCH_PRIORITY', 1),
                    gc.KeyTuple('num_occupied_reg',
                                low=int(range_table[i][0]),
                                high=int(range_table[i][1]))
                ])
            ], [
                card_range_tcam.make_data([
                    gc.DataTuple(
                        'card_match',
                        int(
                            lc_cardinality(float(range_table[i][0]),
                                           float(n_leaf))))
                ], 'SwitchIngress.fcmsketch.fcm_action_set_cardinality')
            ])
        logger.info(
            "[INFO-Switch] TCAM Ranges %d entries are successfully added.",
            n_entry)

        # generate random packets and insert
        logger.info("[INFO-Switch] Sending %d flows on port %d", NUM_FLOWS,
                    ig_port)
        for i in range(NUM_FLOWS):
            flow_size = random.randint(1, MAX_FLOW_SIZE)  # 1 ~ 10
            num_packets += flow_size
            ip_src = "%d.%d.%d.%d" % (random.randint(
                0, 255), random.randint(0, 255), random.randint(
                    0, 255), random.randint(0, 255))
            ip_src_list.append((ip_src, flow_size))
            # sending packets
            pkt = testutils.simple_tcp_packet(eth_dst=dmac,
                                              ip_src=ip_src,
                                              ip_dst=ip_dst)
            testutils.send_packet(self, ig_port, pkt, count=flow_size)
            if (i % 100 is 0):
                logger.info("[INFO-Switch] %d / %d flows are done...", i,
                            NUM_FLOWS)

        logger.info("[INFO-Switch] Wait until packets are all received...")
        # check all packets are sent
        while True:
            register_pktcount = bfrt_info.table_get("SwitchIngress.num_pkt")
            register_pktcount.operations_execute(target, 'Sync')

            resp_pktcount = register_pktcount.entry_get(
                target, [
                    register_pktcount.make_key(
                        [gc.KeyTuple('$REGISTER_INDEX', 0)])
                ], {"from_hw": FROM_HW})
            data, _ = next(resp_pktcount)
            data_dict = data.to_dict()

            logger.info(
                "[INFO-Switch] Sent : %d, Received : %d\t\t wait 10s more...",
                num_packets, data_dict["SwitchIngress.num_pkt.f1"][0])
            if (data_dict["SwitchIngress.num_pkt.f1"][0] == num_packets):
                break
            time.sleep(10)

        assert data_dict["SwitchIngress.num_pkt.f1"][
            0] == num_packets, "Error: Packets are not correctly inserted..."

        # call the register values and get flow size estimation
        logger.info("[INFO-FCM] Start query processing...")
        ARE = 0
        AAE = 0
        Card_RE = 0
        for i in range(NUM_FLOWS):
            # Flow size

            ## depth 1, level 1
            hash_d1 = fcm_crc32(ip_src_list[i][0])
            register_l1_d1 = bfrt_info.table_get(
                "SwitchIngress.fcmsketch.sketch_reg_l1_d1")
            resp_l1_d1 = register_l1_d1.entry_get(target, [
                register_l1_d1.make_key(
                    [gc.KeyTuple('$REGISTER_INDEX', hash_d1 % SKETCH_W1)])
            ], {"from_hw": FROM_HW})
            data_d1, _ = next(resp_l1_d1)
            data_d1_dict = data_d1.to_dict()
            val_d1 = data_d1_dict[
                "SwitchIngress.fcmsketch.sketch_reg_l1_d1.f1"][0]
            # overflow to level 2?
            if (val_d1 is ADD_LEVEL1):
                register_l2_d1 = bfrt_info.table_get(
                    "SwitchIngress.fcmsketch.sketch_reg_l2_d1")
                resp_l2_d1 = register_l2_d1.entry_get(target, [
                    register_l2_d1.make_key(
                        [gc.KeyTuple('$REGISTER_INDEX', hash_d1 % SKETCH_W2)])
                ], {"from_hw": FROM_HW})
                data_d1, _ = next(resp_l2_d1)
                data_d1_dict = data_d1.to_dict()
                val_d1 = data_d1_dict[
                    "SwitchIngress.fcmsketch.sketch_reg_l2_d1.f1"][
                        0] + ADD_LEVEL1 - 1
                # overflow to level 3?
                if (val_d1 is ADD_LEVEL2):
                    register_l3_d1 = bfrt_info.table_get(
                        "SwitchIngress.fcmsketch.sketch_reg_l3_d1")
                    resp_l3_d1 = register_l3_d1.entry_get(
                        target, [
                            register_l3_d1.make_key([
                                gc.KeyTuple('$REGISTER_INDEX',
                                            hash_d1 % SKETCH_W3)
                            ])
                        ], {"from_hw": FROM_HW})
                    data_d1, _ = next(resp_l3_d1)
                    data_d1_dict = data_d1.to_dict()
                    val_d1 = data_d1_dict[
                        "SwitchIngress.fcmsketch.sketch_reg_l3_d1.f1"][
                            0] + ADD_LEVEL2 - 1

            ## depth 2, level 1
            hash_d2 = fcm_crc32_mpeg2(ip_src_list[i][0])
            register_l1_d2 = bfrt_info.table_get(
                "SwitchIngress.fcmsketch.sketch_reg_l1_d2")
            resp_l1_d2 = register_l1_d2.entry_get(target, [
                register_l1_d2.make_key(
                    [gc.KeyTuple('$REGISTER_INDEX', hash_d2 % SKETCH_W1)])
            ], {"from_hw": FROM_HW})
            data_d2, _ = next(resp_l1_d2)
            data_d2_dict = data_d2.to_dict()
            val_d2 = data_d2_dict[
                "SwitchIngress.fcmsketch.sketch_reg_l1_d2.f1"][0]
            # overflow to level 2?
            if (val_d2 is ADD_LEVEL1):
                register_l2_d2 = bfrt_info.table_get(
                    "SwitchIngress.fcmsketch.sketch_reg_l2_d2")
                resp_l2_d2 = register_l2_d2.entry_get(target, [
                    register_l2_d2.make_key(
                        [gc.KeyTuple('$REGISTER_INDEX', hash_d2 % SKETCH_W2)])
                ], {"from_hw": FROM_HW})
                data_d2, _ = next(resp_l2_d2)
                data_d2_dict = data_d2.to_dict()
                val_d2 = data_d2_dict[
                    "SwitchIngress.fcmsketch.sketch_reg_l2_d2.f1"][
                        0] + ADD_LEVEL1 - 1
                # overflow to level 3?
                if (val_d2 is ADD_LEVEL2):
                    register_l3_d2 = bfrt_info.table_get(
                        "SwitchIngress.fcmsketch.sketch_reg_l3_d2")
                    resp_l3_d2 = register_l3_d2.entry_get(
                        target, [
                            register_l3_d2.make_key([
                                gc.KeyTuple('$REGISTER_INDEX',
                                            hash_d2 % SKETCH_W3)
                            ])
                        ], {"from_hw": FROM_HW})
                    data_d2, _ = next(resp_l3_d2)
                    data_d2_dict = data_d2.to_dict()
                    val_d2 = data_d2_dict[
                        "SwitchIngress.fcmsketch.sketch_reg_l3_d2.f1"][
                            0] + ADD_LEVEL2 - 1

            if DEBUGGING:
                logger.info("[INFO-FCM] Flow %d - True : %d, Est of FCM : %d",
                            i, ip_src_list[i][1], min(val_d1, val_d2))

            final_query = min(val_d1, val_d2)
            ARE += abs(final_query - ip_src_list[i][1]) / float(
                ip_src_list[i][1])
            AAE += abs(final_query - ip_src_list[i][1]) / 1.0
        logger.info(
            bcolors.OKBLUE + "[INFO-FCM] Flow Size - ARE = %2.8f" +
            bcolors.ENDC, (ARE / NUM_FLOWS))
        logger.info(
            bcolors.OKBLUE + "[INFO-FCM] Flow Size - AAE = %2.8f" +
            bcolors.ENDC, (AAE / NUM_FLOWS))

        # # Cardinality

        ## check the cardinality parameter
        register_occupied_num = bfrt_info.table_get(
            "SwitchIngress.fcmsketch.reg_num_empty")
        resp_occupied_num = register_occupied_num.entry_get(
            target, [
                register_occupied_num.make_key(
                    [gc.KeyTuple('$REGISTER_INDEX', 0)])
            ], {"from_hw": FROM_HW})
        data, _ = next(resp_occupied_num)
        data_dict = data.to_dict()
        avg_occupied_leaf = math.floor(
            data_dict["SwitchIngress.fcmsketch.reg_num_empty.f1"][0] / 2.0)
        est_cardinality = match_table[int(avg_occupied_leaf)]
        Card_RE = abs(est_cardinality - NUM_FLOWS) / NUM_FLOWS
        logger.info(
            bcolors.OKBLUE +
            "[INFO-FCM] Cardinality RE = %0.9e (True : %d, Est of FCM : %d)" +
            bcolors.ENDC, Card_RE, NUM_FLOWS, est_cardinality)
Ejemplo n.º 22
0
import logging

from ptf import config
import ptf.testutils as testutils
from ptf.testutils import *
from bfruntime_client_base_tests import BfRuntimeTest, BaseTest
import bfrt_grpc.bfruntime_pb2 as bfruntime_pb2
import bfrt_grpc.client as gc
import random

logger = logging.getLogger('Test')
if not len(logger.handlers):
    logger.addHandler(logging.StreamHandler())

base_pick_path = testutils.test_param_get("base_pick_path")
binary_name = testutils.test_param_get("arch")
if binary_name is not "tofino2" and binary_name is not "tofino":
    assert 0, "%s is unknown arch" % (binary_name)

if not base_pick_path:
    base_pick_path = "install/share/" + binary_name + "pd/"

base_put_path = testutils.test_param_get("base_put_path")
if not base_put_path:
    base_put_path = "install/share/" + binary_name + "pd/forwarding"

logger.info("\nbase_put_path=%s \nbase_pick_path=%s", base_pick_path, base_put_path)

swports = []
for device, port, ifname in config["interfaces"]:
Ejemplo n.º 23
0
#
# Copyright (c) Intel Corporation
# SPDX-License-Identifier: CC-BY-ND-4.0
#

import logging
import time

from ptf import config
import ptf.testutils as testutils
from bfruntime_client_base_tests import BfRuntimeTest
import bfrt_grpc.client as client

g_arch = testutils.test_param_get("arch").lower()
g_is_tofino = (g_arch == "tofino")
g_is_tofino2 = (g_arch == "tofino2")

logger = logging.getLogger('Test')
if not len(logger.handlers):
    logger.addHandler(logging.StreamHandler())

swports = []
for device, port, ifname in config["interfaces"]:
    swports.append(port)
    swports.sort()


class SnapshotTest(BfRuntimeTest):
    def setUp(self):
        client_id = 0
        p4_name = "tna_snapshot"
Ejemplo n.º 24
0
    def runTest(self):
        target = client.Target(device_id=0, pipe_id=0xffff)
        seed = random.randint(1, 65535)
        logger.info("Seed used %d" % (seed))
        random.seed(seed)

        # Get bfrt_info and set it as part of the test
        bfrt_info = self.interface.bfrt_info_get("tna_meter_lpf_wred")
        meter_table = bfrt_info.table_get("SwitchIngress.meter")

        num_entries = 500
        meter_data = self.getMeterData(num_entries)

        logger.info("Adding %d entries to the Meter table", num_entries)
        for x in range(num_entries):
            meter_table.entry_add(
                target,
                [meter_table.make_key([client.KeyTuple('$METER_INDEX', x)])], [
                    meter_table.make_data([
                        client.DataTuple('$METER_SPEC_CIR_KBPS',
                                         meter_data['cir'][x]),
                        client.DataTuple('$METER_SPEC_PIR_KBPS',
                                         meter_data['pir'][x]),
                        client.DataTuple('$METER_SPEC_CBS_KBITS',
                                         meter_data['cbs'][x]),
                        client.DataTuple('$METER_SPEC_PBS_KBITS',
                                         meter_data['pbs'][x])
                    ])
                ])

        logger.info("Reading %d entries from the Meter table to verify",
                    num_entries)

        resp = meter_table.entry_get(target, None, {"from_hw": False})

        i = 0
        for data, key in resp:
            data_dict = data.to_dict()
            key_dict = key.to_dict()
            recv_cir = data_dict["$METER_SPEC_CIR_KBPS"]
            recv_pir = data_dict["$METER_SPEC_PIR_KBPS"]
            recv_cbs = data_dict["$METER_SPEC_CBS_KBITS"]
            recv_pbs = data_dict["$METER_SPEC_PBS_KBITS"]

            # Read back meter values are not always the same. It should be within a 2% error rate

            if abs(recv_cir -
                   meter_data['cir'][i]) > meter_data['cir'][i] * 0.02:
                assert 0
            if abs(recv_pir -
                   meter_data['pir'][i]) > meter_data['pir'][i] * 0.02:
                assert 0
            if abs(recv_cbs -
                   meter_data['cbs'][i]) > meter_data['cbs'][i] * 0.02:
                assert 0
            if abs(recv_pbs -
                   meter_data['pbs'][i]) > meter_data['pbs'][i] * 0.02:
                assert 0

            assert key_dict["$METER_INDEX"]['value'] == i
            i += 1
        logger.info("Deleting entries in the meter table")
        meter_table.entry_del(target)
        logger.info("Verifying that all entries were reset in the meter table")
        # Now get all the entries and check whether they were
        # reset to the defaults or not
        # Rate default values,i.e, for CIR and PIR depends upon clock speed
        # and hence checks are only enabled for model. Also, the clock speed
        # is different for tofino and tofino2 being 1.27 and 1.0 Ghz respectively
        # We come up with these values with reverse calculation from the
        # mantissa and exponent restrictions.
        resp = meter_table.entry_get(target, None, {"from_hw": False})
        for data, key in resp:
            data_dict = data.to_dict()
            key_dict = key.to_dict()
            if testutils.test_param_get("target") is not "hw":
                if g_is_tofino:
                    self.assertEqual(data_dict["$METER_SPEC_CIR_KBPS"],
                                     5195848221)
                    self.assertEqual(data_dict["$METER_SPEC_PIR_KBPS"],
                                     5195848221)
                elif g_is_tofino2:
                    self.assertEqual(data_dict["$METER_SPEC_CIR_KBPS"],
                                     4087999890)
                    self.assertEqual(data_dict["$METER_SPEC_PIR_KBPS"],
                                     4087999890)
            self.assertEqual(data_dict["$METER_SPEC_CBS_KBITS"], 4380866642)
            self.assertEqual(data_dict["$METER_SPEC_PBS_KBITS"], 4380866642)

        logger.info("All entries matched")
Ejemplo n.º 25
0
    def runTest(self):
        seed = random.randint(0, 10000000)
        logger.info("Seed used for Indirect Register Sync Test is %d", seed)
        random.seed(seed)
        ig_port = swports[1]
        reg_index = random.randint(0, 1023)
        dmac = '00:11:22:33:44:55'

        # Get bfrt_info and set it as part of the test
        bfrt_info = self.interface.bfrt_info_get("tna_register")

        register_table = bfrt_info.table_get("SwitchIngress.test_reg")
        reg_match_table = bfrt_info.table_get("SwitchIngress.reg_match")
        reg_match_table.info.key_field_annotation_add("hdr.ethernet.dst_addr",
                                                      "mac")

        register_value_hi = random.randint(0, 12345678)
        register_value_lo = random.randint(0, 23456789)
        register_value_hi_arr = {}
        register_value_lo_arr = {}
        num_pipes = int(testutils.test_param_get('num_pipes'))
        for i in range(num_pipes):
            register_value_hi_arr[i] = register_value_hi
            register_value_lo_arr[i] = register_value_lo

        pkt = testutils.simple_tcp_packet(eth_dst=dmac)
        exp_pkt = pkt

        # Program the same register values in all the 4 pipes
        logger.info(
            "Inserting entry in test_reg stful table with hi = %s lo = %s",
            str(register_value_hi), str(register_value_lo))
        target = gc.Target(device_id=0, pipe_id=0xffff)
        try:
            # insert entry in MAT and the indirect register table both
            register_table.entry_add(target, [
                register_table.make_key(
                    [gc.KeyTuple('$REGISTER_INDEX', reg_index)])
            ], [
                register_table.make_data([
                    gc.DataTuple('SwitchIngress.test_reg.first',
                                 register_value_lo),
                    gc.DataTuple('SwitchIngress.test_reg.second',
                                 register_value_hi)
                ])
            ])
            reg_match_table.entry_add(target, [
                reg_match_table.make_key(
                    [gc.KeyTuple('hdr.ethernet.dst_addr', dmac)])
            ], [
                reg_match_table.make_data([gc.DataTuple('idx', reg_index)],
                                          'SwitchIngress.register_action')
            ])

            # Apply table operations to sync the registers on the indirect register table
            logger.info("Syncing indirect stful registers")
            register_table.operations_execute(target, 'Sync')

            # Get from sw and check its value.
            logger.info(
                "Reading back the indirect stful registers for the programmed match entry"
            )
            resp = register_table.entry_get(target, [
                register_table.make_key(
                    [gc.KeyTuple('$REGISTER_INDEX', reg_index)])
            ], {"from_hw": False})
            # The values read back should match the initialized values
            logger.info("Verifying read back indirect register values")
            data, _ = next(resp)
            data_dict = data.to_dict()
            VerifyReadRegisters(self, "SwitchIngress.test_reg.first",
                                "SwitchIngress.test_reg.second",
                                register_value_lo_arr, register_value_hi_arr,
                                data_dict)
            logger.info(
                "Indirect Register values matched before seding packets")

            num_pkts = random.randint(1, 10)
            logger.info("Sending %d packets on port %d", num_pkts, ig_port)
            for i in range(num_pkts):
                testutils.send_packet(self, ig_port, pkt)
                testutils.verify_packet(self, pkt, ig_port)

            # Apply table operations to sync the registers on the indirect register table
            logger.info("Syncing indirect stful registers")
            register_table.operations_execute(target, 'Sync')

            # Get from sw and check its value. They should be the correct updated values now
            logger.info(
                "Reading back the indirect stful registers for the programmed match entry"
            )
            resp = register_table.entry_get(target, [
                register_table.make_key(
                    [gc.KeyTuple('$REGISTER_INDEX', reg_index)])
            ], {"from_hw": False})
            # Since the packet is sent on a single pipe only the register entry
            # from that pipe will be updated.
            ingress_pipe = ig_port >> 7
            register_value_lo_arr[ingress_pipe] = register_value_lo + (
                1 * num_pkts)
            register_value_hi_arr[ingress_pipe] = register_value_hi + (
                100 * num_pkts)
            logger.info("Verifying read back indirect register values")
            data, _ = next(resp)
            data_dict = data.to_dict()
            VerifyReadRegisters(self, "SwitchIngress.test_reg.first",
                                "SwitchIngress.test_reg.second",
                                register_value_lo_arr, register_value_hi_arr,
                                data_dict)
            logger.info(
                "Indirect Register values matched after seding packets")

        finally:
            logger.info(
                "Deleting entries from the match action and the indirect stful tables"
            )
            reg_match_table.entry_del(target)
            register_table.entry_del(target)
            logger.info(
                "Reading back the indirect register table and ensuring it got deleted"
            )
            resp = register_table.entry_get(target, [
                register_table.make_key(
                    [gc.KeyTuple('$REGISTER_INDEX', reg_index)])
            ], {"from_hw": True})
            for data, key in resp:
                data_dict = data.to_dict()
                assert data_dict["SwitchIngress.test_reg.first"] == data_dict["SwitchIngress.test_reg.second"]\
                    == [0]*num_pipes
Ejemplo n.º 26
0
    def runTest(self):
        ig_port = swports[1]
        smac = '00:11:22:33:44:55'
        seed = random.randint(0, 10000000)
        logger.info("Seed used for Direct Register Sync Test is %d", seed)
        random.seed(seed)

        # Get bfrt_info and set it as part of the test
        bfrt_info = self.interface.bfrt_info_get("tna_register")

        register_dir_table = bfrt_info.table_get("SwitchIngress.reg_match_dir")
        register_dir_table.info.key_field_annotation_add(
            "hdr.ethernet.src_addr", "mac")

        register_value_hi = random.randint(0, 12345678)
        register_value_lo = random.randint(0, 23456789)
        register_value_hi_arr = {}
        register_value_lo_arr = {}

        num_pipes = int(testutils.test_param_get('num_pipes'))
        for i in range(num_pipes):
            register_value_hi_arr[i] = register_value_hi
            register_value_lo_arr[i] = register_value_lo

        pkt = testutils.simple_tcp_packet(eth_src=smac)
        exp_pkt = pkt

        # Program the same register values in all the 4 pipes
        logger.info(
            "Inserting entry in reg_match_dir table and programming stful reg with hi = %s lo = %s",
            str(register_value_hi), str(register_value_lo))
        target = gc.Target(device_id=0, pipe_id=0xffff)
        try:
            # Insert entry in Match table
            register_dir_table.entry_add(target, [
                register_dir_table.make_key(
                    [gc.KeyTuple('hdr.ethernet.src_addr', smac)])
            ], [
                register_dir_table.make_data([
                    gc.DataTuple('SwitchIngress.test_reg_dir.first',
                                 register_value_lo),
                    gc.DataTuple('SwitchIngress.test_reg_dir.second',
                                 register_value_hi)
                ], 'SwitchIngress.register_action_dir')
            ])

            # Apply table operations to sync the direct registers
            logger.info("Syncing stful registers")
            register_dir_table.operations_execute(target, 'SyncRegisters')

            # Get from sw and check its value
            logger.info(
                "Reading back the stful registers for the programmed match entry"
            )
            resp = register_dir_table.entry_get(target, [
                register_dir_table.make_key(
                    [gc.KeyTuple('hdr.ethernet.src_addr', smac)])
            ], {"from_hw": False})
            # The values read back should match the initialized values
            logger.info("Verifying read back register values")
            data_dict = next(resp)[0].to_dict()
            VerifyReadRegisters(self, "SwitchIngress.test_reg_dir.first",
                                "SwitchIngress.test_reg_dir.second",
                                register_value_lo_arr, register_value_hi_arr,
                                data_dict)
            logger.info("Register values matched before sending packets")

            num_pkts = random.randint(1, 10)
            logger.info("Sending %d packets on port %d", num_pkts, ig_port)
            for i in range(num_pkts):
                testutils.send_packet(self, ig_port, pkt)
                testutils.verify_packet(self, pkt, ig_port)

            # Apply table operations to sync the direct registers
            logger.info("Syncing stful registers")
            register_dir_table.operations_execute(target, 'SyncRegisters')

            # Get from sw and check its value. They should be updated
            logger.info(
                "Reading back the stful registers for the programmed match entry"
            )
            resp = register_dir_table.entry_get(target, [
                register_dir_table.make_key(
                    [gc.KeyTuple('hdr.ethernet.src_addr', smac)])
            ], {"from_hw": False})

            # Since the packet is sent on a single pipe only the register entry
            # from that pipe will be updated.
            ingress_pipe = ig_port >> 7
            register_value_lo_arr[ingress_pipe] = register_value_lo + (
                1 * num_pkts)
            register_value_hi_arr[ingress_pipe] = register_value_hi + (
                100 * num_pkts)
            logger.info("Verifying read back register values")
            data_dict = next(resp)[0].to_dict()
            VerifyReadRegisters(self, "SwitchIngress.test_reg_dir.first",
                                "SwitchIngress.test_reg_dir.second",
                                register_value_lo_arr, register_value_hi_arr,
                                data_dict)
            logger.info("Register values matched after seding packets")

        finally:
            logger.info("Deleting entry from the table")
            register_dir_table.entry_del(target, [
                register_dir_table.make_key(
                    [gc.KeyTuple('hdr.ethernet.src_addr', smac)])
            ])
Ejemplo n.º 27
0
    import Queue as q

test_dir = sys.argv[sys.argv.index("--test-dir") + 1]
sys.path.append(test_dir + "/../../")
from tna_32q_multiprogram.test import *
del (MultiProgramFixedComponentTest)

logger = logging.getLogger('Test')
if not len(logger.handlers):
    formatter = logging.Formatter(
        '[%(levelname)s] (%(threadName)-10s) %(message)s')
    sh = logging.StreamHandler()
    sh.setFormatter(formatter)
    logger.addHandler(sh)

base_pick_path = testutils.test_param_get("base_pick_path")
binary_name = testutils.test_param_get("arch")
if binary_name is not "tofino2" and binary_name is not "tofino":
    assert 0, "%s is unknown arch" % (binary_name)

if not base_pick_path:
    base_pick_path = "install/share/" + binary_name + "pd/"

base_put_path = testutils.test_param_get("base_put_path")
if not base_put_path:
    base_put_path = "install/share/" + binary_name + "pd/forwarding"

logger.info("\nbase_put_path=%s \nbase_pick_path=%s", base_pick_path,
            base_put_path)

Ejemplo n.º 28
0
    def runTest(self):
        target = gc.Target(device_id=dev_id, pipe_id=0xffff)
        port_meta = self.bfrt_info.table_get("$PORT_METADATA")
        pass_one = self.bfrt_info.table_get("pass_one")
        pass_two_a = self.bfrt_info.table_get("pass_two_type_a")
        pass_two_b = self.bfrt_info.table_get("pass_two_type_b")
        pass_two_c = self.bfrt_info.table_get("pass_two_type_c")
        port = random.choice(swports)
        port_meta_values = [random.getrandbits(32), random.getrandbits(32)]
        a_f1 = random.getrandbits(8)
        a_f2 = random.getrandbits(16)
        a_f3 = random.getrandbits(32)
        a_md = random.getrandbits(64)
        b_f1 = random.getrandbits(8)
        b_md = random.getrandbits(64)
        c_f1 = random.getrandbits(16)
        c_f2 = random.getrandbits(16)
        c_f3 = random.getrandbits(16)
        c_md = random.getrandbits(64)
        pkt = testutils.simple_ip_packet()
        tof1 = testutils.test_param_get('arch') == 'tofino'

        try:
            # Add a port metadata entry to assign the metadata used in the table
            # key for the pass_one table.
            k = port_meta.make_key(
                [gc.KeyTuple('ig_intr_md.ingress_port', port)])
            d = port_meta.make_data([
                gc.DataTuple('f1', port_meta_values[0]),
                gc.DataTuple('f2', port_meta_values[1])
            ])
            port_meta.entry_add(target, [k], [d])

            # Add an entry to each of the pass two tables which validates the
            # metadata passed through the resubmit path.
            key_fields = [
                gc.KeyTuple('md.a.f1', a_f1),
                gc.KeyTuple('md.a.f2', a_f2),
                gc.KeyTuple('md.a.f3', a_f3)
            ]
            if not tof1:
                key_fields.append(gc.KeyTuple('md.a.additional', a_md))
            d = pass_two_a.make_data([], 'SwitchIngress.okay_a')
            pass_two_a.entry_add(target, [pass_two_a.make_key(key_fields)],
                                 [d])

            key_fields = [gc.KeyTuple('md.b.f1', b_f1)]
            if not tof1:
                key_fields.append(gc.KeyTuple('md.b.additional', b_md))
            d = pass_two_b.make_data([], 'SwitchIngress.okay_b')
            pass_two_b.entry_add(target, [pass_two_b.make_key(key_fields)],
                                 [d])

            key_fields = [
                gc.KeyTuple('md.c.f1', c_f1),
                gc.KeyTuple('md.c.f2', c_f2),
                gc.KeyTuple('md.c.f3', c_f3)
            ]
            if not tof1:
                key_fields.append(gc.KeyTuple('md.c.additional', c_md))
            d = pass_two_c.make_data([], 'SwitchIngress.okay_c')
            pass_two_c.entry_add(target, [pass_two_c.make_key(key_fields)],
                                 [d])

            # Clear the counters to ensure we are starting in a known state
            # since other tests may have sent traffic which incremented them.
            self.clrCntrs()

            # Add an entry to the pass_one table to cause the packet to resubmit
            # with the first resubmit type.
            k = pass_one.make_key([
                gc.KeyTuple("port", port),
                gc.KeyTuple("f1", port_meta_values[0]),
                gc.KeyTuple("f2", port_meta_values[1])
            ])
            d = pass_one.make_data([
                gc.DataTuple('f1', a_f1),
                gc.DataTuple('f2', a_f2),
                gc.DataTuple('f3', a_f3),
                gc.DataTuple('more_data', a_md)
            ], "SwitchIngress.resub_a")
            pass_one.entry_add(target, [k], [d])

            # Verify it works as expected. There should be one count at index 0
            # from the first pass and one count at index 1 for a resubmit type A.
            testutils.send_packet(self, port, pkt)
            testutils.verify_packet(self, pkt, port)
            c1 = self.getCntr(0)
            c2 = self.getCntr(1)
            self.assertEqual(c1, 1)
            self.assertEqual(c2, 1)

            # Now modify the entry to use the next resubmit type and verify it
            # also works.
            d = pass_one.make_data(
                [gc.DataTuple('f1', b_f1),
                 gc.DataTuple('more_data', b_md)], "SwitchIngress.resub_b")
            pass_one.entry_mod(target, [k], [d])
            testutils.send_packet(self, port, pkt)
            testutils.verify_packet(self, pkt, port)
            c1 = self.getCntr(0)
            c2 = self.getCntr(2)
            self.assertEqual(c1, 2)
            self.assertEqual(c2, 1)

            # Modify it again to use the third resubmit type and verify.
            d = pass_one.make_data([
                gc.DataTuple('f1', c_f1),
                gc.DataTuple('f2', c_f2),
                gc.DataTuple('f3', c_f3),
                gc.DataTuple('more_data', c_md)
            ], "SwitchIngress.resub_c")
            pass_one.entry_mod(target, [k], [d])
            testutils.send_packet(self, port, pkt)
            testutils.verify_packet(self, pkt, port)
            c1 = self.getCntr(0)
            c2 = self.getCntr(3)
            self.assertEqual(c1, 3)
            self.assertEqual(c2, 1)

        finally:
            port_meta.entry_del(target)
            pass_one.entry_del(target)
            pass_two_a.entry_del(target)
            pass_two_b.entry_del(target)
            pass_two_c.entry_del(target)
Ejemplo n.º 29
0
#
# Copyright (c) Intel Corporation
# SPDX-License-Identifier: CC-BY-ND-4.0
#

import logging
import random

import ptf.testutils as testutils
from bfruntime_client_base_tests import BfRuntimeTest
import bfrt_grpc.client as client

import base64

g_is_tofino = testutils.test_param_get("arch") == "tofino"
g_is_tofino2 = testutils.test_param_get("arch") == "tofino2"
assert g_is_tofino or g_is_tofino2

logger = logging.getLogger('Test')
if not len(logger.handlers):
    logger.addHandler(logging.StreamHandler())


def meterParamConvert(param):
    '''
    Converts a hex decoded meter parameter byte stream to an integer
    '''
    a = base64.b16encode(param)
    return int(a, 16)

Ejemplo n.º 30
0
Archivo: test.py Proyecto: wsobow/ptf
 def runTest(self):
     v = testutils.test_param_get('k1', default=-1)
     if v is None:
         print(">>>None")
     else:
         print(">>>k1={}".format(v))