eBPF नेटवर्क ट्रैफ़िक टूल, कर्नेल और उपयोगकर्ता स्पेस के कॉम्बिनेशन का इस्तेमाल करता है. इससे डिवाइस के बूट होने के बाद से लेकर अब तक, डिवाइस पर नेटवर्क के इस्तेमाल की निगरानी की जाती है. यह अतिरिक्त सुविधाएं देता है, जैसे कि सॉकेट टैगिंग, फ़ोरग्राउंड/बैकग्राउंड ट्रैफ़िक को अलग करना, और हर यूआईडी के लिए फ़ायरवॉल. इससे फ़ोन की स्थिति के आधार पर, ऐप्लिकेशन को नेटवर्क ऐक्सेस करने से रोका जा सकता है. इस टूल से इकट्ठा किए गए आंकड़े, कर्नल डेटा स्ट्रक्चर में सेव किए जाते हैं. इसे 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 से, कर्नेल 4.9 या इसके बाद के वर्शन पर काम करने वाले और P रिलीज़ के साथ शिप किए गए Android डिवाइसों को xt_qtaguid के बजाय, eBPF पर आधारित नेटवर्क ट्रैफ़िक मॉनिटरिंग अकाउंटिंग का इस्तेमाल करना होगा. नया इन्फ़्रास्ट्रक्चर ज़्यादा बेहतर है और इसे मैनेज करना भी आसान है. इसके लिए, किसी भी आउट-ऑफ़-ट्री कर्नल कोड की ज़रूरत नहीं होती.
लेगसी और eBPF ट्रैफ़िक मॉनिटरिंग के बीच डिज़ाइन से जुड़े मुख्य अंतर, इमेज 1 में दिखाए गए हैं.
पहली इमेज. लेगसी (बाएं) और eBPF (दाएं) ट्रैफ़िक मॉनिटरिंग डिज़ाइन के बीच अंतर
नया trafficController डिज़ाइन, हर cgroup eBPF फ़िल्टर के साथ-साथ कर्नल के अंदर मौजूद xt_bpf netfilter मॉड्यूल पर भी आधारित है. ये eBPF फ़िल्टर, पैकेट tx/rx पर लागू होते हैं. ऐसा तब होता है, जब वे फ़िल्टर से गुज़रते हैं. cgroup eBPF फ़िल्टर, ट्रांसपोर्ट लेयर पर मौजूद होता है. यह सॉकेट यूआईडी और यूज़रस्पेस सेटिंग के आधार पर, सही यूआईडी के हिसाब से ट्रैफ़िक को गिनने के लिए ज़िम्मेदार होता है.
xt_bpf netfilter, bw_raw_PREROUTING और bw_mangle_POSTROUTING चेन से जुड़ा होता है. साथ ही, यह सही इंटरफ़ेस के हिसाब से ट्रैफ़िक को गिनने के लिए ज़िम्मेदार होता है.
बूट होने के समय, userspace प्रोसेस 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 फ़िल्टर भी, फ़ोन की सेटिंग के आधार पर कुछ यूआईडी से ट्रैफ़िक को ब्लॉक करने के लिए ज़िम्मेदार होते हैं. यूआईडी के आधार पर नेटवर्क ट्रैफ़िक को ब्लॉक करने की सुविधा, कर्नल के अंदर मौजूद 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, ड्राइवर या कर्नेल कोड में कोई बदलाव करने की ज़रूरत नहीं है.
ज़रूरी शर्तें
कर्नेल कॉन्फ़िगरेशन में, ये कॉन्फ़िगरेशन चालू होने चाहिए:
CONFIG_CGROUP_BPF=yCONFIG_BPF=yCONFIG_BPF_SYSCALL=yCONFIG_NETFILTER_XT_MATCH_BPF=yCONFIG_INET_UDP_DIAG=y
वीटीएस कर्नल कॉन्फ़िगरेशन टेस्ट यह पुष्टि करने में मददगार होता है कि सही कॉन्फ़िगरेशन चालू है.
xt_qtaguid के लेगसी वर्शन को बंद करने की प्रोसेस
नया eBPF टूल, xt_qtaguid मॉड्यूल और xt_owner मॉड्यूल की जगह ले रहा है. हम Android कर्नल से xt_qtaguid मॉड्यूल को हटाना शुरू कर देंगे. साथ ही, इसके गैर-ज़रूरी कॉन्फ़िगरेशन बंद कर देंगे.
Android 9 के रिलीज़ में, सभी डिवाइसों में xt_qtaguid मॉड्यूल चालू होता है. हालांकि, xt_qtaguid मॉड्यूल की proc फ़ाइल को सीधे तौर पर पढ़ने वाले सभी सार्वजनिक एपीआई को NetworkManagement सेवा में ले जाया जाता है.
डिवाइस के कर्नल वर्शन और पहले एपीआई लेवल के आधार पर, NetworkManagement सेवा को पता होता है कि eBPF टूल चालू है या नहीं. साथ ही, यह हर ऐप्लिकेशन के नेटवर्क इस्तेमाल के आंकड़े पाने के लिए सही मॉड्यूल चुनती है. एसडीके लेवल 28 और इससे ज़्यादा लेवल वाले ऐप्लिकेशन को sepolicy, xt_qtaguid proc फ़ाइलों को ऐक्सेस करने से रोकता है.
Android 9 के बाद रिलीज़ होने वाले Android के अगले वर्शन में, ऐप्लिकेशन को उन xt_qtaguid proc फ़ाइलों का ऐक्सेस नहीं मिलेगा. हम नए Android कॉमन कर्नल से xt_qtaguid मॉड्यूल को हटाना शुरू कर देंगे. इसे हटाने के बाद, हम उस कर्नल वर्शन के लिए Android के बेस कॉन्फ़िगरेशन को अपडेट करेंगे, ताकि xt_qtaguid मॉड्यूल को साफ़ तौर पर बंद किया जा सके. Android के किसी वर्शन के लिए कर्नल का सबसे कम वर्शन 4.9 या इससे ज़्यादा होने पर, xt_qtaguid मॉड्यूल पूरी तरह से बंद हो जाएगा.
Android 9 की रिलीज़ में, सिर्फ़ उन डिवाइसों में नई eBPF सुविधा होनी चाहिए जो Android 9 की रिलीज़ के साथ लॉन्च हुए हैं. जिन डिवाइसों में ऐसा कर्नेल है जो eBPF टूल के साथ काम कर सकता है उनके लिए, हमारा सुझाव है कि Android 9 पर अपग्रेड करते समय, कर्नेल को नई eBPF सुविधा पर अपडेट करें. इस अपडेट को लागू करने के लिए, कोई सीटीएस टेस्ट नहीं है.
सत्यापन
आपको Android के सामान्य कर्नल और Android AOSP
main से नियमित तौर पर पैच लेने चाहिए. पक्का करें कि आपका लागू किया गया तरीका, VTS और CTS टेस्ट, netd_unit_test, और libbpf_test पास कर ले.
जांच करना
यह पक्का करने के लिए कि आपके पास ज़रूरी सुविधाएं चालू हों और ज़रूरी कर्नल पैच बैकपोर्ट किए गए हों, कर्नल net_tests होते हैं. इन टेस्ट को, Android 9 के रिलीज़ किए गए वीटीएस टेस्ट के हिस्से के तौर पर इंटिग्रेट किया गया है. system/netd/ में कुछ यूनिट टेस्ट हैं netd_unit_test
और
libbpf_test).
netd_integration_test में कुछ टेस्ट हैं, ताकि नए टूल के पूरे व्यवहार की पुष्टि की जा सके.
सीटीएस और सीटीएस की पुष्टि करने वाला टूल
Android 9 की रिलीज़ में, ट्रैफ़िक मॉनिटरिंग के दोनों मॉड्यूल काम करते हैं. इसलिए, सभी डिवाइसों पर नया मॉड्यूल लागू करने के लिए, कोई सीटीएस टेस्ट नहीं है. हालांकि, कर्नेल वर्शन 4.9 से ज़्यादा वाले ऐसे डिवाइस जो मूल रूप से Android 9 के साथ शिप किए गए थे (यानी, पहला एपीआई लेवल >= 28), उनके लिए GSI पर CTS टेस्ट उपलब्ध हैं. इनसे यह पुष्टि की जा सकती है कि नया मॉड्यूल सही तरीके से कॉन्फ़िगर किया गया है. TrafficStatsTest, NetworkUsageStatsTest, और CtsNativeNetTestCases जैसे पुराने सीटीएस टेस्ट का इस्तेमाल करके, यह पुष्टि की जा सकती है कि व्यवहार, पुराने यूआईडी मॉड्यूल के मुताबिक है.
मैन्युअल टेस्टिंग
system/netd/ में कुछ यूनिट टेस्ट हैं
(netd_unit_test,
netd_integration_test
और
libbpf_test).
स्टेटस की मैन्युअल तरीके से जांच करने के लिए, dumpsys का इस्तेमाल किया जा सकता है. dumpsys netd कमांड से, trafficController मॉड्यूल का बुनियादी स्टेटस दिखता है. साथ ही, यह भी पता चलता है कि eBPF सही तरीके से चालू है या नहीं. अगर eBPF चालू है, तो dumpsys netd trafficcontroller कमांड से, हर eBPF मैप का पूरा कॉन्टेंट दिखता है. इसमें टैग किए गए सॉकेट की जानकारी, हर टैग के हिसाब से आंकड़े, यूआईडी और iface, और मालिक के यूआईडी से मैच होने की जानकारी शामिल होती है.
टेस्ट लोकेशन
सीटीएस टेस्ट यहां मौजूद हैं:
- 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
वीटीएस टेस्ट, https://android.googlesource.com/kernel/tests/+/android17-release/net/test/bpf_test.py पर मौजूद हैं.
यूनिट टेस्ट यहां मौजूद हैं: