diff --git a/Tethering/apishim/31/com/android/networkstack/tethering/apishim/api31/BpfCoordinatorShimImpl.java b/Tethering/apishim/31/com/android/networkstack/tethering/apishim/api31/BpfCoordinatorShimImpl.java index 2bdddc11b3..4dc1c51f68 100644 --- a/Tethering/apishim/31/com/android/networkstack/tethering/apishim/api31/BpfCoordinatorShimImpl.java +++ b/Tethering/apishim/31/com/android/networkstack/tethering/apishim/api31/BpfCoordinatorShimImpl.java @@ -324,20 +324,20 @@ public class BpfCoordinatorShimImpl return true; } + private String mapStatus(BpfMap m, String name) { + return name + "{" + (m != null ? "OK" : "ERROR") + "}"; + } + @Override public String toString() { - return "mBpfDownstream4Map{" - + (mBpfDownstream4Map != null ? "initialized" : "not initialized") + "}, " - + "mBpfUpstream4Map{" - + (mBpfUpstream4Map != null ? "initialized" : "not initialized") + "}, " - + "mBpfUpstream6Map{" - + (mBpfUpstream6Map != null ? "initialized" : "not initialized") + "}, " - + "mBpfDownstream6Map{" - + (mBpfDownstream6Map != null ? "initialized" : "not initialized") + "}, " - + "mBpfStatsMap{" - + (mBpfStatsMap != null ? "initialized" : "not initialized") + "}, " - + "mBpfLimitMap{" - + (mBpfLimitMap != null ? "initialized" : "not initialized") + "} "; + return String.join(", ", new String[] { + mapStatus(mBpfDownstream6Map, "mBpfDownstream6Map"), + mapStatus(mBpfUpstream6Map, "mBpfUpstream6Map"), + mapStatus(mBpfDownstream4Map, "mBpfDownstream4Map"), + mapStatus(mBpfUpstream4Map, "mBpfUpstream4Map"), + mapStatus(mBpfStatsMap, "mBpfStatsMap"), + mapStatus(mBpfLimitMap, "mBpfLimitMap") + }); } /** diff --git a/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java b/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java index 35de4003ea..b17bfcf8af 100644 --- a/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java +++ b/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java @@ -64,6 +64,7 @@ import com.android.networkstack.tethering.apishim.common.BpfCoordinatorShim; import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; +import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -677,6 +678,12 @@ public class BpfCoordinator { } } + + // TODO: make mInterfaceNames accessible to the shim and move this code to there. + private String getIfName(long ifindex) { + return mInterfaceNames.get((int) ifindex, Long.toString(ifindex)); + } + /** * Dump information. * Block the function until all the data are dumped on the handler thread or timed-out. The @@ -705,11 +712,9 @@ public class BpfCoordinator { pw.println("Forwarding rules:"); pw.increaseIndent(); - if (mIpv6ForwardingRules.size() == 0) { - pw.println(""); - } else { - dumpIpv6ForwardingRules(pw); - } + dumpIpv6UpstreamRules(pw); + dumpIpv6ForwardingRules(pw); + dumpIpv4ForwardingRules(pw); pw.decreaseIndent(); dumpDone.open(); @@ -729,6 +734,11 @@ public class BpfCoordinator { } private void dumpIpv6ForwardingRules(@NonNull IndentingPrintWriter pw) { + if (mIpv6ForwardingRules.size() == 0) { + pw.println("No IPv6 rules"); + return; + } + for (Map.Entry> entry : mIpv6ForwardingRules.entrySet()) { IpServer ipServer = entry.getKey(); @@ -749,6 +759,63 @@ public class BpfCoordinator { } } + private String ipv6UpstreamRuletoString(TetherUpstream6Key key, Tether6Value value) { + return String.format("%d(%s) -> %d(%s) %04x %s %s", + key.iif, getIfName(key.iif), value.oif, getIfName(value.oif), + value.ethProto, value.ethSrcMac, value.ethDstMac); + } + + private void dumpIpv6UpstreamRules(IndentingPrintWriter pw) { + final BpfMap ipv6UpstreamMap = mDeps.getBpfUpstream6Map(); + if (ipv6UpstreamMap == null) { + pw.println("No IPv6 upstream"); + return; + } + try { + if (ipv6UpstreamMap.isEmpty()) { + pw.println("No IPv6 upstream rules"); + return; + } + ipv6UpstreamMap.forEach((k, v) -> pw.println(ipv6UpstreamRuletoString(k, v))); + } catch (ErrnoException e) { + pw.println("Error dumping IPv4 map: " + e); + } + } + + private String ipv4RuleToString(Tether4Key key, Tether4Value value) { + final String private4, public4, dst4; + try { + private4 = InetAddress.getByAddress(key.src4).getHostAddress(); + dst4 = InetAddress.getByAddress(key.dst4).getHostAddress(); + public4 = InetAddress.getByAddress(value.src46).getHostAddress(); + } catch (UnknownHostException impossible) { + throw new AssertionError("4-byte array not valid IPv4 address!"); + } + return String.format("%d(%s) %d(%s) %s:%d -> %s:%d -> %s:%d", + key.iif, getIfName(key.iif), value.oif, getIfName(value.oif), + private4, key.srcPort, public4, value.srcPort, dst4, key.dstPort); + } + + private void dumpIpv4ForwardingRules(IndentingPrintWriter pw) { + final BpfMap ipv4UpstreamMap = mDeps.getBpfUpstream4Map(); + if (ipv4UpstreamMap == null) { + pw.println("No IPv4 support"); + return; + } + try { + if (ipv4UpstreamMap.isEmpty()) { + pw.println("No IPv4 rules"); + return; + } + pw.println("[IPv4]: iif(iface) oif(iface) src nat dst"); + pw.increaseIndent(); + ipv4UpstreamMap.forEach((k, v) -> pw.println(ipv4RuleToString(k, v))); + } catch (ErrnoException e) { + pw.println("Error dumping IPv4 map: " + e); + } + pw.decreaseIndent(); + } + /** IPv6 forwarding rule class. */ public static class Ipv6ForwardingRule { public final int upstreamIfindex; diff --git a/Tethering/src/com/android/networkstack/tethering/Tethering.java b/Tethering/src/com/android/networkstack/tethering/Tethering.java index 2354c2d2ed..385c691025 100644 --- a/Tethering/src/com/android/networkstack/tethering/Tethering.java +++ b/Tethering/src/com/android/networkstack/tethering/Tethering.java @@ -2225,6 +2225,13 @@ public class Tethering { && !isProvisioningNeededButUnavailable(); } + private void dumpBpf(IndentingPrintWriter pw) { + pw.println("BPF offload:"); + pw.increaseIndent(); + mBpfCoordinator.dump(pw); + pw.decreaseIndent(); + } + void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter writer, @Nullable String[] args) { // Binder.java closes the resource for us. @SuppressWarnings("resource") @@ -2235,6 +2242,11 @@ public class Tethering { return; } + if (argsContain(args, "bpf")) { + dumpBpf(pw); + return; + } + pw.println("Tethering:"); pw.increaseIndent(); @@ -2286,10 +2298,7 @@ public class Tethering { mOffloadController.dump(pw); pw.decreaseIndent(); - pw.println("BPF offload:"); - pw.increaseIndent(); - mBpfCoordinator.dump(pw); - pw.decreaseIndent(); + dumpBpf(pw); pw.println("Private address coordinator:"); pw.increaseIndent();