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