blob: 8689192fad11a7cd91c226707317830df063556a [file] [log] [blame]
Chenbo Feng75b410b2018-10-10 15:01:19 -07001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "BpfUtils"
18
Bernie Innocenti26ffded2018-10-19 15:41:53 +090019#include "bpf/BpfUtils.h"
20
Chenbo Feng75b410b2018-10-10 15:01:19 -070021#include <elf.h>
22#include <inttypes.h>
23#include <linux/bpf.h>
24#include <linux/if_ether.h>
25#include <linux/in.h>
Chenbo Feng9cd8f142018-12-04 16:54:56 -080026#include <linux/pfkeyv2.h>
Chenbo Feng75b410b2018-10-10 15:01:19 -070027#include <stdlib.h>
28#include <string.h>
29#include <sys/mman.h>
Chenbo Feng0a1a9a12019-04-09 12:05:04 -070030#include <sys/resource.h>
Chenbo Feng75b410b2018-10-10 15:01:19 -070031#include <sys/socket.h>
32#include <sys/stat.h>
33#include <sys/utsname.h>
34#include <sstream>
35#include <string>
36
Chenbo Feng75b410b2018-10-10 15:01:19 -070037#include <android-base/unique_fd.h>
Bernie Innocenti26ffded2018-10-19 15:41:53 +090038#include <log/log.h>
Suren Baghdasaryan9217ccb2018-12-19 17:29:13 -080039#include <processgroup/processgroup.h>
Chenbo Feng75b410b2018-10-10 15:01:19 -070040
Chenbo Feng75b410b2018-10-10 15:01:19 -070041using android::base::unique_fd;
Chenbo Feng75b410b2018-10-10 15:01:19 -070042
Chenbo Feng9cd8f142018-12-04 16:54:56 -080043// The buffer size for the buffer that records program loading logs, needs to be large enough for
44// the largest kernel program.
Chenbo Feng75b410b2018-10-10 15:01:19 -070045
46namespace android {
47namespace bpf {
48
Chenbo Feng75b410b2018-10-10 15:01:19 -070049uint64_t getSocketCookie(int sockFd) {
50 uint64_t sock_cookie;
51 socklen_t cookie_len = sizeof(sock_cookie);
52 int res = getsockopt(sockFd, SOL_SOCKET, SO_COOKIE, &sock_cookie, &cookie_len);
53 if (res < 0) {
54 res = -errno;
55 ALOGE("Failed to get socket cookie: %s\n", strerror(errno));
56 errno = -res;
57 // 0 is an invalid cookie. See sock_gen_cookie.
58 return NONEXISTENT_COOKIE;
59 }
60 return sock_cookie;
61}
62
Chenbo Feng9cd8f142018-12-04 16:54:56 -080063int synchronizeKernelRCU() {
64 // This is a temporary hack for network stats map swap on devices running
65 // 4.9 kernels. The kernel code of socket release on pf_key socket will
66 // explicitly call synchronize_rcu() which is exactly what we need.
67 int pfSocket = socket(AF_KEY, SOCK_RAW | SOCK_CLOEXEC, PF_KEY_V2);
68
69 if (pfSocket < 0) {
70 int ret = -errno;
71 ALOGE("create PF_KEY socket failed: %s", strerror(errno));
72 return ret;
73 }
74
75 // When closing socket, synchronize_rcu() gets called in sock_release().
76 if (close(pfSocket)) {
77 int ret = -errno;
78 ALOGE("failed to close the PF_KEY socket: %s", strerror(errno));
79 return ret;
80 }
81 return 0;
82}
83
Chenbo Feng0a1a9a12019-04-09 12:05:04 -070084int setrlimitForTest() {
85 // Set the memory rlimit for the test process if the default MEMLOCK rlimit is not enough.
86 struct rlimit limit = {
Maciej Żenczykowskibd98c022020-03-31 03:03:53 -070087 .rlim_cur = 1073741824, // 1 GiB
88 .rlim_max = 1073741824, // 1 GiB
Chenbo Feng0a1a9a12019-04-09 12:05:04 -070089 };
90 int res = setrlimit(RLIMIT_MEMLOCK, &limit);
91 if (res) {
92 ALOGE("Failed to set the default MEMLOCK rlimit: %s", strerror(errno));
93 }
94 return res;
95}
96
Maciej Żenczykowski07375e22020-02-19 14:23:59 -080097unsigned kernelVersion() {
98 struct utsname buf;
99 int ret = uname(&buf);
100 if (ret) return 0;
101
102 unsigned kver_major;
103 unsigned kver_minor;
104 unsigned kver_sub;
105 char dummy;
106 ret = sscanf(buf.release, "%u.%u.%u%c", &kver_major, &kver_minor, &kver_sub, &dummy);
107 // Check the device kernel version
108 if (ret < 3) return 0;
109
110 return KVER(kver_major, kver_minor, kver_sub);
111}
112
Chenbo Feng75b410b2018-10-10 15:01:19 -0700113} // namespace bpf
114} // namespace android