2 stable releases
1.0.1 | Apr 8, 2024 |
---|---|
1.0.0 | Apr 4, 2024 |
#308 in Unix APIs
147 downloads per month
4MB
101K
SLoC
Packetvisor(PV)
System dependencies
- clang version >= 11
- llvm version >= 11
bpftool & XDP-tools (submodules)
PV uses libxdp
in XDP-tools.
Build Library
You can use cargo build -r
command to build PV library and the library file will be located in target/release/
.
Getting started
This guide will walk you through the process of compiling and using example source code written with the PV library.
The following explanation will be based on the Echo example.
Please install the dependent packages first.
# Install build dependencies
$ sudo apt-get install llvm clang libelf-dev gcc-multilib libpcap-dev m4 make curl
# Install Rust
$ curl https://sh.rustup.rs -sSf | sh
$ source "$HOME/.cargo/env"
And compile the example source.
# Compile all examples.
$ cargo build -r --examples
# Compile the specific example.
$ cargo build -r --example echo
The compiled example binaries are located in the target/release/examples/
directory.
Before running the Echo example, you need to create a Linux network namespace.
We provide two scripts for this:
examples/set_veth.sh
: Create two linux network namespaces.examples/unset_veth.sh
: Delete the two linux network namespaces that were created.
Running the examples/set_veth.sh
script creates two namespaces(test1 and test2) within the Host.
# Host veth0 is connected to veth1 in the test1 namespace.
# Host veth2 is connected to veth3 in the test2 namespace.
+-----------+ +-----------+
| test1 | | test2 |
+--[veth1]--+ +--[veth3]--+
| |
+--[veth0]----------------[veth2]--+
| Host |
+----------------------------------+
Only the test1 namespace is used in the Echo example test.
Now, open two terminals.
- On one terminal (TERM1), run Echo on the veth1 interface of test1 namespace.
- The other terminal (TERM2) sends ARP, ICMP, and UDP packets from Host to test1.
In summary, Host and test1 perform ARP, ICMP, and UDP Echo (Ping-Pong) with each other.
Please execute the following commands on TERM1 and TERM2.
# Working directory on TERM1 is packetvisor/.
(TERM1) $ sudo ip netns exec test1 /bin/bash
(TERM1) $ ./target/release/examples/echo veth1
-------------------------------------------------
(TERM2) $ sudo apt-get install arping 2ping
# ARP echo test
(TERM2) $ sudo arping 10.0.0.5
# ICMP echo test
(TERM2) $ ping 10.0.0.5
# UDP echo test
(TERM2) $ 2ping 10.0.0.5 --port 7
You can now see ARP, ICMP, and UDP (Port 7) packets being echoed in the test1 namespace through the TERM1 logs!
Description of XSK (XDP Socket)
Elements of XSK
- TX Ring: has descriptors of packets to be sent
- RX Ring: has descriptors of packets to have been received
- Completion Ring (= CQ, Completion queue): has chunks where packets sent successfully are saved
- Filling Ring (= FQ, Filling queue): has chunks which are allocated to receive packets
RX side procedure
user should pre-allocate chunks which are empty or ready to be used in advance before getting to receive packets and then putting them. the following steps describe how to receive packets through XSK
.
- user informs kernel that how many slots should be reserved in
FQ
throughxsk_ring_prod__reserve()
, then the function will returnthe number of reserved slots
andindex
value which means the first index of reserved slots in the ring. - user puts an
index
inxsk_ring_prod__fill_addr()
as a parameter and the function will return the pointer of a slot by theindex
. then, user allocates chunk address by putting it to the pointer like*xsk_ring_prod__fill_addr() = chunk_addr
as much asthe number of reserved slots
with iteration. - after the allocation of chunks,
xsk_ring_prod__submit()
will inform kernel that how many chunks are allocated to slots inFQ
. - when some packets are getting received, kernel will copy the packet into chunks as allocation information of
FQ
and it will make descriptors about packets inRX Ring
. - user can know how many packets have been received through
xsk_ring_cons__peek()
. the function will returnsthe number of received packets
andindex
value which means the first index of received slots in the ring. - with
xsk_ring_cons__rx_desc()
, user can fetch information of received packets by putting theindex
in the function as a parameter. - After fetching all information of received packets, user should inform kernel that how many packets in
RX Ring
are consumed throughxsk_ring_cons__release()
. so that, kernel will movetail
ofRX ring
for the future packet's descriptors to be saved.
TX side procedure
in contrast to RX side procedure, CQ
should have enough empty slots before sending packets through XSK
because CQ
will be allocated after packets are sent sucessfully. if there is no any slot ready to be allocated in CQ
, kernel may not able to send packets. user can know what packet has been sent successfully through CQ
. the following steps describe how to send packets thorugh XSK
.
- packets to be sent are ready in chunks.
- user should reserve slots of
TX Ring
throughxsk_ring_prod__reserve()
. the function will returnthe number of reserved slots
andindex
which means the first index of reserved slots. - when user puts the
index
inxsk_ring_prod__tx_desc()
as parameter, the function will return descriptor as theindex
. Then, user puts address of payload and payload length of a packet to be sent into the descriptor. - after all descriptors have information about packets, user should inform kernel that how many packets will be sent through
xsk_ring_prod__submit()
. - calling
xsk_ring_prod__submit()
alone doesn't send any packet in actual. callingsendto()
will let kernel to send them. - if packets are sent successfully, Kernel will allocate chunks in
CQ
where sent packets used. - user can know how many packets are sent through
xsk_ring_cons__peek()
by puttingCQ
as a parameter. the function will returnthe number of sent packets
andindex
. the index means the index of the first slot inCQ
. xsk_ring_cons__comp_addr()
will return chunk address allocated inCQ
. and then user can reuse the chunk in the next time.- lastly, user should inform kernel how many slots in
CQ
are consumed throughxsk_ring_cons__release()
. so that kernel will movetail
ofCQ
for the next packet's chunk to be saved in the ring.
License
This software is distributed under GPLv3 or any later version.
If you need other license than GPLv3 for proprietary use or professional support, please mail us to contact at tsnlab dot com.
TODO
Make an installer including an option to change capabilities of the application.
use the following command: sudo setcap CAP_SYS_ADMIN,CAP_NET_ADMIN,CAP_NET_RAW,CAP_DAC_OVERRIDE+ep target/release/pv3_rust
Dependencies
~4.5–7.5MB
~145K SLoC