tools/bpftool: Add `link detach` subcommand
authorAndrii Nakryiko <andriin@fb.com>
Fri, 31 Jul 2020 18:28:29 +0000 (11:28 -0700)
committerAlexei Starovoitov <ast@kernel.org>
Sun, 2 Aug 2020 03:38:29 +0000 (20:38 -0700)
Add ability to force-detach BPF link. Also add missing error message, if
specified link ID is wrong.

Signed-off-by: Andrii Nakryiko <andriin@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: Song Liu <songliubraving@fb.com>
Acked-by: John Fastabend <john.fastabend@gmail.com>
Link: https://lore.kernel.org/bpf/20200731182830.286260-5-andriin@fb.com
tools/bpf/bpftool/link.c

index 326b8fd..1b79375 100644 (file)
@@ -22,6 +22,8 @@ static const char * const link_type_name[] = {
 
 static int link_parse_fd(int *argc, char ***argv)
 {
+       int fd;
+
        if (is_prefix(**argv, "id")) {
                unsigned int id;
                char *endptr;
@@ -35,7 +37,10 @@ static int link_parse_fd(int *argc, char ***argv)
                }
                NEXT_ARGP();
 
-               return bpf_link_get_fd_by_id(id);
+               fd = bpf_link_get_fd_by_id(id);
+               if (fd < 0)
+                       p_err("failed to get link with ID %d: %s", id, strerror(errno));
+               return fd;
        } else if (is_prefix(**argv, "pinned")) {
                char *path;
 
@@ -316,6 +321,34 @@ static int do_pin(int argc, char **argv)
        return err;
 }
 
+static int do_detach(int argc, char **argv)
+{
+       int err, fd;
+
+       if (argc != 2) {
+               p_err("link specifier is invalid or missing\n");
+               return 1;
+       }
+
+       fd = link_parse_fd(&argc, &argv);
+       if (fd < 0)
+               return 1;
+
+       err = bpf_link_detach(fd);
+       if (err)
+               err = -errno;
+       close(fd);
+       if (err) {
+               p_err("failed link detach: %s", strerror(-err));
+               return 1;
+       }
+
+       if (json_output)
+               jsonw_null(json_wtr);
+
+       return 0;
+}
+
 static int do_help(int argc, char **argv)
 {
        if (json_output) {
@@ -326,6 +359,7 @@ static int do_help(int argc, char **argv)
        fprintf(stderr,
                "Usage: %1$s %2$s { show | list }   [LINK]\n"
                "       %1$s %2$s pin        LINK  FILE\n"
+               "       %1$s %2$s detach     LINK\n"
                "       %1$s %2$s help\n"
                "\n"
                "       " HELP_SPEC_LINK "\n"
@@ -341,6 +375,7 @@ static const struct cmd cmds[] = {
        { "list",       do_show },
        { "help",       do_help },
        { "pin",        do_pin },
+       { "detach",     do_detach },
        { 0 }
 };