The eBPF network traffic tool uses a combination of kernel and user space
implementation to monitor network usage on the device since the last device
boot. It provides additional functionality such as socket tagging, separating
foreground/background traffic and per-UID firewall to block apps from network
access depending on phone state. The statistics gathered from the tool are
stored in a kernel data structure called
eBPF maps and the result is used by
NetworkStatsService to provide persistent traffic statistics
since the last boot.
Examples and source
The userspace changes are mainly in the
projects. Development is being done in AOSP, so AOSP code will always be up to
date. The source is mainly located at
Some necessary framework changes are in
Starting with Android 9, Android devices running on
kernel 4.9 or above and originally shipped with the P release MUST use
eBPF-based network traffic monitoring accounting instead of
new infrastructure is more flexible and more maintainable and does not require
any out-of-tree kernel code.
The major design differences between legacy and eBPF traffic monitoring are illustrated in Figure 1.
Figure 1. Legacy (left) and eBPF (right) traffic monitoring design differences
trafficController design is based on per-
cgroup eBPF filter as well
xt_bpf netfilter module inside the kernel. These eBPF filters are applied
on the packet tx/rx when they pass through the filter. The
cgroup eBPF filter
is located at the transport layer and is responsible for counting the traffic
against the right UID depending on the socket UID as well as userspace setting.
xt_bpf netfilter is hooked at the
bw_mangle_POSTROUTING chain and is responsible for counting traffic against
the correct interface.
At boot time, the userspace process
trafficController creates the eBPF maps
used for data collection and pins all maps as a virtual file at
Then the privileged process
bpfloader loads the precompiled eBPF program into
the kernel and attaches it to the correct
cgroup. There is a single root
cgroup for all traffic so all the process should be included in that
At run time, the
trafficController can tag/untag a socket by writing to the
NetworkStatsService can read the traffic stats data from
Besides the traffic stats collection function, the
cgroup eBPF filter are also responsible for blocking traffic from certain UIDs
depending on the phone settings. The UID-based networking traffic blocking
feature is a replacement of the
xt_owner module inside the kernel and the
detail mode can be configured by writing to
The new implementation follows the legacy
xt_qtaguid module implementation so
NetworkStatsService will run with either the legacy or
new implementation. If the app uses public APIs, it should not experience any
xt_qtaguid or eBPF tools are used in the background.
If the device kernel is based on the Android common kernel 4.9 (SHA 39c856663dcc81739e52b02b77d6af259eb838f6 or above), then no modifications to HALs, drivers, or kernel code are required to implement the new eBPF tool.
The kernel config MUST have these following configs turned on:
The VTS kernel config test is helpful when verifying the correct config is turned on.
Legacy xt_qtaguid deprecation process
The new eBPF tool is replacing the
xt_qtaguid module and the
it is based on. We will start to remove the
xt_qtaguid module from the Android
kernel and disable its unnecessary configs.
In the Android 9 release, the
xt_qtaguid module is
turned on in all devices, but all the public APIs that directly read the
xt_qtaguid module proc file are moved into the
Depending on the device kernel version and first API level, the
NetworkManagement Service knows whether eBPF tools is turned on and chooses
the right module to get for each app network usage stat. Apps with SDK level 28
and higher are blocked from accessing
xt_qtaguid proc files by sepolicy.
In the next Android release after 9, app access to
xt_qtaguid proc files will be completely blocked we will start to remove
xt_qtaguid module from the new Android common kernels. After it is
removed, we will update the Android base config for that kernel version to
explicitly turn the
xt_qtaguid module off. The
xt_qtaguid module will be
completely deprecated when the minimum kernel version requirement for an Android
release is 4.9 or above.
In the Android 9 release, only devices that launch with the Android 9 release are required to have the new eBPF feature. For devices that shipped with a kernel that can support eBPF tools, we recommend updating it to the new eBPF feature when upgrading to the Android 9 release. There is no CTS test to enforce that update.
You should regularly take patches from Android common kernels and Android AOSP
main. Ensure your implementation passes the applicable VTS and CTS tests, the
netd_unit_test, and the
to ensure you have the required features turned on and required kernel patches
backported. The tests are integrated as part of Android 9
release VTS tests. There are some unit tests in
There are some tests in
netd_integration_test to validate the overall behavior
of the new tool.
CTS and CTS verifier
Because both traffic monitoring modules are supported in the Android
9 release, there is no CTS test to force implementing the
new module on all devices. But for devices with kernel version higher then 4.9
that originally ship with the Android 9 release (i.e.
the first API level >= 28), there are CTS tests on GSI to validate the new
module is correctly configured. Old CTS tests such as
CtsNativeNetTestCases can be used to verify the
behavior to be consistent with old UID module.
There are some unit tests in
There is dumpsys support for manually checking the status. The command
dumpsys netd shows the basic status of the
trafficController module and
whether eBPF is correctly turned on. If eBPF is turned on, the command
dumpsys netd trafficcontroller shows the detailed content of each eBPF
map, including tagged socket information, stats per tag, UID and iface, and
owner UID match.
CTS tests are located at:
VTS tests are located at https://android.googlesource.com/kernel/tests/+/main/net/test/bpf_test.py.
Unit tests are located at: