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