ابزار ترافیک شبکه 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 عرضه میشوند، باید به جای xt_qtaguid
از حسابداری نظارت بر ترافیک شبکه مبتنی بر eBPF استفاده کنند. زیرساخت جدید انعطاف پذیرتر و قابل نگهداری تر است و نیازی به کد هسته خارج از درخت ندارد.
تفاوت های اصلی طراحی بین نظارت بر ترافیک قدیمی و eBPF در شکل 1 نشان داده شده است.
شکل 1. تفاوت طراحی نظارت بر ترافیک میراث (چپ) و eBPF (راست).
طراحی جدید trafficController
بر اساس فیلتر eBPF برای هر cgroup
و همچنین ماژول فیلتر شبکه 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
و فیلتر eBPF cgroup
نیز بسته به تنظیمات تلفن، مسئول مسدود کردن ترافیک از 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
از هسته اندروید و غیرفعال کردن تنظیمات غیر ضروری آن می کنیم.
در نسخه اندروید 9، ماژول xt_qtaguid
در همه دستگاهها روشن است، اما همه APIهای عمومی که مستقیماً فایل proc ماژول xt_qtaguid
را میخوانند به سرویس NetworkManagement
منتقل میشوند. بسته به نسخه هسته دستگاه و سطح اول API، سرویس NetworkManagement
میداند که آیا ابزارهای eBPF روشن هستند یا خیر و ماژول مناسبی را برای دریافت آمار استفاده از شبکه هر برنامه انتخاب میکند. برنامههای دارای SDK سطح 28 و بالاتر از دسترسی به فایلهای xt_qtaguid
proc توسط سیاستگذاری مسدود شدهاند.
در نسخه بعدی اندروید پس از 9، دسترسی برنامه به آن فایلهای xt_qtaguid
proc به طور کامل مسدود میشود، ما شروع به حذف ماژول xt_qtaguid
از هستههای رایج جدید اندروید خواهیم کرد. پس از حذف، پیکربندی پایه اندروید را برای آن نسخه هسته بهروزرسانی میکنیم تا ماژول xt_qtaguid
به صراحت خاموش شود. ماژول xt_qtaguid
زمانی که حداقل نسخه هسته مورد نیاز برای نسخه اندروید 4.9 یا بالاتر باشد به طور کامل منسوخ می شود.
در نسخه اندروید 9، تنها دستگاه هایی که با نسخه اندروید 9 راه اندازی می شوند، باید ویژگی جدید eBPF را داشته باشند. برای دستگاههایی که دارای هستهای هستند که میتوانند از ابزارهای eBPF پشتیبانی کنند، توصیه میکنیم هنگام ارتقا به نسخه اندروید 9، آن را به ویژگی جدید eBPF بهروزرسانی کنید. هیچ تست CTS برای اجرای آن به روز رسانی وجود ندارد.
اعتبار سنجی
شما باید به طور مرتب وصله هایی را از هسته های رایج اندروید و AOSP اصلی اندروید دریافت کنید. مطمئن شوید که پیاده سازی شما تست های VTS و CTS قابل اجرا، netd_unit_test
و libbpf_test
را گذرانده است.
تست کردن
هسته net_tests وجود دارد تا اطمینان حاصل شود که ویژگیهای مورد نیاز را روشن کردهاید و وصلههای هسته مورد نیاز را بکپورت کردهاید. این تست ها به عنوان بخشی از تست های VTS انتشار اندروید 9 یکپارچه شده اند. تعدادی تست واحد در system/netd/
وجود دارد ( netd_unit_test
و libbpf_test
). تستهایی در netd_integration_test
برای تایید رفتار کلی ابزار جدید وجود دارد.
تایید کننده CTS و CTS
از آنجایی که هر دو ماژول نظارت بر ترافیک در نسخه اندروید 9 پشتیبانی میشوند، هیچ تست CTS برای اجرای ماژول جدید در همه دستگاهها وجود ندارد. اما برای دستگاههایی با نسخه هسته بالاتر از 4.9 که در ابتدا با نسخه اندروید 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 در آدرس زیر قرار دارند:
- 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 قرار دارند.
آزمون های واحد در: