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