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),个数为单位
{
    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, '\0', sizeof(attr));
    // 完成 bpf_attr的赋值初始化
    attr.map_type = create_attr->map_type;
    attr.key_size = create_attr->key_size;
    attr.value_size = create_attr->value_size;
    attr.max_entries = create_attr->max_entries;
    attr.map_flags = create_attr->map_flags;
    if (create_attr->name)
        memcpy(attr.map_name, create_attr->name,
               min(strlen(create_attr->name), BPF_OBJ_NAME_LEN - 1));
    attr.numa_node = create_attr->numa_node;
    attr.btf_fd = create_attr->btf_fd;
    attr.btf_key_type_id = create_attr->btf_key_type_id;
    attr.btf_value_type_id = create_attr->btf_value_type_id;
    attr.map_ifindex = create_attr->map_ifindex;
    if (attr.map_type == BPF_MAP_TYPE_STRUCT_OPS)
        attr.btf_vmlinux_value_type_id =
            create_attr->btf_vmlinux_value_type_id;
    else
        attr.inner_map_fd = create_attr->inner_map_fd;
    //调用bpf 系统调用 创建 一个map bpf 第一个参数为命令参数,比如: BPF_MAP_CREATE BPF_MAP_UPDATE_ELEM BPF_MAP_DELETE_ELEM
    return sys_bpf(BPF_MAP_CREATE, &attr, sizeof(attr));
}
View Code

相关文章:

  • 2022-12-23
  • 2022-02-17
  • 2022-12-23
  • 2022-12-23
  • 2022-01-01
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2021-09-08
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-12-25
相关资源
相似解决方案