diff --git a/staticlibs/device/com/android/net/module/util/BpfUtils.java b/staticlibs/device/com/android/net/module/util/BpfUtils.java
index 94af11b34723748f794efefe13ac2d80412e17e3..f1546c09249a341f9bdca12c22bf4c059e905d08 100644
--- a/staticlibs/device/com/android/net/module/util/BpfUtils.java
+++ b/staticlibs/device/com/android/net/module/util/BpfUtils.java
@@ -66,4 +66,6 @@ public class BpfUtils {
             throws IOException;
     private static native boolean native_detachSingleProgramFromCgroup(int type,
             String programPath, String cgroupPath) throws IOException;
+    private static native int native_getProgramIdFromCgroup(int type, String cgroupPath)
+            throws IOException;
 }
diff --git a/staticlibs/native/bpfutiljni/com_android_net_module_util_BpfUtils.cpp b/staticlibs/native/bpfutiljni/com_android_net_module_util_BpfUtils.cpp
index 0f2ebbd49a546675ec99951351a2dc1099b10450..df9e586245dd8ddfb86a1a9d1b489522c4cad3b9 100644
--- a/staticlibs/native/bpfutiljni/com_android_net_module_util_BpfUtils.cpp
+++ b/staticlibs/native/bpfutiljni/com_android_net_module_util_BpfUtils.cpp
@@ -110,6 +110,29 @@ static jboolean com_android_net_module_util_BpfUtil_detachSingleProgramFromCgrou
     return true;
 }
 
+static jint com_android_net_module_util_BpfUtil_getProgramIdFromCgroup(JNIEnv *env,
+        jclass clazz, jint type, jstring cgroupPath) {
+
+    ScopedUtfChars dirPath(env, cgroupPath);
+    unique_fd cg_fd(open(dirPath.c_str(), O_DIRECTORY | O_RDONLY | O_CLOEXEC));
+    if (cg_fd == -1) {
+        jniThrowExceptionFmt(env, "java/io/IOException",
+                             "Failed to open the cgroup directory %s: %s",
+                             dirPath.c_str(), strerror(errno));
+        return -1;
+    }
+
+    int id = bpf::queryProgram(cg_fd, (bpf_attach_type) type);
+    if (id < 0) {
+        jniThrowExceptionFmt(env, "java/io/IOException",
+                             "Failed to query bpf program %d at %s: %s",
+                             type, dirPath.c_str(), strerror(errno));
+        return -1;
+    }
+    return id;  // may return 0 meaning none
+}
+
+
 /*
  * JNI registration.
  */
@@ -121,6 +144,8 @@ static const JNINativeMethod gMethods[] = {
         (void*) com_android_net_module_util_BpfUtil_detachProgramFromCgroup },
     { "native_detachSingleProgramFromCgroup", "(ILjava/lang/String;Ljava/lang/String;)Z",
         (void*) com_android_net_module_util_BpfUtil_detachSingleProgramFromCgroup },
+    { "native_getProgramIdFromCgroup", "(ILjava/lang/String;)I",
+        (void*) com_android_net_module_util_BpfUtil_getProgramIdFromCgroup },
 };
 
 int register_com_android_net_module_util_BpfUtils(JNIEnv* env, char const* class_name) {