prevent DscpPolicyTracker from printing big scary exception stack

when the program is missing due to too old kernel.
Program presence is already enforced by CRITICAL annotation and bpfloader.

Test: TreeHugger
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: Ic5f53636c833e65c611a7b8069f28c088c249158
diff --git a/service/src/com/android/server/connectivity/DscpPolicyTracker.java b/service/src/com/android/server/connectivity/DscpPolicyTracker.java
index 15d6adb..9c2b9e8 100644
--- a/service/src/com/android/server/connectivity/DscpPolicyTracker.java
+++ b/service/src/com/android/server/connectivity/DscpPolicyTracker.java
@@ -64,6 +64,8 @@
         return "/sys/fs/bpf/net_shared/map_" + which + "_map";
     }
 
+    private final boolean mHaveProgram = TcUtils.isBpfProgramUsable(PROG_PATH);
+
     private Set<String> mAttachedIfaces;
 
     private final BpfMap<Struct.S32, DscpPolicyValue> mBpfDscpIpv4Policies;
@@ -325,6 +327,7 @@
      * Attach BPF program
      */
     private boolean attachProgram(@NonNull String iface) {
+        if (!mHaveProgram) return false;
         try {
             NetworkInterface netIface = NetworkInterface.getByName(iface);
             TcUtils.tcFilterAddDevBpf(netIface.getIndex(), false, PRIO_DSCP, (short) ETH_P_ALL,
diff --git a/staticlibs/device/com/android/net/module/util/TcUtils.java b/staticlibs/device/com/android/net/module/util/TcUtils.java
index 9d2fb7f..a6b222f 100644
--- a/staticlibs/device/com/android/net/module/util/TcUtils.java
+++ b/staticlibs/device/com/android/net/module/util/TcUtils.java
@@ -101,4 +101,12 @@
      * @throws IOException
      */
     public static native void tcQdiscAddDevClsact(int ifIndex) throws IOException;
+
+    /**
+     * Attempt to fetch a bpf program from a path.
+     * Return true on success, false on non-existence or any other failure.
+     *
+     * @param bpfProgPath
+     */
+    public static native boolean isBpfProgramUsable(String bpfProgPath);
 }
diff --git a/staticlibs/native/bpf_syscall_wrappers/include/BpfSyscallWrappers.h b/staticlibs/native/bpf_syscall_wrappers/include/BpfSyscallWrappers.h
index 9995cb9..cb02de8 100644
--- a/staticlibs/native/bpf_syscall_wrappers/include/BpfSyscallWrappers.h
+++ b/staticlibs/native/bpf_syscall_wrappers/include/BpfSyscallWrappers.h
@@ -148,6 +148,13 @@
     return bpfFdGet(pathname, BPF_F_RDONLY);
 }
 
+inline bool usableProgram(const char* pathname) {
+    int fd = retrieveProgram(pathname);
+    bool ok = (fd >= 0);
+    if (ok) close(fd);
+    return ok;
+}
+
 inline int attachProgram(bpf_attach_type type, const BPF_FD_TYPE prog_fd,
                          const BPF_FD_TYPE cg_fd, uint32_t flags = 0) {
     return bpf(BPF_PROG_ATTACH, {
diff --git a/staticlibs/native/bpfmapjni/com_android_net_module_util_TcUtils.cpp b/staticlibs/native/bpfmapjni/com_android_net_module_util_TcUtils.cpp
index ab83da6..2a587b6 100644
--- a/staticlibs/native/bpfmapjni/com_android_net_module_util_TcUtils.cpp
+++ b/staticlibs/native/bpfmapjni/com_android_net_module_util_TcUtils.cpp
@@ -19,6 +19,9 @@
 #include <nativehelper/scoped_utf_chars.h>
 #include <tcutils/tcutils.h>
 
+#define BPF_FD_JUST_USE_INT
+#include "BpfSyscallWrappers.h"
+
 namespace android {
 
 static void throwIOException(JNIEnv *env, const char *msg, int error) {
@@ -96,6 +99,14 @@
   }
 }
 
+static jboolean com_android_net_module_util_TcUtils_isBpfProgramUsable(JNIEnv *env,
+                                                                       jclass clazz,
+                                                                       jstring bpfProgPath) {
+    ScopedUtfChars pathname(env, bpfProgPath);
+    return bpf::usableProgram(pathname.c_str());
+}
+
+
 /*
  * JNI registration.
  */
@@ -111,6 +122,8 @@
      (void *)com_android_net_module_util_TcUtils_tcFilterDelDev},
     {"tcQdiscAddDevClsact", "(I)V",
      (void *)com_android_net_module_util_TcUtils_tcQdiscAddDevClsact},
+    {"isBpfProgramUsable", "(Ljava/lang/String;)Z",
+     (void *)com_android_net_module_util_TcUtils_isBpfProgramUsable},
 };
 
 int register_com_android_net_module_util_TcUtils(JNIEnv *env,