diff --git a/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java b/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java index 40956f7876..6550de2ea7 100644 --- a/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java +++ b/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java @@ -52,6 +52,7 @@ import android.system.ErrnoException; import android.system.OsConstants; import android.text.TextUtils; import android.util.ArraySet; +import android.util.Base64; import android.util.Log; import android.util.SparseArray; @@ -118,6 +119,9 @@ public class BpfCoordinator { private static final String TETHER_ERROR_MAP_PATH = makeMapPath("error"); private static final String TETHER_DEV_MAP_PATH = makeMapPath("dev"); + // Using "," as a separator is safe because base64 characters are [0-9a-zA-Z/=+]. + private static final String DUMP_BASE64_DELIMITER = ","; + /** The names of all the BPF counters defined in bpf_tethering.h. */ public static final String[] sBpfCounterNames = getBpfCounterNames(); @@ -1068,6 +1072,42 @@ public class BpfCoordinator { } } + private String ipv4RuleToBase64String(Tether4Key key, Tether4Value value) { + final byte[] keyBytes = key.writeToBytes(); + final String keyBase64Str = Base64.encodeToString(keyBytes, Base64.DEFAULT) + .replace("\n", ""); + final byte[] valueBytes = value.writeToBytes(); + final String valueBase64Str = Base64.encodeToString(valueBytes, Base64.DEFAULT) + .replace("\n", ""); + + return keyBase64Str + DUMP_BASE64_DELIMITER + valueBase64Str; + } + + private void dumpRawIpv4ForwardingRuleMap( + BpfMap map, IndentingPrintWriter pw) throws ErrnoException { + if (map == null) { + pw.println("No IPv4 support"); + return; + } + if (map.isEmpty()) { + pw.println("No rules"); + return; + } + map.forEach((k, v) -> pw.println(ipv4RuleToBase64String(k, v))); + } + + /** + * Dump raw BPF map in base64 encoded strings. For test only. + */ + public void dumpRawMap(@NonNull IndentingPrintWriter pw) { + try (BpfMap upstreamMap = mDeps.getBpfUpstream4Map()) { + // TODO: dump downstream map. + dumpRawIpv4ForwardingRuleMap(upstreamMap, pw); + } catch (ErrnoException e) { + pw.println("Error dumping IPv4 map: " + e); + } + } + private String l4protoToString(int proto) { if (proto == OsConstants.IPPROTO_TCP) { return "tcp"; diff --git a/Tethering/src/com/android/networkstack/tethering/Tethering.java b/Tethering/src/com/android/networkstack/tethering/Tethering.java index db9a64f8ed..301a6824d4 100644 --- a/Tethering/src/com/android/networkstack/tethering/Tethering.java +++ b/Tethering/src/com/android/networkstack/tethering/Tethering.java @@ -2479,6 +2479,13 @@ public class Tethering { @SuppressWarnings("resource") final IndentingPrintWriter pw = new IndentingPrintWriter( writer, " "); + // Used for testing instead of human debug. + // TODO: add options to choose which map to dump. + if (argsContain(args, "bpfRawMap")) { + mBpfCoordinator.dumpRawMap(pw); + return; + } + if (argsContain(args, "bpf")) { dumpBpf(pw); return;