1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (c) 2014-2015 Timo Teräs
16 static int nhrp_config_write(struct vty
*vty
);
17 static struct cmd_node zebra_node
= {
20 .parent_node
= CONFIG_NODE
,
21 .prompt
= "%s(config-router)# ",
22 .config_write
= nhrp_config_write
,
25 #define NHRP_DEBUG_FLAGS_CMD "<all|common|event|interface|kernel|route|vici>"
27 #define NHRP_DEBUG_FLAGS_STR \
29 "Common messages (default)\n" \
30 "Event manager messages\n" \
31 "Interface messages\n" \
36 static const struct message debug_flags_desc
[] = {
37 {NHRP_DEBUG_ALL
, "all"}, {NHRP_DEBUG_COMMON
, "common"},
38 {NHRP_DEBUG_IF
, "interface"}, {NHRP_DEBUG_KERNEL
, "kernel"},
39 {NHRP_DEBUG_ROUTE
, "route"}, {NHRP_DEBUG_VICI
, "vici"},
40 {NHRP_DEBUG_EVENT
, "event"}, {0}};
42 static const struct message interface_flags_desc
[] = {
43 {NHRP_IFF_SHORTCUT
, "shortcut"},
44 {NHRP_IFF_REDIRECT
, "redirect"},
45 {NHRP_IFF_REG_NO_UNIQUE
, "registration no-unique"},
48 static int nhrp_vty_return(struct vty
*vty
, int ret
)
50 static const char *const errmsgs
[] = {
51 [NHRP_ERR_FAIL
] = "Command failed",
52 [NHRP_ERR_NO_MEMORY
] = "Out of memory",
53 [NHRP_ERR_UNSUPPORTED_INTERFACE
] =
54 "NHRP not supported on this interface",
55 [NHRP_ERR_NHRP_NOT_ENABLED
] =
56 "NHRP not enabled (set 'nhrp network-id' first)",
57 [NHRP_ERR_ENTRY_EXISTS
] = "Entry exists already",
58 [NHRP_ERR_ENTRY_NOT_FOUND
] = "Entry not found",
59 [NHRP_ERR_PROTOCOL_ADDRESS_MISMATCH
] =
60 "Protocol address family does not match command (ip/ipv6 mismatch)",
62 const char *str
= NULL
;
68 if (ret
> 0 && ret
<= NHRP_ERR_MAX
)
74 snprintf(buf
, sizeof(buf
), "Unknown error %d", ret
);
77 vty_out(vty
, "%% %s\n", str
);
79 return CMD_WARNING_CONFIG_FAILED
;
83 static int toggle_flag(struct vty
*vty
, const struct message
*flag_desc
,
84 const char *name
, int on_off
, unsigned *flags
)
88 for (i
= 0; flag_desc
[i
].str
!= NULL
; i
++) {
89 if (strcmp(flag_desc
[i
].str
, name
) != 0)
92 *flags
|= flag_desc
[i
].key
;
94 *flags
&= ~flag_desc
[i
].key
;
98 vty_out(vty
, "%% Invalid value %s\n", name
);
99 return CMD_WARNING_CONFIG_FAILED
;
105 DEFUN_NOSH(show_debugging_nhrp
, show_debugging_nhrp_cmd
,
106 "show debugging [nhrp]",
108 "Debugging information\n"
109 "NHRP configuration\n")
113 vty_out(vty
, "NHRP debugging status:\n");
115 for (i
= 0; debug_flags_desc
[i
].str
!= NULL
; i
++) {
116 if (debug_flags_desc
[i
].key
== NHRP_DEBUG_ALL
)
118 if (!(debug_flags_desc
[i
].key
& debug_flags
))
121 vty_out(vty
, " NHRP %s debugging is on\n",
122 debug_flags_desc
[i
].str
);
125 cmd_show_lib_debugs(vty
);
130 DEFUN(debug_nhrp
, debug_nhrp_cmd
,
131 "debug nhrp " NHRP_DEBUG_FLAGS_CMD
,
132 "Enable debug messages for specific or all parts.\n"
134 NHRP_DEBUG_FLAGS_STR
)
136 return toggle_flag(vty
, debug_flags_desc
, argv
[2]->text
, 1,
140 DEFUN(no_debug_nhrp
, no_debug_nhrp_cmd
,
141 "no debug nhrp " NHRP_DEBUG_FLAGS_CMD
,
143 "Disable debug messages for specific or all parts.\n"
145 NHRP_DEBUG_FLAGS_STR
)
147 return toggle_flag(vty
, debug_flags_desc
, argv
[3]->text
, 0,
151 #endif /* NO_DEBUG */
153 static int nhrp_config_write(struct vty
*vty
)
156 if (debug_flags
== NHRP_DEBUG_ALL
) {
157 vty_out(vty
, "debug nhrp all\n");
161 for (i
= 0; debug_flags_desc
[i
].str
!= NULL
; i
++) {
162 if (debug_flags_desc
[i
].key
== NHRP_DEBUG_ALL
)
164 if (!(debug_flags
& debug_flags_desc
[i
].key
))
166 vty_out(vty
, "debug nhrp %s\n",
167 debug_flags_desc
[i
].str
);
171 #endif /* NO_DEBUG */
173 if (nhrp_event_socket_path
) {
174 vty_out(vty
, "nhrp event socket %s\n", nhrp_event_socket_path
);
176 if (netlink_nflog_group
) {
177 vty_out(vty
, "nhrp nflog-group %d\n", netlink_nflog_group
);
179 if (netlink_mcast_nflog_group
)
180 vty_out(vty
, "nhrp multicast-nflog-group %d\n",
181 netlink_mcast_nflog_group
);
186 #define IP_STR "IP information\n"
187 #define IPV6_STR "IPv6 information\n"
188 #define AFI_CMD "<ip|ipv6>"
189 #define AFI_STR IP_STR IPV6_STR
190 #define NHRP_STR "Next Hop Resolution Protocol functions\n"
192 static afi_t
cmd_to_afi(const struct cmd_token
*tok
)
194 return strcmp(tok
->text
, "ipv6") == 0 ? AFI_IP6
: AFI_IP
;
197 static const char *afi_to_cmd(afi_t afi
)
204 DEFUN(nhrp_event_socket
, nhrp_event_socket_cmd
,
205 "nhrp event socket SOCKET",
207 "Event Manager commands\n"
208 "Event Manager unix socket path\n"
209 "Unix path for the socket\n")
211 evmgr_set_socket(argv
[3]->arg
);
215 DEFUN(no_nhrp_event_socket
, no_nhrp_event_socket_cmd
,
216 "no nhrp event socket [SOCKET]",
219 "Event Manager commands\n"
220 "Event Manager unix socket path\n"
221 "Unix path for the socket\n")
223 evmgr_set_socket(NULL
);
227 DEFUN(nhrp_nflog_group
, nhrp_nflog_group_cmd
,
228 "nhrp nflog-group (1-65535)",
230 "Specify NFLOG group number\n"
231 "NFLOG group number\n")
235 nfgroup
= strtoul(argv
[2]->arg
, NULL
, 10);
236 netlink_set_nflog_group(nfgroup
);
241 DEFUN(no_nhrp_nflog_group
, no_nhrp_nflog_group_cmd
,
242 "no nhrp nflog-group [(1-65535)]",
245 "Specify NFLOG group number\n"
246 "NFLOG group number\n")
248 netlink_set_nflog_group(0);
252 DEFUN(nhrp_multicast_nflog_group
, nhrp_multicast_nflog_group_cmd
,
253 "nhrp multicast-nflog-group (1-65535)",
255 "Specify NFLOG group number for Multicast Packets\n"
256 "NFLOG group number\n")
260 nfgroup
= strtoul(argv
[2]->arg
, NULL
, 10);
261 netlink_mcast_set_nflog_group(nfgroup
);
266 DEFUN(no_nhrp_multicast_nflog_group
, no_nhrp_multicast_nflog_group_cmd
,
267 "no nhrp multicast-nflog-group [(1-65535)]",
270 "Specify NFLOG group number\n"
271 "NFLOG group number\n")
273 netlink_mcast_set_nflog_group(0);
277 DEFUN(tunnel_protection
, tunnel_protection_cmd
,
278 "tunnel protection vici profile PROFILE [fallback-profile FALLBACK]",
279 "NHRP/GRE integration\n"
281 "VICI (StrongSwan)\n"
283 "IPsec profile name\n"
284 "Fallback IPsec profile\n"
285 "Fallback IPsec profile name\n")
287 VTY_DECLVAR_CONTEXT(interface
, ifp
);
289 nhrp_interface_set_protection(ifp
, argv
[4]->arg
,
290 argc
> 6 ? argv
[6]->arg
: NULL
);
294 DEFUN(no_tunnel_protection
, no_tunnel_protection_cmd
,
295 "no tunnel protection",
297 "NHRP/GRE integration\n"
298 "IPsec protection\n")
300 VTY_DECLVAR_CONTEXT(interface
, ifp
);
302 nhrp_interface_set_protection(ifp
, NULL
, NULL
);
306 DEFUN(tunnel_source
, tunnel_source_cmd
,
307 "tunnel source INTERFACE",
308 "NHRP/GRE integration\n"
309 "Tunnel device binding tracking\n"
312 VTY_DECLVAR_CONTEXT(interface
, ifp
);
313 nhrp_interface_set_source(ifp
, argv
[2]->arg
);
317 DEFUN(no_tunnel_source
, no_tunnel_source_cmd
,
319 "NHRP/GRE integration\n"
320 "Tunnel device binding tracking\n"
323 VTY_DECLVAR_CONTEXT(interface
, ifp
);
324 nhrp_interface_set_source(ifp
, NULL
);
328 DEFUN(if_nhrp_network_id
, if_nhrp_network_id_cmd
,
329 AFI_CMD
" nhrp network-id (1-4294967295)",
332 "Enable NHRP and specify network-id\n"
333 "System local ID to specify interface group\n")
335 VTY_DECLVAR_CONTEXT(interface
, ifp
);
336 struct nhrp_interface
*nifp
= ifp
->info
;
337 afi_t afi
= cmd_to_afi(argv
[0]);
339 nifp
->afi
[afi
].network_id
= strtoul(argv
[3]->arg
, NULL
, 10);
340 nhrp_interface_update(ifp
);
345 DEFUN(if_no_nhrp_network_id
, if_no_nhrp_network_id_cmd
,
346 "no " AFI_CMD
" nhrp network-id [(1-4294967295)]",
350 "Enable NHRP and specify network-id\n"
351 "System local ID to specify interface group\n")
353 VTY_DECLVAR_CONTEXT(interface
, ifp
);
354 struct nhrp_interface
*nifp
= ifp
->info
;
355 afi_t afi
= cmd_to_afi(argv
[1]);
357 nifp
->afi
[afi
].network_id
= 0;
358 nhrp_interface_update(ifp
);
363 DEFUN(if_nhrp_flags
, if_nhrp_flags_cmd
,
364 AFI_CMD
" nhrp <shortcut|redirect>",
367 "Allow shortcut establishment\n"
368 "Send redirect notifications\n")
370 VTY_DECLVAR_CONTEXT(interface
, ifp
);
371 struct nhrp_interface
*nifp
= ifp
->info
;
372 afi_t afi
= cmd_to_afi(argv
[0]);
374 return toggle_flag(vty
, interface_flags_desc
, argv
[2]->text
, 1,
375 &nifp
->afi
[afi
].flags
);
378 DEFUN(if_no_nhrp_flags
, if_no_nhrp_flags_cmd
,
379 "no " AFI_CMD
" nhrp <shortcut|redirect>",
383 "Allow shortcut establishment\n"
384 "Send redirect notifications\n")
386 VTY_DECLVAR_CONTEXT(interface
, ifp
);
387 struct nhrp_interface
*nifp
= ifp
->info
;
388 afi_t afi
= cmd_to_afi(argv
[1]);
390 return toggle_flag(vty
, interface_flags_desc
, argv
[3]->text
, 0,
391 &nifp
->afi
[afi
].flags
);
394 DEFUN(if_nhrp_reg_flags
, if_nhrp_reg_flags_cmd
,
395 AFI_CMD
" nhrp registration no-unique",
398 "Registration configuration\n"
399 "Don't set unique flag\n")
401 VTY_DECLVAR_CONTEXT(interface
, ifp
);
402 struct nhrp_interface
*nifp
= ifp
->info
;
403 afi_t afi
= cmd_to_afi(argv
[0]);
405 snprintf(name
, sizeof(name
), "registration %s", argv
[3]->text
);
406 return toggle_flag(vty
, interface_flags_desc
, name
, 1,
407 &nifp
->afi
[afi
].flags
);
410 DEFUN(if_no_nhrp_reg_flags
, if_no_nhrp_reg_flags_cmd
,
411 "no " AFI_CMD
" nhrp registration no-unique",
415 "Registration configuration\n"
416 "Don't set unique flag\n")
418 VTY_DECLVAR_CONTEXT(interface
, ifp
);
419 struct nhrp_interface
*nifp
= ifp
->info
;
420 afi_t afi
= cmd_to_afi(argv
[1]);
422 snprintf(name
, sizeof(name
), "registration %s", argv
[4]->text
);
423 return toggle_flag(vty
, interface_flags_desc
, name
, 0,
424 &nifp
->afi
[afi
].flags
);
427 DEFUN(if_nhrp_holdtime
, if_nhrp_holdtime_cmd
,
428 AFI_CMD
" nhrp holdtime (1-65000)",
431 "Specify NBMA address validity time\n"
432 "Time in seconds that NBMA addresses are advertised valid\n")
434 VTY_DECLVAR_CONTEXT(interface
, ifp
);
435 struct nhrp_interface
*nifp
= ifp
->info
;
436 afi_t afi
= cmd_to_afi(argv
[0]);
438 nifp
->afi
[afi
].holdtime
= strtoul(argv
[3]->arg
, NULL
, 10);
439 nhrp_interface_update(ifp
);
444 DEFUN(if_no_nhrp_holdtime
, if_no_nhrp_holdtime_cmd
,
445 "no " AFI_CMD
" nhrp holdtime [(1-65000)]",
449 "Specify NBMA address validity time\n"
450 "Time in seconds that NBMA addresses are advertised valid\n")
452 VTY_DECLVAR_CONTEXT(interface
, ifp
);
453 struct nhrp_interface
*nifp
= ifp
->info
;
454 afi_t afi
= cmd_to_afi(argv
[1]);
456 nifp
->afi
[afi
].holdtime
= NHRPD_DEFAULT_HOLDTIME
;
457 nhrp_interface_update(ifp
);
462 DEFUN(if_nhrp_mtu
, if_nhrp_mtu_cmd
,
463 "ip nhrp mtu <(576-1500)|opennhrp>",
466 "Configure NHRP advertised MTU\n"
468 "Advertise bound interface MTU similar to OpenNHRP\n")
470 VTY_DECLVAR_CONTEXT(interface
, ifp
);
471 struct nhrp_interface
*nifp
= ifp
->info
;
473 if (argv
[3]->arg
[0] == 'o') {
474 nifp
->afi
[AFI_IP
].configured_mtu
= -1;
476 nifp
->afi
[AFI_IP
].configured_mtu
=
477 strtoul(argv
[3]->arg
, NULL
, 10);
479 nhrp_interface_update_mtu(ifp
, AFI_IP
);
484 DEFUN(if_no_nhrp_mtu
, if_no_nhrp_mtu_cmd
,
485 "no ip nhrp mtu [(576-1500)|opennhrp]",
489 "Configure NHRP advertised MTU\n"
491 "Advertise bound interface MTU similar to OpenNHRP\n")
493 VTY_DECLVAR_CONTEXT(interface
, ifp
);
494 struct nhrp_interface
*nifp
= ifp
->info
;
496 nifp
->afi
[AFI_IP
].configured_mtu
= 0;
497 nhrp_interface_update_mtu(ifp
, AFI_IP
);
501 DEFUN(if_nhrp_map
, if_nhrp_map_cmd
,
502 AFI_CMD
" nhrp map <A.B.C.D|X:X::X:X> <A.B.C.D|local>",
505 "Nexthop Server configuration\n"
506 "IPv4 protocol address\n"
507 "IPv6 protocol address\n"
508 "IPv4 NBMA address\n"
509 "Handle protocol address locally\n")
511 VTY_DECLVAR_CONTEXT(interface
, ifp
);
512 afi_t afi
= cmd_to_afi(argv
[0]);
513 union sockunion proto_addr
, nbma_addr
;
514 struct nhrp_cache_config
*cc
;
515 struct nhrp_cache
*c
;
516 enum nhrp_cache_type type
;
518 if (str2sockunion(argv
[3]->arg
, &proto_addr
) < 0
519 || afi2family(afi
) != sockunion_family(&proto_addr
))
520 return nhrp_vty_return(vty
, NHRP_ERR_PROTOCOL_ADDRESS_MISMATCH
);
522 if (strmatch(argv
[4]->text
, "local"))
523 type
= NHRP_CACHE_LOCAL
;
525 if (str2sockunion(argv
[4]->arg
, &nbma_addr
) < 0)
526 return nhrp_vty_return(vty
, NHRP_ERR_FAIL
);
527 type
= NHRP_CACHE_STATIC
;
529 cc
= nhrp_cache_config_get(ifp
, &proto_addr
, 1);
531 return nhrp_vty_return(vty
, NHRP_ERR_FAIL
);
532 cc
->nbma
= nbma_addr
;
534 /* gre layer not ready */
535 if (ifp
->ifindex
== IFINDEX_INTERNAL
)
538 c
= nhrp_cache_get(ifp
, &proto_addr
, 1);
540 return nhrp_vty_return(vty
, NHRP_ERR_FAIL
);
543 if (type
== NHRP_CACHE_LOCAL
)
544 nhrp_cache_update_binding(c
, NHRP_CACHE_LOCAL
, 0, NULL
, 0,
547 nhrp_cache_update_binding(c
, NHRP_CACHE_STATIC
, 0,
548 nhrp_peer_get(ifp
, &nbma_addr
), 0,
553 DEFUN(if_no_nhrp_map
, if_no_nhrp_map_cmd
,
554 "no " AFI_CMD
" nhrp map <A.B.C.D|X:X::X:X> [<A.B.C.D|local>]",
558 "Nexthop Server configuration\n"
559 "IPv4 protocol address\n"
560 "IPv6 protocol address\n"
561 "IPv4 NBMA address\n"
562 "Handle protocol address locally\n")
564 VTY_DECLVAR_CONTEXT(interface
, ifp
);
565 afi_t afi
= cmd_to_afi(argv
[1]);
566 union sockunion proto_addr
, nbma_addr
;
567 struct nhrp_cache_config
*cc
;
568 struct nhrp_cache
*c
;
570 if (str2sockunion(argv
[4]->arg
, &proto_addr
) < 0
571 || afi2family(afi
) != sockunion_family(&proto_addr
))
572 return nhrp_vty_return(vty
, NHRP_ERR_PROTOCOL_ADDRESS_MISMATCH
);
574 cc
= nhrp_cache_config_get(ifp
, &proto_addr
, 0);
576 return nhrp_vty_return(vty
, NHRP_ERR_FAIL
);
577 nhrp_cache_config_free(cc
);
579 c
= nhrp_cache_get(ifp
, &proto_addr
, 0);
580 /* silently return */
584 nhrp_cache_update_binding(c
, c
->cur
.type
, -1,
585 nhrp_peer_get(ifp
, &nbma_addr
), 0, NULL
,
590 DEFUN(if_nhrp_map_multicast
, if_nhrp_map_multicast_cmd
,
591 AFI_CMD
" nhrp map multicast <A.B.C.D|X:X::X:X|dynamic>",
594 "Multicast NBMA Configuration\n"
595 "Use this NBMA mapping for multicasts\n"
596 "IPv4 NBMA address\n"
597 "IPv6 NBMA address\n"
598 "Dynamically learn destinations from client registrations on hub\n")
600 VTY_DECLVAR_CONTEXT(interface
, ifp
);
601 afi_t afi
= cmd_to_afi(argv
[0]);
602 union sockunion nbma_addr
;
605 if (str2sockunion(argv
[4]->arg
, &nbma_addr
) < 0)
606 sockunion_family(&nbma_addr
) = AF_UNSPEC
;
608 ret
= nhrp_multicast_add(ifp
, afi
, &nbma_addr
);
610 return nhrp_vty_return(vty
, ret
);
613 DEFUN(if_no_nhrp_map_multicast
, if_no_nhrp_map_multicast_cmd
,
614 "no " AFI_CMD
" nhrp map multicast <A.B.C.D|X:X::X:X|dynamic>",
618 "Multicast NBMA Configuration\n"
619 "Use this NBMA mapping for multicasts\n"
620 "IPv4 NBMA address\n"
621 "IPv6 NBMA address\n"
622 "Dynamically learn destinations from client registrations on hub\n")
624 VTY_DECLVAR_CONTEXT(interface
, ifp
);
625 afi_t afi
= cmd_to_afi(argv
[1]);
626 union sockunion nbma_addr
;
629 if (str2sockunion(argv
[5]->arg
, &nbma_addr
) < 0)
630 sockunion_family(&nbma_addr
) = AF_UNSPEC
;
632 ret
= nhrp_multicast_del(ifp
, afi
, &nbma_addr
);
634 return nhrp_vty_return(vty
, ret
);
637 DEFUN(if_nhrp_nhs
, if_nhrp_nhs_cmd
,
638 AFI_CMD
" nhrp nhs <A.B.C.D|X:X::X:X|dynamic> nbma <A.B.C.D|FQDN>",
641 "Nexthop Server configuration\n"
642 "IPv4 protocol address\n"
643 "IPv6 protocol address\n"
644 "Automatic detection of protocol address\n"
646 "IPv4 NBMA address\n"
647 "Fully qualified domain name for NBMA address(es)\n")
649 VTY_DECLVAR_CONTEXT(interface
, ifp
);
650 afi_t afi
= cmd_to_afi(argv
[0]);
651 union sockunion proto_addr
;
654 if (str2sockunion(argv
[3]->arg
, &proto_addr
) < 0)
655 sockunion_family(&proto_addr
) = AF_UNSPEC
;
657 ret
= nhrp_nhs_add(ifp
, afi
, &proto_addr
, argv
[5]->arg
);
658 return nhrp_vty_return(vty
, ret
);
661 DEFUN(if_no_nhrp_nhs
, if_no_nhrp_nhs_cmd
,
662 "no " AFI_CMD
" nhrp nhs <A.B.C.D|X:X::X:X|dynamic> nbma <A.B.C.D|FQDN>",
666 "Nexthop Server configuration\n"
667 "IPv4 protocol address\n"
668 "IPv6 protocol address\n"
669 "Automatic detection of protocol address\n"
671 "IPv4 NBMA address\n"
672 "Fully qualified domain name for NBMA address(es)\n")
674 VTY_DECLVAR_CONTEXT(interface
, ifp
);
675 afi_t afi
= cmd_to_afi(argv
[1]);
676 union sockunion proto_addr
;
679 if (str2sockunion(argv
[4]->arg
, &proto_addr
) < 0)
680 sockunion_family(&proto_addr
) = AF_UNSPEC
;
682 ret
= nhrp_nhs_del(ifp
, afi
, &proto_addr
, argv
[6]->arg
);
683 return nhrp_vty_return(vty
, ret
);
690 struct json_object
*json
;
693 static void show_ip_nhrp_cache(struct nhrp_cache
*c
, void *pctx
)
695 struct info_ctx
*ctx
= pctx
;
696 struct vty
*vty
= ctx
->vty
;
697 char buf
[3][SU_ADDRSTRLEN
];
698 struct json_object
*json
= NULL
;
700 if (ctx
->afi
!= family2afi(sockunion_family(&c
->remote_addr
)))
704 if (!ctx
->count
&& !ctx
->json
) {
705 vty_out(vty
, "%-8s %-8s %-24s %-24s %-24s %-6s %s\n", "Iface",
706 "Type", "Protocol", "NBMA", "Claimed NBMA", "Flags",
711 sockunion2str(&c
->remote_addr
, buf
[0], sizeof(buf
[0]));
712 if (c
->cur
.type
== NHRP_CACHE_LOCAL
) {
713 struct nhrp_interface
*nifp
= c
->ifp
->info
;
715 if (sockunion_family(&nifp
->nbma
) != AF_UNSPEC
) {
716 sockunion2str(&nifp
->nbma
, buf
[1], sizeof(buf
[1]));
717 sockunion2str(&nifp
->nbma
, buf
[2], sizeof(buf
[2]));
719 snprintf(buf
[1], sizeof(buf
[1]), "-");
720 snprintf(buf
[2], sizeof(buf
[2]), "-");
723 /* if we are behind NAT then update NBMA field */
724 if (sockunion_family(&nifp
->nat_nbma
) != AF_UNSPEC
)
725 sockunion2str(&nifp
->nat_nbma
, buf
[1], sizeof(buf
[1]));
728 sockunion2str(&c
->cur
.peer
->vc
->remote
.nbma
,
729 buf
[1], sizeof(buf
[1]));
731 snprintf(buf
[1], sizeof(buf
[1]), "-");
734 && sockunion_family(&c
->cur
.remote_nbma_claimed
)
736 sockunion2str(&c
->cur
.remote_nbma_claimed
,
737 buf
[2], sizeof(buf
[2]));
739 snprintf(buf
[2], sizeof(buf
[2]), "-");
743 json
= json_object_new_object();
744 json_object_string_add(json
, "interface", c
->ifp
->name
);
745 json_object_string_add(json
, "type",
746 nhrp_cache_type_str
[c
->cur
.type
]);
747 json_object_string_add(json
, "protocol", buf
[0]);
748 json_object_string_add(json
, "nbma", buf
[1]);
749 json_object_string_add(json
, "claimed_nbma", buf
[2]);
752 json_object_boolean_true_add(json
, "used");
754 json_object_boolean_false_add(json
, "used");
757 json_object_boolean_true_add(json
, "timeout");
759 json_object_boolean_false_add(json
, "timeout");
762 json_object_boolean_true_add(json
, "auth");
764 json_object_boolean_false_add(json
, "auth");
767 json_object_string_add(json
, "identity",
768 c
->cur
.peer
->vc
->remote
.id
);
770 json_object_string_add(json
, "identity", "-");
772 json_object_array_add(ctx
->json
, json
);
775 vty_out(ctx
->vty
, "%-8s %-8s %-24s %-24s %-24s %c%c%c %s\n",
777 nhrp_cache_type_str
[c
->cur
.type
],
778 buf
[0], buf
[1], buf
[2],
779 c
->used
? 'U' : ' ', c
->t_timeout
? 'T' : ' ',
780 c
->t_auth
? 'A' : ' ',
781 c
->cur
.peer
? c
->cur
.peer
->vc
->remote
.id
: "-");
784 static void show_ip_nhrp_nhs(struct nhrp_nhs
*n
, struct nhrp_registration
*reg
,
787 struct info_ctx
*ctx
= pctx
;
788 struct vty
*vty
= ctx
->vty
;
789 char buf
[2][SU_ADDRSTRLEN
];
790 struct json_object
*json
= NULL
;
792 if (!ctx
->count
&& !ctx
->json
) {
793 vty_out(vty
, "%-8s %-24s %-16s %-16s\n", "Iface", "FQDN",
798 if (reg
&& reg
->peer
)
799 sockunion2str(®
->peer
->vc
->remote
.nbma
, buf
[0],
802 snprintf(buf
[0], sizeof(buf
[0]), "-");
803 sockunion2str(reg
? ®
->proto_addr
: &n
->proto_addr
, buf
[1],
807 json
= json_object_new_object();
808 json_object_string_add(json
, "interface", n
->ifp
->name
);
809 json_object_string_add(json
, "fqdn", n
->nbma_fqdn
);
810 json_object_string_add(json
, "nbma", buf
[0]);
811 json_object_string_add(json
, "protocol", buf
[1]);
813 json_object_array_add(ctx
->json
, json
);
817 vty_out(vty
, "%-8s %-24s %-16s %-16s\n", n
->ifp
->name
, n
->nbma_fqdn
,
821 static void show_ip_nhrp_shortcut(struct nhrp_shortcut
*s
, void *pctx
)
823 struct info_ctx
*ctx
= pctx
;
824 struct nhrp_cache
*c
;
825 struct vty
*vty
= ctx
->vty
;
826 char buf1
[PREFIX_STRLEN
], buf2
[SU_ADDRSTRLEN
];
827 struct json_object
*json
= NULL
;
830 vty_out(vty
, "%-8s %-24s %-24s %s\n", "Type", "Prefix", "Via",
838 sockunion2str(&c
->remote_addr
, buf2
, sizeof(buf2
));
839 prefix2str(s
->p
, buf1
, sizeof(buf1
));
842 json
= json_object_new_object();
843 json_object_string_add(json
, "type",
844 nhrp_cache_type_str
[s
->type
]);
845 json_object_string_add(json
, "prefix", buf1
);
848 json_object_string_add(json
, "via", buf2
);
850 if (c
&& c
->cur
.peer
)
851 json_object_string_add(json
, "identity",
852 c
->cur
.peer
->vc
->remote
.id
);
854 json_object_string_add(json
, "identity", "");
856 json_object_array_add(ctx
->json
, json
);
860 vty_out(ctx
->vty
, "%-8s %-24s %-24s %s\n",
861 nhrp_cache_type_str
[s
->type
],
863 (c
&& c
->cur
.peer
) ? c
->cur
.peer
->vc
->remote
.id
: "");
866 static void show_ip_opennhrp_cache(struct nhrp_cache
*c
, void *pctx
)
868 struct info_ctx
*ctx
= pctx
;
869 char buf
[3][SU_ADDRSTRLEN
];
870 struct json_object
*json
= NULL
;
873 if (ctx
->afi
!= family2afi(sockunion_family(&c
->remote_addr
)))
876 sockunion2str(&c
->remote_addr
, buf
[0], sizeof(buf
[0]));
878 sockunion2str(&c
->cur
.peer
->vc
->remote
.nbma
, buf
[1],
880 if (sockunion_family(&c
->cur
.remote_nbma_natoa
) != AF_UNSPEC
)
881 sockunion2str(&c
->cur
.remote_nbma_natoa
, buf
[2],
884 json
= json_object_new_object();
885 json_object_string_add(json
, "type",
886 nhrp_cache_type_str
[c
->cur
.type
]);
888 if (c
->cur
.peer
&& c
->cur
.peer
->online
)
889 json_object_boolean_true_add(json
, "up");
891 json_object_boolean_false_add(json
, "up");
894 json_object_boolean_true_add(json
, "used");
896 json_object_boolean_false_add(json
, "used");
898 json_object_string_add(json
, "protocolAddress", buf
[0]);
899 json_object_int_add(json
, "protocolAddressSize",
900 8 * family2addrsize(sockunion_family
904 json_object_string_add(json
, "nbmaAddress", buf
[1]);
906 if (sockunion_family(&c
->cur
.remote_nbma_natoa
) != AF_UNSPEC
)
907 json_object_string_add(json
, "nbmaNatOaAddress",
910 json_object_array_add(ctx
->json
, json
);
916 "Protocol-Address: %s/%zu\n",
917 nhrp_cache_type_str
[c
->cur
.type
],
918 (c
->cur
.peer
&& c
->cur
.peer
->online
) ? " up" : "",
919 c
->used
? " used" : "",
921 8 * family2addrsize(sockunion_family(&c
->remote_addr
)));
924 vty_out(ctx
->vty
, "NBMA-Address: %s\n", buf
[1]);
926 if (sockunion_family(&c
->cur
.remote_nbma_natoa
) != AF_UNSPEC
)
927 vty_out(ctx
->vty
, "NBMA-NAT-OA-Address: %s\n", buf
[2]);
929 vty_out(ctx
->vty
, "\n\n");
932 DEFUN(show_ip_nhrp
, show_ip_nhrp_cmd
,
933 "show " AFI_CMD
" nhrp [cache|nhs|shortcut|opennhrp] [json]",
937 "Forwarding cache information\n"
938 "Next hop server information\n"
939 "Shortcut information\n"
940 "opennhrpctl style cache dump\n"
943 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
944 struct interface
*ifp
;
945 struct info_ctx ctx
= {
946 .vty
= vty
, .afi
= cmd_to_afi(argv
[1]), .json
= NULL
948 bool uj
= use_json(argc
, argv
);
949 struct json_object
*json_path
= NULL
;
950 struct json_object
*json_vrf
= NULL
, *json_vrf_path
= NULL
;
951 int ret
= CMD_SUCCESS
;
954 json_vrf
= json_object_new_object();
955 json_vrf_path
= json_object_new_object();
956 json_path
= json_object_new_array();
957 ctx
.json
= json_path
;
959 if (argc
<= 3 || argv
[3]->text
[0] == 'c') {
960 FOR_ALL_INTERFACES (vrf
, ifp
)
961 nhrp_cache_foreach(ifp
, show_ip_nhrp_cache
, &ctx
);
962 } else if (argv
[3]->text
[0] == 'n') {
963 FOR_ALL_INTERFACES (vrf
, ifp
)
964 nhrp_nhs_foreach(ifp
, ctx
.afi
, show_ip_nhrp_nhs
, &ctx
);
965 } else if (argv
[3]->text
[0] == 's') {
966 nhrp_shortcut_foreach(ctx
.afi
, show_ip_nhrp_shortcut
, &ctx
);
969 vty_out(vty
, "Status: ok\n\n");
971 json_object_string_add(json_vrf
, "status", "ok");
974 FOR_ALL_INTERFACES (vrf
, ifp
)
975 nhrp_cache_foreach(ifp
, show_ip_opennhrp_cache
, &ctx
);
979 json_object_int_add(json_vrf
, "entriesCount", ctx
.count
);
982 vty_out(vty
, "%% No entries\n");
986 json_object_object_add(json_vrf_path
, "attr", json_vrf
);
987 json_object_object_add(json_vrf_path
, "table", ctx
.json
);
988 vty_json(vty
, json_vrf_path
);
995 struct json_object
*json
;
998 static void show_dmvpn_entry(struct nhrp_vc
*vc
, void *ctx
)
1000 struct dmvpn_cfg
*ctxt
= ctx
;
1002 struct json_object
*json
= NULL
;
1004 if (!ctxt
|| !ctxt
->vty
)
1008 json
= json_object_new_object();
1009 json_object_string_addf(json
, "src", "%pSU", &vc
->local
.nbma
);
1010 json_object_string_addf(json
, "dst", "%pSU", &vc
->remote
.nbma
);
1012 if (notifier_active(&vc
->notifier_list
))
1013 json_object_boolean_true_add(json
, "notifierActive");
1015 json_object_boolean_false_add(json
, "notifierActive");
1017 json_object_int_add(json
, "sas", vc
->ipsec
);
1018 json_object_string_add(json
, "identity", vc
->remote
.id
);
1019 json_object_array_add(ctxt
->json
, json
);
1021 vty_out(vty
, "%-24pSU %-24pSU %c %-4d %-24s\n",
1022 &vc
->local
.nbma
, &vc
->remote
.nbma
,
1023 notifier_active(&vc
->notifier_list
) ? 'n' : ' ',
1024 vc
->ipsec
, vc
->remote
.id
);
1028 DEFUN(show_dmvpn
, show_dmvpn_cmd
,
1029 "show dmvpn [json]",
1031 "DMVPN information\n"
1034 bool uj
= use_json(argc
, argv
);
1035 struct dmvpn_cfg ctxt
;
1036 struct json_object
*json_path
= NULL
;
1041 vty_out(vty
, "%-24s %-24s %-6s %-4s %-24s\n",
1042 "Src", "Dst", "Flags", "SAs", "Identity");
1044 json_path
= json_object_new_array();
1045 ctxt
.json
= json_path
;
1047 nhrp_vc_foreach(show_dmvpn_entry
, &ctxt
);
1049 vty_json(vty
, json_path
);
1053 static void clear_nhrp_cache(struct nhrp_cache
*c
, void *data
)
1055 struct info_ctx
*ctx
= data
;
1056 if (c
->cur
.type
<= NHRP_CACHE_DYNAMIC
) {
1057 nhrp_cache_update_binding(c
, c
->cur
.type
, -1, NULL
, 0, NULL
,
1064 static void clear_nhrp_shortcut(struct nhrp_shortcut
*s
, void *data
)
1066 struct info_ctx
*ctx
= data
;
1067 nhrp_shortcut_purge(s
, 1);
1071 DEFUN(clear_nhrp
, clear_nhrp_cmd
,
1072 "clear " AFI_CMD
" nhrp <cache|shortcut>",
1076 "Dynamic cache entries\n"
1077 "Shortcut entries\n")
1079 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
1080 struct interface
*ifp
;
1081 struct info_ctx ctx
= {
1082 .vty
= vty
, .afi
= cmd_to_afi(argv
[1]), .count
= 0,
1085 if (argc
<= 3 || argv
[3]->text
[0] == 'c') {
1086 FOR_ALL_INTERFACES (vrf
, ifp
)
1087 nhrp_cache_foreach(ifp
, clear_nhrp_cache
, &ctx
);
1089 nhrp_shortcut_foreach(ctx
.afi
, clear_nhrp_shortcut
, &ctx
);
1090 /* Clear cache also because when a shortcut is cleared then its
1091 * cache entry should be cleared as well (otherwise traffic
1092 * continues via the shortcut path)
1094 FOR_ALL_INTERFACES (vrf
, ifp
)
1095 nhrp_cache_foreach(ifp
, clear_nhrp_cache
, NULL
);
1099 vty_out(vty
, "%% No entries\n");
1103 vty_out(vty
, "%% %d entries cleared\n", ctx
.count
);
1107 struct write_map_ctx
{
1113 static void interface_config_write_nhrp_map(struct nhrp_cache_config
*c
,
1116 struct write_map_ctx
*ctx
= data
;
1117 struct vty
*vty
= ctx
->vty
;
1119 if (sockunion_family(&c
->remote_addr
) != ctx
->family
)
1122 vty_out(vty
, " %s nhrp map %pSU ", ctx
->aficmd
, &c
->remote_addr
);
1123 if (c
->type
== NHRP_CACHE_LOCAL
)
1124 vty_out(vty
, "local\n");
1126 vty_out(vty
, "%pSU\n", &c
->nbma
);
1129 static int interface_config_write(struct vty
*vty
)
1131 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
1132 struct write_map_ctx mapctx
;
1133 struct interface
*ifp
;
1134 struct nhrp_interface
*nifp
;
1135 struct nhrp_nhs
*nhs
;
1136 struct nhrp_multicast
*mcast
;
1141 FOR_ALL_INTERFACES (vrf
, ifp
) {
1142 if_vty_config_start(vty
, ifp
);
1144 vty_out(vty
, " description %s\n", ifp
->desc
);
1147 if (nifp
->ipsec_profile
) {
1148 vty_out(vty
, " tunnel protection vici profile %s",
1149 nifp
->ipsec_profile
);
1150 if (nifp
->ipsec_fallback_profile
)
1151 vty_out(vty
, " fallback-profile %s",
1152 nifp
->ipsec_fallback_profile
);
1156 vty_out(vty
, " tunnel source %s\n", nifp
->source
);
1158 for (afi
= 0; afi
< AFI_MAX
; afi
++) {
1159 struct nhrp_afi_data
*ad
= &nifp
->afi
[afi
];
1161 aficmd
= afi_to_cmd(afi
);
1164 vty_out(vty
, " %s nhrp network-id %u\n", aficmd
,
1167 if (ad
->holdtime
!= NHRPD_DEFAULT_HOLDTIME
)
1168 vty_out(vty
, " %s nhrp holdtime %u\n", aficmd
,
1171 if (ad
->configured_mtu
< 0)
1172 vty_out(vty
, " %s nhrp mtu opennhrp\n", aficmd
);
1173 else if (ad
->configured_mtu
)
1174 vty_out(vty
, " %s nhrp mtu %u\n", aficmd
,
1175 ad
->configured_mtu
);
1177 for (i
= 0; interface_flags_desc
[i
].str
!= NULL
; i
++) {
1178 if (!(ad
->flags
& interface_flags_desc
[i
].key
))
1180 vty_out(vty
, " %s nhrp %s\n", aficmd
,
1181 interface_flags_desc
[i
].str
);
1184 mapctx
= (struct write_map_ctx
){
1186 .family
= afi2family(afi
),
1189 nhrp_cache_config_foreach(
1190 ifp
, interface_config_write_nhrp_map
, &mapctx
);
1192 frr_each (nhrp_nhslist
, &ad
->nhslist_head
, nhs
) {
1193 vty_out(vty
, " %s nhrp nhs ", aficmd
);
1194 if (sockunion_family(&nhs
->proto_addr
)
1196 vty_out(vty
, "dynamic");
1198 vty_out(vty
, "%pSU", &nhs
->proto_addr
);
1199 vty_out(vty
, " nbma %s\n", nhs
->nbma_fqdn
);
1202 frr_each (nhrp_mcastlist
, &ad
->mcastlist_head
, mcast
) {
1203 vty_out(vty
, " %s nhrp map multicast ", aficmd
);
1204 if (sockunion_family(&mcast
->nbma_addr
)
1206 vty_out(vty
, "dynamic\n");
1208 vty_out(vty
, "%pSU\n",
1213 if_vty_config_end(vty
);
1219 void nhrp_config_init(void)
1221 install_node(&zebra_node
);
1222 install_default(ZEBRA_NODE
);
1224 /* access-list commands */
1227 /* global commands */
1228 install_element(VIEW_NODE
, &show_ip_nhrp_cmd
);
1229 install_element(VIEW_NODE
, &show_dmvpn_cmd
);
1230 install_element(ENABLE_NODE
, &clear_nhrp_cmd
);
1232 install_element(ENABLE_NODE
, &show_debugging_nhrp_cmd
);
1234 install_element(ENABLE_NODE
, &debug_nhrp_cmd
);
1235 install_element(ENABLE_NODE
, &no_debug_nhrp_cmd
);
1237 install_element(CONFIG_NODE
, &debug_nhrp_cmd
);
1238 install_element(CONFIG_NODE
, &no_debug_nhrp_cmd
);
1240 install_element(CONFIG_NODE
, &nhrp_event_socket_cmd
);
1241 install_element(CONFIG_NODE
, &no_nhrp_event_socket_cmd
);
1242 install_element(CONFIG_NODE
, &nhrp_nflog_group_cmd
);
1243 install_element(CONFIG_NODE
, &no_nhrp_nflog_group_cmd
);
1244 install_element(CONFIG_NODE
, &nhrp_multicast_nflog_group_cmd
);
1245 install_element(CONFIG_NODE
, &no_nhrp_multicast_nflog_group_cmd
);
1249 /* interface specific commands */
1250 if_cmd_init(interface_config_write
);
1251 install_element(INTERFACE_NODE
, &tunnel_protection_cmd
);
1252 install_element(INTERFACE_NODE
, &no_tunnel_protection_cmd
);
1253 install_element(INTERFACE_NODE
, &tunnel_source_cmd
);
1254 install_element(INTERFACE_NODE
, &no_tunnel_source_cmd
);
1255 install_element(INTERFACE_NODE
, &if_nhrp_network_id_cmd
);
1256 install_element(INTERFACE_NODE
, &if_no_nhrp_network_id_cmd
);
1257 install_element(INTERFACE_NODE
, &if_nhrp_holdtime_cmd
);
1258 install_element(INTERFACE_NODE
, &if_no_nhrp_holdtime_cmd
);
1259 install_element(INTERFACE_NODE
, &if_nhrp_mtu_cmd
);
1260 install_element(INTERFACE_NODE
, &if_no_nhrp_mtu_cmd
);
1261 install_element(INTERFACE_NODE
, &if_nhrp_flags_cmd
);
1262 install_element(INTERFACE_NODE
, &if_no_nhrp_flags_cmd
);
1263 install_element(INTERFACE_NODE
, &if_nhrp_reg_flags_cmd
);
1264 install_element(INTERFACE_NODE
, &if_no_nhrp_reg_flags_cmd
);
1265 install_element(INTERFACE_NODE
, &if_nhrp_map_cmd
);
1266 install_element(INTERFACE_NODE
, &if_no_nhrp_map_cmd
);
1267 install_element(INTERFACE_NODE
, &if_nhrp_map_multicast_cmd
);
1268 install_element(INTERFACE_NODE
, &if_no_nhrp_map_multicast_cmd
);
1269 install_element(INTERFACE_NODE
, &if_nhrp_nhs_cmd
);
1270 install_element(INTERFACE_NODE
, &if_no_nhrp_nhs_cmd
);