Add support for handling anonymous inner maps (#3169)
Signed-off-by: Alan Jowett <alan.jowett@microsoft.com> Co-authored-by: Alan Jowett <alan.jowett@microsoft.com>
This commit is contained in:
Родитель
08d9ee561f
Коммит
efb6656b4c
|
@ -182,6 +182,31 @@ _parse_btf_map_info_and_populate_cache(const ELFIO::elfio& reader, const vector<
|
|||
pin_type);
|
||||
}
|
||||
|
||||
// Cache unnamed maps.
|
||||
for (auto& map : map_data) {
|
||||
if (map.name.empty()) {
|
||||
uint32_t idx = (uint32_t)btf_map_name_to_index[map.name];
|
||||
auto& btf_map_descriptor = btf_map_descriptors[idx];
|
||||
// We temporarily stored BTF type ids in the descriptor's fd fields.
|
||||
int btf_type_id = btf_map_descriptor.original_fd;
|
||||
int btf_inner_type_id = btf_map_descriptor.inner_map_fd;
|
||||
|
||||
auto pin_type = _get_pin_type_for_btf_map(btf_data.value(), btf_type_id);
|
||||
cache_map_handle(
|
||||
ebpf_handle_invalid,
|
||||
map_idx_to_original_fd(idx),
|
||||
btf_type_id,
|
||||
btf_map_descriptor.type,
|
||||
btf_map_descriptor.key_size,
|
||||
btf_map_descriptor.value_size,
|
||||
btf_map_descriptor.max_entries,
|
||||
(uint32_t)ebpf_fd_invalid,
|
||||
btf_inner_type_id,
|
||||
MAXSIZE_T,
|
||||
pin_type);
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve inner_map_fd for each map.
|
||||
btf_map_descriptors.clear();
|
||||
g_ebpf_platform_windows.resolve_inner_map_references(btf_map_descriptors);
|
||||
|
@ -212,8 +237,24 @@ _get_map_names(
|
|||
_parse_btf_map_info_and_populate_cache(reader, map_names);
|
||||
}
|
||||
|
||||
if (get_map_descriptor_size() != map_names.size()) {
|
||||
throw std::runtime_error(string("Map name not found for some maps."));
|
||||
// Verify that returned map descriptors are a superset of map names referenced in the symbol section.
|
||||
// Get all map descriptors.
|
||||
auto map_descriptors = get_all_map_descriptors();
|
||||
|
||||
// For each map in map_names (from the symbol table), verify that the map is present in map_descriptors (from the
|
||||
// BTF data).
|
||||
for (const auto& map_name : map_names) {
|
||||
bool found = false;
|
||||
for (const auto& map_descriptor : map_descriptors) {
|
||||
if (map_name.section_offset == map_descriptor.section_offset) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
throw std::runtime_error(string("Map ") + map_name.map_name + " not found.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -390,6 +431,7 @@ load_byte_code(
|
|||
_get_program_and_map_names(file_name, section_to_program_map, map_names);
|
||||
|
||||
auto map_descriptors = get_all_map_descriptors();
|
||||
size_t anonymous_map_count = 0;
|
||||
for (const auto& descriptor : map_descriptors) {
|
||||
bool found = false;
|
||||
int index;
|
||||
|
@ -399,6 +441,15 @@ load_byte_code(
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle anonymous maps.
|
||||
if (descriptor.section_offset == MAXSIZE_T) {
|
||||
std::string name = "__anonymous_map_" + std::to_string(++anonymous_map_count);
|
||||
index = static_cast<int>(map_names.size());
|
||||
map_names.push_back({descriptor.section_offset, name});
|
||||
found = true;
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
result = EBPF_ELF_PARSING_FAILED;
|
||||
goto Exit;
|
||||
|
|
|
@ -219,6 +219,7 @@ DECLARE_TEST("droppacket", _test_mode::Verify)
|
|||
DECLARE_TEST("droppacket_unsafe", _test_mode::NoVerify)
|
||||
DECLARE_TEST("empty", _test_mode::NoVerify)
|
||||
DECLARE_TEST("encap_reflect_packet", _test_mode::Verify)
|
||||
DECLARE_TEST("inner_map", _test_mode::Verify)
|
||||
DECLARE_TEST("invalid_helpers", _test_mode::NoVerify);
|
||||
DECLARE_TEST("invalid_maps1", _test_mode::NoVerify);
|
||||
DECLARE_TEST("invalid_maps2", _test_mode::NoVerify);
|
||||
|
|
|
@ -0,0 +1,243 @@
|
|||
// Copyright (c) Microsoft Corporation
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
// Do not alter this generated file.
|
||||
// This file was generated from inner_map.o
|
||||
|
||||
#include "bpf2c.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
||||
#include <windows.h>
|
||||
|
||||
#define metadata_table inner_map##_metadata_table
|
||||
extern metadata_table_t metadata_table;
|
||||
|
||||
bool APIENTRY
|
||||
DllMain(_In_ HMODULE hModule, unsigned int ul_reason_for_call, _In_ void* lpReserved)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(hModule);
|
||||
UNREFERENCED_PARAMETER(lpReserved);
|
||||
switch (ul_reason_for_call) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
__declspec(dllexport) metadata_table_t* get_metadata_table() { return &metadata_table; }
|
||||
|
||||
#include "bpf2c.h"
|
||||
|
||||
static void
|
||||
_get_hash(_Outptr_result_buffer_maybenull_(*size) const uint8_t** hash, _Out_ size_t* size)
|
||||
{
|
||||
*hash = NULL;
|
||||
*size = 0;
|
||||
}
|
||||
#pragma data_seg(push, "maps")
|
||||
static map_entry_t _maps[] = {
|
||||
{NULL,
|
||||
{
|
||||
BPF_MAP_TYPE_HASH_OF_MAPS, // Type of map.
|
||||
4, // Size in bytes of a map key.
|
||||
4, // Size in bytes of a map value.
|
||||
1, // Maximum number of entries allowed in the map.
|
||||
0, // Inner map index.
|
||||
LIBBPF_PIN_NONE, // Pinning type for the map.
|
||||
15, // Identifier for a map template.
|
||||
11, // The id of the inner map template.
|
||||
},
|
||||
"outer_map"},
|
||||
{NULL,
|
||||
{
|
||||
BPF_MAP_TYPE_ARRAY, // Type of map.
|
||||
4, // Size in bytes of a map key.
|
||||
4, // Size in bytes of a map value.
|
||||
1, // Maximum number of entries allowed in the map.
|
||||
0, // Inner map index.
|
||||
LIBBPF_PIN_NONE, // Pinning type for the map.
|
||||
11, // Identifier for a map template.
|
||||
0, // The id of the inner map template.
|
||||
},
|
||||
"__anonymous_1"},
|
||||
};
|
||||
#pragma data_seg(pop)
|
||||
|
||||
static void
|
||||
_get_maps(_Outptr_result_buffer_maybenull_(*count) map_entry_t** maps, _Out_ size_t* count)
|
||||
{
|
||||
*maps = _maps;
|
||||
*count = 2;
|
||||
}
|
||||
|
||||
static helper_function_entry_t lookup_update_helpers[] = {
|
||||
{NULL, 1, "helper_id_1"},
|
||||
};
|
||||
|
||||
static GUID lookup_update_program_type_guid = {
|
||||
0xf788ef4a, 0x207d, 0x4dc3, {0x85, 0xcf, 0x0f, 0x2e, 0xa1, 0x07, 0x21, 0x3c}};
|
||||
static GUID lookup_update_attach_type_guid = {
|
||||
0xf788ef4b, 0x207d, 0x4dc3, {0x85, 0xcf, 0x0f, 0x2e, 0xa1, 0x07, 0x21, 0x3c}};
|
||||
static uint16_t lookup_update_maps[] = {
|
||||
0,
|
||||
};
|
||||
|
||||
#pragma code_seg(push, "sample~1")
|
||||
static uint64_t
|
||||
lookup_update(void* context)
|
||||
#line 36 "sample/undocked/inner_map.c"
|
||||
{
|
||||
#line 36 "sample/undocked/inner_map.c"
|
||||
// Prologue
|
||||
#line 36 "sample/undocked/inner_map.c"
|
||||
uint64_t stack[(UBPF_STACK_SIZE + 7) / 8];
|
||||
#line 36 "sample/undocked/inner_map.c"
|
||||
register uint64_t r0 = 0;
|
||||
#line 36 "sample/undocked/inner_map.c"
|
||||
register uint64_t r1 = 0;
|
||||
#line 36 "sample/undocked/inner_map.c"
|
||||
register uint64_t r2 = 0;
|
||||
#line 36 "sample/undocked/inner_map.c"
|
||||
register uint64_t r3 = 0;
|
||||
#line 36 "sample/undocked/inner_map.c"
|
||||
register uint64_t r4 = 0;
|
||||
#line 36 "sample/undocked/inner_map.c"
|
||||
register uint64_t r5 = 0;
|
||||
#line 36 "sample/undocked/inner_map.c"
|
||||
register uint64_t r6 = 0;
|
||||
#line 36 "sample/undocked/inner_map.c"
|
||||
register uint64_t r7 = 0;
|
||||
#line 36 "sample/undocked/inner_map.c"
|
||||
register uint64_t r10 = 0;
|
||||
|
||||
#line 36 "sample/undocked/inner_map.c"
|
||||
r1 = (uintptr_t)context;
|
||||
#line 36 "sample/undocked/inner_map.c"
|
||||
r10 = (uintptr_t)((uint8_t*)stack + sizeof(stack));
|
||||
|
||||
// EBPF_OP_MOV64_IMM pc=0 dst=r7 src=r0 offset=0 imm=0
|
||||
#line 36 "sample/undocked/inner_map.c"
|
||||
r7 = IMMEDIATE(0);
|
||||
// EBPF_OP_STXW pc=1 dst=r10 src=r7 offset=-4 imm=0
|
||||
#line 38 "sample/undocked/inner_map.c"
|
||||
*(uint32_t*)(uintptr_t)(r10 + OFFSET(-4)) = (uint32_t)r7;
|
||||
// EBPF_OP_MOV64_REG pc=2 dst=r2 src=r10 offset=0 imm=0
|
||||
#line 38 "sample/undocked/inner_map.c"
|
||||
r2 = r10;
|
||||
// EBPF_OP_ADD64_IMM pc=3 dst=r2 src=r0 offset=0 imm=-4
|
||||
#line 38 "sample/undocked/inner_map.c"
|
||||
r2 += IMMEDIATE(-4);
|
||||
// EBPF_OP_LDDW pc=4 dst=r1 src=r0 offset=0 imm=0
|
||||
#line 41 "sample/undocked/inner_map.c"
|
||||
r1 = POINTER(_maps[0].address);
|
||||
// EBPF_OP_CALL pc=6 dst=r0 src=r0 offset=0 imm=1
|
||||
#line 41 "sample/undocked/inner_map.c"
|
||||
r0 = lookup_update_helpers[0].address
|
||||
#line 41 "sample/undocked/inner_map.c"
|
||||
(r1, r2, r3, r4, r5);
|
||||
#line 41 "sample/undocked/inner_map.c"
|
||||
if ((lookup_update_helpers[0].tail_call) && (r0 == 0))
|
||||
#line 41 "sample/undocked/inner_map.c"
|
||||
return 0;
|
||||
// EBPF_OP_MOV64_IMM pc=7 dst=r6 src=r0 offset=0 imm=1
|
||||
#line 41 "sample/undocked/inner_map.c"
|
||||
r6 = IMMEDIATE(1);
|
||||
// EBPF_OP_JEQ_IMM pc=8 dst=r0 src=r0 offset=9 imm=0
|
||||
#line 42 "sample/undocked/inner_map.c"
|
||||
if (r0 == IMMEDIATE(0))
|
||||
#line 42 "sample/undocked/inner_map.c"
|
||||
goto label_1;
|
||||
// EBPF_OP_STXW pc=9 dst=r10 src=r7 offset=-8 imm=0
|
||||
#line 43 "sample/undocked/inner_map.c"
|
||||
*(uint32_t*)(uintptr_t)(r10 + OFFSET(-8)) = (uint32_t)r7;
|
||||
// EBPF_OP_MOV64_REG pc=10 dst=r2 src=r10 offset=0 imm=0
|
||||
#line 43 "sample/undocked/inner_map.c"
|
||||
r2 = r10;
|
||||
// EBPF_OP_ADD64_IMM pc=11 dst=r2 src=r0 offset=0 imm=-8
|
||||
#line 43 "sample/undocked/inner_map.c"
|
||||
r2 += IMMEDIATE(-8);
|
||||
// EBPF_OP_MOV64_REG pc=12 dst=r1 src=r0 offset=0 imm=0
|
||||
#line 44 "sample/undocked/inner_map.c"
|
||||
r1 = r0;
|
||||
// EBPF_OP_CALL pc=13 dst=r0 src=r0 offset=0 imm=1
|
||||
#line 44 "sample/undocked/inner_map.c"
|
||||
r0 = lookup_update_helpers[0].address
|
||||
#line 44 "sample/undocked/inner_map.c"
|
||||
(r1, r2, r3, r4, r5);
|
||||
#line 44 "sample/undocked/inner_map.c"
|
||||
if ((lookup_update_helpers[0].tail_call) && (r0 == 0))
|
||||
#line 44 "sample/undocked/inner_map.c"
|
||||
return 0;
|
||||
// EBPF_OP_JEQ_IMM pc=14 dst=r0 src=r0 offset=3 imm=0
|
||||
#line 45 "sample/undocked/inner_map.c"
|
||||
if (r0 == IMMEDIATE(0))
|
||||
#line 45 "sample/undocked/inner_map.c"
|
||||
goto label_1;
|
||||
// EBPF_OP_MOV64_IMM pc=15 dst=r1 src=r0 offset=0 imm=1
|
||||
#line 45 "sample/undocked/inner_map.c"
|
||||
r1 = IMMEDIATE(1);
|
||||
// EBPF_OP_STXW pc=16 dst=r0 src=r1 offset=0 imm=0
|
||||
#line 47 "sample/undocked/inner_map.c"
|
||||
*(uint32_t*)(uintptr_t)(r0 + OFFSET(0)) = (uint32_t)r1;
|
||||
// EBPF_OP_MOV64_IMM pc=17 dst=r6 src=r0 offset=0 imm=0
|
||||
#line 47 "sample/undocked/inner_map.c"
|
||||
r6 = IMMEDIATE(0);
|
||||
label_1:
|
||||
// EBPF_OP_MOV64_REG pc=18 dst=r0 src=r6 offset=0 imm=0
|
||||
#line 52 "sample/undocked/inner_map.c"
|
||||
r0 = r6;
|
||||
// EBPF_OP_EXIT pc=19 dst=r0 src=r0 offset=0 imm=0
|
||||
#line 52 "sample/undocked/inner_map.c"
|
||||
return r0;
|
||||
#line 52 "sample/undocked/inner_map.c"
|
||||
}
|
||||
#pragma code_seg(pop)
|
||||
#line __LINE__ __FILE__
|
||||
|
||||
#pragma data_seg(push, "programs")
|
||||
static program_entry_t _programs[] = {
|
||||
{
|
||||
0,
|
||||
lookup_update,
|
||||
"sample~1",
|
||||
"sample_ext",
|
||||
"lookup_update",
|
||||
lookup_update_maps,
|
||||
1,
|
||||
lookup_update_helpers,
|
||||
1,
|
||||
20,
|
||||
&lookup_update_program_type_guid,
|
||||
&lookup_update_attach_type_guid,
|
||||
},
|
||||
};
|
||||
#pragma data_seg(pop)
|
||||
|
||||
static void
|
||||
_get_programs(_Outptr_result_buffer_(*count) program_entry_t** programs, _Out_ size_t* count)
|
||||
{
|
||||
*programs = _programs;
|
||||
*count = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
_get_version(_Out_ bpf2c_version_t* version)
|
||||
{
|
||||
version->major = 0;
|
||||
version->minor = 13;
|
||||
version->revision = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
_get_map_initial_values(_Outptr_result_buffer_(*count) map_initial_values_t** map_initial_values, _Out_ size_t* count)
|
||||
{
|
||||
*map_initial_values = NULL;
|
||||
*count = 0;
|
||||
}
|
||||
|
||||
metadata_table_t inner_map_metadata_table = {
|
||||
sizeof(metadata_table_t), _get_programs, _get_maps, _get_hash, _get_version, _get_map_initial_values};
|
|
@ -0,0 +1,217 @@
|
|||
// Copyright (c) Microsoft Corporation
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
// Do not alter this generated file.
|
||||
// This file was generated from inner_map.o
|
||||
|
||||
#include "bpf2c.h"
|
||||
|
||||
static void
|
||||
_get_hash(_Outptr_result_buffer_maybenull_(*size) const uint8_t** hash, _Out_ size_t* size)
|
||||
{
|
||||
*hash = NULL;
|
||||
*size = 0;
|
||||
}
|
||||
#pragma data_seg(push, "maps")
|
||||
static map_entry_t _maps[] = {
|
||||
{NULL,
|
||||
{
|
||||
BPF_MAP_TYPE_HASH_OF_MAPS, // Type of map.
|
||||
4, // Size in bytes of a map key.
|
||||
4, // Size in bytes of a map value.
|
||||
1, // Maximum number of entries allowed in the map.
|
||||
0, // Inner map index.
|
||||
LIBBPF_PIN_NONE, // Pinning type for the map.
|
||||
15, // Identifier for a map template.
|
||||
11, // The id of the inner map template.
|
||||
},
|
||||
"outer_map"},
|
||||
{NULL,
|
||||
{
|
||||
BPF_MAP_TYPE_ARRAY, // Type of map.
|
||||
4, // Size in bytes of a map key.
|
||||
4, // Size in bytes of a map value.
|
||||
1, // Maximum number of entries allowed in the map.
|
||||
0, // Inner map index.
|
||||
LIBBPF_PIN_NONE, // Pinning type for the map.
|
||||
11, // Identifier for a map template.
|
||||
0, // The id of the inner map template.
|
||||
},
|
||||
"__anonymous_1"},
|
||||
};
|
||||
#pragma data_seg(pop)
|
||||
|
||||
static void
|
||||
_get_maps(_Outptr_result_buffer_maybenull_(*count) map_entry_t** maps, _Out_ size_t* count)
|
||||
{
|
||||
*maps = _maps;
|
||||
*count = 2;
|
||||
}
|
||||
|
||||
static helper_function_entry_t lookup_update_helpers[] = {
|
||||
{NULL, 1, "helper_id_1"},
|
||||
};
|
||||
|
||||
static GUID lookup_update_program_type_guid = {
|
||||
0xf788ef4a, 0x207d, 0x4dc3, {0x85, 0xcf, 0x0f, 0x2e, 0xa1, 0x07, 0x21, 0x3c}};
|
||||
static GUID lookup_update_attach_type_guid = {
|
||||
0xf788ef4b, 0x207d, 0x4dc3, {0x85, 0xcf, 0x0f, 0x2e, 0xa1, 0x07, 0x21, 0x3c}};
|
||||
static uint16_t lookup_update_maps[] = {
|
||||
0,
|
||||
};
|
||||
|
||||
#pragma code_seg(push, "sample~1")
|
||||
static uint64_t
|
||||
lookup_update(void* context)
|
||||
#line 36 "sample/undocked/inner_map.c"
|
||||
{
|
||||
#line 36 "sample/undocked/inner_map.c"
|
||||
// Prologue
|
||||
#line 36 "sample/undocked/inner_map.c"
|
||||
uint64_t stack[(UBPF_STACK_SIZE + 7) / 8];
|
||||
#line 36 "sample/undocked/inner_map.c"
|
||||
register uint64_t r0 = 0;
|
||||
#line 36 "sample/undocked/inner_map.c"
|
||||
register uint64_t r1 = 0;
|
||||
#line 36 "sample/undocked/inner_map.c"
|
||||
register uint64_t r2 = 0;
|
||||
#line 36 "sample/undocked/inner_map.c"
|
||||
register uint64_t r3 = 0;
|
||||
#line 36 "sample/undocked/inner_map.c"
|
||||
register uint64_t r4 = 0;
|
||||
#line 36 "sample/undocked/inner_map.c"
|
||||
register uint64_t r5 = 0;
|
||||
#line 36 "sample/undocked/inner_map.c"
|
||||
register uint64_t r6 = 0;
|
||||
#line 36 "sample/undocked/inner_map.c"
|
||||
register uint64_t r7 = 0;
|
||||
#line 36 "sample/undocked/inner_map.c"
|
||||
register uint64_t r10 = 0;
|
||||
|
||||
#line 36 "sample/undocked/inner_map.c"
|
||||
r1 = (uintptr_t)context;
|
||||
#line 36 "sample/undocked/inner_map.c"
|
||||
r10 = (uintptr_t)((uint8_t*)stack + sizeof(stack));
|
||||
|
||||
// EBPF_OP_MOV64_IMM pc=0 dst=r7 src=r0 offset=0 imm=0
|
||||
#line 36 "sample/undocked/inner_map.c"
|
||||
r7 = IMMEDIATE(0);
|
||||
// EBPF_OP_STXW pc=1 dst=r10 src=r7 offset=-4 imm=0
|
||||
#line 38 "sample/undocked/inner_map.c"
|
||||
*(uint32_t*)(uintptr_t)(r10 + OFFSET(-4)) = (uint32_t)r7;
|
||||
// EBPF_OP_MOV64_REG pc=2 dst=r2 src=r10 offset=0 imm=0
|
||||
#line 38 "sample/undocked/inner_map.c"
|
||||
r2 = r10;
|
||||
// EBPF_OP_ADD64_IMM pc=3 dst=r2 src=r0 offset=0 imm=-4
|
||||
#line 38 "sample/undocked/inner_map.c"
|
||||
r2 += IMMEDIATE(-4);
|
||||
// EBPF_OP_LDDW pc=4 dst=r1 src=r0 offset=0 imm=0
|
||||
#line 41 "sample/undocked/inner_map.c"
|
||||
r1 = POINTER(_maps[0].address);
|
||||
// EBPF_OP_CALL pc=6 dst=r0 src=r0 offset=0 imm=1
|
||||
#line 41 "sample/undocked/inner_map.c"
|
||||
r0 = lookup_update_helpers[0].address
|
||||
#line 41 "sample/undocked/inner_map.c"
|
||||
(r1, r2, r3, r4, r5);
|
||||
#line 41 "sample/undocked/inner_map.c"
|
||||
if ((lookup_update_helpers[0].tail_call) && (r0 == 0))
|
||||
#line 41 "sample/undocked/inner_map.c"
|
||||
return 0;
|
||||
// EBPF_OP_MOV64_IMM pc=7 dst=r6 src=r0 offset=0 imm=1
|
||||
#line 41 "sample/undocked/inner_map.c"
|
||||
r6 = IMMEDIATE(1);
|
||||
// EBPF_OP_JEQ_IMM pc=8 dst=r0 src=r0 offset=9 imm=0
|
||||
#line 42 "sample/undocked/inner_map.c"
|
||||
if (r0 == IMMEDIATE(0))
|
||||
#line 42 "sample/undocked/inner_map.c"
|
||||
goto label_1;
|
||||
// EBPF_OP_STXW pc=9 dst=r10 src=r7 offset=-8 imm=0
|
||||
#line 43 "sample/undocked/inner_map.c"
|
||||
*(uint32_t*)(uintptr_t)(r10 + OFFSET(-8)) = (uint32_t)r7;
|
||||
// EBPF_OP_MOV64_REG pc=10 dst=r2 src=r10 offset=0 imm=0
|
||||
#line 43 "sample/undocked/inner_map.c"
|
||||
r2 = r10;
|
||||
// EBPF_OP_ADD64_IMM pc=11 dst=r2 src=r0 offset=0 imm=-8
|
||||
#line 43 "sample/undocked/inner_map.c"
|
||||
r2 += IMMEDIATE(-8);
|
||||
// EBPF_OP_MOV64_REG pc=12 dst=r1 src=r0 offset=0 imm=0
|
||||
#line 44 "sample/undocked/inner_map.c"
|
||||
r1 = r0;
|
||||
// EBPF_OP_CALL pc=13 dst=r0 src=r0 offset=0 imm=1
|
||||
#line 44 "sample/undocked/inner_map.c"
|
||||
r0 = lookup_update_helpers[0].address
|
||||
#line 44 "sample/undocked/inner_map.c"
|
||||
(r1, r2, r3, r4, r5);
|
||||
#line 44 "sample/undocked/inner_map.c"
|
||||
if ((lookup_update_helpers[0].tail_call) && (r0 == 0))
|
||||
#line 44 "sample/undocked/inner_map.c"
|
||||
return 0;
|
||||
// EBPF_OP_JEQ_IMM pc=14 dst=r0 src=r0 offset=3 imm=0
|
||||
#line 45 "sample/undocked/inner_map.c"
|
||||
if (r0 == IMMEDIATE(0))
|
||||
#line 45 "sample/undocked/inner_map.c"
|
||||
goto label_1;
|
||||
// EBPF_OP_MOV64_IMM pc=15 dst=r1 src=r0 offset=0 imm=1
|
||||
#line 45 "sample/undocked/inner_map.c"
|
||||
r1 = IMMEDIATE(1);
|
||||
// EBPF_OP_STXW pc=16 dst=r0 src=r1 offset=0 imm=0
|
||||
#line 47 "sample/undocked/inner_map.c"
|
||||
*(uint32_t*)(uintptr_t)(r0 + OFFSET(0)) = (uint32_t)r1;
|
||||
// EBPF_OP_MOV64_IMM pc=17 dst=r6 src=r0 offset=0 imm=0
|
||||
#line 47 "sample/undocked/inner_map.c"
|
||||
r6 = IMMEDIATE(0);
|
||||
label_1:
|
||||
// EBPF_OP_MOV64_REG pc=18 dst=r0 src=r6 offset=0 imm=0
|
||||
#line 52 "sample/undocked/inner_map.c"
|
||||
r0 = r6;
|
||||
// EBPF_OP_EXIT pc=19 dst=r0 src=r0 offset=0 imm=0
|
||||
#line 52 "sample/undocked/inner_map.c"
|
||||
return r0;
|
||||
#line 52 "sample/undocked/inner_map.c"
|
||||
}
|
||||
#pragma code_seg(pop)
|
||||
#line __LINE__ __FILE__
|
||||
|
||||
#pragma data_seg(push, "programs")
|
||||
static program_entry_t _programs[] = {
|
||||
{
|
||||
0,
|
||||
lookup_update,
|
||||
"sample~1",
|
||||
"sample_ext",
|
||||
"lookup_update",
|
||||
lookup_update_maps,
|
||||
1,
|
||||
lookup_update_helpers,
|
||||
1,
|
||||
20,
|
||||
&lookup_update_program_type_guid,
|
||||
&lookup_update_attach_type_guid,
|
||||
},
|
||||
};
|
||||
#pragma data_seg(pop)
|
||||
|
||||
static void
|
||||
_get_programs(_Outptr_result_buffer_(*count) program_entry_t** programs, _Out_ size_t* count)
|
||||
{
|
||||
*programs = _programs;
|
||||
*count = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
_get_version(_Out_ bpf2c_version_t* version)
|
||||
{
|
||||
version->major = 0;
|
||||
version->minor = 13;
|
||||
version->revision = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
_get_map_initial_values(_Outptr_result_buffer_(*count) map_initial_values_t** map_initial_values, _Out_ size_t* count)
|
||||
{
|
||||
*map_initial_values = NULL;
|
||||
*count = 0;
|
||||
}
|
||||
|
||||
metadata_table_t inner_map_metadata_table = {
|
||||
sizeof(metadata_table_t), _get_programs, _get_maps, _get_hash, _get_version, _get_map_initial_values};
|
|
@ -0,0 +1,378 @@
|
|||
// Copyright (c) Microsoft Corporation
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
// Do not alter this generated file.
|
||||
// This file was generated from inner_map.o
|
||||
|
||||
#define NO_CRT
|
||||
#include "bpf2c.h"
|
||||
|
||||
#include <guiddef.h>
|
||||
#include <wdm.h>
|
||||
#include <wsk.h>
|
||||
|
||||
DRIVER_INITIALIZE DriverEntry;
|
||||
DRIVER_UNLOAD DriverUnload;
|
||||
RTL_QUERY_REGISTRY_ROUTINE static _bpf2c_query_registry_routine;
|
||||
|
||||
#define metadata_table inner_map##_metadata_table
|
||||
|
||||
static GUID _bpf2c_npi_id = {/* c847aac8-a6f2-4b53-aea3-f4a94b9a80cb */
|
||||
0xc847aac8,
|
||||
0xa6f2,
|
||||
0x4b53,
|
||||
{0xae, 0xa3, 0xf4, 0xa9, 0x4b, 0x9a, 0x80, 0xcb}};
|
||||
static NPI_MODULEID _bpf2c_module_id = {sizeof(_bpf2c_module_id), MIT_GUID, {0}};
|
||||
static HANDLE _bpf2c_nmr_client_handle;
|
||||
static HANDLE _bpf2c_nmr_provider_handle;
|
||||
extern metadata_table_t metadata_table;
|
||||
|
||||
static NTSTATUS
|
||||
_bpf2c_npi_client_attach_provider(
|
||||
_In_ HANDLE nmr_binding_handle,
|
||||
_In_ void* client_context,
|
||||
_In_ const NPI_REGISTRATION_INSTANCE* provider_registration_instance);
|
||||
|
||||
static NTSTATUS
|
||||
_bpf2c_npi_client_detach_provider(_In_ void* client_binding_context);
|
||||
|
||||
static const NPI_CLIENT_CHARACTERISTICS _bpf2c_npi_client_characteristics = {
|
||||
0, // Version
|
||||
sizeof(NPI_CLIENT_CHARACTERISTICS), // Length
|
||||
_bpf2c_npi_client_attach_provider,
|
||||
_bpf2c_npi_client_detach_provider,
|
||||
NULL,
|
||||
{0, // Version
|
||||
sizeof(NPI_REGISTRATION_INSTANCE), // Length
|
||||
&_bpf2c_npi_id,
|
||||
&_bpf2c_module_id,
|
||||
0,
|
||||
&metadata_table}};
|
||||
|
||||
static NTSTATUS
|
||||
_bpf2c_query_npi_module_id(
|
||||
_In_ const wchar_t* value_name,
|
||||
unsigned long value_type,
|
||||
_In_ const void* value_data,
|
||||
unsigned long value_length,
|
||||
_Inout_ void* context,
|
||||
_Inout_ void* entry_context)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(value_name);
|
||||
UNREFERENCED_PARAMETER(context);
|
||||
UNREFERENCED_PARAMETER(entry_context);
|
||||
|
||||
if (value_type != REG_BINARY) {
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
if (value_length != sizeof(_bpf2c_module_id.Guid)) {
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
memcpy(&_bpf2c_module_id.Guid, value_data, value_length);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
DriverEntry(_In_ DRIVER_OBJECT* driver_object, _In_ UNICODE_STRING* registry_path)
|
||||
{
|
||||
NTSTATUS status;
|
||||
RTL_QUERY_REGISTRY_TABLE query_table[] = {
|
||||
{
|
||||
NULL, // Query routine
|
||||
RTL_QUERY_REGISTRY_SUBKEY, // Flags
|
||||
L"Parameters", // Name
|
||||
NULL, // Entry context
|
||||
REG_NONE, // Default type
|
||||
NULL, // Default data
|
||||
0, // Default length
|
||||
},
|
||||
{
|
||||
_bpf2c_query_npi_module_id, // Query routine
|
||||
RTL_QUERY_REGISTRY_REQUIRED, // Flags
|
||||
L"NpiModuleId", // Name
|
||||
NULL, // Entry context
|
||||
REG_NONE, // Default type
|
||||
NULL, // Default data
|
||||
0, // Default length
|
||||
},
|
||||
{0}};
|
||||
|
||||
status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, registry_path->Buffer, query_table, NULL, NULL);
|
||||
if (!NT_SUCCESS(status)) {
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
status = NmrRegisterClient(&_bpf2c_npi_client_characteristics, NULL, &_bpf2c_nmr_client_handle);
|
||||
|
||||
Exit:
|
||||
if (NT_SUCCESS(status)) {
|
||||
driver_object->DriverUnload = DriverUnload;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void
|
||||
DriverUnload(_In_ DRIVER_OBJECT* driver_object)
|
||||
{
|
||||
NTSTATUS status = NmrDeregisterClient(_bpf2c_nmr_client_handle);
|
||||
if (status == STATUS_PENDING) {
|
||||
NmrWaitForClientDeregisterComplete(_bpf2c_nmr_client_handle);
|
||||
}
|
||||
UNREFERENCED_PARAMETER(driver_object);
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
_bpf2c_npi_client_attach_provider(
|
||||
_In_ HANDLE nmr_binding_handle,
|
||||
_In_ void* client_context,
|
||||
_In_ const NPI_REGISTRATION_INSTANCE* provider_registration_instance)
|
||||
{
|
||||
NTSTATUS status = STATUS_SUCCESS;
|
||||
void* provider_binding_context = NULL;
|
||||
void* provider_dispatch_table = NULL;
|
||||
|
||||
UNREFERENCED_PARAMETER(client_context);
|
||||
UNREFERENCED_PARAMETER(provider_registration_instance);
|
||||
|
||||
if (_bpf2c_nmr_provider_handle != NULL) {
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning( \
|
||||
disable : 6387) // Param 3 does not adhere to the specification for the function 'NmrClientAttachProvider'
|
||||
// As per MSDN, client dispatch can be NULL, but SAL does not allow it.
|
||||
// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/netioddk/nf-netioddk-nmrclientattachprovider
|
||||
status = NmrClientAttachProvider(
|
||||
nmr_binding_handle, client_context, NULL, &provider_binding_context, &provider_dispatch_table);
|
||||
if (status != STATUS_SUCCESS) {
|
||||
goto Done;
|
||||
}
|
||||
#pragma warning(pop)
|
||||
_bpf2c_nmr_provider_handle = nmr_binding_handle;
|
||||
|
||||
Done:
|
||||
return status;
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
_bpf2c_npi_client_detach_provider(_In_ void* client_binding_context)
|
||||
{
|
||||
_bpf2c_nmr_provider_handle = NULL;
|
||||
UNREFERENCED_PARAMETER(client_binding_context);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#include "bpf2c.h"
|
||||
|
||||
static void
|
||||
_get_hash(_Outptr_result_buffer_maybenull_(*size) const uint8_t** hash, _Out_ size_t* size)
|
||||
{
|
||||
*hash = NULL;
|
||||
*size = 0;
|
||||
}
|
||||
#pragma data_seg(push, "maps")
|
||||
static map_entry_t _maps[] = {
|
||||
{NULL,
|
||||
{
|
||||
BPF_MAP_TYPE_HASH_OF_MAPS, // Type of map.
|
||||
4, // Size in bytes of a map key.
|
||||
4, // Size in bytes of a map value.
|
||||
1, // Maximum number of entries allowed in the map.
|
||||
0, // Inner map index.
|
||||
LIBBPF_PIN_NONE, // Pinning type for the map.
|
||||
15, // Identifier for a map template.
|
||||
11, // The id of the inner map template.
|
||||
},
|
||||
"outer_map"},
|
||||
{NULL,
|
||||
{
|
||||
BPF_MAP_TYPE_ARRAY, // Type of map.
|
||||
4, // Size in bytes of a map key.
|
||||
4, // Size in bytes of a map value.
|
||||
1, // Maximum number of entries allowed in the map.
|
||||
0, // Inner map index.
|
||||
LIBBPF_PIN_NONE, // Pinning type for the map.
|
||||
11, // Identifier for a map template.
|
||||
0, // The id of the inner map template.
|
||||
},
|
||||
"__anonymous_1"},
|
||||
};
|
||||
#pragma data_seg(pop)
|
||||
|
||||
static void
|
||||
_get_maps(_Outptr_result_buffer_maybenull_(*count) map_entry_t** maps, _Out_ size_t* count)
|
||||
{
|
||||
*maps = _maps;
|
||||
*count = 2;
|
||||
}
|
||||
|
||||
static helper_function_entry_t lookup_update_helpers[] = {
|
||||
{NULL, 1, "helper_id_1"},
|
||||
};
|
||||
|
||||
static GUID lookup_update_program_type_guid = {
|
||||
0xf788ef4a, 0x207d, 0x4dc3, {0x85, 0xcf, 0x0f, 0x2e, 0xa1, 0x07, 0x21, 0x3c}};
|
||||
static GUID lookup_update_attach_type_guid = {
|
||||
0xf788ef4b, 0x207d, 0x4dc3, {0x85, 0xcf, 0x0f, 0x2e, 0xa1, 0x07, 0x21, 0x3c}};
|
||||
static uint16_t lookup_update_maps[] = {
|
||||
0,
|
||||
};
|
||||
|
||||
#pragma code_seg(push, "sample~1")
|
||||
static uint64_t
|
||||
lookup_update(void* context)
|
||||
#line 36 "sample/undocked/inner_map.c"
|
||||
{
|
||||
#line 36 "sample/undocked/inner_map.c"
|
||||
// Prologue
|
||||
#line 36 "sample/undocked/inner_map.c"
|
||||
uint64_t stack[(UBPF_STACK_SIZE + 7) / 8];
|
||||
#line 36 "sample/undocked/inner_map.c"
|
||||
register uint64_t r0 = 0;
|
||||
#line 36 "sample/undocked/inner_map.c"
|
||||
register uint64_t r1 = 0;
|
||||
#line 36 "sample/undocked/inner_map.c"
|
||||
register uint64_t r2 = 0;
|
||||
#line 36 "sample/undocked/inner_map.c"
|
||||
register uint64_t r3 = 0;
|
||||
#line 36 "sample/undocked/inner_map.c"
|
||||
register uint64_t r4 = 0;
|
||||
#line 36 "sample/undocked/inner_map.c"
|
||||
register uint64_t r5 = 0;
|
||||
#line 36 "sample/undocked/inner_map.c"
|
||||
register uint64_t r6 = 0;
|
||||
#line 36 "sample/undocked/inner_map.c"
|
||||
register uint64_t r7 = 0;
|
||||
#line 36 "sample/undocked/inner_map.c"
|
||||
register uint64_t r10 = 0;
|
||||
|
||||
#line 36 "sample/undocked/inner_map.c"
|
||||
r1 = (uintptr_t)context;
|
||||
#line 36 "sample/undocked/inner_map.c"
|
||||
r10 = (uintptr_t)((uint8_t*)stack + sizeof(stack));
|
||||
|
||||
// EBPF_OP_MOV64_IMM pc=0 dst=r7 src=r0 offset=0 imm=0
|
||||
#line 36 "sample/undocked/inner_map.c"
|
||||
r7 = IMMEDIATE(0);
|
||||
// EBPF_OP_STXW pc=1 dst=r10 src=r7 offset=-4 imm=0
|
||||
#line 38 "sample/undocked/inner_map.c"
|
||||
*(uint32_t*)(uintptr_t)(r10 + OFFSET(-4)) = (uint32_t)r7;
|
||||
// EBPF_OP_MOV64_REG pc=2 dst=r2 src=r10 offset=0 imm=0
|
||||
#line 38 "sample/undocked/inner_map.c"
|
||||
r2 = r10;
|
||||
// EBPF_OP_ADD64_IMM pc=3 dst=r2 src=r0 offset=0 imm=-4
|
||||
#line 38 "sample/undocked/inner_map.c"
|
||||
r2 += IMMEDIATE(-4);
|
||||
// EBPF_OP_LDDW pc=4 dst=r1 src=r0 offset=0 imm=0
|
||||
#line 41 "sample/undocked/inner_map.c"
|
||||
r1 = POINTER(_maps[0].address);
|
||||
// EBPF_OP_CALL pc=6 dst=r0 src=r0 offset=0 imm=1
|
||||
#line 41 "sample/undocked/inner_map.c"
|
||||
r0 = lookup_update_helpers[0].address
|
||||
#line 41 "sample/undocked/inner_map.c"
|
||||
(r1, r2, r3, r4, r5);
|
||||
#line 41 "sample/undocked/inner_map.c"
|
||||
if ((lookup_update_helpers[0].tail_call) && (r0 == 0))
|
||||
#line 41 "sample/undocked/inner_map.c"
|
||||
return 0;
|
||||
// EBPF_OP_MOV64_IMM pc=7 dst=r6 src=r0 offset=0 imm=1
|
||||
#line 41 "sample/undocked/inner_map.c"
|
||||
r6 = IMMEDIATE(1);
|
||||
// EBPF_OP_JEQ_IMM pc=8 dst=r0 src=r0 offset=9 imm=0
|
||||
#line 42 "sample/undocked/inner_map.c"
|
||||
if (r0 == IMMEDIATE(0))
|
||||
#line 42 "sample/undocked/inner_map.c"
|
||||
goto label_1;
|
||||
// EBPF_OP_STXW pc=9 dst=r10 src=r7 offset=-8 imm=0
|
||||
#line 43 "sample/undocked/inner_map.c"
|
||||
*(uint32_t*)(uintptr_t)(r10 + OFFSET(-8)) = (uint32_t)r7;
|
||||
// EBPF_OP_MOV64_REG pc=10 dst=r2 src=r10 offset=0 imm=0
|
||||
#line 43 "sample/undocked/inner_map.c"
|
||||
r2 = r10;
|
||||
// EBPF_OP_ADD64_IMM pc=11 dst=r2 src=r0 offset=0 imm=-8
|
||||
#line 43 "sample/undocked/inner_map.c"
|
||||
r2 += IMMEDIATE(-8);
|
||||
// EBPF_OP_MOV64_REG pc=12 dst=r1 src=r0 offset=0 imm=0
|
||||
#line 44 "sample/undocked/inner_map.c"
|
||||
r1 = r0;
|
||||
// EBPF_OP_CALL pc=13 dst=r0 src=r0 offset=0 imm=1
|
||||
#line 44 "sample/undocked/inner_map.c"
|
||||
r0 = lookup_update_helpers[0].address
|
||||
#line 44 "sample/undocked/inner_map.c"
|
||||
(r1, r2, r3, r4, r5);
|
||||
#line 44 "sample/undocked/inner_map.c"
|
||||
if ((lookup_update_helpers[0].tail_call) && (r0 == 0))
|
||||
#line 44 "sample/undocked/inner_map.c"
|
||||
return 0;
|
||||
// EBPF_OP_JEQ_IMM pc=14 dst=r0 src=r0 offset=3 imm=0
|
||||
#line 45 "sample/undocked/inner_map.c"
|
||||
if (r0 == IMMEDIATE(0))
|
||||
#line 45 "sample/undocked/inner_map.c"
|
||||
goto label_1;
|
||||
// EBPF_OP_MOV64_IMM pc=15 dst=r1 src=r0 offset=0 imm=1
|
||||
#line 45 "sample/undocked/inner_map.c"
|
||||
r1 = IMMEDIATE(1);
|
||||
// EBPF_OP_STXW pc=16 dst=r0 src=r1 offset=0 imm=0
|
||||
#line 47 "sample/undocked/inner_map.c"
|
||||
*(uint32_t*)(uintptr_t)(r0 + OFFSET(0)) = (uint32_t)r1;
|
||||
// EBPF_OP_MOV64_IMM pc=17 dst=r6 src=r0 offset=0 imm=0
|
||||
#line 47 "sample/undocked/inner_map.c"
|
||||
r6 = IMMEDIATE(0);
|
||||
label_1:
|
||||
// EBPF_OP_MOV64_REG pc=18 dst=r0 src=r6 offset=0 imm=0
|
||||
#line 52 "sample/undocked/inner_map.c"
|
||||
r0 = r6;
|
||||
// EBPF_OP_EXIT pc=19 dst=r0 src=r0 offset=0 imm=0
|
||||
#line 52 "sample/undocked/inner_map.c"
|
||||
return r0;
|
||||
#line 52 "sample/undocked/inner_map.c"
|
||||
}
|
||||
#pragma code_seg(pop)
|
||||
#line __LINE__ __FILE__
|
||||
|
||||
#pragma data_seg(push, "programs")
|
||||
static program_entry_t _programs[] = {
|
||||
{
|
||||
0,
|
||||
lookup_update,
|
||||
"sample~1",
|
||||
"sample_ext",
|
||||
"lookup_update",
|
||||
lookup_update_maps,
|
||||
1,
|
||||
lookup_update_helpers,
|
||||
1,
|
||||
20,
|
||||
&lookup_update_program_type_guid,
|
||||
&lookup_update_attach_type_guid,
|
||||
},
|
||||
};
|
||||
#pragma data_seg(pop)
|
||||
|
||||
static void
|
||||
_get_programs(_Outptr_result_buffer_(*count) program_entry_t** programs, _Out_ size_t* count)
|
||||
{
|
||||
*programs = _programs;
|
||||
*count = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
_get_version(_Out_ bpf2c_version_t* version)
|
||||
{
|
||||
version->major = 0;
|
||||
version->minor = 13;
|
||||
version->revision = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
_get_map_initial_values(_Outptr_result_buffer_(*count) map_initial_values_t** map_initial_values, _Out_ size_t* count)
|
||||
{
|
||||
*map_initial_values = NULL;
|
||||
*count = 0;
|
||||
}
|
||||
|
||||
metadata_table_t inner_map_metadata_table = {
|
||||
sizeof(metadata_table_t), _get_programs, _get_maps, _get_hash, _get_version, _get_map_initial_values};
|
|
@ -0,0 +1,52 @@
|
|||
// Copyright (c) Microsoft Corporation
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
// clang -O2 -Werror -c inner_map.c -o inner_map.o
|
||||
//
|
||||
// For bpf code: clang -target bpf -O2 -Werror -c inner_map.c -o inner_map.o
|
||||
// this passes the checker
|
||||
|
||||
// Whenever this sample program changes, bpf2c_tests will fail unless the
|
||||
// expected files in tests\bpf2c_tests\expected are updated. The following
|
||||
// script can be used to regenerate the expected files:
|
||||
// generate_expected_bpf2c_output.ps1
|
||||
//
|
||||
// Usage:
|
||||
// .\scripts\generate_expected_bpf2c_output.ps1 <build_output_path>
|
||||
// Example:
|
||||
// .\scripts\generate_expected_bpf2c_output.ps1 .\x64\Debug\
|
||||
|
||||
#include "bpf_helpers.h"
|
||||
#include "sample_ext_helpers.h"
|
||||
|
||||
struct
|
||||
{
|
||||
__uint(type, BPF_MAP_TYPE_HASH_OF_MAPS);
|
||||
__type(key, uint32_t);
|
||||
__uint(max_entries, 1);
|
||||
__array(
|
||||
values, struct {
|
||||
__uint(type, BPF_MAP_TYPE_ARRAY);
|
||||
__type(key, uint32_t);
|
||||
__type(value, uint32_t);
|
||||
__uint(max_entries, 1);
|
||||
});
|
||||
} outer_map SEC(".maps");
|
||||
|
||||
SEC("sample_ext") int lookup_update(sample_program_context_t* ctx)
|
||||
{
|
||||
uint32_t outer_key = 0;
|
||||
|
||||
// Read value from inner map.
|
||||
void* inner_map = bpf_map_lookup_elem(&outer_map, &outer_key);
|
||||
if (inner_map) {
|
||||
uint32_t inner_key = 0;
|
||||
uint32_t* inner_value = (uint32_t*)bpf_map_lookup_elem(inner_map, &inner_key);
|
||||
if (inner_value) {
|
||||
// Update value in inner map.
|
||||
*inner_value = 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
|
@ -1497,6 +1497,30 @@ _test_bind_fd_to_prog_array(ebpf_execution_type_t execution_type)
|
|||
|
||||
DECLARE_ALL_TEST_CASES("disallow setting bind fd in sample prog array", "[libbpf]", _test_bind_fd_to_prog_array);
|
||||
|
||||
static void
|
||||
_load_inner_map(ebpf_execution_type_t execution_type)
|
||||
{
|
||||
_test_helper_end_to_end test_helper;
|
||||
test_helper.initialize();
|
||||
program_info_provider_t sample_program_info;
|
||||
REQUIRE(sample_program_info.initialize(EBPF_PROGRAM_TYPE_SAMPLE) == EBPF_SUCCESS);
|
||||
|
||||
const char* file_name = (execution_type == EBPF_EXECUTION_NATIVE ? "inner_map_um.dll" : "inner_map.o");
|
||||
struct bpf_object* sample_object = bpf_object__open(file_name);
|
||||
REQUIRE(sample_object != nullptr);
|
||||
|
||||
// Load the program(s).
|
||||
REQUIRE(bpf_object__load(sample_object) == 0);
|
||||
|
||||
struct bpf_map* map = bpf_object__find_map_by_name(sample_object, "outer_map");
|
||||
REQUIRE(map != nullptr);
|
||||
REQUIRE(bpf_map__type(map) == BPF_MAP_TYPE_HASH_OF_MAPS);
|
||||
|
||||
bpf_object__close(sample_object);
|
||||
}
|
||||
|
||||
DECLARE_ALL_TEST_CASES("Test loading BPF program with anonymous inner map", "[libbpf]", _load_inner_map);
|
||||
|
||||
#if !defined(CONFIG_BPF_JIT_DISABLED)
|
||||
TEST_CASE("disallow prog_array mixed program type values", "[libbpf]")
|
||||
{
|
||||
|
|
|
@ -452,7 +452,11 @@ bpf_code_generator::parse_btf_maps_section(const unsafe_string& name)
|
|||
|
||||
auto map_data = libbtf::parse_btf_map_section(btf_data.value());
|
||||
std::map<std::string, size_t> map_offsets;
|
||||
size_t anonymous_map_count = 0;
|
||||
for (auto& map : map_data) {
|
||||
if (map.name.empty()) {
|
||||
map.name = "__anonymous_" + std::to_string(++anonymous_map_count);
|
||||
}
|
||||
map_offsets.insert({map.name, map_descriptors.size()});
|
||||
map_descriptors.push_back({
|
||||
.original_fd = static_cast<int>(map.type_id),
|
||||
|
@ -486,6 +490,16 @@ bpf_code_generator::parse_btf_maps_section(const unsafe_string& name)
|
|||
},
|
||||
name);
|
||||
|
||||
// Add anonymous maps to the end of the map list.
|
||||
size_t last_map_offset = map_names_by_offset.size() != 0 ? map_names_by_offset.rbegin()->first.second : 1;
|
||||
for (auto& map : map_data) {
|
||||
if (!map.name.starts_with("__anonymous")) {
|
||||
continue;
|
||||
}
|
||||
map_names_by_offset[std::make_pair(last_map_offset, last_map_offset)] = map.name;
|
||||
last_map_offset++;
|
||||
}
|
||||
|
||||
for (const auto& [range, unsafe_symbol_name] : map_names_by_offset) {
|
||||
if (map_name_to_index.find(unsafe_symbol_name.raw()) == map_name_to_index.end()) {
|
||||
throw bpf_code_generator_exception("map symbol not found in map section");
|
||||
|
|
Загрузка…
Ссылка в новой задаче