Инструмент анализа сетевого трафика eBPF использует сочетание реализации ядра и пользовательского пространства для мониторинга использования сети на устройстве с момента последней загрузки. Он предоставляет дополнительные функции, такие как тегирование сокетов, разделение активного и фонового трафика и брандмауэр на основе UID для блокировки доступа приложений к сети в зависимости от состояния телефона. Статистика, собранная инструментом, хранится в структуре данных ядра, называемой eBPF maps
и используется такими службами, как NetworkStatsService
для предоставления постоянной статистики трафика с момента последней загрузки.
Примеры и источники
Изменения в пользовательском пространстве в основном касаются проектов system/netd
и framework/base
. Разработка ведётся в AOSP, поэтому код AOSP всегда будет актуальным. Исходный код в основном находится в system/netd/server/TrafficController*
, system/netd/bpfloader
и system/netd/libbpf/
. Некоторые необходимые изменения фреймворка также внесены в framework/base/
и system/core
.
Выполнение
Начиная с Android 9, устройства Android с ядром 4.9 или выше, изначально поставляемые с версией P, ДОЛЖНЫ использовать учёт сетевого трафика на основе eBPF вместо xt_qtaguid
. Новая инфраструктура более гибкая и удобная в обслуживании, а также не требует использования кода ядра, не входящего в состав ядра.
Основные различия в конструкции между традиционным мониторингом трафика и мониторингом трафика eBPF показаны на рисунке 1.
Рисунок 1. Различия в дизайне мониторинга трафика в устаревшей (слева) и eBPF (справа)
Новая архитектура trafficController
основана на фильтре eBPF per- cgroup
и модуле сетевого фильтра xt_bpf
внутри ядра. Эти фильтры eBPF применяются к передаваемым/принимаемым пакетам при их прохождении через фильтр. Фильтр eBPF cgroup
расположен на транспортном уровне и отвечает за подсчёт трафика по правильному UID в зависимости от UID сокета и настроек пользовательского пространства. Сетевой фильтр xt_bpf
подключен к цепочке bw_raw_PREROUTING
и bw_mangle_POSTROUTING
и отвечает за подсчёт трафика по правильному интерфейсу.
Во время загрузки процесс пользовательского пространства trafficController
создаёт карты eBPF, используемые для сбора данных, и закрепляет все карты в виртуальном файле в sys/fs/bpf
. Затем привилегированный процесс bpfloader
загружает предварительно скомпилированную программу eBPF в ядро и подключает её к нужной cgroup
. Для всего трафика существует одна корневая cgroup
, поэтому все процессы должны быть включены в cgroup
по умолчанию.
Во время выполнения trafficController
может помечать/снимать тег с сокета, записывая данные в traffic_cookie_tag_map
и traffic_uid_counterSet_map
. NetworkStatsService
может считывать данные статистики трафика из traffic_tag_stats_map
, traffic_uid_stats_map
и traffic_iface_stats_map
. Помимо функции сбора статистики трафика, trafficController
и фильтр cgroup
eBPF также отвечают за блокировку трафика с определённых UID в зависимости от настроек телефона. Функция блокировки сетевого трафика на основе UID заменяет модуль xt_owner
в ядре, а режим детализации можно настроить, записав данные в traffic_powersave_uid_map
, traffic_standby_uid_map
и traffic_dozable_uid_map
.
Новая реализация соответствует устаревшей реализации модуля xt_qtaguid
, поэтому TrafficController
и NetworkStatsService
будут работать как с устаревшей, так и с новой реализацией. Если приложение использует публичные API, оно не должно испытывать никакой разницы между использованием инструментов xt_qtaguid
или eBPF в фоновом режиме.
Если ядро устройства основано на общем ядре Android 4.9 (SHA 39c856663dcc81739e52b02b77d6af259eb838f6 или выше), то для реализации нового инструмента eBPF не требуется вносить никаких изменений в HAL, драйверы или код ядра.
Требования
В конфигурации ядра ДОЛЖНЫ быть включены следующие конфигурации:
-
CONFIG_CGROUP_BPF=y
-
CONFIG_BPF=y
-
CONFIG_BPF_SYSCALL=y
-
CONFIG_NETFILTER_XT_MATCH_BPF=y
-
CONFIG_INET_UDP_DIAG=y
Тест конфигурации ядра VTS полезен для проверки включения правильной конфигурации.
-
Процесс устаревания устаревшего xt_qtaguid
Новый инструмент eBPF заменяет модуль xt_qtaguid
и модуль xt_owner
, на котором он основан. Мы начнём удалять модуль xt_qtaguid
из ядра Android и отключать его ненужные конфигурации.
В версии Android 9 модуль xt_qtaguid
включён на всех устройствах, но все публичные API, напрямую читающие proc-файл модуля xt_qtaguid
, перемещены в службу NetworkManagement
Service. В зависимости от версии ядра устройства и первого уровня API служба NetworkManagement
Service определяет, включены ли инструменты eBPF, и выбирает нужный модуль для получения статистики использования сети для каждого приложения. Приложениям с уровнем SDK 28 и выше доступ к proc-файлам xt_qtaguid
запрещён политикой sepolicy.
В следующем релизе Android после 9 доступ приложений к этим proc-файлам xt_qtaguid
будет полностью заблокирован. Мы начнём удалять модуль xt_qtaguid
из новых распространённых ядер Android. После этого мы обновим базовую конфигурацию Android для этой версии ядра, чтобы явно отключить модуль xt_qtaguid
. Модуль xt_qtaguid
будет полностью упразднён, когда минимальная требуемая версия ядра для выпуска Android станет 4.9 или выше.
В версии Android 9 новая функция eBPF требуется только для устройств, выпущенных вместе с Android 9. Для устройств с ядром, поддерживающим инструменты eBPF, мы рекомендуем обновить его до новой функции eBPF при обновлении до версии Android 9. Тест CTS для принудительного запуска этого обновления отсутствует.
Проверка
Регулярно устанавливайте патчи из общих ядер Android и основного ядра Android AOSP. Убедитесь, что ваша реализация проходит соответствующие тесты VTS и CTS, netd_unit_test
и libbpf_test
.
Тестирование
Для проверки наличия необходимых функций и бэкпортированных патчей ядра предусмотрены тесты net_tests . Эти тесты интегрированы в состав VTS-тестов релиза Android 9. В каталоге system/netd/
есть несколько модульных тестов ( netd_unit_test
и libbpf_test
). В каталоге netd_integration_test
есть несколько тестов для проверки общего поведения нового инструмента.
CTS и верификатор CTS
Поскольку оба модуля мониторинга трафика поддерживаются в версии Android 9, тест CTS для принудительной реализации нового модуля на всех устройствах отсутствует. Однако для устройств с версией ядра выше 4.9, изначально поставляемых с версией Android 9 (т.е. первый уровень API >= 28), предусмотрены тесты CTS на GSI для проверки корректности настройки нового модуля. Старые тесты CTS, такие как TrafficStatsTest
, NetworkUsageStatsTest
и CtsNativeNetTestCases
можно использовать для проверки соответствия поведения старому модулю UID.
Ручное тестирование
В system/netd/
есть несколько модульных тестов ( netd_unit_test
, netd_integration_test
и libbpf_test
). Для ручной проверки состояния предусмотрена поддержка dumpsys. Команда dumpsys netd
показывает базовое состояние модуля trafficController
и правильность включения eBPF. Если eBPF включен, команда dumpsys netd trafficcontroller
отображает подробное содержимое каждой карты eBPF, включая информацию о тегированных сокетах, статистику по тегам, UID и iface, а также соответствие UID владельца.
Места проведения испытаний
Тесты CTS проводятся по адресу:
- https://android.googlesource.com/platform/cts/+/android16-release/tests/tests/net/src/android/net/cts/TrafficStatsTest.java
- https://android.googlesource.com/platform/cts/+/android16-release/tests/tests/app.usage/src/android/app/usage/cts/NetworkUsageStatsTest.java
- https://android.googlesource.com/platform/system/netd/+/android16-release/tests/bpf_base_test.cpp
Тесты VTS находятся по адресу https://android.googlesource.com/kernel/tests/+/android16-release/net/test/bpf_test.py .
Модульные тесты находятся по адресу: