Page tree

Have questions? Stuck? Please check our FAQ for some common questions and answers.

This wiki documents the current development version of ONOS (master). Refer to the Wiki Archives for documentation for all previous versions of ONOS.

Skip to end of metadata
Go to start of metadata

In this tutorial, you will learn how to set up and ONOS environment capable of controlling P4Runtime-enabled Tofino-based devices. The following set of instructions have been tested with the EdgeCore Wedge-100BF.


  • 1 or more Tofino based switches with Barefoot SDE 6.0.0 or later installed
  • 1 server with the latest ONOS master downloaded. the version has to be 1.12-SNAPSHOT or later.

Prepare the switch

With the SDE and all necessary tools installed the switch process can be started.

Start switchd
bf_switchd --install-dir $SDE_INSTALL --conf-file $SDE_INSTALL/share/p4/targets/skip_p4.conf --skip-p4

It's worth noting the configuration file (skip_p4.conf). This configuration option makes switchd start with no P4 program deployed. The program will be later deployed by ONOS using P4Runtime.  Please also note that the skip_p4.conf file will only be installed if the SDE is built & installed with the p4_examples. Otherwise, this file can be found in the p4_examples tarball in the SDE package with the name

Create a Pipeconf for your P4 program

To build a pipeconf for your p4 program and make ONOS capable of installing it on the device and controlling it you need to write an application

The application must live under onos/pipelines/<p4 program name> and must contain at least two classes:

  • implementation of
  • implementation of

An example of such application can be found under onos/pipeconfs/default this contains the default.p4 P4_16 program, the DefaultPipeconf, DefaultInterpreter and other classes related to the Default.p4 program.


The interpreter is what enables ONOS to understand the specific constructs of your P4 Program. For example the Interpreter enables the translation from Traffic treatments into P4 defined Actions.

You can see an example of an interpreter for the default.p4 program in the class. 


The PiPipeconfFactory is where you piece together all the needed elements for ONOS to understand your P4 program.

You need:

  • bmv2 generated json for your program. 
  • P4Info for your program. 
  • Tofino.bin binary file
  • Tofino context.json file

The bmv2 json and the P4Info can be generated through. 

bmv2 json and P4Info
p4c-bm2-ss default.p4 --p4-16 -o default.json --p4runtime-file default.p4info --p4runtime-format text

This command uses the frontend compiler only.

The Tofino.bin and the context.json can be generated only with a Barefoot SDE and the attached Tofino specific backend compiler. For more information write to 

An example of a Pipeconf builder:

Pipeconf Builder
return DefaultPiPipeconf.builder()
        .withId(new PiPipeconfId(format(PIPECONF_ID_BASE, system)))
        .addBehaviour(PiPipelineInterpreter.class, DefaultP4Interpreter.class)
        .addBehaviour(Pipeliner.class, DefaultSingleTablePipeline.class)
        .addBehaviour(PortStatisticsDiscovery.class, DefaultP4PortStatisticsDiscovery.class)
        .addExtension(P4_INFO_TEXT, p4InfoUrl)
        .addExtension(BMV2_JSON, jsonUrl)
        .addExtension(TOFINO_BIN, tofinoUrl)
        .addExtension(TOFINO_CONTEXT_JSON, contextUrl)

As you can see we are giving the 4 needed files. We are also compiling the pipeline model from the BMv2 json and adding the Interpreter behaviour. In the Pipeconf Builder you can also add other behaviours, specific to the P4 program such as the Pipeliner and the PortStatisticsDiscovery needed to leverage existing ONOS functionality. 

We are also setting a PipeconfId, this is the unique Id ONOS will use to reference the Pipeconf and that we will use in the net-cfg.json later.

The Pipeconf factory can also be the component that reports the pipeconf to the PiPipeconfService through the registerPipeconf method.

Run ONOS and bring the Pipeconf

Moving to the ONOS controller on the server, assuming you downloaded it and placed your pipeconf in it.


You need to run it:

Start ONOS
$ buck run onos-local -- clean debug

It's worth noting that this start ONOS in a single instance cluster. The command also build ONOS and purges any previous state. The debug option offers the possibility to attach the debugger on port 5005. 

Login into the ONOS CLI

Having Started ONOS we need to login in it's CLI.

onos localhost

Start the Pipeconf

Having Started ONOS we need to start the pipeconf.

Start ONOS
onos> app activate <pipeconf_app_name>

Start the Barefoot driver

Having Started ONOS we need to start the toxin drivers.

Activate Drivers
onos> app activate

This command brings in all the needed applications to interact with the switch.

Verify the active applications

please type

apps -s -a

and verify that these app at least are active in your ONOS environment:

  • org.onosproject.generaldeviceprovider (General Device Provider)

  • org.onosproject.drivers (Default Drivers)

  • org.onosproject.protocols.grpc (gRPC Protocol Subsystem)

  • org.onosproject.protocols.p4runtime (P4Runtime Protocol Subsystem)

  • org.onosproject.p4runtime (P4Runtime Provider)

  • org.onosproject.drivers.p4runtime (P4Runtime Drivers)

  • (Barefoot Drivers)

  • your own pipeconf app.

Build and push a configuration json

Having all the needed components in ONOS in place we can now tell ONOS about the device(s) and let the interaction begin.

First we need to create a .json file containing all the needed information such as IP/Port of the device, it's ports and the pipeconf we want to deploy.

  "devices": {
    "device:<name>": {
      "generalprovider": {
        "p4runtime": {
          "ip": "<ip>",
          "port": "<port>",
          "deviceId": <id_of_device>
      "piPipeconf": {
        "piPipeconfId": "<name of your pipeconf>"
      "ports": {
        <ports of 
      "basic": {
        "name": "<freindly_name>",
        "latitude": 41,
        "driver": "tofino",
        "longitude": -107

A working example is in $ONOS_ROOT/tools/test/topos/tofino-demo-simple.json. Change the IP both in the DeviceId at the top and in the devices array. The port number by default on gRPC is 50051, so unless you made any changes to that leave it as is. 
Please note that you need to add the driver as "tofino" and the the piPipeconfId as the name of your pipeconf.

 Upload the configuration you just wrote to the instance of ONOS you are running:

$ curl -X POST -H "content-type:application/json" http://localhost:8181/onos/v1/network/configuration -d @<path_to_your_json_configuration_file> --user onos:rocks


<your_machine>~$ onos-netcfg localhost <path_to_your_json_configuration_file>

This configuration gets picked up by the that 

Check if the device is present in ONOS:

onos> devices

Configure ports on the device

The last step to perform is to configure the ports on the switch.

Please repeat the following command for all the ports that you need on your device. This needs to be done after having pushed the pipeline config. 

bf-sde> pm> show> port-add 1/0 100G NONE> port-enb 1/0


At this point if everything went smoothly you should be able to push rules defined with PiCriterion and PiInstruction according to the P4 program deployed on the device. 

  • No labels