Công cụ lưu lượng truy cập mạng eBPF sử dụng kết hợp việc triển khai không gian nhân và không gian người dùng để theo dõi mức sử dụng mạng trên thiết bị kể từ lần khởi động thiết bị gần đây nhất. Công cụ này cung cấp thêm chức năng như gắn thẻ ổ cắm, tách lưu lượng truy cập ở nền trước/nền sau và tường lửa theo UID để chặn ứng dụng truy cập vào mạng tuỳ thuộc vào trạng thái của điện thoại. Số liệu thống kê thu thập được từ công cụ này được lưu trữ trong một cấu trúc dữ liệu nhân có tên là eBPF maps và kết quả này được các dịch vụ như NetworkStatsService sử dụng để cung cấp số liệu thống kê lưu lượng truy cập liên tục kể từ lần khởi động gần đây nhất.
Ví dụ và nguồn
Các thay đổi về không gian người dùng chủ yếu nằm trong các dự án system/netd và framework/base. Quá trình phát triển đang được thực hiện trong AOSP, vì vậy, mã AOSP sẽ luôn được cập nhật. Nguồn này chủ yếu nằm ở
system/netd/server/TrafficController*,
system/netd/bpfloader,
và
system/netd/libbpf/.
Một số thay đổi cần thiết về khung cũng nằm trong framework/base/ và system/core.
Triển khai
Kể từ Android 9, các thiết bị Android chạy trên nhân 4.9 trở lên và ban đầu được phát hành bằng bản phát hành P PHẢI sử dụng kế toán giám sát lưu lượng truy cập mạng dựa trên eBPF thay vì xt_qtaguid. Cơ sở hạ tầng mới linh hoạt và dễ bảo trì hơn, đồng thời không yêu cầu bất kỳ mã nhân nào ngoài cây.
Hình 1 minh hoạ những điểm khác biệt chính về thiết kế giữa tính năng giám sát lưu lượng truy cập cũ và eBPF.
Hình 1. Những điểm khác biệt về thiết kế giữa tính năng giám sát lưu lượng truy cập cũ (bên trái) và eBPF (bên phải)
Thiết kế trafficController mới dựa trên bộ lọc eBPF theo cgroup cũng như mô-đun netfilter xt_bpf bên trong nhân. Các bộ lọc eBPF này được áp dụng trên gói tx/rx khi chúng đi qua bộ lọc. Bộ lọc eBPF cgroup nằm ở lớp truyền tải và chịu trách nhiệm đếm lưu lượng truy cập theo đúng UID tuỳ thuộc vào UID ổ cắm cũng như chế độ cài đặt không gian người dùng.
Netfilter xt_bpf được kết nối tại chuỗi bw_raw_PREROUTING và bw_mangle_POSTROUTING và chịu trách nhiệm đếm lưu lượng truy cập theo đúng giao diện.
Vào thời điểm khởi động, quy trình không gian người dùng trafficController sẽ tạo các bản đồ eBPF dùng để thu thập dữ liệu và ghim tất cả các bản đồ dưới dạng tệp ảo tại sys/fs/bpf.
Sau đó, quy trình đặc quyền bpfloader sẽ tải chương trình eBPF được biên dịch sẵn vào nhân và đính kèm chương trình đó vào cgroup chính xác. Có một cgroup gốc duy nhất cho tất cả lưu lượng truy cập, vì vậy, theo mặc định, tất cả quy trình sẽ được đưa vào cgroup đó.
Trong thời gian chạy, trafficController có thể gắn thẻ/gỡ thẻ một ổ cắm bằng cách ghi vào traffic_cookie_tag_map và traffic_uid_counterSet_map. NetworkStatsService có thể đọc dữ liệu thống kê lưu lượng truy cập từ traffic_tag_stats_map, traffic_uid_stats_map và traffic_iface_stats_map.
Ngoài chức năng thu thập số liệu thống kê lưu lượng truy cập, bộ lọc eBPF trafficController và cgroup cũng chịu trách nhiệm chặn lưu lượng truy cập từ một số UID nhất định tuỳ thuộc vào chế độ cài đặt của điện thoại. Tính năng chặn lưu lượng truy cập mạng dựa trên UID là tính năng thay thế cho mô-đun xt_owner bên trong nhân và bạn có thể định cấu hình chế độ chi tiết bằng cách ghi vào traffic_powersave_uid_map, traffic_standby_uid_map và traffic_dozable_uid_map.
Cách triển khai mới tuân theo cách triển khai mô-đun xt_qtaguid cũ, vì vậy, TrafficController và NetworkStatsService sẽ chạy với cách triển khai cũ hoặc mới. Nếu ứng dụng sử dụng các API công khai, thì ứng dụng đó sẽ không gặp phải bất kỳ sự khác biệt nào cho dù các công cụ xt_qtaguid hay eBPF được sử dụng ở chế độ nền.
Nếu nhân thiết bị dựa trên nhân chung Android 4.9 (SHA 39c856663dcc81739e52b02b77d6af259eb838f6 trở lên), thì bạn không cần sửa đổi HAL, trình điều khiển hoặc mã nhân để triển khai công cụ eBPF mới.
Yêu cầu
Cấu hình nhân PHẢI bật các cấu hình sau:
CONFIG_CGROUP_BPF=yCONFIG_BPF=yCONFIG_BPF_SYSCALL=yCONFIG_NETFILTER_XT_MATCH_BPF=yCONFIG_INET_UDP_DIAG=y
Bài kiểm thử cấu hình nhân VTS rất hữu ích khi xác minh rằng cấu hình chính xác đã được bật.
Quy trình ngừng sử dụng xt_qtaguid cũ
Công cụ eBPF mới đang thay thế mô-đun xt_qtaguid và mô-đun xt_owner mà công cụ này dựa trên. Chúng tôi sẽ bắt đầu xoá mô-đun xt_qtaguid khỏi nhân Android và tắt các cấu hình không cần thiết của mô-đun này.
Trong bản phát hành Android 9, mô-đun xt_qtaguid được bật trên tất cả các thiết bị, nhưng tất cả các API công khai trực tiếp đọc tệp proc mô-đun xt_qtaguid đều được chuyển vào Dịch vụ NetworkManagement.
Tuỳ thuộc vào phiên bản kernel thiết bị và cấp độ API đầu tiên, Dịch vụ NetworkManagement sẽ biết liệu các công cụ eBPF có được bật hay không và chọn mô-đun phù hợp để nhận số liệu thống kê về mức sử dụng mạng của từng ứng dụng. Các ứng dụng có cấp độ SDK từ 28 trở lên bị sepolicy chặn truy cập vào các tệp proc xt_qtaguid.
Trong bản phát hành Android tiếp theo sau bản phát hành 9, quyền truy cập của ứng dụng vào các tệp proc xt_qtaguid đó sẽ bị chặn hoàn toàn. Chúng tôi sẽ bắt đầu xoá mô-đun xt_qtaguid khỏi các nhân chung Android mới. Sau khi xoá, chúng tôi sẽ cập nhật cấu hình cơ sở của Android cho phiên bản nhân đó để tắt mô-đun xt_qtaguid một cách rõ ràng. Mô-đun xt_qtaguid sẽ hoàn toàn không được dùng nữa khi yêu cầu phiên bản nhân tối thiểu cho bản phát hành Android là 4.9 trở lên.
Trong bản phát hành Android 9, chỉ những thiết bị khởi chạy bằng bản phát hành Android 9 mới bắt buộc phải có tính năng eBPF mới. Đối với các thiết bị được phát hành bằng nhân có thể hỗ trợ các công cụ eBPF, bạn nên cập nhật nhân đó lên tính năng eBPF mới khi nâng cấp lên bản phát hành Android 9. Không có bài kiểm thử CTS nào để bắt buộc cập nhật.
Xác nhận kết quả
Bạn nên thường xuyên lấy các bản vá từ nhân chung Android và Android AOSP chính. Đảm bảo quá trình triển khai của bạn vượt qua các bài kiểm thử VTS và CTS áp dụng, netd_unit_test và libbpf_test.
Thử nghiệm
Có các
net_tests nhân
để đảm bảo bạn đã bật các tính năng bắt buộc và các bản vá nhân bắt buộc
được chuyển ngược. Các bài kiểm thử được tích hợp như một phần của các bài kiểm thử VTS trong bản phát hành Android 9. Có một số bài kiểm thử đơn vị trong system/netd/
(netd_unit_test
và
libbpf_test).
Có một số bài kiểm thử trong netd_integration_test để xác thực hành vi tổng thể
của công cụ mới.
CTS và trình xác minh CTS
Vì cả hai mô-đun giám sát lưu lượng truy cập đều được hỗ trợ trong bản phát hành Android 9, nên không có bài kiểm thử CTS nào để buộc triển khai mô-đun mới trên tất cả các thiết bị. Tuy nhiên, đối với các thiết bị có phiên bản kernel cao hơn 4.9 và ban đầu được phát hành bằng bản phát hành Android 9 (tức là cấp độ API đầu tiên >= 28), có các bài kiểm thử CTS trên GSI để xác thực rằng mô-đun mới được định cấu hình chính xác. Bạn có thể sử dụng các bài kiểm thử CTS cũ như TrafficStatsTest, NetworkUsageStatsTest và CtsNativeNetTestCases để xác minh hành vi nhất quán với mô-đun UID cũ.
Kiểm thử theo cách thủ công
Có một số bài kiểm thử đơn vị trong system/netd/
(netd_unit_test,
netd_integration_test
và
libbpf_test).
Có hỗ trợ dumpsys để kiểm tra trạng thái theo cách thủ công. Lệnh dumpsys netd cho biết trạng thái cơ bản của mô-đun trafficController và liệu eBPF có được bật chính xác hay không. Nếu eBPF được bật, lệnh dumpsys netd trafficcontroller sẽ cho biết nội dung chi tiết của từng bản đồ eBPF, bao gồm thông tin ổ cắm được gắn thẻ, số liệu thống kê theo thẻ, UID và iface, cũng như kết quả so khớp UID của chủ sở hữu.
Vị trí kiểm thử
Các bài kiểm thử CTS nằm ở:
- 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
Các bài kiểm thử VTS nằm ở https://android.googlesource.com/kernel/tests/+/android17-release/net/test/bpf_test.py.
Các bài kiểm thử đơn vị nằm ở: