Example #1
0
def set_fwd_config(test, client_id, action, bind=True):
    """@brief Helper function to send a set fwd config msg for both the programs
        tna_32q_multiprogram_a and tna_32q_multiprogram_b.
        Note, this function cannot be used for sending WARM_INIT_END, since
        it sends a config with it as well. WARM_INIT_END cannot accept a config.

        @param test The test object which has its own interface (Program A)
        @param clinet_id client ID
        @param action proto enum of VERIFY_AND_WARM_INIT_BEGIN or 
        VERIFY_AND_WARM_INIT_BEGIN_AND_END
        @param bind If this client needs to bind to the P4 as well
    """
    p4_name_to_put = p4_name_to_pick = p4_name = "tna_32q_multiprogram_a"
    profile_name_to_put = profile_name_to_pick = "profile_a"

    config_list = [
        gc.ForwardingConfig(
            p4_name_to_put, create_path_bf_rt(base_pick_path, p4_name_to_pick),
            [
                gc.ProfileInfo(
                    profile_name_to_put,
                    create_path_context(base_pick_path, p4_name_to_pick,
                                        profile_name_to_pick),
                    create_path_tofino(base_pick_path, p4_name_to_pick,
                                       profile_name_to_pick), external_pipes)
            ])
    ]

    p4_name_to_put = p4_name_to_pick = "tna_32q_multiprogram_b"
    profile_name_to_put = profile_name_to_pick = "profile_b"
    config_list.append(
        gc.ForwardingConfig(
            p4_name_to_put, create_path_bf_rt(base_pick_path, p4_name_to_pick),
            [
                gc.ProfileInfo(
                    profile_name_to_put,
                    create_path_context(base_pick_path, p4_name_to_pick,
                                        profile_name_to_pick),
                    create_path_tofino(base_pick_path, p4_name_to_pick,
                                       profile_name_to_pick), internal_pipes)
            ]))

    success = test.interface.send_set_forwarding_pipeline_config_request(
        action, base_put_path, config_list)
    if not success:
        raise RuntimeError("Failed to get response for setfwd")
    test.p4_name = p4_name
    if bind:
        test.interface.bind_pipeline_config(p4_name)
Example #2
0
    def setUp(self):
        client_id = 0

        p4_name_to_put = p4_name_to_pick = p4_name = "tna_register"
        profile_name_to_put = profile_name_to_pick = "pipe"

        # Setup and don't perform bind
        BfRuntimeTest.setUp(self, client_id, perform_bind=False)
        # Send a Verify_and_warm_init_begin_and_end
        logger.info("Sending Verify and warm_init_begin and warm_init_end for %s", p4_name_to_put)
        action = bfruntime_pb2.SetForwardingPipelineConfigRequest.VERIFY_AND_WARM_INIT_BEGIN_AND_END
        success = self.interface.send_set_forwarding_pipeline_config_request(
            action,
            base_put_path,
            [gc.ForwardingConfig(p4_name_to_put,
                                 create_path_bf_rt(base_pick_path, p4_name_to_pick),
                                 [gc.ProfileInfo(profile_name_to_put,
                                                 create_path_context(base_pick_path, p4_name_to_pick,
                                                                     profile_name_to_pick),
                                                 create_path_tofino(base_pick_path, p4_name_to_pick,
                                                                    profile_name_to_pick),
                                                 [0, 1, 2, 3])]
                                 )])
        if not success:
            raise RuntimeError("Failed to setFwd")

        self.p4_name = p4_name
        self.interface.bind_pipeline_config("tna_register")
Example #3
0
    def setP4ProgramList(self):
        cfg_list = []
        # By default program is loaded on all TOFINO pipelines
        pipe_id_list = [0, 1, 2, 3]

        try:
            if len(self.p4_name_list) == SINGLE:
                p4_name = self.p4_name_list[0]
                logger.warn("Setting config for: %s" % p4_name)
                cfg_list = [
                    gc.ForwardingConfig(
                        p4_name, self.bfrt_fp(self.p4_base, p4_name), [
                            gc.ProfileInfo(
                                self.profile_name,
                                self.cxt_fp(self.p4_base, p4_name,
                                            self.profile_name),
                                self.tna_fp(self.p4_base, p4_name,
                                            self.profile_name), pipe_id_list)
                        ])
                ]
                logger.warn("p4_base = %s" % self.p4_base)
            else:
                pipe_index = 0
                for p4_name in self.p4_name_list:
                    logger.warn("Setting config for: %s" % p4_name)
                    pfl_info_list = [
                        gc.ProfileInfo(
                            self.profile_name,
                            self.cxt_fp(self.p4_base, p4_name,
                                        self.profile_name),
                            self.tna_fp(self.p4_base, p4_name,
                                        self.profile_name), [pipe_index])
                    ]

                    fwd_cfg = gc.ForwardingConfig(
                        p4_name, self.bfrt_fp(self.p4_base, p4_name),
                        pfl_info_list)

                    cfg_list.append(fwd_cfg)
                    pipe_index = pipe_index + 1

            return cfg_list

        except Exception as e:
            logException(sys._getframe().f_code.co_name, e)
Example #4
0
    def runTest(self):
        # Only changing the name of the program from a to c
        # So it will be picked from a but put into c for testing purposes
        # The server should treat them as different programs
        p4_name_to_put = new_p4_name = "tna_32q_multiprogram_c"
        p4_name_to_pick = "tna_32q_multiprogram_a"
        profile_name_to_put = "profile_c"
        profile_name_to_pick = "profile_a"

        # Send a Verify and warm_init_begin and warm_init_end
        logger.info("Client 1:")
        action = bfruntime_pb2.SetForwardingPipelineConfigRequest.VERIFY_AND_WARM_INIT_BEGIN_AND_END
        config_list = [
            gc.ForwardingConfig(
                p4_name_to_put,
                create_path_bf_rt(base_pick_path, p4_name_to_pick), [
                    gc.ProfileInfo(
                        profile_name_to_put,
                        create_path_context(base_pick_path, p4_name_to_pick,
                                            profile_name_to_pick),
                        create_path_tofino(base_pick_path, p4_name_to_pick,
                                           profile_name_to_pick),
                        external_pipes)
                ])
        ]

        p4_name_to_put = p4_name_to_pick = "tna_32q_multiprogram_b"
        profile_name_to_put = profile_name_to_pick = "profile_b"
        config_list.append(
            gc.ForwardingConfig(
                p4_name_to_put,
                create_path_bf_rt(base_pick_path, p4_name_to_pick), [
                    gc.ProfileInfo(
                        profile_name_to_put,
                        create_path_context(base_pick_path, p4_name_to_pick,
                                            profile_name_to_pick),
                        create_path_tofino(base_pick_path, p4_name_to_pick,
                                           profile_name_to_pick),
                        internal_pipes)
                ]))

        success = self.a.interface.send_set_forwarding_pipeline_config_request(
            action, base_put_path, config_list)
        if not success:
            raise RuntimeError("Failed to get response for setfwd")

        # Check if client 1 has dropped out
        exception = self.a.interface.exception_q.get(timeout=5)
        if exception.grpc_error_get().code() != grpc.StatusCode.CANCELLED:
            logger.error("Did not receive cancelled for a")
            assert (0)
        # client 2 should not drop out
        logger.info("Client 2:")
        is_queue_empty = False
        try:
            exception = self.b.interface.exception_q.get(timeout=5)
        except q.Empty:
            logger.info("Did not receive cancelled for b. Expected behavior")
            is_queue_empty = True
            pass
        if not is_queue_empty:
            logger.error("Exception_queue was supposed to be empty")
            assert (0)

        # Check for WARM_INIT_FINISHED on client 2.
        success = self.b.interface.is_set_fwd_action_done(
            bfruntime_pb2.SetForwardingPipelineConfigResponseType.Value(
                "WARM_INIT_FINISHED"), 5, 5)
        if not success:
            raise RuntimeError("Failed to receive set fwd response")

        # Initiate subscribe and BIND for client 1
        logger.info("Client 1:")
        self.a.setUpBind(1, new_p4_name)
Example #5
0
    def runTest(self):
        p4_name_to_put = p4_name_to_pick = new_p4_name = "tna_ternary_match"
        profile_name_to_put = profile_name_to_pick = "pipe"
        # Send a Verify and warm_init_begin and warm_init_end
        logger.info(
            "Sending Verify and warm_init_begin and warm_init_end for %s",
            p4_name_to_put)
        action = bfruntime_pb2.SetForwardingPipelineConfigRequest.VERIFY_AND_WARM_INIT_BEGIN_AND_END
        success = self.a.interface.send_set_forwarding_pipeline_config_request(
            action, base_put_path, [
                gc.ForwardingConfig(
                    p4_name_to_put,
                    create_path_bf_rt(base_pick_path, p4_name_to_pick), [
                        gc.ProfileInfo(
                            profile_name_to_put,
                            create_path_context(base_pick_path,
                                                p4_name_to_pick,
                                                profile_name_to_pick),
                            create_path_tofino(base_pick_path, p4_name_to_pick,
                                               profile_name_to_pick),
                            [0, 1, 2, 3])
                    ])
            ])
        if not success:
            raise RuntimeError("Failed to setFwd")

        # Check if both the clients have dropped out
        exception = self.a.interface.exception_q.get(timeout=5)
        if exception.grpc_error_get().code() != grpc.StatusCode.CANCELLED:
            logger.error("Did not receive cancelled for a")
            assert (0)
        exception = self.b.interface.exception_q.get(timeout=5)
        if exception.grpc_error_get().code() != grpc.StatusCode.CANCELLED:
            logger.error("Did not receive cancelled for b")
            assert (0)

        # Initiate subscribe and BIND for client 1
        self.a.setUpBind(1, new_p4_name)

        # Try inserting a table entry in the new Program and test it
        target = gc.Target(device_id=0, pipe_id=0xffff)
        ig_port = get_port_from_pipes(external_pipes)
        eg_port = get_port_from_pipes(external_pipes)
        dip = '10.10.0.1'
        pkt = testutils.simple_tcp_packet(ip_dst=dip)
        exp_pkt = pkt
        self.a.bfrt_info = self.a.interface.bfrt_info_get(new_p4_name)
        self.a.forward_table = self.a.bfrt_info.table_get(
            "SwitchIngress.forward")
        self.a.forward_table.info.key_field_annotation_add(
            "hdr.ipv4.dst_addr", "ipv4")
        try:
            key = self.a.forward_table.make_key([
                gc.KeyTuple('$MATCH_PRIORITY', 1),
                gc.KeyTuple('vrf', 0),
                gc.KeyTuple('hdr.ipv4.dst_addr', dip, '255.255.0.0')
            ])
            data = self.a.forward_table.make_data(
                [gc.DataTuple('port', eg_port)], 'SwitchIngress.hit')
            self.a.forward_table.entry_add(target, [key], [data])

            # check get
            resp = self.a.forward_table.entry_get(target, [key],
                                                  {"from_hw": True})

            data_dict = next(resp)[0].to_dict()
            recv_port = data_dict["port"]
            if (recv_port != eg_port):
                logger.error("Error! port sent = %s received port = %s",
                             str(eg_port), str(recv_port))
                assert 0

            logger.info("Sending packet on port %d", ig_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, timeout=2)
        except Exception as e:
            logger.info("!!!! Test Failed!!!!")
            import traceback
            traceback.print_exc()
            raise e

        finally:
            self.a.forward_table.entry_del(target, [
                self.a.forward_table.make_key([
                    gc.KeyTuple('$MATCH_PRIORITY', 1),
                    gc.KeyTuple('vrf', 0),
                    gc.KeyTuple('hdr.ipv4.dst_addr', dip, '255.255.0.0')
                ])
            ])

            logger.info("Sending packet on port %d", ig_port)
            testutils.send_packet(self, ig_port, pkt)

            logger.info("Packet is expected to get dropped.")
            testutils.verify_no_other_packets(self)