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