Monitoraggio del traffico eBPF

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.

Differenze di progettazione del monitoraggio del traffico legacy ed eBPF

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 cgroupeBPF 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

  1. La configurazione del kernel DEVE avere attive le seguenti configurazioni:

    1. CONFIG_CGROUP_BPF=y
    2. CONFIG_BPF=y
    3. CONFIG_BPF_SYSCALL=y
    4. CONFIG_NETFILTER_XT_MATCH_BPF=y
    5. 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:

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: