/*
 * ipaddress.c		"ip address".
 *
 *		This program is free software; you can redistribute it and/or
 *		modify it under the terms of the GNU General Public License
 *		as published by the Free Software Foundation; either version
 *		2 of the License, or (at your option) any later version.
 *
 * Authors:	Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <syslog.h>
#include <inttypes.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <fnmatch.h>

#include <linux/netdevice.h>
#include <linux/if_arp.h>
#include <linux/sockios.h>
#include <linux/net_namespace.h>

#include "rt_names.h"
#include "utils.h"
#include "ll_map.h"
#include "ip_common.h"
#include "color.h"

enum {
	IPADD_LIST,
	IPADD_FLUSH,
	IPADD_SAVE,
};

static struct
{
	int ifindex;
	int family;
	int oneline;
	int showqueue;
	inet_prefix pfx;
	int scope, scopemask;
	int flags, flagmask;
	int up;
	char *label;
	int flushed;
	char *flushb;
	int flushp;
	int flushe;
	int group;
	int master;
	char *kind;
} filter;

static int do_link;

static void usage(void) __attribute__((noreturn));

static void usage(void)
{
	if (do_link) {
		iplink_usage();
	}
	fprintf(stderr, "Usage: ip address {add|change|replace} IFADDR dev IFNAME [ LIFETIME ]\n");
	fprintf(stderr, "                                                      [ CONFFLAG-LIST ]\n");
	fprintf(stderr, "       ip address del IFADDR dev IFNAME [mngtmpaddr]\n");
	fprintf(stderr, "       ip address {show|save|flush} [ dev IFNAME ] [ scope SCOPE-ID ]\n");
	fprintf(stderr, "                            [ to PREFIX ] [ FLAG-LIST ] [ label LABEL ] [up]\n");
	fprintf(stderr, "       ip address {showdump|restore}\n");
	fprintf(stderr, "IFADDR := PREFIX | ADDR peer PREFIX\n");
	fprintf(stderr, "          [ broadcast ADDR ] [ anycast ADDR ]\n");
	fprintf(stderr, "          [ label IFNAME ] [ scope SCOPE-ID ]\n");
	fprintf(stderr, "SCOPE-ID := [ host | link | global | NUMBER ]\n");
	fprintf(stderr, "FLAG-LIST := [ FLAG-LIST ] FLAG\n");
	fprintf(stderr, "FLAG  := [ permanent | dynamic | secondary | primary |\n");
	fprintf(stderr, "           [-]tentative | [-]deprecated | [-]dadfailed | temporary |\n");
	fprintf(stderr, "           CONFFLAG-LIST ]\n");
	fprintf(stderr, "CONFFLAG-LIST := [ CONFFLAG-LIST ] CONFFLAG\n");
	fprintf(stderr, "CONFFLAG  := [ home | nodad | mngtmpaddr | noprefixroute | autojoin ]\n");
	fprintf(stderr, "LIFETIME := [ valid_lft LFT ] [ preferred_lft LFT ]\n");
	fprintf(stderr, "LFT := forever | SECONDS\n");

	exit(-1);
}

static void print_link_flags(FILE *fp, unsigned flags, unsigned mdown)
{
	fprintf(fp, "<");
	if (flags & IFF_UP && !(flags & IFF_RUNNING))
		fprintf(fp, "NO-CARRIER%s", flags ? "," : "");
	flags &= ~IFF_RUNNING;
#define _PF(f) if (flags&IFF_##f) { \
		  flags &= ~IFF_##f ; \
		  fprintf(fp, #f "%s", flags ? "," : ""); }
	_PF(LOOPBACK);
	_PF(BROADCAST);
	_PF(POINTOPOINT);
	_PF(MULTICAST);
	_PF(NOARP);
	_PF(ALLMULTI);
	_PF(PROMISC);
	_PF(MASTER);
	_PF(SLAVE);
	_PF(DEBUG);
	_PF(DYNAMIC);
	_PF(AUTOMEDIA);
	_PF(PORTSEL);
	_PF(NOTRAILERS);
	_PF(UP);
	_PF(LOWER_UP);
	_PF(DORMANT);
	_PF(ECHO);
#undef _PF
	if (flags)
		fprintf(fp, "%x", flags);
	if (mdown)
		fprintf(fp, ",M-DOWN");
	fprintf(fp, "> ");
}

static const char *oper_states[] = {
	"UNKNOWN", "NOTPRESENT", "DOWN", "LOWERLAYERDOWN",
	"TESTING", "DORMANT",	 "UP"
};

static void print_operstate(FILE *f, __u8 state)
{
	if (state >= sizeof(oper_states)/sizeof(oper_states[0]))
		fprintf(f, "state %#x ", state);
	else {
		if (brief) {
			if (strcmp(oper_states[state], "UP") == 0)
				color_fprintf(f, COLOR_OPERSTATE_UP, "%-14s ", oper_states[state]);
			else if (strcmp(oper_states[state], "DOWN") == 0)
				color_fprintf(f, COLOR_OPERSTATE_DOWN, "%-14s ", oper_states[state]);
			else
				fprintf(f, "%-14s ", oper_states[state]);
		} else {
			fprintf(f, "state ");
			if (strcmp(oper_states[state], "UP") == 0)
				color_fprintf(f, COLOR_OPERSTATE_UP, "%s ", oper_states[state]);
			else if (strcmp(oper_states[state], "DOWN") == 0)
				color_fprintf(f, COLOR_OPERSTATE_DOWN, "%s ", oper_states[state]);
			else
				fprintf(f, "%s ", oper_states[state]);
		}
	}
}

int get_operstate(const char *name)
{
	int i;

	for (i = 0; i < sizeof(oper_states)/sizeof(oper_states[0]); i++)
		if (strcasecmp(name, oper_states[i]) == 0)
			return i;
	return -1;
}

static void print_queuelen(FILE *f, struct rtattr *tb[IFLA_MAX + 1])
{
	int qlen;

	if (tb[IFLA_TXQLEN])
		qlen = *(int *)RTA_DATA(tb[IFLA_TXQLEN]);
	else {
		struct ifreq ifr;
		int s = socket(AF_INET, SOCK_STREAM, 0);

		if (s < 0)
			return;

		memset(&ifr, 0, sizeof(ifr));
		strcpy(ifr.ifr_name, rta_getattr_str(tb[IFLA_IFNAME]));
		if (ioctl(s, SIOCGIFTXQLEN, &ifr) < 0) {
			fprintf(f, "ioctl(SIOCGIFTXQLEN) failed: %s\n", strerror(errno));
			close(s);
			return;
		}
		close(s);
		qlen = ifr.ifr_qlen;
	}
	if (qlen)
		fprintf(f, "qlen %d", qlen);
}

static const char *link_modes[] = {
	"DEFAULT", "DORMANT"
};

static void print_linkmode(FILE *f, struct rtattr *tb)
{
	unsigned int mode = rta_getattr_u8(tb);

	if (mode >= sizeof(link_modes) / sizeof(link_modes[0]))
		fprintf(f, "mode %d ", mode);
	else
		fprintf(f, "mode %s ", link_modes[mode]);
}

static char *parse_link_kind(struct rtattr *tb)
{
	struct rtattr *linkinfo[IFLA_INFO_MAX+1];

	parse_rtattr_nested(linkinfo, IFLA_INFO_MAX, tb);

	if (linkinfo[IFLA_INFO_KIND])
		return RTA_DATA(linkinfo[IFLA_INFO_KIND]);

	return "";
}

static void print_linktype(FILE *fp, struct rtattr *tb)
{
	struct rtattr *linkinfo[IFLA_INFO_MAX+1];
	struct link_util *lu;
	struct link_util *slave_lu;
	char *kind;
	char *slave_kind;

	parse_rtattr_nested(linkinfo, IFLA_INFO_MAX, tb);

	if (linkinfo[IFLA_INFO_KIND]) {
		kind = RTA_DATA(linkinfo[IFLA_INFO_KIND]);

		fprintf(fp, "%s", _SL_);
		fprintf(fp, "    %s ", kind);

		lu = get_link_kind(kind);
		if (lu && lu->print_opt) {
			struct rtattr *attr[lu->maxattr+1], **data = NULL;

			if (linkinfo[IFLA_INFO_DATA]) {
				parse_rtattr_nested(attr, lu->maxattr,
						    linkinfo[IFLA_INFO_DATA]);
				data = attr;
			}
			lu->print_opt(lu, fp, data);

			if (linkinfo[IFLA_INFO_XSTATS] && show_stats &&
			    lu->print_xstats)
				lu->print_xstats(lu, fp, linkinfo[IFLA_INFO_XSTATS]);
		}
	}

	if (linkinfo[IFLA_INFO_SLAVE_KIND]) {
		slave_kind = RTA_DATA(linkinfo[IFLA_INFO_SLAVE_KIND]);

		fprintf(fp, "%s", _SL_);
		fprintf(fp, "    %s_slave ", slave_kind);

		slave_lu = get_link_slave_kind(slave_kind);
		if (slave_lu && slave_lu->print_opt) {
			struct rtattr *attr[slave_lu->maxattr+1], **data = NULL;

			if (linkinfo[IFLA_INFO_SLAVE_DATA]) {
				parse_rtattr_nested(attr, slave_lu->maxattr,
						    linkinfo[IFLA_INFO_SLAVE_DATA]);
				data = attr;
			}
			slave_lu->print_opt(slave_lu, fp, data);
		}
	}
}

static void print_af_spec(FILE *fp, struct rtattr *af_spec_attr)
{
	struct rtattr *inet6_attr;
	struct rtattr *tb[IFLA_INET6_MAX + 1];

	inet6_attr = parse_rtattr_one_nested(AF_INET6, af_spec_attr);
	if (!inet6_attr)
		return;

	parse_rtattr_nested(tb, IFLA_INET6_MAX, inet6_attr);

	if (tb[IFLA_INET6_ADDR_GEN_MODE]) {
		__u8 mode = rta_getattr_u8(tb[IFLA_INET6_ADDR_GEN_MODE]);
		switch (mode) {
		case IN6_ADDR_GEN_MODE_EUI64:
			fprintf(fp, "addrgenmode eui64 ");
			break;
		case IN6_ADDR_GEN_MODE_NONE:
			fprintf(fp, "addrgenmode none ");
			break;
		case IN6_ADDR_GEN_MODE_STABLE_PRIVACY:
			fprintf(fp, "addrgenmode stable_secret ");
			break;
		case IN6_ADDR_GEN_MODE_RANDOM:
			fprintf(fp, "addrgenmode random ");
			break;
		default:
			fprintf(fp, "addrgenmode %#.2hhx ", mode);
			break;
		}
	}
}

static void print_vf_stats64(FILE *fp, struct rtattr *vfstats);

static void print_vfinfo(FILE *fp, struct rtattr *vfinfo)
{
	struct ifla_vf_mac *vf_mac;
	struct ifla_vf_vlan *vf_vlan;
	struct ifla_vf_tx_rate *vf_tx_rate;
	struct ifla_vf_spoofchk *vf_spoofchk;
	struct ifla_vf_link_state *vf_linkstate;
	struct rtattr *vf[IFLA_VF_MAX + 1] = {};
	struct rtattr *tmp;
	SPRINT_BUF(b1);

	if (vfinfo->rta_type != IFLA_VF_INFO) {
		fprintf(stderr, "BUG: rta type is %d\n", vfinfo->rta_type);
		return;
	}

	parse_rtattr_nested(vf, IFLA_VF_MAX, vfinfo);

	vf_mac = RTA_DATA(vf[IFLA_VF_MAC]);
	vf_vlan = RTA_DATA(vf[IFLA_VF_VLAN]);
	vf_tx_rate = RTA_DATA(vf[IFLA_VF_TX_RATE]);

	/* Check if the spoof checking vf info type is supported by
	 * this kernel.
	 */
	tmp = (struct rtattr *)((char *)vf[IFLA_VF_TX_RATE] +
			vf[IFLA_VF_TX_RATE]->rta_len);

	if (tmp->rta_type != IFLA_VF_SPOOFCHK)
		vf_spoofchk = NULL;
	else
		vf_spoofchk = RTA_DATA(vf[IFLA_VF_SPOOFCHK]);

	if (vf_spoofchk) {
		/* Check if the link state vf info type is supported by
		 * this kernel.
		 */
		tmp = (struct rtattr *)((char *)vf[IFLA_VF_SPOOFCHK] +
				vf[IFLA_VF_SPOOFCHK]->rta_len);

		if (tmp->rta_type != IFLA_VF_LINK_STATE)
			vf_linkstate = NULL;
		else
			vf_linkstate = RTA_DATA(vf[IFLA_VF_LINK_STATE]);
	} else
		vf_linkstate = NULL;

	fprintf(fp, "%s    vf %d MAC %s", _SL_, vf_mac->vf,
		ll_addr_n2a((unsigned char *)&vf_mac->mac,
		ETH_ALEN, 0, b1, sizeof(b1)));
	if (vf_vlan->vlan)
		fprintf(fp, ", vlan %d", vf_vlan->vlan);
	if (vf_vlan->qos)
		fprintf(fp, ", qos %d", vf_vlan->qos);
	if (vf_tx_rate->rate)
		fprintf(fp, ", tx rate %d (Mbps)", vf_tx_rate->rate);

	if (vf[IFLA_VF_RATE]) {
		struct ifla_vf_rate *vf_rate = RTA_DATA(vf[IFLA_VF_RATE]);

		if (vf_rate->max_tx_rate)
			fprintf(fp, ", max_tx_rate %dMbps", vf_rate->max_tx_rate);
		if (vf_rate->min_tx_rate)
			fprintf(fp, ", min_tx_rate %dMbps", vf_rate->min_tx_rate);
	}

	if (vf_spoofchk && vf_spoofchk->setting != -1) {
		if (vf_spoofchk->setting)
			fprintf(fp, ", spoof checking on");
		else
			fprintf(fp, ", spoof checking off");
	}
	if (vf_linkstate) {
		if (vf_linkstate->link_state == IFLA_VF_LINK_STATE_AUTO)
			fprintf(fp, ", link-state auto");
		else if (vf_linkstate->link_state == IFLA_VF_LINK_STATE_ENABLE)
			fprintf(fp, ", link-state enable");
		else
			fprintf(fp, ", link-state disable");
	}
	if (vf[IFLA_VF_STATS] && show_stats)
		print_vf_stats64(fp, vf[IFLA_VF_STATS]);
}

static void print_num(FILE *fp, unsigned width, uint64_t count)
{
	const char *prefix = "kMGTPE";
	const unsigned int base = use_iec ? 1024 : 1000;
	uint64_t powi = 1;
	uint16_t powj = 1;
	uint8_t precision = 2;
	char buf[64];

	if (!human_readable || count < base) {
		fprintf(fp, "%-*"PRIu64" ", width, count);
		return;
	}

	/* increase value by a factor of 1000/1024 and print
	 * if result is something a human can read */
	for(;;) {
		powi *= base;
		if (count / base < powi)
			break;

		if (!prefix[1])
			break;
		++prefix;
	}

	/* try to guess a good number of digits for precision */
	for (; precision > 0; precision--) {
		powj *= 10;
		if (count / powi < powj)
			break;
	}

	snprintf(buf, sizeof(buf), "%.*f%c%s", precision,
		(double) count / powi, *prefix, use_iec ? "i" : "");

	fprintf(fp, "%-*s ", width, buf);
}

static void print_vf_stats64(FILE *fp, struct rtattr *vfstats)
{
	struct rtattr *vf[IFLA_VF_STATS_MAX + 1] = {};

	if (vfstats->rta_type != IFLA_VF_STATS) {
		fprintf(stderr, "BUG: rta type is %d\n", vfstats->rta_type);
		return;
	}

	parse_rtattr_nested(vf, IFLA_VF_MAX, vfstats);

	/* RX stats */
	fprintf(fp, "%s", _SL_);
	fprintf(fp, "    RX: bytes  packets  mcast   bcast %s", _SL_);
	fprintf(fp, "    ");

	print_num(fp, 10, *(__u64 *)RTA_DATA(vf[IFLA_VF_STATS_RX_BYTES]));
	print_num(fp, 8, *(__u64 *)RTA_DATA(vf[IFLA_VF_STATS_RX_PACKETS]));
	print_num(fp, 7, *(__u64 *)RTA_DATA(vf[IFLA_VF_STATS_MULTICAST]));
	print_num(fp, 7, *(__u64 *)RTA_DATA(vf[IFLA_VF_STATS_BROADCAST]));

	/* TX stats */
	fprintf(fp, "%s", _SL_);
	fprintf(fp, "    TX: bytes  packets %s", _SL_);
	fprintf(fp, "    ");

	print_num(fp, 10, *(__u64 *)RTA_DATA(vf[IFLA_VF_STATS_TX_BYTES]));
	print_num(fp, 8, *(__u64 *)RTA_DATA(vf[IFLA_VF_STATS_TX_PACKETS]));
}

static void print_link_stats64(FILE *fp, const struct rtnl_link_stats64 *s,
                               const struct rtattr *carrier_changes)
{
	/* RX stats */
	fprintf(fp, "    RX: bytes  packets  errors  dropped overrun mcast   %s%s",
		s->rx_compressed ? "compressed" : "", _SL_);

	fprintf(fp, "    ");
	print_num(fp, 10, s->rx_bytes);
	print_num(fp, 8, s->rx_packets);
	print_num(fp, 7, s->rx_errors);
	print_num(fp, 7, s->rx_dropped);
	print_num(fp, 7, s->rx_over_errors);
	print_num(fp, 7, s->multicast);
	if (s->rx_compressed)
		print_num(fp, 7, s->rx_compressed);

	/* RX error stats */
	if (show_stats > 1) {
		fprintf(fp, "%s", _SL_);
		fprintf(fp, "    RX errors: length   crc     frame   fifo    missed%s", _SL_);

		fprintf(fp, "               ");
		print_num(fp, 8, s->rx_length_errors);
		print_num(fp, 7, s->rx_crc_errors);
		print_num(fp, 7, s->rx_frame_errors);
		print_num(fp, 7, s->rx_fifo_errors);
		print_num(fp, 7, s->rx_missed_errors);
	}
	fprintf(fp, "%s", _SL_);

	/* TX stats */
	fprintf(fp, "    TX: bytes  packets  errors  dropped carrier collsns %s%s",
		s->tx_compressed ? "compressed" : "", _SL_);


	fprintf(fp, "    ");
	print_num(fp, 10, s->tx_bytes);
	print_num(fp, 8, s->tx_packets);
	print_num(fp, 7, s->tx_errors);
	print_num(fp, 7, s->tx_dropped);
	print_num(fp, 7, s->tx_carrier_errors);
	print_num(fp, 7, s->collisions);
	if (s->tx_compressed)
		print_num(fp, 7, s->tx_compressed);

	/* TX error stats */
	if (show_stats > 1) {
		fprintf(fp, "%s", _SL_);
		fprintf(fp, "    TX errors: aborted  fifo   window heartbeat");
                if (carrier_changes)
			fprintf(fp, " transns");
		fprintf(fp, "%s", _SL_);

		fprintf(fp, "               ");
		print_num(fp, 8, s->tx_aborted_errors);
		print_num(fp, 7, s->tx_fifo_errors);
		print_num(fp, 7, s->tx_window_errors);
		print_num(fp, 7, s->tx_heartbeat_errors);
		if (carrier_changes)
			print_num(fp, 7, *(uint32_t*)RTA_DATA(carrier_changes));
	}
}

static void print_link_stats32(FILE *fp, const struct rtnl_link_stats *s,
			       const struct rtattr *carrier_changes)
{
	/* RX stats */
	fprintf(fp, "    RX: bytes  packets  errors  dropped overrun mcast   %s%s",
		s->rx_compressed ? "compressed" : "", _SL_);


	fprintf(fp, "    ");
	print_num(fp, 10, s->rx_bytes);
	print_num(fp, 8, s->rx_packets);
	print_num(fp, 7, s->rx_errors);
	print_num(fp, 7, s->rx_dropped);
	print_num(fp, 7, s->rx_over_errors);
	print_num(fp, 7, s->multicast);
	if (s->rx_compressed)
		print_num(fp, 7, s->rx_compressed);

	/* RX error stats */
	if (show_stats > 1) {
		fprintf(fp, "%s", _SL_);
		fprintf(fp, "    RX errors: length   crc     frame   fifo    missed%s", _SL_);
		fprintf(fp, "               ");
		print_num(fp, 8, s->rx_length_errors);
		print_num(fp, 7, s->rx_crc_errors);
		print_num(fp, 7, s->rx_frame_errors);
		print_num(fp, 7, s->rx_fifo_errors);
		print_num(fp, 7, s->rx_missed_errors);
	}
	fprintf(fp, "%s", _SL_);

	/* TX stats */
	fprintf(fp, "    TX: bytes  packets  errors  dropped carrier collsns %s%s",
		s->tx_compressed ? "compressed" : "", _SL_);

	fprintf(fp, "    ");
	print_num(fp, 10, s->tx_bytes);
	print_num(fp, 8, s->tx_packets);
	print_num(fp, 7, s->tx_errors);
	print_num(fp, 7, s->tx_dropped);
	print_num(fp, 7, s->tx_carrier_errors);
	print_num(fp, 7, s->collisions);
	if (s->tx_compressed)
		print_num(fp, 7, s->tx_compressed);

	/* TX error stats */
	if (show_stats > 1) {
		fprintf(fp, "%s", _SL_);
		fprintf(fp, "    TX errors: aborted  fifo   window heartbeat");
                if (carrier_changes)
			fprintf(fp, " transns");
		fprintf(fp, "%s", _SL_);

		fprintf(fp, "               ");
		print_num(fp, 8, s->tx_aborted_errors);
		print_num(fp, 7, s->tx_fifo_errors);
		print_num(fp, 7, s->tx_window_errors);
		print_num(fp, 7, s->tx_heartbeat_errors);
		if (carrier_changes)
			print_num(fp, 7, *(uint32_t*)RTA_DATA(carrier_changes));
	}
}

static void __print_link_stats(FILE *fp, struct rtattr **tb)
{
	if (tb[IFLA_STATS64])
		print_link_stats64(fp, RTA_DATA(tb[IFLA_STATS64]),
					tb[IFLA_CARRIER_CHANGES]);
	else if (tb[IFLA_STATS])
		print_link_stats32(fp, RTA_DATA(tb[IFLA_STATS]),
					tb[IFLA_CARRIER_CHANGES]);
}

static void print_link_stats(FILE *fp, struct nlmsghdr *n)
{
	struct ifinfomsg *ifi = NLMSG_DATA(n);
	struct rtattr * tb[IFLA_MAX+1];

	parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi),
		     n->nlmsg_len - NLMSG_LENGTH(sizeof(*ifi)));
	__print_link_stats(fp, tb);
	fprintf(fp, "%s", _SL_);
}

int print_linkinfo_brief(const struct sockaddr_nl *who,
				struct nlmsghdr *n, void *arg)
{
	FILE *fp = (FILE*)arg;
	struct ifinfomsg *ifi = NLMSG_DATA(n);
	struct rtattr * tb[IFLA_MAX+1];
	int len = n->nlmsg_len;
	char *name;
	char buf[32] = { 0, };
	unsigned m_flag = 0;

	if (n->nlmsg_type != RTM_NEWLINK && n->nlmsg_type != RTM_DELLINK)
		return -1;

	len -= NLMSG_LENGTH(sizeof(*ifi));
	if (len < 0)
		return -1;

	if (filter.ifindex && ifi->ifi_index != filter.ifindex)
		return -1;
	if (filter.up && !(ifi->ifi_flags&IFF_UP))
		return -1;

	parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
	if (tb[IFLA_IFNAME] == NULL) {
		fprintf(stderr, "BUG: device with ifindex %d has nil ifname\n", ifi->ifi_index);
	}
	if (filter.label &&
	    (!filter.family || filter.family == AF_PACKET) &&
	    fnmatch(filter.label, RTA_DATA(tb[IFLA_IFNAME]), 0))
		return -1;

	if (tb[IFLA_GROUP]) {
		int group = *(int*)RTA_DATA(tb[IFLA_GROUP]);
		if (filter.group != -1 && group != filter.group)
			return -1;
	}

	if (tb[IFLA_MASTER]) {
		int master = *(int*)RTA_DATA(tb[IFLA_MASTER]);
		if (filter.master > 0 && master != filter.master)
			return -1;
	}
	else if (filter.master > 0)
		return -1;

	if (filter.kind) {
		if (tb[IFLA_LINKINFO]) {
			char *kind = parse_link_kind(tb[IFLA_LINKINFO]);

			if (strcmp(kind, filter.kind))
				return -1;
		} else {
			return -1;
		}
	}

	if (n->nlmsg_type == RTM_DELLINK)
		fprintf(fp, "Deleted ");

	name = (char *)(tb[IFLA_IFNAME] ? rta_getattr_str(tb[IFLA_IFNAME]) : "<nil>");

	if (tb[IFLA_LINK]) {
		SPRINT_BUF(b1);
		int iflink = *(int*)RTA_DATA(tb[IFLA_LINK]);
		if (iflink == 0)
			snprintf(buf, sizeof(buf), "%s@NONE", name);
		else {
			snprintf(buf, sizeof(buf),
				 "%s@%s", name, ll_idx_n2a(iflink, b1));
			m_flag = ll_index_to_flags(iflink);
			m_flag = !(m_flag & IFF_UP);
		}
	} else
		snprintf(buf, sizeof(buf), "%s", name);

	fprintf(fp, "%-16s ", buf);

	if (tb[IFLA_OPERSTATE])
		print_operstate(fp, rta_getattr_u8(tb[IFLA_OPERSTATE]));

	if (filter.family == AF_PACKET) {
		SPRINT_BUF(b1);
		if (tb[IFLA_ADDRESS]) {
			color_fprintf(fp, COLOR_MAC, "%s ",
					ll_addr_n2a(RTA_DATA(tb[IFLA_ADDRESS]),
						RTA_PAYLOAD(tb[IFLA_ADDRESS]),
						ifi->ifi_type,
						b1, sizeof(b1)));
		}
	}

	if (filter.family == AF_PACKET)
		print_link_flags(fp, ifi->ifi_flags, m_flag);

	if (filter.family == AF_PACKET)
		fprintf(fp, "\n");
	fflush(fp);
	return 0;
}

int print_linkinfo(const struct sockaddr_nl *who,
		   struct nlmsghdr *n, void *arg)
{
	FILE *fp = (FILE*)arg;
	struct ifinfomsg *ifi = NLMSG_DATA(n);
	struct rtattr * tb[IFLA_MAX+1];
	int len = n->nlmsg_len;
	unsigned m_flag = 0;

	if (n->nlmsg_type != RTM_NEWLINK && n->nlmsg_type != RTM_DELLINK)
		return 0;

	len -= NLMSG_LENGTH(sizeof(*ifi));
	if (len < 0)
		return -1;

	if (filter.ifindex && ifi->ifi_index != filter.ifindex)
		return 0;
	if (filter.up && !(ifi->ifi_flags&IFF_UP))
		return 0;

	parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
	if (tb[IFLA_IFNAME] == NULL) {
		fprintf(stderr, "BUG: device with ifindex %d has nil ifname\n", ifi->ifi_index);
	}
	if (filter.label &&
	    (!filter.family || filter.family == AF_PACKET) &&
	    fnmatch(filter.label, RTA_DATA(tb[IFLA_IFNAME]), 0))
		return 0;

	if (tb[IFLA_GROUP]) {
		int group = *(int*)RTA_DATA(tb[IFLA_GROUP]);
		if (filter.group != -1 && group != filter.group)
			return -1;
	}

	if (tb[IFLA_MASTER]) {
		int master = *(int*)RTA_DATA(tb[IFLA_MASTER]);
		if (filter.master > 0 && master != filter.master)
			return -1;
	}
	else if (filter.master > 0)
		return -1;

	if (filter.kind) {
		if (tb[IFLA_LINKINFO]) {
			char *kind = parse_link_kind(tb[IFLA_LINKINFO]);

			if (strcmp(kind, filter.kind))
				return -1;
		} else {
			return -1;
		}
	}

	if (n->nlmsg_type == RTM_DELLINK)
		fprintf(fp, "Deleted ");

	fprintf(fp, "%d: ", ifi->ifi_index);
	color_fprintf(fp, COLOR_IFNAME, "%s",
		tb[IFLA_IFNAME] ? rta_getattr_str(tb[IFLA_IFNAME]) : "<nil>");

	if (tb[IFLA_LINK]) {
		SPRINT_BUF(b1);
		int iflink = *(int*)RTA_DATA(tb[IFLA_LINK]);
		if (iflink == 0)
			fprintf(fp, "@NONE: ");
		else {
			if (tb[IFLA_LINK_NETNSID])
				fprintf(fp, "@if%d: ", iflink);
			else {
				fprintf(fp, "@%s: ", ll_idx_n2a(iflink, b1));
				m_flag = ll_index_to_flags(iflink);
				m_flag = !(m_flag & IFF_UP);
			}
		}
	} else {
		fprintf(fp, ": ");
	}
	print_link_flags(fp, ifi->ifi_flags, m_flag);

	if (tb[IFLA_MTU])
		fprintf(fp, "mtu %u ", *(int*)RTA_DATA(tb[IFLA_MTU]));
	if (tb[IFLA_QDISC])
		fprintf(fp, "qdisc %s ", rta_getattr_str(tb[IFLA_QDISC]));
	if (tb[IFLA_MASTER]) {
		SPRINT_BUF(b1);
		fprintf(fp, "master %s ", ll_idx_n2a(*(int*)RTA_DATA(tb[IFLA_MASTER]), b1));
	}

	if (tb[IFLA_PHYS_PORT_ID]) {
		SPRINT_BUF(b1);
		fprintf(fp, "portid %s ",
			hexstring_n2a(RTA_DATA(tb[IFLA_PHYS_PORT_ID]),
				      RTA_PAYLOAD(tb[IFLA_PHYS_PORT_ID]),
				      b1, sizeof(b1)));
	}

	if (tb[IFLA_PHYS_SWITCH_ID]) {
		SPRINT_BUF(b1);
		fprintf(fp, "switchid %s ",
			hexstring_n2a(RTA_DATA(tb[IFLA_PHYS_SWITCH_ID]),
				      RTA_PAYLOAD(tb[IFLA_PHYS_SWITCH_ID]),
				      b1, sizeof(b1)));
	}

	if (tb[IFLA_OPERSTATE])
		print_operstate(fp, rta_getattr_u8(tb[IFLA_OPERSTATE]));

	if (do_link && tb[IFLA_LINKMODE])
		print_linkmode(fp, tb[IFLA_LINKMODE]);

	if (tb[IFLA_GROUP]) {
		SPRINT_BUF(b1);
		int group = *(int*)RTA_DATA(tb[IFLA_GROUP]);
		fprintf(fp, "group %s ", rtnl_group_n2a(group, b1, sizeof(b1)));
	}

	if (filter.showqueue)
		print_queuelen(fp, tb);

	if (!filter.family || filter.family == AF_PACKET || show_details) {
		SPRINT_BUF(b1);
		fprintf(fp, "%s", _SL_);
		fprintf(fp, "    link/%s ", ll_type_n2a(ifi->ifi_type, b1, sizeof(b1)));

		if (tb[IFLA_ADDRESS]) {
			color_fprintf(fp, COLOR_MAC, "%s",
					ll_addr_n2a(RTA_DATA(tb[IFLA_ADDRESS]),
						RTA_PAYLOAD(tb[IFLA_ADDRESS]),
						ifi->ifi_type,
						b1, sizeof(b1)));
		}
		if (tb[IFLA_BROADCAST]) {
			if (ifi->ifi_flags&IFF_POINTOPOINT)
				fprintf(fp, " peer ");
			else
				fprintf(fp, " brd ");
			fprintf(fp, "%s", ll_addr_n2a(RTA_DATA(tb[IFLA_BROADCAST]),
						      RTA_PAYLOAD(tb[IFLA_BROADCAST]),
						      ifi->ifi_type,
						      b1, sizeof(b1)));
		}
	}

	if (tb[IFLA_LINK_NETNSID]) {
		int id = *(int*)RTA_DATA(tb[IFLA_LINK_NETNSID]);

		if (id >= 0)
			fprintf(fp, " link-netnsid %d", id);
		else
			fprintf(fp, " link-netnsid unknown");
	}

	if (tb[IFLA_PROTO_DOWN]) {
		if (rta_getattr_u8(tb[IFLA_PROTO_DOWN]))
			fprintf(fp, " protodown on ");
	}

	if (tb[IFLA_PROMISCUITY] && show_details)
		fprintf(fp, " promiscuity %u ",
			*(int*)RTA_DATA(tb[IFLA_PROMISCUITY]));

	if (tb[IFLA_LINKINFO] && show_details)
		print_linktype(fp, tb[IFLA_LINKINFO]);

	if (do_link && tb[IFLA_AF_SPEC] && show_details)
		print_af_spec(fp, tb[IFLA_AF_SPEC]);

	if ((do_link || show_details) && tb[IFLA_IFALIAS]) {
		fprintf(fp, "%s    alias %s", _SL_,
			rta_getattr_str(tb[IFLA_IFALIAS]));
	}

	if (do_link && show_stats) {
		fprintf(fp, "%s", _SL_);
		__print_link_stats(fp, tb);
	}

	if ((do_link || show_details) && tb[IFLA_VFINFO_LIST] && tb[IFLA_NUM_VF]) {
		struct rtattr *i, *vflist = tb[IFLA_VFINFO_LIST];
		int rem = RTA_PAYLOAD(vflist);
		for (i = RTA_DATA(vflist); RTA_OK(i, rem); i = RTA_NEXT(i, rem))
			print_vfinfo(fp, i);
	}

	fprintf(fp, "\n");
	fflush(fp);
	return 1;
}

static int flush_update(void)
{

	/*
	 * Note that the kernel may delete multiple addresses for one
	 * delete request (e.g. if ipv4 address promotion is disabled).
	 * Since a flush operation is really a series of delete requests
	 * its possible that we may request an address delete that has
	 * already been done by the kernel. Therefore, ignore EADDRNOTAVAIL
	 * errors returned from a flush request
	 */
	if ((rtnl_send_check(&rth, filter.flushb, filter.flushp) < 0) &&
	    (errno != EADDRNOTAVAIL)) {
		perror("Failed to send flush request");
		return -1;
	}
	filter.flushp = 0;
	return 0;
}

static int set_lifetime(unsigned int *lifetime, char *argv)
{
	if (strcmp(argv, "forever") == 0)
		*lifetime = INFINITY_LIFE_TIME;
	else if (get_u32(lifetime, argv, 0))
		return -1;

	return 0;
}

static unsigned int get_ifa_flags(struct ifaddrmsg *ifa,
				  struct rtattr *ifa_flags_attr)
{
	return ifa_flags_attr ? rta_getattr_u32(ifa_flags_attr) :
				ifa->ifa_flags;
}

int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n,
		   void *arg)
{
	FILE *fp = arg;
	struct ifaddrmsg *ifa = NLMSG_DATA(n);
	int len = n->nlmsg_len;
	int deprecated = 0;
	/* Use local copy of ifa_flags to not interfere with filtering code */
	unsigned int ifa_flags;
	struct rtattr * rta_tb[IFA_MAX+1];
	char abuf[256];
	SPRINT_BUF(b1);

	if (n->nlmsg_type != RTM_NEWADDR && n->nlmsg_type != RTM_DELADDR)
		return 0;
	len -= NLMSG_LENGTH(sizeof(*ifa));
	if (len < 0) {
		fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
		return -1;
	}

	if (filter.flushb && n->nlmsg_type != RTM_NEWADDR)
		return 0;

	parse_rtattr(rta_tb, IFA_MAX, IFA_RTA(ifa),
		     n->nlmsg_len - NLMSG_LENGTH(sizeof(*ifa)));

	ifa_flags = get_ifa_flags(ifa, rta_tb[IFA_FLAGS]);

	if (!rta_tb[IFA_LOCAL])
		rta_tb[IFA_LOCAL] = rta_tb[IFA_ADDRESS];
	if (!rta_tb[IFA_ADDRESS])
		rta_tb[IFA_ADDRESS] = rta_tb[IFA_LOCAL];

	if (filter.ifindex && filter.ifindex != ifa->ifa_index)
		return 0;
	if ((filter.scope^ifa->ifa_scope)&filter.scopemask)
		return 0;
	if ((filter.flags ^ ifa_flags) & filter.flagmask)
		return 0;
	if (filter.label) {
		SPRINT_BUF(b1);
		const char *label;
		if (rta_tb[IFA_LABEL])
			label = RTA_DATA(rta_tb[IFA_LABEL]);
		else
			label = ll_idx_n2a(ifa->ifa_index, b1);
		if (fnmatch(filter.label, label, 0) != 0)
			return 0;
	}
	if (filter.pfx.family) {
		if (rta_tb[IFA_LOCAL]) {
			inet_prefix dst;
			memset(&dst, 0, sizeof(dst));
			dst.family = ifa->ifa_family;
			memcpy(&dst.data, RTA_DATA(rta_tb[IFA_LOCAL]), RTA_PAYLOAD(rta_tb[IFA_LOCAL]));
			if (inet_addr_match(&dst, &filter.pfx, filter.pfx.bitlen))
				return 0;
		}
	}

	if (filter.family && filter.family != ifa->ifa_family)
		return 0;

	if (filter.flushb) {
		struct nlmsghdr *fn;
		if (NLMSG_ALIGN(filter.flushp) + n->nlmsg_len > filter.flushe) {
			if (flush_update())
				return -1;
		}
		fn = (struct nlmsghdr*)(filter.flushb + NLMSG_ALIGN(filter.flushp));
		memcpy(fn, n, n->nlmsg_len);
		fn->nlmsg_type = RTM_DELADDR;
		fn->nlmsg_flags = NLM_F_REQUEST;
		fn->nlmsg_seq = ++rth.seq;
		filter.flushp = (((char*)fn) + n->nlmsg_len) - filter.flushb;
		filter.flushed++;
		if (show_stats < 2)
			return 0;
	}

	if (n->nlmsg_type == RTM_DELADDR)
		fprintf(fp, "Deleted ");

	if (!brief) {
		if (filter.oneline || filter.flushb)
			fprintf(fp, "%u: %s", ifa->ifa_index, ll_index_to_name(ifa->ifa_index));
		if (ifa->ifa_family == AF_INET)
			fprintf(fp, "    inet ");
		else if (ifa->ifa_family == AF_INET6)
			fprintf(fp, "    inet6 ");
		else if (ifa->ifa_family == AF_DECnet)
			fprintf(fp, "    dnet ");
		else if (ifa->ifa_family == AF_IPX)
			fprintf(fp, "     ipx ");
		else
			fprintf(fp, "    family %d ", ifa->ifa_family);
	}

	if (rta_tb[IFA_LOCAL]) {
		if (ifa->ifa_family == AF_INET)
			color_fprintf(fp, COLOR_INET, "%s", format_host(ifa->ifa_family,
						RTA_PAYLOAD(rta_tb[IFA_LOCAL]),
						RTA_DATA(rta_tb[IFA_LOCAL]),
						abuf, sizeof(abuf)));
		else if (ifa->ifa_family == AF_INET6)
			color_fprintf(fp, COLOR_INET6, "%s", format_host(ifa->ifa_family,
						RTA_PAYLOAD(rta_tb[IFA_LOCAL]),
						RTA_DATA(rta_tb[IFA_LOCAL]),
						abuf, sizeof(abuf)));
		else
			fprintf(fp, "%s", format_host(ifa->ifa_family,
						RTA_PAYLOAD(rta_tb[IFA_LOCAL]),
						RTA_DATA(rta_tb[IFA_LOCAL]),
						abuf, sizeof(abuf)));

		if (rta_tb[IFA_ADDRESS] == NULL ||
		    memcmp(RTA_DATA(rta_tb[IFA_ADDRESS]), RTA_DATA(rta_tb[IFA_LOCAL]),
			   ifa->ifa_family == AF_INET ? 4 : 16) == 0) {
			fprintf(fp, "/%d ", ifa->ifa_prefixlen);
		} else {
			fprintf(fp, " peer %s/%d ",
				format_host(ifa->ifa_family,
					    RTA_PAYLOAD(rta_tb[IFA_ADDRESS]),
					    RTA_DATA(rta_tb[IFA_ADDRESS]),
					    abuf, sizeof(abuf)),
				ifa->ifa_prefixlen);
		}
	}

	if (brief)
		goto brief_exit;

	if (rta_tb[IFA_BROADCAST]) {
		fprintf(fp, "brd %s ",
			format_host(ifa->ifa_family,
				    RTA_PAYLOAD(rta_tb[IFA_BROADCAST]),
				    RTA_DATA(rta_tb[IFA_BROADCAST]),
				    abuf, sizeof(abuf)));
	}
	if (rta_tb[IFA_ANYCAST]) {
		fprintf(fp, "any %s ",
			format_host(ifa->ifa_family,
				    RTA_PAYLOAD(rta_tb[IFA_ANYCAST]),
				    RTA_DATA(rta_tb[IFA_ANYCAST]),
				    abuf, sizeof(abuf)));
	}
	fprintf(fp, "scope %s ", rtnl_rtscope_n2a(ifa->ifa_scope, b1, sizeof(b1)));
	if (ifa_flags & IFA_F_SECONDARY) {
		ifa_flags &= ~IFA_F_SECONDARY;
		if (ifa->ifa_family == AF_INET6)
			fprintf(fp, "temporary ");
		else
			fprintf(fp, "secondary ");
	}
	if (ifa_flags & IFA_F_TENTATIVE) {
		ifa_flags &= ~IFA_F_TENTATIVE;
		fprintf(fp, "tentative ");
	}
	if (ifa_flags & IFA_F_DEPRECATED) {
		ifa_flags &= ~IFA_F_DEPRECATED;
		deprecated = 1;
		fprintf(fp, "deprecated ");
	}
	if (ifa_flags & IFA_F_HOMEADDRESS) {
		ifa_flags &= ~IFA_F_HOMEADDRESS;
		fprintf(fp, "home ");
	}
	if (ifa_flags & IFA_F_NODAD) {
		ifa_flags &= ~IFA_F_NODAD;
		fprintf(fp, "nodad ");
	}
	if (ifa_flags & IFA_F_MANAGETEMPADDR) {
		ifa_flags &= ~IFA_F_MANAGETEMPADDR;
		fprintf(fp, "mngtmpaddr ");
	}
	if (ifa_flags & IFA_F_NOPREFIXROUTE) {
		ifa_flags &= ~IFA_F_NOPREFIXROUTE;
		fprintf(fp, "noprefixroute ");
	}
	if (ifa_flags & IFA_F_MCAUTOJOIN) {
		ifa_flags &= ~IFA_F_MCAUTOJOIN;
		fprintf(fp, "autojoin ");
	}
	if (!(ifa_flags & IFA_F_PERMANENT)) {
		fprintf(fp, "dynamic ");
	} else
		ifa_flags &= ~IFA_F_PERMANENT;
	if (ifa_flags & IFA_F_DADFAILED) {
		ifa_flags &= ~IFA_F_DADFAILED;
		fprintf(fp, "dadfailed ");
	}
	if (ifa_flags)
		fprintf(fp, "flags %02x ", ifa_flags);
	if (rta_tb[IFA_LABEL])
		fprintf(fp, "%s", rta_getattr_str(rta_tb[IFA_LABEL]));
	if (rta_tb[IFA_CACHEINFO]) {
		struct ifa_cacheinfo *ci = RTA_DATA(rta_tb[IFA_CACHEINFO]);
		fprintf(fp, "%s", _SL_);
		fprintf(fp, "       valid_lft ");
		if (ci->ifa_valid == INFINITY_LIFE_TIME)
			fprintf(fp, "forever");
		else
			fprintf(fp, "%usec", ci->ifa_valid);
		fprintf(fp, " preferred_lft ");
		if (ci->ifa_prefered == INFINITY_LIFE_TIME)
			fprintf(fp, "forever");
		else {
			if (deprecated)
				fprintf(fp, "%dsec", ci->ifa_prefered);
			else
				fprintf(fp, "%usec", ci->ifa_prefered);
		}
	}
	fprintf(fp, "\n");
brief_exit:
	fflush(fp);
	return 0;
}

struct nlmsg_list
{
	struct nlmsg_list *next;
	struct nlmsghdr	  h;
};

struct nlmsg_chain
{
	struct nlmsg_list *head;
	struct nlmsg_list *tail;
};

static int print_selected_addrinfo(struct ifinfomsg *ifi,
				   struct nlmsg_list *ainfo, FILE *fp)
{
	for ( ;ainfo ;  ainfo = ainfo->next) {
		struct nlmsghdr *n = &ainfo->h;
		struct ifaddrmsg *ifa = NLMSG_DATA(n);

		if (n->nlmsg_type != RTM_NEWADDR)
			continue;

		if (n->nlmsg_len < NLMSG_LENGTH(sizeof(ifa)))
			return -1;

		if (ifa->ifa_index != ifi->ifi_index ||
		    (filter.family && filter.family != ifa->ifa_family))
			continue;

		if (filter.up && !(ifi->ifi_flags&IFF_UP))
			continue;

		print_addrinfo(NULL, n, fp);
	}
	if (brief) {
		fprintf(fp, "\n");
		fflush(fp);
	}
	return 0;
}


static int store_nlmsg(const struct sockaddr_nl *who, struct nlmsghdr *n,
		       void *arg)
{
	struct nlmsg_chain *lchain = (struct nlmsg_chain *)arg;
	struct nlmsg_list *h;

	h = malloc(n->nlmsg_len+sizeof(void*));
	if (h == NULL)
		return -1;

	memcpy(&h->h, n, n->nlmsg_len);
	h->next = NULL;

	if (lchain->tail)
		lchain->tail->next = h;
	else
		lchain->head = h;
	lchain->tail = h;

	ll_remember_index(who, n, NULL);
	return 0;
}

static __u32 ipadd_dump_magic = 0x47361222;

static int ipadd_save_prep(void)
{
	int ret;

	if (isatty(STDOUT_FILENO)) {
		fprintf(stderr, "Not sending a binary stream to stdout\n");
		return -1;
	}

	ret = write(STDOUT_FILENO, &ipadd_dump_magic, sizeof(ipadd_dump_magic));
	if (ret != sizeof(ipadd_dump_magic)) {
		fprintf(stderr, "Can't write magic to dump file\n");
		return -1;
	}

	return 0;
}

static int ipadd_dump_check_magic(void)
{
	int ret;
	__u32 magic = 0;

	if (isatty(STDIN_FILENO)) {
		fprintf(stderr, "Can't restore address dump from a terminal\n");
		return -1;
	}

	ret = fread(&magic, sizeof(magic), 1, stdin);
	if (magic != ipadd_dump_magic) {
		fprintf(stderr, "Magic mismatch (%d elems, %x magic)\n", ret, magic);
		return -1;
	}

	return 0;
}

static int save_nlmsg(const struct sockaddr_nl *who, struct nlmsghdr *n,
		       void *arg)
{
	int ret;

	ret = write(STDOUT_FILENO, n, n->nlmsg_len);
	if ((ret > 0) && (ret != n->nlmsg_len)) {
		fprintf(stderr, "Short write while saving nlmsg\n");
		ret = -EIO;
	}

	return ret == n->nlmsg_len ? 0 : ret;
}

static int show_handler(const struct sockaddr_nl *nl,
			struct rtnl_ctrl_data *ctrl,
			struct nlmsghdr *n, void *arg)
{
	struct ifaddrmsg *ifa = NLMSG_DATA(n);

	printf("if%d:\n", ifa->ifa_index);
	print_addrinfo(NULL, n, stdout);
	return 0;
}

static int ipaddr_showdump(void)
{
	if (ipadd_dump_check_magic())
		exit(-1);

	exit(rtnl_from_file(stdin, &show_handler, NULL));
}

static int restore_handler(const struct sockaddr_nl *nl,
			   struct rtnl_ctrl_data *ctrl,
			   struct nlmsghdr *n, void *arg)
{
	int ret;

	n->nlmsg_flags |= NLM_F_REQUEST | NLM_F_CREATE | NLM_F_ACK;

	ll_init_map(&rth);

	ret = rtnl_talk(&rth, n, n, sizeof(*n));
	if ((ret < 0) && (errno == EEXIST))
		ret = 0;

	return ret;
}

static int ipaddr_restore(void)
{
	if (ipadd_dump_check_magic())
		exit(-1);

	exit(rtnl_from_file(stdin, &restore_handler, NULL));
}

static void free_nlmsg_chain(struct nlmsg_chain *info)
{
	struct nlmsg_list *l, *n;

	for (l = info->head; l; l = n) {
		n = l->next;
		free(l);
	}
}

static void ipaddr_filter(struct nlmsg_chain *linfo, struct nlmsg_chain *ainfo)
{
	struct nlmsg_list *l, **lp;

	lp = &linfo->head;
	while ( (l = *lp) != NULL) {
		int ok = 0;
		int missing_net_address = 1;
		struct ifinfomsg *ifi = NLMSG_DATA(&l->h);
		struct nlmsg_list *a;

		for (a = ainfo->head; a; a = a->next) {
			struct nlmsghdr *n = &a->h;
			struct ifaddrmsg *ifa = NLMSG_DATA(n);
			struct rtattr *tb[IFA_MAX + 1];
			unsigned int ifa_flags;

			if (ifa->ifa_index != ifi->ifi_index)
				continue;
			missing_net_address = 0;
			if (filter.family && filter.family != ifa->ifa_family)
				continue;
			if ((filter.scope^ifa->ifa_scope)&filter.scopemask)
				continue;

			parse_rtattr(tb, IFA_MAX, IFA_RTA(ifa), IFA_PAYLOAD(n));
			ifa_flags = get_ifa_flags(ifa, tb[IFA_FLAGS]);

			if ((filter.flags ^ ifa_flags) & filter.flagmask)
				continue;
			if (filter.pfx.family || filter.label) {
				if (!tb[IFA_LOCAL])
					tb[IFA_LOCAL] = tb[IFA_ADDRESS];

				if (filter.pfx.family && tb[IFA_LOCAL]) {
					inet_prefix dst;
					memset(&dst, 0, sizeof(dst));
					dst.family = ifa->ifa_family;
					memcpy(&dst.data, RTA_DATA(tb[IFA_LOCAL]), RTA_PAYLOAD(tb[IFA_LOCAL]));
					if (inet_addr_match(&dst, &filter.pfx, filter.pfx.bitlen))
						continue;
				}
				if (filter.label) {
					SPRINT_BUF(b1);
					const char *label;
					if (tb[IFA_LABEL])
						label = RTA_DATA(tb[IFA_LABEL]);
					else
						label = ll_idx_n2a(ifa->ifa_index, b1);
					if (fnmatch(filter.label, label, 0) != 0)
						continue;
				}
			}

			ok = 1;
			break;
		}
		if (missing_net_address &&
		    (filter.family == AF_UNSPEC || filter.family == AF_PACKET))
			ok = 1;
		if (!ok) {
			*lp = l->next;
			free(l);
		} else
			lp = &l->next;
	}
}

static int ipaddr_flush(void)
{
	int round = 0;
	char flushb[4096-512];

	filter.flushb = flushb;
	filter.flushp = 0;
	filter.flushe = sizeof(flushb);

	while ((max_flush_loops == 0) || (round < max_flush_loops)) {
		if (rtnl_wilddump_request(&rth, filter.family, RTM_GETADDR) < 0) {
			perror("Cannot send dump request");
			exit(1);
		}
		filter.flushed = 0;
		if (rtnl_dump_filter_nc(&rth, print_addrinfo,
					stdout, NLM_F_DUMP_INTR) < 0) {
			fprintf(stderr, "Flush terminated\n");
			exit(1);
		}
		if (filter.flushed == 0) {
 flush_done:
			if (show_stats) {
				if (round == 0)
					printf("Nothing to flush.\n");
				else
					printf("*** Flush is complete after %d round%s ***\n", round, round>1?"s":"");
			}
			fflush(stdout);
			return 0;
		}
		round++;
		if (flush_update() < 0)
			return 1;

		if (show_stats) {
			printf("\n*** Round %d, deleting %d addresses ***\n", round, filter.flushed);
			fflush(stdout);
		}

		/* If we are flushing, and specifying primary, then we
		 * want to flush only a single round.  Otherwise, we'll
		 * start flushing secondaries that were promoted to
		 * primaries.
		 */
		if (!(filter.flags & IFA_F_SECONDARY) && (filter.flagmask & IFA_F_SECONDARY))
			goto flush_done;
	}
	fprintf(stderr, "*** Flush remains incomplete after %d rounds. ***\n", max_flush_loops);
	fflush(stderr);
	return 1;
}

static int ipaddr_list_flush_or_save(int argc, char **argv, int action)
{
	struct nlmsg_chain linfo = { NULL, NULL};
	struct nlmsg_chain ainfo = { NULL, NULL};
	struct nlmsg_list *l;
	char *filter_dev = NULL;
	int no_link = 0;

	ipaddr_reset_filter(oneline, 0);
	filter.showqueue = 1;
	filter.family = preferred_family;
	filter.group = -1;

	if (action == IPADD_FLUSH) {
		if (argc <= 0) {
			fprintf(stderr, "Flush requires arguments.\n");

			return -1;
		}
		if (filter.family == AF_PACKET) {
			fprintf(stderr, "Cannot flush link addresses.\n");
			return -1;
		}
	}

	while (argc > 0) {
		if (strcmp(*argv, "to") == 0) {
			NEXT_ARG();
			get_prefix(&filter.pfx, *argv, filter.family);
			if (filter.family == AF_UNSPEC)
				filter.family = filter.pfx.family;
		} else if (strcmp(*argv, "scope") == 0) {
			unsigned scope = 0;
			NEXT_ARG();
			filter.scopemask = -1;
			if (rtnl_rtscope_a2n(&scope, *argv)) {
				if (strcmp(*argv, "all") != 0)
					invarg("invalid \"scope\"\n", *argv);
				scope = RT_SCOPE_NOWHERE;
				filter.scopemask = 0;
			}
			filter.scope = scope;
		} else if (strcmp(*argv, "up") == 0) {
			filter.up = 1;
		} else if (strcmp(*argv, "dynamic") == 0) {
			filter.flags &= ~IFA_F_PERMANENT;
			filter.flagmask |= IFA_F_PERMANENT;
		} else if (strcmp(*argv, "permanent") == 0) {
			filter.flags |= IFA_F_PERMANENT;
			filter.flagmask |= IFA_F_PERMANENT;
		} else if (strcmp(*argv, "secondary") == 0 ||
			   strcmp(*argv, "temporary") == 0) {
			filter.flags |= IFA_F_SECONDARY;
			filter.flagmask |= IFA_F_SECONDARY;
		} else if (strcmp(*argv, "primary") == 0) {
			filter.flags &= ~IFA_F_SECONDARY;
			filter.flagmask |= IFA_F_SECONDARY;
		} else if (strcmp(*argv, "tentative") == 0) {
			filter.flags |= IFA_F_TENTATIVE;
			filter.flagmask |= IFA_F_TENTATIVE;
		} else if (strcmp(*argv, "-tentative") == 0) {
			filter.flags &= ~IFA_F_TENTATIVE;
			filter.flagmask |= IFA_F_TENTATIVE;
		} else if (strcmp(*argv, "deprecated") == 0) {
			filter.flags |= IFA_F_DEPRECATED;
			filter.flagmask |= IFA_F_DEPRECATED;
		} else if (strcmp(*argv, "-deprecated") == 0) {
			filter.flags &= ~IFA_F_DEPRECATED;
			filter.flagmask |= IFA_F_DEPRECATED;
		} else if (strcmp(*argv, "home") == 0) {
			filter.flags |= IFA_F_HOMEADDRESS;
			filter.flagmask |= IFA_F_HOMEADDRESS;
		} else if (strcmp(*argv, "nodad") == 0) {
			filter.flags |= IFA_F_NODAD;
			filter.flagmask |= IFA_F_NODAD;
		} else if (strcmp(*argv, "mngtmpaddr") == 0) {
			filter.flags |= IFA_F_MANAGETEMPADDR;
			filter.flagmask |= IFA_F_MANAGETEMPADDR;
		} else if (strcmp(*argv, "noprefixroute") == 0) {
			filter.flags |= IFA_F_NOPREFIXROUTE;
			filter.flagmask |= IFA_F_NOPREFIXROUTE;
		} else if (strcmp(*argv, "autojoin") == 0) {
			filter.flags |= IFA_F_MCAUTOJOIN;
			filter.flagmask |= IFA_F_MCAUTOJOIN;
		} else if (strcmp(*argv, "dadfailed") == 0) {
			filter.flags |= IFA_F_DADFAILED;
			filter.flagmask |= IFA_F_DADFAILED;
		} else if (strcmp(*argv, "-dadfailed") == 0) {
			filter.flags &= ~IFA_F_DADFAILED;
			filter.flagmask |= IFA_F_DADFAILED;
		} else if (strcmp(*argv, "label") == 0) {
			NEXT_ARG();
			filter.label = *argv;
		} else if (strcmp(*argv, "group") == 0) {
			NEXT_ARG();
			if (rtnl_group_a2n(&filter.group, *argv))
				invarg("Invalid \"group\" value\n", *argv);
		} else if (strcmp(*argv, "master") == 0) {
			int ifindex;
			NEXT_ARG();
			ifindex = ll_name_to_index(*argv);
			if (!ifindex)
				invarg("Device does not exist\n", *argv);
			filter.master = ifindex;
		} else if (do_link && strcmp(*argv, "type") == 0) {
			NEXT_ARG();
			filter.kind = *argv;
		} else {
			if (strcmp(*argv, "dev") == 0) {
				NEXT_ARG();
			}
			else if (matches(*argv, "help") == 0)
				usage();
			if (filter_dev)
				duparg2("dev", *argv);
			filter_dev = *argv;
		}
		argv++; argc--;
	}

	if (filter_dev) {
		filter.ifindex = ll_name_to_index(filter_dev);
		if (filter.ifindex <= 0) {
			fprintf(stderr, "Device \"%s\" does not exist.\n", filter_dev);
			return -1;
		}
	}

	if (action == IPADD_FLUSH)
		return ipaddr_flush();

	if (action == IPADD_SAVE) {
		if (ipadd_save_prep())
			exit(1);

		if (rtnl_wilddump_request(&rth, preferred_family, RTM_GETADDR) < 0) {
			perror("Cannot send dump request");
			exit(1);
		}

		if (rtnl_dump_filter(&rth, save_nlmsg, stdout) < 0) {
			fprintf(stderr, "Save terminated\n");
			exit(1);
		}

		exit(0);
	}

	/*
	 * If only filter_dev present and none of the other
	 * link filters are present, use RTM_GETLINK to get
	 * the link device
	 */
	if (filter_dev && filter.group == -1 && do_link == 1) {
		if (iplink_get(0, filter_dev, RTEXT_FILTER_VF) < 0) {
			perror("Cannot send link get request");
			exit(1);
		}
		exit(0);
	}

	if (rtnl_wilddump_request(&rth, preferred_family, RTM_GETLINK) < 0) {
		perror("Cannot send dump request");
		exit(1);
	}

	if (rtnl_dump_filter(&rth, store_nlmsg, &linfo) < 0) {
		fprintf(stderr, "Dump terminated\n");
		exit(1);
	}

	if (filter.family != AF_PACKET) {
		if (filter.oneline)
			no_link = 1;

		if (rtnl_wilddump_request(&rth, filter.family, RTM_GETADDR) < 0) {
			perror("Cannot send dump request");
			exit(1);
		}

		if (rtnl_dump_filter(&rth, store_nlmsg, &ainfo) < 0) {
			fprintf(stderr, "Dump terminated\n");
			exit(1);
		}

		ipaddr_filter(&linfo, &ainfo);
	}

	for (l = linfo.head; l; l = l->next) {
		int res = 0;
		struct ifinfomsg *ifi = NLMSG_DATA(&l->h);

		if (brief) {
			if (print_linkinfo_brief(NULL, &l->h, stdout) == 0)
				if (filter.family != AF_PACKET)
					print_selected_addrinfo(ifi,
								ainfo.head,
								stdout);
		} else if (no_link ||
			 (res = print_linkinfo(NULL, &l->h, stdout)) >= 0) {
			if (filter.family != AF_PACKET)
				print_selected_addrinfo(ifi,
							ainfo.head, stdout);
			if (res > 0 && !do_link && show_stats)
				print_link_stats(stdout, &l->h);
		}
	}
	fflush(stdout);

	free_nlmsg_chain(&ainfo);
	free_nlmsg_chain(&linfo);

	return 0;
}

static void
ipaddr_loop_each_vf(struct rtattr *tb[], int vfnum, int *min, int *max)
{
	struct rtattr *vflist = tb[IFLA_VFINFO_LIST];
	struct rtattr *i, *vf[IFLA_VF_MAX+1];
	struct ifla_vf_rate *vf_rate;
	int rem;

	rem = RTA_PAYLOAD(vflist);

	for (i = RTA_DATA(vflist); RTA_OK(i, rem); i = RTA_NEXT(i, rem)) {
		parse_rtattr_nested(vf, IFLA_VF_MAX, i);
		vf_rate = RTA_DATA(vf[IFLA_VF_RATE]);
		if (vf_rate->vf == vfnum) {
			*min = vf_rate->min_tx_rate;
			*max = vf_rate->max_tx_rate;
			return;
		}
	}
	fprintf(stderr, "Cannot find VF %d\n", vfnum);
	exit(1);
}

void ipaddr_get_vf_rate(int vfnum, int *min, int *max, int idx)
{
	struct nlmsg_chain linfo = { NULL, NULL};
	struct rtattr *tb[IFLA_MAX+1];
	struct ifinfomsg *ifi;
	struct nlmsg_list *l;
	struct nlmsghdr *n;
	int len;

	if (rtnl_wilddump_request(&rth, AF_UNSPEC, RTM_GETLINK) < 0) {
		perror("Cannot send dump request");
		exit(1);
	}
	if (rtnl_dump_filter(&rth, store_nlmsg, &linfo) < 0) {
		fprintf(stderr, "Dump terminated\n");
		exit(1);
	}
	for (l = linfo.head; l; l = l->next) {
		n = &l->h;
		ifi = NLMSG_DATA(n);

		len = n->nlmsg_len - NLMSG_LENGTH(sizeof(*ifi));
		if (len < 0 || (idx && idx != ifi->ifi_index))
			continue;

		parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);

		if ((tb[IFLA_VFINFO_LIST] && tb[IFLA_NUM_VF])) {
			ipaddr_loop_each_vf(tb, vfnum, min, max);
			return;
		}
	}
}

int ipaddr_list_link(int argc, char **argv)
{
	preferred_family = AF_PACKET;
	do_link = 1;
	return ipaddr_list_flush_or_save(argc, argv, IPADD_LIST);
}

void ipaddr_reset_filter(int oneline, int ifindex)
{
	memset(&filter, 0, sizeof(filter));
	filter.oneline = oneline;
	filter.ifindex = ifindex;
}

static int default_scope(inet_prefix *lcl)
{
	if (lcl->family == AF_INET) {
		if (lcl->bytelen >= 1 && *(__u8*)&lcl->data == 127)
			return RT_SCOPE_HOST;
	}
	return 0;
}

static bool ipaddr_is_multicast(inet_prefix *a)
{
	if (a->family == AF_INET)
		return IN_MULTICAST(ntohl(a->data[0]));
	else if (a->family == AF_INET6)
		return IN6_IS_ADDR_MULTICAST(a->data);
	else
		return false;
}

static int ipaddr_modify(int cmd, int flags, int argc, char **argv)
{
	struct {
		struct nlmsghdr	n;
		struct ifaddrmsg	ifa;
		char			buf[256];
	} req;
	char  *d = NULL;
	char  *l = NULL;
	char  *lcl_arg = NULL;
	char  *valid_lftp = NULL;
	char  *preferred_lftp = NULL;
	inet_prefix lcl;
	inet_prefix peer;
	int local_len = 0;
	int peer_len = 0;
	int brd_len = 0;
	int any_len = 0;
	int scoped = 0;
	__u32 preferred_lft = INFINITY_LIFE_TIME;
	__u32 valid_lft = INFINITY_LIFE_TIME;
	struct ifa_cacheinfo cinfo;
	unsigned int ifa_flags = 0;

	memset(&req, 0, sizeof(req));

	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
	req.n.nlmsg_flags = NLM_F_REQUEST | flags;
	req.n.nlmsg_type = cmd;
	req.ifa.ifa_family = preferred_family;

	while (argc > 0) {
		if (strcmp(*argv, "peer") == 0 ||
		    strcmp(*argv, "remote") == 0) {
			NEXT_ARG();

			if (peer_len)
				duparg("peer", *argv);
			get_prefix(&peer, *argv, req.ifa.ifa_family);
			peer_len = peer.bytelen;
			if (req.ifa.ifa_family == AF_UNSPEC)
				req.ifa.ifa_family = peer.family;
			addattr_l(&req.n, sizeof(req), IFA_ADDRESS, &peer.data, peer.bytelen);
			req.ifa.ifa_prefixlen = peer.bitlen;
		} else if (matches(*argv, "broadcast") == 0 ||
			   strcmp(*argv, "brd") == 0) {
			inet_prefix addr;
			NEXT_ARG();
			if (brd_len)
				duparg("broadcast", *argv);
			if (strcmp(*argv, "+") == 0)
				brd_len = -1;
			else if (strcmp(*argv, "-") == 0)
				brd_len = -2;
			else {
				get_addr(&addr, *argv, req.ifa.ifa_family);
				if (req.ifa.ifa_family == AF_UNSPEC)
					req.ifa.ifa_family = addr.family;
				addattr_l(&req.n, sizeof(req), IFA_BROADCAST, &addr.data, addr.bytelen);
				brd_len = addr.bytelen;
			}
		} else if (strcmp(*argv, "anycast") == 0) {
			inet_prefix addr;
			NEXT_ARG();
			if (any_len)
				duparg("anycast", *argv);
			get_addr(&addr, *argv, req.ifa.ifa_family);
			if (req.ifa.ifa_family == AF_UNSPEC)
				req.ifa.ifa_family = addr.family;
			addattr_l(&req.n, sizeof(req), IFA_ANYCAST, &addr.data, addr.bytelen);
			any_len = addr.bytelen;
		} else if (strcmp(*argv, "scope") == 0) {
			unsigned scope = 0;
			NEXT_ARG();
			if (rtnl_rtscope_a2n(&scope, *argv))
				invarg("invalid scope value.", *argv);
			req.ifa.ifa_scope = scope;
			scoped = 1;
		} else if (strcmp(*argv, "dev") == 0) {
			NEXT_ARG();
			d = *argv;
		} else if (strcmp(*argv, "label") == 0) {
			NEXT_ARG();
			l = *argv;
			addattr_l(&req.n, sizeof(req), IFA_LABEL, l, strlen(l)+1);
		} else if (matches(*argv, "valid_lft") == 0) {
			if (valid_lftp)
				duparg("valid_lft", *argv);
			NEXT_ARG();
			valid_lftp = *argv;
			if (set_lifetime(&valid_lft, *argv))
				invarg("valid_lft value", *argv);
		} else if (matches(*argv, "preferred_lft") == 0) {
			if (preferred_lftp)
				duparg("preferred_lft", *argv);
			NEXT_ARG();
			preferred_lftp = *argv;
			if (set_lifetime(&preferred_lft, *argv))
				invarg("preferred_lft value", *argv);
		} else if (strcmp(*argv, "home") == 0) {
			ifa_flags |= IFA_F_HOMEADDRESS;
		} else if (strcmp(*argv, "nodad") == 0) {
			ifa_flags |= IFA_F_NODAD;
		} else if (strcmp(*argv, "mngtmpaddr") == 0) {
			ifa_flags |= IFA_F_MANAGETEMPADDR;
		} else if (strcmp(*argv, "noprefixroute") == 0) {
			ifa_flags |= IFA_F_NOPREFIXROUTE;
		} else if (strcmp(*argv, "autojoin") == 0) {
			ifa_flags |= IFA_F_MCAUTOJOIN;
		} else {
			if (strcmp(*argv, "local") == 0) {
				NEXT_ARG();
			}
			if (matches(*argv, "help") == 0)
				usage();
			if (local_len)
				duparg2("local", *argv);
			lcl_arg = *argv;
			get_prefix(&lcl, *argv, req.ifa.ifa_family);
			if (req.ifa.ifa_family == AF_UNSPEC)
				req.ifa.ifa_family = lcl.family;
			addattr_l(&req.n, sizeof(req), IFA_LOCAL, &lcl.data, lcl.bytelen);
			local_len = lcl.bytelen;
		}
		argc--; argv++;
	}
	if (ifa_flags <= 0xff)
		req.ifa.ifa_flags = ifa_flags;
	else
		addattr32(&req.n, sizeof(req), IFA_FLAGS, ifa_flags);

	if (d == NULL) {
		fprintf(stderr, "Not enough information: \"dev\" argument is required.\n");
		return -1;
	}
	if (l && matches(d, l) != 0) {
		fprintf(stderr, "\"dev\" (%s) must match \"label\" (%s).\n", d, l);
		return -1;
	}

	if (peer_len == 0 && local_len) {
		if (cmd == RTM_DELADDR && lcl.family == AF_INET && !(lcl.flags & PREFIXLEN_SPECIFIED)) {
			fprintf(stderr,
			    "Warning: Executing wildcard deletion to stay compatible with old scripts.\n" \
			    "         Explicitly specify the prefix length (%s/%d) to avoid this warning.\n" \
			    "         This special behaviour is likely to disappear in further releases,\n" \
			    "         fix your scripts!\n", lcl_arg, local_len*8);
		} else {
			peer = lcl;
			addattr_l(&req.n, sizeof(req), IFA_ADDRESS, &lcl.data, lcl.bytelen);
		}
	}
	if (req.ifa.ifa_prefixlen == 0)
		req.ifa.ifa_prefixlen = lcl.bitlen;

	if (brd_len < 0 && cmd != RTM_DELADDR) {
		inet_prefix brd;
		int i;
		if (req.ifa.ifa_family != AF_INET) {
			fprintf(stderr, "Broadcast can be set only for IPv4 addresses\n");
			return -1;
		}
		brd = peer;
		if (brd.bitlen <= 30) {
			for (i = 31; i >= brd.bitlen; i--) {
				if (brd_len == -1)
					brd.data[0] |= htonl(1<<(31-i));
				else
					brd.data[0] &= ~htonl(1<<(31-i));
			}
			addattr_l(&req.n, sizeof(req), IFA_BROADCAST, &brd.data, brd.bytelen);
			brd_len = brd.bytelen;
		}
	}
	if (!scoped && cmd != RTM_DELADDR)
		req.ifa.ifa_scope = default_scope(&lcl);

	if ((req.ifa.ifa_index = ll_name_to_index(d)) == 0) {
		fprintf(stderr, "Cannot find device \"%s\"\n", d);
		return -1;
	}

	if (valid_lftp || preferred_lftp) {
		if (!valid_lft) {
			fprintf(stderr, "valid_lft is zero\n");
			return -1;
		}
		if (valid_lft < preferred_lft) {
			fprintf(stderr, "preferred_lft is greater than valid_lft\n");
			return -1;
		}

		memset(&cinfo, 0, sizeof(cinfo));
		cinfo.ifa_prefered = preferred_lft;
		cinfo.ifa_valid = valid_lft;
		addattr_l(&req.n, sizeof(req), IFA_CACHEINFO, &cinfo,
			  sizeof(cinfo));
	}

	if ((ifa_flags & IFA_F_MCAUTOJOIN) && !ipaddr_is_multicast(&lcl)) {
		fprintf(stderr, "autojoin needs multicast address\n");
		return -1;
	}

	if (rtnl_talk(&rth, &req.n, NULL, 0) < 0)
		return -2;

	return 0;
}

int do_ipaddr(int argc, char **argv)
{
	if (argc < 1)
		return ipaddr_list_flush_or_save(0, NULL, IPADD_LIST);
	if (matches(*argv, "add") == 0)
		return ipaddr_modify(RTM_NEWADDR, NLM_F_CREATE|NLM_F_EXCL, argc-1, argv+1);
	if (matches(*argv, "change") == 0 ||
		strcmp(*argv, "chg") == 0)
		return ipaddr_modify(RTM_NEWADDR, NLM_F_REPLACE, argc-1, argv+1);
	if (matches(*argv, "replace") == 0)
		return ipaddr_modify(RTM_NEWADDR, NLM_F_CREATE|NLM_F_REPLACE, argc-1, argv+1);
	if (matches(*argv, "delete") == 0)
		return ipaddr_modify(RTM_DELADDR, 0, argc-1, argv+1);
	if (matches(*argv, "list") == 0 || matches(*argv, "show") == 0
	    || matches(*argv, "lst") == 0)
		return ipaddr_list_flush_or_save(argc-1, argv+1, IPADD_LIST);
	if (matches(*argv, "flush") == 0)
		return ipaddr_list_flush_or_save(argc-1, argv+1, IPADD_FLUSH);
	if (matches(*argv, "save") == 0)
		return ipaddr_list_flush_or_save(argc-1, argv+1, IPADD_SAVE);
	if (matches(*argv, "showdump") == 0)
		return ipaddr_showdump();
	if (matches(*argv, "restore") == 0)
		return ipaddr_restore();
	if (matches(*argv, "help") == 0)
		usage();
	fprintf(stderr, "Command \"%s\" is unknown, try \"ip address help\".\n", *argv);
	exit(-1);
}
