Мониторинг трафика eBPF

Инструмент сетевого трафика 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.

Различия в дизайне мониторинга трафика в устаревших версиях и eBPF

Рисунок 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, драйверах или коде ядра.

Требования

  1. В конфигурации ядра ДОЛЖНЫ быть включены следующие конфигурации:

    1. CONFIG_CGROUP_BPF=y
    2. CONFIG_BPF=y
    3. CONFIG_BPF_SYSCALL=y
    4. CONFIG_NETFILTER_XT_MATCH_BPF=y
    5. 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 проводятся по адресу:

Тесты VTS находятся по адресу https://android.googlesource.com/kernel/tests/+/main/net/test/bpf_test.py .

Модульные тесты находятся по адресу: