1143969f24bc40e2a28e53d1008852188b8cd767ashemminger/*
2143969f24bc40e2a28e53d1008852188b8cd767ashemminger * Copyright (C)2006 USAGI/WIDE Project
3ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger *
4143969f24bc40e2a28e53d1008852188b8cd767ashemminger * This program is free software; you can redistribute it and/or modify
5143969f24bc40e2a28e53d1008852188b8cd767ashemminger * it under the terms of the GNU General Public License as published by
6143969f24bc40e2a28e53d1008852188b8cd767ashemminger * the Free Software Foundation; either version 2 of the License, or
7143969f24bc40e2a28e53d1008852188b8cd767ashemminger * (at your option) any later version.
8ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger *
9143969f24bc40e2a28e53d1008852188b8cd767ashemminger * This program is distributed in the hope that it will be useful,
10143969f24bc40e2a28e53d1008852188b8cd767ashemminger * but WITHOUT ANY WARRANTY; without even the implied warranty of
11143969f24bc40e2a28e53d1008852188b8cd767ashemminger * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12143969f24bc40e2a28e53d1008852188b8cd767ashemminger * GNU General Public License for more details.
13ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger *
14143969f24bc40e2a28e53d1008852188b8cd767ashemminger * You should have received a copy of the GNU General Public License
15143969f24bc40e2a28e53d1008852188b8cd767ashemminger * along with this program; if not, write to the Free Software
16143969f24bc40e2a28e53d1008852188b8cd767ashemminger * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17143969f24bc40e2a28e53d1008852188b8cd767ashemminger */
18143969f24bc40e2a28e53d1008852188b8cd767ashemminger/*
19143969f24bc40e2a28e53d1008852188b8cd767ashemminger * based on ipneigh.c
20143969f24bc40e2a28e53d1008852188b8cd767ashemminger */
21143969f24bc40e2a28e53d1008852188b8cd767ashemminger/*
22143969f24bc40e2a28e53d1008852188b8cd767ashemminger * Authors:
23143969f24bc40e2a28e53d1008852188b8cd767ashemminger *	Masahide NAKAMURA @USAGI
24143969f24bc40e2a28e53d1008852188b8cd767ashemminger */
25143969f24bc40e2a28e53d1008852188b8cd767ashemminger
26143969f24bc40e2a28e53d1008852188b8cd767ashemminger#include <stdio.h>
27143969f24bc40e2a28e53d1008852188b8cd767ashemminger#include <stdlib.h>
28143969f24bc40e2a28e53d1008852188b8cd767ashemminger#include <string.h>
29143969f24bc40e2a28e53d1008852188b8cd767ashemminger#include <sys/time.h>
30143969f24bc40e2a28e53d1008852188b8cd767ashemminger#include <time.h>
31143969f24bc40e2a28e53d1008852188b8cd767ashemminger
32143969f24bc40e2a28e53d1008852188b8cd767ashemminger#include "utils.h"
33143969f24bc40e2a28e53d1008852188b8cd767ashemminger#include "ip_common.h"
34143969f24bc40e2a28e53d1008852188b8cd767ashemminger
35143969f24bc40e2a28e53d1008852188b8cd767ashemmingerstatic struct
36143969f24bc40e2a28e53d1008852188b8cd767ashemminger{
37143969f24bc40e2a28e53d1008852188b8cd767ashemminger	int family;
38143969f24bc40e2a28e53d1008852188b8cd767ashemminger        int index;
39143969f24bc40e2a28e53d1008852188b8cd767ashemminger#define NONE_DEV	(-1)
40143969f24bc40e2a28e53d1008852188b8cd767ashemminger	char name[1024];
41143969f24bc40e2a28e53d1008852188b8cd767ashemminger} filter;
42143969f24bc40e2a28e53d1008852188b8cd767ashemminger
43143969f24bc40e2a28e53d1008852188b8cd767ashemmingerstatic void usage(void) __attribute__((noreturn));
44143969f24bc40e2a28e53d1008852188b8cd767ashemminger
45143969f24bc40e2a28e53d1008852188b8cd767ashemmingerstatic void usage(void)
46143969f24bc40e2a28e53d1008852188b8cd767ashemminger{
47143969f24bc40e2a28e53d1008852188b8cd767ashemminger	fprintf(stderr,
48143969f24bc40e2a28e53d1008852188b8cd767ashemminger		"Usage: ip ntable change name NAME [ dev DEV ]\n"
49143969f24bc40e2a28e53d1008852188b8cd767ashemminger		"          [ thresh1 VAL ] [ thresh2 VAL ] [ thresh3 VAL ] [ gc_int MSEC ]\n"
50143969f24bc40e2a28e53d1008852188b8cd767ashemminger		"          [ PARMS ]\n"
51143969f24bc40e2a28e53d1008852188b8cd767ashemminger		"Usage: ip ntable show [ dev DEV ] [ name NAME ]\n"
52143969f24bc40e2a28e53d1008852188b8cd767ashemminger
53143969f24bc40e2a28e53d1008852188b8cd767ashemminger		"PARMS := [ base_reachable MSEC ] [ retrans MSEC ] [ gc_stale MSEC ]\n"
54143969f24bc40e2a28e53d1008852188b8cd767ashemminger		"         [ delay_probe MSEC ] [ queue LEN ]\n"
55143969f24bc40e2a28e53d1008852188b8cd767ashemminger		"         [ app_probs VAL ] [ ucast_probes VAL ] [ mcast_probes VAL ]\n"
56143969f24bc40e2a28e53d1008852188b8cd767ashemminger		"         [ anycast_delay MSEC ] [ proxy_delay MSEC ] [ proxy_queue LEN ]\n"
57143969f24bc40e2a28e53d1008852188b8cd767ashemminger		"         [ locktime MSEC ]\n"
58143969f24bc40e2a28e53d1008852188b8cd767ashemminger		);
59143969f24bc40e2a28e53d1008852188b8cd767ashemminger
60143969f24bc40e2a28e53d1008852188b8cd767ashemminger	exit(-1);
61143969f24bc40e2a28e53d1008852188b8cd767ashemminger}
62143969f24bc40e2a28e53d1008852188b8cd767ashemminger
63143969f24bc40e2a28e53d1008852188b8cd767ashemmingerstatic int ipntable_modify(int cmd, int flags, int argc, char **argv)
64143969f24bc40e2a28e53d1008852188b8cd767ashemminger{
65143969f24bc40e2a28e53d1008852188b8cd767ashemminger	struct {
66143969f24bc40e2a28e53d1008852188b8cd767ashemminger		struct nlmsghdr 	n;
67143969f24bc40e2a28e53d1008852188b8cd767ashemminger		struct ndtmsg		ndtm;
68143969f24bc40e2a28e53d1008852188b8cd767ashemminger		char   			buf[1024];
69143969f24bc40e2a28e53d1008852188b8cd767ashemminger	} req;
70143969f24bc40e2a28e53d1008852188b8cd767ashemminger	char *namep = NULL;
71143969f24bc40e2a28e53d1008852188b8cd767ashemminger	char *threshsp = NULL;
72143969f24bc40e2a28e53d1008852188b8cd767ashemminger	char *gc_intp = NULL;
73143969f24bc40e2a28e53d1008852188b8cd767ashemminger	char parms_buf[1024];
74143969f24bc40e2a28e53d1008852188b8cd767ashemminger	struct rtattr *parms_rta = (struct rtattr *)parms_buf;
75143969f24bc40e2a28e53d1008852188b8cd767ashemminger	int parms_change = 0;
76143969f24bc40e2a28e53d1008852188b8cd767ashemminger
77143969f24bc40e2a28e53d1008852188b8cd767ashemminger	memset(&req, 0, sizeof(req));
78143969f24bc40e2a28e53d1008852188b8cd767ashemminger
79143969f24bc40e2a28e53d1008852188b8cd767ashemminger	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ndtmsg));
80143969f24bc40e2a28e53d1008852188b8cd767ashemminger	req.n.nlmsg_flags = NLM_F_REQUEST|flags;
81143969f24bc40e2a28e53d1008852188b8cd767ashemminger	req.n.nlmsg_type = cmd;
82143969f24bc40e2a28e53d1008852188b8cd767ashemminger
83143969f24bc40e2a28e53d1008852188b8cd767ashemminger	req.ndtm.ndtm_family = preferred_family;
84143969f24bc40e2a28e53d1008852188b8cd767ashemminger	req.ndtm.ndtm_pad1 = 0;
85143969f24bc40e2a28e53d1008852188b8cd767ashemminger	req.ndtm.ndtm_pad2 = 0;
86143969f24bc40e2a28e53d1008852188b8cd767ashemminger
87143969f24bc40e2a28e53d1008852188b8cd767ashemminger	memset(&parms_buf, 0, sizeof(parms_buf));
88143969f24bc40e2a28e53d1008852188b8cd767ashemminger
89143969f24bc40e2a28e53d1008852188b8cd767ashemminger	parms_rta->rta_type = NDTA_PARMS;
90143969f24bc40e2a28e53d1008852188b8cd767ashemminger	parms_rta->rta_len = RTA_LENGTH(0);
91143969f24bc40e2a28e53d1008852188b8cd767ashemminger
92143969f24bc40e2a28e53d1008852188b8cd767ashemminger	while (argc > 0) {
93143969f24bc40e2a28e53d1008852188b8cd767ashemminger		if (strcmp(*argv, "name") == 0) {
94143969f24bc40e2a28e53d1008852188b8cd767ashemminger			int len;
95143969f24bc40e2a28e53d1008852188b8cd767ashemminger
96143969f24bc40e2a28e53d1008852188b8cd767ashemminger			NEXT_ARG();
97143969f24bc40e2a28e53d1008852188b8cd767ashemminger			if (namep)
98143969f24bc40e2a28e53d1008852188b8cd767ashemminger				duparg("NAME", *argv);
99143969f24bc40e2a28e53d1008852188b8cd767ashemminger
100143969f24bc40e2a28e53d1008852188b8cd767ashemminger			namep = *argv;
101143969f24bc40e2a28e53d1008852188b8cd767ashemminger			len = strlen(namep) + 1;
102143969f24bc40e2a28e53d1008852188b8cd767ashemminger			addattr_l(&req.n, sizeof(req), NDTA_NAME, namep, len);
103143969f24bc40e2a28e53d1008852188b8cd767ashemminger		} else if (strcmp(*argv, "thresh1") == 0) {
104143969f24bc40e2a28e53d1008852188b8cd767ashemminger			__u32 thresh1;
105143969f24bc40e2a28e53d1008852188b8cd767ashemminger
106143969f24bc40e2a28e53d1008852188b8cd767ashemminger			NEXT_ARG();
107143969f24bc40e2a28e53d1008852188b8cd767ashemminger			threshsp = *argv;
108143969f24bc40e2a28e53d1008852188b8cd767ashemminger
109143969f24bc40e2a28e53d1008852188b8cd767ashemminger			if (get_u32(&thresh1, *argv, 0))
110143969f24bc40e2a28e53d1008852188b8cd767ashemminger				invarg("\"thresh1\" value is invalid", *argv);
111143969f24bc40e2a28e53d1008852188b8cd767ashemminger
112143969f24bc40e2a28e53d1008852188b8cd767ashemminger			addattr32(&req.n, sizeof(req), NDTA_THRESH1, thresh1);
113143969f24bc40e2a28e53d1008852188b8cd767ashemminger		} else if (strcmp(*argv, "thresh2") == 0) {
114143969f24bc40e2a28e53d1008852188b8cd767ashemminger			__u32 thresh2;
115143969f24bc40e2a28e53d1008852188b8cd767ashemminger
116143969f24bc40e2a28e53d1008852188b8cd767ashemminger			NEXT_ARG();
117143969f24bc40e2a28e53d1008852188b8cd767ashemminger			threshsp = *argv;
118143969f24bc40e2a28e53d1008852188b8cd767ashemminger
119143969f24bc40e2a28e53d1008852188b8cd767ashemminger			if (get_u32(&thresh2, *argv, 0))
120143969f24bc40e2a28e53d1008852188b8cd767ashemminger				invarg("\"thresh2\" value is invalid", *argv);
121143969f24bc40e2a28e53d1008852188b8cd767ashemminger
122143969f24bc40e2a28e53d1008852188b8cd767ashemminger			addattr32(&req.n, sizeof(req), NDTA_THRESH2, thresh2);
123143969f24bc40e2a28e53d1008852188b8cd767ashemminger		} else if (strcmp(*argv, "thresh3") == 0) {
124143969f24bc40e2a28e53d1008852188b8cd767ashemminger			__u32 thresh3;
125143969f24bc40e2a28e53d1008852188b8cd767ashemminger
126143969f24bc40e2a28e53d1008852188b8cd767ashemminger			NEXT_ARG();
127143969f24bc40e2a28e53d1008852188b8cd767ashemminger			threshsp = *argv;
128143969f24bc40e2a28e53d1008852188b8cd767ashemminger
129143969f24bc40e2a28e53d1008852188b8cd767ashemminger			if (get_u32(&thresh3, *argv, 0))
130143969f24bc40e2a28e53d1008852188b8cd767ashemminger				invarg("\"thresh3\" value is invalid", *argv);
131143969f24bc40e2a28e53d1008852188b8cd767ashemminger
132143969f24bc40e2a28e53d1008852188b8cd767ashemminger			addattr32(&req.n, sizeof(req), NDTA_THRESH3, thresh3);
133143969f24bc40e2a28e53d1008852188b8cd767ashemminger		} else if (strcmp(*argv, "gc_int") == 0) {
134143969f24bc40e2a28e53d1008852188b8cd767ashemminger			__u64 gc_int;
135143969f24bc40e2a28e53d1008852188b8cd767ashemminger
136143969f24bc40e2a28e53d1008852188b8cd767ashemminger			NEXT_ARG();
137143969f24bc40e2a28e53d1008852188b8cd767ashemminger			gc_intp = *argv;
138143969f24bc40e2a28e53d1008852188b8cd767ashemminger
139143969f24bc40e2a28e53d1008852188b8cd767ashemminger			if (get_u64(&gc_int, *argv, 0))
140143969f24bc40e2a28e53d1008852188b8cd767ashemminger				invarg("\"gc_int\" value is invalid", *argv);
141143969f24bc40e2a28e53d1008852188b8cd767ashemminger
142143969f24bc40e2a28e53d1008852188b8cd767ashemminger			addattr_l(&req.n, sizeof(req), NDTA_GC_INTERVAL,
143143969f24bc40e2a28e53d1008852188b8cd767ashemminger				  &gc_int, sizeof(gc_int));
144143969f24bc40e2a28e53d1008852188b8cd767ashemminger		} else if (strcmp(*argv, "dev") == 0) {
145143969f24bc40e2a28e53d1008852188b8cd767ashemminger			__u32 ifindex;
146143969f24bc40e2a28e53d1008852188b8cd767ashemminger
147143969f24bc40e2a28e53d1008852188b8cd767ashemminger			NEXT_ARG();
148143969f24bc40e2a28e53d1008852188b8cd767ashemminger			ifindex = ll_name_to_index(*argv);
149143969f24bc40e2a28e53d1008852188b8cd767ashemminger			if (ifindex == 0) {
150143969f24bc40e2a28e53d1008852188b8cd767ashemminger				fprintf(stderr, "Cannot find device \"%s\"\n", *argv);
151143969f24bc40e2a28e53d1008852188b8cd767ashemminger				return -1;
152143969f24bc40e2a28e53d1008852188b8cd767ashemminger			}
153143969f24bc40e2a28e53d1008852188b8cd767ashemminger
154143969f24bc40e2a28e53d1008852188b8cd767ashemminger			rta_addattr32(parms_rta, sizeof(parms_buf),
155143969f24bc40e2a28e53d1008852188b8cd767ashemminger				      NDTPA_IFINDEX, ifindex);
156143969f24bc40e2a28e53d1008852188b8cd767ashemminger		} else if (strcmp(*argv, "base_reachable") == 0) {
157143969f24bc40e2a28e53d1008852188b8cd767ashemminger			__u64 breachable;
158143969f24bc40e2a28e53d1008852188b8cd767ashemminger
159143969f24bc40e2a28e53d1008852188b8cd767ashemminger			NEXT_ARG();
160143969f24bc40e2a28e53d1008852188b8cd767ashemminger
161143969f24bc40e2a28e53d1008852188b8cd767ashemminger			if (get_u64(&breachable, *argv, 0))
162143969f24bc40e2a28e53d1008852188b8cd767ashemminger				invarg("\"base_reachable\" value is invalid", *argv);
163143969f24bc40e2a28e53d1008852188b8cd767ashemminger
164143969f24bc40e2a28e53d1008852188b8cd767ashemminger			rta_addattr_l(parms_rta, sizeof(parms_buf),
165143969f24bc40e2a28e53d1008852188b8cd767ashemminger				      NDTPA_BASE_REACHABLE_TIME,
166143969f24bc40e2a28e53d1008852188b8cd767ashemminger				      &breachable, sizeof(breachable));
167143969f24bc40e2a28e53d1008852188b8cd767ashemminger			parms_change = 1;
168143969f24bc40e2a28e53d1008852188b8cd767ashemminger		} else if (strcmp(*argv, "retrans") == 0) {
169143969f24bc40e2a28e53d1008852188b8cd767ashemminger			__u64 retrans;
170143969f24bc40e2a28e53d1008852188b8cd767ashemminger
171143969f24bc40e2a28e53d1008852188b8cd767ashemminger			NEXT_ARG();
172143969f24bc40e2a28e53d1008852188b8cd767ashemminger
173143969f24bc40e2a28e53d1008852188b8cd767ashemminger			if (get_u64(&retrans, *argv, 0))
174143969f24bc40e2a28e53d1008852188b8cd767ashemminger				invarg("\"retrans\" value is invalid", *argv);
175143969f24bc40e2a28e53d1008852188b8cd767ashemminger
176143969f24bc40e2a28e53d1008852188b8cd767ashemminger			rta_addattr_l(parms_rta, sizeof(parms_buf),
177143969f24bc40e2a28e53d1008852188b8cd767ashemminger				      NDTPA_RETRANS_TIME,
178143969f24bc40e2a28e53d1008852188b8cd767ashemminger				      &retrans, sizeof(retrans));
179143969f24bc40e2a28e53d1008852188b8cd767ashemminger			parms_change = 1;
180143969f24bc40e2a28e53d1008852188b8cd767ashemminger		} else if (strcmp(*argv, "gc_stale") == 0) {
181143969f24bc40e2a28e53d1008852188b8cd767ashemminger			__u64 gc_stale;
182143969f24bc40e2a28e53d1008852188b8cd767ashemminger
183143969f24bc40e2a28e53d1008852188b8cd767ashemminger			NEXT_ARG();
184143969f24bc40e2a28e53d1008852188b8cd767ashemminger
185143969f24bc40e2a28e53d1008852188b8cd767ashemminger			if (get_u64(&gc_stale, *argv, 0))
186143969f24bc40e2a28e53d1008852188b8cd767ashemminger				invarg("\"gc_stale\" value is invalid", *argv);
187143969f24bc40e2a28e53d1008852188b8cd767ashemminger
188143969f24bc40e2a28e53d1008852188b8cd767ashemminger			rta_addattr_l(parms_rta, sizeof(parms_buf),
189143969f24bc40e2a28e53d1008852188b8cd767ashemminger				      NDTPA_GC_STALETIME,
190143969f24bc40e2a28e53d1008852188b8cd767ashemminger				      &gc_stale, sizeof(gc_stale));
191143969f24bc40e2a28e53d1008852188b8cd767ashemminger			parms_change = 1;
192143969f24bc40e2a28e53d1008852188b8cd767ashemminger		} else if (strcmp(*argv, "delay_probe") == 0) {
193143969f24bc40e2a28e53d1008852188b8cd767ashemminger			__u64 delay_probe;
194143969f24bc40e2a28e53d1008852188b8cd767ashemminger
195143969f24bc40e2a28e53d1008852188b8cd767ashemminger			NEXT_ARG();
196143969f24bc40e2a28e53d1008852188b8cd767ashemminger
197143969f24bc40e2a28e53d1008852188b8cd767ashemminger			if (get_u64(&delay_probe, *argv, 0))
198143969f24bc40e2a28e53d1008852188b8cd767ashemminger				invarg("\"delay_probe\" value is invalid", *argv);
199143969f24bc40e2a28e53d1008852188b8cd767ashemminger
200143969f24bc40e2a28e53d1008852188b8cd767ashemminger			rta_addattr_l(parms_rta, sizeof(parms_buf),
201143969f24bc40e2a28e53d1008852188b8cd767ashemminger				      NDTPA_DELAY_PROBE_TIME,
202143969f24bc40e2a28e53d1008852188b8cd767ashemminger				      &delay_probe, sizeof(delay_probe));
203143969f24bc40e2a28e53d1008852188b8cd767ashemminger			parms_change = 1;
204143969f24bc40e2a28e53d1008852188b8cd767ashemminger		} else if (strcmp(*argv, "queue") == 0) {
205143969f24bc40e2a28e53d1008852188b8cd767ashemminger			__u32 queue;
206143969f24bc40e2a28e53d1008852188b8cd767ashemminger
207143969f24bc40e2a28e53d1008852188b8cd767ashemminger			NEXT_ARG();
208143969f24bc40e2a28e53d1008852188b8cd767ashemminger
209143969f24bc40e2a28e53d1008852188b8cd767ashemminger			if (get_u32(&queue, *argv, 0))
210143969f24bc40e2a28e53d1008852188b8cd767ashemminger				invarg("\"queue\" value is invalid", *argv);
211143969f24bc40e2a28e53d1008852188b8cd767ashemminger
212143969f24bc40e2a28e53d1008852188b8cd767ashemminger			if (!parms_rta)
213143969f24bc40e2a28e53d1008852188b8cd767ashemminger				parms_rta = (struct rtattr *)&parms_buf;
214143969f24bc40e2a28e53d1008852188b8cd767ashemminger			rta_addattr32(parms_rta, sizeof(parms_buf),
215143969f24bc40e2a28e53d1008852188b8cd767ashemminger				      NDTPA_QUEUE_LEN, queue);
216143969f24bc40e2a28e53d1008852188b8cd767ashemminger			parms_change = 1;
217143969f24bc40e2a28e53d1008852188b8cd767ashemminger		} else if (strcmp(*argv, "app_probes") == 0) {
218143969f24bc40e2a28e53d1008852188b8cd767ashemminger			__u32 aprobe;
219143969f24bc40e2a28e53d1008852188b8cd767ashemminger
220143969f24bc40e2a28e53d1008852188b8cd767ashemminger			NEXT_ARG();
221143969f24bc40e2a28e53d1008852188b8cd767ashemminger
222143969f24bc40e2a28e53d1008852188b8cd767ashemminger			if (get_u32(&aprobe, *argv, 0))
223143969f24bc40e2a28e53d1008852188b8cd767ashemminger				invarg("\"app_probes\" value is invalid", *argv);
224143969f24bc40e2a28e53d1008852188b8cd767ashemminger
225143969f24bc40e2a28e53d1008852188b8cd767ashemminger			rta_addattr32(parms_rta, sizeof(parms_buf),
226143969f24bc40e2a28e53d1008852188b8cd767ashemminger				      NDTPA_APP_PROBES, aprobe);
227143969f24bc40e2a28e53d1008852188b8cd767ashemminger			parms_change = 1;
228143969f24bc40e2a28e53d1008852188b8cd767ashemminger		} else if (strcmp(*argv, "ucast_probes") == 0) {
229143969f24bc40e2a28e53d1008852188b8cd767ashemminger			__u32 uprobe;
230143969f24bc40e2a28e53d1008852188b8cd767ashemminger
231143969f24bc40e2a28e53d1008852188b8cd767ashemminger			NEXT_ARG();
232143969f24bc40e2a28e53d1008852188b8cd767ashemminger
233143969f24bc40e2a28e53d1008852188b8cd767ashemminger			if (get_u32(&uprobe, *argv, 0))
234143969f24bc40e2a28e53d1008852188b8cd767ashemminger				invarg("\"ucast_probes\" value is invalid", *argv);
235143969f24bc40e2a28e53d1008852188b8cd767ashemminger
236143969f24bc40e2a28e53d1008852188b8cd767ashemminger			rta_addattr32(parms_rta, sizeof(parms_buf),
237143969f24bc40e2a28e53d1008852188b8cd767ashemminger				      NDTPA_UCAST_PROBES, uprobe);
238143969f24bc40e2a28e53d1008852188b8cd767ashemminger			parms_change = 1;
239143969f24bc40e2a28e53d1008852188b8cd767ashemminger		} else if (strcmp(*argv, "mcast_probes") == 0) {
240143969f24bc40e2a28e53d1008852188b8cd767ashemminger			__u32 mprobe;
241143969f24bc40e2a28e53d1008852188b8cd767ashemminger
242143969f24bc40e2a28e53d1008852188b8cd767ashemminger			NEXT_ARG();
243143969f24bc40e2a28e53d1008852188b8cd767ashemminger
244143969f24bc40e2a28e53d1008852188b8cd767ashemminger			if (get_u32(&mprobe, *argv, 0))
245143969f24bc40e2a28e53d1008852188b8cd767ashemminger				invarg("\"mcast_probes\" value is invalid", *argv);
246143969f24bc40e2a28e53d1008852188b8cd767ashemminger
247143969f24bc40e2a28e53d1008852188b8cd767ashemminger			rta_addattr32(parms_rta, sizeof(parms_buf),
248143969f24bc40e2a28e53d1008852188b8cd767ashemminger				      NDTPA_MCAST_PROBES, mprobe);
249143969f24bc40e2a28e53d1008852188b8cd767ashemminger			parms_change = 1;
250143969f24bc40e2a28e53d1008852188b8cd767ashemminger		} else if (strcmp(*argv, "anycast_delay") == 0) {
251143969f24bc40e2a28e53d1008852188b8cd767ashemminger			__u64 anycast_delay;
252143969f24bc40e2a28e53d1008852188b8cd767ashemminger
253143969f24bc40e2a28e53d1008852188b8cd767ashemminger			NEXT_ARG();
254143969f24bc40e2a28e53d1008852188b8cd767ashemminger
255143969f24bc40e2a28e53d1008852188b8cd767ashemminger			if (get_u64(&anycast_delay, *argv, 0))
256143969f24bc40e2a28e53d1008852188b8cd767ashemminger				invarg("\"anycast_delay\" value is invalid", *argv);
257143969f24bc40e2a28e53d1008852188b8cd767ashemminger
258143969f24bc40e2a28e53d1008852188b8cd767ashemminger			rta_addattr_l(parms_rta, sizeof(parms_buf),
259143969f24bc40e2a28e53d1008852188b8cd767ashemminger				      NDTPA_ANYCAST_DELAY,
260143969f24bc40e2a28e53d1008852188b8cd767ashemminger				      &anycast_delay, sizeof(anycast_delay));
261143969f24bc40e2a28e53d1008852188b8cd767ashemminger			parms_change = 1;
262143969f24bc40e2a28e53d1008852188b8cd767ashemminger		} else if (strcmp(*argv, "proxy_delay") == 0) {
263143969f24bc40e2a28e53d1008852188b8cd767ashemminger			__u64 proxy_delay;
264143969f24bc40e2a28e53d1008852188b8cd767ashemminger
265143969f24bc40e2a28e53d1008852188b8cd767ashemminger			NEXT_ARG();
266143969f24bc40e2a28e53d1008852188b8cd767ashemminger
267143969f24bc40e2a28e53d1008852188b8cd767ashemminger			if (get_u64(&proxy_delay, *argv, 0))
268143969f24bc40e2a28e53d1008852188b8cd767ashemminger				invarg("\"proxy_delay\" value is invalid", *argv);
269143969f24bc40e2a28e53d1008852188b8cd767ashemminger
270143969f24bc40e2a28e53d1008852188b8cd767ashemminger			rta_addattr_l(parms_rta, sizeof(parms_buf),
271143969f24bc40e2a28e53d1008852188b8cd767ashemminger				      NDTPA_PROXY_DELAY,
272143969f24bc40e2a28e53d1008852188b8cd767ashemminger				      &proxy_delay, sizeof(proxy_delay));
273143969f24bc40e2a28e53d1008852188b8cd767ashemminger			parms_change = 1;
274143969f24bc40e2a28e53d1008852188b8cd767ashemminger		} else if (strcmp(*argv, "proxy_queue") == 0) {
275143969f24bc40e2a28e53d1008852188b8cd767ashemminger			__u32 pqueue;
276143969f24bc40e2a28e53d1008852188b8cd767ashemminger
277143969f24bc40e2a28e53d1008852188b8cd767ashemminger			NEXT_ARG();
278143969f24bc40e2a28e53d1008852188b8cd767ashemminger
279143969f24bc40e2a28e53d1008852188b8cd767ashemminger			if (get_u32(&pqueue, *argv, 0))
280143969f24bc40e2a28e53d1008852188b8cd767ashemminger				invarg("\"proxy_queue\" value is invalid", *argv);
281143969f24bc40e2a28e53d1008852188b8cd767ashemminger
282143969f24bc40e2a28e53d1008852188b8cd767ashemminger			rta_addattr32(parms_rta, sizeof(parms_buf),
283143969f24bc40e2a28e53d1008852188b8cd767ashemminger				      NDTPA_PROXY_QLEN, pqueue);
284143969f24bc40e2a28e53d1008852188b8cd767ashemminger			parms_change = 1;
285143969f24bc40e2a28e53d1008852188b8cd767ashemminger		} else if (strcmp(*argv, "locktime") == 0) {
286143969f24bc40e2a28e53d1008852188b8cd767ashemminger			__u64 locktime;
287143969f24bc40e2a28e53d1008852188b8cd767ashemminger
288143969f24bc40e2a28e53d1008852188b8cd767ashemminger			NEXT_ARG();
289143969f24bc40e2a28e53d1008852188b8cd767ashemminger
290143969f24bc40e2a28e53d1008852188b8cd767ashemminger			if (get_u64(&locktime, *argv, 0))
291143969f24bc40e2a28e53d1008852188b8cd767ashemminger				invarg("\"locktime\" value is invalid", *argv);
292143969f24bc40e2a28e53d1008852188b8cd767ashemminger
293143969f24bc40e2a28e53d1008852188b8cd767ashemminger			rta_addattr_l(parms_rta, sizeof(parms_buf),
294143969f24bc40e2a28e53d1008852188b8cd767ashemminger				      NDTPA_LOCKTIME,
295143969f24bc40e2a28e53d1008852188b8cd767ashemminger				      &locktime, sizeof(locktime));
296143969f24bc40e2a28e53d1008852188b8cd767ashemminger			parms_change = 1;
297143969f24bc40e2a28e53d1008852188b8cd767ashemminger		} else {
298143969f24bc40e2a28e53d1008852188b8cd767ashemminger			invarg("unknown", *argv);
299143969f24bc40e2a28e53d1008852188b8cd767ashemminger		}
300143969f24bc40e2a28e53d1008852188b8cd767ashemminger
301143969f24bc40e2a28e53d1008852188b8cd767ashemminger		argc--; argv++;
302143969f24bc40e2a28e53d1008852188b8cd767ashemminger	}
303143969f24bc40e2a28e53d1008852188b8cd767ashemminger
304143969f24bc40e2a28e53d1008852188b8cd767ashemminger	if (!namep)
305143969f24bc40e2a28e53d1008852188b8cd767ashemminger		missarg("NAME");
306143969f24bc40e2a28e53d1008852188b8cd767ashemminger	if (!threshsp && !gc_intp && !parms_change) {
307143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(stderr, "Not enough information: changable attributes required.\n");
308143969f24bc40e2a28e53d1008852188b8cd767ashemminger		exit(-1);
309143969f24bc40e2a28e53d1008852188b8cd767ashemminger	}
310143969f24bc40e2a28e53d1008852188b8cd767ashemminger
311143969f24bc40e2a28e53d1008852188b8cd767ashemminger	if (parms_rta->rta_len > RTA_LENGTH(0)) {
312143969f24bc40e2a28e53d1008852188b8cd767ashemminger		addattr_l(&req.n, sizeof(req), NDTA_PARMS, RTA_DATA(parms_rta),
313143969f24bc40e2a28e53d1008852188b8cd767ashemminger			  RTA_PAYLOAD(parms_rta));
314143969f24bc40e2a28e53d1008852188b8cd767ashemminger	}
315143969f24bc40e2a28e53d1008852188b8cd767ashemminger
316cd70f3f522e04b4d2fa80ae10292379bf223a53bStephen Hemminger	if (rtnl_talk(&rth, &req.n, 0, 0, NULL) < 0)
317143969f24bc40e2a28e53d1008852188b8cd767ashemminger		exit(2);
318143969f24bc40e2a28e53d1008852188b8cd767ashemminger
319143969f24bc40e2a28e53d1008852188b8cd767ashemminger	return 0;
320143969f24bc40e2a28e53d1008852188b8cd767ashemminger}
321143969f24bc40e2a28e53d1008852188b8cd767ashemminger
322143969f24bc40e2a28e53d1008852188b8cd767ashemmingerstatic const char *ntable_strtime_delta(__u32 msec)
323143969f24bc40e2a28e53d1008852188b8cd767ashemminger{
324143969f24bc40e2a28e53d1008852188b8cd767ashemminger	static char str[32];
325143969f24bc40e2a28e53d1008852188b8cd767ashemminger	struct timeval now;
326143969f24bc40e2a28e53d1008852188b8cd767ashemminger	time_t t;
327143969f24bc40e2a28e53d1008852188b8cd767ashemminger	struct tm *tp;
328143969f24bc40e2a28e53d1008852188b8cd767ashemminger
329143969f24bc40e2a28e53d1008852188b8cd767ashemminger	if (msec == 0)
330143969f24bc40e2a28e53d1008852188b8cd767ashemminger		goto error;
331143969f24bc40e2a28e53d1008852188b8cd767ashemminger
332143969f24bc40e2a28e53d1008852188b8cd767ashemminger	memset(&now, 0, sizeof(now));
333143969f24bc40e2a28e53d1008852188b8cd767ashemminger
334143969f24bc40e2a28e53d1008852188b8cd767ashemminger	if (gettimeofday(&now, NULL) < 0) {
335143969f24bc40e2a28e53d1008852188b8cd767ashemminger		perror("gettimeofday");
336143969f24bc40e2a28e53d1008852188b8cd767ashemminger		goto error;
337143969f24bc40e2a28e53d1008852188b8cd767ashemminger	}
338143969f24bc40e2a28e53d1008852188b8cd767ashemminger
339143969f24bc40e2a28e53d1008852188b8cd767ashemminger	t = now.tv_sec - (msec / 1000);
340143969f24bc40e2a28e53d1008852188b8cd767ashemminger	tp = localtime(&t);
341143969f24bc40e2a28e53d1008852188b8cd767ashemminger	if (!tp)
342143969f24bc40e2a28e53d1008852188b8cd767ashemminger		goto error;
343143969f24bc40e2a28e53d1008852188b8cd767ashemminger
344143969f24bc40e2a28e53d1008852188b8cd767ashemminger	strftime(str, sizeof(str), "%Y-%m-%d %T", tp);
345143969f24bc40e2a28e53d1008852188b8cd767ashemminger
346143969f24bc40e2a28e53d1008852188b8cd767ashemminger	return str;
347143969f24bc40e2a28e53d1008852188b8cd767ashemminger error:
348143969f24bc40e2a28e53d1008852188b8cd767ashemminger	strcpy(str, "(error)");
349143969f24bc40e2a28e53d1008852188b8cd767ashemminger	return str;
350143969f24bc40e2a28e53d1008852188b8cd767ashemminger}
351143969f24bc40e2a28e53d1008852188b8cd767ashemminger
352143969f24bc40e2a28e53d1008852188b8cd767ashemmingerint print_ntable(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
353143969f24bc40e2a28e53d1008852188b8cd767ashemminger{
354143969f24bc40e2a28e53d1008852188b8cd767ashemminger	FILE *fp = (FILE*)arg;
355143969f24bc40e2a28e53d1008852188b8cd767ashemminger	struct ndtmsg *ndtm = NLMSG_DATA(n);
356143969f24bc40e2a28e53d1008852188b8cd767ashemminger	int len = n->nlmsg_len;
357143969f24bc40e2a28e53d1008852188b8cd767ashemminger	struct rtattr *tb[NDTA_MAX+1];
358143969f24bc40e2a28e53d1008852188b8cd767ashemminger	struct rtattr *tpb[NDTPA_MAX+1];
359143969f24bc40e2a28e53d1008852188b8cd767ashemminger	int ret;
360143969f24bc40e2a28e53d1008852188b8cd767ashemminger
361143969f24bc40e2a28e53d1008852188b8cd767ashemminger	if (n->nlmsg_type != RTM_NEWNEIGHTBL) {
362143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(stderr, "Not NEIGHTBL: %08x %08x %08x\n",
363143969f24bc40e2a28e53d1008852188b8cd767ashemminger			n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
364143969f24bc40e2a28e53d1008852188b8cd767ashemminger		return 0;
365143969f24bc40e2a28e53d1008852188b8cd767ashemminger	}
366143969f24bc40e2a28e53d1008852188b8cd767ashemminger	len -= NLMSG_LENGTH(sizeof(*ndtm));
367143969f24bc40e2a28e53d1008852188b8cd767ashemminger	if (len < 0) {
368143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
369143969f24bc40e2a28e53d1008852188b8cd767ashemminger		return -1;
370143969f24bc40e2a28e53d1008852188b8cd767ashemminger	}
371143969f24bc40e2a28e53d1008852188b8cd767ashemminger
372143969f24bc40e2a28e53d1008852188b8cd767ashemminger	if (preferred_family && preferred_family != ndtm->ndtm_family)
373143969f24bc40e2a28e53d1008852188b8cd767ashemminger		return 0;
374143969f24bc40e2a28e53d1008852188b8cd767ashemminger
375143969f24bc40e2a28e53d1008852188b8cd767ashemminger	parse_rtattr(tb, NDTA_MAX, NDTA_RTA(ndtm),
376143969f24bc40e2a28e53d1008852188b8cd767ashemminger		     n->nlmsg_len - NLMSG_LENGTH(sizeof(*ndtm)));
377143969f24bc40e2a28e53d1008852188b8cd767ashemminger
378143969f24bc40e2a28e53d1008852188b8cd767ashemminger	if (tb[NDTA_NAME]) {
379ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger		const char *name = rta_getattr_str(tb[NDTA_NAME]);
380143969f24bc40e2a28e53d1008852188b8cd767ashemminger
381143969f24bc40e2a28e53d1008852188b8cd767ashemminger		if (strlen(filter.name) > 0 && strcmp(filter.name, name))
382143969f24bc40e2a28e53d1008852188b8cd767ashemminger			return 0;
383143969f24bc40e2a28e53d1008852188b8cd767ashemminger	}
384143969f24bc40e2a28e53d1008852188b8cd767ashemminger	if (tb[NDTA_PARMS]) {
385143969f24bc40e2a28e53d1008852188b8cd767ashemminger		parse_rtattr(tpb, NDTPA_MAX, RTA_DATA(tb[NDTA_PARMS]),
386143969f24bc40e2a28e53d1008852188b8cd767ashemminger			     RTA_PAYLOAD(tb[NDTA_PARMS]));
387143969f24bc40e2a28e53d1008852188b8cd767ashemminger
388143969f24bc40e2a28e53d1008852188b8cd767ashemminger		if (tpb[NDTPA_IFINDEX]) {
389ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger			__u32 ifindex = rta_getattr_u32(tpb[NDTPA_IFINDEX]);
390143969f24bc40e2a28e53d1008852188b8cd767ashemminger
391143969f24bc40e2a28e53d1008852188b8cd767ashemminger			if (filter.index && filter.index != ifindex)
392143969f24bc40e2a28e53d1008852188b8cd767ashemminger				return 0;
393143969f24bc40e2a28e53d1008852188b8cd767ashemminger		} else {
394143969f24bc40e2a28e53d1008852188b8cd767ashemminger			if (filter.index && filter.index != NONE_DEV)
395143969f24bc40e2a28e53d1008852188b8cd767ashemminger				return 0;
396143969f24bc40e2a28e53d1008852188b8cd767ashemminger		}
397143969f24bc40e2a28e53d1008852188b8cd767ashemminger	}
398143969f24bc40e2a28e53d1008852188b8cd767ashemminger
399143969f24bc40e2a28e53d1008852188b8cd767ashemminger	if (ndtm->ndtm_family == AF_INET)
400143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "inet ");
401143969f24bc40e2a28e53d1008852188b8cd767ashemminger	else if (ndtm->ndtm_family == AF_INET6)
402143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "inet6 ");
403143969f24bc40e2a28e53d1008852188b8cd767ashemminger	else if (ndtm->ndtm_family == AF_DECnet)
404143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "dnet ");
405143969f24bc40e2a28e53d1008852188b8cd767ashemminger	else
406143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "(%d) ", ndtm->ndtm_family);
407143969f24bc40e2a28e53d1008852188b8cd767ashemminger
408143969f24bc40e2a28e53d1008852188b8cd767ashemminger	if (tb[NDTA_NAME]) {
409ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger		const char *name = rta_getattr_str(tb[NDTA_NAME]);
410143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "%s ", name);
411143969f24bc40e2a28e53d1008852188b8cd767ashemminger	}
412143969f24bc40e2a28e53d1008852188b8cd767ashemminger
413143969f24bc40e2a28e53d1008852188b8cd767ashemminger	fprintf(fp, "%s", _SL_);
414143969f24bc40e2a28e53d1008852188b8cd767ashemminger
415143969f24bc40e2a28e53d1008852188b8cd767ashemminger	ret = (tb[NDTA_THRESH1] || tb[NDTA_THRESH2] || tb[NDTA_THRESH3] ||
416143969f24bc40e2a28e53d1008852188b8cd767ashemminger	       tb[NDTA_GC_INTERVAL]);
417143969f24bc40e2a28e53d1008852188b8cd767ashemminger	if (ret)
418143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "    ");
419143969f24bc40e2a28e53d1008852188b8cd767ashemminger
420143969f24bc40e2a28e53d1008852188b8cd767ashemminger	if (tb[NDTA_THRESH1]) {
421ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger		__u32 thresh1 = rta_getattr_u32(tb[NDTA_THRESH1]);
422143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "thresh1 %u ", thresh1);
423143969f24bc40e2a28e53d1008852188b8cd767ashemminger	}
424143969f24bc40e2a28e53d1008852188b8cd767ashemminger	if (tb[NDTA_THRESH2]) {
425ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger		__u32 thresh2 = rta_getattr_u32(tb[NDTA_THRESH2]);
426143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "thresh2 %u ", thresh2);
427143969f24bc40e2a28e53d1008852188b8cd767ashemminger	}
428143969f24bc40e2a28e53d1008852188b8cd767ashemminger	if (tb[NDTA_THRESH3]) {
429ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger		__u32 thresh3 = rta_getattr_u32(tb[NDTA_THRESH3]);
430143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "thresh3 %u ", thresh3);
431143969f24bc40e2a28e53d1008852188b8cd767ashemminger	}
432143969f24bc40e2a28e53d1008852188b8cd767ashemminger	if (tb[NDTA_GC_INTERVAL]) {
433ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger		__u64 gc_int = rta_getattr_u64(tb[NDTA_GC_INTERVAL]);
434143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "gc_int %llu ", gc_int);
435143969f24bc40e2a28e53d1008852188b8cd767ashemminger	}
436143969f24bc40e2a28e53d1008852188b8cd767ashemminger
437143969f24bc40e2a28e53d1008852188b8cd767ashemminger	if (ret)
438143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "%s", _SL_);
439143969f24bc40e2a28e53d1008852188b8cd767ashemminger
440143969f24bc40e2a28e53d1008852188b8cd767ashemminger	if (tb[NDTA_CONFIG] && show_stats) {
441143969f24bc40e2a28e53d1008852188b8cd767ashemminger		struct ndt_config *ndtc = RTA_DATA(tb[NDTA_CONFIG]);
442143969f24bc40e2a28e53d1008852188b8cd767ashemminger
443143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "    ");
444143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "config ");
445143969f24bc40e2a28e53d1008852188b8cd767ashemminger
446143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "key_len %u ", ndtc->ndtc_key_len);
447143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "entry_size %u ", ndtc->ndtc_entry_size);
448143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "entries %u ", ndtc->ndtc_entries);
449143969f24bc40e2a28e53d1008852188b8cd767ashemminger
450143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "%s", _SL_);
451143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "        ");
452143969f24bc40e2a28e53d1008852188b8cd767ashemminger
453143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "last_flush %s ",
454143969f24bc40e2a28e53d1008852188b8cd767ashemminger			ntable_strtime_delta(ndtc->ndtc_last_flush));
455143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "last_rand %s ",
456143969f24bc40e2a28e53d1008852188b8cd767ashemminger			ntable_strtime_delta(ndtc->ndtc_last_rand));
457143969f24bc40e2a28e53d1008852188b8cd767ashemminger
458143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "%s", _SL_);
459143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "        ");
460143969f24bc40e2a28e53d1008852188b8cd767ashemminger
461143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "hash_rnd %u ", ndtc->ndtc_hash_rnd);
462143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "hash_mask %08x ", ndtc->ndtc_hash_mask);
463143969f24bc40e2a28e53d1008852188b8cd767ashemminger
464143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "hash_chain_gc %u ", ndtc->ndtc_hash_chain_gc);
465143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "proxy_qlen %u ", ndtc->ndtc_proxy_qlen);
466143969f24bc40e2a28e53d1008852188b8cd767ashemminger
467143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "%s", _SL_);
468143969f24bc40e2a28e53d1008852188b8cd767ashemminger	}
469143969f24bc40e2a28e53d1008852188b8cd767ashemminger
470143969f24bc40e2a28e53d1008852188b8cd767ashemminger	if (tb[NDTA_PARMS]) {
471143969f24bc40e2a28e53d1008852188b8cd767ashemminger		if (tpb[NDTPA_IFINDEX]) {
472ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger			__u32 ifindex = rta_getattr_u32(tpb[NDTPA_IFINDEX]);
473143969f24bc40e2a28e53d1008852188b8cd767ashemminger
474143969f24bc40e2a28e53d1008852188b8cd767ashemminger			fprintf(fp, "    ");
475143969f24bc40e2a28e53d1008852188b8cd767ashemminger			fprintf(fp, "dev %s ", ll_index_to_name(ifindex));
476143969f24bc40e2a28e53d1008852188b8cd767ashemminger			fprintf(fp, "%s", _SL_);
477143969f24bc40e2a28e53d1008852188b8cd767ashemminger		}
478143969f24bc40e2a28e53d1008852188b8cd767ashemminger
479143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "    ");
480143969f24bc40e2a28e53d1008852188b8cd767ashemminger
481143969f24bc40e2a28e53d1008852188b8cd767ashemminger		if (tpb[NDTPA_REFCNT]) {
482ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger			__u32 refcnt = rta_getattr_u32(tpb[NDTPA_REFCNT]);
483143969f24bc40e2a28e53d1008852188b8cd767ashemminger			fprintf(fp, "refcnt %u ", refcnt);
484143969f24bc40e2a28e53d1008852188b8cd767ashemminger		}
485143969f24bc40e2a28e53d1008852188b8cd767ashemminger		if (tpb[NDTPA_REACHABLE_TIME]) {
486ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger			__u64 reachable = rta_getattr_u64(tpb[NDTPA_REACHABLE_TIME]);
487143969f24bc40e2a28e53d1008852188b8cd767ashemminger			fprintf(fp, "reachable %llu ", reachable);
488143969f24bc40e2a28e53d1008852188b8cd767ashemminger		}
489143969f24bc40e2a28e53d1008852188b8cd767ashemminger		if (tpb[NDTPA_BASE_REACHABLE_TIME]) {
490ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger			__u64 breachable = rta_getattr_u64(tpb[NDTPA_BASE_REACHABLE_TIME]);
491143969f24bc40e2a28e53d1008852188b8cd767ashemminger			fprintf(fp, "base_reachable %llu ", breachable);
492143969f24bc40e2a28e53d1008852188b8cd767ashemminger		}
493143969f24bc40e2a28e53d1008852188b8cd767ashemminger		if (tpb[NDTPA_RETRANS_TIME]) {
494ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger			__u64 retrans = rta_getattr_u64(tpb[NDTPA_RETRANS_TIME]);
495143969f24bc40e2a28e53d1008852188b8cd767ashemminger			fprintf(fp, "retrans %llu ", retrans);
496143969f24bc40e2a28e53d1008852188b8cd767ashemminger		}
497143969f24bc40e2a28e53d1008852188b8cd767ashemminger
498143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "%s", _SL_);
499143969f24bc40e2a28e53d1008852188b8cd767ashemminger
500143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "    ");
501143969f24bc40e2a28e53d1008852188b8cd767ashemminger
502143969f24bc40e2a28e53d1008852188b8cd767ashemminger		if (tpb[NDTPA_GC_STALETIME]) {
503ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger			__u64 gc_stale = rta_getattr_u64(tpb[NDTPA_GC_STALETIME]);
504143969f24bc40e2a28e53d1008852188b8cd767ashemminger			fprintf(fp, "gc_stale %llu ", gc_stale);
505143969f24bc40e2a28e53d1008852188b8cd767ashemminger		}
506143969f24bc40e2a28e53d1008852188b8cd767ashemminger		if (tpb[NDTPA_DELAY_PROBE_TIME]) {
507ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger			__u64 delay_probe = rta_getattr_u64(tpb[NDTPA_DELAY_PROBE_TIME]);
508143969f24bc40e2a28e53d1008852188b8cd767ashemminger			fprintf(fp, "delay_probe %llu ", delay_probe);
509143969f24bc40e2a28e53d1008852188b8cd767ashemminger		}
510143969f24bc40e2a28e53d1008852188b8cd767ashemminger		if (tpb[NDTPA_QUEUE_LEN]) {
511ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger			__u32 queue = rta_getattr_u32(tpb[NDTPA_QUEUE_LEN]);
512143969f24bc40e2a28e53d1008852188b8cd767ashemminger			fprintf(fp, "queue %u ", queue);
513143969f24bc40e2a28e53d1008852188b8cd767ashemminger		}
514143969f24bc40e2a28e53d1008852188b8cd767ashemminger
515143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "%s", _SL_);
516143969f24bc40e2a28e53d1008852188b8cd767ashemminger
517143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "    ");
518143969f24bc40e2a28e53d1008852188b8cd767ashemminger
519143969f24bc40e2a28e53d1008852188b8cd767ashemminger		if (tpb[NDTPA_APP_PROBES]) {
520ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger			__u32 aprobe = rta_getattr_u32(tpb[NDTPA_APP_PROBES]);
521143969f24bc40e2a28e53d1008852188b8cd767ashemminger			fprintf(fp, "app_probes %u ", aprobe);
522143969f24bc40e2a28e53d1008852188b8cd767ashemminger		}
523143969f24bc40e2a28e53d1008852188b8cd767ashemminger		if (tpb[NDTPA_UCAST_PROBES]) {
524ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger			__u32 uprobe = rta_getattr_u32(tpb[NDTPA_UCAST_PROBES]);
525143969f24bc40e2a28e53d1008852188b8cd767ashemminger			fprintf(fp, "ucast_probes %u ", uprobe);
526143969f24bc40e2a28e53d1008852188b8cd767ashemminger		}
527143969f24bc40e2a28e53d1008852188b8cd767ashemminger		if (tpb[NDTPA_MCAST_PROBES]) {
528ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger			__u32 mprobe = rta_getattr_u32(tpb[NDTPA_MCAST_PROBES]);
529143969f24bc40e2a28e53d1008852188b8cd767ashemminger			fprintf(fp, "mcast_probes %u ", mprobe);
530143969f24bc40e2a28e53d1008852188b8cd767ashemminger		}
531143969f24bc40e2a28e53d1008852188b8cd767ashemminger
532143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "%s", _SL_);
533143969f24bc40e2a28e53d1008852188b8cd767ashemminger
534143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "    ");
535143969f24bc40e2a28e53d1008852188b8cd767ashemminger
536143969f24bc40e2a28e53d1008852188b8cd767ashemminger		if (tpb[NDTPA_ANYCAST_DELAY]) {
537ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger			__u64 anycast_delay = rta_getattr_u64(tpb[NDTPA_ANYCAST_DELAY]);
538143969f24bc40e2a28e53d1008852188b8cd767ashemminger			fprintf(fp, "anycast_delay %llu ", anycast_delay);
539143969f24bc40e2a28e53d1008852188b8cd767ashemminger		}
540143969f24bc40e2a28e53d1008852188b8cd767ashemminger		if (tpb[NDTPA_PROXY_DELAY]) {
541ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger			__u64 proxy_delay = rta_getattr_u64(tpb[NDTPA_PROXY_DELAY]);
542143969f24bc40e2a28e53d1008852188b8cd767ashemminger			fprintf(fp, "proxy_delay %llu ", proxy_delay);
543143969f24bc40e2a28e53d1008852188b8cd767ashemminger		}
544143969f24bc40e2a28e53d1008852188b8cd767ashemminger		if (tpb[NDTPA_PROXY_QLEN]) {
545ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger			__u32 pqueue = rta_getattr_u32(tpb[NDTPA_PROXY_QLEN]);
546143969f24bc40e2a28e53d1008852188b8cd767ashemminger			fprintf(fp, "proxy_queue %u ", pqueue);
547143969f24bc40e2a28e53d1008852188b8cd767ashemminger		}
548143969f24bc40e2a28e53d1008852188b8cd767ashemminger		if (tpb[NDTPA_LOCKTIME]) {
549ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger			__u64 locktime = rta_getattr_u64(tpb[NDTPA_LOCKTIME]);
550143969f24bc40e2a28e53d1008852188b8cd767ashemminger			fprintf(fp, "locktime %llu ", locktime);
551143969f24bc40e2a28e53d1008852188b8cd767ashemminger		}
552143969f24bc40e2a28e53d1008852188b8cd767ashemminger
553143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "%s", _SL_);
554143969f24bc40e2a28e53d1008852188b8cd767ashemminger	}
555143969f24bc40e2a28e53d1008852188b8cd767ashemminger
556143969f24bc40e2a28e53d1008852188b8cd767ashemminger	if (tb[NDTA_STATS] && show_stats) {
557143969f24bc40e2a28e53d1008852188b8cd767ashemminger		struct ndt_stats *ndts = RTA_DATA(tb[NDTA_STATS]);
558143969f24bc40e2a28e53d1008852188b8cd767ashemminger
559143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "    ");
560143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "stats ");
561143969f24bc40e2a28e53d1008852188b8cd767ashemminger
562143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "allocs %llu ", ndts->ndts_allocs);
563143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "destroys %llu ", ndts->ndts_destroys);
564143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "hash_grows %llu ", ndts->ndts_hash_grows);
565143969f24bc40e2a28e53d1008852188b8cd767ashemminger
566143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "%s", _SL_);
567143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "        ");
568143969f24bc40e2a28e53d1008852188b8cd767ashemminger
569143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "res_failed %llu ", ndts->ndts_res_failed);
570143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "lookups %llu ", ndts->ndts_lookups);
571143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "hits %llu ", ndts->ndts_hits);
572143969f24bc40e2a28e53d1008852188b8cd767ashemminger
573143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "%s", _SL_);
574143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "        ");
575143969f24bc40e2a28e53d1008852188b8cd767ashemminger
576143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "rcv_probes_mcast %llu ", ndts->ndts_rcv_probes_mcast);
577143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "rcv_probes_ucast %llu ", ndts->ndts_rcv_probes_ucast);
578143969f24bc40e2a28e53d1008852188b8cd767ashemminger
579143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "%s", _SL_);
580143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "        ");
581143969f24bc40e2a28e53d1008852188b8cd767ashemminger
582143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "periodic_gc_runs %llu ", ndts->ndts_periodic_gc_runs);
583143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "forced_gc_runs %llu ", ndts->ndts_forced_gc_runs);
584143969f24bc40e2a28e53d1008852188b8cd767ashemminger
585143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(fp, "%s", _SL_);
586143969f24bc40e2a28e53d1008852188b8cd767ashemminger	}
587143969f24bc40e2a28e53d1008852188b8cd767ashemminger
588143969f24bc40e2a28e53d1008852188b8cd767ashemminger	fprintf(fp, "\n");
589143969f24bc40e2a28e53d1008852188b8cd767ashemminger
590143969f24bc40e2a28e53d1008852188b8cd767ashemminger	fflush(fp);
591143969f24bc40e2a28e53d1008852188b8cd767ashemminger	return 0;
592143969f24bc40e2a28e53d1008852188b8cd767ashemminger}
593143969f24bc40e2a28e53d1008852188b8cd767ashemminger
594143969f24bc40e2a28e53d1008852188b8cd767ashemmingervoid ipntable_reset_filter(void)
595143969f24bc40e2a28e53d1008852188b8cd767ashemminger{
596143969f24bc40e2a28e53d1008852188b8cd767ashemminger	memset(&filter, 0, sizeof(filter));
597143969f24bc40e2a28e53d1008852188b8cd767ashemminger}
598143969f24bc40e2a28e53d1008852188b8cd767ashemminger
599143969f24bc40e2a28e53d1008852188b8cd767ashemmingerstatic int ipntable_show(int argc, char **argv)
600143969f24bc40e2a28e53d1008852188b8cd767ashemminger{
601143969f24bc40e2a28e53d1008852188b8cd767ashemminger	ipntable_reset_filter();
602143969f24bc40e2a28e53d1008852188b8cd767ashemminger
603143969f24bc40e2a28e53d1008852188b8cd767ashemminger	filter.family = preferred_family;
604143969f24bc40e2a28e53d1008852188b8cd767ashemminger
605143969f24bc40e2a28e53d1008852188b8cd767ashemminger	while (argc > 0) {
606143969f24bc40e2a28e53d1008852188b8cd767ashemminger		if (strcmp(*argv, "dev") == 0) {
607143969f24bc40e2a28e53d1008852188b8cd767ashemminger			NEXT_ARG();
608143969f24bc40e2a28e53d1008852188b8cd767ashemminger
609143969f24bc40e2a28e53d1008852188b8cd767ashemminger			if (strcmp("none", *argv) == 0)
610143969f24bc40e2a28e53d1008852188b8cd767ashemminger				filter.index = NONE_DEV;
611143969f24bc40e2a28e53d1008852188b8cd767ashemminger			else if ((filter.index = ll_name_to_index(*argv)) == 0)
612143969f24bc40e2a28e53d1008852188b8cd767ashemminger				invarg("\"DEV\" is invalid", *argv);
613143969f24bc40e2a28e53d1008852188b8cd767ashemminger		} else if (strcmp(*argv, "name") == 0) {
614143969f24bc40e2a28e53d1008852188b8cd767ashemminger			NEXT_ARG();
615143969f24bc40e2a28e53d1008852188b8cd767ashemminger
616143969f24bc40e2a28e53d1008852188b8cd767ashemminger			strncpy(filter.name, *argv, sizeof(filter.name));
617143969f24bc40e2a28e53d1008852188b8cd767ashemminger		} else
618143969f24bc40e2a28e53d1008852188b8cd767ashemminger			invarg("unknown", *argv);
619143969f24bc40e2a28e53d1008852188b8cd767ashemminger
620143969f24bc40e2a28e53d1008852188b8cd767ashemminger		argc--; argv++;
621143969f24bc40e2a28e53d1008852188b8cd767ashemminger	}
622143969f24bc40e2a28e53d1008852188b8cd767ashemminger
623143969f24bc40e2a28e53d1008852188b8cd767ashemminger	if (rtnl_wilddump_request(&rth, preferred_family, RTM_GETNEIGHTBL) < 0) {
624143969f24bc40e2a28e53d1008852188b8cd767ashemminger		perror("Cannot send dump request");
625143969f24bc40e2a28e53d1008852188b8cd767ashemminger		exit(1);
626143969f24bc40e2a28e53d1008852188b8cd767ashemminger	}
627143969f24bc40e2a28e53d1008852188b8cd767ashemminger
628cd70f3f522e04b4d2fa80ae10292379bf223a53bStephen Hemminger	if (rtnl_dump_filter(&rth, print_ntable, stdout) < 0) {
629143969f24bc40e2a28e53d1008852188b8cd767ashemminger		fprintf(stderr, "Dump terminated\n");
630143969f24bc40e2a28e53d1008852188b8cd767ashemminger		exit(1);
631143969f24bc40e2a28e53d1008852188b8cd767ashemminger	}
632143969f24bc40e2a28e53d1008852188b8cd767ashemminger
633143969f24bc40e2a28e53d1008852188b8cd767ashemminger	return 0;
634143969f24bc40e2a28e53d1008852188b8cd767ashemminger}
635143969f24bc40e2a28e53d1008852188b8cd767ashemminger
636143969f24bc40e2a28e53d1008852188b8cd767ashemmingerint do_ipntable(int argc, char **argv)
637143969f24bc40e2a28e53d1008852188b8cd767ashemminger{
638143969f24bc40e2a28e53d1008852188b8cd767ashemminger	ll_init_map(&rth);
639143969f24bc40e2a28e53d1008852188b8cd767ashemminger
640143969f24bc40e2a28e53d1008852188b8cd767ashemminger	if (argc > 0) {
641143969f24bc40e2a28e53d1008852188b8cd767ashemminger		if (matches(*argv, "change") == 0 ||
642143969f24bc40e2a28e53d1008852188b8cd767ashemminger		    matches(*argv, "chg") == 0)
643143969f24bc40e2a28e53d1008852188b8cd767ashemminger			return ipntable_modify(RTM_SETNEIGHTBL,
644143969f24bc40e2a28e53d1008852188b8cd767ashemminger					       NLM_F_REPLACE,
645143969f24bc40e2a28e53d1008852188b8cd767ashemminger					       argc-1, argv+1);
646143969f24bc40e2a28e53d1008852188b8cd767ashemminger		if (matches(*argv, "show") == 0 ||
647143969f24bc40e2a28e53d1008852188b8cd767ashemminger		    matches(*argv, "lst") == 0 ||
648143969f24bc40e2a28e53d1008852188b8cd767ashemminger		    matches(*argv, "list") == 0)
649143969f24bc40e2a28e53d1008852188b8cd767ashemminger			return ipntable_show(argc-1, argv+1);
650143969f24bc40e2a28e53d1008852188b8cd767ashemminger		if (matches(*argv, "help") == 0)
651143969f24bc40e2a28e53d1008852188b8cd767ashemminger			usage();
652143969f24bc40e2a28e53d1008852188b8cd767ashemminger	} else
653143969f24bc40e2a28e53d1008852188b8cd767ashemminger		return ipntable_show(0, NULL);
654143969f24bc40e2a28e53d1008852188b8cd767ashemminger
655143969f24bc40e2a28e53d1008852188b8cd767ashemminger	fprintf(stderr, "Command \"%s\" is unknown, try \"ip ntable help\".\n", *argv);
656143969f24bc40e2a28e53d1008852188b8cd767ashemminger	exit(-1);
657143969f24bc40e2a28e53d1008852188b8cd767ashemminger}
658