Инструмент сетевого трафика 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
основан на фильтре percgroup cgroup
, а также на модуле netfilter xt_bpf
внутри ядра. Эти фильтры 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 полезен при проверке того, что включена правильная конфигурация.
-
MEM_LOCK
rlimit устройства ДОЛЖЕН быть установлен на 8 МБ или более.
Устаревший процесс xt_qtaguid устаревания
Новый инструмент eBPF заменяет модуль xt_qtaguid
и модуль xt_owner
, на котором он основан. Мы начнем удалять модуль xt_qtaguid
из ядра Android и отключать его ненужные конфиги.
В выпуске Android 9 модуль xt_qtaguid
включен на всех устройствах, но все общедоступные API, которые напрямую считывают файл proc модуля xt_qtaguid
, перемещены в службу NetworkManagement
. В зависимости от версии ядра устройства и первого уровня API служба NetworkManagement
знает, включены ли инструменты 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 только устройства, которые запускаются с выпуском Android 9, должны иметь новую функцию eBPF. Для устройств, поставляемых с ядром, поддерживающим инструменты eBPF, мы рекомендуем обновить его до новой функции eBPF при обновлении до выпуска Android 9. Не существует теста CTS для принудительного применения этого обновления.
Проверка
Вы должны регулярно брать патчи из общих ядер Android и Android AOSP master. Убедитесь, что ваша реализация проходит применимые тесты 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), на GSI есть тесты CTS для проверки правильности настройки нового модуля. Старые тесты 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/+/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}
Тесты VTS находятся по адресу https://android.googlesource.com/kernel/tests/+/master/net/test/bpf_test.py .
Модульные тесты находятся по адресу: