summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Nucca Chen <nuccachen@google.com> 2020-06-17 06:32:35 +0000
committer Nucca Chen <nuccachen@google.com> 2020-06-17 07:29:10 +0000
commit1f9efaff8d2ce77f7cefce1f56659234ad459a8c (patch)
treea2af987343f30050214c04b86a1866292c951076
parent796ee2f306c9ca9933b6ac4f47191e306ecad4b8 (diff)
[BOT.8] Dump BPF offload information in dumpsys
$ adb shell dumpsys tethering BPF offload: Polling started Stats provider registered Upstream quota: {rmnet_data2=9223372036854775807} Forwarding stats: 12(rmnet_data2) - ForwardedStats(rxb: 1065, rxp: 5, txb: 0, txp: 0) Forwarding rules: [wlan1]: iif(iface) oif(iface) v6addr srcmac dstmac 12(rmnet_data2) 31(wlan1) /2401:e180:8831:77ae:a900:a03b:41fb.. Bug: 150736748 Test: Enable tethering on mobile data and check dumpsys tethering Original-Change: https://android-review.googlesource.com/1302438 Merged-In: I95ea3050d92f3ba8136a63cd399d3450d183c8dc Change-Id: I95ea3050d92f3ba8136a63cd399d3450d183c8dc
-rw-r--r--packages/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java73
-rw-r--r--packages/Tethering/src/com/android/networkstack/tethering/Tethering.java5
2 files changed, 78 insertions, 0 deletions
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java b/packages/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
index fc27b6add052..4315485f060a 100644
--- a/packages/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
+++ b/packages/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
@@ -36,6 +36,7 @@ import android.net.ip.IpServer;
import android.net.netstats.provider.NetworkStatsProvider;
import android.net.util.SharedLog;
import android.net.util.TetheringUtils.ForwardedStats;
+import android.os.ConditionVariable;
import android.os.Handler;
import android.os.RemoteException;
import android.os.ServiceSpecificException;
@@ -47,11 +48,13 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.IndentingPrintWriter;
import java.net.Inet6Address;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
+import java.util.Map;
import java.util.Objects;
/**
@@ -65,6 +68,7 @@ import java.util.Objects;
*/
public class BpfCoordinator {
private static final String TAG = BpfCoordinator.class.getSimpleName();
+ private static final int DUMP_TIMEOUT_MS = 10_000;
@VisibleForTesting
static final int DEFAULT_PERFORM_POLL_INTERVAL_MS = 5000; // TODO: Make it customizable.
@@ -344,6 +348,75 @@ public class BpfCoordinator {
}
}
+ /**
+ * Dump information.
+ * Block the function until all the data are dumped on the handler thread or timed-out. The
+ * reason is that dumpsys invokes this function on the thread of caller and the data may only
+ * be allowed to be accessed on the handler thread.
+ */
+ public void dump(@NonNull IndentingPrintWriter pw) {
+ final ConditionVariable dumpDone = new ConditionVariable();
+ mHandler.post(() -> {
+ pw.println("Polling " + (mPollingStarted ? "started" : "not started"));
+ pw.println("Stats provider " + (mStatsProvider != null
+ ? "registered" : "not registered"));
+ pw.println("Upstream quota: " + mInterfaceQuotas.toString());
+
+ pw.println("Forwarding stats:");
+ pw.increaseIndent();
+ if (mStats.size() == 0) {
+ pw.println("<empty>");
+ } else {
+ dumpStats(pw);
+ }
+ pw.decreaseIndent();
+
+ pw.println("Forwarding rules:");
+ pw.increaseIndent();
+ if (mIpv6ForwardingRules.size() == 0) {
+ pw.println("<empty>");
+ } else {
+ dumpIpv6ForwardingRules(pw);
+ }
+ pw.decreaseIndent();
+
+ dumpDone.open();
+ });
+ if (!dumpDone.block(DUMP_TIMEOUT_MS)) {
+ pw.println("... dump timed-out after " + DUMP_TIMEOUT_MS + "ms");
+ }
+ }
+
+ private void dumpStats(@NonNull IndentingPrintWriter pw) {
+ for (int i = 0; i < mStats.size(); i++) {
+ final int upstreamIfindex = mStats.keyAt(i);
+ final ForwardedStats stats = mStats.get(upstreamIfindex);
+ pw.println(String.format("%d(%s) - %s", upstreamIfindex, mInterfaceNames.get(
+ upstreamIfindex), stats.toString()));
+ }
+ }
+
+ private void dumpIpv6ForwardingRules(@NonNull IndentingPrintWriter pw) {
+ for (Map.Entry<IpServer, LinkedHashMap<Inet6Address, Ipv6ForwardingRule>> entry :
+ mIpv6ForwardingRules.entrySet()) {
+ IpServer ipServer = entry.getKey();
+ // The rule downstream interface index is paired with the interface name from
+ // IpServer#interfaceName. See #startIPv6, #updateIpv6ForwardingRules in IpServer.
+ final String downstreamIface = ipServer.interfaceName();
+ pw.println("[" + downstreamIface + "]: iif(iface) oif(iface) v6addr srcmac dstmac");
+
+ pw.increaseIndent();
+ LinkedHashMap<Inet6Address, Ipv6ForwardingRule> rules = entry.getValue();
+ for (Ipv6ForwardingRule rule : rules.values()) {
+ final int upstreamIfindex = rule.upstreamIfindex;
+ pw.println(String.format("%d(%s) %d(%s) %s %s %s", upstreamIfindex,
+ mInterfaceNames.get(upstreamIfindex), rule.downstreamIfindex,
+ downstreamIface, rule.address, rule.srcMac, rule.dstMac));
+ }
+ pw.decreaseIndent();
+ }
+ }
+
/** IPv6 forwarding rule class. */
public static class Ipv6ForwardingRule {
public final int upstreamIfindex;
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java b/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java
index 2f01186b117d..3184b1ffedff 100644
--- a/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java
+++ b/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java
@@ -2236,6 +2236,11 @@ public class Tethering {
mOffloadController.dump(pw);
pw.decreaseIndent();
+ pw.println("BPF offload:");
+ pw.increaseIndent();
+ mBpfCoordinator.dump(pw);
+ pw.decreaseIndent();
+
pw.println("Private address coordinator:");
pw.increaseIndent();
mPrivateAddressCoordinator.dump(pw);