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