Page tree

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

Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 10 Next »

Work in progress

The content of this page is still work in progress

Introduction

P4 is a domain-specific language designed to allow programming of protocol-independent packet processors. Behavioral Model v2 (BMv2) is the reference P4 software switch. Initial support for this type of device has been included into ONOS 1.6 (Goldeneye) with the goal of providing a common groundwork to support programmable data planes in the next versions of ONOS.

This document will guide you through the necessary steps to program a network of BMv2 (virtual) devices using ONOS. This document assumes you are already familiar with ONOS, P4 and BMv2. In other words, we assume you are already able to run ONOS locally, you can write a P4 program and you already know how to build and run BMv2.

Contributors

AuthorOrganizationRoleEmail
Carmelo CasconeON.LabDevelopercarmelo@onlab.us

Features at a glance

By using ONOS 1.6, you'll be able to program a network of BMv2 devices with all the benefits of a logically centralized SDN platform. The following features are currently supported:

  • Device discovery / disconnection events
  • JSON configuration swap

  • Packet-ins and packet-outs

  • Match-action table population (via flow rule/objective/intent service)

  • Port statistics collections

  • Flow statistics collection

Overview

The figure below sketches the high-level architecture of the BMv2 integration in ONOS (click to zoom).

BMv2 integration in ONOS

On the northbound, ONOS provides a new Java API called "BMv2 Device Context Service" that can be used by applications to specify at runtime the JSON configuration of a given BMv2 device. Match-action tables can be populated using existing northbound services such a flow rule, flow objective on intents, with native support for non-standard P4 match and actions (via extension selectors and treatments).

On the southbound, ONOS speaks with BMv2 using Thrift. This project has been based on a customized version of the BMv2 “simple_switch” target that, differently from the original one, supports primitives for generating packet-ins to the controller and receiving packet-outs. The source code of onos-bmv2 is available here.

BMv2 device context

In order to enforce a given JSON configuration on a given device, applications needs to provide a “BMv2 Device Context”. Device contexts are used to bind together in a Java class a BMv2 JSON Configuration and an “Interpreter” implementation. Interpreters are used by ONOS to “understand” a given P4 program. They provide a mapping between ONOS objects and program-specific P4 objects (e.g. headers, actions, table names, etc.), allowing existing services and apps (e.g. host tracking, LLDP discovery, ARP proxy, reactive forwarding, etc.) to work with virtually any P4 program.

Interpreter

The Interpreter interface defines 3 types of mapping:

  1. ONOS table ID ↔ P4 table name

  2. Criterion's type ↔ P4 header instance’s field name

  3. Flow rule's treatment instance → BMv2 action instance

While for criteria and tables it is possible to specify a 1-to-1 relationship through a map, for Instructions the same is not possible or at least it wouldn't’ be convenient. The reason is that Instructions in ONOS are modeled after OpenFlow actions (which are protocol-dependent) and treatments (to be applied asconsequence of a match) are defined as list of Instructions. In P4 instead, actions are defined as a compound of low-level protocol-independent primitives (not expressible using ONOS Instructions), but, most important, P4 allows to specify only one action per table entry. That’s why we expect a programmer to write it’s own interpretation logic (i.e. code) that can map a given treatment instance to a BMv2 action instance.

Some questions you might have regarding interpreters:

 

  • Do I necessarily need to write an interpreter for my P4 program?
    No, interpreters are optional, meaning that a context can be created with an “empty” interpreter. In this case, you can’t expect other ONOS services to work with that given context. When not using an Interpreter or when creating flow rules based on non-standard match or actions, developers can use BMv2 extension treatment and selectors.
  • Do I need to provide a mapping for all the headers and actions defined in my P4 program?
    No, you can provide a mapping for only some of them. The general advice is to provide a mapping for those criterions and treatments used by other ONOS services you need in order to run your applications. Most of the times you can re-use the default interpreter.

"Default" context

When devices connect for the first time to ONOS a “default” context is applied, triggering a configuration swap  on the device and exposing to the system a default interpreter. Such a context is used to provide a minimum set of data plane capabilities for basic ONOS services and apps to work. The default context is based on a default.json BMv2 configuration, (compiled from default.p4) and  default interpreter implementation.

Non-standard match and actions

Code example of BMv2 extension selectors and treatments
ApplicationId myAppId = ...;
DeviceId myDeviceId = ...''
Bmv2DeviceContext myContext = ...;

Bmv2Configuration myConfiguration = myContext.configuration();

Ip4Prefix dstPrefix = Ip4Prefix.valueOf("192.16.184.0/24");

ExtensionSelector extSelector = Bmv2ExtensionSelector.builder()
        .forConfiguration(myConfiguration)
        .matchExact("standard_metadata", "ingress_port", 10)
        .matchLpm("ipv4", "dstAddr", dstPrefix.address().toOctets(), dstPrefix.prefixLength())
        .build();

ExtensionTreatment extTreatment = Bmv2ExtensionTreatment.builder()
        .forConfiguration(myConfiguration)
        .setActionName("next_hop")
        .addParameter("nhop_id", 4)
        .build();

FlowRule rule = DefaultFlowRule.builder()
        .forDevice(myDeviceId)
        .fromApp(myAppId)
        .forTable(0)
        .withSelector(DefaultTrafficSelector.builder()
                              .extension(extSelector, myDeviceId)
                              .build())
        .withTreatment(DefaultTrafficTreatment.builder()
                               .extension(extTreatment, myDeviceId)
                               .build())
        .build();

 

Developers guide (WIP)

ONOS+P4 development environment

bmv2.py Mininet script

  • Command samples to run a network of bmv2 devices connected to ONOS

BMv2 Device Context Service API

  • Prototype API for device configuration management, to be promoted to core APIs in the future
  • How to set a context for a given device?
    • Configuration swap enforcement
  • Why do I need to register the interpreter's class loader?

Known issues (WIP)

  • ...

Future work (WIP)

ONOS-3969 - Getting issue details... STATUS

  • No labels