]> git.proxmox.com Git - mirror_frr.git/blob - zebra/zebra_vty.c
Merge pull request #1618 from donaldsharp/zebra_startup_ordering
[mirror_frr.git] / zebra / zebra_vty.c
1 /* Zebra VTY functions
2 * Copyright (C) 2002 Kunihiro Ishiguro
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include <zebra.h>
22
23 #include "memory.h"
24 #include "zebra_memory.h"
25 #include "if.h"
26 #include "prefix.h"
27 #include "command.h"
28 #include "table.h"
29 #include "rib.h"
30 #include "nexthop.h"
31 #include "vrf.h"
32 #include "mpls.h"
33 #include "routemap.h"
34 #include "srcdest_table.h"
35 #include "vxlan.h"
36
37 #include "zebra/zserv.h"
38 #include "zebra/zebra_vrf.h"
39 #include "zebra/zebra_mpls.h"
40 #include "zebra/zebra_rnh.h"
41 #include "zebra/redistribute.h"
42 #include "zebra/zebra_routemap.h"
43 #include "zebra/zebra_static.h"
44 #include "lib/json.h"
45 #include "zebra/zebra_vxlan.h"
46 #ifndef VTYSH_EXTRACT_PL
47 #include "zebra/zebra_vty_clippy.c"
48 #endif
49 #include "zebra/zserv.h"
50 #include "zebra/router-id.h"
51 #include "zebra/ipforward.h"
52 #include "zebra/zebra_vxlan_private.h"
53
54 extern int allow_delete;
55
56 static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi,
57 safi_t safi, bool use_fib, u_char use_json,
58 route_tag_t tag,
59 const struct prefix *longer_prefix_p,
60 bool supernets_only, int type,
61 u_short ospf_instance_id);
62 static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn,
63 int mcast);
64 static void vty_show_ip_route_summary(struct vty *vty,
65 struct route_table *table);
66 static void vty_show_ip_route_summary_prefix(struct vty *vty,
67 struct route_table *table);
68
69 /*
70 * special macro to allow us to get the correct zebra_vrf
71 */
72 #define ZEBRA_DECLVAR_CONTEXT(A, B) \
73 struct vrf *A = VTY_GET_CONTEXT(vrf); \
74 struct zebra_vrf *B = \
75 (vrf) ? vrf->info : NULL; \
76
77 /* VNI range as per RFC 7432 */
78 #define CMD_VNI_RANGE "(1-16777215)"
79
80 /* General function for static route. */
81 static int zebra_static_route_leak(struct vty *vty,
82 struct zebra_vrf *zvrf,
83 struct zebra_vrf *nh_zvrf,
84 afi_t afi, safi_t safi,
85 const char *negate, const char *dest_str,
86 const char *mask_str, const char *src_str,
87 const char *gate_str, const char *ifname,
88 const char *flag_str, const char *tag_str,
89 const char *distance_str,
90 const char *label_str)
91 {
92 int ret;
93 u_char distance;
94 struct prefix p, src;
95 struct prefix_ipv6 *src_p = NULL;
96 union g_addr gate;
97 union g_addr *gatep = NULL;
98 struct in_addr mask;
99 enum static_blackhole_type bh_type = 0;
100 route_tag_t tag = 0;
101 u_char type;
102 struct static_nh_label snh_label;
103
104 ret = str2prefix(dest_str, &p);
105 if (ret <= 0) {
106 vty_out(vty, "%% Malformed address\n");
107 return CMD_WARNING_CONFIG_FAILED;
108 }
109
110 switch (afi) {
111 case AFI_IP:
112 /* Cisco like mask notation. */
113 if (mask_str) {
114 ret = inet_aton(mask_str, &mask);
115 if (ret == 0) {
116 vty_out(vty, "%% Malformed address\n");
117 return CMD_WARNING_CONFIG_FAILED;
118 }
119 p.prefixlen = ip_masklen(mask);
120 }
121 break;
122 case AFI_IP6:
123 /* srcdest routing */
124 if (src_str) {
125 ret = str2prefix(src_str, &src);
126 if (ret <= 0 || src.family != AF_INET6) {
127 vty_out(vty, "%% Malformed source address\n");
128 return CMD_WARNING_CONFIG_FAILED;
129 }
130 src_p = (struct prefix_ipv6 *)&src;
131 }
132 break;
133 default:
134 break;
135 }
136
137 /* Apply mask for given prefix. */
138 apply_mask(&p);
139
140 /* Administrative distance. */
141 if (distance_str)
142 distance = atoi(distance_str);
143 else
144 distance = ZEBRA_STATIC_DISTANCE_DEFAULT;
145
146 /* tag */
147 if (tag_str)
148 tag = strtoul(tag_str, NULL, 10);
149
150 /* Labels */
151 memset(&snh_label, 0, sizeof(struct static_nh_label));
152 if (label_str) {
153 if (!mpls_enabled) {
154 vty_out(vty,
155 "%% MPLS not turned on in kernel, ignoring command\n");
156 return CMD_WARNING_CONFIG_FAILED;
157 }
158 int rc = mpls_str2label(label_str, &snh_label.num_labels,
159 snh_label.label);
160 if (rc < 0) {
161 switch (rc) {
162 case -1:
163 vty_out(vty, "%% Malformed label(s)\n");
164 break;
165 case -2:
166 vty_out(vty,
167 "%% Cannot use reserved label(s) (%d-%d)\n",
168 MPLS_MIN_RESERVED_LABEL,
169 MPLS_MAX_RESERVED_LABEL);
170 break;
171 case -3:
172 vty_out(vty,
173 "%% Too many labels. Enter %d or fewer\n",
174 MPLS_MAX_LABELS);
175 break;
176 }
177 return CMD_WARNING_CONFIG_FAILED;
178 }
179 }
180
181 /* Null0 static route. */
182 if (ifname != NULL) {
183 if (strncasecmp(ifname, "Null0", strlen(ifname)) == 0 ||
184 strncasecmp(ifname, "reject", strlen(ifname)) == 0 ||
185 strncasecmp(ifname, "blackhole", strlen(ifname)) == 0) {
186 vty_out(vty, "%% Nexthop interface cannot be Null0, reject or blackhole\n");
187 return CMD_WARNING_CONFIG_FAILED;
188 }
189 }
190
191 /* Route flags */
192 if (flag_str) {
193 switch (flag_str[0]) {
194 case 'r':
195 bh_type = STATIC_BLACKHOLE_REJECT;
196 break;
197 case 'b':
198 bh_type = STATIC_BLACKHOLE_DROP;
199 break;
200 case 'N':
201 bh_type = STATIC_BLACKHOLE_NULL;
202 break;
203 default:
204 vty_out(vty, "%% Malformed flag %s \n", flag_str);
205 return CMD_WARNING_CONFIG_FAILED;
206 }
207 }
208
209 if (gate_str) {
210 if (inet_pton(afi2family(afi), gate_str, &gate) != 1) {
211 vty_out(vty, "%% Malformed nexthop address %s\n",
212 gate_str);
213 return CMD_WARNING_CONFIG_FAILED;
214 }
215 gatep = &gate;
216 }
217
218 if (gate_str == NULL && ifname == NULL)
219 type = STATIC_BLACKHOLE;
220 else if (gate_str && ifname) {
221 if (afi == AFI_IP)
222 type = STATIC_IPV4_GATEWAY_IFNAME;
223 else
224 type = STATIC_IPV6_GATEWAY_IFNAME;
225 } else if (ifname)
226 type = STATIC_IFNAME;
227 else {
228 if (afi == AFI_IP)
229 type = STATIC_IPV4_GATEWAY;
230 else
231 type = STATIC_IPV6_GATEWAY;
232 }
233
234 if (!negate)
235 static_add_route(afi, safi, type, &p, src_p, gatep, ifname,
236 bh_type, tag, distance, zvrf, nh_zvrf,
237 &snh_label);
238 else
239 static_delete_route(afi, safi, type, &p, src_p, gatep, ifname,
240 tag, distance, zvrf, &snh_label);
241
242 return CMD_SUCCESS;
243 }
244
245 static int zebra_static_route(struct vty *vty, afi_t afi, safi_t safi,
246 const char *negate, const char *dest_str,
247 const char *mask_str, const char *src_str,
248 const char *gate_str, const char *ifname,
249 const char *flag_str, const char *tag_str,
250 const char *distance_str, const char *vrf_id_str,
251 const char *label_str)
252 {
253 struct zebra_vrf *zvrf;
254
255 /* VRF id */
256 zvrf = zebra_vrf_lookup_by_name(vrf_id_str);
257
258 if (!zvrf) {
259 vty_out(vty, "%% vrf %s is not defined\n", vrf_id_str);
260 return CMD_WARNING_CONFIG_FAILED;
261 }
262
263 return zebra_static_route_leak(vty, zvrf, zvrf, afi, safi,
264 negate, dest_str, mask_str, src_str,
265 gate_str, ifname, flag_str, tag_str,
266 distance_str, label_str);
267 }
268
269
270 /* Static unicast routes for multicast RPF lookup. */
271 DEFPY (ip_mroute_dist,
272 ip_mroute_dist_cmd,
273 "[no] ip mroute A.B.C.D/M$prefix <A.B.C.D$gate|INTERFACE$ifname> [(1-255)$distance]",
274 NO_STR
275 IP_STR
276 "Configure static unicast route into MRIB for multicast RPF lookup\n"
277 "IP destination prefix (e.g. 10.0.0.0/8)\n"
278 "Nexthop address\n"
279 "Nexthop interface name\n"
280 "Distance\n")
281 {
282 return zebra_static_route(vty, AFI_IP, SAFI_MULTICAST, no, prefix_str,
283 NULL, NULL, gate_str, ifname, NULL, NULL,
284 distance_str, NULL, NULL);
285 }
286
287 DEFUN (ip_multicast_mode,
288 ip_multicast_mode_cmd,
289 "ip multicast rpf-lookup-mode <urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>",
290 IP_STR
291 "Multicast options\n"
292 "RPF lookup behavior\n"
293 "Lookup in unicast RIB only\n"
294 "Lookup in multicast RIB only\n"
295 "Try multicast RIB first, fall back to unicast RIB\n"
296 "Lookup both, use entry with lower distance\n"
297 "Lookup both, use entry with longer prefix\n")
298 {
299 char *mode = argv[3]->text;
300
301 if (strmatch(mode, "urib-only"))
302 multicast_mode_ipv4_set(MCAST_URIB_ONLY);
303 else if (strmatch(mode, "mrib-only"))
304 multicast_mode_ipv4_set(MCAST_MRIB_ONLY);
305 else if (strmatch(mode, "mrib-then-urib"))
306 multicast_mode_ipv4_set(MCAST_MIX_MRIB_FIRST);
307 else if (strmatch(mode, "lower-distance"))
308 multicast_mode_ipv4_set(MCAST_MIX_DISTANCE);
309 else if (strmatch(mode, "longer-prefix"))
310 multicast_mode_ipv4_set(MCAST_MIX_PFXLEN);
311 else {
312 vty_out(vty, "Invalid mode specified\n");
313 return CMD_WARNING_CONFIG_FAILED;
314 }
315
316 return CMD_SUCCESS;
317 }
318
319 DEFUN (no_ip_multicast_mode,
320 no_ip_multicast_mode_cmd,
321 "no ip multicast rpf-lookup-mode [<urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>]",
322 NO_STR
323 IP_STR
324 "Multicast options\n"
325 "RPF lookup behavior\n"
326 "Lookup in unicast RIB only\n"
327 "Lookup in multicast RIB only\n"
328 "Try multicast RIB first, fall back to unicast RIB\n"
329 "Lookup both, use entry with lower distance\n"
330 "Lookup both, use entry with longer prefix\n")
331 {
332 multicast_mode_ipv4_set(MCAST_NO_CONFIG);
333 return CMD_SUCCESS;
334 }
335
336
337 DEFUN (show_ip_rpf,
338 show_ip_rpf_cmd,
339 "show ip rpf [json]",
340 SHOW_STR
341 IP_STR
342 "Display RPF information for multicast source\n"
343 JSON_STR)
344 {
345 int uj = use_json(argc, argv);
346 return do_show_ip_route(vty, VRF_DEFAULT_NAME, AFI_IP, SAFI_MULTICAST,
347 false, uj, 0, NULL, false, 0, 0);
348 }
349
350 DEFUN (show_ip_rpf_addr,
351 show_ip_rpf_addr_cmd,
352 "show ip rpf A.B.C.D",
353 SHOW_STR
354 IP_STR
355 "Display RPF information for multicast source\n"
356 "IP multicast source address (e.g. 10.0.0.0)\n")
357 {
358 int idx_ipv4 = 3;
359 struct in_addr addr;
360 struct route_node *rn;
361 struct route_entry *re;
362 int ret;
363
364 ret = inet_aton(argv[idx_ipv4]->arg, &addr);
365 if (ret == 0) {
366 vty_out(vty, "%% Malformed address\n");
367 return CMD_WARNING;
368 }
369
370 re = rib_match_ipv4_multicast(VRF_DEFAULT, addr, &rn);
371
372 if (re)
373 vty_show_ip_route_detail(vty, rn, 1);
374 else
375 vty_out(vty, "%% No match for RPF lookup\n");
376
377 return CMD_SUCCESS;
378 }
379
380 /* Static route configuration. */
381 DEFPY(ip_route_blackhole,
382 ip_route_blackhole_cmd,
383 "[no] ip route\
384 <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
385 <reject|blackhole>$flag \
386 [{ \
387 tag (1-4294967295) \
388 |(1-255)$distance \
389 |vrf NAME \
390 |label WORD \
391 }]",
392 NO_STR IP_STR
393 "Establish static routes\n"
394 "IP destination prefix (e.g. 10.0.0.0/8)\n"
395 "IP destination prefix\n"
396 "IP destination prefix mask\n"
397 "Emit an ICMP unreachable when matched\n"
398 "Silently discard pkts when matched\n"
399 "Set tag for this route\n"
400 "Tag value\n"
401 "Distance value for this route\n"
402 VRF_CMD_HELP_STR
403 MPLS_LABEL_HELPSTR)
404 {
405 return zebra_static_route(vty, AFI_IP, SAFI_UNICAST, no, prefix,
406 mask_str, NULL, NULL, NULL, flag,
407 tag_str, distance_str, vrf, label);
408 }
409
410 DEFPY(ip_route_blackhole_vrf,
411 ip_route_blackhole_vrf_cmd,
412 "[no] ip route\
413 <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
414 <reject|blackhole>$flag \
415 [{ \
416 tag (1-4294967295) \
417 |(1-255)$distance \
418 |label WORD \
419 }]",
420 NO_STR IP_STR
421 "Establish static routes\n"
422 "IP destination prefix (e.g. 10.0.0.0/8)\n"
423 "IP destination prefix\n"
424 "IP destination prefix mask\n"
425 "Emit an ICMP unreachable when matched\n"
426 "Silently discard pkts when matched\n"
427 "Set tag for this route\n"
428 "Tag value\n"
429 "Distance value for this route\n"
430 MPLS_LABEL_HELPSTR)
431 {
432 VTY_DECLVAR_CONTEXT(vrf, vrf);
433 struct zebra_vrf *zvrf = vrf->info;
434
435 return zebra_static_route_leak(vty, zvrf, zvrf,
436 AFI_IP, SAFI_UNICAST, no, prefix,
437 mask_str, NULL, NULL, NULL, flag,
438 tag_str, distance_str, label);
439 }
440
441 DEFPY(ip_route_address_interface,
442 ip_route_address_interface_cmd,
443 "[no] ip route\
444 <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
445 A.B.C.D$gate \
446 INTERFACE$ifname \
447 [{ \
448 tag (1-4294967295) \
449 |(1-255)$distance \
450 |vrf NAME \
451 |label WORD \
452 |nexthop-vrf NAME \
453 }]",
454 NO_STR IP_STR
455 "Establish static routes\n"
456 "IP destination prefix (e.g. 10.0.0.0/8)\n"
457 "IP destination prefix\n"
458 "IP destination prefix mask\n"
459 "IP gateway address\n"
460 "IP gateway interface name. Specify 'Null0' (case-insensitive) for a \
461 null route.\n"
462 "Set tag for this route\n"
463 "Tag value\n"
464 "Distance value for this route\n"
465 VRF_CMD_HELP_STR
466 MPLS_LABEL_HELPSTR
467 VRF_CMD_HELP_STR)
468 {
469 struct zebra_vrf *zvrf;
470 struct zebra_vrf *nh_zvrf;
471
472 const char *flag = NULL;
473 if (ifname && !strncasecmp(ifname, "Null0", 5)) {
474 flag = "Null0";
475 ifname = NULL;
476 }
477
478 nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf);
479 if (!nh_zvrf) {
480 vty_out(vty, "%% nexthop vrf %s is not defined\n",
481 nexthop_vrf);
482 return CMD_WARNING_CONFIG_FAILED;
483 }
484
485 zvrf = zebra_vrf_lookup_by_name(vrf);
486 if (!nh_zvrf) {
487 vty_out(vty, "%% nexthop vrf %s is not defined\n",
488 vrf);
489 return CMD_WARNING_CONFIG_FAILED;
490 }
491
492 return zebra_static_route_leak(vty, zvrf, nh_zvrf,
493 AFI_IP, SAFI_UNICAST, no, prefix,
494 mask_str, NULL, gate_str, ifname, flag,
495 tag_str, distance_str, label);
496 }
497
498 DEFPY(ip_route_address_interface_vrf,
499 ip_route_address_interface_vrf_cmd,
500 "[no] ip route\
501 <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
502 A.B.C.D$gate \
503 INTERFACE$ifname \
504 [{ \
505 tag (1-4294967295) \
506 |(1-255)$distance \
507 |label WORD \
508 |nexthop-vrf NAME \
509 }]",
510 NO_STR IP_STR
511 "Establish static routes\n"
512 "IP destination prefix (e.g. 10.0.0.0/8)\n"
513 "IP destination prefix\n"
514 "IP destination prefix mask\n"
515 "IP gateway address\n"
516 "IP gateway interface name. Specify 'Null0' (case-insensitive) for a \
517 null route.\n"
518 "Set tag for this route\n"
519 "Tag value\n"
520 "Distance value for this route\n"
521 MPLS_LABEL_HELPSTR
522 VRF_CMD_HELP_STR)
523 {
524 VTY_DECLVAR_CONTEXT(vrf, vrf);
525 const char *flag = NULL;
526 struct zebra_vrf *zvrf = vrf->info;
527 struct zebra_vrf *nh_zvrf;
528
529 if (ifname && !strncasecmp(ifname, "Null0", 5)) {
530 flag = "Null0";
531 ifname = NULL;
532 }
533
534 nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf);
535 if (!nh_zvrf) {
536 vty_out(vty, "%% nexthop vrf %s is not defined\n",
537 nexthop_vrf);
538 return CMD_WARNING_CONFIG_FAILED;
539 }
540
541 return zebra_static_route_leak(vty, zvrf, nh_zvrf,
542 AFI_IP, SAFI_UNICAST, no, prefix,
543 mask_str, NULL, gate_str, ifname, flag,
544 tag_str, distance_str, label);
545 }
546
547 DEFPY(ip_route,
548 ip_route_cmd,
549 "[no] ip route\
550 <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
551 <A.B.C.D$gate|INTERFACE$ifname> \
552 [{ \
553 tag (1-4294967295) \
554 |(1-255)$distance \
555 |vrf NAME \
556 |label WORD \
557 |nexthop-vrf NAME \
558 }]",
559 NO_STR IP_STR
560 "Establish static routes\n"
561 "IP destination prefix (e.g. 10.0.0.0/8)\n"
562 "IP destination prefix\n"
563 "IP destination prefix mask\n"
564 "IP gateway address\n"
565 "IP gateway interface name\n"
566 "Set tag for this route\n"
567 "Tag value\n"
568 "Distance value for this route\n"
569 VRF_CMD_HELP_STR
570 MPLS_LABEL_HELPSTR
571 VRF_CMD_HELP_STR)
572 {
573 struct zebra_vrf *zvrf;
574 struct zebra_vrf *nh_zvrf;
575 const char *flag = NULL;
576
577 if (ifname && !strncasecmp(ifname, "Null0", 5)) {
578 flag = "Null0";
579 ifname = NULL;
580 }
581
582 nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf);
583 if (!nh_zvrf) {
584 vty_out(vty, "%% nexthop vrf %s is not defined\n",
585 nexthop_vrf);
586 return CMD_WARNING_CONFIG_FAILED;
587 }
588
589 zvrf = zebra_vrf_lookup_by_name(vrf);
590 if (!nh_zvrf) {
591 vty_out(vty, "%% nexthop vrf %s is not defined\n",
592 vrf);
593 return CMD_WARNING_CONFIG_FAILED;
594 }
595
596 return zebra_static_route_leak(vty, zvrf, nh_zvrf,
597 AFI_IP, SAFI_UNICAST, no, prefix,
598 mask_str, NULL, gate_str, ifname, flag,
599 tag_str, distance_str, label);
600 }
601
602 DEFPY(ip_route_vrf,
603 ip_route_vrf_cmd,
604 "[no] ip route\
605 <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
606 <A.B.C.D$gate|INTERFACE$ifname> \
607 [{ \
608 tag (1-4294967295) \
609 |(1-255)$distance \
610 |label WORD \
611 |nexthop-vrf NAME \
612 }]",
613 NO_STR IP_STR
614 "Establish static routes\n"
615 "IP destination prefix (e.g. 10.0.0.0/8)\n"
616 "IP destination prefix\n"
617 "IP destination prefix mask\n"
618 "IP gateway address\n"
619 "IP gateway interface name\n"
620 "Set tag for this route\n"
621 "Tag value\n"
622 "Distance value for this route\n"
623 MPLS_LABEL_HELPSTR
624 VRF_CMD_HELP_STR)
625 {
626 VTY_DECLVAR_CONTEXT(vrf, vrf);
627 struct zebra_vrf *zvrf = vrf->info;
628 struct zebra_vrf *nh_zvrf;
629
630 const char *flag = NULL;
631 if (ifname && !strncasecmp(ifname, "Null0", 5)) {
632 flag = "Null0";
633 ifname = NULL;
634 }
635
636 nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf);
637 if (!nh_zvrf) {
638 vty_out(vty, "%% nexthop vrf %s is not defined\n",
639 nexthop_vrf);
640 return CMD_WARNING_CONFIG_FAILED;
641 }
642
643 return zebra_static_route_leak(vty, zvrf, nh_zvrf,
644 AFI_IP, SAFI_UNICAST, no, prefix,
645 mask_str, NULL, gate_str, ifname, flag,
646 tag_str, distance_str, label);
647 }
648
649 /* New RIB. Detailed information for IPv4 route. */
650 static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn,
651 int mcast)
652 {
653 struct route_entry *re;
654 struct nexthop *nexthop;
655 char buf[SRCDEST2STR_BUFFER];
656 struct zebra_vrf *zvrf;
657
658 RNODE_FOREACH_RE (rn, re) {
659 const char *mcast_info = "";
660 if (mcast) {
661 rib_table_info_t *info = srcdest_rnode_table_info(rn);
662 mcast_info = (info->safi == SAFI_MULTICAST)
663 ? " using Multicast RIB"
664 : " using Unicast RIB";
665 }
666
667 vty_out(vty, "Routing entry for %s%s\n",
668 srcdest_rnode2str(rn, buf, sizeof(buf)), mcast_info);
669 vty_out(vty, " Known via \"%s", zebra_route_string(re->type));
670 if (re->instance)
671 vty_out(vty, "[%d]", re->instance);
672 vty_out(vty, "\"");
673 vty_out(vty, ", distance %u, metric %u", re->distance,
674 re->metric);
675 if (re->tag) {
676 vty_out(vty, ", tag %u", re->tag);
677 #if defined(SUPPORT_REALMS)
678 if (re->tag > 0 && re->tag <= 255)
679 vty_out(vty, "(realm)");
680 #endif
681 }
682 if (re->mtu)
683 vty_out(vty, ", mtu %u", re->mtu);
684 if (re->vrf_id != VRF_DEFAULT) {
685 zvrf = vrf_info_lookup(re->vrf_id);
686 vty_out(vty, ", vrf %s", zvrf_name(zvrf));
687 }
688 if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED))
689 vty_out(vty, ", best");
690 vty_out(vty, "\n");
691
692 time_t uptime;
693 struct tm *tm;
694
695 uptime = time(NULL);
696 uptime -= re->uptime;
697 tm = gmtime(&uptime);
698
699 vty_out(vty, " Last update ");
700
701 if (uptime < ONE_DAY_SECOND)
702 vty_out(vty, "%02d:%02d:%02d", tm->tm_hour,
703 tm->tm_min, tm->tm_sec);
704 else if (uptime < ONE_WEEK_SECOND)
705 vty_out(vty, "%dd%02dh%02dm", tm->tm_yday,
706 tm->tm_hour, tm->tm_min);
707 else
708 vty_out(vty, "%02dw%dd%02dh", tm->tm_yday / 7,
709 tm->tm_yday - ((tm->tm_yday / 7) * 7),
710 tm->tm_hour);
711 vty_out(vty, " ago\n");
712
713 for (ALL_NEXTHOPS(re->nexthop, nexthop)) {
714 char addrstr[32];
715
716 vty_out(vty, " %c%s",
717 CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)
718 ? CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE)
719 ? ' ' : '*'
720 : ' ',
721 nexthop->rparent ? " " : "");
722
723 switch (nexthop->type) {
724 case NEXTHOP_TYPE_IPV4:
725 case NEXTHOP_TYPE_IPV4_IFINDEX:
726 vty_out(vty, " %s",
727 inet_ntoa(nexthop->gate.ipv4));
728 if (nexthop->ifindex)
729 vty_out(vty, ", via %s",
730 ifindex2ifname(nexthop->ifindex,
731 re->nh_vrf_id));
732 break;
733 case NEXTHOP_TYPE_IPV6:
734 case NEXTHOP_TYPE_IPV6_IFINDEX:
735 vty_out(vty, " %s",
736 inet_ntop(AF_INET6, &nexthop->gate.ipv6,
737 buf, sizeof buf));
738 if (nexthop->ifindex)
739 vty_out(vty, ", via %s",
740 ifindex2ifname(nexthop->ifindex,
741 re->nh_vrf_id));
742 break;
743 case NEXTHOP_TYPE_IFINDEX:
744 vty_out(vty, " directly connected, %s",
745 ifindex2ifname(nexthop->ifindex,
746 re->nh_vrf_id));
747 break;
748 case NEXTHOP_TYPE_BLACKHOLE:
749 vty_out(vty, " unreachable");
750 switch (nexthop->bh_type) {
751 case BLACKHOLE_REJECT:
752 vty_out(vty, " (ICMP unreachable)");
753 break;
754 case BLACKHOLE_ADMINPROHIB:
755 vty_out(vty,
756 " (ICMP admin-prohibited)");
757 break;
758 case BLACKHOLE_NULL:
759 vty_out(vty, " (blackhole)");
760 break;
761 case BLACKHOLE_UNSPEC:
762 break;
763 }
764 break;
765 default:
766 break;
767 }
768
769 if (re->vrf_id != re->nh_vrf_id) {
770 struct vrf *vrf =
771 vrf_lookup_by_id(re->nh_vrf_id);
772
773 vty_out(vty, "(vrf %s)", vrf->name);
774 }
775
776 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE))
777 vty_out(vty, " (duplicate nexthop removed)");
778
779 if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
780 vty_out(vty, " inactive");
781
782 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK))
783 vty_out(vty, " onlink");
784
785 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
786 vty_out(vty, " (recursive)");
787
788 switch (nexthop->type) {
789 case NEXTHOP_TYPE_IPV4:
790 case NEXTHOP_TYPE_IPV4_IFINDEX:
791 if (nexthop->src.ipv4.s_addr) {
792 if (inet_ntop(AF_INET,
793 &nexthop->src.ipv4,
794 addrstr, sizeof addrstr))
795 vty_out(vty, ", src %s",
796 addrstr);
797 }
798 break;
799 case NEXTHOP_TYPE_IPV6:
800 case NEXTHOP_TYPE_IPV6_IFINDEX:
801 if (!IPV6_ADDR_SAME(&nexthop->src.ipv6,
802 &in6addr_any)) {
803 if (inet_ntop(AF_INET6,
804 &nexthop->src.ipv6,
805 addrstr, sizeof addrstr))
806 vty_out(vty, ", src %s",
807 addrstr);
808 }
809 break;
810 default:
811 break;
812 }
813
814 if (re->nexthop_mtu)
815 vty_out(vty, ", mtu %u", re->nexthop_mtu);
816
817 /* Label information */
818 if (nexthop->nh_label
819 && nexthop->nh_label->num_labels) {
820 vty_out(vty, ", label %s",
821 mpls_label2str(
822 nexthop->nh_label->num_labels,
823 nexthop->nh_label->label, buf,
824 sizeof buf, 1));
825 }
826
827 vty_out(vty, "\n");
828 }
829 vty_out(vty, "\n");
830 }
831 }
832
833 static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
834 struct route_entry *re, json_object *json)
835 {
836 struct nexthop *nexthop;
837 int len = 0;
838 char buf[SRCDEST2STR_BUFFER];
839 json_object *json_nexthops = NULL;
840 json_object *json_nexthop = NULL;
841 json_object *json_route = NULL;
842 json_object *json_labels = NULL;
843 time_t uptime;
844 struct tm *tm;
845
846 uptime = time(NULL);
847 uptime -= re->uptime;
848 tm = gmtime(&uptime);
849
850 if (json) {
851 json_route = json_object_new_object();
852 json_nexthops = json_object_new_array();
853
854 json_object_string_add(json_route, "prefix",
855 srcdest_rnode2str(rn, buf, sizeof buf));
856 json_object_string_add(json_route, "protocol",
857 zebra_route_string(re->type));
858
859 if (re->instance)
860 json_object_int_add(json_route, "instance",
861 re->instance);
862
863 if (re->vrf_id)
864 json_object_int_add(json_route, "vrfId", re->vrf_id);
865
866 if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED))
867 json_object_boolean_true_add(json_route, "selected");
868
869 if (re->type != ZEBRA_ROUTE_CONNECT) {
870 json_object_int_add(json_route, "distance",
871 re->distance);
872 json_object_int_add(json_route, "metric", re->metric);
873 }
874
875 if (uptime < ONE_DAY_SECOND)
876 sprintf(buf, "%02d:%02d:%02d", tm->tm_hour,
877 tm->tm_min, tm->tm_sec);
878 else if (uptime < ONE_WEEK_SECOND)
879 sprintf(buf, "%dd%02dh%02dm", tm->tm_yday,
880 tm->tm_hour, tm->tm_min);
881 else
882 sprintf(buf, "%02dw%dd%02dh", tm->tm_yday / 7,
883 tm->tm_yday - ((tm->tm_yday / 7) * 7),
884 tm->tm_hour);
885
886 json_object_string_add(json_route, "uptime", buf);
887
888 for (ALL_NEXTHOPS(re->nexthop, nexthop)) {
889 json_nexthop = json_object_new_object();
890
891 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE))
892 json_object_boolean_true_add(json_nexthop,
893 "duplicate");
894
895 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB))
896 json_object_boolean_true_add(json_nexthop,
897 "fib");
898
899 switch (nexthop->type) {
900 case NEXTHOP_TYPE_IPV4:
901 case NEXTHOP_TYPE_IPV4_IFINDEX:
902 json_object_string_add(
903 json_nexthop, "ip",
904 inet_ntoa(nexthop->gate.ipv4));
905 json_object_string_add(json_nexthop, "afi",
906 "ipv4");
907
908 if (nexthop->ifindex) {
909 json_object_int_add(json_nexthop,
910 "interfaceIndex",
911 nexthop->ifindex);
912 json_object_string_add(
913 json_nexthop, "interfaceName",
914 ifindex2ifname(nexthop->ifindex,
915 re->nh_vrf_id));
916 }
917 break;
918 case NEXTHOP_TYPE_IPV6:
919 case NEXTHOP_TYPE_IPV6_IFINDEX:
920 json_object_string_add(
921 json_nexthop, "ip",
922 inet_ntop(AF_INET6, &nexthop->gate.ipv6,
923 buf, sizeof buf));
924 json_object_string_add(json_nexthop, "afi",
925 "ipv6");
926
927 if (nexthop->ifindex) {
928 json_object_int_add(json_nexthop,
929 "interfaceIndex",
930 nexthop->ifindex);
931 json_object_string_add(
932 json_nexthop, "interfaceName",
933 ifindex2ifname(nexthop->ifindex,
934 re->nh_vrf_id));
935 }
936 break;
937
938 case NEXTHOP_TYPE_IFINDEX:
939 json_object_boolean_true_add(
940 json_nexthop, "directlyConnected");
941 json_object_int_add(json_nexthop,
942 "interfaceIndex",
943 nexthop->ifindex);
944 json_object_string_add(
945 json_nexthop, "interfaceName",
946 ifindex2ifname(nexthop->ifindex,
947 re->nh_vrf_id));
948 break;
949 case NEXTHOP_TYPE_BLACKHOLE:
950 json_object_boolean_true_add(json_nexthop,
951 "unreachable");
952 switch (nexthop->bh_type) {
953 case BLACKHOLE_REJECT:
954 json_object_boolean_true_add(
955 json_nexthop, "reject");
956 break;
957 case BLACKHOLE_ADMINPROHIB:
958 json_object_boolean_true_add(
959 json_nexthop,
960 "admin-prohibited");
961 break;
962 case BLACKHOLE_NULL:
963 json_object_boolean_true_add(
964 json_nexthop, "blackhole");
965 break;
966 case BLACKHOLE_UNSPEC:
967 break;
968 }
969 break;
970 default:
971 break;
972 }
973
974 if (re->nh_vrf_id != re->vrf_id) {
975 struct vrf *vrf =
976 vrf_lookup_by_id(re->nh_vrf_id);
977
978 json_object_string_add(json_nexthop,
979 "vrf",
980 vrf->name);
981 }
982 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE))
983 json_object_boolean_true_add(json_nexthop,
984 "duplicate");
985
986 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
987 json_object_boolean_true_add(json_nexthop,
988 "active");
989
990 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK))
991 json_object_boolean_true_add(json_nexthop,
992 "onLink");
993
994 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
995 json_object_boolean_true_add(json_nexthop,
996 "recursive");
997
998 switch (nexthop->type) {
999 case NEXTHOP_TYPE_IPV4:
1000 case NEXTHOP_TYPE_IPV4_IFINDEX:
1001 if (nexthop->src.ipv4.s_addr) {
1002 if (inet_ntop(AF_INET,
1003 &nexthop->src.ipv4, buf,
1004 sizeof buf))
1005 json_object_string_add(
1006 json_nexthop, "source",
1007 buf);
1008 }
1009 break;
1010 case NEXTHOP_TYPE_IPV6:
1011 case NEXTHOP_TYPE_IPV6_IFINDEX:
1012 if (!IPV6_ADDR_SAME(&nexthop->src.ipv6,
1013 &in6addr_any)) {
1014 if (inet_ntop(AF_INET6,
1015 &nexthop->src.ipv6, buf,
1016 sizeof buf))
1017 json_object_string_add(
1018 json_nexthop, "source",
1019 buf);
1020 }
1021 break;
1022 default:
1023 break;
1024 }
1025
1026 if (nexthop->nh_label
1027 && nexthop->nh_label->num_labels) {
1028 json_labels = json_object_new_array();
1029
1030 for (int label_index = 0;
1031 label_index
1032 < nexthop->nh_label->num_labels;
1033 label_index++)
1034 json_object_array_add(
1035 json_labels,
1036 json_object_new_int(
1037 nexthop->nh_label->label
1038 [label_index]));
1039
1040 json_object_object_add(json_nexthop, "labels",
1041 json_labels);
1042 }
1043
1044 json_object_array_add(json_nexthops, json_nexthop);
1045 }
1046
1047 json_object_object_add(json_route, "nexthops", json_nexthops);
1048 json_object_array_add(json, json_route);
1049 return;
1050 }
1051
1052 /* Nexthop information. */
1053 for (ALL_NEXTHOPS(re->nexthop, nexthop)) {
1054 if (nexthop == re->nexthop) {
1055 /* Prefix information. */
1056 len = vty_out(vty, "%c", zebra_route_char(re->type));
1057 if (re->instance)
1058 len += vty_out(vty, "[%d]", re->instance);
1059 len += vty_out(
1060 vty, "%c%c %s",
1061 CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED)
1062 ? '>'
1063 : ' ',
1064 CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)
1065 ? '*'
1066 : ' ',
1067 srcdest_rnode2str(rn, buf, sizeof buf));
1068
1069 /* Distance and metric display. */
1070 if (re->type != ZEBRA_ROUTE_CONNECT)
1071 len += vty_out(vty, " [%u/%u]", re->distance,
1072 re->metric);
1073 } else {
1074 vty_out(vty, " %c%*c",
1075 CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)
1076 ? CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE)
1077 ? ' ' : '*'
1078 : ' ',
1079 len - 3 + (2 * nexthop_level(nexthop)), ' ');
1080 }
1081
1082 switch (nexthop->type) {
1083 case NEXTHOP_TYPE_IPV4:
1084 case NEXTHOP_TYPE_IPV4_IFINDEX:
1085 vty_out(vty, " via %s", inet_ntoa(nexthop->gate.ipv4));
1086 if (nexthop->ifindex)
1087 vty_out(vty, ", %s",
1088 ifindex2ifname(nexthop->ifindex,
1089 re->nh_vrf_id));
1090 break;
1091 case NEXTHOP_TYPE_IPV6:
1092 case NEXTHOP_TYPE_IPV6_IFINDEX:
1093 vty_out(vty, " via %s",
1094 inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf,
1095 sizeof buf));
1096 if (nexthop->ifindex)
1097 vty_out(vty, ", %s",
1098 ifindex2ifname(nexthop->ifindex,
1099 re->nh_vrf_id));
1100 break;
1101
1102 case NEXTHOP_TYPE_IFINDEX:
1103 vty_out(vty, " is directly connected, %s",
1104 ifindex2ifname(nexthop->ifindex,
1105 re->nh_vrf_id));
1106 break;
1107 case NEXTHOP_TYPE_BLACKHOLE:
1108 vty_out(vty, " unreachable");
1109 switch (nexthop->bh_type) {
1110 case BLACKHOLE_REJECT:
1111 vty_out(vty, " (ICMP unreachable)");
1112 break;
1113 case BLACKHOLE_ADMINPROHIB:
1114 vty_out(vty, " (ICMP admin-prohibited)");
1115 break;
1116 case BLACKHOLE_NULL:
1117 vty_out(vty, " (blackhole)");
1118 break;
1119 case BLACKHOLE_UNSPEC:
1120 break;
1121 }
1122 break;
1123 default:
1124 break;
1125 }
1126
1127 if (re->nh_vrf_id != re->vrf_id) {
1128 struct vrf *vrf =
1129 vrf_lookup_by_id(re->nh_vrf_id);
1130
1131 vty_out(vty, "(vrf %s)", vrf->name);
1132 }
1133
1134 if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1135 vty_out(vty, " inactive");
1136
1137 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK))
1138 vty_out(vty, " onlink");
1139
1140 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
1141 vty_out(vty, " (recursive)");
1142
1143 switch (nexthop->type) {
1144 case NEXTHOP_TYPE_IPV4:
1145 case NEXTHOP_TYPE_IPV4_IFINDEX:
1146 if (nexthop->src.ipv4.s_addr) {
1147 if (inet_ntop(AF_INET, &nexthop->src.ipv4, buf,
1148 sizeof buf))
1149 vty_out(vty, ", src %s", buf);
1150 }
1151 break;
1152 case NEXTHOP_TYPE_IPV6:
1153 case NEXTHOP_TYPE_IPV6_IFINDEX:
1154 if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any)) {
1155 if (inet_ntop(AF_INET6, &nexthop->src.ipv6, buf,
1156 sizeof buf))
1157 vty_out(vty, ", src %s", buf);
1158 }
1159 break;
1160 default:
1161 break;
1162 }
1163
1164 /* Label information */
1165 if (nexthop->nh_label && nexthop->nh_label->num_labels) {
1166 vty_out(vty, ", label %s",
1167 mpls_label2str(nexthop->nh_label->num_labels,
1168 nexthop->nh_label->label, buf,
1169 sizeof buf, 1));
1170 }
1171
1172 if (uptime < ONE_DAY_SECOND)
1173 vty_out(vty, ", %02d:%02d:%02d", tm->tm_hour,
1174 tm->tm_min, tm->tm_sec);
1175 else if (uptime < ONE_WEEK_SECOND)
1176 vty_out(vty, ", %dd%02dh%02dm", tm->tm_yday,
1177 tm->tm_hour, tm->tm_min);
1178 else
1179 vty_out(vty, ", %02dw%dd%02dh", tm->tm_yday / 7,
1180 tm->tm_yday - ((tm->tm_yday / 7) * 7),
1181 tm->tm_hour);
1182 vty_out(vty, "\n");
1183 }
1184 }
1185
1186 static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi,
1187 safi_t safi, bool use_fib, u_char use_json,
1188 route_tag_t tag,
1189 const struct prefix *longer_prefix_p,
1190 bool supernets_only, int type,
1191 u_short ospf_instance_id)
1192 {
1193 struct route_table *table;
1194 rib_dest_t *dest;
1195 struct route_node *rn;
1196 struct route_entry *re;
1197 int first = 1;
1198 struct zebra_vrf *zvrf = NULL;
1199 char buf[BUFSIZ];
1200 json_object *json = NULL;
1201 json_object *json_prefix = NULL;
1202 u_int32_t addr;
1203
1204 if (!(zvrf = zebra_vrf_lookup_by_name(vrf_name))) {
1205 if (use_json)
1206 vty_out(vty, "{}\n");
1207 else
1208 vty_out(vty, "vrf %s not defined\n", vrf_name);
1209 return CMD_SUCCESS;
1210 }
1211
1212 if (zvrf_id(zvrf) == VRF_UNKNOWN) {
1213 if (use_json)
1214 vty_out(vty, "{}\n");
1215 else
1216 vty_out(vty, "vrf %s inactive\n", vrf_name);
1217 return CMD_SUCCESS;
1218 }
1219
1220 table = zebra_vrf_table(afi, safi, zvrf_id(zvrf));
1221 if (!table) {
1222 if (use_json)
1223 vty_out(vty, "{}\n");
1224 return CMD_SUCCESS;
1225 }
1226
1227 if (use_json)
1228 json = json_object_new_object();
1229
1230 /* Show all routes. */
1231 for (rn = route_top(table); rn; rn = route_next(rn)) {
1232 dest = rib_dest_from_rnode(rn);
1233
1234 RNODE_FOREACH_RE (rn, re) {
1235 if (use_fib
1236 && re != dest->selected_fib)
1237 continue;
1238
1239 if (tag && re->tag != tag)
1240 continue;
1241
1242 if (longer_prefix_p
1243 && !prefix_match(longer_prefix_p, &rn->p))
1244 continue;
1245
1246 /* This can only be true when the afi is IPv4 */
1247 if (supernets_only) {
1248 addr = ntohl(rn->p.u.prefix4.s_addr);
1249
1250 if (IN_CLASSC(addr) && rn->p.prefixlen >= 24)
1251 continue;
1252
1253 if (IN_CLASSB(addr) && rn->p.prefixlen >= 16)
1254 continue;
1255
1256 if (IN_CLASSA(addr) && rn->p.prefixlen >= 8)
1257 continue;
1258 }
1259
1260 if (type && re->type != type)
1261 continue;
1262
1263 if (ospf_instance_id
1264 && (re->type != ZEBRA_ROUTE_OSPF
1265 || re->instance != ospf_instance_id))
1266 continue;
1267
1268 if (use_json) {
1269 if (!json_prefix)
1270 json_prefix = json_object_new_array();
1271 } else {
1272 if (first) {
1273 if (afi == AFI_IP)
1274 vty_out(vty,
1275 SHOW_ROUTE_V4_HEADER);
1276 else
1277 vty_out(vty,
1278 SHOW_ROUTE_V6_HEADER);
1279
1280 if (zvrf_id(zvrf) != VRF_DEFAULT)
1281 vty_out(vty, "\nVRF %s:\n",
1282 zvrf_name(zvrf));
1283
1284 first = 0;
1285 }
1286 }
1287
1288 vty_show_ip_route(vty, rn, re, json_prefix);
1289 }
1290
1291 if (json_prefix) {
1292 prefix2str(&rn->p, buf, sizeof buf);
1293 json_object_object_add(json, buf, json_prefix);
1294 json_prefix = NULL;
1295 }
1296 }
1297
1298 if (use_json) {
1299 vty_out(vty, "%s\n", json_object_to_json_string_ext(
1300 json, JSON_C_TO_STRING_PRETTY));
1301 json_object_free(json);
1302 }
1303
1304 return CMD_SUCCESS;
1305 }
1306
1307 DEFUN (show_ip_nht,
1308 show_ip_nht_cmd,
1309 "show ip nht [vrf NAME]",
1310 SHOW_STR
1311 IP_STR
1312 "IP nexthop tracking table\n"
1313 VRF_CMD_HELP_STR)
1314 {
1315 int idx_vrf = 4;
1316 vrf_id_t vrf_id = VRF_DEFAULT;
1317
1318 if (argc == 5)
1319 VRF_GET_ID(vrf_id, argv[idx_vrf]->arg);
1320
1321 zebra_print_rnh_table(vrf_id, AF_INET, vty, RNH_NEXTHOP_TYPE);
1322 return CMD_SUCCESS;
1323 }
1324
1325
1326 DEFUN (show_ip_nht_vrf_all,
1327 show_ip_nht_vrf_all_cmd,
1328 "show ip nht vrf all",
1329 SHOW_STR
1330 IP_STR
1331 "IP nexthop tracking table\n"
1332 VRF_ALL_CMD_HELP_STR)
1333 {
1334 struct vrf *vrf;
1335 struct zebra_vrf *zvrf;
1336
1337 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
1338 if ((zvrf = vrf->info) != NULL) {
1339 vty_out(vty, "\nVRF %s:\n", zvrf_name(zvrf));
1340 zebra_print_rnh_table(zvrf_id(zvrf), AF_INET, vty,
1341 RNH_NEXTHOP_TYPE);
1342 }
1343
1344 return CMD_SUCCESS;
1345 }
1346
1347 DEFUN (show_ipv6_nht,
1348 show_ipv6_nht_cmd,
1349 "show ipv6 nht [vrf NAME]",
1350 SHOW_STR
1351 IPV6_STR
1352 "IPv6 nexthop tracking table\n"
1353 VRF_CMD_HELP_STR)
1354 {
1355 int idx_vrf = 4;
1356 vrf_id_t vrf_id = VRF_DEFAULT;
1357
1358 if (argc == 5)
1359 VRF_GET_ID(vrf_id, argv[idx_vrf]->arg);
1360
1361 zebra_print_rnh_table(vrf_id, AF_INET6, vty, RNH_NEXTHOP_TYPE);
1362 return CMD_SUCCESS;
1363 }
1364
1365
1366 DEFUN (show_ipv6_nht_vrf_all,
1367 show_ipv6_nht_vrf_all_cmd,
1368 "show ipv6 nht vrf all",
1369 SHOW_STR
1370 IP_STR
1371 "IPv6 nexthop tracking table\n"
1372 VRF_ALL_CMD_HELP_STR)
1373 {
1374 struct vrf *vrf;
1375 struct zebra_vrf *zvrf;
1376
1377 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
1378 if ((zvrf = vrf->info) != NULL) {
1379 vty_out(vty, "\nVRF %s:\n", zvrf_name(zvrf));
1380 zebra_print_rnh_table(zvrf_id(zvrf), AF_INET6, vty,
1381 RNH_NEXTHOP_TYPE);
1382 }
1383
1384 return CMD_SUCCESS;
1385 }
1386
1387 DEFUN (ip_nht_default_route,
1388 ip_nht_default_route_cmd,
1389 "ip nht resolve-via-default",
1390 IP_STR
1391 "Filter Next Hop tracking route resolution\n"
1392 "Resolve via default route\n")
1393 {
1394 if (zebra_rnh_ip_default_route)
1395 return CMD_SUCCESS;
1396
1397 zebra_rnh_ip_default_route = 1;
1398 zebra_evaluate_rnh(VRF_DEFAULT, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
1399 return CMD_SUCCESS;
1400 }
1401
1402 DEFUN (no_ip_nht_default_route,
1403 no_ip_nht_default_route_cmd,
1404 "no ip nht resolve-via-default",
1405 NO_STR
1406 IP_STR
1407 "Filter Next Hop tracking route resolution\n"
1408 "Resolve via default route\n")
1409 {
1410 if (!zebra_rnh_ip_default_route)
1411 return CMD_SUCCESS;
1412
1413 zebra_rnh_ip_default_route = 0;
1414 zebra_evaluate_rnh(VRF_DEFAULT, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
1415 return CMD_SUCCESS;
1416 }
1417
1418 DEFUN (ipv6_nht_default_route,
1419 ipv6_nht_default_route_cmd,
1420 "ipv6 nht resolve-via-default",
1421 IP6_STR
1422 "Filter Next Hop tracking route resolution\n"
1423 "Resolve via default route\n")
1424 {
1425 if (zebra_rnh_ipv6_default_route)
1426 return CMD_SUCCESS;
1427
1428 zebra_rnh_ipv6_default_route = 1;
1429 zebra_evaluate_rnh(VRF_DEFAULT, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL);
1430 return CMD_SUCCESS;
1431 }
1432
1433 DEFUN (no_ipv6_nht_default_route,
1434 no_ipv6_nht_default_route_cmd,
1435 "no ipv6 nht resolve-via-default",
1436 NO_STR
1437 IP6_STR
1438 "Filter Next Hop tracking route resolution\n"
1439 "Resolve via default route\n")
1440 {
1441 if (!zebra_rnh_ipv6_default_route)
1442 return CMD_SUCCESS;
1443
1444 zebra_rnh_ipv6_default_route = 0;
1445 zebra_evaluate_rnh(VRF_DEFAULT, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL);
1446 return CMD_SUCCESS;
1447 }
1448
1449 DEFPY (show_route,
1450 show_route_cmd,
1451 "show\
1452 <\
1453 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1454 [{\
1455 tag (1-4294967295)\
1456 |A.B.C.D/M$prefix longer-prefixes\
1457 |supernets-only$supernets_only\
1458 }]\
1459 [<\
1460 " FRR_IP_REDIST_STR_ZEBRA "$type_str\
1461 |ospf$type_str (1-65535)$ospf_instance_id\
1462 >]\
1463 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1464 [{\
1465 tag (1-4294967295)\
1466 |X:X::X:X/M$prefix longer-prefixes\
1467 }]\
1468 [" FRR_IP6_REDIST_STR_ZEBRA "$type_str]\
1469 >\
1470 [json$json]",
1471 SHOW_STR
1472 IP_STR
1473 "IP forwarding table\n"
1474 "IP routing table\n"
1475 VRF_FULL_CMD_HELP_STR
1476 "Show only routes with tag\n"
1477 "Tag value\n"
1478 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1479 "Show route matching the specified Network/Mask pair only\n"
1480 "Show supernet entries only\n"
1481 FRR_IP_REDIST_HELP_STR_ZEBRA
1482 "Open Shortest Path First (OSPFv2)\n"
1483 "Instance ID\n"
1484 IPV6_STR
1485 "IP forwarding table\n"
1486 "IP routing table\n"
1487 VRF_FULL_CMD_HELP_STR
1488 "Show only routes with tag\n"
1489 "Tag value\n"
1490 "IPv6 prefix\n"
1491 "Show route matching the specified Network/Mask pair only\n"
1492 FRR_IP6_REDIST_HELP_STR_ZEBRA
1493 JSON_STR)
1494 {
1495 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
1496 struct vrf *vrf;
1497 int type = 0;
1498
1499 if (type_str) {
1500 type = proto_redistnum(afi, type_str);
1501 if (type < 0) {
1502 vty_out(vty, "Unknown route type\n");
1503 return CMD_WARNING;
1504 }
1505 }
1506
1507 if (vrf_all) {
1508 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
1509 struct zebra_vrf *zvrf;
1510 struct route_table *table;
1511
1512 if ((zvrf = vrf->info) == NULL
1513 || (table = zvrf->table[afi][SAFI_UNICAST]) == NULL)
1514 continue;
1515
1516 do_show_ip_route(
1517 vty, zvrf_name(zvrf), afi, SAFI_UNICAST, !!fib,
1518 !!json, tag, prefix_str ? prefix : NULL,
1519 !!supernets_only, type, ospf_instance_id);
1520 }
1521 } else {
1522 vrf_id_t vrf_id = VRF_DEFAULT;
1523
1524 if (vrf_name)
1525 VRF_GET_ID(vrf_id, vrf_name);
1526 vrf = vrf_lookup_by_id(vrf_id);
1527 do_show_ip_route(vty, vrf->name, afi, SAFI_UNICAST, !!fib,
1528 !!json, tag, prefix_str ? prefix : NULL,
1529 !!supernets_only, type, ospf_instance_id);
1530 }
1531
1532 return CMD_SUCCESS;
1533 }
1534
1535 DEFPY (show_route_detail,
1536 show_route_detail_cmd,
1537 "show\
1538 <\
1539 ip$ipv4 route [vrf <NAME$vrf_name|all$vrf_all>]\
1540 <\
1541 A.B.C.D$address\
1542 |A.B.C.D/M$prefix\
1543 >\
1544 |ipv6$ipv6 route [vrf <NAME$vrf_name|all$vrf_all>]\
1545 <\
1546 X:X::X:X$address\
1547 |X:X::X:X/M$prefix\
1548 >\
1549 >",
1550 SHOW_STR
1551 IP_STR
1552 "IP routing table\n"
1553 VRF_FULL_CMD_HELP_STR
1554 "Network in the IP routing table to display\n"
1555 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1556 IP6_STR
1557 "IP routing table\n"
1558 VRF_FULL_CMD_HELP_STR
1559 "IPv6 Address\n"
1560 "IPv6 prefix\n")
1561 {
1562 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
1563 struct route_table *table;
1564 struct prefix p;
1565 struct route_node *rn;
1566
1567 if (address_str)
1568 prefix_str = address_str;
1569 if (str2prefix(prefix_str, &p) < 0) {
1570 vty_out(vty, "%% Malformed address\n");
1571 return CMD_WARNING;
1572 }
1573
1574 if (vrf_all) {
1575 struct vrf *vrf;
1576 struct zebra_vrf *zvrf;
1577
1578 RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) {
1579 if ((zvrf = vrf->info) == NULL
1580 || (table = zvrf->table[afi][SAFI_UNICAST]) == NULL)
1581 continue;
1582
1583 rn = route_node_match(table, &p);
1584 if (!rn)
1585 continue;
1586 if (!address_str && rn->p.prefixlen != p.prefixlen) {
1587 route_unlock_node(rn);
1588 continue;
1589 }
1590
1591 vty_show_ip_route_detail(vty, rn, 0);
1592
1593 route_unlock_node(rn);
1594 }
1595 } else {
1596 vrf_id_t vrf_id = VRF_DEFAULT;
1597
1598 if (vrf_name)
1599 VRF_GET_ID(vrf_id, vrf_name);
1600
1601 table = zebra_vrf_table(afi, SAFI_UNICAST, vrf_id);
1602 if (!table)
1603 return CMD_SUCCESS;
1604
1605 rn = route_node_match(table, &p);
1606 if (!rn) {
1607 vty_out(vty, "%% Network not in table\n");
1608 return CMD_WARNING;
1609 }
1610 if (!address_str && rn->p.prefixlen != p.prefixlen) {
1611 vty_out(vty, "%% Network not in table\n");
1612 route_unlock_node(rn);
1613 return CMD_WARNING;
1614 }
1615
1616 vty_show_ip_route_detail(vty, rn, 0);
1617
1618 route_unlock_node(rn);
1619 }
1620
1621 return CMD_SUCCESS;
1622 }
1623
1624 DEFPY (show_route_summary,
1625 show_route_summary_cmd,
1626 "show\
1627 <\
1628 ip$ipv4 route [vrf <NAME$vrf_name|all$vrf_all>]\
1629 summary [prefix$prefix]\
1630 |ipv6$ipv6 route [vrf <NAME$vrf_name|all$vrf_all>]\
1631 summary [prefix$prefix]\
1632 >",
1633 SHOW_STR
1634 IP_STR
1635 "IP routing table\n"
1636 VRF_FULL_CMD_HELP_STR
1637 "Summary of all routes\n"
1638 "Prefix routes\n"
1639 IP6_STR
1640 "IP routing table\n"
1641 VRF_FULL_CMD_HELP_STR
1642 "Summary of all routes\n"
1643 "Prefix routes\n")
1644 {
1645 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
1646 struct route_table *table;
1647
1648 if (vrf_all) {
1649 struct vrf *vrf;
1650 struct zebra_vrf *zvrf;
1651
1652 RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) {
1653 if ((zvrf = vrf->info) == NULL
1654 || (table = zvrf->table[afi][SAFI_UNICAST]) == NULL)
1655 continue;
1656
1657 if (prefix)
1658 vty_show_ip_route_summary_prefix(vty, table);
1659 else
1660 vty_show_ip_route_summary(vty, table);
1661 }
1662 } else {
1663 vrf_id_t vrf_id = VRF_DEFAULT;
1664
1665 if (vrf_name)
1666 VRF_GET_ID(vrf_id, vrf_name);
1667
1668 table = zebra_vrf_table(afi, SAFI_UNICAST, vrf_id);
1669 if (!table)
1670 return CMD_SUCCESS;
1671
1672 if (prefix)
1673 vty_show_ip_route_summary_prefix(vty, table);
1674 else
1675 vty_show_ip_route_summary(vty, table);
1676 }
1677
1678 return CMD_SUCCESS;
1679 }
1680
1681 static void vty_show_ip_route_summary(struct vty *vty,
1682 struct route_table *table)
1683 {
1684 struct route_node *rn;
1685 struct route_entry *re;
1686 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1687 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1688 u_int32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1689 u_int32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1690 u_int32_t i;
1691 u_int32_t is_ibgp;
1692
1693 memset(&rib_cnt, 0, sizeof(rib_cnt));
1694 memset(&fib_cnt, 0, sizeof(fib_cnt));
1695 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
1696 RNODE_FOREACH_RE (rn, re) {
1697 is_ibgp = (re->type == ZEBRA_ROUTE_BGP
1698 && CHECK_FLAG(re->flags, ZEBRA_FLAG_IBGP));
1699
1700 rib_cnt[ZEBRA_ROUTE_TOTAL]++;
1701 if (is_ibgp)
1702 rib_cnt[ZEBRA_ROUTE_IBGP]++;
1703 else
1704 rib_cnt[re->type]++;
1705
1706 if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED)) {
1707 fib_cnt[ZEBRA_ROUTE_TOTAL]++;
1708
1709 if (is_ibgp)
1710 fib_cnt[ZEBRA_ROUTE_IBGP]++;
1711 else
1712 fib_cnt[re->type]++;
1713 }
1714 }
1715
1716 vty_out(vty, "%-20s %-20s %s (vrf %s)\n", "Route Source", "Routes",
1717 "FIB", zvrf_name(((rib_table_info_t *)table->info)->zvrf));
1718
1719 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
1720 if ((rib_cnt[i] > 0) || (i == ZEBRA_ROUTE_BGP
1721 && rib_cnt[ZEBRA_ROUTE_IBGP] > 0)) {
1722 if (i == ZEBRA_ROUTE_BGP) {
1723 vty_out(vty, "%-20s %-20d %-20d \n", "ebgp",
1724 rib_cnt[ZEBRA_ROUTE_BGP],
1725 fib_cnt[ZEBRA_ROUTE_BGP]);
1726 vty_out(vty, "%-20s %-20d %-20d \n", "ibgp",
1727 rib_cnt[ZEBRA_ROUTE_IBGP],
1728 fib_cnt[ZEBRA_ROUTE_IBGP]);
1729 } else
1730 vty_out(vty, "%-20s %-20d %-20d \n",
1731 zebra_route_string(i), rib_cnt[i],
1732 fib_cnt[i]);
1733 }
1734 }
1735
1736 vty_out(vty, "------\n");
1737 vty_out(vty, "%-20s %-20d %-20d \n", "Totals",
1738 rib_cnt[ZEBRA_ROUTE_TOTAL], fib_cnt[ZEBRA_ROUTE_TOTAL]);
1739 vty_out(vty, "\n");
1740 }
1741
1742 /*
1743 * Implementation of the ip route summary prefix command.
1744 *
1745 * This command prints the primary prefixes that have been installed by various
1746 * protocols on the box.
1747 *
1748 */
1749 static void vty_show_ip_route_summary_prefix(struct vty *vty,
1750 struct route_table *table)
1751 {
1752 struct route_node *rn;
1753 struct route_entry *re;
1754 struct nexthop *nexthop;
1755 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1756 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1757 u_int32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1758 u_int32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1759 u_int32_t i;
1760 int cnt;
1761
1762 memset(&rib_cnt, 0, sizeof(rib_cnt));
1763 memset(&fib_cnt, 0, sizeof(fib_cnt));
1764 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
1765 RNODE_FOREACH_RE (rn, re) {
1766
1767 /*
1768 * In case of ECMP, count only once.
1769 */
1770 cnt = 0;
1771 for (nexthop = re->nexthop; (!cnt && nexthop);
1772 nexthop = nexthop->next) {
1773 cnt++;
1774 rib_cnt[ZEBRA_ROUTE_TOTAL]++;
1775 rib_cnt[re->type]++;
1776 if (CHECK_FLAG(nexthop->flags,
1777 NEXTHOP_FLAG_FIB)) {
1778 fib_cnt[ZEBRA_ROUTE_TOTAL]++;
1779 fib_cnt[re->type]++;
1780 }
1781 if (re->type == ZEBRA_ROUTE_BGP
1782 && CHECK_FLAG(re->flags, ZEBRA_FLAG_IBGP)) {
1783 rib_cnt[ZEBRA_ROUTE_IBGP]++;
1784 if (CHECK_FLAG(nexthop->flags,
1785 NEXTHOP_FLAG_FIB))
1786 fib_cnt[ZEBRA_ROUTE_IBGP]++;
1787 }
1788 }
1789 }
1790
1791 vty_out(vty, "%-20s %-20s %s (vrf %s)\n", "Route Source",
1792 "Prefix Routes", "FIB",
1793 zvrf_name(((rib_table_info_t *)table->info)->zvrf));
1794
1795 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
1796 if (rib_cnt[i] > 0) {
1797 if (i == ZEBRA_ROUTE_BGP) {
1798 vty_out(vty, "%-20s %-20d %-20d \n", "ebgp",
1799 rib_cnt[ZEBRA_ROUTE_BGP]
1800 - rib_cnt[ZEBRA_ROUTE_IBGP],
1801 fib_cnt[ZEBRA_ROUTE_BGP]
1802 - fib_cnt[ZEBRA_ROUTE_IBGP]);
1803 vty_out(vty, "%-20s %-20d %-20d \n", "ibgp",
1804 rib_cnt[ZEBRA_ROUTE_IBGP],
1805 fib_cnt[ZEBRA_ROUTE_IBGP]);
1806 } else
1807 vty_out(vty, "%-20s %-20d %-20d \n",
1808 zebra_route_string(i), rib_cnt[i],
1809 fib_cnt[i]);
1810 }
1811 }
1812
1813 vty_out(vty, "------\n");
1814 vty_out(vty, "%-20s %-20d %-20d \n", "Totals",
1815 rib_cnt[ZEBRA_ROUTE_TOTAL], fib_cnt[ZEBRA_ROUTE_TOTAL]);
1816 vty_out(vty, "\n");
1817 }
1818
1819 /* Write static route configuration. */
1820 int static_config(struct vty *vty, struct zebra_vrf *zvrf,
1821 afi_t afi, safi_t safi, const char *cmd)
1822 {
1823 char spacing[100];
1824 struct route_node *rn;
1825 struct static_route *si;
1826 struct route_table *stable;
1827 char buf[SRCDEST2STR_BUFFER];
1828 int write = 0;
1829
1830 if ((stable = zvrf->stable[afi][safi]) == NULL)
1831 return write;
1832
1833 sprintf(spacing, "%s%s",
1834 (zvrf->vrf->vrf_id == VRF_DEFAULT) ? "" : " ",
1835 cmd);
1836
1837 for (rn = route_top(stable); rn; rn = srcdest_route_next(rn))
1838 for (si = rn->info; si; si = si->next) {
1839 vty_out(vty, "%s %s", spacing,
1840 srcdest_rnode2str(rn, buf, sizeof buf));
1841
1842 switch (si->type) {
1843 case STATIC_IPV4_GATEWAY:
1844 vty_out(vty, " %s",
1845 inet_ntoa(si->addr.ipv4));
1846 break;
1847 case STATIC_IPV6_GATEWAY:
1848 vty_out(vty, " %s",
1849 inet_ntop(AF_INET6,
1850 &si->addr.ipv6, buf,
1851 sizeof buf));
1852 break;
1853 case STATIC_IFNAME:
1854 vty_out(vty, " %s", si->ifname);
1855 break;
1856 case STATIC_BLACKHOLE:
1857 switch (si->bh_type) {
1858 case STATIC_BLACKHOLE_DROP:
1859 vty_out(vty, " blackhole");
1860 break;
1861 case STATIC_BLACKHOLE_NULL:
1862 vty_out(vty, " Null0");
1863 break;
1864 case STATIC_BLACKHOLE_REJECT:
1865 vty_out(vty, " reject");
1866 break;
1867 }
1868 break;
1869 case STATIC_IPV4_GATEWAY_IFNAME:
1870 vty_out(vty, " %s %s",
1871 inet_ntop(AF_INET,
1872 &si->addr.ipv4, buf,
1873 sizeof buf),
1874 si->ifname);
1875 break;
1876 case STATIC_IPV6_GATEWAY_IFNAME:
1877 vty_out(vty, " %s %s",
1878 inet_ntop(AF_INET6,
1879 &si->addr.ipv6, buf,
1880 sizeof buf),
1881 si->ifname);
1882 break;
1883 }
1884
1885 if (si->tag)
1886 vty_out(vty, " tag %" ROUTE_TAG_PRI,
1887 si->tag);
1888
1889 if (si->distance
1890 != ZEBRA_STATIC_DISTANCE_DEFAULT)
1891 vty_out(vty, " %d", si->distance);
1892
1893 if (si->nh_vrf_id != si->vrf_id) {
1894 struct vrf *vrf;
1895
1896 vrf = vrf_lookup_by_id(si->nh_vrf_id);
1897 vty_out(vty, " nexthop-vrf %s",
1898 (vrf) ? vrf->name : "Unknown");
1899 }
1900
1901 /* Label information */
1902 if (si->snh_label.num_labels)
1903 vty_out(vty, " label %s",
1904 mpls_label2str(si->snh_label.num_labels,
1905 si->snh_label.label,
1906 buf, sizeof buf, 0));
1907
1908 vty_out(vty, "\n");
1909
1910 write = 1;
1911 }
1912 return write;
1913 }
1914
1915 DEFPY(ipv6_route_blackhole,
1916 ipv6_route_blackhole_cmd,
1917 "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
1918 <Null0|reject|blackhole>$flag \
1919 [{ \
1920 tag (1-4294967295) \
1921 |(1-255)$distance \
1922 |vrf NAME \
1923 |label WORD \
1924 }]",
1925 NO_STR
1926 IPV6_STR
1927 "Establish static routes\n"
1928 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1929 "IPv6 source-dest route\n"
1930 "IPv6 source prefix\n"
1931 "Null interface\n"
1932 "Emit an ICMP unreachable when matched\n"
1933 "Silently discard pkts when matched\n"
1934 "Set tag for this route\n"
1935 "Tag value\n"
1936 "Distance value for this prefix\n"
1937 VRF_CMD_HELP_STR
1938 MPLS_LABEL_HELPSTR)
1939 {
1940 return zebra_static_route(vty, AFI_IP6, SAFI_UNICAST, no, prefix_str,
1941 NULL, from_str, NULL, NULL, flag,
1942 tag_str, distance_str, vrf, label);
1943 }
1944
1945 DEFPY(ipv6_route_blackhole_vrf,
1946 ipv6_route_blackhole_vrf_cmd,
1947 "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
1948 <Null0|reject|blackhole>$flag \
1949 [{ \
1950 tag (1-4294967295) \
1951 |(1-255)$distance \
1952 |label WORD \
1953 }]",
1954 NO_STR
1955 IPV6_STR
1956 "Establish static routes\n"
1957 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1958 "IPv6 source-dest route\n"
1959 "IPv6 source prefix\n"
1960 "Null interface\n"
1961 "Emit an ICMP unreachable when matched\n"
1962 "Silently discard pkts when matched\n"
1963 "Set tag for this route\n"
1964 "Tag value\n"
1965 "Distance value for this prefix\n"
1966 MPLS_LABEL_HELPSTR)
1967 {
1968 VTY_DECLVAR_CONTEXT(vrf, vrf);
1969 struct zebra_vrf *zvrf = vrf->info;
1970
1971 return zebra_static_route_leak(vty, zvrf, zvrf,
1972 AFI_IP6, SAFI_UNICAST, no, prefix_str,
1973 NULL, from_str, NULL, NULL, flag,
1974 tag_str, distance_str, label);
1975 }
1976
1977 DEFPY(ipv6_route_address_interface,
1978 ipv6_route_address_interface_cmd,
1979 "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
1980 X:X::X:X$gate \
1981 INTERFACE$ifname \
1982 [{ \
1983 tag (1-4294967295) \
1984 |(1-255)$distance \
1985 |vrf NAME \
1986 |label WORD \
1987 |nexthop-vrf NAME \
1988 }]",
1989 NO_STR
1990 IPV6_STR
1991 "Establish static routes\n"
1992 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1993 "IPv6 source-dest route\n"
1994 "IPv6 source prefix\n"
1995 "IPv6 gateway address\n"
1996 "IPv6 gateway interface name\n"
1997 "Set tag for this route\n"
1998 "Tag value\n"
1999 "Distance value for this prefix\n"
2000 VRF_CMD_HELP_STR
2001 MPLS_LABEL_HELPSTR
2002 VRF_CMD_HELP_STR)
2003 {
2004 struct zebra_vrf *zvrf;
2005 struct zebra_vrf *nh_zvrf;
2006
2007 nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf);
2008 if (!nh_zvrf) {
2009 vty_out(vty, "%% nexthop vrf %s is not defined\n",
2010 nexthop_vrf);
2011 return CMD_WARNING_CONFIG_FAILED;
2012 }
2013
2014 zvrf = zebra_vrf_lookup_by_name(vrf);
2015 if (!nh_zvrf) {
2016 vty_out(vty, "%% nexthop vrf %s is not defined\n",
2017 vrf);
2018 return CMD_WARNING_CONFIG_FAILED;
2019 }
2020
2021 return zebra_static_route_leak(vty, zvrf, nh_zvrf,
2022 AFI_IP6, SAFI_UNICAST, no, prefix_str,
2023 NULL, from_str, gate_str, ifname, NULL,
2024 tag_str, distance_str, label);
2025 }
2026
2027 DEFPY(ipv6_route_address_interface_vrf,
2028 ipv6_route_address_interface_vrf_cmd,
2029 "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
2030 X:X::X:X$gate \
2031 INTERFACE$ifname \
2032 [{ \
2033 tag (1-4294967295) \
2034 |(1-255)$distance \
2035 |label WORD \
2036 |nexthop-vrf NAME \
2037 }]",
2038 NO_STR
2039 IPV6_STR
2040 "Establish static routes\n"
2041 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2042 "IPv6 source-dest route\n"
2043 "IPv6 source prefix\n"
2044 "IPv6 gateway address\n"
2045 "IPv6 gateway interface name\n"
2046 "Set tag for this route\n"
2047 "Tag value\n"
2048 "Distance value for this prefix\n"
2049 MPLS_LABEL_HELPSTR
2050 VRF_CMD_HELP_STR)
2051 {
2052 VTY_DECLVAR_CONTEXT(vrf, vrf);
2053 struct zebra_vrf *zvrf = vrf->info;
2054 struct zebra_vrf *nh_zvrf;
2055
2056 nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf);
2057 if (!nh_zvrf) {
2058 vty_out(vty, "%% nexthop vrf %s is not defined\n",
2059 nexthop_vrf);
2060 return CMD_WARNING_CONFIG_FAILED;
2061 }
2062
2063 return zebra_static_route_leak(vty, zvrf, nh_zvrf,
2064 AFI_IP6, SAFI_UNICAST, no, prefix_str,
2065 NULL, from_str, gate_str, ifname, NULL,
2066 tag_str, distance_str, label);
2067 }
2068
2069 DEFPY(ipv6_route,
2070 ipv6_route_cmd,
2071 "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
2072 <X:X::X:X$gate|INTERFACE$ifname> \
2073 [{ \
2074 tag (1-4294967295) \
2075 |(1-255)$distance \
2076 |vrf NAME \
2077 |label WORD \
2078 |nexthop-vrf NAME \
2079 }]",
2080 NO_STR
2081 IPV6_STR
2082 "Establish static routes\n"
2083 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2084 "IPv6 source-dest route\n"
2085 "IPv6 source prefix\n"
2086 "IPv6 gateway address\n"
2087 "IPv6 gateway interface name\n"
2088 "Set tag for this route\n"
2089 "Tag value\n"
2090 "Distance value for this prefix\n"
2091 VRF_CMD_HELP_STR
2092 MPLS_LABEL_HELPSTR
2093 VRF_CMD_HELP_STR)
2094 {
2095 struct zebra_vrf *zvrf;
2096 struct zebra_vrf *nh_zvrf;
2097
2098 nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf);
2099 if (!nh_zvrf) {
2100 vty_out(vty, "%% nexthop vrf %s is not defined\n",
2101 nexthop_vrf);
2102 return CMD_WARNING_CONFIG_FAILED;
2103 }
2104
2105 zvrf = zebra_vrf_lookup_by_name(vrf);
2106 if (!nh_zvrf) {
2107 vty_out(vty, "%% nexthop vrf %s is not defined\n",
2108 vrf);
2109 return CMD_WARNING_CONFIG_FAILED;
2110 }
2111
2112 return zebra_static_route_leak(vty, zvrf, nh_zvrf,
2113 AFI_IP6, SAFI_UNICAST, no, prefix_str,
2114 NULL, from_str, gate_str, ifname, NULL,
2115 tag_str, distance_str, label);
2116 }
2117
2118 DEFPY(ipv6_route_vrf,
2119 ipv6_route_vrf_cmd,
2120 "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
2121 <X:X::X:X$gate|INTERFACE$ifname> \
2122 [{ \
2123 tag (1-4294967295) \
2124 |(1-255)$distance \
2125 |label WORD \
2126 |nexthop-vrf NAME \
2127 }]",
2128 NO_STR
2129 IPV6_STR
2130 "Establish static routes\n"
2131 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2132 "IPv6 source-dest route\n"
2133 "IPv6 source prefix\n"
2134 "IPv6 gateway address\n"
2135 "IPv6 gateway interface name\n"
2136 "Set tag for this route\n"
2137 "Tag value\n"
2138 "Distance value for this prefix\n"
2139 MPLS_LABEL_HELPSTR
2140 VRF_CMD_HELP_STR)
2141 {
2142 VTY_DECLVAR_CONTEXT(vrf, vrf);
2143 struct zebra_vrf *zvrf = vrf->info;
2144 struct zebra_vrf *nh_zvrf;
2145
2146 nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf);
2147 if (!nh_zvrf) {
2148 vty_out(vty, "%% nexthop vrf %s is not defined\n",
2149 nexthop_vrf);
2150 return CMD_WARNING_CONFIG_FAILED;
2151 }
2152
2153 return zebra_static_route_leak(vty, zvrf, nh_zvrf,
2154 AFI_IP6, SAFI_UNICAST, no, prefix_str,
2155 NULL, from_str, gate_str, ifname, NULL,
2156 tag_str, distance_str, label);
2157 }
2158
2159 /*
2160 * Show IPv6 mroute command.Used to dump
2161 * the Multicast routing table.
2162 */
2163 DEFUN (show_ipv6_mroute,
2164 show_ipv6_mroute_cmd,
2165 "show ipv6 mroute [vrf NAME]",
2166 SHOW_STR
2167 IP_STR
2168 "IPv6 Multicast routing table\n"
2169 VRF_CMD_HELP_STR)
2170 {
2171 struct route_table *table;
2172 struct route_node *rn;
2173 struct route_entry *re;
2174 int first = 1;
2175 vrf_id_t vrf_id = VRF_DEFAULT;
2176
2177 if (argc == 5)
2178 VRF_GET_ID(vrf_id, argv[4]->arg);
2179
2180 table = zebra_vrf_table(AFI_IP6, SAFI_MULTICAST, vrf_id);
2181 if (!table)
2182 return CMD_SUCCESS;
2183
2184 /* Show all IPv6 route. */
2185 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
2186 RNODE_FOREACH_RE (rn, re) {
2187 if (first) {
2188 vty_out(vty, SHOW_ROUTE_V6_HEADER);
2189 first = 0;
2190 }
2191 vty_show_ip_route(vty, rn, re, NULL);
2192 }
2193 return CMD_SUCCESS;
2194 }
2195
2196 DEFUN (show_ipv6_mroute_vrf_all,
2197 show_ipv6_mroute_vrf_all_cmd,
2198 "show ipv6 mroute vrf all",
2199 SHOW_STR
2200 IP_STR
2201 "IPv6 Multicast routing table\n"
2202 VRF_ALL_CMD_HELP_STR)
2203 {
2204 struct route_table *table;
2205 struct route_node *rn;
2206 struct route_entry *re;
2207 struct vrf *vrf;
2208 struct zebra_vrf *zvrf;
2209 int first = 1;
2210
2211 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
2212 if ((zvrf = vrf->info) == NULL
2213 || (table = zvrf->table[AFI_IP6][SAFI_MULTICAST]) == NULL)
2214 continue;
2215
2216 /* Show all IPv6 route. */
2217 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
2218 RNODE_FOREACH_RE (rn, re) {
2219 if (first) {
2220 vty_out(vty, SHOW_ROUTE_V6_HEADER);
2221 first = 0;
2222 }
2223 vty_show_ip_route(vty, rn, re, NULL);
2224 }
2225 }
2226 return CMD_SUCCESS;
2227 }
2228
2229 DEFUN (allow_external_route_update,
2230 allow_external_route_update_cmd,
2231 "allow-external-route-update",
2232 "Allow FRR routes to be overwritten by external processes\n")
2233 {
2234 allow_delete = 1;
2235
2236 return CMD_SUCCESS;
2237 }
2238
2239 DEFUN (no_allow_external_route_update,
2240 no_allow_external_route_update_cmd,
2241 "no allow-external-route-update",
2242 NO_STR
2243 "Allow FRR routes to be overwritten by external processes\n")
2244 {
2245 allow_delete = 0;
2246
2247 return CMD_SUCCESS;
2248 }
2249
2250 /* show vrf */
2251 DEFUN (show_vrf,
2252 show_vrf_cmd,
2253 "show vrf",
2254 SHOW_STR
2255 "VRF\n")
2256 {
2257 struct vrf *vrf;
2258 struct zebra_vrf *zvrf;
2259
2260 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
2261 if (!(zvrf = vrf->info))
2262 continue;
2263 if (zvrf_id(zvrf) == VRF_DEFAULT)
2264 continue;
2265
2266 vty_out(vty, "vrf %s ", zvrf_name(zvrf));
2267 if (zvrf_id(zvrf) == VRF_UNKNOWN)
2268 vty_out(vty, "inactive");
2269 else
2270 vty_out(vty, "id %u table %u", zvrf_id(zvrf),
2271 zvrf->table_id);
2272 vty_out(vty, "\n");
2273 }
2274
2275 return CMD_SUCCESS;
2276 }
2277
2278 DEFUN (vrf_vni_mapping,
2279 vrf_vni_mapping_cmd,
2280 "vni " CMD_VNI_RANGE,
2281 "VNI\n"
2282 "VNI-ID\n")
2283 {
2284 int ret = 0;
2285
2286 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
2287 vni_t vni = strtoul(argv[1]->arg, NULL, 10);
2288 char err[ERR_STR_SZ];
2289
2290 assert(vrf);
2291 assert(zvrf);
2292
2293 ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ, 1);
2294 if (ret != 0) {
2295 vty_out(vty, "%s\n", err);
2296 return CMD_WARNING;
2297 }
2298
2299 return CMD_SUCCESS;
2300 }
2301
2302 DEFUN (no_vrf_vni_mapping,
2303 no_vrf_vni_mapping_cmd,
2304 "no vni " CMD_VNI_RANGE,
2305 NO_STR
2306 "VNI\n"
2307 "VNI-ID")
2308 {
2309 int ret = 0;
2310 char err[ERR_STR_SZ];
2311 vni_t vni = strtoul(argv[2]->arg, NULL, 10);
2312
2313 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
2314
2315 assert(vrf);
2316 assert(zvrf);
2317
2318 ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ, 0);
2319 if (ret != 0) {
2320 vty_out(vty, "%s\n", err);
2321 return CMD_WARNING;
2322 }
2323
2324 return CMD_SUCCESS;
2325 }
2326
2327 /* show vrf */
2328 DEFUN (show_vrf_vni,
2329 show_vrf_vni_cmd,
2330 "show vrf vni [json]",
2331 SHOW_STR
2332 "VRF\n"
2333 "VNI\n"
2334 JSON_STR)
2335 {
2336 struct vrf *vrf;
2337 struct zebra_vrf *zvrf;
2338 json_object *json = NULL;
2339 json_object *json_vrfs = NULL;
2340 u_char uj = use_json(argc, argv);
2341
2342 if (uj) {
2343 json = json_object_new_object();
2344 json_vrfs = json_object_new_array();
2345 }
2346
2347 RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) {
2348 zvrf = vrf->info;
2349 if (!zvrf)
2350 continue;
2351
2352 if (!zvrf->l3vni)
2353 continue;
2354
2355 if (!uj) {
2356 vty_out(vty, "vrf: %s VNI: %u",
2357 zvrf_name(zvrf),
2358 zvrf->l3vni);
2359 vty_out(vty, "\n");
2360 } else {
2361 json_object *json_vrf = NULL;
2362
2363 json_vrf = json_object_new_object();
2364 json_object_string_add(json_vrf, "vrf",
2365 zvrf_name(zvrf));
2366 json_object_int_add(json_vrf, "l3vni",
2367 zvrf->l3vni);
2368 json_object_array_add(json_vrfs, json_vrf);
2369 }
2370 }
2371
2372 if (uj) {
2373 json_object_object_add(json, "vrfs", json_vrfs);
2374 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2375 json, JSON_C_TO_STRING_PRETTY));
2376 json_object_free(json);
2377 }
2378
2379 return CMD_SUCCESS;
2380 }
2381
2382 DEFUN (show_evpn_vni,
2383 show_evpn_vni_cmd,
2384 "show evpn vni [json]",
2385 SHOW_STR
2386 "EVPN\n"
2387 "VxLAN information\n"
2388 JSON_STR)
2389 {
2390 struct zebra_vrf *zvrf;
2391 u_char uj = use_json(argc, argv);
2392
2393 zvrf = vrf_info_lookup(VRF_DEFAULT);
2394 zebra_vxlan_print_vnis(vty, zvrf, uj);
2395 return CMD_SUCCESS;
2396 }
2397
2398 DEFUN (show_evpn_vni_vni,
2399 show_evpn_vni_vni_cmd,
2400 "show evpn vni " CMD_VNI_RANGE "[json]",
2401 SHOW_STR
2402 "EVPN\n"
2403 "VxLAN Network Identifier\n"
2404 "VNI number\n"
2405 JSON_STR)
2406 {
2407 struct zebra_vrf *zvrf;
2408 vni_t vni;
2409 u_char uj = use_json(argc, argv);
2410
2411 vni = strtoul(argv[3]->arg, NULL, 10);
2412 zvrf = vrf_info_lookup(VRF_DEFAULT);
2413 zebra_vxlan_print_vni(vty, zvrf, vni, uj);
2414 return CMD_SUCCESS;
2415 }
2416
2417 DEFUN (show_evpn_l3vni,
2418 show_evpn_l3vni_cmd,
2419 "show evpn l3vni [json]",
2420 SHOW_STR
2421 "EVPN\n"
2422 "L3 VNI\n"
2423 JSON_STR)
2424 {
2425 u_char uj = use_json(argc, argv);
2426
2427 zebra_vxlan_print_l3vnis(vty, uj);
2428 return CMD_SUCCESS;
2429 }
2430
2431 DEFUN (show_evpn_l3vni_vni,
2432 show_evpn_l3vni_vni_cmd,
2433 "show evpn l3vni " CMD_VNI_RANGE "[json]",
2434 SHOW_STR
2435 "EVPN\n"
2436 "L3 VxLAN Network Identifier\n"
2437 "VNI number\n"
2438 JSON_STR)
2439 {
2440 vni_t vni;
2441 u_char uj = use_json(argc, argv);
2442
2443 vni = strtoul(argv[3]->arg, NULL, 10);
2444 zebra_vxlan_print_l3vni(vty, vni, uj);
2445 return CMD_SUCCESS;
2446 }
2447
2448 DEFUN (show_evpn_rmac_l3vni_mac,
2449 show_evpn_rmac_l3vni_mac_cmd,
2450 "show evpn rmac l3vni " CMD_VNI_RANGE " mac WORD [json]",
2451 SHOW_STR
2452 "EVPN\n"
2453 "RMAC\n"
2454 "L3-VNI\n"
2455 "VNI number\n"
2456 "MAC\n"
2457 "mac-address (e.g. 0a:0a:0a:0a:0a:0a)\n"
2458 JSON_STR)
2459 {
2460 vni_t l3vni = 0;
2461 struct ethaddr mac;
2462 u_char uj = use_json(argc, argv);
2463
2464 l3vni = strtoul(argv[4]->arg, NULL, 10);
2465 if (!prefix_str2mac(argv[6]->arg, &mac)) {
2466 vty_out(vty, "%% Malformed MAC address\n");
2467 return CMD_WARNING;
2468 }
2469 zebra_vxlan_print_specific_rmac_l3vni(vty, l3vni, &mac, uj);
2470 return CMD_SUCCESS;
2471 }
2472
2473 DEFUN (show_evpn_rmac_l3vni,
2474 show_evpn_rmac_l3vni_cmd,
2475 "show evpn rmac l3vni " CMD_VNI_RANGE "[json]",
2476 SHOW_STR
2477 "EVPN\n"
2478 "RMAC\n"
2479 "L3-VNI\n"
2480 "VNI number\n"
2481 JSON_STR)
2482 {
2483 vni_t l3vni = 0;
2484 u_char uj = use_json(argc, argv);
2485
2486 l3vni = strtoul(argv[4]->arg, NULL, 10);
2487 zebra_vxlan_print_rmacs_l3vni(vty, l3vni, uj);
2488
2489 return CMD_SUCCESS;
2490 }
2491
2492 DEFUN (show_evpn_rmac_l3vni_all,
2493 show_evpn_rmac_l3vni_all_cmd,
2494 "show evpn rmac l3vni all [json]",
2495 SHOW_STR
2496 "EVPN\n"
2497 "RMAC addresses\n"
2498 "L3-VNI\n"
2499 "All VNIs\n"
2500 JSON_STR)
2501 {
2502 u_char uj = use_json(argc, argv);
2503
2504 zebra_vxlan_print_rmacs_all_l3vni(vty, uj);
2505
2506 return CMD_SUCCESS;
2507 }
2508
2509 DEFUN (show_evpn_nh_l3vni_ip,
2510 show_evpn_nh_l3vni_ip_cmd,
2511 "show evpn next-hops l3vni " CMD_VNI_RANGE " ip WORD [json]",
2512 SHOW_STR
2513 "EVPN\n"
2514 "Remote Vteps\n"
2515 "L3-VNI\n"
2516 "VNI number\n"
2517 "Ip address\n"
2518 "Host address (ipv4 or ipv6)\n"
2519 JSON_STR)
2520 {
2521 vni_t l3vni;
2522 struct ipaddr ip;
2523 u_char uj = use_json(argc, argv);
2524
2525 l3vni = strtoul(argv[4]->arg, NULL, 10);
2526 if (str2ipaddr(argv[6]->arg, &ip) != 0) {
2527 if (!uj)
2528 vty_out(vty, "%% Malformed Neighbor address\n");
2529 return CMD_WARNING;
2530 }
2531 zebra_vxlan_print_specific_nh_l3vni(vty, l3vni, &ip, uj);
2532
2533 return CMD_SUCCESS;
2534 }
2535
2536 DEFUN (show_evpn_nh_l3vni,
2537 show_evpn_nh_l3vni_cmd,
2538 "show evpn next-hops l3vni " CMD_VNI_RANGE "[json]",
2539 SHOW_STR
2540 "EVPN\n"
2541 "Remote Vteps\n"
2542 "L3-VNI\n"
2543 "VNI number\n"
2544 JSON_STR)
2545 {
2546 vni_t l3vni;
2547 u_char uj = use_json(argc, argv);
2548
2549 l3vni = strtoul(argv[4]->arg, NULL, 10);
2550 zebra_vxlan_print_nh_l3vni(vty, l3vni, uj);
2551
2552 return CMD_SUCCESS;
2553 }
2554
2555 DEFUN (show_evpn_nh_l3vni_all,
2556 show_evpn_nh_l3vni_all_cmd,
2557 "show evpn next-hops l3vni all [json]",
2558 SHOW_STR
2559 "EVPN\n"
2560 "Remote VTEPs\n"
2561 "L3-VNI\n"
2562 "All VNIs\n"
2563 JSON_STR)
2564 {
2565 u_char uj = use_json(argc, argv);
2566
2567 zebra_vxlan_print_nh_all_l3vni(vty, uj);
2568
2569 return CMD_SUCCESS;
2570 }
2571
2572 DEFUN (show_evpn_mac_vni,
2573 show_evpn_mac_vni_cmd,
2574 "show evpn mac vni " CMD_VNI_RANGE "[json]",
2575 SHOW_STR
2576 "EVPN\n"
2577 "MAC addresses\n"
2578 "VxLAN Network Identifier\n"
2579 "VNI number\n"
2580 JSON_STR)
2581 {
2582 struct zebra_vrf *zvrf;
2583 vni_t vni;
2584 u_char uj = use_json(argc, argv);
2585
2586 vni = strtoul(argv[4]->arg, NULL, 10);
2587 zvrf = vrf_info_lookup(VRF_DEFAULT);
2588 zebra_vxlan_print_macs_vni(vty, zvrf, vni, uj);
2589 return CMD_SUCCESS;
2590 }
2591
2592 DEFUN (show_evpn_mac_vni_all,
2593 show_evpn_mac_vni_all_cmd,
2594 "show evpn mac vni all [json]",
2595 SHOW_STR
2596 "EVPN\n"
2597 "MAC addresses\n"
2598 "VxLAN Network Identifier\n"
2599 "All VNIs\n"
2600 JSON_STR)
2601 {
2602 struct zebra_vrf *zvrf;
2603 u_char uj = use_json(argc, argv);
2604
2605 zvrf = vrf_info_lookup(VRF_DEFAULT);
2606 zebra_vxlan_print_macs_all_vni(vty, zvrf, uj);
2607 return CMD_SUCCESS;
2608 }
2609
2610 DEFUN (show_evpn_mac_vni_all_vtep,
2611 show_evpn_mac_vni_all_vtep_cmd,
2612 "show evpn mac vni all vtep A.B.C.D [json]",
2613 SHOW_STR
2614 "EVPN\n"
2615 "MAC addresses\n"
2616 "VxLAN Network Identifier\n"
2617 "All VNIs\n"
2618 "Remote VTEP\n"
2619 "Remote VTEP IP address\n"
2620 JSON_STR)
2621 {
2622 struct zebra_vrf *zvrf;
2623 struct in_addr vtep_ip;
2624 u_char uj = use_json(argc, argv);
2625
2626 if (!inet_aton(argv[6]->arg, &vtep_ip)) {
2627 if (!uj)
2628 vty_out(vty, "%% Malformed VTEP IP address\n");
2629 return CMD_WARNING;
2630 }
2631 zvrf = vrf_info_lookup(VRF_DEFAULT);
2632 zebra_vxlan_print_macs_all_vni_vtep(vty, zvrf, vtep_ip, uj);
2633
2634 return CMD_SUCCESS;
2635 }
2636
2637
2638 DEFUN (show_evpn_mac_vni_mac,
2639 show_evpn_mac_vni_mac_cmd,
2640 "show evpn mac vni " CMD_VNI_RANGE " mac WORD",
2641 SHOW_STR
2642 "EVPN\n"
2643 "MAC addresses\n"
2644 "VxLAN Network Identifier\n"
2645 "VNI number\n"
2646 "MAC\n"
2647 "MAC address (e.g., 00:e0:ec:20:12:62)\n")
2648 {
2649 struct zebra_vrf *zvrf;
2650 vni_t vni;
2651 struct ethaddr mac;
2652
2653 vni = strtoul(argv[4]->arg, NULL, 10);
2654 if (!prefix_str2mac(argv[6]->arg, &mac)) {
2655 vty_out(vty, "%% Malformed MAC address");
2656 return CMD_WARNING;
2657 }
2658 zvrf = vrf_info_lookup(VRF_DEFAULT);
2659 zebra_vxlan_print_specific_mac_vni(vty, zvrf, vni, &mac);
2660 return CMD_SUCCESS;
2661 }
2662
2663 DEFUN (show_evpn_mac_vni_vtep,
2664 show_evpn_mac_vni_vtep_cmd,
2665 "show evpn mac vni " CMD_VNI_RANGE " vtep A.B.C.D" "[json]",
2666 SHOW_STR
2667 "EVPN\n"
2668 "MAC addresses\n"
2669 "VxLAN Network Identifier\n"
2670 "VNI number\n"
2671 "Remote VTEP\n"
2672 "Remote VTEP IP address\n"
2673 JSON_STR)
2674 {
2675 struct zebra_vrf *zvrf;
2676 vni_t vni;
2677 struct in_addr vtep_ip;
2678 u_char uj = use_json(argc, argv);
2679
2680 vni = strtoul(argv[4]->arg, NULL, 10);
2681 if (!inet_aton(argv[6]->arg, &vtep_ip)) {
2682 if (!uj)
2683 vty_out(vty, "%% Malformed VTEP IP address\n");
2684 return CMD_WARNING;
2685 }
2686
2687 zvrf = vrf_info_lookup(VRF_DEFAULT);
2688 zebra_vxlan_print_macs_vni_vtep(vty, zvrf, vni, vtep_ip, uj);
2689 return CMD_SUCCESS;
2690 }
2691
2692 DEFUN (show_evpn_neigh_vni,
2693 show_evpn_neigh_vni_cmd,
2694 "show evpn arp-cache vni " CMD_VNI_RANGE "[json]",
2695 SHOW_STR
2696 "EVPN\n"
2697 "ARP and ND cache\n"
2698 "VxLAN Network Identifier\n"
2699 "VNI number\n"
2700 JSON_STR)
2701 {
2702 struct zebra_vrf *zvrf;
2703 vni_t vni;
2704 u_char uj = use_json(argc, argv);
2705
2706 vni = strtoul(argv[4]->arg, NULL, 10);
2707 zvrf = vrf_info_lookup(VRF_DEFAULT);
2708 zebra_vxlan_print_neigh_vni(vty, zvrf, vni, uj);
2709 return CMD_SUCCESS;
2710 }
2711
2712 DEFUN (show_evpn_neigh_vni_all,
2713 show_evpn_neigh_vni_all_cmd,
2714 "show evpn arp-cache vni all [json]",
2715 SHOW_STR
2716 "EVPN\n"
2717 "ARP and ND cache\n"
2718 "VxLAN Network Identifier\n"
2719 "All VNIs\n"
2720 JSON_STR)
2721 {
2722 struct zebra_vrf *zvrf;
2723 u_char uj = use_json(argc, argv);
2724
2725 zvrf = vrf_info_lookup(VRF_DEFAULT);
2726 zebra_vxlan_print_neigh_all_vni(vty, zvrf, uj);
2727 return CMD_SUCCESS;
2728 }
2729
2730 DEFUN (show_evpn_neigh_vni_neigh,
2731 show_evpn_neigh_vni_neigh_cmd,
2732 "show evpn arp-cache vni " CMD_VNI_RANGE " ip WORD [json]",
2733 SHOW_STR
2734 "EVPN\n"
2735 "ARP and ND cache\n"
2736 "VxLAN Network Identifier\n"
2737 "VNI number\n"
2738 "Neighbor\n"
2739 "Neighbor address (IPv4 or IPv6 address)\n"
2740 JSON_STR)
2741 {
2742 struct zebra_vrf *zvrf;
2743 vni_t vni;
2744 struct ipaddr ip;
2745 u_char uj = use_json(argc, argv);
2746
2747 vni = strtoul(argv[4]->arg, NULL, 10);
2748 if (str2ipaddr(argv[6]->arg, &ip) != 0) {
2749 if (!uj)
2750 vty_out(vty, "%% Malformed Neighbor address\n");
2751 return CMD_WARNING;
2752 }
2753 zvrf = vrf_info_lookup(VRF_DEFAULT);
2754 zebra_vxlan_print_specific_neigh_vni(vty, zvrf, vni, &ip, uj);
2755 return CMD_SUCCESS;
2756 }
2757
2758 DEFUN (show_evpn_neigh_vni_vtep,
2759 show_evpn_neigh_vni_vtep_cmd,
2760 "show evpn arp-cache vni " CMD_VNI_RANGE " vtep A.B.C.D [json]",
2761 SHOW_STR
2762 "EVPN\n"
2763 "ARP and ND cache\n"
2764 "VxLAN Network Identifier\n"
2765 "VNI number\n"
2766 "Remote VTEP\n"
2767 "Remote VTEP IP address\n"
2768 JSON_STR)
2769 {
2770 struct zebra_vrf *zvrf;
2771 vni_t vni;
2772 struct in_addr vtep_ip;
2773 u_char uj = use_json(argc, argv);
2774
2775 vni = strtoul(argv[4]->arg, NULL, 10);
2776 if (!inet_aton(argv[6]->arg, &vtep_ip)) {
2777 if (!uj)
2778 vty_out(vty, "%% Malformed VTEP IP address\n");
2779 return CMD_WARNING;
2780 }
2781
2782 zvrf = vrf_info_lookup(VRF_DEFAULT);
2783 zebra_vxlan_print_neigh_vni_vtep(vty, zvrf, vni, vtep_ip, uj);
2784 return CMD_SUCCESS;
2785 }
2786
2787 /* Static ip route configuration write function. */
2788 static int zebra_ip_config(struct vty *vty)
2789 {
2790 int write = 0;
2791
2792 write += zebra_import_table_config(vty);
2793
2794 return write;
2795 }
2796
2797 DEFUN (ip_zebra_import_table_distance,
2798 ip_zebra_import_table_distance_cmd,
2799 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
2800 IP_STR
2801 "import routes from non-main kernel table\n"
2802 "kernel routing table id\n"
2803 "Distance for imported routes\n"
2804 "Default distance value\n"
2805 "route-map for filtering\n"
2806 "route-map name\n")
2807 {
2808 u_int32_t table_id = 0;
2809
2810 table_id = strtoul(argv[2]->arg, NULL, 10);
2811 int distance = ZEBRA_TABLE_DISTANCE_DEFAULT;
2812 char *rmap =
2813 strmatch(argv[argc - 2]->text, "route-map")
2814 ? XSTRDUP(MTYPE_ROUTE_MAP_NAME, argv[argc - 1]->arg)
2815 : NULL;
2816 int ret;
2817
2818 if (argc == 7 || (argc == 5 && !rmap))
2819 distance = strtoul(argv[4]->arg, NULL, 10);
2820
2821 if (!is_zebra_valid_kernel_table(table_id)) {
2822 vty_out(vty,
2823 "Invalid routing table ID, %d. Must be in range 1-252\n",
2824 table_id);
2825 if (rmap)
2826 XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
2827 return CMD_WARNING;
2828 }
2829
2830 if (is_zebra_main_routing_table(table_id)) {
2831 vty_out(vty,
2832 "Invalid routing table ID, %d. Must be non-default table\n",
2833 table_id);
2834 if (rmap)
2835 XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
2836 return CMD_WARNING;
2837 }
2838
2839 ret = zebra_import_table(AFI_IP, table_id, distance, rmap, 1);
2840 if (rmap)
2841 XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
2842
2843 return ret;
2844 }
2845
2846 DEFUN_HIDDEN (zebra_packet_process,
2847 zebra_packet_process_cmd,
2848 "zebra zapi-packets (1-10000)",
2849 ZEBRA_STR
2850 "Zapi Protocol\n"
2851 "Number of packets to process before relinquishing thread\n")
2852 {
2853 uint32_t packets = strtoul(argv[2]->arg, NULL, 10);
2854
2855 zebrad.packets_to_process = packets;
2856
2857 return CMD_SUCCESS;
2858 }
2859
2860 DEFUN_HIDDEN (no_zebra_packet_process,
2861 no_zebra_packet_process_cmd,
2862 "no zebra zapi-packets [(1-10000)]",
2863 NO_STR
2864 ZEBRA_STR
2865 "Zapi Protocol\n"
2866 "Number of packets to process before relinquishing thread\n")
2867 {
2868 zebrad.packets_to_process = ZEBRA_ZAPI_PACKETS_TO_PROCESS;
2869
2870 return CMD_SUCCESS;
2871 }
2872
2873 DEFUN_HIDDEN (zebra_workqueue_timer,
2874 zebra_workqueue_timer_cmd,
2875 "zebra work-queue (0-10000)",
2876 ZEBRA_STR
2877 "Work Queue\n"
2878 "Time in milliseconds\n")
2879 {
2880 uint32_t timer = strtoul(argv[2]->arg, NULL, 10);
2881 zebrad.ribq->spec.hold = timer;
2882
2883 return CMD_SUCCESS;
2884 }
2885
2886 DEFUN_HIDDEN (no_zebra_workqueue_timer,
2887 no_zebra_workqueue_timer_cmd,
2888 "no zebra work-queue [(0-10000)]",
2889 NO_STR
2890 ZEBRA_STR
2891 "Work Queue\n"
2892 "Time in milliseconds\n")
2893 {
2894 zebrad.ribq->spec.hold = ZEBRA_RIB_PROCESS_HOLD_TIME;
2895
2896 return CMD_SUCCESS;
2897 }
2898
2899 DEFUN (no_ip_zebra_import_table,
2900 no_ip_zebra_import_table_cmd,
2901 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
2902 NO_STR
2903 IP_STR
2904 "import routes from non-main kernel table\n"
2905 "kernel routing table id\n"
2906 "Distance for imported routes\n"
2907 "Default distance value\n"
2908 "route-map for filtering\n"
2909 "route-map name\n")
2910 {
2911 u_int32_t table_id = 0;
2912 table_id = strtoul(argv[3]->arg, NULL, 10);
2913
2914 if (!is_zebra_valid_kernel_table(table_id)) {
2915 vty_out(vty,
2916 "Invalid routing table ID. Must be in range 1-252\n");
2917 return CMD_WARNING;
2918 }
2919
2920 if (is_zebra_main_routing_table(table_id)) {
2921 vty_out(vty,
2922 "Invalid routing table ID, %d. Must be non-default table\n",
2923 table_id);
2924 return CMD_WARNING;
2925 }
2926
2927 if (!is_zebra_import_table_enabled(AFI_IP, table_id))
2928 return CMD_SUCCESS;
2929
2930 return (zebra_import_table(AFI_IP, table_id, 0, NULL, 0));
2931 }
2932
2933 static int config_write_protocol(struct vty *vty)
2934 {
2935 if (allow_delete)
2936 vty_out(vty, "allow-external-route-update\n");
2937
2938 if (zebra_rnh_ip_default_route)
2939 vty_out(vty, "ip nht resolve-via-default\n");
2940
2941 if (zebra_rnh_ipv6_default_route)
2942 vty_out(vty, "ipv6 nht resolve-via-default\n");
2943
2944 if (zebrad.ribq->spec.hold != ZEBRA_RIB_PROCESS_HOLD_TIME)
2945 vty_out(vty, "zebra work-queue %u\n", zebrad.ribq->spec.hold);
2946
2947 if (zebrad.packets_to_process != ZEBRA_ZAPI_PACKETS_TO_PROCESS)
2948 vty_out(vty,
2949 "zebra zapi-packets %u\n", zebrad.packets_to_process);
2950
2951 enum multicast_mode ipv4_multicast_mode = multicast_mode_ipv4_get();
2952
2953 if (ipv4_multicast_mode != MCAST_NO_CONFIG)
2954 vty_out(vty, "ip multicast rpf-lookup-mode %s\n",
2955 ipv4_multicast_mode == MCAST_URIB_ONLY
2956 ? "urib-only"
2957 : ipv4_multicast_mode == MCAST_MRIB_ONLY
2958 ? "mrib-only"
2959 : ipv4_multicast_mode
2960 == MCAST_MIX_MRIB_FIRST
2961 ? "mrib-then-urib"
2962 : ipv4_multicast_mode
2963 == MCAST_MIX_DISTANCE
2964 ? "lower-distance"
2965 : "longer-prefix");
2966
2967 zebra_routemap_config_write_protocol(vty);
2968
2969 return 1;
2970 }
2971
2972 #ifdef HAVE_NETLINK
2973 /* Display default rtm_table for all clients. */
2974 DEFUN (show_table,
2975 show_table_cmd,
2976 "show table",
2977 SHOW_STR
2978 "default routing table to use for all clients\n")
2979 {
2980 vty_out(vty, "table %d\n", zebrad.rtm_table_default);
2981 return CMD_SUCCESS;
2982 }
2983
2984 DEFUN (config_table,
2985 config_table_cmd,
2986 "table TABLENO",
2987 "Configure target kernel routing table\n"
2988 "TABLE integer\n")
2989 {
2990 zebrad.rtm_table_default = strtol(argv[1]->arg, (char **)0, 10);
2991 return CMD_SUCCESS;
2992 }
2993
2994 DEFUN (no_config_table,
2995 no_config_table_cmd,
2996 "no table [TABLENO]",
2997 NO_STR
2998 "Configure target kernel routing table\n"
2999 "TABLE integer\n")
3000 {
3001 zebrad.rtm_table_default = 0;
3002 return CMD_SUCCESS;
3003 }
3004 #endif
3005
3006 DEFUN (show_zebra,
3007 show_zebra_cmd,
3008 "show zebra",
3009 SHOW_STR
3010 ZEBRA_STR)
3011 {
3012 struct vrf *vrf;
3013
3014 vty_out(vty,
3015 " Route Route Neighbor LSP LSP\n");
3016 vty_out(vty,
3017 "VRF Installs Removals Updates Installs Removals\n");
3018
3019 RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) {
3020 struct zebra_vrf *zvrf = vrf->info;
3021
3022 vty_out(vty, "%-25s %10" PRIu64 " %10" PRIu64 " %10" PRIu64
3023 " %10" PRIu64 " %10" PRIu64 "\n",
3024 vrf->name, zvrf->installs, zvrf->removals,
3025 zvrf->neigh_updates, zvrf->lsp_installs,
3026 zvrf->lsp_removals);
3027 }
3028
3029 return CMD_SUCCESS;
3030 }
3031
3032 DEFUN (ip_forwarding,
3033 ip_forwarding_cmd,
3034 "ip forwarding",
3035 IP_STR
3036 "Turn on IP forwarding\n")
3037 {
3038 int ret;
3039
3040 ret = ipforward();
3041 if (ret == 0)
3042 ret = ipforward_on();
3043
3044 if (ret == 0) {
3045 vty_out(vty, "Can't turn on IP forwarding\n");
3046 return CMD_WARNING_CONFIG_FAILED;
3047 }
3048
3049 return CMD_SUCCESS;
3050 }
3051
3052 DEFUN (no_ip_forwarding,
3053 no_ip_forwarding_cmd,
3054 "no ip forwarding",
3055 NO_STR
3056 IP_STR
3057 "Turn off IP forwarding\n")
3058 {
3059 int ret;
3060
3061 ret = ipforward();
3062 if (ret != 0)
3063 ret = ipforward_off();
3064
3065 if (ret != 0) {
3066 vty_out(vty, "Can't turn off IP forwarding\n");
3067 return CMD_WARNING_CONFIG_FAILED;
3068 }
3069
3070 return CMD_SUCCESS;
3071 }
3072
3073 /* Only display ip forwarding is enabled or not. */
3074 DEFUN (show_ip_forwarding,
3075 show_ip_forwarding_cmd,
3076 "show ip forwarding",
3077 SHOW_STR
3078 IP_STR
3079 "IP forwarding status\n")
3080 {
3081 int ret;
3082
3083 ret = ipforward();
3084
3085 if (ret == 0)
3086 vty_out(vty, "IP forwarding is off\n");
3087 else
3088 vty_out(vty, "IP forwarding is on\n");
3089 return CMD_SUCCESS;
3090 }
3091
3092 /* Only display ipv6 forwarding is enabled or not. */
3093 DEFUN (show_ipv6_forwarding,
3094 show_ipv6_forwarding_cmd,
3095 "show ipv6 forwarding",
3096 SHOW_STR
3097 "IPv6 information\n"
3098 "Forwarding status\n")
3099 {
3100 int ret;
3101
3102 ret = ipforward_ipv6();
3103
3104 switch (ret) {
3105 case -1:
3106 vty_out(vty, "ipv6 forwarding is unknown\n");
3107 break;
3108 case 0:
3109 vty_out(vty, "ipv6 forwarding is %s\n", "off");
3110 break;
3111 case 1:
3112 vty_out(vty, "ipv6 forwarding is %s\n", "on");
3113 break;
3114 default:
3115 vty_out(vty, "ipv6 forwarding is %s\n", "off");
3116 break;
3117 }
3118 return CMD_SUCCESS;
3119 }
3120
3121 DEFUN (ipv6_forwarding,
3122 ipv6_forwarding_cmd,
3123 "ipv6 forwarding",
3124 IPV6_STR
3125 "Turn on IPv6 forwarding\n")
3126 {
3127 int ret;
3128
3129 ret = ipforward_ipv6();
3130 if (ret == 0)
3131 ret = ipforward_ipv6_on();
3132
3133 if (ret == 0) {
3134 vty_out(vty, "Can't turn on IPv6 forwarding\n");
3135 return CMD_WARNING_CONFIG_FAILED;
3136 }
3137
3138 return CMD_SUCCESS;
3139 }
3140
3141 DEFUN (no_ipv6_forwarding,
3142 no_ipv6_forwarding_cmd,
3143 "no ipv6 forwarding",
3144 NO_STR
3145 IPV6_STR
3146 "Turn off IPv6 forwarding\n")
3147 {
3148 int ret;
3149
3150 ret = ipforward_ipv6();
3151 if (ret != 0)
3152 ret = ipforward_ipv6_off();
3153
3154 if (ret != 0) {
3155 vty_out(vty, "Can't turn off IPv6 forwarding\n");
3156 return CMD_WARNING_CONFIG_FAILED;
3157 }
3158
3159 return CMD_SUCCESS;
3160 }
3161
3162 /* Table configuration write function. */
3163 static int config_write_table(struct vty *vty)
3164 {
3165 if (zebrad.rtm_table_default)
3166 vty_out(vty, "table %d\n", zebrad.rtm_table_default);
3167 return 0;
3168 }
3169
3170 /* IPForwarding configuration write function. */
3171 static int config_write_forwarding(struct vty *vty)
3172 {
3173 /* FIXME: Find better place for that. */
3174 router_id_write(vty);
3175
3176 if (!ipforward())
3177 vty_out(vty, "no ip forwarding\n");
3178 if (!ipforward_ipv6())
3179 vty_out(vty, "no ipv6 forwarding\n");
3180 vty_out(vty, "!\n");
3181 return 0;
3182 }
3183
3184 /* IP node for static routes. */
3185 static struct cmd_node ip_node = {IP_NODE, "", 1};
3186 static struct cmd_node protocol_node = {PROTOCOL_NODE, "", 1};
3187 /* table node for routing tables. */
3188 static struct cmd_node table_node = {TABLE_NODE,
3189 "", /* This node has no interface. */
3190 1};
3191 static struct cmd_node forwarding_node = {FORWARDING_NODE,
3192 "", /* This node has no interface. */
3193 1};
3194
3195 /* Route VTY. */
3196 void zebra_vty_init(void)
3197 {
3198 /* Install configuration write function. */
3199 install_node(&table_node, config_write_table);
3200 install_node(&forwarding_node, config_write_forwarding);
3201
3202 install_element(VIEW_NODE, &show_ip_forwarding_cmd);
3203 install_element(CONFIG_NODE, &ip_forwarding_cmd);
3204 install_element(CONFIG_NODE, &no_ip_forwarding_cmd);
3205 install_element(ENABLE_NODE, &show_zebra_cmd);
3206
3207 #ifdef HAVE_NETLINK
3208 install_element(VIEW_NODE, &show_table_cmd);
3209 install_element(CONFIG_NODE, &config_table_cmd);
3210 install_element(CONFIG_NODE, &no_config_table_cmd);
3211 #endif /* HAVE_NETLINK */
3212
3213 install_element(VIEW_NODE, &show_ipv6_forwarding_cmd);
3214 install_element(CONFIG_NODE, &ipv6_forwarding_cmd);
3215 install_element(CONFIG_NODE, &no_ipv6_forwarding_cmd);
3216
3217 /* Route-map */
3218 zebra_route_map_init();
3219
3220 install_node(&ip_node, zebra_ip_config);
3221 install_node(&protocol_node, config_write_protocol);
3222
3223 install_element(CONFIG_NODE, &allow_external_route_update_cmd);
3224 install_element(CONFIG_NODE, &no_allow_external_route_update_cmd);
3225 install_element(CONFIG_NODE, &ip_mroute_dist_cmd);
3226 install_element(CONFIG_NODE, &ip_multicast_mode_cmd);
3227 install_element(CONFIG_NODE, &no_ip_multicast_mode_cmd);
3228 install_element(CONFIG_NODE, &ip_route_blackhole_cmd);
3229 install_element(VRF_NODE, &ip_route_blackhole_vrf_cmd);
3230 install_element(CONFIG_NODE, &ip_route_address_interface_cmd);
3231 install_element(VRF_NODE, &ip_route_address_interface_vrf_cmd);
3232 install_element(CONFIG_NODE, &ip_route_cmd);
3233 install_element(VRF_NODE, &ip_route_vrf_cmd);
3234 install_element(CONFIG_NODE, &ip_zebra_import_table_distance_cmd);
3235 install_element(CONFIG_NODE, &no_ip_zebra_import_table_cmd);
3236 install_element(CONFIG_NODE, &zebra_workqueue_timer_cmd);
3237 install_element(CONFIG_NODE, &no_zebra_workqueue_timer_cmd);
3238 install_element(CONFIG_NODE, &zebra_packet_process_cmd);
3239 install_element(CONFIG_NODE, &no_zebra_packet_process_cmd);
3240
3241 install_element(VIEW_NODE, &show_vrf_cmd);
3242 install_element(VIEW_NODE, &show_vrf_vni_cmd);
3243 install_element(VIEW_NODE, &show_route_cmd);
3244 install_element(VIEW_NODE, &show_route_detail_cmd);
3245 install_element(VIEW_NODE, &show_route_summary_cmd);
3246 install_element(VIEW_NODE, &show_ip_nht_cmd);
3247 install_element(VIEW_NODE, &show_ip_nht_vrf_all_cmd);
3248 install_element(VIEW_NODE, &show_ipv6_nht_cmd);
3249 install_element(VIEW_NODE, &show_ipv6_nht_vrf_all_cmd);
3250
3251 install_element(VIEW_NODE, &show_ip_rpf_cmd);
3252 install_element(VIEW_NODE, &show_ip_rpf_addr_cmd);
3253
3254 install_element(CONFIG_NODE, &ipv6_route_blackhole_cmd);
3255 install_element(VRF_NODE, &ipv6_route_blackhole_vrf_cmd);
3256 install_element(CONFIG_NODE, &ipv6_route_address_interface_cmd);
3257 install_element(VRF_NODE, &ipv6_route_address_interface_vrf_cmd);
3258 install_element(CONFIG_NODE, &ipv6_route_cmd);
3259 install_element(VRF_NODE, &ipv6_route_vrf_cmd);
3260 install_element(CONFIG_NODE, &ip_nht_default_route_cmd);
3261 install_element(CONFIG_NODE, &no_ip_nht_default_route_cmd);
3262 install_element(CONFIG_NODE, &ipv6_nht_default_route_cmd);
3263 install_element(CONFIG_NODE, &no_ipv6_nht_default_route_cmd);
3264 install_element(VIEW_NODE, &show_ipv6_mroute_cmd);
3265
3266 /* Commands for VRF */
3267 install_element(VIEW_NODE, &show_ipv6_mroute_vrf_all_cmd);
3268
3269 install_element(VIEW_NODE, &show_evpn_vni_cmd);
3270 install_element(VIEW_NODE, &show_evpn_vni_vni_cmd);
3271 install_element(VIEW_NODE, &show_evpn_l3vni_cmd);
3272 install_element(VIEW_NODE, &show_evpn_l3vni_vni_cmd);
3273 install_element(VIEW_NODE, &show_evpn_rmac_l3vni_mac_cmd);
3274 install_element(VIEW_NODE, &show_evpn_rmac_l3vni_cmd);
3275 install_element(VIEW_NODE, &show_evpn_rmac_l3vni_all_cmd);
3276 install_element(VIEW_NODE, &show_evpn_nh_l3vni_ip_cmd);
3277 install_element(VIEW_NODE, &show_evpn_nh_l3vni_cmd);
3278 install_element(VIEW_NODE, &show_evpn_nh_l3vni_all_cmd);
3279 install_element(VIEW_NODE, &show_evpn_mac_vni_cmd);
3280 install_element(VIEW_NODE, &show_evpn_mac_vni_all_cmd);
3281 install_element(VIEW_NODE, &show_evpn_mac_vni_all_vtep_cmd);
3282 install_element(VIEW_NODE, &show_evpn_mac_vni_mac_cmd);
3283 install_element(VIEW_NODE, &show_evpn_mac_vni_vtep_cmd);
3284 install_element(VIEW_NODE, &show_evpn_neigh_vni_cmd);
3285 install_element(VIEW_NODE, &show_evpn_neigh_vni_all_cmd);
3286 install_element(VIEW_NODE, &show_evpn_neigh_vni_neigh_cmd);
3287 install_element(VIEW_NODE, &show_evpn_neigh_vni_vtep_cmd);
3288
3289 install_element(CONFIG_NODE, &no_vrf_vni_mapping_cmd);
3290 install_element(VRF_NODE, &vrf_vni_mapping_cmd);
3291 install_element(VRF_NODE, &no_vrf_vni_mapping_cmd);
3292
3293 }