Инструмент сетевого трафика eBPF использует комбинацию реализации ядра и пользовательского пространства для мониторинга использования сети на устройстве с момента последней загрузки устройства. Он предоставляет дополнительные функции, такие как маркировка сокетов, разделение трафика переднего плана/фонового трафика и брандмауэр по каждому идентификатору пользователя для блокировки доступа приложений к сети в зависимости от состояния телефона. Статистика, собранная инструментом, хранится в структуре данных ядра, называемой 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
основан на фильтре per- cgroup
eBPF, а также на модуле xt_bpf
netfilter внутри ядра. Эти фильтры eBPF применяются к пакету tx/rx, когда он проходит через фильтр. Фильтр cgroup
eBPF расположен на транспортном уровне и отвечает за подсчет трафика по правильному 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 доступ приложений к этим файлам xt_qtaguid
proc будет полностью заблокирован, мы начнем удалять модуль xt_qtaguid
из новых общих ядер Android. После его удаления мы обновим базовую конфигурацию Android для этой версии ядра, чтобы явно отключить модуль xt_qtaguid
. Модуль xt_qtaguid
будет полностью устаревшим, когда минимальная требуемая версия ядра для выпуска Android будет 4.9 или выше.
В выпуске Android 9 только устройства, которые запускаются с выпуском Android 9, должны иметь новую функцию eBPF. Для устройств, которые поставляются с ядром, которое может поддерживать инструменты eBPF, мы рекомендуем обновить его до новой функции eBPF при обновлении до выпуска Android 9. Тест CTS для принудительного выполнения этого обновления отсутствует.
Проверка
Вам следует регулярно брать патчи из общих ядер Android и Android AOSP main. Убедитесь, что ваша реализация проходит соответствующие тесты VTS и CTS, netd_unit_test
и libbpf_test
.
Тестирование
Есть kernel 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/+/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
Тесты VTS находятся по адресу https://android.googlesource.com/kernel/tests/+/main/net/test/bpf_test.py .
Модульные тесты находятся по адресу: