L'outil de trafic réseau eBPF utilise une combinaison d'implémentation du noyau et de l'espace utilisateur pour surveiller l'utilisation du réseau sur l'appareil depuis le dernier démarrage de l'appareil. Il fournit des fonctionnalités supplémentaires telles que le balisage des sockets, la séparation du trafic de premier plan/arrière-plan et un pare-feu par UID pour empêcher les applications d'accéder au réseau en fonction de l'état du téléphone. Les statistiques collectées à partir de l'outil sont stockées dans une structure de données du noyau appelée eBPF maps
et le résultat est utilisé par des services tels que NetworkStatsService
pour fournir des statistiques de trafic persistantes depuis le dernier démarrage.
Exemples et source
Les modifications de l'espace utilisateur concernent principalement les projets system/netd
et framework/base
. Le développement est en cours dans AOSP, donc le code AOSP sera toujours à jour. La source se trouve principalement dans system/netd/server/TrafficController*
, system/netd/bpfloader
et system/netd/libbpf/
. Certains changements de framework nécessaires se trouvent également dans framework/base/
et system/core
.
Mise en œuvre
À partir d'Android 9, les appareils Android fonctionnant sur le noyau 4.9 ou supérieur et livrés à l'origine avec la version P DOIVENT utiliser la comptabilité de surveillance du trafic réseau basée sur eBPF au lieu de xt_qtaguid
. La nouvelle infrastructure est plus flexible et plus maintenable et ne nécessite aucun code de noyau hors arbre.
Les principales différences de conception entre la surveillance du trafic héritée et eBPF sont illustrées à la figure 1.
Figure 1. Différences de conception de la surveillance du trafic hérité (à gauche) et eBPF (à droite)
La nouvelle conception de trafficController
est basée sur le filtre cgroup
par groupe de contrôle ainsi que sur le module netfilter xt_bpf
à l'intérieur du noyau. Ces filtres eBPF sont appliqués sur les paquets tx/rx lorsqu'ils traversent le filtre. Le filtre cgroup
eBPF est situé au niveau de la couche de transport et est responsable du comptage du trafic par rapport au bon UID en fonction de l'UID du socket ainsi que du paramètre de l'espace utilisateur. Le netfilter xt_bpf
est accroché à la chaîne bw_raw_PREROUTING
et bw_mangle_POSTROUTING
et est responsable du comptage du trafic par rapport à la bonne interface.
Au démarrage, le processus de l'espace utilisateur trafficController
crée les cartes eBPF utilisées pour la collecte de données et épingle toutes les cartes en tant que fichier virtuel sur sys/fs/bpf
. Ensuite, le processus privilégié bpfloader
charge le programme eBPF précompilé dans le noyau et l'attache au groupe de cgroup
approprié. Il existe un seul groupe de contrôle cgroup
pour tout le trafic, donc tout le processus doit être inclus dans ce groupe de cgroup
par défaut.
Au moment de l'exécution, le trafficController
peut marquer/démarquer un socket en écrivant dans traffic_cookie_tag_map
et traffic_uid_counterSet_map
. Le NetworkStatsService
peut lire les données de statistiques de trafic à partir de traffic_tag_stats_map
, traffic_uid_stats_map
et traffic_iface_stats_map
. Outre la fonction de collecte des statistiques de trafic, le trafficController
et cgroup
eBPF sont également responsables du blocage du trafic de certains UID en fonction des paramètres du téléphone. La fonctionnalité de blocage du trafic réseau basée sur l'UID remplace le module xt_owner
dans le noyau et le mode détaillé peut être configuré en écrivant dans traffic_powersave_uid_map
, traffic_standby_uid_map
et traffic_dozable_uid_map
.
La nouvelle implémentation suit l'implémentation du module hérité xt_qtaguid
afin que TrafficController
et NetworkStatsService
s'exécutent avec l'ancienne ou la nouvelle implémentation. Si l'application utilise des API publiques, il ne devrait y avoir aucune différence si les outils xt_qtaguid
ou eBPF sont utilisés en arrière-plan.
Si le noyau de l'appareil est basé sur le noyau commun Android 4.9 (SHA 39c856663dcc81739e52b02b77d6af259eb838f6 ou supérieur), aucune modification des HAL, des pilotes ou du code du noyau n'est requise pour implémenter le nouvel outil eBPF.
Conditions
La configuration du noyau DOIT avoir les configurations suivantes activées :
-
CONFIG_CGROUP_BPF=y
-
CONFIG_BPF=y
-
CONFIG_BPF_SYSCALL=y
-
CONFIG_NETFILTER_XT_MATCH_BPF=y
-
CONFIG_INET_UDP_DIAG=y
Le test de configuration du noyau VTS est utile pour vérifier que la configuration correcte est activée.
-
Le périphérique
MEM_LOCK
rlimit DOIT être défini sur 8 Mo ou plus.
Processus de dépréciation hérité xt_qtaguid
Le nouvel outil eBPF remplace le module xt_qtaguid
et le module xt_owner
sur lequel il est basé. Nous allons commencer à supprimer le module xt_qtaguid
du noyau Android et désactiver ses configurations inutiles.
Dans la version Android 9, le module xt_qtaguid
est activé sur tous les appareils, mais toutes les API publiques qui lisent directement le fichier proc du module xt_qtaguid
sont déplacées dans le service NetworkManagement
. En fonction de la version du noyau de l'appareil et du premier niveau d'API, le service NetworkManagement
sait si les outils eBPF sont activés et choisit le bon module à obtenir pour chaque statistique d'utilisation du réseau de l'application. Les applications avec SDK de niveau 28 et supérieur ne peuvent pas accéder aux fichiers proc xt_qtaguid
par sepolicy.
Dans la prochaine version d'Android après 9, l'accès des applications à ces fichiers proc xt_qtaguid
sera complètement bloqué, nous commencerons à supprimer le module xt_qtaguid
des nouveaux noyaux communs Android. Après sa suppression, nous mettrons à jour la configuration de base d'Android pour cette version du noyau afin de désactiver explicitement le module xt_qtaguid
. Le module xt_qtaguid
sera complètement obsolète lorsque la version minimale du noyau requise pour une version Android est 4.9 ou supérieure.
Dans la version Android 9, seuls les appareils lancés avec la version Android 9 doivent disposer de la nouvelle fonctionnalité eBPF. Pour les appareils livrés avec un noyau prenant en charge les outils eBPF, nous vous recommandons de le mettre à jour vers la nouvelle fonctionnalité eBPF lors de la mise à niveau vers la version Android 9. Il n'y a pas de test CTS pour appliquer cette mise à jour.
Validation
Vous devez régulièrement prendre des correctifs à partir des noyaux communs Android et du maître AOSP Android. Assurez-vous que votre implémentation réussit les tests VTS et CTS applicables, netd_unit_test
et libbpf_test
.
Essai
Il existe des net_tests du noyau pour vous assurer que les fonctionnalités requises sont activées et que les correctifs du noyau requis sont rétroportés. Les tests sont intégrés dans le cadre des tests VTS de la version Android 9. Il existe des tests unitaires dans system/netd/
( netd_unit_test
et libbpf_test
). Il y a quelques tests dans netd_integration_test
pour valider le comportement global du nouvel outil.
CTS et vérificateur CTS
Étant donné que les deux modules de surveillance du trafic sont pris en charge dans la version Android 9, il n'y a pas de test CTS pour forcer la mise en œuvre du nouveau module sur tous les appareils. Mais pour les appareils avec une version de noyau supérieure à 4.9 qui étaient initialement livrés avec la version Android 9 (c'est-à-dire le premier niveau d'API>= 28), il existe des tests CTS sur GSI pour valider que le nouveau module est correctement configuré. Les anciens tests CTS tels que TrafficStatsTest
, NetworkUsageStatsTest
et CtsNativeNetTestCases
peuvent être utilisés pour vérifier que le comportement est cohérent avec l'ancien module UID.
Test manuel
Il existe des tests unitaires dans system/netd/
( netd_unit_test
, netd_integration_test
et libbpf_test
). Il existe un support dumpsys pour vérifier manuellement l'état. La commande dumpsys netd
affiche l'état de base du module trafficController
et si eBPF est correctement activé. Si eBPF est activé, la commande dumpsys netd trafficcontroller
affiche le contenu détaillé de chaque carte eBPF, y compris les informations de socket balisées, les statistiques par balise, l'UID et l'iface, et la correspondance UID du propriétaire.
Lieux de test
Les tests CTS sont situés à:
- https://android.googlesource.com/platform/cts/+/master/tests/tests/net/src/android/net/cts/TrafficStatsTest.java {: .external}
- https://android.googlesource.com/platform/cts/+/master/tests/tests/app.usage/src/android/app/usage/cts/NetworkUsageStatsTest.java {: .external}
- https://android.googlesource.com/platform/system/netd/+/master/tests/bpf_base_test.cpp {: .external}
Les tests VTS se trouvent sur https://android.googlesource.com/kernel/tests/+/master/net/test/bpf_test.py .
Les tests unitaires se trouvent à :
- https://android.googlesource.com/platform/system/netd/+/master/libbpf/BpfNetworkStatsTest.cpp {: .external}
- https://android.googlesource.com/platform/system/netd/+/master/server/TrafficControllerTest.cpp {: .external}