]> git.proxmox.com Git - mirror_iproute2.git/blobdiff - ip/ip.c
Allow 'ip addr flush' to loop more than 10 times
[mirror_iproute2.git] / ip / ip.c
diff --git a/ip/ip.c b/ip/ip.c
index df6bc10b3dd544d0b19bb85651bf0d6dbc47363d..b127d5708045e29de21ac18a846b2a5b21be6694 100644 (file)
--- a/ip/ip.c
+++ b/ip/ip.c
@@ -7,11 +7,6 @@
  *             2 of the License, or (at your option) any later version.
  *
  * Authors:    Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
- *
- *
- * Changes:
- *
- * Rani Assaf <rani@magic.metawire.com> 980929:        resolve addresses
  */
 
 #include <stdio.h>
 
 int preferred_family = AF_UNSPEC;
 int show_stats = 0;
+int show_details = 0;
 int resolve_hosts = 0;
 int oneline = 0;
 int timestamp = 0;
 char * _SL_ = NULL;
 char *batch_file = NULL;
 int force = 0;
-struct rtnl_handle rth;
+int max_flush_loops = 10;
+
+struct rtnl_handle rth = { .fd = -1 };
 
 static void usage(void) __attribute__((noreturn));
 
@@ -44,12 +42,14 @@ static void usage(void)
 {
        fprintf(stderr,
 "Usage: ip [ OPTIONS ] OBJECT { COMMAND | help }\n"
-"       ip [ -force ] [-batch filename\n"
-"where  OBJECT := { link | addr | route | rule | neigh | tunnel |\n"
-"                   maddr | mroute | monitor | xfrm }\n"
-"       OPTIONS := { -V[ersion] | -s[tatistics] | -r[esolve] |\n"
+"       ip [ -force ] -batch filename\n"
+"where  OBJECT := { link | addr | addrlabel | route | rule | neigh | ntable |\n"
+"                   tunnel | tuntap | maddr | mroute | mrule | monitor | xfrm }\n"
+"       OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] | -r[esolve] |\n"
 "                    -f[amily] { inet | inet6 | ipx | dnet | link } |\n"
-"                    -o[neline] | -t[imestamp] }\n");
+"                    -l[oops] { maximum-addr-flush-attempts } |\n"
+"                    -o[neline] | -t[imestamp] | -b[atch] [filename] |\n"
+"                    -rc[vbuf] [size]}\n");
        exit(-1);
 }
 
@@ -63,40 +63,36 @@ static const struct cmd {
        int (*func)(int argc, char **argv);
 } cmds[] = {
        { "address",    do_ipaddr },
+       { "addrlabel",  do_ipaddrlabel },
        { "maddress",   do_multiaddr },
        { "route",      do_iproute },
        { "rule",       do_iprule },
        { "neighbor",   do_ipneigh },
        { "neighbour",  do_ipneigh },
+       { "ntable",     do_ipntable },
+       { "ntbl",       do_ipntable },
        { "link",       do_iplink },
        { "tunnel",     do_iptunnel },
        { "tunl",       do_iptunnel },
+       { "tuntap",     do_iptuntap },
+       { "tap",        do_iptuntap },
        { "monitor",    do_ipmonitor },
        { "xfrm",       do_xfrm },
        { "mroute",     do_multiroute },
+       { "mrule",      do_multirule },
        { "help",       do_help },
        { 0 }
 };
 
 static int do_cmd(const char *argv0, int argc, char **argv)
 {
-       const struct cmd *c, *m = NULL;
+       const struct cmd *c;
 
        for (c = cmds; c->cmd; ++c) {
-               if (matches(argv0, c->cmd) == 0) {
-                       if (m && m->func != c->func) {
-                               fprintf(stderr, 
-                                       "Ambiguious command \"%s\" matches both %s and %s\n",
-                                       argv0,  m->cmd, c->cmd);
-                               return -1;
-                       }
-                       m = c;
-               }
+               if (matches(argv0, c->cmd) == 0)
+                       return c->func(argc-1, argv+1);
        }
 
-       if (m) 
-               return m->func(argc-1, argv+1);
-
        fprintf(stderr, "Object \"%s\" is unknown, try \"ip help\".\n", argv0);
        return -1;
 }
@@ -106,11 +102,10 @@ static int batch(const char *name)
        char *line = NULL;
        size_t len = 0;
        int ret = 0;
-       int lineno = 0;
 
        if (name && strcmp(name, "-") != 0) {
                if (freopen(name, "r", stdin) == NULL) {
-                       fprintf(stderr, "Cannot open file \"%s\" for reading: %s=n",
+                       fprintf(stderr, "Cannot open file \"%s\" for reading: %s\n",
                                name, strerror(errno));
                        return -1;
                }
@@ -121,6 +116,7 @@ static int batch(const char *name)
                return -1;
        }
 
+       cmdlineno = 0;
        while (getcmdline(&line, &len, stdin) != -1) {
                char *largv[100];
                int largc;
@@ -130,7 +126,7 @@ static int batch(const char *name)
                        continue;       /* blank line */
 
                if (do_cmd(largv[0], largc, largv)) {
-                       fprintf(stderr, "Command failed %s:%d\n", name, lineno);
+                       fprintf(stderr, "Command failed %s:%d\n", name, cmdlineno);
                        ret = 1;
                        if (!force)
                                break;
@@ -153,7 +149,7 @@ int main(int argc, char **argv)
                basename = argv[0];
        else
                basename++;
-       
+
        while (argc > 1) {
                char *opt = argv[1];
                if (strcmp(opt,"--") == 0) {
@@ -164,7 +160,13 @@ int main(int argc, char **argv)
                        break;
                if (opt[1] == '-')
                        opt++;
-               if (matches(opt, "-family") == 0) {
+               if (matches(opt, "-loops") == 0) {
+                       argc--;
+                       argv++;
+                       if (argc <= 1)
+                               usage();
+                        max_flush_loops = atoi(argv[1]);
+                } else if (matches(opt, "-family") == 0) {
                        argc--;
                        argv++;
                        if (argc <= 1)
@@ -196,6 +198,8 @@ int main(int argc, char **argv)
                } else if (matches(opt, "-stats") == 0 ||
                           matches(opt, "-statistics") == 0) {
                        ++show_stats;
+               } else if (matches(opt, "-details") == 0) {
+                       ++show_details;
                } else if (matches(opt, "-resolve") == 0) {
                        ++resolve_hosts;
                } else if (matches(opt, "-oneline") == 0) {
@@ -217,6 +221,19 @@ int main(int argc, char **argv)
                        if (argc <= 1)
                                usage();
                        batch_file = argv[1];
+               } else if (matches(opt, "-rcvbuf") == 0) {
+                       unsigned int size;
+
+                       argc--;
+                       argv++;
+                       if (argc <= 1)
+                               usage();
+                       if (get_unsigned(&size, argv[1], 0)) {
+                               fprintf(stderr, "Invalid rcvbuf size '%s'\n",
+                                       argv[1]);
+                               exit(-1);
+                       }
+                       rcvbuf = size;
                } else if (matches(opt, "-help") == 0) {
                        usage();
                } else {
@@ -228,16 +245,16 @@ int main(int argc, char **argv)
 
        _SL_ = oneline ? "\\" : "\n" ;
 
-       if (batch_file) 
+       if (batch_file)
                return batch(batch_file);
-               
+
        if (rtnl_open(&rth, 0) < 0)
                exit(1);
 
-       if (strlen(basename) > 2) 
+       if (strlen(basename) > 2)
                return do_cmd(basename+2, argc, argv);
 
-       if (argc > 1) 
+       if (argc > 1)
                return do_cmd(argv[1], argc-1, argv+1);
 
        rtnl_close(&rth);