Lo strumento per il traffico di rete eBPF utilizza una combinazione di implementazione dello spazio kernel e utente
per monitorare l'utilizzo della rete sul dispositivo dall'ultimo
avvio del dispositivo. Fornisce funzionalità aggiuntive come il tagging dei socket, la separazione
del traffico in primo piano/in background e il firewall per UID per bloccare l'accesso
alla rete da parte delle app a seconda dello stato dello smartphone. Le statistiche raccolte dallo strumento vengono
memorizzate in una struttura di dati del kernel chiamata eBPF maps
e il risultato viene utilizzato da
servizi come NetworkStatsService
per fornire statistiche sul traffico persistenti
dall'ultimo avvio.
Esempi e origine
Le modifiche allo spazio utente riguardano principalmente i progetti system/netd
e framework/base
. Lo sviluppo viene eseguito in AOSP, quindi il codice AOSP sarà sempre aggiornato. La fonte si trova principalmente a
system/netd/server/TrafficController*
,
system/netd/bpfloader
,
e
system/netd/libbpf/
.
Sono state apportate alcune modifiche necessarie al framework in framework/base/
e system/core
.
Implementazione
A partire da Android 9, i dispositivi Android con
kernel 4.9 o versioni successive e originariamente forniti con la release P DEVONO utilizzare
il conteggio del monitoraggio del traffico di rete basato su eBPF anziché xt_qtaguid
. La
nuova infrastruttura è più flessibile e più gestibile e non richiede
alcun codice del kernel out-of-tree.
Le principali differenze di progettazione tra il monitoraggio del traffico legacy e quello eBPF sono illustrate nella Figura 1.
Figura 1. Differenze tra la progettazione del monitoraggio del traffico legacy (a sinistra) e eBPF (a destra)
Il nuovo design di trafficController
si basa sul filtro eBPF per cgroup
, nonché sul modulo netfilter xt_bpf
all'interno del kernel. Questi filtri eBPF vengono applicati
alla trasmissione/ricezione dei pacchetti quando passano attraverso il filtro. Il filtro cgroup
eBPF
si trova a livello di trasporto ed è responsabile del conteggio del traffico
rispetto all'UID corretto a seconda dell'UID del socket e dell'impostazione dello spazio utente.
Il filtro netfilter xt_bpf
è collegato alle catene bw_raw_PREROUTING
e bw_mangle_POSTROUTING
ed è responsabile del conteggio del traffico rispetto all'interfaccia corretta.
Al momento dell'avvio, il processo userspace trafficController
crea le mappe eBPF
utilizzate per la raccolta dei dati e blocca tutte le mappe come file virtuale in sys/fs/bpf
.
Il processo privilegiato bpfloader
carica il programma eBPF precompilato nel kernel e lo collega al cgroup
corretto. Esiste una singola radice
cgroup
per tutto il traffico, quindi per impostazione predefinita l'intero processo deve essere incluso in cgroup
.
In fase di runtime, trafficController
può taggare/rimuovere il tag da un socket scrivendo in
traffic_cookie_tag_map
e traffic_uid_counterSet_map
. NetworkStatsService
può leggere i dati delle statistiche sul traffico da traffic_tag_stats_map
, traffic_uid_stats_map
e traffic_iface_stats_map
.
Oltre alla funzione di raccolta delle statistiche sul traffico, anche il filtro trafficController
e
cgroup
eBPF è responsabile del blocco del traffico da determinati UID
a seconda delle impostazioni dello smartphone. La funzionalità di blocco del traffico di rete basato sull'UID
sostituisce il modulo xt_owner
all'interno del kernel e la
modalità dettagli può essere configurata scrivendo atraffic_powersave_uid_map
,
traffic_standby_uid_map
e traffic_dozable_uid_map
.
La nuova implementazione segue l'implementazione del modulo xt_qtaguid
legacy, quindi
TrafficController
e NetworkStatsService
verranno eseguiti con l'implementazione legacy o
nuova. Se l'app utilizza API pubbliche, non dovrebbe riscontrare alcuna
differenza se vengono utilizzati strumenti xt_qtaguid
o eBPF in background.
Se il kernel del dispositivo è basato sul kernel comune Android 4.9 (SHA 39c856663dcc81739e52b02b77d6af259eb838f6 o versioni successive), non sono necessarie modifiche a HAL, driver o codice del kernel per implementare il nuovo strumento eBPF.
Requisiti
La configurazione del kernel DEVE avere attive le seguenti configurazioni:
CONFIG_CGROUP_BPF=y
CONFIG_BPF=y
CONFIG_BPF_SYSCALL=y
CONFIG_NETFILTER_XT_MATCH_BPF=y
CONFIG_INET_UDP_DIAG=y
Il test di configurazione del kernel VTS è utile per verificare che la configurazione corretta sia attivata.
Procedura di ritiro di xt_qtaguid legacy
Il nuovo strumento eBPF sostituisce il moduloxt_qtaguid
e il modulo xt_owner
su cui si basa. Inizieremo a rimuovere il modulo xt_qtaguid
dal kernel Android e a disattivare le relative configurazioni non necessarie.
Nella release di Android 9, il modulo xt_qtaguid
è
attivato in tutti i dispositivi, ma tutte le API pubbliche che leggono direttamente il
file proc del modulo xt_qtaguid
vengono spostate nel servizio NetworkManagement
.
A seconda della versione del kernel del dispositivo e del primo livello API, il
servizio NetworkManagement
sa se gli strumenti eBPF sono attivi e sceglie
il modulo giusto da ottenere per ogni statistica sull'utilizzo della rete da parte delle app. L'accesso ai file xt_qtaguid
proc è bloccato per le app con livello SDK 28 e versioni successive da sepolicy.
Nella prossima release di Android successiva alla 9, l'accesso delle app a
questi file xt_qtaguid
proc verrà completamente bloccato e inizieremo a rimuovere
il modulo xt_qtaguid
dai nuovi kernel comuni di Android. Una volta rimosso, aggiorneremo la configurazione di base di Android per quella versione del kernel in modo da disattivare esplicitamente il modulo xt_qtaguid
. Il modulo xt_qtaguid
verrà completamente ritirato quando il requisito della versione minima del kernel per una release di Android sarà 4.9 o versioni successive.
Nella release Android 9, solo i dispositivi lanciati con la release Android 9 devono avere la nuova funzionalità eBPF. Per i dispositivi forniti con un kernel che supporta gli strumenti eBPF, consigliamo di aggiornarlo alla nuova funzionalità eBPF durante l'upgrade alla versione Android 9. Non esiste un test CTS per applicare questo aggiornamento.
Convalida
Devi applicare regolarmente le patch dai kernel comuni di Android e da Android AOSP
main. Assicurati che l'implementazione superi i test VTS e CTS applicabili, il
netd_unit_test
e il libbpf_test
.
Test
Esistono
test di rete del kernel
per assicurarti di aver attivato le funzionalità richieste e di aver eseguito il backporting delle patch del kernel richieste. I test sono integrati nei test VTS della release Android 9. Sono presenti alcuni unit test in system/netd/
(netd_unit_test
e
libbpf_test
).
Sono presenti alcuni test in netd_integration_test
per convalidare il comportamento complessivo
del nuovo strumento.
CTS e strumento di verifica CTS
Poiché entrambi i moduli di monitoraggio del traffico sono supportati nella release Android 9, non esiste un test CTS per forzare l'implementazione del nuovo modulo su tutti i dispositivi. Tuttavia, per i dispositivi con versione del kernel superiore alla 4.9
forniti originariamente con la release Android 9 (ovvero
il primo livello API >= 28), sono presenti test CTS su GSI per convalidare la corretta
configurazione del nuovo modulo. I vecchi test CTS come TrafficStatsTest
,
NetworkUsageStatsTest
e CtsNativeNetTestCases
possono essere utilizzati per verificare che il comportamento sia coerente con il vecchio modulo UID.
Test manuale
Sono presenti alcuni test unitari in system/netd/
(netd_unit_test
,
netd_integration_test
e
libbpf_test
).
È disponibile il supporto di dumpsys per controllare manualmente lo stato. Il comando
dumpsys netd
mostra lo stato di base del modulo trafficController
e
se eBPF è attivato correttamente. Se eBPF è attivato, il comando
dumpsys netd trafficcontroller
mostra i contenuti dettagliati di ogni mappa eBPF,
incluse informazioni sui socket taggati, statistiche per tag, UID e iface e
corrispondenza UID proprietario.
Località di test
I test CTS si trovano in:
- 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
I test VTS si trovano all'indirizzo https://android.googlesource.com/kernel/tests/+/android16-release/net/test/bpf_test.py.
I test delle unità si trovano in: