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
);
129 cmd_show_lib_debugs(vty
);
134 DEFUN(debug_nhrp
, debug_nhrp_cmd
,
135 "debug nhrp " NHRP_DEBUG_FLAGS_CMD
,
136 "Enable debug messages for specific or all parts.\n"
138 NHRP_DEBUG_FLAGS_STR
)
140 return toggle_flag(vty
, debug_flags_desc
, argv
[2]->text
, 1,
144 DEFUN(no_debug_nhrp
, no_debug_nhrp_cmd
,
145 "no debug nhrp " NHRP_DEBUG_FLAGS_CMD
,
147 "Disable debug messages for specific or all parts.\n"
149 NHRP_DEBUG_FLAGS_STR
)
151 return toggle_flag(vty
, debug_flags_desc
, argv
[3]->text
, 0,
155 #endif /* NO_DEBUG */
157 static int nhrp_config_write(struct vty
*vty
)
160 if (debug_flags
== NHRP_DEBUG_ALL
) {
161 vty_out(vty
, "debug nhrp all\n");
165 for (i
= 0; debug_flags_desc
[i
].str
!= NULL
; i
++) {
166 if (debug_flags_desc
[i
].key
== NHRP_DEBUG_ALL
)
168 if (!(debug_flags
& debug_flags_desc
[i
].key
))
170 vty_out(vty
, "debug nhrp %s\n",
171 debug_flags_desc
[i
].str
);
175 #endif /* NO_DEBUG */
177 if (nhrp_event_socket_path
) {
178 vty_out(vty
, "nhrp event socket %s\n", nhrp_event_socket_path
);
180 if (netlink_nflog_group
) {
181 vty_out(vty
, "nhrp nflog-group %d\n", netlink_nflog_group
);
183 if (netlink_mcast_nflog_group
)
184 vty_out(vty
, "nhrp multicast-nflog-group %d\n",
185 netlink_mcast_nflog_group
);
190 #define IP_STR "IP information\n"
191 #define IPV6_STR "IPv6 information\n"
192 #define AFI_CMD "<ip|ipv6>"
193 #define AFI_STR IP_STR IPV6_STR
194 #define NHRP_STR "Next Hop Resolution Protocol functions\n"
196 static afi_t
cmd_to_afi(const struct cmd_token
*tok
)
198 return strcmp(tok
->text
, "ipv6") == 0 ? AFI_IP6
: AFI_IP
;
201 static const char *afi_to_cmd(afi_t afi
)
208 DEFUN(nhrp_event_socket
, nhrp_event_socket_cmd
,
209 "nhrp event socket SOCKET",
211 "Event Manager commands\n"
212 "Event Manager unix socket path\n"
213 "Unix path for the socket\n")
215 evmgr_set_socket(argv
[3]->arg
);
219 DEFUN(no_nhrp_event_socket
, no_nhrp_event_socket_cmd
,
220 "no nhrp event socket [SOCKET]",
223 "Event Manager commands\n"
224 "Event Manager unix socket path\n"
225 "Unix path for the socket\n")
227 evmgr_set_socket(NULL
);
231 DEFUN(nhrp_nflog_group
, nhrp_nflog_group_cmd
,
232 "nhrp nflog-group (1-65535)",
234 "Specify NFLOG group number\n"
235 "NFLOG group number\n")
239 nfgroup
= strtoul(argv
[2]->arg
, NULL
, 10);
240 netlink_set_nflog_group(nfgroup
);
245 DEFUN(no_nhrp_nflog_group
, no_nhrp_nflog_group_cmd
,
246 "no nhrp nflog-group [(1-65535)]",
249 "Specify NFLOG group number\n"
250 "NFLOG group number\n")
252 netlink_set_nflog_group(0);
256 DEFUN(nhrp_multicast_nflog_group
, nhrp_multicast_nflog_group_cmd
,
257 "nhrp multicast-nflog-group (1-65535)",
259 "Specify NFLOG group number for Multicast Packets\n"
260 "NFLOG group number\n")
264 nfgroup
= strtoul(argv
[2]->arg
, NULL
, 10);
265 netlink_mcast_set_nflog_group(nfgroup
);
270 DEFUN(no_nhrp_multicast_nflog_group
, no_nhrp_multicast_nflog_group_cmd
,
271 "no nhrp multicast-nflog-group [(1-65535)]",
274 "Specify NFLOG group number\n"
275 "NFLOG group number\n")
277 netlink_mcast_set_nflog_group(0);
281 DEFUN(tunnel_protection
, tunnel_protection_cmd
,
282 "tunnel protection vici profile PROFILE [fallback-profile FALLBACK]",
283 "NHRP/GRE integration\n"
285 "VICI (StrongSwan)\n"
287 "IPsec profile name\n"
288 "Fallback IPsec profile\n"
289 "Fallback IPsec profile name\n")
291 VTY_DECLVAR_CONTEXT(interface
, ifp
);
293 nhrp_interface_set_protection(ifp
, argv
[4]->arg
,
294 argc
> 6 ? argv
[6]->arg
: NULL
);
298 DEFUN(no_tunnel_protection
, no_tunnel_protection_cmd
,
299 "no tunnel protection",
301 "NHRP/GRE integration\n"
302 "IPsec protection\n")
304 VTY_DECLVAR_CONTEXT(interface
, ifp
);
306 nhrp_interface_set_protection(ifp
, NULL
, NULL
);
310 DEFUN(tunnel_source
, tunnel_source_cmd
,
311 "tunnel source INTERFACE",
312 "NHRP/GRE integration\n"
313 "Tunnel device binding tracking\n"
316 VTY_DECLVAR_CONTEXT(interface
, ifp
);
317 nhrp_interface_set_source(ifp
, argv
[2]->arg
);
321 DEFUN(no_tunnel_source
, no_tunnel_source_cmd
,
323 "NHRP/GRE integration\n"
324 "Tunnel device binding tracking\n"
327 VTY_DECLVAR_CONTEXT(interface
, ifp
);
328 nhrp_interface_set_source(ifp
, NULL
);
332 DEFUN(if_nhrp_network_id
, if_nhrp_network_id_cmd
,
333 AFI_CMD
" nhrp network-id (1-4294967295)",
336 "Enable NHRP and specify network-id\n"
337 "System local ID to specify interface group\n")
339 VTY_DECLVAR_CONTEXT(interface
, ifp
);
340 struct nhrp_interface
*nifp
= ifp
->info
;
341 afi_t afi
= cmd_to_afi(argv
[0]);
343 nifp
->afi
[afi
].network_id
= strtoul(argv
[3]->arg
, NULL
, 10);
344 nhrp_interface_update(ifp
);
349 DEFUN(if_no_nhrp_network_id
, if_no_nhrp_network_id_cmd
,
350 "no " AFI_CMD
" nhrp network-id [(1-4294967295)]",
354 "Enable NHRP and specify network-id\n"
355 "System local ID to specify interface group\n")
357 VTY_DECLVAR_CONTEXT(interface
, ifp
);
358 struct nhrp_interface
*nifp
= ifp
->info
;
359 afi_t afi
= cmd_to_afi(argv
[1]);
361 nifp
->afi
[afi
].network_id
= 0;
362 nhrp_interface_update(ifp
);
367 DEFUN(if_nhrp_flags
, if_nhrp_flags_cmd
,
368 AFI_CMD
" nhrp <shortcut|redirect>",
371 "Allow shortcut establishment\n"
372 "Send redirect notifications\n")
374 VTY_DECLVAR_CONTEXT(interface
, ifp
);
375 struct nhrp_interface
*nifp
= ifp
->info
;
376 afi_t afi
= cmd_to_afi(argv
[0]);
378 return toggle_flag(vty
, interface_flags_desc
, argv
[2]->text
, 1,
379 &nifp
->afi
[afi
].flags
);
382 DEFUN(if_no_nhrp_flags
, if_no_nhrp_flags_cmd
,
383 "no " AFI_CMD
" nhrp <shortcut|redirect>",
387 "Allow shortcut establishment\n"
388 "Send redirect notifications\n")
390 VTY_DECLVAR_CONTEXT(interface
, ifp
);
391 struct nhrp_interface
*nifp
= ifp
->info
;
392 afi_t afi
= cmd_to_afi(argv
[1]);
394 return toggle_flag(vty
, interface_flags_desc
, argv
[3]->text
, 0,
395 &nifp
->afi
[afi
].flags
);
398 DEFUN(if_nhrp_reg_flags
, if_nhrp_reg_flags_cmd
,
399 AFI_CMD
" nhrp registration no-unique",
402 "Registration configuration\n"
403 "Don't set unique flag\n")
405 VTY_DECLVAR_CONTEXT(interface
, ifp
);
406 struct nhrp_interface
*nifp
= ifp
->info
;
407 afi_t afi
= cmd_to_afi(argv
[0]);
409 snprintf(name
, sizeof(name
), "registration %s", argv
[3]->text
);
410 return toggle_flag(vty
, interface_flags_desc
, name
, 1,
411 &nifp
->afi
[afi
].flags
);
414 DEFUN(if_no_nhrp_reg_flags
, if_no_nhrp_reg_flags_cmd
,
415 "no " AFI_CMD
" nhrp registration no-unique",
419 "Registration configuration\n"
420 "Don't set unique flag\n")
422 VTY_DECLVAR_CONTEXT(interface
, ifp
);
423 struct nhrp_interface
*nifp
= ifp
->info
;
424 afi_t afi
= cmd_to_afi(argv
[1]);
426 snprintf(name
, sizeof(name
), "registration %s", argv
[4]->text
);
427 return toggle_flag(vty
, interface_flags_desc
, name
, 0,
428 &nifp
->afi
[afi
].flags
);
431 DEFUN(if_nhrp_holdtime
, if_nhrp_holdtime_cmd
,
432 AFI_CMD
" nhrp holdtime (1-65000)",
435 "Specify NBMA address validity time\n"
436 "Time in seconds that NBMA addresses are advertised valid\n")
438 VTY_DECLVAR_CONTEXT(interface
, ifp
);
439 struct nhrp_interface
*nifp
= ifp
->info
;
440 afi_t afi
= cmd_to_afi(argv
[0]);
442 nifp
->afi
[afi
].holdtime
= strtoul(argv
[3]->arg
, NULL
, 10);
443 nhrp_interface_update(ifp
);
448 DEFUN(if_no_nhrp_holdtime
, if_no_nhrp_holdtime_cmd
,
449 "no " AFI_CMD
" nhrp holdtime [(1-65000)]",
453 "Specify NBMA address validity time\n"
454 "Time in seconds that NBMA addresses are advertised valid\n")
456 VTY_DECLVAR_CONTEXT(interface
, ifp
);
457 struct nhrp_interface
*nifp
= ifp
->info
;
458 afi_t afi
= cmd_to_afi(argv
[1]);
460 nifp
->afi
[afi
].holdtime
= NHRPD_DEFAULT_HOLDTIME
;
461 nhrp_interface_update(ifp
);
466 DEFUN(if_nhrp_mtu
, if_nhrp_mtu_cmd
,
467 "ip nhrp mtu <(576-1500)|opennhrp>",
470 "Configure NHRP advertised MTU\n"
472 "Advertise bound interface MTU similar to OpenNHRP\n")
474 VTY_DECLVAR_CONTEXT(interface
, ifp
);
475 struct nhrp_interface
*nifp
= ifp
->info
;
477 if (argv
[3]->arg
[0] == 'o') {
478 nifp
->afi
[AFI_IP
].configured_mtu
= -1;
480 nifp
->afi
[AFI_IP
].configured_mtu
=
481 strtoul(argv
[3]->arg
, NULL
, 10);
483 nhrp_interface_update_mtu(ifp
, AFI_IP
);
488 DEFUN(if_no_nhrp_mtu
, if_no_nhrp_mtu_cmd
,
489 "no ip nhrp mtu [(576-1500)|opennhrp]",
493 "Configure NHRP advertised MTU\n"
495 "Advertise bound interface MTU similar to OpenNHRP\n")
497 VTY_DECLVAR_CONTEXT(interface
, ifp
);
498 struct nhrp_interface
*nifp
= ifp
->info
;
500 nifp
->afi
[AFI_IP
].configured_mtu
= 0;
501 nhrp_interface_update_mtu(ifp
, AFI_IP
);
505 DEFUN(if_nhrp_map
, if_nhrp_map_cmd
,
506 AFI_CMD
" nhrp map <A.B.C.D|X:X::X:X> <A.B.C.D|local>",
509 "Nexthop Server configuration\n"
510 "IPv4 protocol address\n"
511 "IPv6 protocol address\n"
512 "IPv4 NBMA address\n"
513 "Handle protocol address locally\n")
515 VTY_DECLVAR_CONTEXT(interface
, ifp
);
516 afi_t afi
= cmd_to_afi(argv
[0]);
517 union sockunion proto_addr
, nbma_addr
;
518 struct nhrp_cache_config
*cc
;
519 struct nhrp_cache
*c
;
520 enum nhrp_cache_type type
;
522 if (str2sockunion(argv
[3]->arg
, &proto_addr
) < 0
523 || afi2family(afi
) != sockunion_family(&proto_addr
))
524 return nhrp_vty_return(vty
, NHRP_ERR_PROTOCOL_ADDRESS_MISMATCH
);
526 if (strmatch(argv
[4]->text
, "local"))
527 type
= NHRP_CACHE_LOCAL
;
529 if (str2sockunion(argv
[4]->arg
, &nbma_addr
) < 0)
530 return nhrp_vty_return(vty
, NHRP_ERR_FAIL
);
531 type
= NHRP_CACHE_STATIC
;
533 cc
= nhrp_cache_config_get(ifp
, &proto_addr
, 1);
535 return nhrp_vty_return(vty
, NHRP_ERR_FAIL
);
536 cc
->nbma
= nbma_addr
;
538 /* gre layer not ready */
539 if (ifp
->ifindex
== IFINDEX_INTERNAL
)
542 c
= nhrp_cache_get(ifp
, &proto_addr
, 1);
544 return nhrp_vty_return(vty
, NHRP_ERR_FAIL
);
547 if (type
== NHRP_CACHE_LOCAL
)
548 nhrp_cache_update_binding(c
, NHRP_CACHE_LOCAL
, 0, NULL
, 0,
551 nhrp_cache_update_binding(c
, NHRP_CACHE_STATIC
, 0,
552 nhrp_peer_get(ifp
, &nbma_addr
), 0,
557 DEFUN(if_no_nhrp_map
, if_no_nhrp_map_cmd
,
558 "no " AFI_CMD
" nhrp map <A.B.C.D|X:X::X:X> [<A.B.C.D|local>]",
562 "Nexthop Server configuration\n"
563 "IPv4 protocol address\n"
564 "IPv6 protocol address\n"
565 "IPv4 NBMA address\n"
566 "Handle protocol address locally\n")
568 VTY_DECLVAR_CONTEXT(interface
, ifp
);
569 afi_t afi
= cmd_to_afi(argv
[1]);
570 union sockunion proto_addr
, nbma_addr
;
571 struct nhrp_cache_config
*cc
;
572 struct nhrp_cache
*c
;
574 if (str2sockunion(argv
[4]->arg
, &proto_addr
) < 0
575 || afi2family(afi
) != sockunion_family(&proto_addr
))
576 return nhrp_vty_return(vty
, NHRP_ERR_PROTOCOL_ADDRESS_MISMATCH
);
578 cc
= nhrp_cache_config_get(ifp
, &proto_addr
, 0);
580 return nhrp_vty_return(vty
, NHRP_ERR_FAIL
);
581 nhrp_cache_config_free(cc
);
583 c
= nhrp_cache_get(ifp
, &proto_addr
, 0);
584 /* silently return */
588 nhrp_cache_update_binding(c
, c
->cur
.type
, -1,
589 nhrp_peer_get(ifp
, &nbma_addr
), 0, NULL
,
594 DEFUN(if_nhrp_map_multicast
, if_nhrp_map_multicast_cmd
,
595 AFI_CMD
" nhrp map multicast <A.B.C.D|X:X::X:X|dynamic>",
598 "Multicast NBMA Configuration\n"
599 "Use this NBMA mapping for multicasts\n"
600 "IPv4 NBMA address\n"
601 "IPv6 NBMA address\n"
602 "Dynamically learn destinations from client registrations on hub\n")
604 VTY_DECLVAR_CONTEXT(interface
, ifp
);
605 afi_t afi
= cmd_to_afi(argv
[0]);
606 union sockunion nbma_addr
;
609 if (str2sockunion(argv
[4]->arg
, &nbma_addr
) < 0)
610 sockunion_family(&nbma_addr
) = AF_UNSPEC
;
612 ret
= nhrp_multicast_add(ifp
, afi
, &nbma_addr
);
614 return nhrp_vty_return(vty
, ret
);
617 DEFUN(if_no_nhrp_map_multicast
, if_no_nhrp_map_multicast_cmd
,
618 "no " AFI_CMD
" nhrp map multicast <A.B.C.D|X:X::X:X|dynamic>",
622 "Multicast NBMA Configuration\n"
623 "Use this NBMA mapping for multicasts\n"
624 "IPv4 NBMA address\n"
625 "IPv6 NBMA address\n"
626 "Dynamically learn destinations from client registrations on hub\n")
628 VTY_DECLVAR_CONTEXT(interface
, ifp
);
629 afi_t afi
= cmd_to_afi(argv
[1]);
630 union sockunion nbma_addr
;
633 if (str2sockunion(argv
[5]->arg
, &nbma_addr
) < 0)
634 sockunion_family(&nbma_addr
) = AF_UNSPEC
;
636 ret
= nhrp_multicast_del(ifp
, afi
, &nbma_addr
);
638 return nhrp_vty_return(vty
, ret
);
641 DEFUN(if_nhrp_nhs
, if_nhrp_nhs_cmd
,
642 AFI_CMD
" nhrp nhs <A.B.C.D|X:X::X:X|dynamic> nbma <A.B.C.D|FQDN>",
645 "Nexthop Server configuration\n"
646 "IPv4 protocol address\n"
647 "IPv6 protocol address\n"
648 "Automatic detection of protocol address\n"
650 "IPv4 NBMA address\n"
651 "Fully qualified domain name for NBMA address(es)\n")
653 VTY_DECLVAR_CONTEXT(interface
, ifp
);
654 afi_t afi
= cmd_to_afi(argv
[0]);
655 union sockunion proto_addr
;
658 if (str2sockunion(argv
[3]->arg
, &proto_addr
) < 0)
659 sockunion_family(&proto_addr
) = AF_UNSPEC
;
661 ret
= nhrp_nhs_add(ifp
, afi
, &proto_addr
, argv
[5]->arg
);
662 return nhrp_vty_return(vty
, ret
);
665 DEFUN(if_no_nhrp_nhs
, if_no_nhrp_nhs_cmd
,
666 "no " AFI_CMD
" nhrp nhs <A.B.C.D|X:X::X:X|dynamic> nbma <A.B.C.D|FQDN>",
670 "Nexthop Server configuration\n"
671 "IPv4 protocol address\n"
672 "IPv6 protocol address\n"
673 "Automatic detection of protocol address\n"
675 "IPv4 NBMA address\n"
676 "Fully qualified domain name for NBMA address(es)\n")
678 VTY_DECLVAR_CONTEXT(interface
, ifp
);
679 afi_t afi
= cmd_to_afi(argv
[1]);
680 union sockunion proto_addr
;
683 if (str2sockunion(argv
[4]->arg
, &proto_addr
) < 0)
684 sockunion_family(&proto_addr
) = AF_UNSPEC
;
686 ret
= nhrp_nhs_del(ifp
, afi
, &proto_addr
, argv
[6]->arg
);
687 return nhrp_vty_return(vty
, ret
);
694 struct json_object
*json
;
697 static void show_ip_nhrp_cache(struct nhrp_cache
*c
, void *pctx
)
699 struct info_ctx
*ctx
= pctx
;
700 struct vty
*vty
= ctx
->vty
;
701 char buf
[3][SU_ADDRSTRLEN
];
702 struct json_object
*json
= NULL
;
704 if (ctx
->afi
!= family2afi(sockunion_family(&c
->remote_addr
)))
708 if (!ctx
->count
&& !ctx
->json
) {
709 vty_out(vty
, "%-8s %-8s %-24s %-24s %-24s %-6s %s\n", "Iface",
710 "Type", "Protocol", "NBMA", "Claimed NBMA", "Flags",
715 sockunion2str(&c
->remote_addr
, buf
[0], sizeof(buf
[0]));
716 if (c
->cur
.type
== NHRP_CACHE_LOCAL
) {
717 struct nhrp_interface
*nifp
= c
->ifp
->info
;
719 if (sockunion_family(&nifp
->nbma
) != AF_UNSPEC
) {
720 sockunion2str(&nifp
->nbma
, buf
[1], sizeof(buf
[1]));
721 sockunion2str(&nifp
->nbma
, buf
[2], sizeof(buf
[2]));
723 snprintf(buf
[1], sizeof(buf
[1]), "-");
724 snprintf(buf
[2], sizeof(buf
[2]), "-");
727 /* if we are behind NAT then update NBMA field */
728 if (sockunion_family(&nifp
->nat_nbma
) != AF_UNSPEC
)
729 sockunion2str(&nifp
->nat_nbma
, buf
[1], sizeof(buf
[1]));
732 sockunion2str(&c
->cur
.peer
->vc
->remote
.nbma
,
733 buf
[1], sizeof(buf
[1]));
735 snprintf(buf
[1], sizeof(buf
[1]), "-");
738 && sockunion_family(&c
->cur
.remote_nbma_claimed
)
740 sockunion2str(&c
->cur
.remote_nbma_claimed
,
741 buf
[2], sizeof(buf
[2]));
743 snprintf(buf
[2], sizeof(buf
[2]), "-");
747 json
= json_object_new_object();
748 json_object_string_add(json
, "interface", c
->ifp
->name
);
749 json_object_string_add(json
, "type",
750 nhrp_cache_type_str
[c
->cur
.type
]);
751 json_object_string_add(json
, "protocol", buf
[0]);
752 json_object_string_add(json
, "nbma", buf
[1]);
753 json_object_string_add(json
, "claimed_nbma", buf
[2]);
756 json_object_boolean_true_add(json
, "used");
758 json_object_boolean_false_add(json
, "used");
761 json_object_boolean_true_add(json
, "timeout");
763 json_object_boolean_false_add(json
, "timeout");
766 json_object_boolean_true_add(json
, "auth");
768 json_object_boolean_false_add(json
, "auth");
771 json_object_string_add(json
, "identity",
772 c
->cur
.peer
->vc
->remote
.id
);
774 json_object_string_add(json
, "identity", "-");
776 json_object_array_add(ctx
->json
, json
);
779 vty_out(ctx
->vty
, "%-8s %-8s %-24s %-24s %-24s %c%c%c %s\n",
781 nhrp_cache_type_str
[c
->cur
.type
],
782 buf
[0], buf
[1], buf
[2],
783 c
->used
? 'U' : ' ', c
->t_timeout
? 'T' : ' ',
784 c
->t_auth
? 'A' : ' ',
785 c
->cur
.peer
? c
->cur
.peer
->vc
->remote
.id
: "-");
788 static void show_ip_nhrp_nhs(struct nhrp_nhs
*n
, struct nhrp_registration
*reg
,
791 struct info_ctx
*ctx
= pctx
;
792 struct vty
*vty
= ctx
->vty
;
793 char buf
[2][SU_ADDRSTRLEN
];
794 struct json_object
*json
= NULL
;
796 if (!ctx
->count
&& !ctx
->json
) {
797 vty_out(vty
, "%-8s %-24s %-16s %-16s\n", "Iface", "FQDN",
802 if (reg
&& reg
->peer
)
803 sockunion2str(®
->peer
->vc
->remote
.nbma
, buf
[0],
806 snprintf(buf
[0], sizeof(buf
[0]), "-");
807 sockunion2str(reg
? ®
->proto_addr
: &n
->proto_addr
, buf
[1],
811 json
= json_object_new_object();
812 json_object_string_add(json
, "interface", n
->ifp
->name
);
813 json_object_string_add(json
, "fqdn", n
->nbma_fqdn
);
814 json_object_string_add(json
, "nbma", buf
[0]);
815 json_object_string_add(json
, "protocol", buf
[1]);
817 json_object_array_add(ctx
->json
, json
);
821 vty_out(vty
, "%-8s %-24s %-16s %-16s\n", n
->ifp
->name
, n
->nbma_fqdn
,
825 static void show_ip_nhrp_shortcut(struct nhrp_shortcut
*s
, void *pctx
)
827 struct info_ctx
*ctx
= pctx
;
828 struct nhrp_cache
*c
;
829 struct vty
*vty
= ctx
->vty
;
830 char buf1
[PREFIX_STRLEN
], buf2
[SU_ADDRSTRLEN
];
831 struct json_object
*json
= NULL
;
834 vty_out(vty
, "%-8s %-24s %-24s %s\n", "Type", "Prefix", "Via",
842 sockunion2str(&c
->remote_addr
, buf2
, sizeof(buf2
));
843 prefix2str(s
->p
, buf1
, sizeof(buf1
));
846 json
= json_object_new_object();
847 json_object_string_add(json
, "type",
848 nhrp_cache_type_str
[s
->type
]);
849 json_object_string_add(json
, "prefix", buf1
);
852 json_object_string_add(json
, "via", buf2
);
854 if (c
&& c
->cur
.peer
)
855 json_object_string_add(json
, "identity",
856 c
->cur
.peer
->vc
->remote
.id
);
858 json_object_string_add(json
, "identity", "");
860 json_object_array_add(ctx
->json
, json
);
864 vty_out(ctx
->vty
, "%-8s %-24s %-24s %s\n",
865 nhrp_cache_type_str
[s
->type
],
867 (c
&& c
->cur
.peer
) ? c
->cur
.peer
->vc
->remote
.id
: "");
870 static void show_ip_opennhrp_cache(struct nhrp_cache
*c
, void *pctx
)
872 struct info_ctx
*ctx
= pctx
;
873 char buf
[3][SU_ADDRSTRLEN
];
874 struct json_object
*json
= NULL
;
877 if (ctx
->afi
!= family2afi(sockunion_family(&c
->remote_addr
)))
880 sockunion2str(&c
->remote_addr
, buf
[0], sizeof(buf
[0]));
882 sockunion2str(&c
->cur
.peer
->vc
->remote
.nbma
, buf
[1],
884 if (sockunion_family(&c
->cur
.remote_nbma_natoa
) != AF_UNSPEC
)
885 sockunion2str(&c
->cur
.remote_nbma_natoa
, buf
[2],
888 json
= json_object_new_object();
889 json_object_string_add(json
, "type",
890 nhrp_cache_type_str
[c
->cur
.type
]);
892 if (c
->cur
.peer
&& c
->cur
.peer
->online
)
893 json_object_boolean_true_add(json
, "up");
895 json_object_boolean_false_add(json
, "up");
898 json_object_boolean_true_add(json
, "used");
900 json_object_boolean_false_add(json
, "used");
902 json_object_string_add(json
, "protocolAddress", buf
[0]);
903 json_object_int_add(json
, "protocolAddressSize",
904 8 * family2addrsize(sockunion_family
908 json_object_string_add(json
, "nbmaAddress", buf
[1]);
910 if (sockunion_family(&c
->cur
.remote_nbma_natoa
) != AF_UNSPEC
)
911 json_object_string_add(json
, "nbmaNatOaAddress",
914 json_object_array_add(ctx
->json
, json
);
920 "Protocol-Address: %s/%zu\n",
921 nhrp_cache_type_str
[c
->cur
.type
],
922 (c
->cur
.peer
&& c
->cur
.peer
->online
) ? " up" : "",
923 c
->used
? " used" : "",
925 8 * family2addrsize(sockunion_family(&c
->remote_addr
)));
928 vty_out(ctx
->vty
, "NBMA-Address: %s\n", buf
[1]);
930 if (sockunion_family(&c
->cur
.remote_nbma_natoa
) != AF_UNSPEC
)
931 vty_out(ctx
->vty
, "NBMA-NAT-OA-Address: %s\n", buf
[2]);
933 vty_out(ctx
->vty
, "\n\n");
936 DEFUN(show_ip_nhrp
, show_ip_nhrp_cmd
,
937 "show " AFI_CMD
" nhrp [cache|nhs|shortcut|opennhrp] [json]",
941 "Forwarding cache information\n"
942 "Next hop server information\n"
943 "Shortcut information\n"
944 "opennhrpctl style cache dump\n"
947 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
948 struct interface
*ifp
;
949 struct info_ctx ctx
= {
950 .vty
= vty
, .afi
= cmd_to_afi(argv
[1]), .json
= NULL
952 bool uj
= use_json(argc
, argv
);
953 struct json_object
*json_path
= NULL
;
954 struct json_object
*json_vrf
= NULL
, *json_vrf_path
= NULL
;
955 int ret
= CMD_SUCCESS
;
958 json_vrf
= json_object_new_object();
959 json_vrf_path
= json_object_new_object();
960 json_path
= json_object_new_array();
961 ctx
.json
= json_path
;
963 if (argc
<= 3 || argv
[3]->text
[0] == 'c') {
964 FOR_ALL_INTERFACES (vrf
, ifp
)
965 nhrp_cache_foreach(ifp
, show_ip_nhrp_cache
, &ctx
);
966 } else if (argv
[3]->text
[0] == 'n') {
967 FOR_ALL_INTERFACES (vrf
, ifp
)
968 nhrp_nhs_foreach(ifp
, ctx
.afi
, show_ip_nhrp_nhs
, &ctx
);
969 } else if (argv
[3]->text
[0] == 's') {
970 nhrp_shortcut_foreach(ctx
.afi
, show_ip_nhrp_shortcut
, &ctx
);
973 vty_out(vty
, "Status: ok\n\n");
975 json_object_string_add(json_vrf
, "status", "ok");
978 FOR_ALL_INTERFACES (vrf
, ifp
)
979 nhrp_cache_foreach(ifp
, show_ip_opennhrp_cache
, &ctx
);
983 json_object_int_add(json_vrf
, "entriesCount", ctx
.count
);
986 vty_out(vty
, "%% No entries\n");
990 json_object_object_add(json_vrf_path
, "attr", json_vrf
);
991 json_object_object_add(json_vrf_path
, "table", ctx
.json
);
992 vty_json(vty
, json_vrf_path
);
999 struct json_object
*json
;
1002 static void show_dmvpn_entry(struct nhrp_vc
*vc
, void *ctx
)
1004 struct dmvpn_cfg
*ctxt
= ctx
;
1006 struct json_object
*json
= NULL
;
1008 if (!ctxt
|| !ctxt
->vty
)
1012 json
= json_object_new_object();
1013 json_object_string_addf(json
, "src", "%pSU", &vc
->local
.nbma
);
1014 json_object_string_addf(json
, "dst", "%pSU", &vc
->remote
.nbma
);
1016 if (notifier_active(&vc
->notifier_list
))
1017 json_object_boolean_true_add(json
, "notifierActive");
1019 json_object_boolean_false_add(json
, "notifierActive");
1021 json_object_int_add(json
, "sas", vc
->ipsec
);
1022 json_object_string_add(json
, "identity", vc
->remote
.id
);
1023 json_object_array_add(ctxt
->json
, json
);
1025 vty_out(vty
, "%-24pSU %-24pSU %c %-4d %-24s\n",
1026 &vc
->local
.nbma
, &vc
->remote
.nbma
,
1027 notifier_active(&vc
->notifier_list
) ? 'n' : ' ',
1028 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
);