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