]> git.proxmox.com Git - mirror_frr.git/blame - nhrpd/nhrp_vty.c
Merge pull request #537 from donaldsharp/vrf_stuff
[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"
14
15#include "nhrpd.h"
16#include "netlink.h"
17
18static struct cmd_node zebra_node = {
19 .node = ZEBRA_NODE,
20 .prompt = "%s(config-router)# ",
21 .vtysh = 1,
22};
23
24static struct cmd_node nhrp_interface_node = {
25 .node = INTERFACE_NODE,
26 .prompt = "%s(config-if)# ",
27 .vtysh = 1,
28};
29
819dc8bb 30#define NHRP_DEBUG_FLAGS_CMD "<all|common|event|interface|kernel|route|vici>"
2fb975da
TT
31
32#define NHRP_DEBUG_FLAGS_STR \
33 "All messages\n" \
34 "Common messages (default)\n" \
35 "Event manager messages\n" \
36 "Interface messages\n" \
37 "Kernel messages\n" \
38 "Route messages\n" \
39 "VICI messages\n"
40
41static const struct message debug_flags_desc[] = {
42 { NHRP_DEBUG_ALL, "all" },
43 { NHRP_DEBUG_COMMON, "common" },
44 { NHRP_DEBUG_IF, "interface" },
45 { NHRP_DEBUG_KERNEL, "kernel" },
46 { NHRP_DEBUG_ROUTE, "route" },
47 { NHRP_DEBUG_VICI, "vici" },
48 { NHRP_DEBUG_EVENT, "event" },
49 { 0, NULL },
50};
51
52static const struct message interface_flags_desc[] = {
53 { NHRP_IFF_SHORTCUT, "shortcut" },
54 { NHRP_IFF_REDIRECT, "redirect" },
55 { NHRP_IFF_REG_NO_UNIQUE, "registration no-unique" },
56 { 0, NULL },
57};
58
59static int nhrp_vty_return(struct vty *vty, int ret)
60{
61 static const char * const errmsgs[] = {
62 [NHRP_ERR_FAIL] = "Command failed",
63 [NHRP_ERR_NO_MEMORY] = "Out of memory",
64 [NHRP_ERR_UNSUPPORTED_INTERFACE] = "NHRP not supported on this interface",
65 [NHRP_ERR_NHRP_NOT_ENABLED] = "NHRP not enabled (set 'nhrp network-id' first)",
66 [NHRP_ERR_ENTRY_EXISTS] = "Entry exists already",
67 [NHRP_ERR_ENTRY_NOT_FOUND] = "Entry not found",
68 [NHRP_ERR_PROTOCOL_ADDRESS_MISMATCH] = "Protocol address family does not match command (ip/ipv6 mismatch)",
69 };
70 const char *str = NULL;
71 char buf[256];
72
73 if (ret == NHRP_OK)
74 return CMD_SUCCESS;
75
76 if (ret > 0 && ret <= (int)ZEBRA_NUM_OF(errmsgs))
77 if (errmsgs[ret])
78 str = errmsgs[ret];
79
80 if (!str) {
81 str = buf;
82 snprintf(buf, sizeof(buf), "Unknown error %d", ret);
83 }
84
85 vty_out (vty, "%% %s%s", str, VTY_NEWLINE);
86
87 return CMD_WARNING;
88}
89
90static int toggle_flag(
91 struct vty *vty, const struct message *flag_desc,
92 const char *name, int on_off, unsigned *flags)
93{
94 int i;
95
96 for (i = 0; flag_desc[i].str != NULL; i++) {
97 if (strcmp(flag_desc[i].str, name) != 0)
98 continue;
99 if (on_off)
100 *flags |= flag_desc[i].key;
101 else
102 *flags &= ~flag_desc[i].key;
103 return CMD_SUCCESS;
104 }
105
106 vty_out(vty, "%% Invalid value %s%s", name, VTY_NEWLINE);
107 return CMD_WARNING;
108}
109
110#ifndef NO_DEBUG
111
112DEFUN(show_debugging_nhrp, show_debugging_nhrp_cmd,
113 "show debugging nhrp",
114 SHOW_STR
115 "Debugging information\n"
116 "NHRP configuration\n")
117{
118 int i;
119
120 vty_out(vty, "NHRP debugging status:%s", VTY_NEWLINE);
121
122 for (i = 0; debug_flags_desc[i].str != NULL; i++) {
123 if (debug_flags_desc[i].key == NHRP_DEBUG_ALL)
124 continue;
125 if (!(debug_flags_desc[i].key & debug_flags))
126 continue;
127
128 vty_out(vty, " NHRP %s debugging is on%s",
129 debug_flags_desc[i].str, VTY_NEWLINE);
130 }
131
132 return CMD_SUCCESS;
133}
134
135DEFUN(debug_nhrp, debug_nhrp_cmd,
136 "debug nhrp " NHRP_DEBUG_FLAGS_CMD,
137 "Enable debug messages for specific or all parts.\n"
138 "NHRP information\n"
139 NHRP_DEBUG_FLAGS_STR)
140{
819dc8bb 141 return toggle_flag(vty, debug_flags_desc, argv[2]->text, 1, &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{
819dc8bb 151 return toggle_flag(vty, debug_flags_desc, argv[3]->text, 0, &debug_flags);
2fb975da
TT
152}
153
154#endif /* NO_DEBUG */
155
156static int nhrp_config_write(struct vty *vty)
157{
158#ifndef NO_DEBUG
159 if (debug_flags == NHRP_DEBUG_ALL) {
160 vty_out(vty, "debug nhrp all%s", VTY_NEWLINE);
161 } else {
162 int i;
163
164 for (i = 0; debug_flags_desc[i].str != NULL; i++) {
165 if (debug_flags_desc[i].key == NHRP_DEBUG_ALL)
166 continue;
167 if (!(debug_flags & debug_flags_desc[i].key))
168 continue;
169 vty_out(vty, "debug nhrp %s%s", debug_flags_desc[i].str, VTY_NEWLINE);
170 }
171 }
172 vty_out(vty, "!%s", VTY_NEWLINE);
173#endif /* NO_DEBUG */
174
175 if (nhrp_event_socket_path) {
176 vty_out(vty, "nhrp event socket %s%s",
177 nhrp_event_socket_path, VTY_NEWLINE);
178 }
179 if (netlink_nflog_group) {
180 vty_out(vty, "nhrp nflog-group %d%s",
181 netlink_nflog_group, VTY_NEWLINE);
182 }
183
184 return 0;
185}
186
187#define IP_STR "IP information\n"
188#define IPV6_STR "IPv6 information\n"
819dc8bb 189#define AFI_CMD "<ip|ipv6>"
2fb975da
TT
190#define AFI_STR IP_STR IPV6_STR
191#define NHRP_STR "Next Hop Resolution Protocol functions\n"
192
819dc8bb 193static afi_t cmd_to_afi(const struct cmd_token *tok)
2fb975da 194{
819dc8bb 195 return strcmp(tok->text, "ipv6") == 0 ? AFI_IP6 : AFI_IP;
2fb975da
TT
196}
197
198static const char *afi_to_cmd(afi_t afi)
199{
200 if (afi == AFI_IP6) return "ipv6";
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"
209 "Unix path for the socket")
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"
221 "Unix path for the socket")
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
819dc8bb 235 VTY_GET_INTEGER_RANGE("nflog-group", nfgroup, argv[2]->arg, 1, 65535);
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
252DEFUN(tunnel_protection, tunnel_protection_cmd,
819dc8bb 253 "tunnel protection vici profile PROFILE [fallback-profile FALLBACK]",
2fb975da
TT
254 "NHRP/GRE integration\n"
255 "IPsec protection\n"
256 "VICI (StrongSwan)\n"
257 "IPsec profile\n"
258 "IPsec profile name\n"
259 "Fallback IPsec profile\n"
260 "Fallback IPsec profile name\n")
261{
819dc8bb 262 VTY_DECLVAR_CONTEXT(interface, ifp);
2fb975da 263
819dc8bb
DL
264 nhrp_interface_set_protection(ifp, argv[4]->arg,
265 argc > 6 ? argv[6]->arg : NULL);
2fb975da
TT
266 return CMD_SUCCESS;
267}
268
269DEFUN(no_tunnel_protection, no_tunnel_protection_cmd,
270 "no tunnel protection",
271 NO_STR
272 "NHRP/GRE integration\n"
273 "IPsec protection\n")
274{
819dc8bb 275 VTY_DECLVAR_CONTEXT(interface, ifp);
2fb975da
TT
276
277 nhrp_interface_set_protection(ifp, NULL, NULL);
278 return CMD_SUCCESS;
279}
280
281DEFUN(tunnel_source, tunnel_source_cmd,
282 "tunnel source INTERFACE",
283 "NHRP/GRE integration\n"
284 "Tunnel device binding tracking\n"
285 "Interface name\n")
286{
819dc8bb
DL
287 VTY_DECLVAR_CONTEXT(interface, ifp);
288 nhrp_interface_set_source(ifp, argv[2]->arg);
2fb975da
TT
289 return CMD_SUCCESS;
290}
291
292DEFUN(no_tunnel_source, no_tunnel_source_cmd,
293 "no tunnel source",
294 "NHRP/GRE integration\n"
295 "Tunnel device binding tracking\n"
296 "Interface name\n")
297{
819dc8bb 298 VTY_DECLVAR_CONTEXT(interface, ifp);
2fb975da
TT
299 nhrp_interface_set_source(ifp, NULL);
300 return CMD_SUCCESS;
301}
302
303DEFUN(if_nhrp_network_id, if_nhrp_network_id_cmd,
819dc8bb 304 AFI_CMD " nhrp network-id (1-4294967295)",
2fb975da
TT
305 AFI_STR
306 NHRP_STR
307 "Enable NHRP and specify network-id\n"
308 "System local ID to specify interface group\n")
309{
819dc8bb 310 VTY_DECLVAR_CONTEXT(interface, ifp);
2fb975da
TT
311 struct nhrp_interface *nifp = ifp->info;
312 afi_t afi = cmd_to_afi(argv[0]);
313
819dc8bb 314 VTY_GET_INTEGER_RANGE("network-id", nifp->afi[afi].network_id, argv[3]->arg, 1, 4294967295);
2fb975da
TT
315 nhrp_interface_update(ifp);
316
317 return CMD_SUCCESS;
318}
319
320DEFUN(if_no_nhrp_network_id, if_no_nhrp_network_id_cmd,
819dc8bb 321 "no " AFI_CMD " nhrp network-id [(1-4294967295)]",
2fb975da
TT
322 NO_STR
323 AFI_STR
324 NHRP_STR
325 "Enable NHRP and specify network-id\n"
326 "System local ID to specify interface group\n")
327{
819dc8bb 328 VTY_DECLVAR_CONTEXT(interface, ifp);
2fb975da 329 struct nhrp_interface *nifp = ifp->info;
819dc8bb 330 afi_t afi = cmd_to_afi(argv[1]);
2fb975da
TT
331
332 nifp->afi[afi].network_id = 0;
333 nhrp_interface_update(ifp);
334
335 return CMD_SUCCESS;
336}
337
338DEFUN(if_nhrp_flags, if_nhrp_flags_cmd,
819dc8bb 339 AFI_CMD " nhrp <shortcut|redirect>",
2fb975da
TT
340 AFI_STR
341 NHRP_STR
342 "Allow shortcut establishment\n"
343 "Send redirect notifications\n")
344{
819dc8bb 345 VTY_DECLVAR_CONTEXT(interface, ifp);
2fb975da
TT
346 struct nhrp_interface *nifp = ifp->info;
347 afi_t afi = cmd_to_afi(argv[0]);
348
819dc8bb 349 return toggle_flag(vty, interface_flags_desc, argv[2]->text, 1, &nifp->afi[afi].flags);
2fb975da
TT
350}
351
352DEFUN(if_no_nhrp_flags, if_no_nhrp_flags_cmd,
819dc8bb 353 "no " AFI_CMD " nhrp <shortcut|redirect>",
2fb975da
TT
354 NO_STR
355 AFI_STR
356 NHRP_STR
357 "Allow shortcut establishment\n"
358 "Send redirect notifications\n")
359{
819dc8bb 360 VTY_DECLVAR_CONTEXT(interface, ifp);
2fb975da 361 struct nhrp_interface *nifp = ifp->info;
819dc8bb 362 afi_t afi = cmd_to_afi(argv[1]);
2fb975da 363
819dc8bb 364 return toggle_flag(vty, interface_flags_desc, argv[3]->text, 0, &nifp->afi[afi].flags);
2fb975da
TT
365}
366
367DEFUN(if_nhrp_reg_flags, if_nhrp_reg_flags_cmd,
819dc8bb 368 AFI_CMD " nhrp registration no-unique",
2fb975da
TT
369 AFI_STR
370 NHRP_STR
371 "Registration configuration\n"
372 "Don't set unique flag\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 char name[256];
819dc8bb 378 snprintf(name, sizeof(name), "registration %s", argv[3]->text);
2fb975da
TT
379 return toggle_flag(vty, interface_flags_desc, name, 1, &nifp->afi[afi].flags);
380}
381
382DEFUN(if_no_nhrp_reg_flags, if_no_nhrp_reg_flags_cmd,
819dc8bb 383 "no " AFI_CMD " nhrp registration no-unique",
2fb975da
TT
384 NO_STR
385 AFI_STR
386 NHRP_STR
387 "Registration configuration\n"
388 "Don't set unique flag\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 char name[256];
819dc8bb 394 snprintf(name, sizeof(name), "registration %s", argv[4]->text);
2fb975da
TT
395 return toggle_flag(vty, interface_flags_desc, name, 0, &nifp->afi[afi].flags);
396}
397
398DEFUN(if_nhrp_holdtime, if_nhrp_holdtime_cmd,
819dc8bb 399 AFI_CMD " nhrp holdtime (1-65000)",
2fb975da
TT
400 AFI_STR
401 NHRP_STR
402 "Specify NBMA address validity time\n"
403 "Time in seconds that NBMA addresses are advertised valid\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
819dc8bb 409 VTY_GET_INTEGER_RANGE("holdtime", nifp->afi[afi].holdtime, argv[3]->arg, 1, 65000);
2fb975da
TT
410 nhrp_interface_update(ifp);
411
412 return CMD_SUCCESS;
413}
414
415DEFUN(if_no_nhrp_holdtime, if_no_nhrp_holdtime_cmd,
819dc8bb 416 "no " AFI_CMD " nhrp holdtime [(1-65000)]",
2fb975da
TT
417 NO_STR
418 AFI_STR
419 NHRP_STR
420 "Specify NBMA address validity time\n"
421 "Time in seconds that NBMA addresses are advertised valid\n")
422{
819dc8bb 423 VTY_DECLVAR_CONTEXT(interface, ifp);
2fb975da 424 struct nhrp_interface *nifp = ifp->info;
819dc8bb 425 afi_t afi = cmd_to_afi(argv[1]);
2fb975da
TT
426
427 nifp->afi[afi].holdtime = NHRPD_DEFAULT_HOLDTIME;
428 nhrp_interface_update(ifp);
429
430 return CMD_SUCCESS;
431}
432
433DEFUN(if_nhrp_mtu, if_nhrp_mtu_cmd,
819dc8bb 434 "ip nhrp mtu <(576-1500)|opennhrp>",
2fb975da
TT
435 IP_STR
436 NHRP_STR
437 "Configure NHRP advertised MTU\n"
438 "MTU value\n"
439 "Advertise bound interface MTU similar to OpenNHRP")
440{
819dc8bb 441 VTY_DECLVAR_CONTEXT(interface, ifp);
2fb975da
TT
442 struct nhrp_interface *nifp = ifp->info;
443
819dc8bb 444 if (argv[3]->arg[0] == 'o') {
2fb975da
TT
445 nifp->afi[AFI_IP].configured_mtu = -1;
446 } else {
819dc8bb 447 VTY_GET_INTEGER_RANGE("mtu", nifp->afi[AFI_IP].configured_mtu, argv[3]->arg, 576, 1500);
2fb975da
TT
448 }
449 nhrp_interface_update_mtu(ifp, AFI_IP);
450
451 return CMD_SUCCESS;
452}
453
454DEFUN(if_no_nhrp_mtu, if_no_nhrp_mtu_cmd,
819dc8bb 455 "no ip nhrp mtu [(576-1500)|opennhrp]",
2fb975da
TT
456 NO_STR
457 IP_STR
458 NHRP_STR
459 "Configure NHRP advertised MTU\n"
460 "MTU value\n"
461 "Advertise bound interface MTU similar to OpenNHRP")
462{
819dc8bb 463 VTY_DECLVAR_CONTEXT(interface, ifp);
2fb975da
TT
464 struct nhrp_interface *nifp = ifp->info;
465
466 nifp->afi[AFI_IP].configured_mtu = 0;
467 nhrp_interface_update_mtu(ifp, AFI_IP);
468 return CMD_SUCCESS;
469}
470
471DEFUN(if_nhrp_map, if_nhrp_map_cmd,
819dc8bb 472 AFI_CMD " nhrp map <A.B.C.D|X:X::X:X> <A.B.C.D|local>",
2fb975da
TT
473 AFI_STR
474 NHRP_STR
475 "Nexthop Server configuration\n"
476 "IPv4 protocol address\n"
477 "IPv6 protocol address\n"
478 "IPv4 NBMA address\n"
479 "Handle protocol address locally\n")
480{
819dc8bb 481 VTY_DECLVAR_CONTEXT(interface, ifp);
2fb975da
TT
482 afi_t afi = cmd_to_afi(argv[0]);
483 union sockunion proto_addr, nbma_addr;
484 struct nhrp_cache *c;
485
819dc8bb 486 if (str2sockunion(argv[3]->arg, &proto_addr) < 0 ||
2fb975da
TT
487 afi2family(afi) != sockunion_family(&proto_addr))
488 return nhrp_vty_return(vty, NHRP_ERR_PROTOCOL_ADDRESS_MISMATCH);
489
490 c = nhrp_cache_get(ifp, &proto_addr, 1);
491 if (!c)
492 return nhrp_vty_return(vty, NHRP_ERR_FAIL);
493
494 c->map = 1;
819dc8bb 495 if (strcmp(argv[4]->text, "local") == 0) {
2fb975da
TT
496 nhrp_cache_update_binding(c, NHRP_CACHE_LOCAL, 0, NULL, 0, NULL);
497 } else{
819dc8bb 498 if (str2sockunion(argv[4]->arg, &nbma_addr) < 0)
2fb975da
TT
499 return nhrp_vty_return(vty, NHRP_ERR_FAIL);
500 nhrp_cache_update_binding(c, NHRP_CACHE_STATIC, 0,
501 nhrp_peer_get(ifp, &nbma_addr), 0, NULL);
502 }
503
504 return CMD_SUCCESS;
505}
506
2d4eab22 507DEFUN(if_no_nhrp_map, if_no_nhrp_map_cmd,
c1c17a0f 508 "no " AFI_CMD " nhrp map <A.B.C.D|X:X::X:X>",
2d4eab22
TT
509 NO_STR
510 AFI_STR
511 NHRP_STR
512 "Nexthop Server configuration\n"
513 "IPv4 protocol address\n"
514 "IPv6 protocol address\n")
515{
516 VTY_DECLVAR_CONTEXT(interface,ifp);
517 afi_t afi = cmd_to_afi(argv[1]);
518 union sockunion proto_addr;
519 struct nhrp_cache *c;
520
521 if (str2sockunion(argv[4]->arg, &proto_addr) < 0 ||
522 afi2family(afi) != sockunion_family(&proto_addr))
523 return nhrp_vty_return(vty, NHRP_ERR_PROTOCOL_ADDRESS_MISMATCH);
524
525 c = nhrp_cache_get(ifp, &proto_addr, 0);
526 if (!c || !c->map)
527 return nhrp_vty_return(vty, NHRP_ERR_ENTRY_NOT_FOUND);
528
529 nhrp_cache_update_binding(c, c->cur.type, -1, NULL, 0, NULL);
530 return CMD_SUCCESS;
531}
532
2fb975da 533DEFUN(if_nhrp_nhs, if_nhrp_nhs_cmd,
819dc8bb 534 AFI_CMD " nhrp nhs <A.B.C.D|X:X::X:X|dynamic> nbma <A.B.C.D|FQDN>",
2fb975da
TT
535 AFI_STR
536 NHRP_STR
537 "Nexthop Server configuration\n"
538 "IPv4 protocol address\n"
539 "IPv6 protocol address\n"
540 "Automatic detection of protocol address\n"
819dc8bb 541 "NBMA address\n"
2fb975da
TT
542 "IPv4 NBMA address\n"
543 "Fully qualified domain name for NBMA address(es)\n")
544{
819dc8bb 545 VTY_DECLVAR_CONTEXT(interface, ifp);
2fb975da
TT
546 afi_t afi = cmd_to_afi(argv[0]);
547 union sockunion proto_addr;
548 int ret;
549
819dc8bb 550 if (str2sockunion(argv[3]->arg, &proto_addr) < 0)
2fb975da
TT
551 sockunion_family(&proto_addr) = AF_UNSPEC;
552
819dc8bb 553 ret = nhrp_nhs_add(ifp, afi, &proto_addr, argv[5]->arg);
2fb975da
TT
554 return nhrp_vty_return(vty, ret);
555}
556
557DEFUN(if_no_nhrp_nhs, if_no_nhrp_nhs_cmd,
819dc8bb 558 "no " AFI_CMD " nhrp nhs <A.B.C.D|X:X::X:X|dynamic> nbma <A.B.C.D|FQDN>",
2fb975da
TT
559 NO_STR
560 AFI_STR
561 NHRP_STR
562 "Nexthop Server configuration\n"
563 "IPv4 protocol address\n"
564 "IPv6 protocol address\n"
565 "Automatic detection of protocol address\n"
819dc8bb 566 "NBMA address\n"
2fb975da
TT
567 "IPv4 NBMA address\n"
568 "Fully qualified domain name for NBMA address(es)\n")
569{
819dc8bb
DL
570 VTY_DECLVAR_CONTEXT(interface, ifp);
571 afi_t afi = cmd_to_afi(argv[1]);
2fb975da
TT
572 union sockunion proto_addr;
573 int ret;
574
819dc8bb 575 if (str2sockunion(argv[4]->arg, &proto_addr) < 0)
2fb975da
TT
576 sockunion_family(&proto_addr) = AF_UNSPEC;
577
819dc8bb 578 ret = nhrp_nhs_del(ifp, afi, &proto_addr, argv[6]->arg);
2fb975da
TT
579 return nhrp_vty_return(vty, ret);
580}
581
582struct info_ctx {
583 struct vty *vty;
584 afi_t afi;
585 int count;
586};
587
588static void show_ip_nhrp_cache(struct nhrp_cache *c, void *pctx)
589{
590 struct info_ctx *ctx = pctx;
591 struct vty *vty = ctx->vty;
592 char buf[2][SU_ADDRSTRLEN];
593
594 if (ctx->afi != family2afi(sockunion_family(&c->remote_addr)))
595 return;
596
597 if (!ctx->count) {
598 vty_out(vty, "%-8s %-8s %-24s %-24s %-6s %s%s",
599 "Iface",
600 "Type",
601 "Protocol",
602 "NBMA",
603 "Flags",
604 "Identity",
605 VTY_NEWLINE);
606 }
607 ctx->count++;
608
609 vty_out(ctx->vty, "%-8s %-8s %-24s %-24s %c%c%c %s%s",
610 c->ifp->name,
611 nhrp_cache_type_str[c->cur.type],
612 sockunion2str(&c->remote_addr, buf[0], sizeof buf[0]),
613 c->cur.peer ? sockunion2str(&c->cur.peer->vc->remote.nbma, buf[1], sizeof buf[1]) : "-",
614 c->used ? 'U' : ' ',
615 c->t_timeout ? 'T' : ' ',
616 c->t_auth ? 'A' : ' ',
617 c->cur.peer ? c->cur.peer->vc->remote.id : "-",
618 VTY_NEWLINE);
619}
620
0ca036b4
TT
621static void show_ip_nhrp_nhs(struct nhrp_nhs *n, struct nhrp_registration *reg, void *pctx)
622{
623 struct info_ctx *ctx = pctx;
624 struct vty *vty = ctx->vty;
625 char buf[2][SU_ADDRSTRLEN];
626
627 if (!ctx->count) {
628 vty_out(vty, "%-8s %-24s %-16s %-16s%s",
629 "Iface",
630 "FQDN",
631 "NBMA",
632 "Protocol",
633 VTY_NEWLINE);
634 }
635 ctx->count++;
636
637 vty_out(vty, "%-8s %-24s %-16s %-16s%s",
638 n->ifp->name,
639 n->nbma_fqdn,
640 (reg && reg->peer) ? sockunion2str(&reg->peer->vc->remote.nbma, buf[0], sizeof buf[0]) : "-",
641 sockunion2str(reg ? &reg->proto_addr : &n->proto_addr, buf[1], sizeof buf[1]),
642 VTY_NEWLINE);
643}
644
645static void show_ip_nhrp_shortcut(struct nhrp_shortcut *s, void *pctx)
646{
647 struct info_ctx *ctx = pctx;
648 struct nhrp_cache *c;
649 struct vty *vty = ctx->vty;
650 char buf1[PREFIX_STRLEN], buf2[SU_ADDRSTRLEN];
651
652 if (!ctx->count) {
653 vty_out(vty, "%-8s %-24s %-24s %s%s",
654 "Type",
655 "Prefix",
656 "Via",
657 "Identity",
658 VTY_NEWLINE);
659 }
660 ctx->count++;
661
662 c = s->cache;
663 vty_out(ctx->vty, "%-8s %-24s %-24s %s%s",
664 nhrp_cache_type_str[s->type],
665 prefix2str(s->p, buf1, sizeof buf1),
666 c ? sockunion2str(&c->remote_addr, buf2, sizeof buf2) : "",
667 (c && c->cur.peer) ? c->cur.peer->vc->remote.id : "",
668 VTY_NEWLINE);
669}
670
2fb975da
TT
671static void show_ip_opennhrp_cache(struct nhrp_cache *c, void *pctx)
672{
673 struct info_ctx *ctx = pctx;
674 struct vty *vty = ctx->vty;
675 char buf[SU_ADDRSTRLEN];
676
677 if (ctx->afi != family2afi(sockunion_family(&c->remote_addr)))
678 return;
679
680 vty_out(ctx->vty,
681 "Type: %s%s"
682 "Flags:%s%s%s"
683 "Protocol-Address: %s/%zu%s",
684 nhrp_cache_type_str[c->cur.type],
685 VTY_NEWLINE,
686 (c->cur.peer && c->cur.peer->online) ? " up": "",
687 c->used ? " used": "",
688 VTY_NEWLINE,
689 sockunion2str(&c->remote_addr, buf, sizeof buf),
690 8 * family2addrsize(sockunion_family(&c->remote_addr)),
691 VTY_NEWLINE);
692
693 if (c->cur.peer) {
694 vty_out(ctx->vty,
695 "NBMA-Address: %s%s",
696 sockunion2str(&c->cur.peer->vc->remote.nbma, buf, sizeof buf),
697 VTY_NEWLINE);
698 }
699
700 if (sockunion_family(&c->cur.remote_nbma_natoa) != AF_UNSPEC) {
701 vty_out(ctx->vty,
702 "NBMA-NAT-OA-Address: %s%s",
703 sockunion2str(&c->cur.remote_nbma_natoa, buf, sizeof buf),
704 VTY_NEWLINE);
705 }
706
707 vty_out(ctx->vty, "%s", VTY_NEWLINE);
708}
709
2fb975da 710DEFUN(show_ip_nhrp, show_ip_nhrp_cmd,
0ca036b4 711 "show " AFI_CMD " nhrp [cache|nhs|shortcut|opennhrp]",
2fb975da
TT
712 SHOW_STR
713 AFI_STR
714 "NHRP information\n"
715 "Forwarding cache information\n"
0ca036b4 716 "Next hop server information\n"
2fb975da
TT
717 "Shortcut information\n"
718 "opennhrpctl style cache dump\n")
719{
720 struct listnode *node;
721 struct interface *ifp;
722 struct info_ctx ctx = {
723 .vty = vty,
819dc8bb 724 .afi = cmd_to_afi(argv[1]),
2fb975da
TT
725 };
726
819dc8bb
DL
727 if (argc <= 3 || argv[3]->text[0] == 'c') {
728 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp))
2fb975da 729 nhrp_cache_foreach(ifp, show_ip_nhrp_cache, &ctx);
0ca036b4
TT
730 } else if (argv[3]->text[0] == 'n') {
731 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp))
732 nhrp_nhs_foreach(ifp, ctx.afi, show_ip_nhrp_nhs, &ctx);
733 } else if (argv[3]->text[0] == 's') {
734 nhrp_shortcut_foreach(ctx.afi, show_ip_nhrp_shortcut, &ctx);
735 } else {
2fb975da
TT
736 vty_out(vty, "Status: ok%s%s", VTY_NEWLINE, VTY_NEWLINE);
737 ctx.count++;
819dc8bb 738 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp))
2fb975da 739 nhrp_cache_foreach(ifp, show_ip_opennhrp_cache, &ctx);
2fb975da
TT
740 }
741
742 if (!ctx.count) {
743 vty_out(vty, "%% No entries%s", VTY_NEWLINE);
744 return CMD_WARNING;
745 }
746
747 return CMD_SUCCESS;
748}
749
750static void show_dmvpn_entry(struct nhrp_vc *vc, void *ctx)
751{
752 struct vty *vty = ctx;
753 char buf[2][SU_ADDRSTRLEN];
754
755 vty_out(vty, "%-24s %-24s %c %-4d %-24s%s",
756 sockunion2str(&vc->local.nbma, buf[0], sizeof buf[0]),
757 sockunion2str(&vc->remote.nbma, buf[1], sizeof buf[1]),
758 notifier_active(&vc->notifier_list) ? 'n' : ' ',
759 vc->ipsec,
760 vc->remote.id,
761 VTY_NEWLINE);
762}
763
764DEFUN(show_dmvpn, show_dmvpn_cmd,
765 "show dmvpn",
766 SHOW_STR
767 "DMVPN information\n")
768{
769 vty_out(vty, "%-24s %-24s %-6s %-4s %-24s%s",
770 "Src",
771 "Dst",
772 "Flags",
773 "SAs",
774 "Identity",
775 VTY_NEWLINE);
776
777 nhrp_vc_foreach(show_dmvpn_entry, vty);
778
779 return CMD_SUCCESS;
780}
781
782static void clear_nhrp_cache(struct nhrp_cache *c, void *data)
783{
784 struct info_ctx *ctx = data;
785 if (c->cur.type <= NHRP_CACHE_CACHED) {
786 nhrp_cache_update_binding(c, c->cur.type, -1, NULL, 0, NULL);
787 ctx->count++;
788 }
789}
790
791static void clear_nhrp_shortcut(struct nhrp_shortcut *s, void *data)
792{
793 struct info_ctx *ctx = data;
794 nhrp_shortcut_purge(s, 1);
795 ctx->count++;
796}
797
798DEFUN(clear_nhrp, clear_nhrp_cmd,
819dc8bb 799 "clear " AFI_CMD " nhrp <cache|shortcut>",
2fb975da
TT
800 CLEAR_STR
801 AFI_STR
802 NHRP_STR
803 "Dynamic cache entries\n"
804 "Shortcut entries\n")
805{
806 struct listnode *node;
807 struct interface *ifp;
808 struct info_ctx ctx = {
809 .vty = vty,
819dc8bb 810 .afi = cmd_to_afi(argv[1]),
2fb975da
TT
811 .count = 0,
812 };
813
819dc8bb
DL
814 if (argc <= 3 || argv[3]->text[0] == 'c') {
815 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp))
2fb975da
TT
816 nhrp_cache_foreach(ifp, clear_nhrp_cache, &ctx);
817 } else {
818 nhrp_shortcut_foreach(ctx.afi, clear_nhrp_shortcut, &ctx);
819 }
820
821 if (!ctx.count) {
822 vty_out(vty, "%% No entries%s", VTY_NEWLINE);
823 return CMD_WARNING;
824 }
825
826 vty_out(vty, "%% %d entries cleared%s", ctx.count, VTY_NEWLINE);
827 return CMD_SUCCESS;
828}
829
830struct write_map_ctx {
831 struct vty *vty;
832 int family;
833 const char *aficmd;
834};
835
836static void interface_config_write_nhrp_map(struct nhrp_cache *c, void *data)
837{
838 struct write_map_ctx *ctx = data;
839 struct vty *vty = ctx->vty;
840 char buf[2][SU_ADDRSTRLEN];
841
842 if (!c->map) return;
843 if (sockunion_family(&c->remote_addr) != ctx->family) return;
844
845 vty_out(vty, " %s nhrp map %s %s%s",
846 ctx->aficmd,
847 sockunion2str(&c->remote_addr, buf[0], sizeof buf[0]),
848 c->cur.type == NHRP_CACHE_LOCAL ? "local" :
849 sockunion2str(&c->cur.peer->vc->remote.nbma, buf[1], sizeof buf[1]),
850 VTY_NEWLINE);
851}
852
853static int interface_config_write(struct vty *vty)
854{
855 struct write_map_ctx mapctx;
856 struct listnode *node;
857 struct interface *ifp;
858 struct nhrp_interface *nifp;
859 struct nhrp_nhs *nhs;
860 const char *aficmd;
861 afi_t afi;
862 char buf[SU_ADDRSTRLEN];
863 int i;
864
819dc8bb 865 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) {
2fb975da
TT
866 vty_out(vty, "interface %s%s", ifp->name, VTY_NEWLINE);
867 if (ifp->desc)
868 vty_out(vty, " description %s%s", ifp->desc, VTY_NEWLINE);
869
870 nifp = ifp->info;
871 if (nifp->ipsec_profile) {
872 vty_out(vty, " tunnel protection vici profile %s",
873 nifp->ipsec_profile);
874 if (nifp->ipsec_fallback_profile)
875 vty_out(vty, " fallback-profile %s",
876 nifp->ipsec_fallback_profile);
877 vty_out(vty, "%s", VTY_NEWLINE);
878 }
879 if (nifp->source)
880 vty_out(vty, " tunnel source %s%s",
881 nifp->source, VTY_NEWLINE);
882
883 for (afi = 0; afi < AFI_MAX; afi++) {
884 struct nhrp_afi_data *ad = &nifp->afi[afi];
885
886 aficmd = afi_to_cmd(afi);
887
888 if (ad->network_id)
889 vty_out(vty, " %s nhrp network-id %u%s",
890 aficmd, ad->network_id,
891 VTY_NEWLINE);
892
893 if (ad->holdtime != NHRPD_DEFAULT_HOLDTIME)
894 vty_out(vty, " %s nhrp holdtime %u%s",
895 aficmd, ad->holdtime,
896 VTY_NEWLINE);
897
898 if (ad->configured_mtu < 0)
899 vty_out(vty, " %s nhrp mtu opennhrp%s",
900 aficmd, VTY_NEWLINE);
901 else if (ad->configured_mtu)
902 vty_out(vty, " %s nhrp mtu %u%s",
903 aficmd, ad->configured_mtu,
904 VTY_NEWLINE);
905
906 for (i = 0; interface_flags_desc[i].str != NULL; i++) {
907 if (!(ad->flags & interface_flags_desc[i].key))
908 continue;
909 vty_out(vty, " %s nhrp %s%s",
910 aficmd, interface_flags_desc[i].str, VTY_NEWLINE);
911 }
912
913 mapctx = (struct write_map_ctx) {
914 .vty = vty,
915 .family = afi2family(afi),
916 .aficmd = aficmd,
917 };
918 nhrp_cache_foreach(ifp, interface_config_write_nhrp_map, &mapctx);
919
920 list_for_each_entry(nhs, &ad->nhslist_head, nhslist_entry) {
921 vty_out(vty, " %s nhrp nhs %s nbma %s%s",
922 aficmd,
923 sockunion_family(&nhs->proto_addr) == AF_UNSPEC ? "dynamic" : sockunion2str(&nhs->proto_addr, buf, sizeof buf),
924 nhs->nbma_fqdn,
925 VTY_NEWLINE);
926 }
927 }
928
929 vty_out (vty, "!%s", VTY_NEWLINE);
930 }
931
932 return 0;
933}
934
935void nhrp_config_init(void)
936{
937 install_node(&zebra_node, nhrp_config_write);
938 install_default(ZEBRA_NODE);
939
940 /* global commands */
941 install_element(VIEW_NODE, &show_debugging_nhrp_cmd);
942 install_element(VIEW_NODE, &show_ip_nhrp_cmd);
943 install_element(VIEW_NODE, &show_dmvpn_cmd);
2fb975da
TT
944 install_element(ENABLE_NODE, &clear_nhrp_cmd);
945
946 install_element(ENABLE_NODE, &debug_nhrp_cmd);
947 install_element(ENABLE_NODE, &no_debug_nhrp_cmd);
948
949 install_element(CONFIG_NODE, &debug_nhrp_cmd);
950 install_element(CONFIG_NODE, &no_debug_nhrp_cmd);
951
952 install_element(CONFIG_NODE, &nhrp_event_socket_cmd);
953 install_element(CONFIG_NODE, &no_nhrp_event_socket_cmd);
954 install_element(CONFIG_NODE, &nhrp_nflog_group_cmd);
955 install_element(CONFIG_NODE, &no_nhrp_nflog_group_cmd);
956
957 /* interface specific commands */
958 install_node(&nhrp_interface_node, interface_config_write);
2fb975da 959
819dc8bb 960 if_cmd_init();
2fb975da
TT
961 install_element(INTERFACE_NODE, &tunnel_protection_cmd);
962 install_element(INTERFACE_NODE, &no_tunnel_protection_cmd);
963 install_element(INTERFACE_NODE, &tunnel_source_cmd);
964 install_element(INTERFACE_NODE, &no_tunnel_source_cmd);
965 install_element(INTERFACE_NODE, &if_nhrp_network_id_cmd);
966 install_element(INTERFACE_NODE, &if_no_nhrp_network_id_cmd);
967 install_element(INTERFACE_NODE, &if_nhrp_holdtime_cmd);
968 install_element(INTERFACE_NODE, &if_no_nhrp_holdtime_cmd);
969 install_element(INTERFACE_NODE, &if_nhrp_mtu_cmd);
970 install_element(INTERFACE_NODE, &if_no_nhrp_mtu_cmd);
971 install_element(INTERFACE_NODE, &if_nhrp_flags_cmd);
972 install_element(INTERFACE_NODE, &if_no_nhrp_flags_cmd);
973 install_element(INTERFACE_NODE, &if_nhrp_reg_flags_cmd);
974 install_element(INTERFACE_NODE, &if_no_nhrp_reg_flags_cmd);
975 install_element(INTERFACE_NODE, &if_nhrp_map_cmd);
2d4eab22 976 install_element(INTERFACE_NODE, &if_no_nhrp_map_cmd);
2fb975da
TT
977 install_element(INTERFACE_NODE, &if_nhrp_nhs_cmd);
978 install_element(INTERFACE_NODE, &if_no_nhrp_nhs_cmd);
979}