]> git.ipfire.org Git - thirdparty/iproute2.git/commitdiff
ip: drop 2-char command assumption
authorTony Ambardar <tony.ambardar@gmail.com>
Tue, 20 Apr 2021 08:26:36 +0000 (01:26 -0700)
committerDavid Ahern <dsahern@kernel.org>
Mon, 26 Apr 2021 02:29:42 +0000 (02:29 +0000)
The 'ip' utility hardcodes the assumption of being a 2-char command, where
any follow-on characters are passed as an argument:

  $ ./ip-full help
  Object "-full" is unknown, try "ip help".

This confusing behaviour isn't seen with 'tc' for example, and was added in
a 2005 commit without documentation. It was noticed during testing of 'ip'
variants built/packaged with different feature sets (e.g. w/o BPF support).

Mitigate the problem by redoing the command without the 2-char assumption
if the follow-on characters fail to parse as a valid command.

Fixes: 351efcde4e62 ("Update header files to 2.6.14")
Signed-off-by: Tony Ambardar <Tony.Ambardar@gmail.com>
Signed-off-by: David Ahern <dsahern@kernel.org>
ip/ip.c

diff --git a/ip/ip.c b/ip/ip.c
index c561c01f6810bb5f88e69c37e4219d4e1aade170..16ba94a1878769ee2b2fec4926517341d0e1cde0 100644 (file)
--- a/ip/ip.c
+++ b/ip/ip.c
@@ -125,7 +125,7 @@ static const struct cmd {
        { 0 }
 };
 
-static int do_cmd(const char *argv0, int argc, char **argv)
+static int do_cmd(const char *argv0, int argc, char **argv, bool final)
 {
        const struct cmd *c;
 
@@ -134,7 +134,8 @@ static int do_cmd(const char *argv0, int argc, char **argv)
                        return -(c->func(argc-1, argv+1));
        }
 
-       fprintf(stderr, "Object \"%s\" is unknown, try \"ip help\".\n", argv0);
+       if (final)
+               fprintf(stderr, "Object \"%s\" is unknown, try \"ip help\".\n", argv0);
        return EXIT_FAILURE;
 }
 
@@ -143,7 +144,7 @@ static int ip_batch_cmd(int argc, char *argv[], void *data)
        const int *orig_family = data;
 
        preferred_family = *orig_family;
-       return do_cmd(argv[0], argc, argv);
+       return do_cmd(argv[0], argc, argv, true);
 }
 
 static int batch(const char *name)
@@ -312,11 +313,14 @@ int main(int argc, char **argv)
 
        rtnl_set_strict_dump(&rth);
 
-       if (strlen(basename) > 2)
-               return do_cmd(basename+2, argc, argv);
+       if (strlen(basename) > 2) {
+               int ret = do_cmd(basename+2, argc, argv, false);
+               if (ret != EXIT_FAILURE)
+                       return ret;
+       }
 
        if (argc > 1)
-               return do_cmd(argv[1], argc-1, argv+1);
+               return do_cmd(argv[1], argc-1, argv+1, true);
 
        rtnl_close(&rth);
        usage();