add --type option to bpf2c tool (#1283)

* add --type option to bpf2c tool

* fix test

* fix failing test, CR comments

* add negative test

* negative test
This commit is contained in:
saxena-anurag 2022-07-13 14:24:32 -07:00 коммит произвёл GitHub
Родитель bc1c96c3cd
Коммит 4ad167dbbd
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
6 изменённых файлов: 87 добавлений и 12 удалений

Просмотреть файл

@ -0,0 +1,23 @@
# Copyright (c) Microsoft Corporation
# SPDX-License-Identifier: MIT
param([Parameter(Mandatory=$True)][string]$FileName,
[Parameter(Mandatory=$True)][string]$FilePath,
[Parameter(Mandatory=$True)][string]$Platform,
[Parameter(Mandatory=$True)][string]$Configuration,
[Parameter(Mandatory=$True)][string]$IncludePath)
Push-Location $FilePath
$ProgramType = ""
if ($FileName -eq "bpf")
{
$ProgramType = "xdp"
}
.\Convert-BpfToNative.ps1 -ProgramName $Filename -Type $ProgramType -IncludeDir $IncludePath -Platform $Platform -Configuration $Configuration -KernelMode $True
.\Convert-BpfToNative.ps1 -ProgramName $Filename -Type $ProgramType -IncludeDir $IncludePath -Platform $Platform -Configuration $Configuration -KernelMode $False
Pop-Location

Просмотреть файл

@ -5,6 +5,7 @@
#define CATCH_CONFIG_MAIN
#include <optional>
#include <string>
#include <vector>
@ -91,7 +92,7 @@ enum class _test_mode
};
void
run_test_elf(const std::string& elf_file, _test_mode test_mode)
run_test_elf(const std::string& elf_file, _test_mode test_mode, const std::optional<std::string>& type)
{
std::vector<const char*> argv;
auto name = elf_file.substr(0, elf_file.find('.'));
@ -108,6 +109,10 @@ run_test_elf(const std::string& elf_file, _test_mode test_mode)
argv.push_back("--hash");
argv.push_back("none");
}
if (type) {
argv.push_back("--type");
argv.push_back(type.value().c_str());
}
auto test = [&](const char* option, const char* suffix) {
if (option) {
@ -148,12 +153,15 @@ run_test_elf(const std::string& elf_file, _test_mode test_mode)
}
#define DECLARE_TEST(FILE, MODE) \
TEST_CASE(FILE " " #MODE, "[elf_bpf_code_gen]") { run_test_elf(FILE ".o", MODE); }
TEST_CASE(FILE " " #MODE, "[elf_bpf_code_gen]") { run_test_elf(FILE ".o", MODE, std::nullopt); }
#define DECLARE_TEST_CUSTOM_PROGRAM_TYPE(FILE, MODE, TYPE) \
TEST_CASE(FILE "-custom-" #MODE, "[elf_bpf_code_gen]") { run_test_elf(FILE ".o", MODE, TYPE); }
DECLARE_TEST("bindmonitor", _test_mode::Verify)
DECLARE_TEST("bindmonitor_ringbuf", _test_mode::Verify)
DECLARE_TEST("bindmonitor_tailcall", _test_mode::Verify)
DECLARE_TEST("bpf", _test_mode::Verify)
DECLARE_TEST_CUSTOM_PROGRAM_TYPE("bpf", _test_mode::Verify, std::string("xdp"))
DECLARE_TEST("bpf_call", _test_mode::Verify)
DECLARE_TEST("cgroup_sock_addr", _test_mode::Verify)
DECLARE_TEST("decap_permit_packet", _test_mode::Verify)
@ -180,7 +188,10 @@ DECLARE_TEST("empty", _test_mode::NoVerify)
DECLARE_TEST("droppacket_unsafe", _test_mode::VerifyFail)
DECLARE_TEST("printk_unsafe", _test_mode::VerifyFail)
DECLARE_TEST("no_such_file", _test_mode::FileNotFound)
DECLARE_TEST("bpf", _test_mode::UseHash)
DECLARE_TEST_CUSTOM_PROGRAM_TYPE("bpf", _test_mode::UseHash, std::string("xdp"))
DECLARE_TEST("bpf", _test_mode::VerifyFail)
DECLARE_TEST_CUSTOM_PROGRAM_TYPE("bpf", _test_mode::VerifyFail, std::string("invalid"))
TEST_CASE("help", "[bpf2c_cli]")
{

Просмотреть файл

Просмотреть файл

@ -130,6 +130,19 @@
<Outputs>$(OutputPath)%(Filename).o</Outputs>
</CustomBuild>
</ItemGroup>
<!-- Build BPF programs that pass verification and build native images for them but require custom program type. -->
<ItemGroup Condition="'$(Analysis)'==''">
<CustomBuild Include="custom_program_type\*.c">
<FileType>CppCode</FileType>
<Command>
clang $(ClangFlags) -I../xdp -I../socket -I./ext/inc -c custom_program_type\%(Filename).c -o $(OutputPath)%(Filename).o
pushd $(SolutionDir)\scripts
powershell -NonInteractive -ExecutionPolicy Unrestricted .\build_custom_sample_programs.ps1 -FileName %(Filename) -FilePath $(OutDir) -IncludePath $(SolutionDir)\include -Platform $(Platform) -Configuration $(Configuration)
popd
</Command>
<Outputs>$(OutputPath)%(Filename).o;$(OutputPath)%(Filename)_um.dll;$(OutputPath)%(Filename).sys</Outputs>
</CustomBuild>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>

Просмотреть файл

@ -2,6 +2,7 @@
# SPDX-License-Identifier: MIT
param([parameter(Mandatory = $true)] [string] $ProgramName,
[parameter(Mandatory = $false)] [string] $Type,
[parameter(Mandatory = $false)] [string] $IncludeDir = "$PSScriptRoot\..\include",
[parameter(Mandatory = $false)] [string] $BinDir = "$PSScriptRoot",
[parameter(Mandatory = $false)] [string] $OutDir = "$PWD",
@ -47,6 +48,10 @@ else {
$AdditionalOptions = If ($SkipVerification) {"--no-verify"} Else {""}
if ($PSBoundParameters.ContainsKey("Type")) {
$AdditionalOptions += " --type $Type"
}
msbuild /p:BinDir="$BinDir\" /p:OutDir="$PWD\" /p:IncludeDir="$IncludeDir" /p:Configuration="$Configuration" /p:Platform="$Platform" /p:ProgramName="$ProgramName" /p:AdditionalOptions="$AdditionalOptions" $ProjectFile
if ($LASTEXITCODE -ne 0) {

Просмотреть файл

@ -149,6 +149,7 @@ main(int argc, char** argv)
} type = output_type::Bare;
std::string verifier_output_file;
std::string file;
std::string type_string = "";
std::string hash_algorithm = "SHA256";
bool verify_programs = true;
std::vector<std::string> parameters(argv + 1, argv + argc);
@ -187,6 +188,18 @@ main(int argc, char** argv)
return true;
}
}}},
{"--type",
{"Type string for the eBPF programs",
[&]() {
++iter;
if (iter == iter_end) {
std::cerr << "Invalid --type option" << std::endl;
return false;
} else {
type_string = *iter;
return true;
}
}}},
{"--hash",
{"Algorithm used to hash ELF file",
[&]() {
@ -255,17 +268,27 @@ main(int argc, char** argv)
// Parse global data.
generator.parse();
// Get global program and attach types, if any.
ebpf_program_type_t program_type;
ebpf_attach_type_t attach_type;
bool global_program_type_set = false;
if (type_string != "") {
if (ebpf_get_program_type_by_name(type_string.c_str(), &program_type, &attach_type) != EBPF_SUCCESS) {
std::cerr << "Program type not found for type string " << type_string << std::endl;
return 1;
}
global_program_type_set = true;
}
// Parse per-section data.
for (const auto& section : sections) {
ebpf_program_type_t program_type;
ebpf_attach_type_t attach_type;
// TODO: Issue #1172
// Workaround: If querying the program and attach type fails, default it to XDP until
// Issue #1172 is fixed.
if (ebpf_get_program_type_by_name(section.raw().c_str(), &program_type, &attach_type) != EBPF_SUCCESS) {
program_type = EBPF_PROGRAM_TYPE_XDP;
attach_type = EBPF_ATTACH_TYPE_XDP;
if (!global_program_type_set) {
if (ebpf_get_program_type_by_name(section.raw().c_str(), &program_type, &attach_type) != EBPF_SUCCESS) {
std::cerr << "Program type not found for section name " << section.raw() << std::endl;
return 1;
}
}
const char* report = nullptr;
const char* error_message = nullptr;
ebpf_api_verifier_stats_t stats;