diff --git a/apps/p4-tutorial/README.md b/apps/p4-tutorial/README.md index 1d11e17086..9373890ac4 100644 --- a/apps/p4-tutorial/README.md +++ b/apps/p4-tutorial/README.md @@ -1,7 +1,9 @@ # ONOS+P4 Tutorial -This directory contains the source code and instructions to run the ONOS+P4 -tutorial exercises. +This directory contains source code and instructions to run the ONOS+P4 +tutorial exercises. Goal of the exercises is to learn how to use ONOS to control +P4-capable devices via P4Runtime, and how to write ONOS apps to control custom +data plane capabilities implemented in P4. For help, please write to the mailing list [brigade-p4@onosproject.org](mailto:brigade-p4@onosproject.org) or check the @@ -21,12 +23,15 @@ following links: * * -For more information on the content of the VM, and minimum system requirements, +For more information on the content of the VM and minimum system requirements, [click here](/tools/dev/p4vm/README.md). ### VM credentials -The VM comes with one user with sudo privileges named `sdn` with password `rocks`. +The VM comes with one user with sudo privileges. Use these credentials to log in: + +* Username: `sdn` +* Password: `rocks` ## Overview @@ -36,15 +41,14 @@ These exercises are based on a simple P4 program called [mytunnel.p4](./pipeconf/src/main/resources/mytunnel.p4) designed for this tutorial. -To start, have a look a the P4 source code. Even if this is the first time you +To start, have a look a the P4 program. Even if this is the first time you see P4 code, the program has been commented to provide an understanding of the -pipeline behavior to anyone with basic programming and networking background -and an high level knowledge of P4. While checking the P4 program, try answering -to the following questions: +pipeline behavior to anyone with basic programming and networking background. +While checking the P4 program, try answering the following questions: * Which protocol headers are being extracted from each packet? * How can the parser distinguish a packet with MyTunnel encapsulation from one - without? + without? * How many match+action tables are defined in the P4 program? * What is the first table in the pipeline applied to every packet? * Which headers can be matched on table `t_l2_fwd`? @@ -61,28 +65,28 @@ The `mytunnel.p4` program is provided to ONOS as part of a "pipeconf". The main class used to implement the pipeconf is [PipeconfFactory.java](./pipeconf/src/main/java/org/onosproject/p4tutorial/pipeconf/PipeconfFactory.java). -This class is declared as an OSGi component which is "activated" once the -pipeconf app is loaded in ONOS. The main purpose of this class is to +This class is declared as an OSGi runtime component which is "activated" once +the pipeconf app is loaded in ONOS. The main purpose of this class is to instantiate the Pipeconf object and register that with the corresponding service in ONOS. This is where we associate ONOS driver behaviors with the pipeconf, and also define the necessary pipeconf extensions to be able to deploy the P4 program to a device. This pipeconf contains: - -* [mytunnel.json](/apps/p4-tutorial/pipeconf/src/main/resources/mytunnel.json): -The BMv2 JSON configuration used to execute the P4 program. This is an output of -the P4 compiler for BMv2. + +* [mytunnel.json](/apps/p4-tutorial/pipeconf/src/main/resources/mytunnel.json): +The JSON configuration used to execute the P4 program on BMv2. This is an output +of the P4 compiler for BMv2. * [mytunnel.p4info](/apps/p4-tutorial/pipeconf/src/main/resources/mytunnel.p4info): P4Info file obtained from the P4 compiler. -* [PipelineInterpreterImple.java](./pipeconf/src/main/java/org/onosproject/p4tutorial/pipeconf/PipelineInterpreterImpl.java): +* [PipelineInterpreterImpl.java](./pipeconf/src/main/java/org/onosproject/p4tutorial/pipeconf/PipelineInterpreterImpl.java): Implementation of the `PipelineInterpreter` ONOS driver behavior. The main purpose of this class is to provide a mapping between ONOS constructs and P4 program-specific ones, for example methods to map ONOS well-known header fields -and actions to those defined in the P4 program. For a more detailed explanation -of each method, check the +and packet forwarding/manipulation actions to those defined in the P4 program. +For a more detailed explanation of each method, check the [PipelineInterpreter interface](./core/api/src/main/java/org/onosproject/net/pi/model/PiPipelineInterpreter.java). * [PortStatisticsDiscoveryImpl.java](./pipeconf/src/main/java/org/onosproject/p4tutorial/pipeconf/PipelineInterpreterImpl.java): @@ -94,8 +98,9 @@ implementation works by reading the value of two P4 counters defined in ### MyTunnel App -This app is used to provide connectivity between each pair of hosts via -the MyTunnel protocol. The implementation can be found +This app is used to provide connectivity between each pair of hosts via the +MyTunnel protocol, a non-standard tunneling protocol created for this exercise. +The implementation of this app can be found [here](./mytunnel/src/main/java/org/onosproject/p4tutorial/mytunnel/MyTunnelApp.java), and it will be discussed in more details on Exercise 2. diff --git a/apps/p4-tutorial/exercise-1.md b/apps/p4-tutorial/exercise-1.md index af0dd4b555..631ea1f8fe 100644 --- a/apps/p4-tutorial/exercise-1.md +++ b/apps/p4-tutorial/exercise-1.md @@ -1,10 +1,10 @@ # ONOS+P4 Tutorial: Exercise 1 The goal of this exercise is to introduce P4 and P4Runtime support in ONOS, -along with the tools to practically experiment with it. This integration allows -existing applications in ONOS to communicate to and program P4 devices on the -network, and to operate in a pipeline agnostic manner, i.e. independently of the -P4 program. +along with the tools to practically experiment with it. In this exercise we will +see how the ONOS "pipeconf" mechanism allow one to re-use existing ONOS apps to +provide basic forwarding capabilities in a pipeline-agnostic manner, i.e. +independently of the P4 program. To run this exercise you will need multiple terminal windows (or tabs) to operate with the CLI of Mininet, ONOS, and BMv2. We use the following convention @@ -18,7 +18,7 @@ to distinguish between commands of different CLIs: ## Exercise steps -1. On terminal window 1, **start ONOS with a small subset of the applications** +1. On terminal window 1, **start ONOS with a small subset of the apps** by executing the following command: ``` @@ -43,6 +43,13 @@ by executing the following command: $ onos localhost ``` + You should now see the ONOS CLI command prompt. For a list of possible + commands that you can use here, type: + + ``` + onos> help onos + ``` + 2. Enter the following command to **activate the BMv2 driver**: ``` @@ -68,7 +75,7 @@ by executing the following command: Application org.onosproject.p4tutorial.pipeconf has been activated ``` - Note the specific name used for this pipeconf `p4-tutorial-pipeconf`. We + Please note the specific name used for this pipeconf `p4-tutorial-pipeconf`. We will later use this name to tell ONOS to deploy that specific P4 program to the switches. @@ -79,7 +86,7 @@ by executing the following command: onos> apps -a -s ``` - Make sure you see the following list of applications displayed: + Make sure you see the following list of apps displayed: ``` org.onosproject.generaldeviceprovider ... General Device Provider @@ -129,12 +136,9 @@ by executing the following command: sub-argument is used to tell ONOS which pipeconf to deploy on all devices. - If needed, you can run BMv2 with debug logging enabled by passing the - sub-argument `loglevel=debug`. For example: - - ``` - $ sudo -E mn [...] --switch onosbmv2,loglevel=debug,pipeconf=p4-tutorial-pipeconf [...] - ``` + The `--controller` argument specifies the address of the controller, + ONOS in this case, which is running on the same machine where we are + executing Mininet. 2. A set of **files are generated in the `/tmp` folder as part of this startup process**, to view them (on a separate terminal window): @@ -174,14 +178,14 @@ by executing the following command: $ less /tmp/bmv2-s1-log ``` - By scrolling the BMv2 log, you should see a number of P4Runtime messages - processed by the switch. These messages are used to install table - entries and to read counters. You should also see many `PACKET_IN` and - `PACKET_OUT` messages corresponding to packet-in/out processed by the - switch and used for LLDP-based link discovery. + By scrolling the BMv2 log, you should see all P4Runtime messages + received by the switch. These messages are sent by ONOS and are used to + install table entries and to read counters. You should also see many + `PACKET_IN` and `PACKET_OUT` messages corresponding to packet-in/out + processed by the switch and used for LLDP-based link discovery. Table entry messages are generated by ONOS according to the flow rules - generated by each application and based on the P4Info associated with + generated by each app and based on the P4Info associated with the `p4-tutorial-pipeconf`. If you prefer to watch the BMv2 log updating in real time, you can use @@ -194,7 +198,19 @@ by executing the following command: This command will show the log of the BMv2 switch in Mininet with name "s1". - 5. **Check the flow rules inserted by each application in ONOS**. In the + If needed, you can run BMv2 with **debug logging** enabled by passing + the sub-argument `loglevel=debug` when starting Mininet. For example: + + ``` + $ sudo -E mn [...] --switch onosbmv2,loglevel=debug,pipeconf=p4-tutorial-pipeconf [...] + ``` + + Debug logging in BMv2 is useful to observe the life of a packet inside the + pipeline, e.g. showing the header fields extracted by the parser for a + specific packet, the tables used to process the packets, matching table + entries (if any), etc. + + 5. **Check the flow rules inserted by each app in ONOS**. In the ONOS CLI type: ``` @@ -211,7 +227,7 @@ by executing the following command: ``` These flow rules are installed automatically for each device by the - Proxy ARP and LLDP Link Discovery applications. The first one is used to + Proxy ARP and LLDP Link Discovery apps. The first one is used to intercept ARP requests (`selector=[ETH_TYPE:arp]`), which are sent to the controller (`treatment=[immediate=[OUTPUT:CONTROLLER]`), who in turn will reply with an ARP response or broadcast the requests to all hosts. @@ -240,7 +256,7 @@ by executing the following command: On the BMv2 CLI prompt, type the following command: - ``` + ``` RuntimeCmd: table_dump c_ingress.t_l2_fwd ``` @@ -282,32 +298,32 @@ by executing the following command: ``` The **ping should NOT work**, and the reason is that we did not activate - yet any ONOS application providing connectivity between hosts. + yet any ONOS app providing connectivity between hosts. 2. While leaving the ping running on Mininet, **activate the Reactive - Forwarding application using the ONOS CLI**: + Forwarding app using the ONOS CLI**: ``` onos> app activate org.onosproject.fwd ``` Once activated, you should see the the ping working. Indeed, this - application installs the necessary flow rules to forward packets between + app installs the necessary flow rules to forward packets between the two hosts. 3. Use steps 3.v and 3.vi to **check the new flow rules**. You should see 3 new flow rules. - The Reactive Forwarding application works in the following way. It - installs a low priority flow objective to intercepts all IPv4 packets - via a `send_to_cpu` action (`[OUTPUT:CONTROLLER]` in ONOS) When a packet - is received by the control plane, the packet is processed by the - application which, by querying the Topology service and the Host - Location service is ONOS, computes the shortest path between the two - hosts, and installs higher priority flow rules on each hop to forward - packets between the two hosts (after having re-injected that packet in - the network via a packet-out). + The Reactive Forwarding app works in the following way. It installs a + low priority flow rule to intercepts all IPv4 packets via a + `send_to_cpu` action (`[OUTPUT:CONTROLLER]` in ONOS). When a packet is + received by the control plane, the packet is processed by the app, which + in turn, by querying the Topology service and the Host Location service + is ONOS, computes the shortest path between the two hosts, and installs + higher priority flow rules on each hop to forward packets between the + two hosts (after having re-injected that packet in the network via a + packet-out). 5. Congratulations, you completed the first exercise of the ONOS+P4 tutorial! @@ -325,6 +341,9 @@ Exercise 1 works with a more complex topology. $ sudo -E mn --custom $BMV2_MN_PY --switch onosbmv2,pipeconf=p4-tutorial-pipeconf --topo tree,3 --controller remote,ip=127.0.0.1 ``` + By using the argument `--topo` we are telling Mininet to emulate a Tree + topology with depth 3, i.e. with 7 switches, 6 links, and 8 hosts. + **Important:** due to the limited resources of the VM, when executing many switches in Mininet, it might happen that some flow rules are not installed correctly on the switch (showing state `PENDING_ADD` when using ONOS command @@ -332,7 +351,7 @@ Exercise 1 works with a more complex topology. that tries to re-install the failed entries. To force ONOS to perform this process more often, **make sure to apply step 2.v before starting Mininet**. -2. After you activated the Reactive Forwarding application as in step 4.ii., +2. After you activate the Reactive Forwarding app as in step 4.ii., you can ping all hosts in the network using the following Mininet command: ``` @@ -345,7 +364,9 @@ Exercise 1 works with a more complex topology. 3. You can visualize the topology using the ONOS web UI. Open a browser from within the tutorial VM (e.g. Firefox) to - [http://127.0.0.1:8181/onos/ui/](). When asked, use the username `onos` + . When asked, use the username `onos` and password `rocks`. You should see a nice tree topology. - While here, feel free to interact and discover the ONOS UI. + While here, feel free to interact with and discover the ONOS UI. For more + information on how to use the ONOS web UI please refer to this guide: + diff --git a/apps/p4-tutorial/exercise-2.md b/apps/p4-tutorial/exercise-2.md index 5ab33c53a6..a2a4b1c2d8 100644 --- a/apps/p4-tutorial/exercise-2.md +++ b/apps/p4-tutorial/exercise-2.md @@ -10,12 +10,12 @@ Similarly to exercise 1, in this example we want to provide connectivity between hosts of a network when using switches programmed with the `mytunnel.p4` program. Differently from exercise 1, forwarding between hosts will be provided by the MyTunnel app, instead of Reactive Forwarding. The MyTunnel app provides -connectivity by programming the dataplane to forward packets via the MyTunnel +connectivity by programming the data plane to forward packets using the MyTunnel protocol. -Before starting, we suggest to open the onos/apps/p4-tutorial directory in your -editor of choice for an easier access to the different files of this exercise. -For example, if using atom: +Before starting, we suggest to open the `onos/apps/p4-tutorial` directory in +your editor of choice for an easier access to the different files of this +exercise. For example, if using the Atom editor: ``` $ atom $ONOS_ROOT/apps/p4-tutorial/ @@ -36,15 +36,15 @@ header my_tunnel_t { ``` A switch implementing the MyTunnel protocol can forward packets using three -different forwarding behaviors: +different forwarding behaviors. 1. **Ingress**: for IPv4 packets received at a edge switch, i.e. the first node in the tunnel path, the MyTunnel header is applied with an arbitrary tunnel identifier decided by the control plane. 2. **Transit**: for packets with the MyTunnel header processed by an -intermediate node in the tunnel path, the switch simply forwards the packet by -looking at the tunnel ID field. +intermediate node in the tunnel path. When operating in this mode, the switch +simply forwards the packet by looking at the tunnel ID field. 3. **Egress**: for packets with the MyTunnel header processed by the last node in the path, the switch removes the MyTunnel header before forwarding the packet @@ -64,7 +64,7 @@ header with a given tunnel ID (action parameter). * `t_tunnel_fwd`: this table is used to implement both the transit and egress behaviors. It matches on the tunnel ID, and allows two different actions, `set_out_port` and `my_tunnel_egress`. `set_out_port` is used to set the -output port where the packet should be transmitted, without further +output port where the packet should be transmitted without further modifications. With `my_tunnel_egress`, the packet is stripped of the MyTunnel header before setting the output port. @@ -74,20 +74,21 @@ To begin, open [MyTunnelApp.java](./mytunnel/src/main/java/org/onosproject/p4tutorial/mytunnel/MyTunnelApp.java) in your editor of choice, and familiarize with the app implementation. -The file is located here: +For example, if using the Atom editor: ``` -$ONOS_ROOT/apps/mytunnel/src/main/java/org/onosproject/p4tutorial/mytunnel/MyTunnelApp.java +$ atom $ONOS_ROOT/apps/p4-tutorial/mytunnel/src/main/java/org/onosproject/p4tutorial/mytunnel/MyTunnelApp.java ``` The MyTunnel app works by registering an event listener with the ONOS Host Service (`class InternalHostListener` at line 308). This listener is used to notify the MyTunnel app every time a new host is discovered. Host discovery is -performed by the Proxy-ARP app. Each time an ARP request is received (via -packet-in), ONOS learns the location of the sender of the ARP request, before -generating an ARP reply or forwarding the requests to other hosts. When learning -the location of a new host, ONOS informs all apps that have registered a -listener with an `HOST_ADDED` event. +performed by means of two ONOS core services: Host Location Provider and +Proxy-ARP app. Each time an ARP request is received (via packet-in), ONOS learns +the location of the sender of the ARP request, before generating an ARP reply or +forwarding the requests to other hosts. When learning the location of a new +host, ONOS informs all apps that have registered a listener with an `HOST_ADDED` +event. Once an `HOST_ADDED` event is notified to the MyTunnel app, this creates two unidirectional tunnels between that host and any other host previously @@ -112,7 +113,7 @@ egress behaviors. **Spoiler alert:** There is a reference solution in the same directory as MyTunnelApp.java. Feel free to compare your implementation to the - reference. + reference one. 2. **Start ONOS with and all the apps**. @@ -134,7 +135,7 @@ egress behaviors. ``` onos> app activate org.onosproject.drivers.bmv2 onos> app activate org.onosproject.p4tutorial.pipeconf - onos> app activate org.onosproject.p4tutorial.pipeconf + onos> app activate org.onosproject.p4tutorial.mytunnel ``` **Hint:** To avoid accessing the CLI to start all applications, you can @@ -155,20 +156,21 @@ egress behaviors. You should see an output like this: ``` - * 5 org.onosproject.hostprovider 1.14.0.SNAPSHOT Host Location Provider - * 6 org.onosproject.lldpprovider 1.14.0.SNAPSHOT LLDP Link Provider - * 16 org.onosproject.proxyarp 1.14.0.SNAPSHOT Proxy ARP/NDP - * 20 org.onosproject.drivers 1.14.0.SNAPSHOT Default Drivers - * 42 org.onosproject.protocols.grpc 1.14.0.SNAPSHOT gRPC Protocol Subsystem - * 43 org.onosproject.protocols.p4runtime 1.14.0.SNAPSHOT P4Runtime Protocol Subsystem - * 44 org.onosproject.p4runtime 1.14.0.SNAPSHOT P4Runtime Provider - * 50 org.onosproject.generaldeviceprovider 1.14.0.SNAPSHOT General Device Provider - * 51 org.onosproject.drivers.p4runtime 1.14.0.SNAPSHOT P4Runtime Drivers - * 52 org.onosproject.p4tutorial.pipeconf 1.14.0.SNAPSHOT P4 Tutorial Pipeconf - * 79 org.onosproject.pipelines.basic 1.14.0.SNAPSHOT Basic Pipelines - * 90 org.onosproject.protocols.gnmi 1.14.0.SNAPSHOT gNMI Protocol Subsystem - * 91 org.onosproject.drivers.gnmi 1.14.0.SNAPSHOT gNMI Drivers - * 160 org.onosproject.drivers.bmv2 1.14.0.SNAPSHOT BMv2 Drivers + org.onosproject.hostprovider ... Host Location Provider + org.onosproject.lldpprovider ... LLDP Link Provider + org.onosproject.proxyarp ... Proxy ARP/NDP + 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.generaldeviceprovider ... General Device Provider + org.onosproject.drivers.p4runtime ... P4Runtime Drivers + org.onosproject.p4tutorial.pipeconf ... P4 Tutorial Pipeconf + org.onosproject.pipelines.basic ... Basic Pipelines + org.onosproject.protocols.gnmi ... gNMI Protocol Subsystem + org.onosproject.drivers.gnmi ... gNMI Drivers + org.onosproject.drivers.bmv2 ... BMv2 Drivers + org.onosproject.p4tutorial.mytunnel ... MyTunnel Demo App ``` 4. (optional) **Change flow rule polling interval**. Run the following @@ -218,20 +220,16 @@ window type: You should see 0 hosts, as we have not injected any ARP packet yet. -5. **Ping hosts** +5. **Ping hosts**, on the Mininet CLI, type: - 1. On the Mininet CLI, type: + ``` + mininet> h1 ping h7 + ``` - ``` - mininet> h1 ping h7 - ``` - - If the implementation of MyTunnelApp.java has been completed correctly, - ping should work. If not, check the reference solution in the same - directory as MyTunnelApp.java. - - 2. Check the ONOS log, you should see messages from the MyTunnel app setting - up the tunnel. + If the implementation of MyTunnelApp.java has been completed correctly, + ping should work. If not, check the ONOS log for possible errors in the + MyTunnel app. As a last resort, please check the reference solution in + the same directory as MyTunnelApp.java and compare that to yours. 6. **Look around**.