Introduction To P4 Programmable Data Planes Lab 3: P4 Program Building Blocks
Introduction To P4 Programmable Data Planes Lab 3: P4 Program Building Blocks
DATA PLANES
Award 2118311
“CyberTraining on P4 Programmable Devices using an Online Scalable
Platform with Physical and Virtual Switches and Real Protocol Stacks”
Lab 3: P4 Program Building Blocks
Contents
Overview ............................................................................................................................. 3
Objectives............................................................................................................................ 3
Lab settings ......................................................................................................................... 3
Lab roadmap ....................................................................................................................... 3
1 The PISA architecture.................................................................................................. 3
1.1 The PISA architecture ........................................................................................... 4
1.2 Programmable parser .......................................................................................... 4
1.3 Programmable match-action pipeline ................................................................. 5
1.4 Programmable deparser ...................................................................................... 5
1.5 The V1Model ........................................................................................................ 5
1.6 P4 program mapping to the V1Model ................................................................. 6
2 Lab topology................................................................................................................ 6
2.1 Starting host h1 and host h2 ................................................................................ 8
3 Navigating through the components of a basic P4 program ...................................... 8
3.1 Loading the programming environment .............................................................. 9
3.2 Describing the components of the P4 program ................................................... 9
3.3 Programming the pipeline sequence ................................................................. 14
4 Loading the P4 program............................................................................................ 15
4.1 Compiling and loading the P4 program to switch s1 ......................................... 15
4.2 Verifying the configuration ................................................................................ 17
5 Configuring switch s1 ................................................................................................ 18
5.1 Mapping the P4 program’s ports ....................................................................... 18
5.2 Loading the rules to the switch .......................................................................... 20
6 Testing and verifying the P4 program....................................................................... 21
References ........................................................................................................................ 23
Page 2
Lab 3: P4 Program Building Blocks
Overview
This lab describes the building blocks and the general structure of a P4 program. It maps
the program’s components to the Protocol-Independent Switching Architecture (PISA), a
programmable pipeline used by modern whitebox switching hardware. The lab also
demonstrates how to track an incoming packet as it traverses the pipeline of the switch.
Such capability is very useful to debug and troubleshoot a P4 program.
Objectives
Lab settings
The information in Table 1 provides the credentials of the machine containing Mininet.
Lab roadmap
Page 3
Lab 3: P4 Program Building Blocks
The Protocol Independent Switch Architecture (PISA)1 is a packet processing model that
includes the following elements: programmable parser, programmable match-action
pipeline, and programmable deparser, see Figure 1. The programmable parser permits
the programmer to define the headers (according to custom or standard protocols) and
to parse them. The parser can be represented as a state machine. The programmable
match-action pipeline executes the operations over the packet headers and intermediate
results. A single match-action stage has multiple memory blocks (e.g., tables, registers)
and Arithmetic Logic Units (ALUs), which allow for simultaneous lookups and actions.
Since some action results may be needed for further processing (e.g., data dependencies),
stages are arranged sequentially. The programmable deparser assembles the packet
headers back and serializes them for transmission. A PISA device is protocol independent.
The P4 program defines the format of the keys used for lookup operations. Keys can be
formed using packet header’s information. The control plane populates table entries with
keys and action data. Keys are used for matching packet information (e.g., destination IP
address) and action data is used for operations (e.g., output port).
Stage 1 Stage N
...
Packets Packets
Switch
ASIC
The programmable parser permits the programmer to define the headers (according to
custom or standard protocols) and to describe how the switch should process those
headers. The parser de-encapsulates the headers, converting the original packet into a
parsed representation of the packet. The programmer declares the headers that must be
recognized and their order in the packet. The parser can be represented as a state
machine without cycles (direct acyclic graph), with one initial state (start) and two final
states (accept or reject).
Page 4
Lab 3: P4 Program Building Blocks
The match-action pipeline implements the processing occurring at a switch. The pipeline
consists of multiple identical stages (N stages are shown in Figure 1). Practical
implementations may have 10/15 stages on the ingress and egress pipelines. Each stage
contains multiple match-action units (4 units per stage in Figure 1). A match-action unit
has a match phase and an action phase. During the match phase, a table is used to match
a header field of the incoming packet against entries in the table (e.g., destination IP
address). Note that there are multiple tables in a stage (4 tables per stage in Figure 1),
which permit the switch to perform multiple matches in parallel over different header
fields. Once a match occurs, a corresponding action is performed by the ALU. Examples
of actions include: modify a header field, forward the packet to an egress port, drop the
packet, and others. The sequential arrangement of stages allows for the implementation
of serial dependencies. For example, if the result of an operation is needed prior to
perform a second operation, then the compiler would place the first operation at an
earlier stage than the second operation.
The deparser assembles back the packet and serializes it for transmission. The
programmer specifies the headers to be emitted by the deparser. When assembling the
packet, the deparser emits the specified headers followed by the original payload of the
packet.
Ingress match-action and checksum verification Egress match-action and checksum verification
Page 5
Lab 3: P4 Program Building Blocks
The P4 program used in this lab is separated into different files. Figure 3 shows the
V1Model and its associated P4 files. These files are as follows:
• headers.p4: this file contains the packet headers’ and the metadata’s definitions.
• parser.p4: this file contains the implementation of the programmable parser.
• ingress.p4: this file contains the ingress control block that includes match-action
tables.
• egress.p4: this file contains the egress control block.
• deparser.p4: this file contains the deparser logic that describes how headers are
emitted from the switch.
• checksum.p4: this file contains the code that verifies and computes checksums.
• basic.p4: this file contains the starting point of the program (main) and invokes
the other files. This file must be compiled.
Ingress match-action and checksum verification Egress match-action and checksum verification
headers.p4 parser.p4 ingress.p4 egress.p4 deparser.p4
2 Lab topology
Let’s get started with creating a simple Mininet topology using MiniEdit. The topology
uses 10.0.0.0/8 which is the default network assigned by Mininet.
h1 s1 h2
10.0.0.1 10.0.0.2
Figure 4. Lab topology.
Page 6
Lab 3: P4 Program Building Blocks
Step 2. In the MiniEdit application, load the topology by clicking on File then Open.
Navigate to the lab3 folder and search for the topology file called lab3.mn and click on
Open. A new topology will be loaded to MiniEdit.
Step 3. The network must be started. Click on the Run button located at the bottom left
of MiniEdit’s window to start the emulation.
Page 7
Lab 3: P4 Program Building Blocks
Step 1. Right-click on host h1 and select Terminal. This opens the terminal of host h1 and
allows the execution of commands on that host.
Step 2. Test the connectivity between host h1 and host h2 by issuing the command below.
ping 10.0.0.2 -c 4
The figure above indicates no connectivity between host h1 and host h2 because there is
no program loaded on the switch.
Page 8
Lab 3: P4 Program Building Blocks
This section shows the steps required to compile the P4 program. It illustrates the editor
that will be used to modify the P4 program, and the P4 compiler that will produce a data
plane program for the software switch.
Step 1. Launch a Linux terminal by double-clicking on the icon located on the desktop.
Step 2. In the terminal, type the command below. This command launches the Visual
Studio Code (VS Code) and opens the directory where the P4 program for this lab is
located.
code ~/P4_Labs/lab3/
Figure 11. Launching the editor and opening the lab3 directory.
Step 1. Once the previous command is executed, VS Code will start. Click on basic.p4 in
the file explorer panel on the left hand side to open the P4 program in the editor.
Page 9
Lab 3: P4 Program Building Blocks
Figure 12. The main P4 file and how it includes other user-defined files.
The basic.p4 file includes the starting point of the P4 program and other files that are
specific to the language (core.p4) and to the architecture (v1model.p4). To make the P4
program easier to read and understand, we separated the whole program into different
files. Note how the files in the explorer panel correspond to the components of the
V1Model. To use those files, the main file (basic.p4) must include them first. For example,
to use the parser, we need to include the parser.p4 file (#include “parser.p4” ).
We will navigate through the files in sequence as they appear in the architecture.
Step 2. Click on the headers.p4 file to display the content of the file.
Page 10
Lab 3: P4 Program Building Blocks
The headers.p4 above shows the headers that will be used in our pipeline. We can see
that the ethernet and the IPv4 headers are defined. We can also see how they are
grouped into a structure ( struct headers ). The headers name will be used throughout
the program when referring to the headers. Furthermore, the file shows how we can use
typedef to provide an alternative name to a type.
Step 3. Click on the parser.p4 file to display the content of the parser.
Page 11
Lab 3: P4 Program Building Blocks
The figure above shows the content of the parser.p4 file. We can see that the parser is
already written with the name MyParser. This name will be used when defining the
pipeline sequence.
Step 4. Click on the ingress.p4 file to display the content of the file.
Page 12
Lab 3: P4 Program Building Blocks
The figure above shows the content of the ingress.p4 file. We can see that the ingress is
already written with the name MyIngress. This name will be used when defining the
pipeline sequence.
Step 5. Click on the egress.p4 file to display the content of the file.
The figure above shows the content of the egress.p4 file. We can see that the egress is
already written with the name MyEgress. This name will be used when defining the
pipeline sequence.
Step 6. Click on the checksum.p4 file to display the content of the file.
Page 13
Lab 3: P4 Program Building Blocks
The figure above shows the content of the checksum.p4 file. We can see that the
checksum is already written with two control blocks: MyVerifyChecksum and
MyComputeChecksum . These names will be used when defining the pipeline sequence.
Note that MyVerifyChecksum is empty since no checksum verification is performed in
this lab.
Step 7. Click on the deparser.p4 file to display the content of the file.
The figure above shows the content of the deparser.p4 file. We can see that the deparser
is already written with two instructions that reassemble the packet.
Step 1. Click on the basic.p4 file to display the content of the file.
Step 2. Write the following block of code at the end of the file
Page 14
Lab 3: P4 Program Building Blocks
V1Switch (
MyParser(),
MyVerifyChecksum(),
MyIngress(),
MyEgress(),
MyComputeChecksum(),
MyDeparser()
) main;
We can see here that we are defining the pipeline sequence according to the V1Model
architecture. First, we start by the parser, then we verify the checksum. Afterwards, we
specify the ingress block and the egress block, and we recompute the checksum. Finally,
we specify the deparser.
Step 1. Issue the following command in the terminal panel inside the Visual Studio Code
to compile the program.
p4c basic.p4
Page 15
Lab 3: P4 Program Building Blocks
Step 2. Type the command below in the terminal panel to download the basic.json file to
the switch s1’s filesystem. The script accepts as input the JSON output of the p4c compiler,
and the target switch name. If asked for a password, type the password password .
push_to_switch basic.json s1
Page 16
Lab 3: P4 Program Building Blocks
Step 1. Click on the MinEdit tab in the start bar to maximize the window.
Step 2. In MiniEdit, right-click on the P4 switch icon and start the Terminal.
Page 17
Lab 3: P4 Program Building Blocks
Note that the switch is running on an Ubuntu image started on a Docker container. Thus,
you will be able to execute any Linux command on the switch terminal.
Step 3. Issue the command ls on the terminal of the switch s1 that was opened in the
previous step.
ls
Figure 25. Displaying the contents of the current directory in the switch s1.
We can see that the switch contains the basic.json file that was downloaded to switch s1
after compiling the P4 program.
5 Configuring switch s1
Step 1. Issue the following command to display the interfaces on the switch s1.
ifconfig
Page 18
Lab 3: P4 Program Building Blocks
We can see that the switch has the interfaces s1-eth0 and s1-eth1. The interface s1-eth0
on the switch s1 connects host h1. The interface s1-eth1 on the switch s1 connects host
h2.
Figure 27. Starting the switch daemon and mapping the logical interfaces to Linux interfaces.
The --nanolog option is used to instruct the switch daemon that we want to see the
logs of the switch.
Page 19
Lab 3: P4 Program Building Blocks
s1-eth0 0 1 s1-eth1
Figure 28. Mapping of the logical interface numbers (0, 1) to the Linux interfaces (s1-eth0, s1-
eth1).
Step 2. Push the table entries to the switch by typing the following command.
Figure 30. Loading the forwarding table entries into switch s1.
Page 20
Lab 3: P4 Program Building Blocks
Step 1. Type the following command to initiate the nanolog client that will display the
switch logs.
nanomsg_client.py
Step 2. On host h2’s terminal, type the command below so that the host starts listening
for incoming packets.
./recv.py
Step 3. On host h1’s terminal, type the following command to send a packet to host h2.
Page 21
Lab 3: P4 Program Building Blocks
Now that the switch has a program with tables properly populated, the hosts are able to
reach each other.
The figure above shows the processing logic as the packet enters switch s1. The packet
arrives on port 0 ( port_in: 0 ), then the parser starts extracting the headers. After the
Page 22
Lab 3: P4 Program Building Blocks
parsing is done, the packet is processed in the ingress and in the egress pipelines. Then,
the checksum update is executed and the deparser reassembles and emits the packet
using port 1 ( port_out: 1 ).
This concludes lab 3. Stop the emulation and then exit out of MiniEdit.
References
Page 23