aboutsummaryrefslogtreecommitdiffstats
path: root/tools/lib/bpf
diff options
context:
space:
mode:
authorAndrey Ignatov <rdna@fb.com>2018-09-26 18:24:53 -0400
committerDaniel Borkmann <daniel@iogearbox.net>2018-09-27 15:14:59 -0400
commit956b620fcf0b64de403cd26a56bc41e6e4826ea6 (patch)
tree49a7679ff3ad2a83ed6a07fb3ca4498da0789452 /tools/lib/bpf
parent100811936f89fd455eda1984810c09003550555b (diff)
libbpf: Introduce libbpf_attach_type_by_name
There is a common use-case when ELF object contains multiple BPF programs and every program has its own section name. If it's cgroup-bpf then programs have to be 1) loaded and 2) attached to a cgroup. It's convenient to have information necessary to load BPF program together with program itself. This is where section name works fine in conjunction with libbpf_prog_type_by_name that identifies prog_type and expected_attach_type and these can be used with BPF_PROG_LOAD. But there is currently no way to identify attach_type by section name and it leads to messy code in user space that reinvents guessing logic every time it has to identify attach type to use with BPF_PROG_ATTACH. The patch introduces libbpf_attach_type_by_name that guesses attach type by section name if a program can be attached. The difference between expected_attach_type provided by libbpf_prog_type_by_name and attach_type provided by libbpf_attach_type_by_name is the former is used at BPF_PROG_LOAD time and can be zero if a program of prog_type X has only one corresponding attach type Y whether the latter provides specific attach type to use with BPF_PROG_ATTACH. No new section names were added to section_names array. Only existing ones were reorganized and attach_type was added where appropriate. Signed-off-by: Andrey Ignatov <rdna@fb.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Diffstat (limited to 'tools/lib/bpf')
-rw-r--r--tools/lib/bpf/libbpf.c121
-rw-r--r--tools/lib/bpf/libbpf.h2
2 files changed, 84 insertions, 39 deletions
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 4f8d43ae20d2..59e589a64d5c 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -2085,58 +2085,82 @@ void bpf_program__set_expected_attach_type(struct bpf_program *prog,
2085 prog->expected_attach_type = type; 2085 prog->expected_attach_type = type;
2086} 2086}
2087 2087
2088#define BPF_PROG_SEC_FULL(string, ptype, atype) \ 2088#define BPF_PROG_SEC_IMPL(string, ptype, eatype, atype) \
2089 { string, sizeof(string) - 1, ptype, atype } 2089 { string, sizeof(string) - 1, ptype, eatype, atype }
2090 2090
2091#define BPF_PROG_SEC(string, ptype) BPF_PROG_SEC_FULL(string, ptype, 0) 2091/* Programs that can NOT be attached. */
2092#define BPF_PROG_SEC(string, ptype) BPF_PROG_SEC_IMPL(string, ptype, 0, -EINVAL)
2092 2093
2093#define BPF_S_PROG_SEC(string, ptype) \ 2094/* Programs that can be attached. */
2094 BPF_PROG_SEC_FULL(string, BPF_PROG_TYPE_CGROUP_SOCK, ptype) 2095#define BPF_APROG_SEC(string, ptype, atype) \
2096 BPF_PROG_SEC_IMPL(string, ptype, 0, atype)
2095 2097
2096#define BPF_SA_PROG_SEC(string, ptype) \ 2098/* Programs that must specify expected attach type at load time. */
2097 BPF_PROG_SEC_FULL(string, BPF_PROG_TYPE_CGROUP_SOCK_ADDR, ptype) 2099#define BPF_EAPROG_SEC(string, ptype, eatype) \
2100 BPF_PROG_SEC_IMPL(string, ptype, eatype, eatype)
2101
2102/* Programs that can be attached but attach type can't be identified by section
2103 * name. Kept for backward compatibility.
2104 */
2105#define BPF_APROG_COMPAT(string, ptype) BPF_PROG_SEC(string, ptype)
2098 2106
2099static const struct { 2107static const struct {
2100 const char *sec; 2108 const char *sec;
2101 size_t len; 2109 size_t len;
2102 enum bpf_prog_type prog_type; 2110 enum bpf_prog_type prog_type;
2103 enum bpf_attach_type expected_attach_type; 2111 enum bpf_attach_type expected_attach_type;
2112 enum bpf_attach_type attach_type;
2104} section_names[] = { 2113} section_names[] = {
2105 BPF_PROG_SEC("socket", BPF_PROG_TYPE_SOCKET_FILTER), 2114 BPF_PROG_SEC("socket", BPF_PROG_TYPE_SOCKET_FILTER),
2106 BPF_PROG_SEC("kprobe/", BPF_PROG_TYPE_KPROBE), 2115 BPF_PROG_SEC("kprobe/", BPF_PROG_TYPE_KPROBE),
2107 BPF_PROG_SEC("kretprobe/", BPF_PROG_TYPE_KPROBE), 2116 BPF_PROG_SEC("kretprobe/", BPF_PROG_TYPE_KPROBE),
2108 BPF_PROG_SEC("classifier", BPF_PROG_TYPE_SCHED_CLS), 2117 BPF_PROG_SEC("classifier", BPF_PROG_TYPE_SCHED_CLS),
2109 BPF_PROG_SEC("action", BPF_PROG_TYPE_SCHED_ACT), 2118 BPF_PROG_SEC("action", BPF_PROG_TYPE_SCHED_ACT),
2110 BPF_PROG_SEC("tracepoint/", BPF_PROG_TYPE_TRACEPOINT), 2119 BPF_PROG_SEC("tracepoint/", BPF_PROG_TYPE_TRACEPOINT),
2111 BPF_PROG_SEC("raw_tracepoint/", BPF_PROG_TYPE_RAW_TRACEPOINT), 2120 BPF_PROG_SEC("raw_tracepoint/", BPF_PROG_TYPE_RAW_TRACEPOINT),
2112 BPF_PROG_SEC("xdp", BPF_PROG_TYPE_XDP), 2121 BPF_PROG_SEC("xdp", BPF_PROG_TYPE_XDP),
2113 BPF_PROG_SEC("perf_event", BPF_PROG_TYPE_PERF_EVENT), 2122 BPF_PROG_SEC("perf_event", BPF_PROG_TYPE_PERF_EVENT),
2114 BPF_PROG_SEC("cgroup/skb", BPF_PROG_TYPE_CGROUP_SKB), 2123 BPF_PROG_SEC("lwt_in", BPF_PROG_TYPE_LWT_IN),
2115 BPF_PROG_SEC("cgroup/sock", BPF_PROG_TYPE_CGROUP_SOCK), 2124 BPF_PROG_SEC("lwt_out", BPF_PROG_TYPE_LWT_OUT),
2116 BPF_PROG_SEC("cgroup/dev", BPF_PROG_TYPE_CGROUP_DEVICE), 2125 BPF_PROG_SEC("lwt_xmit", BPF_PROG_TYPE_LWT_XMIT),
2117 BPF_PROG_SEC("lwt_in", BPF_PROG_TYPE_LWT_IN), 2126 BPF_PROG_SEC("lwt_seg6local", BPF_PROG_TYPE_LWT_SEG6LOCAL),
2118 BPF_PROG_SEC("lwt_out", BPF_PROG_TYPE_LWT_OUT), 2127 BPF_APROG_COMPAT("cgroup/skb", BPF_PROG_TYPE_CGROUP_SKB),
2119 BPF_PROG_SEC("lwt_xmit", BPF_PROG_TYPE_LWT_XMIT), 2128 BPF_APROG_SEC("cgroup/sock", BPF_PROG_TYPE_CGROUP_SOCK,
2120 BPF_PROG_SEC("lwt_seg6local", BPF_PROG_TYPE_LWT_SEG6LOCAL), 2129 BPF_CGROUP_INET_SOCK_CREATE),
2121 BPF_PROG_SEC("sockops", BPF_PROG_TYPE_SOCK_OPS), 2130 BPF_EAPROG_SEC("cgroup/post_bind4", BPF_PROG_TYPE_CGROUP_SOCK,
2122 BPF_PROG_SEC("sk_skb", BPF_PROG_TYPE_SK_SKB), 2131 BPF_CGROUP_INET4_POST_BIND),
2123 BPF_PROG_SEC("sk_msg", BPF_PROG_TYPE_SK_MSG), 2132 BPF_EAPROG_SEC("cgroup/post_bind6", BPF_PROG_TYPE_CGROUP_SOCK,
2124 BPF_PROG_SEC("lirc_mode2", BPF_PROG_TYPE_LIRC_MODE2), 2133 BPF_CGROUP_INET6_POST_BIND),
2125 BPF_PROG_SEC("flow_dissector", BPF_PROG_TYPE_FLOW_DISSECTOR), 2134 BPF_APROG_SEC("cgroup/dev", BPF_PROG_TYPE_CGROUP_DEVICE,
2126 BPF_SA_PROG_SEC("cgroup/bind4", BPF_CGROUP_INET4_BIND), 2135 BPF_CGROUP_DEVICE),
2127 BPF_SA_PROG_SEC("cgroup/bind6", BPF_CGROUP_INET6_BIND), 2136 BPF_APROG_SEC("sockops", BPF_PROG_TYPE_SOCK_OPS,
2128 BPF_SA_PROG_SEC("cgroup/connect4", BPF_CGROUP_INET4_CONNECT), 2137 BPF_CGROUP_SOCK_OPS),
2129 BPF_SA_PROG_SEC("cgroup/connect6", BPF_CGROUP_INET6_CONNECT), 2138 BPF_APROG_COMPAT("sk_skb", BPF_PROG_TYPE_SK_SKB),
2130 BPF_SA_PROG_SEC("cgroup/sendmsg4", BPF_CGROUP_UDP4_SENDMSG), 2139 BPF_APROG_SEC("sk_msg", BPF_PROG_TYPE_SK_MSG,
2131 BPF_SA_PROG_SEC("cgroup/sendmsg6", BPF_CGROUP_UDP6_SENDMSG), 2140 BPF_SK_MSG_VERDICT),
2132 BPF_S_PROG_SEC("cgroup/post_bind4", BPF_CGROUP_INET4_POST_BIND), 2141 BPF_APROG_SEC("lirc_mode2", BPF_PROG_TYPE_LIRC_MODE2,
2133 BPF_S_PROG_SEC("cgroup/post_bind6", BPF_CGROUP_INET6_POST_BIND), 2142 BPF_LIRC_MODE2),
2143 BPF_APROG_SEC("flow_dissector", BPF_PROG_TYPE_FLOW_DISSECTOR,
2144 BPF_FLOW_DISSECTOR),
2145 BPF_EAPROG_SEC("cgroup/bind4", BPF_PROG_TYPE_CGROUP_SOCK_ADDR,
2146 BPF_CGROUP_INET4_BIND),
2147 BPF_EAPROG_SEC("cgroup/bind6", BPF_PROG_TYPE_CGROUP_SOCK_ADDR,
2148 BPF_CGROUP_INET6_BIND),
2149 BPF_EAPROG_SEC("cgroup/connect4", BPF_PROG_TYPE_CGROUP_SOCK_ADDR,
2150 BPF_CGROUP_INET4_CONNECT),
2151 BPF_EAPROG_SEC("cgroup/connect6", BPF_PROG_TYPE_CGROUP_SOCK_ADDR,
2152 BPF_CGROUP_INET6_CONNECT),
2153 BPF_EAPROG_SEC("cgroup/sendmsg4", BPF_PROG_TYPE_CGROUP_SOCK_ADDR,
2154 BPF_CGROUP_UDP4_SENDMSG),
2155 BPF_EAPROG_SEC("cgroup/sendmsg6", BPF_PROG_TYPE_CGROUP_SOCK_ADDR,
2156 BPF_CGROUP_UDP6_SENDMSG),
2134}; 2157};
2135 2158
2159#undef BPF_PROG_SEC_IMPL
2136#undef BPF_PROG_SEC 2160#undef BPF_PROG_SEC
2137#undef BPF_PROG_SEC_FULL 2161#undef BPF_APROG_SEC
2138#undef BPF_S_PROG_SEC 2162#undef BPF_EAPROG_SEC
2139#undef BPF_SA_PROG_SEC 2163#undef BPF_APROG_COMPAT
2140 2164
2141int libbpf_prog_type_by_name(const char *name, enum bpf_prog_type *prog_type, 2165int libbpf_prog_type_by_name(const char *name, enum bpf_prog_type *prog_type,
2142 enum bpf_attach_type *expected_attach_type) 2166 enum bpf_attach_type *expected_attach_type)
@@ -2156,6 +2180,25 @@ int libbpf_prog_type_by_name(const char *name, enum bpf_prog_type *prog_type,
2156 return -EINVAL; 2180 return -EINVAL;
2157} 2181}
2158 2182
2183int libbpf_attach_type_by_name(const char *name,
2184 enum bpf_attach_type *attach_type)
2185{
2186 int i;
2187
2188 if (!name)
2189 return -EINVAL;
2190
2191 for (i = 0; i < ARRAY_SIZE(section_names); i++) {
2192 if (strncmp(name, section_names[i].sec, section_names[i].len))
2193 continue;
2194 if (section_names[i].attach_type == -EINVAL)
2195 return -EINVAL;
2196 *attach_type = section_names[i].attach_type;
2197 return 0;
2198 }
2199 return -EINVAL;
2200}
2201
2159static int 2202static int
2160bpf_program__identify_section(struct bpf_program *prog, 2203bpf_program__identify_section(struct bpf_program *prog,
2161 enum bpf_prog_type *prog_type, 2204 enum bpf_prog_type *prog_type,
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index e3b00e23e181..511c1294dcbf 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -104,6 +104,8 @@ void *bpf_object__priv(struct bpf_object *prog);
104 104
105int libbpf_prog_type_by_name(const char *name, enum bpf_prog_type *prog_type, 105int libbpf_prog_type_by_name(const char *name, enum bpf_prog_type *prog_type,
106 enum bpf_attach_type *expected_attach_type); 106 enum bpf_attach_type *expected_attach_type);
107int libbpf_attach_type_by_name(const char *name,
108 enum bpf_attach_type *attach_type);
107 109
108/* Accessors of bpf_program */ 110/* Accessors of bpf_program */
109struct bpf_program; 111struct bpf_program;