BPF and XDP

Overview

Definition of API to configure BPF/XDP programs. More…

// typedefs

typedef enum tapi_bpf_state tapi_bpf_state;
typedef enum tapi_bpf_prog_type tapi_bpf_prog_type;
typedef enum tapi_bpf_map_type tapi_bpf_map_type;
typedef enum tapi_bpf_link_point tapi_bpf_link_point;
typedef enum tapi_bpf_xdp_action tapi_bpf_xdp_action;
typedef struct tapi_bpf_lpm_trie_key tapi_bpf_lpm_trie_key;

// enums

enum tapi_bpf_link_point;
enum tapi_bpf_map_type;
enum tapi_bpf_prog_type;
enum tapi_bpf_state;
enum tapi_bpf_xdp_action;

// structs

struct tapi_bpf_lpm_trie_key;

// global functions

char* tapi_bpf_build_bpf_obj_path(const char* ta, const char* bpf_prog_name);
te_errno tapi_bpf_obj_add(const char* ta, const char* fname, unsigned int* bpf_id);
te_errno tapi_bpf_obj_del(const char* ta, unsigned int bpf_id);
te_errno tapi_bpf_obj_load(const char* ta, unsigned int bpf_id);
te_errno tapi_bpf_obj_get_state(const char* ta, unsigned int bpf_id, tapi_bpf_state* bpf_state);
te_errno tapi_bpf_obj_unload(const char* ta, unsigned int bpf_id);
te_errno tapi_bpf_obj_get_type(const char* ta, unsigned int bpf_id, tapi_bpf_prog_type* type);
te_errno tapi_bpf_obj_set_type(const char* ta, unsigned int bpf_id, tapi_bpf_prog_type type);
te_errno tapi_bpf_prog_get_list(const char* ta, unsigned int bpf_id, char*** prog, unsigned int* prog_count);
te_errno tapi_bpf_prog_link(const char* ta, const char* ifname, unsigned int bpf_id, tapi_bpf_link_point link_type, const char* prog);
te_errno tapi_bpf_prog_unlink(const char* ta, const char* ifname, tapi_bpf_link_point link_type);
te_errno tapi_bpf_map_get_list(const char* ta, unsigned int bpf_id, char*** map, unsigned int* map_count);
te_errno tapi_bpf_map_get_type(const char* ta, unsigned int bpf_id, const char* map, tapi_bpf_map_type* type);
te_errno tapi_bpf_map_get_key_size(const char* ta, unsigned int bpf_id, const char* map, unsigned int* key_size);
te_errno tapi_bpf_map_get_val_size(const char* ta, unsigned int bpf_id, const char* map, unsigned int* val_size);
te_errno tapi_bpf_map_get_max_entries(const char* ta, unsigned int bpf_id, const char* map, unsigned int* max_entries);
te_errno tapi_bpf_map_get_writable_state(const char* ta, unsigned int bpf_id, const char* map, bool* is_writable);
te_errno tapi_bpf_map_set_writable(const char* ta, unsigned int bpf_id, const char* map);
te_errno tapi_bpf_map_unset_writable(const char* ta, unsigned int bpf_id, const char* map);
te_errno tapi_bpf_map_update_kvpair(const char* ta, unsigned int bpf_id, const char* map, const uint8_t* key, unsigned int key_size, const uint8_t* val, unsigned int val_size);
te_errno tapi_bpf_map_lookup_kvpair(const char* ta, unsigned int bpf_id, const char* map, const uint8_t* key, unsigned int key_size, uint8_t* val, unsigned int val_size);
te_errno tapi_bpf_map_delete_kvpair(const char* ta, unsigned int bpf_id, const char* map, const uint8_t* key, unsigned int key_size);
te_errno tapi_bpf_map_get_key_list(const char* ta, unsigned int bpf_id, const char* map, unsigned int* key_size, uint8_t*** key, unsigned int* count);
te_errno tapi_bpf_map_set_pin(const char* ta, unsigned int bpf_id, const char* map, const char* pin_path);
te_errno tapi_bpf_map_get_pin(const char* ta, unsigned int bpf_id, const char* map, char** pin_path);
te_errno tapi_bpf_perf_event_init(const char* ta, unsigned int bpf_id, const char* map, unsigned int event_size);
te_errno tapi_bpf_perf_event_deinit(const char* ta, unsigned int bpf_id, const char* map);
te_errno tapi_bpf_perf_get_events(const char* ta, unsigned int bpf_id, const char* map, unsigned int* num, uint8_t** data);
te_errno tapi_bpf_perf_map_get_list(const char* ta, unsigned int bpf_id, char*** map, unsigned int* map_count);
te_errno tapi_bpf_obj_init(const char* ta, const char* path, tapi_bpf_prog_type type, unsigned int* bpf_id);
te_errno tapi_bpf_obj_fini(const char* ta, unsigned int bpf_id);
te_errno tapi_bpf_prog_name_check(const char* ta, unsigned int bpf_id, const char* prog_name);
te_errno tapi_bpf_map_type_name_check(const char* ta, unsigned int bpf_id, const char* map_name, tapi_bpf_map_type map_type);
static te_errno tapi_bpf_map_name_check(const char* ta, unsigned int bpf_id, const char* map_name);
te_errno tapi_bpf_map_check_type(const char* ta, unsigned int bpf_id, const char* map_name, tapi_bpf_map_type exp_map_type);
te_errno tapi_bpf_ip_tcpudp_filter_from_sa(te_bpf_ip_tcpudp_filter* filter, int family, int protocol, const struct sockaddr* src_addr, const struct sockaddr* dst_addr);

// macros

#define TE_BPF_U8

Detailed Documentation

Definition of API to configure BPF/XDP programs.

Copyright (C) 2019-2022 OKTET Labs Ltd. All rights reserved.

Typedefs

typedef enum tapi_bpf_state tapi_bpf_state

BPF object states

typedef enum tapi_bpf_prog_type tapi_bpf_prog_type

BPF program types

typedef enum tapi_bpf_map_type tapi_bpf_map_type

BPF map types

typedef enum tapi_bpf_link_point tapi_bpf_link_point

BPF program link point types.

typedef enum tapi_bpf_xdp_action tapi_bpf_xdp_action

BPF XDP actions

typedef struct tapi_bpf_lpm_trie_key tapi_bpf_lpm_trie_key

Key of a TAPI_BPF_MAP_TYPE_LPM_TRIE map entry

Global Functions

char* tapi_bpf_build_bpf_obj_path(const char* ta, const char* bpf_prog_name)

Get full path to BPF object on Test Agent.

Note

Return value should be freed when it is no longer needed.

Parameters:

ta

Test Agent name

bpf_prog_name

BPF object name

Returns:

Path to BPF object or NULL in case of error.

te_errno tapi_bpf_obj_add(const char* ta, const char* fname, unsigned int* bpf_id)

Add BPF object

Parameters:

ta

Test Agent name

fname

File path on agent side, file should exist on agent

bpf_id

Id of created BPF object

Returns:

Status code

te_errno tapi_bpf_obj_del(const char* ta, unsigned int bpf_id)

Remove BPF object

Parameters:

ta

Test Agent name

bpf_id

Bpf ID

Returns:

Status code

te_errno tapi_bpf_obj_load(const char* ta, unsigned int bpf_id)

Load BPF object into the kernel. Only after the BPF object has been loaded into the kernel, it becomes possible to get list of programs/maps and attach an XDP program to network interface.

Parameters:

ta

Test Agent name

bpf_id

Bpf ID

Returns:

Status code

te_errno tapi_bpf_obj_get_state(const char* ta, unsigned int bpf_id, tapi_bpf_state* bpf_state)

Get state of BPF object

Parameters:

ta

Test Agent name

bpf_id

Bpf ID

bpf_state

Current BPF state

Returns:

Status code

See also:

tapi_bpf_obj_load()

te_errno tapi_bpf_obj_unload(const char* ta, unsigned int bpf_id)

Unload BPF object from kernel

Parameters:

ta

Test Agent name

bpf_id

Bpf ID

Returns:

Status code

te_errno tapi_bpf_obj_get_type(const char* ta, unsigned int bpf_id, tapi_bpf_prog_type* type)

Get program type for BPF object

Parameters:

ta

Test Agent name

bpf_id

Bpf ID

type

Type of BPF program

Returns:

Status code

te_errno tapi_bpf_obj_set_type(const char* ta, unsigned int bpf_id, tapi_bpf_prog_type type)

Set program type in bfp object

Parameters:

ta

Test Agent name

bpf_id

Bpf ID

type

Type of BPF program

Returns:

Status code

te_errno tapi_bpf_prog_get_list(const char* ta, unsigned int bpf_id, char*** prog, unsigned int* prog_count)

Get list of programs in BPF object, it means that BPF object was loaded before by calling tapi_bpf_obj_load()

unused if NULL

Parameters:

ta

Test Agent name

bpf_id

Bpf ID

prog

Array of program names, should be freed by user, see te_str_free_array

prog_count

Pointer to store number of programs in

Returns:

Status code

te_errno tapi_bpf_prog_link(const char* ta, const char* ifname, unsigned int bpf_id, tapi_bpf_link_point link_type, const char* prog)

Link program to network interface.

Note

only one program can be linked to interface.

Note

clsact qdisc must be enabled in order to link BPF program to TC attach point.

Parameters:

ta

Test Agent name

ifname

Interface name

bpf_id

Bpf ID

link_type

Type of link point

prog

Program name

Returns:

Status code

te_errno tapi_bpf_prog_unlink(const char* ta, const char* ifname, tapi_bpf_link_point link_type)

Unlink the XDP program from network interface

Parameters:

ta

Test Agent name

ifname

Interface name

link_type

Type of link point

Returns:

Status code

te_errno tapi_bpf_map_get_list(const char* ta, unsigned int bpf_id, char*** map, unsigned int* map_count)

Get list of loaded maps from BPF object

unused if NULL

Parameters:

ta

Test Agent name

bpf_id

Bpf ID

map

Array of map names, should be freed by user, see te_str_free_array

prog_count

Pointer to store number of maps in

Returns:

Status code

te_errno tapi_bpf_map_get_type(const char* ta, unsigned int bpf_id, const char* map, tapi_bpf_map_type* type)

Get map type for BPF object

Parameters:

ta

Test Agent name

bpf_id

Bpf ID

map

Map name

type

Pointer to store map type

Returns:

Status code

te_errno tapi_bpf_map_get_key_size(const char* ta, unsigned int bpf_id, const char* map, unsigned int* key_size)

Get size of key in the map

Parameters:

ta

Test Agent name

bpf_id

Bpf ID

map

Map name

key_size

Size of keys in bytes

Returns:

Status code

te_errno tapi_bpf_map_get_val_size(const char* ta, unsigned int bpf_id, const char* map, unsigned int* val_size)

Get size of values in the map

Parameters:

ta

Test Agent name

bpf_id

Bpf ID

map

Map name

val_size

Size of value in bytes

Returns:

Status code

te_errno tapi_bpf_map_get_max_entries(const char* ta, unsigned int bpf_id, const char* map, unsigned int* max_entries)

Get maximum number of key/value entries in the map

Parameters:

ta

Test Agent name

bpf_id

Bpf ID

map

Map name

max_entries

Maximum number of entries

Returns:

Status code

te_errno tapi_bpf_map_get_writable_state(const char* ta, unsigned int bpf_id, const char* map, bool* is_writable)

Get current state of writable view of the map

Parameters:

ta

Test Agent name

bpf_id

Bpf ID

map

Map name

is_writable

State of map

Returns:

Status code

te_errno tapi_bpf_map_set_writable(const char* ta, unsigned int bpf_id, const char* map)

Enable writable view for the map

Parameters:

ta

Test Agent name

bpf_id

Bpf ID

map

Map name

Returns:

Status code

te_errno tapi_bpf_map_unset_writable(const char* ta, unsigned int bpf_id, const char* map)

Disable writable view for the map

Parameters:

ta

Test Agent name

bpf_id

Bpf ID

map

Map name

Returns:

Status code

te_errno tapi_bpf_map_update_kvpair(const char* ta, unsigned int bpf_id, const char* map, const uint8_t* key, unsigned int key_size, const uint8_t* val, unsigned int val_size)

Update value for given key in the map

Parameters:

ta

Test Agent name

bpf_id

Bpf ID

map

Map name

key

Pointer to key

key_size

Size of key

val

Pointer to value which be set to key

val_size

Size of value

Returns:

Status code

te_errno tapi_bpf_map_lookup_kvpair(const char* ta, unsigned int bpf_id, const char* map, const uint8_t* key, unsigned int key_size, uint8_t* val, unsigned int val_size)

Get raw key value for the map

Parameters:

ta

Test Agent name

bpf_id

Bpf ID

map

Map name

key

Pointer to key

key_size

Size of key

val

Pointer to value of key

val_size

Size of value

Returns:

Status code

te_errno tapi_bpf_map_delete_kvpair(const char* ta, unsigned int bpf_id, const char* map, const uint8_t* key, unsigned int key_size)

Delete key/value pair from the map

Parameters:

ta

Test Agent name

bpf_id

Bpf ID

map

Map name

key

Pointer to key

key_size

Size of key

Returns:

Status code

te_errno tapi_bpf_map_get_key_list(const char* ta, unsigned int bpf_id, const char* map, unsigned int* key_size, uint8_t*** key, unsigned int* count)

Get list of keys (raw value) in the map

Parameters:

ta

Test Agent name

bpf_id

Bpf ID

map

Map name

key_size

The size of each item in array key (in bytes)

key

Array of keys (raw value), should be freed by user

count

Number of keys in array key

Returns:

Status code

te_errno tapi_bpf_map_set_pin(const char* ta, unsigned int bpf_id, const char* map, const char* pin_path)

Pin BPF map to a file that can be then opened from another process to obtain map descriptor and use it from there.

Parameters:

ta

Test Agent name

bpf_id

BPF ID

map

Map name

pin_path

Path to the file. It must be inside BPF file system (usually mounted at /sys/fs/bpf/). If empty, map is unpinned from the currently assigned file.

Returns:

Status code.

te_errno tapi_bpf_map_get_pin(const char* ta, unsigned int bpf_id, const char* map, char** pin_path)

Get path to a file to which a BPF map is currently pinned.

Parameters:

ta

Test Agent name

bpf_id

BPF ID

map

Map name

pin_path

Path to the file (NULL if the map is not pinned) - should be released by caller

Returns:

Status code.

te_errno tapi_bpf_perf_event_init(const char* ta, unsigned int bpf_id, const char* map, unsigned int event_size)

Initialize perf_event XDP map. Set size of event data and enable event processing.

Parameters:

ta

Test Agent name

bpf_id

Bpf ID

map

Map name

event_size

Size of data passed via an event

Returns:

Status code

te_errno tapi_bpf_perf_event_deinit(const char* ta, unsigned int bpf_id, const char* map)

Disable event processing for specified perf_event map.

Parameters:

ta

Test Agent name

bpf_id

Bpf ID

map

Map name

Returns:

Status code

te_errno tapi_bpf_perf_get_events(const char* ta, unsigned int bpf_id, const char* map, unsigned int* num, uint8_t** data)

Get data from all processed events.

Parameters:

ta

Test Agent name

bpf_id

Bpf ID

map

Map name

num

Number of events

data

Pointer to location for writing events data, memory for the data is allocated by the function using malloc().

Returns:

Status code

te_errno tapi_bpf_perf_map_get_list(const char* ta, unsigned int bpf_id, char*** map, unsigned int* map_count)

Get list of loaded perf_event maps from BPF object

unused if NULL

Parameters:

ta

Test Agent name

bpf_id

Bpf ID

map

Array of map names, should be freed by user, see te_str_free_array

map_count

Pointer to store number of maps in

Returns:

Status code

te_errno tapi_bpf_obj_init(const char* ta, const char* path, tapi_bpf_prog_type type, unsigned int* bpf_id)

Add and load BPF object

Note

The function calls the following functions:

Parameters:

ta

Test Agent name

fname

File path on agent side, file should be exist on agent

type

Type of BPF program

bpf_id

Id of created BPF object

Returns:

Status code

te_errno tapi_bpf_obj_fini(const char* ta, unsigned int bpf_id)

Unload and delete BPF object

Parameters:

ta

Test Agent name

bpf_id

Id of BPF object

Returns:

Status code

te_errno tapi_bpf_prog_name_check(const char* ta, unsigned int bpf_id, const char* prog_name)

Check that program name is in list of loaded programs

Parameters:

ta

Test Agent name

bpf_id

Id of BPF object

prog_name

The name of program to search

Returns:

Status code

te_errno tapi_bpf_map_type_name_check(const char* ta, unsigned int bpf_id, const char* map_name, tapi_bpf_map_type map_type)

Check that map name is in list of loaded maps assuming its type.

Parameters:

ta

Test Agent name

bpf_id

Id of BPF object

map_name

The name of map to search

map_type

Type of the checked map

Returns:

Status code

static te_errno tapi_bpf_map_name_check(const char* ta, unsigned int bpf_id, const char* map_name)

Check that map name is in list of loaded maps

Parameters:

ta

Test Agent name

bpf_id

Id of BPF object

map_name

The name of map to search

Returns:

Status code

te_errno tapi_bpf_ip_tcpudp_filter_from_sa(te_bpf_ip_tcpudp_filter* filter, int family, int protocol, const struct sockaddr* src_addr, const struct sockaddr* dst_addr)

Fill IP TCP/UDP filter for BPF/XDP hook from provided sockaddr structures.

Parameters:

filter

Filter to fill

family

AF_INET or AF_INET6

protocol

IPPROTO_TCP or IPPROTO_UDP

src_addr

Source address/port (may be NULL to match everything)

dst_addr

Destination address/port (may be NULL to match everything)

Returns:

Status code.