Pemantauan traffic eBPF

Alat traffic jaringan eBPF menggunakan kombinasi penerapan ruang kernel dan pengguna untuk memantau penggunaan jaringan di perangkat sejak perangkat terakhir kali di-boot. Fitur ini menyediakan fungsi tambahan seperti pemberian tag soket, pemisahan traffic latar depan/latar belakang, dan firewall per-UID untuk memblokir akses jaringan aplikasi, bergantung pada status ponsel. Statistik yang dikumpulkan dari alat ini disimpan dalam struktur data kernel yang disebut eBPF maps dan hasilnya digunakan oleh layanan seperti NetworkStatsService untuk memberikan statistik traffic persisten sejak booting terakhir.

Contoh dan sumber

Perubahan ruang pengguna terutama ada di proyek system/netd dan framework/base. Pengembangan dilakukan di AOSP, sehingga kode AOSP akan selalu terbaru. Sumbernya terutama terletak di system/netd/server/TrafficController*, system/netd/bpfloader, dan system/netd/libbpf/. Beberapa perubahan framework yang diperlukan juga ada di framework/base/ dan system/core.

Implementasi

Mulai dari Android 9, perangkat Android yang berjalan di kernel 4.9 atau yang lebih tinggi dan awalnya dikirimkan dengan rilis P HARUS menggunakan penghitungan pemantauan traffic jaringan berbasis eBPF, bukan xt_qtaguid. Infrastruktur baru ini lebih fleksibel dan lebih mudah dikelola serta tidak memerlukan kode kernel di luar struktur.

Perbedaan desain utama antara pemantauan traffic lama dan eBPF diilustrasikan dalam Gambar 1.

Perbedaan desain pemantauan traffic eBPF dan lama

Gambar 1. Perbedaan desain pemantauan traffic lama (kiri) dan eBPF (kanan)

Desain trafficController baru didasarkan pada filter eBPF per-cgroup dan modul netfilter xt_bpf di dalam kernel. Filter eBPF ini diterapkan pada tx/rx paket saat melewati filter. Filter eBPF cgroup berada di lapisan transport dan bertanggung jawab untuk menghitung traffic terhadap UID yang tepat, bergantung pada UID soket serta setelan ruang pengguna. Netfilter xt_bpf terhubung di rantai bw_raw_PREROUTING dan bw_mangle_POSTROUTING dan bertanggung jawab untuk menghitung traffic terhadap antarmuka yang benar.

Saat waktu booting, proses ruang pengguna trafficController membuat peta eBPF yang digunakan untuk pengumpulan data dan menyematkan semua peta sebagai file virtual di sys/fs/bpf. Kemudian, proses yang memiliki hak istimewa bpfloader memuat program eBPF yang telah dikompilasi sebelumnya ke dalam kernel dan melampirkannya ke cgroup yang benar. Ada satu root cgroup untuk semua traffic, sehingga semua proses harus disertakan dalam cgroup tersebut secara default.

Saat runtime, trafficController dapat memberi/menghapus tag soket dengan menulis ke traffic_cookie_tag_map dan traffic_uid_counterSet_map. NetworkStatsService dapat membaca data statistik traffic dari traffic_tag_stats_map, traffic_uid_stats_map, dan traffic_iface_stats_map. Selain fungsi pengumpulan statistik traffic, filter eBPF trafficController dan cgroup juga bertanggung jawab untuk memblokir traffic dari UID tertentu, bergantung pada setelan ponsel. Fitur pemblokiran traffic jaringan berbasis UID menggantikan modul xt_owner di dalam kernel dan mode detail dapat dikonfigurasi dengan menulis ketraffic_powersave_uid_map, traffic_standby_uid_map, dan traffic_dozable_uid_map.

Implementasi baru mengikuti implementasi modul xt_qtaguid lama sehingga TrafficController dan NetworkStatsService akan berjalan dengan implementasi lama atau baru. Jika menggunakan API publik, aplikasi tidak akan mengalami perbedaan apa pun, baik saat alat xt_qtaguid maupun eBPF digunakan di latar belakang.

Jika kernel perangkat didasarkan pada kernel umum Android 4.9 (SHA 39c856663dcc81739e52b02b77d6af259eb838f6 atau yang lebih baru), tidak ada modifikasi pada HAL, driver, atau kode kernel yang diperlukan untuk menerapkan alat eBPF baru.

Persyaratan

  1. Konfigurasi kernel HARUS mengaktifkan konfigurasi berikut:

    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

    Pengujian konfigurasi kernel VTS berguna saat memverifikasi apakah konfigurasi yang benar diaktifkan.

Proses penghentian penggunaan xt_qtaguid lama

Alat eBPF baru menggantikan modulxt_qtaguid dan modul xt_owner yang menjadi dasarnya. Kita akan mulai menghapus modul xt_qtaguid dari kernel Android dan menonaktifkan konfigurasi yang tidak diperlukan.

Pada rilis Android 9, modul xt_qtaguid diaktifkan di semua perangkat, tetapi semua API publik yang langsung membaca file proc modul xt_qtaguid dipindahkan ke Layanan NetworkManagement. Bergantung pada versi kernel perangkat dan level API pertama, Layanan NetworkManagement mengetahui apakah alat eBPF diaktifkan dan memilih modul yang tepat untuk mendapatkan setiap statistik penggunaan jaringan aplikasi. Aplikasi dengan level SDK 28 dan yang lebih tinggi diblokir untuk mengakses file proc xt_qtaguid oleh sepolicy.

Pada rilis Android berikutnya setelah 9, akses aplikasi ke file proc xt_qtaguid tersebut akan diblokir sepenuhnya dan kami akan mulai menghapus modul xt_qtaguid dari kernel umum Android baru. Setelah dihapus, kami akan mengupdate konfigurasi dasar Android untuk versi kernel tersebut guna menonaktifkan modul xt_qtaguid secara eksplisit. Modul xt_qtaguid akan sepenuhnya dihentikan penggunaannya saat persyaratan versi kernel minimum untuk rilis Android adalah 4.9 atau yang lebih baru.

Dalam rilis Android 9, hanya perangkat yang diluncurkan dengan rilis Android 9 yang diwajibkan memiliki fitur eBPF baru. Untuk perangkat yang dikirim dengan kernel yang dapat mendukung alat eBPF, sebaiknya update ke fitur eBPF baru saat mengupgrade ke rilis Android 9. Tidak ada pengujian CTS untuk menerapkan update tersebut.

Validasi

Anda harus mengambil patch secara rutin dari kernel umum Android dan main AOSP Android. Pastikan implementasi Anda lulus uji VTS dan CTS yang berlaku, netd_unit_test, dan libbpf_test.

Pengujian

Ada net_tests kernel untuk memastikan Anda telah mengaktifkan fitur yang diperlukan dan patch kernel yang diperlukan telah di-backport. Pengujian ini diintegrasikan sebagai bagian dari pengujian VTS rilis Android 9. Ada beberapa pengujian unit di system/netd/ (netd_unit_test dan libbpf_test). Ada beberapa pengujian di netd_integration_test untuk memvalidasi perilaku keseluruhan alat baru.

CTS dan pemverifikasi CTS

Karena kedua modul pemantauan traffic didukung dalam rilis Android 9, tidak ada pengujian CTS untuk mewajibkan penerapan modul baru di semua perangkat. Namun, untuk perangkat dengan versi kernel yang lebih tinggi dari 4.9 yang awalnya dikirimkan dengan rilis Android 9 (yaitu level API pertama >= 28), ada tes CTS di GSI untuk memvalidasi apakah modul baru dikonfigurasi dengan benar. Pengujian CTS lama seperti TrafficStatsTest, NetworkUsageStatsTest, dan CtsNativeNetTestCases dapat digunakan untuk memverifikasi perilaku agar konsisten dengan modul UID lama.

Pengujian manual

Ada beberapa pengujian unit di system/netd/ (netd_unit_test, netd_integration_test dan libbpf_test). Ada dukungan dumpsys untuk memeriksa status secara manual. Perintah dumpsys netd menampilkan status dasar modul trafficController dan apakah eBPF diaktifkan dengan benar. Jika eBPF diaktifkan, perintah dumpsys netd trafficcontroller akan menampilkan konten mendetail dari setiap peta eBPF, termasuk informasi soket yang diberi tag, statistik per tag, UID dan antarmuka, serta kecocokan UID pemilik.

Lokasi pengujian

Pengujian CTS terletak di:

Pengujian VTS terletak di https://android.googlesource.com/kernel/tests/+/android16-release/net/test/bpf_test.py.

Pengujian unit terletak di: