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 static int interface_config_write(struct vty
*vty
);
30 static struct cmd_node nhrp_interface_node
= {
32 .node
= INTERFACE_NODE
,
33 .parent_node
= CONFIG_NODE
,
34 .prompt
= "%s(config-if)# ",
35 .config_write
= interface_config_write
,
38 #define NHRP_DEBUG_FLAGS_CMD "<all|common|event|interface|kernel|route|vici>"
40 #define NHRP_DEBUG_FLAGS_STR \
42 "Common messages (default)\n" \
43 "Event manager messages\n" \
44 "Interface messages\n" \
49 static const struct message debug_flags_desc
[] = {
50 {NHRP_DEBUG_ALL
, "all"}, {NHRP_DEBUG_COMMON
, "common"},
51 {NHRP_DEBUG_IF
, "interface"}, {NHRP_DEBUG_KERNEL
, "kernel"},
52 {NHRP_DEBUG_ROUTE
, "route"}, {NHRP_DEBUG_VICI
, "vici"},
53 {NHRP_DEBUG_EVENT
, "event"}, {0}};
55 static const struct message interface_flags_desc
[] = {
56 {NHRP_IFF_SHORTCUT
, "shortcut"},
57 {NHRP_IFF_REDIRECT
, "redirect"},
58 {NHRP_IFF_REG_NO_UNIQUE
, "registration no-unique"},
61 static int nhrp_vty_return(struct vty
*vty
, int ret
)
63 static const char *const errmsgs
[] = {
64 [NHRP_ERR_FAIL
] = "Command failed",
65 [NHRP_ERR_NO_MEMORY
] = "Out of memory",
66 [NHRP_ERR_UNSUPPORTED_INTERFACE
] =
67 "NHRP not supported on this interface",
68 [NHRP_ERR_NHRP_NOT_ENABLED
] =
69 "NHRP not enabled (set 'nhrp network-id' first)",
70 [NHRP_ERR_ENTRY_EXISTS
] = "Entry exists already",
71 [NHRP_ERR_ENTRY_NOT_FOUND
] = "Entry not found",
72 [NHRP_ERR_PROTOCOL_ADDRESS_MISMATCH
] =
73 "Protocol address family does not match command (ip/ipv6 mismatch)",
75 const char *str
= NULL
;
81 if (ret
> 0 && ret
<= NHRP_ERR_MAX
)
87 snprintf(buf
, sizeof(buf
), "Unknown error %d", ret
);
90 vty_out(vty
, "%% %s\n", str
);
92 return CMD_WARNING_CONFIG_FAILED
;
96 static int toggle_flag(struct vty
*vty
, const struct message
*flag_desc
,
97 const char *name
, int on_off
, unsigned *flags
)
101 for (i
= 0; flag_desc
[i
].str
!= NULL
; i
++) {
102 if (strcmp(flag_desc
[i
].str
, name
) != 0)
105 *flags
|= flag_desc
[i
].key
;
107 *flags
&= ~flag_desc
[i
].key
;
111 vty_out(vty
, "%% Invalid value %s\n", name
);
112 return CMD_WARNING_CONFIG_FAILED
;
118 DEFUN_NOSH(show_debugging_nhrp
, show_debugging_nhrp_cmd
,
119 "show debugging [nhrp]",
121 "Debugging information\n"
122 "NHRP configuration\n")
126 vty_out(vty
, "NHRP debugging status:\n");
128 for (i
= 0; debug_flags_desc
[i
].str
!= NULL
; i
++) {
129 if (debug_flags_desc
[i
].key
== NHRP_DEBUG_ALL
)
131 if (!(debug_flags_desc
[i
].key
& debug_flags
))
134 vty_out(vty
, " NHRP %s debugging is on\n",
135 debug_flags_desc
[i
].str
);
141 DEFUN(debug_nhrp
, debug_nhrp_cmd
,
142 "debug nhrp " NHRP_DEBUG_FLAGS_CMD
,
143 "Enable debug messages for specific or all parts.\n"
145 NHRP_DEBUG_FLAGS_STR
)
147 return toggle_flag(vty
, debug_flags_desc
, argv
[2]->text
, 1,
151 DEFUN(no_debug_nhrp
, no_debug_nhrp_cmd
,
152 "no debug nhrp " NHRP_DEBUG_FLAGS_CMD
,
154 "Disable debug messages for specific or all parts.\n"
156 NHRP_DEBUG_FLAGS_STR
)
158 return toggle_flag(vty
, debug_flags_desc
, argv
[3]->text
, 0,
162 #endif /* NO_DEBUG */
164 static int nhrp_config_write(struct vty
*vty
)
167 if (debug_flags
== NHRP_DEBUG_ALL
) {
168 vty_out(vty
, "debug nhrp all\n");
172 for (i
= 0; debug_flags_desc
[i
].str
!= NULL
; i
++) {
173 if (debug_flags_desc
[i
].key
== NHRP_DEBUG_ALL
)
175 if (!(debug_flags
& debug_flags_desc
[i
].key
))
177 vty_out(vty
, "debug nhrp %s\n",
178 debug_flags_desc
[i
].str
);
182 #endif /* NO_DEBUG */
184 if (nhrp_event_socket_path
) {
185 vty_out(vty
, "nhrp event socket %s\n", nhrp_event_socket_path
);
187 if (netlink_nflog_group
) {
188 vty_out(vty
, "nhrp nflog-group %d\n", netlink_nflog_group
);
194 #define IP_STR "IP information\n"
195 #define IPV6_STR "IPv6 information\n"
196 #define AFI_CMD "<ip|ipv6>"
197 #define AFI_STR IP_STR IPV6_STR
198 #define NHRP_STR "Next Hop Resolution Protocol functions\n"
200 static afi_t
cmd_to_afi(const struct cmd_token
*tok
)
202 return strcmp(tok
->text
, "ipv6") == 0 ? AFI_IP6
: AFI_IP
;
205 static const char *afi_to_cmd(afi_t afi
)
212 DEFUN(nhrp_event_socket
, nhrp_event_socket_cmd
,
213 "nhrp event socket SOCKET",
215 "Event Manager commands\n"
216 "Event Manager unix socket path\n"
217 "Unix path for the socket\n")
219 evmgr_set_socket(argv
[3]->arg
);
223 DEFUN(no_nhrp_event_socket
, no_nhrp_event_socket_cmd
,
224 "no nhrp event socket [SOCKET]",
227 "Event Manager commands\n"
228 "Event Manager unix socket path\n"
229 "Unix path for the socket\n")
231 evmgr_set_socket(NULL
);
235 DEFUN(nhrp_nflog_group
, nhrp_nflog_group_cmd
,
236 "nhrp nflog-group (1-65535)",
238 "Specify NFLOG group number\n"
239 "NFLOG group number\n")
243 nfgroup
= strtoul(argv
[2]->arg
, NULL
, 10);
244 netlink_set_nflog_group(nfgroup
);
249 DEFUN(no_nhrp_nflog_group
, no_nhrp_nflog_group_cmd
,
250 "no nhrp nflog-group [(1-65535)]",
253 "Specify NFLOG group number\n"
254 "NFLOG group number\n")
256 netlink_set_nflog_group(0);
260 DEFUN(tunnel_protection
, tunnel_protection_cmd
,
261 "tunnel protection vici profile PROFILE [fallback-profile FALLBACK]",
262 "NHRP/GRE integration\n"
264 "VICI (StrongSwan)\n"
266 "IPsec profile name\n"
267 "Fallback IPsec profile\n"
268 "Fallback IPsec profile name\n")
270 VTY_DECLVAR_CONTEXT(interface
, ifp
);
272 nhrp_interface_set_protection(ifp
, argv
[4]->arg
,
273 argc
> 6 ? argv
[6]->arg
: NULL
);
277 DEFUN(no_tunnel_protection
, no_tunnel_protection_cmd
,
278 "no tunnel protection",
280 "NHRP/GRE integration\n"
281 "IPsec protection\n")
283 VTY_DECLVAR_CONTEXT(interface
, ifp
);
285 nhrp_interface_set_protection(ifp
, NULL
, NULL
);
289 DEFUN(tunnel_source
, tunnel_source_cmd
,
290 "tunnel source INTERFACE",
291 "NHRP/GRE integration\n"
292 "Tunnel device binding tracking\n"
295 VTY_DECLVAR_CONTEXT(interface
, ifp
);
296 nhrp_interface_set_source(ifp
, argv
[2]->arg
);
300 DEFUN(no_tunnel_source
, no_tunnel_source_cmd
,
302 "NHRP/GRE integration\n"
303 "Tunnel device binding tracking\n"
306 VTY_DECLVAR_CONTEXT(interface
, ifp
);
307 nhrp_interface_set_source(ifp
, NULL
);
311 DEFUN(if_nhrp_network_id
, if_nhrp_network_id_cmd
,
312 AFI_CMD
" nhrp network-id (1-4294967295)",
315 "Enable NHRP and specify network-id\n"
316 "System local ID to specify interface group\n")
318 VTY_DECLVAR_CONTEXT(interface
, ifp
);
319 struct nhrp_interface
*nifp
= ifp
->info
;
320 afi_t afi
= cmd_to_afi(argv
[0]);
322 nifp
->afi
[afi
].network_id
= strtoul(argv
[3]->arg
, NULL
, 10);
323 nhrp_interface_update(ifp
);
328 DEFUN(if_no_nhrp_network_id
, if_no_nhrp_network_id_cmd
,
329 "no " AFI_CMD
" nhrp network-id [(1-4294967295)]",
333 "Enable NHRP and specify network-id\n"
334 "System local ID to specify interface group\n")
336 VTY_DECLVAR_CONTEXT(interface
, ifp
);
337 struct nhrp_interface
*nifp
= ifp
->info
;
338 afi_t afi
= cmd_to_afi(argv
[1]);
340 nifp
->afi
[afi
].network_id
= 0;
341 nhrp_interface_update(ifp
);
346 DEFUN(if_nhrp_flags
, if_nhrp_flags_cmd
,
347 AFI_CMD
" nhrp <shortcut|redirect>",
350 "Allow shortcut establishment\n"
351 "Send redirect notifications\n")
353 VTY_DECLVAR_CONTEXT(interface
, ifp
);
354 struct nhrp_interface
*nifp
= ifp
->info
;
355 afi_t afi
= cmd_to_afi(argv
[0]);
357 return toggle_flag(vty
, interface_flags_desc
, argv
[2]->text
, 1,
358 &nifp
->afi
[afi
].flags
);
361 DEFUN(if_no_nhrp_flags
, if_no_nhrp_flags_cmd
,
362 "no " AFI_CMD
" nhrp <shortcut|redirect>",
366 "Allow shortcut establishment\n"
367 "Send redirect notifications\n")
369 VTY_DECLVAR_CONTEXT(interface
, ifp
);
370 struct nhrp_interface
*nifp
= ifp
->info
;
371 afi_t afi
= cmd_to_afi(argv
[1]);
373 return toggle_flag(vty
, interface_flags_desc
, argv
[3]->text
, 0,
374 &nifp
->afi
[afi
].flags
);
377 DEFUN(if_nhrp_reg_flags
, if_nhrp_reg_flags_cmd
,
378 AFI_CMD
" nhrp registration no-unique",
381 "Registration configuration\n"
382 "Don't set unique flag\n")
384 VTY_DECLVAR_CONTEXT(interface
, ifp
);
385 struct nhrp_interface
*nifp
= ifp
->info
;
386 afi_t afi
= cmd_to_afi(argv
[0]);
388 snprintf(name
, sizeof(name
), "registration %s", argv
[3]->text
);
389 return toggle_flag(vty
, interface_flags_desc
, name
, 1,
390 &nifp
->afi
[afi
].flags
);
393 DEFUN(if_no_nhrp_reg_flags
, if_no_nhrp_reg_flags_cmd
,
394 "no " 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
[1]);
405 snprintf(name
, sizeof(name
), "registration %s", argv
[4]->text
);
406 return toggle_flag(vty
, interface_flags_desc
, name
, 0,
407 &nifp
->afi
[afi
].flags
);
410 DEFUN(if_nhrp_holdtime
, if_nhrp_holdtime_cmd
,
411 AFI_CMD
" nhrp holdtime (1-65000)",
414 "Specify NBMA address validity time\n"
415 "Time in seconds that NBMA addresses are advertised valid\n")
417 VTY_DECLVAR_CONTEXT(interface
, ifp
);
418 struct nhrp_interface
*nifp
= ifp
->info
;
419 afi_t afi
= cmd_to_afi(argv
[0]);
421 nifp
->afi
[afi
].holdtime
= strtoul(argv
[3]->arg
, NULL
, 10);
422 nhrp_interface_update(ifp
);
427 DEFUN(if_no_nhrp_holdtime
, if_no_nhrp_holdtime_cmd
,
428 "no " AFI_CMD
" nhrp holdtime [(1-65000)]",
432 "Specify NBMA address validity time\n"
433 "Time in seconds that NBMA addresses are advertised valid\n")
435 VTY_DECLVAR_CONTEXT(interface
, ifp
);
436 struct nhrp_interface
*nifp
= ifp
->info
;
437 afi_t afi
= cmd_to_afi(argv
[1]);
439 nifp
->afi
[afi
].holdtime
= NHRPD_DEFAULT_HOLDTIME
;
440 nhrp_interface_update(ifp
);
445 DEFUN(if_nhrp_mtu
, if_nhrp_mtu_cmd
,
446 "ip nhrp mtu <(576-1500)|opennhrp>",
449 "Configure NHRP advertised MTU\n"
451 "Advertise bound interface MTU similar to OpenNHRP\n")
453 VTY_DECLVAR_CONTEXT(interface
, ifp
);
454 struct nhrp_interface
*nifp
= ifp
->info
;
456 if (argv
[3]->arg
[0] == 'o') {
457 nifp
->afi
[AFI_IP
].configured_mtu
= -1;
459 nifp
->afi
[AFI_IP
].configured_mtu
=
460 strtoul(argv
[3]->arg
, NULL
, 10);
462 nhrp_interface_update_mtu(ifp
, AFI_IP
);
467 DEFUN(if_no_nhrp_mtu
, if_no_nhrp_mtu_cmd
,
468 "no ip nhrp mtu [(576-1500)|opennhrp]",
472 "Configure NHRP advertised MTU\n"
474 "Advertise bound interface MTU similar to OpenNHRP\n")
476 VTY_DECLVAR_CONTEXT(interface
, ifp
);
477 struct nhrp_interface
*nifp
= ifp
->info
;
479 nifp
->afi
[AFI_IP
].configured_mtu
= 0;
480 nhrp_interface_update_mtu(ifp
, AFI_IP
);
484 DEFUN(if_nhrp_map
, if_nhrp_map_cmd
,
485 AFI_CMD
" nhrp map <A.B.C.D|X:X::X:X> <A.B.C.D|local>",
488 "Nexthop Server configuration\n"
489 "IPv4 protocol address\n"
490 "IPv6 protocol address\n"
491 "IPv4 NBMA address\n"
492 "Handle protocol address locally\n")
494 VTY_DECLVAR_CONTEXT(interface
, ifp
);
495 afi_t afi
= cmd_to_afi(argv
[0]);
496 union sockunion proto_addr
, nbma_addr
;
497 struct nhrp_cache_config
*cc
;
498 struct nhrp_cache
*c
;
499 enum nhrp_cache_type type
;
501 if (str2sockunion(argv
[3]->arg
, &proto_addr
) < 0
502 || afi2family(afi
) != sockunion_family(&proto_addr
))
503 return nhrp_vty_return(vty
, NHRP_ERR_PROTOCOL_ADDRESS_MISMATCH
);
505 if (strmatch(argv
[4]->text
, "local"))
506 type
= NHRP_CACHE_LOCAL
;
508 if (str2sockunion(argv
[4]->arg
, &nbma_addr
) < 0)
509 return nhrp_vty_return(vty
, NHRP_ERR_FAIL
);
510 type
= NHRP_CACHE_STATIC
;
512 cc
= nhrp_cache_config_get(ifp
, &proto_addr
, 1);
514 return nhrp_vty_return(vty
, NHRP_ERR_FAIL
);
515 cc
->nbma
= nbma_addr
;
517 /* gre layer not ready */
518 if (ifp
->ifindex
== IFINDEX_INTERNAL
)
521 c
= nhrp_cache_get(ifp
, &proto_addr
, 1);
523 return nhrp_vty_return(vty
, NHRP_ERR_FAIL
);
526 if (type
== NHRP_CACHE_LOCAL
)
527 nhrp_cache_update_binding(c
, NHRP_CACHE_LOCAL
, 0, NULL
, 0,
530 nhrp_cache_update_binding(c
, NHRP_CACHE_STATIC
, 0,
531 nhrp_peer_get(ifp
, &nbma_addr
), 0,
536 DEFUN(if_no_nhrp_map
, if_no_nhrp_map_cmd
,
537 "no " AFI_CMD
" nhrp map <A.B.C.D|X:X::X:X> [<A.B.C.D|local>]",
541 "Nexthop Server configuration\n"
542 "IPv4 protocol address\n"
543 "IPv6 protocol address\n"
544 "IPv4 NBMA address\n"
545 "Handle protocol address locally\n")
547 VTY_DECLVAR_CONTEXT(interface
, ifp
);
548 afi_t afi
= cmd_to_afi(argv
[1]);
549 union sockunion proto_addr
, nbma_addr
;
550 struct nhrp_cache_config
*cc
;
551 struct nhrp_cache
*c
;
553 if (str2sockunion(argv
[4]->arg
, &proto_addr
) < 0
554 || afi2family(afi
) != sockunion_family(&proto_addr
))
555 return nhrp_vty_return(vty
, NHRP_ERR_PROTOCOL_ADDRESS_MISMATCH
);
557 cc
= nhrp_cache_config_get(ifp
, &proto_addr
, 0);
559 return nhrp_vty_return(vty
, NHRP_ERR_FAIL
);
560 nhrp_cache_config_free(cc
);
562 c
= nhrp_cache_get(ifp
, &proto_addr
, 0);
563 /* silently return */
567 nhrp_cache_update_binding(c
, c
->cur
.type
, -1,
568 nhrp_peer_get(ifp
, &nbma_addr
), 0, NULL
);
572 DEFUN(if_nhrp_nhs
, if_nhrp_nhs_cmd
,
573 AFI_CMD
" nhrp nhs <A.B.C.D|X:X::X:X|dynamic> nbma <A.B.C.D|FQDN>",
576 "Nexthop Server configuration\n"
577 "IPv4 protocol address\n"
578 "IPv6 protocol address\n"
579 "Automatic detection of protocol address\n"
581 "IPv4 NBMA address\n"
582 "Fully qualified domain name for NBMA address(es)\n")
584 VTY_DECLVAR_CONTEXT(interface
, ifp
);
585 afi_t afi
= cmd_to_afi(argv
[0]);
586 union sockunion proto_addr
;
589 if (str2sockunion(argv
[3]->arg
, &proto_addr
) < 0)
590 sockunion_family(&proto_addr
) = AF_UNSPEC
;
592 ret
= nhrp_nhs_add(ifp
, afi
, &proto_addr
, argv
[5]->arg
);
593 return nhrp_vty_return(vty
, ret
);
596 DEFUN(if_no_nhrp_nhs
, if_no_nhrp_nhs_cmd
,
597 "no " AFI_CMD
" nhrp nhs <A.B.C.D|X:X::X:X|dynamic> nbma <A.B.C.D|FQDN>",
601 "Nexthop Server configuration\n"
602 "IPv4 protocol address\n"
603 "IPv6 protocol address\n"
604 "Automatic detection of protocol address\n"
606 "IPv4 NBMA address\n"
607 "Fully qualified domain name for NBMA address(es)\n")
609 VTY_DECLVAR_CONTEXT(interface
, ifp
);
610 afi_t afi
= cmd_to_afi(argv
[1]);
611 union sockunion proto_addr
;
614 if (str2sockunion(argv
[4]->arg
, &proto_addr
) < 0)
615 sockunion_family(&proto_addr
) = AF_UNSPEC
;
617 ret
= nhrp_nhs_del(ifp
, afi
, &proto_addr
, argv
[6]->arg
);
618 return nhrp_vty_return(vty
, ret
);
625 struct json_object
*json
;
628 static void show_ip_nhrp_cache(struct nhrp_cache
*c
, void *pctx
)
630 struct info_ctx
*ctx
= pctx
;
631 struct vty
*vty
= ctx
->vty
;
632 char buf
[2][SU_ADDRSTRLEN
];
633 struct json_object
*json
= NULL
;
635 if (ctx
->afi
!= family2afi(sockunion_family(&c
->remote_addr
)))
639 if (!ctx
->count
&& !ctx
->json
) {
640 vty_out(vty
, "%-8s %-8s %-24s %-24s %-6s %s\n", "Iface", "Type",
641 "Protocol", "NBMA", "Flags", "Identity");
645 sockunion2str(&c
->remote_addr
, buf
[0], sizeof(buf
[0]));
647 sockunion2str(&c
->cur
.peer
->vc
->remote
.nbma
,
648 buf
[1], sizeof(buf
[1]));
650 snprintf(buf
[1], sizeof(buf
[1]), "-");
653 json
= json_object_new_object();
654 json_object_string_add(json
, "interface", c
->ifp
->name
);
655 json_object_string_add(json
, "type",
656 nhrp_cache_type_str
[c
->cur
.type
]);
657 json_object_string_add(json
, "protocol", buf
[0]);
658 json_object_string_add(json
, "nbma", buf
[1]);
661 json_object_boolean_true_add(json
, "used");
663 json_object_boolean_false_add(json
, "used");
666 json_object_boolean_true_add(json
, "timeout");
668 json_object_boolean_false_add(json
, "timeout");
671 json_object_boolean_true_add(json
, "auth");
673 json_object_boolean_false_add(json
, "auth");
676 json_object_string_add(json
, "identity",
677 c
->cur
.peer
->vc
->remote
.id
);
679 json_object_string_add(json
, "identity", "-");
681 json_object_array_add(ctx
->json
, json
);
684 vty_out(ctx
->vty
, "%-8s %-8s %-24s %-24s %c%c%c %s\n", c
->ifp
->name
,
685 nhrp_cache_type_str
[c
->cur
.type
],
687 c
->used
? 'U' : ' ', c
->t_timeout
? 'T' : ' ',
688 c
->t_auth
? 'A' : ' ',
689 c
->cur
.peer
? c
->cur
.peer
->vc
->remote
.id
: "-");
692 static void show_ip_nhrp_nhs(struct nhrp_nhs
*n
, struct nhrp_registration
*reg
,
695 struct info_ctx
*ctx
= pctx
;
696 struct vty
*vty
= ctx
->vty
;
697 char buf
[2][SU_ADDRSTRLEN
];
698 struct json_object
*json
= NULL
;
700 if (!ctx
->count
&& !ctx
->json
) {
701 vty_out(vty
, "%-8s %-24s %-16s %-16s\n", "Iface", "FQDN",
706 if (reg
&& reg
->peer
)
707 sockunion2str(®
->peer
->vc
->remote
.nbma
,
708 buf
[0], sizeof(buf
[0]));
710 snprintf(buf
[0], sizeof(buf
[0]), "-");
711 sockunion2str(reg
? ®
->proto_addr
: &n
->proto_addr
, buf
[1],
715 json
= json_object_new_object();
716 json_object_string_add(json
, "interface", n
->ifp
->name
);
717 json_object_string_add(json
, "fqdn", n
->nbma_fqdn
);
718 json_object_string_add(json
, "nbma", buf
[0]);
719 json_object_string_add(json
, "protocol", buf
[1]);
721 json_object_array_add(ctx
->json
, json
);
725 vty_out(vty
, "%-8s %-24s %-16s %-16s\n", n
->ifp
->name
, n
->nbma_fqdn
,
729 static void show_ip_nhrp_shortcut(struct nhrp_shortcut
*s
, void *pctx
)
731 struct info_ctx
*ctx
= pctx
;
732 struct nhrp_cache
*c
;
733 struct vty
*vty
= ctx
->vty
;
734 char buf1
[PREFIX_STRLEN
], buf2
[SU_ADDRSTRLEN
];
735 struct json_object
*json
= NULL
;
738 vty_out(vty
, "%-8s %-24s %-24s %s\n", "Type", "Prefix", "Via",
745 sockunion2str(&c
->remote_addr
, buf2
, sizeof(buf2
));
746 prefix2str(s
->p
, buf1
, sizeof(buf1
));
749 json
= json_object_new_object();
750 json_object_string_add(json
, "type",
751 nhrp_cache_type_str
[s
->type
]);
752 json_object_string_add(json
, "prefix", buf1
);
755 json_object_string_add(json
, "via", buf2
);
757 if (c
&& c
->cur
.peer
)
758 json_object_string_add(json
, "identity",
759 c
->cur
.peer
->vc
->remote
.id
);
761 json_object_string_add(json
, "identity", "");
763 json_object_array_add(ctx
->json
, json
);
767 vty_out(ctx
->vty
, "%-8s %-24s %-24s %s\n",
768 nhrp_cache_type_str
[s
->type
],
770 (c
&& c
->cur
.peer
) ? c
->cur
.peer
->vc
->remote
.id
: "");
773 static void show_ip_opennhrp_cache(struct nhrp_cache
*c
, void *pctx
)
775 struct info_ctx
*ctx
= pctx
;
776 char buf
[3][SU_ADDRSTRLEN
];
777 struct json_object
*json
= NULL
;
780 if (ctx
->afi
!= family2afi(sockunion_family(&c
->remote_addr
)))
783 sockunion2str(&c
->remote_addr
, buf
[0], sizeof(buf
[0]));
785 sockunion2str(&c
->cur
.peer
->vc
->remote
.nbma
, buf
[1],
787 if (sockunion_family(&c
->cur
.remote_nbma_natoa
) != AF_UNSPEC
)
788 sockunion2str(&c
->cur
.remote_nbma_natoa
, buf
[2],
791 json
= json_object_new_object();
792 json_object_string_add(json
, "type",
793 nhrp_cache_type_str
[c
->cur
.type
]);
795 if (c
->cur
.peer
&& c
->cur
.peer
->online
)
796 json_object_boolean_true_add(json
, "up");
798 json_object_boolean_false_add(json
, "up");
801 json_object_boolean_true_add(json
, "used");
803 json_object_boolean_false_add(json
, "used");
805 json_object_string_add(json
, "protocolAddress", buf
[0]);
806 json_object_int_add(json
, "protocolAddressSize",
807 8 * family2addrsize(sockunion_family
811 json_object_string_add(json
, "nbmaAddress", buf
[1]);
813 if (sockunion_family(&c
->cur
.remote_nbma_natoa
) != AF_UNSPEC
)
814 json_object_string_add(json
, "nbmaNatOaAddress",
817 json_object_array_add(ctx
->json
, json
);
823 "Protocol-Address: %s/%zu\n",
824 nhrp_cache_type_str
[c
->cur
.type
],
825 (c
->cur
.peer
&& c
->cur
.peer
->online
) ? " up" : "",
826 c
->used
? " used" : "",
828 8 * family2addrsize(sockunion_family(&c
->remote_addr
)));
831 vty_out(ctx
->vty
, "NBMA-Address: %s\n", buf
[1]);
833 if (sockunion_family(&c
->cur
.remote_nbma_natoa
) != AF_UNSPEC
)
834 vty_out(ctx
->vty
, "NBMA-NAT-OA-Address: %s\n", buf
[2]);
836 vty_out(ctx
->vty
, "\n\n");
839 DEFUN(show_ip_nhrp
, show_ip_nhrp_cmd
,
840 "show " AFI_CMD
" nhrp [cache|nhs|shortcut|opennhrp] [json]",
844 "Forwarding cache information\n"
845 "Next hop server information\n"
846 "Shortcut information\n"
847 "opennhrpctl style cache dump\n"
850 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
851 struct interface
*ifp
;
852 struct info_ctx ctx
= {
853 .vty
= vty
, .afi
= cmd_to_afi(argv
[1]), .json
= NULL
855 bool uj
= use_json(argc
, argv
);
856 struct json_object
*json_path
= NULL
;
857 struct json_object
*json_vrf
= NULL
, *json_vrf_path
= NULL
;
858 int ret
= CMD_SUCCESS
;
861 json_vrf
= json_object_new_object();
862 json_vrf_path
= json_object_new_object();
863 json_path
= json_object_new_array();
864 ctx
.json
= json_path
;
866 if (argc
<= 3 || argv
[3]->text
[0] == 'c') {
867 FOR_ALL_INTERFACES (vrf
, ifp
)
868 nhrp_cache_foreach(ifp
, show_ip_nhrp_cache
, &ctx
);
869 } else if (argv
[3]->text
[0] == 'n') {
870 FOR_ALL_INTERFACES (vrf
, ifp
)
871 nhrp_nhs_foreach(ifp
, ctx
.afi
, show_ip_nhrp_nhs
, &ctx
);
872 } else if (argv
[3]->text
[0] == 's') {
873 nhrp_shortcut_foreach(ctx
.afi
, show_ip_nhrp_shortcut
, &ctx
);
876 vty_out(vty
, "Status: ok\n\n");
878 json_object_string_add(json_vrf
, "status", "ok");
881 FOR_ALL_INTERFACES (vrf
, ifp
)
882 nhrp_cache_foreach(ifp
, show_ip_opennhrp_cache
, &ctx
);
886 json_object_int_add(json_vrf
, "entriesCount", ctx
.count
);
889 vty_out(vty
, "%% No entries\n");
893 json_object_object_add(json_vrf_path
, "attr", json_vrf
);
894 json_object_object_add(json_vrf_path
, "table", ctx
.json
);
896 json_object_to_json_string_ext(
897 json_vrf_path
, JSON_C_TO_STRING_PRETTY
));
898 json_object_free(json_vrf_path
);
905 struct json_object
*json
;
908 static void show_dmvpn_entry(struct nhrp_vc
*vc
, void *ctx
)
910 struct dmvpn_cfg
*ctxt
= ctx
;
912 char buf
[2][SU_ADDRSTRLEN
];
913 struct json_object
*json
= NULL
;
915 if (!ctxt
|| !ctxt
->vty
)
918 sockunion2str(&vc
->local
.nbma
, buf
[0], sizeof(buf
[0]));
919 sockunion2str(&vc
->remote
.nbma
, buf
[1], sizeof(buf
[1]));
921 json
= json_object_new_object();
922 json_object_string_add(json
, "src", buf
[0]);
923 json_object_string_add(json
, "dst", buf
[1]);
925 if (notifier_active(&vc
->notifier_list
))
926 json_object_boolean_true_add(json
, "notifierActive");
928 json_object_boolean_false_add(json
, "notifierActive");
930 json_object_int_add(json
, "sas", vc
->ipsec
);
931 json_object_string_add(json
, "identity", vc
->remote
.id
);
932 json_object_array_add(ctxt
->json
, json
);
934 vty_out(vty
, "%-24s %-24s %c %-4d %-24s\n",
935 buf
[0], buf
[1], notifier_active(&vc
->notifier_list
) ?
936 'n' : ' ', vc
->ipsec
, vc
->remote
.id
);
940 DEFUN(show_dmvpn
, show_dmvpn_cmd
,
943 "DMVPN information\n"
946 bool uj
= use_json(argc
, argv
);
947 struct dmvpn_cfg ctxt
;
948 struct json_object
*json_path
= NULL
;
953 vty_out(vty
, "%-24s %-24s %-6s %-4s %-24s\n",
954 "Src", "Dst", "Flags", "SAs", "Identity");
956 json_path
= json_object_new_array();
957 ctxt
.json
= json_path
;
959 nhrp_vc_foreach(show_dmvpn_entry
, &ctxt
);
962 json_object_to_json_string_ext(
963 json_path
, JSON_C_TO_STRING_PRETTY
));
964 json_object_free(json_path
);
969 static void clear_nhrp_cache(struct nhrp_cache
*c
, void *data
)
971 struct info_ctx
*ctx
= data
;
972 if (c
->cur
.type
<= NHRP_CACHE_DYNAMIC
) {
973 nhrp_cache_update_binding(c
, c
->cur
.type
, -1, NULL
, 0, NULL
);
978 static void clear_nhrp_shortcut(struct nhrp_shortcut
*s
, void *data
)
980 struct info_ctx
*ctx
= data
;
981 nhrp_shortcut_purge(s
, 1);
985 DEFUN(clear_nhrp
, clear_nhrp_cmd
,
986 "clear " AFI_CMD
" nhrp <cache|shortcut>",
990 "Dynamic cache entries\n"
991 "Shortcut entries\n")
993 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
994 struct interface
*ifp
;
995 struct info_ctx ctx
= {
996 .vty
= vty
, .afi
= cmd_to_afi(argv
[1]), .count
= 0,
999 if (argc
<= 3 || argv
[3]->text
[0] == 'c') {
1000 FOR_ALL_INTERFACES (vrf
, ifp
)
1001 nhrp_cache_foreach(ifp
, clear_nhrp_cache
, &ctx
);
1003 nhrp_shortcut_foreach(ctx
.afi
, clear_nhrp_shortcut
, &ctx
);
1007 vty_out(vty
, "%% No entries\n");
1011 vty_out(vty
, "%% %d entries cleared\n", ctx
.count
);
1015 struct write_map_ctx
{
1021 static void interface_config_write_nhrp_map(struct nhrp_cache_config
*c
, void *data
)
1023 struct write_map_ctx
*ctx
= data
;
1024 struct vty
*vty
= ctx
->vty
;
1025 char buf
[2][SU_ADDRSTRLEN
];
1027 if (sockunion_family(&c
->remote_addr
) != ctx
->family
)
1030 vty_out(vty
, " %s nhrp map %s %s\n", ctx
->aficmd
,
1031 sockunion2str(&c
->remote_addr
, buf
[0], sizeof(buf
[0])),
1032 c
->type
== NHRP_CACHE_LOCAL
1033 ? "local" : sockunion2str(&c
->nbma
, buf
[1], sizeof(buf
[1])));
1036 static int interface_config_write(struct vty
*vty
)
1038 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
1039 struct write_map_ctx mapctx
;
1040 struct interface
*ifp
;
1041 struct nhrp_interface
*nifp
;
1042 struct nhrp_nhs
*nhs
;
1045 char buf
[SU_ADDRSTRLEN
];
1048 FOR_ALL_INTERFACES (vrf
, ifp
) {
1049 vty_frame(vty
, "interface %s\n", ifp
->name
);
1051 vty_out(vty
, " description %s\n", ifp
->desc
);
1054 if (nifp
->ipsec_profile
) {
1055 vty_out(vty
, " tunnel protection vici profile %s",
1056 nifp
->ipsec_profile
);
1057 if (nifp
->ipsec_fallback_profile
)
1058 vty_out(vty
, " fallback-profile %s",
1059 nifp
->ipsec_fallback_profile
);
1063 vty_out(vty
, " tunnel source %s\n", nifp
->source
);
1065 for (afi
= 0; afi
< AFI_MAX
; afi
++) {
1066 struct nhrp_afi_data
*ad
= &nifp
->afi
[afi
];
1068 aficmd
= afi_to_cmd(afi
);
1071 vty_out(vty
, " %s nhrp network-id %u\n", aficmd
,
1074 if (ad
->holdtime
!= NHRPD_DEFAULT_HOLDTIME
)
1075 vty_out(vty
, " %s nhrp holdtime %u\n", aficmd
,
1078 if (ad
->configured_mtu
< 0)
1079 vty_out(vty
, " %s nhrp mtu opennhrp\n", aficmd
);
1080 else if (ad
->configured_mtu
)
1081 vty_out(vty
, " %s nhrp mtu %u\n", aficmd
,
1082 ad
->configured_mtu
);
1084 for (i
= 0; interface_flags_desc
[i
].str
!= NULL
; i
++) {
1085 if (!(ad
->flags
& interface_flags_desc
[i
].key
))
1087 vty_out(vty
, " %s nhrp %s\n", aficmd
,
1088 interface_flags_desc
[i
].str
);
1091 mapctx
= (struct write_map_ctx
){
1093 .family
= afi2family(afi
),
1096 nhrp_cache_config_foreach(ifp
, interface_config_write_nhrp_map
,
1099 list_for_each_entry(nhs
, &ad
->nhslist_head
,
1102 vty_out(vty
, " %s nhrp nhs %s nbma %s\n",
1104 sockunion_family(&nhs
->proto_addr
)
1108 &nhs
->proto_addr
, buf
,
1114 vty_endframe(vty
, "!\n");
1120 void nhrp_config_init(void)
1122 install_node(&zebra_node
);
1123 install_default(ZEBRA_NODE
);
1125 /* access-list commands */
1128 /* global commands */
1129 install_element(VIEW_NODE
, &show_ip_nhrp_cmd
);
1130 install_element(VIEW_NODE
, &show_dmvpn_cmd
);
1131 install_element(ENABLE_NODE
, &clear_nhrp_cmd
);
1133 install_element(ENABLE_NODE
, &show_debugging_nhrp_cmd
);
1135 install_element(ENABLE_NODE
, &debug_nhrp_cmd
);
1136 install_element(ENABLE_NODE
, &no_debug_nhrp_cmd
);
1138 install_element(CONFIG_NODE
, &debug_nhrp_cmd
);
1139 install_element(CONFIG_NODE
, &no_debug_nhrp_cmd
);
1141 install_element(CONFIG_NODE
, &nhrp_event_socket_cmd
);
1142 install_element(CONFIG_NODE
, &no_nhrp_event_socket_cmd
);
1143 install_element(CONFIG_NODE
, &nhrp_nflog_group_cmd
);
1144 install_element(CONFIG_NODE
, &no_nhrp_nflog_group_cmd
);
1146 /* interface specific commands */
1147 install_node(&nhrp_interface_node
);
1150 install_element(INTERFACE_NODE
, &tunnel_protection_cmd
);
1151 install_element(INTERFACE_NODE
, &no_tunnel_protection_cmd
);
1152 install_element(INTERFACE_NODE
, &tunnel_source_cmd
);
1153 install_element(INTERFACE_NODE
, &no_tunnel_source_cmd
);
1154 install_element(INTERFACE_NODE
, &if_nhrp_network_id_cmd
);
1155 install_element(INTERFACE_NODE
, &if_no_nhrp_network_id_cmd
);
1156 install_element(INTERFACE_NODE
, &if_nhrp_holdtime_cmd
);
1157 install_element(INTERFACE_NODE
, &if_no_nhrp_holdtime_cmd
);
1158 install_element(INTERFACE_NODE
, &if_nhrp_mtu_cmd
);
1159 install_element(INTERFACE_NODE
, &if_no_nhrp_mtu_cmd
);
1160 install_element(INTERFACE_NODE
, &if_nhrp_flags_cmd
);
1161 install_element(INTERFACE_NODE
, &if_no_nhrp_flags_cmd
);
1162 install_element(INTERFACE_NODE
, &if_nhrp_reg_flags_cmd
);
1163 install_element(INTERFACE_NODE
, &if_no_nhrp_reg_flags_cmd
);
1164 install_element(INTERFACE_NODE
, &if_nhrp_map_cmd
);
1165 install_element(INTERFACE_NODE
, &if_no_nhrp_map_cmd
);
1166 install_element(INTERFACE_NODE
, &if_nhrp_nhs_cmd
);
1167 install_element(INTERFACE_NODE
, &if_no_nhrp_nhs_cmd
);