Clone3 function on stratum_bmv2

Hi All,

I’m trying to use clone3 function on the stratum_bmv2 software switch, but cannot detect the cloned packets using the standard_metadata.instance_type value of the packet. Every packet seems NORMAL type instead of I2E clone type. No errors found on any log file during the execution of the P4 program.

These are the execution parameters of the stratum_bmv2 executable:

stratum_bmv2 -device_id=1 -chassis_config_file=<chassis_config_file> -forwarding_pipeline_configs_file=<pipeline_config_file>  
-persistent_config_dir=<persistent_file> -cpu_port=255 -external_stratum_urls=0.0.0.0:50001 -max_num_controllers_per_node=10 
-write_req_log_file=<write_reqs_file> -bmv2_log_level=debug -logtosyslog=true -logtostderr=true

I set up the P4 program using the ONOS controller, which works fine, except for the clone3 functionality.
Is there any configuration that I missed, during the launch of the program or the ONOS configuration, maybe any kind of clone session ID? Right now I’m using ID 10 on the clone3 function but I have used ID 500 previously.

Thanks

I am more familiar with the bmv2 software switch code in the repo GitHub - p4lang/behavioral-model: The reference P4 software switch, and I do not know which version of that code that stratum_bmv2 is using. I do know it has been a long time since anything in behavioral-model code changed in regard to controlling how the instance_type is assigned for cloned packets, and I have written tests for behavioral-model BMv2 that this works, about 5-6 years ago, and those tests are still regularly run and are passing.

If you know how to interpret the logs from executing your P4 program, I would recommend adding a “debug table” to your P4 code, as the first thing in the egress control’s apply block, so you can see what the value is for all metadata fields for all packets being processed in egress, e.g. like this one: p4-guide/v1model-special-ops/v1model-special-ops.p4 at master · jafingerhut/p4-guide · GitHub

Note: By “debug table” I simply mean a table with key fields for all of the fields you would like to see their value in the log while the packets are being processed, because the log shows the values of all key fields every time a table lookup is done. The table has no entries, and a const default_action of NoAction, so applying that table never changes how the packet is processed later.

It is definitely the case that if a clone session id is not configured, then in the initial state when your P4 program is loaded, attempting to clone a packet to it will cause it to be dropped, because the clone session has no information about where to send the packet.

I guessed that the clone function (I2E in this case) simply clones a packet that is redirected to the egress pipeline, so I thought that I did not need to configure an specific clone session ID. I Think I saw how to do it on bmv2 simple_switch or simple_switch_grpc, but I’m using stratum_bmv2 because i’m more familiar on how to connect it to the ONOS controller, and have no idea how to set up that kind of clone session ID, if it is even needed when launching the software switch.

About the debug tables, I’ve been using dummy tables with counters to see if a cloned packet reaches certain points of the execution but I had no luck. I’ll try to use the tables that you mentioned, I hope I can get those values on the log files.

And unfortunately I know nothing about how ONOS works, or if/how it configures clone sessions.

To help any other people who works with ONOS controller, I just found a solution that may be useful, which apparently appears to work. Thanks @andyfingerhut for suggesting the debug table, it really helped to debug quicker.

This is the java code that I used to configure clone sessions on my ONOS application:

private boolean setCloneSession(){

        P4RuntimeController controller = DefaultServiceDirectory.getService(P4RuntimeController.class);
        P4RuntimeClient client = controller.get(deviceId);
        if (client == null) {
            log.error("P4Runtime client not found for device {}", deviceId);
        }

        PiCloneSessionEntry cloneSessionEntry = PiCloneSessionEntry
                .builder()
                //This is the clone session ID used on the clone3 P4 function
                .withSessionId(CLONE_SESSION_ID) 
                //Port number used in this case represents CPU port on Stratum simple_switch
                .addReplica(new PiPreReplica(PortNumber.portNumber(255), 0))
                .build();

        PiPipeconf devicePipeconf = piPipeconfService.getPipeconf(deviceId).get();
        
        //Integer 1 is the P4DeviceId -devide_id param, at stratum_bmv2 launch
        //Also should be accesible through netcfg service I guess
        P4RuntimeWriteClient.WriteRequest writeRequest = client.write(1, devicePipeconf);

        writeRequest.insert(cloneSessionEntry);

        CompletableFuture<P4RuntimeWriteClient.WriteResponse> writeFuture = writeRequest.submit();
        // Handle the response
        writeFuture.thenAccept(success -> {
            if (success.isSuccess()) {
                log.info("✅ Successfully configured clone session {} on device {}", CLONE_SESSION_ID, deviceId);
            } else {
                log.error("❌ Failed to configure clone session {} on device {}", CLONE_SESSION_ID, deviceId);
            }
        });

        return true;
    }
1 Like