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