From 855712aa556ee5f78575a2bed407a8e0afcc8ee6 Mon Sep 17 00:00:00 2001 From: KH Shi Date: Wed, 21 Jun 2023 17:15:35 +0800 Subject: [PATCH] Clatd: add dump raw BPF map support Add dump raw BPF map command to connectivity service. The result will be encoded as base64 strings. This is a preparation for Clatd's tests. Usage: dumpsys connectivity {clatEgress4RawBpfMap|clatIngress6RawBpfMap} Bug: 285124667 Test: test with MtsEthernetTetheringTest#testTetherClatBpfOffloadUdp which will be uploaded in a separated CL Change-Id: I02c8efadb1c4b861d9bf6168667816b13412dc75 --- .../tethering/BpfCoordinator.java | 4 ++-- .../android/server/ConnectivityService.java | 17 +++++++++++++ .../server/connectivity/ClatCoordinator.java | 24 +++++++++++++++++++ .../server/connectivity/Nat464Xlat.java | 12 ++++++++++ .../com/android/net/module/util/BpfDump.java | 22 ++++++++++------- 5 files changed, 68 insertions(+), 11 deletions(-) diff --git a/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java b/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java index 155333aa63..00d915230f 100644 --- a/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java +++ b/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java @@ -1362,7 +1362,7 @@ public class BpfCoordinator { if (CollectionUtils.contains(args, DUMPSYS_RAWMAP_ARG_STATS)) { try (IBpfMap statsMap = mDeps.getBpfStatsMap()) { BpfDump.dumpRawMap(statsMap, pw); - } catch (ErrnoException | IOException e) { + } catch (IOException e) { pw.println("Error dumping stats map: " + e); } return; @@ -1370,7 +1370,7 @@ public class BpfCoordinator { if (CollectionUtils.contains(args, DUMPSYS_RAWMAP_ARG_UPSTREAM4)) { try (IBpfMap upstreamMap = mDeps.getBpfUpstream4Map()) { BpfDump.dumpRawMap(upstreamMap, pw); - } catch (ErrnoException | IOException e) { + } catch (IOException e) { pw.println("Error dumping IPv4 map: " + e); } return; diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java index b99d0dea32..997672b5f6 100755 --- a/service/src/com/android/server/ConnectivityService.java +++ b/service/src/com/android/server/ConnectivityService.java @@ -398,6 +398,8 @@ public class ConnectivityService extends IConnectivityManager.Stub private static final String NETWORK_ARG = "networks"; private static final String REQUEST_ARG = "requests"; private static final String TRAFFICCONTROLLER_ARG = "trafficcontroller"; + public static final String CLATEGRESS4RAWBPFMAP_ARG = "clatEgress4RawBpfMap"; + public static final String CLATINGRESS6RAWBPFMAP_ARG = "clatIngress6RawBpfMap"; private static final boolean DBG = true; private static final boolean DDBG = Log.isLoggable(TAG, Log.DEBUG); @@ -4006,6 +4008,12 @@ public class ConnectivityService extends IConnectivityManager.Stub boolean verbose = !CollectionUtils.contains(args, SHORT_ARG); dumpTrafficController(pw, fd, verbose); return; + } else if (CollectionUtils.contains(args, CLATEGRESS4RAWBPFMAP_ARG)) { + dumpClatBpfRawMap(pw, true /* isEgress4Map */); + return; + } else if (CollectionUtils.contains(args, CLATINGRESS6RAWBPFMAP_ARG)) { + dumpClatBpfRawMap(pw, false /* isEgress4Map */); + return; } pw.println("NetworkProviders for:"); @@ -4265,6 +4273,15 @@ public class ConnectivityService extends IConnectivityManager.Stub } } + private void dumpClatBpfRawMap(IndentingPrintWriter pw, boolean isEgress4Map) { + for (NetworkAgentInfo nai : networksSortedById()) { + if (nai.clatd != null) { + nai.clatd.dumpRawBpfMap(pw, isEgress4Map); + break; + } + } + } + private void dumpAllRequestInfoLogsToLogcat() { try (PrintWriter logPw = new PrintWriter(new Writer() { @Override diff --git a/service/src/com/android/server/connectivity/ClatCoordinator.java b/service/src/com/android/server/connectivity/ClatCoordinator.java index aec4f243da..34cd1e111b 100644 --- a/service/src/com/android/server/connectivity/ClatCoordinator.java +++ b/service/src/com/android/server/connectivity/ClatCoordinator.java @@ -41,6 +41,7 @@ import androidx.annotation.RequiresApi; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.IndentingPrintWriter; +import com.android.net.module.util.BpfDump; import com.android.net.module.util.BpfMap; import com.android.net.module.util.IBpfMap; import com.android.net.module.util.InterfaceParams; @@ -888,6 +889,29 @@ public class ClatCoordinator { } } + /** + * Dump raw BPF map into base64 encoded strings {@literal ","}. + * Allow to dump only one map in each call. For test only. + * + * @param pw print writer. + * @param isEgress4Map whether to dump the egress4 map (true) or the ingress6 map (false). + * + * Usage: + * $ dumpsys connectivity {clatEgress4RawBpfMap|clatIngress6RawBpfMap} + * + * Output: + * {@literal ,} + * {@literal ,} + * .. + */ + public void dumpRawMap(@NonNull IndentingPrintWriter pw, boolean isEgress4Map) { + if (isEgress4Map) { + BpfDump.dumpRawMap(mEgressMap, pw); + } else { + BpfDump.dumpRawMap(mIngressMap, pw); + } + } + /** * Dump the coordinator information. * diff --git a/service/src/com/android/server/connectivity/Nat464Xlat.java b/service/src/com/android/server/connectivity/Nat464Xlat.java index 065922dcd8..adddb39c3b 100644 --- a/service/src/com/android/server/connectivity/Nat464Xlat.java +++ b/service/src/com/android/server/connectivity/Nat464Xlat.java @@ -622,6 +622,18 @@ public class Nat464Xlat { } } + /** + * Dump the raw BPF maps in 464XLAT + * + * @param pw print writer. + * @param isEgress4Map whether to dump the egress4 map (true) or the ingress6 map (false). + */ + public void dumpRawBpfMap(IndentingPrintWriter pw, boolean isEgress4Map) { + if (SdkLevel.isAtLeastT()) { + mClatCoordinator.dumpRawMap(pw, isEgress4Map); + } + } + @Override public String toString() { return "mBaseIface: " + mBaseIface + ", mIface: " + mIface + ", mState: " + mState; diff --git a/staticlibs/device/com/android/net/module/util/BpfDump.java b/staticlibs/device/com/android/net/module/util/BpfDump.java index 914c4ee160..422719477f 100644 --- a/staticlibs/device/com/android/net/module/util/BpfDump.java +++ b/staticlibs/device/com/android/net/module/util/BpfDump.java @@ -84,16 +84,20 @@ public class BpfDump { * Dump the BpfMap entries with base64 format encoding. */ public static void dumpRawMap(IBpfMap map, - PrintWriter pw) throws ErrnoException { - if (map == null) { - pw.println("BPF map is null"); - return; + PrintWriter pw) { + try { + if (map == null) { + pw.println("BPF map is null"); + return; + } + if (map.isEmpty()) { + pw.println("No entries"); + return; + } + map.forEach((k, v) -> pw.println(toBase64EncodedString(k, v))); + } catch (ErrnoException e) { + pw.println("Map dump end with error: " + Os.strerror(e.errno)); } - if (map.isEmpty()) { - pw.println("No entries"); - return; - } - map.forEach((k, v) -> pw.println(toBase64EncodedString(k, v))); } /**