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