Dump BPF map in base64 encoded strings for testing
Test: atest EthernetTetheringTest
Change-Id: I3ae863cbb8ed0af1ffc78c6dda21b9e3c0ac74c9
diff --git a/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java b/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
index 40956f7..6550de2 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.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 @@
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 @@
}
}
+ 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<Tether4Key, Tether4Value> 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<Tether4Key, Tether4Value> 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 db9a64f..301a682 100644
--- a/Tethering/src/com/android/networkstack/tethering/Tethering.java
+++ b/Tethering/src/com/android/networkstack/tethering/Tethering.java
@@ -2479,6 +2479,13 @@
@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;