xref: /aosp_15_r20/external/iproute2/ip/ip.c (revision de1e4e894b0c224df933550f0afdecc354b238c4)
1*de1e4e89SAndroid Build Coastguard Worker /*
2*de1e4e89SAndroid Build Coastguard Worker  * ip.c		"ip" utility frontend.
3*de1e4e89SAndroid Build Coastguard Worker  *
4*de1e4e89SAndroid Build Coastguard Worker  *		This program is free software; you can redistribute it and/or
5*de1e4e89SAndroid Build Coastguard Worker  *		modify it under the terms of the GNU General Public License
6*de1e4e89SAndroid Build Coastguard Worker  *		as published by the Free Software Foundation; either version
7*de1e4e89SAndroid Build Coastguard Worker  *		2 of the License, or (at your option) any later version.
8*de1e4e89SAndroid Build Coastguard Worker  *
9*de1e4e89SAndroid Build Coastguard Worker  * Authors:	Alexey Kuznetsov, <[email protected]>
10*de1e4e89SAndroid Build Coastguard Worker  */
11*de1e4e89SAndroid Build Coastguard Worker 
12*de1e4e89SAndroid Build Coastguard Worker #include <stdio.h>
13*de1e4e89SAndroid Build Coastguard Worker #include <stdlib.h>
14*de1e4e89SAndroid Build Coastguard Worker #include <unistd.h>
15*de1e4e89SAndroid Build Coastguard Worker #include <syslog.h>
16*de1e4e89SAndroid Build Coastguard Worker #include <fcntl.h>
17*de1e4e89SAndroid Build Coastguard Worker #include <sys/socket.h>
18*de1e4e89SAndroid Build Coastguard Worker #include <netinet/in.h>
19*de1e4e89SAndroid Build Coastguard Worker #include <string.h>
20*de1e4e89SAndroid Build Coastguard Worker #include <errno.h>
21*de1e4e89SAndroid Build Coastguard Worker 
22*de1e4e89SAndroid Build Coastguard Worker #include "SNAPSHOT.h"
23*de1e4e89SAndroid Build Coastguard Worker #include "utils.h"
24*de1e4e89SAndroid Build Coastguard Worker #include "ip_common.h"
25*de1e4e89SAndroid Build Coastguard Worker #include "namespace.h"
26*de1e4e89SAndroid Build Coastguard Worker #include "color.h"
27*de1e4e89SAndroid Build Coastguard Worker 
28*de1e4e89SAndroid Build Coastguard Worker int preferred_family = AF_UNSPEC;
29*de1e4e89SAndroid Build Coastguard Worker int human_readable;
30*de1e4e89SAndroid Build Coastguard Worker int use_iec;
31*de1e4e89SAndroid Build Coastguard Worker int show_stats;
32*de1e4e89SAndroid Build Coastguard Worker int show_details;
33*de1e4e89SAndroid Build Coastguard Worker int oneline;
34*de1e4e89SAndroid Build Coastguard Worker int brief;
35*de1e4e89SAndroid Build Coastguard Worker int json;
36*de1e4e89SAndroid Build Coastguard Worker int timestamp;
37*de1e4e89SAndroid Build Coastguard Worker const char *_SL_;
38*de1e4e89SAndroid Build Coastguard Worker int force;
39*de1e4e89SAndroid Build Coastguard Worker int max_flush_loops = 10;
40*de1e4e89SAndroid Build Coastguard Worker int batch_mode;
41*de1e4e89SAndroid Build Coastguard Worker bool do_all;
42*de1e4e89SAndroid Build Coastguard Worker 
43*de1e4e89SAndroid Build Coastguard Worker struct rtnl_handle rth = { .fd = -1 };
44*de1e4e89SAndroid Build Coastguard Worker 
45*de1e4e89SAndroid Build Coastguard Worker static void usage(void) __attribute__((noreturn));
46*de1e4e89SAndroid Build Coastguard Worker 
usage(void)47*de1e4e89SAndroid Build Coastguard Worker static void usage(void)
48*de1e4e89SAndroid Build Coastguard Worker {
49*de1e4e89SAndroid Build Coastguard Worker 	fprintf(stderr,
50*de1e4e89SAndroid Build Coastguard Worker "Usage: ip [ OPTIONS ] OBJECT { COMMAND | help }\n"
51*de1e4e89SAndroid Build Coastguard Worker "       ip [ -force ] -batch filename\n"
52*de1e4e89SAndroid Build Coastguard Worker "where  OBJECT := { link | address | addrlabel | route | rule | neigh | ntable |\n"
53*de1e4e89SAndroid Build Coastguard Worker "                   tunnel | tuntap | maddress | mroute | mrule | monitor | xfrm |\n"
54*de1e4e89SAndroid Build Coastguard Worker "                   netns | l2tp | fou | macsec | tcp_metrics | token | netconf | ila |\n"
55*de1e4e89SAndroid Build Coastguard Worker "                   vrf | sr }\n"
56*de1e4e89SAndroid Build Coastguard Worker "       OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] | -r[esolve] |\n"
57*de1e4e89SAndroid Build Coastguard Worker "                    -h[uman-readable] | -iec |\n"
58*de1e4e89SAndroid Build Coastguard Worker "                    -f[amily] { inet | inet6 | ipx | dnet | mpls | bridge | link } |\n"
59*de1e4e89SAndroid Build Coastguard Worker "                    -4 | -6 | -I | -D | -B | -0 |\n"
60*de1e4e89SAndroid Build Coastguard Worker "                    -l[oops] { maximum-addr-flush-attempts } | -br[ief] |\n"
61*de1e4e89SAndroid Build Coastguard Worker "                    -o[neline] | -t[imestamp] | -ts[hort] | -b[atch] [filename] |\n"
62*de1e4e89SAndroid Build Coastguard Worker "                    -rc[vbuf] [size] | -n[etns] name | -a[ll] | -c[olor]}\n");
63*de1e4e89SAndroid Build Coastguard Worker 	exit(-1);
64*de1e4e89SAndroid Build Coastguard Worker }
65*de1e4e89SAndroid Build Coastguard Worker 
do_help(int argc,char ** argv)66*de1e4e89SAndroid Build Coastguard Worker static int do_help(int argc, char **argv)
67*de1e4e89SAndroid Build Coastguard Worker {
68*de1e4e89SAndroid Build Coastguard Worker 	usage();
69*de1e4e89SAndroid Build Coastguard Worker 	return 0;
70*de1e4e89SAndroid Build Coastguard Worker }
71*de1e4e89SAndroid Build Coastguard Worker 
72*de1e4e89SAndroid Build Coastguard Worker static const struct cmd {
73*de1e4e89SAndroid Build Coastguard Worker 	const char *cmd;
74*de1e4e89SAndroid Build Coastguard Worker 	int (*func)(int argc, char **argv);
75*de1e4e89SAndroid Build Coastguard Worker } cmds[] = {
76*de1e4e89SAndroid Build Coastguard Worker 	{ "address",	do_ipaddr },
77*de1e4e89SAndroid Build Coastguard Worker 	{ "addrlabel",	do_ipaddrlabel },
78*de1e4e89SAndroid Build Coastguard Worker 	{ "maddress",	do_multiaddr },
79*de1e4e89SAndroid Build Coastguard Worker 	{ "route",	do_iproute },
80*de1e4e89SAndroid Build Coastguard Worker 	{ "rule",	do_iprule },
81*de1e4e89SAndroid Build Coastguard Worker 	{ "neighbor",	do_ipneigh },
82*de1e4e89SAndroid Build Coastguard Worker 	{ "neighbour",	do_ipneigh },
83*de1e4e89SAndroid Build Coastguard Worker 	{ "ntable",	do_ipntable },
84*de1e4e89SAndroid Build Coastguard Worker 	{ "ntbl",	do_ipntable },
85*de1e4e89SAndroid Build Coastguard Worker 	{ "link",	do_iplink },
86*de1e4e89SAndroid Build Coastguard Worker 	{ "l2tp",	do_ipl2tp },
87*de1e4e89SAndroid Build Coastguard Worker 	{ "fou",	do_ipfou },
88*de1e4e89SAndroid Build Coastguard Worker 	{ "ila",	do_ipila },
89*de1e4e89SAndroid Build Coastguard Worker 	{ "macsec",	do_ipmacsec },
90*de1e4e89SAndroid Build Coastguard Worker 	{ "tunnel",	do_iptunnel },
91*de1e4e89SAndroid Build Coastguard Worker 	{ "tunl",	do_iptunnel },
92*de1e4e89SAndroid Build Coastguard Worker 	{ "tuntap",	do_iptuntap },
93*de1e4e89SAndroid Build Coastguard Worker 	{ "tap",	do_iptuntap },
94*de1e4e89SAndroid Build Coastguard Worker 	{ "token",	do_iptoken },
95*de1e4e89SAndroid Build Coastguard Worker 	{ "tcpmetrics",	do_tcp_metrics },
96*de1e4e89SAndroid Build Coastguard Worker 	{ "tcp_metrics", do_tcp_metrics },
97*de1e4e89SAndroid Build Coastguard Worker 	{ "monitor",	do_ipmonitor },
98*de1e4e89SAndroid Build Coastguard Worker 	{ "xfrm",	do_xfrm },
99*de1e4e89SAndroid Build Coastguard Worker 	{ "mroute",	do_multiroute },
100*de1e4e89SAndroid Build Coastguard Worker 	{ "mrule",	do_multirule },
101*de1e4e89SAndroid Build Coastguard Worker 	{ "netns",	do_netns },
102*de1e4e89SAndroid Build Coastguard Worker 	{ "netconf",	do_ipnetconf },
103*de1e4e89SAndroid Build Coastguard Worker 	{ "vrf",	do_ipvrf},
104*de1e4e89SAndroid Build Coastguard Worker 	{ "sr",		do_seg6 },
105*de1e4e89SAndroid Build Coastguard Worker 	{ "help",	do_help },
106*de1e4e89SAndroid Build Coastguard Worker 	{ 0 }
107*de1e4e89SAndroid Build Coastguard Worker };
108*de1e4e89SAndroid Build Coastguard Worker 
do_cmd(const char * argv0,int argc,char ** argv)109*de1e4e89SAndroid Build Coastguard Worker static int do_cmd(const char *argv0, int argc, char **argv)
110*de1e4e89SAndroid Build Coastguard Worker {
111*de1e4e89SAndroid Build Coastguard Worker 	const struct cmd *c;
112*de1e4e89SAndroid Build Coastguard Worker 
113*de1e4e89SAndroid Build Coastguard Worker 	for (c = cmds; c->cmd; ++c) {
114*de1e4e89SAndroid Build Coastguard Worker 		if (matches(argv0, c->cmd) == 0)
115*de1e4e89SAndroid Build Coastguard Worker 			return -(c->func(argc-1, argv+1));
116*de1e4e89SAndroid Build Coastguard Worker 	}
117*de1e4e89SAndroid Build Coastguard Worker 
118*de1e4e89SAndroid Build Coastguard Worker 	fprintf(stderr, "Object \"%s\" is unknown, try \"ip help\".\n", argv0);
119*de1e4e89SAndroid Build Coastguard Worker 	return EXIT_FAILURE;
120*de1e4e89SAndroid Build Coastguard Worker }
121*de1e4e89SAndroid Build Coastguard Worker 
batch(const char * name)122*de1e4e89SAndroid Build Coastguard Worker static int batch(const char *name)
123*de1e4e89SAndroid Build Coastguard Worker {
124*de1e4e89SAndroid Build Coastguard Worker 	char *line = NULL;
125*de1e4e89SAndroid Build Coastguard Worker 	size_t len = 0;
126*de1e4e89SAndroid Build Coastguard Worker 	int ret = EXIT_SUCCESS;
127*de1e4e89SAndroid Build Coastguard Worker 	int orig_family = preferred_family;
128*de1e4e89SAndroid Build Coastguard Worker 
129*de1e4e89SAndroid Build Coastguard Worker 	batch_mode = 1;
130*de1e4e89SAndroid Build Coastguard Worker 
131*de1e4e89SAndroid Build Coastguard Worker 	if (name && strcmp(name, "-") != 0) {
132*de1e4e89SAndroid Build Coastguard Worker 		if (freopen(name, "r", stdin) == NULL) {
133*de1e4e89SAndroid Build Coastguard Worker 			fprintf(stderr,
134*de1e4e89SAndroid Build Coastguard Worker 				"Cannot open file \"%s\" for reading: %s\n",
135*de1e4e89SAndroid Build Coastguard Worker 				name, strerror(errno));
136*de1e4e89SAndroid Build Coastguard Worker 			return EXIT_FAILURE;
137*de1e4e89SAndroid Build Coastguard Worker 		}
138*de1e4e89SAndroid Build Coastguard Worker 	}
139*de1e4e89SAndroid Build Coastguard Worker 
140*de1e4e89SAndroid Build Coastguard Worker 	if (rtnl_open(&rth, 0) < 0) {
141*de1e4e89SAndroid Build Coastguard Worker 		fprintf(stderr, "Cannot open rtnetlink\n");
142*de1e4e89SAndroid Build Coastguard Worker 		return EXIT_FAILURE;
143*de1e4e89SAndroid Build Coastguard Worker 	}
144*de1e4e89SAndroid Build Coastguard Worker 
145*de1e4e89SAndroid Build Coastguard Worker 	cmdlineno = 0;
146*de1e4e89SAndroid Build Coastguard Worker 	while (getcmdline(&line, &len, stdin) != -1) {
147*de1e4e89SAndroid Build Coastguard Worker 		char *largv[100];
148*de1e4e89SAndroid Build Coastguard Worker 		int largc;
149*de1e4e89SAndroid Build Coastguard Worker 
150*de1e4e89SAndroid Build Coastguard Worker 		preferred_family = orig_family;
151*de1e4e89SAndroid Build Coastguard Worker 
152*de1e4e89SAndroid Build Coastguard Worker 		largc = makeargs(line, largv, 100);
153*de1e4e89SAndroid Build Coastguard Worker 		if (largc == 0)
154*de1e4e89SAndroid Build Coastguard Worker 			continue;	/* blank line */
155*de1e4e89SAndroid Build Coastguard Worker 
156*de1e4e89SAndroid Build Coastguard Worker 		if (do_cmd(largv[0], largc, largv)) {
157*de1e4e89SAndroid Build Coastguard Worker 			fprintf(stderr, "Command failed %s:%d\n",
158*de1e4e89SAndroid Build Coastguard Worker 				name, cmdlineno);
159*de1e4e89SAndroid Build Coastguard Worker 			ret = EXIT_FAILURE;
160*de1e4e89SAndroid Build Coastguard Worker 			if (!force)
161*de1e4e89SAndroid Build Coastguard Worker 				break;
162*de1e4e89SAndroid Build Coastguard Worker 		}
163*de1e4e89SAndroid Build Coastguard Worker 	}
164*de1e4e89SAndroid Build Coastguard Worker 	if (line)
165*de1e4e89SAndroid Build Coastguard Worker 		free(line);
166*de1e4e89SAndroid Build Coastguard Worker 
167*de1e4e89SAndroid Build Coastguard Worker 	rtnl_close(&rth);
168*de1e4e89SAndroid Build Coastguard Worker 	return ret;
169*de1e4e89SAndroid Build Coastguard Worker }
170*de1e4e89SAndroid Build Coastguard Worker 
171*de1e4e89SAndroid Build Coastguard Worker 
main(int argc,char ** argv)172*de1e4e89SAndroid Build Coastguard Worker int main(int argc, char **argv)
173*de1e4e89SAndroid Build Coastguard Worker {
174*de1e4e89SAndroid Build Coastguard Worker 	char *basename;
175*de1e4e89SAndroid Build Coastguard Worker 	char *batch_file = NULL;
176*de1e4e89SAndroid Build Coastguard Worker 
177*de1e4e89SAndroid Build Coastguard Worker 	basename = strrchr(argv[0], '/');
178*de1e4e89SAndroid Build Coastguard Worker 	if (basename == NULL)
179*de1e4e89SAndroid Build Coastguard Worker 		basename = argv[0];
180*de1e4e89SAndroid Build Coastguard Worker 	else
181*de1e4e89SAndroid Build Coastguard Worker 		basename++;
182*de1e4e89SAndroid Build Coastguard Worker 
183*de1e4e89SAndroid Build Coastguard Worker 	while (argc > 1) {
184*de1e4e89SAndroid Build Coastguard Worker 		char *opt = argv[1];
185*de1e4e89SAndroid Build Coastguard Worker 
186*de1e4e89SAndroid Build Coastguard Worker 		if (strcmp(opt, "--") == 0) {
187*de1e4e89SAndroid Build Coastguard Worker 			argc--; argv++;
188*de1e4e89SAndroid Build Coastguard Worker 			break;
189*de1e4e89SAndroid Build Coastguard Worker 		}
190*de1e4e89SAndroid Build Coastguard Worker 		if (opt[0] != '-')
191*de1e4e89SAndroid Build Coastguard Worker 			break;
192*de1e4e89SAndroid Build Coastguard Worker 		if (opt[1] == '-')
193*de1e4e89SAndroid Build Coastguard Worker 			opt++;
194*de1e4e89SAndroid Build Coastguard Worker 		if (matches(opt, "-loops") == 0) {
195*de1e4e89SAndroid Build Coastguard Worker 			argc--;
196*de1e4e89SAndroid Build Coastguard Worker 			argv++;
197*de1e4e89SAndroid Build Coastguard Worker 			if (argc <= 1)
198*de1e4e89SAndroid Build Coastguard Worker 				usage();
199*de1e4e89SAndroid Build Coastguard Worker 			max_flush_loops = atoi(argv[1]);
200*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(opt, "-family") == 0) {
201*de1e4e89SAndroid Build Coastguard Worker 			argc--;
202*de1e4e89SAndroid Build Coastguard Worker 			argv++;
203*de1e4e89SAndroid Build Coastguard Worker 			if (argc <= 1)
204*de1e4e89SAndroid Build Coastguard Worker 				usage();
205*de1e4e89SAndroid Build Coastguard Worker 			if (strcmp(argv[1], "help") == 0)
206*de1e4e89SAndroid Build Coastguard Worker 				usage();
207*de1e4e89SAndroid Build Coastguard Worker 			else
208*de1e4e89SAndroid Build Coastguard Worker 				preferred_family = read_family(argv[1]);
209*de1e4e89SAndroid Build Coastguard Worker 			if (preferred_family == AF_UNSPEC)
210*de1e4e89SAndroid Build Coastguard Worker 				invarg("invalid protocol family", argv[1]);
211*de1e4e89SAndroid Build Coastguard Worker 		} else if (strcmp(opt, "-4") == 0) {
212*de1e4e89SAndroid Build Coastguard Worker 			preferred_family = AF_INET;
213*de1e4e89SAndroid Build Coastguard Worker 		} else if (strcmp(opt, "-6") == 0) {
214*de1e4e89SAndroid Build Coastguard Worker 			preferred_family = AF_INET6;
215*de1e4e89SAndroid Build Coastguard Worker 		} else if (strcmp(opt, "-0") == 0) {
216*de1e4e89SAndroid Build Coastguard Worker 			preferred_family = AF_PACKET;
217*de1e4e89SAndroid Build Coastguard Worker 		} else if (strcmp(opt, "-I") == 0) {
218*de1e4e89SAndroid Build Coastguard Worker 			preferred_family = AF_IPX;
219*de1e4e89SAndroid Build Coastguard Worker 		} else if (strcmp(opt, "-D") == 0) {
220*de1e4e89SAndroid Build Coastguard Worker 			preferred_family = AF_DECnet;
221*de1e4e89SAndroid Build Coastguard Worker 		} else if (strcmp(opt, "-M") == 0) {
222*de1e4e89SAndroid Build Coastguard Worker 			preferred_family = AF_MPLS;
223*de1e4e89SAndroid Build Coastguard Worker 		} else if (strcmp(opt, "-B") == 0) {
224*de1e4e89SAndroid Build Coastguard Worker 			preferred_family = AF_BRIDGE;
225*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(opt, "-human") == 0 ||
226*de1e4e89SAndroid Build Coastguard Worker 			   matches(opt, "-human-readable") == 0) {
227*de1e4e89SAndroid Build Coastguard Worker 			++human_readable;
228*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(opt, "-iec") == 0) {
229*de1e4e89SAndroid Build Coastguard Worker 			++use_iec;
230*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(opt, "-stats") == 0 ||
231*de1e4e89SAndroid Build Coastguard Worker 			   matches(opt, "-statistics") == 0) {
232*de1e4e89SAndroid Build Coastguard Worker 			++show_stats;
233*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(opt, "-details") == 0) {
234*de1e4e89SAndroid Build Coastguard Worker 			++show_details;
235*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(opt, "-resolve") == 0) {
236*de1e4e89SAndroid Build Coastguard Worker 			++resolve_hosts;
237*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(opt, "-oneline") == 0) {
238*de1e4e89SAndroid Build Coastguard Worker 			++oneline;
239*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(opt, "-timestamp") == 0) {
240*de1e4e89SAndroid Build Coastguard Worker 			++timestamp;
241*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(opt, "-tshort") == 0) {
242*de1e4e89SAndroid Build Coastguard Worker 			++timestamp;
243*de1e4e89SAndroid Build Coastguard Worker 			++timestamp_short;
244*de1e4e89SAndroid Build Coastguard Worker #if 0
245*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(opt, "-numeric") == 0) {
246*de1e4e89SAndroid Build Coastguard Worker 			rtnl_names_numeric++;
247*de1e4e89SAndroid Build Coastguard Worker #endif
248*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(opt, "-Version") == 0) {
249*de1e4e89SAndroid Build Coastguard Worker 			printf("ip utility, iproute2-ss%s\n", SNAPSHOT);
250*de1e4e89SAndroid Build Coastguard Worker 			exit(0);
251*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(opt, "-force") == 0) {
252*de1e4e89SAndroid Build Coastguard Worker 			++force;
253*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(opt, "-batch") == 0) {
254*de1e4e89SAndroid Build Coastguard Worker 			argc--;
255*de1e4e89SAndroid Build Coastguard Worker 			argv++;
256*de1e4e89SAndroid Build Coastguard Worker 			if (argc <= 1)
257*de1e4e89SAndroid Build Coastguard Worker 				usage();
258*de1e4e89SAndroid Build Coastguard Worker 			batch_file = argv[1];
259*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(opt, "-brief") == 0) {
260*de1e4e89SAndroid Build Coastguard Worker 			++brief;
261*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(opt, "-json") == 0) {
262*de1e4e89SAndroid Build Coastguard Worker 			++json;
263*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(opt, "-rcvbuf") == 0) {
264*de1e4e89SAndroid Build Coastguard Worker 			unsigned int size;
265*de1e4e89SAndroid Build Coastguard Worker 
266*de1e4e89SAndroid Build Coastguard Worker 			argc--;
267*de1e4e89SAndroid Build Coastguard Worker 			argv++;
268*de1e4e89SAndroid Build Coastguard Worker 			if (argc <= 1)
269*de1e4e89SAndroid Build Coastguard Worker 				usage();
270*de1e4e89SAndroid Build Coastguard Worker 			if (get_unsigned(&size, argv[1], 0)) {
271*de1e4e89SAndroid Build Coastguard Worker 				fprintf(stderr, "Invalid rcvbuf size '%s'\n",
272*de1e4e89SAndroid Build Coastguard Worker 					argv[1]);
273*de1e4e89SAndroid Build Coastguard Worker 				exit(-1);
274*de1e4e89SAndroid Build Coastguard Worker 			}
275*de1e4e89SAndroid Build Coastguard Worker 			rcvbuf = size;
276*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(opt, "-color") == 0) {
277*de1e4e89SAndroid Build Coastguard Worker 			enable_color();
278*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(opt, "-help") == 0) {
279*de1e4e89SAndroid Build Coastguard Worker 			usage();
280*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(opt, "-netns") == 0) {
281*de1e4e89SAndroid Build Coastguard Worker 			NEXT_ARG();
282*de1e4e89SAndroid Build Coastguard Worker 			if (netns_switch(argv[1]))
283*de1e4e89SAndroid Build Coastguard Worker 				exit(-1);
284*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(opt, "-all") == 0) {
285*de1e4e89SAndroid Build Coastguard Worker 			do_all = true;
286*de1e4e89SAndroid Build Coastguard Worker 		} else {
287*de1e4e89SAndroid Build Coastguard Worker 			fprintf(stderr,
288*de1e4e89SAndroid Build Coastguard Worker 				"Option \"%s\" is unknown, try \"ip -help\".\n",
289*de1e4e89SAndroid Build Coastguard Worker 				opt);
290*de1e4e89SAndroid Build Coastguard Worker 			exit(-1);
291*de1e4e89SAndroid Build Coastguard Worker 		}
292*de1e4e89SAndroid Build Coastguard Worker 		argc--;	argv++;
293*de1e4e89SAndroid Build Coastguard Worker 	}
294*de1e4e89SAndroid Build Coastguard Worker 
295*de1e4e89SAndroid Build Coastguard Worker 	_SL_ = oneline ? "\\" : "\n";
296*de1e4e89SAndroid Build Coastguard Worker 
297*de1e4e89SAndroid Build Coastguard Worker 	if (json)
298*de1e4e89SAndroid Build Coastguard Worker 		check_if_color_enabled();
299*de1e4e89SAndroid Build Coastguard Worker 
300*de1e4e89SAndroid Build Coastguard Worker 	if (batch_file)
301*de1e4e89SAndroid Build Coastguard Worker 		return batch(batch_file);
302*de1e4e89SAndroid Build Coastguard Worker 
303*de1e4e89SAndroid Build Coastguard Worker 	if (rtnl_open(&rth, 0) < 0)
304*de1e4e89SAndroid Build Coastguard Worker 		exit(1);
305*de1e4e89SAndroid Build Coastguard Worker 
306*de1e4e89SAndroid Build Coastguard Worker 	if (strlen(basename) > 2)
307*de1e4e89SAndroid Build Coastguard Worker 		return do_cmd(basename+2, argc, argv);
308*de1e4e89SAndroid Build Coastguard Worker 
309*de1e4e89SAndroid Build Coastguard Worker 	if (argc > 1)
310*de1e4e89SAndroid Build Coastguard Worker 		return do_cmd(argv[1], argc-1, argv+1);
311*de1e4e89SAndroid Build Coastguard Worker 
312*de1e4e89SAndroid Build Coastguard Worker 	rtnl_close(&rth);
313*de1e4e89SAndroid Build Coastguard Worker 	usage();
314*de1e4e89SAndroid Build Coastguard Worker }
315