source: src/router/quagga/nhrpd/nhrp_vty.c @ 31640

Last change on this file since 31640 was 31640, checked in by brainslayer, 4 months ago

update quagga

File size: 23.3 KB
Line 
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
30#define NHRP_DEBUG_FLAGS_CMD "(all|common|event|interface|kernel|route|vici)"
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{
141        return toggle_flag(vty, debug_flags_desc, argv[0], 1, &debug_flags);
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{
151        return toggle_flag(vty, debug_flags_desc, argv[0], 0, &debug_flags);
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"
189#define AFI_CMD         "(ip|ipv6)"
190#define AFI_STR         IP_STR IPV6_STR
191#define NHRP_STR        "Next Hop Resolution Protocol functions\n"
192
193static afi_t cmd_to_afi(const char *cmd)
194{
195        return strncmp(cmd, "ipv6", 4) == 0 ? AFI_IP6 : AFI_IP;
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{
211        evmgr_set_socket(argv[0]);
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,
228        "nhrp nflog-group <1-65535>",
229        NHRP_STR
230        "Specify NFLOG group number\n"
231        "NFLOG group number\n")
232{
233        uint32_t nfgroup;
234
235        VTY_GET_INTEGER_RANGE("nflog-group", nfgroup, argv[0], 1, 65535);
236        netlink_set_nflog_group(nfgroup);
237
238        return CMD_SUCCESS;
239}
240
241DEFUN(no_nhrp_nflog_group, no_nhrp_nflog_group_cmd,
242        "no nhrp nflog-group [<1-65535>]",
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,
253        "tunnel protection vici profile PROFILE {fallback-profile FALLBACK}",
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{
262        struct interface *ifp = vty->index;
263
264        nhrp_interface_set_protection(ifp, argv[0], argv[1]);
265        return CMD_SUCCESS;
266}
267
268DEFUN(no_tunnel_protection, no_tunnel_protection_cmd,
269        "no tunnel protection",
270        NO_STR
271        "NHRP/GRE integration\n"
272        "IPsec protection\n")
273{
274        struct interface *ifp = vty->index;
275
276        nhrp_interface_set_protection(ifp, NULL, NULL);
277        return CMD_SUCCESS;
278}
279
280DEFUN(tunnel_source, tunnel_source_cmd,
281        "tunnel source INTERFACE",
282        "NHRP/GRE integration\n"
283        "Tunnel device binding tracking\n"
284        "Interface name\n")
285{
286        struct interface *ifp = vty->index;
287        nhrp_interface_set_source(ifp, argv[0]);
288        return CMD_SUCCESS;
289}
290
291DEFUN(no_tunnel_source, no_tunnel_source_cmd,
292        "no tunnel source",
293        "NHRP/GRE integration\n"
294        "Tunnel device binding tracking\n"
295        "Interface name\n")
296{
297        struct interface *ifp = vty->index;
298        nhrp_interface_set_source(ifp, NULL);
299        return CMD_SUCCESS;
300}
301
302DEFUN(if_nhrp_network_id, if_nhrp_network_id_cmd,
303        AFI_CMD " nhrp network-id <1-4294967295>",
304        AFI_STR
305        NHRP_STR
306        "Enable NHRP and specify network-id\n"
307        "System local ID to specify interface group\n")
308{
309        struct interface *ifp = vty->index;
310        struct nhrp_interface *nifp = ifp->info;
311        afi_t afi = cmd_to_afi(argv[0]);
312
313        VTY_GET_INTEGER_RANGE("network-id", nifp->afi[afi].network_id, argv[1], 1, 4294967295);
314        nhrp_interface_update(ifp);
315
316        return CMD_SUCCESS;
317}
318
319DEFUN(if_no_nhrp_network_id, if_no_nhrp_network_id_cmd,
320        "no " AFI_CMD " nhrp network-id [<1-4294967295>]",
321        NO_STR
322        AFI_STR
323        NHRP_STR
324        "Enable NHRP and specify network-id\n"
325        "System local ID to specify interface group\n")
326{
327        struct interface *ifp = vty->index;
328        struct nhrp_interface *nifp = ifp->info;
329        afi_t afi = cmd_to_afi(argv[0]);
330
331        nifp->afi[afi].network_id = 0;
332        nhrp_interface_update(ifp);
333
334        return CMD_SUCCESS;
335}
336
337DEFUN(if_nhrp_flags, if_nhrp_flags_cmd,
338        AFI_CMD " nhrp (shortcut|redirect)",
339        AFI_STR
340        NHRP_STR
341        "Allow shortcut establishment\n"
342        "Send redirect notifications\n")
343{
344        struct interface *ifp = vty->index;
345        struct nhrp_interface *nifp = ifp->info;
346        afi_t afi = cmd_to_afi(argv[0]);
347
348        return toggle_flag(vty, interface_flags_desc, argv[1], 1, &nifp->afi[afi].flags);
349}
350
351DEFUN(if_no_nhrp_flags, if_no_nhrp_flags_cmd,
352        "no " AFI_CMD " nhrp (shortcut|redirect)",
353        NO_STR
354        AFI_STR
355        NHRP_STR
356        "Allow shortcut establishment\n"
357        "Send redirect notifications\n")
358{
359        struct interface *ifp = vty->index;
360        struct nhrp_interface *nifp = ifp->info;
361        afi_t afi = cmd_to_afi(argv[0]);
362
363        return toggle_flag(vty, interface_flags_desc, argv[1], 0, &nifp->afi[afi].flags);
364}
365
366DEFUN(if_nhrp_reg_flags, if_nhrp_reg_flags_cmd,
367        AFI_CMD " nhrp registration (no-unique)",
368        AFI_STR
369        NHRP_STR
370        "Registration configuration\n"
371        "Don't set unique flag\n")
372{
373        struct interface *ifp = vty->index;
374        struct nhrp_interface *nifp = ifp->info;
375        afi_t afi = cmd_to_afi(argv[0]);
376        char name[256];
377        snprintf(name, sizeof(name), "registration %s", argv[1]);
378        return toggle_flag(vty, interface_flags_desc, name, 1, &nifp->afi[afi].flags);
379}
380
381DEFUN(if_no_nhrp_reg_flags, if_no_nhrp_reg_flags_cmd,
382        "no " AFI_CMD " nhrp registration (no-unique)",
383        NO_STR
384        AFI_STR
385        NHRP_STR
386        "Registration configuration\n"
387        "Don't set unique flag\n")
388{
389        struct interface *ifp = vty->index;
390        struct nhrp_interface *nifp = ifp->info;
391        afi_t afi = cmd_to_afi(argv[0]);
392        char name[256];
393        snprintf(name, sizeof(name), "registration %s", argv[1]);
394        return toggle_flag(vty, interface_flags_desc, name, 0, &nifp->afi[afi].flags);
395}
396
397DEFUN(if_nhrp_holdtime, if_nhrp_holdtime_cmd,
398        AFI_CMD " nhrp holdtime <1-65000>",
399        AFI_STR
400        NHRP_STR
401        "Specify NBMA address validity time\n"
402        "Time in seconds that NBMA addresses are advertised valid\n")
403{
404        struct interface *ifp = vty->index;
405        struct nhrp_interface *nifp = ifp->info;
406        afi_t afi = cmd_to_afi(argv[0]);
407
408        VTY_GET_INTEGER_RANGE("holdtime", nifp->afi[afi].holdtime, argv[1], 1, 65000);
409        nhrp_interface_update(ifp);
410
411        return CMD_SUCCESS;
412}
413
414DEFUN(if_no_nhrp_holdtime, if_no_nhrp_holdtime_cmd,
415        "no " AFI_CMD " nhrp holdtime [1-65000]",
416        NO_STR
417        AFI_STR
418        NHRP_STR
419        "Specify NBMA address validity time\n"
420        "Time in seconds that NBMA addresses are advertised valid\n")
421{
422        struct interface *ifp = vty->index;
423        struct nhrp_interface *nifp = ifp->info;
424        afi_t afi = cmd_to_afi(argv[0]);
425
426        nifp->afi[afi].holdtime = NHRPD_DEFAULT_HOLDTIME;
427        nhrp_interface_update(ifp);
428
429        return CMD_SUCCESS;
430}
431
432DEFUN(if_nhrp_mtu, if_nhrp_mtu_cmd,
433        "ip nhrp mtu (<576-1500>|opennhrp)",
434        IP_STR
435        NHRP_STR
436        "Configure NHRP advertised MTU\n"
437        "MTU value\n"
438        "Advertise bound interface MTU similar to OpenNHRP")
439{
440        struct interface *ifp = vty->index;
441        struct nhrp_interface *nifp = ifp->info;
442
443        if (argv[0][0] == 'o') {
444                nifp->afi[AFI_IP].configured_mtu = -1;
445        } else {
446                VTY_GET_INTEGER_RANGE("mtu", nifp->afi[AFI_IP].configured_mtu, argv[0], 576, 1500);
447        }
448        nhrp_interface_update_mtu(ifp, AFI_IP);
449
450        return CMD_SUCCESS;
451}
452
453DEFUN(if_no_nhrp_mtu, if_no_nhrp_mtu_cmd,
454        "no ip nhrp mtu [(<576-1500>|opennhrp)]",
455        NO_STR
456        IP_STR
457        NHRP_STR
458        "Configure NHRP advertised MTU\n"
459        "MTU value\n"
460        "Advertise bound interface MTU similar to OpenNHRP")
461{
462        struct interface *ifp = vty->index;
463        struct nhrp_interface *nifp = ifp->info;
464
465        nifp->afi[AFI_IP].configured_mtu = 0;
466        nhrp_interface_update_mtu(ifp, AFI_IP);
467        return CMD_SUCCESS;
468}
469
470DEFUN(if_nhrp_map, if_nhrp_map_cmd,
471        AFI_CMD " nhrp map (A.B.C.D|X:X::X:X) (A.B.C.D|local)",
472        AFI_STR
473        NHRP_STR
474        "Nexthop Server configuration\n"
475        "IPv4 protocol address\n"
476        "IPv6 protocol address\n"
477        "IPv4 NBMA address\n"
478        "Handle protocol address locally\n")
479{
480        struct interface *ifp = vty->index;
481        afi_t afi = cmd_to_afi(argv[0]);
482        union sockunion proto_addr, nbma_addr;
483        struct nhrp_cache *c;
484
485        if (str2sockunion(argv[1], &proto_addr) < 0 ||
486            afi2family(afi) != sockunion_family(&proto_addr))
487                return nhrp_vty_return(vty, NHRP_ERR_PROTOCOL_ADDRESS_MISMATCH);
488
489        c = nhrp_cache_get(ifp, &proto_addr, 1);
490        if (!c)
491                return nhrp_vty_return(vty, NHRP_ERR_FAIL);
492
493        c->map = 1;
494        if (strcmp(argv[2], "local") == 0) {
495                nhrp_cache_update_binding(c, NHRP_CACHE_LOCAL, 0, NULL, 0, NULL);
496        } else{
497                if (str2sockunion(argv[2], &nbma_addr) < 0)
498                        return nhrp_vty_return(vty, NHRP_ERR_FAIL);
499                nhrp_cache_update_binding(c, NHRP_CACHE_STATIC, 0,
500                        nhrp_peer_get(ifp, &nbma_addr), 0, NULL);
501        }
502
503        return CMD_SUCCESS;
504}
505
506DEFUN(if_nhrp_nhs, if_nhrp_nhs_cmd,
507        AFI_CMD " nhrp nhs (A.B.C.D|X:X::X:X|dynamic) nbma (A.B.C.D|FQDN)",
508        AFI_STR
509        NHRP_STR
510        "Nexthop Server configuration\n"
511        "IPv4 protocol address\n"
512        "IPv6 protocol address\n"
513        "Automatic detection of protocol address\n"
514        "IPv4 NBMA address\n"
515        "Fully qualified domain name for NBMA address(es)\n")
516{
517        struct interface *ifp = vty->index;
518        afi_t afi = cmd_to_afi(argv[0]);
519        union sockunion proto_addr;
520        int ret;
521
522        if (str2sockunion(argv[1], &proto_addr) < 0)
523                sockunion_family(&proto_addr) = AF_UNSPEC;
524
525        ret = nhrp_nhs_add(ifp, afi, &proto_addr, argv[2]);
526        return nhrp_vty_return(vty, ret);
527}
528
529DEFUN(if_no_nhrp_nhs, if_no_nhrp_nhs_cmd,
530        "no " AFI_CMD " nhrp nhs (A.B.C.D|X:X::X:X|dynamic) nbma (A.B.C.D|FQDN)",
531        NO_STR
532        AFI_STR
533        NHRP_STR
534        "Nexthop Server configuration\n"
535        "IPv4 protocol address\n"
536        "IPv6 protocol address\n"
537        "Automatic detection of protocol address\n"
538        "IPv4 NBMA address\n"
539        "Fully qualified domain name for NBMA address(es)\n")
540{
541        struct interface *ifp = vty->index;
542        afi_t afi = cmd_to_afi(argv[0]);
543        union sockunion proto_addr;
544        int ret;
545
546        if (str2sockunion(argv[1], &proto_addr) < 0)
547                sockunion_family(&proto_addr) = AF_UNSPEC;
548
549        ret = nhrp_nhs_del(ifp, afi, &proto_addr, argv[2]);
550        return nhrp_vty_return(vty, ret);
551}
552
553struct info_ctx {
554        struct vty *vty;
555        afi_t afi;
556        int count;
557};
558
559static void show_ip_nhrp_cache(struct nhrp_cache *c, void *pctx)
560{
561        struct info_ctx *ctx = pctx;
562        struct vty *vty = ctx->vty;
563        char buf[2][SU_ADDRSTRLEN];
564
565        if (ctx->afi != family2afi(sockunion_family(&c->remote_addr)))
566                return;
567
568        if (!ctx->count) {
569                vty_out(vty, "%-8s %-8s %-24s %-24s %-6s %s%s",
570                        "Iface",
571                        "Type",
572                        "Protocol",
573                        "NBMA",
574                        "Flags",
575                        "Identity",
576                        VTY_NEWLINE);
577        }
578        ctx->count++;
579
580        vty_out(ctx->vty, "%-8s %-8s %-24s %-24s %c%c%c    %s%s",
581                c->ifp->name,
582                nhrp_cache_type_str[c->cur.type],
583                sockunion2str(&c->remote_addr, buf[0], sizeof buf[0]),
584                c->cur.peer ? sockunion2str(&c->cur.peer->vc->remote.nbma, buf[1], sizeof buf[1]) : "-",
585                c->used ? 'U' : ' ',
586                c->t_timeout ? 'T' : ' ',
587                c->t_auth ? 'A' : ' ',
588                c->cur.peer ? c->cur.peer->vc->remote.id : "-",
589                VTY_NEWLINE);
590}
591
592static void show_ip_opennhrp_cache(struct nhrp_cache *c, void *pctx)
593{
594        struct info_ctx *ctx = pctx;
595        struct vty *vty = ctx->vty;
596        char buf[SU_ADDRSTRLEN];
597
598        if (ctx->afi != family2afi(sockunion_family(&c->remote_addr)))
599                return;
600
601        vty_out(ctx->vty,
602                "Type: %s%s"
603                "Flags:%s%s%s"
604                "Protocol-Address: %s/%zu%s",
605                nhrp_cache_type_str[c->cur.type],
606                VTY_NEWLINE,
607                (c->cur.peer && c->cur.peer->online) ? " up": "",
608                c->used ? " used": "",
609                VTY_NEWLINE,
610                sockunion2str(&c->remote_addr, buf, sizeof buf),
611                8 * family2addrsize(sockunion_family(&c->remote_addr)),
612                VTY_NEWLINE);
613
614        if (c->cur.peer) {
615                vty_out(ctx->vty,
616                        "NBMA-Address: %s%s",
617                        sockunion2str(&c->cur.peer->vc->remote.nbma, buf, sizeof buf),
618                        VTY_NEWLINE);
619        }
620
621        if (sockunion_family(&c->cur.remote_nbma_natoa) != AF_UNSPEC) {
622                vty_out(ctx->vty,
623                        "NBMA-NAT-OA-Address: %s%s",
624                        sockunion2str(&c->cur.remote_nbma_natoa, buf, sizeof buf),
625                        VTY_NEWLINE);
626        }
627
628        vty_out(ctx->vty, "%s", VTY_NEWLINE);
629}
630
631static void show_ip_nhrp_shortcut(struct nhrp_shortcut *s, void *pctx)
632{
633        struct info_ctx *ctx = pctx;
634        struct nhrp_cache *c;
635        struct vty *vty = ctx->vty;
636        char buf1[PREFIX_STRLEN], buf2[SU_ADDRSTRLEN];
637
638        if (!ctx->count) {
639                vty_out(vty, "%-8s %-24s %-24s %s%s",
640                        "Type",
641                        "Prefix",
642                        "Via",
643                        "Identity",
644                        VTY_NEWLINE);
645        }
646        ctx->count++;
647
648        c = s->cache;
649        vty_out(ctx->vty, "%-8s %-24s %-24s %s%s",
650                nhrp_cache_type_str[s->type],
651                prefix2str(s->p, buf1, sizeof buf1),
652                c ? sockunion2str(&c->remote_addr, buf2, sizeof buf2) : "",
653                (c && c->cur.peer) ? c->cur.peer->vc->remote.id : "",
654                VTY_NEWLINE);
655}
656
657DEFUN(show_ip_nhrp, show_ip_nhrp_cmd,
658        "show " AFI_CMD " nhrp (cache|shortcut|opennhrp|)",
659        SHOW_STR
660        AFI_STR
661        "NHRP information\n"
662        "Forwarding cache information\n"
663        "Shortcut information\n"
664        "opennhrpctl style cache dump\n")
665{
666        struct listnode *node;
667        struct interface *ifp;
668        struct info_ctx ctx = {
669                .vty = vty,
670                .afi = cmd_to_afi(argv[0]),
671        };
672
673        if (!argv[1] || argv[1][0] == 'c') {
674                for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp))
675                        nhrp_cache_foreach(ifp, show_ip_nhrp_cache, &ctx);
676        } else if (argv[1][0] == 'o') {
677                vty_out(vty, "Status: ok%s%s", VTY_NEWLINE, VTY_NEWLINE);
678                ctx.count++;
679                for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp))
680                        nhrp_cache_foreach(ifp, show_ip_opennhrp_cache, &ctx);
681        } else {
682                nhrp_shortcut_foreach(ctx.afi, show_ip_nhrp_shortcut, &ctx);
683        }
684
685        if (!ctx.count) {
686                vty_out(vty, "%% No entries%s", VTY_NEWLINE);
687                return CMD_WARNING;
688        }
689
690        return CMD_SUCCESS;
691}
692
693static void show_dmvpn_entry(struct nhrp_vc *vc, void *ctx)
694{
695        struct vty *vty = ctx;
696        char buf[2][SU_ADDRSTRLEN];
697
698        vty_out(vty, "%-24s %-24s %c      %-4d %-24s%s",
699                sockunion2str(&vc->local.nbma, buf[0], sizeof buf[0]),
700                sockunion2str(&vc->remote.nbma, buf[1], sizeof buf[1]),
701                notifier_active(&vc->notifier_list) ? 'n' : ' ',
702                vc->ipsec,
703                vc->remote.id,
704                VTY_NEWLINE);
705}
706
707DEFUN(show_dmvpn, show_dmvpn_cmd,
708        "show dmvpn",
709        SHOW_STR
710        "DMVPN information\n")
711{
712        vty_out(vty, "%-24s %-24s %-6s %-4s %-24s%s",
713                "Src",
714                "Dst",
715                "Flags",
716                "SAs",
717                "Identity",
718                VTY_NEWLINE);
719
720        nhrp_vc_foreach(show_dmvpn_entry, vty);
721
722        return CMD_SUCCESS;
723}
724
725static void clear_nhrp_cache(struct nhrp_cache *c, void *data)
726{
727        struct info_ctx *ctx = data;
728        if (c->cur.type <= NHRP_CACHE_CACHED) {
729                nhrp_cache_update_binding(c, c->cur.type, -1, NULL, 0, NULL);
730                ctx->count++;
731        }
732}
733
734static void clear_nhrp_shortcut(struct nhrp_shortcut *s, void *data)
735{
736        struct info_ctx *ctx = data;
737        nhrp_shortcut_purge(s, 1);
738        ctx->count++;
739}
740
741DEFUN(clear_nhrp, clear_nhrp_cmd,
742        "clear " AFI_CMD " nhrp (cache|shortcut)",
743        CLEAR_STR
744        AFI_STR
745        NHRP_STR
746        "Dynamic cache entries\n"
747        "Shortcut entries\n")
748{
749        struct listnode *node;
750        struct interface *ifp;
751        struct info_ctx ctx = {
752                .vty = vty,
753                .afi = cmd_to_afi(argv[0]),
754                .count = 0,
755        };
756
757        if (!argv[1] || argv[1][0] == 'c') {
758                for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp))
759                        nhrp_cache_foreach(ifp, clear_nhrp_cache, &ctx);
760        } else {
761                nhrp_shortcut_foreach(ctx.afi, clear_nhrp_shortcut, &ctx);
762        }
763
764        if (!ctx.count) {
765                vty_out(vty, "%% No entries%s", VTY_NEWLINE);
766                return CMD_WARNING;
767        }
768
769        vty_out(vty, "%% %d entries cleared%s", ctx.count, VTY_NEWLINE);
770        return CMD_SUCCESS;
771}
772
773struct write_map_ctx {
774        struct vty *vty;
775        int family;
776        const char *aficmd;
777};
778
779static void interface_config_write_nhrp_map(struct nhrp_cache *c, void *data)
780{
781        struct write_map_ctx *ctx = data;
782        struct vty *vty = ctx->vty;
783        char buf[2][SU_ADDRSTRLEN];
784
785        if (!c->map) return;
786        if (sockunion_family(&c->remote_addr) != ctx->family) return;
787
788        vty_out(vty, " %s nhrp map %s %s%s",
789                ctx->aficmd,
790                sockunion2str(&c->remote_addr, buf[0], sizeof buf[0]),
791                c->cur.type == NHRP_CACHE_LOCAL ? "local" :
792                sockunion2str(&c->cur.peer->vc->remote.nbma, buf[1], sizeof buf[1]),
793                VTY_NEWLINE);
794}
795
796static int interface_config_write(struct vty *vty)
797{
798        struct write_map_ctx mapctx;
799        struct listnode *node;
800        struct interface *ifp;
801        struct nhrp_interface *nifp;
802        struct nhrp_nhs *nhs;
803        const char *aficmd;
804        afi_t afi;
805        char buf[SU_ADDRSTRLEN];
806        int i;
807
808        for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
809                vty_out(vty, "interface %s%s", ifp->name, VTY_NEWLINE);
810                if (ifp->desc)
811                        vty_out(vty, " description %s%s", ifp->desc, VTY_NEWLINE);
812
813                nifp = ifp->info;
814                if (nifp->ipsec_profile) {
815                        vty_out(vty, " tunnel protection vici profile %s",
816                                nifp->ipsec_profile);
817                        if (nifp->ipsec_fallback_profile)
818                                vty_out(vty, " fallback-profile %s",
819                                        nifp->ipsec_fallback_profile);
820                        vty_out(vty, "%s", VTY_NEWLINE);
821                }
822                if (nifp->source)
823                        vty_out(vty, " tunnel source %s%s",
824                                nifp->source, VTY_NEWLINE);
825
826                for (afi = 0; afi < AFI_MAX; afi++) {
827                        struct nhrp_afi_data *ad = &nifp->afi[afi];
828
829                        aficmd = afi_to_cmd(afi);
830
831                        if (ad->network_id)
832                                vty_out(vty, " %s nhrp network-id %u%s",
833                                        aficmd, ad->network_id,
834                                        VTY_NEWLINE);
835
836                        if (ad->holdtime != NHRPD_DEFAULT_HOLDTIME)
837                                vty_out(vty, " %s nhrp holdtime %u%s",
838                                        aficmd, ad->holdtime,
839                                        VTY_NEWLINE);
840
841                        if (ad->configured_mtu < 0)
842                                vty_out(vty, " %s nhrp mtu opennhrp%s",
843                                        aficmd, VTY_NEWLINE);
844                        else if (ad->configured_mtu)
845                                vty_out(vty, " %s nhrp mtu %u%s",
846                                        aficmd, ad->configured_mtu,
847                                        VTY_NEWLINE);
848
849                        for (i = 0; interface_flags_desc[i].str != NULL; i++) {
850                                if (!(ad->flags & interface_flags_desc[i].key))
851                                        continue;
852                                vty_out(vty, " %s nhrp %s%s",
853                                        aficmd, interface_flags_desc[i].str, VTY_NEWLINE);
854                        }
855
856                        mapctx = (struct write_map_ctx) {
857                                .vty = vty,
858                                .family = afi2family(afi),
859                                .aficmd = aficmd,
860                        };
861                        nhrp_cache_foreach(ifp, interface_config_write_nhrp_map, &mapctx);
862
863                        list_for_each_entry(nhs, &ad->nhslist_head, nhslist_entry) {
864                                vty_out(vty, " %s nhrp nhs %s nbma %s%s",
865                                        aficmd,
866                                        sockunion_family(&nhs->proto_addr) == AF_UNSPEC ? "dynamic" : sockunion2str(&nhs->proto_addr, buf, sizeof buf),
867                                        nhs->nbma_fqdn,
868                                        VTY_NEWLINE);
869                        }
870                }
871
872                vty_out (vty, "!%s", VTY_NEWLINE);
873        }
874
875        return 0;
876}
877
878void nhrp_config_init(void)
879{
880        install_node(&zebra_node, nhrp_config_write);
881        install_default(ZEBRA_NODE);
882
883        /* global commands */
884        install_element(VIEW_NODE, &show_debugging_nhrp_cmd);
885        install_element(VIEW_NODE, &show_ip_nhrp_cmd);
886        install_element(VIEW_NODE, &show_dmvpn_cmd);
887        install_element(ENABLE_NODE, &show_debugging_nhrp_cmd);
888        install_element(ENABLE_NODE, &show_ip_nhrp_cmd);
889        install_element(ENABLE_NODE, &show_dmvpn_cmd);
890        install_element(ENABLE_NODE, &clear_nhrp_cmd);
891
892        install_element(ENABLE_NODE, &debug_nhrp_cmd);
893        install_element(ENABLE_NODE, &no_debug_nhrp_cmd);
894
895        install_element(CONFIG_NODE, &debug_nhrp_cmd);
896        install_element(CONFIG_NODE, &no_debug_nhrp_cmd);
897
898        install_element(CONFIG_NODE, &nhrp_event_socket_cmd);
899        install_element(CONFIG_NODE, &no_nhrp_event_socket_cmd);
900        install_element(CONFIG_NODE, &nhrp_nflog_group_cmd);
901        install_element(CONFIG_NODE, &no_nhrp_nflog_group_cmd);
902
903        /* interface specific commands */
904        install_node(&nhrp_interface_node, interface_config_write);
905        install_default(INTERFACE_NODE);
906
907        install_element(CONFIG_NODE, &interface_cmd);
908        install_element(CONFIG_NODE, &no_interface_cmd);
909        install_element(INTERFACE_NODE, &interface_cmd);
910        install_element(INTERFACE_NODE, &no_interface_cmd);
911        install_element(INTERFACE_NODE, &tunnel_protection_cmd);
912        install_element(INTERFACE_NODE, &no_tunnel_protection_cmd);
913        install_element(INTERFACE_NODE, &tunnel_source_cmd);
914        install_element(INTERFACE_NODE, &no_tunnel_source_cmd);
915        install_element(INTERFACE_NODE, &if_nhrp_network_id_cmd);
916        install_element(INTERFACE_NODE, &if_no_nhrp_network_id_cmd);
917        install_element(INTERFACE_NODE, &if_nhrp_holdtime_cmd);
918        install_element(INTERFACE_NODE, &if_no_nhrp_holdtime_cmd);
919        install_element(INTERFACE_NODE, &if_nhrp_mtu_cmd);
920        install_element(INTERFACE_NODE, &if_no_nhrp_mtu_cmd);
921        install_element(INTERFACE_NODE, &if_nhrp_flags_cmd);
922        install_element(INTERFACE_NODE, &if_no_nhrp_flags_cmd);
923        install_element(INTERFACE_NODE, &if_nhrp_reg_flags_cmd);
924        install_element(INTERFACE_NODE, &if_no_nhrp_reg_flags_cmd);
925        install_element(INTERFACE_NODE, &if_nhrp_map_cmd);
926        install_element(INTERFACE_NODE, &if_nhrp_nhs_cmd);
927        install_element(INTERFACE_NODE, &if_no_nhrp_nhs_cmd);
928}
Note: See TracBrowser for help on using the repository browser.