ebpf-for-windows/libs/execution_context/ebpf_program.h

347 строки
14 KiB
C

// Copyright (c) Microsoft Corporation
// SPDX-License-Identifier: MIT
#pragma once
#include "ebpf_link.h"
#include "ebpf_maps.h"
#include "ebpf_platform.h"
#include "ebpf_program_types.h"
#include "ebpf_protocol.h"
#ifdef __cplusplus
extern "C"
{
#endif
typedef enum _ebpf_code_type ebpf_code_type_t;
typedef struct _ebpf_instruction
{
uint8_t opcode;
uint8_t dst : 4; //< Destination register
uint8_t src : 4; //< Source register
int16_t offset;
int32_t imm; //< Immediate constant
} ebpf_instruction_t;
typedef struct _ebpf_program_parameters
{
ebpf_program_type_t program_type;
ebpf_attach_type_t expected_attach_type;
ebpf_utf8_string_t program_name;
ebpf_utf8_string_t section_name;
ebpf_utf8_string_t file_name;
ebpf_code_type_t code_type;
const uint8_t* program_info_hash;
size_t program_info_hash_length;
} ebpf_program_parameters_t;
typedef ebpf_result_t (*ebpf_program_entry_point_t)(void* context);
/**
* @brief Initialize global state for the ebpf program module.
*
* @retval EBPF_SUCCESS The operation was successful.
* @retval EBPF_NO_MEMORY Unable to allocate resources for this
* operation.
*/
_Must_inspect_result_ ebpf_result_t
ebpf_program_initiate();
/**
* @brief Uninitialize the eBPF state tracking module.
*
*/
void
ebpf_program_terminate();
/**
* @brief Create a new program instance.
*
* @param[out] program Pointer to memory that will contain the program instance.
* @retval EBPF_SUCCESS The operation was successful.
* @retval EBPF_NO_MEMORY Unable to allocate resources for this
* program instance.
*/
_Must_inspect_result_ ebpf_result_t
ebpf_program_create(_Outptr_ ebpf_program_t** program);
/**
* @brief Initialize a program instance from the provided program
* parameters.
*
* @param[in, out] program Program instance to initialize.
* @param[in] program_parameters Program parameters to be used to initialize
* the program instance.
* @retval EBPF_SUCCESS The operation was successful.
* @retval EBPF_NO_MEMORY Unable to allocate resources for this
* program instance.
*/
_Must_inspect_result_ ebpf_result_t
ebpf_program_initialize(_Inout_ ebpf_program_t* program, _In_ const ebpf_program_parameters_t* program_parameters);
/**
* @brief Get parameters describing the program instance.
*
* @param[in] program Program instance to query.
* @returns Pointer to parameters of the program.
*/
_Ret_notnull_ const ebpf_program_parameters_t*
ebpf_program_get_parameters(_In_ const ebpf_program_t* program);
_Ret_notnull_ const ebpf_program_type_t*
ebpf_program_type_uuid(_In_ const ebpf_program_t* program);
_Ret_notnull_ const ebpf_attach_type_t*
ebpf_expected_attach_type(_In_ const ebpf_program_t* program);
/**
* @brief Get the program info from the program info extension.
*
* @param[in] program Program that loaded the extension.
* @param[out] program_info Pointer to the output allocated program info. Must be freed by caller by calling
* ebpf_program_free_program_info().
* @retval EBPF_SUCCESS The operation was successful.
* @retval EBPF_INVALID_ARGUMENT One or more arguments are invalid.
* @retval EBPF_ARITHMETIC_OVERFLOW An arithmetic overflow has occurred.
* @retval EBPF_NO_MEMORY Output program info could not be allocated.
* @retval EBPF_ERROR_EXTENSION_FAILED_TO_LOAD The program info isn't
* available.
*/
_Must_inspect_result_ ebpf_result_t
ebpf_program_get_program_info(_In_ const ebpf_program_t* program, _Outptr_ ebpf_program_info_t** program_info);
/**
* @brief Free the program info allocated by ebpf_program_get_program_info().
*
* @param[in] program_info Program info to be freed.
*/
void
ebpf_program_free_program_info(_In_opt_ _Post_invalid_ ebpf_program_info_t* program_info);
/**
* @brief Associate a set of maps with this program instance.
*
* @param[in] program Program instance to associate with the maps.
* @param[in] maps Array of maps to associate with this program.
* @param[in] maps_count Count of elements in the maps array.
* @retval EBPF_SUCCESS The operation was successful.
* @retval EBPF_NO_MEMORY Unable to allocate resources for this
* program instance.
*/
_Must_inspect_result_ ebpf_result_t
ebpf_program_associate_maps(ebpf_program_t* program, ebpf_map_t** maps, uint32_t maps_count);
/**
* @brief Associate an additional map with this program instance.
*
* @param[in] program Program instance to associate with the map.
* @param[in] map Map to associate with this program.
* @retval EBPF_SUCCESS The operation was successful.
* @retval EBPF_NO_MEMORY Unable to allocate resources for this
* program instance.
*/
_Must_inspect_result_ ebpf_result_t
ebpf_program_associate_additional_map(ebpf_program_t* program, ebpf_map_t* map);
/**
* @brief Load a block of eBPF code into the program instance.
*
* @param[in, out] program Program instance to load the eBPF code into.
* @param[in] code_type Specifies whether eBPF code is JIT compiled or byte code.
* @param[in] code_context Optionally, pointer to code context.
* @param[in] code Pointer to memory containing the eBPF code.
* @param[in] code_size Size of the memory block containing the eBPF
* code.
* @retval EBPF_SUCCESS The operation was successful.
* @retval EBPF_NO_MEMORY Unable to allocate resources for this
* program instance.
*/
_Must_inspect_result_ ebpf_result_t
ebpf_program_load_code(
_Inout_ ebpf_program_t* program,
ebpf_code_type_t code_type,
_In_opt_ const void* code_context,
_In_reads_(code_size) const uint8_t* code,
size_t code_size);
/**
* @brief Invoke an ebpf_program_t instance.
*
* @param[in] program Program to invoke.
* @param[in] context Pointer to eBPF context for this program.
* @param[out] result Output from the program.
*/
void
ebpf_program_invoke(_In_ const ebpf_program_t* program, _Inout_ void* context, _Out_ uint32_t* result);
/**
* @brief Store the helper function IDs that are used by the eBPF program in an array
* inside the program object. The array index is the helper function ID to be used by
* uBPF whereas the array value is the actual helper ID.
*
* @param[in, out] program Program object to query this on.
* @param[in] helper_function_count Count of helper functions.
* @param[in] helper_function_ids Array of helper function IDs to store.
* @retval EBPF_SUCCESS The operation was successful.
* @retval EBPF_INVALID_ARGUMENT The helper function IDs array is already populated.
* @retval EBPF_NO_MEMORY Could not allocate array of helper function IDs.
*/
_Must_inspect_result_ ebpf_result_t
ebpf_program_set_helper_function_ids(
_Inout_ ebpf_program_t* program,
const size_t helper_function_count,
_In_reads_(helper_function_count) const uint32_t* helper_function_ids);
/**
* @brief Get the addresses of helper functions referred to by the program. Assumes
* ebpf_program_set_helper_function_ids has already been invoked on the program object.
*
* @param[in] program Program object to query this on.
* @param[in] addresses_count Length of caller supplied output array.
* @param[out] address Caller supplied output array where the addresses of the helper functions are written to.
* @retval EBPF_SUCCESS The operation was successful.
* @retval EBPF_INSUFFICIENT_BUFFER Output array is insufficient.
* @retval EBPF_INVALID_ARGUMENT At least one helper function id is not valid.
*/
_Must_inspect_result_ ebpf_result_t
ebpf_program_get_helper_function_addresses(
_In_ const ebpf_program_t* program,
const size_t addresses_count,
_Out_writes_(addresses_count) uint64_t* addresses);
/**
* @brief Attach a link object to an eBPF program.
*
* @param[in, out] program Program to attach to the link object.
* @param[in, out] link The link object.
*/
void
ebpf_program_attach_link(_Inout_ ebpf_program_t* program, _Inout_ ebpf_link_t* link);
/**
* @brief Detach a link object from the eBPF program it is attached to.
*
* @param[in, out] program Program to detach to the link object from.
* @param[in, out] link The link object.
*/
void
ebpf_program_detach_link(_Inout_ ebpf_program_t* program, _Inout_ ebpf_link_t* link);
/**
* @brief Store the pointer to the program to execute on tail call.
*
* @param[in] next_program Next program to execute.
* @retval EBPF_SUCCESS The operation was successful.
* @retval EBPF_INVALID_ARGUMENT Internal error.
* @retval EBPF_NO_MORE_TAIL_CALLS Program has executed to many tail calls.
*/
_Must_inspect_result_ ebpf_result_t
ebpf_program_set_tail_call(_In_ const ebpf_program_t* next_program);
/**
* @brief Get bpf_prog_info about a program.
*
* @param[in] program The program to get info about.
* @param[in] input_buffer Buffer to read bpf_prog_info from.
* @param[out] output_buffer Buffer to write bpf_prog_info into.
* @param[in, out] info_size On input, the size in bytes of the buffer.
* 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_prog_info.
*/
_Must_inspect_result_ ebpf_result_t
ebpf_program_get_info(
_In_ const ebpf_program_t* program,
_In_reads_(*info_size) const uint8_t* input_buffer,
_Out_writes_to_(*info_size, *info_size) uint8_t* output_buffer,
_Inout_ uint16_t* info_size);
/**
* @brief Create a new program instance and initialize the instance from
* the provided program parameters.
*
* @param[in] parameters Program parameters to be used to initialize
* the program instance.
* @param[out] program_handle Handle to the created program instance.
*
* @retval EBPF_SUCCESS The operation was successful.
* @retval EBPF_NO_MEMORY Unable to allocate resources for this
* program instance.
*/
_Must_inspect_result_ ebpf_result_t
ebpf_program_create_and_initialize(
_In_ const ebpf_program_parameters_t* parameters, _Out_ ebpf_handle_t* program_handle);
typedef struct _ebpf_program_test_run_options
{
_Readable_bytes_(data_size_in) const uint8_t* data_in; ///< Input data to the program.
_Writable_bytes_(data_size_out) uint8_t* data_out; ///< Output data from the program.
size_t data_size_in; ///< Size of input data.
size_t data_size_out; ///< Maximum length of data_out on input and actual length of data_out on output.
_Readable_bytes_(context_size_in) const uint8_t* context_in; ///< Input context to the program.
_Writable_bytes_(context_size_out) uint8_t* context_out; ///< Output context from the program.
size_t context_size_in; ///< Size of input context.
size_t context_size_out; ///< Maximum length of context_out on input and actual length of context_out on output.
uint64_t return_value; ///< Return value from the program.
size_t repeat_count; ///< Number of times to repeat the program.
uint64_t duration; ///< Duration in nanoseconds of the program execution.
uint32_t flags; ///< Flags to control the test run.
uint32_t cpu; ///< CPU to run the program on.
size_t batch_size; ///< Number of times to repeat the program in a batch.
} ebpf_program_test_run_options_t;
/**
* @brief Function called when the program test run completes.
*
*/
typedef void (*ebpf_program_test_run_complete_callback_t)(
_In_ ebpf_result_t result,
_In_ const ebpf_program_t* program,
_In_ const ebpf_program_test_run_options_t* options,
_Inout_ void* completion_context,
_Inout_ void* async_context);
/**
* @brief Run the program with the given input and output buffers and measure the duration.
*
* @param[in] program Program to run.
* @param[in, out] options Options to control the test run.
* @param[in] async_context Async context to receive cancellation notifications on.
* @param[in] completion_context Context to pass to the completion callback.
* @param[in] callback Completion callback.
* @retval EBPF_SUCCESS The operation was successful.
* @retval EBPF_INVALID_ARGUMENT Invalid argument.
* @retval EBPF_NO_MEMORY Unable to allocate resources for this program.
*/
_Must_inspect_result_ ebpf_result_t
ebpf_program_execute_test_run(
_In_ const ebpf_program_t* program,
_Inout_ ebpf_program_test_run_options_t* options,
_In_ void* async_context,
_In_ void* completion_context,
_In_ ebpf_program_test_run_complete_callback_t callback);
typedef ebpf_result_t (*ebpf_helper_function_addresses_changed_callback_t)(
_Inout_ ebpf_program_t* program, _In_opt_ void* context);
/**
* @brief Register to be notified when the helper function addresses change.
*
* @param[in,out] program Program to register for helper function address changes.
* @param[in] callback Function to call when helper function addresses change.
* @param[in] context Context to pass to the callback.
* @retval EBPF_SUCCESS The operation was successful.
* @retval EBPF_INVALID_ARGUMENT Invalid argument.
*/
_Must_inspect_result_ ebpf_result_t
ebpf_program_register_for_helper_changes(
_Inout_ ebpf_program_t* program,
_In_ ebpf_helper_function_addresses_changed_callback_t callback,
_In_opt_ void* context);
#ifdef __cplusplus
}
#endif