1dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat/*
2dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * ipaddress.c		"ip address".
3dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *
4dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *		This program is free software; you can redistribute it and/or
5dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *		modify it under the terms of the GNU General Public License
6dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *		as published by the Free Software Foundation; either version
7dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *		2 of the License, or (at your option) any later version.
8dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *
9dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * Authors:	Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
10dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *
11dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat */
12dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
13dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <stdio.h>
14dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <stdlib.h>
15dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <unistd.h>
16dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <syslog.h>
17dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <fcntl.h>
18dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <sys/ioctl.h>
19dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <sys/socket.h>
20dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <sys/ioctl.h>
21dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <sys/errno.h>
22dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <netinet/in.h>
23dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <arpa/inet.h>
24dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <string.h>
25dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <fnmatch.h>
26dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
27dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <linux/netdevice.h>
28dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <linux/if_arp.h>
29dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <linux/sockios.h>
30dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
31dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include "rt_names.h"
32dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include "utils.h"
33dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include "ll_map.h"
34dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include "ip_common.h"
35dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
36dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#define MAX_ROUNDS 10
37dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
38dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic struct
39dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{
40dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	int ifindex;
41dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	int family;
42dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	int oneline;
43dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	int showqueue;
44dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	inet_prefix pfx;
45dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	int scope, scopemask;
46dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	int flags, flagmask;
47dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	int up;
48dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	char *label;
49dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	int flushed;
50dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	char *flushb;
51dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	int flushp;
52dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	int flushe;
53dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} filter;
54dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
55dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic int do_link;
56dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
57dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic void usage(void) __attribute__((noreturn));
58dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
59dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic void usage(void)
60dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{
61dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (do_link) {
62dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		iplink_usage();
63dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	}
64dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	fprintf(stderr, "Usage: ip addr {add|change|replace} IFADDR dev STRING [ LIFETIME ]\n");
651a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt	fprintf(stderr, "                                                      [ CONFFLAG-LIST ]\n");
66dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	fprintf(stderr, "       ip addr del IFADDR dev STRING\n");
67dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	fprintf(stderr, "       ip addr {show|flush} [ dev STRING ] [ scope SCOPE-ID ]\n");
68dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	fprintf(stderr, "                            [ to PREFIX ] [ FLAG-LIST ] [ label PATTERN ]\n");
69dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	fprintf(stderr, "IFADDR := PREFIX | ADDR peer PREFIX\n");
70dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	fprintf(stderr, "          [ broadcast ADDR ] [ anycast ADDR ]\n");
71dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	fprintf(stderr, "          [ label STRING ] [ scope SCOPE-ID ]\n");
72dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	fprintf(stderr, "SCOPE-ID := [ host | link | global | NUMBER ]\n");
73dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	fprintf(stderr, "FLAG-LIST := [ FLAG-LIST ] FLAG\n");
74dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	fprintf(stderr, "FLAG  := [ permanent | dynamic | secondary | primary |\n");
751a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt	fprintf(stderr, "           tentative | deprecated | dadfailed | temporary |\n");
761a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt	fprintf(stderr, "           CONFFLAG-LIST ]\n");
77dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	fprintf(stderr, "CONFFLAG-LIST := [ CONFFLAG-LIST ] CONFFLAG\n");
78dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	fprintf(stderr, "CONFFLAG  := [ home | nodad ]\n");
79dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	fprintf(stderr, "LIFETIME := [ valid_lft LFT ] [ preferred_lft LFT ]\n");
80dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	fprintf(stderr, "LFT := forever | SECONDS\n");
81dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
82dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	exit(-1);
83dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat}
84dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
85dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatvoid print_link_flags(FILE *fp, unsigned flags, unsigned mdown)
86dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{
87dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	fprintf(fp, "<");
88dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (flags & IFF_UP && !(flags & IFF_RUNNING))
89dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(fp, "NO-CARRIER%s", flags ? "," : "");
90dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	flags &= ~IFF_RUNNING;
91dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#define _PF(f) if (flags&IFF_##f) { \
92dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat                  flags &= ~IFF_##f ; \
93dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat                  fprintf(fp, #f "%s", flags ? "," : ""); }
94dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	_PF(LOOPBACK);
95dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	_PF(BROADCAST);
96dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	_PF(POINTOPOINT);
97dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	_PF(MULTICAST);
98dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	_PF(NOARP);
99dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	_PF(ALLMULTI);
100dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	_PF(PROMISC);
101dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	_PF(MASTER);
102dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	_PF(SLAVE);
103dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	_PF(DEBUG);
104dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	_PF(DYNAMIC);
105dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	_PF(AUTOMEDIA);
106dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	_PF(PORTSEL);
107dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	_PF(NOTRAILERS);
108dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	_PF(UP);
109dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	_PF(LOWER_UP);
110dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	_PF(DORMANT);
111dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	_PF(ECHO);
112dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#undef _PF
113dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat        if (flags)
114dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(fp, "%x", flags);
115dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (mdown)
116dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(fp, ",M-DOWN");
117dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	fprintf(fp, "> ");
118dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat}
119dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
120dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic const char *oper_states[] = {
121dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	"UNKNOWN", "NOTPRESENT", "DOWN", "LOWERLAYERDOWN",
122dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	"TESTING", "DORMANT",	 "UP"
123dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat};
124dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
125dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic void print_operstate(FILE *f, __u8 state)
126dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{
127dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (state >= sizeof(oper_states)/sizeof(oper_states[0]))
128dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(f, "state %#x ", state);
129dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	else
130dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(f, "state %s ", oper_states[state]);
131dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat}
132dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
133dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic void print_queuelen(FILE *f, const char *name)
134dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{
135dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	struct ifreq ifr;
136dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	int s;
137dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
138dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	s = socket(AF_INET, SOCK_STREAM, 0);
139dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (s < 0)
140dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		return;
141dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
142dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	memset(&ifr, 0, sizeof(ifr));
143dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	strcpy(ifr.ifr_name, name);
144dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (ioctl(s, SIOCGIFTXQLEN, &ifr) < 0) {
145dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(f, "ioctl(SIOCGIFXQLEN) failed: %s\n", strerror(errno));
146dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		close(s);
147dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		return;
148dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	}
149dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	close(s);
150dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
151dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (ifr.ifr_qlen)
152dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(f, "qlen %d", ifr.ifr_qlen);
153dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat}
154dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
155dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic void print_linktype(FILE *fp, struct rtattr *tb)
156dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{
157dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	struct rtattr *linkinfo[IFLA_INFO_MAX+1];
158dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	struct link_util *lu;
159dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	char *kind;
160dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
161dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	parse_rtattr_nested(linkinfo, IFLA_INFO_MAX, tb);
162dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
163dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (!linkinfo[IFLA_INFO_KIND])
164dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		return;
165dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	kind = RTA_DATA(linkinfo[IFLA_INFO_KIND]);
166dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
167dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	fprintf(fp, "%s", _SL_);
168dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	fprintf(fp, "    %s ", kind);
169dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
170dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	lu = get_link_kind(kind);
171dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (!lu || !lu->print_opt)
172dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		return;
173dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
174dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (1) {
175dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		struct rtattr *attr[lu->maxattr+1], **data = NULL;
176dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
177dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		if (linkinfo[IFLA_INFO_DATA]) {
178dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			parse_rtattr_nested(attr, lu->maxattr,
179dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat					    linkinfo[IFLA_INFO_DATA]);
180dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			data = attr;
181dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		}
182dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		lu->print_opt(lu, fp, data);
183dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
184dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		if (linkinfo[IFLA_INFO_XSTATS] && show_stats &&
185dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		    lu->print_xstats)
186dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			lu->print_xstats(lu, fp, linkinfo[IFLA_INFO_XSTATS]);
187dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	}
188dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat}
189dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
1901a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidtstatic void print_vfinfo(FILE *fp, struct rtattr *vfinfo)
1911a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt{
1921a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt	struct ifla_vf_mac *vf_mac;
1931a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt	struct ifla_vf_vlan *vf_vlan;
1941a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt	struct ifla_vf_tx_rate *vf_tx_rate;
1951a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt	struct rtattr *vf[IFLA_VF_MAX+1];
1961a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt	SPRINT_BUF(b1);
1971a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt
1981a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt	if (vfinfo->rta_type != IFLA_VF_INFO) {
1991a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt		fprintf(stderr, "BUG: rta type is %d\n", vfinfo->rta_type);
2001a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt		return;
2011a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt	}
2021a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt
2031a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt	parse_rtattr_nested(vf, IFLA_VF_MAX, vfinfo);
2041a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt
2051a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt	vf_mac = RTA_DATA(vf[IFLA_VF_MAC]);
2061a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt	vf_vlan = RTA_DATA(vf[IFLA_VF_VLAN]);
2071a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt	vf_tx_rate = RTA_DATA(vf[IFLA_VF_TX_RATE]);
2081a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt
2091a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt	fprintf(fp, "\n    vf %d MAC %s", vf_mac->vf,
2101a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt		ll_addr_n2a((unsigned char *)&vf_mac->mac,
2111a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt		ETH_ALEN, 0, b1, sizeof(b1)));
2121a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt	if (vf_vlan->vlan)
2131a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt		fprintf(fp, ", vlan %d", vf_vlan->vlan);
2141a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt	if (vf_vlan->qos)
2151a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt		fprintf(fp, ", qos %d", vf_vlan->qos);
2161a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt	if (vf_tx_rate->rate)
2171a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt		fprintf(fp, ", tx rate %d (Mbps)", vf_tx_rate->rate);
2181a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt}
2191a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt
220dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint print_linkinfo(const struct sockaddr_nl *who,
221dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		   struct nlmsghdr *n, void *arg)
222dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{
223dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	FILE *fp = (FILE*)arg;
224dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	struct ifinfomsg *ifi = NLMSG_DATA(n);
225dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	struct rtattr * tb[IFLA_MAX+1];
226dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	int len = n->nlmsg_len;
227dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	unsigned m_flag = 0;
228dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
229dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (n->nlmsg_type != RTM_NEWLINK && n->nlmsg_type != RTM_DELLINK)
230dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		return 0;
231dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
232dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	len -= NLMSG_LENGTH(sizeof(*ifi));
233dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (len < 0)
234dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		return -1;
235dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
236dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (filter.ifindex && ifi->ifi_index != filter.ifindex)
237dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		return 0;
238dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (filter.up && !(ifi->ifi_flags&IFF_UP))
239dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		return 0;
240dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
241dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
242dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (tb[IFLA_IFNAME] == NULL) {
243dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(stderr, "BUG: device with ifindex %d has nil ifname\n", ifi->ifi_index);
244dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	}
245dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (filter.label &&
246dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	    (!filter.family || filter.family == AF_PACKET) &&
247dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	    fnmatch(filter.label, RTA_DATA(tb[IFLA_IFNAME]), 0))
248dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		return 0;
249dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
250dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (n->nlmsg_type == RTM_DELLINK)
251dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(fp, "Deleted ");
252dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
253dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	fprintf(fp, "%d: %s", ifi->ifi_index,
254dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		tb[IFLA_IFNAME] ? (char*)RTA_DATA(tb[IFLA_IFNAME]) : "<nil>");
255dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
256dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (tb[IFLA_LINK]) {
257dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		SPRINT_BUF(b1);
258dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		int iflink = *(int*)RTA_DATA(tb[IFLA_LINK]);
259dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		if (iflink == 0)
260dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			fprintf(fp, "@NONE: ");
261dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		else {
262dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			fprintf(fp, "@%s: ", ll_idx_n2a(iflink, b1));
263dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			m_flag = ll_index_to_flags(iflink);
264dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			m_flag = !(m_flag & IFF_UP);
265dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		}
266dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	} else {
267dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(fp, ": ");
268dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	}
269dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	print_link_flags(fp, ifi->ifi_flags, m_flag);
270dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
271dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (tb[IFLA_MTU])
272dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(fp, "mtu %u ", *(int*)RTA_DATA(tb[IFLA_MTU]));
273dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (tb[IFLA_QDISC])
274dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(fp, "qdisc %s ", (char*)RTA_DATA(tb[IFLA_QDISC]));
275dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#ifdef IFLA_MASTER
276dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (tb[IFLA_MASTER]) {
277dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		SPRINT_BUF(b1);
278dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(fp, "master %s ", ll_idx_n2a(*(int*)RTA_DATA(tb[IFLA_MASTER]), b1));
279dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	}
280dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#endif
281dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (tb[IFLA_OPERSTATE])
282dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		print_operstate(fp, *(__u8 *)RTA_DATA(tb[IFLA_OPERSTATE]));
283dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
284dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (filter.showqueue)
285dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		print_queuelen(fp, (char*)RTA_DATA(tb[IFLA_IFNAME]));
286dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
287dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (!filter.family || filter.family == AF_PACKET) {
288dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		SPRINT_BUF(b1);
289dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(fp, "%s", _SL_);
290dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(fp, "    link/%s ", ll_type_n2a(ifi->ifi_type, b1, sizeof(b1)));
291dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
292dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		if (tb[IFLA_ADDRESS]) {
293dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			fprintf(fp, "%s", ll_addr_n2a(RTA_DATA(tb[IFLA_ADDRESS]),
294dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat						      RTA_PAYLOAD(tb[IFLA_ADDRESS]),
295dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat						      ifi->ifi_type,
296dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat						      b1, sizeof(b1)));
297dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		}
298dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		if (tb[IFLA_BROADCAST]) {
299dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			if (ifi->ifi_flags&IFF_POINTOPOINT)
300dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				fprintf(fp, " peer ");
301dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			else
302dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				fprintf(fp, " brd ");
303dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			fprintf(fp, "%s", ll_addr_n2a(RTA_DATA(tb[IFLA_BROADCAST]),
304dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat						      RTA_PAYLOAD(tb[IFLA_BROADCAST]),
305dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat						      ifi->ifi_type,
306dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat						      b1, sizeof(b1)));
307dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		}
308dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	}
309dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
310dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (do_link && tb[IFLA_LINKINFO] && show_details)
311dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		print_linktype(fp, tb[IFLA_LINKINFO]);
312dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
313dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (do_link && tb[IFLA_IFALIAS])
314dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(fp,"\n    alias %s",
315dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			(const char *) RTA_DATA(tb[IFLA_IFALIAS]));
316dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
3171a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt	if (do_link && tb[IFLA_STATS64] && show_stats) {
3181a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt		struct rtnl_link_stats64 slocal;
3191a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt		struct rtnl_link_stats64 *s = RTA_DATA(tb[IFLA_STATS64]);
3201a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt		if (((unsigned long)s) & (sizeof(unsigned long)-1)) {
3211a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt			memcpy(&slocal, s, sizeof(slocal));
3221a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt			s = &slocal;
3231a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt		}
3241a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt		fprintf(fp, "%s", _SL_);
3251a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt		fprintf(fp, "    RX: bytes  packets  errors  dropped overrun mcast   %s%s",
3261a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt			s->rx_compressed ? "compressed" : "", _SL_);
3271a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt		fprintf(fp, "    %-10llu %-8llu %-7llu %-7llu %-7llu %-7llu",
3281a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt			(unsigned long long)s->rx_bytes,
3291a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt			(unsigned long long)s->rx_packets,
3301a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt			(unsigned long long)s->rx_errors,
3311a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt			(unsigned long long)s->rx_dropped,
3321a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt			(unsigned long long)s->rx_over_errors,
3331a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt			(unsigned long long)s->multicast);
3341a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt		if (s->rx_compressed)
3351a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt			fprintf(fp, " %-7llu",
3361a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt				(unsigned long long)s->rx_compressed);
3371a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt		if (show_stats > 1) {
3381a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt			fprintf(fp, "%s", _SL_);
3391a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt			fprintf(fp, "    RX errors: length  crc     frame   fifo    missed%s", _SL_);
3401a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt			fprintf(fp, "               %-7llu  %-7llu %-7llu %-7llu %-7llu",
3411a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt				(unsigned long long)s->rx_length_errors,
3421a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt				(unsigned long long)s->rx_crc_errors,
3431a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt				(unsigned long long)s->rx_frame_errors,
3441a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt				(unsigned long long)s->rx_fifo_errors,
3451a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt				(unsigned long long)s->rx_missed_errors);
3461a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt		}
3471a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt		fprintf(fp, "%s", _SL_);
3481a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt		fprintf(fp, "    TX: bytes  packets  errors  dropped carrier collsns %s%s",
3491a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt			s->tx_compressed ? "compressed" : "", _SL_);
3501a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt		fprintf(fp, "    %-10llu %-8llu %-7llu %-7llu %-7llu %-7llu",
3511a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt			(unsigned long long)s->tx_bytes,
3521a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt			(unsigned long long)s->tx_packets,
3531a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt			(unsigned long long)s->tx_errors,
3541a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt			(unsigned long long)s->tx_dropped,
3551a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt			(unsigned long long)s->tx_carrier_errors,
3561a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt			(unsigned long long)s->collisions);
3571a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt		if (s->tx_compressed)
3581a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt			fprintf(fp, " %-7llu",
3591a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt				(unsigned long long)s->tx_compressed);
3601a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt		if (show_stats > 1) {
3611a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt			fprintf(fp, "%s", _SL_);
3621a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt			fprintf(fp, "    TX errors: aborted fifo    window  heartbeat%s", _SL_);
3631a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt			fprintf(fp, "               %-7llu  %-7llu %-7llu %-7llu",
3641a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt				(unsigned long long)s->tx_aborted_errors,
3651a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt				(unsigned long long)s->tx_fifo_errors,
3661a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt				(unsigned long long)s->tx_window_errors,
3671a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt				(unsigned long long)s->tx_heartbeat_errors);
3681a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt		}
3691a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt	}
3701a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt	if (do_link && !tb[IFLA_STATS64] && tb[IFLA_STATS] && show_stats) {
371dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		struct rtnl_link_stats slocal;
372dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		struct rtnl_link_stats *s = RTA_DATA(tb[IFLA_STATS]);
373dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		if (((unsigned long)s) & (sizeof(unsigned long)-1)) {
374dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			memcpy(&slocal, s, sizeof(slocal));
375dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			s = &slocal;
376dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		}
377dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(fp, "%s", _SL_);
378dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(fp, "    RX: bytes  packets  errors  dropped overrun mcast   %s%s",
379dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			s->rx_compressed ? "compressed" : "", _SL_);
380dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(fp, "    %-10u %-8u %-7u %-7u %-7u %-7u",
381dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			s->rx_bytes, s->rx_packets, s->rx_errors,
382dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			s->rx_dropped, s->rx_over_errors,
383dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			s->multicast
384dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			);
385dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		if (s->rx_compressed)
386dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			fprintf(fp, " %-7u", s->rx_compressed);
387dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		if (show_stats > 1) {
388dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			fprintf(fp, "%s", _SL_);
389dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			fprintf(fp, "    RX errors: length  crc     frame   fifo    missed%s", _SL_);
390dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			fprintf(fp, "               %-7u  %-7u %-7u %-7u %-7u",
391dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				s->rx_length_errors,
392dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				s->rx_crc_errors,
393dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				s->rx_frame_errors,
394dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				s->rx_fifo_errors,
395dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				s->rx_missed_errors
396dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				);
397dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		}
398dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(fp, "%s", _SL_);
399dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(fp, "    TX: bytes  packets  errors  dropped carrier collsns %s%s",
400dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			s->tx_compressed ? "compressed" : "", _SL_);
401dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(fp, "    %-10u %-8u %-7u %-7u %-7u %-7u",
402dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			s->tx_bytes, s->tx_packets, s->tx_errors,
403dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			s->tx_dropped, s->tx_carrier_errors, s->collisions);
404dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		if (s->tx_compressed)
405dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			fprintf(fp, " %-7u", s->tx_compressed);
406dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		if (show_stats > 1) {
407dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			fprintf(fp, "%s", _SL_);
408dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			fprintf(fp, "    TX errors: aborted fifo    window  heartbeat%s", _SL_);
409dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			fprintf(fp, "               %-7u  %-7u %-7u %-7u",
410dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				s->tx_aborted_errors,
411dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				s->tx_fifo_errors,
412dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				s->tx_window_errors,
413dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				s->tx_heartbeat_errors
414dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				);
415dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		}
416dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	}
4171a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt	if (do_link && tb[IFLA_VFINFO_LIST] && tb[IFLA_NUM_VF]) {
4181a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt		struct rtattr *i, *vflist = tb[IFLA_VFINFO_LIST];
4191a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt		int rem = RTA_PAYLOAD(vflist);
4201a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt		for (i = RTA_DATA(vflist); RTA_OK(i, rem); i = RTA_NEXT(i, rem))
4211a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt			print_vfinfo(fp, i);
4221a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt	}
4231a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt
424dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	fprintf(fp, "\n");
425dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	fflush(fp);
426dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	return 0;
427dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat}
428dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
429dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic int flush_update(void)
430dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{
431dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (rtnl_send_check(&rth, filter.flushb, filter.flushp) < 0) {
432dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		perror("Failed to send flush request");
433dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		return -1;
434dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	}
435dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	filter.flushp = 0;
436dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	return 0;
437dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat}
438dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
439dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic int set_lifetime(unsigned int *lifetime, char *argv)
440dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{
441dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (strcmp(argv, "forever") == 0)
442dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		*lifetime = INFINITY_LIFE_TIME;
443dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	else if (get_u32(lifetime, argv, 0))
444dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		return -1;
445dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
446dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	return 0;
447dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat}
448dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
449dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n,
450dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		   void *arg)
451dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{
452dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	FILE *fp = (FILE*)arg;
453dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	struct ifaddrmsg *ifa = NLMSG_DATA(n);
454dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	int len = n->nlmsg_len;
455dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	int deprecated = 0;
456dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	struct rtattr * rta_tb[IFA_MAX+1];
457dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	char abuf[256];
458dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	SPRINT_BUF(b1);
459dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
460dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (n->nlmsg_type != RTM_NEWADDR && n->nlmsg_type != RTM_DELADDR)
461dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		return 0;
462dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	len -= NLMSG_LENGTH(sizeof(*ifa));
463dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (len < 0) {
464dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
465dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		return -1;
466dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	}
467dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
468dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (filter.flushb && n->nlmsg_type != RTM_NEWADDR)
469dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		return 0;
470dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
471dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	parse_rtattr(rta_tb, IFA_MAX, IFA_RTA(ifa), n->nlmsg_len - NLMSG_LENGTH(sizeof(*ifa)));
472dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
473dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (!rta_tb[IFA_LOCAL])
474dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		rta_tb[IFA_LOCAL] = rta_tb[IFA_ADDRESS];
475dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (!rta_tb[IFA_ADDRESS])
476dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		rta_tb[IFA_ADDRESS] = rta_tb[IFA_LOCAL];
477dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
478dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (filter.ifindex && filter.ifindex != ifa->ifa_index)
479dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		return 0;
480dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if ((filter.scope^ifa->ifa_scope)&filter.scopemask)
481dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		return 0;
482dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if ((filter.flags^ifa->ifa_flags)&filter.flagmask)
483dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		return 0;
484dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (filter.label) {
485dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		SPRINT_BUF(b1);
486dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		const char *label;
487dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		if (rta_tb[IFA_LABEL])
488dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			label = RTA_DATA(rta_tb[IFA_LABEL]);
489dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		else
490dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			label = ll_idx_n2a(ifa->ifa_index, b1);
491dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		if (fnmatch(filter.label, label, 0) != 0)
492dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			return 0;
493dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	}
494dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (filter.pfx.family) {
495dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		if (rta_tb[IFA_LOCAL]) {
496dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			inet_prefix dst;
497dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			memset(&dst, 0, sizeof(dst));
498dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			dst.family = ifa->ifa_family;
499dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			memcpy(&dst.data, RTA_DATA(rta_tb[IFA_LOCAL]), RTA_PAYLOAD(rta_tb[IFA_LOCAL]));
500dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			if (inet_addr_match(&dst, &filter.pfx, filter.pfx.bitlen))
501dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				return 0;
502dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		}
503dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	}
504dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
505dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (filter.family && filter.family != ifa->ifa_family)
506dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		return 0;
507dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
508dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (filter.flushb) {
509dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		struct nlmsghdr *fn;
510dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		if (NLMSG_ALIGN(filter.flushp) + n->nlmsg_len > filter.flushe) {
511dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			if (flush_update())
512dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				return -1;
513dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		}
514dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fn = (struct nlmsghdr*)(filter.flushb + NLMSG_ALIGN(filter.flushp));
515dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		memcpy(fn, n, n->nlmsg_len);
516dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fn->nlmsg_type = RTM_DELADDR;
517dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fn->nlmsg_flags = NLM_F_REQUEST;
518dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fn->nlmsg_seq = ++rth.seq;
519dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		filter.flushp = (((char*)fn) + n->nlmsg_len) - filter.flushb;
520dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		filter.flushed++;
521dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		if (show_stats < 2)
522dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			return 0;
523dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	}
524dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
525dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (n->nlmsg_type == RTM_DELADDR)
526dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(fp, "Deleted ");
527dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
528dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (filter.oneline || filter.flushb)
529dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(fp, "%u: %s", ifa->ifa_index, ll_index_to_name(ifa->ifa_index));
530dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (ifa->ifa_family == AF_INET)
531dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(fp, "    inet ");
532dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	else if (ifa->ifa_family == AF_INET6)
533dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(fp, "    inet6 ");
534dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	else if (ifa->ifa_family == AF_DECnet)
535dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(fp, "    dnet ");
536dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	else if (ifa->ifa_family == AF_IPX)
537dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(fp, "     ipx ");
538dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	else
539dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(fp, "    family %d ", ifa->ifa_family);
540dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
541dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (rta_tb[IFA_LOCAL]) {
542dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(fp, "%s", rt_addr_n2a(ifa->ifa_family,
543dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat					      RTA_PAYLOAD(rta_tb[IFA_LOCAL]),
544dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat					      RTA_DATA(rta_tb[IFA_LOCAL]),
545dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat					      abuf, sizeof(abuf)));
546dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
547dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		if (rta_tb[IFA_ADDRESS] == NULL ||
548dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		    memcmp(RTA_DATA(rta_tb[IFA_ADDRESS]), RTA_DATA(rta_tb[IFA_LOCAL]), 4) == 0) {
549dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			fprintf(fp, "/%d ", ifa->ifa_prefixlen);
550dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		} else {
551dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			fprintf(fp, " peer %s/%d ",
552dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				rt_addr_n2a(ifa->ifa_family,
553dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat					    RTA_PAYLOAD(rta_tb[IFA_ADDRESS]),
554dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat					    RTA_DATA(rta_tb[IFA_ADDRESS]),
555dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat					    abuf, sizeof(abuf)),
556dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				ifa->ifa_prefixlen);
557dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		}
558dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	}
559dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
560dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (rta_tb[IFA_BROADCAST]) {
561dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(fp, "brd %s ",
562dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			rt_addr_n2a(ifa->ifa_family,
563dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				    RTA_PAYLOAD(rta_tb[IFA_BROADCAST]),
564dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				    RTA_DATA(rta_tb[IFA_BROADCAST]),
565dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				    abuf, sizeof(abuf)));
566dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	}
567dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (rta_tb[IFA_ANYCAST]) {
568dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(fp, "any %s ",
569dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			rt_addr_n2a(ifa->ifa_family,
570dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				    RTA_PAYLOAD(rta_tb[IFA_ANYCAST]),
571dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				    RTA_DATA(rta_tb[IFA_ANYCAST]),
572dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				    abuf, sizeof(abuf)));
573dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	}
574dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	fprintf(fp, "scope %s ", rtnl_rtscope_n2a(ifa->ifa_scope, b1, sizeof(b1)));
575dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (ifa->ifa_flags&IFA_F_SECONDARY) {
576dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		ifa->ifa_flags &= ~IFA_F_SECONDARY;
5771a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt		if (ifa->ifa_family == AF_INET6)
5781a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt			fprintf(fp, "temporary ");
5791a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt		else
5801a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt			fprintf(fp, "secondary ");
581dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	}
582dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (ifa->ifa_flags&IFA_F_TENTATIVE) {
583dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		ifa->ifa_flags &= ~IFA_F_TENTATIVE;
584dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(fp, "tentative ");
585dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	}
586dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (ifa->ifa_flags&IFA_F_DEPRECATED) {
587dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		ifa->ifa_flags &= ~IFA_F_DEPRECATED;
588dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		deprecated = 1;
589dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(fp, "deprecated ");
590dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	}
591dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (ifa->ifa_flags&IFA_F_HOMEADDRESS) {
592dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		ifa->ifa_flags &= ~IFA_F_HOMEADDRESS;
593dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(fp, "home ");
594dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	}
595dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (ifa->ifa_flags&IFA_F_NODAD) {
596dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		ifa->ifa_flags &= ~IFA_F_NODAD;
597dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(fp, "nodad ");
598dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	}
599dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (!(ifa->ifa_flags&IFA_F_PERMANENT)) {
600dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(fp, "dynamic ");
601dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	} else
602dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		ifa->ifa_flags &= ~IFA_F_PERMANENT;
603dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (ifa->ifa_flags&IFA_F_DADFAILED) {
604dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		ifa->ifa_flags &= ~IFA_F_DADFAILED;
605dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(fp, "dadfailed ");
606dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	}
607dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (ifa->ifa_flags)
608dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(fp, "flags %02x ", ifa->ifa_flags);
609dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (rta_tb[IFA_LABEL])
610dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(fp, "%s", (char*)RTA_DATA(rta_tb[IFA_LABEL]));
611dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (rta_tb[IFA_CACHEINFO]) {
612dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		struct ifa_cacheinfo *ci = RTA_DATA(rta_tb[IFA_CACHEINFO]);
613dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		char buf[128];
614dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(fp, "%s", _SL_);
615dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		if (ci->ifa_valid == INFINITY_LIFE_TIME)
616dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			sprintf(buf, "valid_lft forever");
617dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		else
618dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			sprintf(buf, "valid_lft %usec", ci->ifa_valid);
619dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		if (ci->ifa_prefered == INFINITY_LIFE_TIME)
620dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			sprintf(buf+strlen(buf), " preferred_lft forever");
621dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		else {
622dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			if (deprecated)
623dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				sprintf(buf+strlen(buf), " preferred_lft %dsec",
624dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat					ci->ifa_prefered);
625dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			else
626dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				sprintf(buf+strlen(buf), " preferred_lft %usec",
627dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat					ci->ifa_prefered);
628dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		}
629dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(fp, "       %s", buf);
630dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	}
631dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	fprintf(fp, "\n");
632dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	fflush(fp);
633dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	return 0;
634dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat}
635dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
636dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint print_addrinfo_primary(const struct sockaddr_nl *who, struct nlmsghdr *n,
637dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			   void *arg)
638dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{
639dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	struct ifaddrmsg *ifa = NLMSG_DATA(n);
640dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
641dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (!ifa->ifa_flags & IFA_F_SECONDARY)
642dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		return 0;
643dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
644dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	return print_addrinfo(who, n, arg);
645dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat}
646dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
647dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint print_addrinfo_secondary(const struct sockaddr_nl *who, struct nlmsghdr *n,
648dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			     void *arg)
649dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{
650dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	struct ifaddrmsg *ifa = NLMSG_DATA(n);
651dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
652dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (ifa->ifa_flags & IFA_F_SECONDARY)
653dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		return 0;
654dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
655dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	return print_addrinfo(who, n, arg);
656dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat}
657dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
658dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstruct nlmsg_list
659dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{
660dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	struct nlmsg_list *next;
661dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	struct nlmsghdr	  h;
662dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat};
663dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
664dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic int print_selected_addrinfo(int ifindex, struct nlmsg_list *ainfo, FILE *fp)
665dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{
666dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	for ( ;ainfo ;  ainfo = ainfo->next) {
667dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		struct nlmsghdr *n = &ainfo->h;
668dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		struct ifaddrmsg *ifa = NLMSG_DATA(n);
669dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
670dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		if (n->nlmsg_type != RTM_NEWADDR)
671dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			continue;
672dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
673dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		if (n->nlmsg_len < NLMSG_LENGTH(sizeof(ifa)))
674dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			return -1;
675dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
676dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		if (ifa->ifa_index != ifindex ||
677dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		    (filter.family && filter.family != ifa->ifa_family))
678dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			continue;
679dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
680dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		print_addrinfo(NULL, n, fp);
681dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	}
682dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	return 0;
683dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat}
684dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
685dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
686dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic int store_nlmsg(const struct sockaddr_nl *who, struct nlmsghdr *n,
687dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		       void *arg)
688dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{
689dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	struct nlmsg_list **linfo = (struct nlmsg_list**)arg;
690dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	struct nlmsg_list *h;
691dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	struct nlmsg_list **lp;
692dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
693dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	h = malloc(n->nlmsg_len+sizeof(void*));
694dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (h == NULL)
695dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		return -1;
696dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
697dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	memcpy(&h->h, n, n->nlmsg_len);
698dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	h->next = NULL;
699dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
700dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	for (lp = linfo; *lp; lp = &(*lp)->next) /* NOTHING */;
701dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	*lp = h;
702dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
703dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	ll_remember_index(who, n, NULL);
704dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	return 0;
705dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat}
706dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
707dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic int ipaddr_list_or_flush(int argc, char **argv, int flush)
708dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{
709dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	struct nlmsg_list *linfo = NULL;
710dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	struct nlmsg_list *ainfo = NULL;
711dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	struct nlmsg_list *l, *n;
712dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	char *filter_dev = NULL;
713dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	int no_link = 0;
714dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
715dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	ipaddr_reset_filter(oneline);
716dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	filter.showqueue = 1;
717dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
718dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (filter.family == AF_UNSPEC)
719dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		filter.family = preferred_family;
720dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
721dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (flush) {
722dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		if (argc <= 0) {
723dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			fprintf(stderr, "Flush requires arguments.\n");
724dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			return -1;
725dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		}
726dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		if (filter.family == AF_PACKET) {
727dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			fprintf(stderr, "Cannot flush link addresses.\n");
728dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			return -1;
729dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		}
730dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	}
731dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
732dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	while (argc > 0) {
733dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		if (strcmp(*argv, "to") == 0) {
734dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			NEXT_ARG();
735dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			get_prefix(&filter.pfx, *argv, filter.family);
736dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			if (filter.family == AF_UNSPEC)
737dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				filter.family = filter.pfx.family;
738dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		} else if (strcmp(*argv, "scope") == 0) {
739dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			unsigned scope = 0;
740dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			NEXT_ARG();
741dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			filter.scopemask = -1;
742dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			if (rtnl_rtscope_a2n(&scope, *argv)) {
743dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				if (strcmp(*argv, "all") != 0)
744dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat					invarg("invalid \"scope\"\n", *argv);
745dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				scope = RT_SCOPE_NOWHERE;
746dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				filter.scopemask = 0;
747dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			}
748dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			filter.scope = scope;
749dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		} else if (strcmp(*argv, "up") == 0) {
750dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			filter.up = 1;
751dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		} else if (strcmp(*argv, "dynamic") == 0) {
752dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			filter.flags &= ~IFA_F_PERMANENT;
753dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			filter.flagmask |= IFA_F_PERMANENT;
754dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		} else if (strcmp(*argv, "permanent") == 0) {
755dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			filter.flags |= IFA_F_PERMANENT;
756dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			filter.flagmask |= IFA_F_PERMANENT;
7571a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt		} else if (strcmp(*argv, "secondary") == 0 ||
7581a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt			   strcmp(*argv, "temporary") == 0) {
759dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			filter.flags |= IFA_F_SECONDARY;
760dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			filter.flagmask |= IFA_F_SECONDARY;
761dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		} else if (strcmp(*argv, "primary") == 0) {
762dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			filter.flags &= ~IFA_F_SECONDARY;
763dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			filter.flagmask |= IFA_F_SECONDARY;
764dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		} else if (strcmp(*argv, "tentative") == 0) {
765dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			filter.flags |= IFA_F_TENTATIVE;
766dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			filter.flagmask |= IFA_F_TENTATIVE;
767dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		} else if (strcmp(*argv, "deprecated") == 0) {
768dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			filter.flags |= IFA_F_DEPRECATED;
769dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			filter.flagmask |= IFA_F_DEPRECATED;
770dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		} else if (strcmp(*argv, "home") == 0) {
771dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			filter.flags |= IFA_F_HOMEADDRESS;
772dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			filter.flagmask |= IFA_F_HOMEADDRESS;
773dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		} else if (strcmp(*argv, "nodad") == 0) {
774dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			filter.flags |= IFA_F_NODAD;
775dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			filter.flagmask |= IFA_F_NODAD;
7761a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt		} else if (strcmp(*argv, "dadfailed") == 0) {
7771a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt			filter.flags |= IFA_F_DADFAILED;
7781a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt			filter.flagmask |= IFA_F_DADFAILED;
779dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		} else if (strcmp(*argv, "label") == 0) {
780dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			NEXT_ARG();
781dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			filter.label = *argv;
782dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		} else {
783dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			if (strcmp(*argv, "dev") == 0) {
784dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				NEXT_ARG();
785dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			}
786dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			if (matches(*argv, "help") == 0)
787dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				usage();
788dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			if (filter_dev)
789dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				duparg2("dev", *argv);
790dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			filter_dev = *argv;
791dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		}
792dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		argv++; argc--;
793dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	}
794dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
795dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (rtnl_wilddump_request(&rth, preferred_family, RTM_GETLINK) < 0) {
796dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		perror("Cannot send dump request");
797dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		exit(1);
798dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	}
799dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
800dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (rtnl_dump_filter(&rth, store_nlmsg, &linfo, NULL, NULL) < 0) {
801dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(stderr, "Dump terminated\n");
802dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		exit(1);
803dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	}
804dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
805dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (filter_dev) {
806dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		filter.ifindex = ll_name_to_index(filter_dev);
807dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		if (filter.ifindex <= 0) {
808dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			fprintf(stderr, "Device \"%s\" does not exist.\n", filter_dev);
809dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			return -1;
810dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		}
811dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	}
812dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
813dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (flush) {
814dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		int round = 0;
815dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		char flushb[4096-512];
816dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
817dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		filter.flushb = flushb;
818dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		filter.flushp = 0;
819dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		filter.flushe = sizeof(flushb);
820dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
821dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		while (round < MAX_ROUNDS) {
822dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			const struct rtnl_dump_filter_arg a[3] = {
823dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				{
824dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat					.filter = print_addrinfo_secondary,
825dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat					.arg1 = stdout,
826dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat					.junk = NULL,
827dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat					.arg2 = NULL
828dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				},
829dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				{
830dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat					.filter = print_addrinfo_primary,
831dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat					.arg1 = stdout,
832dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat					.junk = NULL,
833dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat					.arg2 = NULL
834dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				},
835dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				{
836dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat					.filter = NULL,
837dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat					.arg1 = NULL,
838dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat					.junk = NULL,
839dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat					.arg2 = NULL
840dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				},
841dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			};
842dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			if (rtnl_wilddump_request(&rth, filter.family, RTM_GETADDR) < 0) {
843dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				perror("Cannot send dump request");
844dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				exit(1);
845dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			}
846dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			filter.flushed = 0;
847dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			if (rtnl_dump_filter_l(&rth, a) < 0) {
848dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				fprintf(stderr, "Flush terminated\n");
849dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				exit(1);
850dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			}
851dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			if (filter.flushed == 0) {
852dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				if (show_stats) {
853dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat					if (round == 0)
854dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat						printf("Nothing to flush.\n");
855dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat					else
856dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat						printf("*** Flush is complete after %d round%s ***\n", round, round>1?"s":"");
857dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				}
858dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				fflush(stdout);
859dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				return 0;
860dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			}
861dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			round++;
862dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			if (flush_update() < 0)
863dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				return 1;
864dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
865dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			if (show_stats) {
866dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				printf("\n*** Round %d, deleting %d addresses ***\n", round, filter.flushed);
867dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				fflush(stdout);
868dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			}
869dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		}
870dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(stderr, "*** Flush remains incomplete after %d rounds. ***\n", MAX_ROUNDS); fflush(stderr);
871dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		return 1;
872dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	}
873dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
874dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (filter.family != AF_PACKET) {
875dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		if (rtnl_wilddump_request(&rth, filter.family, RTM_GETADDR) < 0) {
876dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			perror("Cannot send dump request");
877dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			exit(1);
878dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		}
879dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
880dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		if (rtnl_dump_filter(&rth, store_nlmsg, &ainfo, NULL, NULL) < 0) {
881dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			fprintf(stderr, "Dump terminated\n");
882dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			exit(1);
883dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		}
884dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	}
885dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
886dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
887dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (filter.family && filter.family != AF_PACKET) {
888dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		struct nlmsg_list **lp;
889dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		lp=&linfo;
890dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
891dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		if (filter.oneline)
892dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			no_link = 1;
893dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
894dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		while ((l=*lp)!=NULL) {
895dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			int ok = 0;
896dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			struct ifinfomsg *ifi = NLMSG_DATA(&l->h);
897dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			struct nlmsg_list *a;
898dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
899dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			for (a=ainfo; a; a=a->next) {
900dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				struct nlmsghdr *n = &a->h;
901dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				struct ifaddrmsg *ifa = NLMSG_DATA(n);
902dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
903dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				if (ifa->ifa_index != ifi->ifi_index ||
904dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				    (filter.family && filter.family != ifa->ifa_family))
905dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat					continue;
906dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				if ((filter.scope^ifa->ifa_scope)&filter.scopemask)
907dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat					continue;
908dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				if ((filter.flags^ifa->ifa_flags)&filter.flagmask)
909dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat					continue;
910dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				if (filter.pfx.family || filter.label) {
911dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat					struct rtattr *tb[IFA_MAX+1];
912dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat					parse_rtattr(tb, IFA_MAX, IFA_RTA(ifa), IFA_PAYLOAD(n));
913dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat					if (!tb[IFA_LOCAL])
914dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat						tb[IFA_LOCAL] = tb[IFA_ADDRESS];
915dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
916dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat					if (filter.pfx.family && tb[IFA_LOCAL]) {
917dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat						inet_prefix dst;
918dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat						memset(&dst, 0, sizeof(dst));
919dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat						dst.family = ifa->ifa_family;
920dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat						memcpy(&dst.data, RTA_DATA(tb[IFA_LOCAL]), RTA_PAYLOAD(tb[IFA_LOCAL]));
921dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat						if (inet_addr_match(&dst, &filter.pfx, filter.pfx.bitlen))
922dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat							continue;
923dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat					}
924dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat					if (filter.label) {
925dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat						SPRINT_BUF(b1);
926dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat						const char *label;
927dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat						if (tb[IFA_LABEL])
928dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat							label = RTA_DATA(tb[IFA_LABEL]);
929dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat						else
930dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat							label = ll_idx_n2a(ifa->ifa_index, b1);
931dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat						if (fnmatch(filter.label, label, 0) != 0)
932dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat							continue;
933dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat					}
934dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				}
935dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
936dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				ok = 1;
937dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				break;
938dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			}
939dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			if (!ok)
940dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				*lp = l->next;
941dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			else
942dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				lp = &l->next;
943dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		}
944dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	}
945dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
946dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	for (l=linfo; l; l = n) {
947dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		n = l->next;
948dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		if (no_link || print_linkinfo(NULL, &l->h, stdout) == 0) {
949dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			struct ifinfomsg *ifi = NLMSG_DATA(&l->h);
950dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			if (filter.family != AF_PACKET)
951dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				print_selected_addrinfo(ifi->ifi_index, ainfo, stdout);
952dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		}
953dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fflush(stdout);
954dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		free(l);
955dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	}
956dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
957dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	return 0;
958dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat}
959dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
960dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint ipaddr_list_link(int argc, char **argv)
961dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{
962dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	preferred_family = AF_PACKET;
963dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	do_link = 1;
964dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	return ipaddr_list_or_flush(argc, argv, 0);
965dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat}
966dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
967dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatvoid ipaddr_reset_filter(int oneline)
968dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{
969dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	memset(&filter, 0, sizeof(filter));
970dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	filter.oneline = oneline;
971dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat}
972dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
973dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic int default_scope(inet_prefix *lcl)
974dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{
975dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (lcl->family == AF_INET) {
976dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		if (lcl->bytelen >= 1 && *(__u8*)&lcl->data == 127)
977dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			return RT_SCOPE_HOST;
978dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	}
979dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	return 0;
980dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat}
981dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
982dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic int ipaddr_modify(int cmd, int flags, int argc, char **argv)
983dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{
984dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	struct {
985dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		struct nlmsghdr 	n;
986dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		struct ifaddrmsg 	ifa;
987dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		char   			buf[256];
988dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	} req;
989dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	char  *d = NULL;
990dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	char  *l = NULL;
991dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	char  *lcl_arg = NULL;
992dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	char  *valid_lftp = NULL;
993dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	char  *preferred_lftp = NULL;
994dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	inet_prefix lcl;
995dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	inet_prefix peer;
996dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	int local_len = 0;
997dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	int peer_len = 0;
998dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	int brd_len = 0;
999dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	int any_len = 0;
1000dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	int scoped = 0;
1001dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	__u32 preferred_lft = INFINITY_LIFE_TIME;
1002dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	__u32 valid_lft = INFINITY_LIFE_TIME;
1003dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	struct ifa_cacheinfo cinfo;
1004dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
1005dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	memset(&req, 0, sizeof(req));
1006dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
1007dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
1008dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	req.n.nlmsg_flags = NLM_F_REQUEST | flags;
1009dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	req.n.nlmsg_type = cmd;
1010dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	req.ifa.ifa_family = preferred_family;
1011dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
1012dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	while (argc > 0) {
1013dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		if (strcmp(*argv, "peer") == 0 ||
1014dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		    strcmp(*argv, "remote") == 0) {
1015dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			NEXT_ARG();
1016dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
1017dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			if (peer_len)
1018dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				duparg("peer", *argv);
1019dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			get_prefix(&peer, *argv, req.ifa.ifa_family);
1020dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			peer_len = peer.bytelen;
1021dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			if (req.ifa.ifa_family == AF_UNSPEC)
1022dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				req.ifa.ifa_family = peer.family;
1023dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			addattr_l(&req.n, sizeof(req), IFA_ADDRESS, &peer.data, peer.bytelen);
1024dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			req.ifa.ifa_prefixlen = peer.bitlen;
1025dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		} else if (matches(*argv, "broadcast") == 0 ||
1026dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			   strcmp(*argv, "brd") == 0) {
1027dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			inet_prefix addr;
1028dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			NEXT_ARG();
1029dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			if (brd_len)
1030dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				duparg("broadcast", *argv);
1031dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			if (strcmp(*argv, "+") == 0)
1032dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				brd_len = -1;
1033dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			else if (strcmp(*argv, "-") == 0)
1034dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				brd_len = -2;
1035dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			else {
1036dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				get_addr(&addr, *argv, req.ifa.ifa_family);
1037dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				if (req.ifa.ifa_family == AF_UNSPEC)
1038dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat					req.ifa.ifa_family = addr.family;
1039dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				addattr_l(&req.n, sizeof(req), IFA_BROADCAST, &addr.data, addr.bytelen);
1040dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				brd_len = addr.bytelen;
1041dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			}
1042dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		} else if (strcmp(*argv, "anycast") == 0) {
1043dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			inet_prefix addr;
1044dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			NEXT_ARG();
1045dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			if (any_len)
1046dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				duparg("anycast", *argv);
1047dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			get_addr(&addr, *argv, req.ifa.ifa_family);
1048dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			if (req.ifa.ifa_family == AF_UNSPEC)
1049dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				req.ifa.ifa_family = addr.family;
1050dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			addattr_l(&req.n, sizeof(req), IFA_ANYCAST, &addr.data, addr.bytelen);
1051dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			any_len = addr.bytelen;
1052dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		} else if (strcmp(*argv, "scope") == 0) {
1053dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			unsigned scope = 0;
1054dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			NEXT_ARG();
1055dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			if (rtnl_rtscope_a2n(&scope, *argv))
1056dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				invarg(*argv, "invalid scope value.");
1057dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			req.ifa.ifa_scope = scope;
1058dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			scoped = 1;
1059dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		} else if (strcmp(*argv, "dev") == 0) {
1060dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			NEXT_ARG();
1061dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			d = *argv;
1062dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		} else if (strcmp(*argv, "label") == 0) {
1063dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			NEXT_ARG();
1064dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			l = *argv;
1065dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			addattr_l(&req.n, sizeof(req), IFA_LABEL, l, strlen(l)+1);
1066dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		} else if (matches(*argv, "valid_lft") == 0) {
1067dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			if (valid_lftp)
1068dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				duparg("valid_lft", *argv);
1069dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			NEXT_ARG();
1070dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			valid_lftp = *argv;
1071dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			if (set_lifetime(&valid_lft, *argv))
1072dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				invarg("valid_lft value", *argv);
1073dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		} else if (matches(*argv, "preferred_lft") == 0) {
1074dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			if (preferred_lftp)
1075dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				duparg("preferred_lft", *argv);
1076dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			NEXT_ARG();
1077dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			preferred_lftp = *argv;
1078dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			if (set_lifetime(&preferred_lft, *argv))
1079dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				invarg("preferred_lft value", *argv);
1080dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		} else if (strcmp(*argv, "home") == 0) {
1081dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			req.ifa.ifa_flags |= IFA_F_HOMEADDRESS;
1082dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		} else if (strcmp(*argv, "nodad") == 0) {
1083dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			req.ifa.ifa_flags |= IFA_F_NODAD;
1084dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		} else {
1085dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			if (strcmp(*argv, "local") == 0) {
1086dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				NEXT_ARG();
1087dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			}
1088dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			if (matches(*argv, "help") == 0)
1089dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				usage();
1090dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			if (local_len)
1091dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				duparg2("local", *argv);
1092dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			lcl_arg = *argv;
1093dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			get_prefix(&lcl, *argv, req.ifa.ifa_family);
1094dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			if (req.ifa.ifa_family == AF_UNSPEC)
1095dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				req.ifa.ifa_family = lcl.family;
1096dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			addattr_l(&req.n, sizeof(req), IFA_LOCAL, &lcl.data, lcl.bytelen);
1097dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			local_len = lcl.bytelen;
1098dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		}
1099dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		argc--; argv++;
1100dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	}
1101dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (d == NULL) {
1102dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(stderr, "Not enough information: \"dev\" argument is required.\n");
1103dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		return -1;
1104dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	}
1105dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (l && matches(d, l) != 0) {
1106dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(stderr, "\"dev\" (%s) must match \"label\" (%s).\n", d, l);
11071a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt		return -1;
1108dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	}
1109dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
1110dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (peer_len == 0 && local_len) {
1111dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		if (cmd == RTM_DELADDR && lcl.family == AF_INET && !(lcl.flags & PREFIXLEN_SPECIFIED)) {
1112dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			fprintf(stderr,
1113dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			    "Warning: Executing wildcard deletion to stay compatible with old scripts.\n" \
1114dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			    "         Explicitly specify the prefix length (%s/%d) to avoid this warning.\n" \
1115dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			    "         This special behaviour is likely to disappear in further releases,\n" \
1116dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			    "         fix your scripts!\n", lcl_arg, local_len*8);
1117dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		} else {
1118dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			peer = lcl;
1119dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			addattr_l(&req.n, sizeof(req), IFA_ADDRESS, &lcl.data, lcl.bytelen);
1120dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		}
1121dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	}
1122dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (req.ifa.ifa_prefixlen == 0)
1123dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		req.ifa.ifa_prefixlen = lcl.bitlen;
1124dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
1125dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (brd_len < 0 && cmd != RTM_DELADDR) {
1126dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		inet_prefix brd;
1127dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		int i;
1128dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		if (req.ifa.ifa_family != AF_INET) {
1129dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			fprintf(stderr, "Broadcast can be set only for IPv4 addresses\n");
1130dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			return -1;
1131dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		}
1132dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		brd = peer;
1133dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		if (brd.bitlen <= 30) {
1134dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			for (i=31; i>=brd.bitlen; i--) {
1135dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				if (brd_len == -1)
1136dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat					brd.data[0] |= htonl(1<<(31-i));
1137dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat				else
1138dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat					brd.data[0] &= ~htonl(1<<(31-i));
1139dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			}
1140dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			addattr_l(&req.n, sizeof(req), IFA_BROADCAST, &brd.data, brd.bytelen);
1141dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			brd_len = brd.bytelen;
1142dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		}
1143dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	}
1144dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (!scoped && cmd != RTM_DELADDR)
1145dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		req.ifa.ifa_scope = default_scope(&lcl);
1146dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
1147dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	ll_init_map(&rth);
1148dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
1149dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if ((req.ifa.ifa_index = ll_name_to_index(d)) == 0) {
1150dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		fprintf(stderr, "Cannot find device \"%s\"\n", d);
1151dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		return -1;
1152dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	}
1153dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
1154dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (valid_lftp || preferred_lftp) {
1155dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		if (!valid_lft) {
1156dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			fprintf(stderr, "valid_lft is zero\n");
1157dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			return -1;
1158dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		}
1159dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		if (valid_lft < preferred_lft) {
1160dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			fprintf(stderr, "preferred_lft is greater than valid_lft\n");
1161dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			return -1;
1162dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		}
1163dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
1164dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		memset(&cinfo, 0, sizeof(cinfo));
1165dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		cinfo.ifa_prefered = preferred_lft;
1166dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		cinfo.ifa_valid = valid_lft;
1167dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		addattr_l(&req.n, sizeof(req), IFA_CACHEINFO, &cinfo,
1168dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat			  sizeof(cinfo));
1169dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	}
1170dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
1171dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0)
11721a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt		return -2;
1173dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
1174dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	return 0;
1175dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat}
1176dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
1177dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint do_ipaddr(int argc, char **argv)
1178dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{
1179dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (argc < 1)
1180dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		return ipaddr_list_or_flush(0, NULL, 0);
1181dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (matches(*argv, "add") == 0)
1182dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		return ipaddr_modify(RTM_NEWADDR, NLM_F_CREATE|NLM_F_EXCL, argc-1, argv+1);
1183dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (matches(*argv, "change") == 0 ||
1184dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		strcmp(*argv, "chg") == 0)
1185dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		return ipaddr_modify(RTM_NEWADDR, NLM_F_REPLACE, argc-1, argv+1);
1186dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (matches(*argv, "replace") == 0)
1187dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		return ipaddr_modify(RTM_NEWADDR, NLM_F_CREATE|NLM_F_REPLACE, argc-1, argv+1);
1188dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (matches(*argv, "delete") == 0)
1189dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		return ipaddr_modify(RTM_DELADDR, 0, argc-1, argv+1);
1190dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (matches(*argv, "list") == 0 || matches(*argv, "show") == 0
1191dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	    || matches(*argv, "lst") == 0)
1192dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		return ipaddr_list_or_flush(argc-1, argv+1, 0);
1193dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (matches(*argv, "flush") == 0)
1194dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		return ipaddr_list_or_flush(argc-1, argv+1, 1);
1195dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	if (matches(*argv, "help") == 0)
1196dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat		usage();
1197dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	fprintf(stderr, "Command \"%s\" is unknown, try \"ip addr help\".\n", *argv);
1198dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat	exit(-1);
1199dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat}
1200dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat
1201