NIKSS is an in-kernel implementation of a P4 software switch. It works in conjunction with the P4-eBPF compiler. The NIKSS switch uses Portable Switch Architecture (PSA) as a forwarding model and extended Berkeley Packet Filter (eBPF) as a packet processing engine. NIKSS works seamlessly with both TC-based and XDP-based flavors of the PSA model for the P4-eBPF compiler.
This repository implements a low-level C API and CLI tool (nikss-ctl
) to manage P4/PSA programs for NIKSS. The PSA-eBPF compiler that is used to generate P4 programs for NIKSS sits in the p4lang/p4c repository.
Main features of NIKSS:
Refer to the ACM CoNEXT paper for more details on design and performance numbers:
Tomasz Osiński, Jan Palimąka, Mateusz Kossakowski, Frédéric Dang Tran, El-Fadel Bonfoh, and Halina Tarasiuk. 2022. "A novel programmable software datapath for Software-Defined Networking". In Proceedings of the 18th International Conference on emerging Networking EXperiments and Technologies (CoNEXT '22). Association for Computing Machinery, New York, NY, USA, 245–260. https://doi.org/10.1145/3555050.3569117
To discuss the NIKSS project you can use the following communication channels:
You can build a Docker image for NIKSS by running the below command from the project's root directory:
docker build -t nikss:latest .
We also provide a stable Docker image that is built on CI. You can fetch it by:
docker pull osinstom/nikss:latest
NIKSS depends on following libraries and utilities:
All the dependencies can be installed on Ubuntu 20.04 with the following command:
sudo apt install make cmake gcc git libgmp-dev libelf-dev zlib1g-dev libjansson-dev
Note that nikss-ctl
is statically linked with shipped libbpf
, so there is no need to install this library
system-wide. It is a submodule for this repository.
Get the code with submodules:
git clone --recursive https://github.com/NIKSS-vSwitch/nikss.git
cd nikss
Build libbpf:
./build_libbpf.sh
Build the code and install binaries:
mkdir build
cd build
cmake <CMAKE_OPTIONS> ..
make -j4
sudo make install
Possible cmake options to customize build are listed in the table below:
CMake option | Possible values | Default value | Description |
---|---|---|---|
-DCMAKE_BUILD_TYPE |
empty | Release | Debug |
empty | Build type. Empty means Debug without debug symbols. |
-DCMAKE_INSTALL_PREFIX |
any path | /usr/local |
Sets the directory where make install intall the binaries. |
-DBUILD_SHARED |
on | off |
off |
Build shared library. When disabled only the nikss-ctl is built. |
Note on installing shared library: remember to execute sudo ldconfig
after installation. If libnikss
still can't
be loaded, you can do one of these things:
/usr
and reinstall.LD_LIBRARY_PATH
, e.g.:
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
echo "/usr/local/lib" > /etc/ld.so.conf.d/usr_local_lib.conf
ldconfig
(Optional) Install C/C++ headers files:
sudo make install_headers
This step makes sense only when shared library is built (BUILD_SHARED
is set to on
) because otherwise linker will
fail to find references to the libnikss
library.
See command reference for all the possible commands. Here listed only the most important ones.
All objects can be accessed by name created by the p4c
compiler. These names follow format <pipeline>_<extern name>
.
For example so defined table and actions:
control ingress(/* ... */) {
action a() {}
action b() {}
table example_table {
key = { /* ... */ }
actions = { NoAction; a1; a2; }
}
/* ... */
}
Table example_table
can be accessed with name ingress_example_table
, and action a
with name ingress_a
.
NoAction
can be accessed with name _NoAction
because it is not define within pipeline. In the same way names for all
other externs are created.
Load pipeline into kernel bpf subsystem:
nikss-ctl pipeline load id <ID> <FILENAME>
Unload pipeline from kernel bpf subsystem:
nikss-ctl pipeline unload id <ID>
Attach port:
nikss-ctl add-port pipe <ID> dev <INTERFACE>
Detach port:
nikss-ctl del-port pipe <ID> dev <INTERFACE>
Show pipeline information:
nikss-ctl pipeline show id <ID>
Create clone session and add member to it:
nikss-ctl clone-session create pipe <ID> id <SESSION_ID>
nikss-ctl clone-session add-member pipe <ID> id <SESSION_ID> egress-port <OUTPUT_PORT> instance <INSTANCE_ID> [cos <CLASS_OF_SERVICE>] [truncate plen_bytes <BYTES>]
ip link
command.Create multicast group and add member to it:
nikss-ctl multicast-group create pipe <ID> id <MULTICAST_GROUP_ID>
nikss-ctl multicast-group add-member pipe <ID> id <MULTICAST_GROUP_ID> egress-port <OUTPUT_PORT> instance <INSTANCE_ID>
ip link
command.Add an entry to a table without implementation:
nikss-ctl table add pipe <ID> <TABLE> action <ACTION> key <KEY> data <DATA> [priority <PRIORITY>]
id 2
or by name, e.g. name _NoAction
.2
./
, e.g. 192.168.1.0/24
^
, e.g. 0x12^0xFF