Add method for reading stats by iface index
This change adds the nativeGetIfIndexStat JNI method, which can be used to read the traffic stats associated with a specific iface index. Test: Included unit test. Bug: 241098920 Change-Id: I7a4adcb9610562ff01fe5cd1234d6dfc57f9408d
This commit is contained in:
parent
b2455c626e
commit
07923dec2d
5 changed files with 49 additions and 0 deletions
|
|
@ -34,6 +34,7 @@
|
|||
|
||||
using android::bpf::bpfGetUidStats;
|
||||
using android::bpf::bpfGetIfaceStats;
|
||||
using android::bpf::bpfGetIfIndexStats;
|
||||
using android::bpf::NetworkTraceHandler;
|
||||
|
||||
namespace android {
|
||||
|
|
@ -94,6 +95,15 @@ static jlong nativeGetIfaceStat(JNIEnv* env, jclass clazz, jstring iface, jint t
|
|||
}
|
||||
}
|
||||
|
||||
static jlong nativeGetIfIndexStat(JNIEnv* env, jclass clazz, jint ifindex, jint type) {
|
||||
Stats stats = {};
|
||||
if (bpfGetIfIndexStats(ifindex, &stats) == 0) {
|
||||
return getStatsType(&stats, (StatsType) type);
|
||||
} else {
|
||||
return UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
static jlong nativeGetUidStat(JNIEnv* env, jclass clazz, jint uid, jint type) {
|
||||
Stats stats = {};
|
||||
|
||||
|
|
@ -111,6 +121,7 @@ static void nativeInitNetworkTracing(JNIEnv* env, jclass clazz) {
|
|||
static const JNINativeMethod gMethods[] = {
|
||||
{"nativeGetTotalStat", "(I)J", (void*)nativeGetTotalStat},
|
||||
{"nativeGetIfaceStat", "(Ljava/lang/String;I)J", (void*)nativeGetIfaceStat},
|
||||
{"nativeGetIfIndexStat", "(II)J", (void*)nativeGetIfIndexStat},
|
||||
{"nativeGetUidStat", "(II)J", (void*)nativeGetUidStat},
|
||||
{"nativeInitNetworkTracing", "()V", (void*)nativeInitNetworkTracing},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -105,6 +105,25 @@ int bpfGetIfaceStats(const char* iface, Stats* stats) {
|
|||
return bpfGetIfaceStatsInternal(iface, stats, ifaceStatsMap, ifaceIndexNameMap);
|
||||
}
|
||||
|
||||
int bpfGetIfIndexStatsInternal(uint32_t ifindex, Stats* stats,
|
||||
const BpfMap<uint32_t, StatsValue>& ifaceStatsMap) {
|
||||
InitStats(stats);
|
||||
auto statsEntry = ifaceStatsMap.readValue(ifindex);
|
||||
if (statsEntry.ok()) {
|
||||
stats->rxPackets = statsEntry.value().rxPackets;
|
||||
stats->txPackets = statsEntry.value().txPackets;
|
||||
stats->rxBytes = statsEntry.value().rxBytes;
|
||||
stats->txBytes = statsEntry.value().txBytes;
|
||||
return 0;
|
||||
}
|
||||
return (statsEntry.error().code() == ENOENT) ? 0 : -statsEntry.error().code();
|
||||
}
|
||||
|
||||
int bpfGetIfIndexStats(int ifindex, Stats* stats) {
|
||||
static BpfMapRO<uint32_t, StatsValue> ifaceStatsMap(IFACE_STATS_MAP_PATH);
|
||||
return bpfGetIfIndexStatsInternal(ifindex, stats, ifaceStatsMap);
|
||||
}
|
||||
|
||||
stats_line populateStatsEntry(const StatsKey& statsKey, const StatsValue& statsEntry,
|
||||
const char* ifname) {
|
||||
stats_line newLine;
|
||||
|
|
|
|||
|
|
@ -275,6 +275,20 @@ TEST_F(BpfNetworkStatsHelperTest, TestGetIfaceStatsInternal) {
|
|||
expectStatsEqual(totalValue, totalResult);
|
||||
}
|
||||
|
||||
TEST_F(BpfNetworkStatsHelperTest, TestGetIfIndexStatsInternal) {
|
||||
StatsValue value = {
|
||||
.rxPackets = TEST_PACKET0,
|
||||
.rxBytes = TEST_BYTES0,
|
||||
.txPackets = TEST_PACKET1,
|
||||
.txBytes = TEST_BYTES1,
|
||||
};
|
||||
EXPECT_RESULT_OK(mFakeIfaceStatsMap.writeValue(IFACE_INDEX1, value, BPF_ANY));
|
||||
|
||||
Stats result = {};
|
||||
ASSERT_EQ(0, bpfGetIfIndexStatsInternal(IFACE_INDEX1, &result, mFakeIfaceStatsMap));
|
||||
expectStatsEqual(value, result);
|
||||
}
|
||||
|
||||
TEST_F(BpfNetworkStatsHelperTest, TestGetStatsDetail) {
|
||||
updateIfaceMap(IFACE_NAME1, IFACE_INDEX1);
|
||||
updateIfaceMap(IFACE_NAME2, IFACE_INDEX2);
|
||||
|
|
|
|||
|
|
@ -63,6 +63,9 @@ int bpfGetIfaceStatsInternal(const char* iface, Stats* stats,
|
|||
const BpfMap<uint32_t, StatsValue>& ifaceStatsMap,
|
||||
const BpfMap<uint32_t, IfaceValue>& ifaceNameMap);
|
||||
// For test only
|
||||
int bpfGetIfIndexStatsInternal(uint32_t ifindex, Stats* stats,
|
||||
const BpfMap<uint32_t, StatsValue>& ifaceStatsMap);
|
||||
// For test only
|
||||
int parseBpfNetworkStatsDetailInternal(std::vector<stats_line>& lines,
|
||||
const BpfMap<StatsKey, StatsValue>& statsMap,
|
||||
const BpfMap<uint32_t, IfaceValue>& ifaceMap);
|
||||
|
|
@ -112,6 +115,7 @@ int parseBpfNetworkStatsDevInternal(std::vector<stats_line>& lines,
|
|||
|
||||
int bpfGetUidStats(uid_t uid, Stats* stats);
|
||||
int bpfGetIfaceStats(const char* iface, Stats* stats);
|
||||
int bpfGetIfIndexStats(int ifindex, Stats* stats);
|
||||
int parseBpfNetworkStatsDetail(std::vector<stats_line>* lines);
|
||||
|
||||
int parseBpfNetworkStatsDev(std::vector<stats_line>* lines);
|
||||
|
|
|
|||
|
|
@ -3303,6 +3303,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||
|
||||
private static native long nativeGetTotalStat(int type);
|
||||
private static native long nativeGetIfaceStat(String iface, int type);
|
||||
private static native long nativeGetIfIndexStat(int ifindex, int type);
|
||||
private static native long nativeGetUidStat(int uid, int type);
|
||||
|
||||
/** Initializes and registers the Perfetto Network Trace data source */
|
||||
|
|
|
|||
Loading…
Reference in a new issue