Explicit key and value lengths passed to map layer (#380)
* Explicit key and value lengths passed to map layer Signed-off-by: Alan Jowett <alanjo@microsoft.com>
This commit is contained in:
Родитель
8cc5a7f5be
Коммит
e68dece71d
|
@ -125,7 +125,7 @@ ebpf_api_create_map(
|
|||
UNREFERENCED_PARAMETER(map_flags);
|
||||
|
||||
_ebpf_operation_create_map_request request{
|
||||
sizeof(_ebpf_operation_create_map_request),
|
||||
EBPF_OFFSET_OF(ebpf_operation_create_map_request_t, data),
|
||||
ebpf_operation_id_t::EBPF_OPERATION_CREATE_MAP,
|
||||
{sizeof(struct _ebpf_map_definition), type, key_size, value_size, max_entries}};
|
||||
|
||||
|
@ -171,9 +171,6 @@ _create_map(
|
|||
map_name_size = map_name.size();
|
||||
|
||||
size_t buffer_size = offsetof(ebpf_operation_create_map_request_t, data) + map_name_size;
|
||||
if (buffer_size < sizeof(ebpf_operation_create_map_request_t)) {
|
||||
buffer_size = sizeof(ebpf_operation_create_map_request_t);
|
||||
}
|
||||
request_buffer.resize(buffer_size);
|
||||
|
||||
request = reinterpret_cast<ebpf_operation_create_map_request_t*>(request_buffer.data());
|
||||
|
@ -273,10 +270,12 @@ _map_lookup_element(
|
|||
{
|
||||
ebpf_result_t result = EBPF_SUCCESS;
|
||||
try {
|
||||
ebpf_protocol_buffer_t request_buffer(sizeof(_ebpf_operation_map_find_element_request) + key_size - 1);
|
||||
ebpf_protocol_buffer_t reply_buffer(sizeof(_ebpf_operation_map_find_element_reply) + value_size - 1);
|
||||
auto request = reinterpret_cast<_ebpf_operation_map_find_element_request*>(request_buffer.data());
|
||||
auto reply = reinterpret_cast<_ebpf_operation_map_find_element_reply*>(reply_buffer.data());
|
||||
ebpf_protocol_buffer_t request_buffer(
|
||||
EBPF_OFFSET_OF(ebpf_operation_map_find_element_request_t, key) + key_size);
|
||||
ebpf_protocol_buffer_t reply_buffer(
|
||||
EBPF_OFFSET_OF(ebpf_operation_map_find_element_reply_t, value) + value_size);
|
||||
auto request = reinterpret_cast<ebpf_operation_map_find_element_request_t*>(request_buffer.data());
|
||||
auto reply = reinterpret_cast<ebpf_operation_map_find_element_reply_t*>(reply_buffer.data());
|
||||
|
||||
request->header.length = static_cast<uint16_t>(request_buffer.size());
|
||||
request->header.id = ebpf_operation_id_t::EBPF_OPERATION_MAP_FIND_ELEMENT;
|
||||
|
@ -385,7 +384,7 @@ _update_map_element(
|
|||
epf_operation_map_update_element_request_t* request;
|
||||
|
||||
try {
|
||||
request_buffer.resize(sizeof(_ebpf_operation_map_update_element_request) - 1 + key_size + value_size);
|
||||
request_buffer.resize(EBPF_OFFSET_OF(epf_operation_map_update_element_request_t, data) + key_size + value_size);
|
||||
request = reinterpret_cast<_ebpf_operation_map_update_element_request*>(request_buffer.data());
|
||||
|
||||
request->header.length = static_cast<uint16_t>(request_buffer.size());
|
||||
|
@ -418,8 +417,8 @@ _update_map_element_with_handle(
|
|||
ebpf_handle_t value_handle) noexcept
|
||||
{
|
||||
ebpf_protocol_buffer_t request_buffer(
|
||||
sizeof(_ebpf_operation_map_update_element_with_handle_request) - 1 + key_size + value_size);
|
||||
auto request = reinterpret_cast<_ebpf_operation_map_update_element_with_handle_request*>(request_buffer.data());
|
||||
EBPF_OFFSET_OF(ebpf_operation_map_update_element_with_handle_request_t, data) + key_size + value_size);
|
||||
auto request = reinterpret_cast<ebpf_operation_map_update_element_with_handle_request_t*>(request_buffer.data());
|
||||
|
||||
request->header.length = static_cast<uint16_t>(request_buffer.size());
|
||||
request->header.id = ebpf_operation_id_t::EBPF_OPERATION_MAP_UPDATE_ELEMENT_WITH_HANDLE;
|
||||
|
@ -503,8 +502,8 @@ ebpf_map_delete_element(fd_t map_fd, _In_ const void* key)
|
|||
assert(value_size != 0);
|
||||
|
||||
try {
|
||||
request_buffer.resize(sizeof(_ebpf_operation_map_delete_element_request) - 1 + key_size);
|
||||
request = reinterpret_cast<_ebpf_operation_map_delete_element_request*>(request_buffer.data());
|
||||
request_buffer.resize(EBPF_OFFSET_OF(ebpf_operation_map_delete_element_request_t, key) + key_size);
|
||||
request = reinterpret_cast<ebpf_operation_map_delete_element_request_t*>(request_buffer.data());
|
||||
|
||||
request->header.length = static_cast<uint16_t>(request_buffer.size());
|
||||
request->header.id = ebpf_operation_id_t::EBPF_OPERATION_MAP_DELETE_ELEMENT;
|
||||
|
@ -1022,10 +1021,10 @@ ebpf_get_next_map(fd_t previous_fd, _Out_ fd_t* next_fd)
|
|||
*next_fd = ebpf_fd_invalid;
|
||||
|
||||
ebpf_handle_t previous_handle = _get_handle_from_fd(local_fd);
|
||||
_ebpf_operation_get_next_map_request request{
|
||||
ebpf_operation_get_next_map_request_t request{
|
||||
sizeof(request), ebpf_operation_id_t::EBPF_OPERATION_GET_NEXT_MAP, reinterpret_cast<uint64_t>(previous_handle)};
|
||||
|
||||
_ebpf_operation_get_next_map_reply reply;
|
||||
ebpf_operation_get_next_map_reply_t reply;
|
||||
|
||||
uint32_t retval = invoke_ioctl(request, reply);
|
||||
if (retval == ERROR_SUCCESS) {
|
||||
|
@ -1056,11 +1055,12 @@ ebpf_get_next_program(fd_t previous_fd, _Out_ fd_t* next_fd)
|
|||
*next_fd = ebpf_fd_invalid;
|
||||
|
||||
ebpf_handle_t previous_handle = _get_handle_from_fd(local_fd);
|
||||
_ebpf_operation_get_next_program_request request{sizeof(request),
|
||||
ebpf_operation_id_t::EBPF_OPERATION_GET_NEXT_PROGRAM,
|
||||
reinterpret_cast<uint64_t>(previous_handle)};
|
||||
ebpf_operation_get_next_program_request_t request{
|
||||
sizeof(request),
|
||||
ebpf_operation_id_t::EBPF_OPERATION_GET_NEXT_PROGRAM,
|
||||
reinterpret_cast<uint64_t>(previous_handle)};
|
||||
|
||||
_ebpf_operation_get_next_program_reply reply;
|
||||
ebpf_operation_get_next_program_reply_t reply;
|
||||
|
||||
uint32_t retval = invoke_ioctl(request, reply);
|
||||
if (retval == ERROR_SUCCESS) {
|
||||
|
@ -1115,10 +1115,10 @@ ebpf_program_query_info(
|
|||
}
|
||||
|
||||
ebpf_protocol_buffer_t reply_buffer(1024);
|
||||
_ebpf_operation_query_program_info_request request{
|
||||
ebpf_operation_query_program_info_request_t request{
|
||||
sizeof(request), ebpf_operation_id_t::EBPF_OPERATION_QUERY_PROGRAM_INFO, reinterpret_cast<uint64_t>(handle)};
|
||||
|
||||
auto reply = reinterpret_cast<_ebpf_operation_query_program_info_reply*>(reply_buffer.data());
|
||||
auto reply = reinterpret_cast<ebpf_operation_query_program_info_reply_t*>(reply_buffer.data());
|
||||
|
||||
uint32_t retval = invoke_ioctl(request, reply_buffer);
|
||||
if (retval != ERROR_SUCCESS) {
|
||||
|
@ -1155,7 +1155,10 @@ uint32_t
|
|||
ebpf_api_link_program(ebpf_handle_t program_handle, ebpf_attach_type_t attach_type, ebpf_handle_t* link_handle)
|
||||
{
|
||||
ebpf_operation_link_program_request_t request = {
|
||||
sizeof(request), EBPF_OPERATION_LINK_PROGRAM, reinterpret_cast<uint64_t>(program_handle), attach_type};
|
||||
EBPF_OFFSET_OF(ebpf_operation_link_program_request_t, data),
|
||||
EBPF_OPERATION_LINK_PROGRAM,
|
||||
reinterpret_cast<uint64_t>(program_handle),
|
||||
attach_type};
|
||||
ebpf_operation_link_program_reply_t reply;
|
||||
|
||||
uint32_t retval = invoke_ioctl(request, reply);
|
||||
|
@ -1187,9 +1190,6 @@ _link_ebpf_program(
|
|||
|
||||
try {
|
||||
size_t buffer_size = offsetof(ebpf_operation_link_program_request_t, data) + attach_parameter_size;
|
||||
if (buffer_size < sizeof(ebpf_operation_link_program_request_t)) {
|
||||
buffer_size = sizeof(ebpf_operation_link_program_request_t);
|
||||
}
|
||||
request_buffer.resize(buffer_size);
|
||||
request = reinterpret_cast<ebpf_operation_link_program_request_t*>(request_buffer.data());
|
||||
request->header.id = EBPF_OPERATION_LINK_PROGRAM;
|
||||
|
|
|
@ -52,21 +52,23 @@ static ebpf_helper_function_prototype_t _ebpf_map_helper_function_prototype[] =
|
|||
{EBPF_ARGUMENT_TYPE_PTR_TO_CTX, EBPF_ARGUMENT_TYPE_PTR_TO_MAP_OF_PROGRAMS, EBPF_ARGUMENT_TYPE_ANYTHING}},
|
||||
};
|
||||
|
||||
static ebpf_program_info_t _ebpf_global_helper_program_info = {{"global_helper", NULL, {0}},
|
||||
EBPF_COUNT_OF(_ebpf_map_helper_function_prototype),
|
||||
_ebpf_map_helper_function_prototype};
|
||||
static ebpf_program_info_t _ebpf_global_helper_program_info = {
|
||||
{"global_helper", NULL, {0}},
|
||||
EBPF_COUNT_OF(_ebpf_map_helper_function_prototype),
|
||||
_ebpf_map_helper_function_prototype};
|
||||
|
||||
static const void* _ebpf_general_helpers[] = {NULL,
|
||||
(void*)&_ebpf_core_map_find_element,
|
||||
(void*)&_ebpf_core_map_update_element,
|
||||
(void*)&_ebpf_core_map_delete_element,
|
||||
(void*)&_ebpf_core_tail_call};
|
||||
static const void* _ebpf_general_helpers[] = {
|
||||
NULL,
|
||||
(void*)&_ebpf_core_map_find_element,
|
||||
(void*)&_ebpf_core_map_update_element,
|
||||
(void*)&_ebpf_core_map_delete_element,
|
||||
(void*)&_ebpf_core_tail_call};
|
||||
|
||||
static ebpf_extension_provider_t* _ebpf_global_helper_function_provider_context = NULL;
|
||||
static ebpf_helper_function_addresses_t _ebpf_global_helper_function_dispatch_table = {
|
||||
EBPF_COUNT_OF(_ebpf_general_helpers), (uint64_t*)_ebpf_general_helpers};
|
||||
static ebpf_program_data_t _ebpf_global_helper_function_program_data = {&_ebpf_global_helper_program_info,
|
||||
&_ebpf_global_helper_function_dispatch_table};
|
||||
static ebpf_program_data_t _ebpf_global_helper_function_program_data = {
|
||||
&_ebpf_global_helper_program_info, &_ebpf_global_helper_function_dispatch_table};
|
||||
|
||||
static ebpf_extension_data_t _ebpf_global_helper_function_extension_data = {
|
||||
EBPF_CORE_GLOBAL_HELPER_EXTENSION_VERSION,
|
||||
|
@ -373,33 +375,29 @@ _ebpf_core_protocol_map_find_element(
|
|||
{
|
||||
ebpf_result_t retval;
|
||||
ebpf_map_t* map = NULL;
|
||||
uint8_t* value = NULL;
|
||||
size_t value_length;
|
||||
size_t key_length;
|
||||
|
||||
retval = ebpf_reference_object_by_handle(request->handle, EBPF_OBJECT_MAP, (ebpf_object_t**)&map);
|
||||
if (retval != EBPF_SUCCESS)
|
||||
goto Done;
|
||||
|
||||
const ebpf_map_definition_t* map_definition = ebpf_map_get_definition(map);
|
||||
|
||||
if (request->header.length <
|
||||
(EBPF_OFFSET_OF(ebpf_operation_map_find_element_request_t, key) + map_definition->key_size)) {
|
||||
retval = EBPF_INVALID_ARGUMENT;
|
||||
retval = ebpf_safe_size_t_subtract(
|
||||
request->header.length, EBPF_OFFSET_OF(ebpf_operation_map_find_element_request_t, key), &key_length);
|
||||
if (retval != EBPF_SUCCESS)
|
||||
goto Done;
|
||||
}
|
||||
|
||||
if (reply_length < (EBPF_OFFSET_OF(ebpf_operation_map_find_element_reply_t, value) + map_definition->value_size)) {
|
||||
retval = EBPF_INVALID_ARGUMENT;
|
||||
retval = ebpf_safe_size_t_subtract(
|
||||
reply_length, EBPF_OFFSET_OF(ebpf_operation_map_find_element_reply_t, value), &value_length);
|
||||
if (retval != EBPF_SUCCESS)
|
||||
goto Done;
|
||||
}
|
||||
|
||||
value = ebpf_map_find_entry(map, request->key, 0);
|
||||
if (value == NULL) {
|
||||
retval = EBPF_KEY_NOT_FOUND;
|
||||
retval = ebpf_map_find_entry(map, key_length, request->key, value_length, reply->value, 0);
|
||||
if (retval != EBPF_SUCCESS)
|
||||
goto Done;
|
||||
}
|
||||
|
||||
memcpy(reply->value, value, map_definition->value_size);
|
||||
retval = EBPF_SUCCESS;
|
||||
reply->header.length = reply_length;
|
||||
|
||||
Done:
|
||||
ebpf_object_release_reference((ebpf_object_t*)map);
|
||||
|
@ -411,6 +409,8 @@ _ebpf_core_protocol_map_update_element(_In_ const epf_operation_map_update_eleme
|
|||
{
|
||||
ebpf_result_t retval;
|
||||
ebpf_map_t* map = NULL;
|
||||
size_t value_length;
|
||||
size_t key_length;
|
||||
|
||||
retval = ebpf_reference_object_by_handle(request->handle, EBPF_OBJECT_MAP, (ebpf_object_t**)&map);
|
||||
if (retval != EBPF_SUCCESS)
|
||||
|
@ -418,13 +418,18 @@ _ebpf_core_protocol_map_update_element(_In_ const epf_operation_map_update_eleme
|
|||
|
||||
const ebpf_map_definition_t* map_definition = ebpf_map_get_definition(map);
|
||||
|
||||
if (request->header.length < (EBPF_OFFSET_OF(epf_operation_map_update_element_request_t, data) +
|
||||
map_definition->key_size + map_definition->value_size)) {
|
||||
retval = EBPF_INVALID_ARGUMENT;
|
||||
retval = ebpf_safe_size_t_subtract(
|
||||
request->header.length, EBPF_OFFSET_OF(epf_operation_map_update_element_request_t, data), &value_length);
|
||||
if (retval != EBPF_SUCCESS)
|
||||
goto Done;
|
||||
}
|
||||
|
||||
retval = ebpf_map_update_entry(map, request->data, request->data + map_definition->key_size);
|
||||
retval = ebpf_safe_size_t_subtract(value_length, map_definition->key_size, &value_length);
|
||||
if (retval != EBPF_SUCCESS)
|
||||
goto Done;
|
||||
|
||||
key_length = map_definition->key_size;
|
||||
|
||||
retval = ebpf_map_update_entry(map, key_length, request->data, value_length, request->data + key_length, 0);
|
||||
|
||||
Done:
|
||||
ebpf_object_release_reference((ebpf_object_t*)map);
|
||||
|
@ -433,10 +438,12 @@ Done:
|
|||
|
||||
static ebpf_result_t
|
||||
_ebpf_core_protocol_map_update_element_with_handle(
|
||||
_In_ const epf_operation_map_update_element_with_handle_request_t* request)
|
||||
_In_ const ebpf_operation_map_update_element_with_handle_request_t* request)
|
||||
{
|
||||
ebpf_result_t retval;
|
||||
ebpf_map_t* map = NULL;
|
||||
size_t value_length;
|
||||
size_t key_length;
|
||||
|
||||
retval = ebpf_reference_object_by_handle(request->map_handle, EBPF_OBJECT_MAP, (ebpf_object_t**)&map);
|
||||
if (retval != EBPF_SUCCESS)
|
||||
|
@ -444,14 +451,21 @@ _ebpf_core_protocol_map_update_element_with_handle(
|
|||
|
||||
const ebpf_map_definition_t* map_definition = ebpf_map_get_definition(map);
|
||||
|
||||
if (request->header.length < (EBPF_OFFSET_OF(epf_operation_map_update_element_with_handle_request_t, data) +
|
||||
map_definition->key_size + map_definition->value_size)) {
|
||||
retval = EBPF_INVALID_ARGUMENT;
|
||||
retval = ebpf_safe_size_t_subtract(
|
||||
request->header.length,
|
||||
EBPF_OFFSET_OF(ebpf_operation_map_update_element_with_handle_request_t, data),
|
||||
&value_length);
|
||||
if (retval != EBPF_SUCCESS)
|
||||
goto Done;
|
||||
}
|
||||
|
||||
retval = ebpf_safe_size_t_subtract(value_length, map_definition->key_size, &value_length);
|
||||
if (retval != EBPF_SUCCESS)
|
||||
goto Done;
|
||||
|
||||
key_length = map_definition->key_size;
|
||||
|
||||
retval = ebpf_map_update_entry_with_handle(
|
||||
map, request->data, request->data + map_definition->key_size, request->value_handle);
|
||||
map, key_length, request->data, value_length, request->data + map_definition->key_size, request->value_handle);
|
||||
|
||||
Done:
|
||||
ebpf_object_release_reference((ebpf_object_t*)map);
|
||||
|
@ -463,20 +477,18 @@ _ebpf_core_protocol_map_delete_element(_In_ const ebpf_operation_map_delete_elem
|
|||
{
|
||||
ebpf_result_t retval;
|
||||
ebpf_map_t* map = NULL;
|
||||
size_t key_length;
|
||||
|
||||
retval = ebpf_reference_object_by_handle(request->handle, EBPF_OBJECT_MAP, (ebpf_object_t**)&map);
|
||||
if (retval != EBPF_SUCCESS)
|
||||
goto Done;
|
||||
|
||||
const ebpf_map_definition_t* map_definition = ebpf_map_get_definition(map);
|
||||
|
||||
if (request->header.length <
|
||||
(EBPF_OFFSET_OF(ebpf_operation_map_delete_element_request_t, key) + map_definition->key_size)) {
|
||||
retval = EBPF_INVALID_ARGUMENT;
|
||||
retval = ebpf_safe_size_t_subtract(
|
||||
request->header.length, EBPF_OFFSET_OF(ebpf_operation_map_delete_element_request_t, key), &key_length);
|
||||
if (retval != EBPF_SUCCESS)
|
||||
goto Done;
|
||||
}
|
||||
|
||||
retval = ebpf_map_delete_entry(map, request->key);
|
||||
retval = ebpf_map_delete_entry(map, key_length, request->key, 0);
|
||||
|
||||
Done:
|
||||
ebpf_object_release_reference((ebpf_object_t*)map);
|
||||
|
@ -491,34 +503,32 @@ _ebpf_core_protocol_map_get_next_key(
|
|||
{
|
||||
ebpf_result_t retval;
|
||||
ebpf_map_t* map = NULL;
|
||||
const uint8_t* previous_key;
|
||||
uint8_t* next_key = NULL;
|
||||
size_t previous_key_length;
|
||||
size_t next_key_length;
|
||||
|
||||
retval = ebpf_reference_object_by_handle(request->handle, EBPF_OBJECT_MAP, (ebpf_object_t**)&map);
|
||||
if (retval != EBPF_SUCCESS)
|
||||
goto Done;
|
||||
|
||||
const ebpf_map_definition_t* map_definition = ebpf_map_get_definition(map);
|
||||
|
||||
// If request length shows zero key, treat as restart.
|
||||
if (request->header.length == EBPF_OFFSET_OF(ebpf_operation_map_get_next_key_request_t, previous_key)) {
|
||||
previous_key = NULL;
|
||||
} else if (
|
||||
request->header.length <
|
||||
(EBPF_OFFSET_OF(ebpf_operation_map_get_next_key_request_t, previous_key) + map_definition->key_size)) {
|
||||
retval = EBPF_INVALID_ARGUMENT;
|
||||
retval = ebpf_safe_size_t_subtract(
|
||||
request->header.length,
|
||||
EBPF_OFFSET_OF(ebpf_operation_map_get_next_key_request_t, previous_key),
|
||||
&previous_key_length);
|
||||
if (retval != EBPF_SUCCESS)
|
||||
goto Done;
|
||||
} else {
|
||||
previous_key = request->previous_key;
|
||||
}
|
||||
|
||||
next_key = reply->next_key;
|
||||
if (reply_length < (EBPF_OFFSET_OF(ebpf_operation_map_get_next_key_reply_t, next_key) + map_definition->key_size)) {
|
||||
retval = ebpf_safe_size_t_subtract(
|
||||
reply_length, EBPF_OFFSET_OF(ebpf_operation_map_get_next_key_reply_t, next_key), &next_key_length);
|
||||
if (retval != EBPF_SUCCESS)
|
||||
goto Done;
|
||||
|
||||
if (previous_key_length != 0 && previous_key_length != next_key_length) {
|
||||
retval = EBPF_INVALID_ARGUMENT;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
retval = ebpf_map_next_key(map, previous_key, next_key);
|
||||
retval = ebpf_map_next_key(
|
||||
map, next_key_length, previous_key_length == 0 ? NULL : request->previous_key, reply->next_key);
|
||||
|
||||
Done:
|
||||
ebpf_object_release_reference((ebpf_object_t*)map);
|
||||
|
@ -651,9 +661,9 @@ static ebpf_result_t
|
|||
_ebpf_core_protocol_update_pinning(_In_ const struct _ebpf_operation_update_map_pinning_request* request)
|
||||
{
|
||||
ebpf_result_t retval;
|
||||
const ebpf_utf8_string_t name = {(uint8_t*)request->name,
|
||||
request->header.length -
|
||||
EBPF_OFFSET_OF(ebpf_operation_update_pinning_request_t, name)};
|
||||
const ebpf_utf8_string_t name = {
|
||||
(uint8_t*)request->name,
|
||||
request->header.length - EBPF_OFFSET_OF(ebpf_operation_update_pinning_request_t, name)};
|
||||
ebpf_object_t* object = NULL;
|
||||
|
||||
if (name.length == 0) {
|
||||
|
@ -952,27 +962,33 @@ Exit:
|
|||
static void*
|
||||
_ebpf_core_map_find_element(ebpf_map_t* map, const uint8_t* key)
|
||||
{
|
||||
return ebpf_map_find_entry(map, key, EBPF_MAP_FIND_ENTRY_FLAG_HELPER);
|
||||
ebpf_result_t retval;
|
||||
uint8_t* value;
|
||||
retval = ebpf_map_find_entry(map, 0, key, sizeof(&value), (uint8_t*)&value, EBPF_MAP_FLAG_HELPER);
|
||||
if (retval != EBPF_SUCCESS)
|
||||
return NULL;
|
||||
else
|
||||
return value;
|
||||
}
|
||||
|
||||
static int64_t
|
||||
_ebpf_core_map_update_element(ebpf_map_t* map, const uint8_t* key, const uint8_t* value, uint64_t flags)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(flags);
|
||||
return -ebpf_map_update_entry(map, key, value);
|
||||
return -ebpf_map_update_entry(map, 0, key, 0, value, EBPF_MAP_FLAG_HELPER);
|
||||
}
|
||||
|
||||
static int64_t
|
||||
_ebpf_core_map_delete_element(ebpf_map_t* map, const uint8_t* key)
|
||||
{
|
||||
return -ebpf_map_delete_entry(map, key);
|
||||
return -ebpf_map_delete_entry(map, 0, key, EBPF_MAP_FLAG_HELPER);
|
||||
}
|
||||
|
||||
static int64_t
|
||||
_ebpf_core_tail_call(void* context, ebpf_map_t* map, uint32_t index)
|
||||
{
|
||||
// Get program from map[index].
|
||||
ebpf_program_t* callee = ebpf_map_get_program_from_entry(map, (uint8_t*)&index, sizeof(index));
|
||||
ebpf_program_t* callee = ebpf_map_get_program_from_entry(map, sizeof(index), (uint8_t*)&index);
|
||||
if (callee == NULL) {
|
||||
return -EBPF_INVALID_ARGUMENT;
|
||||
}
|
||||
|
@ -1013,39 +1029,39 @@ static ebpf_protocol_handler_t _ebpf_protocol_handlers[] = {
|
|||
|
||||
// EBPF_OPERATION_CREATE_PROGRAM
|
||||
{(ebpf_result_t(__cdecl*)(const void*))_ebpf_core_protocol_create_program,
|
||||
sizeof(struct _ebpf_operation_create_program_request),
|
||||
EBPF_OFFSET_OF(ebpf_operation_create_program_request_t, data),
|
||||
sizeof(struct _ebpf_operation_create_program_reply)},
|
||||
|
||||
// EBPF_OPERATION_CREATE_MAP
|
||||
{(ebpf_result_t(__cdecl*)(const void*))_ebpf_core_protocol_create_map,
|
||||
sizeof(struct _ebpf_operation_create_map_request),
|
||||
EBPF_OFFSET_OF(ebpf_operation_create_map_request_t, data),
|
||||
sizeof(struct _ebpf_operation_create_map_reply)},
|
||||
|
||||
// EBPF_OPERATION_LOAD_CODE
|
||||
{(ebpf_result_t(__cdecl*)(const void*))_ebpf_core_protocol_load_code,
|
||||
sizeof(struct _ebpf_operation_load_code_request),
|
||||
EBPF_OFFSET_OF(ebpf_operation_load_code_request_t, code),
|
||||
0},
|
||||
|
||||
// EBPF_OPERATION_MAP_FIND_ELEMENT
|
||||
{(ebpf_result_t(__cdecl*)(const void*))_ebpf_core_protocol_map_find_element,
|
||||
sizeof(struct _ebpf_operation_map_find_element_request),
|
||||
sizeof(struct _ebpf_operation_map_find_element_reply)},
|
||||
EBPF_OFFSET_OF(ebpf_operation_map_find_element_request_t, key),
|
||||
EBPF_OFFSET_OF(ebpf_operation_map_find_element_reply_t, value)},
|
||||
|
||||
// EBPF_OPERATION_MAP_UPDATE_ELEMENT
|
||||
{_ebpf_core_protocol_map_update_element, sizeof(struct _ebpf_operation_map_update_element_request), 0},
|
||||
{_ebpf_core_protocol_map_update_element, EBPF_OFFSET_OF(epf_operation_map_update_element_request_t, data), 0},
|
||||
|
||||
// EBPF_OPERATION_MAP_UPDATE_ELEMENT_WITH_HANDLE
|
||||
{_ebpf_core_protocol_map_update_element_with_handle,
|
||||
sizeof(struct _ebpf_operation_map_update_element_with_handle_request),
|
||||
EBPF_OFFSET_OF(ebpf_operation_map_update_element_with_handle_request_t, data),
|
||||
0},
|
||||
|
||||
// EBPF_OPERATION_MAP_DELETE_ELEMENT
|
||||
{_ebpf_core_protocol_map_delete_element, sizeof(struct _ebpf_operation_map_delete_element_request), 0},
|
||||
{_ebpf_core_protocol_map_delete_element, EBPF_OFFSET_OF(ebpf_operation_map_delete_element_request_t, key), 0},
|
||||
|
||||
// EBPF_OPERATION_MAP_GET_NEXT_KEY
|
||||
{(ebpf_result_t(__cdecl*)(const void*))_ebpf_core_protocol_map_get_next_key,
|
||||
EBPF_OFFSET_OF(ebpf_operation_map_get_next_key_request_t, previous_key),
|
||||
sizeof(ebpf_operation_map_get_next_key_reply_t)},
|
||||
EBPF_OFFSET_OF(ebpf_operation_map_get_next_key_reply_t, next_key)},
|
||||
|
||||
// EBPF_OPERATION_GET_NEXT_MAP
|
||||
{(ebpf_result_t(__cdecl*)(const void*))_ebpf_core_protocol_get_next_map,
|
||||
|
@ -1065,19 +1081,19 @@ static ebpf_protocol_handler_t _ebpf_protocol_handlers[] = {
|
|||
// EBPF_OPERATION_QUERY_PROGRAM_INFO
|
||||
{(ebpf_result_t(__cdecl*)(const void*))_ebpf_core_protocol_query_program_info,
|
||||
sizeof(struct _ebpf_operation_query_program_info_request),
|
||||
sizeof(struct _ebpf_operation_query_program_info_reply)},
|
||||
EBPF_OFFSET_OF(ebpf_operation_query_program_info_reply_t, data)},
|
||||
|
||||
// EBPF_OPERATION_UPDATE_PINNING
|
||||
{_ebpf_core_protocol_update_pinning, sizeof(struct _ebpf_operation_update_map_pinning_request), 0},
|
||||
{_ebpf_core_protocol_update_pinning, EBPF_OFFSET_OF(ebpf_operation_update_pinning_request_t, name), 0},
|
||||
|
||||
// EBPF_OPERATION_GET_PINNING
|
||||
{(ebpf_result_t(__cdecl*)(const void*))_ebpf_core_protocol_get_pinned_object,
|
||||
sizeof(struct _ebpf_operation_get_pinning_request),
|
||||
EBPF_OFFSET_OF(ebpf_operation_get_pinning_request_t, name),
|
||||
sizeof(struct _ebpf_operation_get_pinning_reply)},
|
||||
|
||||
// EBPF_OPERATION_LINK_PROGRAM
|
||||
{(ebpf_result_t(__cdecl*)(const void*))_ebpf_core_protocol_link_program,
|
||||
sizeof(ebpf_operation_link_program_request_t),
|
||||
EBPF_OFFSET_OF(ebpf_operation_link_program_request_t, data),
|
||||
sizeof(ebpf_operation_link_program_reply_t)},
|
||||
|
||||
// EBPF_OPERATION_UNLINK_PROGRAM
|
||||
|
@ -1098,12 +1114,12 @@ static ebpf_protocol_handler_t _ebpf_protocol_handlers[] = {
|
|||
// EBPF_OPERATION_GET_PROGRAM_INFO
|
||||
{(ebpf_result_t(__cdecl*)(const void*))_ebpf_core_protocol_get_program_info,
|
||||
sizeof(ebpf_operation_get_program_info_request_t),
|
||||
sizeof(ebpf_operation_get_program_info_reply_t)},
|
||||
EBPF_OFFSET_OF(ebpf_operation_get_program_info_reply_t, data)},
|
||||
|
||||
// EBPF_OPERATION_GET_MAP_INFO
|
||||
{(ebpf_result_t(__cdecl*)(const void*))_ebpf_core_protocol_get_map_info,
|
||||
sizeof(ebpf_operation_get_map_info_request_t),
|
||||
sizeof(ebpf_operation_get_map_info_reply_t)}};
|
||||
EBPF_OFFSET_OF(ebpf_operation_get_map_info_reply_t, data)}};
|
||||
|
||||
ebpf_result_t
|
||||
ebpf_core_get_protocol_handler_properties(
|
||||
|
|
|
@ -23,11 +23,11 @@ typedef struct _ebpf_program_array_map
|
|||
ebpf_program_type_t program_type;
|
||||
} ebpf_program_array_map_t;
|
||||
|
||||
typedef struct _ebpf_core_map_per_cpu
|
||||
typedef struct _ebpf_core_per_cpu_data
|
||||
{
|
||||
uint32_t count;
|
||||
uint8_t data[1];
|
||||
} ebpf_core_map_per_cpu_t;
|
||||
} ebpf_core_per_cpu_data_t;
|
||||
|
||||
typedef struct _ebpf_map_function_table
|
||||
{
|
||||
|
@ -454,7 +454,7 @@ _create_per_cpu_hash_map(_In_ const ebpf_map_definition_t* map_definition)
|
|||
uint32_t cpu_count;
|
||||
uint32_t index;
|
||||
size_t per_cpu_size = 0;
|
||||
ebpf_core_map_per_cpu_t* per_cpu = NULL;
|
||||
ebpf_core_per_cpu_data_t* per_cpu_data = NULL;
|
||||
|
||||
ebpf_get_cpu_count(&cpu_count);
|
||||
|
||||
|
@ -463,7 +463,7 @@ _create_per_cpu_hash_map(_In_ const ebpf_map_definition_t* map_definition)
|
|||
goto Done;
|
||||
}
|
||||
|
||||
retval = ebpf_safe_size_t_add(EBPF_OFFSET_OF(ebpf_core_map_per_cpu_t, data), per_cpu_size, &per_cpu_size);
|
||||
retval = ebpf_safe_size_t_add(EBPF_OFFSET_OF(ebpf_core_per_cpu_data_t, data), per_cpu_size, &per_cpu_size);
|
||||
if (retval != EBPF_SUCCESS) {
|
||||
goto Done;
|
||||
}
|
||||
|
@ -481,10 +481,10 @@ _create_per_cpu_hash_map(_In_ const ebpf_map_definition_t* map_definition)
|
|||
|
||||
map->ebpf_map_definition = *map_definition;
|
||||
map->data = (uint8_t*)(map + 1);
|
||||
per_cpu = (ebpf_core_map_per_cpu_t*)map->data;
|
||||
per_cpu_data = (ebpf_core_per_cpu_data_t*)map->data;
|
||||
|
||||
for (index = 0; index < cpu_count; index++) {
|
||||
ebpf_hash_table_t** tables = (ebpf_hash_table_t**)&per_cpu->data;
|
||||
ebpf_hash_table_t** tables = (ebpf_hash_table_t**)&per_cpu_data->data;
|
||||
retval = ebpf_hash_table_create(
|
||||
tables + index,
|
||||
ebpf_epoch_allocate,
|
||||
|
@ -497,17 +497,17 @@ _create_per_cpu_hash_map(_In_ const ebpf_map_definition_t* map_definition)
|
|||
}
|
||||
}
|
||||
|
||||
map->data = (uint8_t*)per_cpu;
|
||||
per_cpu->count = cpu_count;
|
||||
map->data = (uint8_t*)per_cpu_data;
|
||||
per_cpu_data->count = cpu_count;
|
||||
|
||||
ebpf_lock_create(&map->lock);
|
||||
retval = EBPF_SUCCESS;
|
||||
|
||||
Done:
|
||||
if (retval != EBPF_SUCCESS) {
|
||||
if (per_cpu) {
|
||||
for (index = 0; index < per_cpu->count; index++) {
|
||||
ebpf_hash_table_t** tables = (ebpf_hash_table_t**)&per_cpu->data;
|
||||
if (per_cpu_data) {
|
||||
for (index = 0; index < per_cpu_data->count; index++) {
|
||||
ebpf_hash_table_t** tables = (ebpf_hash_table_t**)&per_cpu_data->data;
|
||||
ebpf_hash_table_destroy(tables[index]);
|
||||
}
|
||||
}
|
||||
|
@ -521,11 +521,11 @@ static void
|
|||
_delete_per_cpu_hash_map(_In_ ebpf_core_map_t* map)
|
||||
{
|
||||
uint32_t index;
|
||||
ebpf_core_map_per_cpu_t* per_cpu = NULL;
|
||||
ebpf_core_per_cpu_data_t* per_cpu_data = NULL;
|
||||
ebpf_lock_destroy(&map->lock);
|
||||
per_cpu = (ebpf_core_map_per_cpu_t*)map->data;
|
||||
for (index = 0; index < per_cpu->count; index++) {
|
||||
ebpf_hash_table_t** tables = (ebpf_hash_table_t**)&per_cpu->data;
|
||||
per_cpu_data = (ebpf_core_per_cpu_data_t*)map->data;
|
||||
for (index = 0; index < per_cpu_data->count; index++) {
|
||||
ebpf_hash_table_t** tables = (ebpf_hash_table_t**)&per_cpu_data->data;
|
||||
ebpf_hash_table_destroy(tables[index]);
|
||||
}
|
||||
ebpf_free(map);
|
||||
|
@ -535,16 +535,16 @@ static ebpf_hash_table_t*
|
|||
_get_hash_table_for_cpu(_In_ ebpf_core_map_t* map)
|
||||
{
|
||||
uint32_t current_cpu;
|
||||
ebpf_core_map_per_cpu_t* per_cpu = NULL;
|
||||
ebpf_core_per_cpu_data_t* per_cpu_data = NULL;
|
||||
ebpf_hash_table_t** tables;
|
||||
if (ebpf_is_preemptible()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
current_cpu = ebpf_get_current_cpu();
|
||||
per_cpu = (ebpf_core_map_per_cpu_t*)map->data;
|
||||
tables = (ebpf_hash_table_t**)&per_cpu->data;
|
||||
if (current_cpu < per_cpu->count) {
|
||||
per_cpu_data = (ebpf_core_per_cpu_data_t*)map->data;
|
||||
tables = (ebpf_hash_table_t**)&per_cpu_data->data;
|
||||
if (current_cpu < per_cpu_data->count) {
|
||||
return tables[current_cpu];
|
||||
} else {
|
||||
return NULL;
|
||||
|
@ -623,14 +623,14 @@ _next_per_cpu_hash_map_key(_In_ ebpf_core_map_t* map, _In_ const uint8_t* previo
|
|||
}
|
||||
|
||||
static ebpf_core_map_t*
|
||||
_create_array_map_per_cpu(_In_ const ebpf_map_definition_t* map_definition)
|
||||
_create_per_cpu_array_map(_In_ const ebpf_map_definition_t* map_definition)
|
||||
{
|
||||
ebpf_result_t retval;
|
||||
uint32_t cpu_count;
|
||||
size_t map_entry_size = sizeof(ebpf_core_map_t);
|
||||
size_t map_data_size = 0;
|
||||
ebpf_core_map_t* map = NULL;
|
||||
ebpf_core_map_per_cpu_t* per_cpu = NULL;
|
||||
ebpf_core_per_cpu_data_t* per_cpu_data = NULL;
|
||||
ebpf_get_cpu_count(&cpu_count);
|
||||
|
||||
retval = ebpf_safe_size_t_multiply(map_definition->max_entries, map_definition->value_size, &map_data_size);
|
||||
|
@ -643,7 +643,7 @@ _create_array_map_per_cpu(_In_ const ebpf_map_definition_t* map_definition)
|
|||
goto Done;
|
||||
}
|
||||
|
||||
retval = ebpf_safe_size_t_add(map_data_size, EBPF_OFFSET_OF(ebpf_core_map_per_cpu_t, data), &map_data_size);
|
||||
retval = ebpf_safe_size_t_add(map_data_size, EBPF_OFFSET_OF(ebpf_core_per_cpu_data_t, data), &map_data_size);
|
||||
if (retval != EBPF_SUCCESS) {
|
||||
goto Done;
|
||||
}
|
||||
|
@ -662,15 +662,15 @@ _create_array_map_per_cpu(_In_ const ebpf_map_definition_t* map_definition)
|
|||
map->ebpf_map_definition = *map_definition;
|
||||
map->data = (uint8_t*)(map + 1);
|
||||
|
||||
per_cpu = (ebpf_core_map_per_cpu_t*)map->data;
|
||||
per_cpu->count = cpu_count;
|
||||
per_cpu_data = (ebpf_core_per_cpu_data_t*)map->data;
|
||||
per_cpu_data->count = cpu_count;
|
||||
|
||||
Done:
|
||||
return map;
|
||||
}
|
||||
|
||||
static void
|
||||
_delete_array_map_per_cpu(_In_ ebpf_core_map_t* map)
|
||||
_delete_per_cpu_array_map(_In_ ebpf_core_map_t* map)
|
||||
{
|
||||
ebpf_free(map);
|
||||
}
|
||||
|
@ -680,22 +680,22 @@ _get_array_table_for_cpu(_In_ ebpf_core_map_t* map)
|
|||
{
|
||||
size_t offset = (size_t)map->ebpf_map_definition.max_entries * (size_t)map->ebpf_map_definition.value_size;
|
||||
uint32_t current_cpu;
|
||||
ebpf_core_map_per_cpu_t* per_cpu = NULL;
|
||||
ebpf_core_per_cpu_data_t* per_cpu_data = NULL;
|
||||
if (ebpf_is_preemptible()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
current_cpu = ebpf_get_current_cpu();
|
||||
per_cpu = (ebpf_core_map_per_cpu_t*)map->data;
|
||||
if (current_cpu < per_cpu->count) {
|
||||
return per_cpu->data + current_cpu * offset;
|
||||
per_cpu_data = (ebpf_core_per_cpu_data_t*)map->data;
|
||||
if (current_cpu < per_cpu_data->count) {
|
||||
return per_cpu_data->data + current_cpu * offset;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t*
|
||||
_find_array_map_entry_per_cpu(_In_ ebpf_core_map_t* map, _In_ const uint8_t* key)
|
||||
_find_per_cpu_array_map_entry(_In_ ebpf_core_map_t* map, _In_ const uint8_t* key)
|
||||
{
|
||||
uint8_t* data;
|
||||
uint32_t key_value;
|
||||
|
@ -716,9 +716,9 @@ _find_array_map_entry_per_cpu(_In_ ebpf_core_map_t* map, _In_ const uint8_t* key
|
|||
}
|
||||
|
||||
static ebpf_result_t
|
||||
_update_array_map_entry_per_cpu(_In_ ebpf_core_map_t* map, _In_ const uint8_t* key, _In_ const uint8_t* data)
|
||||
_update_per_cpu_array_map_entry(_In_ ebpf_core_map_t* map, _In_ const uint8_t* key, _In_ const uint8_t* data)
|
||||
{
|
||||
uint8_t* entry = _find_array_map_entry_per_cpu(map, key);
|
||||
uint8_t* entry = _find_per_cpu_array_map_entry(map, key);
|
||||
if (!entry)
|
||||
return EBPF_INVALID_ARGUMENT;
|
||||
|
||||
|
@ -727,9 +727,9 @@ _update_array_map_entry_per_cpu(_In_ ebpf_core_map_t* map, _In_ const uint8_t* k
|
|||
}
|
||||
|
||||
static ebpf_result_t
|
||||
_delete_array_map_entry_per_cpu(_In_ ebpf_core_map_t* map, _In_ const uint8_t* key)
|
||||
_delete_per_cpu_array_map_entry(_In_ ebpf_core_map_t* map, _In_ const uint8_t* key)
|
||||
{
|
||||
uint8_t* entry = _find_array_map_entry_per_cpu(map, key);
|
||||
uint8_t* entry = _find_per_cpu_array_map_entry(map, key);
|
||||
if (!entry)
|
||||
return EBPF_KEY_NOT_FOUND;
|
||||
|
||||
|
@ -791,7 +791,7 @@ ebpf_map_function_table_t ebpf_map_function_tables[] = {
|
|||
_update_prog_array_map_entry_with_handle,
|
||||
_delete_prog_array_map_entry,
|
||||
_next_array_map_key},
|
||||
{// BPF_MAP_TYPE_HASH
|
||||
{// BPF_MAP_TYPE_PERCPU_HASH
|
||||
_create_per_cpu_hash_map,
|
||||
_delete_per_cpu_hash_map,
|
||||
NULL,
|
||||
|
@ -801,15 +801,15 @@ ebpf_map_function_table_t ebpf_map_function_tables[] = {
|
|||
NULL,
|
||||
_delete_per_cpu_hash_map_entry,
|
||||
_next_per_cpu_hash_map_key},
|
||||
{// BPF_MAP_TYPE_ARRAY
|
||||
_create_array_map_per_cpu,
|
||||
_delete_array_map_per_cpu,
|
||||
{// BPF_MAP_TYPE_PERCPU_ARRAY
|
||||
_create_per_cpu_array_map,
|
||||
_delete_per_cpu_array_map,
|
||||
NULL,
|
||||
_find_array_map_entry_per_cpu,
|
||||
_find_per_cpu_array_map_entry,
|
||||
NULL,
|
||||
_update_array_map_entry_per_cpu,
|
||||
_update_per_cpu_array_map_entry,
|
||||
NULL,
|
||||
_delete_array_map_entry_per_cpu,
|
||||
_delete_per_cpu_array_map_entry,
|
||||
_next_array_map_key_per_cpu},
|
||||
};
|
||||
|
||||
|
@ -861,15 +861,40 @@ Exit:
|
|||
return result;
|
||||
}
|
||||
|
||||
uint8_t*
|
||||
ebpf_map_find_entry(_In_ ebpf_map_t* map, _In_ const uint8_t* key, int flags)
|
||||
ebpf_result_t
|
||||
ebpf_map_find_entry(
|
||||
_In_ ebpf_map_t* map,
|
||||
size_t key_size,
|
||||
_In_reads_(key_size) const uint8_t* key,
|
||||
size_t value_size,
|
||||
_Out_writes_(value_size) uint8_t* value,
|
||||
int flags)
|
||||
{
|
||||
// Disallow reads to prog array maps from this helper call for now.
|
||||
if ((flags & EBPF_MAP_FIND_ENTRY_FLAG_HELPER) && map->ebpf_map_definition.type == BPF_MAP_TYPE_PROG_ARRAY) {
|
||||
return NULL;
|
||||
uint8_t* return_value;
|
||||
if (!(flags & EBPF_MAP_FLAG_HELPER) && (key_size != map->ebpf_map_definition.key_size)) {
|
||||
return EBPF_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
return ebpf_map_function_tables[map->ebpf_map_definition.type].find_entry(map, key);
|
||||
if (!(flags & EBPF_MAP_FLAG_HELPER) && (value_size != map->ebpf_map_definition.value_size)) {
|
||||
return EBPF_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
// Disallow reads to prog array maps from this helper call for now.
|
||||
if ((flags & EBPF_MAP_FLAG_HELPER) && map->ebpf_map_definition.type == BPF_MAP_TYPE_PROG_ARRAY) {
|
||||
return EBPF_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
return_value = ebpf_map_function_tables[map->ebpf_map_definition.type].find_entry(map, key);
|
||||
if (return_value == NULL) {
|
||||
return EBPF_OBJECT_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (flags & EBPF_MAP_FLAG_HELPER) {
|
||||
*(uint8_t**)value = return_value;
|
||||
} else {
|
||||
memcpy(value, return_value, value_size);
|
||||
}
|
||||
return EBPF_SUCCESS;
|
||||
}
|
||||
|
||||
ebpf_result_t
|
||||
|
@ -881,7 +906,7 @@ ebpf_map_associate_program(_In_ ebpf_map_t* map, _In_ const ebpf_program_t* prog
|
|||
}
|
||||
|
||||
_Ret_maybenull_ ebpf_program_t*
|
||||
ebpf_map_get_program_from_entry(_In_ ebpf_map_t* map, _In_ const uint8_t* key, size_t key_size)
|
||||
ebpf_map_get_program_from_entry(_In_ ebpf_map_t* map, size_t key_size, _In_reads_(key_size) const uint8_t* key)
|
||||
{
|
||||
if (key_size != map->ebpf_map_definition.key_size) {
|
||||
return NULL;
|
||||
|
@ -898,8 +923,22 @@ ebpf_map_get_program_from_entry(_In_ ebpf_map_t* map, _In_ const uint8_t* key, s
|
|||
}
|
||||
|
||||
ebpf_result_t
|
||||
ebpf_map_update_entry(_In_ ebpf_map_t* map, _In_ const uint8_t* key, _In_ const uint8_t* value)
|
||||
ebpf_map_update_entry(
|
||||
_In_ ebpf_map_t* map,
|
||||
size_t key_size,
|
||||
_In_reads_(key_size) const uint8_t* key,
|
||||
size_t value_size,
|
||||
_In_reads_(value_size) const uint8_t* value,
|
||||
int flags)
|
||||
{
|
||||
if (!(flags & EBPF_MAP_FLAG_HELPER) && (key_size != map->ebpf_map_definition.key_size)) {
|
||||
return EBPF_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (!(flags & EBPF_MAP_FLAG_HELPER) && (value_size != map->ebpf_map_definition.value_size)) {
|
||||
return EBPF_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (ebpf_map_function_tables[map->ebpf_map_definition.type].update_entry == NULL) {
|
||||
return EBPF_INVALID_ARGUMENT;
|
||||
}
|
||||
|
@ -908,8 +947,21 @@ ebpf_map_update_entry(_In_ ebpf_map_t* map, _In_ const uint8_t* key, _In_ const
|
|||
|
||||
ebpf_result_t
|
||||
ebpf_map_update_entry_with_handle(
|
||||
_In_ ebpf_map_t* map, _In_ const uint8_t* key, _In_ const uint8_t* value, uintptr_t value_handle)
|
||||
_In_ ebpf_map_t* map,
|
||||
size_t key_size,
|
||||
_In_reads_(key_size) const uint8_t* key,
|
||||
size_t value_size,
|
||||
_In_reads_(value_size) const uint8_t* value,
|
||||
uintptr_t value_handle)
|
||||
{
|
||||
if (key_size != map->ebpf_map_definition.key_size) {
|
||||
return EBPF_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (value_size != map->ebpf_map_definition.value_size) {
|
||||
return EBPF_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (ebpf_map_function_tables[map->ebpf_map_definition.type].update_entry_with_handle == NULL) {
|
||||
return EBPF_OPERATION_NOT_SUPPORTED;
|
||||
}
|
||||
|
@ -918,13 +970,23 @@ ebpf_map_update_entry_with_handle(
|
|||
}
|
||||
|
||||
ebpf_result_t
|
||||
ebpf_map_delete_entry(_In_ ebpf_map_t* map, _In_ const uint8_t* key)
|
||||
ebpf_map_delete_entry(_In_ ebpf_map_t* map, size_t key_size, _In_reads_(key_size) const uint8_t* key, int flags)
|
||||
{
|
||||
if (!(flags & EBPF_MAP_FLAG_HELPER) && (key_size != map->ebpf_map_definition.key_size)) {
|
||||
return EBPF_INVALID_ARGUMENT;
|
||||
}
|
||||
return ebpf_map_function_tables[map->ebpf_map_definition.type].delete_entry(map, key);
|
||||
}
|
||||
|
||||
ebpf_result_t
|
||||
ebpf_map_next_key(_In_ ebpf_map_t* map, _In_opt_ const uint8_t* previous_key, _Out_ uint8_t* next_key)
|
||||
ebpf_map_next_key(
|
||||
_In_ ebpf_map_t* map,
|
||||
size_t key_size,
|
||||
_In_reads_opt_(key_size) const uint8_t* previous_key,
|
||||
_Out_writes_(key_size) uint8_t* next_key)
|
||||
{
|
||||
if (key_size != map->ebpf_map_definition.key_size) {
|
||||
return EBPF_INVALID_ARGUMENT;
|
||||
}
|
||||
return ebpf_map_function_tables[map->ebpf_map_definition.type].next_key(map, previous_key, next_key);
|
||||
}
|
||||
|
|
|
@ -38,7 +38,8 @@ extern "C"
|
|||
const ebpf_map_definition_t*
|
||||
ebpf_map_get_definition(_In_ const ebpf_map_t* map);
|
||||
|
||||
#define EBPF_MAP_FIND_ENTRY_FLAG_HELPER 0x01 /* Called by an eBPF program */
|
||||
#define EBPF_MAP_FLAG_HELPER 0x01 /* Called by an eBPF program */
|
||||
|
||||
/**
|
||||
* @brief Get a pointer to an entry in the map.
|
||||
*
|
||||
|
@ -47,8 +48,14 @@ extern "C"
|
|||
* @param[in] flags Zero or more EBPF_MAP_FIND_ENTRY_FLAG_* flags.
|
||||
* @return Pointer to the value if found or NULL.
|
||||
*/
|
||||
uint8_t*
|
||||
ebpf_map_find_entry(_In_ ebpf_map_t* map, _In_ const uint8_t* key, int flags);
|
||||
ebpf_result_t
|
||||
ebpf_map_find_entry(
|
||||
_In_ ebpf_map_t* map,
|
||||
size_t key_size,
|
||||
_In_reads_(key_size) const uint8_t* key,
|
||||
size_t value_size,
|
||||
_Out_writes_(value_size) uint8_t* value,
|
||||
int flags);
|
||||
|
||||
/**
|
||||
* @brief Insert or update an entry in the map.
|
||||
|
@ -61,7 +68,13 @@ extern "C"
|
|||
* entry.
|
||||
*/
|
||||
ebpf_result_t
|
||||
ebpf_map_update_entry(_In_ ebpf_map_t* map, _In_ const uint8_t* key, _In_ const uint8_t* value);
|
||||
ebpf_map_update_entry(
|
||||
_In_ ebpf_map_t* map,
|
||||
size_t key_size,
|
||||
_In_reads_(key_size) const uint8_t* key,
|
||||
size_t value_size,
|
||||
_In_reads_(value_size) const uint8_t* value,
|
||||
int flags);
|
||||
|
||||
/**
|
||||
* @brief Insert or update an entry in the map.
|
||||
|
@ -76,7 +89,12 @@ extern "C"
|
|||
*/
|
||||
ebpf_result_t
|
||||
ebpf_map_update_entry_with_handle(
|
||||
_In_ ebpf_map_t* map, _In_ const uint8_t* key, _In_ const uint8_t* value, uintptr_t value_handle);
|
||||
_In_ ebpf_map_t* map,
|
||||
size_t key_size,
|
||||
_In_reads_(key_size) const uint8_t* key,
|
||||
size_t value_size,
|
||||
_In_reads_(value_size) const uint8_t* value,
|
||||
uintptr_t value_handle);
|
||||
|
||||
/**
|
||||
* @brief Remove an entry from the map.
|
||||
|
@ -88,7 +106,8 @@ extern "C"
|
|||
* invalid.
|
||||
*/
|
||||
ebpf_result_t
|
||||
ebpf_map_delete_entry(_In_ ebpf_map_t* map, _In_ const uint8_t* key);
|
||||
ebpf_map_delete_entry(
|
||||
_In_ ebpf_map_t* map, size_t key_size, _In_reads_(key_size) const uint8_t* key, int flags);
|
||||
|
||||
/**
|
||||
* @brief Retrieve the next key from the map.
|
||||
|
@ -103,7 +122,11 @@ extern "C"
|
|||
* key in lexicographically order.
|
||||
*/
|
||||
ebpf_result_t
|
||||
ebpf_map_next_key(_In_ ebpf_map_t* map, _In_opt_ const uint8_t* previous_key, _Out_ uint8_t* next_key);
|
||||
ebpf_map_next_key(
|
||||
_In_ ebpf_map_t* map,
|
||||
size_t key_size,
|
||||
_In_reads_opt_(key_size) const uint8_t* previous_key,
|
||||
_Out_writes_(key_size) uint8_t* next_key);
|
||||
|
||||
/**
|
||||
* @brief Get a program from an entry in a map that holds programs. The
|
||||
|
@ -116,7 +139,7 @@ extern "C"
|
|||
* @returns Program pointer, or NULL if none.
|
||||
*/
|
||||
_Ret_maybenull_ struct _ebpf_program*
|
||||
ebpf_map_get_program_from_entry(_In_ ebpf_map_t* map, _In_ const uint8_t* key, size_t key_size);
|
||||
ebpf_map_get_program_from_entry(_In_ ebpf_map_t* map, size_t key_size, _In_reads_(key_size) const uint8_t* key);
|
||||
|
||||
/**
|
||||
* @brief Let a map take any actions when first
|
||||
|
|
|
@ -141,7 +141,7 @@ typedef struct _ebpf_operation_map_update_element_with_handle_request
|
|||
uintptr_t map_handle;
|
||||
uintptr_t value_handle;
|
||||
uint8_t data[1]; // data is key+value
|
||||
} epf_operation_map_update_element_with_handle_request_t;
|
||||
} ebpf_operation_map_update_element_with_handle_request_t;
|
||||
|
||||
typedef struct _ebpf_operation_map_delete_element_request
|
||||
{
|
||||
|
@ -154,7 +154,7 @@ typedef struct _ebpf_operation_get_next_map_request
|
|||
{
|
||||
struct _ebpf_operation_header header;
|
||||
uint64_t previous_handle;
|
||||
} ebpf_operation_get_next_map_request;
|
||||
} ebpf_operation_get_next_map_request_t;
|
||||
|
||||
typedef struct _ebpf_operation_get_next_map_reply
|
||||
{
|
||||
|
@ -166,7 +166,7 @@ typedef struct _ebpf_operation_get_next_program_request
|
|||
{
|
||||
struct _ebpf_operation_header header;
|
||||
uint64_t previous_handle;
|
||||
} ebpf_operation_get_next_program_request;
|
||||
} ebpf_operation_get_next_program_request_t;
|
||||
|
||||
typedef struct _ebpf_operation_get_next_program_reply
|
||||
{
|
||||
|
@ -184,13 +184,13 @@ typedef struct _ebpf_operation_query_map_definition_reply
|
|||
{
|
||||
struct _ebpf_operation_header header;
|
||||
struct _ebpf_map_definition map_definition;
|
||||
} ebpf_operation_query_map_definition_reply;
|
||||
} ebpf_operation_query_map_definition_reply_t;
|
||||
|
||||
typedef struct _ebpf_operation_query_program_info_request
|
||||
{
|
||||
struct _ebpf_operation_header header;
|
||||
uint64_t handle;
|
||||
} ebpf_operation_query_program_info_request;
|
||||
} ebpf_operation_query_program_info_request_t;
|
||||
|
||||
typedef struct _ebpf_operation_query_program_info_reply
|
||||
{
|
||||
|
@ -199,7 +199,7 @@ typedef struct _ebpf_operation_query_program_info_reply
|
|||
uint16_t file_name_offset;
|
||||
uint16_t section_name_offset;
|
||||
uint8_t data[1];
|
||||
} ebpf_operation_query_program_info_reply;
|
||||
} ebpf_operation_query_program_info_reply_t;
|
||||
|
||||
typedef struct _ebpf_operation_map_get_next_key_request
|
||||
{
|
||||
|
|
|
@ -48,8 +48,12 @@ test_crud_operations(ebpf_map_type_t map_type)
|
|||
uint64_t value = static_cast<uint64_t>(key) * static_cast<uint64_t>(key);
|
||||
REQUIRE(
|
||||
ebpf_map_update_entry(
|
||||
map.get(), reinterpret_cast<const uint8_t*>(&key), reinterpret_cast<const uint8_t*>(&value)) ==
|
||||
EBPF_SUCCESS);
|
||||
map.get(),
|
||||
sizeof(key),
|
||||
reinterpret_cast<const uint8_t*>(&key),
|
||||
sizeof(value),
|
||||
reinterpret_cast<const uint8_t*>(&value),
|
||||
0) == EBPF_SUCCESS);
|
||||
}
|
||||
|
||||
// Test for inserting max_entries + 1
|
||||
|
@ -57,17 +61,29 @@ test_crud_operations(ebpf_map_type_t map_type)
|
|||
uint64_t bad_value = 11 * 11;
|
||||
REQUIRE(
|
||||
ebpf_map_update_entry(
|
||||
map.get(), reinterpret_cast<const uint8_t*>(&bad_key), reinterpret_cast<const uint8_t*>(&bad_value)) ==
|
||||
EBPF_INVALID_ARGUMENT);
|
||||
map.get(),
|
||||
sizeof(bad_key),
|
||||
reinterpret_cast<const uint8_t*>(&bad_key),
|
||||
sizeof(bad_value),
|
||||
reinterpret_cast<const uint8_t*>(&bad_value),
|
||||
0) == EBPF_INVALID_ARGUMENT);
|
||||
|
||||
REQUIRE(ebpf_map_delete_entry(map.get(), reinterpret_cast<const uint8_t*>(&bad_key)) == EBPF_KEY_NOT_FOUND);
|
||||
REQUIRE(
|
||||
ebpf_map_delete_entry(map.get(), sizeof(bad_key), reinterpret_cast<const uint8_t*>(&bad_key), 0) ==
|
||||
EBPF_KEY_NOT_FOUND);
|
||||
|
||||
for (uint32_t key = 0; key < 10; key++) {
|
||||
uint64_t* value =
|
||||
reinterpret_cast<uint64_t*>(ebpf_map_find_entry(map.get(), reinterpret_cast<const uint8_t*>(&key), FALSE));
|
||||
uint64_t value;
|
||||
REQUIRE(
|
||||
ebpf_map_find_entry(
|
||||
map.get(),
|
||||
sizeof(key),
|
||||
reinterpret_cast<const uint8_t*>(&key),
|
||||
sizeof(value),
|
||||
reinterpret_cast<uint8_t*>(&value),
|
||||
0) == EBPF_SUCCESS);
|
||||
|
||||
REQUIRE(value != nullptr);
|
||||
REQUIRE(*value == key * key);
|
||||
REQUIRE(value == key * key);
|
||||
}
|
||||
|
||||
uint32_t previous_key;
|
||||
|
@ -76,6 +92,7 @@ test_crud_operations(ebpf_map_type_t map_type)
|
|||
REQUIRE(
|
||||
ebpf_map_next_key(
|
||||
map.get(),
|
||||
sizeof(key),
|
||||
key == 0 ? nullptr : reinterpret_cast<const uint8_t*>(&previous_key),
|
||||
reinterpret_cast<uint8_t*>(&next_key)) == EBPF_SUCCESS);
|
||||
|
||||
|
@ -84,11 +101,14 @@ test_crud_operations(ebpf_map_type_t map_type)
|
|||
}
|
||||
REQUIRE(
|
||||
ebpf_map_next_key(
|
||||
map.get(), reinterpret_cast<const uint8_t*>(&previous_key), reinterpret_cast<uint8_t*>(&next_key)) ==
|
||||
EBPF_NO_MORE_KEYS);
|
||||
map.get(),
|
||||
sizeof(previous_key),
|
||||
reinterpret_cast<const uint8_t*>(&previous_key),
|
||||
reinterpret_cast<uint8_t*>(&next_key)) == EBPF_NO_MORE_KEYS);
|
||||
|
||||
for (uint32_t key = 0; key < 10; key++) {
|
||||
REQUIRE(ebpf_map_delete_entry(map.get(), reinterpret_cast<const uint8_t*>(&key)) == EBPF_SUCCESS);
|
||||
REQUIRE(
|
||||
ebpf_map_delete_entry(map.get(), sizeof(key), reinterpret_cast<const uint8_t*>(&key), 0) == EBPF_SUCCESS);
|
||||
}
|
||||
|
||||
auto retrieved_map_definition = ebpf_map_get_definition(map.get());
|
||||
|
|
Загрузка…
Ссылка в новой задаче