blob: 8f1b9a28aca8234b6c34712523db3760cc7c3c17 [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
Maciej Żenczykowski23c436f2021-01-21 14:24:15 -080017#pragma once
Chenbo Feng75b410b2018-10-10 15:01:19 -070018
Chenbo Feng75b410b2018-10-10 15:01:19 -070019#include <linux/if_ether.h>
Ken Chen02c25362021-10-25 17:14:26 +080020#include <linux/pfkeyv2.h>
Chenbo Feng75b410b2018-10-10 15:01:19 -070021#include <net/if.h>
22#include <stdlib.h>
23#include <string.h>
Ken Chen02c25362021-10-25 17:14:26 +080024#include <sys/resource.h>
Chenbo Feng75b410b2018-10-10 15:01:19 -070025#include <sys/socket.h>
Ken Chen02c25362021-10-25 17:14:26 +080026#include <sys/utsname.h>
Chenbo Feng75b410b2018-10-10 15:01:19 -070027
Steven Morelande7cd2a72020-01-10 17:49:35 -080028#include <string>
29
Ken Chen02c25362021-10-25 17:14:26 +080030#include <android-base/unique_fd.h>
31#include <log/log.h>
32
Hungming Chena46f2172021-01-13 13:56:38 +080033#include "BpfSyscallWrappers.h"
Chenbo Feng0a1a9a12019-04-09 12:05:04 -070034
Ken Chen02c25362021-10-25 17:14:26 +080035// The buffer size for the buffer that records program loading logs, needs to be large enough for
36// the largest kernel program.
37
Chenbo Feng75b410b2018-10-10 15:01:19 -070038namespace android {
39namespace bpf {
40
Chenbo Feng75b410b2018-10-10 15:01:19 -070041constexpr const int OVERFLOW_COUNTERSET = 2;
42
43constexpr const uint64_t NONEXISTENT_COOKIE = 0;
44
Ken Chen02c25362021-10-25 17:14:26 +080045static inline uint64_t getSocketCookie(int sockFd) {
46 uint64_t sock_cookie;
47 socklen_t cookie_len = sizeof(sock_cookie);
48 int res = getsockopt(sockFd, SOL_SOCKET, SO_COOKIE, &sock_cookie, &cookie_len);
49 if (res < 0) {
50 res = -errno;
51 ALOGE("Failed to get socket cookie: %s\n", strerror(errno));
52 errno = -res;
53 // 0 is an invalid cookie. See sock_gen_cookie.
54 return NONEXISTENT_COOKIE;
55 }
56 return sock_cookie;
57}
58
59static inline int synchronizeKernelRCU() {
60 // This is a temporary hack for network stats map swap on devices running
61 // 4.9 kernels. The kernel code of socket release on pf_key socket will
62 // explicitly call synchronize_rcu() which is exactly what we need.
63 int pfSocket = socket(AF_KEY, SOCK_RAW | SOCK_CLOEXEC, PF_KEY_V2);
64
65 if (pfSocket < 0) {
66 int ret = -errno;
67 ALOGE("create PF_KEY socket failed: %s", strerror(errno));
68 return ret;
69 }
70
71 // When closing socket, synchronize_rcu() gets called in sock_release().
72 if (close(pfSocket)) {
73 int ret = -errno;
74 ALOGE("failed to close the PF_KEY socket: %s", strerror(errno));
75 return ret;
76 }
77 return 0;
78}
79
80static inline int setrlimitForTest() {
81 // Set the memory rlimit for the test process if the default MEMLOCK rlimit is not enough.
82 struct rlimit limit = {
83 .rlim_cur = 1073741824, // 1 GiB
84 .rlim_max = 1073741824, // 1 GiB
85 };
86 int res = setrlimit(RLIMIT_MEMLOCK, &limit);
87 if (res) {
88 ALOGE("Failed to set the default MEMLOCK rlimit: %s", strerror(errno));
89 }
90 return res;
91}
Maciej Żenczykowskidcb52282021-01-17 03:36:34 -080092
Maciej Żenczykowski30af4b52021-02-11 15:58:12 -080093#define KVER(a, b, c) (((a) << 24) + ((b) << 16) + (c))
Maciej Żenczykowskidcb52282021-01-17 03:36:34 -080094
Ken Chen02c25362021-10-25 17:14:26 +080095static inline unsigned kernelVersion() {
96 struct utsname buf;
97 int ret = uname(&buf);
98 if (ret) return 0;
99
100 unsigned kver_major;
101 unsigned kver_minor;
102 unsigned kver_sub;
103 char unused;
104 ret = sscanf(buf.release, "%u.%u.%u%c", &kver_major, &kver_minor, &kver_sub, &unused);
105 // Check the device kernel version
106 if (ret < 3) return 0;
107
108 return KVER(kver_major, kver_minor, kver_sub);
109}
Maciej Żenczykowskidcb52282021-01-17 03:36:34 -0800110
111static inline bool isAtLeastKernelVersion(unsigned major, unsigned minor, unsigned sub) {
112 return kernelVersion() >= KVER(major, minor, sub);
113}
Maciej Żenczykowskic3a640d2020-02-11 15:01:21 -0800114
Maciej Żenczykowski54605272021-09-17 15:27:42 -0700115#define SKIP_IF_BPF_SUPPORTED \
116 do { \
117 if (android::bpf::isAtLeastKernelVersion(4, 9, 0)) \
118 GTEST_SKIP() << "Skip: bpf is supported."; \
Maciej Żenczykowski67fa2072021-03-11 19:50:48 -0800119 } while (0)
120
Maciej Żenczykowski54605272021-09-17 15:27:42 -0700121#define SKIP_IF_BPF_NOT_SUPPORTED \
122 do { \
123 if (!android::bpf::isAtLeastKernelVersion(4, 9, 0)) \
124 GTEST_SKIP() << "Skip: bpf is not supported."; \
Maciej Żenczykowski67fa2072021-03-11 19:50:48 -0800125 } while (0)
126
Maciej Żenczykowski54605272021-09-17 15:27:42 -0700127#define SKIP_IF_EXTENDED_BPF_NOT_SUPPORTED \
128 do { \
129 if (!android::bpf::isAtLeastKernelVersion(4, 14, 0)) \
130 GTEST_SKIP() << "Skip: extended bpf feature not supported."; \
Maciej Żenczykowski672b0e72020-02-12 04:15:20 -0800131 } while (0)
132
Maciej Żenczykowski54605272021-09-17 15:27:42 -0700133#define SKIP_IF_XDP_NOT_SUPPORTED \
134 do { \
135 if (!android::bpf::isAtLeastKernelVersion(5, 9, 0)) \
136 GTEST_SKIP() << "Skip: xdp not supported."; \
Maciej Żenczykowskia36bed32021-01-20 15:23:40 -0800137 } while (0)
138
Chenbo Feng75b410b2018-10-10 15:01:19 -0700139} // namespace bpf
140} // namespace android