2 * Copyright (c) 2014-2015 Timo Teräs
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.
20 static int nhrp_config_write(struct vty
*vty
);
21 static struct cmd_node zebra_node
= {
24 .parent_node
= CONFIG_NODE
,
25 .prompt
= "%s(config-router)# ",
26 .config_write
= nhrp_config_write
,
29 #define NHRP_DEBUG_FLAGS_CMD "<all|common|event|interface|kernel|route|vici>"
31 #define NHRP_DEBUG_FLAGS_STR \
33 "Common messages (default)\n" \
34 "Event manager messages\n" \
35 "Interface messages\n" \
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}};
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"},
52 static int nhrp_vty_return(struct vty
*vty
, int ret
)
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)",
66 const char *str
= NULL
;
72 if (ret
> 0 && ret
<= NHRP_ERR_MAX
)
78 snprintf(buf
, sizeof(buf
), "Unknown error %d", ret
);
81 vty_out(vty
, "%% %s\n", str
);
83 return CMD_WARNING_CONFIG_FAILED
;
87 static int toggle_flag(struct vty
*vty
, const struct message
*flag_desc
,
88 const char *name
, int on_off
, unsigned *flags
)
92 for (i
= 0; flag_desc
[i
].str
!= NULL
; i
++) {
93 if (strcmp(flag_desc
[i
].str
, name
) != 0)
96 *flags
|= flag_desc
[i
].key
;
98 *flags
&= ~flag_desc
[i
].key
;
102 vty_out(vty
, "%% Invalid value %s\n", name
);
103 return CMD_WARNING_CONFIG_FAILED
;
109 DEFUN_NOSH(show_debugging_nhrp
, show_debugging_nhrp_cmd
,
110 "show debugging [nhrp]",
112 "Debugging information\n"
113 "NHRP configuration\n")
117 vty_out(vty
, "NHRP debugging status:\n");
119 for (i
= 0; debug_flags_desc
[i
].str
!= NULL
; i
++) {
120 if (debug_flags_desc
[i
].key
== NHRP_DEBUG_ALL
)
122 if (!(debug_flags_desc
[i
].key
& debug_flags
))
125 vty_out(vty
, " NHRP %s debugging is on\n",
126 debug_flags_desc
[i
].str
);
132 DEFUN(debug_nhrp
, debug_nhrp_cmd
,
133 "debug nhrp " NHRP_DEBUG_FLAGS_CMD
,
134 "Enable debug messages for specific or all parts.\n"
136 NHRP_DEBUG_FLAGS_STR
)
138 return toggle_flag(vty
, debug_flags_desc
, argv
[2]->text
, 1,
142 DEFUN(no_debug_nhrp
, no_debug_nhrp_cmd
,
143 "no debug nhrp " NHRP_DEBUG_FLAGS_CMD
,
145 "Disable debug messages for specific or all parts.\n"
147 NHRP_DEBUG_FLAGS_STR
)
149 return toggle_flag(vty
, debug_flags_desc
, argv
[3]->text
, 0,
153 #endif /* NO_DEBUG */
155 static int nhrp_config_write(struct vty
*vty
)
158 if (debug_flags
== NHRP_DEBUG_ALL
) {
159 vty_out(vty
, "debug nhrp all\n");
163 for (i
= 0; debug_flags_desc
[i
].str
!= NULL
; i
++) {
164 if (debug_flags_desc
[i
].key
== NHRP_DEBUG_ALL
)
166 if (!(debug_flags
& debug_flags_desc
[i
].key
))
168 vty_out(vty
, "debug nhrp %s\n",
169 debug_flags_desc
[i
].str
);
173 #endif /* NO_DEBUG */
175 if (nhrp_event_socket_path
) {
176 vty_out(vty
, "nhrp event socket %s\n", nhrp_event_socket_path
);
178 if (netlink_nflog_group
) {
179 vty_out(vty
, "nhrp nflog-group %d\n", netlink_nflog_group
);
181 if (netlink_mcast_nflog_group
)
182 vty_out(vty
, "nhrp multicast-nflog-group %d\n",
183 netlink_mcast_nflog_group
);
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"
194 static afi_t
cmd_to_afi(const struct cmd_token
*tok
)
196 return strcmp(tok
->text
, "ipv6") == 0 ? AFI_IP6
: AFI_IP
;
199 static const char *afi_to_cmd(afi_t afi
)
206 DEFUN(nhrp_event_socket
, nhrp_event_socket_cmd
,
207 "nhrp event socket SOCKET",
209 "Event Manager commands\n"
210 "Event Manager unix socket path\n"
211 "Unix path for the socket\n")
213 evmgr_set_socket(argv
[3]->arg
);
217 DEFUN(no_nhrp_event_socket
, no_nhrp_event_socket_cmd
,
218 "no nhrp event socket [SOCKET]",
221 "Event Manager commands\n"
222 "Event Manager unix socket path\n"
223 "Unix path for the socket\n")
225 evmgr_set_socket(NULL
);
229 DEFUN(nhrp_nflog_group
, nhrp_nflog_group_cmd
,
230 "nhrp nflog-group (1-65535)",
232 "Specify NFLOG group number\n"
233 "NFLOG group number\n")
237 nfgroup
= strtoul(argv
[2]->arg
, NULL
, 10);
238 netlink_set_nflog_group(nfgroup
);
243 DEFUN(no_nhrp_nflog_group
, no_nhrp_nflog_group_cmd
,
244 "no nhrp nflog-group [(1-65535)]",
247 "Specify NFLOG group number\n"
248 "NFLOG group number\n")
250 netlink_set_nflog_group(0);
254 DEFUN(nhrp_multicast_nflog_group
, nhrp_multicast_nflog_group_cmd
,
255 "nhrp multicast-nflog-group (1-65535)",
257 "Specify NFLOG group number for Multicast Packets\n"
258 "NFLOG group number\n")
262 nfgroup
= strtoul(argv
[2]->arg
, NULL
, 10);
263 netlink_mcast_set_nflog_group(nfgroup
);
268 DEFUN(no_nhrp_multicast_nflog_group
, no_nhrp_multicast_nflog_group_cmd
,
269 "no nhrp multicast-nflog-group [(1-65535)]",
272 "Specify NFLOG group number\n"
273 "NFLOG group number\n")
275 netlink_mcast_set_nflog_group(0);
279 DEFUN(tunnel_protection
, tunnel_protection_cmd
,
280 "tunnel protection vici profile PROFILE [fallback-profile FALLBACK]",
281 "NHRP/GRE integration\n"
283 "VICI (StrongSwan)\n"
285 "IPsec profile name\n"
286 "Fallback IPsec profile\n"
287 "Fallback IPsec profile name\n")
289 VTY_DECLVAR_CONTEXT(interface
, ifp
);
291 nhrp_interface_set_protection(ifp
, argv
[4]->arg
,
292 argc
> 6 ? argv
[6]->arg
: NULL
);
296 DEFUN(no_tunnel_protection
, no_tunnel_protection_cmd
,
297 "no tunnel protection",
299 "NHRP/GRE integration\n"
300 "IPsec protection\n")
302 VTY_DECLVAR_CONTEXT(interface
, ifp
);
304 nhrp_interface_set_protection(ifp
, NULL
, NULL
);
308 DEFUN(tunnel_source
, tunnel_source_cmd
,
309 "tunnel source INTERFACE",
310 "NHRP/GRE integration\n"
311 "Tunnel device binding tracking\n"
314 VTY_DECLVAR_CONTEXT(interface
, ifp
);
315 nhrp_interface_set_source(ifp
, argv
[2]->arg
);
319 DEFUN(no_tunnel_source
, no_tunnel_source_cmd
,
321 "NHRP/GRE integration\n"
322 "Tunnel device binding tracking\n"
325 VTY_DECLVAR_CONTEXT(interface
, ifp
);
326 nhrp_interface_set_source(ifp
, NULL
);
330 DEFUN(if_nhrp_network_id
, if_nhrp_network_id_cmd
,
331 AFI_CMD
" nhrp network-id (1-4294967295)",
334 "Enable NHRP and specify network-id\n"
335 "System local ID to specify interface group\n")
337 VTY_DECLVAR_CONTEXT(interface
, ifp
);
338 struct nhrp_interface
*nifp
= ifp
->info
;
339 afi_t afi
= cmd_to_afi(argv
[0]);
341 nifp
->afi
[afi
].network_id
= strtoul(argv
[3]->arg
, NULL
, 10);
342 nhrp_interface_update(ifp
);
347 DEFUN(if_no_nhrp_network_id
, if_no_nhrp_network_id_cmd
,
348 "no " AFI_CMD
" nhrp network-id [(1-4294967295)]",
352 "Enable NHRP and specify network-id\n"
353 "System local ID to specify interface group\n")
355 VTY_DECLVAR_CONTEXT(interface
, ifp
);
356 struct nhrp_interface
*nifp
= ifp
->info
;
357 afi_t afi
= cmd_to_afi(argv
[1]);
359 nifp
->afi
[afi
].network_id
= 0;
360 nhrp_interface_update(ifp
);
365 DEFUN(if_nhrp_flags
, if_nhrp_flags_cmd
,
366 AFI_CMD
" nhrp <shortcut|redirect>",
369 "Allow shortcut establishment\n"
370 "Send redirect notifications\n")
372 VTY_DECLVAR_CONTEXT(interface
, ifp
);
373 struct nhrp_interface
*nifp
= ifp
->info
;
374 afi_t afi
= cmd_to_afi(argv
[0]);
376 return toggle_flag(vty
, interface_flags_desc
, argv
[2]->text
, 1,
377 &nifp
->afi
[afi
].flags
);
380 DEFUN(if_no_nhrp_flags
, if_no_nhrp_flags_cmd
,
381 "no " AFI_CMD
" nhrp <shortcut|redirect>",
385 "Allow shortcut establishment\n"
386 "Send redirect notifications\n")
388 VTY_DECLVAR_CONTEXT(interface
, ifp
);
389 struct nhrp_interface
*nifp
= ifp
->info
;
390 afi_t afi
= cmd_to_afi(argv
[1]);
392 return toggle_flag(vty
, interface_flags_desc
, argv
[3]->text
, 0,
393 &nifp
->afi
[afi
].flags
);
396 DEFUN(if_nhrp_reg_flags
, if_nhrp_reg_flags_cmd
,
397 AFI_CMD
" nhrp registration no-unique",
400 "Registration configuration\n"
401 "Don't set unique flag\n")
403 VTY_DECLVAR_CONTEXT(interface
, ifp
);
404 struct nhrp_interface
*nifp
= ifp
->info
;
405 afi_t afi
= cmd_to_afi(argv
[0]);
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
);
412 DEFUN(if_no_nhrp_reg_flags
, if_no_nhrp_reg_flags_cmd
,
413 "no " AFI_CMD
" nhrp registration no-unique",
417 "Registration configuration\n"
418 "Don't set unique flag\n")
420 VTY_DECLVAR_CONTEXT(interface
, ifp
);
421 struct nhrp_interface
*nifp
= ifp
->info
;
422 afi_t afi
= cmd_to_afi(argv
[1]);
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
);
429 DEFUN(if_nhrp_holdtime
, if_nhrp_holdtime_cmd
,
430 AFI_CMD
" nhrp holdtime (1-65000)",
433 "Specify NBMA address validity time\n"
434 "Time in seconds that NBMA addresses are advertised valid\n")
436 VTY_DECLVAR_CONTEXT(interface
, ifp
);
437 struct nhrp_interface
*nifp
= ifp
->info
;
438 afi_t afi
= cmd_to_afi(argv
[0]);
440 nifp
->afi
[afi
].holdtime
= strtoul(argv
[3]->arg
, NULL
, 10);
441 nhrp_interface_update(ifp
);
446 DEFUN(if_no_nhrp_holdtime
, if_no_nhrp_holdtime_cmd
,
447 "no " AFI_CMD
" nhrp holdtime [(1-65000)]",
451 "Specify NBMA address validity time\n"
452 "Time in seconds that NBMA addresses are advertised valid\n")
454 VTY_DECLVAR_CONTEXT(interface
, ifp
);
455 struct nhrp_interface
*nifp
= ifp
->info
;
456 afi_t afi
= cmd_to_afi(argv
[1]);
458 nifp
->afi
[afi
].holdtime
= NHRPD_DEFAULT_HOLDTIME
;
459 nhrp_interface_update(ifp
);
464 DEFUN(if_nhrp_mtu
, if_nhrp_mtu_cmd
,
465 "ip nhrp mtu <(576-1500)|opennhrp>",
468 "Configure NHRP advertised MTU\n"
470 "Advertise bound interface MTU similar to OpenNHRP\n")
472 VTY_DECLVAR_CONTEXT(interface
, ifp
);
473 struct nhrp_interface
*nifp
= ifp
->info
;
475 if (argv
[3]->arg
[0] == 'o') {
476 nifp
->afi
[AFI_IP
].configured_mtu
= -1;
478 nifp
->afi
[AFI_IP
].configured_mtu
=
479 strtoul(argv
[3]->arg
, NULL
, 10);
481 nhrp_interface_update_mtu(ifp
, AFI_IP
);
486 DEFUN(if_no_nhrp_mtu
, if_no_nhrp_mtu_cmd
,
487 "no ip nhrp mtu [(576-1500)|opennhrp]",
491 "Configure NHRP advertised MTU\n"
493 "Advertise bound interface MTU similar to OpenNHRP\n")
495 VTY_DECLVAR_CONTEXT(interface
, ifp
);
496 struct nhrp_interface
*nifp
= ifp
->info
;
498 nifp
->afi
[AFI_IP
].configured_mtu
= 0;
499 nhrp_interface_update_mtu(ifp
, AFI_IP
);
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>",
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")
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
;
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
);
524 if (strmatch(argv
[4]->text
, "local"))
525 type
= NHRP_CACHE_LOCAL
;
527 if (str2sockunion(argv
[4]->arg
, &nbma_addr
) < 0)
528 return nhrp_vty_return(vty
, NHRP_ERR_FAIL
);
529 type
= NHRP_CACHE_STATIC
;
531 cc
= nhrp_cache_config_get(ifp
, &proto_addr
, 1);
533 return nhrp_vty_return(vty
, NHRP_ERR_FAIL
);
534 cc
->nbma
= nbma_addr
;
536 /* gre layer not ready */
537 if (ifp
->ifindex
== IFINDEX_INTERNAL
)
540 c
= nhrp_cache_get(ifp
, &proto_addr
, 1);
542 return nhrp_vty_return(vty
, NHRP_ERR_FAIL
);
545 if (type
== NHRP_CACHE_LOCAL
)
546 nhrp_cache_update_binding(c
, NHRP_CACHE_LOCAL
, 0, NULL
, 0,
549 nhrp_cache_update_binding(c
, NHRP_CACHE_STATIC
, 0,
550 nhrp_peer_get(ifp
, &nbma_addr
), 0,
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>]",
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")
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
;
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
);
576 cc
= nhrp_cache_config_get(ifp
, &proto_addr
, 0);
578 return nhrp_vty_return(vty
, NHRP_ERR_FAIL
);
579 nhrp_cache_config_free(cc
);
581 c
= nhrp_cache_get(ifp
, &proto_addr
, 0);
582 /* silently return */
586 nhrp_cache_update_binding(c
, c
->cur
.type
, -1,
587 nhrp_peer_get(ifp
, &nbma_addr
), 0, NULL
,
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>",
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")
602 VTY_DECLVAR_CONTEXT(interface
, ifp
);
603 afi_t afi
= cmd_to_afi(argv
[0]);
604 union sockunion nbma_addr
;
607 if (str2sockunion(argv
[4]->arg
, &nbma_addr
) < 0)
608 sockunion_family(&nbma_addr
) = AF_UNSPEC
;
610 ret
= nhrp_multicast_add(ifp
, afi
, &nbma_addr
);
612 return nhrp_vty_return(vty
, ret
);
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>",
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")
626 VTY_DECLVAR_CONTEXT(interface
, ifp
);
627 afi_t afi
= cmd_to_afi(argv
[1]);
628 union sockunion nbma_addr
;
631 if (str2sockunion(argv
[5]->arg
, &nbma_addr
) < 0)
632 sockunion_family(&nbma_addr
) = AF_UNSPEC
;
634 ret
= nhrp_multicast_del(ifp
, afi
, &nbma_addr
);
636 return nhrp_vty_return(vty
, ret
);
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>",
643 "Nexthop Server configuration\n"
644 "IPv4 protocol address\n"
645 "IPv6 protocol address\n"
646 "Automatic detection of protocol address\n"
648 "IPv4 NBMA address\n"
649 "Fully qualified domain name for NBMA address(es)\n")
651 VTY_DECLVAR_CONTEXT(interface
, ifp
);
652 afi_t afi
= cmd_to_afi(argv
[0]);
653 union sockunion proto_addr
;
656 if (str2sockunion(argv
[3]->arg
, &proto_addr
) < 0)
657 sockunion_family(&proto_addr
) = AF_UNSPEC
;
659 ret
= nhrp_nhs_add(ifp
, afi
, &proto_addr
, argv
[5]->arg
);
660 return nhrp_vty_return(vty
, ret
);
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>",
668 "Nexthop Server configuration\n"
669 "IPv4 protocol address\n"
670 "IPv6 protocol address\n"
671 "Automatic detection of protocol address\n"
673 "IPv4 NBMA address\n"
674 "Fully qualified domain name for NBMA address(es)\n")
676 VTY_DECLVAR_CONTEXT(interface
, ifp
);
677 afi_t afi
= cmd_to_afi(argv
[1]);
678 union sockunion proto_addr
;
681 if (str2sockunion(argv
[4]->arg
, &proto_addr
) < 0)
682 sockunion_family(&proto_addr
) = AF_UNSPEC
;
684 ret
= nhrp_nhs_del(ifp
, afi
, &proto_addr
, argv
[6]->arg
);
685 return nhrp_vty_return(vty
, ret
);
692 struct json_object
*json
;
695 static void show_ip_nhrp_cache(struct nhrp_cache
*c
, void *pctx
)
697 struct info_ctx
*ctx
= pctx
;
698 struct vty
*vty
= ctx
->vty
;
699 char buf
[3][SU_ADDRSTRLEN
];
700 struct json_object
*json
= NULL
;
702 if (ctx
->afi
!= family2afi(sockunion_family(&c
->remote_addr
)))
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",
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
;
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]));
721 snprintf(buf
[1], sizeof(buf
[1]), "-");
722 snprintf(buf
[2], sizeof(buf
[2]), "-");
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]));
730 sockunion2str(&c
->cur
.peer
->vc
->remote
.nbma
,
731 buf
[1], sizeof(buf
[1]));
733 snprintf(buf
[1], sizeof(buf
[1]), "-");
736 && sockunion_family(&c
->cur
.remote_nbma_claimed
)
738 sockunion2str(&c
->cur
.remote_nbma_claimed
,
739 buf
[2], sizeof(buf
[2]));
741 snprintf(buf
[2], sizeof(buf
[2]), "-");
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]);
754 json_object_boolean_true_add(json
, "used");
756 json_object_boolean_false_add(json
, "used");
759 json_object_boolean_true_add(json
, "timeout");
761 json_object_boolean_false_add(json
, "timeout");
764 json_object_boolean_true_add(json
, "auth");
766 json_object_boolean_false_add(json
, "auth");
769 json_object_string_add(json
, "identity",
770 c
->cur
.peer
->vc
->remote
.id
);
772 json_object_string_add(json
, "identity", "-");
774 json_object_array_add(ctx
->json
, json
);
777 vty_out(ctx
->vty
, "%-8s %-8s %-24s %-24s %-24s %c%c%c %s\n",
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
: "-");
786 static void show_ip_nhrp_nhs(struct nhrp_nhs
*n
, struct nhrp_registration
*reg
,
789 struct info_ctx
*ctx
= pctx
;
790 struct vty
*vty
= ctx
->vty
;
791 char buf
[2][SU_ADDRSTRLEN
];
792 struct json_object
*json
= NULL
;
794 if (!ctx
->count
&& !ctx
->json
) {
795 vty_out(vty
, "%-8s %-24s %-16s %-16s\n", "Iface", "FQDN",
800 if (reg
&& reg
->peer
)
801 sockunion2str(®
->peer
->vc
->remote
.nbma
, buf
[0],
804 snprintf(buf
[0], sizeof(buf
[0]), "-");
805 sockunion2str(reg
? ®
->proto_addr
: &n
->proto_addr
, buf
[1],
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]);
815 json_object_array_add(ctx
->json
, json
);
819 vty_out(vty
, "%-8s %-24s %-16s %-16s\n", n
->ifp
->name
, n
->nbma_fqdn
,
823 static void show_ip_nhrp_shortcut(struct nhrp_shortcut
*s
, void *pctx
)
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
;
832 vty_out(vty
, "%-8s %-24s %-24s %s\n", "Type", "Prefix", "Via",
840 sockunion2str(&c
->remote_addr
, buf2
, sizeof(buf2
));
841 prefix2str(s
->p
, buf1
, sizeof(buf1
));
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
);
850 json_object_string_add(json
, "via", buf2
);
852 if (c
&& c
->cur
.peer
)
853 json_object_string_add(json
, "identity",
854 c
->cur
.peer
->vc
->remote
.id
);
856 json_object_string_add(json
, "identity", "");
858 json_object_array_add(ctx
->json
, json
);
862 vty_out(ctx
->vty
, "%-8s %-24s %-24s %s\n",
863 nhrp_cache_type_str
[s
->type
],
865 (c
&& c
->cur
.peer
) ? c
->cur
.peer
->vc
->remote
.id
: "");
868 static void show_ip_opennhrp_cache(struct nhrp_cache
*c
, void *pctx
)
870 struct info_ctx
*ctx
= pctx
;
871 char buf
[3][SU_ADDRSTRLEN
];
872 struct json_object
*json
= NULL
;
875 if (ctx
->afi
!= family2afi(sockunion_family(&c
->remote_addr
)))
878 sockunion2str(&c
->remote_addr
, buf
[0], sizeof(buf
[0]));
880 sockunion2str(&c
->cur
.peer
->vc
->remote
.nbma
, buf
[1],
882 if (sockunion_family(&c
->cur
.remote_nbma_natoa
) != AF_UNSPEC
)
883 sockunion2str(&c
->cur
.remote_nbma_natoa
, buf
[2],
886 json
= json_object_new_object();
887 json_object_string_add(json
, "type",
888 nhrp_cache_type_str
[c
->cur
.type
]);
890 if (c
->cur
.peer
&& c
->cur
.peer
->online
)
891 json_object_boolean_true_add(json
, "up");
893 json_object_boolean_false_add(json
, "up");
896 json_object_boolean_true_add(json
, "used");
898 json_object_boolean_false_add(json
, "used");
900 json_object_string_add(json
, "protocolAddress", buf
[0]);
901 json_object_int_add(json
, "protocolAddressSize",
902 8 * family2addrsize(sockunion_family
906 json_object_string_add(json
, "nbmaAddress", buf
[1]);
908 if (sockunion_family(&c
->cur
.remote_nbma_natoa
) != AF_UNSPEC
)
909 json_object_string_add(json
, "nbmaNatOaAddress",
912 json_object_array_add(ctx
->json
, json
);
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" : "",
923 8 * family2addrsize(sockunion_family(&c
->remote_addr
)));
926 vty_out(ctx
->vty
, "NBMA-Address: %s\n", buf
[1]);
928 if (sockunion_family(&c
->cur
.remote_nbma_natoa
) != AF_UNSPEC
)
929 vty_out(ctx
->vty
, "NBMA-NAT-OA-Address: %s\n", buf
[2]);
931 vty_out(ctx
->vty
, "\n\n");
934 DEFUN(show_ip_nhrp
, show_ip_nhrp_cmd
,
935 "show " AFI_CMD
" nhrp [cache|nhs|shortcut|opennhrp] [json]",
939 "Forwarding cache information\n"
940 "Next hop server information\n"
941 "Shortcut information\n"
942 "opennhrpctl style cache dump\n"
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
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
;
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
;
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
);
971 vty_out(vty
, "Status: ok\n\n");
973 json_object_string_add(json_vrf
, "status", "ok");
976 FOR_ALL_INTERFACES (vrf
, ifp
)
977 nhrp_cache_foreach(ifp
, show_ip_opennhrp_cache
, &ctx
);
981 json_object_int_add(json_vrf
, "entriesCount", ctx
.count
);
984 vty_out(vty
, "%% No entries\n");
988 json_object_object_add(json_vrf_path
, "attr", json_vrf
);
989 json_object_object_add(json_vrf_path
, "table", ctx
.json
);
990 vty_json(vty
, json_vrf_path
);
997 struct json_object
*json
;
1000 static void show_dmvpn_entry(struct nhrp_vc
*vc
, void *ctx
)
1002 struct dmvpn_cfg
*ctxt
= ctx
;
1004 char buf
[2][SU_ADDRSTRLEN
];
1005 struct json_object
*json
= NULL
;
1007 if (!ctxt
|| !ctxt
->vty
)
1010 sockunion2str(&vc
->local
.nbma
, buf
[0], sizeof(buf
[0]));
1011 sockunion2str(&vc
->remote
.nbma
, buf
[1], sizeof(buf
[1]));
1013 json
= json_object_new_object();
1014 json_object_string_add(json
, "src", buf
[0]);
1015 json_object_string_add(json
, "dst", buf
[1]);
1017 if (notifier_active(&vc
->notifier_list
))
1018 json_object_boolean_true_add(json
, "notifierActive");
1020 json_object_boolean_false_add(json
, "notifierActive");
1022 json_object_int_add(json
, "sas", vc
->ipsec
);
1023 json_object_string_add(json
, "identity", vc
->remote
.id
);
1024 json_object_array_add(ctxt
->json
, json
);
1026 vty_out(vty
, "%-24s %-24s %c %-4d %-24s\n",
1027 buf
[0], buf
[1], notifier_active(&vc
->notifier_list
) ?
1028 'n' : ' ', vc
->ipsec
, vc
->remote
.id
);
1032 DEFUN(show_dmvpn
, show_dmvpn_cmd
,
1033 "show dmvpn [json]",
1035 "DMVPN information\n"
1038 bool uj
= use_json(argc
, argv
);
1039 struct dmvpn_cfg ctxt
;
1040 struct json_object
*json_path
= NULL
;
1045 vty_out(vty
, "%-24s %-24s %-6s %-4s %-24s\n",
1046 "Src", "Dst", "Flags", "SAs", "Identity");
1048 json_path
= json_object_new_array();
1049 ctxt
.json
= json_path
;
1051 nhrp_vc_foreach(show_dmvpn_entry
, &ctxt
);
1053 vty_json(vty
, json_path
);
1057 static void clear_nhrp_cache(struct nhrp_cache
*c
, void *data
)
1059 struct info_ctx
*ctx
= data
;
1060 if (c
->cur
.type
<= NHRP_CACHE_DYNAMIC
) {
1061 nhrp_cache_update_binding(c
, c
->cur
.type
, -1, NULL
, 0, NULL
,
1068 static void clear_nhrp_shortcut(struct nhrp_shortcut
*s
, void *data
)
1070 struct info_ctx
*ctx
= data
;
1071 nhrp_shortcut_purge(s
, 1);
1075 DEFUN(clear_nhrp
, clear_nhrp_cmd
,
1076 "clear " AFI_CMD
" nhrp <cache|shortcut>",
1080 "Dynamic cache entries\n"
1081 "Shortcut entries\n")
1083 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
1084 struct interface
*ifp
;
1085 struct info_ctx ctx
= {
1086 .vty
= vty
, .afi
= cmd_to_afi(argv
[1]), .count
= 0,
1089 if (argc
<= 3 || argv
[3]->text
[0] == 'c') {
1090 FOR_ALL_INTERFACES (vrf
, ifp
)
1091 nhrp_cache_foreach(ifp
, clear_nhrp_cache
, &ctx
);
1093 nhrp_shortcut_foreach(ctx
.afi
, clear_nhrp_shortcut
, &ctx
);
1094 /* Clear cache also because when a shortcut is cleared then its
1095 * cache entry should be cleared as well (otherwise traffic
1096 * continues via the shortcut path)
1098 FOR_ALL_INTERFACES (vrf
, ifp
)
1099 nhrp_cache_foreach(ifp
, clear_nhrp_cache
, NULL
);
1103 vty_out(vty
, "%% No entries\n");
1107 vty_out(vty
, "%% %d entries cleared\n", ctx
.count
);
1111 struct write_map_ctx
{
1117 static void interface_config_write_nhrp_map(struct nhrp_cache_config
*c
,
1120 struct write_map_ctx
*ctx
= data
;
1121 struct vty
*vty
= ctx
->vty
;
1123 if (sockunion_family(&c
->remote_addr
) != ctx
->family
)
1126 vty_out(vty
, " %s nhrp map %pSU ", ctx
->aficmd
, &c
->remote_addr
);
1127 if (c
->type
== NHRP_CACHE_LOCAL
)
1128 vty_out(vty
, "local\n");
1130 vty_out(vty
, "%pSU\n", &c
->nbma
);
1133 static int interface_config_write(struct vty
*vty
)
1135 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
1136 struct write_map_ctx mapctx
;
1137 struct interface
*ifp
;
1138 struct nhrp_interface
*nifp
;
1139 struct nhrp_nhs
*nhs
;
1140 struct nhrp_multicast
*mcast
;
1145 FOR_ALL_INTERFACES (vrf
, ifp
) {
1146 if_vty_config_start(vty
, ifp
);
1148 vty_out(vty
, " description %s\n", ifp
->desc
);
1151 if (nifp
->ipsec_profile
) {
1152 vty_out(vty
, " tunnel protection vici profile %s",
1153 nifp
->ipsec_profile
);
1154 if (nifp
->ipsec_fallback_profile
)
1155 vty_out(vty
, " fallback-profile %s",
1156 nifp
->ipsec_fallback_profile
);
1160 vty_out(vty
, " tunnel source %s\n", nifp
->source
);
1162 for (afi
= 0; afi
< AFI_MAX
; afi
++) {
1163 struct nhrp_afi_data
*ad
= &nifp
->afi
[afi
];
1165 aficmd
= afi_to_cmd(afi
);
1168 vty_out(vty
, " %s nhrp network-id %u\n", aficmd
,
1171 if (ad
->holdtime
!= NHRPD_DEFAULT_HOLDTIME
)
1172 vty_out(vty
, " %s nhrp holdtime %u\n", aficmd
,
1175 if (ad
->configured_mtu
< 0)
1176 vty_out(vty
, " %s nhrp mtu opennhrp\n", aficmd
);
1177 else if (ad
->configured_mtu
)
1178 vty_out(vty
, " %s nhrp mtu %u\n", aficmd
,
1179 ad
->configured_mtu
);
1181 for (i
= 0; interface_flags_desc
[i
].str
!= NULL
; i
++) {
1182 if (!(ad
->flags
& interface_flags_desc
[i
].key
))
1184 vty_out(vty
, " %s nhrp %s\n", aficmd
,
1185 interface_flags_desc
[i
].str
);
1188 mapctx
= (struct write_map_ctx
){
1190 .family
= afi2family(afi
),
1193 nhrp_cache_config_foreach(
1194 ifp
, interface_config_write_nhrp_map
, &mapctx
);
1196 frr_each (nhrp_nhslist
, &ad
->nhslist_head
, nhs
) {
1197 vty_out(vty
, " %s nhrp nhs ", aficmd
);
1198 if (sockunion_family(&nhs
->proto_addr
)
1200 vty_out(vty
, "dynamic");
1202 vty_out(vty
, "%pSU", &nhs
->proto_addr
);
1203 vty_out(vty
, " nbma %s\n", nhs
->nbma_fqdn
);
1206 frr_each (nhrp_mcastlist
, &ad
->mcastlist_head
, mcast
) {
1207 vty_out(vty
, " %s nhrp map multicast ", aficmd
);
1208 if (sockunion_family(&mcast
->nbma_addr
)
1210 vty_out(vty
, "dynamic\n");
1212 vty_out(vty
, "%pSU\n",
1217 if_vty_config_end(vty
);
1223 void nhrp_config_init(void)
1225 install_node(&zebra_node
);
1226 install_default(ZEBRA_NODE
);
1228 /* access-list commands */
1231 /* global commands */
1232 install_element(VIEW_NODE
, &show_ip_nhrp_cmd
);
1233 install_element(VIEW_NODE
, &show_dmvpn_cmd
);
1234 install_element(ENABLE_NODE
, &clear_nhrp_cmd
);
1236 install_element(ENABLE_NODE
, &show_debugging_nhrp_cmd
);
1238 install_element(ENABLE_NODE
, &debug_nhrp_cmd
);
1239 install_element(ENABLE_NODE
, &no_debug_nhrp_cmd
);
1241 install_element(CONFIG_NODE
, &debug_nhrp_cmd
);
1242 install_element(CONFIG_NODE
, &no_debug_nhrp_cmd
);
1244 install_element(CONFIG_NODE
, &nhrp_event_socket_cmd
);
1245 install_element(CONFIG_NODE
, &no_nhrp_event_socket_cmd
);
1246 install_element(CONFIG_NODE
, &nhrp_nflog_group_cmd
);
1247 install_element(CONFIG_NODE
, &no_nhrp_nflog_group_cmd
);
1248 install_element(CONFIG_NODE
, &nhrp_multicast_nflog_group_cmd
);
1249 install_element(CONFIG_NODE
, &no_nhrp_multicast_nflog_group_cmd
);
1253 /* interface specific commands */
1254 if_cmd_init(interface_config_write
);
1255 install_element(INTERFACE_NODE
, &tunnel_protection_cmd
);
1256 install_element(INTERFACE_NODE
, &no_tunnel_protection_cmd
);
1257 install_element(INTERFACE_NODE
, &tunnel_source_cmd
);
1258 install_element(INTERFACE_NODE
, &no_tunnel_source_cmd
);
1259 install_element(INTERFACE_NODE
, &if_nhrp_network_id_cmd
);
1260 install_element(INTERFACE_NODE
, &if_no_nhrp_network_id_cmd
);
1261 install_element(INTERFACE_NODE
, &if_nhrp_holdtime_cmd
);
1262 install_element(INTERFACE_NODE
, &if_no_nhrp_holdtime_cmd
);
1263 install_element(INTERFACE_NODE
, &if_nhrp_mtu_cmd
);
1264 install_element(INTERFACE_NODE
, &if_no_nhrp_mtu_cmd
);
1265 install_element(INTERFACE_NODE
, &if_nhrp_flags_cmd
);
1266 install_element(INTERFACE_NODE
, &if_no_nhrp_flags_cmd
);
1267 install_element(INTERFACE_NODE
, &if_nhrp_reg_flags_cmd
);
1268 install_element(INTERFACE_NODE
, &if_no_nhrp_reg_flags_cmd
);
1269 install_element(INTERFACE_NODE
, &if_nhrp_map_cmd
);
1270 install_element(INTERFACE_NODE
, &if_no_nhrp_map_cmd
);
1271 install_element(INTERFACE_NODE
, &if_nhrp_map_multicast_cmd
);
1272 install_element(INTERFACE_NODE
, &if_no_nhrp_map_multicast_cmd
);
1273 install_element(INTERFACE_NODE
, &if_nhrp_nhs_cmd
);
1274 install_element(INTERFACE_NODE
, &if_no_nhrp_nhs_cmd
);