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