DPDK Setup Guide
This document explains how to build, install, and run P4 Control Plane for the DPDK target.
Prerequisites
It is assumed that the DPDK SDE dependencies have been installed on the
system. The list of dependencies can be found
in sde/tools/setup/install_dep.py
file.
Prerequisites for stratum-deps are assumed to be installed. Some of them also apply to networking-recipe.
Install the following packages for building networking-recipe.
For Fedora:
yum install libatomic libnl3-devel
pip3 install -r requirements.txt
For Ubuntu:
apt install libatomic1 libnl-route-3-dev
pip3 install -r requirements.txt
See the OpenSSL security guide for information on installing OpenSSL.
Build and install DPDK SDE
Clone the repository used to build the DPDK SDE:
git clone --recursive https://github.com/p4lang/p4-dpdk-target.git p4sde
Follow the build and installation instructions in the P4 SDE Readme.
Remember the directory in which you install the DPDK SDE.
You will need it to define the SDE_INSTALL
environment variable.
Build and install stratum dependencies
Clone the repository used to build the Stratum dependencies:
git clone --recursive https://github.com/ipdk-io/stratum-deps.git
Now follow the instructions in the Building Host Dependencies document.
Remember the directory in which you install the Stratum dependencies.
You will need it to define the DEPEND_INSTALL
environment variable.
Define environment variables
Define the following environment variables. They supply default values to the build system and helper scripts.
Variable |
Definition |
---|---|
|
Path to the directory in which the Stratum dependencies are installed. |
|
Path to the directory in which the DPDK SDE is installed. |
Build networking recipe
Clone repository
Clone the repository used to build P4 Control Plane:
git clone --recursive https://github.com/ipdk-io/networking-recipe.git p4cp.recipe
cd p4cp.recipe
export P4CP_RECIPE=`pwd`
Compile the recipe
$P4CP_RECIPE/make-all.sh --target=dpdk --rpath
By default, make-all.sh will create an install
folder in the networking-recipe
directory in which to install the build artifacts. You can specify a different
directory by means of the --prefix
parameter.
See the make-all.sh user guide for information
about the options of the make-all.sh
helper script.
Define P4CP_INSTALL
We recommend that you define the following environment variable:
Variable |
Definition |
---|---|
|
Path to the directory in which the P4 Control Plane build artifacts are installed. |
It is used throughout the remainder of this document.
Run Infrap4d
Set up the environment required by infrap4d
Note: sudo
is required when running copy_config_files.sh
since you are
copying files to system directories.
source $P4CP_INSTALL/sbin/setup_env.sh $P4CP_INSTALL $SDE_INSTALL $DEPEND_INSTALL
sudo $P4CP_INSTALL/sbin/copy_config_files.sh $P4CP_INSTALL $SDE_INSTALL
Set hugepages required for DPDK
Run the hugepages script.
sudo $P4CP_INSTALL/sbin/set_hugepages.sh
Export all environment variables to sudo user
alias sudo='sudo PATH="$PATH" HOME="$HOME" LD_LIBRARY_PATH="$LD_LIBRARY_PATH" SDE_INSTALL="$SDE_INSTALL"'
Run the infrap4d daemon
By default, infrap4d runs in secure mode and expects certificates to be available in a specific directory. For information on running infrap4d in insecure mode, or steps to generate TLS certificates, see the security guide.
sudo $P4CP_INSTALL/sbin/infrap4d
By default, infrap4d runs in detached mode. If you want to run
infrap4d in attached mode, use the --nodetach
option.
All infrap4d logs are by default logged under /var/log/stratum.
All P4SDE logs are logged in p4_driver.log under $P4CP_RECIPE.
All OVS logs are logged under /tmp/ovs-vswitchd.log.
Run a sample program
Open a new terminal to set the pipeline and try the sample P4 program. Set up the environment and export all environment variables to sudo user.
source $P4CP_INSTALL/sbin/setup_env.sh $P4CP_INSTALL $SDE_INSTALL $DEPEND_INSTALL
$P4CP_INSTALL/sbin/copy_config_files.sh $P4CP_INSTALL $SDE_INSTALL
alias sudo='sudo PATH="$PATH" HOME="$HOME" LD_LIBRARY_PATH="$LD_LIBRARY_PATH" SDE_INSTALL="$SDE_INSTALL"'
Create two TAP ports
sudo ./install/bin/gnmi-ctl set "device:virtual-device,name:TAP0,pipeline-name:pipe,mempool-name:MEMPOOL0,mtu:1500,port-type:TAP"
sudo ./install/bin/gnmi-ctl set "device:virtual-device,name:TAP1,pipeline-name:pipe,mempool-name:MEMPOOL0,mtu:1500,port-type:TAP"
ifconfig TAP0 up
ifconfig TAP1 up
Note: See gnmi-ctl client guide for more information on the gnmi-ctl utility.
Create P4 artifacts
Clone the ipdk repo for scripts to build p4c and sample p4 program
git clone https://github.com/ipdk-io/ipdk.git --recursive ipdk-io
Install p4c compiler from p4c repository and follow the readme for procedure. Alternatively, refer to p4c script
Set the environment variable OUTPUT_DIR to the directory in which artifacts should be generated and where p4 files are available
export OUTPUT_DIR=/root/ipdk-io/build/networking/examples/simple_l3
Generate the artifacts using the p4c compiler installed in the previous step:
mkdir $OUTPUT_DIR/pipe
p4c-dpdk --arch pna --target dpdk \
--p4runtime-files $OUTPUT_DIR/p4Info.txt \
--bf-rt-schema $OUTPUT_DIR/bf-rt.json \
--context $OUTPUT_DIR/pipe/context.json \
-o $OUTPUT_DIR/pipe/simple_l3.spec $OUTPUT_DIR/simple_l3.p4
The above commands will generate three files (p4Info.txt, bf-rt.json, and context.json).
Modify simple_l3.conf file to provide correct paths for bfrt-config, context, and config.
TDI pipeline builder combines the artifacts generated by p4c compiler to generate a single bin file to be pushed from the controller. Generate binary executable using tdi-pipeline builder command below:
$P4CP_INSTALL/bin/tdi_pipeline_builder \
--p4c_conf_file=$OUTPUT_DIR/simple_l3.conf \
--tdi_pipeline_config_binary_file=$OUTPUT_DIR/simple_l3.pb.bin
Set forwarding pipeline
sudo $P4CP_INSTALL/bin/p4rt-ctl set-pipe br0 $OUTPUT_DIR/simple_l3.pb.bin $OUTPUT_DIR/p4Info.txt
Configure forwarding rules
sudo $P4CP_INSTALL/bin/p4rt-ctl add-entry br0 ingress.ipv4_host "hdr.ipv4.dst_addr=1.1.1.1,action=ingress.send(0)"
sudo $P4CP_INSTALL/bin/p4rt-ctl add-entry br0 ingress.ipv4_host "hdr.ipv4.dst_addr=2.2.2.2,action=ingress.send(1)"
See p4rt-ctl client guide for more information on the p4rt-ctl utility.
Test traffic between TAP0 and TAP1
Send packet from TAP 0 to TAP1 using scapy and listen on TAP1 using tcpdump
.
sendp(Ether(dst="00:00:00:00:03:14", src="a6:c0:aa:27:c8:2b")/IP(src="192.168.1.10", dst="2.2.2.2")/UDP()/Raw(load="0"*50), iface='TAP0')