[NETD_BPF#8] Move BpfUtils.cpp to BpfUtils.h

Functions in BpfUtils.cpp are trivial, they can be static inlined
in BpfUtils.h.

Bug: 202086915
Test: m; flash; boot; cd system/netd && atest
Test: m gpuservice_unittest libtimeinstate_test bpf_module_test
      CtsAppOpsTestCases libmeminfo_test VtsBootconfigTest
      vts_test_binary_bpf_module
Change-Id: Ie1ece23b6fc9a4db5fc95930209a10da1e528cb5
diff --git a/libbpf_android/include/bpf/BpfUtils.h b/libbpf_android/include/bpf/BpfUtils.h
index f0d73e0..8f1b9a2 100644
--- a/libbpf_android/include/bpf/BpfUtils.h
+++ b/libbpf_android/include/bpf/BpfUtils.h
@@ -17,15 +17,24 @@
 #pragma once
 
 #include <linux/if_ether.h>
+#include <linux/pfkeyv2.h>
 #include <net/if.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/resource.h>
 #include <sys/socket.h>
+#include <sys/utsname.h>
 
 #include <string>
 
+#include <android-base/unique_fd.h>
+#include <log/log.h>
+
 #include "BpfSyscallWrappers.h"
 
+// The buffer size for the buffer that records program loading logs, needs to be large enough for
+// the largest kernel program.
+
 namespace android {
 namespace bpf {
 
@@ -33,13 +42,71 @@
 
 constexpr const uint64_t NONEXISTENT_COOKIE = 0;
 
-uint64_t getSocketCookie(int sockFd);
-int synchronizeKernelRCU();
-int setrlimitForTest();
+static inline uint64_t getSocketCookie(int sockFd) {
+    uint64_t sock_cookie;
+    socklen_t cookie_len = sizeof(sock_cookie);
+    int res = getsockopt(sockFd, SOL_SOCKET, SO_COOKIE, &sock_cookie, &cookie_len);
+    if (res < 0) {
+        res = -errno;
+        ALOGE("Failed to get socket cookie: %s\n", strerror(errno));
+        errno = -res;
+        // 0 is an invalid cookie. See sock_gen_cookie.
+        return NONEXISTENT_COOKIE;
+    }
+    return sock_cookie;
+}
+
+static inline int synchronizeKernelRCU() {
+    // This is a temporary hack for network stats map swap on devices running
+    // 4.9 kernels. The kernel code of socket release on pf_key socket will
+    // explicitly call synchronize_rcu() which is exactly what we need.
+    int pfSocket = socket(AF_KEY, SOCK_RAW | SOCK_CLOEXEC, PF_KEY_V2);
+
+    if (pfSocket < 0) {
+        int ret = -errno;
+        ALOGE("create PF_KEY socket failed: %s", strerror(errno));
+        return ret;
+    }
+
+    // When closing socket, synchronize_rcu() gets called in sock_release().
+    if (close(pfSocket)) {
+        int ret = -errno;
+        ALOGE("failed to close the PF_KEY socket: %s", strerror(errno));
+        return ret;
+    }
+    return 0;
+}
+
+static inline int setrlimitForTest() {
+    // Set the memory rlimit for the test process if the default MEMLOCK rlimit is not enough.
+    struct rlimit limit = {
+            .rlim_cur = 1073741824,  // 1 GiB
+            .rlim_max = 1073741824,  // 1 GiB
+    };
+    int res = setrlimit(RLIMIT_MEMLOCK, &limit);
+    if (res) {
+        ALOGE("Failed to set the default MEMLOCK rlimit: %s", strerror(errno));
+    }
+    return res;
+}
 
 #define KVER(a, b, c) (((a) << 24) + ((b) << 16) + (c))
 
-unsigned kernelVersion();
+static inline unsigned kernelVersion() {
+    struct utsname buf;
+    int ret = uname(&buf);
+    if (ret) return 0;
+
+    unsigned kver_major;
+    unsigned kver_minor;
+    unsigned kver_sub;
+    char unused;
+    ret = sscanf(buf.release, "%u.%u.%u%c", &kver_major, &kver_minor, &kver_sub, &unused);
+    // Check the device kernel version
+    if (ret < 3) return 0;
+
+    return KVER(kver_major, kver_minor, kver_sub);
+}
 
 static inline bool isAtLeastKernelVersion(unsigned major, unsigned minor, unsigned sub) {
     return kernelVersion() >= KVER(major, minor, sub);