]> git.proxmox.com Git - mirror_frr.git/blame - zebra/zebra_vty.c
zebra: dup addr detect operation commands
[mirror_frr.git] / zebra / zebra_vty.c
CommitLineData
718e3744 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 *
896014f4
DL
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
718e3744 19 */
20
21#include <zebra.h>
22
7514fb77 23#include "memory.h"
4a1ab8e4 24#include "zebra_memory.h"
718e3744 25#include "if.h"
26#include "prefix.h"
27#include "command.h"
28#include "table.h"
29#include "rib.h"
fb018d25 30#include "nexthop.h"
b72ede27 31#include "vrf.h"
4060008b 32#include "linklist.h"
7758e3f3 33#include "mpls.h"
4a1ab8e4 34#include "routemap.h"
05737783 35#include "srcdest_table.h"
cec2e17d 36#include "vxlan.h"
718e3744 37
89272910 38#include "zebra/zebra_router.h"
a1ac18c4 39#include "zebra/zserv.h"
7c551956 40#include "zebra/zebra_vrf.h"
7758e3f3 41#include "zebra/zebra_mpls.h"
fb018d25 42#include "zebra/zebra_rnh.h"
7a4bb9c5 43#include "zebra/redistribute.h"
6baf7bb8 44#include "zebra/zebra_routemap.h"
1d666fcb 45#include "lib/json.h"
cec2e17d 46#include "zebra/zebra_vxlan.h"
ab59f4f7 47#ifndef VTYSH_EXTRACT_PL
00685a85 48#include "zebra/zebra_vty_clippy.c"
ab59f4f7 49#endif
3a30f50f 50#include "zebra/zserv.h"
c0d136ae
DS
51#include "zebra/router-id.h"
52#include "zebra/ipforward.h"
b7cfce93 53#include "zebra/zebra_vxlan_private.h"
586f4ccf 54#include "zebra/zebra_pbr.h"
6baf7bb8
DS
55
56extern int allow_delete;
a1ac18c4 57
d62a17ae 58static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi,
9f049418 59 safi_t safi, bool use_fib, bool use_json,
ecffa493
RW
60 route_tag_t tag,
61 const struct prefix *longer_prefix_p,
d62a17ae 62 bool supernets_only, int type,
d7c0a89a 63 unsigned short ospf_instance_id);
d62a17ae 64static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn,
65 int mcast);
5ce91022
RW
66static void vty_show_ip_route_summary(struct vty *vty,
67 struct route_table *table);
68static void vty_show_ip_route_summary_prefix(struct vty *vty,
69 struct route_table *table);
b78a80d7 70
4623d897
DL
71DEFUN (ip_multicast_mode,
72 ip_multicast_mode_cmd,
6147e2c6 73 "ip multicast rpf-lookup-mode <urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>",
4623d897
DL
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{
d62a17ae 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 }
4623d897 99
d62a17ae 100 return CMD_SUCCESS;
4623d897
DL
101}
102
103DEFUN (no_ip_multicast_mode,
104 no_ip_multicast_mode_cmd,
b62ecea5 105 "no ip multicast rpf-lookup-mode [<urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>]",
4623d897
DL
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{
d62a17ae 116 multicast_mode_ipv4_set(MCAST_NO_CONFIG);
117 return CMD_SUCCESS;
4623d897
DL
118}
119
4623d897 120
b78a80d7
EM
121DEFUN (show_ip_rpf,
122 show_ip_rpf_cmd,
acb25e73 123 "show ip rpf [json]",
b78a80d7
EM
124 SHOW_STR
125 IP_STR
acb25e73
DW
126 "Display RPF information for multicast source\n"
127 JSON_STR)
b78a80d7 128{
9f049418 129 bool uj = use_json(argc, argv);
d62a17ae 130 return do_show_ip_route(vty, VRF_DEFAULT_NAME, AFI_IP, SAFI_MULTICAST,
fba31af2 131 false, uj, 0, NULL, false, 0, 0);
b78a80d7
EM
132}
133
65dd94cf
DL
134DEFUN (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{
d62a17ae 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
8f527c5e 164/* New RIB. Detailed information for IPv4 route. */
d62a17ae 165static 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
a2addae8 173 RNODE_FOREACH_RE (rn, re) {
d62a17ae 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);
0efb5e9b 190 if (re->tag) {
8526b842 191 vty_out(vty, ", tag %u", re->tag);
0efb5e9b
DS
192#if defined(SUPPORT_REALMS)
193 if (re->tag > 0 && re->tag <= 255)
194 vty_out(vty, "(realm)");
195#endif
196 }
d62a17ae 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");
d62a17ae 205 vty_out(vty, "\n");
206
14a481d9
DS
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)
996c9314
LB
217 vty_out(vty, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min,
218 tm->tm_sec);
14a481d9 219 else if (uptime < ONE_WEEK_SECOND)
996c9314
LB
220 vty_out(vty, "%dd%02dh%02dm", tm->tm_yday, tm->tm_hour,
221 tm->tm_min);
14a481d9
DS
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");
d62a17ae 227
7ee30f28 228 for (ALL_NEXTHOPS(re->ng, nexthop)) {
d62a17ae 229 char addrstr[32];
230
231 vty_out(vty, " %c%s",
232 CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)
996c9314
LB
233 ? CHECK_FLAG(nexthop->flags,
234 NEXTHOP_FLAG_DUPLICATE)
235 ? ' '
236 : '*'
d62a17ae 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",
4a7371e9
DS
247 ifindex2ifname(
248 nexthop->ifindex,
249 nexthop->vrf_id));
d62a17ae 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",
4a7371e9
DS
258 ifindex2ifname(
259 nexthop->ifindex,
260 nexthop->vrf_id));
d62a17ae 261 break;
262 case NEXTHOP_TYPE_IFINDEX:
263 vty_out(vty, " directly connected, %s",
264 ifindex2ifname(nexthop->ifindex,
4a7371e9 265 nexthop->vrf_id));
d62a17ae 266 break;
267 case NEXTHOP_TYPE_BLACKHOLE:
a8309422
DL
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:
60466a63
QY
274 vty_out(vty,
275 " (ICMP admin-prohibited)");
a8309422
DL
276 break;
277 case BLACKHOLE_NULL:
278 vty_out(vty, " (blackhole)");
279 break;
280 case BLACKHOLE_UNSPEC:
281 break;
282 }
d62a17ae 283 break;
284 default:
285 break;
286 }
2793a098 287
fc132690 288 if ((re->vrf_id != nexthop->vrf_id)
bbde7a0f 289 && (nexthop->type != NEXTHOP_TYPE_BLACKHOLE)) {
2793a098 290 struct vrf *vrf =
4a7371e9 291 vrf_lookup_by_id(nexthop->vrf_id);
2793a098 292
4c66767c
DS
293 if (vrf)
294 vty_out(vty, "(vrf %s)", vrf->name);
295 else
0437e105 296 vty_out(vty, "(vrf UNKNOWN)");
2793a098
DS
297 }
298
eaf5150f
DS
299 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE))
300 vty_out(vty, " (duplicate nexthop removed)");
301
d62a17ae 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
1994ae60
JB
337 if (re->nexthop_mtu)
338 vty_out(vty, ", mtu %u", re->nexthop_mtu);
339
d62a17ae 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
356static 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;
14a481d9
DS
366 time_t uptime;
367 struct tm *tm;
368
369 uptime = time(NULL);
370 uptime -= re->uptime;
371 tm = gmtime(&uptime);
d62a17ae 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
925c2f88 392 if (re->type != ZEBRA_ROUTE_CONNECT) {
d62a17ae 393 json_object_int_add(json_route, "distance",
394 re->distance);
395 json_object_int_add(json_route, "metric", re->metric);
396 }
397
96d71e38
AD
398 if (re->tag)
399 json_object_int_add(json_route, "tag", re->tag);
400
f03098f9
DS
401 json_object_int_add(json_route, "internalStatus",
402 re->status);
403 json_object_int_add(json_route, "internalFlags",
404 re->flags);
14a481d9 405 if (uptime < ONE_DAY_SECOND)
996c9314
LB
406 sprintf(buf, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min,
407 tm->tm_sec);
14a481d9 408 else if (uptime < ONE_WEEK_SECOND)
996c9314
LB
409 sprintf(buf, "%dd%02dh%02dm", tm->tm_yday, tm->tm_hour,
410 tm->tm_min);
14a481d9
DS
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);
d62a17ae 417
7ee30f28 418 for (ALL_NEXTHOPS(re->ng, nexthop)) {
d62a17ae 419 json_nexthop = json_object_new_object();
420
f03098f9
DS
421 json_object_int_add(json_nexthop, "flags",
422 nexthop->flags);
423
eaf5150f
DS
424 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE))
425 json_object_boolean_true_add(json_nexthop,
426 "duplicate");
427
d62a17ae 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",
4a7371e9
DS
447 ifindex2ifname(
448 nexthop->ifindex,
449 nexthop->vrf_id));
d62a17ae 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",
4a7371e9
DS
467 ifindex2ifname(
468 nexthop->ifindex,
469 nexthop->vrf_id));
d62a17ae 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,
4a7371e9 482 nexthop->vrf_id));
d62a17ae 483 break;
484 case NEXTHOP_TYPE_BLACKHOLE:
485 json_object_boolean_true_add(json_nexthop,
a8309422
DL
486 "unreachable");
487 switch (nexthop->bh_type) {
488 case BLACKHOLE_REJECT:
489 json_object_boolean_true_add(
60466a63 490 json_nexthop, "reject");
a8309422
DL
491 break;
492 case BLACKHOLE_ADMINPROHIB:
493 json_object_boolean_true_add(
60466a63
QY
494 json_nexthop,
495 "admin-prohibited");
a8309422
DL
496 break;
497 case BLACKHOLE_NULL:
498 json_object_boolean_true_add(
60466a63 499 json_nexthop, "blackhole");
a8309422
DL
500 break;
501 case BLACKHOLE_UNSPEC:
502 break;
503 }
d62a17ae 504 break;
505 default:
506 break;
507 }
508
fc132690 509 if ((nexthop->vrf_id != re->vrf_id)
bbde7a0f 510 && (nexthop->type != NEXTHOP_TYPE_BLACKHOLE)) {
2793a098 511 struct vrf *vrf =
4a7371e9 512 vrf_lookup_by_id(nexthop->vrf_id);
2793a098 513
996c9314 514 json_object_string_add(json_nexthop, "vrf",
2793a098
DS
515 vrf->name);
516 }
eaf5150f
DS
517 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE))
518 json_object_boolean_true_add(json_nexthop,
519 "duplicate");
520
d62a17ae 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. */
7ee30f28
DS
588 for (ALL_NEXTHOPS(re->ng, nexthop)) {
589 if (nexthop == re->ng.nexthop) {
d62a17ae 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. */
925c2f88 605 if (re->type != ZEBRA_ROUTE_CONNECT)
8526b842 606 len += vty_out(vty, " [%u/%u]", re->distance,
d62a17ae 607 re->metric);
eaf5150f 608 } else {
d62a17ae 609 vty_out(vty, " %c%*c",
610 CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)
996c9314
LB
611 ? CHECK_FLAG(nexthop->flags,
612 NEXTHOP_FLAG_DUPLICATE)
613 ? ' '
614 : '*'
d62a17ae 615 : ' ',
616 len - 3 + (2 * nexthop_level(nexthop)), ' ');
eaf5150f 617 }
d62a17ae 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,
4a7371e9 626 nexthop->vrf_id));
d62a17ae 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,
4a7371e9 636 nexthop->vrf_id));
d62a17ae 637 break;
638
639 case NEXTHOP_TYPE_IFINDEX:
640 vty_out(vty, " is directly connected, %s",
99b9d960 641 ifindex2ifname(nexthop->ifindex,
4a7371e9 642 nexthop->vrf_id));
d62a17ae 643 break;
644 case NEXTHOP_TYPE_BLACKHOLE:
a8309422
DL
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 }
d62a17ae 659 break;
660 default:
661 break;
662 }
2793a098 663
fc132690 664 if ((nexthop->vrf_id != re->vrf_id)
bbde7a0f 665 && (nexthop->type != NEXTHOP_TYPE_BLACKHOLE)) {
4a7371e9 666 struct vrf *vrf = vrf_lookup_by_id(nexthop->vrf_id);
2793a098 667
4c66767c
DS
668 if (vrf)
669 vty_out(vty, "(vrf %s)", vrf->name);
670 else
0437e105 671 vty_out(vty, "(vrf UNKNOWN)");
2793a098
DS
672 }
673
d62a17ae 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
14a481d9
DS
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);
d62a17ae 722 vty_out(vty, "\n");
723 }
724}
725
96d71e38
AD
726static 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
ae825b8b
DS
749static 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,
9f049418 754 unsigned short ospf_instance_id, bool use_json)
d62a17ae 755{
d62a17ae 756 struct route_node *rn;
757 struct route_entry *re;
758 int first = 1;
ae825b8b 759 rib_dest_t *dest;
d62a17ae 760 json_object *json = NULL;
761 json_object *json_prefix = NULL;
ae825b8b
DS
762 uint32_t addr;
763 char buf[BUFSIZ];
d62a17ae 764
765 if (use_json)
766 json = json_object_new_object();
767
768 /* Show all routes. */
c9591045 769 for (rn = route_top(table); rn; rn = srcdest_route_next(rn)) {
5f7a4718
DS
770 dest = rib_dest_from_rnode(rn);
771
a2addae8 772 RNODE_FOREACH_RE (rn, re) {
996c9314 773 if (use_fib && re != dest->selected_fib)
d62a17ae 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) {
96d71e38 829 prefix2str(&rn->p, buf, sizeof(buf));
d62a17ae 830 json_object_object_add(json, buf, json_prefix);
831 json_prefix = NULL;
832 }
833 }
834
835 if (use_json) {
96d71e38
AD
836 vty_out(vty, "%s\n", json_object_to_json_string_ext(json,
837 JSON_C_TO_STRING_PRETTY));
d62a17ae 838 json_object_free(json);
839 }
ae825b8b
DS
840}
841
842static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi,
9f049418 843 safi_t safi, bool use_fib, bool use_json,
ae825b8b
DS
844 route_tag_t tag,
845 const struct prefix *longer_prefix_p,
846 bool supernets_only, int type,
d7c0a89a 847 unsigned short ospf_instance_id)
ae825b8b
DS
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
882DEFPY (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
89272910 897 t = zebra_router_find_table(zvrf, table, afi, SAFI_UNICAST);
ae825b8b
DS
898 if (t)
899 do_show_route_helper(vty, zvrf, t, afi, false, 0, false, false,
900 0, 0, !!json);
d62a17ae 901
902 return CMD_SUCCESS;
abbda2d4 903}
d511d7f1 904
87d6ac7a
PG
905DEFPY (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)
ec1db588 923 VRF_GET_ID(vrf_id, vrf_name, !!json);
87d6ac7a
PG
924 zvrf = zebra_vrf_lookup_by_id(vrf_id);
925
89272910 926 t = zebra_router_find_table(zvrf, table, afi, SAFI_UNICAST);
87d6ac7a
PG
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
8f527c5e
FL
934DEFUN (show_ip_nht,
935 show_ip_nht_cmd,
9bf96c84 936 "show ip nht [vrf NAME]",
8f527c5e
FL
937 SHOW_STR
938 IP_STR
9bf96c84
DW
939 "IP nexthop tracking table\n"
940 VRF_CMD_HELP_STR)
8f527c5e 941{
d62a17ae 942 int idx_vrf = 4;
943 vrf_id_t vrf_id = VRF_DEFAULT;
12f6fb97 944
d62a17ae 945 if (argc == 5)
ec1db588 946 VRF_GET_ID(vrf_id, argv[idx_vrf]->arg, false);
12f6fb97 947
d62a17ae 948 zebra_print_rnh_table(vrf_id, AF_INET, vty, RNH_NEXTHOP_TYPE);
949 return CMD_SUCCESS;
8f527c5e
FL
950}
951
12f6fb97 952
d511d7f1
DS
953DEFUN (show_ip_nht_vrf_all,
954 show_ip_nht_vrf_all_cmd,
5bebf568 955 "show ip nht vrf all",
d511d7f1
DS
956 SHOW_STR
957 IP_STR
958 "IP nexthop tracking table\n"
959 VRF_ALL_CMD_HELP_STR)
960{
d62a17ae 961 struct vrf *vrf;
962 struct zebra_vrf *zvrf;
d511d7f1 963
a2addae8
RW
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 }
d511d7f1 970
d62a17ae 971 return CMD_SUCCESS;
d511d7f1
DS
972}
973
8f527c5e
FL
974DEFUN (show_ipv6_nht,
975 show_ipv6_nht_cmd,
9bf96c84 976 "show ipv6 nht [vrf NAME]",
8f527c5e 977 SHOW_STR
689e6694 978 IPV6_STR
9bf96c84
DW
979 "IPv6 nexthop tracking table\n"
980 VRF_CMD_HELP_STR)
8f527c5e 981{
d62a17ae 982 int idx_vrf = 4;
983 vrf_id_t vrf_id = VRF_DEFAULT;
12f6fb97 984
d62a17ae 985 if (argc == 5)
ec1db588 986 VRF_GET_ID(vrf_id, argv[idx_vrf]->arg, false);
12f6fb97 987
d62a17ae 988 zebra_print_rnh_table(vrf_id, AF_INET6, vty, RNH_NEXTHOP_TYPE);
989 return CMD_SUCCESS;
8f527c5e
FL
990}
991
12f6fb97 992
d511d7f1
DS
993DEFUN (show_ipv6_nht_vrf_all,
994 show_ipv6_nht_vrf_all_cmd,
5bebf568 995 "show ipv6 nht vrf all",
d511d7f1
DS
996 SHOW_STR
997 IP_STR
998 "IPv6 nexthop tracking table\n"
999 VRF_ALL_CMD_HELP_STR)
1000{
d62a17ae 1001 struct vrf *vrf;
1002 struct zebra_vrf *zvrf;
d511d7f1 1003
a2addae8
RW
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 }
d511d7f1 1010
d62a17ae 1011 return CMD_SUCCESS;
d511d7f1
DS
1012}
1013
8f527c5e
FL
1014DEFUN (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{
214e5c26 1021 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
6d53d7b1 1022
1023 if (!zvrf)
1024 return CMD_WARNING;
1025
214e5c26 1026 if (zebra_rnh_ip_default_route)
1027 return CMD_SUCCESS;
1028
d62a17ae 1029 zebra_rnh_ip_default_route = 1;
214e5c26 1030
6d53d7b1 1031 zebra_evaluate_rnh(zvrf, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
d62a17ae 1032 return CMD_SUCCESS;
8f527c5e
FL
1033}
1034
1035DEFUN (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{
214e5c26 1043 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
6d53d7b1 1044
1045 if (!zvrf)
1046 return CMD_WARNING;
1047
214e5c26 1048 if (!zebra_rnh_ip_default_route)
1049 return CMD_SUCCESS;
1050
d62a17ae 1051 zebra_rnh_ip_default_route = 0;
6d53d7b1 1052 zebra_evaluate_rnh(zvrf, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
d62a17ae 1053 return CMD_SUCCESS;
8f527c5e
FL
1054}
1055
1056DEFUN (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{
214e5c26 1063 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
6d53d7b1 1064
1065 if (!zvrf)
1066 return CMD_WARNING;
1067
214e5c26 1068 if (zebra_rnh_ipv6_default_route)
1069 return CMD_SUCCESS;
1070
d62a17ae 1071 zebra_rnh_ipv6_default_route = 1;
6d53d7b1 1072 zebra_evaluate_rnh(zvrf, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL);
d62a17ae 1073 return CMD_SUCCESS;
8f527c5e
FL
1074}
1075
1076DEFUN (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{
8f527c5e 1084
214e5c26 1085 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
6d53d7b1 1086
1087 if (!zvrf)
1088 return CMD_WARNING;
1089
214e5c26 1090 if (!zebra_rnh_ipv6_default_route)
1091 return CMD_SUCCESS;
1092
d62a17ae 1093 zebra_rnh_ipv6_default_route = 0;
6d53d7b1 1094 zebra_evaluate_rnh(zvrf, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL);
d62a17ae 1095 return CMD_SUCCESS;
8f527c5e
FL
1096}
1097
ecffa493
RW
1098DEFPY (show_route,
1099 show_route_cmd,
1100 "show\
1101 <\
1102 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
a3e13ef3 1103 [{\
ecffa493
RW
1104 tag (1-4294967295)\
1105 |A.B.C.D/M$prefix longer-prefixes\
1106 |supernets-only$supernets_only\
a3e13ef3
RW
1107 }]\
1108 [<\
1109 " FRR_IP_REDIST_STR_ZEBRA "$type_str\
ecffa493 1110 |ospf$type_str (1-65535)$ospf_instance_id\
a3e13ef3 1111 >]\
ecffa493 1112 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
a3e13ef3 1113 [{\
ecffa493
RW
1114 tag (1-4294967295)\
1115 |X:X::X:X/M$prefix longer-prefixes\
a3e13ef3
RW
1116 }]\
1117 [" FRR_IP6_REDIST_STR_ZEBRA "$type_str]\
ecffa493
RW
1118 >\
1119 [json$json]",
8f527c5e
FL
1120 SHOW_STR
1121 IP_STR
87a88962 1122 "IP forwarding table\n"
8f527c5e 1123 "IP routing table\n"
ecffa493 1124 VRF_FULL_CMD_HELP_STR
8f527c5e 1125 "Show only routes with tag\n"
acb25e73
DW
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"
ecffa493
RW
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
acb25e73 1142 JSON_STR)
8f527c5e 1143{
ecffa493 1144 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
d62a17ae 1145 struct vrf *vrf;
d62a17ae 1146 int type = 0;
d62a17ae 1147
ecffa493
RW
1148 if (type_str) {
1149 type = proto_redistnum(afi, type_str);
d62a17ae 1150 if (type < 0) {
1151 vty_out(vty, "Unknown route type\n");
1152 return CMD_WARNING;
1153 }
1154 }
1155
1156 if (vrf_all) {
a2addae8 1157 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
ecffa493
RW
1158 struct zebra_vrf *zvrf;
1159 struct route_table *table;
1160
d62a17ae 1161 if ((zvrf = vrf->info) == NULL
ecffa493 1162 || (table = zvrf->table[afi][SAFI_UNICAST]) == NULL)
d62a17ae 1163 continue;
1164
1165 do_show_ip_route(
ecffa493
RW
1166 vty, zvrf_name(zvrf), afi, SAFI_UNICAST, !!fib,
1167 !!json, tag, prefix_str ? prefix : NULL,
1168 !!supernets_only, type, ospf_instance_id);
d62a17ae 1169 }
1170 } else {
ecffa493
RW
1171 vrf_id_t vrf_id = VRF_DEFAULT;
1172
1173 if (vrf_name)
ec1db588 1174 VRF_GET_ID(vrf_id, vrf_name, !!json);
d62a17ae 1175 vrf = vrf_lookup_by_id(vrf_id);
ecffa493
RW
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);
d62a17ae 1179 }
ecffa493 1180
d62a17ae 1181 return CMD_SUCCESS;
8f527c5e
FL
1182}
1183
5ce91022
RW
1184DEFPY (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 >\
96d71e38
AD
1198 >\
1199 [json$json]",
8f527c5e
FL
1200 SHOW_STR
1201 IP_STR
1202 "IP routing table\n"
5ce91022
RW
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"
96d71e38
AD
1210 "IPv6 prefix\n"
1211 JSON_STR)
8f527c5e 1212{
5ce91022 1213 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
d62a17ae 1214 struct route_table *table;
5ce91022 1215 struct prefix p;
d62a17ae 1216 struct route_node *rn;
d511d7f1 1217
5ce91022
RW
1218 if (address_str)
1219 prefix_str = address_str;
1220 if (str2prefix(prefix_str, &p) < 0) {
1221 vty_out(vty, "%% Malformed address\n");
d62a17ae 1222 return CMD_WARNING;
1223 }
8f527c5e 1224
5ce91022
RW
1225 if (vrf_all) {
1226 struct vrf *vrf;
1227 struct zebra_vrf *zvrf;
8f527c5e 1228
996c9314 1229 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
5ce91022
RW
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
96d71e38
AD
1242 if (json)
1243 vty_show_ip_route_detail_json(vty, rn);
1244 else
1245 vty_show_ip_route_detail(vty, rn, 0);
5ce91022
RW
1246
1247 route_unlock_node(rn);
1248 }
1249 } else {
1250 vrf_id_t vrf_id = VRF_DEFAULT;
1251
1252 if (vrf_name)
ec1db588 1253 VRF_GET_ID(vrf_id, vrf_name, false);
5ce91022
RW
1254
1255 table = zebra_vrf_table(afi, SAFI_UNICAST, vrf_id);
1256 if (!table)
1257 return CMD_SUCCESS;
8f527c5e 1258
5ce91022
RW
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 }
8f527c5e 1269
96d71e38
AD
1270 if (json)
1271 vty_show_ip_route_detail_json(vty, rn);
1272 else
1273 vty_show_ip_route_detail(vty, rn, 0);
5ce91022
RW
1274
1275 route_unlock_node(rn);
1276 }
8f527c5e 1277
d62a17ae 1278 return CMD_SUCCESS;
8f527c5e
FL
1279}
1280
5ce91022
RW
1281DEFPY (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 >",
8f527c5e
FL
1290 SHOW_STR
1291 IP_STR
1292 "IP routing table\n"
5ce91022
RW
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")
8f527c5e 1301{
5ce91022 1302 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
d62a17ae 1303 struct route_table *table;
d62a17ae 1304
5ce91022
RW
1305 if (vrf_all) {
1306 struct vrf *vrf;
1307 struct zebra_vrf *zvrf;
d511d7f1 1308
996c9314 1309 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
5ce91022
RW
1310 if ((zvrf = vrf->info) == NULL
1311 || (table = zvrf->table[afi][SAFI_UNICAST]) == NULL)
1312 continue;
8f527c5e 1313
5ce91022
RW
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;
8f527c5e 1321
5ce91022 1322 if (vrf_name)
ec1db588 1323 VRF_GET_ID(vrf_id, vrf_name, false);
8f527c5e 1324
5ce91022
RW
1325 table = zebra_vrf_table(afi, SAFI_UNICAST, vrf_id);
1326 if (!table)
1327 return CMD_SUCCESS;
8f527c5e 1328
5ce91022
RW
1329 if (prefix)
1330 vty_show_ip_route_summary_prefix(vty, table);
1331 else
1332 vty_show_ip_route_summary(vty, table);
1333 }
8f527c5e 1334
d62a17ae 1335 return CMD_SUCCESS;
8f527c5e
FL
1336}
1337
d62a17ae 1338static void vty_show_ip_route_summary(struct vty *vty,
1339 struct route_table *table)
8f527c5e 1340{
d62a17ae 1341 struct route_node *rn;
1342 struct route_entry *re;
8f527c5e
FL
1343#define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1344#define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
d7c0a89a
QY
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;
d62a17ae 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))
a2addae8 1353 RNODE_FOREACH_RE (rn, re) {
d62a17ae 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",
6ca30e9e 1374 "FIB", zvrf_name(((rib_table_info_t *)route_table_get_info(table))->zvrf));
d62a17ae 1375
1376 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
9d303b37
DL
1377 if ((rib_cnt[i] > 0) || (i == ZEBRA_ROUTE_BGP
1378 && rib_cnt[ZEBRA_ROUTE_IBGP] > 0)) {
d62a17ae 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");
8f527c5e
FL
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 */
d62a17ae 1406static void vty_show_ip_route_summary_prefix(struct vty *vty,
1407 struct route_table *table)
8f527c5e 1408{
d62a17ae 1409 struct route_node *rn;
1410 struct route_entry *re;
1411 struct nexthop *nexthop;
8f527c5e
FL
1412#define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1413#define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
d7c0a89a
QY
1414 uint32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1415 uint32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1416 uint32_t i;
d62a17ae 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))
a2addae8 1422 RNODE_FOREACH_RE (rn, re) {
d62a17ae 1423
1424 /*
1425 * In case of ECMP, count only once.
1426 */
1427 cnt = 0;
7ee30f28 1428 for (nexthop = re->ng.nexthop; (!cnt && nexthop);
d62a17ae 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",
6ca30e9e 1450 zvrf_name(((rib_table_info_t *)route_table_get_info(table))->zvrf));
d62a17ae 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");
9343ce83
DS
1474}
1475
cddf391b
B
1476/*
1477 * Show IPv6 mroute command.Used to dump
1478 * the Multicast routing table.
1479 */
cddf391b
B
1480DEFUN (show_ipv6_mroute,
1481 show_ipv6_mroute_cmd,
9bf96c84 1482 "show ipv6 mroute [vrf NAME]",
cddf391b
B
1483 SHOW_STR
1484 IP_STR
9bf96c84
DW
1485 "IPv6 Multicast routing table\n"
1486 VRF_CMD_HELP_STR)
cddf391b 1487{
d62a17ae 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)
ec1db588 1495 VRF_GET_ID(vrf_id, argv[4]->arg, false);
d62a17ae 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))
a2addae8 1503 RNODE_FOREACH_RE (rn, re) {
d62a17ae 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;
cddf391b
B
1511}
1512
af41b63a
FL
1513DEFUN (show_ipv6_mroute_vrf_all,
1514 show_ipv6_mroute_vrf_all_cmd,
5bebf568 1515 "show ipv6 mroute vrf all",
af41b63a
FL
1516 SHOW_STR
1517 IP_STR
1518 "IPv6 Multicast routing table\n"
1519 VRF_ALL_CMD_HELP_STR)
1520{
d62a17ae 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
a2addae8 1528 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
d62a17ae 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))
a2addae8 1535 RNODE_FOREACH_RE (rn, re) {
d62a17ae 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;
af41b63a
FL
1544}
1545
6baf7bb8
DS
1546DEFUN (allow_external_route_update,
1547 allow_external_route_update_cmd,
1548 "allow-external-route-update",
17d990c1 1549 "Allow FRR routes to be overwritten by external processes\n")
6baf7bb8 1550{
d62a17ae 1551 allow_delete = 1;
6baf7bb8 1552
d62a17ae 1553 return CMD_SUCCESS;
6baf7bb8
DS
1554}
1555
1556DEFUN (no_allow_external_route_update,
1557 no_allow_external_route_update_cmd,
1558 "no allow-external-route-update",
17d990c1
DS
1559 NO_STR
1560 "Allow FRR routes to be overwritten by external processes\n")
6baf7bb8 1561{
d62a17ae 1562 allow_delete = 0;
6baf7bb8 1563
d62a17ae 1564 return CMD_SUCCESS;
6baf7bb8
DS
1565}
1566
12f6fb97
DS
1567/* show vrf */
1568DEFUN (show_vrf,
1569 show_vrf_cmd,
1570 "show vrf",
1571 SHOW_STR
1572 "VRF\n")
1573{
d62a17ae 1574 struct vrf *vrf;
1575 struct zebra_vrf *zvrf;
12f6fb97 1576
b73823ef
PG
1577 if (vrf_is_backend_netns())
1578 vty_out(vty, "netns-based vrfs\n");
1579
a2addae8 1580 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
d62a17ae 1581 if (!(zvrf = vrf->info))
1582 continue;
90ac32c2 1583 if (zvrf_id(zvrf) == VRF_DEFAULT)
d62a17ae 1584 continue;
1585
1586 vty_out(vty, "vrf %s ", zvrf_name(zvrf));
996c9314 1587 if (zvrf_id(zvrf) == VRF_UNKNOWN || !zvrf_is_active(zvrf))
d62a17ae 1588 vty_out(vty, "inactive");
81c9005f 1589 else if (zvrf_ns_name(zvrf))
996c9314
LB
1590 vty_out(vty, "id %u netns %s", zvrf_id(zvrf),
1591 zvrf_ns_name(zvrf));
d62a17ae 1592 else
1593 vty_out(vty, "id %u table %u", zvrf_id(zvrf),
1594 zvrf->table_id);
22bd3e94 1595 if (vrf_is_user_cfged(vrf))
1596 vty_out(vty, " (configured)");
d62a17ae 1597 vty_out(vty, "\n");
1598 }
12f6fb97 1599
d62a17ae 1600 return CMD_SUCCESS;
12f6fb97
DS
1601}
1602
62710e2b 1603DEFUN_HIDDEN (default_vrf_vni_mapping,
e8d26197 1604 default_vrf_vni_mapping_cmd,
c48d9f5f 1605 "vni " CMD_VNI_RANGE "[prefix-routes-only]",
e8d26197 1606 "VNI corresponding to the DEFAULT VRF\n"
c48d9f5f
MK
1607 "VNI-ID\n"
1608 "Prefix routes only \n")
e8d26197
MK
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);
c48d9f5f 1614 int filter = 0;
e8d26197
MK
1615
1616 zvrf = vrf_info_lookup(VRF_DEFAULT);
1617 if (!zvrf)
1618 return CMD_WARNING;
1619
c48d9f5f
MK
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);
e8d26197
MK
1625 if (ret != 0) {
1626 vty_out(vty, "%s\n", err);
1627 return CMD_WARNING;
1628 }
1629
1630 return CMD_SUCCESS;
1631}
1632
62710e2b 1633DEFUN_HIDDEN (no_default_vrf_vni_mapping,
e8d26197
MK
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
c48d9f5f 1649 ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ, 0, 0);
e8d26197
MK
1650 if (ret != 0) {
1651 vty_out(vty, "%s\n", err);
1652 return CMD_WARNING;
1653 }
1654
1655 return CMD_SUCCESS;
1656}
1657
b7cfce93
MK
1658DEFUN (vrf_vni_mapping,
1659 vrf_vni_mapping_cmd,
c48d9f5f 1660 "vni " CMD_VNI_RANGE "[prefix-routes-only]",
e8d26197 1661 "VNI corresponding to tenant VRF\n"
c48d9f5f
MK
1662 "VNI-ID\n"
1663 "prefix-routes-only\n")
b7cfce93
MK
1664{
1665 int ret = 0;
c48d9f5f 1666 int filter = 0;
b7cfce93
MK
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
c48d9f5f
MK
1675 if (argc == 3)
1676 filter = 1;
1677
317f1fe0 1678 /* Mark as having FRR configuration */
1679 vrf_set_user_cfged(vrf);
c48d9f5f
MK
1680 ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ,
1681 filter, 1);
b7cfce93
MK
1682 if (ret != 0) {
1683 vty_out(vty, "%s\n", err);
1684 return CMD_WARNING;
1685 }
1686
1687 return CMD_SUCCESS;
1688}
1689
1690DEFUN (no_vrf_vni_mapping,
1691 no_vrf_vni_mapping_cmd,
cf299714 1692 "no vni " CMD_VNI_RANGE "[prefix-routes-only]",
b7cfce93 1693 NO_STR
e8d26197 1694 "VNI corresponding to tenant VRF\n"
cf299714
MK
1695 "VNI-ID\n"
1696 "prefix-routes-only\n")
b7cfce93
MK
1697{
1698 int ret = 0;
cf299714 1699 int filter = 0;
b7cfce93
MK
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
cf299714
MK
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);
b7cfce93
MK
1713 if (ret != 0) {
1714 vty_out(vty, "%s\n", err);
1715 return CMD_WARNING;
1716 }
1717
22bd3e94 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
b7cfce93
MK
1722 return CMD_SUCCESS;
1723}
1724
1725/* show vrf */
1726DEFUN (show_vrf_vni,
1727 show_vrf_vni_cmd,
35be5542 1728 "show vrf vni [json]",
b7cfce93
MK
1729 SHOW_STR
1730 "VRF\n"
35be5542
MK
1731 "VNI\n"
1732 JSON_STR)
b7cfce93
MK
1733{
1734 struct vrf *vrf;
1735 struct zebra_vrf *zvrf;
35be5542
MK
1736 json_object *json = NULL;
1737 json_object *json_vrfs = NULL;
9f049418 1738 bool uj = use_json(argc, argv);
35be5542
MK
1739
1740 if (uj) {
1741 json = json_object_new_object();
1742 json_vrfs = json_object_new_array();
1743 }
b7cfce93 1744
4cce389e 1745 if (!uj)
996c9314
LB
1746 vty_out(vty, "%-37s %-10s %-20s %-20s %-5s %-18s\n", "VRF",
1747 "VNI", "VxLAN IF", "L3-SVI", "State", "Rmac");
4cce389e 1748
996c9314 1749 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
b7cfce93
MK
1750 zvrf = vrf->info;
1751 if (!zvrf)
1752 continue;
1753
4cce389e 1754 zebra_vxlan_print_vrf_vni(vty, zvrf, json_vrfs);
35be5542
MK
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);
b7cfce93
MK
1762 }
1763
1764 return CMD_SUCCESS;
1765}
1766
4cce389e
MK
1767DEFUN (show_evpn_global,
1768 show_evpn_global_cmd,
1769 "show evpn [json]",
1770 SHOW_STR
1771 "EVPN\n"
1772 JSON_STR)
1773{
9f049418 1774 bool uj = use_json(argc, argv);
4cce389e
MK
1775
1776 zebra_vxlan_print_evpn(vty, uj);
1777 return CMD_SUCCESS;
1778}
1779
cec2e17d 1780DEFUN (show_evpn_vni,
1781 show_evpn_vni_cmd,
cd233079 1782 "show evpn vni [json]",
cec2e17d 1783 SHOW_STR
1784 "EVPN\n"
cd233079 1785 "VxLAN information\n"
bd592158 1786 JSON_STR)
cec2e17d 1787{
d62a17ae 1788 struct zebra_vrf *zvrf;
9f049418 1789 bool uj = use_json(argc, argv);
cec2e17d 1790
d62a17ae 1791 zvrf = vrf_info_lookup(VRF_DEFAULT);
cd233079 1792 zebra_vxlan_print_vnis(vty, zvrf, uj);
d62a17ae 1793 return CMD_SUCCESS;
cec2e17d 1794}
1795
1796DEFUN (show_evpn_vni_vni,
1797 show_evpn_vni_vni_cmd,
cd233079 1798 "show evpn vni " CMD_VNI_RANGE "[json]",
cec2e17d 1799 SHOW_STR
1800 "EVPN\n"
1801 "VxLAN Network Identifier\n"
cd233079 1802 "VNI number\n"
bd592158 1803 JSON_STR)
cec2e17d 1804{
d62a17ae 1805 struct zebra_vrf *zvrf;
1806 vni_t vni;
9f049418 1807 bool uj = use_json(argc, argv);
cec2e17d 1808
d62a17ae 1809 vni = strtoul(argv[3]->arg, NULL, 10);
1810 zvrf = vrf_info_lookup(VRF_DEFAULT);
cd233079 1811 zebra_vxlan_print_vni(vty, zvrf, vni, uj);
d62a17ae 1812 return CMD_SUCCESS;
cec2e17d 1813}
1814
4cce389e
MK
1815DEFUN (show_evpn_rmac_vni_mac,
1816 show_evpn_rmac_vni_mac_cmd,
1817 "show evpn rmac vni " CMD_VNI_RANGE " mac WORD [json]",
9aa741ea
MK
1818 SHOW_STR
1819 "EVPN\n"
1820 "RMAC\n"
4cce389e 1821 "L3 VNI\n"
9aa741ea
MK
1822 "VNI number\n"
1823 "MAC\n"
316f4ca4
MK
1824 "mac-address (e.g. 0a:0a:0a:0a:0a:0a)\n"
1825 JSON_STR)
9aa741ea
MK
1826{
1827 vni_t l3vni = 0;
1828 struct ethaddr mac;
9f049418 1829 bool uj = use_json(argc, argv);
9aa741ea
MK
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 }
316f4ca4 1836 zebra_vxlan_print_specific_rmac_l3vni(vty, l3vni, &mac, uj);
9aa741ea
MK
1837 return CMD_SUCCESS;
1838}
1839
4cce389e
MK
1840DEFUN (show_evpn_rmac_vni,
1841 show_evpn_rmac_vni_cmd,
1842 "show evpn rmac vni " CMD_VNI_RANGE "[json]",
b7cfce93
MK
1843 SHOW_STR
1844 "EVPN\n"
1845 "RMAC\n"
4cce389e 1846 "L3 VNI\n"
b7cfce93
MK
1847 "VNI number\n"
1848 JSON_STR)
1849{
1850 vni_t l3vni = 0;
9f049418 1851 bool uj = use_json(argc, argv);
b7cfce93
MK
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
4cce389e
MK
1859DEFUN (show_evpn_rmac_vni_all,
1860 show_evpn_rmac_vni_all_cmd,
1861 "show evpn rmac vni all [json]",
b7cfce93
MK
1862 SHOW_STR
1863 "EVPN\n"
1864 "RMAC addresses\n"
4cce389e 1865 "L3 VNI\n"
b7cfce93
MK
1866 "All VNIs\n"
1867 JSON_STR)
1868{
9f049418 1869 bool uj = use_json(argc, argv);
b7cfce93
MK
1870
1871 zebra_vxlan_print_rmacs_all_l3vni(vty, uj);
1872
1873 return CMD_SUCCESS;
1874}
1875
4cce389e
MK
1876DEFUN (show_evpn_nh_vni_ip,
1877 show_evpn_nh_vni_ip_cmd,
1878 "show evpn next-hops vni " CMD_VNI_RANGE " ip WORD [json]",
9aa741ea
MK
1879 SHOW_STR
1880 "EVPN\n"
1881 "Remote Vteps\n"
4cce389e 1882 "L3 VNI\n"
9aa741ea
MK
1883 "VNI number\n"
1884 "Ip address\n"
c0e519d3
MK
1885 "Host address (ipv4 or ipv6)\n"
1886 JSON_STR)
9aa741ea
MK
1887{
1888 vni_t l3vni;
9aa741ea 1889 struct ipaddr ip;
9f049418 1890 bool uj = use_json(argc, argv);
9aa741ea
MK
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 }
c0e519d3 1898 zebra_vxlan_print_specific_nh_l3vni(vty, l3vni, &ip, uj);
9aa741ea
MK
1899
1900 return CMD_SUCCESS;
1901}
1902
4cce389e
MK
1903DEFUN (show_evpn_nh_vni,
1904 show_evpn_nh_vni_cmd,
1905 "show evpn next-hops vni " CMD_VNI_RANGE "[json]",
b7cfce93
MK
1906 SHOW_STR
1907 "EVPN\n"
1908 "Remote Vteps\n"
4cce389e 1909 "L3 VNI\n"
b7cfce93
MK
1910 "VNI number\n"
1911 JSON_STR)
1912{
1913 vni_t l3vni;
9f049418 1914 bool uj = use_json(argc, argv);
b7cfce93
MK
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
4cce389e
MK
1922DEFUN (show_evpn_nh_vni_all,
1923 show_evpn_nh_vni_all_cmd,
1924 "show evpn next-hops vni all [json]",
b7cfce93
MK
1925 SHOW_STR
1926 "EVPN\n"
1927 "Remote VTEPs\n"
4cce389e 1928 "L3 VNI\n"
b7cfce93
MK
1929 "All VNIs\n"
1930 JSON_STR)
1931{
9f049418 1932 bool uj = use_json(argc, argv);
b7cfce93
MK
1933
1934 zebra_vxlan_print_nh_all_l3vni(vty, uj);
1935
1936 return CMD_SUCCESS;
1937}
1938
cec2e17d 1939DEFUN (show_evpn_mac_vni,
1940 show_evpn_mac_vni_cmd,
cd233079 1941 "show evpn mac vni " CMD_VNI_RANGE "[json]",
cec2e17d 1942 SHOW_STR
1943 "EVPN\n"
1944 "MAC addresses\n"
1945 "VxLAN Network Identifier\n"
cd233079 1946 "VNI number\n"
bd592158 1947 JSON_STR)
cec2e17d 1948{
d62a17ae 1949 struct zebra_vrf *zvrf;
1950 vni_t vni;
9f049418 1951 bool uj = use_json(argc, argv);
cec2e17d 1952
d62a17ae 1953 vni = strtoul(argv[4]->arg, NULL, 10);
1954 zvrf = vrf_info_lookup(VRF_DEFAULT);
cd233079 1955 zebra_vxlan_print_macs_vni(vty, zvrf, vni, uj);
d62a17ae 1956 return CMD_SUCCESS;
cec2e17d 1957}
1958
1959DEFUN (show_evpn_mac_vni_all,
1960 show_evpn_mac_vni_all_cmd,
cd233079 1961 "show evpn mac vni all [json]",
cec2e17d 1962 SHOW_STR
1963 "EVPN\n"
1964 "MAC addresses\n"
1965 "VxLAN Network Identifier\n"
cd233079 1966 "All VNIs\n"
bd592158 1967 JSON_STR)
cec2e17d 1968{
d62a17ae 1969 struct zebra_vrf *zvrf;
9f049418 1970 bool uj = use_json(argc, argv);
cec2e17d 1971
d62a17ae 1972 zvrf = vrf_info_lookup(VRF_DEFAULT);
1374d4db 1973 zebra_vxlan_print_macs_all_vni(vty, zvrf, false, uj);
d62a17ae 1974 return CMD_SUCCESS;
cec2e17d 1975}
1976
1977DEFUN (show_evpn_mac_vni_all_vtep,
1978 show_evpn_mac_vni_all_vtep_cmd,
cd233079 1979 "show evpn mac vni all vtep A.B.C.D [json]",
cec2e17d 1980 SHOW_STR
1981 "EVPN\n"
1982 "MAC addresses\n"
1983 "VxLAN Network Identifier\n"
1984 "All VNIs\n"
1985 "Remote VTEP\n"
cd233079 1986 "Remote VTEP IP address\n"
bd592158 1987 JSON_STR)
cec2e17d 1988{
d62a17ae 1989 struct zebra_vrf *zvrf;
1990 struct in_addr vtep_ip;
9f049418 1991 bool uj = use_json(argc, argv);
cec2e17d 1992
d62a17ae 1993 if (!inet_aton(argv[6]->arg, &vtep_ip)) {
cd233079
CS
1994 if (!uj)
1995 vty_out(vty, "%% Malformed VTEP IP address\n");
d62a17ae 1996 return CMD_WARNING;
1997 }
1998 zvrf = vrf_info_lookup(VRF_DEFAULT);
cd233079 1999 zebra_vxlan_print_macs_all_vni_vtep(vty, zvrf, vtep_ip, uj);
cec2e17d 2000
d62a17ae 2001 return CMD_SUCCESS;
cec2e17d 2002}
2003
2004
2005DEFUN (show_evpn_mac_vni_mac,
2006 show_evpn_mac_vni_mac_cmd,
24cdbd0d 2007 "show evpn mac vni " CMD_VNI_RANGE " mac WORD [json]",
cec2e17d 2008 SHOW_STR
2009 "EVPN\n"
2010 "MAC addresses\n"
2011 "VxLAN Network Identifier\n"
2012 "VNI number\n"
2013 "MAC\n"
24cdbd0d
DS
2014 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2015 JSON_STR)
2016
cec2e17d 2017{
d62a17ae 2018 struct zebra_vrf *zvrf;
2019 vni_t vni;
2020 struct ethaddr mac;
24cdbd0d 2021 bool uj = use_json(argc, argv);
cec2e17d 2022
d62a17ae 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);
24cdbd0d 2029 zebra_vxlan_print_specific_mac_vni(vty, zvrf, vni, &mac, uj);
d62a17ae 2030 return CMD_SUCCESS;
cec2e17d 2031}
2032
2033DEFUN (show_evpn_mac_vni_vtep,
2034 show_evpn_mac_vni_vtep_cmd,
cd233079 2035 "show evpn mac vni " CMD_VNI_RANGE " vtep A.B.C.D" "[json]",
cec2e17d 2036 SHOW_STR
2037 "EVPN\n"
2038 "MAC addresses\n"
2039 "VxLAN Network Identifier\n"
2040 "VNI number\n"
2041 "Remote VTEP\n"
cd233079 2042 "Remote VTEP IP address\n"
bd592158 2043 JSON_STR)
cec2e17d 2044{
d62a17ae 2045 struct zebra_vrf *zvrf;
2046 vni_t vni;
2047 struct in_addr vtep_ip;
9f049418 2048 bool uj = use_json(argc, argv);
cec2e17d 2049
d62a17ae 2050 vni = strtoul(argv[4]->arg, NULL, 10);
2051 if (!inet_aton(argv[6]->arg, &vtep_ip)) {
cd233079
CS
2052 if (!uj)
2053 vty_out(vty, "%% Malformed VTEP IP address\n");
d62a17ae 2054 return CMD_WARNING;
2055 }
cec2e17d 2056
d62a17ae 2057 zvrf = vrf_info_lookup(VRF_DEFAULT);
cd233079 2058 zebra_vxlan_print_macs_vni_vtep(vty, zvrf, vni, vtep_ip, uj);
d62a17ae 2059 return CMD_SUCCESS;
cec2e17d 2060}
2061
1374d4db
CS
2062DEFPY (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
2082DEFPY (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
2105DEFPY (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
2126DEFPY (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
cec2e17d 2146DEFUN (show_evpn_neigh_vni,
2147 show_evpn_neigh_vni_cmd,
cd233079 2148 "show evpn arp-cache vni " CMD_VNI_RANGE "[json]",
cec2e17d 2149 SHOW_STR
2150 "EVPN\n"
2151 "ARP and ND cache\n"
2152 "VxLAN Network Identifier\n"
cd233079 2153 "VNI number\n"
bd592158 2154 JSON_STR)
cec2e17d 2155{
d62a17ae 2156 struct zebra_vrf *zvrf;
2157 vni_t vni;
9f049418 2158 bool uj = use_json(argc, argv);
cec2e17d 2159
d62a17ae 2160 vni = strtoul(argv[4]->arg, NULL, 10);
2161 zvrf = vrf_info_lookup(VRF_DEFAULT);
cd233079 2162 zebra_vxlan_print_neigh_vni(vty, zvrf, vni, uj);
d62a17ae 2163 return CMD_SUCCESS;
cec2e17d 2164}
2165
2166DEFUN (show_evpn_neigh_vni_all,
2167 show_evpn_neigh_vni_all_cmd,
cd233079 2168 "show evpn arp-cache vni all [json]",
cec2e17d 2169 SHOW_STR
2170 "EVPN\n"
2171 "ARP and ND cache\n"
2172 "VxLAN Network Identifier\n"
cd233079 2173 "All VNIs\n"
bd592158 2174 JSON_STR)
cec2e17d 2175{
d62a17ae 2176 struct zebra_vrf *zvrf;
9f049418 2177 bool uj = use_json(argc, argv);
cec2e17d 2178
d62a17ae 2179 zvrf = vrf_info_lookup(VRF_DEFAULT);
1374d4db 2180 zebra_vxlan_print_neigh_all_vni(vty, zvrf, false, uj);
d62a17ae 2181 return CMD_SUCCESS;
cec2e17d 2182}
2183
2184DEFUN (show_evpn_neigh_vni_neigh,
2185 show_evpn_neigh_vni_neigh_cmd,
cd233079 2186 "show evpn arp-cache vni " CMD_VNI_RANGE " ip WORD [json]",
cec2e17d 2187 SHOW_STR
2188 "EVPN\n"
2189 "ARP and ND cache\n"
2190 "VxLAN Network Identifier\n"
2191 "VNI number\n"
2192 "Neighbor\n"
cd233079 2193 "Neighbor address (IPv4 or IPv6 address)\n"
bd592158 2194 JSON_STR)
cec2e17d 2195{
d62a17ae 2196 struct zebra_vrf *zvrf;
2197 vni_t vni;
2198 struct ipaddr ip;
9f049418 2199 bool uj = use_json(argc, argv);
cec2e17d 2200
d62a17ae 2201 vni = strtoul(argv[4]->arg, NULL, 10);
2202 if (str2ipaddr(argv[6]->arg, &ip) != 0) {
cd233079
CS
2203 if (!uj)
2204 vty_out(vty, "%% Malformed Neighbor address\n");
d62a17ae 2205 return CMD_WARNING;
2206 }
2207 zvrf = vrf_info_lookup(VRF_DEFAULT);
cd233079 2208 zebra_vxlan_print_specific_neigh_vni(vty, zvrf, vni, &ip, uj);
d62a17ae 2209 return CMD_SUCCESS;
cec2e17d 2210}
2211
2212DEFUN (show_evpn_neigh_vni_vtep,
2213 show_evpn_neigh_vni_vtep_cmd,
cd233079 2214 "show evpn arp-cache vni " CMD_VNI_RANGE " vtep A.B.C.D [json]",
cec2e17d 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"
cd233079 2221 "Remote VTEP IP address\n"
bd592158 2222 JSON_STR)
cec2e17d 2223{
d62a17ae 2224 struct zebra_vrf *zvrf;
2225 vni_t vni;
2226 struct in_addr vtep_ip;
9f049418 2227 bool uj = use_json(argc, argv);
cec2e17d 2228
d62a17ae 2229 vni = strtoul(argv[4]->arg, NULL, 10);
2230 if (!inet_aton(argv[6]->arg, &vtep_ip)) {
cd233079
CS
2231 if (!uj)
2232 vty_out(vty, "%% Malformed VTEP IP address\n");
d62a17ae 2233 return CMD_WARNING;
2234 }
cec2e17d 2235
d62a17ae 2236 zvrf = vrf_info_lookup(VRF_DEFAULT);
cd233079 2237 zebra_vxlan_print_neigh_vni_vtep(vty, zvrf, vni, vtep_ip, uj);
d62a17ae 2238 return CMD_SUCCESS;
cec2e17d 2239}
2240
586f4ccf
PG
2241/* policy routing contexts */
2242DEFUN (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 */
2261DEFUN (show_pbr_iptable,
2262 show_pbr_iptable_cmd,
7929821a 2263 "show pbr iptable [WORD]",
586f4ccf
PG
2264 SHOW_STR
2265 "Policy-Based Routing\n"
7929821a
PG
2266 "IPtable Context information\n"
2267 "IPtable Name information\n")
586f4ccf 2268{
7929821a
PG
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);
586f4ccf
PG
2277 return CMD_SUCCESS;
2278}
2279
718e3744 2280/* Static ip route configuration write function. */
d62a17ae 2281static int zebra_ip_config(struct vty *vty)
718e3744 2282{
d62a17ae 2283 int write = 0;
718e3744 2284
d62a17ae 2285 write += zebra_import_table_config(vty);
37728041 2286
d62a17ae 2287 return write;
718e3744 2288}
2289
7a4bb9c5
DS
2290DEFUN (ip_zebra_import_table_distance,
2291 ip_zebra_import_table_distance_cmd,
12dcf78e 2292 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
8902474b
DS
2293 IP_STR
2294 "import routes from non-main kernel table\n"
2295 "kernel routing table id\n"
2296 "Distance for imported routes\n"
2297 "Default distance value\n"
2298 "route-map for filtering\n"
2299 "route-map name\n")
2300{
d7c0a89a 2301 uint32_t table_id = 0;
8902474b 2302
d62a17ae 2303 table_id = strtoul(argv[2]->arg, NULL, 10);
2304 int distance = ZEBRA_TABLE_DISTANCE_DEFAULT;
2305 char *rmap =
2306 strmatch(argv[argc - 2]->text, "route-map")
2307 ? XSTRDUP(MTYPE_ROUTE_MAP_NAME, argv[argc - 1]->arg)
2308 : NULL;
2309 int ret;
d722f26e 2310
d62a17ae 2311 if (argc == 7 || (argc == 5 && !rmap))
2312 distance = strtoul(argv[4]->arg, NULL, 10);
8902474b 2313
d62a17ae 2314 if (!is_zebra_valid_kernel_table(table_id)) {
2315 vty_out(vty,
2316 "Invalid routing table ID, %d. Must be in range 1-252\n",
2317 table_id);
0af35d90
RW
2318 if (rmap)
2319 XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
d62a17ae 2320 return CMD_WARNING;
2321 }
8902474b 2322
d62a17ae 2323 if (is_zebra_main_routing_table(table_id)) {
2324 vty_out(vty,
2325 "Invalid routing table ID, %d. Must be non-default table\n",
2326 table_id);
0af35d90
RW
2327 if (rmap)
2328 XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
d62a17ae 2329 return CMD_WARNING;
2330 }
8902474b 2331
d62a17ae 2332 ret = zebra_import_table(AFI_IP, table_id, distance, rmap, 1);
2333 if (rmap)
2334 XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
d722f26e 2335
d62a17ae 2336 return ret;
8902474b
DS
2337}
2338
62d52ded
DS
2339DEFUN_HIDDEN (zebra_packet_process,
2340 zebra_packet_process_cmd,
2341 "zebra zapi-packets (1-10000)",
2342 ZEBRA_STR
2343 "Zapi Protocol\n"
2344 "Number of packets to process before relinquishing thread\n")
2345{
2346 uint32_t packets = strtoul(argv[2]->arg, NULL, 10);
2347
ccd51bd2
QY
2348 atomic_store_explicit(&zebrad.packets_to_process, packets,
2349 memory_order_relaxed);
62d52ded
DS
2350
2351 return CMD_SUCCESS;
2352}
2353
2354DEFUN_HIDDEN (no_zebra_packet_process,
2355 no_zebra_packet_process_cmd,
2356 "no zebra zapi-packets [(1-10000)]",
2357 NO_STR
2358 ZEBRA_STR
2359 "Zapi Protocol\n"
2360 "Number of packets to process before relinquishing thread\n")
2361{
ccd51bd2
QY
2362 atomic_store_explicit(&zebrad.packets_to_process,
2363 ZEBRA_ZAPI_PACKETS_TO_PROCESS,
2364 memory_order_relaxed);
62d52ded
DS
2365
2366 return CMD_SUCCESS;
2367}
2368
3a30f50f
DS
2369DEFUN_HIDDEN (zebra_workqueue_timer,
2370 zebra_workqueue_timer_cmd,
2371 "zebra work-queue (0-10000)",
2372 ZEBRA_STR
2373 "Work Queue\n"
2374 "Time in milliseconds\n")
2375{
996c9314
LB
2376 uint32_t timer = strtoul(argv[2]->arg, NULL, 10);
2377 zebrad.ribq->spec.hold = timer;
3a30f50f 2378
996c9314 2379 return CMD_SUCCESS;
3a30f50f
DS
2380}
2381
2382DEFUN_HIDDEN (no_zebra_workqueue_timer,
2383 no_zebra_workqueue_timer_cmd,
2384 "no zebra work-queue [(0-10000)]",
2385 NO_STR
2386 ZEBRA_STR
2387 "Work Queue\n"
2388 "Time in milliseconds\n")
2389{
996c9314 2390 zebrad.ribq->spec.hold = ZEBRA_RIB_PROCESS_HOLD_TIME;
3a30f50f 2391
996c9314 2392 return CMD_SUCCESS;
3a30f50f
DS
2393}
2394
7a4bb9c5
DS
2395DEFUN (no_ip_zebra_import_table,
2396 no_ip_zebra_import_table_cmd,
b62ecea5 2397 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
7a4bb9c5
DS
2398 NO_STR
2399 IP_STR
2400 "import routes from non-main kernel table\n"
3a2d747c
QY
2401 "kernel routing table id\n"
2402 "Distance for imported routes\n"
2403 "Default distance value\n"
2404 "route-map for filtering\n"
2405 "route-map name\n")
7a4bb9c5 2406{
d7c0a89a 2407 uint32_t table_id = 0;
d62a17ae 2408 table_id = strtoul(argv[3]->arg, NULL, 10);
7a4bb9c5 2409
d62a17ae 2410 if (!is_zebra_valid_kernel_table(table_id)) {
2411 vty_out(vty,
2412 "Invalid routing table ID. Must be in range 1-252\n");
2413 return CMD_WARNING;
2414 }
7a4bb9c5 2415
d62a17ae 2416 if (is_zebra_main_routing_table(table_id)) {
2417 vty_out(vty,
2418 "Invalid routing table ID, %d. Must be non-default table\n",
2419 table_id);
2420 return CMD_WARNING;
2421 }
7a4bb9c5 2422
d62a17ae 2423 if (!is_zebra_import_table_enabled(AFI_IP, table_id))
2424 return CMD_SUCCESS;
7a4bb9c5 2425
d62a17ae 2426 return (zebra_import_table(AFI_IP, table_id, 0, NULL, 0));
7a4bb9c5
DS
2427}
2428
d62a17ae 2429static int config_write_protocol(struct vty *vty)
6baf7bb8 2430{
d62a17ae 2431 if (allow_delete)
2432 vty_out(vty, "allow-external-route-update\n");
6baf7bb8 2433
d62a17ae 2434 if (zebra_rnh_ip_default_route)
2435 vty_out(vty, "ip nht resolve-via-default\n");
6baf7bb8 2436
d62a17ae 2437 if (zebra_rnh_ipv6_default_route)
2438 vty_out(vty, "ipv6 nht resolve-via-default\n");
6baf7bb8 2439
3a30f50f
DS
2440 if (zebrad.ribq->spec.hold != ZEBRA_RIB_PROCESS_HOLD_TIME)
2441 vty_out(vty, "zebra work-queue %u\n", zebrad.ribq->spec.hold);
2442
62d52ded 2443 if (zebrad.packets_to_process != ZEBRA_ZAPI_PACKETS_TO_PROCESS)
996c9314
LB
2444 vty_out(vty, "zebra zapi-packets %u\n",
2445 zebrad.packets_to_process);
62d52ded 2446
d62a17ae 2447 enum multicast_mode ipv4_multicast_mode = multicast_mode_ipv4_get();
4623d897 2448
d62a17ae 2449 if (ipv4_multicast_mode != MCAST_NO_CONFIG)
2450 vty_out(vty, "ip multicast rpf-lookup-mode %s\n",
2451 ipv4_multicast_mode == MCAST_URIB_ONLY
2452 ? "urib-only"
2453 : ipv4_multicast_mode == MCAST_MRIB_ONLY
2454 ? "mrib-only"
2455 : ipv4_multicast_mode
2456 == MCAST_MIX_MRIB_FIRST
2457 ? "mrib-then-urib"
2458 : ipv4_multicast_mode
2459 == MCAST_MIX_DISTANCE
2460 ? "lower-distance"
2461 : "longer-prefix");
d62a17ae 2462 return 1;
6baf7bb8
DS
2463}
2464
c0d136ae
DS
2465#ifdef HAVE_NETLINK
2466/* Display default rtm_table for all clients. */
2467DEFUN (show_table,
2468 show_table_cmd,
2469 "show table",
2470 SHOW_STR
2471 "default routing table to use for all clients\n")
2472{
2473 vty_out(vty, "table %d\n", zebrad.rtm_table_default);
2474 return CMD_SUCCESS;
2475}
2476
2477DEFUN (config_table,
2478 config_table_cmd,
2479 "table TABLENO",
2480 "Configure target kernel routing table\n"
2481 "TABLE integer\n")
2482{
2483 zebrad.rtm_table_default = strtol(argv[1]->arg, (char **)0, 10);
2484 return CMD_SUCCESS;
2485}
2486
2487DEFUN (no_config_table,
2488 no_config_table_cmd,
2489 "no table [TABLENO]",
2490 NO_STR
2491 "Configure target kernel routing table\n"
2492 "TABLE integer\n")
2493{
2494 zebrad.rtm_table_default = 0;
2495 return CMD_SUCCESS;
2496}
2497#endif
2498
2499DEFUN (show_zebra,
2500 show_zebra_cmd,
2501 "show zebra",
2502 SHOW_STR
2503 ZEBRA_STR)
2504{
2505 struct vrf *vrf;
2506
2507 vty_out(vty,
2508 " Route Route Neighbor LSP LSP\n");
2509 vty_out(vty,
2510 "VRF Installs Removals Updates Installs Removals\n");
2511
996c9314 2512 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
c0d136ae
DS
2513 struct zebra_vrf *zvrf = vrf->info;
2514
2515 vty_out(vty, "%-25s %10" PRIu64 " %10" PRIu64 " %10" PRIu64
2516 " %10" PRIu64 " %10" PRIu64 "\n",
2517 vrf->name, zvrf->installs, zvrf->removals,
2518 zvrf->neigh_updates, zvrf->lsp_installs,
2519 zvrf->lsp_removals);
2520 }
2521
2522 return CMD_SUCCESS;
2523}
2524
2525DEFUN (ip_forwarding,
2526 ip_forwarding_cmd,
2527 "ip forwarding",
2528 IP_STR
2529 "Turn on IP forwarding\n")
2530{
2531 int ret;
2532
2533 ret = ipforward();
2534 if (ret == 0)
2535 ret = ipforward_on();
2536
2537 if (ret == 0) {
2538 vty_out(vty, "Can't turn on IP forwarding\n");
2539 return CMD_WARNING_CONFIG_FAILED;
2540 }
2541
2542 return CMD_SUCCESS;
2543}
2544
2545DEFUN (no_ip_forwarding,
2546 no_ip_forwarding_cmd,
2547 "no ip forwarding",
2548 NO_STR
2549 IP_STR
2550 "Turn off IP forwarding\n")
2551{
2552 int ret;
2553
2554 ret = ipforward();
2555 if (ret != 0)
2556 ret = ipforward_off();
2557
2558 if (ret != 0) {
2559 vty_out(vty, "Can't turn off IP forwarding\n");
2560 return CMD_WARNING_CONFIG_FAILED;
2561 }
2562
2563 return CMD_SUCCESS;
2564}
2565
2566/* Only display ip forwarding is enabled or not. */
2567DEFUN (show_ip_forwarding,
2568 show_ip_forwarding_cmd,
2569 "show ip forwarding",
2570 SHOW_STR
2571 IP_STR
2572 "IP forwarding status\n")
2573{
2574 int ret;
2575
2576 ret = ipforward();
2577
2578 if (ret == 0)
2579 vty_out(vty, "IP forwarding is off\n");
2580 else
2581 vty_out(vty, "IP forwarding is on\n");
2582 return CMD_SUCCESS;
2583}
2584
2585/* Only display ipv6 forwarding is enabled or not. */
2586DEFUN (show_ipv6_forwarding,
2587 show_ipv6_forwarding_cmd,
2588 "show ipv6 forwarding",
2589 SHOW_STR
2590 "IPv6 information\n"
2591 "Forwarding status\n")
2592{
2593 int ret;
2594
2595 ret = ipforward_ipv6();
2596
2597 switch (ret) {
2598 case -1:
2599 vty_out(vty, "ipv6 forwarding is unknown\n");
2600 break;
2601 case 0:
2602 vty_out(vty, "ipv6 forwarding is %s\n", "off");
2603 break;
2604 case 1:
2605 vty_out(vty, "ipv6 forwarding is %s\n", "on");
2606 break;
2607 default:
2608 vty_out(vty, "ipv6 forwarding is %s\n", "off");
2609 break;
2610 }
2611 return CMD_SUCCESS;
2612}
2613
2614DEFUN (ipv6_forwarding,
2615 ipv6_forwarding_cmd,
2616 "ipv6 forwarding",
2617 IPV6_STR
2618 "Turn on IPv6 forwarding\n")
2619{
2620 int ret;
2621
2622 ret = ipforward_ipv6();
2623 if (ret == 0)
2624 ret = ipforward_ipv6_on();
2625
2626 if (ret == 0) {
2627 vty_out(vty, "Can't turn on IPv6 forwarding\n");
2628 return CMD_WARNING_CONFIG_FAILED;
2629 }
2630
2631 return CMD_SUCCESS;
2632}
2633
2634DEFUN (no_ipv6_forwarding,
2635 no_ipv6_forwarding_cmd,
2636 "no ipv6 forwarding",
2637 NO_STR
2638 IPV6_STR
2639 "Turn off IPv6 forwarding\n")
2640{
2641 int ret;
2642
2643 ret = ipforward_ipv6();
2644 if (ret != 0)
2645 ret = ipforward_ipv6_off();
2646
2647 if (ret != 0) {
2648 vty_out(vty, "Can't turn off IPv6 forwarding\n");
2649 return CMD_WARNING_CONFIG_FAILED;
2650 }
2651
2652 return CMD_SUCCESS;
2653}
2654
1d11b21f
MS
2655/* Display dataplane info */
2656DEFUN (show_dataplane,
2657 show_dataplane_cmd,
2658 "show zebra dplane [detailed]",
2659 SHOW_STR
2660 ZEBRA_STR
2661 "Zebra dataplane information\n"
2662 "Detailed output\n")
2663{
2664 int idx = 0;
2665 bool detailed = false;
2666
2667 if (argv_find(argv, argc, "detailed", &idx))
2668 detailed = true;
2669
2670 return dplane_show_helper(vty, detailed);
2671}
2672
2673/* Display dataplane providers info */
2674DEFUN (show_dataplane_providers,
2675 show_dataplane_providers_cmd,
2676 "show zebra dplane providers [detailed]",
2677 SHOW_STR
2678 ZEBRA_STR
2679 "Zebra dataplane information\n"
2680 "Zebra dataplane provider information\n"
2681 "Detailed output\n")
2682{
2683 int idx = 0;
2684 bool detailed = false;
2685
2686 if (argv_find(argv, argc, "detailed", &idx))
2687 detailed = true;
2688
2689 return dplane_show_provs_helper(vty, detailed);
2690}
2691
91f16812
MS
2692/* Configure dataplane incoming queue limit */
2693DEFUN (zebra_dplane_queue_limit,
2694 zebra_dplane_queue_limit_cmd,
2695 "zebra dplane limit (0-10000)",
2696 ZEBRA_STR
2697 "Zebra dataplane\n"
2698 "Limit incoming queued updates\n"
2699 "Number of queued updates\n")
2700{
2701 uint32_t limit = 0;
2702
2703 limit = strtoul(argv[3]->arg, NULL, 10);
2704
2705 dplane_set_in_queue_limit(limit, true);
2706
2707 return CMD_SUCCESS;
2708}
2709
2710/* Reset dataplane queue limit to default value */
2711DEFUN (no_zebra_dplane_queue_limit,
2712 no_zebra_dplane_queue_limit_cmd,
2713 "no zebra dplane limit [(0-10000)]",
2714 NO_STR
2715 ZEBRA_STR
2716 "Zebra dataplane\n"
2717 "Limit incoming queued updates\n"
2718 "Number of queued updates\n")
2719{
2720 dplane_set_in_queue_limit(0, false);
2721
2722 return CMD_SUCCESS;
2723}
1d11b21f 2724
c0d136ae
DS
2725/* Table configuration write function. */
2726static int config_write_table(struct vty *vty)
2727{
2728 if (zebrad.rtm_table_default)
2729 vty_out(vty, "table %d\n", zebrad.rtm_table_default);
2730 return 0;
2731}
2732
2733/* IPForwarding configuration write function. */
2734static int config_write_forwarding(struct vty *vty)
2735{
2736 /* FIXME: Find better place for that. */
2737 router_id_write(vty);
2738
2739 if (!ipforward())
2740 vty_out(vty, "no ip forwarding\n");
2741 if (!ipforward_ipv6())
2742 vty_out(vty, "no ipv6 forwarding\n");
2743 vty_out(vty, "!\n");
2744 return 0;
2745}
2746
718e3744 2747/* IP node for static routes. */
d62a17ae 2748static struct cmd_node ip_node = {IP_NODE, "", 1};
2749static struct cmd_node protocol_node = {PROTOCOL_NODE, "", 1};
c0d136ae
DS
2750/* table node for routing tables. */
2751static struct cmd_node table_node = {TABLE_NODE,
2752 "", /* This node has no interface. */
2753 1};
2754static struct cmd_node forwarding_node = {FORWARDING_NODE,
2755 "", /* This node has no interface. */
2756 1};
718e3744 2757
2758/* Route VTY. */
d62a17ae 2759void zebra_vty_init(void)
2760{
c0d136ae
DS
2761 /* Install configuration write function. */
2762 install_node(&table_node, config_write_table);
2763 install_node(&forwarding_node, config_write_forwarding);
2764
2765 install_element(VIEW_NODE, &show_ip_forwarding_cmd);
2766 install_element(CONFIG_NODE, &ip_forwarding_cmd);
2767 install_element(CONFIG_NODE, &no_ip_forwarding_cmd);
2768 install_element(ENABLE_NODE, &show_zebra_cmd);
2769
2770#ifdef HAVE_NETLINK
2771 install_element(VIEW_NODE, &show_table_cmd);
2772 install_element(CONFIG_NODE, &config_table_cmd);
2773 install_element(CONFIG_NODE, &no_config_table_cmd);
2774#endif /* HAVE_NETLINK */
2775
2776 install_element(VIEW_NODE, &show_ipv6_forwarding_cmd);
2777 install_element(CONFIG_NODE, &ipv6_forwarding_cmd);
2778 install_element(CONFIG_NODE, &no_ipv6_forwarding_cmd);
2779
2780 /* Route-map */
2781 zebra_route_map_init();
2782
d62a17ae 2783 install_node(&ip_node, zebra_ip_config);
2784 install_node(&protocol_node, config_write_protocol);
2785
2786 install_element(CONFIG_NODE, &allow_external_route_update_cmd);
2787 install_element(CONFIG_NODE, &no_allow_external_route_update_cmd);
7e24fdf3 2788
d62a17ae 2789 install_element(CONFIG_NODE, &ip_multicast_mode_cmd);
2790 install_element(CONFIG_NODE, &no_ip_multicast_mode_cmd);
b3b08602 2791
d62a17ae 2792 install_element(CONFIG_NODE, &ip_zebra_import_table_distance_cmd);
2793 install_element(CONFIG_NODE, &no_ip_zebra_import_table_cmd);
3a30f50f
DS
2794 install_element(CONFIG_NODE, &zebra_workqueue_timer_cmd);
2795 install_element(CONFIG_NODE, &no_zebra_workqueue_timer_cmd);
62d52ded
DS
2796 install_element(CONFIG_NODE, &zebra_packet_process_cmd);
2797 install_element(CONFIG_NODE, &no_zebra_packet_process_cmd);
d62a17ae 2798
2799 install_element(VIEW_NODE, &show_vrf_cmd);
b7cfce93 2800 install_element(VIEW_NODE, &show_vrf_vni_cmd);
ecffa493 2801 install_element(VIEW_NODE, &show_route_cmd);
ae825b8b 2802 install_element(VIEW_NODE, &show_route_table_cmd);
87d6ac7a
PG
2803 if (vrf_is_backend_netns())
2804 install_element(VIEW_NODE, &show_route_table_vrf_cmd);
5ce91022
RW
2805 install_element(VIEW_NODE, &show_route_detail_cmd);
2806 install_element(VIEW_NODE, &show_route_summary_cmd);
d62a17ae 2807 install_element(VIEW_NODE, &show_ip_nht_cmd);
2808 install_element(VIEW_NODE, &show_ip_nht_vrf_all_cmd);
2809 install_element(VIEW_NODE, &show_ipv6_nht_cmd);
2810 install_element(VIEW_NODE, &show_ipv6_nht_vrf_all_cmd);
d62a17ae 2811
2812 install_element(VIEW_NODE, &show_ip_rpf_cmd);
2813 install_element(VIEW_NODE, &show_ip_rpf_addr_cmd);
2814
d62a17ae 2815 install_element(CONFIG_NODE, &ip_nht_default_route_cmd);
2816 install_element(CONFIG_NODE, &no_ip_nht_default_route_cmd);
2817 install_element(CONFIG_NODE, &ipv6_nht_default_route_cmd);
2818 install_element(CONFIG_NODE, &no_ipv6_nht_default_route_cmd);
214e5c26 2819 install_element(VRF_NODE, &ip_nht_default_route_cmd);
2820 install_element(VRF_NODE, &no_ip_nht_default_route_cmd);
2821 install_element(VRF_NODE, &ipv6_nht_default_route_cmd);
2822 install_element(VRF_NODE, &no_ipv6_nht_default_route_cmd);
d62a17ae 2823 install_element(VIEW_NODE, &show_ipv6_mroute_cmd);
2824
2825 /* Commands for VRF */
d62a17ae 2826 install_element(VIEW_NODE, &show_ipv6_mroute_vrf_all_cmd);
2827
4cce389e 2828 install_element(VIEW_NODE, &show_evpn_global_cmd);
d62a17ae 2829 install_element(VIEW_NODE, &show_evpn_vni_cmd);
2830 install_element(VIEW_NODE, &show_evpn_vni_vni_cmd);
4cce389e
MK
2831 install_element(VIEW_NODE, &show_evpn_rmac_vni_mac_cmd);
2832 install_element(VIEW_NODE, &show_evpn_rmac_vni_cmd);
2833 install_element(VIEW_NODE, &show_evpn_rmac_vni_all_cmd);
2834 install_element(VIEW_NODE, &show_evpn_nh_vni_ip_cmd);
2835 install_element(VIEW_NODE, &show_evpn_nh_vni_cmd);
2836 install_element(VIEW_NODE, &show_evpn_nh_vni_all_cmd);
d62a17ae 2837 install_element(VIEW_NODE, &show_evpn_mac_vni_cmd);
2838 install_element(VIEW_NODE, &show_evpn_mac_vni_all_cmd);
2839 install_element(VIEW_NODE, &show_evpn_mac_vni_all_vtep_cmd);
2840 install_element(VIEW_NODE, &show_evpn_mac_vni_mac_cmd);
2841 install_element(VIEW_NODE, &show_evpn_mac_vni_vtep_cmd);
1374d4db
CS
2842 install_element(VIEW_NODE, &show_evpn_mac_vni_dad_cmd);
2843 install_element(VIEW_NODE, &show_evpn_mac_vni_all_dad_cmd);
d62a17ae 2844 install_element(VIEW_NODE, &show_evpn_neigh_vni_cmd);
2845 install_element(VIEW_NODE, &show_evpn_neigh_vni_all_cmd);
2846 install_element(VIEW_NODE, &show_evpn_neigh_vni_neigh_cmd);
2847 install_element(VIEW_NODE, &show_evpn_neigh_vni_vtep_cmd);
1374d4db
CS
2848 install_element(VIEW_NODE, &show_evpn_neigh_vni_dad_cmd);
2849 install_element(VIEW_NODE, &show_evpn_neigh_vni_all_dad_cmd);
b7cfce93 2850
586f4ccf
PG
2851 install_element(VIEW_NODE, &show_pbr_ipset_cmd);
2852 install_element(VIEW_NODE, &show_pbr_iptable_cmd);
2853
e8d26197
MK
2854 install_element(CONFIG_NODE, &default_vrf_vni_mapping_cmd);
2855 install_element(CONFIG_NODE, &no_default_vrf_vni_mapping_cmd);
b7cfce93
MK
2856 install_element(VRF_NODE, &vrf_vni_mapping_cmd);
2857 install_element(VRF_NODE, &no_vrf_vni_mapping_cmd);
4060008b 2858
1d11b21f
MS
2859 install_element(VIEW_NODE, &show_dataplane_cmd);
2860 install_element(VIEW_NODE, &show_dataplane_providers_cmd);
91f16812
MS
2861 install_element(CONFIG_NODE, &zebra_dplane_queue_limit_cmd);
2862 install_element(CONFIG_NODE, &no_zebra_dplane_queue_limit_cmd);
718e3744 2863}