SEC_DEF("netkit/peer", SCHED_CLS, BPF_NETKIT_PEER, SEC_NONE),
SEC_DEF("tracepoint+", TRACEPOINT, 0, SEC_NONE, attach_tp),
SEC_DEF("tp+", TRACEPOINT, 0, SEC_NONE, attach_tp),
+ SEC_DEF("tracepoint.s+", TRACEPOINT, 0, SEC_SLEEPABLE, attach_tp),
+ SEC_DEF("tp.s+", TRACEPOINT, 0, SEC_SLEEPABLE, attach_tp),
SEC_DEF("raw_tracepoint+", RAW_TRACEPOINT, 0, SEC_NONE, attach_raw_tp),
SEC_DEF("raw_tp+", RAW_TRACEPOINT, 0, SEC_NONE, attach_raw_tp),
+ SEC_DEF("raw_tracepoint.s+", RAW_TRACEPOINT, 0, SEC_SLEEPABLE, attach_raw_tp),
+ SEC_DEF("raw_tp.s+", RAW_TRACEPOINT, 0, SEC_SLEEPABLE, attach_raw_tp),
SEC_DEF("raw_tracepoint.w+", RAW_TRACEPOINT_WRITABLE, 0, SEC_NONE, attach_raw_tp),
SEC_DEF("raw_tp.w+", RAW_TRACEPOINT_WRITABLE, 0, SEC_NONE, attach_raw_tp),
SEC_DEF("tp_btf+", TRACING, BPF_TRACE_RAW_TP, SEC_ATTACH_BTF, attach_trace),
+ SEC_DEF("tp_btf.s+", TRACING, BPF_TRACE_RAW_TP, SEC_ATTACH_BTF | SEC_SLEEPABLE, attach_trace),
SEC_DEF("fentry+", TRACING, BPF_TRACE_FENTRY, SEC_ATTACH_BTF, attach_trace),
SEC_DEF("fmod_ret+", TRACING, BPF_MODIFY_RETURN, SEC_ATTACH_BTF, attach_trace),
SEC_DEF("fexit+", TRACING, BPF_TRACE_FEXIT, SEC_ATTACH_BTF, attach_trace),
return bpf_program__attach_tracepoint_opts(prog, tp_category, tp_name, NULL);
}
+/*
+ * Match section name against a prefix array. Returns pointer past
+ * "prefix/" on match, empty string for bare sections (exact prefix
+ * match), or NULL if no prefix matches.
+ */
+static const char *sec_name_match_prefix(const char *sec_name,
+ const char *const *prefixes,
+ size_t n)
+{
+ size_t i;
+
+ for (i = 0; i < n; i++) {
+ size_t pfx_len;
+
+ if (!str_has_pfx(sec_name, prefixes[i]))
+ continue;
+
+ pfx_len = strlen(prefixes[i]);
+ if (sec_name[pfx_len] == '\0')
+ return sec_name + pfx_len;
+
+ if (sec_name[pfx_len] != '/' || sec_name[pfx_len + 1] == '\0')
+ continue;
+
+ return sec_name + pfx_len + 1;
+ }
+ return NULL;
+}
+
static int attach_tp(const struct bpf_program *prog, long cookie, struct bpf_link **link)
{
+ static const char *const prefixes[] = {
+ "tp.s",
+ "tp",
+ "tracepoint.s",
+ "tracepoint",
+ };
char *sec_name, *tp_cat, *tp_name;
+ const char *match;
*link = NULL;
- /* no auto-attach for SEC("tp") or SEC("tracepoint") */
- if (strcmp(prog->sec_name, "tp") == 0 || strcmp(prog->sec_name, "tracepoint") == 0)
+ match = sec_name_match_prefix(prog->sec_name, prefixes, ARRAY_SIZE(prefixes));
+ if (!match) {
+ pr_warn("prog '%s': invalid section name '%s'\n", prog->name, prog->sec_name);
+ return -EINVAL;
+ }
+ if (!match[0]) /* bare section name no autoattach */
return 0;
sec_name = strdup(prog->sec_name);
if (!sec_name)
return -ENOMEM;
- /* extract "tp/<category>/<name>" or "tracepoint/<category>/<name>" */
- if (str_has_pfx(prog->sec_name, "tp/"))
- tp_cat = sec_name + sizeof("tp/") - 1;
- else
- tp_cat = sec_name + sizeof("tracepoint/") - 1;
+ tp_cat = sec_name + (match - prog->sec_name);
tp_name = strchr(tp_cat, '/');
if (!tp_name) {
free(sec_name);
"raw_tracepoint",
"raw_tp.w",
"raw_tracepoint.w",
+ "raw_tp.s",
+ "raw_tracepoint.s",
};
- size_t i;
- const char *tp_name = NULL;
+ const char *match;
*link = NULL;
- for (i = 0; i < ARRAY_SIZE(prefixes); i++) {
- size_t pfx_len;
-
- if (!str_has_pfx(prog->sec_name, prefixes[i]))
- continue;
-
- pfx_len = strlen(prefixes[i]);
- /* no auto-attach case of, e.g., SEC("raw_tp") */
- if (prog->sec_name[pfx_len] == '\0')
- return 0;
-
- if (prog->sec_name[pfx_len] != '/')
- continue;
-
- tp_name = prog->sec_name + pfx_len + 1;
- break;
- }
-
- if (!tp_name) {
- pr_warn("prog '%s': invalid section name '%s'\n",
- prog->name, prog->sec_name);
+ match = sec_name_match_prefix(prog->sec_name, prefixes, ARRAY_SIZE(prefixes));
+ if (!match) {
+ pr_warn("prog '%s': invalid section name '%s'\n", prog->name, prog->sec_name);
return -EINVAL;
}
+ if (!match[0])
+ return 0;
- *link = bpf_program__attach_raw_tracepoint(prog, tp_name);
+ *link = bpf_program__attach_raw_tracepoint(prog, match);
return libbpf_get_error(*link);
}