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