• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * ipaddress.c		"ip address".
3  *
4  *		This program is free software; you can redistribute it and/or
5  *		modify it under the terms of the GNU General Public License
6  *		as published by the Free Software Foundation; either version
7  *		2 of the License, or (at your option) any later version.
8  *
9  * Authors:	Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
10  *
11  */
12 
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <unistd.h>
16 #include <syslog.h>
17 #include <inttypes.h>
18 #include <fcntl.h>
19 #include <sys/ioctl.h>
20 #include <sys/socket.h>
21 #include <sys/ioctl.h>
22 #include <errno.h>
23 #include <netinet/in.h>
24 #include <arpa/inet.h>
25 #include <string.h>
26 #include <fnmatch.h>
27 
28 #include <linux/netdevice.h>
29 #include <linux/if_arp.h>
30 #include <linux/sockios.h>
31 #include <linux/net_namespace.h>
32 
33 #include "rt_names.h"
34 #include "utils.h"
35 #include "ll_map.h"
36 #include "ip_common.h"
37 #include "color.h"
38 
39 enum {
40 	IPADD_LIST,
41 	IPADD_FLUSH,
42 	IPADD_SAVE,
43 };
44 
45 static struct
46 {
47 	int ifindex;
48 	int family;
49 	int oneline;
50 	int showqueue;
51 	inet_prefix pfx;
52 	int scope, scopemask;
53 	int flags, flagmask;
54 	int up;
55 	char *label;
56 	int flushed;
57 	char *flushb;
58 	int flushp;
59 	int flushe;
60 	int group;
61 	int master;
62 	char *kind;
63 } filter;
64 
65 static int do_link;
66 
67 static void usage(void) __attribute__((noreturn));
68 
usage(void)69 static void usage(void)
70 {
71 	if (do_link) {
72 		iplink_usage();
73 	}
74 	fprintf(stderr, "Usage: ip address {add|change|replace} IFADDR dev IFNAME [ LIFETIME ]\n");
75 	fprintf(stderr, "                                                      [ CONFFLAG-LIST ]\n");
76 	fprintf(stderr, "       ip address del IFADDR dev IFNAME [mngtmpaddr]\n");
77 	fprintf(stderr, "       ip address {show|save|flush} [ dev IFNAME ] [ scope SCOPE-ID ]\n");
78 	fprintf(stderr, "                            [ to PREFIX ] [ FLAG-LIST ] [ label LABEL ] [up]\n");
79 	fprintf(stderr, "       ip address {showdump|restore}\n");
80 	fprintf(stderr, "IFADDR := PREFIX | ADDR peer PREFIX\n");
81 	fprintf(stderr, "          [ broadcast ADDR ] [ anycast ADDR ]\n");
82 	fprintf(stderr, "          [ label IFNAME ] [ scope SCOPE-ID ]\n");
83 	fprintf(stderr, "SCOPE-ID := [ host | link | global | NUMBER ]\n");
84 	fprintf(stderr, "FLAG-LIST := [ FLAG-LIST ] FLAG\n");
85 	fprintf(stderr, "FLAG  := [ permanent | dynamic | secondary | primary |\n");
86 	fprintf(stderr, "           [-]tentative | [-]deprecated | [-]dadfailed | temporary |\n");
87 	fprintf(stderr, "           CONFFLAG-LIST ]\n");
88 	fprintf(stderr, "CONFFLAG-LIST := [ CONFFLAG-LIST ] CONFFLAG\n");
89 	fprintf(stderr, "CONFFLAG  := [ home | nodad | mngtmpaddr | noprefixroute | autojoin ]\n");
90 	fprintf(stderr, "LIFETIME := [ valid_lft LFT ] [ preferred_lft LFT ]\n");
91 	fprintf(stderr, "LFT := forever | SECONDS\n");
92 
93 	exit(-1);
94 }
95 
print_link_flags(FILE * fp,unsigned flags,unsigned mdown)96 static void print_link_flags(FILE *fp, unsigned flags, unsigned mdown)
97 {
98 	fprintf(fp, "<");
99 	if (flags & IFF_UP && !(flags & IFF_RUNNING))
100 		fprintf(fp, "NO-CARRIER%s", flags ? "," : "");
101 	flags &= ~IFF_RUNNING;
102 #define _PF(f) if (flags&IFF_##f) { \
103 		  flags &= ~IFF_##f ; \
104 		  fprintf(fp, #f "%s", flags ? "," : ""); }
105 	_PF(LOOPBACK);
106 	_PF(BROADCAST);
107 	_PF(POINTOPOINT);
108 	_PF(MULTICAST);
109 	_PF(NOARP);
110 	_PF(ALLMULTI);
111 	_PF(PROMISC);
112 	_PF(MASTER);
113 	_PF(SLAVE);
114 	_PF(DEBUG);
115 	_PF(DYNAMIC);
116 	_PF(AUTOMEDIA);
117 	_PF(PORTSEL);
118 	_PF(NOTRAILERS);
119 	_PF(UP);
120 	_PF(LOWER_UP);
121 	_PF(DORMANT);
122 	_PF(ECHO);
123 #undef _PF
124 	if (flags)
125 		fprintf(fp, "%x", flags);
126 	if (mdown)
127 		fprintf(fp, ",M-DOWN");
128 	fprintf(fp, "> ");
129 }
130 
131 static const char *oper_states[] = {
132 	"UNKNOWN", "NOTPRESENT", "DOWN", "LOWERLAYERDOWN",
133 	"TESTING", "DORMANT",	 "UP"
134 };
135 
print_operstate(FILE * f,__u8 state)136 static void print_operstate(FILE *f, __u8 state)
137 {
138 	if (state >= sizeof(oper_states)/sizeof(oper_states[0]))
139 		fprintf(f, "state %#x ", state);
140 	else {
141 		if (brief) {
142 			if (strcmp(oper_states[state], "UP") == 0)
143 				color_fprintf(f, COLOR_OPERSTATE_UP, "%-14s ", oper_states[state]);
144 			else if (strcmp(oper_states[state], "DOWN") == 0)
145 				color_fprintf(f, COLOR_OPERSTATE_DOWN, "%-14s ", oper_states[state]);
146 			else
147 				fprintf(f, "%-14s ", oper_states[state]);
148 		} else {
149 			fprintf(f, "state ");
150 			if (strcmp(oper_states[state], "UP") == 0)
151 				color_fprintf(f, COLOR_OPERSTATE_UP, "%s ", oper_states[state]);
152 			else if (strcmp(oper_states[state], "DOWN") == 0)
153 				color_fprintf(f, COLOR_OPERSTATE_DOWN, "%s ", oper_states[state]);
154 			else
155 				fprintf(f, "%s ", oper_states[state]);
156 		}
157 	}
158 }
159 
get_operstate(const char * name)160 int get_operstate(const char *name)
161 {
162 	int i;
163 
164 	for (i = 0; i < sizeof(oper_states)/sizeof(oper_states[0]); i++)
165 		if (strcasecmp(name, oper_states[i]) == 0)
166 			return i;
167 	return -1;
168 }
169 
print_queuelen(FILE * f,struct rtattr * tb[IFLA_MAX+1])170 static void print_queuelen(FILE *f, struct rtattr *tb[IFLA_MAX + 1])
171 {
172 	int qlen;
173 
174 	if (tb[IFLA_TXQLEN])
175 		qlen = *(int *)RTA_DATA(tb[IFLA_TXQLEN]);
176 	else {
177 		struct ifreq ifr;
178 		int s = socket(AF_INET, SOCK_STREAM, 0);
179 
180 		if (s < 0)
181 			return;
182 
183 		memset(&ifr, 0, sizeof(ifr));
184 		strcpy(ifr.ifr_name, rta_getattr_str(tb[IFLA_IFNAME]));
185 		if (ioctl(s, SIOCGIFTXQLEN, &ifr) < 0) {
186 			fprintf(f, "ioctl(SIOCGIFTXQLEN) failed: %s\n", strerror(errno));
187 			close(s);
188 			return;
189 		}
190 		close(s);
191 		qlen = ifr.ifr_qlen;
192 	}
193 	if (qlen)
194 		fprintf(f, "qlen %d", qlen);
195 }
196 
197 static const char *link_modes[] = {
198 	"DEFAULT", "DORMANT"
199 };
200 
print_linkmode(FILE * f,struct rtattr * tb)201 static void print_linkmode(FILE *f, struct rtattr *tb)
202 {
203 	unsigned int mode = rta_getattr_u8(tb);
204 
205 	if (mode >= sizeof(link_modes) / sizeof(link_modes[0]))
206 		fprintf(f, "mode %d ", mode);
207 	else
208 		fprintf(f, "mode %s ", link_modes[mode]);
209 }
210 
parse_link_kind(struct rtattr * tb)211 static char *parse_link_kind(struct rtattr *tb)
212 {
213 	struct rtattr *linkinfo[IFLA_INFO_MAX+1];
214 
215 	parse_rtattr_nested(linkinfo, IFLA_INFO_MAX, tb);
216 
217 	if (linkinfo[IFLA_INFO_KIND])
218 		return RTA_DATA(linkinfo[IFLA_INFO_KIND]);
219 
220 	return "";
221 }
222 
print_linktype(FILE * fp,struct rtattr * tb)223 static void print_linktype(FILE *fp, struct rtattr *tb)
224 {
225 	struct rtattr *linkinfo[IFLA_INFO_MAX+1];
226 	struct link_util *lu;
227 	struct link_util *slave_lu;
228 	char *kind;
229 	char *slave_kind;
230 
231 	parse_rtattr_nested(linkinfo, IFLA_INFO_MAX, tb);
232 
233 	if (linkinfo[IFLA_INFO_KIND]) {
234 		kind = RTA_DATA(linkinfo[IFLA_INFO_KIND]);
235 
236 		fprintf(fp, "%s", _SL_);
237 		fprintf(fp, "    %s ", kind);
238 
239 		lu = get_link_kind(kind);
240 		if (lu && lu->print_opt) {
241 			struct rtattr *attr[lu->maxattr+1], **data = NULL;
242 
243 			if (linkinfo[IFLA_INFO_DATA]) {
244 				parse_rtattr_nested(attr, lu->maxattr,
245 						    linkinfo[IFLA_INFO_DATA]);
246 				data = attr;
247 			}
248 			lu->print_opt(lu, fp, data);
249 
250 			if (linkinfo[IFLA_INFO_XSTATS] && show_stats &&
251 			    lu->print_xstats)
252 				lu->print_xstats(lu, fp, linkinfo[IFLA_INFO_XSTATS]);
253 		}
254 	}
255 
256 	if (linkinfo[IFLA_INFO_SLAVE_KIND]) {
257 		slave_kind = RTA_DATA(linkinfo[IFLA_INFO_SLAVE_KIND]);
258 
259 		fprintf(fp, "%s", _SL_);
260 		fprintf(fp, "    %s_slave ", slave_kind);
261 
262 		slave_lu = get_link_slave_kind(slave_kind);
263 		if (slave_lu && slave_lu->print_opt) {
264 			struct rtattr *attr[slave_lu->maxattr+1], **data = NULL;
265 
266 			if (linkinfo[IFLA_INFO_SLAVE_DATA]) {
267 				parse_rtattr_nested(attr, slave_lu->maxattr,
268 						    linkinfo[IFLA_INFO_SLAVE_DATA]);
269 				data = attr;
270 			}
271 			slave_lu->print_opt(slave_lu, fp, data);
272 		}
273 	}
274 }
275 
print_af_spec(FILE * fp,struct rtattr * af_spec_attr)276 static void print_af_spec(FILE *fp, struct rtattr *af_spec_attr)
277 {
278 	struct rtattr *inet6_attr;
279 	struct rtattr *tb[IFLA_INET6_MAX + 1];
280 
281 	inet6_attr = parse_rtattr_one_nested(AF_INET6, af_spec_attr);
282 	if (!inet6_attr)
283 		return;
284 
285 	parse_rtattr_nested(tb, IFLA_INET6_MAX, inet6_attr);
286 
287 	if (tb[IFLA_INET6_ADDR_GEN_MODE]) {
288 		__u8 mode = rta_getattr_u8(tb[IFLA_INET6_ADDR_GEN_MODE]);
289 		switch (mode) {
290 		case IN6_ADDR_GEN_MODE_EUI64:
291 			fprintf(fp, "addrgenmode eui64 ");
292 			break;
293 		case IN6_ADDR_GEN_MODE_NONE:
294 			fprintf(fp, "addrgenmode none ");
295 			break;
296 		case IN6_ADDR_GEN_MODE_STABLE_PRIVACY:
297 			fprintf(fp, "addrgenmode stable_secret ");
298 			break;
299 		case IN6_ADDR_GEN_MODE_RANDOM:
300 			fprintf(fp, "addrgenmode random ");
301 			break;
302 		default:
303 			fprintf(fp, "addrgenmode %#.2hhx ", mode);
304 			break;
305 		}
306 	}
307 }
308 
309 static void print_vf_stats64(FILE *fp, struct rtattr *vfstats);
310 
print_vfinfo(FILE * fp,struct rtattr * vfinfo)311 static void print_vfinfo(FILE *fp, struct rtattr *vfinfo)
312 {
313 	struct ifla_vf_mac *vf_mac;
314 	struct ifla_vf_vlan *vf_vlan;
315 	struct ifla_vf_tx_rate *vf_tx_rate;
316 	struct ifla_vf_spoofchk *vf_spoofchk;
317 	struct ifla_vf_link_state *vf_linkstate;
318 	struct rtattr *vf[IFLA_VF_MAX + 1] = {};
319 	struct rtattr *tmp;
320 	SPRINT_BUF(b1);
321 
322 	if (vfinfo->rta_type != IFLA_VF_INFO) {
323 		fprintf(stderr, "BUG: rta type is %d\n", vfinfo->rta_type);
324 		return;
325 	}
326 
327 	parse_rtattr_nested(vf, IFLA_VF_MAX, vfinfo);
328 
329 	vf_mac = RTA_DATA(vf[IFLA_VF_MAC]);
330 	vf_vlan = RTA_DATA(vf[IFLA_VF_VLAN]);
331 	vf_tx_rate = RTA_DATA(vf[IFLA_VF_TX_RATE]);
332 
333 	/* Check if the spoof checking vf info type is supported by
334 	 * this kernel.
335 	 */
336 	tmp = (struct rtattr *)((char *)vf[IFLA_VF_TX_RATE] +
337 			vf[IFLA_VF_TX_RATE]->rta_len);
338 
339 	if (tmp->rta_type != IFLA_VF_SPOOFCHK)
340 		vf_spoofchk = NULL;
341 	else
342 		vf_spoofchk = RTA_DATA(vf[IFLA_VF_SPOOFCHK]);
343 
344 	if (vf_spoofchk) {
345 		/* Check if the link state vf info type is supported by
346 		 * this kernel.
347 		 */
348 		tmp = (struct rtattr *)((char *)vf[IFLA_VF_SPOOFCHK] +
349 				vf[IFLA_VF_SPOOFCHK]->rta_len);
350 
351 		if (tmp->rta_type != IFLA_VF_LINK_STATE)
352 			vf_linkstate = NULL;
353 		else
354 			vf_linkstate = RTA_DATA(vf[IFLA_VF_LINK_STATE]);
355 	} else
356 		vf_linkstate = NULL;
357 
358 	fprintf(fp, "%s    vf %d MAC %s", _SL_, vf_mac->vf,
359 		ll_addr_n2a((unsigned char *)&vf_mac->mac,
360 		ETH_ALEN, 0, b1, sizeof(b1)));
361 	if (vf_vlan->vlan)
362 		fprintf(fp, ", vlan %d", vf_vlan->vlan);
363 	if (vf_vlan->qos)
364 		fprintf(fp, ", qos %d", vf_vlan->qos);
365 	if (vf_tx_rate->rate)
366 		fprintf(fp, ", tx rate %d (Mbps)", vf_tx_rate->rate);
367 
368 	if (vf[IFLA_VF_RATE]) {
369 		struct ifla_vf_rate *vf_rate = RTA_DATA(vf[IFLA_VF_RATE]);
370 
371 		if (vf_rate->max_tx_rate)
372 			fprintf(fp, ", max_tx_rate %dMbps", vf_rate->max_tx_rate);
373 		if (vf_rate->min_tx_rate)
374 			fprintf(fp, ", min_tx_rate %dMbps", vf_rate->min_tx_rate);
375 	}
376 
377 	if (vf_spoofchk && vf_spoofchk->setting != -1) {
378 		if (vf_spoofchk->setting)
379 			fprintf(fp, ", spoof checking on");
380 		else
381 			fprintf(fp, ", spoof checking off");
382 	}
383 	if (vf_linkstate) {
384 		if (vf_linkstate->link_state == IFLA_VF_LINK_STATE_AUTO)
385 			fprintf(fp, ", link-state auto");
386 		else if (vf_linkstate->link_state == IFLA_VF_LINK_STATE_ENABLE)
387 			fprintf(fp, ", link-state enable");
388 		else
389 			fprintf(fp, ", link-state disable");
390 	}
391 	if (vf[IFLA_VF_STATS] && show_stats)
392 		print_vf_stats64(fp, vf[IFLA_VF_STATS]);
393 }
394 
print_num(FILE * fp,unsigned width,uint64_t count)395 static void print_num(FILE *fp, unsigned width, uint64_t count)
396 {
397 	const char *prefix = "kMGTPE";
398 	const unsigned int base = use_iec ? 1024 : 1000;
399 	uint64_t powi = 1;
400 	uint16_t powj = 1;
401 	uint8_t precision = 2;
402 	char buf[64];
403 
404 	if (!human_readable || count < base) {
405 		fprintf(fp, "%-*"PRIu64" ", width, count);
406 		return;
407 	}
408 
409 	/* increase value by a factor of 1000/1024 and print
410 	 * if result is something a human can read */
411 	for(;;) {
412 		powi *= base;
413 		if (count / base < powi)
414 			break;
415 
416 		if (!prefix[1])
417 			break;
418 		++prefix;
419 	}
420 
421 	/* try to guess a good number of digits for precision */
422 	for (; precision > 0; precision--) {
423 		powj *= 10;
424 		if (count / powi < powj)
425 			break;
426 	}
427 
428 	snprintf(buf, sizeof(buf), "%.*f%c%s", precision,
429 		(double) count / powi, *prefix, use_iec ? "i" : "");
430 
431 	fprintf(fp, "%-*s ", width, buf);
432 }
433 
print_vf_stats64(FILE * fp,struct rtattr * vfstats)434 static void print_vf_stats64(FILE *fp, struct rtattr *vfstats)
435 {
436 	struct rtattr *vf[IFLA_VF_STATS_MAX + 1] = {};
437 
438 	if (vfstats->rta_type != IFLA_VF_STATS) {
439 		fprintf(stderr, "BUG: rta type is %d\n", vfstats->rta_type);
440 		return;
441 	}
442 
443 	parse_rtattr_nested(vf, IFLA_VF_MAX, vfstats);
444 
445 	/* RX stats */
446 	fprintf(fp, "%s", _SL_);
447 	fprintf(fp, "    RX: bytes  packets  mcast   bcast %s", _SL_);
448 	fprintf(fp, "    ");
449 
450 	print_num(fp, 10, *(__u64 *)RTA_DATA(vf[IFLA_VF_STATS_RX_BYTES]));
451 	print_num(fp, 8, *(__u64 *)RTA_DATA(vf[IFLA_VF_STATS_RX_PACKETS]));
452 	print_num(fp, 7, *(__u64 *)RTA_DATA(vf[IFLA_VF_STATS_MULTICAST]));
453 	print_num(fp, 7, *(__u64 *)RTA_DATA(vf[IFLA_VF_STATS_BROADCAST]));
454 
455 	/* TX stats */
456 	fprintf(fp, "%s", _SL_);
457 	fprintf(fp, "    TX: bytes  packets %s", _SL_);
458 	fprintf(fp, "    ");
459 
460 	print_num(fp, 10, *(__u64 *)RTA_DATA(vf[IFLA_VF_STATS_TX_BYTES]));
461 	print_num(fp, 8, *(__u64 *)RTA_DATA(vf[IFLA_VF_STATS_TX_PACKETS]));
462 }
463 
print_link_stats64(FILE * fp,const struct rtnl_link_stats64 * s,const struct rtattr * carrier_changes)464 static void print_link_stats64(FILE *fp, const struct rtnl_link_stats64 *s,
465                                const struct rtattr *carrier_changes)
466 {
467 	/* RX stats */
468 	fprintf(fp, "    RX: bytes  packets  errors  dropped overrun mcast   %s%s",
469 		s->rx_compressed ? "compressed" : "", _SL_);
470 
471 	fprintf(fp, "    ");
472 	print_num(fp, 10, s->rx_bytes);
473 	print_num(fp, 8, s->rx_packets);
474 	print_num(fp, 7, s->rx_errors);
475 	print_num(fp, 7, s->rx_dropped);
476 	print_num(fp, 7, s->rx_over_errors);
477 	print_num(fp, 7, s->multicast);
478 	if (s->rx_compressed)
479 		print_num(fp, 7, s->rx_compressed);
480 
481 	/* RX error stats */
482 	if (show_stats > 1) {
483 		fprintf(fp, "%s", _SL_);
484 		fprintf(fp, "    RX errors: length   crc     frame   fifo    missed%s", _SL_);
485 
486 		fprintf(fp, "               ");
487 		print_num(fp, 8, s->rx_length_errors);
488 		print_num(fp, 7, s->rx_crc_errors);
489 		print_num(fp, 7, s->rx_frame_errors);
490 		print_num(fp, 7, s->rx_fifo_errors);
491 		print_num(fp, 7, s->rx_missed_errors);
492 	}
493 	fprintf(fp, "%s", _SL_);
494 
495 	/* TX stats */
496 	fprintf(fp, "    TX: bytes  packets  errors  dropped carrier collsns %s%s",
497 		s->tx_compressed ? "compressed" : "", _SL_);
498 
499 
500 	fprintf(fp, "    ");
501 	print_num(fp, 10, s->tx_bytes);
502 	print_num(fp, 8, s->tx_packets);
503 	print_num(fp, 7, s->tx_errors);
504 	print_num(fp, 7, s->tx_dropped);
505 	print_num(fp, 7, s->tx_carrier_errors);
506 	print_num(fp, 7, s->collisions);
507 	if (s->tx_compressed)
508 		print_num(fp, 7, s->tx_compressed);
509 
510 	/* TX error stats */
511 	if (show_stats > 1) {
512 		fprintf(fp, "%s", _SL_);
513 		fprintf(fp, "    TX errors: aborted  fifo   window heartbeat");
514                 if (carrier_changes)
515 			fprintf(fp, " transns");
516 		fprintf(fp, "%s", _SL_);
517 
518 		fprintf(fp, "               ");
519 		print_num(fp, 8, s->tx_aborted_errors);
520 		print_num(fp, 7, s->tx_fifo_errors);
521 		print_num(fp, 7, s->tx_window_errors);
522 		print_num(fp, 7, s->tx_heartbeat_errors);
523 		if (carrier_changes)
524 			print_num(fp, 7, *(uint32_t*)RTA_DATA(carrier_changes));
525 	}
526 }
527 
print_link_stats32(FILE * fp,const struct rtnl_link_stats * s,const struct rtattr * carrier_changes)528 static void print_link_stats32(FILE *fp, const struct rtnl_link_stats *s,
529 			       const struct rtattr *carrier_changes)
530 {
531 	/* RX stats */
532 	fprintf(fp, "    RX: bytes  packets  errors  dropped overrun mcast   %s%s",
533 		s->rx_compressed ? "compressed" : "", _SL_);
534 
535 
536 	fprintf(fp, "    ");
537 	print_num(fp, 10, s->rx_bytes);
538 	print_num(fp, 8, s->rx_packets);
539 	print_num(fp, 7, s->rx_errors);
540 	print_num(fp, 7, s->rx_dropped);
541 	print_num(fp, 7, s->rx_over_errors);
542 	print_num(fp, 7, s->multicast);
543 	if (s->rx_compressed)
544 		print_num(fp, 7, s->rx_compressed);
545 
546 	/* RX error stats */
547 	if (show_stats > 1) {
548 		fprintf(fp, "%s", _SL_);
549 		fprintf(fp, "    RX errors: length   crc     frame   fifo    missed%s", _SL_);
550 		fprintf(fp, "               ");
551 		print_num(fp, 8, s->rx_length_errors);
552 		print_num(fp, 7, s->rx_crc_errors);
553 		print_num(fp, 7, s->rx_frame_errors);
554 		print_num(fp, 7, s->rx_fifo_errors);
555 		print_num(fp, 7, s->rx_missed_errors);
556 	}
557 	fprintf(fp, "%s", _SL_);
558 
559 	/* TX stats */
560 	fprintf(fp, "    TX: bytes  packets  errors  dropped carrier collsns %s%s",
561 		s->tx_compressed ? "compressed" : "", _SL_);
562 
563 	fprintf(fp, "    ");
564 	print_num(fp, 10, s->tx_bytes);
565 	print_num(fp, 8, s->tx_packets);
566 	print_num(fp, 7, s->tx_errors);
567 	print_num(fp, 7, s->tx_dropped);
568 	print_num(fp, 7, s->tx_carrier_errors);
569 	print_num(fp, 7, s->collisions);
570 	if (s->tx_compressed)
571 		print_num(fp, 7, s->tx_compressed);
572 
573 	/* TX error stats */
574 	if (show_stats > 1) {
575 		fprintf(fp, "%s", _SL_);
576 		fprintf(fp, "    TX errors: aborted  fifo   window heartbeat");
577                 if (carrier_changes)
578 			fprintf(fp, " transns");
579 		fprintf(fp, "%s", _SL_);
580 
581 		fprintf(fp, "               ");
582 		print_num(fp, 8, s->tx_aborted_errors);
583 		print_num(fp, 7, s->tx_fifo_errors);
584 		print_num(fp, 7, s->tx_window_errors);
585 		print_num(fp, 7, s->tx_heartbeat_errors);
586 		if (carrier_changes)
587 			print_num(fp, 7, *(uint32_t*)RTA_DATA(carrier_changes));
588 	}
589 }
590 
__print_link_stats(FILE * fp,struct rtattr ** tb)591 static void __print_link_stats(FILE *fp, struct rtattr **tb)
592 {
593 	if (tb[IFLA_STATS64])
594 		print_link_stats64(fp, RTA_DATA(tb[IFLA_STATS64]),
595 					tb[IFLA_CARRIER_CHANGES]);
596 	else if (tb[IFLA_STATS])
597 		print_link_stats32(fp, RTA_DATA(tb[IFLA_STATS]),
598 					tb[IFLA_CARRIER_CHANGES]);
599 }
600 
print_link_stats(FILE * fp,struct nlmsghdr * n)601 static void print_link_stats(FILE *fp, struct nlmsghdr *n)
602 {
603 	struct ifinfomsg *ifi = NLMSG_DATA(n);
604 	struct rtattr * tb[IFLA_MAX+1];
605 
606 	parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi),
607 		     n->nlmsg_len - NLMSG_LENGTH(sizeof(*ifi)));
608 	__print_link_stats(fp, tb);
609 	fprintf(fp, "%s", _SL_);
610 }
611 
print_linkinfo_brief(const struct sockaddr_nl * who,struct nlmsghdr * n,void * arg)612 int print_linkinfo_brief(const struct sockaddr_nl *who,
613 				struct nlmsghdr *n, void *arg)
614 {
615 	FILE *fp = (FILE*)arg;
616 	struct ifinfomsg *ifi = NLMSG_DATA(n);
617 	struct rtattr * tb[IFLA_MAX+1];
618 	int len = n->nlmsg_len;
619 	char *name;
620 	char buf[32] = { 0, };
621 	unsigned m_flag = 0;
622 
623 	if (n->nlmsg_type != RTM_NEWLINK && n->nlmsg_type != RTM_DELLINK)
624 		return -1;
625 
626 	len -= NLMSG_LENGTH(sizeof(*ifi));
627 	if (len < 0)
628 		return -1;
629 
630 	if (filter.ifindex && ifi->ifi_index != filter.ifindex)
631 		return -1;
632 	if (filter.up && !(ifi->ifi_flags&IFF_UP))
633 		return -1;
634 
635 	parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
636 	if (tb[IFLA_IFNAME] == NULL) {
637 		fprintf(stderr, "BUG: device with ifindex %d has nil ifname\n", ifi->ifi_index);
638 	}
639 	if (filter.label &&
640 	    (!filter.family || filter.family == AF_PACKET) &&
641 	    fnmatch(filter.label, RTA_DATA(tb[IFLA_IFNAME]), 0))
642 		return -1;
643 
644 	if (tb[IFLA_GROUP]) {
645 		int group = *(int*)RTA_DATA(tb[IFLA_GROUP]);
646 		if (filter.group != -1 && group != filter.group)
647 			return -1;
648 	}
649 
650 	if (tb[IFLA_MASTER]) {
651 		int master = *(int*)RTA_DATA(tb[IFLA_MASTER]);
652 		if (filter.master > 0 && master != filter.master)
653 			return -1;
654 	}
655 	else if (filter.master > 0)
656 		return -1;
657 
658 	if (filter.kind) {
659 		if (tb[IFLA_LINKINFO]) {
660 			char *kind = parse_link_kind(tb[IFLA_LINKINFO]);
661 
662 			if (strcmp(kind, filter.kind))
663 				return -1;
664 		} else {
665 			return -1;
666 		}
667 	}
668 
669 	if (n->nlmsg_type == RTM_DELLINK)
670 		fprintf(fp, "Deleted ");
671 
672 	name = (char *)(tb[IFLA_IFNAME] ? rta_getattr_str(tb[IFLA_IFNAME]) : "<nil>");
673 
674 	if (tb[IFLA_LINK]) {
675 		SPRINT_BUF(b1);
676 		int iflink = *(int*)RTA_DATA(tb[IFLA_LINK]);
677 		if (iflink == 0)
678 			snprintf(buf, sizeof(buf), "%s@NONE", name);
679 		else {
680 			snprintf(buf, sizeof(buf),
681 				 "%s@%s", name, ll_idx_n2a(iflink, b1));
682 			m_flag = ll_index_to_flags(iflink);
683 			m_flag = !(m_flag & IFF_UP);
684 		}
685 	} else
686 		snprintf(buf, sizeof(buf), "%s", name);
687 
688 	fprintf(fp, "%-16s ", buf);
689 
690 	if (tb[IFLA_OPERSTATE])
691 		print_operstate(fp, rta_getattr_u8(tb[IFLA_OPERSTATE]));
692 
693 	if (filter.family == AF_PACKET) {
694 		SPRINT_BUF(b1);
695 		if (tb[IFLA_ADDRESS]) {
696 			color_fprintf(fp, COLOR_MAC, "%s ",
697 					ll_addr_n2a(RTA_DATA(tb[IFLA_ADDRESS]),
698 						RTA_PAYLOAD(tb[IFLA_ADDRESS]),
699 						ifi->ifi_type,
700 						b1, sizeof(b1)));
701 		}
702 	}
703 
704 	if (filter.family == AF_PACKET)
705 		print_link_flags(fp, ifi->ifi_flags, m_flag);
706 
707 	if (filter.family == AF_PACKET)
708 		fprintf(fp, "\n");
709 	fflush(fp);
710 	return 0;
711 }
712 
print_linkinfo(const struct sockaddr_nl * who,struct nlmsghdr * n,void * arg)713 int print_linkinfo(const struct sockaddr_nl *who,
714 		   struct nlmsghdr *n, void *arg)
715 {
716 	FILE *fp = (FILE*)arg;
717 	struct ifinfomsg *ifi = NLMSG_DATA(n);
718 	struct rtattr * tb[IFLA_MAX+1];
719 	int len = n->nlmsg_len;
720 	unsigned m_flag = 0;
721 
722 	if (n->nlmsg_type != RTM_NEWLINK && n->nlmsg_type != RTM_DELLINK)
723 		return 0;
724 
725 	len -= NLMSG_LENGTH(sizeof(*ifi));
726 	if (len < 0)
727 		return -1;
728 
729 	if (filter.ifindex && ifi->ifi_index != filter.ifindex)
730 		return 0;
731 	if (filter.up && !(ifi->ifi_flags&IFF_UP))
732 		return 0;
733 
734 	parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
735 	if (tb[IFLA_IFNAME] == NULL) {
736 		fprintf(stderr, "BUG: device with ifindex %d has nil ifname\n", ifi->ifi_index);
737 	}
738 	if (filter.label &&
739 	    (!filter.family || filter.family == AF_PACKET) &&
740 	    fnmatch(filter.label, RTA_DATA(tb[IFLA_IFNAME]), 0))
741 		return 0;
742 
743 	if (tb[IFLA_GROUP]) {
744 		int group = *(int*)RTA_DATA(tb[IFLA_GROUP]);
745 		if (filter.group != -1 && group != filter.group)
746 			return -1;
747 	}
748 
749 	if (tb[IFLA_MASTER]) {
750 		int master = *(int*)RTA_DATA(tb[IFLA_MASTER]);
751 		if (filter.master > 0 && master != filter.master)
752 			return -1;
753 	}
754 	else if (filter.master > 0)
755 		return -1;
756 
757 	if (filter.kind) {
758 		if (tb[IFLA_LINKINFO]) {
759 			char *kind = parse_link_kind(tb[IFLA_LINKINFO]);
760 
761 			if (strcmp(kind, filter.kind))
762 				return -1;
763 		} else {
764 			return -1;
765 		}
766 	}
767 
768 	if (n->nlmsg_type == RTM_DELLINK)
769 		fprintf(fp, "Deleted ");
770 
771 	fprintf(fp, "%d: ", ifi->ifi_index);
772 	color_fprintf(fp, COLOR_IFNAME, "%s",
773 		tb[IFLA_IFNAME] ? rta_getattr_str(tb[IFLA_IFNAME]) : "<nil>");
774 
775 	if (tb[IFLA_LINK]) {
776 		SPRINT_BUF(b1);
777 		int iflink = *(int*)RTA_DATA(tb[IFLA_LINK]);
778 		if (iflink == 0)
779 			fprintf(fp, "@NONE: ");
780 		else {
781 			if (tb[IFLA_LINK_NETNSID])
782 				fprintf(fp, "@if%d: ", iflink);
783 			else {
784 				fprintf(fp, "@%s: ", ll_idx_n2a(iflink, b1));
785 				m_flag = ll_index_to_flags(iflink);
786 				m_flag = !(m_flag & IFF_UP);
787 			}
788 		}
789 	} else {
790 		fprintf(fp, ": ");
791 	}
792 	print_link_flags(fp, ifi->ifi_flags, m_flag);
793 
794 	if (tb[IFLA_MTU])
795 		fprintf(fp, "mtu %u ", *(int*)RTA_DATA(tb[IFLA_MTU]));
796 	if (tb[IFLA_QDISC])
797 		fprintf(fp, "qdisc %s ", rta_getattr_str(tb[IFLA_QDISC]));
798 	if (tb[IFLA_MASTER]) {
799 		SPRINT_BUF(b1);
800 		fprintf(fp, "master %s ", ll_idx_n2a(*(int*)RTA_DATA(tb[IFLA_MASTER]), b1));
801 	}
802 
803 	if (tb[IFLA_PHYS_PORT_ID]) {
804 		SPRINT_BUF(b1);
805 		fprintf(fp, "portid %s ",
806 			hexstring_n2a(RTA_DATA(tb[IFLA_PHYS_PORT_ID]),
807 				      RTA_PAYLOAD(tb[IFLA_PHYS_PORT_ID]),
808 				      b1, sizeof(b1)));
809 	}
810 
811 	if (tb[IFLA_PHYS_SWITCH_ID]) {
812 		SPRINT_BUF(b1);
813 		fprintf(fp, "switchid %s ",
814 			hexstring_n2a(RTA_DATA(tb[IFLA_PHYS_SWITCH_ID]),
815 				      RTA_PAYLOAD(tb[IFLA_PHYS_SWITCH_ID]),
816 				      b1, sizeof(b1)));
817 	}
818 
819 	if (tb[IFLA_OPERSTATE])
820 		print_operstate(fp, rta_getattr_u8(tb[IFLA_OPERSTATE]));
821 
822 	if (do_link && tb[IFLA_LINKMODE])
823 		print_linkmode(fp, tb[IFLA_LINKMODE]);
824 
825 	if (tb[IFLA_GROUP]) {
826 		SPRINT_BUF(b1);
827 		int group = *(int*)RTA_DATA(tb[IFLA_GROUP]);
828 		fprintf(fp, "group %s ", rtnl_group_n2a(group, b1, sizeof(b1)));
829 	}
830 
831 	if (filter.showqueue)
832 		print_queuelen(fp, tb);
833 
834 	if (!filter.family || filter.family == AF_PACKET || show_details) {
835 		SPRINT_BUF(b1);
836 		fprintf(fp, "%s", _SL_);
837 		fprintf(fp, "    link/%s ", ll_type_n2a(ifi->ifi_type, b1, sizeof(b1)));
838 
839 		if (tb[IFLA_ADDRESS]) {
840 			color_fprintf(fp, COLOR_MAC, "%s",
841 					ll_addr_n2a(RTA_DATA(tb[IFLA_ADDRESS]),
842 						RTA_PAYLOAD(tb[IFLA_ADDRESS]),
843 						ifi->ifi_type,
844 						b1, sizeof(b1)));
845 		}
846 		if (tb[IFLA_BROADCAST]) {
847 			if (ifi->ifi_flags&IFF_POINTOPOINT)
848 				fprintf(fp, " peer ");
849 			else
850 				fprintf(fp, " brd ");
851 			fprintf(fp, "%s", ll_addr_n2a(RTA_DATA(tb[IFLA_BROADCAST]),
852 						      RTA_PAYLOAD(tb[IFLA_BROADCAST]),
853 						      ifi->ifi_type,
854 						      b1, sizeof(b1)));
855 		}
856 	}
857 
858 	if (tb[IFLA_LINK_NETNSID]) {
859 		int id = *(int*)RTA_DATA(tb[IFLA_LINK_NETNSID]);
860 
861 		if (id >= 0)
862 			fprintf(fp, " link-netnsid %d", id);
863 		else
864 			fprintf(fp, " link-netnsid unknown");
865 	}
866 
867 	if (tb[IFLA_PROTO_DOWN]) {
868 		if (rta_getattr_u8(tb[IFLA_PROTO_DOWN]))
869 			fprintf(fp, " protodown on ");
870 	}
871 
872 	if (tb[IFLA_PROMISCUITY] && show_details)
873 		fprintf(fp, " promiscuity %u ",
874 			*(int*)RTA_DATA(tb[IFLA_PROMISCUITY]));
875 
876 	if (tb[IFLA_LINKINFO] && show_details)
877 		print_linktype(fp, tb[IFLA_LINKINFO]);
878 
879 	if (do_link && tb[IFLA_AF_SPEC] && show_details)
880 		print_af_spec(fp, tb[IFLA_AF_SPEC]);
881 
882 	if ((do_link || show_details) && tb[IFLA_IFALIAS]) {
883 		fprintf(fp, "%s    alias %s", _SL_,
884 			rta_getattr_str(tb[IFLA_IFALIAS]));
885 	}
886 
887 	if (do_link && show_stats) {
888 		fprintf(fp, "%s", _SL_);
889 		__print_link_stats(fp, tb);
890 	}
891 
892 	if ((do_link || show_details) && tb[IFLA_VFINFO_LIST] && tb[IFLA_NUM_VF]) {
893 		struct rtattr *i, *vflist = tb[IFLA_VFINFO_LIST];
894 		int rem = RTA_PAYLOAD(vflist);
895 		for (i = RTA_DATA(vflist); RTA_OK(i, rem); i = RTA_NEXT(i, rem))
896 			print_vfinfo(fp, i);
897 	}
898 
899 	fprintf(fp, "\n");
900 	fflush(fp);
901 	return 1;
902 }
903 
flush_update(void)904 static int flush_update(void)
905 {
906 
907 	/*
908 	 * Note that the kernel may delete multiple addresses for one
909 	 * delete request (e.g. if ipv4 address promotion is disabled).
910 	 * Since a flush operation is really a series of delete requests
911 	 * its possible that we may request an address delete that has
912 	 * already been done by the kernel. Therefore, ignore EADDRNOTAVAIL
913 	 * errors returned from a flush request
914 	 */
915 	if ((rtnl_send_check(&rth, filter.flushb, filter.flushp) < 0) &&
916 	    (errno != EADDRNOTAVAIL)) {
917 		perror("Failed to send flush request");
918 		return -1;
919 	}
920 	filter.flushp = 0;
921 	return 0;
922 }
923 
set_lifetime(unsigned int * lifetime,char * argv)924 static int set_lifetime(unsigned int *lifetime, char *argv)
925 {
926 	if (strcmp(argv, "forever") == 0)
927 		*lifetime = INFINITY_LIFE_TIME;
928 	else if (get_u32(lifetime, argv, 0))
929 		return -1;
930 
931 	return 0;
932 }
933 
get_ifa_flags(struct ifaddrmsg * ifa,struct rtattr * ifa_flags_attr)934 static unsigned int get_ifa_flags(struct ifaddrmsg *ifa,
935 				  struct rtattr *ifa_flags_attr)
936 {
937 	return ifa_flags_attr ? rta_getattr_u32(ifa_flags_attr) :
938 				ifa->ifa_flags;
939 }
940 
print_addrinfo(const struct sockaddr_nl * who,struct nlmsghdr * n,void * arg)941 int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n,
942 		   void *arg)
943 {
944 	FILE *fp = arg;
945 	struct ifaddrmsg *ifa = NLMSG_DATA(n);
946 	int len = n->nlmsg_len;
947 	int deprecated = 0;
948 	/* Use local copy of ifa_flags to not interfere with filtering code */
949 	unsigned int ifa_flags;
950 	struct rtattr * rta_tb[IFA_MAX+1];
951 	char abuf[256];
952 	SPRINT_BUF(b1);
953 
954 	if (n->nlmsg_type != RTM_NEWADDR && n->nlmsg_type != RTM_DELADDR)
955 		return 0;
956 	len -= NLMSG_LENGTH(sizeof(*ifa));
957 	if (len < 0) {
958 		fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
959 		return -1;
960 	}
961 
962 	if (filter.flushb && n->nlmsg_type != RTM_NEWADDR)
963 		return 0;
964 
965 	parse_rtattr(rta_tb, IFA_MAX, IFA_RTA(ifa),
966 		     n->nlmsg_len - NLMSG_LENGTH(sizeof(*ifa)));
967 
968 	ifa_flags = get_ifa_flags(ifa, rta_tb[IFA_FLAGS]);
969 
970 	if (!rta_tb[IFA_LOCAL])
971 		rta_tb[IFA_LOCAL] = rta_tb[IFA_ADDRESS];
972 	if (!rta_tb[IFA_ADDRESS])
973 		rta_tb[IFA_ADDRESS] = rta_tb[IFA_LOCAL];
974 
975 	if (filter.ifindex && filter.ifindex != ifa->ifa_index)
976 		return 0;
977 	if ((filter.scope^ifa->ifa_scope)&filter.scopemask)
978 		return 0;
979 	if ((filter.flags ^ ifa_flags) & filter.flagmask)
980 		return 0;
981 	if (filter.label) {
982 		SPRINT_BUF(b1);
983 		const char *label;
984 		if (rta_tb[IFA_LABEL])
985 			label = RTA_DATA(rta_tb[IFA_LABEL]);
986 		else
987 			label = ll_idx_n2a(ifa->ifa_index, b1);
988 		if (fnmatch(filter.label, label, 0) != 0)
989 			return 0;
990 	}
991 	if (filter.pfx.family) {
992 		if (rta_tb[IFA_LOCAL]) {
993 			inet_prefix dst;
994 			memset(&dst, 0, sizeof(dst));
995 			dst.family = ifa->ifa_family;
996 			memcpy(&dst.data, RTA_DATA(rta_tb[IFA_LOCAL]), RTA_PAYLOAD(rta_tb[IFA_LOCAL]));
997 			if (inet_addr_match(&dst, &filter.pfx, filter.pfx.bitlen))
998 				return 0;
999 		}
1000 	}
1001 
1002 	if (filter.family && filter.family != ifa->ifa_family)
1003 		return 0;
1004 
1005 	if (filter.flushb) {
1006 		struct nlmsghdr *fn;
1007 		if (NLMSG_ALIGN(filter.flushp) + n->nlmsg_len > filter.flushe) {
1008 			if (flush_update())
1009 				return -1;
1010 		}
1011 		fn = (struct nlmsghdr*)(filter.flushb + NLMSG_ALIGN(filter.flushp));
1012 		memcpy(fn, n, n->nlmsg_len);
1013 		fn->nlmsg_type = RTM_DELADDR;
1014 		fn->nlmsg_flags = NLM_F_REQUEST;
1015 		fn->nlmsg_seq = ++rth.seq;
1016 		filter.flushp = (((char*)fn) + n->nlmsg_len) - filter.flushb;
1017 		filter.flushed++;
1018 		if (show_stats < 2)
1019 			return 0;
1020 	}
1021 
1022 	if (n->nlmsg_type == RTM_DELADDR)
1023 		fprintf(fp, "Deleted ");
1024 
1025 	if (!brief) {
1026 		if (filter.oneline || filter.flushb)
1027 			fprintf(fp, "%u: %s", ifa->ifa_index, ll_index_to_name(ifa->ifa_index));
1028 		if (ifa->ifa_family == AF_INET)
1029 			fprintf(fp, "    inet ");
1030 		else if (ifa->ifa_family == AF_INET6)
1031 			fprintf(fp, "    inet6 ");
1032 		else if (ifa->ifa_family == AF_DECnet)
1033 			fprintf(fp, "    dnet ");
1034 		else if (ifa->ifa_family == AF_IPX)
1035 			fprintf(fp, "     ipx ");
1036 		else
1037 			fprintf(fp, "    family %d ", ifa->ifa_family);
1038 	}
1039 
1040 	if (rta_tb[IFA_LOCAL]) {
1041 		if (ifa->ifa_family == AF_INET)
1042 			color_fprintf(fp, COLOR_INET, "%s", format_host(ifa->ifa_family,
1043 						RTA_PAYLOAD(rta_tb[IFA_LOCAL]),
1044 						RTA_DATA(rta_tb[IFA_LOCAL]),
1045 						abuf, sizeof(abuf)));
1046 		else if (ifa->ifa_family == AF_INET6)
1047 			color_fprintf(fp, COLOR_INET6, "%s", format_host(ifa->ifa_family,
1048 						RTA_PAYLOAD(rta_tb[IFA_LOCAL]),
1049 						RTA_DATA(rta_tb[IFA_LOCAL]),
1050 						abuf, sizeof(abuf)));
1051 		else
1052 			fprintf(fp, "%s", format_host(ifa->ifa_family,
1053 						RTA_PAYLOAD(rta_tb[IFA_LOCAL]),
1054 						RTA_DATA(rta_tb[IFA_LOCAL]),
1055 						abuf, sizeof(abuf)));
1056 
1057 		if (rta_tb[IFA_ADDRESS] == NULL ||
1058 		    memcmp(RTA_DATA(rta_tb[IFA_ADDRESS]), RTA_DATA(rta_tb[IFA_LOCAL]),
1059 			   ifa->ifa_family == AF_INET ? 4 : 16) == 0) {
1060 			fprintf(fp, "/%d ", ifa->ifa_prefixlen);
1061 		} else {
1062 			fprintf(fp, " peer %s/%d ",
1063 				format_host(ifa->ifa_family,
1064 					    RTA_PAYLOAD(rta_tb[IFA_ADDRESS]),
1065 					    RTA_DATA(rta_tb[IFA_ADDRESS]),
1066 					    abuf, sizeof(abuf)),
1067 				ifa->ifa_prefixlen);
1068 		}
1069 	}
1070 
1071 	if (brief)
1072 		goto brief_exit;
1073 
1074 	if (rta_tb[IFA_BROADCAST]) {
1075 		fprintf(fp, "brd %s ",
1076 			format_host(ifa->ifa_family,
1077 				    RTA_PAYLOAD(rta_tb[IFA_BROADCAST]),
1078 				    RTA_DATA(rta_tb[IFA_BROADCAST]),
1079 				    abuf, sizeof(abuf)));
1080 	}
1081 	if (rta_tb[IFA_ANYCAST]) {
1082 		fprintf(fp, "any %s ",
1083 			format_host(ifa->ifa_family,
1084 				    RTA_PAYLOAD(rta_tb[IFA_ANYCAST]),
1085 				    RTA_DATA(rta_tb[IFA_ANYCAST]),
1086 				    abuf, sizeof(abuf)));
1087 	}
1088 	fprintf(fp, "scope %s ", rtnl_rtscope_n2a(ifa->ifa_scope, b1, sizeof(b1)));
1089 	if (ifa_flags & IFA_F_SECONDARY) {
1090 		ifa_flags &= ~IFA_F_SECONDARY;
1091 		if (ifa->ifa_family == AF_INET6)
1092 			fprintf(fp, "temporary ");
1093 		else
1094 			fprintf(fp, "secondary ");
1095 	}
1096 	if (ifa_flags & IFA_F_TENTATIVE) {
1097 		ifa_flags &= ~IFA_F_TENTATIVE;
1098 		fprintf(fp, "tentative ");
1099 	}
1100 	if (ifa_flags & IFA_F_DEPRECATED) {
1101 		ifa_flags &= ~IFA_F_DEPRECATED;
1102 		deprecated = 1;
1103 		fprintf(fp, "deprecated ");
1104 	}
1105 	if (ifa_flags & IFA_F_HOMEADDRESS) {
1106 		ifa_flags &= ~IFA_F_HOMEADDRESS;
1107 		fprintf(fp, "home ");
1108 	}
1109 	if (ifa_flags & IFA_F_NODAD) {
1110 		ifa_flags &= ~IFA_F_NODAD;
1111 		fprintf(fp, "nodad ");
1112 	}
1113 	if (ifa_flags & IFA_F_MANAGETEMPADDR) {
1114 		ifa_flags &= ~IFA_F_MANAGETEMPADDR;
1115 		fprintf(fp, "mngtmpaddr ");
1116 	}
1117 	if (ifa_flags & IFA_F_NOPREFIXROUTE) {
1118 		ifa_flags &= ~IFA_F_NOPREFIXROUTE;
1119 		fprintf(fp, "noprefixroute ");
1120 	}
1121 	if (ifa_flags & IFA_F_MCAUTOJOIN) {
1122 		ifa_flags &= ~IFA_F_MCAUTOJOIN;
1123 		fprintf(fp, "autojoin ");
1124 	}
1125 	if (!(ifa_flags & IFA_F_PERMANENT)) {
1126 		fprintf(fp, "dynamic ");
1127 	} else
1128 		ifa_flags &= ~IFA_F_PERMANENT;
1129 	if (ifa_flags & IFA_F_DADFAILED) {
1130 		ifa_flags &= ~IFA_F_DADFAILED;
1131 		fprintf(fp, "dadfailed ");
1132 	}
1133 	if (ifa_flags)
1134 		fprintf(fp, "flags %02x ", ifa_flags);
1135 	if (rta_tb[IFA_LABEL])
1136 		fprintf(fp, "%s", rta_getattr_str(rta_tb[IFA_LABEL]));
1137 	if (rta_tb[IFA_CACHEINFO]) {
1138 		struct ifa_cacheinfo *ci = RTA_DATA(rta_tb[IFA_CACHEINFO]);
1139 		fprintf(fp, "%s", _SL_);
1140 		fprintf(fp, "       valid_lft ");
1141 		if (ci->ifa_valid == INFINITY_LIFE_TIME)
1142 			fprintf(fp, "forever");
1143 		else
1144 			fprintf(fp, "%usec", ci->ifa_valid);
1145 		fprintf(fp, " preferred_lft ");
1146 		if (ci->ifa_prefered == INFINITY_LIFE_TIME)
1147 			fprintf(fp, "forever");
1148 		else {
1149 			if (deprecated)
1150 				fprintf(fp, "%dsec", ci->ifa_prefered);
1151 			else
1152 				fprintf(fp, "%usec", ci->ifa_prefered);
1153 		}
1154 	}
1155 	fprintf(fp, "\n");
1156 brief_exit:
1157 	fflush(fp);
1158 	return 0;
1159 }
1160 
1161 struct nlmsg_list
1162 {
1163 	struct nlmsg_list *next;
1164 	struct nlmsghdr	  h;
1165 };
1166 
1167 struct nlmsg_chain
1168 {
1169 	struct nlmsg_list *head;
1170 	struct nlmsg_list *tail;
1171 };
1172 
print_selected_addrinfo(struct ifinfomsg * ifi,struct nlmsg_list * ainfo,FILE * fp)1173 static int print_selected_addrinfo(struct ifinfomsg *ifi,
1174 				   struct nlmsg_list *ainfo, FILE *fp)
1175 {
1176 	for ( ;ainfo ;  ainfo = ainfo->next) {
1177 		struct nlmsghdr *n = &ainfo->h;
1178 		struct ifaddrmsg *ifa = NLMSG_DATA(n);
1179 
1180 		if (n->nlmsg_type != RTM_NEWADDR)
1181 			continue;
1182 
1183 		if (n->nlmsg_len < NLMSG_LENGTH(sizeof(ifa)))
1184 			return -1;
1185 
1186 		if (ifa->ifa_index != ifi->ifi_index ||
1187 		    (filter.family && filter.family != ifa->ifa_family))
1188 			continue;
1189 
1190 		if (filter.up && !(ifi->ifi_flags&IFF_UP))
1191 			continue;
1192 
1193 		print_addrinfo(NULL, n, fp);
1194 	}
1195 	if (brief) {
1196 		fprintf(fp, "\n");
1197 		fflush(fp);
1198 	}
1199 	return 0;
1200 }
1201 
1202 
store_nlmsg(const struct sockaddr_nl * who,struct nlmsghdr * n,void * arg)1203 static int store_nlmsg(const struct sockaddr_nl *who, struct nlmsghdr *n,
1204 		       void *arg)
1205 {
1206 	struct nlmsg_chain *lchain = (struct nlmsg_chain *)arg;
1207 	struct nlmsg_list *h;
1208 
1209 	h = malloc(n->nlmsg_len+sizeof(void*));
1210 	if (h == NULL)
1211 		return -1;
1212 
1213 	memcpy(&h->h, n, n->nlmsg_len);
1214 	h->next = NULL;
1215 
1216 	if (lchain->tail)
1217 		lchain->tail->next = h;
1218 	else
1219 		lchain->head = h;
1220 	lchain->tail = h;
1221 
1222 	ll_remember_index(who, n, NULL);
1223 	return 0;
1224 }
1225 
1226 static __u32 ipadd_dump_magic = 0x47361222;
1227 
ipadd_save_prep(void)1228 static int ipadd_save_prep(void)
1229 {
1230 	int ret;
1231 
1232 	if (isatty(STDOUT_FILENO)) {
1233 		fprintf(stderr, "Not sending a binary stream to stdout\n");
1234 		return -1;
1235 	}
1236 
1237 	ret = write(STDOUT_FILENO, &ipadd_dump_magic, sizeof(ipadd_dump_magic));
1238 	if (ret != sizeof(ipadd_dump_magic)) {
1239 		fprintf(stderr, "Can't write magic to dump file\n");
1240 		return -1;
1241 	}
1242 
1243 	return 0;
1244 }
1245 
ipadd_dump_check_magic(void)1246 static int ipadd_dump_check_magic(void)
1247 {
1248 	int ret;
1249 	__u32 magic = 0;
1250 
1251 	if (isatty(STDIN_FILENO)) {
1252 		fprintf(stderr, "Can't restore address dump from a terminal\n");
1253 		return -1;
1254 	}
1255 
1256 	ret = fread(&magic, sizeof(magic), 1, stdin);
1257 	if (magic != ipadd_dump_magic) {
1258 		fprintf(stderr, "Magic mismatch (%d elems, %x magic)\n", ret, magic);
1259 		return -1;
1260 	}
1261 
1262 	return 0;
1263 }
1264 
save_nlmsg(const struct sockaddr_nl * who,struct nlmsghdr * n,void * arg)1265 static int save_nlmsg(const struct sockaddr_nl *who, struct nlmsghdr *n,
1266 		       void *arg)
1267 {
1268 	int ret;
1269 
1270 	ret = write(STDOUT_FILENO, n, n->nlmsg_len);
1271 	if ((ret > 0) && (ret != n->nlmsg_len)) {
1272 		fprintf(stderr, "Short write while saving nlmsg\n");
1273 		ret = -EIO;
1274 	}
1275 
1276 	return ret == n->nlmsg_len ? 0 : ret;
1277 }
1278 
show_handler(const struct sockaddr_nl * nl,struct rtnl_ctrl_data * ctrl,struct nlmsghdr * n,void * arg)1279 static int show_handler(const struct sockaddr_nl *nl,
1280 			struct rtnl_ctrl_data *ctrl,
1281 			struct nlmsghdr *n, void *arg)
1282 {
1283 	struct ifaddrmsg *ifa = NLMSG_DATA(n);
1284 
1285 	printf("if%d:\n", ifa->ifa_index);
1286 	print_addrinfo(NULL, n, stdout);
1287 	return 0;
1288 }
1289 
ipaddr_showdump(void)1290 static int ipaddr_showdump(void)
1291 {
1292 	if (ipadd_dump_check_magic())
1293 		exit(-1);
1294 
1295 	exit(rtnl_from_file(stdin, &show_handler, NULL));
1296 }
1297 
restore_handler(const struct sockaddr_nl * nl,struct rtnl_ctrl_data * ctrl,struct nlmsghdr * n,void * arg)1298 static int restore_handler(const struct sockaddr_nl *nl,
1299 			   struct rtnl_ctrl_data *ctrl,
1300 			   struct nlmsghdr *n, void *arg)
1301 {
1302 	int ret;
1303 
1304 	n->nlmsg_flags |= NLM_F_REQUEST | NLM_F_CREATE | NLM_F_ACK;
1305 
1306 	ll_init_map(&rth);
1307 
1308 	ret = rtnl_talk(&rth, n, n, sizeof(*n));
1309 	if ((ret < 0) && (errno == EEXIST))
1310 		ret = 0;
1311 
1312 	return ret;
1313 }
1314 
ipaddr_restore(void)1315 static int ipaddr_restore(void)
1316 {
1317 	if (ipadd_dump_check_magic())
1318 		exit(-1);
1319 
1320 	exit(rtnl_from_file(stdin, &restore_handler, NULL));
1321 }
1322 
free_nlmsg_chain(struct nlmsg_chain * info)1323 static void free_nlmsg_chain(struct nlmsg_chain *info)
1324 {
1325 	struct nlmsg_list *l, *n;
1326 
1327 	for (l = info->head; l; l = n) {
1328 		n = l->next;
1329 		free(l);
1330 	}
1331 }
1332 
ipaddr_filter(struct nlmsg_chain * linfo,struct nlmsg_chain * ainfo)1333 static void ipaddr_filter(struct nlmsg_chain *linfo, struct nlmsg_chain *ainfo)
1334 {
1335 	struct nlmsg_list *l, **lp;
1336 
1337 	lp = &linfo->head;
1338 	while ( (l = *lp) != NULL) {
1339 		int ok = 0;
1340 		int missing_net_address = 1;
1341 		struct ifinfomsg *ifi = NLMSG_DATA(&l->h);
1342 		struct nlmsg_list *a;
1343 
1344 		for (a = ainfo->head; a; a = a->next) {
1345 			struct nlmsghdr *n = &a->h;
1346 			struct ifaddrmsg *ifa = NLMSG_DATA(n);
1347 			struct rtattr *tb[IFA_MAX + 1];
1348 			unsigned int ifa_flags;
1349 
1350 			if (ifa->ifa_index != ifi->ifi_index)
1351 				continue;
1352 			missing_net_address = 0;
1353 			if (filter.family && filter.family != ifa->ifa_family)
1354 				continue;
1355 			if ((filter.scope^ifa->ifa_scope)&filter.scopemask)
1356 				continue;
1357 
1358 			parse_rtattr(tb, IFA_MAX, IFA_RTA(ifa), IFA_PAYLOAD(n));
1359 			ifa_flags = get_ifa_flags(ifa, tb[IFA_FLAGS]);
1360 
1361 			if ((filter.flags ^ ifa_flags) & filter.flagmask)
1362 				continue;
1363 			if (filter.pfx.family || filter.label) {
1364 				if (!tb[IFA_LOCAL])
1365 					tb[IFA_LOCAL] = tb[IFA_ADDRESS];
1366 
1367 				if (filter.pfx.family && tb[IFA_LOCAL]) {
1368 					inet_prefix dst;
1369 					memset(&dst, 0, sizeof(dst));
1370 					dst.family = ifa->ifa_family;
1371 					memcpy(&dst.data, RTA_DATA(tb[IFA_LOCAL]), RTA_PAYLOAD(tb[IFA_LOCAL]));
1372 					if (inet_addr_match(&dst, &filter.pfx, filter.pfx.bitlen))
1373 						continue;
1374 				}
1375 				if (filter.label) {
1376 					SPRINT_BUF(b1);
1377 					const char *label;
1378 					if (tb[IFA_LABEL])
1379 						label = RTA_DATA(tb[IFA_LABEL]);
1380 					else
1381 						label = ll_idx_n2a(ifa->ifa_index, b1);
1382 					if (fnmatch(filter.label, label, 0) != 0)
1383 						continue;
1384 				}
1385 			}
1386 
1387 			ok = 1;
1388 			break;
1389 		}
1390 		if (missing_net_address &&
1391 		    (filter.family == AF_UNSPEC || filter.family == AF_PACKET))
1392 			ok = 1;
1393 		if (!ok) {
1394 			*lp = l->next;
1395 			free(l);
1396 		} else
1397 			lp = &l->next;
1398 	}
1399 }
1400 
ipaddr_flush(void)1401 static int ipaddr_flush(void)
1402 {
1403 	int round = 0;
1404 	char flushb[4096-512];
1405 
1406 	filter.flushb = flushb;
1407 	filter.flushp = 0;
1408 	filter.flushe = sizeof(flushb);
1409 
1410 	while ((max_flush_loops == 0) || (round < max_flush_loops)) {
1411 		if (rtnl_wilddump_request(&rth, filter.family, RTM_GETADDR) < 0) {
1412 			perror("Cannot send dump request");
1413 			exit(1);
1414 		}
1415 		filter.flushed = 0;
1416 		if (rtnl_dump_filter_nc(&rth, print_addrinfo,
1417 					stdout, NLM_F_DUMP_INTR) < 0) {
1418 			fprintf(stderr, "Flush terminated\n");
1419 			exit(1);
1420 		}
1421 		if (filter.flushed == 0) {
1422  flush_done:
1423 			if (show_stats) {
1424 				if (round == 0)
1425 					printf("Nothing to flush.\n");
1426 				else
1427 					printf("*** Flush is complete after %d round%s ***\n", round, round>1?"s":"");
1428 			}
1429 			fflush(stdout);
1430 			return 0;
1431 		}
1432 		round++;
1433 		if (flush_update() < 0)
1434 			return 1;
1435 
1436 		if (show_stats) {
1437 			printf("\n*** Round %d, deleting %d addresses ***\n", round, filter.flushed);
1438 			fflush(stdout);
1439 		}
1440 
1441 		/* If we are flushing, and specifying primary, then we
1442 		 * want to flush only a single round.  Otherwise, we'll
1443 		 * start flushing secondaries that were promoted to
1444 		 * primaries.
1445 		 */
1446 		if (!(filter.flags & IFA_F_SECONDARY) && (filter.flagmask & IFA_F_SECONDARY))
1447 			goto flush_done;
1448 	}
1449 	fprintf(stderr, "*** Flush remains incomplete after %d rounds. ***\n", max_flush_loops);
1450 	fflush(stderr);
1451 	return 1;
1452 }
1453 
ipaddr_list_flush_or_save(int argc,char ** argv,int action)1454 static int ipaddr_list_flush_or_save(int argc, char **argv, int action)
1455 {
1456 	struct nlmsg_chain linfo = { NULL, NULL};
1457 	struct nlmsg_chain ainfo = { NULL, NULL};
1458 	struct nlmsg_list *l;
1459 	char *filter_dev = NULL;
1460 	int no_link = 0;
1461 
1462 	ipaddr_reset_filter(oneline, 0);
1463 	filter.showqueue = 1;
1464 	filter.family = preferred_family;
1465 	filter.group = -1;
1466 
1467 	if (action == IPADD_FLUSH) {
1468 		if (argc <= 0) {
1469 			fprintf(stderr, "Flush requires arguments.\n");
1470 
1471 			return -1;
1472 		}
1473 		if (filter.family == AF_PACKET) {
1474 			fprintf(stderr, "Cannot flush link addresses.\n");
1475 			return -1;
1476 		}
1477 	}
1478 
1479 	while (argc > 0) {
1480 		if (strcmp(*argv, "to") == 0) {
1481 			NEXT_ARG();
1482 			get_prefix(&filter.pfx, *argv, filter.family);
1483 			if (filter.family == AF_UNSPEC)
1484 				filter.family = filter.pfx.family;
1485 		} else if (strcmp(*argv, "scope") == 0) {
1486 			unsigned scope = 0;
1487 			NEXT_ARG();
1488 			filter.scopemask = -1;
1489 			if (rtnl_rtscope_a2n(&scope, *argv)) {
1490 				if (strcmp(*argv, "all") != 0)
1491 					invarg("invalid \"scope\"\n", *argv);
1492 				scope = RT_SCOPE_NOWHERE;
1493 				filter.scopemask = 0;
1494 			}
1495 			filter.scope = scope;
1496 		} else if (strcmp(*argv, "up") == 0) {
1497 			filter.up = 1;
1498 		} else if (strcmp(*argv, "dynamic") == 0) {
1499 			filter.flags &= ~IFA_F_PERMANENT;
1500 			filter.flagmask |= IFA_F_PERMANENT;
1501 		} else if (strcmp(*argv, "permanent") == 0) {
1502 			filter.flags |= IFA_F_PERMANENT;
1503 			filter.flagmask |= IFA_F_PERMANENT;
1504 		} else if (strcmp(*argv, "secondary") == 0 ||
1505 			   strcmp(*argv, "temporary") == 0) {
1506 			filter.flags |= IFA_F_SECONDARY;
1507 			filter.flagmask |= IFA_F_SECONDARY;
1508 		} else if (strcmp(*argv, "primary") == 0) {
1509 			filter.flags &= ~IFA_F_SECONDARY;
1510 			filter.flagmask |= IFA_F_SECONDARY;
1511 		} else if (strcmp(*argv, "tentative") == 0) {
1512 			filter.flags |= IFA_F_TENTATIVE;
1513 			filter.flagmask |= IFA_F_TENTATIVE;
1514 		} else if (strcmp(*argv, "-tentative") == 0) {
1515 			filter.flags &= ~IFA_F_TENTATIVE;
1516 			filter.flagmask |= IFA_F_TENTATIVE;
1517 		} else if (strcmp(*argv, "deprecated") == 0) {
1518 			filter.flags |= IFA_F_DEPRECATED;
1519 			filter.flagmask |= IFA_F_DEPRECATED;
1520 		} else if (strcmp(*argv, "-deprecated") == 0) {
1521 			filter.flags &= ~IFA_F_DEPRECATED;
1522 			filter.flagmask |= IFA_F_DEPRECATED;
1523 		} else if (strcmp(*argv, "home") == 0) {
1524 			filter.flags |= IFA_F_HOMEADDRESS;
1525 			filter.flagmask |= IFA_F_HOMEADDRESS;
1526 		} else if (strcmp(*argv, "nodad") == 0) {
1527 			filter.flags |= IFA_F_NODAD;
1528 			filter.flagmask |= IFA_F_NODAD;
1529 		} else if (strcmp(*argv, "mngtmpaddr") == 0) {
1530 			filter.flags |= IFA_F_MANAGETEMPADDR;
1531 			filter.flagmask |= IFA_F_MANAGETEMPADDR;
1532 		} else if (strcmp(*argv, "noprefixroute") == 0) {
1533 			filter.flags |= IFA_F_NOPREFIXROUTE;
1534 			filter.flagmask |= IFA_F_NOPREFIXROUTE;
1535 		} else if (strcmp(*argv, "autojoin") == 0) {
1536 			filter.flags |= IFA_F_MCAUTOJOIN;
1537 			filter.flagmask |= IFA_F_MCAUTOJOIN;
1538 		} else if (strcmp(*argv, "dadfailed") == 0) {
1539 			filter.flags |= IFA_F_DADFAILED;
1540 			filter.flagmask |= IFA_F_DADFAILED;
1541 		} else if (strcmp(*argv, "-dadfailed") == 0) {
1542 			filter.flags &= ~IFA_F_DADFAILED;
1543 			filter.flagmask |= IFA_F_DADFAILED;
1544 		} else if (strcmp(*argv, "label") == 0) {
1545 			NEXT_ARG();
1546 			filter.label = *argv;
1547 		} else if (strcmp(*argv, "group") == 0) {
1548 			NEXT_ARG();
1549 			if (rtnl_group_a2n(&filter.group, *argv))
1550 				invarg("Invalid \"group\" value\n", *argv);
1551 		} else if (strcmp(*argv, "master") == 0) {
1552 			int ifindex;
1553 			NEXT_ARG();
1554 			ifindex = ll_name_to_index(*argv);
1555 			if (!ifindex)
1556 				invarg("Device does not exist\n", *argv);
1557 			filter.master = ifindex;
1558 		} else if (do_link && strcmp(*argv, "type") == 0) {
1559 			NEXT_ARG();
1560 			filter.kind = *argv;
1561 		} else {
1562 			if (strcmp(*argv, "dev") == 0) {
1563 				NEXT_ARG();
1564 			}
1565 			else if (matches(*argv, "help") == 0)
1566 				usage();
1567 			if (filter_dev)
1568 				duparg2("dev", *argv);
1569 			filter_dev = *argv;
1570 		}
1571 		argv++; argc--;
1572 	}
1573 
1574 	if (filter_dev) {
1575 		filter.ifindex = ll_name_to_index(filter_dev);
1576 		if (filter.ifindex <= 0) {
1577 			fprintf(stderr, "Device \"%s\" does not exist.\n", filter_dev);
1578 			return -1;
1579 		}
1580 	}
1581 
1582 	if (action == IPADD_FLUSH)
1583 		return ipaddr_flush();
1584 
1585 	if (action == IPADD_SAVE) {
1586 		if (ipadd_save_prep())
1587 			exit(1);
1588 
1589 		if (rtnl_wilddump_request(&rth, preferred_family, RTM_GETADDR) < 0) {
1590 			perror("Cannot send dump request");
1591 			exit(1);
1592 		}
1593 
1594 		if (rtnl_dump_filter(&rth, save_nlmsg, stdout) < 0) {
1595 			fprintf(stderr, "Save terminated\n");
1596 			exit(1);
1597 		}
1598 
1599 		exit(0);
1600 	}
1601 
1602 	/*
1603 	 * If only filter_dev present and none of the other
1604 	 * link filters are present, use RTM_GETLINK to get
1605 	 * the link device
1606 	 */
1607 	if (filter_dev && filter.group == -1 && do_link == 1) {
1608 		if (iplink_get(0, filter_dev, RTEXT_FILTER_VF) < 0) {
1609 			perror("Cannot send link get request");
1610 			exit(1);
1611 		}
1612 		exit(0);
1613 	}
1614 
1615 	if (rtnl_wilddump_request(&rth, preferred_family, RTM_GETLINK) < 0) {
1616 		perror("Cannot send dump request");
1617 		exit(1);
1618 	}
1619 
1620 	if (rtnl_dump_filter(&rth, store_nlmsg, &linfo) < 0) {
1621 		fprintf(stderr, "Dump terminated\n");
1622 		exit(1);
1623 	}
1624 
1625 	if (filter.family != AF_PACKET) {
1626 		if (filter.oneline)
1627 			no_link = 1;
1628 
1629 		if (rtnl_wilddump_request(&rth, filter.family, RTM_GETADDR) < 0) {
1630 			perror("Cannot send dump request");
1631 			exit(1);
1632 		}
1633 
1634 		if (rtnl_dump_filter(&rth, store_nlmsg, &ainfo) < 0) {
1635 			fprintf(stderr, "Dump terminated\n");
1636 			exit(1);
1637 		}
1638 
1639 		ipaddr_filter(&linfo, &ainfo);
1640 	}
1641 
1642 	for (l = linfo.head; l; l = l->next) {
1643 		int res = 0;
1644 		struct ifinfomsg *ifi = NLMSG_DATA(&l->h);
1645 
1646 		if (brief) {
1647 			if (print_linkinfo_brief(NULL, &l->h, stdout) == 0)
1648 				if (filter.family != AF_PACKET)
1649 					print_selected_addrinfo(ifi,
1650 								ainfo.head,
1651 								stdout);
1652 		} else if (no_link ||
1653 			 (res = print_linkinfo(NULL, &l->h, stdout)) >= 0) {
1654 			if (filter.family != AF_PACKET)
1655 				print_selected_addrinfo(ifi,
1656 							ainfo.head, stdout);
1657 			if (res > 0 && !do_link && show_stats)
1658 				print_link_stats(stdout, &l->h);
1659 		}
1660 	}
1661 	fflush(stdout);
1662 
1663 	free_nlmsg_chain(&ainfo);
1664 	free_nlmsg_chain(&linfo);
1665 
1666 	return 0;
1667 }
1668 
1669 static void
ipaddr_loop_each_vf(struct rtattr * tb[],int vfnum,int * min,int * max)1670 ipaddr_loop_each_vf(struct rtattr *tb[], int vfnum, int *min, int *max)
1671 {
1672 	struct rtattr *vflist = tb[IFLA_VFINFO_LIST];
1673 	struct rtattr *i, *vf[IFLA_VF_MAX+1];
1674 	struct ifla_vf_rate *vf_rate;
1675 	int rem;
1676 
1677 	rem = RTA_PAYLOAD(vflist);
1678 
1679 	for (i = RTA_DATA(vflist); RTA_OK(i, rem); i = RTA_NEXT(i, rem)) {
1680 		parse_rtattr_nested(vf, IFLA_VF_MAX, i);
1681 		vf_rate = RTA_DATA(vf[IFLA_VF_RATE]);
1682 		if (vf_rate->vf == vfnum) {
1683 			*min = vf_rate->min_tx_rate;
1684 			*max = vf_rate->max_tx_rate;
1685 			return;
1686 		}
1687 	}
1688 	fprintf(stderr, "Cannot find VF %d\n", vfnum);
1689 	exit(1);
1690 }
1691 
ipaddr_get_vf_rate(int vfnum,int * min,int * max,int idx)1692 void ipaddr_get_vf_rate(int vfnum, int *min, int *max, int idx)
1693 {
1694 	struct nlmsg_chain linfo = { NULL, NULL};
1695 	struct rtattr *tb[IFLA_MAX+1];
1696 	struct ifinfomsg *ifi;
1697 	struct nlmsg_list *l;
1698 	struct nlmsghdr *n;
1699 	int len;
1700 
1701 	if (rtnl_wilddump_request(&rth, AF_UNSPEC, RTM_GETLINK) < 0) {
1702 		perror("Cannot send dump request");
1703 		exit(1);
1704 	}
1705 	if (rtnl_dump_filter(&rth, store_nlmsg, &linfo) < 0) {
1706 		fprintf(stderr, "Dump terminated\n");
1707 		exit(1);
1708 	}
1709 	for (l = linfo.head; l; l = l->next) {
1710 		n = &l->h;
1711 		ifi = NLMSG_DATA(n);
1712 
1713 		len = n->nlmsg_len - NLMSG_LENGTH(sizeof(*ifi));
1714 		if (len < 0 || (idx && idx != ifi->ifi_index))
1715 			continue;
1716 
1717 		parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
1718 
1719 		if ((tb[IFLA_VFINFO_LIST] && tb[IFLA_NUM_VF])) {
1720 			ipaddr_loop_each_vf(tb, vfnum, min, max);
1721 			return;
1722 		}
1723 	}
1724 }
1725 
ipaddr_list_link(int argc,char ** argv)1726 int ipaddr_list_link(int argc, char **argv)
1727 {
1728 	preferred_family = AF_PACKET;
1729 	do_link = 1;
1730 	return ipaddr_list_flush_or_save(argc, argv, IPADD_LIST);
1731 }
1732 
ipaddr_reset_filter(int oneline,int ifindex)1733 void ipaddr_reset_filter(int oneline, int ifindex)
1734 {
1735 	memset(&filter, 0, sizeof(filter));
1736 	filter.oneline = oneline;
1737 	filter.ifindex = ifindex;
1738 }
1739 
default_scope(inet_prefix * lcl)1740 static int default_scope(inet_prefix *lcl)
1741 {
1742 	if (lcl->family == AF_INET) {
1743 		if (lcl->bytelen >= 1 && *(__u8*)&lcl->data == 127)
1744 			return RT_SCOPE_HOST;
1745 	}
1746 	return 0;
1747 }
1748 
ipaddr_is_multicast(inet_prefix * a)1749 static bool ipaddr_is_multicast(inet_prefix *a)
1750 {
1751 	if (a->family == AF_INET)
1752 		return IN_MULTICAST(ntohl(a->data[0]));
1753 	else if (a->family == AF_INET6)
1754 		return IN6_IS_ADDR_MULTICAST(a->data);
1755 	else
1756 		return false;
1757 }
1758 
ipaddr_modify(int cmd,int flags,int argc,char ** argv)1759 static int ipaddr_modify(int cmd, int flags, int argc, char **argv)
1760 {
1761 	struct {
1762 		struct nlmsghdr	n;
1763 		struct ifaddrmsg	ifa;
1764 		char			buf[256];
1765 	} req;
1766 	char  *d = NULL;
1767 	char  *l = NULL;
1768 	char  *lcl_arg = NULL;
1769 	char  *valid_lftp = NULL;
1770 	char  *preferred_lftp = NULL;
1771 	inet_prefix lcl;
1772 	inet_prefix peer;
1773 	int local_len = 0;
1774 	int peer_len = 0;
1775 	int brd_len = 0;
1776 	int any_len = 0;
1777 	int scoped = 0;
1778 	__u32 preferred_lft = INFINITY_LIFE_TIME;
1779 	__u32 valid_lft = INFINITY_LIFE_TIME;
1780 	struct ifa_cacheinfo cinfo;
1781 	unsigned int ifa_flags = 0;
1782 
1783 	memset(&req, 0, sizeof(req));
1784 
1785 	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
1786 	req.n.nlmsg_flags = NLM_F_REQUEST | flags;
1787 	req.n.nlmsg_type = cmd;
1788 	req.ifa.ifa_family = preferred_family;
1789 
1790 	while (argc > 0) {
1791 		if (strcmp(*argv, "peer") == 0 ||
1792 		    strcmp(*argv, "remote") == 0) {
1793 			NEXT_ARG();
1794 
1795 			if (peer_len)
1796 				duparg("peer", *argv);
1797 			get_prefix(&peer, *argv, req.ifa.ifa_family);
1798 			peer_len = peer.bytelen;
1799 			if (req.ifa.ifa_family == AF_UNSPEC)
1800 				req.ifa.ifa_family = peer.family;
1801 			addattr_l(&req.n, sizeof(req), IFA_ADDRESS, &peer.data, peer.bytelen);
1802 			req.ifa.ifa_prefixlen = peer.bitlen;
1803 		} else if (matches(*argv, "broadcast") == 0 ||
1804 			   strcmp(*argv, "brd") == 0) {
1805 			inet_prefix addr;
1806 			NEXT_ARG();
1807 			if (brd_len)
1808 				duparg("broadcast", *argv);
1809 			if (strcmp(*argv, "+") == 0)
1810 				brd_len = -1;
1811 			else if (strcmp(*argv, "-") == 0)
1812 				brd_len = -2;
1813 			else {
1814 				get_addr(&addr, *argv, req.ifa.ifa_family);
1815 				if (req.ifa.ifa_family == AF_UNSPEC)
1816 					req.ifa.ifa_family = addr.family;
1817 				addattr_l(&req.n, sizeof(req), IFA_BROADCAST, &addr.data, addr.bytelen);
1818 				brd_len = addr.bytelen;
1819 			}
1820 		} else if (strcmp(*argv, "anycast") == 0) {
1821 			inet_prefix addr;
1822 			NEXT_ARG();
1823 			if (any_len)
1824 				duparg("anycast", *argv);
1825 			get_addr(&addr, *argv, req.ifa.ifa_family);
1826 			if (req.ifa.ifa_family == AF_UNSPEC)
1827 				req.ifa.ifa_family = addr.family;
1828 			addattr_l(&req.n, sizeof(req), IFA_ANYCAST, &addr.data, addr.bytelen);
1829 			any_len = addr.bytelen;
1830 		} else if (strcmp(*argv, "scope") == 0) {
1831 			unsigned scope = 0;
1832 			NEXT_ARG();
1833 			if (rtnl_rtscope_a2n(&scope, *argv))
1834 				invarg("invalid scope value.", *argv);
1835 			req.ifa.ifa_scope = scope;
1836 			scoped = 1;
1837 		} else if (strcmp(*argv, "dev") == 0) {
1838 			NEXT_ARG();
1839 			d = *argv;
1840 		} else if (strcmp(*argv, "label") == 0) {
1841 			NEXT_ARG();
1842 			l = *argv;
1843 			addattr_l(&req.n, sizeof(req), IFA_LABEL, l, strlen(l)+1);
1844 		} else if (matches(*argv, "valid_lft") == 0) {
1845 			if (valid_lftp)
1846 				duparg("valid_lft", *argv);
1847 			NEXT_ARG();
1848 			valid_lftp = *argv;
1849 			if (set_lifetime(&valid_lft, *argv))
1850 				invarg("valid_lft value", *argv);
1851 		} else if (matches(*argv, "preferred_lft") == 0) {
1852 			if (preferred_lftp)
1853 				duparg("preferred_lft", *argv);
1854 			NEXT_ARG();
1855 			preferred_lftp = *argv;
1856 			if (set_lifetime(&preferred_lft, *argv))
1857 				invarg("preferred_lft value", *argv);
1858 		} else if (strcmp(*argv, "home") == 0) {
1859 			ifa_flags |= IFA_F_HOMEADDRESS;
1860 		} else if (strcmp(*argv, "nodad") == 0) {
1861 			ifa_flags |= IFA_F_NODAD;
1862 		} else if (strcmp(*argv, "mngtmpaddr") == 0) {
1863 			ifa_flags |= IFA_F_MANAGETEMPADDR;
1864 		} else if (strcmp(*argv, "noprefixroute") == 0) {
1865 			ifa_flags |= IFA_F_NOPREFIXROUTE;
1866 		} else if (strcmp(*argv, "autojoin") == 0) {
1867 			ifa_flags |= IFA_F_MCAUTOJOIN;
1868 		} else {
1869 			if (strcmp(*argv, "local") == 0) {
1870 				NEXT_ARG();
1871 			}
1872 			if (matches(*argv, "help") == 0)
1873 				usage();
1874 			if (local_len)
1875 				duparg2("local", *argv);
1876 			lcl_arg = *argv;
1877 			get_prefix(&lcl, *argv, req.ifa.ifa_family);
1878 			if (req.ifa.ifa_family == AF_UNSPEC)
1879 				req.ifa.ifa_family = lcl.family;
1880 			addattr_l(&req.n, sizeof(req), IFA_LOCAL, &lcl.data, lcl.bytelen);
1881 			local_len = lcl.bytelen;
1882 		}
1883 		argc--; argv++;
1884 	}
1885 	if (ifa_flags <= 0xff)
1886 		req.ifa.ifa_flags = ifa_flags;
1887 	else
1888 		addattr32(&req.n, sizeof(req), IFA_FLAGS, ifa_flags);
1889 
1890 	if (d == NULL) {
1891 		fprintf(stderr, "Not enough information: \"dev\" argument is required.\n");
1892 		return -1;
1893 	}
1894 	if (l && matches(d, l) != 0) {
1895 		fprintf(stderr, "\"dev\" (%s) must match \"label\" (%s).\n", d, l);
1896 		return -1;
1897 	}
1898 
1899 	if (peer_len == 0 && local_len) {
1900 		if (cmd == RTM_DELADDR && lcl.family == AF_INET && !(lcl.flags & PREFIXLEN_SPECIFIED)) {
1901 			fprintf(stderr,
1902 			    "Warning: Executing wildcard deletion to stay compatible with old scripts.\n" \
1903 			    "         Explicitly specify the prefix length (%s/%d) to avoid this warning.\n" \
1904 			    "         This special behaviour is likely to disappear in further releases,\n" \
1905 			    "         fix your scripts!\n", lcl_arg, local_len*8);
1906 		} else {
1907 			peer = lcl;
1908 			addattr_l(&req.n, sizeof(req), IFA_ADDRESS, &lcl.data, lcl.bytelen);
1909 		}
1910 	}
1911 	if (req.ifa.ifa_prefixlen == 0)
1912 		req.ifa.ifa_prefixlen = lcl.bitlen;
1913 
1914 	if (brd_len < 0 && cmd != RTM_DELADDR) {
1915 		inet_prefix brd;
1916 		int i;
1917 		if (req.ifa.ifa_family != AF_INET) {
1918 			fprintf(stderr, "Broadcast can be set only for IPv4 addresses\n");
1919 			return -1;
1920 		}
1921 		brd = peer;
1922 		if (brd.bitlen <= 30) {
1923 			for (i = 31; i >= brd.bitlen; i--) {
1924 				if (brd_len == -1)
1925 					brd.data[0] |= htonl(1<<(31-i));
1926 				else
1927 					brd.data[0] &= ~htonl(1<<(31-i));
1928 			}
1929 			addattr_l(&req.n, sizeof(req), IFA_BROADCAST, &brd.data, brd.bytelen);
1930 			brd_len = brd.bytelen;
1931 		}
1932 	}
1933 	if (!scoped && cmd != RTM_DELADDR)
1934 		req.ifa.ifa_scope = default_scope(&lcl);
1935 
1936 	if ((req.ifa.ifa_index = ll_name_to_index(d)) == 0) {
1937 		fprintf(stderr, "Cannot find device \"%s\"\n", d);
1938 		return -1;
1939 	}
1940 
1941 	if (valid_lftp || preferred_lftp) {
1942 		if (!valid_lft) {
1943 			fprintf(stderr, "valid_lft is zero\n");
1944 			return -1;
1945 		}
1946 		if (valid_lft < preferred_lft) {
1947 			fprintf(stderr, "preferred_lft is greater than valid_lft\n");
1948 			return -1;
1949 		}
1950 
1951 		memset(&cinfo, 0, sizeof(cinfo));
1952 		cinfo.ifa_prefered = preferred_lft;
1953 		cinfo.ifa_valid = valid_lft;
1954 		addattr_l(&req.n, sizeof(req), IFA_CACHEINFO, &cinfo,
1955 			  sizeof(cinfo));
1956 	}
1957 
1958 	if ((ifa_flags & IFA_F_MCAUTOJOIN) && !ipaddr_is_multicast(&lcl)) {
1959 		fprintf(stderr, "autojoin needs multicast address\n");
1960 		return -1;
1961 	}
1962 
1963 	if (rtnl_talk(&rth, &req.n, NULL, 0) < 0)
1964 		return -2;
1965 
1966 	return 0;
1967 }
1968 
do_ipaddr(int argc,char ** argv)1969 int do_ipaddr(int argc, char **argv)
1970 {
1971 	if (argc < 1)
1972 		return ipaddr_list_flush_or_save(0, NULL, IPADD_LIST);
1973 	if (matches(*argv, "add") == 0)
1974 		return ipaddr_modify(RTM_NEWADDR, NLM_F_CREATE|NLM_F_EXCL, argc-1, argv+1);
1975 	if (matches(*argv, "change") == 0 ||
1976 		strcmp(*argv, "chg") == 0)
1977 		return ipaddr_modify(RTM_NEWADDR, NLM_F_REPLACE, argc-1, argv+1);
1978 	if (matches(*argv, "replace") == 0)
1979 		return ipaddr_modify(RTM_NEWADDR, NLM_F_CREATE|NLM_F_REPLACE, argc-1, argv+1);
1980 	if (matches(*argv, "delete") == 0)
1981 		return ipaddr_modify(RTM_DELADDR, 0, argc-1, argv+1);
1982 	if (matches(*argv, "list") == 0 || matches(*argv, "show") == 0
1983 	    || matches(*argv, "lst") == 0)
1984 		return ipaddr_list_flush_or_save(argc-1, argv+1, IPADD_LIST);
1985 	if (matches(*argv, "flush") == 0)
1986 		return ipaddr_list_flush_or_save(argc-1, argv+1, IPADD_FLUSH);
1987 	if (matches(*argv, "save") == 0)
1988 		return ipaddr_list_flush_or_save(argc-1, argv+1, IPADD_SAVE);
1989 	if (matches(*argv, "showdump") == 0)
1990 		return ipaddr_showdump();
1991 	if (matches(*argv, "restore") == 0)
1992 		return ipaddr_restore();
1993 	if (matches(*argv, "help") == 0)
1994 		usage();
1995 	fprintf(stderr, "Command \"%s\" is unknown, try \"ip address help\".\n", *argv);
1996 	exit(-1);
1997 }
1998