כדי לעקוב אחרי השימוש ברשת במכשיר מאז ההפעלה האחרונה של המכשיר, כלי התעבורה ברשת 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 וגם על מודול netfilter בתוך הליבה.xt_bpf מסנני ה-eBPF האלה מוחלים על חבילות הנתונים שנשלחות או מתקבלות כשהן עוברות דרך המסנן. מסנן 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) מסוימים, בהתאם להגדרות הטלפון. התכונה של חסימת תנועת רשת שמבוססת על 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=yCONFIG_BPF=yCONFIG_BPF_SYSCALL=yCONFIG_NETFILTER_XT_MATCH_BPF=yCONFIG_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 ומעלה נחסמות מגישה לקבצים של xt_qtaguid proc על ידי sepolicy.
בגרסת 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/+/android17-release/tests/tests/net/src/android/net/cts/TrafficStatsTest.java
- https://android.googlesource.com/platform/cts/+/android17-release/tests/tests/app.usage/src/android/app/usage/cts/NetworkUsageStatsTest.java
- https://android.googlesource.com/platform/system/netd/+/android17-release/tests/bpf_base_test.cpp
הבדיקות של VTS נמצאות בכתובת https://android.googlesource.com/kernel/tests/+/android17-release/net/test/bpf_test.py.
בדיקות היחידה נמצאות ב: