diff options
author | Andrey Ignatov <rdna@fb.com> | 2018-09-26 18:24:53 -0400 |
---|---|---|
committer | Daniel Borkmann <daniel@iogearbox.net> | 2018-09-27 15:14:59 -0400 |
commit | 956b620fcf0b64de403cd26a56bc41e6e4826ea6 (patch) | |
tree | 49a7679ff3ad2a83ed6a07fb3ca4498da0789452 | |
parent | 100811936f89fd455eda1984810c09003550555b (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>
-rw-r--r-- | tools/lib/bpf/libbpf.c | 121 | ||||
-rw-r--r-- | tools/lib/bpf/libbpf.h | 2 |
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 | ||
2099 | static const struct { | 2107 | static 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 | ||
2141 | int libbpf_prog_type_by_name(const char *name, enum bpf_prog_type *prog_type, | 2165 | int 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 | ||
2183 | int 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 | |||
2159 | static int | 2202 | static int |
2160 | bpf_program__identify_section(struct bpf_program *prog, | 2203 | bpf_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 | ||
105 | int libbpf_prog_type_by_name(const char *name, enum bpf_prog_type *prog_type, | 105 | int 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); |
107 | int 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 */ |
109 | struct bpf_program; | 111 | struct bpf_program; |