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