]> git.proxmox.com Git - mirror_frr.git/blob - zebra/zebra_vty.c
1ce4f66b16387e169109936755a0d12cdd322050
[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 #include "zebra/zebra_vty_clippy.c"
47
48 extern int allow_delete;
49
50 static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi,
51 safi_t safi, bool use_fib, u_char use_json,
52 route_tag_t tag, struct prefix *longer_prefix_p,
53 bool supernets_only, int type,
54 u_short ospf_instance_id);
55 static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn,
56 int mcast);
57
58 /* VNI range as per RFC 7432 */
59 #define CMD_VNI_RANGE "(1-16777215)"
60
61 /* General function for static route. */
62 static int zebra_static_route(struct vty *vty, afi_t afi, safi_t safi,
63 const char *negate, const char *dest_str,
64 const char *mask_str, const char *src_str,
65 const char *gate_str, const char *ifname,
66 const char *flag_str, const char *tag_str,
67 const char *distance_str, const char *vrf_id_str,
68 const char *label_str)
69 {
70 int ret;
71 u_char distance;
72 struct prefix p, src;
73 struct prefix_ipv6 *src_p = NULL;
74 union g_addr gate;
75 union g_addr *gatep = NULL;
76 struct in_addr mask;
77 enum static_blackhole_type bh_type = 0;
78 route_tag_t tag = 0;
79 struct zebra_vrf *zvrf;
80 u_char type;
81 struct static_nh_label snh_label;
82
83 ret = str2prefix(dest_str, &p);
84 if (ret <= 0) {
85 vty_out(vty, "%% Malformed address\n");
86 return CMD_WARNING_CONFIG_FAILED;
87 }
88
89 switch (afi) {
90 case AFI_IP:
91 /* Cisco like mask notation. */
92 if (mask_str) {
93 ret = inet_aton(mask_str, &mask);
94 if (ret == 0) {
95 vty_out(vty, "%% Malformed address\n");
96 return CMD_WARNING_CONFIG_FAILED;
97 }
98 p.prefixlen = ip_masklen(mask);
99 }
100 break;
101 case AFI_IP6:
102 /* srcdest routing */
103 if (src_str) {
104 ret = str2prefix(src_str, &src);
105 if (ret <= 0 || src.family != AF_INET6) {
106 vty_out(vty, "%% Malformed source address\n");
107 return CMD_WARNING_CONFIG_FAILED;
108 }
109 src_p = (struct prefix_ipv6 *)&src;
110 }
111 break;
112 default:
113 break;
114 }
115
116 /* Apply mask for given prefix. */
117 apply_mask(&p);
118
119 /* Administrative distance. */
120 if (distance_str)
121 distance = atoi(distance_str);
122 else
123 distance = ZEBRA_STATIC_DISTANCE_DEFAULT;
124
125 /* tag */
126 if (tag_str)
127 tag = strtoul(tag_str, NULL, 10);
128
129 /* VRF id */
130 zvrf = zebra_vrf_lookup_by_name(vrf_id_str);
131
132 if (!zvrf) {
133 vty_out(vty, "%% vrf %s is not defined\n", vrf_id_str);
134 return CMD_WARNING_CONFIG_FAILED;
135 }
136
137 /* Labels */
138 memset(&snh_label, 0, sizeof(struct static_nh_label));
139 if (label_str) {
140 if (!mpls_enabled) {
141 vty_out(vty,
142 "%% MPLS not turned on in kernel, ignoring command\n");
143 return CMD_WARNING_CONFIG_FAILED;
144 }
145 int rc = mpls_str2label(label_str, &snh_label.num_labels,
146 snh_label.label);
147 if (rc < 0) {
148 switch (rc) {
149 case -1:
150 vty_out(vty, "%% Malformed label(s)\n");
151 break;
152 case -2:
153 vty_out(vty,
154 "%% Cannot use reserved label(s) (%d-%d)\n",
155 MPLS_MIN_RESERVED_LABEL,
156 MPLS_MAX_RESERVED_LABEL);
157 break;
158 case -3:
159 vty_out(vty,
160 "%% Too many labels. Enter %d or fewer\n",
161 MPLS_MAX_LABELS);
162 break;
163 }
164 return CMD_WARNING_CONFIG_FAILED;
165 }
166 }
167
168 /* Null0 static route. */
169 if ((ifname != NULL)
170 && (strncasecmp(ifname, "Null0", strlen(ifname)) == 0)) {
171 bh_type = STATIC_BLACKHOLE_NULL;
172 ifname = NULL;
173 }
174
175 /* Route flags */
176 if (flag_str) {
177 switch (flag_str[0]) {
178 case 'r':
179 bh_type = STATIC_BLACKHOLE_REJECT;
180 break;
181 case 'b':
182 bh_type = STATIC_BLACKHOLE_DROP;
183 break;
184 default:
185 vty_out(vty, "%% Malformed flag %s \n", flag_str);
186 return CMD_WARNING_CONFIG_FAILED;
187 }
188 }
189
190 if (gate_str) {
191 if (inet_pton(afi2family(afi), gate_str, &gate) != 1) {
192 vty_out(vty, "%% Malformed nexthop address %s\n",
193 gate_str);
194 return CMD_WARNING_CONFIG_FAILED;
195 }
196 gatep = &gate;
197 }
198
199 if (gate_str == NULL && ifname == NULL)
200 type = STATIC_BLACKHOLE;
201 else if (gate_str && ifname) {
202 if (afi == AFI_IP)
203 type = STATIC_IPV4_GATEWAY_IFNAME;
204 else
205 type = STATIC_IPV6_GATEWAY_IFNAME;
206 } else if (ifname)
207 type = STATIC_IFNAME;
208 else {
209 if (afi == AFI_IP)
210 type = STATIC_IPV4_GATEWAY;
211 else
212 type = STATIC_IPV6_GATEWAY;
213 }
214
215 if (!negate)
216 static_add_route(afi, safi, type, &p, src_p, gatep, ifname,
217 bh_type, tag, distance, zvrf, &snh_label);
218 else
219 static_delete_route(afi, safi, type, &p, src_p, gatep, ifname,
220 tag, distance, zvrf, &snh_label);
221
222 return CMD_SUCCESS;
223 }
224
225 /* Static unicast routes for multicast RPF lookup. */
226 DEFPY (ip_mroute_dist,
227 ip_mroute_dist_cmd,
228 "[no] ip mroute A.B.C.D/M$prefix <A.B.C.D$gate|INTERFACE$ifname> [(1-255)$distance]",
229 NO_STR
230 IP_STR
231 "Configure static unicast route into MRIB for multicast RPF lookup\n"
232 "IP destination prefix (e.g. 10.0.0.0/8)\n"
233 "Nexthop address\n"
234 "Nexthop interface name\n"
235 "Distance\n")
236 {
237 return zebra_static_route(vty, AFI_IP, SAFI_MULTICAST, no, prefix_str,
238 NULL, NULL, gate_str, ifname, NULL, NULL,
239 distance_str, NULL, NULL);
240 }
241
242 DEFUN (ip_multicast_mode,
243 ip_multicast_mode_cmd,
244 "ip multicast rpf-lookup-mode <urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>",
245 IP_STR
246 "Multicast options\n"
247 "RPF lookup behavior\n"
248 "Lookup in unicast RIB only\n"
249 "Lookup in multicast RIB only\n"
250 "Try multicast RIB first, fall back to unicast RIB\n"
251 "Lookup both, use entry with lower distance\n"
252 "Lookup both, use entry with longer prefix\n")
253 {
254 char *mode = argv[3]->text;
255
256 if (strmatch(mode, "urib-only"))
257 multicast_mode_ipv4_set(MCAST_URIB_ONLY);
258 else if (strmatch(mode, "mrib-only"))
259 multicast_mode_ipv4_set(MCAST_MRIB_ONLY);
260 else if (strmatch(mode, "mrib-then-urib"))
261 multicast_mode_ipv4_set(MCAST_MIX_MRIB_FIRST);
262 else if (strmatch(mode, "lower-distance"))
263 multicast_mode_ipv4_set(MCAST_MIX_DISTANCE);
264 else if (strmatch(mode, "longer-prefix"))
265 multicast_mode_ipv4_set(MCAST_MIX_PFXLEN);
266 else {
267 vty_out(vty, "Invalid mode specified\n");
268 return CMD_WARNING_CONFIG_FAILED;
269 }
270
271 return CMD_SUCCESS;
272 }
273
274 DEFUN (no_ip_multicast_mode,
275 no_ip_multicast_mode_cmd,
276 "no ip multicast rpf-lookup-mode [<urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>]",
277 NO_STR
278 IP_STR
279 "Multicast options\n"
280 "RPF lookup behavior\n"
281 "Lookup in unicast RIB only\n"
282 "Lookup in multicast RIB only\n"
283 "Try multicast RIB first, fall back to unicast RIB\n"
284 "Lookup both, use entry with lower distance\n"
285 "Lookup both, use entry with longer prefix\n")
286 {
287 multicast_mode_ipv4_set(MCAST_NO_CONFIG);
288 return CMD_SUCCESS;
289 }
290
291
292 DEFUN (show_ip_rpf,
293 show_ip_rpf_cmd,
294 "show ip rpf [json]",
295 SHOW_STR
296 IP_STR
297 "Display RPF information for multicast source\n"
298 JSON_STR)
299 {
300 int uj = use_json(argc, argv);
301 return do_show_ip_route(vty, VRF_DEFAULT_NAME, AFI_IP, SAFI_MULTICAST,
302 false, uj, 0, NULL, false, -1, 0);
303 }
304
305 DEFUN (show_ip_rpf_addr,
306 show_ip_rpf_addr_cmd,
307 "show ip rpf A.B.C.D",
308 SHOW_STR
309 IP_STR
310 "Display RPF information for multicast source\n"
311 "IP multicast source address (e.g. 10.0.0.0)\n")
312 {
313 int idx_ipv4 = 3;
314 struct in_addr addr;
315 struct route_node *rn;
316 struct route_entry *re;
317 int ret;
318
319 ret = inet_aton(argv[idx_ipv4]->arg, &addr);
320 if (ret == 0) {
321 vty_out(vty, "%% Malformed address\n");
322 return CMD_WARNING;
323 }
324
325 re = rib_match_ipv4_multicast(VRF_DEFAULT, addr, &rn);
326
327 if (re)
328 vty_show_ip_route_detail(vty, rn, 1);
329 else
330 vty_out(vty, "%% No match for RPF lookup\n");
331
332 return CMD_SUCCESS;
333 }
334
335 /* Static route configuration. */
336 DEFPY(ip_route, ip_route_cmd,
337 "[no] ip route\
338 <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask>\
339 <\
340 {A.B.C.D$gate|INTERFACE$ifname}\
341 |null0$ifname\
342 |<reject|blackhole>$flag\
343 >\
344 [{\
345 tag (1-4294967295)\
346 |(1-255)$distance\
347 |vrf NAME\
348 |label WORD\
349 }]",
350 NO_STR IP_STR
351 "Establish static routes\n"
352 "IP destination prefix (e.g. 10.0.0.0/8)\n"
353 "IP destination prefix\n"
354 "IP destination prefix mask\n"
355 "IP gateway address\n"
356 "IP gateway interface name\n"
357 "Null interface\n"
358 "Emit an ICMP unreachable when matched\n"
359 "Silently discard pkts when matched\n"
360 "Set tag for this route\n"
361 "Tag value\n"
362 "Distance value for this route\n"
363 VRF_CMD_HELP_STR
364 MPLS_LABEL_HELPSTR)
365 {
366 return zebra_static_route(vty, AFI_IP, SAFI_UNICAST, no, prefix,
367 mask_str, NULL, gate_str, ifname, flag,
368 tag_str, distance_str, vrf, label);
369 return 0;
370 }
371
372 /* New RIB. Detailed information for IPv4 route. */
373 static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn,
374 int mcast)
375 {
376 struct route_entry *re;
377 struct nexthop *nexthop;
378 char buf[SRCDEST2STR_BUFFER];
379 struct zebra_vrf *zvrf;
380
381 RNODE_FOREACH_RE(rn, re)
382 {
383 const char *mcast_info = "";
384 if (mcast) {
385 rib_table_info_t *info = srcdest_rnode_table_info(rn);
386 mcast_info = (info->safi == SAFI_MULTICAST)
387 ? " using Multicast RIB"
388 : " using Unicast RIB";
389 }
390
391 vty_out(vty, "Routing entry for %s%s\n",
392 srcdest_rnode2str(rn, buf, sizeof(buf)), mcast_info);
393 vty_out(vty, " Known via \"%s", zebra_route_string(re->type));
394 if (re->instance)
395 vty_out(vty, "[%d]", re->instance);
396 vty_out(vty, "\"");
397 vty_out(vty, ", distance %u, metric %u", re->distance,
398 re->metric);
399 if (re->tag)
400 vty_out(vty, ", tag %d", re->tag);
401 if (re->mtu)
402 vty_out(vty, ", mtu %u", re->mtu);
403 if (re->vrf_id != VRF_DEFAULT) {
404 zvrf = vrf_info_lookup(re->vrf_id);
405 vty_out(vty, ", vrf %s", zvrf_name(zvrf));
406 }
407 if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED))
408 vty_out(vty, ", best");
409 vty_out(vty, "\n");
410
411 time_t uptime;
412 struct tm *tm;
413
414 uptime = time(NULL);
415 uptime -= re->uptime;
416 tm = gmtime(&uptime);
417
418 vty_out(vty, " Last update ");
419
420 if (uptime < ONE_DAY_SECOND)
421 vty_out(vty, "%02d:%02d:%02d", tm->tm_hour,
422 tm->tm_min, tm->tm_sec);
423 else if (uptime < ONE_WEEK_SECOND)
424 vty_out(vty, "%dd%02dh%02dm", tm->tm_yday,
425 tm->tm_hour, tm->tm_min);
426 else
427 vty_out(vty, "%02dw%dd%02dh", tm->tm_yday / 7,
428 tm->tm_yday - ((tm->tm_yday / 7) * 7),
429 tm->tm_hour);
430 vty_out(vty, " ago\n");
431
432 for (ALL_NEXTHOPS(re->nexthop, nexthop)) {
433 char addrstr[32];
434
435 vty_out(vty, " %c%s",
436 CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)
437 ? CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE)
438 ? ' ' : '*'
439 : ' ',
440 nexthop->rparent ? " " : "");
441
442 switch (nexthop->type) {
443 case NEXTHOP_TYPE_IPV4:
444 case NEXTHOP_TYPE_IPV4_IFINDEX:
445 vty_out(vty, " %s",
446 inet_ntoa(nexthop->gate.ipv4));
447 if (nexthop->ifindex)
448 vty_out(vty, ", via %s",
449 ifindex2ifname(nexthop->ifindex,
450 re->vrf_id));
451 break;
452 case NEXTHOP_TYPE_IPV6:
453 case NEXTHOP_TYPE_IPV6_IFINDEX:
454 vty_out(vty, " %s",
455 inet_ntop(AF_INET6, &nexthop->gate.ipv6,
456 buf, sizeof buf));
457 if (nexthop->ifindex)
458 vty_out(vty, ", via %s",
459 ifindex2ifname(nexthop->ifindex,
460 re->vrf_id));
461 break;
462 case NEXTHOP_TYPE_IFINDEX:
463 vty_out(vty, " directly connected, %s",
464 ifindex2ifname(nexthop->ifindex,
465 re->vrf_id));
466 break;
467 case NEXTHOP_TYPE_BLACKHOLE:
468 vty_out(vty, " unreachable");
469 switch (nexthop->bh_type) {
470 case BLACKHOLE_REJECT:
471 vty_out(vty, " (ICMP unreachable)");
472 break;
473 case BLACKHOLE_ADMINPROHIB:
474 vty_out(vty,
475 " (ICMP admin-prohibited)");
476 break;
477 case BLACKHOLE_NULL:
478 vty_out(vty, " (blackhole)");
479 break;
480 case BLACKHOLE_UNSPEC:
481 break;
482 }
483 break;
484 default:
485 break;
486 }
487 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE))
488 vty_out(vty, " (duplicate nexthop removed)");
489
490 if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
491 vty_out(vty, " inactive");
492
493 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK))
494 vty_out(vty, " onlink");
495
496 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
497 vty_out(vty, " (recursive)");
498
499 switch (nexthop->type) {
500 case NEXTHOP_TYPE_IPV4:
501 case NEXTHOP_TYPE_IPV4_IFINDEX:
502 if (nexthop->src.ipv4.s_addr) {
503 if (inet_ntop(AF_INET,
504 &nexthop->src.ipv4,
505 addrstr, sizeof addrstr))
506 vty_out(vty, ", src %s",
507 addrstr);
508 }
509 break;
510 case NEXTHOP_TYPE_IPV6:
511 case NEXTHOP_TYPE_IPV6_IFINDEX:
512 if (!IPV6_ADDR_SAME(&nexthop->src.ipv6,
513 &in6addr_any)) {
514 if (inet_ntop(AF_INET6,
515 &nexthop->src.ipv6,
516 addrstr, sizeof addrstr))
517 vty_out(vty, ", src %s",
518 addrstr);
519 }
520 break;
521 default:
522 break;
523 }
524
525 if (re->nexthop_mtu)
526 vty_out(vty, ", mtu %u", re->nexthop_mtu);
527
528 /* Label information */
529 if (nexthop->nh_label
530 && nexthop->nh_label->num_labels) {
531 vty_out(vty, ", label %s",
532 mpls_label2str(
533 nexthop->nh_label->num_labels,
534 nexthop->nh_label->label, buf,
535 sizeof buf, 1));
536 }
537
538 vty_out(vty, "\n");
539 }
540 vty_out(vty, "\n");
541 }
542 }
543
544 static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
545 struct route_entry *re, json_object *json)
546 {
547 struct nexthop *nexthop;
548 int len = 0;
549 char buf[SRCDEST2STR_BUFFER];
550 json_object *json_nexthops = NULL;
551 json_object *json_nexthop = NULL;
552 json_object *json_route = NULL;
553 json_object *json_labels = NULL;
554 time_t uptime;
555 struct tm *tm;
556
557 uptime = time(NULL);
558 uptime -= re->uptime;
559 tm = gmtime(&uptime);
560
561 if (json) {
562 json_route = json_object_new_object();
563 json_nexthops = json_object_new_array();
564
565 json_object_string_add(json_route, "prefix",
566 srcdest_rnode2str(rn, buf, sizeof buf));
567 json_object_string_add(json_route, "protocol",
568 zebra_route_string(re->type));
569
570 if (re->instance)
571 json_object_int_add(json_route, "instance",
572 re->instance);
573
574 if (re->vrf_id)
575 json_object_int_add(json_route, "vrfId", re->vrf_id);
576
577 if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED))
578 json_object_boolean_true_add(json_route, "selected");
579
580 if (re->type != ZEBRA_ROUTE_CONNECT) {
581 json_object_int_add(json_route, "distance",
582 re->distance);
583 json_object_int_add(json_route, "metric", re->metric);
584 }
585
586 if (uptime < ONE_DAY_SECOND)
587 sprintf(buf, "%02d:%02d:%02d", tm->tm_hour,
588 tm->tm_min, tm->tm_sec);
589 else if (uptime < ONE_WEEK_SECOND)
590 sprintf(buf, "%dd%02dh%02dm", tm->tm_yday,
591 tm->tm_hour, tm->tm_min);
592 else
593 sprintf(buf, "%02dw%dd%02dh", tm->tm_yday / 7,
594 tm->tm_yday - ((tm->tm_yday / 7) * 7),
595 tm->tm_hour);
596
597 json_object_string_add(json_route, "uptime", buf);
598
599 for (ALL_NEXTHOPS(re->nexthop, nexthop)) {
600 json_nexthop = json_object_new_object();
601
602 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE))
603 json_object_boolean_true_add(json_nexthop,
604 "duplicate");
605
606 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB))
607 json_object_boolean_true_add(json_nexthop,
608 "fib");
609
610 switch (nexthop->type) {
611 case NEXTHOP_TYPE_IPV4:
612 case NEXTHOP_TYPE_IPV4_IFINDEX:
613 json_object_string_add(
614 json_nexthop, "ip",
615 inet_ntoa(nexthop->gate.ipv4));
616 json_object_string_add(json_nexthop, "afi",
617 "ipv4");
618
619 if (nexthop->ifindex) {
620 json_object_int_add(json_nexthop,
621 "interfaceIndex",
622 nexthop->ifindex);
623 json_object_string_add(
624 json_nexthop, "interfaceName",
625 ifindex2ifname(nexthop->ifindex,
626 re->vrf_id));
627 }
628 break;
629 case NEXTHOP_TYPE_IPV6:
630 case NEXTHOP_TYPE_IPV6_IFINDEX:
631 json_object_string_add(
632 json_nexthop, "ip",
633 inet_ntop(AF_INET6, &nexthop->gate.ipv6,
634 buf, sizeof buf));
635 json_object_string_add(json_nexthop, "afi",
636 "ipv6");
637
638 if (nexthop->ifindex) {
639 json_object_int_add(json_nexthop,
640 "interfaceIndex",
641 nexthop->ifindex);
642 json_object_string_add(
643 json_nexthop, "interfaceName",
644 ifindex2ifname(nexthop->ifindex,
645 re->vrf_id));
646 }
647 break;
648
649 case NEXTHOP_TYPE_IFINDEX:
650 json_object_boolean_true_add(
651 json_nexthop, "directlyConnected");
652 json_object_int_add(json_nexthop,
653 "interfaceIndex",
654 nexthop->ifindex);
655 json_object_string_add(
656 json_nexthop, "interfaceName",
657 ifindex2ifname(nexthop->ifindex,
658 re->vrf_id));
659 break;
660 case NEXTHOP_TYPE_BLACKHOLE:
661 json_object_boolean_true_add(json_nexthop,
662 "unreachable");
663 switch (nexthop->bh_type) {
664 case BLACKHOLE_REJECT:
665 json_object_boolean_true_add(
666 json_nexthop, "reject");
667 break;
668 case BLACKHOLE_ADMINPROHIB:
669 json_object_boolean_true_add(
670 json_nexthop,
671 "admin-prohibited");
672 break;
673 case BLACKHOLE_NULL:
674 json_object_boolean_true_add(
675 json_nexthop, "blackhole");
676 break;
677 case BLACKHOLE_UNSPEC:
678 break;
679 }
680 break;
681 default:
682 break;
683 }
684
685 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE))
686 json_object_boolean_true_add(json_nexthop,
687 "duplicate");
688
689 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
690 json_object_boolean_true_add(json_nexthop,
691 "active");
692
693 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK))
694 json_object_boolean_true_add(json_nexthop,
695 "onLink");
696
697 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
698 json_object_boolean_true_add(json_nexthop,
699 "recursive");
700
701 switch (nexthop->type) {
702 case NEXTHOP_TYPE_IPV4:
703 case NEXTHOP_TYPE_IPV4_IFINDEX:
704 if (nexthop->src.ipv4.s_addr) {
705 if (inet_ntop(AF_INET,
706 &nexthop->src.ipv4, buf,
707 sizeof buf))
708 json_object_string_add(
709 json_nexthop, "source",
710 buf);
711 }
712 break;
713 case NEXTHOP_TYPE_IPV6:
714 case NEXTHOP_TYPE_IPV6_IFINDEX:
715 if (!IPV6_ADDR_SAME(&nexthop->src.ipv6,
716 &in6addr_any)) {
717 if (inet_ntop(AF_INET6,
718 &nexthop->src.ipv6, buf,
719 sizeof buf))
720 json_object_string_add(
721 json_nexthop, "source",
722 buf);
723 }
724 break;
725 default:
726 break;
727 }
728
729 if (nexthop->nh_label
730 && nexthop->nh_label->num_labels) {
731 json_labels = json_object_new_array();
732
733 for (int label_index = 0;
734 label_index
735 < nexthop->nh_label->num_labels;
736 label_index++)
737 json_object_array_add(
738 json_labels,
739 json_object_new_int(
740 nexthop->nh_label->label
741 [label_index]));
742
743 json_object_object_add(json_nexthop, "labels",
744 json_labels);
745 }
746
747 json_object_array_add(json_nexthops, json_nexthop);
748 }
749
750 json_object_object_add(json_route, "nexthops", json_nexthops);
751 json_object_array_add(json, json_route);
752 return;
753 }
754
755 /* Nexthop information. */
756 for (ALL_NEXTHOPS(re->nexthop, nexthop)) {
757 if (nexthop == re->nexthop) {
758 /* Prefix information. */
759 len = vty_out(vty, "%c", zebra_route_char(re->type));
760 if (re->instance)
761 len += vty_out(vty, "[%d]", re->instance);
762 len += vty_out(
763 vty, "%c%c %s",
764 CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED)
765 ? '>'
766 : ' ',
767 CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)
768 ? '*'
769 : ' ',
770 srcdest_rnode2str(rn, buf, sizeof buf));
771
772 /* Distance and metric display. */
773 if (re->type != ZEBRA_ROUTE_CONNECT)
774 len += vty_out(vty, " [%d/%d]", re->distance,
775 re->metric);
776 } else {
777 vty_out(vty, " %c%*c",
778 CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)
779 ? CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE)
780 ? ' ' : '*'
781 : ' ',
782 len - 3 + (2 * nexthop_level(nexthop)), ' ');
783 }
784
785 switch (nexthop->type) {
786 case NEXTHOP_TYPE_IPV4:
787 case NEXTHOP_TYPE_IPV4_IFINDEX:
788 vty_out(vty, " via %s", inet_ntoa(nexthop->gate.ipv4));
789 if (nexthop->ifindex)
790 vty_out(vty, ", %s",
791 ifindex2ifname(nexthop->ifindex,
792 re->vrf_id));
793 break;
794 case NEXTHOP_TYPE_IPV6:
795 case NEXTHOP_TYPE_IPV6_IFINDEX:
796 vty_out(vty, " via %s",
797 inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf,
798 sizeof buf));
799 if (nexthop->ifindex)
800 vty_out(vty, ", %s",
801 ifindex2ifname(nexthop->ifindex,
802 re->vrf_id));
803 break;
804
805 case NEXTHOP_TYPE_IFINDEX:
806 vty_out(vty, " is directly connected, %s",
807 ifindex2ifname(nexthop->ifindex, re->vrf_id));
808 break;
809 case NEXTHOP_TYPE_BLACKHOLE:
810 vty_out(vty, " unreachable");
811 switch (nexthop->bh_type) {
812 case BLACKHOLE_REJECT:
813 vty_out(vty, " (ICMP unreachable)");
814 break;
815 case BLACKHOLE_ADMINPROHIB:
816 vty_out(vty, " (ICMP admin-prohibited)");
817 break;
818 case BLACKHOLE_NULL:
819 vty_out(vty, " (blackhole)");
820 break;
821 case BLACKHOLE_UNSPEC:
822 break;
823 }
824 break;
825 default:
826 break;
827 }
828 if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
829 vty_out(vty, " inactive");
830
831 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK))
832 vty_out(vty, " onlink");
833
834 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
835 vty_out(vty, " (recursive)");
836
837 switch (nexthop->type) {
838 case NEXTHOP_TYPE_IPV4:
839 case NEXTHOP_TYPE_IPV4_IFINDEX:
840 if (nexthop->src.ipv4.s_addr) {
841 if (inet_ntop(AF_INET, &nexthop->src.ipv4, buf,
842 sizeof buf))
843 vty_out(vty, ", src %s", buf);
844 }
845 break;
846 case NEXTHOP_TYPE_IPV6:
847 case NEXTHOP_TYPE_IPV6_IFINDEX:
848 if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any)) {
849 if (inet_ntop(AF_INET6, &nexthop->src.ipv6, buf,
850 sizeof buf))
851 vty_out(vty, ", src %s", buf);
852 }
853 break;
854 default:
855 break;
856 }
857
858 /* Label information */
859 if (nexthop->nh_label && nexthop->nh_label->num_labels) {
860 vty_out(vty, ", label %s",
861 mpls_label2str(nexthop->nh_label->num_labels,
862 nexthop->nh_label->label, buf,
863 sizeof buf, 1));
864 }
865
866 if (uptime < ONE_DAY_SECOND)
867 vty_out(vty, ", %02d:%02d:%02d", tm->tm_hour,
868 tm->tm_min, tm->tm_sec);
869 else if (uptime < ONE_WEEK_SECOND)
870 vty_out(vty, ", %dd%02dh%02dm", tm->tm_yday,
871 tm->tm_hour, tm->tm_min);
872 else
873 vty_out(vty, ", %02dw%dd%02dh", tm->tm_yday / 7,
874 tm->tm_yday - ((tm->tm_yday / 7) * 7),
875 tm->tm_hour);
876 vty_out(vty, "\n");
877 }
878 }
879
880 static bool use_fib(struct cmd_token *token)
881 {
882 return strncmp(token->arg, "route", strlen(token->arg));
883 }
884
885 static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi,
886 safi_t safi, bool use_fib, u_char use_json,
887 route_tag_t tag, struct prefix *longer_prefix_p,
888 bool supernets_only, int type,
889 u_short ospf_instance_id)
890 {
891 struct route_table *table;
892 struct route_node *rn;
893 struct route_entry *re;
894 int first = 1;
895 struct zebra_vrf *zvrf = NULL;
896 char buf[BUFSIZ];
897 json_object *json = NULL;
898 json_object *json_prefix = NULL;
899 u_int32_t addr;
900
901 if (!(zvrf = zebra_vrf_lookup_by_name(vrf_name))) {
902 if (use_json)
903 vty_out(vty, "{}\n");
904 else
905 vty_out(vty, "vrf %s not defined\n", vrf_name);
906 return CMD_SUCCESS;
907 }
908
909 if (zvrf_id(zvrf) == VRF_UNKNOWN) {
910 if (use_json)
911 vty_out(vty, "{}\n");
912 else
913 vty_out(vty, "vrf %s inactive\n", vrf_name);
914 return CMD_SUCCESS;
915 }
916
917 table = zebra_vrf_table(afi, safi, zvrf_id(zvrf));
918 if (!table) {
919 if (use_json)
920 vty_out(vty, "{}\n");
921 return CMD_SUCCESS;
922 }
923
924 if (use_json)
925 json = json_object_new_object();
926
927 /* Show all routes. */
928 for (rn = route_top(table); rn; rn = route_next(rn)) {
929 RNODE_FOREACH_RE(rn, re)
930 {
931 if (use_fib
932 && !CHECK_FLAG(re->status,
933 ROUTE_ENTRY_SELECTED_FIB))
934 continue;
935
936 if (tag && re->tag != tag)
937 continue;
938
939 if (longer_prefix_p
940 && !prefix_match(longer_prefix_p, &rn->p))
941 continue;
942
943 /* This can only be true when the afi is IPv4 */
944 if (supernets_only) {
945 addr = ntohl(rn->p.u.prefix4.s_addr);
946
947 if (IN_CLASSC(addr) && rn->p.prefixlen >= 24)
948 continue;
949
950 if (IN_CLASSB(addr) && rn->p.prefixlen >= 16)
951 continue;
952
953 if (IN_CLASSA(addr) && rn->p.prefixlen >= 8)
954 continue;
955 }
956
957 if (type && re->type != type)
958 continue;
959
960 if (ospf_instance_id
961 && (re->type != ZEBRA_ROUTE_OSPF
962 || re->instance != ospf_instance_id))
963 continue;
964
965 if (use_json) {
966 if (!json_prefix)
967 json_prefix = json_object_new_array();
968 } else {
969 if (first) {
970 if (afi == AFI_IP)
971 vty_out(vty,
972 SHOW_ROUTE_V4_HEADER);
973 else
974 vty_out(vty,
975 SHOW_ROUTE_V6_HEADER);
976
977 if (zvrf_id(zvrf) != VRF_DEFAULT)
978 vty_out(vty, "\nVRF %s:\n",
979 zvrf_name(zvrf));
980
981 first = 0;
982 }
983 }
984
985 vty_show_ip_route(vty, rn, re, json_prefix);
986 }
987
988 if (json_prefix) {
989 prefix2str(&rn->p, buf, sizeof buf);
990 json_object_object_add(json, buf, json_prefix);
991 json_prefix = NULL;
992 }
993 }
994
995 if (use_json) {
996 vty_out(vty, "%s\n", json_object_to_json_string_ext(
997 json, JSON_C_TO_STRING_PRETTY));
998 json_object_free(json);
999 }
1000
1001 return CMD_SUCCESS;
1002 }
1003
1004 DEFUN (show_ip_nht,
1005 show_ip_nht_cmd,
1006 "show ip nht [vrf NAME]",
1007 SHOW_STR
1008 IP_STR
1009 "IP nexthop tracking table\n"
1010 VRF_CMD_HELP_STR)
1011 {
1012 int idx_vrf = 4;
1013 vrf_id_t vrf_id = VRF_DEFAULT;
1014
1015 if (argc == 5)
1016 VRF_GET_ID(vrf_id, argv[idx_vrf]->arg);
1017
1018 zebra_print_rnh_table(vrf_id, AF_INET, vty, RNH_NEXTHOP_TYPE);
1019 return CMD_SUCCESS;
1020 }
1021
1022
1023 DEFUN (show_ip_nht_vrf_all,
1024 show_ip_nht_vrf_all_cmd,
1025 "show ip nht vrf all",
1026 SHOW_STR
1027 IP_STR
1028 "IP nexthop tracking table\n"
1029 VRF_ALL_CMD_HELP_STR)
1030 {
1031 struct vrf *vrf;
1032 struct zebra_vrf *zvrf;
1033
1034 RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name)
1035 if ((zvrf = vrf->info) != NULL) {
1036 vty_out(vty, "\nVRF %s:\n", zvrf_name(zvrf));
1037 zebra_print_rnh_table(zvrf_id(zvrf), AF_INET, vty,
1038 RNH_NEXTHOP_TYPE);
1039 }
1040
1041 return CMD_SUCCESS;
1042 }
1043
1044 DEFUN (show_ipv6_nht,
1045 show_ipv6_nht_cmd,
1046 "show ipv6 nht [vrf NAME]",
1047 SHOW_STR
1048 IPV6_STR
1049 "IPv6 nexthop tracking table\n"
1050 VRF_CMD_HELP_STR)
1051 {
1052 int idx_vrf = 4;
1053 vrf_id_t vrf_id = VRF_DEFAULT;
1054
1055 if (argc == 5)
1056 VRF_GET_ID(vrf_id, argv[idx_vrf]->arg);
1057
1058 zebra_print_rnh_table(vrf_id, AF_INET6, vty, RNH_NEXTHOP_TYPE);
1059 return CMD_SUCCESS;
1060 }
1061
1062
1063 DEFUN (show_ipv6_nht_vrf_all,
1064 show_ipv6_nht_vrf_all_cmd,
1065 "show ipv6 nht vrf all",
1066 SHOW_STR
1067 IP_STR
1068 "IPv6 nexthop tracking table\n"
1069 VRF_ALL_CMD_HELP_STR)
1070 {
1071 struct vrf *vrf;
1072 struct zebra_vrf *zvrf;
1073
1074 RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name)
1075 if ((zvrf = vrf->info) != NULL) {
1076 vty_out(vty, "\nVRF %s:\n", zvrf_name(zvrf));
1077 zebra_print_rnh_table(zvrf_id(zvrf), AF_INET6, vty,
1078 RNH_NEXTHOP_TYPE);
1079 }
1080
1081 return CMD_SUCCESS;
1082 }
1083
1084 DEFUN (ip_nht_default_route,
1085 ip_nht_default_route_cmd,
1086 "ip nht resolve-via-default",
1087 IP_STR
1088 "Filter Next Hop tracking route resolution\n"
1089 "Resolve via default route\n")
1090 {
1091 if (zebra_rnh_ip_default_route)
1092 return CMD_SUCCESS;
1093
1094 zebra_rnh_ip_default_route = 1;
1095 zebra_evaluate_rnh(0, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
1096 return CMD_SUCCESS;
1097 }
1098
1099 DEFUN (no_ip_nht_default_route,
1100 no_ip_nht_default_route_cmd,
1101 "no ip nht resolve-via-default",
1102 NO_STR
1103 IP_STR
1104 "Filter Next Hop tracking route resolution\n"
1105 "Resolve via default route\n")
1106 {
1107 if (!zebra_rnh_ip_default_route)
1108 return CMD_SUCCESS;
1109
1110 zebra_rnh_ip_default_route = 0;
1111 zebra_evaluate_rnh(0, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
1112 return CMD_SUCCESS;
1113 }
1114
1115 DEFUN (ipv6_nht_default_route,
1116 ipv6_nht_default_route_cmd,
1117 "ipv6 nht resolve-via-default",
1118 IP6_STR
1119 "Filter Next Hop tracking route resolution\n"
1120 "Resolve via default route\n")
1121 {
1122 if (zebra_rnh_ipv6_default_route)
1123 return CMD_SUCCESS;
1124
1125 zebra_rnh_ipv6_default_route = 1;
1126 zebra_evaluate_rnh(0, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL);
1127 return CMD_SUCCESS;
1128 }
1129
1130 DEFUN (no_ipv6_nht_default_route,
1131 no_ipv6_nht_default_route_cmd,
1132 "no ipv6 nht resolve-via-default",
1133 NO_STR
1134 IP6_STR
1135 "Filter Next Hop tracking route resolution\n"
1136 "Resolve via default route\n")
1137 {
1138 if (!zebra_rnh_ipv6_default_route)
1139 return CMD_SUCCESS;
1140
1141 zebra_rnh_ipv6_default_route = 0;
1142 zebra_evaluate_rnh(0, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL);
1143 return CMD_SUCCESS;
1144 }
1145
1146 DEFUN (show_ip_route,
1147 show_ip_route_cmd,
1148 "show ip <fib|route> [vrf NAME] [tag (1-4294967295)|A.B.C.D/M longer-prefixes|supernets-only|" FRR_IP_REDIST_STR_ZEBRA "|ospf (1-65535)] [json]",
1149 SHOW_STR
1150 IP_STR
1151 "IP forwarding table\n"
1152 "IP routing table\n"
1153 VRF_CMD_HELP_STR
1154 "Show only routes with tag\n"
1155 "Tag value\n"
1156 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1157 "Show route matching the specified Network/Mask pair only\n"
1158 "Show supernet entries only\n"
1159 FRR_IP_REDIST_HELP_STR_ZEBRA
1160 "Open Shortest Path First (OSPFv2)\n"
1161 "Instance ID\n"
1162 JSON_STR)
1163 {
1164 bool uf = use_fib(argv[2]);
1165 struct route_table *table;
1166 int vrf_all = 0;
1167 route_tag_t tag = 0;
1168 vrf_id_t vrf_id = VRF_DEFAULT;
1169 struct vrf *vrf;
1170 struct zebra_vrf *zvrf;
1171 int uj = use_json(argc, argv);
1172 int idx = 0;
1173 struct prefix p;
1174 bool longer_prefixes = false;
1175 bool supernets_only = false;
1176 int type = 0;
1177 u_short ospf_instance_id = 0;
1178
1179 if (argv_find(argv, argc, "vrf", &idx)) {
1180 if (strmatch(argv[idx + 1]->arg, "all"))
1181 vrf_all = 1;
1182 else
1183 VRF_GET_ID(vrf_id, argv[idx + 1]->arg);
1184 }
1185
1186 if (argv_find(argv, argc, "tag", &idx))
1187 tag = strtoul(argv[idx + 1]->arg, NULL, 10);
1188
1189 else if (argv_find(argv, argc, "A.B.C.D/M", &idx)) {
1190 if (str2prefix(argv[idx]->arg, &p) <= 0) {
1191 vty_out(vty, "%% Malformed prefix\n");
1192 return CMD_WARNING;
1193 }
1194 longer_prefixes = true;
1195 }
1196
1197 else if (argv_find(argv, argc, "supernets_only", &idx))
1198 supernets_only = true;
1199
1200 else {
1201 if (argv_find(argv, argc, "kernel", &idx))
1202 type = proto_redistnum(AFI_IP, argv[idx]->text);
1203 else if (argv_find(argv, argc, "babel", &idx))
1204 type = proto_redistnum(AFI_IP, argv[idx]->text);
1205 else if (argv_find(argv, argc, "connected", &idx))
1206 type = proto_redistnum(AFI_IP, argv[idx]->text);
1207 else if (argv_find(argv, argc, "static", &idx))
1208 type = proto_redistnum(AFI_IP, argv[idx]->text);
1209 else if (argv_find(argv, argc, "rip", &idx))
1210 type = proto_redistnum(AFI_IP, argv[idx]->text);
1211 else if (argv_find(argv, argc, "ospf", &idx))
1212 type = proto_redistnum(AFI_IP, argv[idx]->text);
1213 else if (argv_find(argv, argc, "isis", &idx))
1214 type = proto_redistnum(AFI_IP, argv[idx]->text);
1215 else if (argv_find(argv, argc, "bgp", &idx))
1216 type = proto_redistnum(AFI_IP, argv[idx]->text);
1217 else if (argv_find(argv, argc, "pim", &idx))
1218 type = proto_redistnum(AFI_IP, argv[idx]->text);
1219 else if (argv_find(argv, argc, "eigrp", &idx))
1220 type = proto_redistnum(AFI_IP, argv[idx]->text);
1221 else if (argv_find(argv, argc, "nhrp", &idx))
1222 type = proto_redistnum(AFI_IP, argv[idx]->text);
1223 else if (argv_find(argv, argc, "table", &idx))
1224 type = proto_redistnum(AFI_IP, argv[idx]->text);
1225 else if (argv_find(argv, argc, "vnc", &idx))
1226 type = proto_redistnum(AFI_IP, argv[idx]->text);
1227
1228 if (argv_find(argv, argc, "(1-65535)", &idx))
1229 ospf_instance_id = strtoul(argv[idx]->arg, NULL, 10);
1230
1231 if (type < 0) {
1232 vty_out(vty, "Unknown route type\n");
1233 return CMD_WARNING;
1234 }
1235 }
1236
1237 if (vrf_all) {
1238 RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name)
1239 {
1240 if ((zvrf = vrf->info) == NULL
1241 || (table = zvrf->table[AFI_IP][SAFI_UNICAST])
1242 == NULL)
1243 continue;
1244
1245 do_show_ip_route(
1246 vty, zvrf_name(zvrf), AFI_IP, SAFI_UNICAST, uf,
1247 uj, tag, longer_prefixes ? &p : NULL,
1248 supernets_only, type, ospf_instance_id);
1249 }
1250 } else {
1251 vrf = vrf_lookup_by_id(vrf_id);
1252 do_show_ip_route(vty, vrf->name, AFI_IP, SAFI_UNICAST, uf, uj,
1253 tag, longer_prefixes ? &p : NULL,
1254 supernets_only, type, ospf_instance_id);
1255 }
1256 return CMD_SUCCESS;
1257 }
1258
1259 DEFUN (show_ip_route_addr,
1260 show_ip_route_addr_cmd,
1261 "show ip route [vrf NAME] A.B.C.D",
1262 SHOW_STR
1263 IP_STR
1264 "IP routing table\n"
1265 VRF_CMD_HELP_STR
1266 "Network in the IP routing table to display\n")
1267 {
1268 int ret;
1269 struct prefix_ipv4 p;
1270 struct route_table *table;
1271 struct route_node *rn;
1272 vrf_id_t vrf_id = VRF_DEFAULT;
1273
1274 if (strmatch(argv[3]->text, "vrf")) {
1275 VRF_GET_ID(vrf_id, argv[4]->arg);
1276 ret = str2prefix_ipv4(argv[5]->arg, &p);
1277 } else {
1278 ret = str2prefix_ipv4(argv[3]->arg, &p);
1279 }
1280
1281 if (ret <= 0) {
1282 vty_out(vty, "%% Malformed IPv4 address\n");
1283 return CMD_WARNING;
1284 }
1285
1286 table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, vrf_id);
1287 if (!table)
1288 return CMD_SUCCESS;
1289
1290 rn = route_node_match(table, (struct prefix *)&p);
1291 if (!rn) {
1292 vty_out(vty, "%% Network not in table\n");
1293 return CMD_WARNING;
1294 }
1295
1296 vty_show_ip_route_detail(vty, rn, 0);
1297
1298 route_unlock_node(rn);
1299
1300 return CMD_SUCCESS;
1301 }
1302
1303 DEFUN (show_ip_route_prefix,
1304 show_ip_route_prefix_cmd,
1305 "show ip route [vrf NAME] A.B.C.D/M",
1306 SHOW_STR
1307 IP_STR
1308 "IP routing table\n"
1309 VRF_CMD_HELP_STR
1310 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
1311 {
1312 int ret;
1313 struct prefix_ipv4 p;
1314 struct route_table *table;
1315 struct route_node *rn;
1316 vrf_id_t vrf_id = VRF_DEFAULT;
1317
1318 if (strmatch(argv[3]->text, "vrf")) {
1319 VRF_GET_ID(vrf_id, argv[4]->arg);
1320 ret = str2prefix_ipv4(argv[5]->arg, &p);
1321 } else {
1322 ret = str2prefix_ipv4(argv[3]->arg, &p);
1323 }
1324
1325 if (ret <= 0) {
1326 vty_out(vty, "%% Malformed IPv4 address\n");
1327 return CMD_WARNING;
1328 }
1329
1330 table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, vrf_id);
1331 if (!table)
1332 return CMD_SUCCESS;
1333
1334 rn = route_node_match(table, (struct prefix *)&p);
1335 if (!rn || rn->p.prefixlen != p.prefixlen) {
1336 vty_out(vty, "%% Network not in table\n");
1337 return CMD_WARNING;
1338 }
1339
1340 vty_show_ip_route_detail(vty, rn, 0);
1341
1342 route_unlock_node(rn);
1343
1344 return CMD_SUCCESS;
1345 }
1346
1347
1348 static void vty_show_ip_route_summary(struct vty *vty,
1349 struct route_table *table)
1350 {
1351 struct route_node *rn;
1352 struct route_entry *re;
1353 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1354 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1355 u_int32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1356 u_int32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1357 u_int32_t i;
1358 u_int32_t is_ibgp;
1359
1360 memset(&rib_cnt, 0, sizeof(rib_cnt));
1361 memset(&fib_cnt, 0, sizeof(fib_cnt));
1362 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
1363 RNODE_FOREACH_RE(rn, re)
1364 {
1365 is_ibgp = (re->type == ZEBRA_ROUTE_BGP
1366 && CHECK_FLAG(re->flags, ZEBRA_FLAG_IBGP));
1367
1368 rib_cnt[ZEBRA_ROUTE_TOTAL]++;
1369 if (is_ibgp)
1370 rib_cnt[ZEBRA_ROUTE_IBGP]++;
1371 else
1372 rib_cnt[re->type]++;
1373
1374 if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED)) {
1375 fib_cnt[ZEBRA_ROUTE_TOTAL]++;
1376
1377 if (is_ibgp)
1378 fib_cnt[ZEBRA_ROUTE_IBGP]++;
1379 else
1380 fib_cnt[re->type]++;
1381 }
1382 }
1383
1384 vty_out(vty, "%-20s %-20s %s (vrf %s)\n", "Route Source", "Routes",
1385 "FIB", zvrf_name(((rib_table_info_t *)table->info)->zvrf));
1386
1387 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
1388 if ((rib_cnt[i] > 0) || (i == ZEBRA_ROUTE_BGP
1389 && rib_cnt[ZEBRA_ROUTE_IBGP] > 0)) {
1390 if (i == ZEBRA_ROUTE_BGP) {
1391 vty_out(vty, "%-20s %-20d %-20d \n", "ebgp",
1392 rib_cnt[ZEBRA_ROUTE_BGP],
1393 fib_cnt[ZEBRA_ROUTE_BGP]);
1394 vty_out(vty, "%-20s %-20d %-20d \n", "ibgp",
1395 rib_cnt[ZEBRA_ROUTE_IBGP],
1396 fib_cnt[ZEBRA_ROUTE_IBGP]);
1397 } else
1398 vty_out(vty, "%-20s %-20d %-20d \n",
1399 zebra_route_string(i), rib_cnt[i],
1400 fib_cnt[i]);
1401 }
1402 }
1403
1404 vty_out(vty, "------\n");
1405 vty_out(vty, "%-20s %-20d %-20d \n", "Totals",
1406 rib_cnt[ZEBRA_ROUTE_TOTAL], fib_cnt[ZEBRA_ROUTE_TOTAL]);
1407 vty_out(vty, "\n");
1408 }
1409
1410 /*
1411 * Implementation of the ip route summary prefix command.
1412 *
1413 * This command prints the primary prefixes that have been installed by various
1414 * protocols on the box.
1415 *
1416 */
1417 static void vty_show_ip_route_summary_prefix(struct vty *vty,
1418 struct route_table *table)
1419 {
1420 struct route_node *rn;
1421 struct route_entry *re;
1422 struct nexthop *nexthop;
1423 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1424 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1425 u_int32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1426 u_int32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1427 u_int32_t i;
1428 int cnt;
1429
1430 memset(&rib_cnt, 0, sizeof(rib_cnt));
1431 memset(&fib_cnt, 0, sizeof(fib_cnt));
1432 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
1433 RNODE_FOREACH_RE(rn, re)
1434 {
1435
1436 /*
1437 * In case of ECMP, count only once.
1438 */
1439 cnt = 0;
1440 for (nexthop = re->nexthop; (!cnt && nexthop);
1441 nexthop = nexthop->next) {
1442 cnt++;
1443 rib_cnt[ZEBRA_ROUTE_TOTAL]++;
1444 rib_cnt[re->type]++;
1445 if (CHECK_FLAG(nexthop->flags,
1446 NEXTHOP_FLAG_FIB)) {
1447 fib_cnt[ZEBRA_ROUTE_TOTAL]++;
1448 fib_cnt[re->type]++;
1449 }
1450 if (re->type == ZEBRA_ROUTE_BGP
1451 && CHECK_FLAG(re->flags, ZEBRA_FLAG_IBGP)) {
1452 rib_cnt[ZEBRA_ROUTE_IBGP]++;
1453 if (CHECK_FLAG(nexthop->flags,
1454 NEXTHOP_FLAG_FIB))
1455 fib_cnt[ZEBRA_ROUTE_IBGP]++;
1456 }
1457 }
1458 }
1459
1460 vty_out(vty, "%-20s %-20s %s (vrf %s)\n", "Route Source",
1461 "Prefix Routes", "FIB",
1462 zvrf_name(((rib_table_info_t *)table->info)->zvrf));
1463
1464 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
1465 if (rib_cnt[i] > 0) {
1466 if (i == ZEBRA_ROUTE_BGP) {
1467 vty_out(vty, "%-20s %-20d %-20d \n", "ebgp",
1468 rib_cnt[ZEBRA_ROUTE_BGP]
1469 - rib_cnt[ZEBRA_ROUTE_IBGP],
1470 fib_cnt[ZEBRA_ROUTE_BGP]
1471 - fib_cnt[ZEBRA_ROUTE_IBGP]);
1472 vty_out(vty, "%-20s %-20d %-20d \n", "ibgp",
1473 rib_cnt[ZEBRA_ROUTE_IBGP],
1474 fib_cnt[ZEBRA_ROUTE_IBGP]);
1475 } else
1476 vty_out(vty, "%-20s %-20d %-20d \n",
1477 zebra_route_string(i), rib_cnt[i],
1478 fib_cnt[i]);
1479 }
1480 }
1481
1482 vty_out(vty, "------\n");
1483 vty_out(vty, "%-20s %-20d %-20d \n", "Totals",
1484 rib_cnt[ZEBRA_ROUTE_TOTAL], fib_cnt[ZEBRA_ROUTE_TOTAL]);
1485 vty_out(vty, "\n");
1486 }
1487
1488 /* Show route summary. */
1489 DEFUN (show_ip_route_summary,
1490 show_ip_route_summary_cmd,
1491 "show ip route [vrf NAME] summary",
1492 SHOW_STR
1493 IP_STR
1494 "IP routing table\n"
1495 VRF_CMD_HELP_STR
1496 "Summary of all routes\n")
1497 {
1498 struct route_table *table;
1499 vrf_id_t vrf_id = VRF_DEFAULT;
1500
1501 if (strmatch(argv[3]->text, "vrf"))
1502 VRF_GET_ID(vrf_id, argv[4]->arg);
1503
1504 table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, vrf_id);
1505 if (!table)
1506 return CMD_SUCCESS;
1507
1508 vty_show_ip_route_summary(vty, table);
1509
1510 return CMD_SUCCESS;
1511 }
1512
1513 /* Show route summary prefix. */
1514 DEFUN (show_ip_route_summary_prefix,
1515 show_ip_route_summary_prefix_cmd,
1516 "show ip route [vrf NAME] summary prefix",
1517 SHOW_STR
1518 IP_STR
1519 "IP routing table\n"
1520 VRF_CMD_HELP_STR
1521 "Summary of all routes\n"
1522 "Prefix routes\n")
1523 {
1524 struct route_table *table;
1525 vrf_id_t vrf_id = VRF_DEFAULT;
1526
1527 if (strmatch(argv[3]->text, "vrf"))
1528 VRF_GET_ID(vrf_id, argv[4]->arg);
1529
1530 table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, vrf_id);
1531 if (!table)
1532 return CMD_SUCCESS;
1533
1534 vty_show_ip_route_summary_prefix(vty, table);
1535
1536 return CMD_SUCCESS;
1537 }
1538
1539
1540 DEFUN (show_ip_route_vrf_all_addr,
1541 show_ip_route_vrf_all_addr_cmd,
1542 "show ip route vrf all A.B.C.D",
1543 SHOW_STR
1544 IP_STR
1545 "IP routing table\n"
1546 VRF_ALL_CMD_HELP_STR
1547 "Network in the IP routing table to display\n")
1548 {
1549 int idx_ipv4 = 5;
1550 int ret;
1551 struct prefix_ipv4 p;
1552 struct route_table *table;
1553 struct route_node *rn;
1554 struct vrf *vrf;
1555 struct zebra_vrf *zvrf;
1556
1557 ret = str2prefix_ipv4(argv[idx_ipv4]->arg, &p);
1558 if (ret <= 0) {
1559 vty_out(vty, "%% Malformed IPv4 address\n");
1560 return CMD_WARNING;
1561 }
1562
1563 RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name)
1564 {
1565 if ((zvrf = vrf->info) == NULL
1566 || (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
1567 continue;
1568
1569 rn = route_node_match(table, (struct prefix *)&p);
1570 if (!rn)
1571 continue;
1572
1573 vty_show_ip_route_detail(vty, rn, 0);
1574
1575 route_unlock_node(rn);
1576 }
1577
1578 return CMD_SUCCESS;
1579 }
1580
1581 DEFUN (show_ip_route_vrf_all_prefix,
1582 show_ip_route_vrf_all_prefix_cmd,
1583 "show ip route vrf all A.B.C.D/M",
1584 SHOW_STR
1585 IP_STR
1586 "IP routing table\n"
1587 VRF_ALL_CMD_HELP_STR
1588 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
1589 {
1590 int idx_ipv4_prefixlen = 5;
1591 int ret;
1592 struct prefix_ipv4 p;
1593 struct route_table *table;
1594 struct route_node *rn;
1595 struct vrf *vrf;
1596 struct zebra_vrf *zvrf;
1597
1598 ret = str2prefix_ipv4(argv[idx_ipv4_prefixlen]->arg, &p);
1599 if (ret <= 0) {
1600 vty_out(vty, "%% Malformed IPv4 address\n");
1601 return CMD_WARNING;
1602 }
1603
1604 RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name)
1605 {
1606 if ((zvrf = vrf->info) == NULL
1607 || (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
1608 continue;
1609
1610 rn = route_node_match(table, (struct prefix *)&p);
1611 if (!rn)
1612 continue;
1613 if (rn->p.prefixlen != p.prefixlen) {
1614 route_unlock_node(rn);
1615 continue;
1616 }
1617
1618 vty_show_ip_route_detail(vty, rn, 0);
1619
1620 route_unlock_node(rn);
1621 }
1622
1623 return CMD_SUCCESS;
1624 }
1625
1626 DEFUN (show_ip_route_vrf_all_summary,
1627 show_ip_route_vrf_all_summary_cmd,
1628 "show ip route vrf all summary ",
1629 SHOW_STR
1630 IP_STR
1631 "IP routing table\n"
1632 VRF_ALL_CMD_HELP_STR
1633 "Summary of all routes\n")
1634 {
1635 struct vrf *vrf;
1636 struct zebra_vrf *zvrf;
1637
1638 RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name)
1639 if ((zvrf = vrf->info) != NULL)
1640 vty_show_ip_route_summary(vty,
1641 zvrf->table[AFI_IP][SAFI_UNICAST]);
1642
1643 return CMD_SUCCESS;
1644 }
1645
1646 DEFUN (show_ip_route_vrf_all_summary_prefix,
1647 show_ip_route_vrf_all_summary_prefix_cmd,
1648 "show ip route vrf all summary prefix",
1649 SHOW_STR
1650 IP_STR
1651 "IP routing table\n"
1652 VRF_ALL_CMD_HELP_STR
1653 "Summary of all routes\n"
1654 "Prefix routes\n")
1655 {
1656 struct vrf *vrf;
1657 struct zebra_vrf *zvrf;
1658
1659 RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name)
1660 if ((zvrf = vrf->info) != NULL)
1661 vty_show_ip_route_summary_prefix(
1662 vty, zvrf->table[AFI_IP][SAFI_UNICAST]);
1663
1664 return CMD_SUCCESS;
1665 }
1666
1667 /* Write static route configuration. */
1668 static int static_config(struct vty *vty, afi_t afi, safi_t safi,
1669 const char *cmd)
1670 {
1671 struct route_node *rn;
1672 struct static_route *si;
1673 struct route_table *stable;
1674 struct vrf *vrf;
1675 struct zebra_vrf *zvrf;
1676 char buf[SRCDEST2STR_BUFFER];
1677 int write = 0;
1678
1679 RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name)
1680 {
1681 if (!(zvrf = vrf->info))
1682 continue;
1683 if ((stable = zvrf->stable[afi][safi]) == NULL)
1684 continue;
1685
1686 for (rn = route_top(stable); rn; rn = srcdest_route_next(rn))
1687 for (si = rn->info; si; si = si->next) {
1688 vty_out(vty, "%s %s", cmd,
1689 srcdest_rnode2str(rn, buf, sizeof buf));
1690
1691 switch (si->type) {
1692 case STATIC_IPV4_GATEWAY:
1693 vty_out(vty, " %s",
1694 inet_ntoa(si->addr.ipv4));
1695 break;
1696 case STATIC_IPV6_GATEWAY:
1697 vty_out(vty, " %s",
1698 inet_ntop(AF_INET6,
1699 &si->addr.ipv6, buf,
1700 sizeof buf));
1701 break;
1702 case STATIC_IFNAME:
1703 vty_out(vty, " %s", si->ifname);
1704 break;
1705 case STATIC_BLACKHOLE:
1706 switch (si->bh_type) {
1707 case STATIC_BLACKHOLE_DROP:
1708 vty_out(vty, " blackhole");
1709 break;
1710 case STATIC_BLACKHOLE_NULL:
1711 vty_out(vty, " Null0");
1712 break;
1713 case STATIC_BLACKHOLE_REJECT:
1714 vty_out(vty, " reject");
1715 break;
1716 }
1717 break;
1718 case STATIC_IPV4_GATEWAY_IFNAME:
1719 vty_out(vty, " %s %s",
1720 inet_ntop(AF_INET,
1721 &si->addr.ipv4, buf,
1722 sizeof buf),
1723 si->ifname);
1724 break;
1725 case STATIC_IPV6_GATEWAY_IFNAME:
1726 vty_out(vty, " %s %s",
1727 inet_ntop(AF_INET6,
1728 &si->addr.ipv6, buf,
1729 sizeof buf),
1730 si->ifname);
1731 break;
1732 }
1733
1734 if (si->tag)
1735 vty_out(vty, " tag %" ROUTE_TAG_PRI,
1736 si->tag);
1737
1738 if (si->distance
1739 != ZEBRA_STATIC_DISTANCE_DEFAULT)
1740 vty_out(vty, " %d", si->distance);
1741
1742 if (si->vrf_id != VRF_DEFAULT)
1743 vty_out(vty, " vrf %s",
1744 zvrf_name(zvrf));
1745
1746 /* Label information */
1747 if (si->snh_label.num_labels)
1748 vty_out(vty, " label %s",
1749 mpls_label2str(
1750 si->snh_label
1751 .num_labels,
1752 si->snh_label.label,
1753 buf, sizeof buf, 0));
1754
1755 vty_out(vty, "\n");
1756
1757 write = 1;
1758 }
1759 }
1760 return write;
1761 }
1762
1763 DEFPY(ipv6_route,
1764 ipv6_route_cmd,
1765 "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M]\
1766 <\
1767 {X:X::X:X$gate|INTERFACE$ifname}\
1768 |null0$ifname\
1769 |<reject|blackhole>$flag\
1770 >\
1771 [{\
1772 tag (1-4294967295)\
1773 |(1-255)$distance\
1774 |vrf NAME\
1775 |label WORD\
1776 }]",
1777 NO_STR
1778 IPV6_STR
1779 "Establish static routes\n"
1780 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1781 "IPv6 source-dest route\n"
1782 "IPv6 source prefix\n"
1783 "IPv6 gateway address\n"
1784 "IPv6 gateway interface name\n"
1785 "Null interface\n"
1786 "Emit an ICMP unreachable when matched\n"
1787 "Silently discard pkts when matched\n"
1788 "Set tag for this route\n"
1789 "Tag value\n"
1790 "Distance value for this prefix\n"
1791 VRF_CMD_HELP_STR
1792 MPLS_LABEL_HELPSTR)
1793 {
1794 return zebra_static_route(vty, AFI_IP6, SAFI_UNICAST, no, prefix_str,
1795 NULL, from_str, gate_str, ifname, flag,
1796 tag_str, distance_str, vrf, label);
1797 }
1798
1799 DEFUN (show_ipv6_route,
1800 show_ipv6_route_cmd,
1801 "show ipv6 <fib|route> [vrf NAME] [tag (1-4294967295)|X:X::X:X/M longer-prefixes|" FRR_IP6_REDIST_STR_ZEBRA "] [json]",
1802 SHOW_STR
1803 IP_STR
1804 "IP forwarding table\n"
1805 "IP routing table\n"
1806 VRF_CMD_HELP_STR
1807 "Show only routes with tag\n"
1808 "Tag value\n"
1809 "IPv6 prefix\n"
1810 "Show route matching the specified Network/Mask pair only\n"
1811 FRR_IP6_REDIST_HELP_STR_ZEBRA
1812 JSON_STR)
1813 {
1814 bool uf = use_fib(argv[2]);
1815 struct route_table *table;
1816 int vrf_all = 0;
1817 route_tag_t tag = 0;
1818 vrf_id_t vrf_id = VRF_DEFAULT;
1819 struct vrf *vrf;
1820 struct zebra_vrf *zvrf;
1821 int uj = use_json(argc, argv);
1822 int idx = 0;
1823 struct prefix p;
1824 bool longer_prefixes = false;
1825 bool supernets_only = false;
1826 int type = 0;
1827
1828 if (argv_find(argv, argc, "vrf", &idx)) {
1829 if (strmatch(argv[idx + 1]->arg, "all"))
1830 vrf_all = 1;
1831 else
1832 VRF_GET_ID(vrf_id, argv[idx + 1]->arg);
1833 }
1834
1835 if (argv_find(argv, argc, "tag", &idx))
1836 tag = strtoul(argv[idx + 1]->arg, NULL, 10);
1837
1838 else if (argv_find(argv, argc, "X:X::X:X/M", &idx)) {
1839 if (str2prefix(argv[idx]->arg, &p) <= 0) {
1840 vty_out(vty, "%% Malformed prefix\n");
1841 return CMD_WARNING;
1842 }
1843 longer_prefixes = true;
1844 }
1845
1846 else {
1847 if (argv_find(argv, argc, "kernel", &idx))
1848 type = proto_redistnum(AFI_IP6, argv[idx]->text);
1849 else if (argv_find(argv, argc, "babel", &idx))
1850 type = proto_redistnum(AFI_IP6, argv[idx]->text);
1851 else if (argv_find(argv, argc, "connected", &idx))
1852 type = proto_redistnum(AFI_IP6, argv[idx]->text);
1853 else if (argv_find(argv, argc, "static", &idx))
1854 type = proto_redistnum(AFI_IP6, argv[idx]->text);
1855 else if (argv_find(argv, argc, "ripng", &idx))
1856 type = proto_redistnum(AFI_IP6, argv[idx]->text);
1857 else if (argv_find(argv, argc, "ospf6", &idx))
1858 type = proto_redistnum(AFI_IP6, argv[idx]->text);
1859 else if (argv_find(argv, argc, "isis", &idx))
1860 type = proto_redistnum(AFI_IP6, argv[idx]->text);
1861 else if (argv_find(argv, argc, "bgp", &idx))
1862 type = proto_redistnum(AFI_IP6, argv[idx]->text);
1863 else if (argv_find(argv, argc, "nhrp", &idx))
1864 type = proto_redistnum(AFI_IP6, argv[idx]->text);
1865 else if (argv_find(argv, argc, "table", &idx))
1866 type = proto_redistnum(AFI_IP6, argv[idx]->text);
1867 else if (argv_find(argv, argc, "vnc", &idx))
1868 type = proto_redistnum(AFI_IP6, argv[idx]->text);
1869
1870 if (type < 0) {
1871 vty_out(vty, "Unknown route type\n");
1872 return CMD_WARNING;
1873 }
1874 }
1875
1876 if (vrf_all) {
1877 RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name)
1878 {
1879 if ((zvrf = vrf->info) == NULL
1880 || (table = zvrf->table[AFI_IP6][SAFI_UNICAST])
1881 == NULL)
1882 continue;
1883
1884 do_show_ip_route(vty, zvrf_name(zvrf), AFI_IP6,
1885 SAFI_UNICAST, uf, uj, tag,
1886 longer_prefixes ? &p : NULL,
1887 supernets_only, type, 0);
1888 }
1889 } else {
1890 vrf = vrf_lookup_by_id(vrf_id);
1891 do_show_ip_route(vty, vrf->name, AFI_IP6, SAFI_UNICAST, uf, uj,
1892 tag, longer_prefixes ? &p : NULL,
1893 supernets_only, type, 0);
1894 }
1895 return CMD_SUCCESS;
1896 }
1897
1898 DEFUN (show_ipv6_route_addr,
1899 show_ipv6_route_addr_cmd,
1900 "show ipv6 route [vrf NAME] X:X::X:X",
1901 SHOW_STR
1902 IP_STR
1903 "IPv6 routing table\n"
1904 VRF_CMD_HELP_STR
1905 "IPv6 Address\n")
1906 {
1907 int ret;
1908 struct prefix_ipv6 p;
1909 struct route_table *table;
1910 struct route_node *rn;
1911 vrf_id_t vrf_id = VRF_DEFAULT;
1912
1913 if (strmatch(argv[3]->text, "vrf")) {
1914 VRF_GET_ID(vrf_id, argv[4]->arg);
1915 ret = str2prefix_ipv6(argv[5]->arg, &p);
1916 } else {
1917 ret = str2prefix_ipv6(argv[3]->arg, &p);
1918 }
1919
1920 if (ret <= 0) {
1921 vty_out(vty, "Malformed IPv6 address\n");
1922 return CMD_WARNING;
1923 }
1924
1925 table = zebra_vrf_table(AFI_IP6, SAFI_UNICAST, vrf_id);
1926 if (!table)
1927 return CMD_SUCCESS;
1928
1929 rn = route_node_match(table, (struct prefix *)&p);
1930 if (!rn) {
1931 vty_out(vty, "%% Network not in table\n");
1932 return CMD_WARNING;
1933 }
1934
1935 vty_show_ip_route_detail(vty, rn, 0);
1936
1937 route_unlock_node(rn);
1938
1939 return CMD_SUCCESS;
1940 }
1941
1942 DEFUN (show_ipv6_route_prefix,
1943 show_ipv6_route_prefix_cmd,
1944 "show ipv6 route [vrf NAME] X:X::X:X/M",
1945 SHOW_STR
1946 IP_STR
1947 "IPv6 routing table\n"
1948 VRF_CMD_HELP_STR
1949 "IPv6 prefix\n")
1950 {
1951 int ret;
1952 struct prefix_ipv6 p;
1953 struct route_table *table;
1954 struct route_node *rn;
1955 vrf_id_t vrf_id = VRF_DEFAULT;
1956
1957 if (strmatch(argv[3]->text, "vrf")) {
1958 VRF_GET_ID(vrf_id, argv[4]->arg);
1959 ret = str2prefix_ipv6(argv[5]->arg, &p);
1960 } else
1961 ret = str2prefix_ipv6(argv[3]->arg, &p);
1962
1963 if (ret <= 0) {
1964 vty_out(vty, "Malformed IPv6 prefix\n");
1965 return CMD_WARNING;
1966 }
1967
1968 table = zebra_vrf_table(AFI_IP6, SAFI_UNICAST, vrf_id);
1969 if (!table)
1970 return CMD_SUCCESS;
1971
1972 rn = route_node_match(table, (struct prefix *)&p);
1973 if (!rn || rn->p.prefixlen != p.prefixlen) {
1974 vty_out(vty, "%% Network not in table\n");
1975 return CMD_WARNING;
1976 }
1977
1978 vty_show_ip_route_detail(vty, rn, 0);
1979
1980 route_unlock_node(rn);
1981
1982 return CMD_SUCCESS;
1983 }
1984
1985
1986 /* Show route summary. */
1987 DEFUN (show_ipv6_route_summary,
1988 show_ipv6_route_summary_cmd,
1989 "show ipv6 route [vrf NAME] summary",
1990 SHOW_STR
1991 IP_STR
1992 "IPv6 routing table\n"
1993 VRF_CMD_HELP_STR
1994 "Summary of all IPv6 routes\n")
1995 {
1996 struct route_table *table;
1997 vrf_id_t vrf_id = VRF_DEFAULT;
1998
1999 if (strmatch(argv[3]->text, "vrf"))
2000 VRF_GET_ID(vrf_id, argv[4]->arg);
2001
2002 table = zebra_vrf_table(AFI_IP6, SAFI_UNICAST, vrf_id);
2003 if (!table)
2004 return CMD_SUCCESS;
2005
2006 vty_show_ip_route_summary(vty, table);
2007
2008 return CMD_SUCCESS;
2009 }
2010
2011
2012 /* Show ipv6 route summary prefix. */
2013 DEFUN (show_ipv6_route_summary_prefix,
2014 show_ipv6_route_summary_prefix_cmd,
2015 "show ipv6 route [vrf NAME] summary prefix",
2016 SHOW_STR
2017 IP_STR
2018 "IPv6 routing table\n"
2019 VRF_CMD_HELP_STR
2020 "Summary of all IPv6 routes\n"
2021 "Prefix routes\n")
2022 {
2023 struct route_table *table;
2024 vrf_id_t vrf_id = VRF_DEFAULT;
2025
2026 if (strmatch(argv[3]->text, "vrf"))
2027 VRF_GET_ID(vrf_id, argv[4]->arg);
2028
2029 table = zebra_vrf_table(AFI_IP6, SAFI_UNICAST, vrf_id);
2030 if (!table)
2031 return CMD_SUCCESS;
2032
2033 vty_show_ip_route_summary_prefix(vty, table);
2034
2035 return CMD_SUCCESS;
2036 }
2037
2038
2039 /*
2040 * Show IPv6 mroute command.Used to dump
2041 * the Multicast routing table.
2042 */
2043 DEFUN (show_ipv6_mroute,
2044 show_ipv6_mroute_cmd,
2045 "show ipv6 mroute [vrf NAME]",
2046 SHOW_STR
2047 IP_STR
2048 "IPv6 Multicast routing table\n"
2049 VRF_CMD_HELP_STR)
2050 {
2051 struct route_table *table;
2052 struct route_node *rn;
2053 struct route_entry *re;
2054 int first = 1;
2055 vrf_id_t vrf_id = VRF_DEFAULT;
2056
2057 if (argc == 5)
2058 VRF_GET_ID(vrf_id, argv[4]->arg);
2059
2060 table = zebra_vrf_table(AFI_IP6, SAFI_MULTICAST, vrf_id);
2061 if (!table)
2062 return CMD_SUCCESS;
2063
2064 /* Show all IPv6 route. */
2065 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
2066 RNODE_FOREACH_RE(rn, re)
2067 {
2068 if (first) {
2069 vty_out(vty, SHOW_ROUTE_V6_HEADER);
2070 first = 0;
2071 }
2072 vty_show_ip_route(vty, rn, re, NULL);
2073 }
2074 return CMD_SUCCESS;
2075 }
2076
2077 DEFUN (show_ipv6_route_vrf_all_addr,
2078 show_ipv6_route_vrf_all_addr_cmd,
2079 "show ipv6 route vrf all X:X::X:X",
2080 SHOW_STR
2081 IP_STR
2082 "IPv6 routing table\n"
2083 VRF_ALL_CMD_HELP_STR
2084 "IPv6 Address\n")
2085 {
2086 int idx_ipv6 = 5;
2087 int ret;
2088 struct prefix_ipv6 p;
2089 struct route_table *table;
2090 struct route_node *rn;
2091 struct vrf *vrf;
2092 struct zebra_vrf *zvrf;
2093
2094 ret = str2prefix_ipv6(argv[idx_ipv6]->arg, &p);
2095 if (ret <= 0) {
2096 vty_out(vty, "Malformed IPv6 address\n");
2097 return CMD_WARNING;
2098 }
2099
2100 RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name)
2101 {
2102 if ((zvrf = vrf->info) == NULL
2103 || (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
2104 continue;
2105
2106 rn = route_node_match(table, (struct prefix *)&p);
2107 if (!rn)
2108 continue;
2109
2110 vty_show_ip_route_detail(vty, rn, 0);
2111
2112 route_unlock_node(rn);
2113 }
2114
2115 return CMD_SUCCESS;
2116 }
2117
2118 DEFUN (show_ipv6_route_vrf_all_prefix,
2119 show_ipv6_route_vrf_all_prefix_cmd,
2120 "show ipv6 route vrf all X:X::X:X/M",
2121 SHOW_STR
2122 IP_STR
2123 "IPv6 routing table\n"
2124 VRF_ALL_CMD_HELP_STR
2125 "IPv6 prefix\n")
2126 {
2127 int idx_ipv6_prefixlen = 5;
2128 int ret;
2129 struct prefix_ipv6 p;
2130 struct route_table *table;
2131 struct route_node *rn;
2132 struct vrf *vrf;
2133 struct zebra_vrf *zvrf;
2134
2135 ret = str2prefix_ipv6(argv[idx_ipv6_prefixlen]->arg, &p);
2136 if (ret <= 0) {
2137 vty_out(vty, "Malformed IPv6 prefix\n");
2138 return CMD_WARNING;
2139 }
2140
2141 RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name)
2142 {
2143 if ((zvrf = vrf->info) == NULL
2144 || (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
2145 continue;
2146
2147 rn = route_node_match(table, (struct prefix *)&p);
2148 if (!rn)
2149 continue;
2150 if (rn->p.prefixlen != p.prefixlen) {
2151 route_unlock_node(rn);
2152 continue;
2153 }
2154
2155 vty_show_ip_route_detail(vty, rn, 0);
2156
2157 route_unlock_node(rn);
2158 }
2159
2160 return CMD_SUCCESS;
2161 }
2162
2163 DEFUN (show_ipv6_route_vrf_all_summary,
2164 show_ipv6_route_vrf_all_summary_cmd,
2165 "show ipv6 route vrf all summary",
2166 SHOW_STR
2167 IP_STR
2168 "IPv6 routing table\n"
2169 VRF_ALL_CMD_HELP_STR
2170 "Summary of all IPv6 routes\n")
2171 {
2172 struct vrf *vrf;
2173 struct zebra_vrf *zvrf;
2174
2175 RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name)
2176 if ((zvrf = vrf->info) != NULL)
2177 vty_show_ip_route_summary(vty,
2178 zvrf->table[AFI_IP6][SAFI_UNICAST]);
2179
2180 return CMD_SUCCESS;
2181 }
2182
2183 DEFUN (show_ipv6_mroute_vrf_all,
2184 show_ipv6_mroute_vrf_all_cmd,
2185 "show ipv6 mroute vrf all",
2186 SHOW_STR
2187 IP_STR
2188 "IPv6 Multicast routing table\n"
2189 VRF_ALL_CMD_HELP_STR)
2190 {
2191 struct route_table *table;
2192 struct route_node *rn;
2193 struct route_entry *re;
2194 struct vrf *vrf;
2195 struct zebra_vrf *zvrf;
2196 int first = 1;
2197
2198 RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name)
2199 {
2200 if ((zvrf = vrf->info) == NULL
2201 || (table = zvrf->table[AFI_IP6][SAFI_MULTICAST]) == NULL)
2202 continue;
2203
2204 /* Show all IPv6 route. */
2205 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
2206 RNODE_FOREACH_RE(rn, re)
2207 {
2208 if (first) {
2209 vty_out(vty, SHOW_ROUTE_V6_HEADER);
2210 first = 0;
2211 }
2212 vty_show_ip_route(vty, rn, re, NULL);
2213 }
2214 }
2215 return CMD_SUCCESS;
2216 }
2217
2218 DEFUN (show_ipv6_route_vrf_all_summary_prefix,
2219 show_ipv6_route_vrf_all_summary_prefix_cmd,
2220 "show ipv6 route vrf all summary prefix",
2221 SHOW_STR
2222 IP_STR
2223 "IPv6 routing table\n"
2224 VRF_ALL_CMD_HELP_STR
2225 "Summary of all IPv6 routes\n"
2226 "Prefix routes\n")
2227 {
2228 struct vrf *vrf;
2229 struct zebra_vrf *zvrf;
2230
2231 RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name)
2232 if ((zvrf = vrf->info) != NULL)
2233 vty_show_ip_route_summary_prefix(
2234 vty, zvrf->table[AFI_IP6][SAFI_UNICAST]);
2235
2236 return CMD_SUCCESS;
2237 }
2238
2239 DEFUN (allow_external_route_update,
2240 allow_external_route_update_cmd,
2241 "allow-external-route-update",
2242 "Allow FRR routes to be overwritten by external processes\n")
2243 {
2244 allow_delete = 1;
2245
2246 return CMD_SUCCESS;
2247 }
2248
2249 DEFUN (no_allow_external_route_update,
2250 no_allow_external_route_update_cmd,
2251 "no allow-external-route-update",
2252 NO_STR
2253 "Allow FRR routes to be overwritten by external processes\n")
2254 {
2255 allow_delete = 0;
2256
2257 return CMD_SUCCESS;
2258 }
2259
2260 /* show vrf */
2261 DEFUN (show_vrf,
2262 show_vrf_cmd,
2263 "show vrf",
2264 SHOW_STR
2265 "VRF\n")
2266 {
2267 struct vrf *vrf;
2268 struct zebra_vrf *zvrf;
2269
2270 RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name)
2271 {
2272 if (!(zvrf = vrf->info))
2273 continue;
2274 if (!zvrf_id(zvrf))
2275 continue;
2276
2277 vty_out(vty, "vrf %s ", zvrf_name(zvrf));
2278 if (zvrf_id(zvrf) == VRF_UNKNOWN)
2279 vty_out(vty, "inactive");
2280 else
2281 vty_out(vty, "id %u table %u", zvrf_id(zvrf),
2282 zvrf->table_id);
2283 vty_out(vty, "\n");
2284 }
2285
2286 return CMD_SUCCESS;
2287 }
2288
2289 DEFUN (show_evpn_vni,
2290 show_evpn_vni_cmd,
2291 "show evpn vni [json]",
2292 SHOW_STR
2293 "EVPN\n"
2294 "VxLAN information\n"
2295 JSON_STR)
2296 {
2297 struct zebra_vrf *zvrf;
2298 u_char uj = use_json(argc, argv);
2299
2300 zvrf = vrf_info_lookup(VRF_DEFAULT);
2301 zebra_vxlan_print_vnis(vty, zvrf, uj);
2302 return CMD_SUCCESS;
2303 }
2304
2305 DEFUN (show_evpn_vni_vni,
2306 show_evpn_vni_vni_cmd,
2307 "show evpn vni " CMD_VNI_RANGE "[json]",
2308 SHOW_STR
2309 "EVPN\n"
2310 "VxLAN Network Identifier\n"
2311 "VNI number\n"
2312 JSON_STR)
2313 {
2314 struct zebra_vrf *zvrf;
2315 vni_t vni;
2316 u_char uj = use_json(argc, argv);
2317
2318 vni = strtoul(argv[3]->arg, NULL, 10);
2319 zvrf = vrf_info_lookup(VRF_DEFAULT);
2320 zebra_vxlan_print_vni(vty, zvrf, vni, uj);
2321 return CMD_SUCCESS;
2322 }
2323
2324 DEFUN (show_evpn_mac_vni,
2325 show_evpn_mac_vni_cmd,
2326 "show evpn mac vni " CMD_VNI_RANGE "[json]",
2327 SHOW_STR
2328 "EVPN\n"
2329 "MAC addresses\n"
2330 "VxLAN Network Identifier\n"
2331 "VNI number\n"
2332 JSON_STR)
2333 {
2334 struct zebra_vrf *zvrf;
2335 vni_t vni;
2336 u_char uj = use_json(argc, argv);
2337
2338 vni = strtoul(argv[4]->arg, NULL, 10);
2339 zvrf = vrf_info_lookup(VRF_DEFAULT);
2340 zebra_vxlan_print_macs_vni(vty, zvrf, vni, uj);
2341 return CMD_SUCCESS;
2342 }
2343
2344 DEFUN (show_evpn_mac_vni_all,
2345 show_evpn_mac_vni_all_cmd,
2346 "show evpn mac vni all [json]",
2347 SHOW_STR
2348 "EVPN\n"
2349 "MAC addresses\n"
2350 "VxLAN Network Identifier\n"
2351 "All VNIs\n"
2352 JSON_STR)
2353 {
2354 struct zebra_vrf *zvrf;
2355 u_char uj = use_json(argc, argv);
2356
2357 zvrf = vrf_info_lookup(VRF_DEFAULT);
2358 zebra_vxlan_print_macs_all_vni(vty, zvrf, uj);
2359 return CMD_SUCCESS;
2360 }
2361
2362 DEFUN (show_evpn_mac_vni_all_vtep,
2363 show_evpn_mac_vni_all_vtep_cmd,
2364 "show evpn mac vni all vtep A.B.C.D [json]",
2365 SHOW_STR
2366 "EVPN\n"
2367 "MAC addresses\n"
2368 "VxLAN Network Identifier\n"
2369 "All VNIs\n"
2370 "Remote VTEP\n"
2371 "Remote VTEP IP address\n"
2372 JSON_STR)
2373 {
2374 struct zebra_vrf *zvrf;
2375 struct in_addr vtep_ip;
2376 u_char uj = use_json(argc, argv);
2377
2378 if (!inet_aton(argv[6]->arg, &vtep_ip)) {
2379 if (!uj)
2380 vty_out(vty, "%% Malformed VTEP IP address\n");
2381 return CMD_WARNING;
2382 }
2383 zvrf = vrf_info_lookup(VRF_DEFAULT);
2384 zebra_vxlan_print_macs_all_vni_vtep(vty, zvrf, vtep_ip, uj);
2385
2386 return CMD_SUCCESS;
2387 }
2388
2389
2390 DEFUN (show_evpn_mac_vni_mac,
2391 show_evpn_mac_vni_mac_cmd,
2392 "show evpn mac vni " CMD_VNI_RANGE " mac WORD",
2393 SHOW_STR
2394 "EVPN\n"
2395 "MAC addresses\n"
2396 "VxLAN Network Identifier\n"
2397 "VNI number\n"
2398 "MAC\n"
2399 "MAC address (e.g., 00:e0:ec:20:12:62)\n")
2400 {
2401 struct zebra_vrf *zvrf;
2402 vni_t vni;
2403 struct ethaddr mac;
2404
2405 vni = strtoul(argv[4]->arg, NULL, 10);
2406 if (!prefix_str2mac(argv[6]->arg, &mac)) {
2407 vty_out(vty, "%% Malformed MAC address");
2408 return CMD_WARNING;
2409 }
2410 zvrf = vrf_info_lookup(VRF_DEFAULT);
2411 zebra_vxlan_print_specific_mac_vni(vty, zvrf, vni, &mac);
2412 return CMD_SUCCESS;
2413 }
2414
2415 DEFUN (show_evpn_mac_vni_vtep,
2416 show_evpn_mac_vni_vtep_cmd,
2417 "show evpn mac vni " CMD_VNI_RANGE " vtep A.B.C.D" "[json]",
2418 SHOW_STR
2419 "EVPN\n"
2420 "MAC addresses\n"
2421 "VxLAN Network Identifier\n"
2422 "VNI number\n"
2423 "Remote VTEP\n"
2424 "Remote VTEP IP address\n"
2425 JSON_STR)
2426 {
2427 struct zebra_vrf *zvrf;
2428 vni_t vni;
2429 struct in_addr vtep_ip;
2430 u_char uj = use_json(argc, argv);
2431
2432 vni = strtoul(argv[4]->arg, NULL, 10);
2433 if (!inet_aton(argv[6]->arg, &vtep_ip)) {
2434 if (!uj)
2435 vty_out(vty, "%% Malformed VTEP IP address\n");
2436 return CMD_WARNING;
2437 }
2438
2439 zvrf = vrf_info_lookup(VRF_DEFAULT);
2440 zebra_vxlan_print_macs_vni_vtep(vty, zvrf, vni, vtep_ip, uj);
2441 return CMD_SUCCESS;
2442 }
2443
2444 DEFUN (show_evpn_neigh_vni,
2445 show_evpn_neigh_vni_cmd,
2446 "show evpn arp-cache vni " CMD_VNI_RANGE "[json]",
2447 SHOW_STR
2448 "EVPN\n"
2449 "ARP and ND cache\n"
2450 "VxLAN Network Identifier\n"
2451 "VNI number\n"
2452 JSON_STR)
2453 {
2454 struct zebra_vrf *zvrf;
2455 vni_t vni;
2456 u_char uj = use_json(argc, argv);
2457
2458 vni = strtoul(argv[4]->arg, NULL, 10);
2459 zvrf = vrf_info_lookup(VRF_DEFAULT);
2460 zebra_vxlan_print_neigh_vni(vty, zvrf, vni, uj);
2461 return CMD_SUCCESS;
2462 }
2463
2464 DEFUN (show_evpn_neigh_vni_all,
2465 show_evpn_neigh_vni_all_cmd,
2466 "show evpn arp-cache vni all [json]",
2467 SHOW_STR
2468 "EVPN\n"
2469 "ARP and ND cache\n"
2470 "VxLAN Network Identifier\n"
2471 "All VNIs\n"
2472 JSON_STR)
2473 {
2474 struct zebra_vrf *zvrf;
2475 u_char uj = use_json(argc, argv);
2476
2477 zvrf = vrf_info_lookup(VRF_DEFAULT);
2478 zebra_vxlan_print_neigh_all_vni(vty, zvrf, uj);
2479 return CMD_SUCCESS;
2480 }
2481
2482 DEFUN (show_evpn_neigh_vni_neigh,
2483 show_evpn_neigh_vni_neigh_cmd,
2484 "show evpn arp-cache vni " CMD_VNI_RANGE " ip WORD [json]",
2485 SHOW_STR
2486 "EVPN\n"
2487 "ARP and ND cache\n"
2488 "VxLAN Network Identifier\n"
2489 "VNI number\n"
2490 "Neighbor\n"
2491 "Neighbor address (IPv4 or IPv6 address)\n"
2492 JSON_STR)
2493 {
2494 struct zebra_vrf *zvrf;
2495 vni_t vni;
2496 struct ipaddr ip;
2497 u_char uj = use_json(argc, argv);
2498
2499 vni = strtoul(argv[4]->arg, NULL, 10);
2500 if (str2ipaddr(argv[6]->arg, &ip) != 0) {
2501 if (!uj)
2502 vty_out(vty, "%% Malformed Neighbor address\n");
2503 return CMD_WARNING;
2504 }
2505 zvrf = vrf_info_lookup(VRF_DEFAULT);
2506 zebra_vxlan_print_specific_neigh_vni(vty, zvrf, vni, &ip, uj);
2507 return CMD_SUCCESS;
2508 }
2509
2510 DEFUN (show_evpn_neigh_vni_vtep,
2511 show_evpn_neigh_vni_vtep_cmd,
2512 "show evpn arp-cache vni " CMD_VNI_RANGE " vtep A.B.C.D [json]",
2513 SHOW_STR
2514 "EVPN\n"
2515 "ARP and ND cache\n"
2516 "VxLAN Network Identifier\n"
2517 "VNI number\n"
2518 "Remote VTEP\n"
2519 "Remote VTEP IP address\n"
2520 JSON_STR)
2521 {
2522 struct zebra_vrf *zvrf;
2523 vni_t vni;
2524 struct in_addr vtep_ip;
2525 u_char uj = use_json(argc, argv);
2526
2527 vni = strtoul(argv[4]->arg, NULL, 10);
2528 if (!inet_aton(argv[6]->arg, &vtep_ip)) {
2529 if (!uj)
2530 vty_out(vty, "%% Malformed VTEP IP address\n");
2531 return CMD_WARNING;
2532 }
2533
2534 zvrf = vrf_info_lookup(VRF_DEFAULT);
2535 zebra_vxlan_print_neigh_vni_vtep(vty, zvrf, vni, vtep_ip, uj);
2536 return CMD_SUCCESS;
2537 }
2538
2539 /* Static ip route configuration write function. */
2540 static int zebra_ip_config(struct vty *vty)
2541 {
2542 int write = 0;
2543
2544 write += static_config(vty, AFI_IP, SAFI_UNICAST, "ip route");
2545 write += static_config(vty, AFI_IP, SAFI_MULTICAST, "ip mroute");
2546 write += static_config(vty, AFI_IP6, SAFI_UNICAST, "ipv6 route");
2547
2548 write += zebra_import_table_config(vty);
2549 return write;
2550 }
2551
2552 DEFUN (ip_zebra_import_table_distance,
2553 ip_zebra_import_table_distance_cmd,
2554 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
2555 IP_STR
2556 "import routes from non-main kernel table\n"
2557 "kernel routing table id\n"
2558 "Distance for imported routes\n"
2559 "Default distance value\n"
2560 "route-map for filtering\n"
2561 "route-map name\n")
2562 {
2563 u_int32_t table_id = 0;
2564
2565 table_id = strtoul(argv[2]->arg, NULL, 10);
2566 int distance = ZEBRA_TABLE_DISTANCE_DEFAULT;
2567 char *rmap =
2568 strmatch(argv[argc - 2]->text, "route-map")
2569 ? XSTRDUP(MTYPE_ROUTE_MAP_NAME, argv[argc - 1]->arg)
2570 : NULL;
2571 int ret;
2572
2573 if (argc == 7 || (argc == 5 && !rmap))
2574 distance = strtoul(argv[4]->arg, NULL, 10);
2575
2576 if (!is_zebra_valid_kernel_table(table_id)) {
2577 vty_out(vty,
2578 "Invalid routing table ID, %d. Must be in range 1-252\n",
2579 table_id);
2580 if (rmap)
2581 XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
2582 return CMD_WARNING;
2583 }
2584
2585 if (is_zebra_main_routing_table(table_id)) {
2586 vty_out(vty,
2587 "Invalid routing table ID, %d. Must be non-default table\n",
2588 table_id);
2589 if (rmap)
2590 XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
2591 return CMD_WARNING;
2592 }
2593
2594 ret = zebra_import_table(AFI_IP, table_id, distance, rmap, 1);
2595 if (rmap)
2596 XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
2597
2598 return ret;
2599 }
2600
2601 DEFUN (no_ip_zebra_import_table,
2602 no_ip_zebra_import_table_cmd,
2603 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
2604 NO_STR
2605 IP_STR
2606 "import routes from non-main kernel table\n"
2607 "kernel routing table id\n"
2608 "Distance for imported routes\n"
2609 "Default distance value\n"
2610 "route-map for filtering\n"
2611 "route-map name\n")
2612 {
2613 u_int32_t table_id = 0;
2614 table_id = strtoul(argv[3]->arg, NULL, 10);
2615
2616 if (!is_zebra_valid_kernel_table(table_id)) {
2617 vty_out(vty,
2618 "Invalid routing table ID. Must be in range 1-252\n");
2619 return CMD_WARNING;
2620 }
2621
2622 if (is_zebra_main_routing_table(table_id)) {
2623 vty_out(vty,
2624 "Invalid routing table ID, %d. Must be non-default table\n",
2625 table_id);
2626 return CMD_WARNING;
2627 }
2628
2629 if (!is_zebra_import_table_enabled(AFI_IP, table_id))
2630 return CMD_SUCCESS;
2631
2632 return (zebra_import_table(AFI_IP, table_id, 0, NULL, 0));
2633 }
2634
2635 static int config_write_protocol(struct vty *vty)
2636 {
2637 if (allow_delete)
2638 vty_out(vty, "allow-external-route-update\n");
2639
2640 if (zebra_rnh_ip_default_route)
2641 vty_out(vty, "ip nht resolve-via-default\n");
2642
2643 if (zebra_rnh_ipv6_default_route)
2644 vty_out(vty, "ipv6 nht resolve-via-default\n");
2645
2646 enum multicast_mode ipv4_multicast_mode = multicast_mode_ipv4_get();
2647
2648 if (ipv4_multicast_mode != MCAST_NO_CONFIG)
2649 vty_out(vty, "ip multicast rpf-lookup-mode %s\n",
2650 ipv4_multicast_mode == MCAST_URIB_ONLY
2651 ? "urib-only"
2652 : ipv4_multicast_mode == MCAST_MRIB_ONLY
2653 ? "mrib-only"
2654 : ipv4_multicast_mode
2655 == MCAST_MIX_MRIB_FIRST
2656 ? "mrib-then-urib"
2657 : ipv4_multicast_mode
2658 == MCAST_MIX_DISTANCE
2659 ? "lower-distance"
2660 : "longer-prefix");
2661
2662 zebra_routemap_config_write_protocol(vty);
2663
2664 return 1;
2665 }
2666
2667 /* IP node for static routes. */
2668 static struct cmd_node ip_node = {IP_NODE, "", 1};
2669 static struct cmd_node protocol_node = {PROTOCOL_NODE, "", 1};
2670
2671 /* Route VTY. */
2672 void zebra_vty_init(void)
2673 {
2674 install_node(&ip_node, zebra_ip_config);
2675 install_node(&protocol_node, config_write_protocol);
2676
2677 install_element(CONFIG_NODE, &allow_external_route_update_cmd);
2678 install_element(CONFIG_NODE, &no_allow_external_route_update_cmd);
2679 install_element(CONFIG_NODE, &ip_mroute_dist_cmd);
2680 install_element(CONFIG_NODE, &ip_multicast_mode_cmd);
2681 install_element(CONFIG_NODE, &no_ip_multicast_mode_cmd);
2682 install_element(CONFIG_NODE, &ip_route_cmd);
2683 install_element(CONFIG_NODE, &ip_zebra_import_table_distance_cmd);
2684 install_element(CONFIG_NODE, &no_ip_zebra_import_table_cmd);
2685
2686 install_element(VIEW_NODE, &show_vrf_cmd);
2687 install_element(VIEW_NODE, &show_ip_route_cmd);
2688 install_element(VIEW_NODE, &show_ip_nht_cmd);
2689 install_element(VIEW_NODE, &show_ip_nht_vrf_all_cmd);
2690 install_element(VIEW_NODE, &show_ipv6_nht_cmd);
2691 install_element(VIEW_NODE, &show_ipv6_nht_vrf_all_cmd);
2692 install_element(VIEW_NODE, &show_ip_route_addr_cmd);
2693 install_element(VIEW_NODE, &show_ip_route_prefix_cmd);
2694 install_element(VIEW_NODE, &show_ip_route_summary_cmd);
2695 install_element(VIEW_NODE, &show_ip_route_summary_prefix_cmd);
2696
2697 install_element(VIEW_NODE, &show_ip_rpf_cmd);
2698 install_element(VIEW_NODE, &show_ip_rpf_addr_cmd);
2699
2700 install_element(VIEW_NODE, &show_ip_route_vrf_all_addr_cmd);
2701 install_element(VIEW_NODE, &show_ip_route_vrf_all_prefix_cmd);
2702 install_element(VIEW_NODE, &show_ip_route_vrf_all_summary_cmd);
2703 install_element(VIEW_NODE, &show_ip_route_vrf_all_summary_prefix_cmd);
2704
2705 install_element(CONFIG_NODE, &ipv6_route_cmd);
2706 install_element(CONFIG_NODE, &ip_nht_default_route_cmd);
2707 install_element(CONFIG_NODE, &no_ip_nht_default_route_cmd);
2708 install_element(CONFIG_NODE, &ipv6_nht_default_route_cmd);
2709 install_element(CONFIG_NODE, &no_ipv6_nht_default_route_cmd);
2710 install_element(VIEW_NODE, &show_ipv6_route_cmd);
2711 install_element(VIEW_NODE, &show_ipv6_route_summary_cmd);
2712 install_element(VIEW_NODE, &show_ipv6_route_summary_prefix_cmd);
2713 install_element(VIEW_NODE, &show_ipv6_route_addr_cmd);
2714 install_element(VIEW_NODE, &show_ipv6_route_prefix_cmd);
2715 install_element(VIEW_NODE, &show_ipv6_mroute_cmd);
2716
2717 /* Commands for VRF */
2718 install_element(VIEW_NODE, &show_ipv6_route_vrf_all_summary_cmd);
2719 install_element(VIEW_NODE, &show_ipv6_route_vrf_all_summary_prefix_cmd);
2720 install_element(VIEW_NODE, &show_ipv6_route_vrf_all_addr_cmd);
2721 install_element(VIEW_NODE, &show_ipv6_route_vrf_all_prefix_cmd);
2722
2723 install_element(VIEW_NODE, &show_ipv6_mroute_vrf_all_cmd);
2724
2725 install_element(VIEW_NODE, &show_evpn_vni_cmd);
2726 install_element(VIEW_NODE, &show_evpn_vni_vni_cmd);
2727 install_element(VIEW_NODE, &show_evpn_mac_vni_cmd);
2728 install_element(VIEW_NODE, &show_evpn_mac_vni_all_cmd);
2729 install_element(VIEW_NODE, &show_evpn_mac_vni_all_vtep_cmd);
2730 install_element(VIEW_NODE, &show_evpn_mac_vni_mac_cmd);
2731 install_element(VIEW_NODE, &show_evpn_mac_vni_vtep_cmd);
2732 install_element(VIEW_NODE, &show_evpn_neigh_vni_cmd);
2733 install_element(VIEW_NODE, &show_evpn_neigh_vni_all_cmd);
2734 install_element(VIEW_NODE, &show_evpn_neigh_vni_neigh_cmd);
2735 install_element(VIEW_NODE, &show_evpn_neigh_vni_vtep_cmd);
2736 }