blob: 081bf216e80199e03e07b6b4176869de425c58eb [file] [log] [blame]
Lorenzo Colitti3b38b122022-01-12 16:06:07 +09001/*
2 * Copyright 2022 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 * bpf_existence_test.cpp - checks that the device runs expected BPF programs
17 */
18
19#include <cstdint>
Lorenzo Colitti32bd0712022-01-13 15:44:29 +090020#include <set>
Lorenzo Colitti3b38b122022-01-12 16:06:07 +090021#include <string>
Lorenzo Colitti3b38b122022-01-12 16:06:07 +090022
Lorenzo Colitti32bd0712022-01-13 15:44:29 +090023#include <android/api-level.h>
Lorenzo Colitti3b38b122022-01-12 16:06:07 +090024#include <android-base/properties.h>
25#include <android-modules-utils/sdk_level.h>
26
27#include <gtest/gtest.h>
28
29using std::find;
Lorenzo Colitti32bd0712022-01-13 15:44:29 +090030using std::set;
Lorenzo Colitti3b38b122022-01-12 16:06:07 +090031using std::string;
Lorenzo Colitti3b38b122022-01-12 16:06:07 +090032
33using android::modules::sdklevel::IsAtLeastR;
34using android::modules::sdklevel::IsAtLeastS;
35using android::modules::sdklevel::IsAtLeastT;
36
Lorenzo Colitti32bd0712022-01-13 15:44:29 +090037// Mainline development branches lack the constant for the current development OS.
38#ifndef __ANDROID_API_T__
39#define __ANDROID_API_T__ 33
40#endif
41
Lorenzo Colitti3b38b122022-01-12 16:06:07 +090042class BpfExistenceTest : public ::testing::Test {
43};
44
Lorenzo Colitti32bd0712022-01-13 15:44:29 +090045static const set<string> INTRODUCED_R = {
Lorenzo Colitti3b38b122022-01-12 16:06:07 +090046 "/sys/fs/bpf/prog_offload_schedcls_ingress_tether_ether",
47 "/sys/fs/bpf/prog_offload_schedcls_ingress_tether_rawip",
48};
49
Lorenzo Colitti32bd0712022-01-13 15:44:29 +090050static const set<string> INTRODUCED_S = {
Lorenzo Colitti3b38b122022-01-12 16:06:07 +090051 "/sys/fs/bpf/tethering/prog_offload_schedcls_tether_downstream4_ether",
52 "/sys/fs/bpf/tethering/prog_offload_schedcls_tether_downstream4_rawip",
53 "/sys/fs/bpf/tethering/prog_offload_schedcls_tether_downstream6_ether",
54 "/sys/fs/bpf/tethering/prog_offload_schedcls_tether_downstream6_rawip",
55 "/sys/fs/bpf/tethering/prog_offload_schedcls_tether_upstream4_ether",
56 "/sys/fs/bpf/tethering/prog_offload_schedcls_tether_upstream4_rawip",
57 "/sys/fs/bpf/tethering/prog_offload_schedcls_tether_upstream6_ether",
58 "/sys/fs/bpf/tethering/prog_offload_schedcls_tether_upstream6_rawip",
59};
60
Lorenzo Colitti32bd0712022-01-13 15:44:29 +090061static const set<string> REMOVED_S = {
Lorenzo Colitti3b38b122022-01-12 16:06:07 +090062 "/sys/fs/bpf/prog_offload_schedcls_ingress_tether_ether",
63 "/sys/fs/bpf/prog_offload_schedcls_ingress_tether_rawip",
64};
65
Lorenzo Colitti32bd0712022-01-13 15:44:29 +090066static const set<string> INTRODUCED_T = {
Lorenzo Colitti3b38b122022-01-12 16:06:07 +090067};
68
Lorenzo Colitti32bd0712022-01-13 15:44:29 +090069static const set<string> REMOVED_T = {
Lorenzo Colitti3b38b122022-01-12 16:06:07 +090070};
71
Lorenzo Colitti32bd0712022-01-13 15:44:29 +090072void addAll(set<string>* a, const set<string>& b) {
73 a->insert(b.begin(), b.end());
Lorenzo Colitti3b38b122022-01-12 16:06:07 +090074}
75
Lorenzo Colitti32bd0712022-01-13 15:44:29 +090076void removeAll(set<string>* a, const set<string> b) {
Lorenzo Colitti3b38b122022-01-12 16:06:07 +090077 for (const auto& toRemove : b) {
Lorenzo Colitti32bd0712022-01-13 15:44:29 +090078 a->erase(toRemove);
Lorenzo Colitti3b38b122022-01-12 16:06:07 +090079 }
80}
81
Lorenzo Colitti32bd0712022-01-13 15:44:29 +090082void getFileLists(set<string>* expected, set<string>* unexpected) {
Lorenzo Colitti3b38b122022-01-12 16:06:07 +090083 unexpected->clear();
84 expected->clear();
85
86 addAll(unexpected, INTRODUCED_R);
87 addAll(unexpected, INTRODUCED_S);
88 addAll(unexpected, INTRODUCED_T);
89
90 if (IsAtLeastR()) {
91 addAll(expected, INTRODUCED_R);
92 removeAll(unexpected, INTRODUCED_R);
93 // Nothing removed in R.
94 }
95
96 if (IsAtLeastS()) {
97 addAll(expected, INTRODUCED_S);
98 removeAll(expected, REMOVED_S);
99
100 addAll(unexpected, REMOVED_S);
101 removeAll(unexpected, INTRODUCED_S);
102 }
103
104 // Nothing added or removed in SCv2.
105
106 if (IsAtLeastT()) {
107 addAll(expected, INTRODUCED_T);
108 removeAll(expected, REMOVED_T);
109
110 addAll(unexpected, REMOVED_T);
111 removeAll(unexpected, INTRODUCED_T);
112 }
113}
114
115void checkFiles() {
Lorenzo Colitti32bd0712022-01-13 15:44:29 +0900116 set<string> mustExist;
117 set<string> mustNotExist;
Lorenzo Colitti3b38b122022-01-12 16:06:07 +0900118
119 getFileLists(&mustExist, &mustNotExist);
120
121 for (const auto& file : mustExist) {
122 EXPECT_EQ(0, access(file.c_str(), R_OK)) << file << " does not exist";
123 }
124 for (const auto& file : mustNotExist) {
125 int ret = access(file.c_str(), R_OK);
126 int err = errno;
127 EXPECT_EQ(-1, ret) << file << " unexpectedly exists";
128 if (ret == -1) {
129 EXPECT_EQ(ENOENT, err) << " accessing " << file << " failed with errno " << err;
130 }
131 }
132}
133
134TEST_F(BpfExistenceTest, TestPrograms) {
135 // Pre-flight check to ensure test has been updated.
Lorenzo Colitti32bd0712022-01-13 15:44:29 +0900136 uint64_t buildVersionSdk = android_get_device_api_level();
Lorenzo Colitti3b38b122022-01-12 16:06:07 +0900137 ASSERT_NE(0, buildVersionSdk) << "Unable to determine device SDK version";
Lorenzo Colitti32bd0712022-01-13 15:44:29 +0900138 if (buildVersionSdk > __ANDROID_API_T__ && buildVersionSdk != __ANDROID_API_FUTURE__) {
Lorenzo Colitti3b38b122022-01-12 16:06:07 +0900139 FAIL() << "Unknown OS version " << buildVersionSdk << ", please update this test";
140 }
141
142 // Only unconfined root is guaranteed to be able to access everything in /sys/fs/bpf.
143 ASSERT_EQ(0, getuid()) << "This test must run as root.";
144
145 checkFiles();
146}