Lo strumento per il monitoraggio del traffico di rete eBPF utilizza una combinazione di implementazione nello spazio utente e nel kernel per monitorare l'utilizzo della rete sul dispositivo dall'ultimo avvio. Fornisce funzionalità aggiuntive come il tagging delle 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 in base allo 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 permanenti 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, pertanto il codice AOSP sarà sempre aggiornato. La fonte si trova principalmente su
system/netd/server/TrafficController*
,
system/netd/bpfloader
,
e
system/netd/libbpf/
.
Alcune modifiche necessarie al framework sono presenti anche 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 monitoraggio del traffico di rete basato su eBPF anziché xt_qtaguid
. La nuova infrastruttura è più flessibile e più gestibile e non richiede codice del kernel out-of-tree.
Le principali differenze di progettazione tra il monitoraggio del traffico precedente e quello eBPF sono illustrate nella Figura 1.
Figura 1. Differenze di progettazione del monitoraggio del traffico legacy (a sinistra) ed eBPF (a destra)
Il nuovo design di trafficController
si basa su cgroup
filtro eBPF e su
xt_bpf
modulo netfilter all'interno del kernel. Questi filtri eBPF vengono applicati ai pacchetti tx/rx quando passano attraverso il filtro. Il filtro eBPF cgroup
si trova nel livello di trasporto ed è responsabile del conteggio del traffico rispetto all'UID corretto, a seconda dell'UID della socket e dell'impostazione dello spazio utente.
Il netfilter xt_bpf
è agganciato alle catene bw_raw_PREROUTING
e
bw_mangle_POSTROUTING
ed è responsabile del conteggio del traffico
in base all'interfaccia corretta.
Al momento dell'avvio, il processo nello spazio utente trafficController
crea le mappe eBPF impiegate per la raccolta dei dati e fissa 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 un singolo cgroup
di primo livello per tutto il traffico, pertanto l'intera procedura dovrebbe essere inclusa in questo cgroup
per impostazione predefinita.
In fase di esecuzione, trafficController
può taggare/scollegare 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, il filtro eBPF trafficController
e
cgroup
è responsabile anche del blocco del traffico da determinati UID
a seconda delle impostazioni dello smartphone. La funzionalità di blocco del traffico di rete basata su UID è un'alternativa al modulo xt_owner
all'interno del kernel e la modalità di dettaglio può essere configurata scrivendo in traffic_powersave_uid_map
, traffic_standby_uid_map
e traffic_dozable_uid_map
.
La nuova implementazione segue l'implementazione precedente del modulo xt_qtaguid
, quindi TrafficController
e NetworkStatsService
verranno eseguite con la precedente o con la nuova. Se l'app utilizza API pubbliche, non dovrebbe notare alcuna differenza tra l'utilizzo in background degli strumenti xt_qtaguid
o eBPF.
Se il kernel del dispositivo è basato sul kernel comune di Android 4.9 (SHA 39c856663dcc81739e52b02b77d6af259eb838f6 o versioni successive), non sono necessarie modifiche ai HAL, ai driver o al codice del kernel per implementare il nuovo strumento eBPF.
Requisiti
La configurazione del kernel DEVE avere le seguenti configurazioni attive:
CONFIG_CGROUP_BPF=y
CONFIG_BPF=y
CONFIG_BPF_SYSCALL=y
CONFIG_NETFILTER_XT_MATCH_BPF=y
CONFIG_INET_UDP_DIAG=y
Il test della configurazione del kernel VTS è utile per verificare che sia attivata la configurazione corretta.
Procedura di ritiro del parametro xt_qtaguid legacy
Il nuovo strumento eBPF sostituirà il moduloxt_qtaguid
e il moduloxt_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
è attivo su 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 di utilizzo della rete dell'app. Le app con SDK di livello 28
e superiori non possono accedere ai file procedura xt_qtaguid
dal sepolicy.
Nella prossima release di Android dopo la 9, l'accesso delle app a questi file proc xt_qtaguid
verrà completamente bloccato e inizieremo a rimuovere il modulo xt_qtaguid
dai nuovi kernel comuni di Android. Dopo la rimozione, 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à ritirato completamente quando il requisito di versione minima del kernel per una release di Android è 4.9 o superiore.
Nella release di Android 9, solo i dispositivi lanciati con la release di Android 9 devono disporre della nuova funzionalità eBPF. Per i dispositivi forniti con un kernel in grado di supportare gli strumenti eBPF, consigliamo di aggiornarli alla nuova funzionalità eBPF durante l'upgrade alla release Android 9. Non esiste un test CTS per applicare questo aggiornamento.
Convalida
Dovresti prendere 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 backport delle patch del kernel necessarie. I test sono integrati come parte dei test VTS della release di Android 9. Esistono alcuni test delle unità in system/netd/
(netd_unit_test
e
libbpf_test
).
Esistono alcuni test in netd_integration_test
per convalidare il comportamento complessivo
del nuovo strumento.
CTS e CTS verifier
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 a 4.9
forniti originariamente con la release Android 9 (ovvero
il primo livello API >= 28), sono disponibili test CTS su GSI per convalidare il nuovo
modulo è configurato correttamente. È possibile utilizzare vecchi test CTS come TrafficStatsTest
,
NetworkUsageStatsTest
e CtsNativeNetTestCases
per verificare il
comportamento in modo che sia coerente con il modulo UID precedente.
Test manuale
Sono disponibili alcuni test delle unità in system/netd/
(netd_unit_test
,
netd_integration_test
e
libbpf_test
).
È disponibile il supporto di dumpsys per il controllo manuale dello stato. Il comando dumpsys netd
mostra lo stato di base del modulo trafficController
e se eBPF è correttamente attivato. Se eBPF è attivo, il comando dumpsys netd trafficcontroller
mostra i contenuti dettagliati di ogni mappa eBPF, incluse le informazioni sui socket con tag, le statistiche per tag, l'UID e iface e la corrispondenza dell'UID del proprietario.
Sedi di test
I test CTS si trovano all'indirizzo:
- 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
I test VTS si trovano all'indirizzo https://android.googlesource.com/kernel/tests/+/main/net/test/bpf_test.py.
I test delle unità si trovano in:
- https://android.googlesource.com/platform/system/netd/+/main/libbpf/BpfNetworkStatsTest.cpp
- https://android.googlesource.com/platform/system/netd/+/main/server/TrafficControllerTest.cpp