X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=ip%2Fip.c;h=e4131714018f9a843a02cbff2fa9054eae75e75d;hb=25c6339b223f17d1603702c0c87f06b252bb4949;hp=e0cf17534dd6f27b89cf8bc553895b152a58c05d;hpb=f411a6289e68d67e6d3ec4ef059b0ae16ed361e7;p=mirror_iproute2.git diff --git a/ip/ip.c b/ip/ip.c index e0cf1753..e4131714 100644 --- a/ip/ip.c +++ b/ip/ip.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -22,16 +21,23 @@ #include "SNAPSHOT.h" #include "utils.h" #include "ip_common.h" +#include "namespace.h" +#include "color.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; +int human_readable; +int use_iec; +int show_stats; +int show_details; +int oneline; +int brief; +int json; +int timestamp; +int force; +int max_flush_loops = 10; +int batch_mode; +bool do_all; + struct rtnl_handle rth = { .fd = -1 }; static void usage(void) __attribute__((noreturn)); @@ -41,25 +47,31 @@ static void usage(void) fprintf(stderr, "Usage: ip [ OPTIONS ] OBJECT { COMMAND | help }\n" " ip [ -force ] -batch filename\n" -"where OBJECT := { link | addr | addrlabel | route | rule | neigh | ntable |\n" -" tunnel | tuntap | maddr | mroute | monitor | xfrm }\n" +"where OBJECT := { link | address | addrlabel | route | rule | neigh | ntable |\n" +" tunnel | tuntap | maddress | mroute | mrule | monitor | xfrm |\n" +" netns | l2tp | fou | macsec | tcp_metrics | token | netconf | ila |\n" +" vrf | sr }\n" " OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] | -r[esolve] |\n" -" -f[amily] { inet | inet6 | ipx | dnet | link } |\n" -" -o[neline] | -t[imestamp] | -b[atch] [filename] |\n" -" -rc[vbuf] [size]}\n"); +" -h[uman-readable] | -iec | -j[son] | -p[retty] |\n" +" -f[amily] { inet | inet6 | mpls | bridge | link } |\n" +" -4 | -6 | -I | -D | -M | -B | -0 |\n" +" -l[oops] { maximum-addr-flush-attempts } | -br[ief] |\n" +" -o[neline] | -t[imestamp] | -ts[hort] | -b[atch] [filename] |\n" +" -rc[vbuf] [size] | -n[etns] name | -a[ll] | -c[olor]}\n"); exit(-1); } static int do_help(int argc, char **argv) { usage(); + return 0; } static const struct cmd { const char *cmd; int (*func)(int argc, char **argv); } cmds[] = { - { "address", do_ipaddr }, + { "address", do_ipaddr }, { "addrlabel", do_ipaddrlabel }, { "maddress", do_multiaddr }, { "route", do_iproute }, @@ -69,13 +81,25 @@ static const struct cmd { { "ntable", do_ipntable }, { "ntbl", do_ipntable }, { "link", do_iplink }, + { "l2tp", do_ipl2tp }, + { "fou", do_ipfou }, + { "ila", do_ipila }, + { "macsec", do_ipmacsec }, { "tunnel", do_iptunnel }, { "tunl", do_iptunnel }, { "tuntap", do_iptuntap }, { "tap", do_iptuntap }, + { "token", do_iptoken }, + { "tcpmetrics", do_tcp_metrics }, + { "tcp_metrics", do_tcp_metrics }, { "monitor", do_ipmonitor }, { "xfrm", do_xfrm }, { "mroute", do_multiroute }, + { "mrule", do_multirule }, + { "netns", do_netns }, + { "netconf", do_ipnetconf }, + { "vrf", do_ipvrf}, + { "sr", do_seg6 }, { "help", do_help }, { 0 } }; @@ -86,30 +110,34 @@ static int do_cmd(const char *argv0, int argc, char **argv) for (c = cmds; c->cmd; ++c) { if (matches(argv0, c->cmd) == 0) - return c->func(argc-1, argv+1); + return -(c->func(argc-1, argv+1)); } fprintf(stderr, "Object \"%s\" is unknown, try \"ip help\".\n", argv0); - return -1; + return EXIT_FAILURE; } static int batch(const char *name) { char *line = NULL; size_t len = 0; - int ret = 0; + int ret = EXIT_SUCCESS; + int orig_family = preferred_family; + + batch_mode = 1; 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; + return EXIT_FAILURE; } } if (rtnl_open(&rth, 0) < 0) { fprintf(stderr, "Cannot open rtnetlink\n"); - return -1; + return EXIT_FAILURE; } cmdlineno = 0; @@ -117,13 +145,16 @@ static int batch(const char *name) char *largv[100]; int largc; + preferred_family = orig_family; + largc = makeargs(line, largv, 100); if (largc == 0) continue; /* blank line */ if (do_cmd(largv[0], largc, largv)) { - fprintf(stderr, "Command failed %s:%d\n", name, cmdlineno); - ret = 1; + fprintf(stderr, "Command failed %s:%d\n", + name, cmdlineno); + ret = EXIT_FAILURE; if (!force) break; } @@ -139,6 +170,20 @@ static int batch(const char *name) int main(int argc, char **argv) { char *basename; + char *batch_file = NULL; + int color = 0; + + /* to run vrf exec without root, capabilities might be set, drop them + * if not needed as the first thing. + * execv will drop them for the child command. + * vrf exec requires: + * - cap_dac_override to create the cgroup subdir in /sys + * - cap_sys_admin to load the BPF program + * - cap_net_admin to set the socket into the cgroup + */ + if (argc < 3 || strcmp(argv[1], "vrf") != 0 || + strcmp(argv[2], "exec") != 0) + drop_cap(); basename = strrchr(argv[0], '/'); if (basename == NULL) @@ -148,7 +193,8 @@ int main(int argc, char **argv) while (argc > 1) { char *opt = argv[1]; - if (strcmp(opt,"--") == 0) { + + if (strcmp(opt, "--") == 0) { argc--; argv++; break; } @@ -156,35 +202,40 @@ 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(); - if (strcmp(argv[1], "inet") == 0) - preferred_family = AF_INET; - else if (strcmp(argv[1], "inet6") == 0) - preferred_family = AF_INET6; - else if (strcmp(argv[1], "dnet") == 0) - preferred_family = AF_DECnet; - else if (strcmp(argv[1], "link") == 0) - preferred_family = AF_PACKET; - else if (strcmp(argv[1], "ipx") == 0) - preferred_family = AF_IPX; - else if (strcmp(argv[1], "help") == 0) + max_flush_loops = atoi(argv[1]); + } else if (matches(opt, "-family") == 0) { + argc--; + argv++; + if (argc <= 1) + usage(); + if (strcmp(argv[1], "help") == 0) usage(); else - invarg(argv[1], "invalid protocol family"); + preferred_family = read_family(argv[1]); + if (preferred_family == AF_UNSPEC) + invarg("invalid protocol family", argv[1]); } else if (strcmp(opt, "-4") == 0) { preferred_family = AF_INET; } else if (strcmp(opt, "-6") == 0) { preferred_family = AF_INET6; } else if (strcmp(opt, "-0") == 0) { preferred_family = AF_PACKET; - } else if (strcmp(opt, "-I") == 0) { - preferred_family = AF_IPX; } else if (strcmp(opt, "-D") == 0) { preferred_family = AF_DECnet; + } else if (strcmp(opt, "-M") == 0) { + preferred_family = AF_MPLS; + } else if (strcmp(opt, "-B") == 0) { + preferred_family = AF_BRIDGE; + } else if (matches(opt, "-human") == 0 || + matches(opt, "-human-readable") == 0) { + ++human_readable; + } else if (matches(opt, "-iec") == 0) { + ++use_iec; } else if (matches(opt, "-stats") == 0 || matches(opt, "-statistics") == 0) { ++show_stats; @@ -196,10 +247,9 @@ int main(int argc, char **argv) ++oneline; } else if (matches(opt, "-timestamp") == 0) { ++timestamp; -#if 0 - } else if (matches(opt, "-numeric") == 0) { - rtnl_names_numeric++; -#endif + } else if (matches(opt, "-tshort") == 0) { + ++timestamp; + ++timestamp_short; } else if (matches(opt, "-Version") == 0) { printf("ip utility, iproute2-ss%s\n", SNAPSHOT); exit(0); @@ -211,6 +261,12 @@ int main(int argc, char **argv) if (argc <= 1) usage(); batch_file = argv[1]; + } else if (matches(opt, "-brief") == 0) { + ++brief; + } else if (matches(opt, "-json") == 0) { + ++json; + } else if (matches(opt, "-pretty") == 0) { + ++pretty; } else if (matches(opt, "-rcvbuf") == 0) { unsigned int size; @@ -224,16 +280,27 @@ int main(int argc, char **argv) exit(-1); } rcvbuf = size; + } else if (matches_color(opt, &color)) { } else if (matches(opt, "-help") == 0) { usage(); + } else if (matches(opt, "-netns") == 0) { + NEXT_ARG(); + if (netns_switch(argv[1])) + exit(-1); + } else if (matches(opt, "-all") == 0) { + do_all = true; } else { - fprintf(stderr, "Option \"%s\" is unknown, try \"ip -help\".\n", opt); + fprintf(stderr, + "Option \"%s\" is unknown, try \"ip -help\".\n", + opt); exit(-1); } argc--; argv++; } - _SL_ = oneline ? "\\" : "\n" ; + _SL_ = oneline ? "\\" : "\n"; + + check_enable_color(color, json); if (batch_file) return batch(batch_file); @@ -241,6 +308,8 @@ int main(int argc, char **argv) if (rtnl_open(&rth, 0) < 0) exit(1); + rtnl_set_strict_dump(&rth); + if (strlen(basename) > 2) return do_cmd(basename+2, argc, argv);