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