]> git.proxmox.com Git - mirror_frr.git/blob - zebra/zebra_vty.c
Merge pull request #5060 from chiragshah6/evpn_dev2
[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 if (zrt->table)
1029 do_show_route_helper(vty, info->zvrf, zrt->table, afi,
1030 false, 0, false, false,
1031 0, 0, !!json, zrt->tableid);
1032 }
1033 return CMD_SUCCESS;
1034 }
1035
1036 DEFPY (show_ip_nht,
1037 show_ip_nht_cmd,
1038 "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]",
1039 SHOW_STR
1040 IP_STR
1041 IP6_STR
1042 "IP nexthop tracking table\n"
1043 "IP import check tracking table\n"
1044 "IPv4 Address\n"
1045 "IPv6 Address\n"
1046 VRF_CMD_HELP_STR
1047 "IPv4 Address\n"
1048 "IPv6 Address\n"
1049 VRF_ALL_CMD_HELP_STR)
1050 {
1051 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
1052 vrf_id_t vrf_id = VRF_DEFAULT;
1053 struct prefix prefix, *p = NULL;
1054 rnh_type_t rtype;
1055
1056 if (strcmp(type, "nht") == 0)
1057 rtype = RNH_NEXTHOP_TYPE;
1058 else
1059 rtype = RNH_IMPORT_CHECK_TYPE;
1060
1061 if (vrf_all) {
1062 struct vrf *vrf;
1063 struct zebra_vrf *zvrf;
1064
1065 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
1066 if ((zvrf = vrf->info) != NULL) {
1067 vty_out(vty, "\nVRF %s:\n", zvrf_name(zvrf));
1068 zebra_print_rnh_table(zvrf_id(zvrf), afi, vty,
1069 rtype, NULL);
1070 }
1071 return CMD_SUCCESS;
1072 }
1073 if (vrf_name)
1074 VRF_GET_ID(vrf_id, vrf_name, false);
1075
1076 memset(&prefix, 0, sizeof(prefix));
1077 if (addr)
1078 p = sockunion2hostprefix(addr, &prefix);
1079
1080 zebra_print_rnh_table(vrf_id, afi, vty, rtype, p);
1081 return CMD_SUCCESS;
1082 }
1083
1084 DEFUN (ip_nht_default_route,
1085 ip_nht_default_route_cmd,
1086 "ip nht resolve-via-default",
1087 IP_STR
1088 "Filter Next Hop tracking route resolution\n"
1089 "Resolve via default route\n")
1090 {
1091 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
1092
1093 if (!zvrf)
1094 return CMD_WARNING;
1095
1096 if (zvrf->zebra_rnh_ip_default_route)
1097 return CMD_SUCCESS;
1098
1099 zvrf->zebra_rnh_ip_default_route = 1;
1100
1101 zebra_evaluate_rnh(zvrf, AFI_IP, 1, RNH_NEXTHOP_TYPE, NULL);
1102 return CMD_SUCCESS;
1103 }
1104
1105 DEFUN (no_ip_nht_default_route,
1106 no_ip_nht_default_route_cmd,
1107 "no ip nht resolve-via-default",
1108 NO_STR
1109 IP_STR
1110 "Filter Next Hop tracking route resolution\n"
1111 "Resolve via default route\n")
1112 {
1113 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
1114
1115 if (!zvrf)
1116 return CMD_WARNING;
1117
1118 if (!zvrf->zebra_rnh_ip_default_route)
1119 return CMD_SUCCESS;
1120
1121 zvrf->zebra_rnh_ip_default_route = 0;
1122 zebra_evaluate_rnh(zvrf, AFI_IP, 1, RNH_NEXTHOP_TYPE, NULL);
1123 return CMD_SUCCESS;
1124 }
1125
1126 DEFUN (ipv6_nht_default_route,
1127 ipv6_nht_default_route_cmd,
1128 "ipv6 nht resolve-via-default",
1129 IP6_STR
1130 "Filter Next Hop tracking route resolution\n"
1131 "Resolve via default route\n")
1132 {
1133 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
1134
1135 if (!zvrf)
1136 return CMD_WARNING;
1137
1138 if (zvrf->zebra_rnh_ipv6_default_route)
1139 return CMD_SUCCESS;
1140
1141 zvrf->zebra_rnh_ipv6_default_route = 1;
1142 zebra_evaluate_rnh(zvrf, AFI_IP6, 1, RNH_NEXTHOP_TYPE, NULL);
1143 return CMD_SUCCESS;
1144 }
1145
1146 DEFUN (no_ipv6_nht_default_route,
1147 no_ipv6_nht_default_route_cmd,
1148 "no ipv6 nht resolve-via-default",
1149 NO_STR
1150 IP6_STR
1151 "Filter Next Hop tracking route resolution\n"
1152 "Resolve via default route\n")
1153 {
1154
1155 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
1156
1157 if (!zvrf)
1158 return CMD_WARNING;
1159
1160 if (!zvrf->zebra_rnh_ipv6_default_route)
1161 return CMD_SUCCESS;
1162
1163 zvrf->zebra_rnh_ipv6_default_route = 0;
1164 zebra_evaluate_rnh(zvrf, AFI_IP6, 1, RNH_NEXTHOP_TYPE, NULL);
1165 return CMD_SUCCESS;
1166 }
1167
1168 DEFPY (show_route,
1169 show_route_cmd,
1170 "show\
1171 <\
1172 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1173 [{\
1174 tag (1-4294967295)\
1175 |A.B.C.D/M$prefix longer-prefixes\
1176 |supernets-only$supernets_only\
1177 }]\
1178 [<\
1179 " FRR_IP_REDIST_STR_ZEBRA "$type_str\
1180 |ospf$type_str (1-65535)$ospf_instance_id\
1181 >]\
1182 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1183 [{\
1184 tag (1-4294967295)\
1185 |X:X::X:X/M$prefix longer-prefixes\
1186 }]\
1187 [" FRR_IP6_REDIST_STR_ZEBRA "$type_str]\
1188 >\
1189 [json$json]",
1190 SHOW_STR
1191 IP_STR
1192 "IP forwarding table\n"
1193 "IP routing table\n"
1194 VRF_FULL_CMD_HELP_STR
1195 "Show only routes with tag\n"
1196 "Tag value\n"
1197 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1198 "Show route matching the specified Network/Mask pair only\n"
1199 "Show supernet entries only\n"
1200 FRR_IP_REDIST_HELP_STR_ZEBRA
1201 "Open Shortest Path First (OSPFv2)\n"
1202 "Instance ID\n"
1203 IPV6_STR
1204 "IP forwarding table\n"
1205 "IP routing table\n"
1206 VRF_FULL_CMD_HELP_STR
1207 "Show only routes with tag\n"
1208 "Tag value\n"
1209 "IPv6 prefix\n"
1210 "Show route matching the specified Network/Mask pair only\n"
1211 FRR_IP6_REDIST_HELP_STR_ZEBRA
1212 JSON_STR)
1213 {
1214 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
1215 struct vrf *vrf;
1216 int type = 0;
1217
1218 if (type_str) {
1219 type = proto_redistnum(afi, type_str);
1220 if (type < 0) {
1221 vty_out(vty, "Unknown route type\n");
1222 return CMD_WARNING;
1223 }
1224 }
1225
1226 if (vrf_all) {
1227 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
1228 struct zebra_vrf *zvrf;
1229 struct route_table *table;
1230
1231 if ((zvrf = vrf->info) == NULL
1232 || (table = zvrf->table[afi][SAFI_UNICAST]) == NULL)
1233 continue;
1234
1235 do_show_ip_route(
1236 vty, zvrf_name(zvrf), afi, SAFI_UNICAST, !!fib,
1237 !!json, tag, prefix_str ? prefix : NULL,
1238 !!supernets_only, type, ospf_instance_id);
1239 }
1240 } else {
1241 vrf_id_t vrf_id = VRF_DEFAULT;
1242
1243 if (vrf_name)
1244 VRF_GET_ID(vrf_id, vrf_name, !!json);
1245 vrf = vrf_lookup_by_id(vrf_id);
1246 do_show_ip_route(vty, vrf->name, afi, SAFI_UNICAST, !!fib,
1247 !!json, tag, prefix_str ? prefix : NULL,
1248 !!supernets_only, type, ospf_instance_id);
1249 }
1250
1251 return CMD_SUCCESS;
1252 }
1253
1254 DEFPY (show_route_detail,
1255 show_route_detail_cmd,
1256 "show\
1257 <\
1258 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1259 <\
1260 A.B.C.D$address\
1261 |A.B.C.D/M$prefix\
1262 >\
1263 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1264 <\
1265 X:X::X:X$address\
1266 |X:X::X:X/M$prefix\
1267 >\
1268 >\
1269 [json$json]",
1270 SHOW_STR
1271 IP_STR
1272 "IPv6 forwarding table\n"
1273 "IP routing table\n"
1274 VRF_FULL_CMD_HELP_STR
1275 "Network in the IP routing table to display\n"
1276 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1277 IP6_STR
1278 "IPv6 forwarding table\n"
1279 "IPv6 routing table\n"
1280 VRF_FULL_CMD_HELP_STR
1281 "IPv6 Address\n"
1282 "IPv6 prefix\n"
1283 JSON_STR)
1284 {
1285 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
1286 struct route_table *table;
1287 struct prefix p;
1288 struct route_node *rn;
1289 bool use_fib = !!fib;
1290 rib_dest_t *dest;
1291 bool network_found = false;
1292
1293 if (address_str)
1294 prefix_str = address_str;
1295 if (str2prefix(prefix_str, &p) < 0) {
1296 vty_out(vty, "%% Malformed address\n");
1297 return CMD_WARNING;
1298 }
1299
1300 if (vrf_all) {
1301 struct vrf *vrf;
1302 struct zebra_vrf *zvrf;
1303
1304 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
1305 if ((zvrf = vrf->info) == NULL
1306 || (table = zvrf->table[afi][SAFI_UNICAST]) == NULL)
1307 continue;
1308
1309 rn = route_node_match(table, &p);
1310 if (!rn)
1311 continue;
1312 if (!address_str && rn->p.prefixlen != p.prefixlen) {
1313 route_unlock_node(rn);
1314 continue;
1315 }
1316
1317 dest = rib_dest_from_rnode(rn);
1318 if (use_fib && !dest->selected_fib) {
1319 route_unlock_node(rn);
1320 continue;
1321 }
1322
1323 network_found = true;
1324 if (json)
1325 vty_show_ip_route_detail_json(vty, rn,
1326 use_fib);
1327 else
1328 vty_show_ip_route_detail(vty, rn, 0, use_fib);
1329
1330 route_unlock_node(rn);
1331 }
1332
1333 if (!network_found) {
1334 if (json)
1335 vty_out(vty, "{}\n");
1336 else {
1337 if (use_fib)
1338 vty_out(vty,
1339 "%% Network not in FIB\n");
1340 else
1341 vty_out(vty,
1342 "%% Network not in RIB\n");
1343 }
1344 return CMD_WARNING;
1345 }
1346 } else {
1347 vrf_id_t vrf_id = VRF_DEFAULT;
1348
1349 if (vrf_name)
1350 VRF_GET_ID(vrf_id, vrf_name, false);
1351
1352 table = zebra_vrf_table(afi, SAFI_UNICAST, vrf_id);
1353 if (!table)
1354 return CMD_SUCCESS;
1355
1356 rn = route_node_match(table, &p);
1357 if (rn)
1358 dest = rib_dest_from_rnode(rn);
1359
1360 if (!rn || (!address_str && rn->p.prefixlen != p.prefixlen) ||
1361 (use_fib && dest && !dest->selected_fib)) {
1362 if (json)
1363 vty_out(vty, "{}\n");
1364 else {
1365 if (use_fib)
1366 vty_out(vty,
1367 "%% Network not in FIB\n");
1368 else
1369 vty_out(vty,
1370 "%% Network not in table\n");
1371 }
1372 if (rn)
1373 route_unlock_node(rn);
1374 return CMD_WARNING;
1375 }
1376
1377 if (json)
1378 vty_show_ip_route_detail_json(vty, rn, use_fib);
1379 else
1380 vty_show_ip_route_detail(vty, rn, 0, use_fib);
1381
1382 route_unlock_node(rn);
1383 }
1384
1385 return CMD_SUCCESS;
1386 }
1387
1388 DEFPY (show_route_summary,
1389 show_route_summary_cmd,
1390 "show <ip$ipv4|ipv6$ipv6> route [vrf <NAME$vrf_name|all$vrf_all>] \
1391 summary [table (1-4294967295)$table_id] [prefix$prefix]",
1392 SHOW_STR
1393 IP_STR
1394 IP6_STR
1395 "IP routing table\n"
1396 VRF_FULL_CMD_HELP_STR
1397 "Summary of all routes\n"
1398 "Table to display summary for\n"
1399 "The table number\n"
1400 "Prefix routes\n")
1401 {
1402 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
1403 struct route_table *table;
1404
1405 if (table_id == 0)
1406 table_id = RT_TABLE_MAIN;
1407
1408 if (vrf_all) {
1409 struct vrf *vrf;
1410 struct zebra_vrf *zvrf;
1411
1412 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
1413 if ((zvrf = vrf->info) == NULL)
1414 continue;
1415
1416 table = zebra_vrf_table_with_table_id(afi,
1417 SAFI_UNICAST,
1418 zvrf->vrf->vrf_id,
1419 table_id);
1420 if (!table)
1421 continue;
1422
1423 if (prefix)
1424 vty_show_ip_route_summary_prefix(vty, table);
1425 else
1426 vty_show_ip_route_summary(vty, table);
1427 }
1428 } else {
1429 vrf_id_t vrf_id = VRF_DEFAULT;
1430
1431 if (vrf_name)
1432 VRF_GET_ID(vrf_id, vrf_name, false);
1433
1434 table = zebra_vrf_table_with_table_id(afi,
1435 SAFI_UNICAST,
1436 vrf_id, table_id);
1437 if (!table)
1438 return CMD_SUCCESS;
1439
1440 if (prefix)
1441 vty_show_ip_route_summary_prefix(vty, table);
1442 else
1443 vty_show_ip_route_summary(vty, table);
1444 }
1445
1446 return CMD_SUCCESS;
1447 }
1448
1449 static void vty_show_ip_route_summary(struct vty *vty,
1450 struct route_table *table)
1451 {
1452 struct route_node *rn;
1453 struct route_entry *re;
1454 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1455 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1456 uint32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1457 uint32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1458 uint32_t i;
1459 uint32_t is_ibgp;
1460
1461 memset(&rib_cnt, 0, sizeof(rib_cnt));
1462 memset(&fib_cnt, 0, sizeof(fib_cnt));
1463 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
1464 RNODE_FOREACH_RE (rn, re) {
1465 is_ibgp = (re->type == ZEBRA_ROUTE_BGP
1466 && CHECK_FLAG(re->flags, ZEBRA_FLAG_IBGP));
1467
1468 rib_cnt[ZEBRA_ROUTE_TOTAL]++;
1469 if (is_ibgp)
1470 rib_cnt[ZEBRA_ROUTE_IBGP]++;
1471 else
1472 rib_cnt[re->type]++;
1473
1474 if (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED)) {
1475 fib_cnt[ZEBRA_ROUTE_TOTAL]++;
1476
1477 if (is_ibgp)
1478 fib_cnt[ZEBRA_ROUTE_IBGP]++;
1479 else
1480 fib_cnt[re->type]++;
1481 }
1482 }
1483
1484 vty_out(vty, "%-20s %-20s %s (vrf %s)\n", "Route Source", "Routes",
1485 "FIB", zvrf_name(((rib_table_info_t *)route_table_get_info(table))->zvrf));
1486
1487 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
1488 if ((rib_cnt[i] > 0) || (i == ZEBRA_ROUTE_BGP
1489 && rib_cnt[ZEBRA_ROUTE_IBGP] > 0)) {
1490 if (i == ZEBRA_ROUTE_BGP) {
1491 vty_out(vty, "%-20s %-20d %-20d \n", "ebgp",
1492 rib_cnt[ZEBRA_ROUTE_BGP],
1493 fib_cnt[ZEBRA_ROUTE_BGP]);
1494 vty_out(vty, "%-20s %-20d %-20d \n", "ibgp",
1495 rib_cnt[ZEBRA_ROUTE_IBGP],
1496 fib_cnt[ZEBRA_ROUTE_IBGP]);
1497 } else
1498 vty_out(vty, "%-20s %-20d %-20d \n",
1499 zebra_route_string(i), rib_cnt[i],
1500 fib_cnt[i]);
1501 }
1502 }
1503
1504 vty_out(vty, "------\n");
1505 vty_out(vty, "%-20s %-20d %-20d \n", "Totals",
1506 rib_cnt[ZEBRA_ROUTE_TOTAL], fib_cnt[ZEBRA_ROUTE_TOTAL]);
1507 vty_out(vty, "\n");
1508 }
1509
1510 /*
1511 * Implementation of the ip route summary prefix command.
1512 *
1513 * This command prints the primary prefixes that have been installed by various
1514 * protocols on the box.
1515 *
1516 */
1517 static void vty_show_ip_route_summary_prefix(struct vty *vty,
1518 struct route_table *table)
1519 {
1520 struct route_node *rn;
1521 struct route_entry *re;
1522 struct nexthop *nexthop;
1523 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1524 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1525 uint32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1526 uint32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1527 uint32_t i;
1528 int cnt;
1529
1530 memset(&rib_cnt, 0, sizeof(rib_cnt));
1531 memset(&fib_cnt, 0, sizeof(fib_cnt));
1532 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
1533 RNODE_FOREACH_RE (rn, re) {
1534
1535 /*
1536 * In case of ECMP, count only once.
1537 */
1538 cnt = 0;
1539 if (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED)) {
1540 fib_cnt[ZEBRA_ROUTE_TOTAL]++;
1541 fib_cnt[re->type]++;
1542 }
1543 for (nexthop = re->ng.nexthop; (!cnt && nexthop);
1544 nexthop = nexthop->next) {
1545 cnt++;
1546 rib_cnt[ZEBRA_ROUTE_TOTAL]++;
1547 rib_cnt[re->type]++;
1548 if (re->type == ZEBRA_ROUTE_BGP
1549 && CHECK_FLAG(re->flags, ZEBRA_FLAG_IBGP)) {
1550 rib_cnt[ZEBRA_ROUTE_IBGP]++;
1551 if (CHECK_FLAG(re->status,
1552 ROUTE_ENTRY_INSTALLED))
1553 fib_cnt[ZEBRA_ROUTE_IBGP]++;
1554 }
1555 }
1556 }
1557
1558 vty_out(vty, "%-20s %-20s %s (vrf %s)\n", "Route Source",
1559 "Prefix Routes", "FIB",
1560 zvrf_name(((rib_table_info_t *)route_table_get_info(table))->zvrf));
1561
1562 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
1563 if (rib_cnt[i] > 0) {
1564 if (i == ZEBRA_ROUTE_BGP) {
1565 vty_out(vty, "%-20s %-20d %-20d \n", "ebgp",
1566 rib_cnt[ZEBRA_ROUTE_BGP]
1567 - rib_cnt[ZEBRA_ROUTE_IBGP],
1568 fib_cnt[ZEBRA_ROUTE_BGP]
1569 - fib_cnt[ZEBRA_ROUTE_IBGP]);
1570 vty_out(vty, "%-20s %-20d %-20d \n", "ibgp",
1571 rib_cnt[ZEBRA_ROUTE_IBGP],
1572 fib_cnt[ZEBRA_ROUTE_IBGP]);
1573 } else
1574 vty_out(vty, "%-20s %-20d %-20d \n",
1575 zebra_route_string(i), rib_cnt[i],
1576 fib_cnt[i]);
1577 }
1578 }
1579
1580 vty_out(vty, "------\n");
1581 vty_out(vty, "%-20s %-20d %-20d \n", "Totals",
1582 rib_cnt[ZEBRA_ROUTE_TOTAL], fib_cnt[ZEBRA_ROUTE_TOTAL]);
1583 vty_out(vty, "\n");
1584 }
1585
1586 /*
1587 * Show IPv6 mroute command.Used to dump
1588 * the Multicast routing table.
1589 */
1590 DEFUN (show_ipv6_mroute,
1591 show_ipv6_mroute_cmd,
1592 "show ipv6 mroute [vrf NAME]",
1593 SHOW_STR
1594 IP_STR
1595 "IPv6 Multicast routing table\n"
1596 VRF_CMD_HELP_STR)
1597 {
1598 struct route_table *table;
1599 struct route_node *rn;
1600 struct route_entry *re;
1601 int first = 1;
1602 vrf_id_t vrf_id = VRF_DEFAULT;
1603
1604 if (argc == 5)
1605 VRF_GET_ID(vrf_id, argv[4]->arg, false);
1606
1607 table = zebra_vrf_table(AFI_IP6, SAFI_MULTICAST, vrf_id);
1608 if (!table)
1609 return CMD_SUCCESS;
1610
1611 /* Show all IPv6 route. */
1612 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
1613 RNODE_FOREACH_RE (rn, re) {
1614 if (first) {
1615 vty_out(vty, SHOW_ROUTE_V6_HEADER);
1616 first = 0;
1617 }
1618 vty_show_ip_route(vty, rn, re, NULL, false);
1619 }
1620 return CMD_SUCCESS;
1621 }
1622
1623 DEFUN (show_ipv6_mroute_vrf_all,
1624 show_ipv6_mroute_vrf_all_cmd,
1625 "show ipv6 mroute vrf all",
1626 SHOW_STR
1627 IP_STR
1628 "IPv6 Multicast routing table\n"
1629 VRF_ALL_CMD_HELP_STR)
1630 {
1631 struct route_table *table;
1632 struct route_node *rn;
1633 struct route_entry *re;
1634 struct vrf *vrf;
1635 struct zebra_vrf *zvrf;
1636 int first = 1;
1637
1638 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
1639 if ((zvrf = vrf->info) == NULL
1640 || (table = zvrf->table[AFI_IP6][SAFI_MULTICAST]) == NULL)
1641 continue;
1642
1643 /* Show all IPv6 route. */
1644 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
1645 RNODE_FOREACH_RE (rn, re) {
1646 if (first) {
1647 vty_out(vty, SHOW_ROUTE_V6_HEADER);
1648 first = 0;
1649 }
1650 vty_show_ip_route(vty, rn, re, NULL, false);
1651 }
1652 }
1653 return CMD_SUCCESS;
1654 }
1655
1656 DEFUN (allow_external_route_update,
1657 allow_external_route_update_cmd,
1658 "allow-external-route-update",
1659 "Allow FRR routes to be overwritten by external processes\n")
1660 {
1661 allow_delete = 1;
1662
1663 return CMD_SUCCESS;
1664 }
1665
1666 DEFUN (no_allow_external_route_update,
1667 no_allow_external_route_update_cmd,
1668 "no allow-external-route-update",
1669 NO_STR
1670 "Allow FRR routes to be overwritten by external processes\n")
1671 {
1672 allow_delete = 0;
1673
1674 return CMD_SUCCESS;
1675 }
1676
1677 /* show vrf */
1678 DEFUN (show_vrf,
1679 show_vrf_cmd,
1680 "show vrf",
1681 SHOW_STR
1682 "VRF\n")
1683 {
1684 struct vrf *vrf;
1685 struct zebra_vrf *zvrf;
1686
1687 if (vrf_is_backend_netns())
1688 vty_out(vty, "netns-based vrfs\n");
1689
1690 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
1691 if (!(zvrf = vrf->info))
1692 continue;
1693 if (zvrf_id(zvrf) == VRF_DEFAULT)
1694 continue;
1695
1696 vty_out(vty, "vrf %s ", zvrf_name(zvrf));
1697 if (zvrf_id(zvrf) == VRF_UNKNOWN || !zvrf_is_active(zvrf))
1698 vty_out(vty, "inactive");
1699 else if (zvrf_ns_name(zvrf))
1700 vty_out(vty, "id %u netns %s", zvrf_id(zvrf),
1701 zvrf_ns_name(zvrf));
1702 else
1703 vty_out(vty, "id %u table %u", zvrf_id(zvrf),
1704 zvrf->table_id);
1705 if (vrf_is_user_cfged(vrf))
1706 vty_out(vty, " (configured)");
1707 vty_out(vty, "\n");
1708 }
1709
1710 return CMD_SUCCESS;
1711 }
1712
1713 DEFUN (default_vrf_vni_mapping,
1714 default_vrf_vni_mapping_cmd,
1715 "vni " CMD_VNI_RANGE "[prefix-routes-only]",
1716 "VNI corresponding to the DEFAULT VRF\n"
1717 "VNI-ID\n"
1718 "Prefix routes only \n")
1719 {
1720 int ret = 0;
1721 char err[ERR_STR_SZ];
1722 struct zebra_vrf *zvrf = NULL;
1723 vni_t vni = strtoul(argv[1]->arg, NULL, 10);
1724 int filter = 0;
1725
1726 zvrf = vrf_info_lookup(VRF_DEFAULT);
1727 if (!zvrf)
1728 return CMD_WARNING;
1729
1730 if (argc == 3)
1731 filter = 1;
1732
1733 ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ,
1734 filter, 1);
1735 if (ret != 0) {
1736 vty_out(vty, "%s\n", err);
1737 return CMD_WARNING;
1738 }
1739
1740 return CMD_SUCCESS;
1741 }
1742
1743 DEFUN (no_default_vrf_vni_mapping,
1744 no_default_vrf_vni_mapping_cmd,
1745 "no vni " CMD_VNI_RANGE,
1746 NO_STR
1747 "VNI corresponding to DEFAULT VRF\n"
1748 "VNI-ID")
1749 {
1750 int ret = 0;
1751 char err[ERR_STR_SZ];
1752 vni_t vni = strtoul(argv[2]->arg, NULL, 10);
1753 struct zebra_vrf *zvrf = NULL;
1754
1755 zvrf = vrf_info_lookup(VRF_DEFAULT);
1756 if (!zvrf)
1757 return CMD_WARNING;
1758
1759 ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ, 0, 0);
1760 if (ret != 0) {
1761 vty_out(vty, "%s\n", err);
1762 return CMD_WARNING;
1763 }
1764
1765 return CMD_SUCCESS;
1766 }
1767
1768 DEFUN (vrf_vni_mapping,
1769 vrf_vni_mapping_cmd,
1770 "vni " CMD_VNI_RANGE "[prefix-routes-only]",
1771 "VNI corresponding to tenant VRF\n"
1772 "VNI-ID\n"
1773 "prefix-routes-only\n")
1774 {
1775 int ret = 0;
1776 int filter = 0;
1777
1778 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
1779 vni_t vni = strtoul(argv[1]->arg, NULL, 10);
1780 char err[ERR_STR_SZ];
1781
1782 assert(vrf);
1783 assert(zvrf);
1784
1785 if (argc == 3)
1786 filter = 1;
1787
1788 /* Mark as having FRR configuration */
1789 vrf_set_user_cfged(vrf);
1790 ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ,
1791 filter, 1);
1792 if (ret != 0) {
1793 vty_out(vty, "%s\n", err);
1794 return CMD_WARNING;
1795 }
1796
1797 return CMD_SUCCESS;
1798 }
1799
1800 DEFUN (no_vrf_vni_mapping,
1801 no_vrf_vni_mapping_cmd,
1802 "no vni " CMD_VNI_RANGE "[prefix-routes-only]",
1803 NO_STR
1804 "VNI corresponding to tenant VRF\n"
1805 "VNI-ID\n"
1806 "prefix-routes-only\n")
1807 {
1808 int ret = 0;
1809 int filter = 0;
1810 char err[ERR_STR_SZ];
1811 vni_t vni = strtoul(argv[2]->arg, NULL, 10);
1812
1813 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
1814
1815 assert(vrf);
1816 assert(zvrf);
1817
1818 if (argc == 4)
1819 filter = 1;
1820
1821 ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err,
1822 ERR_STR_SZ, filter, 0);
1823 if (ret != 0) {
1824 vty_out(vty, "%s\n", err);
1825 return CMD_WARNING;
1826 }
1827
1828 /* If no other FRR config for this VRF, mark accordingly. */
1829 if (!zebra_vrf_has_config(zvrf))
1830 vrf_reset_user_cfged(vrf);
1831
1832 return CMD_SUCCESS;
1833 }
1834
1835 /* show vrf */
1836 DEFUN (show_vrf_vni,
1837 show_vrf_vni_cmd,
1838 "show vrf vni [json]",
1839 SHOW_STR
1840 "VRF\n"
1841 "VNI\n"
1842 JSON_STR)
1843 {
1844 struct vrf *vrf;
1845 struct zebra_vrf *zvrf;
1846 json_object *json = NULL;
1847 json_object *json_vrfs = NULL;
1848 bool uj = use_json(argc, argv);
1849
1850 if (uj) {
1851 json = json_object_new_object();
1852 json_vrfs = json_object_new_array();
1853 }
1854
1855 if (!uj)
1856 vty_out(vty, "%-37s %-10s %-20s %-20s %-5s %-18s\n", "VRF",
1857 "VNI", "VxLAN IF", "L3-SVI", "State", "Rmac");
1858
1859 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
1860 zvrf = vrf->info;
1861 if (!zvrf)
1862 continue;
1863
1864 zebra_vxlan_print_vrf_vni(vty, zvrf, json_vrfs);
1865 }
1866
1867 if (uj) {
1868 json_object_object_add(json, "vrfs", json_vrfs);
1869 vty_out(vty, "%s\n", json_object_to_json_string_ext(
1870 json, JSON_C_TO_STRING_PRETTY));
1871 json_object_free(json);
1872 }
1873
1874 return CMD_SUCCESS;
1875 }
1876
1877 DEFUN (show_evpn_global,
1878 show_evpn_global_cmd,
1879 "show evpn [json]",
1880 SHOW_STR
1881 "EVPN\n"
1882 JSON_STR)
1883 {
1884 bool uj = use_json(argc, argv);
1885
1886 zebra_vxlan_print_evpn(vty, uj);
1887 return CMD_SUCCESS;
1888 }
1889
1890 DEFUN (show_evpn_vni,
1891 show_evpn_vni_cmd,
1892 "show evpn vni [json]",
1893 SHOW_STR
1894 "EVPN\n"
1895 "VxLAN Network Identifier\n"
1896 JSON_STR)
1897 {
1898 struct zebra_vrf *zvrf;
1899 bool uj = use_json(argc, argv);
1900
1901 zvrf = zebra_vrf_get_evpn();
1902 zebra_vxlan_print_vnis(vty, zvrf, uj);
1903 return CMD_SUCCESS;
1904 }
1905
1906 DEFUN (show_evpn_vni_detail, show_evpn_vni_detail_cmd,
1907 "show evpn vni detail [json]",
1908 SHOW_STR
1909 "EVPN\n"
1910 "VxLAN Network Identifier\n"
1911 "Detailed Information On Each VNI\n"
1912 JSON_STR)
1913 {
1914 struct zebra_vrf *zvrf;
1915 bool uj = use_json(argc, argv);
1916
1917 zvrf = zebra_vrf_get_evpn();
1918 zebra_vxlan_print_vnis_detail(vty, zvrf, uj);
1919 return CMD_SUCCESS;
1920 }
1921
1922 DEFUN (show_evpn_vni_vni,
1923 show_evpn_vni_vni_cmd,
1924 "show evpn vni " CMD_VNI_RANGE "[json]",
1925 SHOW_STR
1926 "EVPN\n"
1927 "VxLAN Network Identifier\n"
1928 "VNI number\n"
1929 JSON_STR)
1930 {
1931 struct zebra_vrf *zvrf;
1932 vni_t vni;
1933 bool uj = use_json(argc, argv);
1934
1935 vni = strtoul(argv[3]->arg, NULL, 10);
1936 zvrf = zebra_vrf_get_evpn();
1937 zebra_vxlan_print_vni(vty, zvrf, vni, uj);
1938 return CMD_SUCCESS;
1939 }
1940
1941 DEFUN (show_evpn_rmac_vni_mac,
1942 show_evpn_rmac_vni_mac_cmd,
1943 "show evpn rmac vni " CMD_VNI_RANGE " mac WORD [json]",
1944 SHOW_STR
1945 "EVPN\n"
1946 "RMAC\n"
1947 "L3 VNI\n"
1948 "VNI number\n"
1949 "MAC\n"
1950 "mac-address (e.g. 0a:0a:0a:0a:0a:0a)\n"
1951 JSON_STR)
1952 {
1953 vni_t l3vni = 0;
1954 struct ethaddr mac;
1955 bool uj = use_json(argc, argv);
1956
1957 l3vni = strtoul(argv[4]->arg, NULL, 10);
1958 if (!prefix_str2mac(argv[6]->arg, &mac)) {
1959 vty_out(vty, "%% Malformed MAC address\n");
1960 return CMD_WARNING;
1961 }
1962 zebra_vxlan_print_specific_rmac_l3vni(vty, l3vni, &mac, uj);
1963 return CMD_SUCCESS;
1964 }
1965
1966 DEFUN (show_evpn_rmac_vni,
1967 show_evpn_rmac_vni_cmd,
1968 "show evpn rmac vni " CMD_VNI_RANGE "[json]",
1969 SHOW_STR
1970 "EVPN\n"
1971 "RMAC\n"
1972 "L3 VNI\n"
1973 "VNI number\n"
1974 JSON_STR)
1975 {
1976 vni_t l3vni = 0;
1977 bool uj = use_json(argc, argv);
1978
1979 l3vni = strtoul(argv[4]->arg, NULL, 10);
1980 zebra_vxlan_print_rmacs_l3vni(vty, l3vni, uj);
1981
1982 return CMD_SUCCESS;
1983 }
1984
1985 DEFUN (show_evpn_rmac_vni_all,
1986 show_evpn_rmac_vni_all_cmd,
1987 "show evpn rmac vni all [json]",
1988 SHOW_STR
1989 "EVPN\n"
1990 "RMAC addresses\n"
1991 "L3 VNI\n"
1992 "All VNIs\n"
1993 JSON_STR)
1994 {
1995 bool uj = use_json(argc, argv);
1996
1997 zebra_vxlan_print_rmacs_all_l3vni(vty, uj);
1998
1999 return CMD_SUCCESS;
2000 }
2001
2002 DEFUN (show_evpn_nh_vni_ip,
2003 show_evpn_nh_vni_ip_cmd,
2004 "show evpn next-hops vni " CMD_VNI_RANGE " ip WORD [json]",
2005 SHOW_STR
2006 "EVPN\n"
2007 "Remote Vteps\n"
2008 "L3 VNI\n"
2009 "VNI number\n"
2010 "Ip address\n"
2011 "Host address (ipv4 or ipv6)\n"
2012 JSON_STR)
2013 {
2014 vni_t l3vni;
2015 struct ipaddr ip;
2016 bool uj = use_json(argc, argv);
2017
2018 l3vni = strtoul(argv[4]->arg, NULL, 10);
2019 if (str2ipaddr(argv[6]->arg, &ip) != 0) {
2020 if (!uj)
2021 vty_out(vty, "%% Malformed Neighbor address\n");
2022 return CMD_WARNING;
2023 }
2024 zebra_vxlan_print_specific_nh_l3vni(vty, l3vni, &ip, uj);
2025
2026 return CMD_SUCCESS;
2027 }
2028
2029 DEFUN (show_evpn_nh_vni,
2030 show_evpn_nh_vni_cmd,
2031 "show evpn next-hops vni " CMD_VNI_RANGE "[json]",
2032 SHOW_STR
2033 "EVPN\n"
2034 "Remote Vteps\n"
2035 "L3 VNI\n"
2036 "VNI number\n"
2037 JSON_STR)
2038 {
2039 vni_t l3vni;
2040 bool uj = use_json(argc, argv);
2041
2042 l3vni = strtoul(argv[4]->arg, NULL, 10);
2043 zebra_vxlan_print_nh_l3vni(vty, l3vni, uj);
2044
2045 return CMD_SUCCESS;
2046 }
2047
2048 DEFUN (show_evpn_nh_vni_all,
2049 show_evpn_nh_vni_all_cmd,
2050 "show evpn next-hops vni all [json]",
2051 SHOW_STR
2052 "EVPN\n"
2053 "Remote VTEPs\n"
2054 "L3 VNI\n"
2055 "All VNIs\n"
2056 JSON_STR)
2057 {
2058 bool uj = use_json(argc, argv);
2059
2060 zebra_vxlan_print_nh_all_l3vni(vty, uj);
2061
2062 return CMD_SUCCESS;
2063 }
2064
2065 DEFUN (show_evpn_mac_vni,
2066 show_evpn_mac_vni_cmd,
2067 "show evpn mac vni " CMD_VNI_RANGE "[json]",
2068 SHOW_STR
2069 "EVPN\n"
2070 "MAC addresses\n"
2071 "VxLAN Network Identifier\n"
2072 "VNI number\n"
2073 JSON_STR)
2074 {
2075 struct zebra_vrf *zvrf;
2076 vni_t vni;
2077 bool uj = use_json(argc, argv);
2078
2079 vni = strtoul(argv[4]->arg, NULL, 10);
2080 zvrf = zebra_vrf_get_evpn();
2081 zebra_vxlan_print_macs_vni(vty, zvrf, vni, uj);
2082 return CMD_SUCCESS;
2083 }
2084
2085 DEFUN (show_evpn_mac_vni_all,
2086 show_evpn_mac_vni_all_cmd,
2087 "show evpn mac vni all [json]",
2088 SHOW_STR
2089 "EVPN\n"
2090 "MAC addresses\n"
2091 "VxLAN Network Identifier\n"
2092 "All VNIs\n"
2093 JSON_STR)
2094 {
2095 struct zebra_vrf *zvrf;
2096 bool uj = use_json(argc, argv);
2097
2098 zvrf = zebra_vrf_get_evpn();
2099 zebra_vxlan_print_macs_all_vni(vty, zvrf, false, uj);
2100 return CMD_SUCCESS;
2101 }
2102
2103 DEFUN (show_evpn_mac_vni_all_detail, show_evpn_mac_vni_all_detail_cmd,
2104 "show evpn mac vni all detail [json]",
2105 SHOW_STR
2106 "EVPN\n"
2107 "MAC addresses\n"
2108 "VxLAN Network Identifier\n"
2109 "All VNIs\n"
2110 "Detailed Information On Each VNI MAC\n"
2111 JSON_STR)
2112 {
2113 struct zebra_vrf *zvrf;
2114 bool uj = use_json(argc, argv);
2115
2116 zvrf = zebra_vrf_get_evpn();
2117 zebra_vxlan_print_macs_all_vni_detail(vty, zvrf, false, uj);
2118 return CMD_SUCCESS;
2119 }
2120
2121 DEFUN (show_evpn_mac_vni_all_vtep,
2122 show_evpn_mac_vni_all_vtep_cmd,
2123 "show evpn mac vni all vtep A.B.C.D [json]",
2124 SHOW_STR
2125 "EVPN\n"
2126 "MAC addresses\n"
2127 "VxLAN Network Identifier\n"
2128 "All VNIs\n"
2129 "Remote VTEP\n"
2130 "Remote VTEP IP address\n"
2131 JSON_STR)
2132 {
2133 struct zebra_vrf *zvrf;
2134 struct in_addr vtep_ip;
2135 bool uj = use_json(argc, argv);
2136
2137 if (!inet_aton(argv[6]->arg, &vtep_ip)) {
2138 if (!uj)
2139 vty_out(vty, "%% Malformed VTEP IP address\n");
2140 return CMD_WARNING;
2141 }
2142 zvrf = zebra_vrf_get_evpn();
2143 zebra_vxlan_print_macs_all_vni_vtep(vty, zvrf, vtep_ip, uj);
2144
2145 return CMD_SUCCESS;
2146 }
2147
2148
2149 DEFUN (show_evpn_mac_vni_mac,
2150 show_evpn_mac_vni_mac_cmd,
2151 "show evpn mac vni " CMD_VNI_RANGE " mac WORD [json]",
2152 SHOW_STR
2153 "EVPN\n"
2154 "MAC addresses\n"
2155 "VxLAN Network Identifier\n"
2156 "VNI number\n"
2157 "MAC\n"
2158 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2159 JSON_STR)
2160
2161 {
2162 struct zebra_vrf *zvrf;
2163 vni_t vni;
2164 struct ethaddr mac;
2165 bool uj = use_json(argc, argv);
2166
2167 vni = strtoul(argv[4]->arg, NULL, 10);
2168 if (!prefix_str2mac(argv[6]->arg, &mac)) {
2169 vty_out(vty, "%% Malformed MAC address");
2170 return CMD_WARNING;
2171 }
2172 zvrf = zebra_vrf_get_evpn();
2173 zebra_vxlan_print_specific_mac_vni(vty, zvrf, vni, &mac, uj);
2174 return CMD_SUCCESS;
2175 }
2176
2177 DEFUN (show_evpn_mac_vni_vtep,
2178 show_evpn_mac_vni_vtep_cmd,
2179 "show evpn mac vni " CMD_VNI_RANGE " vtep A.B.C.D" "[json]",
2180 SHOW_STR
2181 "EVPN\n"
2182 "MAC addresses\n"
2183 "VxLAN Network Identifier\n"
2184 "VNI number\n"
2185 "Remote VTEP\n"
2186 "Remote VTEP IP address\n"
2187 JSON_STR)
2188 {
2189 struct zebra_vrf *zvrf;
2190 vni_t vni;
2191 struct in_addr vtep_ip;
2192 bool uj = use_json(argc, argv);
2193
2194 vni = strtoul(argv[4]->arg, NULL, 10);
2195 if (!inet_aton(argv[6]->arg, &vtep_ip)) {
2196 if (!uj)
2197 vty_out(vty, "%% Malformed VTEP IP address\n");
2198 return CMD_WARNING;
2199 }
2200
2201 zvrf = zebra_vrf_get_evpn();
2202 zebra_vxlan_print_macs_vni_vtep(vty, zvrf, vni, vtep_ip, uj);
2203 return CMD_SUCCESS;
2204 }
2205
2206 DEFPY (show_evpn_mac_vni_all_dad,
2207 show_evpn_mac_vni_all_dad_cmd,
2208 "show evpn mac vni all duplicate [json]",
2209 SHOW_STR
2210 "EVPN\n"
2211 "MAC addresses\n"
2212 "VxLAN Network Identifier\n"
2213 "All VNIs\n"
2214 "Duplicate address list\n"
2215 JSON_STR)
2216 {
2217 struct zebra_vrf *zvrf;
2218 bool uj = use_json(argc, argv);
2219
2220 zvrf = zebra_vrf_get_evpn();
2221 zebra_vxlan_print_macs_all_vni(vty, zvrf, true, uj);
2222 return CMD_SUCCESS;
2223 }
2224
2225
2226 DEFPY (show_evpn_mac_vni_dad,
2227 show_evpn_mac_vni_dad_cmd,
2228 "show evpn mac vni " CMD_VNI_RANGE " duplicate [json]",
2229 SHOW_STR
2230 "EVPN\n"
2231 "MAC addresses\n"
2232 "VxLAN Network Identifier\n"
2233 "VNI number\n"
2234 "Duplicate address list\n"
2235 JSON_STR)
2236 {
2237 struct zebra_vrf *zvrf;
2238 bool uj = use_json(argc, argv);
2239
2240 zvrf = zebra_vrf_get_evpn();
2241
2242 zebra_vxlan_print_macs_vni_dad(vty, zvrf, vni, uj);
2243
2244 return CMD_SUCCESS;
2245 }
2246
2247 DEFPY (show_evpn_neigh_vni_dad,
2248 show_evpn_neigh_vni_dad_cmd,
2249 "show evpn arp-cache vni " CMD_VNI_RANGE "duplicate [json]",
2250 SHOW_STR
2251 "EVPN\n"
2252 "ARP and ND cache\n"
2253 "VxLAN Network Identifier\n"
2254 "VNI number\n"
2255 "Duplicate address list\n"
2256 JSON_STR)
2257 {
2258 struct zebra_vrf *zvrf;
2259 bool uj = use_json(argc, argv);
2260
2261 zvrf = zebra_vrf_get_evpn();
2262 zebra_vxlan_print_neigh_vni_dad(vty, zvrf, vni, uj);
2263 return CMD_SUCCESS;
2264 }
2265
2266 DEFPY (show_evpn_neigh_vni_all_dad,
2267 show_evpn_neigh_vni_all_dad_cmd,
2268 "show evpn arp-cache vni all duplicate [json]",
2269 SHOW_STR
2270 "EVPN\n"
2271 "ARP and ND cache\n"
2272 "VxLAN Network Identifier\n"
2273 "All VNIs\n"
2274 "Duplicate address list\n"
2275 JSON_STR)
2276 {
2277 struct zebra_vrf *zvrf;
2278 bool uj = use_json(argc, argv);
2279
2280 zvrf = zebra_vrf_get_evpn();
2281 zebra_vxlan_print_neigh_all_vni(vty, zvrf, true, uj);
2282 return CMD_SUCCESS;
2283 }
2284
2285
2286 DEFUN (show_evpn_neigh_vni,
2287 show_evpn_neigh_vni_cmd,
2288 "show evpn arp-cache vni " CMD_VNI_RANGE "[json]",
2289 SHOW_STR
2290 "EVPN\n"
2291 "ARP and ND cache\n"
2292 "VxLAN Network Identifier\n"
2293 "VNI number\n"
2294 JSON_STR)
2295 {
2296 struct zebra_vrf *zvrf;
2297 vni_t vni;
2298 bool uj = use_json(argc, argv);
2299
2300 vni = strtoul(argv[4]->arg, NULL, 10);
2301 zvrf = zebra_vrf_get_evpn();
2302 zebra_vxlan_print_neigh_vni(vty, zvrf, vni, uj);
2303 return CMD_SUCCESS;
2304 }
2305
2306 DEFUN (show_evpn_neigh_vni_all,
2307 show_evpn_neigh_vni_all_cmd,
2308 "show evpn arp-cache vni all [json]",
2309 SHOW_STR
2310 "EVPN\n"
2311 "ARP and ND cache\n"
2312 "VxLAN Network Identifier\n"
2313 "All VNIs\n"
2314 JSON_STR)
2315 {
2316 struct zebra_vrf *zvrf;
2317 bool uj = use_json(argc, argv);
2318
2319 zvrf = zebra_vrf_get_evpn();
2320 zebra_vxlan_print_neigh_all_vni(vty, zvrf, false, uj);
2321 return CMD_SUCCESS;
2322 }
2323
2324 DEFUN (show_evpn_neigh_vni_all_detail, show_evpn_neigh_vni_all_detail_cmd,
2325 "show evpn arp-cache vni all detail [json]",
2326 SHOW_STR
2327 "EVPN\n"
2328 "ARP and ND cache\n"
2329 "VxLAN Network Identifier\n"
2330 "All VNIs\n"
2331 "Neighbor details for all vnis in detail\n" JSON_STR)
2332 {
2333 struct zebra_vrf *zvrf;
2334 bool uj = use_json(argc, argv);
2335
2336 zvrf = zebra_vrf_get_evpn();
2337 zebra_vxlan_print_neigh_all_vni_detail(vty, zvrf, false, uj);
2338 return CMD_SUCCESS;
2339 }
2340
2341 DEFUN (show_evpn_neigh_vni_neigh,
2342 show_evpn_neigh_vni_neigh_cmd,
2343 "show evpn arp-cache vni " CMD_VNI_RANGE " ip WORD [json]",
2344 SHOW_STR
2345 "EVPN\n"
2346 "ARP and ND cache\n"
2347 "VxLAN Network Identifier\n"
2348 "VNI number\n"
2349 "Neighbor\n"
2350 "Neighbor address (IPv4 or IPv6 address)\n"
2351 JSON_STR)
2352 {
2353 struct zebra_vrf *zvrf;
2354 vni_t vni;
2355 struct ipaddr ip;
2356 bool uj = use_json(argc, argv);
2357
2358 vni = strtoul(argv[4]->arg, NULL, 10);
2359 if (str2ipaddr(argv[6]->arg, &ip) != 0) {
2360 if (!uj)
2361 vty_out(vty, "%% Malformed Neighbor address\n");
2362 return CMD_WARNING;
2363 }
2364 zvrf = zebra_vrf_get_evpn();
2365 zebra_vxlan_print_specific_neigh_vni(vty, zvrf, vni, &ip, uj);
2366 return CMD_SUCCESS;
2367 }
2368
2369 DEFUN (show_evpn_neigh_vni_vtep,
2370 show_evpn_neigh_vni_vtep_cmd,
2371 "show evpn arp-cache vni " CMD_VNI_RANGE " vtep A.B.C.D [json]",
2372 SHOW_STR
2373 "EVPN\n"
2374 "ARP and ND cache\n"
2375 "VxLAN Network Identifier\n"
2376 "VNI number\n"
2377 "Remote VTEP\n"
2378 "Remote VTEP IP address\n"
2379 JSON_STR)
2380 {
2381 struct zebra_vrf *zvrf;
2382 vni_t vni;
2383 struct in_addr vtep_ip;
2384 bool uj = use_json(argc, argv);
2385
2386 vni = strtoul(argv[4]->arg, NULL, 10);
2387 if (!inet_aton(argv[6]->arg, &vtep_ip)) {
2388 if (!uj)
2389 vty_out(vty, "%% Malformed VTEP IP address\n");
2390 return CMD_WARNING;
2391 }
2392
2393 zvrf = zebra_vrf_get_evpn();
2394 zebra_vxlan_print_neigh_vni_vtep(vty, zvrf, vni, vtep_ip, uj);
2395 return CMD_SUCCESS;
2396 }
2397
2398 /* policy routing contexts */
2399 DEFUN (show_pbr_ipset,
2400 show_pbr_ipset_cmd,
2401 "show pbr ipset [WORD]",
2402 SHOW_STR
2403 "Policy-Based Routing\n"
2404 "IPset Context information\n"
2405 "IPset Name information\n")
2406 {
2407 int idx = 0;
2408 int found = 0;
2409 found = argv_find(argv, argc, "WORD", &idx);
2410 if (!found)
2411 zebra_pbr_show_ipset_list(vty, NULL);
2412 else
2413 zebra_pbr_show_ipset_list(vty, argv[idx]->arg);
2414 return CMD_SUCCESS;
2415 }
2416
2417 /* policy routing contexts */
2418 DEFUN (show_pbr_iptable,
2419 show_pbr_iptable_cmd,
2420 "show pbr iptable [WORD]",
2421 SHOW_STR
2422 "Policy-Based Routing\n"
2423 "IPtable Context information\n"
2424 "IPtable Name information\n")
2425 {
2426 int idx = 0;
2427 int found = 0;
2428
2429 found = argv_find(argv, argc, "WORD", &idx);
2430 if (!found)
2431 zebra_pbr_show_iptable(vty, NULL);
2432 else
2433 zebra_pbr_show_iptable(vty, argv[idx]->arg);
2434 return CMD_SUCCESS;
2435 }
2436
2437 DEFPY (clear_evpn_dup_addr,
2438 clear_evpn_dup_addr_cmd,
2439 "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>]>",
2440 CLEAR_STR
2441 "EVPN\n"
2442 "Duplicate address \n"
2443 "VxLAN Network Identifier\n"
2444 "VNI number\n"
2445 "All VNIs\n"
2446 "MAC\n"
2447 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2448 "IP\n"
2449 "IPv4 address\n"
2450 "IPv6 address\n")
2451 {
2452 struct zebra_vrf *zvrf;
2453 struct ipaddr host_ip = {.ipa_type = IPADDR_NONE };
2454 int ret = CMD_SUCCESS;
2455
2456 zvrf = zebra_vrf_get_evpn();
2457 if (vni_str) {
2458 if (!is_zero_mac(&mac->eth_addr)) {
2459 ret = zebra_vxlan_clear_dup_detect_vni_mac(vty, zvrf,
2460 vni,
2461 &mac->eth_addr);
2462 } else if (ip) {
2463 if (sockunion_family(ip) == AF_INET) {
2464 host_ip.ipa_type = IPADDR_V4;
2465 host_ip.ipaddr_v4.s_addr = sockunion2ip(ip);
2466 } else {
2467 host_ip.ipa_type = IPADDR_V6;
2468 memcpy(&host_ip.ipaddr_v6, &ip->sin6.sin6_addr,
2469 sizeof(struct in6_addr));
2470 }
2471 ret = zebra_vxlan_clear_dup_detect_vni_ip(vty, zvrf,
2472 vni,
2473 &host_ip);
2474 } else
2475 ret = zebra_vxlan_clear_dup_detect_vni(vty, zvrf, vni);
2476
2477 } else {
2478 ret = zebra_vxlan_clear_dup_detect_vni_all(vty, zvrf);
2479 }
2480
2481 return ret;
2482 }
2483
2484 /* Static ip route configuration write function. */
2485 static int zebra_ip_config(struct vty *vty)
2486 {
2487 int write = 0;
2488
2489 write += zebra_import_table_config(vty, VRF_DEFAULT);
2490
2491 return write;
2492 }
2493
2494 DEFUN (ip_zebra_import_table_distance,
2495 ip_zebra_import_table_distance_cmd,
2496 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
2497 IP_STR
2498 "import routes from non-main kernel table\n"
2499 "kernel routing table id\n"
2500 "Distance for imported routes\n"
2501 "Default distance value\n"
2502 "route-map for filtering\n"
2503 "route-map name\n")
2504 {
2505 uint32_t table_id = 0;
2506
2507 table_id = strtoul(argv[2]->arg, NULL, 10);
2508 int distance = ZEBRA_TABLE_DISTANCE_DEFAULT;
2509 char *rmap =
2510 strmatch(argv[argc - 2]->text, "route-map")
2511 ? XSTRDUP(MTYPE_ROUTE_MAP_NAME, argv[argc - 1]->arg)
2512 : NULL;
2513 int ret;
2514
2515 if (argc == 7 || (argc == 5 && !rmap))
2516 distance = strtoul(argv[4]->arg, NULL, 10);
2517
2518 if (!is_zebra_valid_kernel_table(table_id)) {
2519 vty_out(vty,
2520 "Invalid routing table ID, %d. Must be in range 1-252\n",
2521 table_id);
2522 if (rmap)
2523 XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
2524 return CMD_WARNING;
2525 }
2526
2527 if (is_zebra_main_routing_table(table_id)) {
2528 vty_out(vty,
2529 "Invalid routing table ID, %d. Must be non-default table\n",
2530 table_id);
2531 if (rmap)
2532 XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
2533 return CMD_WARNING;
2534 }
2535
2536 ret = zebra_import_table(AFI_IP, VRF_DEFAULT, table_id,
2537 distance, rmap, 1);
2538 if (rmap)
2539 XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
2540
2541 return ret;
2542 }
2543
2544 DEFUN_HIDDEN (zebra_packet_process,
2545 zebra_packet_process_cmd,
2546 "zebra zapi-packets (1-10000)",
2547 ZEBRA_STR
2548 "Zapi Protocol\n"
2549 "Number of packets to process before relinquishing thread\n")
2550 {
2551 uint32_t packets = strtoul(argv[2]->arg, NULL, 10);
2552
2553 atomic_store_explicit(&zrouter.packets_to_process, packets,
2554 memory_order_relaxed);
2555
2556 return CMD_SUCCESS;
2557 }
2558
2559 DEFUN_HIDDEN (no_zebra_packet_process,
2560 no_zebra_packet_process_cmd,
2561 "no zebra zapi-packets [(1-10000)]",
2562 NO_STR
2563 ZEBRA_STR
2564 "Zapi Protocol\n"
2565 "Number of packets to process before relinquishing thread\n")
2566 {
2567 atomic_store_explicit(&zrouter.packets_to_process,
2568 ZEBRA_ZAPI_PACKETS_TO_PROCESS,
2569 memory_order_relaxed);
2570
2571 return CMD_SUCCESS;
2572 }
2573
2574 DEFUN_HIDDEN (zebra_workqueue_timer,
2575 zebra_workqueue_timer_cmd,
2576 "zebra work-queue (0-10000)",
2577 ZEBRA_STR
2578 "Work Queue\n"
2579 "Time in milliseconds\n")
2580 {
2581 uint32_t timer = strtoul(argv[2]->arg, NULL, 10);
2582 zrouter.ribq->spec.hold = timer;
2583
2584 return CMD_SUCCESS;
2585 }
2586
2587 DEFUN_HIDDEN (no_zebra_workqueue_timer,
2588 no_zebra_workqueue_timer_cmd,
2589 "no zebra work-queue [(0-10000)]",
2590 NO_STR
2591 ZEBRA_STR
2592 "Work Queue\n"
2593 "Time in milliseconds\n")
2594 {
2595 zrouter.ribq->spec.hold = ZEBRA_RIB_PROCESS_HOLD_TIME;
2596
2597 return CMD_SUCCESS;
2598 }
2599
2600 DEFUN (no_ip_zebra_import_table,
2601 no_ip_zebra_import_table_cmd,
2602 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
2603 NO_STR
2604 IP_STR
2605 "import routes from non-main kernel table\n"
2606 "kernel routing table id\n"
2607 "Distance for imported routes\n"
2608 "Default distance value\n"
2609 "route-map for filtering\n"
2610 "route-map name\n")
2611 {
2612 uint32_t table_id = 0;
2613 table_id = strtoul(argv[3]->arg, NULL, 10);
2614
2615 if (!is_zebra_valid_kernel_table(table_id)) {
2616 vty_out(vty,
2617 "Invalid routing table ID. Must be in range 1-252\n");
2618 return CMD_WARNING;
2619 }
2620
2621 if (is_zebra_main_routing_table(table_id)) {
2622 vty_out(vty,
2623 "Invalid routing table ID, %d. Must be non-default table\n",
2624 table_id);
2625 return CMD_WARNING;
2626 }
2627
2628 if (!is_zebra_import_table_enabled(AFI_IP, VRF_DEFAULT, table_id))
2629 return CMD_SUCCESS;
2630
2631 return (zebra_import_table(AFI_IP, VRF_DEFAULT, table_id, 0, NULL, 0));
2632 }
2633
2634 static int config_write_protocol(struct vty *vty)
2635 {
2636 if (allow_delete)
2637 vty_out(vty, "allow-external-route-update\n");
2638
2639 if (zrouter.ribq->spec.hold != ZEBRA_RIB_PROCESS_HOLD_TIME)
2640 vty_out(vty, "zebra work-queue %u\n", zrouter.ribq->spec.hold);
2641
2642 if (zrouter.packets_to_process != ZEBRA_ZAPI_PACKETS_TO_PROCESS)
2643 vty_out(vty, "zebra zapi-packets %u\n",
2644 zrouter.packets_to_process);
2645
2646 enum multicast_mode ipv4_multicast_mode = multicast_mode_ipv4_get();
2647
2648 if (ipv4_multicast_mode != MCAST_NO_CONFIG)
2649 vty_out(vty, "ip multicast rpf-lookup-mode %s\n",
2650 ipv4_multicast_mode == MCAST_URIB_ONLY
2651 ? "urib-only"
2652 : ipv4_multicast_mode == MCAST_MRIB_ONLY
2653 ? "mrib-only"
2654 : ipv4_multicast_mode
2655 == MCAST_MIX_MRIB_FIRST
2656 ? "mrib-then-urib"
2657 : ipv4_multicast_mode
2658 == MCAST_MIX_DISTANCE
2659 ? "lower-distance"
2660 : "longer-prefix");
2661
2662 /* Include dataplane info */
2663 dplane_config_write_helper(vty);
2664
2665 return 1;
2666 }
2667
2668 DEFUN (show_zebra,
2669 show_zebra_cmd,
2670 "show zebra",
2671 SHOW_STR
2672 ZEBRA_STR)
2673 {
2674 struct vrf *vrf;
2675
2676 vty_out(vty,
2677 " Route Route Neighbor LSP LSP\n");
2678 vty_out(vty,
2679 "VRF Installs Removals Updates Installs Removals\n");
2680
2681 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
2682 struct zebra_vrf *zvrf = vrf->info;
2683
2684 vty_out(vty, "%-25s %10" PRIu64 " %10" PRIu64 " %10" PRIu64
2685 " %10" PRIu64 " %10" PRIu64 "\n",
2686 vrf->name, zvrf->installs, zvrf->removals,
2687 zvrf->neigh_updates, zvrf->lsp_installs,
2688 zvrf->lsp_removals);
2689 }
2690
2691 return CMD_SUCCESS;
2692 }
2693
2694 DEFUN (ip_forwarding,
2695 ip_forwarding_cmd,
2696 "ip forwarding",
2697 IP_STR
2698 "Turn on IP forwarding\n")
2699 {
2700 int ret;
2701
2702 ret = ipforward();
2703 if (ret == 0)
2704 ret = ipforward_on();
2705
2706 if (ret == 0) {
2707 vty_out(vty, "Can't turn on IP forwarding\n");
2708 return CMD_WARNING_CONFIG_FAILED;
2709 }
2710
2711 return CMD_SUCCESS;
2712 }
2713
2714 DEFUN (no_ip_forwarding,
2715 no_ip_forwarding_cmd,
2716 "no ip forwarding",
2717 NO_STR
2718 IP_STR
2719 "Turn off IP forwarding\n")
2720 {
2721 int ret;
2722
2723 ret = ipforward();
2724 if (ret != 0)
2725 ret = ipforward_off();
2726
2727 if (ret != 0) {
2728 vty_out(vty, "Can't turn off IP forwarding\n");
2729 return CMD_WARNING_CONFIG_FAILED;
2730 }
2731
2732 return CMD_SUCCESS;
2733 }
2734
2735 /* Only display ip forwarding is enabled or not. */
2736 DEFUN (show_ip_forwarding,
2737 show_ip_forwarding_cmd,
2738 "show ip forwarding",
2739 SHOW_STR
2740 IP_STR
2741 "IP forwarding status\n")
2742 {
2743 int ret;
2744
2745 ret = ipforward();
2746
2747 if (ret == 0)
2748 vty_out(vty, "IP forwarding is off\n");
2749 else
2750 vty_out(vty, "IP forwarding is on\n");
2751 return CMD_SUCCESS;
2752 }
2753
2754 /* Only display ipv6 forwarding is enabled or not. */
2755 DEFUN (show_ipv6_forwarding,
2756 show_ipv6_forwarding_cmd,
2757 "show ipv6 forwarding",
2758 SHOW_STR
2759 "IPv6 information\n"
2760 "Forwarding status\n")
2761 {
2762 int ret;
2763
2764 ret = ipforward_ipv6();
2765
2766 switch (ret) {
2767 case -1:
2768 vty_out(vty, "ipv6 forwarding is unknown\n");
2769 break;
2770 case 0:
2771 vty_out(vty, "ipv6 forwarding is %s\n", "off");
2772 break;
2773 case 1:
2774 vty_out(vty, "ipv6 forwarding is %s\n", "on");
2775 break;
2776 default:
2777 vty_out(vty, "ipv6 forwarding is %s\n", "off");
2778 break;
2779 }
2780 return CMD_SUCCESS;
2781 }
2782
2783 DEFUN (ipv6_forwarding,
2784 ipv6_forwarding_cmd,
2785 "ipv6 forwarding",
2786 IPV6_STR
2787 "Turn on IPv6 forwarding\n")
2788 {
2789 int ret;
2790
2791 ret = ipforward_ipv6();
2792 if (ret == 0)
2793 ret = ipforward_ipv6_on();
2794
2795 if (ret == 0) {
2796 vty_out(vty, "Can't turn on IPv6 forwarding\n");
2797 return CMD_WARNING_CONFIG_FAILED;
2798 }
2799
2800 return CMD_SUCCESS;
2801 }
2802
2803 DEFUN (no_ipv6_forwarding,
2804 no_ipv6_forwarding_cmd,
2805 "no ipv6 forwarding",
2806 NO_STR
2807 IPV6_STR
2808 "Turn off IPv6 forwarding\n")
2809 {
2810 int ret;
2811
2812 ret = ipforward_ipv6();
2813 if (ret != 0)
2814 ret = ipforward_ipv6_off();
2815
2816 if (ret != 0) {
2817 vty_out(vty, "Can't turn off IPv6 forwarding\n");
2818 return CMD_WARNING_CONFIG_FAILED;
2819 }
2820
2821 return CMD_SUCCESS;
2822 }
2823
2824 /* Display dataplane info */
2825 DEFUN (show_dataplane,
2826 show_dataplane_cmd,
2827 "show zebra dplane [detailed]",
2828 SHOW_STR
2829 ZEBRA_STR
2830 "Zebra dataplane information\n"
2831 "Detailed output\n")
2832 {
2833 int idx = 0;
2834 bool detailed = false;
2835
2836 if (argv_find(argv, argc, "detailed", &idx))
2837 detailed = true;
2838
2839 return dplane_show_helper(vty, detailed);
2840 }
2841
2842 /* Display dataplane providers info */
2843 DEFUN (show_dataplane_providers,
2844 show_dataplane_providers_cmd,
2845 "show zebra dplane providers [detailed]",
2846 SHOW_STR
2847 ZEBRA_STR
2848 "Zebra dataplane information\n"
2849 "Zebra dataplane provider information\n"
2850 "Detailed output\n")
2851 {
2852 int idx = 0;
2853 bool detailed = false;
2854
2855 if (argv_find(argv, argc, "detailed", &idx))
2856 detailed = true;
2857
2858 return dplane_show_provs_helper(vty, detailed);
2859 }
2860
2861 /* Configure dataplane incoming queue limit */
2862 DEFUN (zebra_dplane_queue_limit,
2863 zebra_dplane_queue_limit_cmd,
2864 "zebra dplane limit (0-10000)",
2865 ZEBRA_STR
2866 "Zebra dataplane\n"
2867 "Limit incoming queued updates\n"
2868 "Number of queued updates\n")
2869 {
2870 uint32_t limit = 0;
2871
2872 limit = strtoul(argv[3]->arg, NULL, 10);
2873
2874 dplane_set_in_queue_limit(limit, true);
2875
2876 return CMD_SUCCESS;
2877 }
2878
2879 /* Reset dataplane queue limit to default value */
2880 DEFUN (no_zebra_dplane_queue_limit,
2881 no_zebra_dplane_queue_limit_cmd,
2882 "no zebra dplane limit [(0-10000)]",
2883 NO_STR
2884 ZEBRA_STR
2885 "Zebra dataplane\n"
2886 "Limit incoming queued updates\n"
2887 "Number of queued updates\n")
2888 {
2889 dplane_set_in_queue_limit(0, false);
2890
2891 return CMD_SUCCESS;
2892 }
2893
2894 DEFUN (zebra_show_routing_tables_summary,
2895 zebra_show_routing_tables_summary_cmd,
2896 "show zebra router table summary",
2897 SHOW_STR
2898 ZEBRA_STR
2899 "The Zebra Router Information\n"
2900 "Table Information about this Zebra Router\n"
2901 "Summary Information\n")
2902 {
2903 zebra_router_show_table_summary(vty);
2904
2905 return CMD_SUCCESS;
2906 }
2907
2908 /* Table configuration write function. */
2909 static int config_write_table(struct vty *vty)
2910 {
2911 return 0;
2912 }
2913
2914 /* IPForwarding configuration write function. */
2915 static int config_write_forwarding(struct vty *vty)
2916 {
2917 /* FIXME: Find better place for that. */
2918 router_id_write(vty);
2919
2920 if (!ipforward())
2921 vty_out(vty, "no ip forwarding\n");
2922 if (!ipforward_ipv6())
2923 vty_out(vty, "no ipv6 forwarding\n");
2924 vty_out(vty, "!\n");
2925 return 0;
2926 }
2927
2928 DEFUN_HIDDEN (show_frr,
2929 show_frr_cmd,
2930 "show frr",
2931 SHOW_STR
2932 "FRR\n")
2933 {
2934 vty_out(vty, "........ .. . .. . ..... ...77:................................................\n");
2935 vty_out(vty, ".............................7777:..............................................\n");
2936 vty_out(vty, ".............................777777,............................................\n");
2937 vty_out(vty, "... .........................77777777,..........................................\n");
2938 vty_out(vty, "............................=7777777777:........................................\n");
2939 vty_out(vty, "........................:7777777777777777,......................................\n");
2940 vty_out(vty, ".................... ~7777777777777?~,..........................................\n");
2941 vty_out(vty, "...................I7777777777+.................................................\n");
2942 vty_out(vty, "................,777777777?............ .......................................\n");
2943 vty_out(vty, "..............:77777777?..........~?77777.......................................\n");
2944 vty_out(vty, ".............77777777~........=7777777777.......................................\n");
2945 vty_out(vty, ".......... +7777777,.......?7777777777777.......................................\n");
2946 vty_out(vty, "..........7777777~......:7777777777777777......77?,.............................\n");
2947 vty_out(vty, "........:777777?......+777777777777777777......777777I,.........................\n");
2948 vty_out(vty, ".......?777777,.....+77777777777777777777......777777777?.......................\n");
2949 vty_out(vty, "......?777777......7777777777777777777777......,?777777777?.....................\n");
2950 vty_out(vty, ".....?77777?.....=7777777777777777777I~............,I7777777~...................\n");
2951 vty_out(vty, "....+77777+.....I77777777777777777:...................+777777I..................\n");
2952 vty_out(vty, "...~77777+.....7777777777777777=........................?777777...... .......\n");
2953 vty_out(vty, "...77777I.....I77777777777777~.........:?................,777777.....I777.......\n");
2954 vty_out(vty, "..777777.....I7777777777777I .......?7777..................777777.....777?......\n");
2955 vty_out(vty, ".~77777,....=7777777777777:......,7777777..................,77777+....+777......\n");
2956 vty_out(vty, ".77777I.....7777777777777,......777777777.......ONNNN.......=77777.....777~.....\n");
2957 vty_out(vty, ",77777.....I777777777777,.....:7777777777......DNNNNNN.......77777+ ...7777.....\n");
2958 vty_out(vty, "I7777I.....777777777777=.....~77777777777......NNNNNNN~......=7777I....=777.....\n");
2959 vty_out(vty, "77777:....=777777777777.....,777777777777......$NNNNND ......:77777....:777.....\n");
2960 vty_out(vty, "77777. ...777777777777~.....7777777777777........7DZ,........:77777.....777.....\n");
2961 vty_out(vty, "????? . ..777777777777.....,7777777777777....................:77777I....777.....\n");
2962 vty_out(vty, "....... ..777777777777.....+7777777777777....................=7777777+...?7.....\n");
2963 vty_out(vty, "..........77777777777I.....I7777777777777....................7777777777:........\n");
2964 vty_out(vty, "..........77777777777I.....?7777777777777...................~777777777777.......\n");
2965 vty_out(vty, "..........777777777777.....~7777777777777..................,77777777777777+.....\n");
2966 vty_out(vty, "..........777777777777......7777777777777..................77777777777777777,...\n");
2967 vty_out(vty, "..... ....?77777777777I.....~777777777777................,777777.....,:+77777I..\n");
2968 vty_out(vty, "........ .:777777777777,.....?77777777777...............?777777..............,:=\n");
2969 vty_out(vty, ".......... 7777777777777..... ?7777777777.............=7777777.....~777I........\n");
2970 vty_out(vty, "...........:777777777777I......~777777777...........I7777777~.....+777I.........\n");
2971 vty_out(vty, "..... ......7777777777777I.......I7777777.......+777777777I......7777I..........\n");
2972 vty_out(vty, ".............77777777777777........?77777......777777777?......=7777=...........\n");
2973 vty_out(vty, ".............,77777777777777+.........~77......777777I,......:77777.............\n");
2974 vty_out(vty, "..............~777777777777777~................777777......:77777=..............\n");
2975 vty_out(vty, "...............:7777777777777777?..............:777777,.....=77=................\n");
2976 vty_out(vty, "................,777777777777777777?,...........,777777:.....,..................\n");
2977 vty_out(vty, "........... ......I777777777777777777777I.........777777~.......................\n");
2978 vty_out(vty, "...................,777777777777777777777..........777777+......................\n");
2979 vty_out(vty, ".....................+7777777777777777777...........777777?.....................\n");
2980 vty_out(vty, ".......................=77777777777777777............777777I....................\n");
2981 vty_out(vty, ".........................:777777777777777.............I77777I...................\n");
2982 vty_out(vty, "............................~777777777777..............+777777..................\n");
2983 vty_out(vty, "................................~77777777...............=777777.................\n");
2984 vty_out(vty, ".....................................:=?I................~777777................\n");
2985 vty_out(vty, "..........................................................:777777,..............\n");
2986 vty_out(vty, ".... ... ... . . .... ....... ....... ....................:777777..............\n");
2987
2988 return CMD_SUCCESS;
2989 }
2990
2991 /* IP node for static routes. */
2992 static struct cmd_node ip_node = {IP_NODE, "", 1};
2993 static struct cmd_node protocol_node = {PROTOCOL_NODE, "", 1};
2994 /* table node for routing tables. */
2995 static struct cmd_node table_node = {TABLE_NODE,
2996 "", /* This node has no interface. */
2997 1};
2998 static struct cmd_node forwarding_node = {FORWARDING_NODE,
2999 "", /* This node has no interface. */
3000 1};
3001
3002 /* Route VTY. */
3003 void zebra_vty_init(void)
3004 {
3005 /* Install configuration write function. */
3006 install_node(&table_node, config_write_table);
3007 install_node(&forwarding_node, config_write_forwarding);
3008
3009 install_element(VIEW_NODE, &show_ip_forwarding_cmd);
3010 install_element(CONFIG_NODE, &ip_forwarding_cmd);
3011 install_element(CONFIG_NODE, &no_ip_forwarding_cmd);
3012 install_element(ENABLE_NODE, &show_zebra_cmd);
3013
3014 install_element(VIEW_NODE, &show_ipv6_forwarding_cmd);
3015 install_element(CONFIG_NODE, &ipv6_forwarding_cmd);
3016 install_element(CONFIG_NODE, &no_ipv6_forwarding_cmd);
3017
3018 /* Route-map */
3019 zebra_route_map_init();
3020
3021 install_node(&ip_node, zebra_ip_config);
3022 install_node(&protocol_node, config_write_protocol);
3023
3024 install_element(CONFIG_NODE, &allow_external_route_update_cmd);
3025 install_element(CONFIG_NODE, &no_allow_external_route_update_cmd);
3026
3027 install_element(CONFIG_NODE, &ip_multicast_mode_cmd);
3028 install_element(CONFIG_NODE, &no_ip_multicast_mode_cmd);
3029
3030 install_element(CONFIG_NODE, &ip_zebra_import_table_distance_cmd);
3031 install_element(CONFIG_NODE, &no_ip_zebra_import_table_cmd);
3032 install_element(CONFIG_NODE, &zebra_workqueue_timer_cmd);
3033 install_element(CONFIG_NODE, &no_zebra_workqueue_timer_cmd);
3034 install_element(CONFIG_NODE, &zebra_packet_process_cmd);
3035 install_element(CONFIG_NODE, &no_zebra_packet_process_cmd);
3036
3037 install_element(VIEW_NODE, &show_vrf_cmd);
3038 install_element(VIEW_NODE, &show_vrf_vni_cmd);
3039 install_element(VIEW_NODE, &show_route_cmd);
3040 install_element(VIEW_NODE, &show_route_table_cmd);
3041 if (vrf_is_backend_netns())
3042 install_element(VIEW_NODE, &show_route_table_vrf_cmd);
3043 install_element(VIEW_NODE, &show_route_all_table_vrf_cmd);
3044 install_element(VIEW_NODE, &show_route_detail_cmd);
3045 install_element(VIEW_NODE, &show_route_summary_cmd);
3046 install_element(VIEW_NODE, &show_ip_nht_cmd);
3047
3048 install_element(VIEW_NODE, &show_ip_rpf_cmd);
3049 install_element(VIEW_NODE, &show_ip_rpf_addr_cmd);
3050
3051 install_element(CONFIG_NODE, &ip_nht_default_route_cmd);
3052 install_element(CONFIG_NODE, &no_ip_nht_default_route_cmd);
3053 install_element(CONFIG_NODE, &ipv6_nht_default_route_cmd);
3054 install_element(CONFIG_NODE, &no_ipv6_nht_default_route_cmd);
3055 install_element(VRF_NODE, &ip_nht_default_route_cmd);
3056 install_element(VRF_NODE, &no_ip_nht_default_route_cmd);
3057 install_element(VRF_NODE, &ipv6_nht_default_route_cmd);
3058 install_element(VRF_NODE, &no_ipv6_nht_default_route_cmd);
3059 install_element(VIEW_NODE, &show_ipv6_mroute_cmd);
3060
3061 /* Commands for VRF */
3062 install_element(VIEW_NODE, &show_ipv6_mroute_vrf_all_cmd);
3063
3064 install_element(VIEW_NODE, &show_frr_cmd);
3065 install_element(VIEW_NODE, &show_evpn_global_cmd);
3066 install_element(VIEW_NODE, &show_evpn_vni_cmd);
3067 install_element(VIEW_NODE, &show_evpn_vni_detail_cmd);
3068 install_element(VIEW_NODE, &show_evpn_vni_vni_cmd);
3069 install_element(VIEW_NODE, &show_evpn_rmac_vni_mac_cmd);
3070 install_element(VIEW_NODE, &show_evpn_rmac_vni_cmd);
3071 install_element(VIEW_NODE, &show_evpn_rmac_vni_all_cmd);
3072 install_element(VIEW_NODE, &show_evpn_nh_vni_ip_cmd);
3073 install_element(VIEW_NODE, &show_evpn_nh_vni_cmd);
3074 install_element(VIEW_NODE, &show_evpn_nh_vni_all_cmd);
3075 install_element(VIEW_NODE, &show_evpn_mac_vni_cmd);
3076 install_element(VIEW_NODE, &show_evpn_mac_vni_all_cmd);
3077 install_element(VIEW_NODE, &show_evpn_mac_vni_all_detail_cmd);
3078 install_element(VIEW_NODE, &show_evpn_mac_vni_all_vtep_cmd);
3079 install_element(VIEW_NODE, &show_evpn_mac_vni_mac_cmd);
3080 install_element(VIEW_NODE, &show_evpn_mac_vni_vtep_cmd);
3081 install_element(VIEW_NODE, &show_evpn_mac_vni_dad_cmd);
3082 install_element(VIEW_NODE, &show_evpn_mac_vni_all_dad_cmd);
3083 install_element(VIEW_NODE, &show_evpn_neigh_vni_cmd);
3084 install_element(VIEW_NODE, &show_evpn_neigh_vni_all_cmd);
3085 install_element(VIEW_NODE, &show_evpn_neigh_vni_all_detail_cmd);
3086 install_element(VIEW_NODE, &show_evpn_neigh_vni_neigh_cmd);
3087 install_element(VIEW_NODE, &show_evpn_neigh_vni_vtep_cmd);
3088 install_element(VIEW_NODE, &show_evpn_neigh_vni_dad_cmd);
3089 install_element(VIEW_NODE, &show_evpn_neigh_vni_all_dad_cmd);
3090 install_element(ENABLE_NODE, &clear_evpn_dup_addr_cmd);
3091
3092 install_element(VIEW_NODE, &show_pbr_ipset_cmd);
3093 install_element(VIEW_NODE, &show_pbr_iptable_cmd);
3094
3095 install_element(CONFIG_NODE, &default_vrf_vni_mapping_cmd);
3096 install_element(CONFIG_NODE, &no_default_vrf_vni_mapping_cmd);
3097 install_element(VRF_NODE, &vrf_vni_mapping_cmd);
3098 install_element(VRF_NODE, &no_vrf_vni_mapping_cmd);
3099
3100 install_element(VIEW_NODE, &show_dataplane_cmd);
3101 install_element(VIEW_NODE, &show_dataplane_providers_cmd);
3102 install_element(CONFIG_NODE, &zebra_dplane_queue_limit_cmd);
3103 install_element(CONFIG_NODE, &no_zebra_dplane_queue_limit_cmd);
3104
3105 install_element(VIEW_NODE, &zebra_show_routing_tables_summary_cmd);
3106 }