پایش ترافیک 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 که از هسته ۴.۹ یا بالاتر استفاده می‌کنند و در ابتدا با نسخه P عرضه شده‌اند باید به‌جای xt_qtaguid از حسابداری پایش ترافیک شبکه مبتنی بر eBPF استفاده کنند. زیرساخت جدید انعطاف‌پذیرتر و قابل‌نگهداری‌تر است و به هیچ کد هسته خارج از درخت نیاز ندارد.

تفاوت‌های طراحی اصلی بین پایش ترافیک قدیمی و eBPF در شکل ۱ نشان داده شده است.

تفاوت‌های طراحی نظارت بر ترافیک قدیمی و eBPF

شکل ۱. تفاوت‌های طراحی پایش ترافیک قدیمی (چپ) و eBPF (راست)

طراحی جدید trafficController براساس فیلتر eBPF به‌ازای هر cgroup و همچنین واحد netfilter xt_bpf در هسته است. این فیلترهای eBPF هنگام عبور بسته‌ها از فیلتر، روی بسته‌های tx/rx اعمال می‌شوند. فیلتر eBPF cgroup در لایه انتقال قرار دارد و مسئول شمارش ترافیک دربرابر شناسه کاربری صحیح بسته به شناسه کاربری سوکت و همچنین تنظیمات فضای کاربر است. ‫xt_bpf netfilter در زنجیره 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 بخواند. علاوه‌بر عملکرد جمع‌آوری آمار ترافیک، فیلتر eBPF trafficController و cgroup نیز مسئول مسدود کردن ترافیک از شناسه‌های کاربری خاص بسته به تنظیمات تلفن است. ویژگی مسدود کردن ترافیک شبکه براساس UID جایگزین واحد xt_owner در هسته است و حالت جزئیات را می‌توان با نوشتن در traffic_powersave_uid_map، traffic_standby_uid_map، و traffic_dozable_uid_map پیکربندی کرد.

پیاده‌سازی جدید از پیاده‌سازی واحد xt_qtaguid قدیمی پیروی می‌کند، بنابراین TrafficController و NetworkStatsService با پیاده‌سازی قدیمی یا جدید اجرا خواهند شد. اگر برنامه از میاناهای برنامه‌سازی کاربردی عمومی استفاده می‌کند، نباید تفاوتی داشته باشد که آیا از ابزارهای 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 در همه دستگاه‌ها روشن است، اما همه میاناهای برنامه‌سازی کاربردی عمومی که مستقیماً فایل proc ماژول xt_qtaguid را می‌خوانند به سرویس NetworkManagement منتقل شده‌اند. بسته به نسخه هسته دستگاه و اولین سطح میانای برنامه‌سازی کاربردی، «خدمات» NetworkManagement می‌داند که آیا ابزارهای eBPF روشن است یا نه و واحد مناسب را برای دریافت آمار استفاده از شبکه هر برنامه انتخاب می‌کند. برنامه‌هایی با سطح کیت توسعه نرم‌افزار ۲۸ و بالاتر از دسترسی به فایل‌های xt_qtaguid proc توسط sepolicy مسدود می‌شوند.

در نسخه بعدی Android پس‌از نسخه ۹، دسترسی برنامه به آن فایل‌های xt_qtaguid proc کاملاً مسدود خواهد شد و ما شروع به برداشتن ماژول xt_qtaguid از هسته‌های مشترک جدید Android خواهیم کرد. پس‌از برداشته شدن آن، پیکربندی پایه Android را برای آن نسخه هسته به‌روزرسانی خواهیم کرد تا صریحاً ماژول xt_qtaguid را خاموش کنیم. وقتی حداقل نسخه هسته موردنیاز برای انتشار Android نسخه ۴.۹ یا بالاتر باشد، ماژول xt_qtaguid کاملاً منسوخ خواهد شد.

در نسخه Android 9، فقط دستگاه‌هایی که با نسخه Android 9 راه‌اندازی می‌شوند ملزم به داشتن ویژگی جدید eBPF هستند. برای دستگاه‌هایی که با هسته‌ای عرضه شده‌اند که می‌تواند از ابزارهای eBPF پشتیبانی کند، توصیه می‌کنیم هنگام ارتقا به نسخه Android 9، آن را به ویژگی جدید eBPF به‌روزرسانی کنید. آزمایش CTS برای اعمال آن به‌روزرسانی وجود ندارد.

اعتبارسنجی

باید به‌طور منظم وصله‌هایی از هسته‌های مشترک Android و Android AOSP main دریافت کنید. مطمئن شوید پیاده‌سازی شما در آزمون‌های VTS و CTS مربوطه، netd_unit_test، و libbpf_test قبول شود.

آزمایش

آزمایش‌های شبکه هسته وجود دارد تا مطمئن شود ویژگی‌های موردنیاز روشن است و وصله‌های هسته موردنیاز به نسخه‌های قبلی منتقل شده است. آزمایش‌ها به‌عنوان بخشی از آزمایش‌های VTS نسخه Android 9 ادغام شده‌اند. چند آزمایش واحد در system/netd/ (netd_unit_test و libbpf_test) وجود دارد. چند آزمایش در netd_integration_test برای اعتبارسنجی رفتار کلی ابزار جدید وجود دارد.

«مجموعه آزمایش سازگاری» و «درستی‌سنج مجموعه آزمایش سازگاری»

ازآنجایی‌که هر دو واحد پایش ترافیک در نسخه Android 9 پشتیبانی می‌شوند، آزمون CTS برای اجبار کردن پیاده‌سازی واحد جدید در همه دستگاه‌ها وجود ندارد. اما برای دستگاه‌هایی با نسخه هسته بالاتر از ۴.۹ که در ابتدا با نسخه 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/+/android17-release/net/test/bpf_test.py قرار دارند.

آزمون‌های واحد در اینجا قرار دارند: