Инструмент сетевого трафика 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. Различия в конструкции мониторинга трафика Legacy (слева) и eBPF (справа)
Новый дизайн trafficController
основан на фильтре eBPF 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 полезен при проверке правильной конфигурации.
-
Устаревший процесс прекращения поддержки xt_qtaguid
Новый инструмент eBPF заменяет модуль xt_qtaguid
и модуль xt_owner
, на котором он основан. Начнем удалять модуль xt_qtaguid
из ядра Android и отключать его ненужные конфиги.
В выпуске Android 9 модуль xt_qtaguid
включен на всех устройствах, но все общедоступные API, которые напрямую читают файл процедуры модуля xt_qtaguid
, перемещаются в службу NetworkManagement
Service. В зависимости от версии ядра устройства и первого уровня API служба NetworkManagement
определяет, включены ли инструменты eBPF, и выбирает правильный модуль для получения статистики использования сети для каждого приложения. Sepolicy блокирует доступ приложений с уровнем SDK 28 и выше к файлам процедур xt_qtaguid
.
В следующем выпуске Android после 9 доступ приложений к этим файлам процедуры 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. Убедитесь, что ваша реализация проходит применимые тесты 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/+/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 .
Модульные тесты находятся по адресу: