Das eBPF-Netzwerk-Traffic-Tool verwendet eine Kombination aus Kernel- und Userspace-Implementierung, um die Netzwerknutzung auf dem Gerät seit dem letzten Start zu überwachen. Sie bietet zusätzliche Funktionen wie Socket-Tagging, die Trennung von Vordergrund-/Hintergrund-Traffic und eine UID-spezifische Firewall, um Apps je nach Smartphone-Status den Netzwerkzugriff zu blockieren. Die vom Tool erfassten Statistiken werden in einer Kernel-Datenstruktur namens eBPF maps
gespeichert. Das Ergebnis wird von Diensten wie NetworkStatsService
verwendet, um persistente Traffic-Statistiken seit dem letzten Start bereitzustellen.
Beispiele und Quelle
Die Änderungen im Userspace betreffen hauptsächlich die Projekte system/netd
und framework/base
. Die Entwicklung erfolgt in AOSP. Der AOSP-Code ist also immer auf dem neuesten Stand. Die Quelle befindet sich hauptsächlich unter system/netd/server/TrafficController*
, system/netd/bpfloader
und system/netd/libbpf/
.
Einige notwendige Framework-Änderungen finden Sie auch in framework/base/
und system/core
.
Implementierung
Ab Android 9 müssen Android-Geräte mit Kernel 4.9 oder höher, die ursprünglich mit der P-Version ausgeliefert wurden, anstelle von xt_qtaguid
die eBPF-basierte Netzwerküberwachung verwenden. Die neue Infrastruktur ist flexibler und wartungsfreundlicher und erfordert keinen Out-of-Tree-Kernelcode.
Die wichtigsten Designunterschiede zwischen dem Legacy- und dem eBPF-Traffic-Monitoring sind in Abbildung 1 dargestellt.
Abbildung 1. Unterschiede beim Design der Legacy- (links) und eBPF-Verkehrsüberwachung (rechts)
Das neue trafficController
-Design basiert auf einem pro-cgroup
-eBPF-Filter sowie dem xt_bpf
-Netfilter-Modul im Kernel. Diese eBPF-Filter werden auf die Pakete angewendet, wenn sie den Filter passieren. Der cgroup
-eBPF-Filter befindet sich in der Transportschicht und ist dafür verantwortlich, den Traffic je nach Socket-UID und Userspace-Einstellung der richtigen UID zuzuordnen.
Der Netfilter xt_bpf
wird an die Kette bw_raw_PREROUTING
und bw_mangle_POSTROUTING
angehängt und ist für die Zählung des Traffics für die richtige Schnittstelle verantwortlich.
Beim Booten erstellt der Userspace-Prozess trafficController
die eBPF-Karten, die für die Datenerhebung verwendet werden, und pinnen alle Karten als virtuelle Datei unter sys/fs/bpf
an.
Anschließend lädt der privilegierte Prozess bpfloader
das vorab kompilierte eBPF-Programm in den Kernel und fügt es der richtigen cgroup
hinzu. Da es für den gesamten Traffic eine einzige Stamm-cgroup
gibt, sollte der gesamte Prozess standardmäßig in dieser cgroup
enthalten sein.
Während der Laufzeit kann der trafficController
einen Socket taggen oder enttippen, indem er in traffic_cookie_tag_map
und traffic_uid_counterSet_map
schreibt. Der NetworkStatsService
kann die Besucherstatistiken von traffic_tag_stats_map
, traffic_uid_stats_map
und traffic_iface_stats_map
lesen.
Neben der Funktion zum Erfassen von Traffic-Statistiken sind die eBPF-Filter trafficController
und cgroup
auch für das Blockieren von Traffic von bestimmten UIDs verantwortlich, je nach den Einstellungen des Smartphones. Die UID-basierte Blockierung von Netzwerkverkehr ersetzt das xt_owner
-Modul im Kernel. Der Detailmodus kann durch Schreiben in traffic_powersave_uid_map
, traffic_standby_uid_map
und traffic_dozable_uid_map
konfiguriert werden.
Die neue Implementierung folgt der alten xt_qtaguid
-Modulimplementierung. TrafficController
und NetworkStatsService
werden also entweder mit der alten oder der neuen Implementierung ausgeführt. Wenn die Anwendung öffentliche APIs verwendet, sollte es keinen Unterschied geben, ob xt_qtaguid
- oder eBPF-Tools im Hintergrund verwendet werden.
Wenn der Geräte-Kernel auf dem allgemeinen Android-Kernel 4.9 (SHA 39c856663dcc81739e52b02b77d6af259eb838f6 oder höher) basiert, sind keine Änderungen an HALs, Treibern oder Kernelcode erforderlich, um das neue eBPF-Tool zu implementieren.
Voraussetzungen
In der Kernelkonfiguration MÜSSEN die folgenden Konfigurationen aktiviert sein:
CONFIG_CGROUP_BPF=y
CONFIG_BPF=y
CONFIG_BPF_SYSCALL=y
CONFIG_NETFILTER_XT_MATCH_BPF=y
CONFIG_INET_UDP_DIAG=y
Der VTS-Kernel-Konfigurationstest ist hilfreich, um zu prüfen, ob die richtige Konfiguration aktiviert ist.
Einstellung der Legacy-Kennzeichnung „xt_qtaguid“
Das neue eBPF-Tool ersetzt das Modul xt_qtaguid
und das Modul xt_owner
, auf dem es basiert. Wir beginnen damit, das xt_qtaguid
-Modul aus dem Android-Kernel zu entfernen und die unnötigen Konfigurationen zu deaktivieren.
In Android 9 ist das Modul xt_qtaguid
auf allen Geräten aktiviert, aber alle öffentlichen APIs, die die Modulproc-Datei xt_qtaguid
direkt lesen, werden in den Dienst NetworkManagement
verschoben.
Abhängig von der Kernel-Version des Geräts und der ersten API-Ebene weiß der NetworkManagement
-Dienst, ob eBPF-Tools aktiviert sind, und wählt das richtige Modul für jede Statistik zur Netzwerknutzung der App aus. Apps mit SDK-Level 28 und höher können durch sepolicy nicht auf xt_qtaguid
-Prozessdateien zugreifen.
Im nächsten Android-Release nach 9 wird der App-Zugriff auf diese xt_qtaguid
-Proc-Dateien vollständig blockiert. Wir beginnen damit, das xt_qtaguid
-Modul aus den neuen allgemeinen Android-Kerneln zu entfernen. Nach der Entfernung aktualisieren wir die Android-Basiskonfiguration für diese Kernelversion, um das xt_qtaguid
-Modul explizit zu deaktivieren. Das xt_qtaguid
-Modul wird vollständig eingestellt, wenn die Mindestkernelversionsanforderung für eine Android-Version 4.9 oder höher ist.
Bei der Android 9-Version müssen nur Geräte, die mit der Android 9-Version auf den Markt kommen, die neue eBPF-Funktion haben. Bei Geräten mit einem Kernel, der eBPF-Tools unterstützt, empfehlen wir, beim Upgrade auf Android 9 auf die neue eBPF-Funktion zu aktualisieren. Es gibt keinen CTS-Test, um diese Aktualisierung zu erzwingen.
Zertifizierungsstufe
Sie sollten regelmäßig Patches aus den Android Common Kernels und Android AOSP main übernehmen. Ihre Implementierung muss die entsprechenden VTS- und CTS-Tests, den netd_unit_test
und den libbpf_test
bestehen.
Testen
Es gibt Kernel-net_tests, mit denen Sie prüfen können, ob die erforderlichen Funktionen aktiviert und die erforderlichen Kernel-Patches zurückportiert wurden. Die Tests sind Teil der VTS-Tests für Release-Versionen von Android 9. In system/netd/
gibt es einige Unit-Tests (netd_unit_test
und libbpf_test
). In netd_integration_test
gibt es einige Tests, um das Gesamtverhalten des neuen Tools zu validieren.
CTS- und CTS-Verifizierung
Da beide Module zur Verkehrsüberwachung in der Android 9-Version unterstützt werden, gibt es keinen CTS-Test, mit dem die Implementierung des neuen Moduls auf allen Geräten erzwungen werden kann. Für Geräte mit einer Kernelversion höher als 4.9, die ursprünglich mit der Android 9-Version ausgeliefert wurden (d.h. die erste API-Ebene >= 28), gibt es CTS-Tests auf GSI, um zu prüfen, ob das neue Modul richtig konfiguriert ist. Mit alten CTS-Tests wie TrafficStatsTest
, NetworkUsageStatsTest
und CtsNativeNetTestCases
können Sie das Verhalten prüfen, damit es mit dem alten UID-Modul konsistent ist.
Manuelle Tests
In system/netd/
gibt es einige Einheitentests (netd_unit_test
, netd_integration_test
und libbpf_test
). Dumpsys unterstützt die manuelle Statusprüfung. Der Befehl dumpsys netd
zeigt den grundlegenden Status des trafficController
-Moduls und ob eBPF richtig aktiviert ist. Wenn eBPF aktiviert ist, zeigt der Befehl dumpsys netd trafficcontroller
den detaillierten Inhalt jeder eBPF-Map an, einschließlich getaggter Socket-Informationen, Statistiken pro Tag, UID und iface sowie der Übereinstimmung der Eigentümer-UID.
Testorte
CTS-Tests finden Sie hier:
- https://android.googlesource.com/platform/cts/+/main/tests/tests/net/src/android/net/cts/TrafficStatsTest.java
- https://android.googlesource.com/platform/cts/+/main/tests/tests/app.usage/src/android/app/usage/cts/NetworkUsageStatsTest.java
- https://android.googlesource.com/platform/system/netd/+/main/tests/bpf_base_test.cpp
VTS-Tests finden Sie unter https://android.googlesource.com/kernel/tests/+/main/net/test/bpf_test.py.
Die Unittests finden Sie hier:
- https://android.googlesource.com/platform/system/netd/+/main/libbpf/BpfNetworkStatsTest.cpp
- https://android.googlesource.com/platform/system/netd/+/main/server/TrafficControllerTest.cpp