From 02c2536103ce0ac59d3794951f670d70f7becedf Mon Sep 17 00:00:00 2001 From: Ken Chen Date: Mon, 25 Oct 2021 17:14:26 +0800 Subject: [PATCH] [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 --- libbpf_android/Android.bp | 1 - libbpf_android/BpfUtils.cpp | 113 -------------------------- libbpf_android/include/bpf/BpfUtils.h | 75 ++++++++++++++++- 3 files changed, 71 insertions(+), 118 deletions(-) delete mode 100644 libbpf_android/BpfUtils.cpp diff --git a/libbpf_android/Android.bp b/libbpf_android/Android.bp index e305cc9..cf4a4fc 100644 --- a/libbpf_android/Android.bp +++ b/libbpf_android/Android.bp @@ -46,7 +46,6 @@ cc_library { target: { android: { srcs: [ - "BpfUtils.cpp", "Loader.cpp", ], sanitize: { diff --git a/libbpf_android/BpfUtils.cpp b/libbpf_android/BpfUtils.cpp deleted file mode 100644 index 414b7b2..0000000 --- a/libbpf_android/BpfUtils.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "BpfUtils" - -#include "bpf/BpfUtils.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -using android::base::unique_fd; - -// 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 { - -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; -} - -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; -} - -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; -} - -unsigned kernelVersion() { - struct utsname buf; - int ret = uname(&buf); - if (ret) return 0; - - unsigned kver_major; - unsigned kver_minor; - unsigned kver_sub; - char dummy; - ret = sscanf(buf.release, "%u.%u.%u%c", &kver_major, &kver_minor, &kver_sub, &dummy); - // Check the device kernel version - if (ret < 3) return 0; - - return KVER(kver_major, kver_minor, kver_sub); -} - -} // namespace bpf -} // namespace android 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 +#include #include #include #include +#include #include +#include #include +#include +#include + #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 int OVERFLOW_COUNTERSET = 2; 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);