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