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