Narzędzie do analizy ruchu sieciowego eBPF wykorzystuje połączenie implementacji w przestrzeni jądra i użytkownika do monitorowania wykorzystania sieci na urządzeniu od ostatniego uruchomienia. Zapewnia dodatkowe funkcje, takie jak tagowanie gniazd, rozdzielanie ruchu na pierwszym planie i w tle oraz zapora sieciowa dla każdego identyfikatora UID, która blokuje aplikacjom dostęp do sieci w zależności od stanu telefonu. Statystyki zbierane przez to narzędzie są przechowywane w strukturze danych jądra o nazwie eBPF maps
, a wynik jest używany przez usługi takie jak NetworkStatsService
do dostarczania trwałych statystyk ruchu od ostatniego uruchomienia.
Przykłady i źródło
Zmiany w przestrzeni użytkownika dotyczą głównie projektów system/netd
i framework/base
. Prace rozwojowe są prowadzone w ramach AOSP, więc kod AOSP będzie zawsze aktualny. Źródło znajduje się głównie w system/netd/server/TrafficController*
, system/netd/bpfloader
i system/netd/libbpf/
.
Niektóre niezbędne zmiany w platformie są też dostępne w framework/base/
i system/core
.
Implementacja
Począwszy od Androida 9, urządzenia z Androidem z jądrem 4.9 lub nowszym, które zostały pierwotnie dostarczone z Androidem P, MUSZĄ używać rozliczania monitorowania ruchu sieciowego opartego na eBPF zamiast xt_qtaguid
. Nowa infrastruktura jest bardziej elastyczna i łatwiejsza w utrzymaniu oraz nie wymaga żadnego kodu jądra poza drzewem.
Główne różnice w konstrukcji między starszym a eBPF-owym monitorowaniem ruchu przedstawiono na rysunku 1.
Rysunek 1. Różnice w architekturze starszego (po lewej) i eBPF (po prawej) monitorowania ruchu
Nowa trafficController
architektura opiera się na filtrze cgroup
eBPF oraz xt_bpf
module netfilter w jądrze. Te filtry eBPF są stosowane do pakietów wysyłanych i odbieranych, gdy przechodzą przez filtr. cgroup
Filtr eBPF znajduje się w warstwie transportowej i odpowiada za zliczanie ruchu w odniesieniu do odpowiedniego identyfikatora UID w zależności od identyfikatora UID gniazda oraz ustawień przestrzeni użytkownika.
Filtr sieciowy xt_bpf
jest podłączony do łańcuchów bw_raw_PREROUTING
i bw_mangle_POSTROUTING
i odpowiada za zliczanie ruchu na odpowiednim interfejsie.
Podczas uruchamiania procesu przestrzeni użytkownika trafficController
tworzone są mapy eBPF
używane do zbierania danych, a wszystkie mapy są przypinane jako plik wirtualny w lokalizacji sys/fs/bpf
.
Następnie uprzywilejowany proces bpfloader
wczytuje wstępnie skompilowany program eBPF do jądra i dołącza go do odpowiedniego cgroup
. W przypadku całego ruchu jest jeden węzeł główny cgroup
, więc domyślnie wszystkie procesy powinny być w nim uwzględnione.cgroup
W czasie działania trafficController
może oznaczać gniazdo tagiem lub usuwać tag, zapisując dane w polach traffic_cookie_tag_map
i traffic_uid_counterSet_map
. Usługa NetworkStatsService
może odczytywać dane o statystykach ruchu z usług traffic_tag_stats_map
, traffic_uid_stats_map
i traffic_iface_stats_map
.
Oprócz funkcji zbierania statystyk ruchu filtr trafficController
i cgroup
eBPF odpowiada też za blokowanie ruchu z określonych identyfikatorów UID w zależności od ustawień telefonu. Funkcja blokowania ruchu sieciowego na podstawie identyfikatora UID zastępuje moduł xt_owner
w jądrze, a tryb szczegółowy można skonfigurować, zapisując dane w plikach traffic_powersave_uid_map
, traffic_standby_uid_map
i traffic_dozable_uid_map
.
Nowa implementacja jest zgodna ze starszą implementacją modułu xt_qtaguid
, więc funkcje TrafficController
i NetworkStatsService
będą działać zarówno w przypadku starszej, jak i nowej implementacji. Jeśli aplikacja korzysta z publicznych interfejsów API, nie powinna odczuwać żadnej różnicy, niezależnie od tego, czy w tle są używane narzędzia xt_qtaguid
czy eBPF.
Jeśli jądro urządzenia jest oparte na wspólnym jądrze Androida 4.9 (SHA 39c856663dcc81739e52b02b77d6af259eb838f6 lub nowszym), do wdrożenia nowego narzędzia eBPF nie są wymagane żadne modyfikacje HAL, sterowników ani kodu jądra.
Wymagania
W konfiguracji jądra MUSZĄ być włączone te ustawienia:
CONFIG_CGROUP_BPF=y
CONFIG_BPF=y
CONFIG_BPF_SYSCALL=y
CONFIG_NETFILTER_XT_MATCH_BPF=y
CONFIG_INET_UDP_DIAG=y
Test konfiguracji jądra VTS pomaga sprawdzić, czy włączona jest prawidłowa konfiguracja.
Proces wycofywania starszego parametru xt_qtaguid
Nowe narzędzie eBPF zastępuje modułxt_qtaguid
i modułxt_owner
, na którym jest oparte. Zaczniemy usuwać moduł xt_qtaguid
z jądra Androida i wyłączać jego niepotrzebne konfiguracje.
W Androidzie 9 moduł xt_qtaguid
jest włączony na wszystkich urządzeniach, ale wszystkie publiczne interfejsy API, które bezpośrednio odczytują plik proc modułu xt_qtaguid
, zostały przeniesione do usługi NetworkManagement
.
W zależności od wersji jądra urządzenia i pierwszego poziomu interfejsu API usługa NetworkManagement
wie, czy narzędzia eBPF są włączone, i wybiera odpowiedni moduł, aby uzyskać statystyki wykorzystania sieci przez każdą aplikację. Aplikacje z pakietem SDK na poziomie 28 lub wyższym nie mają dostępu do plików xt_qtaguid
proc ze względu na zasady bezpieczeństwa.
W kolejnej wersji Androida po wersji 9 dostęp aplikacji do tych plików xt_qtaguid
proc zostanie całkowicie zablokowany, a my zaczniemy usuwać moduł xt_qtaguid
z nowych wspólnych jąder Androida. Po usunięciu modułu zaktualizujemy podstawową konfigurację Androida dla tej wersji jądra, aby wyraźnie wyłączyć moduł xt_qtaguid
. Moduł xt_qtaguid
zostanie całkowicie wycofany, gdy minimalna wersja jądra wymagana w przypadku wersji Androida będzie wynosić 4.9 lub więcej.
W przypadku Androida 9 tylko urządzenia, które są wprowadzane na rynek z Androidem 9, muszą mieć nową funkcję eBPF. W przypadku urządzeń, które zostały dostarczone z jądrem obsługującym narzędzia eBPF, zalecamy zaktualizowanie go do nowej funkcji eBPF podczas uaktualniania do Androida 9. Nie ma testu CTS, który wymuszałby tę aktualizację.
Weryfikacja
Regularnie pobieraj poprawki z wspólnych jąder Androida i głównej gałęzi AOSP Androida. Upewnij się, że Twoja implementacja przechodzi odpowiednie testy VTS i CTS, netd_unit_test
oraz libbpf_test
.
Testowanie
Istnieją testy jądra net_tests, które sprawdzają, czy masz włączone wymagane funkcje i czy masz przeniesione wstecz wymagane poprawki jądra. Testy są zintegrowane z testami VTS w wersji Androida 9. W folderach system/netd/
(netd_unit_test
i libbpf_test
) znajdują się testy jednostkowe. W folderze netd_integration_test
są testy, które sprawdzają ogólne działanie nowego narzędzia.
CTS i weryfikator CTS
Oba moduły monitorowania ruchu są obsługiwane w Androidzie 9, więc nie ma testu CTS, który wymuszałby wdrożenie nowego modułu na wszystkich urządzeniach. W przypadku urządzeń z jądrem w wersji nowszej niż 4.9, które pierwotnie były dostarczane z Androidem 9 (tzn. pierwszy poziom interfejsu API >= 28), istnieją testy CTS na GSI, które sprawdzają, czy nowy moduł jest prawidłowo skonfigurowany. Stare testy CTS, takie jak TrafficStatsTest
, NetworkUsageStatsTest
i CtsNativeNetTestCases
, mogą służyć do weryfikacji zachowania pod kątem zgodności ze starym modułem UID.
Testy ręczne
W system/netd/
znajdują się testy jednostkowe (netd_unit_test
, netd_integration_test
i libbpf_test
).
Dostępna jest funkcja dumpsys, która umożliwia ręczne sprawdzanie stanu. Polecenie
dumpsys netd
wyświetla podstawowy stan modułu trafficController
i informację, czy eBPF jest prawidłowo włączony. Jeśli eBPF jest włączony, polecenie dumpsys netd trafficcontroller
wyświetla szczegółową zawartość każdej mapy eBPF, w tym informacje o oznaczonych gniazdach, statystyki według tagu, identyfikator UID i interfejs oraz dopasowanie identyfikatora UID właściciela.
Lokalizacje testów
Testy CTS znajdują się w tym katalogu:
- https://android.googlesource.com/platform/cts/+/android16-release/tests/tests/net/src/android/net/cts/TrafficStatsTest.java
- https://android.googlesource.com/platform/cts/+/android16-release/tests/tests/app.usage/src/android/app/usage/cts/NetworkUsageStatsTest.java
- https://android.googlesource.com/platform/system/netd/+/android16-release/tests/bpf_base_test.cpp
Testy VTS znajdują się na stronie https://android.googlesource.com/kernel/tests/+/android16-release/net/test/bpf_test.py.
Testy jednostkowe znajdują się w: