From 155760b57b0872a31109d7af76826b2aa59cd70d Mon Sep 17 00:00:00 2001
From: Junyu Lai <junyulai@google.com>
Date: Thu, 5 Oct 2023 14:51:00 +0800
Subject: [PATCH] Dump bpf program status in dumpsys

Sample output:
Bpf Program Status:
  CGROUP_INET_INGRESS: 21
  CGROUP_INET_EGRESS: 22
  CGROUP_INET_SOCK_CREATE: 28
  CGROUP_INET4_BIND: 30
  CGROUP_INET6_BIND: 31

Test: adb shell dumpsys connectivity
Test: atest FrameworksNetTests:android.net.connectivity.com.android.server.ConnectivityServiceTest#testDumpDoesNotCrash
Test: atest ConnectivityCoverageTests:android.net.connectivity.com.android.server.ConnectivityServiceTest#testDumpDoesNotCrash
Bug: 292156770
Change-Id: I312c90c524af12d093536156d6d5c6febd64305a
---
 .../android/server/ConnectivityService.java   | 37 +++++++++++++++++++
 .../ConnectivityNativeService.java            |  7 +---
 .../com/android/net/module/util/BpfUtils.java | 18 +++++++++
 .../server/ConnectivityServiceTest.java       |  5 +++
 4 files changed, 61 insertions(+), 6 deletions(-)

diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index da7229ce69..86f49d35bb 100755
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -98,6 +98,11 @@ import static android.system.OsConstants.ETH_P_ALL;
 import static android.system.OsConstants.IPPROTO_TCP;
 import static android.system.OsConstants.IPPROTO_UDP;
 
+import static com.android.net.module.util.BpfUtils.BPF_CGROUP_INET4_BIND;
+import static com.android.net.module.util.BpfUtils.BPF_CGROUP_INET6_BIND;
+import static com.android.net.module.util.BpfUtils.BPF_CGROUP_INET_EGRESS;
+import static com.android.net.module.util.BpfUtils.BPF_CGROUP_INET_INGRESS;
+import static com.android.net.module.util.BpfUtils.BPF_CGROUP_INET_SOCK_CREATE;
 import static com.android.net.module.util.NetworkMonitorUtils.isPrivateDnsValidationRequired;
 import static com.android.net.module.util.PermissionUtils.checkAnyPermissionOf;
 import static com.android.net.module.util.PermissionUtils.enforceAnyPermissionOf;
@@ -277,6 +282,7 @@ import com.android.modules.utils.build.SdkLevel;
 import com.android.net.module.util.BaseNetdUnsolicitedEventListener;
 import com.android.net.module.util.BinderUtils;
 import com.android.net.module.util.BitUtils;
+import com.android.net.module.util.BpfUtils;
 import com.android.net.module.util.CollectionUtils;
 import com.android.net.module.util.DeviceConfigUtils;
 import com.android.net.module.util.InterfaceParams;
@@ -1525,6 +1531,14 @@ public class ConnectivityService extends IConnectivityManager.Stub
             }
         }
 
+        /**
+         * Get BPF program Id from CGROUP. See {@link BpfUtils#getProgramId}.
+         */
+        public int getBpfProgramId(final int attachType, @NonNull final String cgroupPath)
+                throws IOException {
+            return BpfUtils.getProgramId(attachType, cgroupPath);
+        }
+
         /**
          * Wraps {@link BroadcastOptionsShimImpl#newInstance(BroadcastOptions)}
          */
@@ -3249,6 +3263,26 @@ public class ConnectivityService extends IConnectivityManager.Stub
         pw.decreaseIndent();
     }
 
+    private void dumpBpfProgramStatus(IndentingPrintWriter pw) {
+        pw.println("Bpf Program Status:");
+        pw.increaseIndent();
+        try {
+            pw.print("CGROUP_INET_INGRESS: ");
+            pw.println(mDeps.getBpfProgramId(BPF_CGROUP_INET_INGRESS, BpfUtils.CGROUP_PATH));
+            pw.print("CGROUP_INET_EGRESS: ");
+            pw.println(mDeps.getBpfProgramId(BPF_CGROUP_INET_EGRESS, BpfUtils.CGROUP_PATH));
+            pw.print("CGROUP_INET_SOCK_CREATE: ");
+            pw.println(mDeps.getBpfProgramId(BPF_CGROUP_INET_SOCK_CREATE, BpfUtils.CGROUP_PATH));
+            pw.print("CGROUP_INET4_BIND: ");
+            pw.println(mDeps.getBpfProgramId(BPF_CGROUP_INET4_BIND, BpfUtils.CGROUP_PATH));
+            pw.print("CGROUP_INET6_BIND: ");
+            pw.println(mDeps.getBpfProgramId(BPF_CGROUP_INET6_BIND, BpfUtils.CGROUP_PATH));
+        } catch (IOException e) {
+            pw.println("  IOException");
+        }
+        pw.decreaseIndent();
+    }
+
     @VisibleForTesting
     static final String KEY_DESTROY_FROZEN_SOCKETS_VERSION = "destroy_frozen_sockets_version";
     @VisibleForTesting
@@ -3862,6 +3896,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
         pw.println();
         dumpCloseFrozenAppSockets(pw);
 
+        pw.println();
+        dumpBpfProgramStatus(pw);
+
         pw.println();
 
         if (!CollectionUtils.contains(args, SHORT_ARG)) {
diff --git a/service/src/com/android/server/connectivity/ConnectivityNativeService.java b/service/src/com/android/server/connectivity/ConnectivityNativeService.java
index e16117be56..cf6127f71a 100644
--- a/service/src/com/android/server/connectivity/ConnectivityNativeService.java
+++ b/service/src/com/android/server/connectivity/ConnectivityNativeService.java
@@ -16,9 +16,6 @@
 
 package com.android.server.connectivity;
 
-import static com.android.net.module.util.BpfUtils.BPF_CGROUP_INET4_BIND;
-import static com.android.net.module.util.BpfUtils.BPF_CGROUP_INET6_BIND;
-
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
@@ -31,11 +28,9 @@ import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.net.module.util.BpfBitmap;
-import com.android.net.module.util.BpfUtils;
 import com.android.net.module.util.CollectionUtils;
 import com.android.net.module.util.PermissionUtils;
 
-import java.io.IOException;
 import java.util.ArrayList;
 
 /**
@@ -45,7 +40,7 @@ public class ConnectivityNativeService extends ConnectivityNative.Stub {
     public static final String SERVICE_NAME = "connectivity_native";
 
     private static final String TAG = ConnectivityNativeService.class.getSimpleName();
-    private static final String CGROUP_PATH = "/sys/fs/cgroup";
+
     private static final String BLOCKED_PORTS_MAP_PATH =
             "/sys/fs/bpf/net_shared/map_block_blocked_ports_map";
 
diff --git a/staticlibs/device/com/android/net/module/util/BpfUtils.java b/staticlibs/device/com/android/net/module/util/BpfUtils.java
index f1546c0924..6116a5fec9 100644
--- a/staticlibs/device/com/android/net/module/util/BpfUtils.java
+++ b/staticlibs/device/com/android/net/module/util/BpfUtils.java
@@ -32,9 +32,13 @@ public class BpfUtils {
     // Defined in include/uapi/linux/bpf.h. Only adding the CGROUPS currently being used for now.
     public static final int BPF_CGROUP_INET_INGRESS = 0;
     public static final int BPF_CGROUP_INET_EGRESS = 1;
+    public static final int BPF_CGROUP_INET_SOCK_CREATE = 2;
     public static final int BPF_CGROUP_INET4_BIND = 8;
     public static final int BPF_CGROUP_INET6_BIND = 9;
 
+    // Note: This is only guaranteed to be accurate on U+ devices. It is likely to be accurate
+    // on T+ devices as well, but this is not guaranteed.
+    public static final String CGROUP_PATH = "/sys/fs/cgroup/";
 
     /**
      * Attach BPF program to CGROUP
@@ -52,6 +56,20 @@ public class BpfUtils {
         native_detachProgramFromCgroup(type, cgroupPath);
     }
 
+    /**
+     * Get BPF program Id from CGROUP.
+     *
+     * Note: This requires a 4.19 kernel which is only guaranteed on V+.
+     *
+     * @param attachType Bpf attach type. See bpf_attach_type in include/uapi/linux/bpf.h.
+     * @param cgroupPath Path of cgroup.
+     * @return Positive integer for a Program Id. 0 if no program is attached.
+     * @throws IOException if failed to open the cgroup directory or query bpf program.
+     */
+    public static int getProgramId(int attachType, @NonNull String cgroupPath) throws IOException {
+        return native_getProgramIdFromCgroup(attachType, cgroupPath);
+    }
+
     /**
      * Detach single BPF program from CGROUP
      */
diff --git a/tests/unit/java/com/android/server/ConnectivityServiceTest.java b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
index ee11f7caee..3c70b112e7 100755
--- a/tests/unit/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
@@ -2267,6 +2267,11 @@ public class ConnectivityServiceTest {
             mActiveRateLimit.put(iface, -1L);
         }
 
+        @Override
+        public int getBpfProgramId(final int attachType, @NonNull final String cgroupPath) {
+            return 0;
+        }
+
         @Override
         public BroadcastOptionsShim makeBroadcastOptionsShim(BroadcastOptions options) {
             reset(mBroadcastOptionsShim);
-- 
GitLab