A ferramenta de tráfego de rede eBPF usa uma combinação de kernel e implementação de espaço
do usuário para monitorar o uso da rede no dispositivo desde a última inicialização
do dispositivo. Ela oferece outras funcionalidades, como inclusão de tag em soquetes, separação
de tráfego em primeiro e segundo plano e firewall por UID para impedir que apps acessem a rede,
dependendo do estado do smartphone. As estatísticas coletadas da ferramenta são
armazenadas em uma estrutura de dados do kernel chamada eBPF maps
, e o resultado é usado por
serviços como NetworkStatsService
para fornecer estatísticas de tráfego persistentes
desde a última inicialização.
Exemplos e origem
As mudanças no espaço do usuário estão principalmente nos projetos system/netd
e
framework/base
. O desenvolvimento está sendo feito no AOSP, então o código do AOSP sempre estará atualizado. A origem está localizada principalmente em
system/netd/server/TrafficController*
,
system/netd/bpfloader
e
system/netd/libbpf/
.
Algumas mudanças necessárias no framework também estão em framework/base/
e system/core
.
Implementação
A partir do Android 9, os dispositivos Android que executam o
kernel 4.9 ou mais recente e que foram enviados originalmente com a versão P PRECISAM usar
a contabilidade de monitoramento de tráfego de rede baseada em eBPF em vez de xt_qtaguid
. A
nova infraestrutura é mais flexível e fácil de manter e não requer
nenhum código de kernel fora da árvore.
As principais diferenças de design entre o monitoramento de tráfego legado e o eBPF são ilustradas na Figura 1.
Figura 1. Diferenças no design do monitoramento de tráfego legado (à esquerda) e eBPF (à direita)
O novo design do trafficController
é baseado no filtro eBPF por cgroup
,
bem como no módulo xt_bpf
netfilter dentro do kernel. Esses filtros eBPF são aplicados
na transmissão/recepção de pacotes quando eles passam pelo filtro. O filtro eBPF cgroup
está localizado na camada de transporte e é responsável por contar o tráfego
com o UID correto, dependendo do UID do soquete e da configuração do espaço do usuário.
O Netfilter xt_bpf
é conectado na cadeia bw_raw_PREROUTING
e
bw_mangle_POSTROUTING
e é responsável por contar o tráfego na
interface correta.
No momento da inicialização, o processo do espaço do usuário trafficController
cria os mapas eBPF usados para a coleta de dados e fixa todos os mapas como um arquivo virtual em sys/fs/bpf
.
Em seguida, o processo privilegiado bpfloader
carrega o programa eBPF pré-compilado no
kernel e o anexa ao cgroup
correto. Há um único cgroup
raiz
para todo o tráfego. Portanto, todo o processo precisa ser incluído nesse cgroup
por padrão.
No momento da execução, o trafficController
pode marcar/remover a marcação de um soquete escrevendo no
traffic_cookie_tag_map
e traffic_uid_counterSet_map
. O NetworkStatsService
pode ler os dados de estatísticas de tráfego de traffic_tag_stats_map
, traffic_uid_stats_map
e traffic_iface_stats_map
.
Além da função de coleta de estatísticas de tráfego, os filtros eBPF trafficController
e
cgroup
também são responsáveis por bloquear o tráfego de determinados UIDs,
dependendo das configurações do smartphone. O recurso de bloqueio de tráfego de rede com base no UID
é uma substituição do módulo xt_owner
no kernel, e o
modo de detalhes pode ser configurado gravando em traffic_powersave_uid_map
,
traffic_standby_uid_map
e traffic_dozable_uid_map
.
A nova implementação segue a implementação legada do módulo xt_qtaguid
. Portanto,
TrafficController
e NetworkStatsService
serão executados com a implementação legada ou
nova. Se o app usa APIs públicas, não haverá
diferença se as ferramentas xt_qtaguid
ou eBPF forem usadas em segundo plano.
Se o kernel do dispositivo for baseado no kernel comum do Android 4.9 (SHA 39c856663dcc81739e52b02b77d6af259eb838f6 ou mais recente), nenhuma modificação em HALs, drivers ou código do kernel será necessária para implementar a nova ferramenta eBPF.
Requisitos
A configuração do kernel PRECISA ter as seguintes configurações ativadas:
CONFIG_CGROUP_BPF=y
CONFIG_BPF=y
CONFIG_BPF_SYSCALL=y
CONFIG_NETFILTER_XT_MATCH_BPF=y
CONFIG_INET_UDP_DIAG=y
O teste de configuração do kernel do VTS é útil para verificar se a configuração correta está ativada.
Processo de descontinuação do xt_qtaguid legado
A nova ferramenta eBPF está substituindo o módulo xt_qtaguid
e o módulo xt_owner
em que ela se baseia. Vamos começar a remover o módulo xt_qtaguid
do kernel
do Android e desativar as configurações desnecessárias.
Na versão do Android 9, o módulo xt_qtaguid
é
ativado em todos os dispositivos, mas todas as APIs públicas que leem diretamente o
arquivo proc do módulo xt_qtaguid
são movidas para o serviço NetworkManagement
.
Dependendo da versão do kernel do dispositivo e do primeiro nível da API, o
serviço NetworkManagement
sabe se as ferramentas eBPF estão ativadas e escolhe
o módulo certo para cada estatística de uso de rede do app. Apps com o nível 28
do SDK e mais recentes são bloqueados para acessar arquivos de processo xt_qtaguid
por sepolicy.
Na próxima versão do Android após a 9, o acesso do app a
esses arquivos proc xt_qtaguid
será totalmente bloqueado, e vamos começar a remover
o módulo xt_qtaguid
dos novos kernels comuns do Android. Depois que ele for
removido, vamos atualizar a configuração de base do Android para essa versão do kernel para
desativar explicitamente o módulo xt_qtaguid
. O módulo xt_qtaguid
será
descontinuado completamente quando o requisito mínimo de versão do kernel para uma versão
do Android for 4.9 ou mais recente.
Na versão do Android 9, apenas os dispositivos lançados com a versão do Android 9 precisam ter o novo recurso eBPF. Para dispositivos que foram enviados com um kernel que pode oferecer suporte a ferramentas eBPF, recomendamos atualizar para o novo recurso eBPF ao fazer upgrade para a versão do Android 9. Não há teste do CTS para aplicar essa atualização.
Validação
É necessário usar patches regularmente de kernels comuns do Android e do
Android AOSP principal. Verifique se a implementação foi aprovada nos testes de VTS e CTS, netd_unit_test
e libbpf_test
aplicáveis.
Teste
Há
kernel net_tests
para garantir que os recursos necessários estejam ativados e que os patches do kernel necessários
sejam enviados de volta. Os testes são integrados como parte dos testes VTS da versão
do Android 9. Há alguns testes de unidade em system/netd/
(netd_unit_test
e
libbpf_test
).
Há alguns testes em netd_integration_test
para validar o comportamento geral
da nova ferramenta.
CTS e verificador do CTS
Como os dois módulos de monitoramento de tráfego são compatíveis com a versão do Android
9, não há teste de CTS para forçar a implementação do
novo módulo em todos os dispositivos. No entanto, para dispositivos com versão do kernel superior a 4.9
que são enviados originalmente com a versão do Android 9 (ou seja,
o primeiro nível de API >= 28), há testes de CTS na GSI para validar se o novo
módulo está configurado corretamente. Testes antigos do CTS, como TrafficStatsTest
,
NetworkUsageStatsTest
e CtsNativeNetTestCases
, podem ser usados para verificar se o
comportamento é consistente com o módulo UID antigo.
Teste manual
Há alguns testes de unidade em system/netd/
(netd_unit_test
,
netd_integration_test
e
libbpf_test
).
Há suporte a dumpsys para verificar o status manualmente. O comando
dumpsys netd
mostra o status básico do módulo trafficController
e
se o eBPF está ativado corretamente. Se o eBPF estiver ativado, o comando
dumpsys netd trafficcontroller
vai mostrar o conteúdo detalhado de cada mapa
eBPF, incluindo informações de soquete marcadas, estatísticas por tag, UID e iface e
correspondência de UID do proprietário.
Locais de teste
Os testes do CTS estão localizados em:
- 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
Os testes do VTS estão localizados em https://android.googlesource.com/kernel/tests/+/main/net/test/bpf_test.py.
Os testes de unidade estão localizados em: