The NetSoft 2025 paper describes an approach to slice the resources of an RMT-based match-action pipeline such as Tofino. This repository contains the implementation of the approach and all tools and data used in the evaluation. The modified p4c is available at https://github.com/johannes-krude/p4c-slicing in a separate repository.
The content of this repository originates from several sources and authors.
- The main slicing approach:
scripts/*.rbcreated by Johannes Krude krude@comsys.rwth-aachen.de - The SMT-based slice compiler:
scripts/JuliaAnnotator/created by Felix Frei felix.frei@rwth-aachen.de - Generating P4 tables for forbidden resources:
scripts/*.pycreated by Pedram Ahmadiyeh pedram.ahmadiyeh@rwth-aachen.de
The example programs were adapted to the Tofino Native Architecture and normalized by putting implicit actions into tables without a match key.
accelerator_normalized.p4from https://github.com/johannes-krude/nfp-pred-artifacts (paper)aes_normalized.p4from https://github.com/Princeton-Cabernet/p4-projects/tree/master/AES-tofino (paper)chord_normalized.p4created by Justus Breyer breyer@comsys.rwth-aachen.deconquest_baseline_normalized.p4from https://github.com/Princeton-Cabernet/p4-projects/tree/master/ConQuest-tofino (paper)firewall_normalized.p4created by Yutao Wang yutao.wang@rwth-aachen.deflowlet_normalized.p4from https://github.com/nsg-ethz/p4-learning/blob/master/exercises/05-Flowlet_Switching/solution/p4src/flowlet_switching.p4mpls_normalized.p4created by Yutao Wang yutao.wang@rwth-aachen.derouting_free.p4,routing.p4created by Johannes Krude krude@comsys.rwth-aachen.deRTT_normalized.p4from https://github.com/Princeton-Cabernet/p4-projects/tree/master/RTT-tofino (paper)single-table.p4created by Johannes Krude krude@comsys.rwth-aachen.despeedtest/,speedtest.p4created by René Glebke glebke@comsys.rwth-aachen.detutorial_*.p4from https://github.com/p4lang/tutorialsvxlan_normalized.p4created by Yutao Wang yutao.wang@rwth-aachen.de
The instructions on preparing your system for running the included code are described in the Dockerfile. The paper's evaluation results were obtained using the closed-source p4c-barefoot and a modified variant of the open-source p4c. Most of the evaluation will also run with only the open source p4c but may result in different results. The SMT-based compilation approach will need to be modified to call p4c-barefoot differently since it currently relies on behavior not present in the open-source p4c.
To build an image, obtain bf-sde-9.9.0.tgz from Intel and place it into the main directory of this repository. Then, build the image with:
sudo docker build -t switch-slicing:latest .
Start an interactive shell in the image with:
sudo docker run -it --rm -u $(id -u):$(id -g) -v $(pwd):/switch-slicing -w /switch-slicing switch-slicing:latest
The evaluation can be executed as in the paper with the following. While preparing the paper, this took 57 days on a Ryzen 7 5800X.
mkdir data
./scripts/bfa_eval.rb --evaluate --for-paper --data-dir=data --skip-data --repeat 3
If the script is interrupted, it can be restarted and will skip the evaluation steps that have already been performed.
To start over with the evaluation, remove the data/ directory.
When evaluating only a single example program, append --example=progname.
The result from the evaluation can be viewed with
./scripts/bfa_eval.rb --analyze --for-paper --data-dir=data
To instead, view the results from the original paper evaluation data:
./scripts/bfa_eval.rb --analyze --for-paper --data-dir=data_paper
Most of the implementation works on programs compiled to Barefoot Assembly (.bfa). Precompiled .bfa files of all example programs are included in the bfa_test/ directory. A .bfa file can be obtained from a .p4 file by p4c-barefoot or with the help of
./scripts/p4.rb --compile --preprocess prog.p4 > prog.bfa
To check if a resulting .bfa file is valid and can be executed on a switch, obtain the assembler from Intel and run it with bfas prog.bfa.
A slice describes a subset of the pipeline resources.
The implementation works on slice files that follow the YAML syntax.
A slice file that describes the complete pipeline can be found in assets/tofino1.slice.
To subtract one slice from another, do
./scripts/bfa_slice.rb a.slice --substract b.slice
Subtraction has special semantics for the PHV. When subtracting a shared PHV field from a slice where the same PHV field is exclusive, the result will be that the field becomes shared.
To divide a slice by, e.g., 3 per stage and the overall stages by 12, do:
./scripts/bfa_slice.rb a.slice --divide 12,3
More useful is getting a slice that fits a given base program, e.g., to subtract the resources used by the if-else base program (described in the paper) from the complete switch and divide the remaining resources, do e.g.:
./scripts/bfa_slice.rb --framework if --divide 12,3
or when using the table base program (not described in the paper)
./scripts/bfa_slice.rb --framework table --divide 12,3
To check whether a .bfa file is within a slice, do:
./scripts/bfa_slice.rb a.slice --check prog.bfa
or e.g.:
./scripts/bfa_slice.rb --framework if --divide 12,3 --check bfa_test/routing_free.bfa
A program that uses the correct number of resources but is not yet aligned to the slice can be relocated with, e.g.,
./scripts/bfa_slice.rb --framework if --divide 12,3 --relocate bfa_test/single-table.bfa > relocated.bfa
The paper describes several approaches to compiling a program into a slice.
To use the modified p4c:
./scripts/p4.rb prog.p4 --slice-compile a.slice > fitted.bfa
To use the SMT-based compiler:
./scripts/p4.rb prog.p4 --smtfit a.slice > fitted.bfa
To generate additional tables for the out-of-slice resources:
./scripts/p4.rb prog.p4 --squeeze a.slice > fitted.bfa
In all cases, the target slice can be calculated from a base program with, e.g.:
./scripts/p4.rb p4code/single-table.p4 --squeeze if --divide 12,3 > fitted.bfa
Merging programs with the compiled base program is done with:
./scripts/bfa_merge.rb if a.bfa b.bfa c.bfa > merged.bfa
To instead merge on a P4 level, e.g., 36 instances of a program into the base program, do:
./scripts/p4.rb --merge if --divide 36 p4code/single-table.p4 > p4merged.bfa
A program in .bfa form can be loaded and executed on a switch. First, the assembler bfas needs to called to obtain a .bin file and the associated context.json file.
Then load and execute the program with:
./scripts/run_bf_switchd <progname> prog.bin context.json bfrt.json
The control plane interface, bfrt.json, is created by p4c-barefoot and needs to be adapted when loading .bfa file modified or merged by our implementation.
To load a program onto the switch emulator, use the --tofino-model argument.