|
@@ -77,6 +77,26 @@ static const char * const prog_type_name[] = {
|
|
[BPF_PROG_TYPE_FLOW_DISSECTOR] = "flow_dissector",
|
|
[BPF_PROG_TYPE_FLOW_DISSECTOR] = "flow_dissector",
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+static const char * const attach_type_strings[] = {
|
|
|
|
+ [BPF_SK_SKB_STREAM_PARSER] = "stream_parser",
|
|
|
|
+ [BPF_SK_SKB_STREAM_VERDICT] = "stream_verdict",
|
|
|
|
+ [BPF_SK_MSG_VERDICT] = "msg_verdict",
|
|
|
|
+ [__MAX_BPF_ATTACH_TYPE] = NULL,
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+enum bpf_attach_type parse_attach_type(const char *str)
|
|
|
|
+{
|
|
|
|
+ enum bpf_attach_type type;
|
|
|
|
+
|
|
|
|
+ for (type = 0; type < __MAX_BPF_ATTACH_TYPE; type++) {
|
|
|
|
+ if (attach_type_strings[type] &&
|
|
|
|
+ is_prefix(str, attach_type_strings[type]))
|
|
|
|
+ return type;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return __MAX_BPF_ATTACH_TYPE;
|
|
|
|
+}
|
|
|
|
+
|
|
static void print_boot_time(__u64 nsecs, char *buf, unsigned int size)
|
|
static void print_boot_time(__u64 nsecs, char *buf, unsigned int size)
|
|
{
|
|
{
|
|
struct timespec real_time_ts, boot_time_ts;
|
|
struct timespec real_time_ts, boot_time_ts;
|
|
@@ -697,6 +717,77 @@ int map_replace_compar(const void *p1, const void *p2)
|
|
return a->idx - b->idx;
|
|
return a->idx - b->idx;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static int do_attach(int argc, char **argv)
|
|
|
|
+{
|
|
|
|
+ enum bpf_attach_type attach_type;
|
|
|
|
+ int err, mapfd, progfd;
|
|
|
|
+
|
|
|
|
+ if (!REQ_ARGS(5)) {
|
|
|
|
+ p_err("too few parameters for map attach");
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ progfd = prog_parse_fd(&argc, &argv);
|
|
|
|
+ if (progfd < 0)
|
|
|
|
+ return progfd;
|
|
|
|
+
|
|
|
|
+ attach_type = parse_attach_type(*argv);
|
|
|
|
+ if (attach_type == __MAX_BPF_ATTACH_TYPE) {
|
|
|
|
+ p_err("invalid attach type");
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ }
|
|
|
|
+ NEXT_ARG();
|
|
|
|
+
|
|
|
|
+ mapfd = map_parse_fd(&argc, &argv);
|
|
|
|
+ if (mapfd < 0)
|
|
|
|
+ return mapfd;
|
|
|
|
+
|
|
|
|
+ err = bpf_prog_attach(progfd, mapfd, attach_type, 0);
|
|
|
|
+ if (err) {
|
|
|
|
+ p_err("failed prog attach to map");
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (json_output)
|
|
|
|
+ jsonw_null(json_wtr);
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int do_detach(int argc, char **argv)
|
|
|
|
+{
|
|
|
|
+ enum bpf_attach_type attach_type;
|
|
|
|
+ int err, mapfd, progfd;
|
|
|
|
+
|
|
|
|
+ if (!REQ_ARGS(5)) {
|
|
|
|
+ p_err("too few parameters for map detach");
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ progfd = prog_parse_fd(&argc, &argv);
|
|
|
|
+ if (progfd < 0)
|
|
|
|
+ return progfd;
|
|
|
|
+
|
|
|
|
+ attach_type = parse_attach_type(*argv);
|
|
|
|
+ if (attach_type == __MAX_BPF_ATTACH_TYPE) {
|
|
|
|
+ p_err("invalid attach type");
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ }
|
|
|
|
+ NEXT_ARG();
|
|
|
|
+
|
|
|
|
+ mapfd = map_parse_fd(&argc, &argv);
|
|
|
|
+ if (mapfd < 0)
|
|
|
|
+ return mapfd;
|
|
|
|
+
|
|
|
|
+ err = bpf_prog_detach2(progfd, mapfd, attach_type);
|
|
|
|
+ if (err) {
|
|
|
|
+ p_err("failed prog detach from map");
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (json_output)
|
|
|
|
+ jsonw_null(json_wtr);
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
static int do_load(int argc, char **argv)
|
|
static int do_load(int argc, char **argv)
|
|
{
|
|
{
|
|
enum bpf_attach_type expected_attach_type;
|
|
enum bpf_attach_type expected_attach_type;
|
|
@@ -942,6 +1033,8 @@ static int do_help(int argc, char **argv)
|
|
" %s %s pin PROG FILE\n"
|
|
" %s %s pin PROG FILE\n"
|
|
" %s %s load OBJ FILE [type TYPE] [dev NAME] \\\n"
|
|
" %s %s load OBJ FILE [type TYPE] [dev NAME] \\\n"
|
|
" [map { idx IDX | name NAME } MAP]\n"
|
|
" [map { idx IDX | name NAME } MAP]\n"
|
|
|
|
+ " %s %s attach PROG ATTACH_TYPE MAP\n"
|
|
|
|
+ " %s %s detach PROG ATTACH_TYPE MAP\n"
|
|
" %s %s help\n"
|
|
" %s %s help\n"
|
|
"\n"
|
|
"\n"
|
|
" " HELP_SPEC_MAP "\n"
|
|
" " HELP_SPEC_MAP "\n"
|
|
@@ -953,10 +1046,12 @@ static int do_help(int argc, char **argv)
|
|
" cgroup/bind4 | cgroup/bind6 | cgroup/post_bind4 |\n"
|
|
" cgroup/bind4 | cgroup/bind6 | cgroup/post_bind4 |\n"
|
|
" cgroup/post_bind6 | cgroup/connect4 | cgroup/connect6 |\n"
|
|
" cgroup/post_bind6 | cgroup/connect4 | cgroup/connect6 |\n"
|
|
" cgroup/sendmsg4 | cgroup/sendmsg6 }\n"
|
|
" cgroup/sendmsg4 | cgroup/sendmsg6 }\n"
|
|
|
|
+ " ATTACH_TYPE := { msg_verdict | skb_verdict | skb_parse }\n"
|
|
" " HELP_SPEC_OPTIONS "\n"
|
|
" " HELP_SPEC_OPTIONS "\n"
|
|
"",
|
|
"",
|
|
bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2],
|
|
bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2],
|
|
- bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2]);
|
|
|
|
|
|
+ bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2],
|
|
|
|
+ bin_name, argv[-2], bin_name, argv[-2]);
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -968,6 +1063,8 @@ static const struct cmd cmds[] = {
|
|
{ "dump", do_dump },
|
|
{ "dump", do_dump },
|
|
{ "pin", do_pin },
|
|
{ "pin", do_pin },
|
|
{ "load", do_load },
|
|
{ "load", do_load },
|
|
|
|
+ { "attach", do_attach },
|
|
|
|
+ { "detach", do_detach },
|
|
{ 0 }
|
|
{ 0 }
|
|
};
|
|
};
|
|
|
|
|