Skip to content

Commit

Permalink
Add support for statically initializing BPF_MAP_TYPE_HASH_OF_MAPS (mi…
Browse files Browse the repository at this point in the history
…crosoft#3211)

* Add support for statically initializing BPF_MAP_TYPE_HASH_OF_MAPS

Signed-off-by: Alan Jowett <[email protected]>

* Update installer and add code gen tests

Signed-off-by: Alan Jowett <[email protected]>

* Add files to expected install list

Signed-off-by: Alan Jowett <[email protected]>

---------

Signed-off-by: Alan Jowett <[email protected]>
Co-authored-by: Alan Jowett <[email protected]>
  • Loading branch information
Alan-Jowett and Alan Jowett authored Jan 31, 2024
1 parent ddd1a00 commit bf2a7c3
Show file tree
Hide file tree
Showing 10 changed files with 994 additions and 1 deletion.
12 changes: 12 additions & 0 deletions installer/Product.wxs
Original file line number Diff line number Diff line change
Expand Up @@ -826,6 +826,18 @@ SPDX-License-Identifier: MIT
<File Id="INVALID_HELPERS_UM.PDB" Name="invalid_helpers_um.pdb" Source="$(var.SolutionDir)$(var.Platform)\$(var.Configuration)\invalid_helpers_um.pdb" />
</Component>
<?endif?>
<Component Id="HAS_OF_MAP.O" DiskId="1" Guid="{c363ade6-46ef-48e7-8f8b-71c90896e0b3}">
<File Id="HAS_OF_MAP.O" Name="hash_of_map.o" Source="$(var.SolutionDir)$(var.Platform)\$(var.Configuration)\hash_of_map.o" />
</Component>
<Component Id="HAS_OF_MAP.SYS" DiskId="1" Guid="{37a23ba5-313e-42e0-9328-ff2cc9c72745}">
<File Id="HAS_OF_MAP.SYS" Name="hash_of_map.sys" Source="$(var.SolutionDir)$(var.Platform)\$(var.Configuration)\hash_of_map.sys" />
</Component>
<Component Id="HAS_OF_MAP_UM.DLL" DiskId="1" Guid="{8c9ad5ef-7507-452d-a3f5-25e3d8cd0baf}">
<File Id="HAS_OF_MAP_UM.DLL" Name="hash_of_map_um.dll" Source="$(var.SolutionDir)$(var.Platform)\$(var.Configuration)\hash_of_map_um.dll" />
</Component>
<Component Id="HAS_OF_MAP_UM.PDB" DiskId="1" Guid="{1ba1063b-438e-4ce6-b1a5-c049c702265d}">
<File Id="HAS_OF_MAP_UM.PDB" Name="hash_of_map_um.pdb" Source="$(var.SolutionDir)$(var.Platform)\$(var.Configuration)\hash_of_map_um.pdb" />
</Component>
<Component Id="MAP.O" DiskId="1" Guid="{C0461A4A-1195-4965-9710-8EED78A271F6}">
<File Id="MAP.O" Name="map.o" Source="$(var.SolutionDir)$(var.Platform)\$(var.Configuration)\map.o" />
</Component>
Expand Down
2 changes: 1 addition & 1 deletion libs/execution_context/ebpf_native.c
Original file line number Diff line number Diff line change
Expand Up @@ -923,7 +923,7 @@ _ebpf_native_set_initial_map_values(_Inout_ ebpf_native_module_t* module)

ebpf_handle_t handle_to_insert = ebpf_handle_invalid;

if (native_map_to_update->entry->definition.type == BPF_MAP_TYPE_ARRAY_OF_MAPS) {
if (_ebpf_native_is_map_in_map(native_map_to_update)) {
ebpf_native_map_t* native_map_to_insert =
_ebpf_native_find_map_by_name(module, map_initial_values[i].values[j]);
if (native_map_to_update == NULL) {
Expand Down
4 changes: 4 additions & 0 deletions scripts/check_msi_installation_files_regular_debug.txt
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,10 @@ C:\Program Files\ebpf-for-windows\testing\empty_um.dll
C:\Program Files\ebpf-for-windows\testing\empty_um.pdb
C:\Program Files\ebpf-for-windows\testing\encap_reflect_packet.o
C:\Program Files\ebpf-for-windows\testing\encap_reflect_packet.sys
C:\Program Files\ebpf-for-windows\testing\hash_of_map_um.dll
C:\Program Files\ebpf-for-windows\testing\hash_of_map_um.pdb
C:\Program Files\ebpf-for-windows\testing\hash_of_map.o
C:\Program Files\ebpf-for-windows\testing\hash_of_map.sys
C:\Program Files\ebpf-for-windows\testing\invalid_helpers_um.dll
C:\Program Files\ebpf-for-windows\testing\invalid_helpers_um.pdb
C:\Program Files\ebpf-for-windows\testing\invalid_maps1_um.dll
Expand Down
1 change: 1 addition & 0 deletions tests/bpf2c_tests/elf_bpf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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("hash_of_map", _test_mode::Verify)
DECLARE_TEST("inner_map", _test_mode::Verify)
DECLARE_TEST("invalid_helpers", _test_mode::NoVerify);
DECLARE_TEST("invalid_maps1", _test_mode::NoVerify);
Expand Down
251 changes: 251 additions & 0 deletions tests/bpf2c_tests/expected/hash_of_map_dll.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
// Copyright (c) Microsoft Corporation
// SPDX-License-Identifier: MIT

// Do not alter this generated file.
// This file was generated from hash_of_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 hash_of_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, // 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.
8, // Identifier for a map template.
0, // The id of the inner map template.
},
"inner_map"},
{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.
14, // Identifier for a map template.
8, // The id of the inner map template.
},
"outer_map"},
};
#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_helpers[] = {
{NULL, 1, "helper_id_1"},
};

static GUID lookup_program_type_guid = {0xf788ef4a, 0x207d, 0x4dc3, {0x85, 0xcf, 0x0f, 0x2e, 0xa1, 0x07, 0x21, 0x3c}};
static GUID lookup_attach_type_guid = {0xf788ef4b, 0x207d, 0x4dc3, {0x85, 0xcf, 0x0f, 0x2e, 0xa1, 0x07, 0x21, 0x3c}};
static uint16_t lookup_maps[] = {
1,
};

#pragma code_seg(push, "sample~1")
static uint64_t
lookup(void* context)
#line 36 "sample/undocked/hash_of_map.c"
{
#line 36 "sample/undocked/hash_of_map.c"
// Prologue
#line 36 "sample/undocked/hash_of_map.c"
uint64_t stack[(UBPF_STACK_SIZE + 7) / 8];
#line 36 "sample/undocked/hash_of_map.c"
register uint64_t r0 = 0;
#line 36 "sample/undocked/hash_of_map.c"
register uint64_t r1 = 0;
#line 36 "sample/undocked/hash_of_map.c"
register uint64_t r2 = 0;
#line 36 "sample/undocked/hash_of_map.c"
register uint64_t r3 = 0;
#line 36 "sample/undocked/hash_of_map.c"
register uint64_t r4 = 0;
#line 36 "sample/undocked/hash_of_map.c"
register uint64_t r5 = 0;
#line 36 "sample/undocked/hash_of_map.c"
register uint64_t r6 = 0;
#line 36 "sample/undocked/hash_of_map.c"
register uint64_t r10 = 0;

#line 36 "sample/undocked/hash_of_map.c"
r1 = (uintptr_t)context;
#line 36 "sample/undocked/hash_of_map.c"
r10 = (uintptr_t)((uint8_t*)stack + sizeof(stack));

// EBPF_OP_MOV64_IMM pc=0 dst=r6 src=r0 offset=0 imm=0
#line 36 "sample/undocked/hash_of_map.c"
r6 = IMMEDIATE(0);
// EBPF_OP_STXW pc=1 dst=r10 src=r6 offset=-4 imm=0
#line 38 "sample/undocked/hash_of_map.c"
*(uint32_t*)(uintptr_t)(r10 + OFFSET(-4)) = (uint32_t)r6;
// EBPF_OP_MOV64_REG pc=2 dst=r2 src=r10 offset=0 imm=0
#line 38 "sample/undocked/hash_of_map.c"
r2 = r10;
// EBPF_OP_ADD64_IMM pc=3 dst=r2 src=r0 offset=0 imm=-4
#line 38 "sample/undocked/hash_of_map.c"
r2 += IMMEDIATE(-4);
// EBPF_OP_LDDW pc=4 dst=r1 src=r0 offset=0 imm=0
#line 39 "sample/undocked/hash_of_map.c"
r1 = POINTER(_maps[1].address);
// EBPF_OP_CALL pc=6 dst=r0 src=r0 offset=0 imm=1
#line 39 "sample/undocked/hash_of_map.c"
r0 = lookup_helpers[0].address
#line 39 "sample/undocked/hash_of_map.c"
(r1, r2, r3, r4, r5);
#line 39 "sample/undocked/hash_of_map.c"
if ((lookup_helpers[0].tail_call) && (r0 == 0))
#line 39 "sample/undocked/hash_of_map.c"
return 0;
// EBPF_OP_JEQ_IMM pc=7 dst=r0 src=r0 offset=9 imm=0
#line 40 "sample/undocked/hash_of_map.c"
if (r0 == IMMEDIATE(0))
#line 40 "sample/undocked/hash_of_map.c"
goto label_2;
// EBPF_OP_MOV64_IMM pc=8 dst=r6 src=r0 offset=0 imm=0
#line 40 "sample/undocked/hash_of_map.c"
r6 = IMMEDIATE(0);
// EBPF_OP_STXW pc=9 dst=r10 src=r6 offset=-8 imm=0
#line 41 "sample/undocked/hash_of_map.c"
*(uint32_t*)(uintptr_t)(r10 + OFFSET(-8)) = (uint32_t)r6;
// EBPF_OP_MOV64_REG pc=10 dst=r2 src=r10 offset=0 imm=0
#line 41 "sample/undocked/hash_of_map.c"
r2 = r10;
// EBPF_OP_ADD64_IMM pc=11 dst=r2 src=r0 offset=0 imm=-8
#line 41 "sample/undocked/hash_of_map.c"
r2 += IMMEDIATE(-8);
// EBPF_OP_MOV64_REG pc=12 dst=r1 src=r0 offset=0 imm=0
#line 42 "sample/undocked/hash_of_map.c"
r1 = r0;
// EBPF_OP_CALL pc=13 dst=r0 src=r0 offset=0 imm=1
#line 42 "sample/undocked/hash_of_map.c"
r0 = lookup_helpers[0].address
#line 42 "sample/undocked/hash_of_map.c"
(r1, r2, r3, r4, r5);
#line 42 "sample/undocked/hash_of_map.c"
if ((lookup_helpers[0].tail_call) && (r0 == 0))
#line 42 "sample/undocked/hash_of_map.c"
return 0;
// EBPF_OP_JNE_IMM pc=14 dst=r0 src=r0 offset=1 imm=0
#line 43 "sample/undocked/hash_of_map.c"
if (r0 != IMMEDIATE(0))
#line 43 "sample/undocked/hash_of_map.c"
goto label_1;
// EBPF_OP_JA pc=15 dst=r0 src=r0 offset=1 imm=0
#line 43 "sample/undocked/hash_of_map.c"
goto label_2;
label_1:
// EBPF_OP_LDXW pc=16 dst=r6 src=r0 offset=0 imm=0
#line 44 "sample/undocked/hash_of_map.c"
r6 = *(uint32_t*)(uintptr_t)(r0 + OFFSET(0));
label_2:
// EBPF_OP_MOV64_REG pc=17 dst=r0 src=r6 offset=0 imm=0
#line 48 "sample/undocked/hash_of_map.c"
r0 = r6;
// EBPF_OP_EXIT pc=18 dst=r0 src=r0 offset=0 imm=0
#line 48 "sample/undocked/hash_of_map.c"
return r0;
#line 48 "sample/undocked/hash_of_map.c"
}
#pragma code_seg(pop)
#line __LINE__ __FILE__

#pragma data_seg(push, "programs")
static program_entry_t _programs[] = {
{
0,
lookup,
"sample~1",
"sample_ext",
"lookup",
lookup_maps,
1,
lookup_helpers,
1,
19,
&lookup_program_type_guid,
&lookup_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;
}

#pragma data_seg(push, "map_initial_values")
static const char* _outer_map_initial_string_table[] = {
"inner_map",
};

static map_initial_values_t _map_initial_values_array[] = {
{
.name = "outer_map",
.count = 1,
.values = _outer_map_initial_string_table,
},
};
#pragma data_seg(pop)

static void
_get_map_initial_values(_Outptr_result_buffer_(*count) map_initial_values_t** map_initial_values, _Out_ size_t* count)
{
*map_initial_values = _map_initial_values_array;
*count = 1;
}

metadata_table_t hash_of_map_metadata_table = {
sizeof(metadata_table_t), _get_programs, _get_maps, _get_hash, _get_version, _get_map_initial_values};
Loading

0 comments on commit bf2a7c3

Please sign in to comment.