Connecting Onos and P4 Dataplane in Simulation

Hello,

I’m new on P4 and now I’m working on my thesis, I have a problem connecting/integrating ONOS and P4, I need ONOS for monitoring and controlling my SDN Simulation, I need a tutorial on how to connect ONOS Controller and P4 Dataplane on Mininet Simulation, I was searched many websites and keywords but still have not found a good tutorial to connecting and setup ONOS+P4 configuration, sure I saw NGSDN-Tutorial but I still not know how that system can connecting ONOS+P4, can somebody explain to me or just passing me the resources-related about this.

Thanks,
heggiraihan

Hi,

My personal recommendation is that you do the NG-SDN tutorial, from Exercise 1 until you reach the last one. It takes a little bit of time, but you will be able to understand the way it works. Still, let me ask you some questions:

Which problem exactly?

What do you exactly mean by monitoring and controlling? Is monitoring just able to “see” the switches at the ONOS web GUI? Is controlling just to check the tables*? Is it installing rules?

OK, so this is the best summary I can provide you. However, I greatly encourage you to do all exercises one by one and read all READMEs. I will assume you will use ONOS and Stratum+BMv2. The way that ONOS works with P4 can be summarized in this way.

  • P4 programs will need the controller_header annotation. You can see this in Exercise 4. Using this annotation you can use the cpu_in_header_t and cpu_out_header_t headers to let the controller know the ingress port (P4Runtime PacketIn and PacketOut messages). ONOS (Stratum indeed) already knows that a specific header comes prepended before the header’s original packet as specified in the P4Info file. The inverse function happens in Stratum with a packet_out. Check them out here:
@controller_header("packet_in")
header cpu_in_header_t {
    port_num_t ingress_port;
    bit<7> _pad;
}

@controller_header("packet_out")
header cpu_out_header_t {
    port_num_t egress_port;
    bit<7> _pad;
}
  • If you want to create your applications, you shall do it, as usual, using the Templates provided by ONOS. See specific commands here. I still recommend using the NG-SDN VM and modifying the app for the tutorial for your own tests. It will just be easier.

  • How does ONOS tell the switch to load a P4 program? Before ONOS does anything, it needs the P4 program to be compiled (make app-build). If you check that command (see Makefile) and you follow the execution you will see that the command above does several things:

    1. Builds a P4 program with a docker container (see here)
    2. Copies the compiled program for BMv2 (bmv2.json file) and the P4info file (p4info.txt) to the ONOS app directory. (see here)
    3. Creates the .oar ONOS app package to be installed later on. This .oar package includes the bmv2.json file. (see here)

    You might ask, well, the bmv2.json is packaged along with the control plane ONOS app, but how does the program know it has to “inform” the switch to load the bmv2.json file? You can find this information in the PipeConfLoader.java file. Here an excerpt:

    private static final String P4INFO_PATH = "/p4info.txt";
    private static final String BMV2_JSON_PATH = "/bmv2.json";
    // more code
    @Activate
    public void activate() {
        //mode code
        try {
            pipeconfService.register(buildPipeconf());
        } catch (P4InfoParserException e) {
            log.error("Unable to register " + PIPECONF_ID, e);
        }
    }

    private PiPipeconf buildPipeconf() throws P4InfoParserException {

        final URL p4InfoUrl = PipeconfLoader.class.getResource(P4INFO_PATH);
        final URL bmv2JsonUrlUrl = PipeconfLoader.class.getResource(BMV2_JSON_PATH);
        final PiPipelineModel pipelineModel = P4InfoParser.parse(p4InfoUrl);

        return DefaultPiPipeconf.builder()
                .withId(PIPECONF_ID)
                .withPipelineModel(pipelineModel)
                .addBehaviour(PiPipelineInterpreter.class, InterpreterImpl.class)
                .addBehaviour(Pipeliner.class, PipelinerImpl.class)
                .addExtension(P4_INFO_TEXT, p4InfoUrl) // Here the path to the P4info file
                .addExtension(BMV2_JSON, bmv2JsonUrlUrl) // Here the path to the compiled P4 file
                .build();
    }

  • In general, you need three important files (this might vary from app to app), apart from the typical main control plane code: * PipeconfLoader.java, InterpreterImpl.java, PipelinerImpl.java. I cannot give you the best explanation on what each file does exactly. Still, I can tell you my interpretation.

    PipeconfLoader's main function seems to be the pipeconf registration. In other words, register the compiled P4 app, the P4info file, etc.

    PipelinerImpl's implements the Pipeliner and is associated with the ACL table of the P4 program. It is adapting the forwarding objectives to that particular table. For instance, if you check the code, you will see that it filters some treatments, so null treatment builders are discarded or any that is not equal to cloning to the CPU (because that is the main function of the ACL table). In the end, it keeps the Selector but adds “CloneToCPU” action (or Treatment). Once the rule is built, it is then applied (flowRuleService.applyFlowRules(ruleBuilder.build())) or removed.

    Finally, InterpreterImpl tries to build an “interpreter” app for the pipeline to it adapt operations like a PACKET_OUT to your specific pipeline. See buildPacketOut. First, it makes sure the PACKET_OUT port fits into the 9-bit wide port supported by the V1Model. It then builds the specific output port metadata (egress_port, which equals the packet_out P4 header name) and builds this “custom” packet_out action. These functions are necessary because all P4 programs are different, so there needs to be some kind of “adaptation”. Check the mapInboundPacket because the main function is the inverse one. It takes the received bytes and adapts them to a DefaultInboundPacket, because that (I believe) is the default way for ONOS to deal with packet_in messages. It is able to build a DefaultInboundPacket because the custom mapInboundPacket function can extract the metadata (in port), the original packet and so on.

  • Finally, you will also see a command in NG-SDN tutorial stated as make netcfg (see here). This command makes sure that ONOS can discover each switch appropriately. The command, as mentioned earlier, sends config files to ONOS to let it know switch port and IPs, the pipeconf that needs to be associated with each switch, the driver to be used, and so on. See an example here.

Cheers,

Yes, Monitoring just to see switches on ONOS GUI and for controlling to check the tables, thanks for your answer, I think I will spend my time doing the NGSDN-Tutorial example.

Thanks