1*8542734aSAndroid Build Coastguard Worker /*
2*8542734aSAndroid Build Coastguard Worker * Copyright (C) 2022 The Android Open Source Project
3*8542734aSAndroid Build Coastguard Worker *
4*8542734aSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*8542734aSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*8542734aSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*8542734aSAndroid Build Coastguard Worker *
8*8542734aSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*8542734aSAndroid Build Coastguard Worker *
10*8542734aSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*8542734aSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*8542734aSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*8542734aSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*8542734aSAndroid Build Coastguard Worker * limitations under the License.
15*8542734aSAndroid Build Coastguard Worker *
16*8542734aSAndroid Build Coastguard Worker */
17*8542734aSAndroid Build Coastguard Worker
18*8542734aSAndroid Build Coastguard Worker #include <unistd.h>
19*8542734aSAndroid Build Coastguard Worker
20*8542734aSAndroid Build Coastguard Worker #include <gtest/gtest.h>
21*8542734aSAndroid Build Coastguard Worker #include <vintf/VintfObject.h>
22*8542734aSAndroid Build Coastguard Worker
23*8542734aSAndroid Build Coastguard Worker #include <fstream>
24*8542734aSAndroid Build Coastguard Worker #include <string>
25*8542734aSAndroid Build Coastguard Worker
26*8542734aSAndroid Build Coastguard Worker #include "bpf/KernelUtils.h"
27*8542734aSAndroid Build Coastguard Worker
28*8542734aSAndroid Build Coastguard Worker namespace android {
29*8542734aSAndroid Build Coastguard Worker namespace net {
30*8542734aSAndroid Build Coastguard Worker
31*8542734aSAndroid Build Coastguard Worker namespace {
32*8542734aSAndroid Build Coastguard Worker
33*8542734aSAndroid Build Coastguard Worker using ::android::vintf::RuntimeInfo;
34*8542734aSAndroid Build Coastguard Worker using ::android::vintf::VintfObject;
35*8542734aSAndroid Build Coastguard Worker
36*8542734aSAndroid Build Coastguard Worker class KernelConfigVerifier final {
37*8542734aSAndroid Build Coastguard Worker public:
KernelConfigVerifier()38*8542734aSAndroid Build Coastguard Worker KernelConfigVerifier() : mRuntimeInfo(VintfObject::GetRuntimeInfo()) {}
39*8542734aSAndroid Build Coastguard Worker
hasOption(const std::string & option) const40*8542734aSAndroid Build Coastguard Worker bool hasOption(const std::string& option) const {
41*8542734aSAndroid Build Coastguard Worker const auto& configMap = mRuntimeInfo->kernelConfigs();
42*8542734aSAndroid Build Coastguard Worker auto it = configMap.find(option);
43*8542734aSAndroid Build Coastguard Worker if (it != configMap.cend()) {
44*8542734aSAndroid Build Coastguard Worker return it->second == "y";
45*8542734aSAndroid Build Coastguard Worker }
46*8542734aSAndroid Build Coastguard Worker return false;
47*8542734aSAndroid Build Coastguard Worker }
48*8542734aSAndroid Build Coastguard Worker
hasModule(const std::string & option) const49*8542734aSAndroid Build Coastguard Worker bool hasModule(const std::string& option) const {
50*8542734aSAndroid Build Coastguard Worker const auto& configMap = mRuntimeInfo->kernelConfigs();
51*8542734aSAndroid Build Coastguard Worker auto it = configMap.find(option);
52*8542734aSAndroid Build Coastguard Worker if (it != configMap.cend()) {
53*8542734aSAndroid Build Coastguard Worker return (it->second == "y") || (it->second == "m");
54*8542734aSAndroid Build Coastguard Worker }
55*8542734aSAndroid Build Coastguard Worker return false;
56*8542734aSAndroid Build Coastguard Worker }
57*8542734aSAndroid Build Coastguard Worker
58*8542734aSAndroid Build Coastguard Worker private:
59*8542734aSAndroid Build Coastguard Worker std::shared_ptr<const RuntimeInfo> mRuntimeInfo;
60*8542734aSAndroid Build Coastguard Worker };
61*8542734aSAndroid Build Coastguard Worker
62*8542734aSAndroid Build Coastguard Worker } // namespace
63*8542734aSAndroid Build Coastguard Worker
64*8542734aSAndroid Build Coastguard Worker /**
65*8542734aSAndroid Build Coastguard Worker * If this test fails, enable the following kernel modules in your kernel config:
66*8542734aSAndroid Build Coastguard Worker * CONFIG_NET_CLS_MATCHALL=y
67*8542734aSAndroid Build Coastguard Worker * CONFIG_NET_ACT_POLICE=y
68*8542734aSAndroid Build Coastguard Worker * CONFIG_NET_ACT_BPF=y
69*8542734aSAndroid Build Coastguard Worker * CONFIG_BPF_JIT=y
70*8542734aSAndroid Build Coastguard Worker */
TEST(KernelTest,TestRateLimitingSupport)71*8542734aSAndroid Build Coastguard Worker TEST(KernelTest, TestRateLimitingSupport) {
72*8542734aSAndroid Build Coastguard Worker KernelConfigVerifier configVerifier;
73*8542734aSAndroid Build Coastguard Worker EXPECT_TRUE(configVerifier.hasOption("CONFIG_NET_CLS_MATCHALL"));
74*8542734aSAndroid Build Coastguard Worker EXPECT_TRUE(configVerifier.hasOption("CONFIG_NET_ACT_POLICE"));
75*8542734aSAndroid Build Coastguard Worker EXPECT_TRUE(configVerifier.hasOption("CONFIG_NET_ACT_BPF"));
76*8542734aSAndroid Build Coastguard Worker EXPECT_TRUE(configVerifier.hasOption("CONFIG_BPF_JIT"));
77*8542734aSAndroid Build Coastguard Worker }
78*8542734aSAndroid Build Coastguard Worker
TEST(KernelTest,TestRequireBpfUnprivDefaultOn)79*8542734aSAndroid Build Coastguard Worker TEST(KernelTest, TestRequireBpfUnprivDefaultOn) {
80*8542734aSAndroid Build Coastguard Worker KernelConfigVerifier configVerifier;
81*8542734aSAndroid Build Coastguard Worker EXPECT_FALSE(configVerifier.hasOption("CONFIG_BPF_UNPRIV_DEFAULT_OFF"));
82*8542734aSAndroid Build Coastguard Worker }
83*8542734aSAndroid Build Coastguard Worker
TEST(KernelTest,TestBpfJitAlwaysOn)84*8542734aSAndroid Build Coastguard Worker TEST(KernelTest, TestBpfJitAlwaysOn) {
85*8542734aSAndroid Build Coastguard Worker if (bpf::isKernel32Bit() && !bpf::isAtLeastKernelVersion(5, 16, 0))
86*8542734aSAndroid Build Coastguard Worker GTEST_SKIP() << "Exempt on obsolete 32-bit kernels.";
87*8542734aSAndroid Build Coastguard Worker KernelConfigVerifier configVerifier;
88*8542734aSAndroid Build Coastguard Worker ASSERT_TRUE(configVerifier.hasOption("CONFIG_BPF_JIT_ALWAYS_ON"));
89*8542734aSAndroid Build Coastguard Worker }
90*8542734aSAndroid Build Coastguard Worker
TEST(KernelTest,TestHaveEfficientUnalignedAccess)91*8542734aSAndroid Build Coastguard Worker TEST(KernelTest, TestHaveEfficientUnalignedAccess) {
92*8542734aSAndroid Build Coastguard Worker // Turns out the bpf verifier is stricter if you don't have this option.
93*8542734aSAndroid Build Coastguard Worker // At least *some* of our bpf code fails to verify without it.
94*8542734aSAndroid Build Coastguard Worker KernelConfigVerifier configVerifier;
95*8542734aSAndroid Build Coastguard Worker ASSERT_TRUE(configVerifier.hasOption("CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS"));
96*8542734aSAndroid Build Coastguard Worker }
97*8542734aSAndroid Build Coastguard Worker
98*8542734aSAndroid Build Coastguard Worker /* Android 14/U should only launch on 64-bit kernels
99*8542734aSAndroid Build Coastguard Worker * T launches on 5.10/5.15
100*8542734aSAndroid Build Coastguard Worker * U launches on 5.15/6.1
101*8542734aSAndroid Build Coastguard Worker * So >=5.16 implies isKernel64Bit()
102*8542734aSAndroid Build Coastguard Worker */
TEST(KernelTest,TestKernel64Bit)103*8542734aSAndroid Build Coastguard Worker TEST(KernelTest, TestKernel64Bit) {
104*8542734aSAndroid Build Coastguard Worker if (!bpf::isAtLeastKernelVersion(5, 16, 0)) GTEST_SKIP() << "Exempt on < 5.16 kernel.";
105*8542734aSAndroid Build Coastguard Worker ASSERT_TRUE(bpf::isKernel64Bit());
106*8542734aSAndroid Build Coastguard Worker }
107*8542734aSAndroid Build Coastguard Worker
108*8542734aSAndroid Build Coastguard Worker // Android V requires x86 kernels to be 64-bit, as among other things
109*8542734aSAndroid Build Coastguard Worker // 32-bit x86 kernels have subtly different structure layouts for XFRM
TEST(KernelTest,TestX86Kernel64Bit)110*8542734aSAndroid Build Coastguard Worker TEST(KernelTest, TestX86Kernel64Bit) {
111*8542734aSAndroid Build Coastguard Worker if (!bpf::isX86()) GTEST_SKIP() << "Exempt on non-x86 architecture.";
112*8542734aSAndroid Build Coastguard Worker ASSERT_TRUE(bpf::isKernel64Bit());
113*8542734aSAndroid Build Coastguard Worker }
114*8542734aSAndroid Build Coastguard Worker
115*8542734aSAndroid Build Coastguard Worker // Android W requires 64-bit userspace on new 6.7+ kernels.
TEST(KernelTest,TestUser64Bit)116*8542734aSAndroid Build Coastguard Worker TEST(KernelTest, TestUser64Bit) {
117*8542734aSAndroid Build Coastguard Worker if (!bpf::isAtLeastKernelVersion(6, 7, 0)) GTEST_SKIP() << "Exempt on < 6.7 kernel.";
118*8542734aSAndroid Build Coastguard Worker ASSERT_TRUE(bpf::isUserspace64bit());
119*8542734aSAndroid Build Coastguard Worker }
120*8542734aSAndroid Build Coastguard Worker
121*8542734aSAndroid Build Coastguard Worker // Android V requires 4.19+
TEST(KernelTest,TestKernel419)122*8542734aSAndroid Build Coastguard Worker TEST(KernelTest, TestKernel419) {
123*8542734aSAndroid Build Coastguard Worker ASSERT_TRUE(bpf::isAtLeastKernelVersion(4, 19, 0));
124*8542734aSAndroid Build Coastguard Worker }
125*8542734aSAndroid Build Coastguard Worker
126*8542734aSAndroid Build Coastguard Worker // Android W requires 5.4+
TEST(KernelTest,TestKernel54)127*8542734aSAndroid Build Coastguard Worker TEST(KernelTest, TestKernel54) {
128*8542734aSAndroid Build Coastguard Worker ASSERT_TRUE(bpf::isAtLeastKernelVersion(5, 4, 0));
129*8542734aSAndroid Build Coastguard Worker }
130*8542734aSAndroid Build Coastguard Worker
131*8542734aSAndroid Build Coastguard Worker // RiscV is not yet supported: make it fail VTS.
TEST(KernelTest,TestNotRiscV)132*8542734aSAndroid Build Coastguard Worker TEST(KernelTest, TestNotRiscV) {
133*8542734aSAndroid Build Coastguard Worker ASSERT_TRUE(!bpf::isRiscV());
134*8542734aSAndroid Build Coastguard Worker }
135*8542734aSAndroid Build Coastguard Worker
TEST(KernelTest,TestIsLTS)136*8542734aSAndroid Build Coastguard Worker TEST(KernelTest, TestIsLTS) {
137*8542734aSAndroid Build Coastguard Worker ASSERT_TRUE(bpf::isLtsKernel());
138*8542734aSAndroid Build Coastguard Worker }
139*8542734aSAndroid Build Coastguard Worker
exists(const char * filename)140*8542734aSAndroid Build Coastguard Worker static bool exists(const char* filename) {
141*8542734aSAndroid Build Coastguard Worker return !access(filename, F_OK);
142*8542734aSAndroid Build Coastguard Worker }
143*8542734aSAndroid Build Coastguard Worker
isGSI()144*8542734aSAndroid Build Coastguard Worker static bool isGSI() {
145*8542734aSAndroid Build Coastguard Worker // From //system/gsid/libgsi.cpp IsGsiRunning()
146*8542734aSAndroid Build Coastguard Worker return exists("/metadata/gsi/dsu/booted");
147*8542734aSAndroid Build Coastguard Worker }
148*8542734aSAndroid Build Coastguard Worker
149*8542734aSAndroid Build Coastguard Worker #define ifIsKernelThenMinLTS(major, minor, sub) do { \
150*8542734aSAndroid Build Coastguard Worker if (isGSI()) GTEST_SKIP() << "Test is meaningless on GSI."; \
151*8542734aSAndroid Build Coastguard Worker if (!bpf::isKernelVersion((major), (minor))) GTEST_SKIP() << "Not for this LTS ver."; \
152*8542734aSAndroid Build Coastguard Worker ASSERT_TRUE(bpf::isAtLeastKernelVersion((major), (minor), (sub))); \
153*8542734aSAndroid Build Coastguard Worker } while (0)
154*8542734aSAndroid Build Coastguard Worker
TEST(KernelTest,TestMinRequiredLTS_4_19)155*8542734aSAndroid Build Coastguard Worker TEST(KernelTest, TestMinRequiredLTS_4_19) { ifIsKernelThenMinLTS(4, 19, 236); }
TEST(KernelTest,TestMinRequiredLTS_5_4)156*8542734aSAndroid Build Coastguard Worker TEST(KernelTest, TestMinRequiredLTS_5_4) { ifIsKernelThenMinLTS(5, 4, 186); }
TEST(KernelTest,TestMinRequiredLTS_5_10)157*8542734aSAndroid Build Coastguard Worker TEST(KernelTest, TestMinRequiredLTS_5_10) { ifIsKernelThenMinLTS(5, 10, 199); }
TEST(KernelTest,TestMinRequiredLTS_5_15)158*8542734aSAndroid Build Coastguard Worker TEST(KernelTest, TestMinRequiredLTS_5_15) { ifIsKernelThenMinLTS(5, 15, 136); }
TEST(KernelTest,TestMinRequiredLTS_6_1)159*8542734aSAndroid Build Coastguard Worker TEST(KernelTest, TestMinRequiredLTS_6_1) { ifIsKernelThenMinLTS(6, 1, 57); }
TEST(KernelTest,TestMinRequiredLTS_6_6)160*8542734aSAndroid Build Coastguard Worker TEST(KernelTest, TestMinRequiredLTS_6_6) { ifIsKernelThenMinLTS(6, 6, 0); }
TEST(KernelTest,TestMinRequiredLTS_6_12)161*8542734aSAndroid Build Coastguard Worker TEST(KernelTest, TestMinRequiredLTS_6_12) { ifIsKernelThenMinLTS(6, 12, 0); }
162*8542734aSAndroid Build Coastguard Worker
TEST(KernelTest,TestSupportsAcceptRaMinLft)163*8542734aSAndroid Build Coastguard Worker TEST(KernelTest, TestSupportsAcceptRaMinLft) {
164*8542734aSAndroid Build Coastguard Worker if (isGSI()) GTEST_SKIP() << "Meaningless on GSI due to ancient kernels.";
165*8542734aSAndroid Build Coastguard Worker if (!bpf::isAtLeastKernelVersion(5, 10, 0)) GTEST_SKIP() << "Too old base kernel.";
166*8542734aSAndroid Build Coastguard Worker ASSERT_TRUE(exists("/proc/sys/net/ipv6/conf/default/accept_ra_min_lft"));
167*8542734aSAndroid Build Coastguard Worker }
168*8542734aSAndroid Build Coastguard Worker
TEST(KernelTest,TestSupportsCommonUsbEthernetDongles)169*8542734aSAndroid Build Coastguard Worker TEST(KernelTest, TestSupportsCommonUsbEthernetDongles) {
170*8542734aSAndroid Build Coastguard Worker KernelConfigVerifier configVerifier;
171*8542734aSAndroid Build Coastguard Worker if (!configVerifier.hasModule("CONFIG_USB")) GTEST_SKIP() << "Exempt without USB support.";
172*8542734aSAndroid Build Coastguard Worker EXPECT_TRUE(configVerifier.hasModule("CONFIG_USB_NET_AX8817X"));
173*8542734aSAndroid Build Coastguard Worker EXPECT_TRUE(configVerifier.hasModule("CONFIG_USB_NET_AX88179_178A"));
174*8542734aSAndroid Build Coastguard Worker EXPECT_TRUE(configVerifier.hasModule("CONFIG_USB_NET_CDCETHER"));
175*8542734aSAndroid Build Coastguard Worker EXPECT_TRUE(configVerifier.hasModule("CONFIG_USB_NET_CDC_EEM"));
176*8542734aSAndroid Build Coastguard Worker EXPECT_TRUE(configVerifier.hasModule("CONFIG_USB_NET_CDC_NCM"));
177*8542734aSAndroid Build Coastguard Worker if (bpf::isAtLeastKernelVersion(5, 4, 0))
178*8542734aSAndroid Build Coastguard Worker EXPECT_TRUE(configVerifier.hasModule("CONFIG_USB_NET_AQC111"));
179*8542734aSAndroid Build Coastguard Worker
180*8542734aSAndroid Build Coastguard Worker EXPECT_TRUE(configVerifier.hasModule("CONFIG_USB_RTL8152"));
181*8542734aSAndroid Build Coastguard Worker EXPECT_TRUE(configVerifier.hasModule("CONFIG_USB_RTL8150"));
182*8542734aSAndroid Build Coastguard Worker if (bpf::isAtLeastKernelVersion(5, 15, 0)) {
183*8542734aSAndroid Build Coastguard Worker EXPECT_TRUE(configVerifier.hasModule("CONFIG_USB_RTL8153_ECM"));
184*8542734aSAndroid Build Coastguard Worker EXPECT_TRUE(configVerifier.hasModule("CONFIG_AX88796B_PHY"));
185*8542734aSAndroid Build Coastguard Worker }
186*8542734aSAndroid Build Coastguard Worker }
187*8542734aSAndroid Build Coastguard Worker
188*8542734aSAndroid Build Coastguard Worker } // namespace net
189*8542734aSAndroid Build Coastguard Worker } // namespace android
190