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