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