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