Fix push/pop APIs on queues (#985)
* Fix push/pop APIs on queues Signed-off-by: Dave Thaler <dthaler@microsoft.com> * Fix SAL warning Signed-off-by: Dave Thaler <dthaler@microsoft.com> * Remove deprecated code Fixes #980 Signed-off-by: Dave Thaler <dthaler@microsoft.com>
This commit is contained in:
Родитель
70d5e42587
Коммит
2f484db0c7
|
@ -88,7 +88,6 @@ EXPORTS
|
|||
ebpf_api_elf_verify_section_from_file
|
||||
ebpf_api_elf_verify_section_from_memory
|
||||
ebpf_api_elf_free
|
||||
ebpf_api_link_program
|
||||
ebpf_api_close_handle
|
||||
ebpf_api_get_pinned_map_info
|
||||
ebpf_api_map_info_free
|
||||
|
|
|
@ -238,20 +238,6 @@ extern "C"
|
|||
uint32_t
|
||||
ebpf_api_get_pinned_map(const uint8_t* name, uint32_t name_length, ebpf_handle_t* handle);
|
||||
|
||||
/**
|
||||
* @brief Bind a program to an attach point and return a handle representing
|
||||
* the link.
|
||||
*
|
||||
* @param[in] program_handle Handle to program to attach.
|
||||
* @param[in] attach_type Attach point to attach program to.
|
||||
* @param[out] link_handle Pointer to memory that contains the link handle
|
||||
* on success.
|
||||
* @retval ERROR_SUCCESS The operations succeeded.
|
||||
* @retval ERROR_INVALID_PARAMETER One or more parameters are incorrect.
|
||||
*/
|
||||
uint32_t
|
||||
ebpf_api_link_program(ebpf_handle_t program_handle, ebpf_attach_type_t attach_type, ebpf_handle_t* link_handle);
|
||||
|
||||
/**
|
||||
* @brief Detach the eBPF program from the link.
|
||||
*
|
||||
|
|
|
@ -216,15 +216,6 @@ ebpf_map_create(
|
|||
fd_t
|
||||
ebpf_program_get_fd(_In_ const struct bpf_program* program);
|
||||
|
||||
/**
|
||||
* @brief Fetch fd for a map object.
|
||||
*
|
||||
* @param[in] map Pointer to eBPF map.
|
||||
* @return fd for the map on success, ebpf_fd_invalid on failure.
|
||||
*/
|
||||
fd_t
|
||||
ebpf_map_get_fd(_In_ const struct bpf_map* map);
|
||||
|
||||
/**
|
||||
* @brief Clean up ebpf_object. Also delete all the sub objects
|
||||
* (maps, programs) and close the related file descriptors.
|
||||
|
@ -273,13 +264,13 @@ ebpf_map_set_pin_path(_In_ struct bpf_map* map, _In_ const char* path);
|
|||
* @brief Update value for the specified key in an eBPF map.
|
||||
*
|
||||
* @param[in] map_fd File descriptor for the eBPF map.
|
||||
* @param[in] key Pointer to buffer containing key.
|
||||
* @param[in] key Pointer to buffer containing key, or NULL for a map with no keys.
|
||||
* @param[out] value Pointer to buffer containing value.
|
||||
*
|
||||
* @retval EBPF_SUCCESS The operation was successful.
|
||||
*/
|
||||
ebpf_result_t
|
||||
ebpf_map_update_element(fd_t map_fd, _In_ const void* key, _In_ const void* value, uint64_t flags);
|
||||
ebpf_map_update_element(fd_t map_fd, _In_opt_ const void* key, _In_ const void* value, uint64_t flags);
|
||||
|
||||
/**
|
||||
* @brief Delete an element in an eBPF map.
|
||||
|
@ -313,13 +304,13 @@ ebpf_map_lookup_element(fd_t map_fd, _In_ const void* key, _Out_ void* value);
|
|||
* On successful lookup, the element is removed from the map.
|
||||
*
|
||||
* @param[in] map_fd File descriptor for the eBPF map.
|
||||
* @param[in] key Pointer to buffer containing key.
|
||||
* @param[in] key Pointer to buffer containing key, or NULL for a map with no keys.
|
||||
* @param[out] value Pointer to buffer that contains value on success.
|
||||
*
|
||||
* @retval EBPF_SUCCESS The operation was successful.
|
||||
*/
|
||||
ebpf_result_t
|
||||
ebpf_map_lookup_and_delete_element(fd_t map_fd, _In_ const void* key, _Out_ void* value);
|
||||
ebpf_map_lookup_and_delete_element(fd_t map_fd, _In_opt_ const void* key, _Out_ void* value);
|
||||
|
||||
/**
|
||||
* @brief Return the next key in an eBPF map.
|
||||
|
|
|
@ -256,7 +256,7 @@ _map_lookup_element(
|
|||
ebpf_handle_t handle,
|
||||
bool find_and_delete,
|
||||
uint32_t key_size,
|
||||
_In_ const uint8_t* key,
|
||||
_In_reads_opt_(key_size) const uint8_t* key,
|
||||
uint32_t value_size,
|
||||
_Out_ uint8_t* value) noexcept
|
||||
{
|
||||
|
@ -273,7 +273,9 @@ _map_lookup_element(
|
|||
request->header.id = ebpf_operation_id_t::EBPF_OPERATION_MAP_FIND_ELEMENT;
|
||||
request->find_and_delete = find_and_delete;
|
||||
request->handle = handle;
|
||||
std::copy(key, key + key_size, request->key);
|
||||
if (key_size > 0) {
|
||||
std::copy(key, key + key_size, request->key);
|
||||
}
|
||||
|
||||
result = win32_error_code_to_ebpf_result(invoke_ioctl(request_buffer, reply_buffer));
|
||||
|
||||
|
@ -334,7 +336,7 @@ Exit:
|
|||
}
|
||||
|
||||
static ebpf_result_t
|
||||
_ebpf_map_lookup_element_helper(fd_t map_fd, bool find_and_delete, _In_ const void* key, _Out_ void* value)
|
||||
_ebpf_map_lookup_element_helper(fd_t map_fd, bool find_and_delete, _In_opt_ const void* key, _Out_ void* value)
|
||||
{
|
||||
ebpf_result_t result = EBPF_SUCCESS;
|
||||
ebpf_handle_t map_handle;
|
||||
|
@ -343,7 +345,7 @@ _ebpf_map_lookup_element_helper(fd_t map_fd, bool find_and_delete, _In_ const vo
|
|||
uint32_t max_entries = 0;
|
||||
uint32_t type;
|
||||
|
||||
if (map_fd <= 0 || key == nullptr || value == nullptr) {
|
||||
if (map_fd <= 0 || value == nullptr) {
|
||||
result = EBPF_INVALID_ARGUMENT;
|
||||
goto Exit;
|
||||
}
|
||||
|
@ -360,7 +362,10 @@ _ebpf_map_lookup_element_helper(fd_t map_fd, bool find_and_delete, _In_ const vo
|
|||
if (result != EBPF_SUCCESS) {
|
||||
goto Exit;
|
||||
}
|
||||
assert(key_size != 0);
|
||||
if ((key == nullptr) != (key_size == 0)) {
|
||||
result = EBPF_INVALID_ARGUMENT;
|
||||
goto Exit;
|
||||
}
|
||||
assert(value_size != 0);
|
||||
|
||||
result = _map_lookup_element(map_handle, find_and_delete, key_size, (uint8_t*)key, value_size, (uint8_t*)value);
|
||||
|
@ -376,7 +381,7 @@ ebpf_map_lookup_element(fd_t map_fd, _In_ const void* key, _Out_ void* value)
|
|||
}
|
||||
|
||||
ebpf_result_t
|
||||
ebpf_map_lookup_and_delete_element(fd_t map_fd, _In_ const void* key, _Out_ void* value)
|
||||
ebpf_map_lookup_and_delete_element(fd_t map_fd, _In_opt_ const void* key, _Out_ void* value)
|
||||
{
|
||||
return _ebpf_map_lookup_element_helper(map_fd, true, key, value);
|
||||
}
|
||||
|
@ -384,7 +389,7 @@ ebpf_map_lookup_and_delete_element(fd_t map_fd, _In_ const void* key, _Out_ void
|
|||
static ebpf_result_t
|
||||
_update_map_element(
|
||||
ebpf_handle_t map_handle,
|
||||
_In_ const void* key,
|
||||
_In_opt_ const void* key,
|
||||
uint32_t key_size,
|
||||
_In_ const void* value,
|
||||
uint32_t value_size,
|
||||
|
@ -402,7 +407,9 @@ _update_map_element(
|
|||
request->header.id = ebpf_operation_id_t::EBPF_OPERATION_MAP_UPDATE_ELEMENT;
|
||||
request->handle = (uint64_t)map_handle;
|
||||
request->option = static_cast<ebpf_map_option_t>(flags);
|
||||
std::copy((uint8_t*)key, (uint8_t*)key + key_size, request->data);
|
||||
if (key_size > 0) {
|
||||
std::copy((uint8_t*)key, (uint8_t*)key + key_size, request->data);
|
||||
}
|
||||
std::copy((uint8_t*)value, (uint8_t*)value + value_size, request->data + key_size);
|
||||
|
||||
result = win32_error_code_to_ebpf_result(invoke_ioctl(request_buffer));
|
||||
|
@ -441,7 +448,7 @@ _update_map_element_with_handle(
|
|||
}
|
||||
|
||||
ebpf_result_t
|
||||
ebpf_map_update_element(fd_t map_fd, _In_ const void* key, _In_ const void* value, uint64_t flags)
|
||||
ebpf_map_update_element(fd_t map_fd, _In_opt_ const void* key, _In_ const void* value, uint64_t flags)
|
||||
{
|
||||
ebpf_result_t result = EBPF_SUCCESS;
|
||||
ebpf_handle_t map_handle;
|
||||
|
@ -450,7 +457,7 @@ ebpf_map_update_element(fd_t map_fd, _In_ const void* key, _In_ const void* valu
|
|||
uint32_t max_entries = 0;
|
||||
uint32_t type;
|
||||
|
||||
if (map_fd <= 0 || key == nullptr || value == nullptr) {
|
||||
if (map_fd <= 0 || value == nullptr) {
|
||||
return EBPF_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
|
@ -473,7 +480,9 @@ ebpf_map_update_element(fd_t map_fd, _In_ const void* key, _In_ const void* valu
|
|||
if (result != EBPF_SUCCESS) {
|
||||
return result;
|
||||
}
|
||||
assert(key_size != 0);
|
||||
if ((key == nullptr) != (key_size == 0)) {
|
||||
return EBPF_INVALID_ARGUMENT;
|
||||
}
|
||||
assert(value_size != 0);
|
||||
assert(type != 0);
|
||||
|
||||
|
@ -489,6 +498,8 @@ ebpf_map_update_element(fd_t map_fd, _In_ const void* key, _In_ const void* valu
|
|||
}
|
||||
}
|
||||
|
||||
assert(key_size != 0);
|
||||
__analysis_assume(key_size != 0);
|
||||
return _update_map_element_with_handle(map_handle, key_size, (const uint8_t*)key, handle, flags);
|
||||
} else {
|
||||
return _update_map_element(map_handle, key, key_size, value, value_size, flags);
|
||||
|
@ -605,12 +616,12 @@ ebpf_map_get_next_key(fd_t map_fd, _In_opt_ const void* previous_key, _Out_ void
|
|||
|
||||
result = win32_error_code_to_ebpf_result(invoke_ioctl(request_buffer, reply_buffer));
|
||||
|
||||
if (reply->header.id != ebpf_operation_id_t::EBPF_OPERATION_MAP_GET_NEXT_KEY) {
|
||||
result = EBPF_INVALID_ARGUMENT;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if (result == EBPF_SUCCESS) {
|
||||
if (reply->header.id != ebpf_operation_id_t::EBPF_OPERATION_MAP_GET_NEXT_KEY) {
|
||||
result = EBPF_INVALID_ARGUMENT;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
std::copy(reply->next_key, reply->next_key + key_size, (uint8_t*)next_key);
|
||||
}
|
||||
} catch (const std::bad_alloc&) {
|
||||
|
@ -963,29 +974,6 @@ ebpf_program_query_info(
|
|||
return win32_error_code_to_ebpf_result(retval);
|
||||
}
|
||||
|
||||
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 = {
|
||||
EBPF_OFFSET_OF(ebpf_operation_link_program_request_t, data),
|
||||
EBPF_OPERATION_LINK_PROGRAM,
|
||||
program_handle,
|
||||
attach_type};
|
||||
ebpf_operation_link_program_reply_t reply;
|
||||
|
||||
uint32_t retval = invoke_ioctl(request, reply);
|
||||
if (retval != ERROR_SUCCESS) {
|
||||
return retval;
|
||||
}
|
||||
|
||||
if (reply.header.id != ebpf_operation_id_t::EBPF_OPERATION_LINK_PROGRAM) {
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
*link_handle = reply.link_handle;
|
||||
return retval;
|
||||
}
|
||||
|
||||
static ebpf_result_t
|
||||
_link_ebpf_program(
|
||||
ebpf_handle_t program_handle,
|
||||
|
@ -2663,15 +2651,6 @@ ebpf_program_get_fd(_In_ const struct bpf_program* program)
|
|||
return program->fd;
|
||||
}
|
||||
|
||||
fd_t
|
||||
ebpf_map_get_fd(_In_ const struct bpf_map* map)
|
||||
{
|
||||
if (map == nullptr) {
|
||||
return ebpf_fd_invalid;
|
||||
}
|
||||
return map->map_fd;
|
||||
}
|
||||
|
||||
void
|
||||
ebpf_object_close(_In_opt_ _Post_invalid_ struct bpf_object* object)
|
||||
{
|
||||
|
|
|
@ -1359,10 +1359,13 @@ static ebpf_result_t
|
|||
_find_circular_map_entry(
|
||||
_In_ ebpf_core_map_t* map, _In_opt_ const uint8_t* key, _In_ bool delete_on_success, _Outptr_ uint8_t** data)
|
||||
{
|
||||
// Queue uses no key, so key must be NULL.
|
||||
if (!map || key)
|
||||
if (!map)
|
||||
return EBPF_INVALID_ARGUMENT;
|
||||
|
||||
// Queue uses no key, but the caller always passes in a non-null pointer (with a 0 key size)
|
||||
// so we cannot require key to be null.
|
||||
UNREFERENCED_PARAMETER(key);
|
||||
|
||||
ebpf_core_circular_map_t* circular_map = EBPF_FROM_FIELD(ebpf_core_circular_map_t, core_map, map);
|
||||
ebpf_lock_state_t state = ebpf_lock_lock(&circular_map->lock);
|
||||
*data = _ebpf_core_circular_map_peek_or_pop(circular_map, delete_on_success);
|
||||
|
@ -1375,10 +1378,14 @@ _update_circular_map_entry(
|
|||
_In_ ebpf_core_map_t* map, _In_ const uint8_t* key, _In_opt_ const uint8_t* data, ebpf_map_option_t option)
|
||||
{
|
||||
ebpf_result_t result;
|
||||
// Queue uses no key, so key must be NULL.
|
||||
if (!map || key || !data)
|
||||
|
||||
if (!map || !data)
|
||||
return EBPF_INVALID_ARGUMENT;
|
||||
|
||||
// Queue uses no key, but the caller always passes in a non-null pointer (with a 0 key size)
|
||||
// so we cannot require key to be null.
|
||||
UNREFERENCED_PARAMETER(key);
|
||||
|
||||
ebpf_core_circular_map_t* circular_map = EBPF_FROM_FIELD(ebpf_core_circular_map_t, core_map, map);
|
||||
ebpf_lock_state_t state = ebpf_lock_lock(&circular_map->lock);
|
||||
result = _ebpf_core_circular_map_push(circular_map, data, option & BPF_EXIST);
|
||||
|
@ -1947,7 +1954,7 @@ ebpf_map_update_entry(
|
|||
switch (map->ebpf_map_definition.type) {
|
||||
case BPF_MAP_TYPE_QUEUE:
|
||||
case BPF_MAP_TYPE_STACK:
|
||||
if (key_size != 0 || key != NULL) {
|
||||
if (key_size != 0) {
|
||||
EBPF_LOG_MESSAGE_UINT64(
|
||||
EBPF_TRACELOG_LEVEL_ERROR,
|
||||
EBPF_TRACELOG_KEYWORD_MAP,
|
||||
|
|
|
@ -110,12 +110,6 @@ typedef class _single_instance_hook : public _hook_helper
|
|||
ebpf_provider_unload(provider);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
attach(ebpf_handle_t program_handle)
|
||||
{
|
||||
return ebpf_api_link_program(program_handle, attach_type, &link_handle);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
attach(bpf_program* program)
|
||||
{
|
||||
|
|
|
@ -470,6 +470,24 @@ TEST_CASE("libbpf create queue", "[libbpf]")
|
|||
int err = bpf_map_get_next_key(map_fd, NULL, &next_key);
|
||||
REQUIRE(err == -ENOTSUP);
|
||||
|
||||
// Push 2 elements.
|
||||
uint32_t value = 1;
|
||||
REQUIRE(bpf_map_update_elem(map_fd, nullptr, &value, 0) == 0);
|
||||
value = 2;
|
||||
REQUIRE(bpf_map_update_elem(map_fd, nullptr, &value, 0) == 0);
|
||||
|
||||
// Pop elements.
|
||||
REQUIRE(bpf_map_lookup_elem(map_fd, nullptr, &value) == 0);
|
||||
REQUIRE(value == 1);
|
||||
REQUIRE(bpf_map_lookup_and_delete_elem(map_fd, nullptr, &value) == 0);
|
||||
REQUIRE(value == 1);
|
||||
REQUIRE(bpf_map_lookup_elem(map_fd, nullptr, &value) == 0);
|
||||
REQUIRE(value == 2);
|
||||
REQUIRE(bpf_map_lookup_and_delete_elem(map_fd, nullptr, &value) == 0);
|
||||
REQUIRE(value == 2);
|
||||
REQUIRE(bpf_map_lookup_elem(map_fd, nullptr, &value) == -ENOENT);
|
||||
REQUIRE(bpf_map_lookup_and_delete_elem(map_fd, nullptr, &value) == -ENOENT);
|
||||
|
||||
Platform::_close(map_fd);
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче