Support read iface stats detail
The networkStatsFactory need to parse the detail traffic stats of each
interface instead of the total number. This change added a helper
function to return a vector of stats_line contain stats for each iface.
Bug: 72111305
Test: ./libbpf_test
Change-Id: I9a9cda7ab90cf533c2f2cc81b37b4d520d442ce2
diff --git a/libbpf/BpfNetworkStats.cpp b/libbpf/BpfNetworkStats.cpp
index bc9a932..acde1e6 100644
--- a/libbpf/BpfNetworkStats.cpp
+++ b/libbpf/BpfNetworkStats.cpp
@@ -123,9 +123,9 @@
const char* ifname) {
stats_line newLine;
strlcpy(newLine.iface, ifname, sizeof(newLine.iface));
- newLine.uid = statsKey.uid;
- newLine.set = statsKey.counterSet;
- newLine.tag = statsKey.tag;
+ newLine.uid = (int32_t)statsKey.uid;
+ newLine.set = (int32_t)statsKey.counterSet;
+ newLine.tag = (int32_t)statsKey.tag;
newLine.rxPackets = statsEntry.rxPackets;
newLine.txPackets = statsEntry.txPackets;
newLine.rxBytes = statsEntry.rxBytes;
@@ -240,6 +240,47 @@
return ret;
}
+int parseBpfNetworkStatsDevInternal(std::vector<stats_line>* lines,
+ const base::unique_fd& statsMapFd,
+ const base::unique_fd& ifaceMapFd) {
+ int64_t unknownIfaceBytesTotal = 0;
+ uint32_t nonExistentKey = NONEXISTENT_IFACE_STATS_KEY;
+ struct StatsValue dummyValue;
+ auto processDetailIfaceStats = [lines, &unknownIfaceBytesTotal, &ifaceMapFd](
+ void* key, void* value, const base::unique_fd& statsMapFd) {
+ uint32_t ifIndex = *(uint32_t*)key;
+ char ifname[IFNAMSIZ];
+ if (getIfaceNameFromMap(ifaceMapFd, statsMapFd, ifIndex, ifname, &ifIndex,
+ &unknownIfaceBytesTotal)) {
+ return BPF_CONTINUE;
+ }
+ StatsValue* statsEntry = (StatsValue*)value;
+ StatsKey fakeKey = {
+ .uid = (uint32_t)UID_ALL, .counterSet = (uint32_t)SET_ALL, .tag = (uint32_t)TAG_NONE};
+ lines->push_back(populateStatsEntry(fakeKey, *statsEntry, ifname));
+ return BPF_CONTINUE;
+ };
+ return bpfIterateMapWithValue(nonExistentKey, dummyValue, statsMapFd, processDetailIfaceStats);
+}
+
+int parseBpfNetworkStatsDev(std::vector<stats_line>* lines) {
+ int ret = 0;
+ base::unique_fd ifaceIndexNameMap(bpf::mapRetrieve(IFACE_INDEX_NAME_MAP_PATH, BPF_OPEN_FLAGS));
+ if (ifaceIndexNameMap < 0) {
+ ret = -errno;
+ ALOGE("get ifaceIndexName map fd failed: %s", strerror(errno));
+ return ret;
+ }
+
+ base::unique_fd ifaceStatsMap(bpf::mapRetrieve(IFACE_STATS_MAP_PATH, BPF_OPEN_FLAGS));
+ if (ifaceStatsMap < 0) {
+ ret = -errno;
+ ALOGE("get ifaceStats map fd failed: %s", strerror(errno));
+ return ret;
+ }
+ return parseBpfNetworkStatsDevInternal(lines, ifaceStatsMap, ifaceIndexNameMap);
+}
+
uint64_t combineUidTag(const uid_t uid, const uint32_t tag) {
return (uint64_t)uid << 32 | tag;
}