Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DRAFT]: Support for multiple load of native programs #3556

Draft
wants to merge 21 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions ebpfapi/Source.def
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ EXPORTS
ebpf_get_program_info_from_verifier
ebpf_get_program_type_by_name
ebpf_get_program_type_name
ebpf_initialize_native_program_state
ebpf_link_close
ebpf_object_get
ebpf_object_get_execution_type
Expand All @@ -122,6 +123,7 @@ EXPORTS
ebpf_store_delete_section_information
ebpf_store_update_program_information_array
ebpf_store_update_section_information
ebpf_uninitialize_native_program_state
libbpf_attach_type_by_name
libbpf_bpf_attach_type_str
libbpf_bpf_link_type_str
Expand Down
30 changes: 26 additions & 4 deletions include/bpf2c.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,24 +53,46 @@ extern "C"
*/
typedef struct _helper_function_entry
{
uint64_t (*address)(uint64_t r1, uint64_t r2, uint64_t r3, uint64_t r4, uint64_t r5);
// uint64_t (*address)(uint64_t r1, uint64_t r2, uint64_t r3, uint64_t r4, uint64_t r5);
uint32_t helper_id;
const char* name;
bool tail_call;
// bool tail_call;
} helper_function_entry_t;

typedef struct _helper_function_data
{
uint64_t (*address)(uint64_t r1, uint64_t r2, uint64_t r3, uint64_t r4, uint64_t r5);
bool tail_call;
} helper_function_data_t;

/**
* @brief Map entry.
* This structure contains the address of the map and the map definition. The address is written into the entry
* during load time. The map definition is used to initialize the map when the program is loaded.
*/
typedef struct _map_entry
{
void* address;
// DLLs put the strings into the same section, so add a marker
// at the start of a map entry to make it easy to find
// entries in the maps section.
uint64_t zero_marker;

// void* address;
ebpf_map_definition_in_file_t definition;
const char* name;
} map_entry_t;

typedef struct _map_data
{
uintptr_t address;
} map_data_t;

typedef struct _program_runtime_context
{
helper_function_data_t* helper_data;
map_data_t* map_data;
} program_runtime_context_t;

/**
* @brief Map initial values.
* This structure contains the initial values for a map. The values are used to initialize the map when the
Expand All @@ -95,7 +117,7 @@ extern "C"
// entries in the programs section.
uint64_t zero;

uint64_t (*function)(void*); ///< Address of the program.
uint64_t (*function)(void*, void*); ///< Address of the program.
const char* pe_section_name; ///< Name of the PE section containing the program.
const char* section_name; ///< Name of the section containing the program.
const char* program_name; ///< Name of the program.
Expand Down
41 changes: 41 additions & 0 deletions include/ebpf_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,47 @@ extern "C"
_Must_inspect_result_ ebpf_result_t
ebpf_program_test_run(fd_t program_fd, _Inout_ ebpf_test_run_options_t* options) EBPF_NO_EXCEPT;

/**
* @brief Initialize state for the native program. This API should be called
* once before trying to load a native eBPF program. Once the state is
* initialized, multiple instances of the program can be loaded at the same
* time from the same native module file. Once the loaded programs have been unloaded or
* if no more instances of the programs need to be loaded from the same native module file,
* the state should be uninitialized using \ref ebpf_uninitialize_native_program_state().
*
* In case a previous call to \ref ebpf_uninitialize_native_program_state() is still pending,
* and the programs or driver have not been unloaded, this API call will return EBPF_INVALID_STATE.
* In such a case, the application should unload any loaded programs and retry after sometime.
*
* Note: If an application exclusively owns a native eBPF program file, and does not have
* any requirement of multiple loads, it can skip calling this API and directly call
* bpf_object__open() / bpf_object__load().
*
* @param[in] file Name of the native module containing eBPF program.
*
* @retval EBPF_SUCCESS The operation was successful.
* @retval EBPF_INVALID_ARGUMENT Invalid argument was passed.
* @retval EBPF_INVALID_STATE State cleanup from previous call to
* \ref ebpf_uninitialize_native_program_state is still pending. Retry after sometime.
*/
_Must_inspect_result_ ebpf_result_t
ebpf_initialize_native_program_state(_In_z_ const char* file) EBPF_NO_EXCEPT;

/**
* @brief Uninitialize state for the native program previously created by
* \ref ebpf_initialize_native_program. This API should be called once all
* the loaded programs have been unloaded. If this API is called while
* there are still loaded programs, the actual cleanup of the state will be
* deferred until all the loaded programs are unloaded.
*
* @param[in] file Name of the native module containing eBPF program.
*
* @retval EBPF_SUCCESS The operation was successful.
* @retval EBPF_INVALID_OBJECT Invalid object was passed.
*/
_Must_inspect_result_ ebpf_result_t
ebpf_uninitialize_native_program_state(_In_z_ const char* file) EBPF_NO_EXCEPT;

#ifdef __cplusplus
}
#endif
5 changes: 4 additions & 1 deletion include/ebpf_result.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,12 @@ extern "C"

/// The system is in an invalid state for this operation.
EBPF_INVALID_STATE,

/// The operation should be retried.
EBPF_TRY_AGAIN, // = 35
} ebpf_result_t;

#define EBPF_RESULT_COUNT (EBPF_INVALID_STATE + 1)
#define EBPF_RESULT_COUNT (EBPF_TRY_AGAIN + 1)

#ifdef __cplusplus
}
Expand Down
4 changes: 4 additions & 0 deletions include/ebpf_utilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,10 @@ _When_(error != ERROR_SUCCESS, _Ret_range_(1, 65535)) __forceinline ebpf_result_
result = EBPF_INVALID_STATE;
break;

case ERROR_RETRY:
result = EBPF_TRY_AGAIN;
break;

default:
result = EBPF_FAILED;
break;
Expand Down
Loading
Loading