diff options
| author | 2020-06-17 06:32:35 +0000 | |
|---|---|---|
| committer | 2020-06-17 07:29:10 +0000 | |
| commit | 1f9efaff8d2ce77f7cefce1f56659234ad459a8c (patch) | |
| tree | a2af987343f30050214c04b86a1866292c951076 | |
| parent | 796ee2f306c9ca9933b6ac4f47191e306ecad4b8 (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.java | 73 | ||||
| -rw-r--r-- | packages/Tethering/src/com/android/networkstack/tethering/Tethering.java | 5 |
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); |