A ferramenta de tráfego de rede eBPF usa uma combinação de implementação de kernel e espaço do usuário para monitorar o uso da rede no dispositivo desde a última inicialização do dispositivo. Ele fornece funcionalidades adicionais, como marcação de soquete, separação de tráfego de primeiro/segundo plano e firewall por UID para bloquear o acesso de aplicativos à rede, dependendo do estado do telefone. As estatísticas coletadas pela 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 fonte
As mudanças no espaço do usuário ocorrem principalmente nos projetos system/netd
e framework/base
. O desenvolvimento está sendo feito em AOSP, então o código AOSP estará sempre atualizado. A fonte está localizada principalmente em system/netd/server/TrafficController*
, system/netd/bpfloader
e system/netd/libbpf/
. Algumas mudanças necessárias na estrutura também estão na framework/base/
e system/core
.
Implementação
A partir do Android 9, os dispositivos Android executados no kernel 4.9 ou superior e originalmente fornecidos com a versão P DEVEM 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 de fácil manutenção e não requer nenhum código de kernel fora da árvore.
As principais diferenças de projeto entre o monitoramento de tráfego legado e eBPF são ilustradas na Figura 1.
Figura 1. Diferenças de design de monitoramento de tráfego legado (esquerda) e eBPF (direita)
O novo design trafficController
é baseado no filtro cgroup
eBPF, bem como no módulo xt_bpf
netfilter dentro do kernel. Esses filtros eBPF são aplicados no pacote tx/rx quando eles passam pelo filtro. O filtro cgroup
eBPF está localizado na camada de transporte e é responsável por contar o tráfego em relação ao UID correto, dependendo do UID do soquete, bem como da configuração do espaço do usuário. O netfilter xt_bpf
está conectado à 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 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. Existe um único cgroup
raiz para todo o tráfego, portanto todo o processo deve ser incluído nesse cgroup
por padrão.
Em tempo de execução, o trafficController
pode marcar/desmarcar um soquete gravando em 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, o filtro trafficController
e cgroup
eBPF também são responsáveis por bloquear o tráfego de determinados UIDs, dependendo das configurações do telefone. O recurso de bloqueio de tráfego de rede baseado em UID é uma substituição do módulo xt_owner
dentro do kernel e o modo detalhado 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 herdada do módulo xt_qtaguid
para que TrafficController
e NetworkStatsService
sejam executados com a implementação herdada ou nova. Se o aplicativo usar APIs públicas, não deverá haver nenhuma 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 superior), nenhuma modificação nos HALs, drivers ou código do kernel será necessária para implementar a nova ferramenta eBPF.
Requisitos
A configuração do kernel DEVE 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 VTS é útil ao verificar se a configuração correta está ativada.
-
Processo de descontinuação legado do xt_qtaguid
A nova ferramenta eBPF está substituindo o módulo xt_qtaguid
e o módulo xt_owner
no qual se baseia. Começaremos a remover o módulo xt_qtaguid
do kernel do Android e desabilitar suas configurações desnecessárias.
Na versão Android 9, o módulo xt_qtaguid
está 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 NetworkManagement
Service. Dependendo da versão do kernel do dispositivo e do primeiro nível da API, o NetworkManagement
Service sabe se as ferramentas eBPF estão ativadas e escolhe o módulo certo para obter para cada estatística de uso da rede do aplicativo. Aplicativos com SDK de nível 28 e superior são impedidos de acessar arquivos proc xt_qtaguid
pela sepolicy.
Na próxima versão do Android após 9, o acesso do aplicativo a esses arquivos proc xt_qtaguid
será completamente bloqueado e começaremos a remover o módulo xt_qtaguid
dos novos kernels comuns do Android. Depois de removido, atualizaremos a configuração base do Android para essa versão do kernel para desativar explicitamente o módulo xt_qtaguid
. O módulo xt_qtaguid
será completamente obsoleto quando o requisito mínimo de versão do kernel para uma versão do Android for 4.9 ou superior.
Na versão Android 9, apenas os dispositivos lançados com a versão Android 9 são obrigados a ter o novo recurso eBPF. Para dispositivos fornecidos com um kernel compatível com ferramentas eBPF, recomendamos atualizá-lo para o novo recurso eBPF ao atualizar para a versão Android 9. Não há teste CTS para impor essa atualização.
Validação
Você deve obter regularmente patches dos kernels comuns do Android e do Android AOSP principal. Certifique-se de que sua implementação passe nos testes VTS e CTS aplicáveis, no netd_unit_test
e no libbpf_test
.
Teste
Existem net_tests de kernel para garantir que você tenha os recursos necessários ativados e os patches de kernel necessários sejam portados. Os testes são integrados como parte dos testes VTS da versão Android 9. Existem alguns testes de unidade em system/netd/
( netd_unit_test
e libbpf_test
). Existem alguns testes em netd_integration_test
para validar o comportamento geral da nova ferramenta.
CTS e verificador CTS
Como ambos os módulos de monitoramento de tráfego são compatíveis com a versão Android 9, não há teste CTS para forçar a implementação do novo módulo em todos os dispositivos. Mas para dispositivos com versão de kernel superior a 4.9 que vêm originalmente com a versão Android 9 (ou seja, o primeiro nível de API >= 28), existem testes CTS no GSI para validar se o novo módulo está configurado corretamente. Testes CTS antigos, como TrafficStatsTest
, NetworkUsageStatsTest
e CtsNativeNetTestCases
podem ser usados para verificar se o comportamento é consistente com o módulo UID antigo.
Teste manual
Existem alguns testes de unidade em system/netd/
( netd_unit_test
, netd_integration_test
e libbpf_test
). Há suporte dumpsys para verificar manualmente o status. 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
mostra o conteúdo detalhado de cada mapa eBPF, incluindo informações de soquete marcado, estatísticas por tag, UID e iface e correspondência de UID do proprietário.
Locais de teste
Os testes 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 VTS estão localizados em https://android.googlesource.com/kernel/tests/+/main/net/test/bpf_test.py .
Os testes unitários estão localizados em:
- https://android.googlesource.com/platform/system/netd/+/main/libbpf/BpfNetworkStatsTest.cpp
- https://android.googlesource.com/platform/system/netd/+/main/server/TrafficControllerTest.cpp