Merge "Make system/bpf changes trigger connectivity CTS tests in presubmit"
diff --git a/bpfloader/BpfLoader.cpp b/bpfloader/BpfLoader.cpp
index 64e4de3..aab0a62 100644
--- a/bpfloader/BpfLoader.cpp
+++ b/bpfloader/BpfLoader.cpp
@@ -54,6 +54,32 @@
 using android::bpf::domain;
 using std::string;
 
+bool exists(const char* const path) {
+    int v = access(path, F_OK);
+    if (!v) {
+        ALOGI("%s exists.", path);
+        return true;
+    }
+    if (errno == ENOENT) return false;
+    ALOGE("FATAL: access(%s, F_OK) -> %d [%d:%s]", path, v, errno, strerror(errno));
+    abort();  // can only hit this if permissions (likely selinux) are screwed up
+}
+
+bool isInProcessTethering() {
+    bool in = exists("/apex/com.android.tethering/etc/flag/in-process");
+    bool out = exists("/apex/com.android.tethering/etc/flag/out-of-process");
+    if (in && out) abort();  // bad build
+
+    // Handle cases where the module explicitly tells us
+    if (in) return true;
+    if (out) return false;
+
+    // Backup handling for older tethering modules, which don't have a flag,
+    // just assume it's not in process.  We could potentially just abort()
+    // here, but what if there isn't even a tethering module installed?
+    return false;
+}
+
 constexpr unsigned long long kTetheringApexDomainBitmask =
         domainToBitmask(domain::tethering) |
         domainToBitmask(domain::net_private) |
@@ -203,7 +229,7 @@
         errno = 0;
         int ret = mkdir(s.c_str(), S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO);
         if (ret && errno != EEXIST) {
-            ALOGW("Failed to create directory: %s, ret: %s", s.c_str(), std::strerror(errno));
+            ALOGE("Failed to create directory: %s, ret: %s", s.c_str(), std::strerror(errno));
         }
 
         umask(prevUmask);
@@ -214,6 +240,21 @@
     (void)argc;
     android::base::InitLogging(argv, &android::base::KernelLogger);
 
+    // This is ugly... but this allows InProcessTethering which runs as system_server,
+    // instead of as network_stack to access /sys/fs/bpf/tethering, which would otherwise
+    // (due to genfscon rules) have fs_bpf_tethering selinux context, which is restricted
+    // to the network_stack process only (which is where out of process tethering runs)
+    if (isInProcessTethering() && !exists("/sys/fs/bpf/tethering")) {
+        createSysFsBpfSubDir(/* /sys/fs/bpf/ */ "net_shared");
+        createSysFsBpfSubDir(/* /sys/fs/bpf/ */ "net_shared/tethering");
+
+        /* /sys/fs/bpf/tethering -> net_shared/tethering */
+        if (symlink("net_shared/tethering", "/sys/fs/bpf/tethering")) {
+            ALOGE("symlink(net_shared/tethering, /sys/fs/bpf/tethering) -> %s", strerror(errno));
+            return 1;
+        }
+    }
+
     // Create all the pin subdirectories
     // (this must be done first to allow selinux_context and pin_subdir functionality,
     //  which could otherwise fail with ENOENT during object pinning or renaming,
diff --git a/libbpf_android/Android.bp b/libbpf_android/Android.bp
index 1fac19d..620f844 100644
--- a/libbpf_android/Android.bp
+++ b/libbpf_android/Android.bp
@@ -86,8 +86,8 @@
     ],
 
     data: [
-        ":bpf_load_tp_prog.o",
-        ":bpf_load_tp_prog_btf.o",
+        ":bpfLoadTpProg.o",
+        ":bpfLoadTpProgBtf.o",
     ],
     require_root: true,
 }
diff --git a/libbpf_android/BpfLoadTest.cpp b/libbpf_android/BpfLoadTest.cpp
index d5e5814..8e853b9 100644
--- a/libbpf_android/BpfLoadTest.cpp
+++ b/libbpf_android/BpfLoadTest.cpp
@@ -101,7 +101,7 @@
         // Earlier kernels lack BPF_BTF_LOAD support
         if (!isAtLeastKernelVersion(4, 19, 0)) GTEST_SKIP() << "pre-4.19 kernel does not support BTF";
 
-        const bool haveBtf = GetParam().find("btf") != std::string::npos;
+        const bool haveBtf = GetParam().find("Btf") != std::string::npos;
 
         std::string str;
         EXPECT_EQ(android::base::ReadFileToString(mTpMapPath, &str), haveBtf);
@@ -115,8 +115,7 @@
 };
 
 INSTANTIATE_TEST_SUITE_P(BpfLoadTests, BpfLoadTest,
-                         ::testing::Values("bpf_load_tp_prog",
-                                           "bpf_load_tp_prog_btf"));
+                         ::testing::Values("bpfLoadTpProg", "bpfLoadTpProgBtf"));
 
 TEST_P(BpfLoadTest, bpfCheckMap) {
     checkMapNonZero();
diff --git a/libbpf_android/Loader.cpp b/libbpf_android/Loader.cpp
index 859d1c5..ad20176 100644
--- a/libbpf_android/Loader.cpp
+++ b/libbpf_android/Loader.cpp
@@ -30,9 +30,9 @@
 #include <sys/wait.h>
 #include <unistd.h>
 
-// This is BpfLoader v0.25
+// This is BpfLoader v0.27
 #define BPFLOADER_VERSION_MAJOR 0u
-#define BPFLOADER_VERSION_MINOR 25u
+#define BPFLOADER_VERSION_MINOR 27u
 #define BPFLOADER_VERSION ((BPFLOADER_VERSION_MAJOR << 16) | BPFLOADER_VERSION_MINOR)
 
 #include "bpf/BpfUtils.h"
@@ -1078,7 +1078,7 @@
                 for (const auto& line : lines) ALOGW("%s", line.c_str());
                 ALOGW("bpf_prog_load - END log_buf contents.");
 
-                if (cs[i].prog_def->optional) {
+                if (cs[i].prog_def.has_value() && cs[i].prog_def->optional) {
                     ALOGW("failed program is marked optional - continuing...");
                     continue;
                 }