Add netsh command to show maps (#476)
Signed-off-by: Dave Thaler <dthaler@microsoft.com> Co-authored-by: saxena-anurag <43585259+saxena-anurag@users.noreply.github.com>
This commit is contained in:
Родитель
2aaa711f7d
Коммит
d5c275acb3
|
@ -164,10 +164,12 @@
|
|||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="elf.cpp" />
|
||||
<ClCompile Include="maps.cpp" />
|
||||
<ClCompile Include="programs.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="elf.h" />
|
||||
<ClInclude Include="maps.h" />
|
||||
<ClInclude Include="programs.h" />
|
||||
<ClInclude Include="tokens.h" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -25,6 +25,9 @@
|
|||
<ClCompile Include="programs.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="maps.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="elf.h">
|
||||
|
@ -36,5 +39,8 @@
|
|||
<ClInclude Include="tokens.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="maps.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
|
@ -0,0 +1,82 @@
|
|||
// Copyright (c) Microsoft Corporation
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <netsh.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "ebpf_api.h"
|
||||
#include "ebpf_windows.h"
|
||||
#include "maps.h"
|
||||
#include "tokens.h"
|
||||
|
||||
static std::string _map_type_names[] = {
|
||||
"Other", "Hash", "Array", "Program array", "Per-CPU hash table", "Per-CPU array", "Hash of maps", "Array of maps"};
|
||||
|
||||
static std::string
|
||||
_get_map_type_name(ebpf_map_type_t type)
|
||||
{
|
||||
int index = (type >= _countof(_map_type_names)) ? 0 : type;
|
||||
return _map_type_names[index];
|
||||
}
|
||||
|
||||
DWORD
|
||||
handle_ebpf_show_maps(
|
||||
LPCWSTR machine, LPWSTR* argv, DWORD current_index, DWORD argc, DWORD flags, LPCVOID data, BOOL* done)
|
||||
{
|
||||
ebpf_result_t result;
|
||||
|
||||
UNREFERENCED_PARAMETER(machine);
|
||||
UNREFERENCED_PARAMETER(flags);
|
||||
UNREFERENCED_PARAMETER(data);
|
||||
UNREFERENCED_PARAMETER(done);
|
||||
|
||||
std::cout << "\n";
|
||||
std::cout << " Key Value Max Inner\n";
|
||||
std::cout << " Map Type Size Size Entries Index\n";
|
||||
std::cout << "================== ==== ===== ======= =====\n";
|
||||
|
||||
fd_t map_fd = ebpf_fd_invalid;
|
||||
for (;;) {
|
||||
fd_t next_map_fd;
|
||||
result = ebpf_get_next_map(map_fd, &next_map_fd);
|
||||
if (result != EBPF_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (map_fd != ebpf_fd_invalid) {
|
||||
ebpf_close_fd(map_fd);
|
||||
}
|
||||
map_fd = next_map_fd;
|
||||
|
||||
if (map_fd == ebpf_fd_invalid) {
|
||||
break;
|
||||
}
|
||||
|
||||
ebpf_map_definition_in_file_t map_definition;
|
||||
result = ebpf_map_query_definition(
|
||||
map_fd,
|
||||
&map_definition.size,
|
||||
(uint32_t*)&map_definition.type,
|
||||
&map_definition.key_size,
|
||||
&map_definition.value_size,
|
||||
&map_definition.max_entries,
|
||||
&map_definition.inner_map_idx);
|
||||
if (result != EBPF_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
|
||||
std::cout << std::setw(18) << std::right << _get_map_type_name(map_definition.type) << std::setw(6)
|
||||
<< std::right << map_definition.key_size << std::setw(7) << std::right << map_definition.value_size
|
||||
<< std::setw(9) << std::right << map_definition.max_entries << std::setw(7) << std::right
|
||||
<< map_definition.inner_map_idx << "\n";
|
||||
}
|
||||
if (map_fd != ebpf_fd_invalid) {
|
||||
ebpf_close_fd(map_fd);
|
||||
}
|
||||
return result;
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
// Copyright (c) Microsoft Corporation
|
||||
// SPDX-License-Identifier: MIT
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
FN_HANDLE_CMD handle_ebpf_show_maps;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -3,9 +3,15 @@
|
|||
|
||||
#include <windows.h>
|
||||
#include <netsh.h> // Must be included after windows.h
|
||||
#include "bpf.h"
|
||||
#include "capture_helper.hpp"
|
||||
#include "catch_wrapper.hpp"
|
||||
#include "elf.h"
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4200)
|
||||
#include "libbpf.h"
|
||||
#pragma warning(pop)
|
||||
#include "maps.h"
|
||||
#include "programs.h"
|
||||
#include "test_helper.hpp"
|
||||
|
||||
|
@ -65,8 +71,6 @@ static std::string
|
|||
_run_netsh_command(
|
||||
_In_ FN_HANDLE_CMD* command, _In_opt_z_ const wchar_t* arg1, _In_opt_z_ const wchar_t* arg2, _Out_ int* result)
|
||||
{
|
||||
_test_helper_end_to_end test_helper;
|
||||
|
||||
capture_helper_t capture;
|
||||
errno_t error = capture.begin_capture();
|
||||
if (error != NO_ERROR) {
|
||||
|
@ -193,6 +197,8 @@ TEST_CASE("show verification bpf.o", "[netsh][verification]")
|
|||
|
||||
TEST_CASE("show verification droppacket.o", "[netsh][verification]")
|
||||
{
|
||||
_test_helper_libbpf test_helper;
|
||||
|
||||
int result;
|
||||
std::string output = _run_netsh_command(handle_ebpf_show_verification, L"droppacket.o", L"xdp", &result);
|
||||
REQUIRE(result == NO_ERROR);
|
||||
|
@ -206,6 +212,8 @@ TEST_CASE("show verification droppacket.o", "[netsh][verification]")
|
|||
|
||||
TEST_CASE("show verification droppacket_unsafe.o", "[netsh][verification]")
|
||||
{
|
||||
_test_helper_libbpf test_helper;
|
||||
|
||||
int result;
|
||||
std::string output = _run_netsh_command(handle_ebpf_show_verification, L"droppacket_unsafe.o", L"xdp", &result);
|
||||
REQUIRE(result == ERROR_SUPPRESS_OUTPUT);
|
||||
|
@ -225,13 +233,52 @@ TEST_CASE("show verification droppacket_unsafe.o", "[netsh][verification]")
|
|||
|
||||
TEST_CASE("show programs", "[netsh][programs]")
|
||||
{
|
||||
int result;
|
||||
_test_helper_libbpf test_helper;
|
||||
|
||||
// Load a program to show.
|
||||
struct bpf_object* object;
|
||||
int program_fd;
|
||||
int result = bpf_prog_load("tail_call.o", BPF_PROG_TYPE_XDP, &object, &program_fd);
|
||||
REQUIRE(result == 0);
|
||||
REQUIRE(object != nullptr);
|
||||
REQUIRE(program_fd != -1);
|
||||
|
||||
std::string output = _run_netsh_command(handle_ebpf_show_programs, nullptr, nullptr, &result);
|
||||
REQUIRE(result == NO_ERROR);
|
||||
|
||||
// Since we mocked the ioctl, there should be no programs shown.
|
||||
REQUIRE(
|
||||
output == "\n"
|
||||
" File Name Section Requested Execution Type\n"
|
||||
"==================== =============== ========================\n");
|
||||
"==================== =============== ========================\n"
|
||||
" tail_call.o xdp_prog JIT\n"
|
||||
" tail_call.o xdp_prog/0 JIT\n");
|
||||
|
||||
bpf_object__close(object);
|
||||
}
|
||||
|
||||
TEST_CASE("show maps", "[netsh][maps]")
|
||||
{
|
||||
_test_helper_end_to_end test_helper;
|
||||
|
||||
// Create maps to show.
|
||||
int outer_map_fd = bpf_create_map(BPF_MAP_TYPE_HASH_OF_MAPS, sizeof(__u32), sizeof(__u32), 2, 0);
|
||||
REQUIRE(outer_map_fd > 0);
|
||||
|
||||
int inner_map_fd = bpf_create_map(BPF_MAP_TYPE_ARRAY, sizeof(__u32), sizeof(__u32), 1, 0);
|
||||
REQUIRE(inner_map_fd > 0);
|
||||
|
||||
int result;
|
||||
std::string output = _run_netsh_command(handle_ebpf_show_maps, nullptr, nullptr, &result);
|
||||
REQUIRE(result == NO_ERROR);
|
||||
|
||||
REQUIRE(
|
||||
output == "\n"
|
||||
" Key Value Max Inner\n"
|
||||
" Map Type Size Size Entries Index\n"
|
||||
"================== ==== ===== ======= =====\n"
|
||||
" Hash of maps 4 4 2 0\n"
|
||||
" Array 4 4 1 0\n");
|
||||
|
||||
ebpf_close_fd(inner_map_fd); // TODO(issue #287): change to _close(inner_map_fd);
|
||||
ebpf_close_fd(outer_map_fd); // TODO(issue #287): change to _close(outer_map_fd);
|
||||
}
|
|
@ -211,6 +211,14 @@ BEGIN
|
|||
\nRemarks: Shows the verifier results of the specified eBPF program.\
|
||||
\n"
|
||||
|
||||
HLP_EBPF_SHOW_MAPS "Shows eBPF maps.\n"
|
||||
HLP_EBPF_SHOW_MAPS_EX "\
|
||||
\nUsage: %1!s!\
|
||||
\n\
|
||||
\nRemarks: Shows all loaded maps.\
|
||||
\n"
|
||||
|
||||
|
||||
END
|
||||
|
||||
#endif // English (United States) resources
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
#define HLP_EBPF_SHOW_SECTIONS_EX 112
|
||||
#define HLP_EBPF_SHOW_VERIFICATION 113
|
||||
#define HLP_EBPF_SHOW_VERIFICATION_EX 114
|
||||
#define HLP_EBPF_SHOW_MAPS 115
|
||||
#define HLP_EBPF_SHOW_MAPS_EX 116
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
|
|
Загрузка…
Ссылка в новой задаче