- C 71.1%
- Shell 18.4%
- Python 6.4%
- M4 2.9%
- Makefile 1.2%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
|
||
| benchmarks | ||
| contrib | ||
| debian | ||
| doc | ||
| m4 | ||
| man | ||
| po | ||
| src | ||
| tests | ||
| tools | ||
| .gitignore | ||
| autogen.sh | ||
| configure.ac | ||
| COPYING | ||
| Jenkinsfile | ||
| Makefile.am | ||
| README.md | ||
fireperf
Find out what your network can really take - and what is in between.
fireperf measures bandwidth like iperf3 does, but it has been built to test
firewalls, routers and everything else that keeps state for every connection.
It moves data at line rate on every CPU without copying it, opens hundreds of
thousands of connections per second, and tells you exactly what happened to every
one of them.
It finds out whether your terminal is dark or light, and looks good on both:
Why fireperf?
🔥 Built for what is in between. A firewall is not a link. It keeps a table of connections that fills up, it forgets connections that have been quiet for too long, and new connections per second matter to it as much as gigabits. fireperf can
- open connections at a fixed rate (
--rate 10000) - on schedule, whether the firewall keeps up or not - and tell you how many were late or never made it, - tell you why a connection failed: it timed out, it was rejected, or this side ran out of ports or file descriptors,
- show how long the handshake took, as median, 99th percentile and maximum, across millions of connections,
- keep thousands of connections open and find those that the firewall has
silently forgotten (
--keepalive), - send a request and wait for a response on every connection, like a web server
would (
--exchange 100:10000), or reset connections instead of closing them (--reset).
⚡ Fast, so that it is never what holds the test back. One worker per CPU,
nothing shared between them, io_uring where the kernel has it and epoll
everywhere else. fireperf doesn't copy what it sends: it comes from a 32 MiB pool
of random data that the kernel sends straight from memory. And if a worker has
been the limit, fireperf says so instead of reporting a number that only measured
itself.
🤝 One server for everybody. Clients connect to a single port - easy to put
into firewall rules - and every client can run its own test at the same time. An
iperf3 server turns everybody else away until the current test is done.
🔁 Speaks iperf3 and iperf. fireperf finds out what is on the other side and
talks to it. Point it at an iperf3 or iperf server, or point an iperf3
client at a fireperf server. Nobody has to say anything.
📈 Shows you what is going on. A live graph of the traffic in both directions,
the numbers that matter, and every client with its connections and traffic - right
in your terminal. Without a terminal, fireperf prints a line every second, and
--json gives you one JSON object per second for your scripts and dashboards.
How it compares
| fireperf | iperf3 | |
|---|---|---|
| Several clients, each with its own test, at once | ✅ | ❌ one at a time |
| Opens connections at a fixed rate | ✅ | ❌ |
| Tells why connections could not be established | ✅ | ❌ |
| Handshake times across all connections | ✅ | ❌ |
| Finds connections that a firewall has forgotten | ✅ | ❌ |
| Request and response on every connection | ✅ | ❌ |
| Sends without copying | ✅ always | with -Z |
| Live graph in the terminal | ✅ | ❌ |
| JSON output | ✅ | ✅ |
| Talks to iperf3 and iperf | ✅ | - |
In numbers
Sending from one VM (2 cores) to another over virtio, eight connections, CPU time of the sender per GiB that it has sent (less is better):
| Sender | Gbit/s | CPU seconds per GiB |
|---|---|---|
| fireperf (io_uring) | 19.0 | 0.071 |
| fireperf (epoll) | 19.4 | 0.151 |
iperf3 -Z |
17.9 | 0.153 |
| iperf3 | 15.9 | 0.505 |
| iperf 2 | 15.7 | 0.509 |
That is a seventh of the CPU time that iperf3 and iperf need by default, and
half of what iperf3 needs with --zerocopy - CPU time that is left to push the
network instead of the benchmark.
Opening and closing connections over loopback on a 16-core machine, fireperf gets through more than 230,000 connections per second, about 20 µs of CPU time on the server for every one of them.
All of this is in benchmarks/results.csv, and
tools/benchmark measures it on your hardware (see
benchmarks/README).
Getting started
Start a server:
fireperf --server
And point a client at it:
# How fast is it? The server sends, the client receives.
fireperf --client server.example.com
# Both directions at once, over 16 connections
fireperf --client server.example.com --duplex --parallel 16
# Can the firewall open 10,000 connections per second?
fireperf --client 192.0.2.1 --rate 10000 --close
# Like a web server: 100 bytes request, 10 KB response, 5,000 times per second
fireperf --client 192.0.2.1 --exchange 100:10000 --rate 5000
# Keep 100,000 connections open, and find those that the firewall forgets
fireperf --client 192.0.2.1 --parallel 100000 --keepalive
# Talk to an iperf3 server (which listens on another port)
fireperf --client iperf3.example.org --port 5201
# Feed your scripts
fireperf --client server.example.com --timeout 10 --json | jq .
fireperf(8) explains every
option, and how to run a connection test that tells you something about the
firewall rather than about the machines on either side.
fireperf-design(7)
explains how fireperf works and why.
Installing
Every build of the master branch is being published in the master repositories,
and releases in the stable ones, for Debian, Arch Linux, RHEL (and AlmaLinux,
Rocky Linux and the other clones) and openSUSE Tumbleweed.
Debian (bookworm, trixie, forky and sid, on amd64, arm64, armel, armhf, i386, loong64, ppc64el, riscv64 and s390x, as far as the release has them):
sudo curl -o /usr/share/keyrings/fireperf.asc \
https://repo.ipfire.org/debian/fireperf/stable/fireperf.asc
echo "deb [signed-by=/usr/share/keyrings/fireperf.asc] https://repo.ipfire.org/debian/fireperf/stable $(. /etc/os-release && echo $VERSION_CODENAME) main" \
| sudo tee /etc/apt/sources.list.d/fireperf.list
sudo apt update && sudo apt install fireperf
Arch Linux - import the key and add the repository to /etc/pacman.conf:
curl https://repo.ipfire.org/archlinux/fireperf/stable/fireperf.asc | sudo pacman-key --add -
sudo pacman-key --lsign-key 274205B524A108FD0416482AA49D90BBC489A8E7
[fireperf]
Server = https://repo.ipfire.org/archlinux/fireperf/stable/$arch
RHEL 9 and 10 (and their clones) - add this as /etc/yum.repos.d/fireperf.repo
and install it with dnf install fireperf:
[fireperf]
name=fireperf
baseurl=https://repo.ipfire.org/el/fireperf/stable/$releasever/
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://repo.ipfire.org/el/fireperf/stable/$releasever/RPM-GPG-KEY-fireperf
openSUSE Tumbleweed:
sudo rpm --import https://repo.ipfire.org/opensuse/fireperf/stable/tumbleweed/RPM-GPG-KEY-fireperf
sudo zypper addrepo https://repo.ipfire.org/opensuse/fireperf/stable/tumbleweed/ fireperf
sudo zypper install fireperf
Replace stable with master for the latest development version.
Running the server as a service
fireperf comes with a systemd unit. It runs the server as an unprivileged user, and logs every test that a client has run to the journal:
systemctl enable --now fireperf
journalctl -u fireperf
Building
You need a C compiler, autotools, pkg-config, ncursesw, gettext and
intltool. liburing (2.3 or later) is optional but recommended, and asciidoc
and xsltproc build the man pages (or use --disable-man-pages).
./autogen.sh
./configure
make
make check
sudo make install
On Debian and Ubuntu:
sudo apt install build-essential autoconf automake autopoint libtool pkg-config \
gettext intltool libncurses-dev liburing-dev asciidoc docbook-xml docbook-xsl xsltproc
Contributing
fireperf is being developed by the IPFire Project. The source is at https://git.ipfire.org/?p=fireperf.git, and bugs go to Bugzilla.
fireperf is free software, licensed under the GNU General Public License, version 3 or later.

