This is how to use SOCKMAP: SOCKMAP or specifically "BPF_MAP_TYPE_SOCKMAP", is a type of an eBPF map. This map is an "array" - indices are integers. All this is pretty standard. The magic is in the map values - they must be TCP socket descriptors.
copy from:https://blog.cloudflare.com/sockmap-tcp-splicing-of-the-future/
也就是eBPF程序必须attach一个map,不是attach一个socket。so how to use SOCKMAP ?
sock_map = bpf_create_map(BPF_MAP_TYPE_SOCKMAP, sizeof(int), sizeof(int), 2, 0) prog_parser = bpf_load_program(BPF_PROG_TYPE_SK_SKB, ...) prog_verdict = bpf_load_program(BPF_PROG_TYPE_SK_SKB, ...) bpf_prog_attach(prog_parser, sock_map, BPF_SK_SKB_STREAM_PARSER) bpf_prog_attach(prog_verdict, sock_map, BPF_SK_SKB_STREAM_VERDICT)
-
先看看 bpf_create_map的作用: 创建一个map内存块
-
BPF map的应用场景有几种:
- BPF程序和用户态态的交互:BPF程序运行完,得到的结果存储到map中,供用户态访问;
- BPF程序内部交互:如果BPF程序内部需要用全局变量来交互,但是由于安全原因BPF程序不允许访问全局变量,可以使用map来充当全局变量;
- BPF Tail call:Tail call是一个BPF程序跳转到另一BPF程序,BPF程序首先通过BPF_MAP_TYPE_PROG_ARRAY类型的map来知道另一个BPF程序的指针,然后调用tail_call()的helper function来执行Tail call。
- BPF程序和内核态的交互:和BPF程序以外的内核程序交互,也可以使用map作为中介;
-
- Map 类型(
map_type
),就是上文提到的各种 Map 类型 - Map 的键大小(
key_size
),以字节为单位 - Map 的值大小(
value_size
),以字节为单位 - Map 的元素最大容量(
max_entries
),个数为单位
- Map 类型(
{ struct { /* anonymous struct used by BPF_MAP_CREATE command */ __u32 map_type; /* one of enum bpf_map_type */ __u32 key_size; /* size of key in bytes */ __u32 value_size; /* size of value in bytes */ __u32 max_entries; /* max number of entries in a map */ __u32 map_flags; /* BPF_MAP_CREATE related * flags defined above. */ __u32 inner_map_fd; /* fd pointing to the inner map */ __u32 numa_node; /* numa node (effective only if * BPF_F_NUMA_NODE is set). */ char map_name[BPF_OBJ_NAME_LEN]; __u32 map_ifindex; /* ifindex of netdev to create on */ __u32 btf_fd; /* fd pointing to a BTF type data */ __u32 btf_key_type_id; /* BTF type_id of the key */ __u32 btf_value_type_id; /* BTF type_id of the value */ __u32 btf_vmlinux_value_type_id;/* BTF type_id of a kernel- * struct stored as the * map value */ }; --------------------------- }
int bpf_create_map(enum bpf_map_type map_type, int key_size, int value_size, int max_entries, __u32 map_flags) { struct bpf_create_map_attr map_attr = {}; map_attr.map_type = map_type;//BPF_MAP_TYPE_SOCKMAP BPF_MAP_TYPE_HASH BPF_MAP_TYPE_ARRAY and so on map_attr.map_flags = map_flags;//map的标志位 map_attr.key_size = key_size; //键值 中键的大小 map_attr.value_size = value_size;// 键值中值的大小 map_attr.max_entries = max_entries;//map键值对 最大数目 return bpf_create_map_xattr(&map_attr); }

int bpf_create_map_xattr(const struct bpf_create_map_attr *create_attr) { union bpf_attr attr; memset(&attr, '