]> git.proxmox.com Git - mirror_frr.git/blob - zebra/zebra_vty.c
zebra: dup addr detect clear command
[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
736 RNODE_FOREACH_RE (rn, re) {
737 json_prefix = json_object_new_array();
738 vty_show_ip_route(vty, rn, re, json_prefix);
739 prefix2str(&rn->p, buf, sizeof buf);
740 json_object_object_add(json, buf, json_prefix);
741 json_prefix = NULL;
742 }
743
744 vty_out(vty, "%s\n", json_object_to_json_string_ext(
745 json, JSON_C_TO_STRING_PRETTY));
746 json_object_free(json);
747 }
748
749 static void do_show_route_helper(struct vty *vty, struct zebra_vrf *zvrf,
750 struct route_table *table, afi_t afi,
751 bool use_fib, route_tag_t tag,
752 const struct prefix *longer_prefix_p,
753 bool supernets_only, int type,
754 unsigned short ospf_instance_id, bool use_json)
755 {
756 struct route_node *rn;
757 struct route_entry *re;
758 int first = 1;
759 rib_dest_t *dest;
760 json_object *json = NULL;
761 json_object *json_prefix = NULL;
762 uint32_t addr;
763 char buf[BUFSIZ];
764
765 if (use_json)
766 json = json_object_new_object();
767
768 /* Show all routes. */
769 for (rn = route_top(table); rn; rn = srcdest_route_next(rn)) {
770 dest = rib_dest_from_rnode(rn);
771
772 RNODE_FOREACH_RE (rn, re) {
773 if (use_fib && re != dest->selected_fib)
774 continue;
775
776 if (tag && re->tag != tag)
777 continue;
778
779 if (longer_prefix_p
780 && !prefix_match(longer_prefix_p, &rn->p))
781 continue;
782
783 /* This can only be true when the afi is IPv4 */
784 if (supernets_only) {
785 addr = ntohl(rn->p.u.prefix4.s_addr);
786
787 if (IN_CLASSC(addr) && rn->p.prefixlen >= 24)
788 continue;
789
790 if (IN_CLASSB(addr) && rn->p.prefixlen >= 16)
791 continue;
792
793 if (IN_CLASSA(addr) && rn->p.prefixlen >= 8)
794 continue;
795 }
796
797 if (type && re->type != type)
798 continue;
799
800 if (ospf_instance_id
801 && (re->type != ZEBRA_ROUTE_OSPF
802 || re->instance != ospf_instance_id))
803 continue;
804
805 if (use_json) {
806 if (!json_prefix)
807 json_prefix = json_object_new_array();
808 } else {
809 if (first) {
810 if (afi == AFI_IP)
811 vty_out(vty,
812 SHOW_ROUTE_V4_HEADER);
813 else
814 vty_out(vty,
815 SHOW_ROUTE_V6_HEADER);
816
817 if (zvrf_id(zvrf) != VRF_DEFAULT)
818 vty_out(vty, "\nVRF %s:\n",
819 zvrf_name(zvrf));
820
821 first = 0;
822 }
823 }
824
825 vty_show_ip_route(vty, rn, re, json_prefix);
826 }
827
828 if (json_prefix) {
829 prefix2str(&rn->p, buf, sizeof(buf));
830 json_object_object_add(json, buf, json_prefix);
831 json_prefix = NULL;
832 }
833 }
834
835 if (use_json) {
836 vty_out(vty, "%s\n", json_object_to_json_string_ext(json,
837 JSON_C_TO_STRING_PRETTY));
838 json_object_free(json);
839 }
840 }
841
842 static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi,
843 safi_t safi, bool use_fib, bool use_json,
844 route_tag_t tag,
845 const struct prefix *longer_prefix_p,
846 bool supernets_only, int type,
847 unsigned short ospf_instance_id)
848 {
849 struct route_table *table;
850 struct zebra_vrf *zvrf = NULL;
851
852 if (!(zvrf = zebra_vrf_lookup_by_name(vrf_name))) {
853 if (use_json)
854 vty_out(vty, "{}\n");
855 else
856 vty_out(vty, "vrf %s not defined\n", vrf_name);
857 return CMD_SUCCESS;
858 }
859
860 if (zvrf_id(zvrf) == VRF_UNKNOWN) {
861 if (use_json)
862 vty_out(vty, "{}\n");
863 else
864 vty_out(vty, "vrf %s inactive\n", vrf_name);
865 return CMD_SUCCESS;
866 }
867
868 table = zebra_vrf_table(afi, safi, zvrf_id(zvrf));
869 if (!table) {
870 if (use_json)
871 vty_out(vty, "{}\n");
872 return CMD_SUCCESS;
873 }
874
875 do_show_route_helper(vty, zvrf, table, afi, use_fib, tag,
876 longer_prefix_p, supernets_only, type,
877 ospf_instance_id, use_json);
878
879 return CMD_SUCCESS;
880 }
881
882 DEFPY (show_route_table,
883 show_route_table_cmd,
884 "show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table [json$json]",
885 SHOW_STR
886 IP_STR
887 IP6_STR
888 "IP routing table\n"
889 "Table to display\n"
890 "The table number to display, if available\n"
891 JSON_STR)
892 {
893 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
894 struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
895 struct route_table *t;
896
897 t = zebra_router_find_table(zvrf, table, afi, SAFI_UNICAST);
898 if (t)
899 do_show_route_helper(vty, zvrf, t, afi, false, 0, false, false,
900 0, 0, !!json);
901
902 return CMD_SUCCESS;
903 }
904
905 DEFPY (show_route_table_vrf,
906 show_route_table_vrf_cmd,
907 "show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table vrf NAME$vrf_name [json$json]",
908 SHOW_STR
909 IP_STR
910 IP6_STR
911 "IP routing table\n"
912 "Table to display\n"
913 "The table number to display, if available\n"
914 VRF_CMD_HELP_STR
915 JSON_STR)
916 {
917 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
918 struct zebra_vrf *zvrf;
919 struct route_table *t;
920 vrf_id_t vrf_id = VRF_DEFAULT;
921
922 if (vrf_name)
923 VRF_GET_ID(vrf_id, vrf_name, !!json);
924 zvrf = zebra_vrf_lookup_by_id(vrf_id);
925
926 t = zebra_router_find_table(zvrf, table, afi, SAFI_UNICAST);
927 if (t)
928 do_show_route_helper(vty, zvrf, t, afi, false, 0, false, false,
929 0, 0, !!json);
930
931 return CMD_SUCCESS;
932 }
933
934 DEFUN (show_ip_nht,
935 show_ip_nht_cmd,
936 "show ip nht [vrf NAME]",
937 SHOW_STR
938 IP_STR
939 "IP nexthop tracking table\n"
940 VRF_CMD_HELP_STR)
941 {
942 int idx_vrf = 4;
943 vrf_id_t vrf_id = VRF_DEFAULT;
944
945 if (argc == 5)
946 VRF_GET_ID(vrf_id, argv[idx_vrf]->arg, false);
947
948 zebra_print_rnh_table(vrf_id, AF_INET, vty, RNH_NEXTHOP_TYPE);
949 return CMD_SUCCESS;
950 }
951
952
953 DEFUN (show_ip_nht_vrf_all,
954 show_ip_nht_vrf_all_cmd,
955 "show ip nht vrf all",
956 SHOW_STR
957 IP_STR
958 "IP nexthop tracking table\n"
959 VRF_ALL_CMD_HELP_STR)
960 {
961 struct vrf *vrf;
962 struct zebra_vrf *zvrf;
963
964 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
965 if ((zvrf = vrf->info) != NULL) {
966 vty_out(vty, "\nVRF %s:\n", zvrf_name(zvrf));
967 zebra_print_rnh_table(zvrf_id(zvrf), AF_INET, vty,
968 RNH_NEXTHOP_TYPE);
969 }
970
971 return CMD_SUCCESS;
972 }
973
974 DEFUN (show_ipv6_nht,
975 show_ipv6_nht_cmd,
976 "show ipv6 nht [vrf NAME]",
977 SHOW_STR
978 IPV6_STR
979 "IPv6 nexthop tracking table\n"
980 VRF_CMD_HELP_STR)
981 {
982 int idx_vrf = 4;
983 vrf_id_t vrf_id = VRF_DEFAULT;
984
985 if (argc == 5)
986 VRF_GET_ID(vrf_id, argv[idx_vrf]->arg, false);
987
988 zebra_print_rnh_table(vrf_id, AF_INET6, vty, RNH_NEXTHOP_TYPE);
989 return CMD_SUCCESS;
990 }
991
992
993 DEFUN (show_ipv6_nht_vrf_all,
994 show_ipv6_nht_vrf_all_cmd,
995 "show ipv6 nht vrf all",
996 SHOW_STR
997 IP_STR
998 "IPv6 nexthop tracking table\n"
999 VRF_ALL_CMD_HELP_STR)
1000 {
1001 struct vrf *vrf;
1002 struct zebra_vrf *zvrf;
1003
1004 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
1005 if ((zvrf = vrf->info) != NULL) {
1006 vty_out(vty, "\nVRF %s:\n", zvrf_name(zvrf));
1007 zebra_print_rnh_table(zvrf_id(zvrf), AF_INET6, vty,
1008 RNH_NEXTHOP_TYPE);
1009 }
1010
1011 return CMD_SUCCESS;
1012 }
1013
1014 DEFUN (ip_nht_default_route,
1015 ip_nht_default_route_cmd,
1016 "ip nht resolve-via-default",
1017 IP_STR
1018 "Filter Next Hop tracking route resolution\n"
1019 "Resolve via default route\n")
1020 {
1021 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
1022
1023 if (!zvrf)
1024 return CMD_WARNING;
1025
1026 if (zebra_rnh_ip_default_route)
1027 return CMD_SUCCESS;
1028
1029 zebra_rnh_ip_default_route = 1;
1030
1031 zebra_evaluate_rnh(zvrf, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
1032 return CMD_SUCCESS;
1033 }
1034
1035 DEFUN (no_ip_nht_default_route,
1036 no_ip_nht_default_route_cmd,
1037 "no ip nht resolve-via-default",
1038 NO_STR
1039 IP_STR
1040 "Filter Next Hop tracking route resolution\n"
1041 "Resolve via default route\n")
1042 {
1043 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
1044
1045 if (!zvrf)
1046 return CMD_WARNING;
1047
1048 if (!zebra_rnh_ip_default_route)
1049 return CMD_SUCCESS;
1050
1051 zebra_rnh_ip_default_route = 0;
1052 zebra_evaluate_rnh(zvrf, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
1053 return CMD_SUCCESS;
1054 }
1055
1056 DEFUN (ipv6_nht_default_route,
1057 ipv6_nht_default_route_cmd,
1058 "ipv6 nht resolve-via-default",
1059 IP6_STR
1060 "Filter Next Hop tracking route resolution\n"
1061 "Resolve via default route\n")
1062 {
1063 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
1064
1065 if (!zvrf)
1066 return CMD_WARNING;
1067
1068 if (zebra_rnh_ipv6_default_route)
1069 return CMD_SUCCESS;
1070
1071 zebra_rnh_ipv6_default_route = 1;
1072 zebra_evaluate_rnh(zvrf, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL);
1073 return CMD_SUCCESS;
1074 }
1075
1076 DEFUN (no_ipv6_nht_default_route,
1077 no_ipv6_nht_default_route_cmd,
1078 "no ipv6 nht resolve-via-default",
1079 NO_STR
1080 IP6_STR
1081 "Filter Next Hop tracking route resolution\n"
1082 "Resolve via default route\n")
1083 {
1084
1085 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
1086
1087 if (!zvrf)
1088 return CMD_WARNING;
1089
1090 if (!zebra_rnh_ipv6_default_route)
1091 return CMD_SUCCESS;
1092
1093 zebra_rnh_ipv6_default_route = 0;
1094 zebra_evaluate_rnh(zvrf, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL);
1095 return CMD_SUCCESS;
1096 }
1097
1098 DEFPY (show_route,
1099 show_route_cmd,
1100 "show\
1101 <\
1102 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1103 [{\
1104 tag (1-4294967295)\
1105 |A.B.C.D/M$prefix longer-prefixes\
1106 |supernets-only$supernets_only\
1107 }]\
1108 [<\
1109 " FRR_IP_REDIST_STR_ZEBRA "$type_str\
1110 |ospf$type_str (1-65535)$ospf_instance_id\
1111 >]\
1112 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1113 [{\
1114 tag (1-4294967295)\
1115 |X:X::X:X/M$prefix longer-prefixes\
1116 }]\
1117 [" FRR_IP6_REDIST_STR_ZEBRA "$type_str]\
1118 >\
1119 [json$json]",
1120 SHOW_STR
1121 IP_STR
1122 "IP forwarding table\n"
1123 "IP routing table\n"
1124 VRF_FULL_CMD_HELP_STR
1125 "Show only routes with tag\n"
1126 "Tag value\n"
1127 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1128 "Show route matching the specified Network/Mask pair only\n"
1129 "Show supernet entries only\n"
1130 FRR_IP_REDIST_HELP_STR_ZEBRA
1131 "Open Shortest Path First (OSPFv2)\n"
1132 "Instance ID\n"
1133 IPV6_STR
1134 "IP forwarding table\n"
1135 "IP routing table\n"
1136 VRF_FULL_CMD_HELP_STR
1137 "Show only routes with tag\n"
1138 "Tag value\n"
1139 "IPv6 prefix\n"
1140 "Show route matching the specified Network/Mask pair only\n"
1141 FRR_IP6_REDIST_HELP_STR_ZEBRA
1142 JSON_STR)
1143 {
1144 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
1145 struct vrf *vrf;
1146 int type = 0;
1147
1148 if (type_str) {
1149 type = proto_redistnum(afi, type_str);
1150 if (type < 0) {
1151 vty_out(vty, "Unknown route type\n");
1152 return CMD_WARNING;
1153 }
1154 }
1155
1156 if (vrf_all) {
1157 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
1158 struct zebra_vrf *zvrf;
1159 struct route_table *table;
1160
1161 if ((zvrf = vrf->info) == NULL
1162 || (table = zvrf->table[afi][SAFI_UNICAST]) == NULL)
1163 continue;
1164
1165 do_show_ip_route(
1166 vty, zvrf_name(zvrf), afi, SAFI_UNICAST, !!fib,
1167 !!json, tag, prefix_str ? prefix : NULL,
1168 !!supernets_only, type, ospf_instance_id);
1169 }
1170 } else {
1171 vrf_id_t vrf_id = VRF_DEFAULT;
1172
1173 if (vrf_name)
1174 VRF_GET_ID(vrf_id, vrf_name, !!json);
1175 vrf = vrf_lookup_by_id(vrf_id);
1176 do_show_ip_route(vty, vrf->name, afi, SAFI_UNICAST, !!fib,
1177 !!json, tag, prefix_str ? prefix : NULL,
1178 !!supernets_only, type, ospf_instance_id);
1179 }
1180
1181 return CMD_SUCCESS;
1182 }
1183
1184 DEFPY (show_route_detail,
1185 show_route_detail_cmd,
1186 "show\
1187 <\
1188 ip$ipv4 route [vrf <NAME$vrf_name|all$vrf_all>]\
1189 <\
1190 A.B.C.D$address\
1191 |A.B.C.D/M$prefix\
1192 >\
1193 |ipv6$ipv6 route [vrf <NAME$vrf_name|all$vrf_all>]\
1194 <\
1195 X:X::X:X$address\
1196 |X:X::X:X/M$prefix\
1197 >\
1198 >\
1199 [json$json]",
1200 SHOW_STR
1201 IP_STR
1202 "IP routing table\n"
1203 VRF_FULL_CMD_HELP_STR
1204 "Network in the IP routing table to display\n"
1205 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1206 IP6_STR
1207 "IP routing table\n"
1208 VRF_FULL_CMD_HELP_STR
1209 "IPv6 Address\n"
1210 "IPv6 prefix\n"
1211 JSON_STR)
1212 {
1213 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
1214 struct route_table *table;
1215 struct prefix p;
1216 struct route_node *rn;
1217
1218 if (address_str)
1219 prefix_str = address_str;
1220 if (str2prefix(prefix_str, &p) < 0) {
1221 vty_out(vty, "%% Malformed address\n");
1222 return CMD_WARNING;
1223 }
1224
1225 if (vrf_all) {
1226 struct vrf *vrf;
1227 struct zebra_vrf *zvrf;
1228
1229 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
1230 if ((zvrf = vrf->info) == NULL
1231 || (table = zvrf->table[afi][SAFI_UNICAST]) == NULL)
1232 continue;
1233
1234 rn = route_node_match(table, &p);
1235 if (!rn)
1236 continue;
1237 if (!address_str && rn->p.prefixlen != p.prefixlen) {
1238 route_unlock_node(rn);
1239 continue;
1240 }
1241
1242 if (json)
1243 vty_show_ip_route_detail_json(vty, rn);
1244 else
1245 vty_show_ip_route_detail(vty, rn, 0);
1246
1247 route_unlock_node(rn);
1248 }
1249 } else {
1250 vrf_id_t vrf_id = VRF_DEFAULT;
1251
1252 if (vrf_name)
1253 VRF_GET_ID(vrf_id, vrf_name, false);
1254
1255 table = zebra_vrf_table(afi, SAFI_UNICAST, vrf_id);
1256 if (!table)
1257 return CMD_SUCCESS;
1258
1259 rn = route_node_match(table, &p);
1260 if (!rn) {
1261 vty_out(vty, "%% Network not in table\n");
1262 return CMD_WARNING;
1263 }
1264 if (!address_str && rn->p.prefixlen != p.prefixlen) {
1265 vty_out(vty, "%% Network not in table\n");
1266 route_unlock_node(rn);
1267 return CMD_WARNING;
1268 }
1269
1270 if (json)
1271 vty_show_ip_route_detail_json(vty, rn);
1272 else
1273 vty_show_ip_route_detail(vty, rn, 0);
1274
1275 route_unlock_node(rn);
1276 }
1277
1278 return CMD_SUCCESS;
1279 }
1280
1281 DEFPY (show_route_summary,
1282 show_route_summary_cmd,
1283 "show\
1284 <\
1285 ip$ipv4 route [vrf <NAME$vrf_name|all$vrf_all>]\
1286 summary [prefix$prefix]\
1287 |ipv6$ipv6 route [vrf <NAME$vrf_name|all$vrf_all>]\
1288 summary [prefix$prefix]\
1289 >",
1290 SHOW_STR
1291 IP_STR
1292 "IP routing table\n"
1293 VRF_FULL_CMD_HELP_STR
1294 "Summary of all routes\n"
1295 "Prefix routes\n"
1296 IP6_STR
1297 "IP routing table\n"
1298 VRF_FULL_CMD_HELP_STR
1299 "Summary of all routes\n"
1300 "Prefix routes\n")
1301 {
1302 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
1303 struct route_table *table;
1304
1305 if (vrf_all) {
1306 struct vrf *vrf;
1307 struct zebra_vrf *zvrf;
1308
1309 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
1310 if ((zvrf = vrf->info) == NULL
1311 || (table = zvrf->table[afi][SAFI_UNICAST]) == NULL)
1312 continue;
1313
1314 if (prefix)
1315 vty_show_ip_route_summary_prefix(vty, table);
1316 else
1317 vty_show_ip_route_summary(vty, table);
1318 }
1319 } else {
1320 vrf_id_t vrf_id = VRF_DEFAULT;
1321
1322 if (vrf_name)
1323 VRF_GET_ID(vrf_id, vrf_name, false);
1324
1325 table = zebra_vrf_table(afi, SAFI_UNICAST, vrf_id);
1326 if (!table)
1327 return CMD_SUCCESS;
1328
1329 if (prefix)
1330 vty_show_ip_route_summary_prefix(vty, table);
1331 else
1332 vty_show_ip_route_summary(vty, table);
1333 }
1334
1335 return CMD_SUCCESS;
1336 }
1337
1338 static void vty_show_ip_route_summary(struct vty *vty,
1339 struct route_table *table)
1340 {
1341 struct route_node *rn;
1342 struct route_entry *re;
1343 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1344 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1345 uint32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1346 uint32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1347 uint32_t i;
1348 uint32_t is_ibgp;
1349
1350 memset(&rib_cnt, 0, sizeof(rib_cnt));
1351 memset(&fib_cnt, 0, sizeof(fib_cnt));
1352 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
1353 RNODE_FOREACH_RE (rn, re) {
1354 is_ibgp = (re->type == ZEBRA_ROUTE_BGP
1355 && CHECK_FLAG(re->flags, ZEBRA_FLAG_IBGP));
1356
1357 rib_cnt[ZEBRA_ROUTE_TOTAL]++;
1358 if (is_ibgp)
1359 rib_cnt[ZEBRA_ROUTE_IBGP]++;
1360 else
1361 rib_cnt[re->type]++;
1362
1363 if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED)) {
1364 fib_cnt[ZEBRA_ROUTE_TOTAL]++;
1365
1366 if (is_ibgp)
1367 fib_cnt[ZEBRA_ROUTE_IBGP]++;
1368 else
1369 fib_cnt[re->type]++;
1370 }
1371 }
1372
1373 vty_out(vty, "%-20s %-20s %s (vrf %s)\n", "Route Source", "Routes",
1374 "FIB", zvrf_name(((rib_table_info_t *)route_table_get_info(table))->zvrf));
1375
1376 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
1377 if ((rib_cnt[i] > 0) || (i == ZEBRA_ROUTE_BGP
1378 && rib_cnt[ZEBRA_ROUTE_IBGP] > 0)) {
1379 if (i == ZEBRA_ROUTE_BGP) {
1380 vty_out(vty, "%-20s %-20d %-20d \n", "ebgp",
1381 rib_cnt[ZEBRA_ROUTE_BGP],
1382 fib_cnt[ZEBRA_ROUTE_BGP]);
1383 vty_out(vty, "%-20s %-20d %-20d \n", "ibgp",
1384 rib_cnt[ZEBRA_ROUTE_IBGP],
1385 fib_cnt[ZEBRA_ROUTE_IBGP]);
1386 } else
1387 vty_out(vty, "%-20s %-20d %-20d \n",
1388 zebra_route_string(i), rib_cnt[i],
1389 fib_cnt[i]);
1390 }
1391 }
1392
1393 vty_out(vty, "------\n");
1394 vty_out(vty, "%-20s %-20d %-20d \n", "Totals",
1395 rib_cnt[ZEBRA_ROUTE_TOTAL], fib_cnt[ZEBRA_ROUTE_TOTAL]);
1396 vty_out(vty, "\n");
1397 }
1398
1399 /*
1400 * Implementation of the ip route summary prefix command.
1401 *
1402 * This command prints the primary prefixes that have been installed by various
1403 * protocols on the box.
1404 *
1405 */
1406 static void vty_show_ip_route_summary_prefix(struct vty *vty,
1407 struct route_table *table)
1408 {
1409 struct route_node *rn;
1410 struct route_entry *re;
1411 struct nexthop *nexthop;
1412 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1413 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1414 uint32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1415 uint32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1416 uint32_t i;
1417 int cnt;
1418
1419 memset(&rib_cnt, 0, sizeof(rib_cnt));
1420 memset(&fib_cnt, 0, sizeof(fib_cnt));
1421 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
1422 RNODE_FOREACH_RE (rn, re) {
1423
1424 /*
1425 * In case of ECMP, count only once.
1426 */
1427 cnt = 0;
1428 for (nexthop = re->ng.nexthop; (!cnt && nexthop);
1429 nexthop = nexthop->next) {
1430 cnt++;
1431 rib_cnt[ZEBRA_ROUTE_TOTAL]++;
1432 rib_cnt[re->type]++;
1433 if (CHECK_FLAG(nexthop->flags,
1434 NEXTHOP_FLAG_FIB)) {
1435 fib_cnt[ZEBRA_ROUTE_TOTAL]++;
1436 fib_cnt[re->type]++;
1437 }
1438 if (re->type == ZEBRA_ROUTE_BGP
1439 && CHECK_FLAG(re->flags, ZEBRA_FLAG_IBGP)) {
1440 rib_cnt[ZEBRA_ROUTE_IBGP]++;
1441 if (CHECK_FLAG(nexthop->flags,
1442 NEXTHOP_FLAG_FIB))
1443 fib_cnt[ZEBRA_ROUTE_IBGP]++;
1444 }
1445 }
1446 }
1447
1448 vty_out(vty, "%-20s %-20s %s (vrf %s)\n", "Route Source",
1449 "Prefix Routes", "FIB",
1450 zvrf_name(((rib_table_info_t *)route_table_get_info(table))->zvrf));
1451
1452 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
1453 if (rib_cnt[i] > 0) {
1454 if (i == ZEBRA_ROUTE_BGP) {
1455 vty_out(vty, "%-20s %-20d %-20d \n", "ebgp",
1456 rib_cnt[ZEBRA_ROUTE_BGP]
1457 - rib_cnt[ZEBRA_ROUTE_IBGP],
1458 fib_cnt[ZEBRA_ROUTE_BGP]
1459 - fib_cnt[ZEBRA_ROUTE_IBGP]);
1460 vty_out(vty, "%-20s %-20d %-20d \n", "ibgp",
1461 rib_cnt[ZEBRA_ROUTE_IBGP],
1462 fib_cnt[ZEBRA_ROUTE_IBGP]);
1463 } else
1464 vty_out(vty, "%-20s %-20d %-20d \n",
1465 zebra_route_string(i), rib_cnt[i],
1466 fib_cnt[i]);
1467 }
1468 }
1469
1470 vty_out(vty, "------\n");
1471 vty_out(vty, "%-20s %-20d %-20d \n", "Totals",
1472 rib_cnt[ZEBRA_ROUTE_TOTAL], fib_cnt[ZEBRA_ROUTE_TOTAL]);
1473 vty_out(vty, "\n");
1474 }
1475
1476 /*
1477 * Show IPv6 mroute command.Used to dump
1478 * the Multicast routing table.
1479 */
1480 DEFUN (show_ipv6_mroute,
1481 show_ipv6_mroute_cmd,
1482 "show ipv6 mroute [vrf NAME]",
1483 SHOW_STR
1484 IP_STR
1485 "IPv6 Multicast routing table\n"
1486 VRF_CMD_HELP_STR)
1487 {
1488 struct route_table *table;
1489 struct route_node *rn;
1490 struct route_entry *re;
1491 int first = 1;
1492 vrf_id_t vrf_id = VRF_DEFAULT;
1493
1494 if (argc == 5)
1495 VRF_GET_ID(vrf_id, argv[4]->arg, false);
1496
1497 table = zebra_vrf_table(AFI_IP6, SAFI_MULTICAST, vrf_id);
1498 if (!table)
1499 return CMD_SUCCESS;
1500
1501 /* Show all IPv6 route. */
1502 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
1503 RNODE_FOREACH_RE (rn, re) {
1504 if (first) {
1505 vty_out(vty, SHOW_ROUTE_V6_HEADER);
1506 first = 0;
1507 }
1508 vty_show_ip_route(vty, rn, re, NULL);
1509 }
1510 return CMD_SUCCESS;
1511 }
1512
1513 DEFUN (show_ipv6_mroute_vrf_all,
1514 show_ipv6_mroute_vrf_all_cmd,
1515 "show ipv6 mroute vrf all",
1516 SHOW_STR
1517 IP_STR
1518 "IPv6 Multicast routing table\n"
1519 VRF_ALL_CMD_HELP_STR)
1520 {
1521 struct route_table *table;
1522 struct route_node *rn;
1523 struct route_entry *re;
1524 struct vrf *vrf;
1525 struct zebra_vrf *zvrf;
1526 int first = 1;
1527
1528 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
1529 if ((zvrf = vrf->info) == NULL
1530 || (table = zvrf->table[AFI_IP6][SAFI_MULTICAST]) == NULL)
1531 continue;
1532
1533 /* Show all IPv6 route. */
1534 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
1535 RNODE_FOREACH_RE (rn, re) {
1536 if (first) {
1537 vty_out(vty, SHOW_ROUTE_V6_HEADER);
1538 first = 0;
1539 }
1540 vty_show_ip_route(vty, rn, re, NULL);
1541 }
1542 }
1543 return CMD_SUCCESS;
1544 }
1545
1546 DEFUN (allow_external_route_update,
1547 allow_external_route_update_cmd,
1548 "allow-external-route-update",
1549 "Allow FRR routes to be overwritten by external processes\n")
1550 {
1551 allow_delete = 1;
1552
1553 return CMD_SUCCESS;
1554 }
1555
1556 DEFUN (no_allow_external_route_update,
1557 no_allow_external_route_update_cmd,
1558 "no allow-external-route-update",
1559 NO_STR
1560 "Allow FRR routes to be overwritten by external processes\n")
1561 {
1562 allow_delete = 0;
1563
1564 return CMD_SUCCESS;
1565 }
1566
1567 /* show vrf */
1568 DEFUN (show_vrf,
1569 show_vrf_cmd,
1570 "show vrf",
1571 SHOW_STR
1572 "VRF\n")
1573 {
1574 struct vrf *vrf;
1575 struct zebra_vrf *zvrf;
1576
1577 if (vrf_is_backend_netns())
1578 vty_out(vty, "netns-based vrfs\n");
1579
1580 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
1581 if (!(zvrf = vrf->info))
1582 continue;
1583 if (zvrf_id(zvrf) == VRF_DEFAULT)
1584 continue;
1585
1586 vty_out(vty, "vrf %s ", zvrf_name(zvrf));
1587 if (zvrf_id(zvrf) == VRF_UNKNOWN || !zvrf_is_active(zvrf))
1588 vty_out(vty, "inactive");
1589 else if (zvrf_ns_name(zvrf))
1590 vty_out(vty, "id %u netns %s", zvrf_id(zvrf),
1591 zvrf_ns_name(zvrf));
1592 else
1593 vty_out(vty, "id %u table %u", zvrf_id(zvrf),
1594 zvrf->table_id);
1595 if (vrf_is_user_cfged(vrf))
1596 vty_out(vty, " (configured)");
1597 vty_out(vty, "\n");
1598 }
1599
1600 return CMD_SUCCESS;
1601 }
1602
1603 DEFUN_HIDDEN (default_vrf_vni_mapping,
1604 default_vrf_vni_mapping_cmd,
1605 "vni " CMD_VNI_RANGE "[prefix-routes-only]",
1606 "VNI corresponding to the DEFAULT VRF\n"
1607 "VNI-ID\n"
1608 "Prefix routes only \n")
1609 {
1610 int ret = 0;
1611 char err[ERR_STR_SZ];
1612 struct zebra_vrf *zvrf = NULL;
1613 vni_t vni = strtoul(argv[1]->arg, NULL, 10);
1614 int filter = 0;
1615
1616 zvrf = vrf_info_lookup(VRF_DEFAULT);
1617 if (!zvrf)
1618 return CMD_WARNING;
1619
1620 if (argc == 3)
1621 filter = 1;
1622
1623 ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ,
1624 filter, 1);
1625 if (ret != 0) {
1626 vty_out(vty, "%s\n", err);
1627 return CMD_WARNING;
1628 }
1629
1630 return CMD_SUCCESS;
1631 }
1632
1633 DEFUN_HIDDEN (no_default_vrf_vni_mapping,
1634 no_default_vrf_vni_mapping_cmd,
1635 "no vni " CMD_VNI_RANGE,
1636 NO_STR
1637 "VNI corresponding to DEFAULT VRF\n"
1638 "VNI-ID")
1639 {
1640 int ret = 0;
1641 char err[ERR_STR_SZ];
1642 vni_t vni = strtoul(argv[2]->arg, NULL, 10);
1643 struct zebra_vrf *zvrf = NULL;
1644
1645 zvrf = vrf_info_lookup(VRF_DEFAULT);
1646 if (!zvrf)
1647 return CMD_WARNING;
1648
1649 ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ, 0, 0);
1650 if (ret != 0) {
1651 vty_out(vty, "%s\n", err);
1652 return CMD_WARNING;
1653 }
1654
1655 return CMD_SUCCESS;
1656 }
1657
1658 DEFUN (vrf_vni_mapping,
1659 vrf_vni_mapping_cmd,
1660 "vni " CMD_VNI_RANGE "[prefix-routes-only]",
1661 "VNI corresponding to tenant VRF\n"
1662 "VNI-ID\n"
1663 "prefix-routes-only\n")
1664 {
1665 int ret = 0;
1666 int filter = 0;
1667
1668 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
1669 vni_t vni = strtoul(argv[1]->arg, NULL, 10);
1670 char err[ERR_STR_SZ];
1671
1672 assert(vrf);
1673 assert(zvrf);
1674
1675 if (argc == 3)
1676 filter = 1;
1677
1678 /* Mark as having FRR configuration */
1679 vrf_set_user_cfged(vrf);
1680 ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ,
1681 filter, 1);
1682 if (ret != 0) {
1683 vty_out(vty, "%s\n", err);
1684 return CMD_WARNING;
1685 }
1686
1687 return CMD_SUCCESS;
1688 }
1689
1690 DEFUN (no_vrf_vni_mapping,
1691 no_vrf_vni_mapping_cmd,
1692 "no vni " CMD_VNI_RANGE "[prefix-routes-only]",
1693 NO_STR
1694 "VNI corresponding to tenant VRF\n"
1695 "VNI-ID\n"
1696 "prefix-routes-only\n")
1697 {
1698 int ret = 0;
1699 int filter = 0;
1700 char err[ERR_STR_SZ];
1701 vni_t vni = strtoul(argv[2]->arg, NULL, 10);
1702
1703 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
1704
1705 assert(vrf);
1706 assert(zvrf);
1707
1708 if (argc == 4)
1709 filter = 1;
1710
1711 ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err,
1712 ERR_STR_SZ, filter, 0);
1713 if (ret != 0) {
1714 vty_out(vty, "%s\n", err);
1715 return CMD_WARNING;
1716 }
1717
1718 /* If no other FRR config for this VRF, mark accordingly. */
1719 if (!zebra_vrf_has_config(zvrf))
1720 vrf_reset_user_cfged(vrf);
1721
1722 return CMD_SUCCESS;
1723 }
1724
1725 /* show vrf */
1726 DEFUN (show_vrf_vni,
1727 show_vrf_vni_cmd,
1728 "show vrf vni [json]",
1729 SHOW_STR
1730 "VRF\n"
1731 "VNI\n"
1732 JSON_STR)
1733 {
1734 struct vrf *vrf;
1735 struct zebra_vrf *zvrf;
1736 json_object *json = NULL;
1737 json_object *json_vrfs = NULL;
1738 bool uj = use_json(argc, argv);
1739
1740 if (uj) {
1741 json = json_object_new_object();
1742 json_vrfs = json_object_new_array();
1743 }
1744
1745 if (!uj)
1746 vty_out(vty, "%-37s %-10s %-20s %-20s %-5s %-18s\n", "VRF",
1747 "VNI", "VxLAN IF", "L3-SVI", "State", "Rmac");
1748
1749 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
1750 zvrf = vrf->info;
1751 if (!zvrf)
1752 continue;
1753
1754 zebra_vxlan_print_vrf_vni(vty, zvrf, json_vrfs);
1755 }
1756
1757 if (uj) {
1758 json_object_object_add(json, "vrfs", json_vrfs);
1759 vty_out(vty, "%s\n", json_object_to_json_string_ext(
1760 json, JSON_C_TO_STRING_PRETTY));
1761 json_object_free(json);
1762 }
1763
1764 return CMD_SUCCESS;
1765 }
1766
1767 DEFUN (show_evpn_global,
1768 show_evpn_global_cmd,
1769 "show evpn [json]",
1770 SHOW_STR
1771 "EVPN\n"
1772 JSON_STR)
1773 {
1774 bool uj = use_json(argc, argv);
1775
1776 zebra_vxlan_print_evpn(vty, uj);
1777 return CMD_SUCCESS;
1778 }
1779
1780 DEFUN (show_evpn_vni,
1781 show_evpn_vni_cmd,
1782 "show evpn vni [json]",
1783 SHOW_STR
1784 "EVPN\n"
1785 "VxLAN information\n"
1786 JSON_STR)
1787 {
1788 struct zebra_vrf *zvrf;
1789 bool uj = use_json(argc, argv);
1790
1791 zvrf = vrf_info_lookup(VRF_DEFAULT);
1792 zebra_vxlan_print_vnis(vty, zvrf, uj);
1793 return CMD_SUCCESS;
1794 }
1795
1796 DEFUN (show_evpn_vni_vni,
1797 show_evpn_vni_vni_cmd,
1798 "show evpn vni " CMD_VNI_RANGE "[json]",
1799 SHOW_STR
1800 "EVPN\n"
1801 "VxLAN Network Identifier\n"
1802 "VNI number\n"
1803 JSON_STR)
1804 {
1805 struct zebra_vrf *zvrf;
1806 vni_t vni;
1807 bool uj = use_json(argc, argv);
1808
1809 vni = strtoul(argv[3]->arg, NULL, 10);
1810 zvrf = vrf_info_lookup(VRF_DEFAULT);
1811 zebra_vxlan_print_vni(vty, zvrf, vni, uj);
1812 return CMD_SUCCESS;
1813 }
1814
1815 DEFUN (show_evpn_rmac_vni_mac,
1816 show_evpn_rmac_vni_mac_cmd,
1817 "show evpn rmac vni " CMD_VNI_RANGE " mac WORD [json]",
1818 SHOW_STR
1819 "EVPN\n"
1820 "RMAC\n"
1821 "L3 VNI\n"
1822 "VNI number\n"
1823 "MAC\n"
1824 "mac-address (e.g. 0a:0a:0a:0a:0a:0a)\n"
1825 JSON_STR)
1826 {
1827 vni_t l3vni = 0;
1828 struct ethaddr mac;
1829 bool uj = use_json(argc, argv);
1830
1831 l3vni = strtoul(argv[4]->arg, NULL, 10);
1832 if (!prefix_str2mac(argv[6]->arg, &mac)) {
1833 vty_out(vty, "%% Malformed MAC address\n");
1834 return CMD_WARNING;
1835 }
1836 zebra_vxlan_print_specific_rmac_l3vni(vty, l3vni, &mac, uj);
1837 return CMD_SUCCESS;
1838 }
1839
1840 DEFUN (show_evpn_rmac_vni,
1841 show_evpn_rmac_vni_cmd,
1842 "show evpn rmac vni " CMD_VNI_RANGE "[json]",
1843 SHOW_STR
1844 "EVPN\n"
1845 "RMAC\n"
1846 "L3 VNI\n"
1847 "VNI number\n"
1848 JSON_STR)
1849 {
1850 vni_t l3vni = 0;
1851 bool uj = use_json(argc, argv);
1852
1853 l3vni = strtoul(argv[4]->arg, NULL, 10);
1854 zebra_vxlan_print_rmacs_l3vni(vty, l3vni, uj);
1855
1856 return CMD_SUCCESS;
1857 }
1858
1859 DEFUN (show_evpn_rmac_vni_all,
1860 show_evpn_rmac_vni_all_cmd,
1861 "show evpn rmac vni all [json]",
1862 SHOW_STR
1863 "EVPN\n"
1864 "RMAC addresses\n"
1865 "L3 VNI\n"
1866 "All VNIs\n"
1867 JSON_STR)
1868 {
1869 bool uj = use_json(argc, argv);
1870
1871 zebra_vxlan_print_rmacs_all_l3vni(vty, uj);
1872
1873 return CMD_SUCCESS;
1874 }
1875
1876 DEFUN (show_evpn_nh_vni_ip,
1877 show_evpn_nh_vni_ip_cmd,
1878 "show evpn next-hops vni " CMD_VNI_RANGE " ip WORD [json]",
1879 SHOW_STR
1880 "EVPN\n"
1881 "Remote Vteps\n"
1882 "L3 VNI\n"
1883 "VNI number\n"
1884 "Ip address\n"
1885 "Host address (ipv4 or ipv6)\n"
1886 JSON_STR)
1887 {
1888 vni_t l3vni;
1889 struct ipaddr ip;
1890 bool uj = use_json(argc, argv);
1891
1892 l3vni = strtoul(argv[4]->arg, NULL, 10);
1893 if (str2ipaddr(argv[6]->arg, &ip) != 0) {
1894 if (!uj)
1895 vty_out(vty, "%% Malformed Neighbor address\n");
1896 return CMD_WARNING;
1897 }
1898 zebra_vxlan_print_specific_nh_l3vni(vty, l3vni, &ip, uj);
1899
1900 return CMD_SUCCESS;
1901 }
1902
1903 DEFUN (show_evpn_nh_vni,
1904 show_evpn_nh_vni_cmd,
1905 "show evpn next-hops vni " CMD_VNI_RANGE "[json]",
1906 SHOW_STR
1907 "EVPN\n"
1908 "Remote Vteps\n"
1909 "L3 VNI\n"
1910 "VNI number\n"
1911 JSON_STR)
1912 {
1913 vni_t l3vni;
1914 bool uj = use_json(argc, argv);
1915
1916 l3vni = strtoul(argv[4]->arg, NULL, 10);
1917 zebra_vxlan_print_nh_l3vni(vty, l3vni, uj);
1918
1919 return CMD_SUCCESS;
1920 }
1921
1922 DEFUN (show_evpn_nh_vni_all,
1923 show_evpn_nh_vni_all_cmd,
1924 "show evpn next-hops vni all [json]",
1925 SHOW_STR
1926 "EVPN\n"
1927 "Remote VTEPs\n"
1928 "L3 VNI\n"
1929 "All VNIs\n"
1930 JSON_STR)
1931 {
1932 bool uj = use_json(argc, argv);
1933
1934 zebra_vxlan_print_nh_all_l3vni(vty, uj);
1935
1936 return CMD_SUCCESS;
1937 }
1938
1939 DEFUN (show_evpn_mac_vni,
1940 show_evpn_mac_vni_cmd,
1941 "show evpn mac vni " CMD_VNI_RANGE "[json]",
1942 SHOW_STR
1943 "EVPN\n"
1944 "MAC addresses\n"
1945 "VxLAN Network Identifier\n"
1946 "VNI number\n"
1947 JSON_STR)
1948 {
1949 struct zebra_vrf *zvrf;
1950 vni_t vni;
1951 bool uj = use_json(argc, argv);
1952
1953 vni = strtoul(argv[4]->arg, NULL, 10);
1954 zvrf = vrf_info_lookup(VRF_DEFAULT);
1955 zebra_vxlan_print_macs_vni(vty, zvrf, vni, uj);
1956 return CMD_SUCCESS;
1957 }
1958
1959 DEFUN (show_evpn_mac_vni_all,
1960 show_evpn_mac_vni_all_cmd,
1961 "show evpn mac vni all [json]",
1962 SHOW_STR
1963 "EVPN\n"
1964 "MAC addresses\n"
1965 "VxLAN Network Identifier\n"
1966 "All VNIs\n"
1967 JSON_STR)
1968 {
1969 struct zebra_vrf *zvrf;
1970 bool uj = use_json(argc, argv);
1971
1972 zvrf = vrf_info_lookup(VRF_DEFAULT);
1973 zebra_vxlan_print_macs_all_vni(vty, zvrf, false, uj);
1974 return CMD_SUCCESS;
1975 }
1976
1977 DEFUN (show_evpn_mac_vni_all_vtep,
1978 show_evpn_mac_vni_all_vtep_cmd,
1979 "show evpn mac vni all vtep A.B.C.D [json]",
1980 SHOW_STR
1981 "EVPN\n"
1982 "MAC addresses\n"
1983 "VxLAN Network Identifier\n"
1984 "All VNIs\n"
1985 "Remote VTEP\n"
1986 "Remote VTEP IP address\n"
1987 JSON_STR)
1988 {
1989 struct zebra_vrf *zvrf;
1990 struct in_addr vtep_ip;
1991 bool uj = use_json(argc, argv);
1992
1993 if (!inet_aton(argv[6]->arg, &vtep_ip)) {
1994 if (!uj)
1995 vty_out(vty, "%% Malformed VTEP IP address\n");
1996 return CMD_WARNING;
1997 }
1998 zvrf = vrf_info_lookup(VRF_DEFAULT);
1999 zebra_vxlan_print_macs_all_vni_vtep(vty, zvrf, vtep_ip, uj);
2000
2001 return CMD_SUCCESS;
2002 }
2003
2004
2005 DEFUN (show_evpn_mac_vni_mac,
2006 show_evpn_mac_vni_mac_cmd,
2007 "show evpn mac vni " CMD_VNI_RANGE " mac WORD [json]",
2008 SHOW_STR
2009 "EVPN\n"
2010 "MAC addresses\n"
2011 "VxLAN Network Identifier\n"
2012 "VNI number\n"
2013 "MAC\n"
2014 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2015 JSON_STR)
2016
2017 {
2018 struct zebra_vrf *zvrf;
2019 vni_t vni;
2020 struct ethaddr mac;
2021 bool uj = use_json(argc, argv);
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, uj);
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 DEFPY (show_evpn_mac_vni_all_dad,
2063 show_evpn_mac_vni_all_dad_cmd,
2064 "show evpn mac vni all duplicate [json]",
2065 SHOW_STR
2066 "EVPN\n"
2067 "MAC addresses\n"
2068 "VxLAN Network Identifier\n"
2069 "All VNIs\n"
2070 "Duplicate address list\n"
2071 JSON_STR)
2072 {
2073 struct zebra_vrf *zvrf;
2074 bool uj = use_json(argc, argv);
2075
2076 zvrf = vrf_info_lookup(VRF_DEFAULT);
2077 zebra_vxlan_print_macs_all_vni(vty, zvrf, true, uj);
2078 return CMD_SUCCESS;
2079 }
2080
2081
2082 DEFPY (show_evpn_mac_vni_dad,
2083 show_evpn_mac_vni_dad_cmd,
2084 "show evpn mac vni " CMD_VNI_RANGE " duplicate" "[json]",
2085 SHOW_STR
2086 "EVPN\n"
2087 "MAC addresses\n"
2088 "VxLAN Network Identifier\n"
2089 "VNI number\n"
2090 "Duplicate address list\n"
2091 JSON_STR)
2092 {
2093 struct zebra_vrf *zvrf;
2094 vni_t vni;
2095 bool uj = use_json(argc, argv);
2096
2097 vni = strtoul(argv[4]->arg, NULL, 10);
2098 zvrf = vrf_info_lookup(VRF_DEFAULT);
2099
2100 zebra_vxlan_print_macs_vni_dad(vty, zvrf, vni, uj);
2101
2102 return CMD_SUCCESS;
2103 }
2104
2105 DEFPY (show_evpn_neigh_vni_dad,
2106 show_evpn_neigh_vni_dad_cmd,
2107 "show evpn arp-cache vni " CMD_VNI_RANGE "duplicate" "[json]",
2108 SHOW_STR
2109 "EVPN\n"
2110 "ARP and ND cache\n"
2111 "VxLAN Network Identifier\n"
2112 "VNI number\n"
2113 "Duplicate address list\n"
2114 JSON_STR)
2115 {
2116 struct zebra_vrf *zvrf;
2117 vni_t vni;
2118 bool uj = use_json(argc, argv);
2119
2120 vni = strtoul(argv[4]->arg, NULL, 10);
2121 zvrf = vrf_info_lookup(VRF_DEFAULT);
2122 zebra_vxlan_print_neigh_vni_dad(vty, zvrf, vni, uj);
2123 return CMD_SUCCESS;
2124 }
2125
2126 DEFPY (show_evpn_neigh_vni_all_dad,
2127 show_evpn_neigh_vni_all_dad_cmd,
2128 "show evpn arp-cache vni all duplicate [json]",
2129 SHOW_STR
2130 "EVPN\n"
2131 "ARP and ND cache\n"
2132 "VxLAN Network Identifier\n"
2133 "All VNIs\n"
2134 "Duplicate address list\n"
2135 JSON_STR)
2136 {
2137 struct zebra_vrf *zvrf;
2138 bool uj = use_json(argc, argv);
2139
2140 zvrf = vrf_info_lookup(VRF_DEFAULT);
2141 zebra_vxlan_print_neigh_all_vni(vty, zvrf, true, uj);
2142 return CMD_SUCCESS;
2143 }
2144
2145
2146 DEFUN (show_evpn_neigh_vni,
2147 show_evpn_neigh_vni_cmd,
2148 "show evpn arp-cache vni " CMD_VNI_RANGE "[json]",
2149 SHOW_STR
2150 "EVPN\n"
2151 "ARP and ND cache\n"
2152 "VxLAN Network Identifier\n"
2153 "VNI number\n"
2154 JSON_STR)
2155 {
2156 struct zebra_vrf *zvrf;
2157 vni_t vni;
2158 bool uj = use_json(argc, argv);
2159
2160 vni = strtoul(argv[4]->arg, NULL, 10);
2161 zvrf = vrf_info_lookup(VRF_DEFAULT);
2162 zebra_vxlan_print_neigh_vni(vty, zvrf, vni, uj);
2163 return CMD_SUCCESS;
2164 }
2165
2166 DEFUN (show_evpn_neigh_vni_all,
2167 show_evpn_neigh_vni_all_cmd,
2168 "show evpn arp-cache vni all [json]",
2169 SHOW_STR
2170 "EVPN\n"
2171 "ARP and ND cache\n"
2172 "VxLAN Network Identifier\n"
2173 "All VNIs\n"
2174 JSON_STR)
2175 {
2176 struct zebra_vrf *zvrf;
2177 bool uj = use_json(argc, argv);
2178
2179 zvrf = vrf_info_lookup(VRF_DEFAULT);
2180 zebra_vxlan_print_neigh_all_vni(vty, zvrf, false, uj);
2181 return CMD_SUCCESS;
2182 }
2183
2184 DEFUN (show_evpn_neigh_vni_neigh,
2185 show_evpn_neigh_vni_neigh_cmd,
2186 "show evpn arp-cache vni " CMD_VNI_RANGE " ip WORD [json]",
2187 SHOW_STR
2188 "EVPN\n"
2189 "ARP and ND cache\n"
2190 "VxLAN Network Identifier\n"
2191 "VNI number\n"
2192 "Neighbor\n"
2193 "Neighbor address (IPv4 or IPv6 address)\n"
2194 JSON_STR)
2195 {
2196 struct zebra_vrf *zvrf;
2197 vni_t vni;
2198 struct ipaddr ip;
2199 bool uj = use_json(argc, argv);
2200
2201 vni = strtoul(argv[4]->arg, NULL, 10);
2202 if (str2ipaddr(argv[6]->arg, &ip) != 0) {
2203 if (!uj)
2204 vty_out(vty, "%% Malformed Neighbor address\n");
2205 return CMD_WARNING;
2206 }
2207 zvrf = vrf_info_lookup(VRF_DEFAULT);
2208 zebra_vxlan_print_specific_neigh_vni(vty, zvrf, vni, &ip, uj);
2209 return CMD_SUCCESS;
2210 }
2211
2212 DEFUN (show_evpn_neigh_vni_vtep,
2213 show_evpn_neigh_vni_vtep_cmd,
2214 "show evpn arp-cache vni " CMD_VNI_RANGE " vtep A.B.C.D [json]",
2215 SHOW_STR
2216 "EVPN\n"
2217 "ARP and ND cache\n"
2218 "VxLAN Network Identifier\n"
2219 "VNI number\n"
2220 "Remote VTEP\n"
2221 "Remote VTEP IP address\n"
2222 JSON_STR)
2223 {
2224 struct zebra_vrf *zvrf;
2225 vni_t vni;
2226 struct in_addr vtep_ip;
2227 bool uj = use_json(argc, argv);
2228
2229 vni = strtoul(argv[4]->arg, NULL, 10);
2230 if (!inet_aton(argv[6]->arg, &vtep_ip)) {
2231 if (!uj)
2232 vty_out(vty, "%% Malformed VTEP IP address\n");
2233 return CMD_WARNING;
2234 }
2235
2236 zvrf = vrf_info_lookup(VRF_DEFAULT);
2237 zebra_vxlan_print_neigh_vni_vtep(vty, zvrf, vni, vtep_ip, uj);
2238 return CMD_SUCCESS;
2239 }
2240
2241 /* policy routing contexts */
2242 DEFUN (show_pbr_ipset,
2243 show_pbr_ipset_cmd,
2244 "show pbr ipset [WORD]",
2245 SHOW_STR
2246 "Policy-Based Routing\n"
2247 "IPset Context information\n"
2248 "IPset Name information\n")
2249 {
2250 int idx = 0;
2251 int found = 0;
2252 found = argv_find(argv, argc, "WORD", &idx);
2253 if (!found)
2254 zebra_pbr_show_ipset_list(vty, NULL);
2255 else
2256 zebra_pbr_show_ipset_list(vty, argv[idx]->arg);
2257 return CMD_SUCCESS;
2258 }
2259
2260 /* policy routing contexts */
2261 DEFUN (show_pbr_iptable,
2262 show_pbr_iptable_cmd,
2263 "show pbr iptable [WORD]",
2264 SHOW_STR
2265 "Policy-Based Routing\n"
2266 "IPtable Context information\n"
2267 "IPtable Name information\n")
2268 {
2269 int idx = 0;
2270 int found = 0;
2271
2272 found = argv_find(argv, argc, "WORD", &idx);
2273 if (!found)
2274 zebra_pbr_show_iptable(vty, NULL);
2275 else
2276 zebra_pbr_show_iptable(vty, argv[idx]->arg);
2277 return CMD_SUCCESS;
2278 }
2279
2280 DEFPY (clear_evpn_dup_addr,
2281 clear_evpn_dup_addr_cmd,
2282 "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>]>",
2283 CLEAR_STR
2284 "EVPN\n"
2285 "Duplicate address \n"
2286 "VxLAN Network Identifier\n"
2287 "VNI number\n"
2288 "All VNIs\n"
2289 "MAC\n"
2290 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2291 "IP\n"
2292 "IPv4 address\n"
2293 "IPv6 address\n")
2294 {
2295 struct zebra_vrf *zvrf;
2296 vni_t vni = 0;
2297 struct ipaddr host_ip = {.ipa_type = IPADDR_NONE };
2298 struct ethaddr mac_addr;
2299
2300 zvrf = vrf_info_lookup(VRF_DEFAULT);
2301 if (vni_val) {
2302 vni = strtoul(vni_val, NULL, 10);
2303
2304 if (mac_val) {
2305 prefix_str2mac(mac_val, &mac_addr);
2306 zebra_vxlan_clear_dup_detect_vni_mac(vty, zvrf, vni,
2307 &mac_addr);
2308 } else if (ip) {
2309 if (sockunion_family(ip) == AF_INET) {
2310 host_ip.ipa_type = IPADDR_V4;
2311 host_ip.ipaddr_v4.s_addr = sockunion2ip(ip);
2312 } else {
2313 host_ip.ipa_type = IPADDR_V6;
2314 memcpy(&host_ip.ipaddr_v6, &ip->sin6.sin6_addr,
2315 sizeof(struct in6_addr));
2316 }
2317 zebra_vxlan_clear_dup_detect_vni_ip(vty, zvrf, vni,
2318 &host_ip);
2319 } else
2320 zebra_vxlan_clear_dup_detect_vni(vty, zvrf, vni);
2321
2322 } else {
2323 zebra_vxlan_clear_dup_detect_vni_all(vty, zvrf);
2324 }
2325
2326 return CMD_SUCCESS;
2327 }
2328
2329 /* Static ip route configuration write function. */
2330 static int zebra_ip_config(struct vty *vty)
2331 {
2332 int write = 0;
2333
2334 write += zebra_import_table_config(vty);
2335
2336 return write;
2337 }
2338
2339 DEFUN (ip_zebra_import_table_distance,
2340 ip_zebra_import_table_distance_cmd,
2341 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
2342 IP_STR
2343 "import routes from non-main kernel table\n"
2344 "kernel routing table id\n"
2345 "Distance for imported routes\n"
2346 "Default distance value\n"
2347 "route-map for filtering\n"
2348 "route-map name\n")
2349 {
2350 uint32_t table_id = 0;
2351
2352 table_id = strtoul(argv[2]->arg, NULL, 10);
2353 int distance = ZEBRA_TABLE_DISTANCE_DEFAULT;
2354 char *rmap =
2355 strmatch(argv[argc - 2]->text, "route-map")
2356 ? XSTRDUP(MTYPE_ROUTE_MAP_NAME, argv[argc - 1]->arg)
2357 : NULL;
2358 int ret;
2359
2360 if (argc == 7 || (argc == 5 && !rmap))
2361 distance = strtoul(argv[4]->arg, NULL, 10);
2362
2363 if (!is_zebra_valid_kernel_table(table_id)) {
2364 vty_out(vty,
2365 "Invalid routing table ID, %d. Must be in range 1-252\n",
2366 table_id);
2367 if (rmap)
2368 XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
2369 return CMD_WARNING;
2370 }
2371
2372 if (is_zebra_main_routing_table(table_id)) {
2373 vty_out(vty,
2374 "Invalid routing table ID, %d. Must be non-default table\n",
2375 table_id);
2376 if (rmap)
2377 XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
2378 return CMD_WARNING;
2379 }
2380
2381 ret = zebra_import_table(AFI_IP, table_id, distance, rmap, 1);
2382 if (rmap)
2383 XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
2384
2385 return ret;
2386 }
2387
2388 DEFUN_HIDDEN (zebra_packet_process,
2389 zebra_packet_process_cmd,
2390 "zebra zapi-packets (1-10000)",
2391 ZEBRA_STR
2392 "Zapi Protocol\n"
2393 "Number of packets to process before relinquishing thread\n")
2394 {
2395 uint32_t packets = strtoul(argv[2]->arg, NULL, 10);
2396
2397 atomic_store_explicit(&zebrad.packets_to_process, packets,
2398 memory_order_relaxed);
2399
2400 return CMD_SUCCESS;
2401 }
2402
2403 DEFUN_HIDDEN (no_zebra_packet_process,
2404 no_zebra_packet_process_cmd,
2405 "no zebra zapi-packets [(1-10000)]",
2406 NO_STR
2407 ZEBRA_STR
2408 "Zapi Protocol\n"
2409 "Number of packets to process before relinquishing thread\n")
2410 {
2411 atomic_store_explicit(&zebrad.packets_to_process,
2412 ZEBRA_ZAPI_PACKETS_TO_PROCESS,
2413 memory_order_relaxed);
2414
2415 return CMD_SUCCESS;
2416 }
2417
2418 DEFUN_HIDDEN (zebra_workqueue_timer,
2419 zebra_workqueue_timer_cmd,
2420 "zebra work-queue (0-10000)",
2421 ZEBRA_STR
2422 "Work Queue\n"
2423 "Time in milliseconds\n")
2424 {
2425 uint32_t timer = strtoul(argv[2]->arg, NULL, 10);
2426 zebrad.ribq->spec.hold = timer;
2427
2428 return CMD_SUCCESS;
2429 }
2430
2431 DEFUN_HIDDEN (no_zebra_workqueue_timer,
2432 no_zebra_workqueue_timer_cmd,
2433 "no zebra work-queue [(0-10000)]",
2434 NO_STR
2435 ZEBRA_STR
2436 "Work Queue\n"
2437 "Time in milliseconds\n")
2438 {
2439 zebrad.ribq->spec.hold = ZEBRA_RIB_PROCESS_HOLD_TIME;
2440
2441 return CMD_SUCCESS;
2442 }
2443
2444 DEFUN (no_ip_zebra_import_table,
2445 no_ip_zebra_import_table_cmd,
2446 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
2447 NO_STR
2448 IP_STR
2449 "import routes from non-main kernel table\n"
2450 "kernel routing table id\n"
2451 "Distance for imported routes\n"
2452 "Default distance value\n"
2453 "route-map for filtering\n"
2454 "route-map name\n")
2455 {
2456 uint32_t table_id = 0;
2457 table_id = strtoul(argv[3]->arg, NULL, 10);
2458
2459 if (!is_zebra_valid_kernel_table(table_id)) {
2460 vty_out(vty,
2461 "Invalid routing table ID. Must be in range 1-252\n");
2462 return CMD_WARNING;
2463 }
2464
2465 if (is_zebra_main_routing_table(table_id)) {
2466 vty_out(vty,
2467 "Invalid routing table ID, %d. Must be non-default table\n",
2468 table_id);
2469 return CMD_WARNING;
2470 }
2471
2472 if (!is_zebra_import_table_enabled(AFI_IP, table_id))
2473 return CMD_SUCCESS;
2474
2475 return (zebra_import_table(AFI_IP, table_id, 0, NULL, 0));
2476 }
2477
2478 static int config_write_protocol(struct vty *vty)
2479 {
2480 if (allow_delete)
2481 vty_out(vty, "allow-external-route-update\n");
2482
2483 if (zebra_rnh_ip_default_route)
2484 vty_out(vty, "ip nht resolve-via-default\n");
2485
2486 if (zebra_rnh_ipv6_default_route)
2487 vty_out(vty, "ipv6 nht resolve-via-default\n");
2488
2489 if (zebrad.ribq->spec.hold != ZEBRA_RIB_PROCESS_HOLD_TIME)
2490 vty_out(vty, "zebra work-queue %u\n", zebrad.ribq->spec.hold);
2491
2492 if (zebrad.packets_to_process != ZEBRA_ZAPI_PACKETS_TO_PROCESS)
2493 vty_out(vty, "zebra zapi-packets %u\n",
2494 zebrad.packets_to_process);
2495
2496 enum multicast_mode ipv4_multicast_mode = multicast_mode_ipv4_get();
2497
2498 if (ipv4_multicast_mode != MCAST_NO_CONFIG)
2499 vty_out(vty, "ip multicast rpf-lookup-mode %s\n",
2500 ipv4_multicast_mode == MCAST_URIB_ONLY
2501 ? "urib-only"
2502 : ipv4_multicast_mode == MCAST_MRIB_ONLY
2503 ? "mrib-only"
2504 : ipv4_multicast_mode
2505 == MCAST_MIX_MRIB_FIRST
2506 ? "mrib-then-urib"
2507 : ipv4_multicast_mode
2508 == MCAST_MIX_DISTANCE
2509 ? "lower-distance"
2510 : "longer-prefix");
2511 return 1;
2512 }
2513
2514 #ifdef HAVE_NETLINK
2515 /* Display default rtm_table for all clients. */
2516 DEFUN (show_table,
2517 show_table_cmd,
2518 "show table",
2519 SHOW_STR
2520 "default routing table to use for all clients\n")
2521 {
2522 vty_out(vty, "table %d\n", zebrad.rtm_table_default);
2523 return CMD_SUCCESS;
2524 }
2525
2526 DEFUN (config_table,
2527 config_table_cmd,
2528 "table TABLENO",
2529 "Configure target kernel routing table\n"
2530 "TABLE integer\n")
2531 {
2532 zebrad.rtm_table_default = strtol(argv[1]->arg, (char **)0, 10);
2533 return CMD_SUCCESS;
2534 }
2535
2536 DEFUN (no_config_table,
2537 no_config_table_cmd,
2538 "no table [TABLENO]",
2539 NO_STR
2540 "Configure target kernel routing table\n"
2541 "TABLE integer\n")
2542 {
2543 zebrad.rtm_table_default = 0;
2544 return CMD_SUCCESS;
2545 }
2546 #endif
2547
2548 DEFUN (show_zebra,
2549 show_zebra_cmd,
2550 "show zebra",
2551 SHOW_STR
2552 ZEBRA_STR)
2553 {
2554 struct vrf *vrf;
2555
2556 vty_out(vty,
2557 " Route Route Neighbor LSP LSP\n");
2558 vty_out(vty,
2559 "VRF Installs Removals Updates Installs Removals\n");
2560
2561 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
2562 struct zebra_vrf *zvrf = vrf->info;
2563
2564 vty_out(vty, "%-25s %10" PRIu64 " %10" PRIu64 " %10" PRIu64
2565 " %10" PRIu64 " %10" PRIu64 "\n",
2566 vrf->name, zvrf->installs, zvrf->removals,
2567 zvrf->neigh_updates, zvrf->lsp_installs,
2568 zvrf->lsp_removals);
2569 }
2570
2571 return CMD_SUCCESS;
2572 }
2573
2574 DEFUN (ip_forwarding,
2575 ip_forwarding_cmd,
2576 "ip forwarding",
2577 IP_STR
2578 "Turn on IP forwarding\n")
2579 {
2580 int ret;
2581
2582 ret = ipforward();
2583 if (ret == 0)
2584 ret = ipforward_on();
2585
2586 if (ret == 0) {
2587 vty_out(vty, "Can't turn on IP forwarding\n");
2588 return CMD_WARNING_CONFIG_FAILED;
2589 }
2590
2591 return CMD_SUCCESS;
2592 }
2593
2594 DEFUN (no_ip_forwarding,
2595 no_ip_forwarding_cmd,
2596 "no ip forwarding",
2597 NO_STR
2598 IP_STR
2599 "Turn off IP forwarding\n")
2600 {
2601 int ret;
2602
2603 ret = ipforward();
2604 if (ret != 0)
2605 ret = ipforward_off();
2606
2607 if (ret != 0) {
2608 vty_out(vty, "Can't turn off IP forwarding\n");
2609 return CMD_WARNING_CONFIG_FAILED;
2610 }
2611
2612 return CMD_SUCCESS;
2613 }
2614
2615 /* Only display ip forwarding is enabled or not. */
2616 DEFUN (show_ip_forwarding,
2617 show_ip_forwarding_cmd,
2618 "show ip forwarding",
2619 SHOW_STR
2620 IP_STR
2621 "IP forwarding status\n")
2622 {
2623 int ret;
2624
2625 ret = ipforward();
2626
2627 if (ret == 0)
2628 vty_out(vty, "IP forwarding is off\n");
2629 else
2630 vty_out(vty, "IP forwarding is on\n");
2631 return CMD_SUCCESS;
2632 }
2633
2634 /* Only display ipv6 forwarding is enabled or not. */
2635 DEFUN (show_ipv6_forwarding,
2636 show_ipv6_forwarding_cmd,
2637 "show ipv6 forwarding",
2638 SHOW_STR
2639 "IPv6 information\n"
2640 "Forwarding status\n")
2641 {
2642 int ret;
2643
2644 ret = ipforward_ipv6();
2645
2646 switch (ret) {
2647 case -1:
2648 vty_out(vty, "ipv6 forwarding is unknown\n");
2649 break;
2650 case 0:
2651 vty_out(vty, "ipv6 forwarding is %s\n", "off");
2652 break;
2653 case 1:
2654 vty_out(vty, "ipv6 forwarding is %s\n", "on");
2655 break;
2656 default:
2657 vty_out(vty, "ipv6 forwarding is %s\n", "off");
2658 break;
2659 }
2660 return CMD_SUCCESS;
2661 }
2662
2663 DEFUN (ipv6_forwarding,
2664 ipv6_forwarding_cmd,
2665 "ipv6 forwarding",
2666 IPV6_STR
2667 "Turn on IPv6 forwarding\n")
2668 {
2669 int ret;
2670
2671 ret = ipforward_ipv6();
2672 if (ret == 0)
2673 ret = ipforward_ipv6_on();
2674
2675 if (ret == 0) {
2676 vty_out(vty, "Can't turn on IPv6 forwarding\n");
2677 return CMD_WARNING_CONFIG_FAILED;
2678 }
2679
2680 return CMD_SUCCESS;
2681 }
2682
2683 DEFUN (no_ipv6_forwarding,
2684 no_ipv6_forwarding_cmd,
2685 "no ipv6 forwarding",
2686 NO_STR
2687 IPV6_STR
2688 "Turn off IPv6 forwarding\n")
2689 {
2690 int ret;
2691
2692 ret = ipforward_ipv6();
2693 if (ret != 0)
2694 ret = ipforward_ipv6_off();
2695
2696 if (ret != 0) {
2697 vty_out(vty, "Can't turn off IPv6 forwarding\n");
2698 return CMD_WARNING_CONFIG_FAILED;
2699 }
2700
2701 return CMD_SUCCESS;
2702 }
2703
2704 /* Display dataplane info */
2705 DEFUN (show_dataplane,
2706 show_dataplane_cmd,
2707 "show zebra dplane [detailed]",
2708 SHOW_STR
2709 ZEBRA_STR
2710 "Zebra dataplane information\n"
2711 "Detailed output\n")
2712 {
2713 int idx = 0;
2714 bool detailed = false;
2715
2716 if (argv_find(argv, argc, "detailed", &idx))
2717 detailed = true;
2718
2719 return dplane_show_helper(vty, detailed);
2720 }
2721
2722 /* Display dataplane providers info */
2723 DEFUN (show_dataplane_providers,
2724 show_dataplane_providers_cmd,
2725 "show zebra dplane providers [detailed]",
2726 SHOW_STR
2727 ZEBRA_STR
2728 "Zebra dataplane information\n"
2729 "Zebra dataplane provider information\n"
2730 "Detailed output\n")
2731 {
2732 int idx = 0;
2733 bool detailed = false;
2734
2735 if (argv_find(argv, argc, "detailed", &idx))
2736 detailed = true;
2737
2738 return dplane_show_provs_helper(vty, detailed);
2739 }
2740
2741 /* Configure dataplane incoming queue limit */
2742 DEFUN (zebra_dplane_queue_limit,
2743 zebra_dplane_queue_limit_cmd,
2744 "zebra dplane limit (0-10000)",
2745 ZEBRA_STR
2746 "Zebra dataplane\n"
2747 "Limit incoming queued updates\n"
2748 "Number of queued updates\n")
2749 {
2750 uint32_t limit = 0;
2751
2752 limit = strtoul(argv[3]->arg, NULL, 10);
2753
2754 dplane_set_in_queue_limit(limit, true);
2755
2756 return CMD_SUCCESS;
2757 }
2758
2759 /* Reset dataplane queue limit to default value */
2760 DEFUN (no_zebra_dplane_queue_limit,
2761 no_zebra_dplane_queue_limit_cmd,
2762 "no zebra dplane limit [(0-10000)]",
2763 NO_STR
2764 ZEBRA_STR
2765 "Zebra dataplane\n"
2766 "Limit incoming queued updates\n"
2767 "Number of queued updates\n")
2768 {
2769 dplane_set_in_queue_limit(0, false);
2770
2771 return CMD_SUCCESS;
2772 }
2773
2774 /* Table configuration write function. */
2775 static int config_write_table(struct vty *vty)
2776 {
2777 if (zebrad.rtm_table_default)
2778 vty_out(vty, "table %d\n", zebrad.rtm_table_default);
2779 return 0;
2780 }
2781
2782 /* IPForwarding configuration write function. */
2783 static int config_write_forwarding(struct vty *vty)
2784 {
2785 /* FIXME: Find better place for that. */
2786 router_id_write(vty);
2787
2788 if (!ipforward())
2789 vty_out(vty, "no ip forwarding\n");
2790 if (!ipforward_ipv6())
2791 vty_out(vty, "no ipv6 forwarding\n");
2792 vty_out(vty, "!\n");
2793 return 0;
2794 }
2795
2796 /* IP node for static routes. */
2797 static struct cmd_node ip_node = {IP_NODE, "", 1};
2798 static struct cmd_node protocol_node = {PROTOCOL_NODE, "", 1};
2799 /* table node for routing tables. */
2800 static struct cmd_node table_node = {TABLE_NODE,
2801 "", /* This node has no interface. */
2802 1};
2803 static struct cmd_node forwarding_node = {FORWARDING_NODE,
2804 "", /* This node has no interface. */
2805 1};
2806
2807 /* Route VTY. */
2808 void zebra_vty_init(void)
2809 {
2810 /* Install configuration write function. */
2811 install_node(&table_node, config_write_table);
2812 install_node(&forwarding_node, config_write_forwarding);
2813
2814 install_element(VIEW_NODE, &show_ip_forwarding_cmd);
2815 install_element(CONFIG_NODE, &ip_forwarding_cmd);
2816 install_element(CONFIG_NODE, &no_ip_forwarding_cmd);
2817 install_element(ENABLE_NODE, &show_zebra_cmd);
2818
2819 #ifdef HAVE_NETLINK
2820 install_element(VIEW_NODE, &show_table_cmd);
2821 install_element(CONFIG_NODE, &config_table_cmd);
2822 install_element(CONFIG_NODE, &no_config_table_cmd);
2823 #endif /* HAVE_NETLINK */
2824
2825 install_element(VIEW_NODE, &show_ipv6_forwarding_cmd);
2826 install_element(CONFIG_NODE, &ipv6_forwarding_cmd);
2827 install_element(CONFIG_NODE, &no_ipv6_forwarding_cmd);
2828
2829 /* Route-map */
2830 zebra_route_map_init();
2831
2832 install_node(&ip_node, zebra_ip_config);
2833 install_node(&protocol_node, config_write_protocol);
2834
2835 install_element(CONFIG_NODE, &allow_external_route_update_cmd);
2836 install_element(CONFIG_NODE, &no_allow_external_route_update_cmd);
2837
2838 install_element(CONFIG_NODE, &ip_multicast_mode_cmd);
2839 install_element(CONFIG_NODE, &no_ip_multicast_mode_cmd);
2840
2841 install_element(CONFIG_NODE, &ip_zebra_import_table_distance_cmd);
2842 install_element(CONFIG_NODE, &no_ip_zebra_import_table_cmd);
2843 install_element(CONFIG_NODE, &zebra_workqueue_timer_cmd);
2844 install_element(CONFIG_NODE, &no_zebra_workqueue_timer_cmd);
2845 install_element(CONFIG_NODE, &zebra_packet_process_cmd);
2846 install_element(CONFIG_NODE, &no_zebra_packet_process_cmd);
2847
2848 install_element(VIEW_NODE, &show_vrf_cmd);
2849 install_element(VIEW_NODE, &show_vrf_vni_cmd);
2850 install_element(VIEW_NODE, &show_route_cmd);
2851 install_element(VIEW_NODE, &show_route_table_cmd);
2852 if (vrf_is_backend_netns())
2853 install_element(VIEW_NODE, &show_route_table_vrf_cmd);
2854 install_element(VIEW_NODE, &show_route_detail_cmd);
2855 install_element(VIEW_NODE, &show_route_summary_cmd);
2856 install_element(VIEW_NODE, &show_ip_nht_cmd);
2857 install_element(VIEW_NODE, &show_ip_nht_vrf_all_cmd);
2858 install_element(VIEW_NODE, &show_ipv6_nht_cmd);
2859 install_element(VIEW_NODE, &show_ipv6_nht_vrf_all_cmd);
2860
2861 install_element(VIEW_NODE, &show_ip_rpf_cmd);
2862 install_element(VIEW_NODE, &show_ip_rpf_addr_cmd);
2863
2864 install_element(CONFIG_NODE, &ip_nht_default_route_cmd);
2865 install_element(CONFIG_NODE, &no_ip_nht_default_route_cmd);
2866 install_element(CONFIG_NODE, &ipv6_nht_default_route_cmd);
2867 install_element(CONFIG_NODE, &no_ipv6_nht_default_route_cmd);
2868 install_element(VRF_NODE, &ip_nht_default_route_cmd);
2869 install_element(VRF_NODE, &no_ip_nht_default_route_cmd);
2870 install_element(VRF_NODE, &ipv6_nht_default_route_cmd);
2871 install_element(VRF_NODE, &no_ipv6_nht_default_route_cmd);
2872 install_element(VIEW_NODE, &show_ipv6_mroute_cmd);
2873
2874 /* Commands for VRF */
2875 install_element(VIEW_NODE, &show_ipv6_mroute_vrf_all_cmd);
2876
2877 install_element(VIEW_NODE, &show_evpn_global_cmd);
2878 install_element(VIEW_NODE, &show_evpn_vni_cmd);
2879 install_element(VIEW_NODE, &show_evpn_vni_vni_cmd);
2880 install_element(VIEW_NODE, &show_evpn_rmac_vni_mac_cmd);
2881 install_element(VIEW_NODE, &show_evpn_rmac_vni_cmd);
2882 install_element(VIEW_NODE, &show_evpn_rmac_vni_all_cmd);
2883 install_element(VIEW_NODE, &show_evpn_nh_vni_ip_cmd);
2884 install_element(VIEW_NODE, &show_evpn_nh_vni_cmd);
2885 install_element(VIEW_NODE, &show_evpn_nh_vni_all_cmd);
2886 install_element(VIEW_NODE, &show_evpn_mac_vni_cmd);
2887 install_element(VIEW_NODE, &show_evpn_mac_vni_all_cmd);
2888 install_element(VIEW_NODE, &show_evpn_mac_vni_all_vtep_cmd);
2889 install_element(VIEW_NODE, &show_evpn_mac_vni_mac_cmd);
2890 install_element(VIEW_NODE, &show_evpn_mac_vni_vtep_cmd);
2891 install_element(VIEW_NODE, &show_evpn_mac_vni_dad_cmd);
2892 install_element(VIEW_NODE, &show_evpn_mac_vni_all_dad_cmd);
2893 install_element(VIEW_NODE, &show_evpn_neigh_vni_cmd);
2894 install_element(VIEW_NODE, &show_evpn_neigh_vni_all_cmd);
2895 install_element(VIEW_NODE, &show_evpn_neigh_vni_neigh_cmd);
2896 install_element(VIEW_NODE, &show_evpn_neigh_vni_vtep_cmd);
2897 install_element(VIEW_NODE, &show_evpn_neigh_vni_dad_cmd);
2898 install_element(VIEW_NODE, &show_evpn_neigh_vni_all_dad_cmd);
2899 install_element(ENABLE_NODE, &clear_evpn_dup_addr_cmd);
2900
2901 install_element(VIEW_NODE, &show_pbr_ipset_cmd);
2902 install_element(VIEW_NODE, &show_pbr_iptable_cmd);
2903
2904 install_element(CONFIG_NODE, &default_vrf_vni_mapping_cmd);
2905 install_element(CONFIG_NODE, &no_default_vrf_vni_mapping_cmd);
2906 install_element(VRF_NODE, &vrf_vni_mapping_cmd);
2907 install_element(VRF_NODE, &no_vrf_vni_mapping_cmd);
2908
2909 install_element(VIEW_NODE, &show_dataplane_cmd);
2910 install_element(VIEW_NODE, &show_dataplane_providers_cmd);
2911 install_element(CONFIG_NODE, &zebra_dplane_queue_limit_cmd);
2912 install_element(CONFIG_NODE, &no_zebra_dplane_queue_limit_cmd);
2913 }