BPF_MAP_TYPE_SK_STORAGE¶
注意
BPF_MAP_TYPE_SK_STORAGE
在内核版本 5.2 中引入
BPF_MAP_TYPE_SK_STORAGE
用于为 BPF 程序提供套接字本地存储。类型为 BPF_MAP_TYPE_SK_STORAGE
的 map 声明要提供的存储类型,并充当访问套接字本地存储的句柄。类型为 BPF_MAP_TYPE_SK_STORAGE
的 map 的值存储在每个套接字本地,而不是与 map 存储在一起。内核负责在请求时为套接字分配存储空间,并在删除 map 或套接字时释放存储空间。
注意
键类型必须为
int
,max_entries
必须设置为0
。创建套接字本地存储的 map 时,必须使用
BPF_F_NO_PREALLOC
标志。
用法¶
内核 BPF¶
bpf_sk_storage_get()¶
void *bpf_sk_storage_get(struct bpf_map *map, void *sk, void *value, u64 flags)
可以使用 bpf_sk_storage_get()
辅助函数从套接字 sk
中检索 map
的套接字本地存储。如果使用 BPF_LOCAL_STORAGE_GET_F_CREATE
标志,则如果 sk
的存储尚不存在,bpf_sk_storage_get()
将为 sk
创建存储空间。value
可以与 BPF_LOCAL_STORAGE_GET_F_CREATE
一起用于初始化存储值,否则将初始化为零。成功时返回指向存储的指针,如果失败则返回 NULL
。
注意
sk
是 LSM 或跟踪程序的内核struct sock
指针。sk
是其他程序类型的struct bpf_sock
指针。
bpf_sk_storage_delete()¶
long bpf_sk_storage_delete(struct bpf_map *map, void *sk)
可以使用 bpf_sk_storage_delete()
辅助函数从套接字 sk
中删除 map
的套接字本地存储。成功时返回 0
,如果失败则返回负错误。
用户空间¶
bpf_map_update_elem()¶
int bpf_map_update_elem(int map_fd, const void *key, const void *value, __u64 flags)
可以使用 bpf_map_update_elem()
libbpf 函数在本地将 map map_fd
的套接字本地存储添加到套接字或更新。套接字由指针 key
中存储的 socket fd
标识。指针 value
包含要添加到套接字 fd
或更新的数据。value
的类型和大小应与 map 定义的值类型相同。
可以使用 flags
参数来控制更新行为
BPF_ANY
将为 socketfd
创建存储空间或更新现有存储空间。仅当 socket
fd
尚未存在时,BPF_NOEXIST
才会为其创建存储空间,否则调用将失败并返回-EEXIST
。如果 socket
fd
的存储空间已存在,则BPF_EXIST
将更新该存储空间,否则调用将失败并返回-ENOENT
。
成功时返回 0
,如果失败则返回负错误。
bpf_map_lookup_elem()¶
int bpf_map_lookup_elem(int map_fd, const void *key, void *value)
可以使用 bpf_map_lookup_elem()
libbpf 函数从套接字中检索 map map_fd
的套接字本地存储。从由指针 key
中存储的 socket fd
标识的套接字检索存储。成功时返回 0
,如果失败则返回负错误。
bpf_map_delete_elem()¶
int bpf_map_delete_elem(int map_fd, const void *key)
可以使用 bpf_map_delete_elem()
libbpf 函数从套接字中删除 map map_fd
的套接字本地存储。从由指针 key
中存储的 socket fd
标识的套接字删除存储。成功时返回 0
,如果失败则返回负错误。
示例¶
内核 BPF¶
此代码段显示如何在 BPF 程序中声明套接字本地存储
struct {
__uint(type, BPF_MAP_TYPE_SK_STORAGE);
__uint(map_flags, BPF_F_NO_PREALLOC);
__type(key, int);
__type(value, struct my_storage);
} socket_storage SEC(".maps");
此代码段显示如何在 BPF 程序中检索套接字本地存储
SEC("sockops")
int _sockops(struct bpf_sock_ops *ctx)
{
struct my_storage *storage;
struct bpf_sock *sk;
sk = ctx->sk;
if (!sk)
return 1;
storage = bpf_sk_storage_get(&socket_storage, sk, 0,
BPF_LOCAL_STORAGE_GET_F_CREATE);
if (!storage)
return 1;
/* Use 'storage' here */
return 1;
}
有关功能示例,请参阅 tools/testing/selftests/bpf
目录。