Skip to content

Commit

Permalink
extension_header
Browse files Browse the repository at this point in the history
  • Loading branch information
shankarseal committed Mar 5, 2024
1 parent ff2a400 commit 308e9c5
Show file tree
Hide file tree
Showing 39 changed files with 883 additions and 534 deletions.
11 changes: 3 additions & 8 deletions include/ebpf_extension.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,13 @@ typedef struct _ebpf_extension_program_dispatch_table

typedef struct _ebpf_extension_data
{
uint16_t version;
size_t size;
ebpf_extension_header_t header;
const void* data;
} ebpf_extension_data_t;

typedef struct _ebpf_attach_provider_data
{
ebpf_extension_header_t header;
ebpf_program_type_t supported_program_type;
bpf_attach_type_t bpf_attach_type;
enum bpf_link_type link_type;
Expand All @@ -118,9 +118,4 @@ typedef struct _ebpf_execution_context_state
const void* next_program;
uint32_t count;
} tail_call_state;
} ebpf_execution_context_state_t;

#define EBPF_ATTACH_CLIENT_DATA_VERSION 0
#define EBPF_ATTACH_PROVIDER_DATA_VERSION 1
#define EBPF_PROGRAM_INFORMATION_PROVIDER_DATA_VERSION 0
#define EBPF_MAX_GENERAL_HELPER_FUNCTION 0xFFFF
} ebpf_execution_context_state_t;
61 changes: 45 additions & 16 deletions include/ebpf_program_attach_type_guids.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,69 +21,98 @@ extern "C"
__declspec(selectany) ebpf_attach_type_t EBPF_ATTACH_TYPE_XDP = {
0x85e0d8ef, 0x579e, 0x4931, {0xb0, 0x72, 0x8e, 0xe2, 0x26, 0xbb, 0x2e, 0x9d}};

#define EBPF_ATTACH_TYPE_BIND_GUID \
{ \
0xb9707e04, 0x8127, 0x4c72, { 0x83, 0x3e, 0x05, 0xb1, 0xfb, 0x43, 0x94, 0x96 } \
}
/** @brief Attach type for handling socket bind() requests.
*
* Program type: \ref EBPF_PROGRAM_TYPE_BIND
*/
__declspec(selectany) ebpf_attach_type_t EBPF_ATTACH_TYPE_BIND = {
0xb9707e04, 0x8127, 0x4c72, {0x83, 0x3e, 0x05, 0xb1, 0xfb, 0x43, 0x94, 0x96}};
__declspec(selectany) ebpf_attach_type_t EBPF_ATTACH_TYPE_BIND = EBPF_ATTACH_TYPE_BIND_GUID;

#define EBPF_ATTACH_TYPE_CGROUP_INET4_CONNECT_GUID \
{ \
0xa82e37b1, 0xaee7, 0x11ec, { 0x9a, 0x30, 0x18, 0x60, 0x24, 0x89, 0xbe, 0xee } \
}
/** @brief The programs attached to the INET4_CONNECT hook will be invoked for
* connect() calls on TCP or UDP sockets or when a UDP socket sends a packet to
* a unique remote address/port tuple.
*
* Program type: \ref EBPF_PROGRAM_TYPE_CGROUP_SOCK_ADDR
*/
__declspec(selectany) ebpf_attach_type_t EBPF_ATTACH_TYPE_CGROUP_INET4_CONNECT = {
0xa82e37b1, 0xaee7, 0x11ec, {0x9a, 0x30, 0x18, 0x60, 0x24, 0x89, 0xbe, 0xee}};
__declspec(selectany)
ebpf_attach_type_t EBPF_ATTACH_TYPE_CGROUP_INET4_CONNECT = EBPF_ATTACH_TYPE_CGROUP_INET4_CONNECT_GUID;

#define EBPF_ATTACH_TYPE_CGROUP_INET6_CONNECT_GUID \
{ \
0xa82e37b2, 0xaee7, 0x11ec, { 0x9a, 0x30, 0x18, 0x60, 0x24, 0x89, 0xbe, 0xee } \
}
/** @brief The programs attached to the INET6_CONNECT hook will be invoked for
* connect() calls on TCP or UDP sockets or when a UDP socket sends a packet to
* a unique remote address/port tuple.
*
* Program type: \ref EBPF_PROGRAM_TYPE_CGROUP_SOCK_ADDR
*/
__declspec(selectany) ebpf_attach_type_t EBPF_ATTACH_TYPE_CGROUP_INET6_CONNECT = {
0xa82e37b2, 0xaee7, 0x11ec, {0x9a, 0x30, 0x18, 0x60, 0x24, 0x89, 0xbe, 0xee}};
__declspec(selectany)
ebpf_attach_type_t EBPF_ATTACH_TYPE_CGROUP_INET6_CONNECT = EBPF_ATTACH_TYPE_CGROUP_INET6_CONNECT_GUID;

#define EBPF_ATTACH_TYPE_CGROUP_INET4_RECV_ACCEPT_GUID \
{ \
0xa82e37b3, 0xaee7, 0x11ec, { 0x9a, 0x30, 0x18, 0x60, 0x24, 0x89, 0xbe, 0xee } \
}
/** @brief The programs attached to the INET4_RECV_ACCEPT hook will get invoked for
* TCP accept() calls or for the first unicast UDP packet from a unique remote
* address/port tuple.
*
* Program type: \ref EBPF_PROGRAM_TYPE_CGROUP_SOCK_ADDR
*/
__declspec(selectany) ebpf_attach_type_t EBPF_ATTACH_TYPE_CGROUP_INET4_RECV_ACCEPT = {
0xa82e37b3, 0xaee7, 0x11ec, {0x9a, 0x30, 0x18, 0x60, 0x24, 0x89, 0xbe, 0xee}};
__declspec(selectany)
ebpf_attach_type_t EBPF_ATTACH_TYPE_CGROUP_INET4_RECV_ACCEPT = EBPF_ATTACH_TYPE_CGROUP_INET4_RECV_ACCEPT_GUID;

#define EBPF_ATTACH_TYPE_CGROUP_INET6_RECV_ACCEPT_GUID \
{ \
0xa82e37b4, 0xaee7, 0x11ec, { 0x9a, 0x30, 0x18, 0x60, 0x24, 0x89, 0xbe, 0xee } \
}
/** @brief The programs attached to the INET6_RECV_ACCEPT hook will get invoked for
* TCP accept() calls or for the first unicast UDP packet from a unique remote
* address/port tuple.
*
* Program type: \ref EBPF_PROGRAM_TYPE_CGROUP_SOCK_ADDR
*/
__declspec(selectany) ebpf_attach_type_t EBPF_ATTACH_TYPE_CGROUP_INET6_RECV_ACCEPT = {
0xa82e37b4, 0xaee7, 0x11ec, {0x9a, 0x30, 0x18, 0x60, 0x24, 0x89, 0xbe, 0xee}};
__declspec(selectany)
ebpf_attach_type_t EBPF_ATTACH_TYPE_CGROUP_INET6_RECV_ACCEPT = EBPF_ATTACH_TYPE_CGROUP_INET6_RECV_ACCEPT_GUID;

#define EBPF_ATTACH_TYPE_CGROUP_SOCK_OPS_GUID \
{ \
0x837d02cd, 0x3251, 0x4632, { 0x8d, 0x94, 0x60, 0xd3, 0xb4, 0x57, 0x69, 0xf2 } \
}
/** @brief Attach type for handling socket event notifications.
*
* Program type: \ref EBPF_PROGRAM_TYPE_SOCK_OPS
*/
__declspec(selectany) ebpf_attach_type_t EBPF_ATTACH_TYPE_CGROUP_SOCK_OPS = {
0x837d02cd, 0x3251, 0x4632, {0x8d, 0x94, 0x60, 0xd3, 0xb4, 0x57, 0x69, 0xf2}};
__declspec(selectany) ebpf_attach_type_t EBPF_ATTACH_TYPE_CGROUP_SOCK_OPS = EBPF_ATTACH_TYPE_CGROUP_SOCK_OPS_GUID;

#define EBPF_ATTACH_TYPE_SAMPLE_GUID \
{ \
0xf788ef4b, 0x207d, 0x4dc3, { 0x85, 0xcf, 0x0f, 0x2e, 0xa1, 0x07, 0x21, 0x3c } \
}

/** @brief Attach type implemented by eBPF Sample Extension driver, used for testing.
*
* Program type: \ref EBPF_PROGRAM_TYPE_SAMPLE
*/
__declspec(selectany) ebpf_attach_type_t EBPF_ATTACH_TYPE_SAMPLE = {
0xf788ef4b, 0x207d, 0x4dc3, {0x85, 0xcf, 0x0f, 0x2e, 0xa1, 0x07, 0x21, 0x3c}};
__declspec(selectany) ebpf_attach_type_t EBPF_ATTACH_TYPE_SAMPLE = EBPF_ATTACH_TYPE_SAMPLE_GUID;

#define EBPF_ATTACH_TYPE_XDP_TEST_GUID \
{ \
0x0dccc15d, 0xa5f9, 0x4dc1, { 0xac, 0x79, 0xfa, 0x25, 0xee, 0xf2, 0x15, 0xc3 } \
}
/** @brief Attach type for handling incoming packets as early as possible.
*
* Program type: \ref EBPF_PROGRAM_TYPE_XDP_TEST
*/
__declspec(selectany) ebpf_attach_type_t EBPF_ATTACH_TYPE_XDP_TEST = {
0x0dccc15d, 0xa5f9, 0x4dc1, {0xac, 0x79, 0xfa, 0x25, 0xee, 0xf2, 0x15, 0xc3}};
__declspec(selectany) ebpf_attach_type_t EBPF_ATTACH_TYPE_XDP_TEST = EBPF_ATTACH_TYPE_XDP_TEST_GUID;

//
// Program Types.
Expand Down
21 changes: 10 additions & 11 deletions include/ebpf_program_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,15 @@

#include "ebpf_base.h"
#include "ebpf_result.h"

#include <guiddef.h>
#if !defined(NO_CRT) && !defined(_NO_CRT_STDIO_INLINE)
#include <stdint.h>
#else
typedef unsigned char uint8_t;
typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
typedef unsigned short wchar_t;
#endif
#include "ebpf_windows.h"

#define EBPF_MAX_PROGRAM_DESCRIPTOR_NAME_LENGTH 256
#define EBPF_MAX_HELPER_FUNCTION_NAME_LENGTH 256

typedef struct _ebpf_program_type_descriptor
{
ebpf_extension_header_t header;
// The following fields are available in version EBPF_PROGRAM_TYPE_DESCRIPTOR_VERSION_0 and later.
const char* name;
const ebpf_context_descriptor_t* context_descriptor;
GUID program_type;
Expand All @@ -29,6 +22,8 @@ typedef struct _ebpf_program_type_descriptor

typedef struct _ebpf_helper_function_prototype
{
ebpf_extension_header_t header;
// The following fields are available in version EBPF_HELPER_FUNCTION_PROTOTYPE_VERSION_0 and later.
uint32_t helper_id;
const char* name;
ebpf_return_type_t return_type;
Expand All @@ -37,7 +32,8 @@ typedef struct _ebpf_helper_function_prototype

typedef struct _ebpf_program_info
{
ebpf_program_type_descriptor_t program_type_descriptor;
ebpf_extension_header_t header;
const ebpf_program_type_descriptor_t* program_type_descriptor;
uint32_t count_of_program_type_specific_helpers;
const ebpf_helper_function_prototype_t* program_type_specific_helper_prototype;
uint32_t count_of_global_helpers;
Expand All @@ -46,6 +42,7 @@ typedef struct _ebpf_program_info

typedef struct _ebpf_helper_function_addresses
{
ebpf_extension_header_t header;
uint32_t helper_function_count;
uint64_t* helper_function_address;
} ebpf_helper_function_addresses_t;
Expand All @@ -66,6 +63,7 @@ typedef void (*ebpf_program_context_destroy_t)(

typedef struct _ebpf_program_data
{
ebpf_extension_header_t header;
const ebpf_program_info_t* program_info; ///< Pointer to program information.
const ebpf_helper_function_addresses_t*
program_type_specific_helper_function_addresses; ///< Pointer to program type specific helper function
Expand All @@ -79,6 +77,7 @@ typedef struct _ebpf_program_data

typedef struct _ebpf_program_section_info
{
ebpf_extension_header_t header;
const wchar_t* section_name;
const GUID* program_type;
const GUID* attach_type;
Expand Down
10 changes: 0 additions & 10 deletions include/ebpf_structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,6 @@

#include "ebpf_windows.h"

#if !defined(NO_CRT) && !defined(_NO_CRT_STDIO_INLINE)
#include <stdbool.h>
#include <stdint.h>
#else
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
#endif

#define MAX_TAIL_CALL_CNT 33

#define BPF_ENUM_TO_STRING(X) #X
Expand Down
41 changes: 38 additions & 3 deletions include/ebpf_windows.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,24 @@
#ifdef _MSC_VER
#include <guiddef.h>
#else
typedef uint8_t GUID[16];
#endif

#if !defined(NO_CRT) && !defined(_NO_CRT_STDIO_INLINE)
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#else
typedef unsigned char uint8_t;
#endif
typedef uint8_t GUID[16];
typedef unsigned short uint16_t;
typedef unsigned short wchar_t;
typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
typedef unsigned long long size_t;
#endif

// This file contains eBPF definitions needed by eBPF programs as well as
// the verifier and execution context.
// the verifier, execution context and extension drivers.

#define EBPF_ROOT_REGISTRY_PATH L"\\Registry\\Machine\\Software\\eBPF"
#define EBPF_ROOT_RELATIVE_PATH L"Software\\eBPF"
Expand Down Expand Up @@ -49,3 +57,30 @@ typedef enum _ebpf_helper_function
EBPF_UPDATE_ELEMENT = 2, ///< Update map element.
EBPF_DELETE_ELEMENT = 3, ///< Delete a map element.
} ebpf_helper_function_t;

#define EBPF_MAX_GENERAL_HELPER_FUNCTION 0xFFFF

// Version 0 of the eBPF extension data structures.
#define EBPF_ATTACH_CLIENT_DATA_VERSION_0 0
#define EBPF_ATTACH_PROVIDER_DATA_VERSION_0 0
#define EBPF_PROGRAM_INFORMATION_CLIENT_DATA_VERSION_0 0
#define EBPF_PROGRAM_TYPE_DESCRIPTOR_VERSION_0 0
#define EBPF_HELPER_FUNCTION_PROTOTYPE_VERSION_0 0
#define EBPF_PROGRAM_INFORMATION_VERSION_0 0
#define EBPF_HELPER_FUNCTION_ADDRESSES_VERSION_0 0
#define EBPF_PROGRAM_SECTION_INFORMATION_VERSION_0 0
#define EBPF_PROGRAM_DATA_VERSION_0 0
#define EBPF_PROGRAM_SECTION_VERSION_0 0

/**
* @brief Header of an eBPF extension data structure.
* Every eBPF extension data structure must start with this header.
* New fields can be added to the end eBPF extension data structure
* without breaking backward compatibility. The version field must be
* updated only if the new data structure is not backward compatible.
*/
typedef struct _ebpf_extension_header
{
uint16_t version; ///< Version of the extension data structure.
size_t size; ///< Size of the extension data structure.
} ebpf_extension_header_t;
22 changes: 16 additions & 6 deletions libs/api_common/store_helper_internal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ _load_program_data_information(
uint32_t bpf_program_type;
ebpf_program_type_t* program_type = nullptr;
ebpf_program_info_t* program_information = nullptr;
ebpf_program_type_descriptor_t* program_type_descriptor = nullptr;
uint32_t helper_count;
wchar_t* helper_name = nullptr;

Expand Down Expand Up @@ -174,16 +175,25 @@ _load_program_data_information(
goto Exit;
}

program_information->program_type_descriptor.name = cxplat_duplicate_string(program_type_name_string.c_str());
if (program_information->program_type_descriptor.name == nullptr) {
program_information->program_type_descriptor =
(ebpf_program_type_descriptor_t*)ebpf_allocate(sizeof(ebpf_program_type_descriptor_t));
if (program_information->program_type_descriptor == nullptr) {
result = EBPF_NO_MEMORY;
goto Exit;
}
program_information->program_type_descriptor.context_descriptor = descriptor;
program_type_descriptor =
const_cast<ebpf_program_type_descriptor_t*>(program_information->program_type_descriptor);

program_type_descriptor->name = cxplat_duplicate_string(program_type_name_string.c_str());
if (program_type_descriptor->name == nullptr) {
result = EBPF_NO_MEMORY;
goto Exit;
}
program_type_descriptor->context_descriptor = descriptor;
descriptor = nullptr;
program_information->program_type_descriptor.is_privileged = !!is_privileged;
program_information->program_type_descriptor.bpf_prog_type = bpf_program_type;
program_information->program_type_descriptor.program_type = *program_type;
program_type_descriptor->is_privileged = !!is_privileged;
program_type_descriptor->bpf_prog_type = bpf_program_type;
program_type_descriptor->program_type = *program_type;

if (helper_count > 0) {
// Read the helper functions prototypes.
Expand Down
5 changes: 4 additions & 1 deletion libs/api_common/windows_helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,10 @@ get_helper_prototype_windows(int32_t n)
}
EbpfHelperPrototype verifier_prototype = {0};

verifier_prototype.context_descriptor = info->program_type_descriptor.context_descriptor;
if (info->program_type_descriptor == nullptr) {
throw std::runtime_error(std::string("program type descriptor not found."));
}
verifier_prototype.context_descriptor = info->program_type_descriptor->context_descriptor;

const ebpf_helper_function_prototype_t* raw_prototype = _get_helper_function_prototype(info, n);
if (raw_prototype == nullptr) {
Expand Down

0 comments on commit 308e9c5

Please sign in to comment.