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