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