From 438e4a85260cfe7923d22a8c13a16f7c72d45478 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20=C5=BBenczykowski?= Date: Thu, 8 Dec 2022 16:35:25 +0000 Subject: [PATCH] copy in bpf_base_test.cpp from system/netd MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Test: N/A Signed-off-by: Maciej Żenczykowski Change-Id: I1bf320f838c7cc203dd72bc5b48aee92288bbb81 --- .../bpf_base_test.cpp | 128 ++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 tests/native/connectivity_native_test/bpf_base_test.cpp diff --git a/tests/native/connectivity_native_test/bpf_base_test.cpp b/tests/native/connectivity_native_test/bpf_base_test.cpp new file mode 100644 index 0000000000..f164b2f31a --- /dev/null +++ b/tests/native/connectivity_native_test/bpf_base_test.cpp @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2018 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. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include + +#include "bpf/BpfMap.h" +#include "bpf/BpfUtils.h" +#include "bpf_shared.h" + +using android::base::Result; + +namespace android { +namespace bpf { + +// Use the upper limit of uid to avoid conflict with real app uids. We can't use UID_MAX because +// it's -1, which is INVALID_UID. +constexpr uid_t TEST_UID = UID_MAX - 1; +constexpr uint32_t TEST_TAG = 42; + +class BpfBasicTest : public NetNativeTestBase { + protected: + BpfBasicTest() {} +}; + +TEST_F(BpfBasicTest, TestCgroupMounted) { + std::string cg2_path; + ASSERT_EQ(true, CgroupGetControllerPath(CGROUPV2_CONTROLLER_NAME, &cg2_path)); + ASSERT_EQ(0, access(cg2_path.c_str(), R_OK)); + ASSERT_EQ(0, access((cg2_path + "/cgroup.controllers").c_str(), R_OK)); +} + +TEST_F(BpfBasicTest, TestTrafficControllerSetUp) { + ASSERT_EQ(0, access(BPF_EGRESS_PROG_PATH, R_OK)); + ASSERT_EQ(0, access(BPF_INGRESS_PROG_PATH, R_OK)); + ASSERT_EQ(0, access(XT_BPF_INGRESS_PROG_PATH, R_OK)); + ASSERT_EQ(0, access(XT_BPF_EGRESS_PROG_PATH, R_OK)); + ASSERT_EQ(0, access(COOKIE_TAG_MAP_PATH, R_OK)); + ASSERT_EQ(0, access(UID_COUNTERSET_MAP_PATH, R_OK)); + ASSERT_EQ(0, access(STATS_MAP_A_PATH, R_OK)); + ASSERT_EQ(0, access(STATS_MAP_B_PATH, R_OK)); + ASSERT_EQ(0, access(IFACE_INDEX_NAME_MAP_PATH, R_OK)); + ASSERT_EQ(0, access(IFACE_STATS_MAP_PATH, R_OK)); + ASSERT_EQ(0, access(CONFIGURATION_MAP_PATH, R_OK)); + ASSERT_EQ(0, access(UID_OWNER_MAP_PATH, R_OK)); +} + +TEST_F(BpfBasicTest, TestSocketFilterSetUp) { + ASSERT_EQ(0, access(CGROUP_SOCKET_PROG_PATH, R_OK)); + ASSERT_EQ(0, access(UID_PERMISSION_MAP_PATH, R_OK)); +} + +TEST_F(BpfBasicTest, TestTagSocket) { + BpfMap cookieTagMap(COOKIE_TAG_MAP_PATH); + ASSERT_TRUE(cookieTagMap.isValid()); + int sock = socket(AF_INET6, SOCK_STREAM | SOCK_CLOEXEC, 0); + ASSERT_LE(0, sock); + uint64_t cookie = getSocketCookie(sock); + ASSERT_NE(NONEXISTENT_COOKIE, cookie); + ASSERT_EQ(0, qtaguid_tagSocket(sock, TEST_TAG, TEST_UID)); + Result tagResult = cookieTagMap.readValue(cookie); + ASSERT_RESULT_OK(tagResult); + ASSERT_EQ(TEST_UID, tagResult.value().uid); + ASSERT_EQ(TEST_TAG, tagResult.value().tag); + ASSERT_EQ(0, qtaguid_untagSocket(sock)); + tagResult = cookieTagMap.readValue(cookie); + ASSERT_FALSE(tagResult.ok()); + ASSERT_EQ(ENOENT, tagResult.error().code()); +} + +TEST_F(BpfBasicTest, TestCloseSocketWithoutUntag) { + BpfMap cookieTagMap(COOKIE_TAG_MAP_PATH); + ASSERT_TRUE(cookieTagMap.isValid()); + int sock = socket(AF_INET6, SOCK_STREAM | SOCK_CLOEXEC, 0); + ASSERT_LE(0, sock); + uint64_t cookie = getSocketCookie(sock); + ASSERT_NE(NONEXISTENT_COOKIE, cookie); + ASSERT_EQ(0, qtaguid_tagSocket(sock, TEST_TAG, TEST_UID)); + Result tagResult = cookieTagMap.readValue(cookie); + ASSERT_RESULT_OK(tagResult); + ASSERT_EQ(TEST_UID, tagResult.value().uid); + ASSERT_EQ(TEST_TAG, tagResult.value().tag); + ASSERT_EQ(0, close(sock)); + // Check map periodically until sk destroy handler have done its job. + for (int i = 0; i < 10; i++) { + usleep(5000); // 5ms + tagResult = cookieTagMap.readValue(cookie); + if (!tagResult.ok()) { + ASSERT_EQ(ENOENT, tagResult.error().code()); + return; + } + } + FAIL() << "socket tag still exist after 50ms"; +} + +} +}