เครื่องมือตรวจสอบการรับส่งข้อมูลเครือข่าย 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 เหล่านี้กับการส่ง/รับแพ็กเก็ตเมื่อผ่านตัวกรอง 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
นอกจากฟังก์ชันการเก็บรวบรวมสถิติการเข้าชมแล้ว ตัวกรอง eBPF trafficController
และ 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 ขึ้นไป) ก็ไม่จำเป็นต้องแก้ไข 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
NetworkManagement
บริการจะทราบว่าเครื่องมือ eBPF เปิดอยู่หรือไม่ และเลือกข้อบังคับที่เหมาะสมเพื่อรับสถิติการใช้งานเครือข่ายของแอปแต่ละรายการ ทั้งนี้ขึ้นอยู่กับเวอร์ชันเคอร์เนลของอุปกรณ์และระดับ API แรก แอปที่มี SDK ระดับ 28 ขึ้นไปจะถูกบล็อกไม่ให้เข้าถึงไฟล์ proc ของ xt_qtaguid
โดย 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 และ AOSP หลักของ Android เป็นประจํา ตรวจสอบว่าการติดตั้งใช้งานของคุณผ่านการทดสอบ 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
เนื่องจากรุ่น Android 9 รองรับทั้ง 2 โมดูลการตรวจสอบการเข้าชม จึงไม่มีการทดสอบ CTS เพื่อบังคับให้ติดตั้งใช้งานโมดูลใหม่ในอุปกรณ์ทั้งหมด แต่สำหรับอุปกรณ์ที่มีเคอร์เนลเวอร์ชันสูงกว่า 4.9 ซึ่งเดิมมาพร้อมกับรุ่น Android 9 (เช่น API ระดับแรก >= 28) จะมี CTS Test ใน 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
การทดสอบ 1 หน่วยจะอยู่ที่นี่
- https://android.googlesource.com/platform/system/netd/+/main/libbpf/BpfNetworkStatsTest.cpp
- https://android.googlesource.com/platform/system/netd/+/main/server/TrafficControllerTest.cpp