• Martin KaFai Lau's avatar
    bpf: libbpf: Add STRUCT_OPS support · 590a0088
    Martin KaFai Lau authored
    This patch adds BPF STRUCT_OPS support to libbpf.
    
    The only sec_name convention is SEC(".struct_ops") to identify the
    struct_ops implemented in BPF,
    e.g. To implement a tcp_congestion_ops:
    
    SEC(".struct_ops")
    struct tcp_congestion_ops dctcp = {
    	.init           = (void *)dctcp_init,  /* <-- a bpf_prog */
    	/* ... some more func prts ... */
    	.name           = "bpf_dctcp",
    };
    
    Each struct_ops is defined as a global variable under SEC(".struct_ops")
    as above.  libbpf creates a map for each variable and the variable name
    is the map's name.  Multiple struct_ops is supported under
    SEC(".struct_ops").
    
    In the bpf_object__open phase, libbpf will look for the SEC(".struct_ops")
    section and find out what is the btf-type the struct_ops is
    implementing.  Note that the btf-type here is referring to
    a type in the bpf_prog.o's btf.  A "struct bpf_map" is added
    by bpf_object__add_map() as other maps do.  It will then
    collect (through SHT_REL) where are the bpf progs that the
    func ptrs are referring to.  No btf_vmlinux is needed in
    the open phase.
    
    In the bpf_object__load phase, the map-fields, which depend
    on the btf_vmlinux, are initialized (in bpf_map__init_kern_struct_ops()).
    It will also set the prog->type, prog->attach_btf_id, and
    prog->expected_attach_type.  Thus, the prog's properties do
    not rely on its section name.
    [ Currently, the bpf_prog's btf-type ==> btf_vmlinux's btf-type matching
      process is as simple as: member-name match + btf-kind match + size match.
      If these matching conditions fail, libbpf will reject.
      The current targeting support is "struct tcp_congestion_ops" which
      most of its members are function pointers.
      The member ordering of the bpf_prog's btf-type can be different from
      the btf_vmlinux's btf-type. ]
    
    Then, all obj->maps are created as usual (in bpf_object__create_maps()).
    
    Once the maps are created and prog's properties are all set,
    the libbpf will proceed to load all the progs.
    
    bpf_map__attach_struct_ops() is added to register a struct_ops
    map to a kernel subsystem.
    Signed-off-by: default avatarMartin KaFai Lau <kafai@fb.com>
    Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
    Link: https://lore.kernel.org/bpf/20200109003514.3856730-1-kafai@fb.com
    590a0088
bpf.c 18.5 KB