Fix negative uid stats caused by 464xlat adjust when eBPF is on.

When using xt_qtaguid to count per uid stats,
NetworkStatsService needs to adjust the 464xlat traffic since
iptables module would double count for ipv4 and ipv6 packet.
But for eBPF, the per uid stats is collected in a different
hook, so the adjustment on root uid would only be needed in tx
direction.

Bug: 112226716
Test: 1. Make ipv4 traffic in ipv6-only network and check data
         usage.
      2. Make ipv4 traffic in a client which connect to
         ipv6-only hotspot.
      3. runtest frameworks-net
      4. cts-tradefed run cts -m CtsNetTestCases -t \
                 android.net.cts.TrafficStatsTest
      5. cts-tradefed run cts -m CtsUsageStatsTestCases

Change-Id: Ic9a84f5446eddc943c255d5f3b89dad171f53cac
This commit is contained in:
junyulai
2018-10-19 21:14:30 +08:00
parent 1742c23b88
commit 1d103a9809

View File

@@ -39,6 +39,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import android.net.NetworkStats.Entry;
import android.os.Process; import android.os.Process;
import android.support.test.runner.AndroidJUnit4; import android.support.test.runner.AndroidJUnit4;
import android.support.test.filters.SmallTest; import android.support.test.filters.SmallTest;
@@ -785,7 +786,38 @@ public class NetworkStatsTest {
ArrayMap<String, String> stackedIface = new ArrayMap<>(); ArrayMap<String, String> stackedIface = new ArrayMap<>();
stackedIface.put(v4Iface, baseIface); stackedIface.put(v4Iface, baseIface);
NetworkStats.Entry otherEntry = new NetworkStats.Entry( // Ipv4 traffic sent/received by an app on stacked interface.
final NetworkStats.Entry appEntry = new NetworkStats.Entry(
v4Iface, appUid, SET_DEFAULT, TAG_NONE,
30501490 /* rxBytes */,
22401 /* rxPackets */,
876235 /* txBytes */,
13805 /* txPackets */,
0 /* operations */);
// Traffic measured for the root uid on the base interface if eBPF is in use.
// Incorrectly includes appEntry's bytes and packets, plus IPv4-IPv6 translation
// overhead (20 bytes per packet), only for TX traffic.
final NetworkStats.Entry ebpfRootUidEntry = new NetworkStats.Entry(
baseIface, rootUid, SET_DEFAULT, TAG_NONE,
163577 /* rxBytes */,
187 /* rxPackets */,
1169942 /* txBytes */,
13902 /* txPackets */,
0 /* operations */);
// Traffic measured for the root uid on the base interface if xt_qtaguid is in use.
// Incorrectly includes appEntry's bytes and packets, plus IPv4-IPv6 translation
// overhead (20 bytes per packet), in both directions.
final NetworkStats.Entry xtRootUidEntry = new NetworkStats.Entry(
baseIface, rootUid, SET_DEFAULT, TAG_NONE,
31113087 /* rxBytes */,
22588 /* rxPackets */,
1169942 /* txBytes */,
13902 /* txPackets */,
0 /* operations */);
final NetworkStats.Entry otherEntry = new NetworkStats.Entry(
otherIface, appUid, SET_DEFAULT, TAG_NONE, otherIface, appUid, SET_DEFAULT, TAG_NONE,
2600 /* rxBytes */, 2600 /* rxBytes */,
2 /* rxPackets */, 2 /* rxPackets */,
@@ -793,39 +825,41 @@ public class NetworkStatsTest {
3 /* txPackets */, 3 /* txPackets */,
0 /* operations */); 0 /* operations */);
NetworkStats stats = new NetworkStats(TEST_START, 3) final NetworkStats statsXt = new NetworkStats(TEST_START, 3)
.addValues(v4Iface, appUid, SET_DEFAULT, TAG_NONE, .addValues(appEntry)
30501490 /* rxBytes */, .addValues(xtRootUidEntry)
22401 /* rxPackets */,
876235 /* txBytes */,
13805 /* txPackets */,
0 /* operations */)
.addValues(baseIface, rootUid, SET_DEFAULT, TAG_NONE,
31113087,
22588,
1169942,
13902,
0)
.addValues(otherEntry); .addValues(otherEntry);
stats.apply464xlatAdjustments(stackedIface); final NetworkStats statsEbpf = new NetworkStats(TEST_START, 3)
.addValues(appEntry)
.addValues(ebpfRootUidEntry)
.addValues(otherEntry);
assertEquals(3, stats.size()); statsXt.apply464xlatAdjustments(stackedIface, false);
assertValues(stats, 0, v4Iface, appUid, SET_DEFAULT, TAG_NONE, statsEbpf.apply464xlatAdjustments(stackedIface, true);
METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO,
assertEquals(3, statsXt.size());
assertEquals(3, statsEbpf.size());
final NetworkStats.Entry expectedAppUid = new NetworkStats.Entry(
v4Iface, appUid, SET_DEFAULT, TAG_NONE,
30949510, 30949510,
22401, 22401,
1152335, 1152335,
13805, 13805,
0); 0);
assertValues(stats, 1, baseIface, 0, SET_DEFAULT, TAG_NONE, final NetworkStats.Entry expectedRootUid = new NetworkStats.Entry(
METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, baseIface, 0, SET_DEFAULT, TAG_NONE,
163577, 163577,
187, 187,
17607, 17607,
97, 97,
0); 0);
assertEquals(otherEntry, stats.getValues(2, null)); assertEquals(expectedAppUid, statsXt.getValues(0, null));
assertEquals(expectedRootUid, statsXt.getValues(1, null));
assertEquals(otherEntry, statsXt.getValues(2, null));
assertEquals(expectedAppUid, statsEbpf.getValues(0, null));
assertEquals(expectedRootUid, statsEbpf.getValues(1, null));
assertEquals(otherEntry, statsEbpf.getValues(2, null));
} }
@Test @Test
@@ -850,7 +884,7 @@ public class NetworkStatsTest {
.addValues(secondEntry); .addValues(secondEntry);
// Empty map: no adjustment // Empty map: no adjustment
stats.apply464xlatAdjustments(new ArrayMap<>()); stats.apply464xlatAdjustments(new ArrayMap<>(), false);
assertEquals(2, stats.size()); assertEquals(2, stats.size());
assertEquals(firstEntry, stats.getValues(0, null)); assertEquals(firstEntry, stats.getValues(0, null));