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