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