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