(Verified this section is updated and working on 2024-Feb-03)
Prerequisites:
- You have started the container, and followed the steps described in the section Useful extra software to install in the container.
- You have a P4 source program that compiles successfully following
the steps below.
- If you want to test these steps on your system with a known-good
example P4 program and PTF test, use the files in the directory
sample
.
- If you want to test these steps on your system with a known-good
example P4 program and PTF test, use the files in the directory
- You have written a PTF test in Python that you want to test it with.
- TODO: Some time write details of how such a test should be written, e.g. what ports exist?
I will use example file names sample.p4
for the P4 program, and
ptf-test1.py
for the Python PTF test. These steps will work even if
the P4 source code is spread over many files, but it is assumed here
(so far) that the Python source code for the PTF test is in a single
file.
These instructions use p4c-dpdk
installed in the base OS for
compiling your P4 program. The reasons for this are:
- I know how to update the
p4c-dpdk
version in the base OS to the latest version, compiled from source code. - I do not yet know how to do so for the version of
p4c-dpdk
that is installed in the container.
Using the p4c-dpdk
in the base OS thus makes it easier for me to
choose which version of source code to build p4c-dpdk
that I wish.
You must do these steps in the base OS in every terminal you create:
export P4GUIDE="${HOME}/p4-guide"
export PYPKG_TESTLIB="${P4GUIDE}/testlib"
export IPDK_HOME="${HOME}/ipdk"
export PATH="${P4GUIDE}/ipdk/bin:${PATH}"
In base OS:
BASENAME="sample"
DIR="${P4GUIDE}/ipdk/${BASENAME}"
cd ${DIR}
compile-base-os.sh -a pna -s ${BASENAME}.p4
In base OS:
mkdir -p ~/.ipdk/volume/${BASENAME}
cp -pr ${DIR}/* ~/.ipdk/volume/${BASENAME}
If runptf.sh
and the Python PTF source code files are not in
directory ${DIR}
, copy them into ~/ipdk/volume/${BASENAME}
, too.
These commands only need to be run in the container once:
source $HOME/my-venv/bin/activate
export PYPKG_TESTLIB="/tmp/testlib"
In container:
BASENAME="sample"
/tmp/bin/start-infrap4d-and-load-p4-in-cont.sh ${BASENAME} ${BASENAME}
cd /tmp/${BASENAME}
./runptf.sh
Note: These steps also work for a P4 program written for the PNA
architecture where the PTF test is auto-generated by the p4testgen
program. See the example P4 program in the testprog2
directory, and
the small bash script create-ptf-test.sh
there that shows example
command line parameters for p4testgen
that have been tested to work
for this purpose. These steps might also work for a PSA architecture
P4 program, but I have not tried that myself yet.
Debugging note: The load_p4_prog.sh
script contains within it a
command that begins with p4rt-ctl set-pipe
. I believe that a side
effect of that command is to create files with these names within the
directory shared between container and base OS:
p4.c
- A C source file that is to be compiled and loaded into the DPDK software switch, generated by translating it from the.spec
file output byp4c-dpdk
.p4.o
- The object file created by compilingp4.c
p4.so
- A shared library file created by compilingp4.c
.
Debugging note: Whatever number N of ports you create, given as the
parameter to the setup_tapports_in_default_ns.sh
script above, the
port numbers as seen by the P4 program are numbered 0 through N-1. At
least in some cases I have seen, attempting to send a packet to a port
larger than N-1 can cause infrap4d to crash with a SEGFAULT.
P4 DPDK limitation: Attempting to load a compiled P4 program that has 0 tables will fail with an error message like this one:
Error: P4Runtime RPC error (INTERNAL): P4Info is missing these required resources: Tables.
It is unusual for a P4 program to have 0 tables, but if you run across
this, a simple workaround is to create a "dummy table", i.e. a table
with 0 key fields, one action, and const default_action = my_action(params_go_here);
, where you can define whatever you want
for my_action
(including any name you want for that action),
including an action with an empty body that does nothing.
See these files in the directory ~/.ipdk/volume/${BASENAME}
:
ptf.pcap
ptf.log
The file ptf.pcap
should contain a mix of all packets on all ports,
in time order. Each should have a "PPI" header, which contains fields
like the ones shown below. You can see the port number that the
packet was sent or received on in the first "Interface ID" field. I
do not know why there are two "Aggregation Extension" and two
"Interface ID" fields, but from my experience it seems that the first
one is the one you should pay attention to.
PPI version 0, 24 bytes
Version: 0
Flags: 0x00
.... ...0 = Alignment: Not aligned
0000 000. = Reserved: 0x00
Header length: 24
DLT: 1
Aggregation Extension
Field type: Aggregation Extension (8)
Field length: 4
Interface ID: 1
Aggregation Extension
Field type: Aggregation Extension (8)
Field length: 4
Interface ID: 0