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

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

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

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

Требования

  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, которые напрямую читают файл процедуры модуля 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 находятся по адресу:

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

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