]> git.proxmox.com Git - mirror_frr.git/blame - nhrpd/nhrp_vty.c
nhrpd: Make some debug prints more informative
[mirror_frr.git] / nhrpd / nhrp_vty.c
CommitLineData
2fb975da
TT
1/* NHRP vty handling
2 * Copyright (c) 2014-2015 Timo Teräs
3 *
4 * This file is free software: you may copy, redistribute and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
8 */
9
10#include "zebra.h"
11#include "command.h"
12#include "zclient.h"
13#include "stream.h"
901fda98 14#include "filter.h"
87b9e982 15#include "json.h"
2fb975da
TT
16
17#include "nhrpd.h"
18#include "netlink.h"
19
612c2c15 20static int nhrp_config_write(struct vty *vty);
2fb975da 21static struct cmd_node zebra_node = {
f4b8291f 22 .name = "zebra",
996c9314 23 .node = ZEBRA_NODE,
24389580 24 .parent_node = CONFIG_NODE,
2fb975da 25 .prompt = "%s(config-router)# ",
612c2c15 26 .config_write = nhrp_config_write,
2fb975da
TT
27};
28
612c2c15 29static int interface_config_write(struct vty *vty);
2fb975da 30static struct cmd_node nhrp_interface_node = {
f4b8291f 31 .name = "interface",
996c9314 32 .node = INTERFACE_NODE,
24389580 33 .parent_node = CONFIG_NODE,
2fb975da 34 .prompt = "%s(config-if)# ",
612c2c15 35 .config_write = interface_config_write,
2fb975da
TT
36};
37
819dc8bb 38#define NHRP_DEBUG_FLAGS_CMD "<all|common|event|interface|kernel|route|vici>"
2fb975da 39
996c9314
LB
40#define NHRP_DEBUG_FLAGS_STR \
41 "All messages\n" \
42 "Common messages (default)\n" \
43 "Event manager messages\n" \
44 "Interface messages\n" \
45 "Kernel messages\n" \
46 "Route messages\n" \
2fb975da
TT
47 "VICI messages\n"
48
49static const struct message debug_flags_desc[] = {
996c9314
LB
50 {NHRP_DEBUG_ALL, "all"}, {NHRP_DEBUG_COMMON, "common"},
51 {NHRP_DEBUG_IF, "interface"}, {NHRP_DEBUG_KERNEL, "kernel"},
52 {NHRP_DEBUG_ROUTE, "route"}, {NHRP_DEBUG_VICI, "vici"},
53 {NHRP_DEBUG_EVENT, "event"}, {0}};
2fb975da
TT
54
55static const struct message interface_flags_desc[] = {
996c9314
LB
56 {NHRP_IFF_SHORTCUT, "shortcut"},
57 {NHRP_IFF_REDIRECT, "redirect"},
58 {NHRP_IFF_REG_NO_UNIQUE, "registration no-unique"},
59 {0}};
2fb975da
TT
60
61static int nhrp_vty_return(struct vty *vty, int ret)
62{
996c9314
LB
63 static const char *const errmsgs[] = {
64 [NHRP_ERR_FAIL] = "Command failed",
65 [NHRP_ERR_NO_MEMORY] = "Out of memory",
66 [NHRP_ERR_UNSUPPORTED_INTERFACE] =
67 "NHRP not supported on this interface",
68 [NHRP_ERR_NHRP_NOT_ENABLED] =
69 "NHRP not enabled (set 'nhrp network-id' first)",
70 [NHRP_ERR_ENTRY_EXISTS] = "Entry exists already",
71 [NHRP_ERR_ENTRY_NOT_FOUND] = "Entry not found",
72 [NHRP_ERR_PROTOCOL_ADDRESS_MISMATCH] =
73 "Protocol address family does not match command (ip/ipv6 mismatch)",
2fb975da
TT
74 };
75 const char *str = NULL;
76 char buf[256];
77
78 if (ret == NHRP_OK)
79 return CMD_SUCCESS;
80
6c8ca260 81 if (ret > 0 && ret <= NHRP_ERR_MAX)
2fb975da
TT
82 if (errmsgs[ret])
83 str = errmsgs[ret];
84
85 if (!str) {
86 str = buf;
87 snprintf(buf, sizeof(buf), "Unknown error %d", ret);
88 }
89
996c9314 90 vty_out(vty, "%% %s\n", str);
2fb975da 91
996c9314
LB
92 return CMD_WARNING_CONFIG_FAILED;
93 ;
2fb975da
TT
94}
95
996c9314
LB
96static int toggle_flag(struct vty *vty, const struct message *flag_desc,
97 const char *name, int on_off, unsigned *flags)
2fb975da
TT
98{
99 int i;
100
101 for (i = 0; flag_desc[i].str != NULL; i++) {
102 if (strcmp(flag_desc[i].str, name) != 0)
103 continue;
104 if (on_off)
105 *flags |= flag_desc[i].key;
106 else
107 *flags &= ~flag_desc[i].key;
108 return CMD_SUCCESS;
109 }
110
996c9314
LB
111 vty_out(vty, "%% Invalid value %s\n", name);
112 return CMD_WARNING_CONFIG_FAILED;
113 ;
2fb975da
TT
114}
115
116#ifndef NO_DEBUG
117
87f6dc50
DS
118DEFUN_NOSH(show_debugging_nhrp, show_debugging_nhrp_cmd,
119 "show debugging [nhrp]",
120 SHOW_STR
121 "Debugging information\n"
122 "NHRP configuration\n")
2fb975da
TT
123{
124 int i;
125
996c9314 126 vty_out(vty, "NHRP debugging status:\n");
2fb975da
TT
127
128 for (i = 0; debug_flags_desc[i].str != NULL; i++) {
129 if (debug_flags_desc[i].key == NHRP_DEBUG_ALL)
130 continue;
131 if (!(debug_flags_desc[i].key & debug_flags))
132 continue;
133
996c9314 134 vty_out(vty, " NHRP %s debugging is on\n",
96ade3ed 135 debug_flags_desc[i].str);
2fb975da
TT
136 }
137
138 return CMD_SUCCESS;
139}
140
141DEFUN(debug_nhrp, debug_nhrp_cmd,
142 "debug nhrp " NHRP_DEBUG_FLAGS_CMD,
143 "Enable debug messages for specific or all parts.\n"
144 "NHRP information\n"
145 NHRP_DEBUG_FLAGS_STR)
146{
996c9314
LB
147 return toggle_flag(vty, debug_flags_desc, argv[2]->text, 1,
148 &debug_flags);
2fb975da
TT
149}
150
151DEFUN(no_debug_nhrp, no_debug_nhrp_cmd,
152 "no debug nhrp " NHRP_DEBUG_FLAGS_CMD,
153 NO_STR
154 "Disable debug messages for specific or all parts.\n"
155 "NHRP information\n"
156 NHRP_DEBUG_FLAGS_STR)
157{
996c9314
LB
158 return toggle_flag(vty, debug_flags_desc, argv[3]->text, 0,
159 &debug_flags);
2fb975da
TT
160}
161
162#endif /* NO_DEBUG */
163
164static int nhrp_config_write(struct vty *vty)
165{
166#ifndef NO_DEBUG
167 if (debug_flags == NHRP_DEBUG_ALL) {
996c9314 168 vty_out(vty, "debug nhrp all\n");
2fb975da
TT
169 } else {
170 int i;
171
172 for (i = 0; debug_flags_desc[i].str != NULL; i++) {
173 if (debug_flags_desc[i].key == NHRP_DEBUG_ALL)
174 continue;
175 if (!(debug_flags & debug_flags_desc[i].key))
176 continue;
996c9314
LB
177 vty_out(vty, "debug nhrp %s\n",
178 debug_flags_desc[i].str);
2fb975da
TT
179 }
180 }
996c9314 181 vty_out(vty, "!\n");
2fb975da
TT
182#endif /* NO_DEBUG */
183
184 if (nhrp_event_socket_path) {
996c9314 185 vty_out(vty, "nhrp event socket %s\n", nhrp_event_socket_path);
2fb975da
TT
186 }
187 if (netlink_nflog_group) {
996c9314 188 vty_out(vty, "nhrp nflog-group %d\n", netlink_nflog_group);
2fb975da
TT
189 }
190
191 return 0;
192}
193
194#define IP_STR "IP information\n"
195#define IPV6_STR "IPv6 information\n"
819dc8bb 196#define AFI_CMD "<ip|ipv6>"
2fb975da
TT
197#define AFI_STR IP_STR IPV6_STR
198#define NHRP_STR "Next Hop Resolution Protocol functions\n"
199
819dc8bb 200static afi_t cmd_to_afi(const struct cmd_token *tok)
2fb975da 201{
819dc8bb 202 return strcmp(tok->text, "ipv6") == 0 ? AFI_IP6 : AFI_IP;
2fb975da
TT
203}
204
205static const char *afi_to_cmd(afi_t afi)
206{
996c9314
LB
207 if (afi == AFI_IP6)
208 return "ipv6";
2fb975da
TT
209 return "ip";
210}
211
212DEFUN(nhrp_event_socket, nhrp_event_socket_cmd,
213 "nhrp event socket SOCKET",
214 NHRP_STR
215 "Event Manager commands\n"
216 "Event Manager unix socket path\n"
201f6271 217 "Unix path for the socket\n")
2fb975da 218{
819dc8bb 219 evmgr_set_socket(argv[3]->arg);
2fb975da
TT
220 return CMD_SUCCESS;
221}
222
223DEFUN(no_nhrp_event_socket, no_nhrp_event_socket_cmd,
224 "no nhrp event socket [SOCKET]",
225 NO_STR
226 NHRP_STR
227 "Event Manager commands\n"
228 "Event Manager unix socket path\n"
201f6271 229 "Unix path for the socket\n")
2fb975da
TT
230{
231 evmgr_set_socket(NULL);
232 return CMD_SUCCESS;
233}
234
235DEFUN(nhrp_nflog_group, nhrp_nflog_group_cmd,
819dc8bb 236 "nhrp nflog-group (1-65535)",
2fb975da
TT
237 NHRP_STR
238 "Specify NFLOG group number\n"
239 "NFLOG group number\n")
240{
241 uint32_t nfgroup;
242
facfee22 243 nfgroup = strtoul(argv[2]->arg, NULL, 10);
2fb975da
TT
244 netlink_set_nflog_group(nfgroup);
245
246 return CMD_SUCCESS;
247}
248
249DEFUN(no_nhrp_nflog_group, no_nhrp_nflog_group_cmd,
819dc8bb 250 "no nhrp nflog-group [(1-65535)]",
2fb975da
TT
251 NO_STR
252 NHRP_STR
253 "Specify NFLOG group number\n"
254 "NFLOG group number\n")
255{
256 netlink_set_nflog_group(0);
257 return CMD_SUCCESS;
258}
259
260DEFUN(tunnel_protection, tunnel_protection_cmd,
819dc8bb 261 "tunnel protection vici profile PROFILE [fallback-profile FALLBACK]",
2fb975da
TT
262 "NHRP/GRE integration\n"
263 "IPsec protection\n"
264 "VICI (StrongSwan)\n"
265 "IPsec profile\n"
266 "IPsec profile name\n"
267 "Fallback IPsec profile\n"
268 "Fallback IPsec profile name\n")
269{
819dc8bb 270 VTY_DECLVAR_CONTEXT(interface, ifp);
2fb975da 271
819dc8bb 272 nhrp_interface_set_protection(ifp, argv[4]->arg,
996c9314 273 argc > 6 ? argv[6]->arg : NULL);
2fb975da
TT
274 return CMD_SUCCESS;
275}
276
277DEFUN(no_tunnel_protection, no_tunnel_protection_cmd,
278 "no tunnel protection",
279 NO_STR
280 "NHRP/GRE integration\n"
281 "IPsec protection\n")
282{
819dc8bb 283 VTY_DECLVAR_CONTEXT(interface, ifp);
2fb975da
TT
284
285 nhrp_interface_set_protection(ifp, NULL, NULL);
286 return CMD_SUCCESS;
287}
288
289DEFUN(tunnel_source, tunnel_source_cmd,
290 "tunnel source INTERFACE",
291 "NHRP/GRE integration\n"
292 "Tunnel device binding tracking\n"
293 "Interface name\n")
294{
819dc8bb
DL
295 VTY_DECLVAR_CONTEXT(interface, ifp);
296 nhrp_interface_set_source(ifp, argv[2]->arg);
2fb975da
TT
297 return CMD_SUCCESS;
298}
299
300DEFUN(no_tunnel_source, no_tunnel_source_cmd,
301 "no tunnel source",
302 "NHRP/GRE integration\n"
303 "Tunnel device binding tracking\n"
304 "Interface name\n")
305{
819dc8bb 306 VTY_DECLVAR_CONTEXT(interface, ifp);
2fb975da
TT
307 nhrp_interface_set_source(ifp, NULL);
308 return CMD_SUCCESS;
309}
310
311DEFUN(if_nhrp_network_id, if_nhrp_network_id_cmd,
819dc8bb 312 AFI_CMD " nhrp network-id (1-4294967295)",
2fb975da
TT
313 AFI_STR
314 NHRP_STR
315 "Enable NHRP and specify network-id\n"
316 "System local ID to specify interface group\n")
317{
819dc8bb 318 VTY_DECLVAR_CONTEXT(interface, ifp);
2fb975da
TT
319 struct nhrp_interface *nifp = ifp->info;
320 afi_t afi = cmd_to_afi(argv[0]);
321
facfee22 322 nifp->afi[afi].network_id = strtoul(argv[3]->arg, NULL, 10);
2fb975da
TT
323 nhrp_interface_update(ifp);
324
325 return CMD_SUCCESS;
326}
327
328DEFUN(if_no_nhrp_network_id, if_no_nhrp_network_id_cmd,
819dc8bb 329 "no " AFI_CMD " nhrp network-id [(1-4294967295)]",
2fb975da
TT
330 NO_STR
331 AFI_STR
332 NHRP_STR
333 "Enable NHRP and specify network-id\n"
334 "System local ID to specify interface group\n")
335{
819dc8bb 336 VTY_DECLVAR_CONTEXT(interface, ifp);
2fb975da 337 struct nhrp_interface *nifp = ifp->info;
819dc8bb 338 afi_t afi = cmd_to_afi(argv[1]);
2fb975da
TT
339
340 nifp->afi[afi].network_id = 0;
341 nhrp_interface_update(ifp);
342
343 return CMD_SUCCESS;
344}
345
346DEFUN(if_nhrp_flags, if_nhrp_flags_cmd,
819dc8bb 347 AFI_CMD " nhrp <shortcut|redirect>",
2fb975da
TT
348 AFI_STR
349 NHRP_STR
350 "Allow shortcut establishment\n"
351 "Send redirect notifications\n")
352{
819dc8bb 353 VTY_DECLVAR_CONTEXT(interface, ifp);
2fb975da
TT
354 struct nhrp_interface *nifp = ifp->info;
355 afi_t afi = cmd_to_afi(argv[0]);
356
996c9314
LB
357 return toggle_flag(vty, interface_flags_desc, argv[2]->text, 1,
358 &nifp->afi[afi].flags);
2fb975da
TT
359}
360
361DEFUN(if_no_nhrp_flags, if_no_nhrp_flags_cmd,
819dc8bb 362 "no " AFI_CMD " nhrp <shortcut|redirect>",
2fb975da
TT
363 NO_STR
364 AFI_STR
365 NHRP_STR
366 "Allow shortcut establishment\n"
367 "Send redirect notifications\n")
368{
819dc8bb 369 VTY_DECLVAR_CONTEXT(interface, ifp);
2fb975da 370 struct nhrp_interface *nifp = ifp->info;
819dc8bb 371 afi_t afi = cmd_to_afi(argv[1]);
2fb975da 372
996c9314
LB
373 return toggle_flag(vty, interface_flags_desc, argv[3]->text, 0,
374 &nifp->afi[afi].flags);
2fb975da
TT
375}
376
377DEFUN(if_nhrp_reg_flags, if_nhrp_reg_flags_cmd,
819dc8bb 378 AFI_CMD " nhrp registration no-unique",
2fb975da
TT
379 AFI_STR
380 NHRP_STR
381 "Registration configuration\n"
382 "Don't set unique flag\n")
383{
819dc8bb 384 VTY_DECLVAR_CONTEXT(interface, ifp);
2fb975da
TT
385 struct nhrp_interface *nifp = ifp->info;
386 afi_t afi = cmd_to_afi(argv[0]);
387 char name[256];
819dc8bb 388 snprintf(name, sizeof(name), "registration %s", argv[3]->text);
996c9314
LB
389 return toggle_flag(vty, interface_flags_desc, name, 1,
390 &nifp->afi[afi].flags);
2fb975da
TT
391}
392
393DEFUN(if_no_nhrp_reg_flags, if_no_nhrp_reg_flags_cmd,
819dc8bb 394 "no " AFI_CMD " nhrp registration no-unique",
2fb975da
TT
395 NO_STR
396 AFI_STR
397 NHRP_STR
398 "Registration configuration\n"
399 "Don't set unique flag\n")
400{
819dc8bb 401 VTY_DECLVAR_CONTEXT(interface, ifp);
2fb975da 402 struct nhrp_interface *nifp = ifp->info;
819dc8bb 403 afi_t afi = cmd_to_afi(argv[1]);
2fb975da 404 char name[256];
819dc8bb 405 snprintf(name, sizeof(name), "registration %s", argv[4]->text);
996c9314
LB
406 return toggle_flag(vty, interface_flags_desc, name, 0,
407 &nifp->afi[afi].flags);
2fb975da
TT
408}
409
410DEFUN(if_nhrp_holdtime, if_nhrp_holdtime_cmd,
819dc8bb 411 AFI_CMD " nhrp holdtime (1-65000)",
2fb975da
TT
412 AFI_STR
413 NHRP_STR
414 "Specify NBMA address validity time\n"
415 "Time in seconds that NBMA addresses are advertised valid\n")
416{
819dc8bb 417 VTY_DECLVAR_CONTEXT(interface, ifp);
2fb975da
TT
418 struct nhrp_interface *nifp = ifp->info;
419 afi_t afi = cmd_to_afi(argv[0]);
420
facfee22 421 nifp->afi[afi].holdtime = strtoul(argv[3]->arg, NULL, 10);
2fb975da
TT
422 nhrp_interface_update(ifp);
423
424 return CMD_SUCCESS;
425}
426
427DEFUN(if_no_nhrp_holdtime, if_no_nhrp_holdtime_cmd,
819dc8bb 428 "no " AFI_CMD " nhrp holdtime [(1-65000)]",
2fb975da
TT
429 NO_STR
430 AFI_STR
431 NHRP_STR
432 "Specify NBMA address validity time\n"
433 "Time in seconds that NBMA addresses are advertised valid\n")
434{
819dc8bb 435 VTY_DECLVAR_CONTEXT(interface, ifp);
2fb975da 436 struct nhrp_interface *nifp = ifp->info;
819dc8bb 437 afi_t afi = cmd_to_afi(argv[1]);
2fb975da
TT
438
439 nifp->afi[afi].holdtime = NHRPD_DEFAULT_HOLDTIME;
440 nhrp_interface_update(ifp);
441
442 return CMD_SUCCESS;
443}
444
445DEFUN(if_nhrp_mtu, if_nhrp_mtu_cmd,
819dc8bb 446 "ip nhrp mtu <(576-1500)|opennhrp>",
2fb975da
TT
447 IP_STR
448 NHRP_STR
449 "Configure NHRP advertised MTU\n"
450 "MTU value\n"
efd7904e 451 "Advertise bound interface MTU similar to OpenNHRP\n")
2fb975da 452{
819dc8bb 453 VTY_DECLVAR_CONTEXT(interface, ifp);
2fb975da
TT
454 struct nhrp_interface *nifp = ifp->info;
455
819dc8bb 456 if (argv[3]->arg[0] == 'o') {
2fb975da
TT
457 nifp->afi[AFI_IP].configured_mtu = -1;
458 } else {
996c9314
LB
459 nifp->afi[AFI_IP].configured_mtu =
460 strtoul(argv[3]->arg, NULL, 10);
2fb975da
TT
461 }
462 nhrp_interface_update_mtu(ifp, AFI_IP);
463
464 return CMD_SUCCESS;
465}
466
467DEFUN(if_no_nhrp_mtu, if_no_nhrp_mtu_cmd,
819dc8bb 468 "no ip nhrp mtu [(576-1500)|opennhrp]",
2fb975da
TT
469 NO_STR
470 IP_STR
471 NHRP_STR
472 "Configure NHRP advertised MTU\n"
473 "MTU value\n"
efd7904e 474 "Advertise bound interface MTU similar to OpenNHRP\n")
2fb975da 475{
819dc8bb 476 VTY_DECLVAR_CONTEXT(interface, ifp);
2fb975da
TT
477 struct nhrp_interface *nifp = ifp->info;
478
479 nifp->afi[AFI_IP].configured_mtu = 0;
480 nhrp_interface_update_mtu(ifp, AFI_IP);
481 return CMD_SUCCESS;
482}
483
484DEFUN(if_nhrp_map, if_nhrp_map_cmd,
819dc8bb 485 AFI_CMD " nhrp map <A.B.C.D|X:X::X:X> <A.B.C.D|local>",
2fb975da
TT
486 AFI_STR
487 NHRP_STR
488 "Nexthop Server configuration\n"
489 "IPv4 protocol address\n"
490 "IPv6 protocol address\n"
491 "IPv4 NBMA address\n"
492 "Handle protocol address locally\n")
493{
819dc8bb 494 VTY_DECLVAR_CONTEXT(interface, ifp);
2fb975da
TT
495 afi_t afi = cmd_to_afi(argv[0]);
496 union sockunion proto_addr, nbma_addr;
fef2ed13 497 struct nhrp_cache_config *cc;
2fb975da 498 struct nhrp_cache *c;
fef2ed13 499 enum nhrp_cache_type type;
2fb975da 500
996c9314
LB
501 if (str2sockunion(argv[3]->arg, &proto_addr) < 0
502 || afi2family(afi) != sockunion_family(&proto_addr))
2fb975da
TT
503 return nhrp_vty_return(vty, NHRP_ERR_PROTOCOL_ADDRESS_MISMATCH);
504
fef2ed13
PG
505 if (strmatch(argv[4]->text, "local"))
506 type = NHRP_CACHE_LOCAL;
507 else {
508 if (str2sockunion(argv[4]->arg, &nbma_addr) < 0)
509 return nhrp_vty_return(vty, NHRP_ERR_FAIL);
510 type = NHRP_CACHE_STATIC;
511 }
512 cc = nhrp_cache_config_get(ifp, &proto_addr, 1);
513 if (!cc)
514 return nhrp_vty_return(vty, NHRP_ERR_FAIL);
515 cc->nbma = nbma_addr;
516 cc->type = type;
517 /* gre layer not ready */
518 if (ifp->ifindex == IFINDEX_INTERNAL)
519 return CMD_SUCCESS;
520
2fb975da
TT
521 c = nhrp_cache_get(ifp, &proto_addr, 1);
522 if (!c)
523 return nhrp_vty_return(vty, NHRP_ERR_FAIL);
524
525 c->map = 1;
fef2ed13 526 if (type == NHRP_CACHE_LOCAL)
996c9314 527 nhrp_cache_update_binding(c, NHRP_CACHE_LOCAL, 0, NULL, 0,
85365e51 528 NULL, NULL);
fef2ed13 529 else
2fb975da 530 nhrp_cache_update_binding(c, NHRP_CACHE_STATIC, 0,
996c9314 531 nhrp_peer_get(ifp, &nbma_addr), 0,
85365e51 532 NULL, NULL);
2fb975da
TT
533 return CMD_SUCCESS;
534}
535
2d4eab22 536DEFUN(if_no_nhrp_map, if_no_nhrp_map_cmd,
29ff6b5c 537 "no " AFI_CMD " nhrp map <A.B.C.D|X:X::X:X> [<A.B.C.D|local>]",
2d4eab22
TT
538 NO_STR
539 AFI_STR
540 NHRP_STR
541 "Nexthop Server configuration\n"
542 "IPv4 protocol address\n"
29ff6b5c
JAG
543 "IPv6 protocol address\n"
544 "IPv4 NBMA address\n"
545 "Handle protocol address locally\n")
2d4eab22 546{
996c9314 547 VTY_DECLVAR_CONTEXT(interface, ifp);
2d4eab22 548 afi_t afi = cmd_to_afi(argv[1]);
b5503506 549 union sockunion proto_addr, nbma_addr;
fef2ed13 550 struct nhrp_cache_config *cc;
2d4eab22
TT
551 struct nhrp_cache *c;
552
996c9314
LB
553 if (str2sockunion(argv[4]->arg, &proto_addr) < 0
554 || afi2family(afi) != sockunion_family(&proto_addr))
2d4eab22
TT
555 return nhrp_vty_return(vty, NHRP_ERR_PROTOCOL_ADDRESS_MISMATCH);
556
fef2ed13
PG
557 cc = nhrp_cache_config_get(ifp, &proto_addr, 0);
558 if (!cc)
559 return nhrp_vty_return(vty, NHRP_ERR_FAIL);
560 nhrp_cache_config_free(cc);
561
2d4eab22 562 c = nhrp_cache_get(ifp, &proto_addr, 0);
fef2ed13 563 /* silently return */
2d4eab22 564 if (!c || !c->map)
fef2ed13 565 return CMD_SUCCESS;
2d4eab22 566
b5503506 567 nhrp_cache_update_binding(c, c->cur.type, -1,
00683a14
RD
568 nhrp_peer_get(ifp, &nbma_addr), 0, NULL,
569 NULL);
2d4eab22
TT
570 return CMD_SUCCESS;
571}
572
2fb975da 573DEFUN(if_nhrp_nhs, if_nhrp_nhs_cmd,
819dc8bb 574 AFI_CMD " nhrp nhs <A.B.C.D|X:X::X:X|dynamic> nbma <A.B.C.D|FQDN>",
2fb975da
TT
575 AFI_STR
576 NHRP_STR
577 "Nexthop Server configuration\n"
578 "IPv4 protocol address\n"
579 "IPv6 protocol address\n"
580 "Automatic detection of protocol address\n"
819dc8bb 581 "NBMA address\n"
2fb975da
TT
582 "IPv4 NBMA address\n"
583 "Fully qualified domain name for NBMA address(es)\n")
584{
819dc8bb 585 VTY_DECLVAR_CONTEXT(interface, ifp);
2fb975da
TT
586 afi_t afi = cmd_to_afi(argv[0]);
587 union sockunion proto_addr;
588 int ret;
589
819dc8bb 590 if (str2sockunion(argv[3]->arg, &proto_addr) < 0)
2fb975da
TT
591 sockunion_family(&proto_addr) = AF_UNSPEC;
592
819dc8bb 593 ret = nhrp_nhs_add(ifp, afi, &proto_addr, argv[5]->arg);
2fb975da
TT
594 return nhrp_vty_return(vty, ret);
595}
596
597DEFUN(if_no_nhrp_nhs, if_no_nhrp_nhs_cmd,
819dc8bb 598 "no " AFI_CMD " nhrp nhs <A.B.C.D|X:X::X:X|dynamic> nbma <A.B.C.D|FQDN>",
2fb975da
TT
599 NO_STR
600 AFI_STR
601 NHRP_STR
602 "Nexthop Server configuration\n"
603 "IPv4 protocol address\n"
604 "IPv6 protocol address\n"
605 "Automatic detection of protocol address\n"
819dc8bb 606 "NBMA address\n"
2fb975da
TT
607 "IPv4 NBMA address\n"
608 "Fully qualified domain name for NBMA address(es)\n")
609{
819dc8bb
DL
610 VTY_DECLVAR_CONTEXT(interface, ifp);
611 afi_t afi = cmd_to_afi(argv[1]);
2fb975da
TT
612 union sockunion proto_addr;
613 int ret;
614
819dc8bb 615 if (str2sockunion(argv[4]->arg, &proto_addr) < 0)
2fb975da
TT
616 sockunion_family(&proto_addr) = AF_UNSPEC;
617
819dc8bb 618 ret = nhrp_nhs_del(ifp, afi, &proto_addr, argv[6]->arg);
2fb975da
TT
619 return nhrp_vty_return(vty, ret);
620}
621
622struct info_ctx {
623 struct vty *vty;
624 afi_t afi;
625 int count;
87b9e982 626 struct json_object *json;
2fb975da
TT
627};
628
629static void show_ip_nhrp_cache(struct nhrp_cache *c, void *pctx)
630{
631 struct info_ctx *ctx = pctx;
632 struct vty *vty = ctx->vty;
85365e51 633 char buf[3][SU_ADDRSTRLEN];
87b9e982 634 struct json_object *json = NULL;
2fb975da
TT
635
636 if (ctx->afi != family2afi(sockunion_family(&c->remote_addr)))
637 return;
638
87b9e982
PG
639
640 if (!ctx->count && !ctx->json) {
00683a14
RD
641 vty_out(vty, "%-8s %-8s %-24s %-24s %-24s %-6s %s\n", "Iface",
642 "Type", "Protocol", "NBMA", "Claimed NBMA", "Flags",
643 "Identity");
2fb975da
TT
644 }
645 ctx->count++;
646
87b9e982 647 sockunion2str(&c->remote_addr, buf[0], sizeof(buf[0]));
bcf5673d
AL
648 if (c->cur.type == NHRP_CACHE_LOCAL) {
649 struct nhrp_interface *nifp = c->ifp->info;
87b9e982 650
bcf5673d
AL
651 if (sockunion_family(&nifp->nbma) != AF_UNSPEC) {
652 sockunion2str(&nifp->nbma, buf[1], sizeof(buf[1]));
653 sockunion2str(&nifp->nbma, buf[2], sizeof(buf[2]));
654 }
655 else {
656 snprintf(buf[1], sizeof(buf[1]), "-");
657 snprintf(buf[2], sizeof(buf[2]), "-");
658 }
85365e51 659
bcf5673d
AL
660 /* if we are behind NAT then update NBMA field */
661 if (sockunion_family(&nifp->nat_nbma) != AF_UNSPEC)
662 sockunion2str(&nifp->nat_nbma, buf[1], sizeof(buf[1]));
663 } else {
664 if (c->cur.peer)
665 sockunion2str(&c->cur.peer->vc->remote.nbma,
666 buf[1], sizeof(buf[1]));
667 else
668 snprintf(buf[1], sizeof(buf[1]), "-");
669
670 if (c->cur.peer
671 && sockunion_family(&c->cur.remote_nbma_claimed)
0551aead 672 != AF_UNSPEC)
bcf5673d
AL
673 sockunion2str(&c->cur.remote_nbma_claimed,
674 buf[2], sizeof(buf[2]));
675 else
676 snprintf(buf[2], sizeof(buf[2]), "-");
677 }
85365e51 678
e0a1fb22 679 if (ctx->json) {
87b9e982
PG
680 json = json_object_new_object();
681 json_object_string_add(json, "interface", c->ifp->name);
682 json_object_string_add(json, "type",
683 nhrp_cache_type_str[c->cur.type]);
684 json_object_string_add(json, "protocol", buf[0]);
685 json_object_string_add(json, "nbma", buf[1]);
85365e51 686 json_object_string_add(json, "claimed_nbma", buf[2]);
87b9e982
PG
687
688 if (c->used)
689 json_object_boolean_true_add(json, "used");
690 else
691 json_object_boolean_false_add(json, "used");
692
693 if (c->t_timeout)
694 json_object_boolean_true_add(json, "timeout");
695 else
696 json_object_boolean_false_add(json, "timeout");
697
698 if (c->t_auth)
699 json_object_boolean_true_add(json, "auth");
700 else
701 json_object_boolean_false_add(json, "auth");
702
703 if (c->cur.peer)
704 json_object_string_add(json, "identity",
705 c->cur.peer->vc->remote.id);
706 else
707 json_object_string_add(json, "identity", "-");
708
709 json_object_array_add(ctx->json, json);
710 return;
711 }
85365e51
AL
712 vty_out(ctx->vty, "%-8s %-8s %-24s %-24s %-24s %c%c%c %s\n",
713 c->ifp->name,
2fb975da 714 nhrp_cache_type_str[c->cur.type],
85365e51 715 buf[0], buf[1], buf[2],
996c9314 716 c->used ? 'U' : ' ', c->t_timeout ? 'T' : ' ',
2fb975da 717 c->t_auth ? 'A' : ' ',
96ade3ed 718 c->cur.peer ? c->cur.peer->vc->remote.id : "-");
2fb975da
TT
719}
720
996c9314
LB
721static void show_ip_nhrp_nhs(struct nhrp_nhs *n, struct nhrp_registration *reg,
722 void *pctx)
0ca036b4
TT
723{
724 struct info_ctx *ctx = pctx;
725 struct vty *vty = ctx->vty;
726 char buf[2][SU_ADDRSTRLEN];
87b9e982 727 struct json_object *json = NULL;
0ca036b4 728
87b9e982 729 if (!ctx->count && !ctx->json) {
996c9314
LB
730 vty_out(vty, "%-8s %-24s %-16s %-16s\n", "Iface", "FQDN",
731 "NBMA", "Protocol");
0ca036b4
TT
732 }
733 ctx->count++;
734
87b9e982
PG
735 if (reg && reg->peer)
736 sockunion2str(&reg->peer->vc->remote.nbma,
737 buf[0], sizeof(buf[0]));
738 else
739 snprintf(buf[0], sizeof(buf[0]), "-");
740 sockunion2str(reg ? &reg->proto_addr : &n->proto_addr, buf[1],
741 sizeof(buf[1]));
742
743 if (ctx->json) {
744 json = json_object_new_object();
745 json_object_string_add(json, "interface", n->ifp->name);
746 json_object_string_add(json, "fqdn", n->nbma_fqdn);
747 json_object_string_add(json, "nbma", buf[0]);
748 json_object_string_add(json, "protocol", buf[1]);
749
750 json_object_array_add(ctx->json, json);
751 return;
752 }
753
996c9314 754 vty_out(vty, "%-8s %-24s %-16s %-16s\n", n->ifp->name, n->nbma_fqdn,
87b9e982 755 buf[0], buf[1]);
0ca036b4
TT
756}
757
758static void show_ip_nhrp_shortcut(struct nhrp_shortcut *s, void *pctx)
759{
760 struct info_ctx *ctx = pctx;
761 struct nhrp_cache *c;
762 struct vty *vty = ctx->vty;
763 char buf1[PREFIX_STRLEN], buf2[SU_ADDRSTRLEN];
87b9e982 764 struct json_object *json = NULL;
0ca036b4
TT
765
766 if (!ctx->count) {
996c9314 767 vty_out(vty, "%-8s %-24s %-24s %s\n", "Type", "Prefix", "Via",
96ade3ed 768 "Identity");
0ca036b4
TT
769 }
770 ctx->count++;
771
772 c = s->cache;
87b9e982
PG
773 if (c)
774 sockunion2str(&c->remote_addr, buf2, sizeof(buf2));
775 prefix2str(s->p, buf1, sizeof(buf1));
776
777 if (ctx->json) {
778 json = json_object_new_object();
779 json_object_string_add(json, "type",
780 nhrp_cache_type_str[s->type]);
781 json_object_string_add(json, "prefix", buf1);
782
783 if (c)
784 json_object_string_add(json, "via", buf2);
785
786 if (c && c->cur.peer)
787 json_object_string_add(json, "identity",
788 c->cur.peer->vc->remote.id);
789 else
790 json_object_string_add(json, "identity", "");
791
792 json_object_array_add(ctx->json, json);
793 return;
794 }
795
796 vty_out(ctx->vty, "%-8s %-24s %-24s %s\n",
797 nhrp_cache_type_str[s->type],
798 buf1, buf2,
96ade3ed 799 (c && c->cur.peer) ? c->cur.peer->vc->remote.id : "");
0ca036b4
TT
800}
801
2fb975da
TT
802static void show_ip_opennhrp_cache(struct nhrp_cache *c, void *pctx)
803{
804 struct info_ctx *ctx = pctx;
87b9e982
PG
805 char buf[3][SU_ADDRSTRLEN];
806 struct json_object *json = NULL;
807
2fb975da
TT
808
809 if (ctx->afi != family2afi(sockunion_family(&c->remote_addr)))
810 return;
811
87b9e982
PG
812 sockunion2str(&c->remote_addr, buf[0], sizeof(buf[0]));
813 if (c->cur.peer)
814 sockunion2str(&c->cur.peer->vc->remote.nbma, buf[1],
815 sizeof(buf[1]));
816 if (sockunion_family(&c->cur.remote_nbma_natoa) != AF_UNSPEC)
817 sockunion2str(&c->cur.remote_nbma_natoa, buf[2],
818 sizeof(buf[2]));
819 if (ctx->json) {
820 json = json_object_new_object();
821 json_object_string_add(json, "type",
822 nhrp_cache_type_str[c->cur.type]);
823
824 if (c->cur.peer && c->cur.peer->online)
825 json_object_boolean_true_add(json, "up");
826 else
827 json_object_boolean_false_add(json, "up");
828
829 if (c->used)
830 json_object_boolean_true_add(json, "used");
831 else
832 json_object_boolean_false_add(json, "used");
833
834 json_object_string_add(json, "protocolAddress", buf[0]);
835 json_object_int_add(json, "protocolAddressSize",
836 8 * family2addrsize(sockunion_family
837 (&c->remote_addr)));
838
839 if (c->cur.peer)
840 json_object_string_add(json, "nbmaAddress", buf[1]);
841
842 if (sockunion_family(&c->cur.remote_nbma_natoa) != AF_UNSPEC)
843 json_object_string_add(json, "nbmaNatOaAddress",
844 buf[2]);
845
846 json_object_array_add(ctx->json, json);
847 return;
848 }
181039f3 849 vty_out(ctx->vty,
996c9314
LB
850 "Type: %s\n"
851 "Flags:%s%s\n"
852 "Protocol-Address: %s/%zu\n",
853 nhrp_cache_type_str[c->cur.type],
854 (c->cur.peer && c->cur.peer->online) ? " up" : "",
855 c->used ? " used" : "",
87b9e982 856 buf[0],
996c9314 857 8 * family2addrsize(sockunion_family(&c->remote_addr)));
2fb975da 858
87b9e982
PG
859 if (c->cur.peer)
860 vty_out(ctx->vty, "NBMA-Address: %s\n", buf[1]);
2fb975da 861
87b9e982
PG
862 if (sockunion_family(&c->cur.remote_nbma_natoa) != AF_UNSPEC)
863 vty_out(ctx->vty, "NBMA-NAT-OA-Address: %s\n", buf[2]);
2fb975da 864
181039f3 865 vty_out(ctx->vty, "\n\n");
2fb975da
TT
866}
867
2fb975da 868DEFUN(show_ip_nhrp, show_ip_nhrp_cmd,
87b9e982 869 "show " AFI_CMD " nhrp [cache|nhs|shortcut|opennhrp] [json]",
2fb975da
TT
870 SHOW_STR
871 AFI_STR
872 "NHRP information\n"
873 "Forwarding cache information\n"
0ca036b4 874 "Next hop server information\n"
2fb975da 875 "Shortcut information\n"
87b9e982
PG
876 "opennhrpctl style cache dump\n"
877 JSON_STR)
2fb975da 878{
f4e14fdb 879 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
2fb975da
TT
880 struct interface *ifp;
881 struct info_ctx ctx = {
87b9e982 882 .vty = vty, .afi = cmd_to_afi(argv[1]), .json = NULL
2fb975da 883 };
87b9e982
PG
884 bool uj = use_json(argc, argv);
885 struct json_object *json_path = NULL;
886 struct json_object *json_vrf = NULL, *json_vrf_path = NULL;
887 int ret = CMD_SUCCESS;
888
889 if (uj) {
890 json_vrf = json_object_new_object();
891 json_vrf_path = json_object_new_object();
892 json_path = json_object_new_array();
893 ctx.json = json_path;
894 }
819dc8bb 895 if (argc <= 3 || argv[3]->text[0] == 'c') {
451fda4f 896 FOR_ALL_INTERFACES (vrf, ifp)
2fb975da 897 nhrp_cache_foreach(ifp, show_ip_nhrp_cache, &ctx);
0ca036b4 898 } else if (argv[3]->text[0] == 'n') {
451fda4f 899 FOR_ALL_INTERFACES (vrf, ifp)
0ca036b4
TT
900 nhrp_nhs_foreach(ifp, ctx.afi, show_ip_nhrp_nhs, &ctx);
901 } else if (argv[3]->text[0] == 's') {
902 nhrp_shortcut_foreach(ctx.afi, show_ip_nhrp_shortcut, &ctx);
903 } else {
87b9e982
PG
904 if (!ctx.json)
905 vty_out(vty, "Status: ok\n\n");
906 else
907 json_object_string_add(json_vrf, "status", "ok");
908
2fb975da 909 ctx.count++;
451fda4f 910 FOR_ALL_INTERFACES (vrf, ifp)
2fb975da 911 nhrp_cache_foreach(ifp, show_ip_opennhrp_cache, &ctx);
2fb975da
TT
912 }
913
87b9e982
PG
914 if (uj)
915 json_object_int_add(json_vrf, "entriesCount", ctx.count);
2fb975da 916 if (!ctx.count) {
87b9e982
PG
917 if (!ctx.json)
918 vty_out(vty, "%% No entries\n");
919 ret = CMD_WARNING;
2fb975da 920 }
87b9e982
PG
921 if (uj) {
922 json_object_object_add(json_vrf_path, "attr", json_vrf);
923 json_object_object_add(json_vrf_path, "table", ctx.json);
924 vty_out(vty, "%s",
925 json_object_to_json_string_ext(
926 json_vrf_path, JSON_C_TO_STRING_PRETTY));
927 json_object_free(json_vrf_path);
928 }
929 return ret;
2fb975da
TT
930}
931
87b9e982
PG
932struct dmvpn_cfg {
933 struct vty *vty;
934 struct json_object *json;
935};
936
2fb975da
TT
937static void show_dmvpn_entry(struct nhrp_vc *vc, void *ctx)
938{
87b9e982
PG
939 struct dmvpn_cfg *ctxt = ctx;
940 struct vty *vty;
2fb975da 941 char buf[2][SU_ADDRSTRLEN];
87b9e982 942 struct json_object *json = NULL;
2fb975da 943
87b9e982
PG
944 if (!ctxt || !ctxt->vty)
945 return;
946 vty = ctxt->vty;
947 sockunion2str(&vc->local.nbma, buf[0], sizeof(buf[0]));
948 sockunion2str(&vc->remote.nbma, buf[1], sizeof(buf[1]));
949 if (ctxt->json) {
950 json = json_object_new_object();
951 json_object_string_add(json, "src", buf[0]);
952 json_object_string_add(json, "dst", buf[1]);
953
954 if (notifier_active(&vc->notifier_list))
955 json_object_boolean_true_add(json, "notifierActive");
956 else
957 json_object_boolean_false_add(json, "notifierActive");
958
959 json_object_int_add(json, "sas", vc->ipsec);
960 json_object_string_add(json, "identity", vc->remote.id);
961 json_object_array_add(ctxt->json, json);
962 } else {
963 vty_out(vty, "%-24s %-24s %c %-4d %-24s\n",
964 buf[0], buf[1], notifier_active(&vc->notifier_list) ?
965 'n' : ' ', vc->ipsec, vc->remote.id);
966 }
2fb975da
TT
967}
968
969DEFUN(show_dmvpn, show_dmvpn_cmd,
87b9e982 970 "show dmvpn [json]",
2fb975da 971 SHOW_STR
87b9e982
PG
972 "DMVPN information\n"
973 JSON_STR)
974{
975 bool uj = use_json(argc, argv);
976 struct dmvpn_cfg ctxt;
977 struct json_object *json_path = NULL;
978
979 ctxt.vty = vty;
980 if (!uj) {
981 ctxt.json = NULL;
982 vty_out(vty, "%-24s %-24s %-6s %-4s %-24s\n",
983 "Src", "Dst", "Flags", "SAs", "Identity");
984 } else {
985 json_path = json_object_new_array();
986 ctxt.json = json_path;
987 }
988 nhrp_vc_foreach(show_dmvpn_entry, &ctxt);
989 if (uj) {
990 vty_out(vty, "%s",
991 json_object_to_json_string_ext(
992 json_path, JSON_C_TO_STRING_PRETTY));
993 json_object_free(json_path);
994 }
2fb975da
TT
995 return CMD_SUCCESS;
996}
997
998static void clear_nhrp_cache(struct nhrp_cache *c, void *data)
999{
1000 struct info_ctx *ctx = data;
db89e514 1001 if (c->cur.type <= NHRP_CACHE_DYNAMIC) {
00683a14
RD
1002 nhrp_cache_update_binding(c, c->cur.type, -1, NULL, 0, NULL,
1003 NULL);
2fb975da
TT
1004 ctx->count++;
1005 }
1006}
1007
1008static void clear_nhrp_shortcut(struct nhrp_shortcut *s, void *data)
1009{
1010 struct info_ctx *ctx = data;
1011 nhrp_shortcut_purge(s, 1);
1012 ctx->count++;
1013}
1014
1015DEFUN(clear_nhrp, clear_nhrp_cmd,
819dc8bb 1016 "clear " AFI_CMD " nhrp <cache|shortcut>",
2fb975da
TT
1017 CLEAR_STR
1018 AFI_STR
1019 NHRP_STR
1020 "Dynamic cache entries\n"
1021 "Shortcut entries\n")
1022{
f4e14fdb 1023 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
2fb975da
TT
1024 struct interface *ifp;
1025 struct info_ctx ctx = {
996c9314 1026 .vty = vty, .afi = cmd_to_afi(argv[1]), .count = 0,
2fb975da
TT
1027 };
1028
819dc8bb 1029 if (argc <= 3 || argv[3]->text[0] == 'c') {
451fda4f 1030 FOR_ALL_INTERFACES (vrf, ifp)
2fb975da
TT
1031 nhrp_cache_foreach(ifp, clear_nhrp_cache, &ctx);
1032 } else {
1033 nhrp_shortcut_foreach(ctx.afi, clear_nhrp_shortcut, &ctx);
1034 }
1035
1036 if (!ctx.count) {
996c9314 1037 vty_out(vty, "%% No entries\n");
2fb975da
TT
1038 return CMD_WARNING;
1039 }
1040
996c9314 1041 vty_out(vty, "%% %d entries cleared\n", ctx.count);
2fb975da
TT
1042 return CMD_SUCCESS;
1043}
1044
1045struct write_map_ctx {
1046 struct vty *vty;
1047 int family;
1048 const char *aficmd;
1049};
1050
fef2ed13 1051static void interface_config_write_nhrp_map(struct nhrp_cache_config *c, void *data)
2fb975da
TT
1052{
1053 struct write_map_ctx *ctx = data;
1054 struct vty *vty = ctx->vty;
1055 char buf[2][SU_ADDRSTRLEN];
1056
996c9314
LB
1057 if (sockunion_family(&c->remote_addr) != ctx->family)
1058 return;
2fb975da 1059
996c9314 1060 vty_out(vty, " %s nhrp map %s %s\n", ctx->aficmd,
0d6f7fd6 1061 sockunion2str(&c->remote_addr, buf[0], sizeof(buf[0])),
fef2ed13
PG
1062 c->type == NHRP_CACHE_LOCAL
1063 ? "local" : sockunion2str(&c->nbma, buf[1], sizeof(buf[1])));
2fb975da
TT
1064}
1065
1066static int interface_config_write(struct vty *vty)
1067{
f4e14fdb 1068 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
2fb975da 1069 struct write_map_ctx mapctx;
2fb975da
TT
1070 struct interface *ifp;
1071 struct nhrp_interface *nifp;
1072 struct nhrp_nhs *nhs;
1073 const char *aficmd;
1074 afi_t afi;
1075 char buf[SU_ADDRSTRLEN];
1076 int i;
1077
451fda4f 1078 FOR_ALL_INTERFACES (vrf, ifp) {
a8b828f3 1079 vty_frame(vty, "interface %s\n", ifp->name);
2fb975da 1080 if (ifp->desc)
996c9314 1081 vty_out(vty, " description %s\n", ifp->desc);
2fb975da
TT
1082
1083 nifp = ifp->info;
1084 if (nifp->ipsec_profile) {
1085 vty_out(vty, " tunnel protection vici profile %s",
1086 nifp->ipsec_profile);
1087 if (nifp->ipsec_fallback_profile)
1088 vty_out(vty, " fallback-profile %s",
1089 nifp->ipsec_fallback_profile);
996c9314 1090 vty_out(vty, "\n");
2fb975da
TT
1091 }
1092 if (nifp->source)
996c9314 1093 vty_out(vty, " tunnel source %s\n", nifp->source);
2fb975da
TT
1094
1095 for (afi = 0; afi < AFI_MAX; afi++) {
1096 struct nhrp_afi_data *ad = &nifp->afi[afi];
1097
1098 aficmd = afi_to_cmd(afi);
1099
1100 if (ad->network_id)
996c9314
LB
1101 vty_out(vty, " %s nhrp network-id %u\n", aficmd,
1102 ad->network_id);
2fb975da
TT
1103
1104 if (ad->holdtime != NHRPD_DEFAULT_HOLDTIME)
996c9314
LB
1105 vty_out(vty, " %s nhrp holdtime %u\n", aficmd,
1106 ad->holdtime);
2fb975da
TT
1107
1108 if (ad->configured_mtu < 0)
996c9314 1109 vty_out(vty, " %s nhrp mtu opennhrp\n", aficmd);
2fb975da 1110 else if (ad->configured_mtu)
996c9314
LB
1111 vty_out(vty, " %s nhrp mtu %u\n", aficmd,
1112 ad->configured_mtu);
2fb975da
TT
1113
1114 for (i = 0; interface_flags_desc[i].str != NULL; i++) {
1115 if (!(ad->flags & interface_flags_desc[i].key))
1116 continue;
996c9314
LB
1117 vty_out(vty, " %s nhrp %s\n", aficmd,
1118 interface_flags_desc[i].str);
2fb975da
TT
1119 }
1120
996c9314 1121 mapctx = (struct write_map_ctx){
2fb975da
TT
1122 .vty = vty,
1123 .family = afi2family(afi),
1124 .aficmd = aficmd,
1125 };
fef2ed13
PG
1126 nhrp_cache_config_foreach(ifp, interface_config_write_nhrp_map,
1127 &mapctx);
2fb975da 1128
996c9314
LB
1129 list_for_each_entry(nhs, &ad->nhslist_head,
1130 nhslist_entry)
1131 {
1132 vty_out(vty, " %s nhrp nhs %s nbma %s\n",
2fb975da 1133 aficmd,
996c9314
LB
1134 sockunion_family(&nhs->proto_addr)
1135 == AF_UNSPEC
1136 ? "dynamic"
1137 : sockunion2str(
1138 &nhs->proto_addr, buf,
0d6f7fd6 1139 sizeof(buf)),
96ade3ed 1140 nhs->nbma_fqdn);
2fb975da
TT
1141 }
1142 }
1143
a8b828f3 1144 vty_endframe(vty, "!\n");
2fb975da
TT
1145 }
1146
1147 return 0;
1148}
1149
1150void nhrp_config_init(void)
1151{
612c2c15 1152 install_node(&zebra_node);
2fb975da
TT
1153 install_default(ZEBRA_NODE);
1154
d2057ea3 1155 /* access-list commands */
996c9314 1156 access_list_init();
d2057ea3 1157
2fb975da 1158 /* global commands */
2fb975da
TT
1159 install_element(VIEW_NODE, &show_ip_nhrp_cmd);
1160 install_element(VIEW_NODE, &show_dmvpn_cmd);
2fb975da
TT
1161 install_element(ENABLE_NODE, &clear_nhrp_cmd);
1162
dd73744d
IR
1163 install_element(ENABLE_NODE, &show_debugging_nhrp_cmd);
1164
2fb975da
TT
1165 install_element(ENABLE_NODE, &debug_nhrp_cmd);
1166 install_element(ENABLE_NODE, &no_debug_nhrp_cmd);
1167
1168 install_element(CONFIG_NODE, &debug_nhrp_cmd);
1169 install_element(CONFIG_NODE, &no_debug_nhrp_cmd);
1170
1171 install_element(CONFIG_NODE, &nhrp_event_socket_cmd);
1172 install_element(CONFIG_NODE, &no_nhrp_event_socket_cmd);
1173 install_element(CONFIG_NODE, &nhrp_nflog_group_cmd);
1174 install_element(CONFIG_NODE, &no_nhrp_nflog_group_cmd);
1175
1176 /* interface specific commands */
612c2c15 1177 install_node(&nhrp_interface_node);
2fb975da 1178
819dc8bb 1179 if_cmd_init();
2fb975da
TT
1180 install_element(INTERFACE_NODE, &tunnel_protection_cmd);
1181 install_element(INTERFACE_NODE, &no_tunnel_protection_cmd);
1182 install_element(INTERFACE_NODE, &tunnel_source_cmd);
1183 install_element(INTERFACE_NODE, &no_tunnel_source_cmd);
1184 install_element(INTERFACE_NODE, &if_nhrp_network_id_cmd);
1185 install_element(INTERFACE_NODE, &if_no_nhrp_network_id_cmd);
1186 install_element(INTERFACE_NODE, &if_nhrp_holdtime_cmd);
1187 install_element(INTERFACE_NODE, &if_no_nhrp_holdtime_cmd);
1188 install_element(INTERFACE_NODE, &if_nhrp_mtu_cmd);
1189 install_element(INTERFACE_NODE, &if_no_nhrp_mtu_cmd);
1190 install_element(INTERFACE_NODE, &if_nhrp_flags_cmd);
1191 install_element(INTERFACE_NODE, &if_no_nhrp_flags_cmd);
1192 install_element(INTERFACE_NODE, &if_nhrp_reg_flags_cmd);
1193 install_element(INTERFACE_NODE, &if_no_nhrp_reg_flags_cmd);
1194 install_element(INTERFACE_NODE, &if_nhrp_map_cmd);
2d4eab22 1195 install_element(INTERFACE_NODE, &if_no_nhrp_map_cmd);
2fb975da
TT
1196 install_element(INTERFACE_NODE, &if_nhrp_nhs_cmd);
1197 install_element(INTERFACE_NODE, &if_no_nhrp_nhs_cmd);
1198}