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