כלי התנועה ברשת 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.
איור 1. הבדלים בין העיצוב של מעקב תנועת הגולשים בגרסה הקודמת (משמאל) לבין העיצוב ב-eBPF (מימין)
העיצוב החדש של trafficController
מבוסס גם על מסנן eBPF לכל cgroup
וגם על מודול xt_bpf
netfilter בתוך הליבה. מסנני ה-eBPF האלה מוחלים על חבילות tx/rx כשהן עוברות דרך המסנן. מסנן cgroup
eBPF
ממוקם בשכבת התעבורה ואחראי לספירת התעבורה
לפי ה-UID הנכון, בהתאם ל-UID של השקע ולהגדרה של מרחב המשתמש.
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
.
בנוסף לפונקציה של איסוף נתוני התנועה, המסנן trafficController
ו-cgroup
eBPF אחראי גם לחסימת תנועה ממזהי משתמש מסוימים, בהתאם להגדרות הטלפון. התכונה של חסימת תנועת רשת שמבוססת על 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 ומעלה), לא נדרשים שינויים ב-HAL, במנהלי ההתקנים או בקוד הליבה כדי להטמיע את כלי ה-eBPF החדש.
דרישות
ההגדרות הבאות צריכות להיות מופעלות בקובץ ההגדרות של ליבת המערכת:
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
מליבת Android ונשבית את ההגדרות המיותרות שלו.
בגרסה Android 9, המודול xt_qtaguid
מופעל בכל המכשירים, אבל כל ממשקי ה-API הציבוריים שקוראים ישירות את קובץ התהליך של המודול xt_qtaguid
מועברים לשירות NetworkManagement
.
בהתאם לגרסת ליבת המכשיר ולרמת ה-API הראשונה, שירות NetworkManagement
יודע אם כלי eBPF מופעלים ובוחר את המודול הנכון לקבלת נתוני השימוש ברשת של כל אפליקציה. אפליקציות עם SDK ברמה 28 ומעלה נחסמות מגישה לקבצים NetworkManagement
proc על ידי sepolicy.xt_qtaguid
בגרסת 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 Verifier
מכיוון ששני מודולי מעקב התנועה נתמכים בגרסה Android 9, אין בדיקת CTS שמאלצת הטמעה של המודול החדש בכל המכשירים. אבל במכשירים עם גרסת ליבה גבוהה מ-4.9 שסופקו במקור עם גרסת Android 9 (כלומר, רמת ה-API הראשונה >= 28), יש בדיקות CTS ב-GSI כדי לאמת שהמודול החדש מוגדר בצורה נכונה. אפשר להשתמש בבדיקות CTS ישנות כמו TrafficStatsTest
,
NetworkUsageStatsTest
ו-CtsNativeNetTestCases
כדי לוודא שההתנהגות עקבית עם מודול UID ישן.
בדיקה ידנית
יש כמה בדיקות יחידה ב-system/netd/
(netd_unit_test
,
netd_integration_test
and
libbpf_test
).
יש תמיכה ב-dumpsys לבדיקה ידנית של הסטטוס. הפקודה
dumpsys netd
מציגה את הסטטוס הבסיסי של מודול trafficController
ואם eBPF מופעל בצורה תקינה. אם eBPF מופעל, הפקודה
dumpsys netd trafficcontroller
מציגה את התוכן המפורט של כל מפת eBPF, כולל מידע על שקע מתויג, נתונים סטטיסטיים לכל תג, UID ו-iface, והתאמה של UID של בעלים.
מיקומי בדיקה
בדיקות CTS ממוקמות ב:
- https://android.googlesource.com/platform/cts/+/android16-release/tests/tests/net/src/android/net/cts/TrafficStatsTest.java
- https://android.googlesource.com/platform/cts/+/android16-release/tests/tests/app.usage/src/android/app/usage/cts/NetworkUsageStatsTest.java
- https://android.googlesource.com/platform/system/netd/+/android16-release/tests/bpf_base_test.cpp
הבדיקות של VTS ממוקמות בכתובת https://android.googlesource.com/kernel/tests/+/android16-release/net/test/bpf_test.py.
בדיקות היחידה נמצאות ב: