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

DEPEND_INSTALL

Path to the directory in which the Stratum dependencies are installed.

SDE_INSTALL

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

P4CP_INSTALL

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')