diff mbox series

[iproute2,v2] ip: drop 2-char command assumption

Message ID 20210420082636.1210305-1-Tony.Ambardar@gmail.com
State New
Headers show
Series [iproute2,v2] ip: drop 2-char command assumption | expand

Commit Message

Tony Ambardar April 20, 2021, 8:26 a.m. UTC
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>
---
v2: (feedback from David Ahern)
  * work around problem but remain compatible with 2-char assumption

---
 ip/ip.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

Comments

David Ahern April 26, 2021, 2:31 a.m. UTC | #1
On 4/20/21 1:26 AM, Tony Ambardar wrote:
> 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>

> ---

> v2: (feedback from David Ahern)

>   * work around problem but remain compatible with 2-char assumption

> 

> ---

>  ip/ip.c | 16 ++++++++++------

>  1 file changed, 10 insertions(+), 6 deletions(-)

> 


Applied. Thanks,
diff mbox series

Patch

diff --git a/ip/ip.c b/ip/ip.c
index 4cf09fc3..8e4c6eb5 100644
--- 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)
@@ -313,11 +314,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();