2021-06-10 22:02:00 +03:00
|
|
|
// Copyright (c) Microsoft Corporation
|
|
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
|
2021-03-10 05:38:31 +03:00
|
|
|
#pragma once
|
2021-04-16 02:15:00 +03:00
|
|
|
|
Rename ebpf_helpers.h to bpf_helpers.h for cross-plat compat (#472)
Libbpf has bpf_helpers.h which is mostly platform-agnostic, and
bpf_helper_defs.h which is platform-specific but is included
by bpf_helpers.h. Until libbpf is made more platform-agnostic
(issue #351), the workaround is to have a separate pair of files.
Our bpf_helpers.h and our own bpf_helper_defs.h, both of which
would ideally be merged into libbpf's in the future.
Platform-specific defines are in ebpf_struct.h, though that
name may need to change later on. Linux uses "linux/bpf.h"
(e.g., as used in the https://docs.cilium.io/en/v1.8/bpf/ and
https://developers.redhat.com/blog/2021/04/01/get-started-with-xdp
articles) or "vmlinux.h" (e.g., as used in the
https://ruderich.org/simon/notes/xdp-minimal-example article),
and these filenames are hard coded in eBPF programs. In the future,
we should probably settle on a cross-platform name and use include
paths to distinguish them, as opposed to requiring ifdefs in eBPF
programs. However, all of that is part of issue 351 and not this
issue.
Also removed obsolete/unused "repro.c" from tests/samples
Fixes #426
Signed-off-by: Dave Thaler <dthaler@microsoft.com>
Co-authored-by: Alan Jowett <alanjo@microsoft.com>
2021-09-02 02:30:33 +03:00
|
|
|
#include "bpf_helpers.h"
|
2023-02-07 21:32:19 +03:00
|
|
|
#include "ebpf_core_structs.h"
|
2021-03-10 05:38:31 +03:00
|
|
|
#include "ebpf_platform.h"
|
|
|
|
|
2021-04-23 18:42:55 +03:00
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C"
|
|
|
|
{
|
|
|
|
#endif
|
2021-04-16 21:59:38 +03:00
|
|
|
|
2021-09-30 03:47:30 +03:00
|
|
|
#define EBPF_MAP_FLAG_HELPER 0x01 /* Called by an eBPF program. */
|
|
|
|
#define EPBF_MAP_FIND_FLAG_DELETE 0x02 /* Perform a find and delete. */
|
|
|
|
|
2021-04-23 18:42:55 +03:00
|
|
|
typedef struct _ebpf_core_map ebpf_map_t;
|
2021-04-16 21:59:38 +03:00
|
|
|
|
2021-04-23 19:48:13 +03:00
|
|
|
/**
|
|
|
|
* @brief Allocate a new map.
|
|
|
|
*
|
2021-08-11 03:04:07 +03:00
|
|
|
* @param[in] map_name Name of the map.
|
2021-04-23 19:48:13 +03:00
|
|
|
* @param[in] ebpf_map_definition Definition of the new map.
|
2021-08-31 05:14:08 +03:00
|
|
|
* @param[in] inner_map_handle Handle to inner map, or ebpf_handle_invalid if none.
|
2021-04-23 19:48:13 +03:00
|
|
|
* @param[out] map Pointer to memory that will contain the map on success.
|
2021-05-20 22:38:58 +03:00
|
|
|
* @retval EBPF_SUCCESS The operation was successful.
|
|
|
|
* @retval EBPF_NO_MEMORY Unable to allocate resources for this
|
2021-04-23 19:48:13 +03:00
|
|
|
* map.
|
|
|
|
*/
|
2022-11-14 20:40:21 +03:00
|
|
|
_Must_inspect_result_ ebpf_result_t
|
2021-08-11 03:04:07 +03:00
|
|
|
ebpf_map_create(
|
|
|
|
_In_ const ebpf_utf8_string_t* map_name,
|
2021-08-31 05:14:08 +03:00
|
|
|
_In_ const ebpf_map_definition_in_memory_t* ebpf_map_definition,
|
2021-09-14 18:25:56 +03:00
|
|
|
ebpf_handle_t inner_map_handle,
|
2021-08-11 03:04:07 +03:00
|
|
|
_Outptr_ ebpf_map_t** map);
|
2021-04-16 21:59:38 +03:00
|
|
|
|
2021-04-23 19:48:13 +03:00
|
|
|
/**
|
|
|
|
* @brief Get a pointer to the map definition.
|
|
|
|
*
|
|
|
|
* @param[in] map Map to get definition from.
|
|
|
|
* @return Pointer to map definition.
|
|
|
|
*/
|
2021-08-31 05:14:08 +03:00
|
|
|
const ebpf_map_definition_in_memory_t*
|
2021-06-16 23:27:22 +03:00
|
|
|
ebpf_map_get_definition(_In_ const ebpf_map_t* map);
|
2021-04-16 21:59:38 +03:00
|
|
|
|
2021-08-18 02:22:32 +03:00
|
|
|
/**
|
|
|
|
* @brief Get the map value size specified when the map was originally
|
|
|
|
* created. For per-cpu maps this will be different from the value in the
|
|
|
|
* returned ebpf_map_definition_t.
|
|
|
|
*
|
|
|
|
* @param[in] map Map to query
|
2022-12-12 20:56:51 +03:00
|
|
|
* @return Effective value size of the entry.
|
2021-08-18 02:22:32 +03:00
|
|
|
*/
|
|
|
|
uint32_t
|
|
|
|
ebpf_map_get_effective_value_size(_In_ const ebpf_map_t* map);
|
|
|
|
|
2021-04-23 19:48:13 +03:00
|
|
|
/**
|
|
|
|
* @brief Get a pointer to an entry in the map.
|
|
|
|
*
|
2022-12-16 02:58:33 +03:00
|
|
|
* @param[in, out] map Map to search and update metadata in.
|
2021-04-23 19:48:13 +03:00
|
|
|
* @param[in] key Key to use when searching map.
|
2021-08-06 23:18:47 +03:00
|
|
|
* @param[in] flags Zero or more EBPF_MAP_FIND_ENTRY_FLAG_* flags.
|
2021-04-23 19:48:13 +03:00
|
|
|
* @return Pointer to the value if found or NULL.
|
|
|
|
*/
|
2022-11-14 20:40:21 +03:00
|
|
|
_Must_inspect_result_ ebpf_result_t
|
2021-08-13 22:13:16 +03:00
|
|
|
ebpf_map_find_entry(
|
2022-12-16 02:58:33 +03:00
|
|
|
_Inout_ ebpf_map_t* map,
|
2021-08-13 22:13:16 +03:00
|
|
|
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);
|
2021-04-16 21:59:38 +03:00
|
|
|
|
2021-04-23 19:48:13 +03:00
|
|
|
/**
|
|
|
|
* @brief Insert or update an entry in the map.
|
|
|
|
*
|
2022-12-16 02:58:33 +03:00
|
|
|
* @param[in, out] map Map to update.
|
2021-04-23 19:48:13 +03:00
|
|
|
* @param[in] key Key to use when searching and updating the map.
|
|
|
|
* @param[in] value Value to insert into the map.
|
2021-08-24 00:49:50 +03:00
|
|
|
* @param[in] option One of ebpf_map_option_t options.
|
|
|
|
* @param[in] flags EBPF_MAP_FLAG_HELPER if called from helper function.
|
2021-05-20 22:38:58 +03:00
|
|
|
* @retval EBPF_SUCCESS The operation was successful.
|
2022-12-12 20:56:51 +03:00
|
|
|
* @retval EBPF_NO_MEMORY Unable to allocate resources for this entry.
|
2021-04-23 19:48:13 +03:00
|
|
|
*/
|
2022-11-14 20:40:21 +03:00
|
|
|
_Must_inspect_result_ ebpf_result_t
|
2021-08-13 22:13:16 +03:00
|
|
|
ebpf_map_update_entry(
|
2022-12-16 02:58:33 +03:00
|
|
|
_Inout_ ebpf_map_t* map,
|
2021-08-13 22:13:16 +03:00
|
|
|
size_t key_size,
|
|
|
|
_In_reads_(key_size) const uint8_t* key,
|
|
|
|
size_t value_size,
|
|
|
|
_In_reads_(value_size) const uint8_t* value,
|
2021-08-24 00:49:50 +03:00
|
|
|
ebpf_map_option_t option,
|
2021-08-13 22:13:16 +03:00
|
|
|
int flags);
|
2021-04-16 21:59:38 +03:00
|
|
|
|
2021-08-06 23:18:47 +03:00
|
|
|
/**
|
|
|
|
* @brief Insert or update an entry in the map.
|
|
|
|
*
|
2022-12-16 02:58:33 +03:00
|
|
|
* @param[in, out] map Map to update.
|
2021-08-06 23:18:47 +03:00
|
|
|
* @param[in] key Key to use when searching and updating the map.
|
2021-09-10 02:02:42 +03:00
|
|
|
* @param[in] value_handle Handle associated with the value to insert.
|
2021-08-24 04:46:24 +03:00
|
|
|
* @param[in] option One of ebpf_map_option_t options.
|
2021-08-06 23:18:47 +03:00
|
|
|
* @retval EBPF_SUCCESS The operation was successful.
|
|
|
|
* @retval EBPF_NO_MEMORY Unable to allocate resources for this
|
|
|
|
* entry.
|
|
|
|
*/
|
2022-11-14 20:40:21 +03:00
|
|
|
_Must_inspect_result_ ebpf_result_t
|
2021-08-06 23:18:47 +03:00
|
|
|
ebpf_map_update_entry_with_handle(
|
2022-12-16 02:58:33 +03:00
|
|
|
_Inout_ ebpf_map_t* map,
|
2021-08-13 22:13:16 +03:00
|
|
|
size_t key_size,
|
|
|
|
_In_reads_(key_size) const uint8_t* key,
|
2021-08-24 04:46:24 +03:00
|
|
|
uintptr_t value_handle,
|
|
|
|
ebpf_map_option_t option);
|
2021-08-06 23:18:47 +03:00
|
|
|
|
2021-04-23 19:48:13 +03:00
|
|
|
/**
|
|
|
|
* @brief Remove an entry from the map.
|
|
|
|
*
|
|
|
|
* @param[in] map Map to update.
|
|
|
|
* @param[in] key Key to use when searching and updating the map.
|
2021-05-20 22:38:58 +03:00
|
|
|
* @retval EBPF_SUCCESS The operation was successful.
|
|
|
|
* @retval EBPF_INVALID_ARGUMENT One or more parameters are
|
2021-04-23 19:48:13 +03:00
|
|
|
* invalid.
|
|
|
|
*/
|
2022-11-14 20:40:21 +03:00
|
|
|
_Must_inspect_result_ ebpf_result_t
|
2021-08-24 00:49:50 +03:00
|
|
|
ebpf_map_delete_entry(_In_ ebpf_map_t* map, size_t key_size, _In_reads_(key_size) const uint8_t* key, int flags);
|
2021-04-23 18:42:55 +03:00
|
|
|
|
2021-04-23 19:48:13 +03:00
|
|
|
/**
|
|
|
|
* @brief Retrieve the next key from the map.
|
|
|
|
*
|
2022-12-16 02:58:33 +03:00
|
|
|
* @param[in, out] map Map to search and update metadata in.
|
2021-04-23 19:48:13 +03:00
|
|
|
* @param[in] previous_key The previous key need not be present. This will
|
2021-06-16 23:27:22 +03:00
|
|
|
* return the next key lexicographically after the specified key. A value of
|
|
|
|
* null indicates that the first key is to be returned.
|
|
|
|
* @param[out] next_key Next key on success.
|
2021-05-20 22:38:58 +03:00
|
|
|
* @retval EBPF_SUCCESS The operation was successful.
|
|
|
|
* @retval EBPF_NO_MORE_KEYS There is no key following the specified
|
2022-12-12 20:56:51 +03:00
|
|
|
* key in lexicographical order.
|
2021-04-23 19:48:13 +03:00
|
|
|
*/
|
2022-11-14 20:40:21 +03:00
|
|
|
_Must_inspect_result_ ebpf_result_t
|
2021-08-13 22:13:16 +03:00
|
|
|
ebpf_map_next_key(
|
2022-12-16 02:58:33 +03:00
|
|
|
_Inout_ ebpf_map_t* map,
|
2021-08-13 22:13:16 +03:00
|
|
|
size_t key_size,
|
|
|
|
_In_reads_opt_(key_size) const uint8_t* previous_key,
|
|
|
|
_Out_writes_(key_size) uint8_t* next_key);
|
2021-04-23 18:42:55 +03:00
|
|
|
|
2021-08-06 23:18:47 +03:00
|
|
|
/**
|
|
|
|
* @brief Get a program from an entry in a map that holds programs. The
|
|
|
|
* program returned holds a reference that the caller is responsible for
|
|
|
|
* releasing.
|
|
|
|
*
|
2022-12-16 02:58:33 +03:00
|
|
|
* @param[in, out] map Map to search and update metadata in.
|
2021-08-06 23:18:47 +03:00
|
|
|
* @param[in] key Pointer to key to search for.
|
|
|
|
* @param[in] key_size Size of value to search for.
|
|
|
|
* @returns Program pointer, or NULL if none.
|
|
|
|
*/
|
|
|
|
_Ret_maybenull_ struct _ebpf_program*
|
2022-12-16 02:58:33 +03:00
|
|
|
ebpf_map_get_program_from_entry(_Inout_ ebpf_map_t* map, size_t key_size, _In_reads_(key_size) const uint8_t* key);
|
2021-08-06 23:18:47 +03:00
|
|
|
|
2021-08-11 22:17:10 +03:00
|
|
|
/**
|
|
|
|
* @brief Let a map take any actions when first
|
|
|
|
* associated with a program.
|
|
|
|
*
|
2022-12-16 02:58:33 +03:00
|
|
|
* @param[in, out] map Map to update.
|
2021-08-11 22:17:10 +03:00
|
|
|
* @param[in] program Program being associated with.
|
|
|
|
*
|
|
|
|
* @retval EBPF_SUCCESS The operation was successful.
|
|
|
|
* @retval EBPF_INVALID_FD The program is incompatible with this map.
|
|
|
|
*/
|
2022-11-14 20:40:21 +03:00
|
|
|
_Must_inspect_result_ ebpf_result_t
|
2022-12-16 02:58:33 +03:00
|
|
|
ebpf_map_associate_program(_Inout_ ebpf_map_t* map, _In_ const struct _ebpf_program* program);
|
2021-08-11 22:17:10 +03:00
|
|
|
|
2021-09-11 07:54:07 +03:00
|
|
|
/**
|
|
|
|
* @brief Get bpf_map_info about a map.
|
|
|
|
*
|
|
|
|
* @param[in] map The map to get info about.
|
|
|
|
* @param[out] buffer Buffer to write bpf_map_info into.
|
2022-12-16 02:58:33 +03:00
|
|
|
* @param[in, out] info_size On input, the size in bytes of the buffer.
|
2021-09-11 07:54:07 +03:00
|
|
|
* On output, the number of bytes actually written.
|
|
|
|
*
|
|
|
|
* @retval EBPF_SUCCESS The operation was successful.
|
|
|
|
* @retval EBPF_INSUFFICIENT_BUFFER The buffer was too small to hold bpf_map_info.
|
|
|
|
*/
|
2022-11-14 20:40:21 +03:00
|
|
|
_Must_inspect_result_ ebpf_result_t
|
2021-09-11 07:54:07 +03:00
|
|
|
ebpf_map_get_info(
|
|
|
|
_In_ const ebpf_map_t* map,
|
|
|
|
_Out_writes_to_(*info_size, *info_size) uint8_t* buffer,
|
|
|
|
_Inout_ uint16_t* info_size);
|
|
|
|
|
2021-10-14 23:22:35 +03:00
|
|
|
/**
|
2021-12-04 00:19:21 +03:00
|
|
|
* @brief Get pointer to the ring buffer map's shared data.
|
2021-10-14 23:22:35 +03:00
|
|
|
*
|
2021-12-04 00:19:21 +03:00
|
|
|
* @param[in] map Ring buffer map to query.
|
|
|
|
* @param[out] buffer Pointer to ring buffer data.
|
|
|
|
* @retval EPBF_SUCCESS Successfully mapped the ring buffer.
|
|
|
|
* @retval EBPF_INVALID_ARGUMENT Unable to map the ring buffer.
|
|
|
|
*/
|
2022-11-14 20:40:21 +03:00
|
|
|
_Must_inspect_result_ ebpf_result_t
|
2021-12-04 00:19:21 +03:00
|
|
|
ebpf_ring_buffer_map_query_buffer(_In_ const ebpf_map_t* map, _Outptr_ uint8_t** buffer);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Return consumed buffer back to the ring buffer map.
|
|
|
|
*
|
|
|
|
* @param[in] map Ring buffer map.
|
|
|
|
* @param[in] length Length of bytes to return to the ring buffer.
|
|
|
|
* @retval EPBF_SUCCESS Successfully returned records to the ring buffer.
|
|
|
|
* @retval EBPF_INVALID_ARGUMENT Unable to return records to the ring buffer.
|
|
|
|
*/
|
2022-11-14 20:40:21 +03:00
|
|
|
_Must_inspect_result_ ebpf_result_t
|
2021-12-04 00:19:21 +03:00
|
|
|
ebpf_ring_buffer_map_return_buffer(_In_ const ebpf_map_t* map, size_t length);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Issue an asynchronous query to ring buffer map.
|
|
|
|
*
|
2022-12-16 02:58:33 +03:00
|
|
|
* @param[in, out] map Ring buffer map to issue the async query on.
|
2021-12-04 00:19:21 +03:00
|
|
|
* @param[in, out] async_query_result Pointer to structure for storing result of the async query.
|
2022-12-16 02:58:33 +03:00
|
|
|
* @param[in, out] async_context Async context associated with the query.
|
2021-10-14 23:22:35 +03:00
|
|
|
* @retval EBPF_SUCCESS The operation was successful.
|
|
|
|
* @retval EBPF_NO_MEMORY Insufficient memory to complete this operation.
|
|
|
|
*/
|
2022-11-14 20:40:21 +03:00
|
|
|
_Must_inspect_result_ ebpf_result_t
|
2021-12-04 00:19:21 +03:00
|
|
|
ebpf_ring_buffer_map_async_query(
|
2022-12-16 02:58:33 +03:00
|
|
|
_Inout_ ebpf_map_t* map,
|
2021-12-04 00:19:21 +03:00
|
|
|
_Inout_ ebpf_ring_buffer_map_async_query_result_t* async_query_result,
|
2022-12-16 02:58:33 +03:00
|
|
|
_Inout_ void* async_context);
|
2021-12-04 00:19:21 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Write out a variable sized record to the ring buffer map.
|
|
|
|
*
|
2022-12-16 02:58:33 +03:00
|
|
|
* @param[in, out] map Pointer to map of type EBPF_MAP_TYPE_RINGBUF.
|
2021-12-04 00:19:21 +03:00
|
|
|
* @param[in] data Data of record to write into ring buffer map.
|
|
|
|
* @param[in] length Length of data.
|
|
|
|
* @retval EPBF_SUCCESS Successfully wrote record into ring buffer.
|
|
|
|
* @retval EBPF_OUT_OF_SPACE Unable to output to ring buffer due to inadequate space.
|
|
|
|
*/
|
2022-11-14 20:40:21 +03:00
|
|
|
_Must_inspect_result_ ebpf_result_t
|
2022-12-16 02:58:33 +03:00
|
|
|
ebpf_ring_buffer_map_output(_Inout_ ebpf_map_t* map, _In_reads_bytes_(length) uint8_t* data, size_t length);
|
2021-10-14 23:22:35 +03:00
|
|
|
|
2022-03-12 03:16:02 +03:00
|
|
|
/**
|
|
|
|
* @brief Insert an element at the end of the map (only valid for stack and queue).
|
|
|
|
*
|
2022-12-16 02:58:33 +03:00
|
|
|
* @param[in, out] map Map to update.
|
2022-03-12 03:16:02 +03:00
|
|
|
* @param[in] value_size Size of value to insert into the map.
|
|
|
|
* @param[in] value Value to insert into the map.
|
|
|
|
* @param[in] flags Map flags - BPF_EXIST: If the map is full, the entry at the start of the map is discarded.
|
|
|
|
* @retval EBPF_SUCCESS The operation was successful.
|
|
|
|
* @retval EBPF_NO_MEMORY Unable to allocate resources for this
|
|
|
|
* entry.
|
|
|
|
* @retval EBPF_OUT_OF_SPACE Map is full and BPF_EXIST was not supplied.
|
|
|
|
*/
|
2022-11-14 20:40:21 +03:00
|
|
|
_Must_inspect_result_ ebpf_result_t
|
2022-03-12 03:16:02 +03:00
|
|
|
ebpf_map_push_entry(
|
2022-12-16 02:58:33 +03:00
|
|
|
_Inout_ ebpf_map_t* map, size_t value_size, _In_reads_(value_size) const uint8_t* value, int flags);
|
2022-03-12 03:16:02 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Copy an entry from the map and remove it from the map (only valid for stack and queue).
|
|
|
|
* Queue pops from the beginning of the map.
|
|
|
|
* Stack pops from the end of the map.
|
|
|
|
*
|
2022-12-16 02:58:33 +03:00
|
|
|
* @param[in, out] map Map to search and update metadata on.
|
2022-03-12 03:16:02 +03:00
|
|
|
* @param[in] value_size Size of the value buffer to copy value from map into.
|
|
|
|
* @param[out] value Value buffer to copy value from map into.
|
|
|
|
* @retval EBPF_SUCCESS The operation was successful.
|
|
|
|
* @retval EBPF_OBJECT_NOT_FOUND The map is empty.
|
|
|
|
*/
|
2022-11-14 20:40:21 +03:00
|
|
|
_Must_inspect_result_ ebpf_result_t
|
2022-12-16 02:58:33 +03:00
|
|
|
ebpf_map_pop_entry(_Inout_ ebpf_map_t* map, size_t value_size, _Out_writes_(value_size) uint8_t* value, int flags);
|
2022-03-12 03:16:02 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Copy an entry from the map (only valid for stack and queue).
|
|
|
|
* Queue peeks at the beginning of the map.
|
|
|
|
* Stack peeks at the end of the map.
|
|
|
|
*
|
2022-12-16 02:58:33 +03:00
|
|
|
* @param[in, out] map Map to search and update metadata on.
|
2022-03-12 03:16:02 +03:00
|
|
|
* @param[in] value_size Size of the value buffer to copy value from map into.
|
|
|
|
* @param[out] value Value buffer to copy value from map into.
|
|
|
|
* @retval EBPF_SUCCESS The operation was successful.
|
|
|
|
* @retval EBPF_OBJECT_NOT_FOUND The map is empty.
|
|
|
|
*/
|
2022-11-14 20:40:21 +03:00
|
|
|
_Must_inspect_result_ ebpf_result_t
|
2022-12-16 02:58:33 +03:00
|
|
|
ebpf_map_peek_entry(_Inout_ ebpf_map_t* map, size_t value_size, _Out_writes_(value_size) uint8_t* value, int flags);
|
2022-03-12 03:16:02 +03:00
|
|
|
|
2022-09-30 22:12:12 +03:00
|
|
|
/**
|
|
|
|
* @brief Get the ID of a given map.
|
|
|
|
*
|
|
|
|
* @param[in] map Map to get ID of.
|
|
|
|
* @returns Map ID.
|
|
|
|
*/
|
|
|
|
ebpf_id_t
|
|
|
|
ebpf_map_get_id(_In_ const ebpf_map_t* map);
|
2021-04-23 18:42:55 +03:00
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|