]> git.proxmox.com Git - mirror_frr.git/blame - zebra/zebra_vty.c
zebra: Replace nexthop_group with pointer in route entry
[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
DS
1105static void show_nexthop_group_cmd_helper(struct vty *vty,
1106 struct zebra_vrf *zvrf, afi_t afi)
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
1115 if (nhe->afi != afi)
1116 continue;
1117
1118 if (nhe->vrf_id != zvrf->vrf->vrf_id)
1119 continue;
1120
c8ee3cdb
DS
1121 vty_out(vty,
1122 "Group: %u RefCnt: %u afi: %d Valid: %d Installed: %d\n",
1123 nhe->dplane_ref, nhe->refcnt, nhe->afi,
1124 nhe->flags & NEXTHOP_GROUP_VALID,
1125 nhe->flags & NEXTHOP_GROUP_INSTALLED);
21be1364
DS
1126
1127 for (ALL_NEXTHOPS(nhe->nhg, nhop)) {
1128 vty_out(vty, " ");
1129 nexthop_group_write_nexthop(vty, nhop);
1130 }
1131 }
1132
1133 list_delete(&list);
1134}
1135
1136DEFPY (show_nexthop_group,
1137 show_nexthop_group_cmd,
1138 "show nexthop-group <ipv4$v4|ipv6$v6> [vrf <NAME$vrf_name|all$vrf_all>]",
1139 SHOW_STR
1140 IP_STR
1141 IP6_STR
1142 "Show Nexthop Groups\n"
1143 VRF_FULL_CMD_HELP_STR)
1144{
1145 afi_t afi = v4 ? AFI_IP : AFI_IP6;
1146 struct zebra_vrf *zvrf;
1147
1148 if (vrf_all) {
1149 struct vrf *vrf;
1150
1151 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
1152 struct zebra_vrf *zvrf;
1153
1154 zvrf = vrf->info;
1155 if (!zvrf)
1156 continue;
1157
1158 vty_out(vty, "VRF: %s\n", vrf->name);
1159 show_nexthop_group_cmd_helper(vty, zvrf, afi);
1160 }
1161
1162 return CMD_SUCCESS;
1163 }
1164
1165 if (vrf_name)
1166 zvrf = zebra_vrf_lookup_by_name(vrf_name);
1167 else
1168 zvrf = zebra_vrf_lookup_by_name(VRF_DEFAULT_NAME);
1169
1170 if (!zvrf) {
1171 vty_out(vty, "VRF %s specified does not exist", vrf_name);
1172 return CMD_SUCCESS;
1173 }
1174
1175 show_nexthop_group_cmd_helper(vty, zvrf, afi);
1176
1177 return CMD_SUCCESS;
1178}
1179
8f527c5e
FL
1180DEFUN (no_ip_nht_default_route,
1181 no_ip_nht_default_route_cmd,
1182 "no ip nht resolve-via-default",
1183 NO_STR
1184 IP_STR
1185 "Filter Next Hop tracking route resolution\n"
1186 "Resolve via default route\n")
1187{
214e5c26 1188 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
6d53d7b1 1189
1190 if (!zvrf)
1191 return CMD_WARNING;
1192
5a0bdc78 1193 if (!zvrf->zebra_rnh_ip_default_route)
214e5c26 1194 return CMD_SUCCESS;
1195
5a0bdc78 1196 zvrf->zebra_rnh_ip_default_route = 0;
73bf60a0 1197 zebra_evaluate_rnh(zvrf, AFI_IP, 1, RNH_NEXTHOP_TYPE, NULL);
d62a17ae 1198 return CMD_SUCCESS;
8f527c5e
FL
1199}
1200
1201DEFUN (ipv6_nht_default_route,
1202 ipv6_nht_default_route_cmd,
1203 "ipv6 nht resolve-via-default",
1204 IP6_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_ipv6_default_route)
214e5c26 1214 return CMD_SUCCESS;
1215
5a0bdc78 1216 zvrf->zebra_rnh_ipv6_default_route = 1;
73bf60a0 1217 zebra_evaluate_rnh(zvrf, AFI_IP6, 1, RNH_NEXTHOP_TYPE, NULL);
d62a17ae 1218 return CMD_SUCCESS;
8f527c5e
FL
1219}
1220
1221DEFUN (no_ipv6_nht_default_route,
1222 no_ipv6_nht_default_route_cmd,
1223 "no ipv6 nht resolve-via-default",
1224 NO_STR
1225 IP6_STR
1226 "Filter Next Hop tracking route resolution\n"
1227 "Resolve via default route\n")
1228{
8f527c5e 1229
214e5c26 1230 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
6d53d7b1 1231
1232 if (!zvrf)
1233 return CMD_WARNING;
1234
5a0bdc78 1235 if (!zvrf->zebra_rnh_ipv6_default_route)
214e5c26 1236 return CMD_SUCCESS;
1237
5a0bdc78 1238 zvrf->zebra_rnh_ipv6_default_route = 0;
73bf60a0 1239 zebra_evaluate_rnh(zvrf, AFI_IP6, 1, RNH_NEXTHOP_TYPE, NULL);
d62a17ae 1240 return CMD_SUCCESS;
8f527c5e
FL
1241}
1242
ecffa493
RW
1243DEFPY (show_route,
1244 show_route_cmd,
1245 "show\
1246 <\
1247 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
a3e13ef3 1248 [{\
ecffa493
RW
1249 tag (1-4294967295)\
1250 |A.B.C.D/M$prefix longer-prefixes\
1251 |supernets-only$supernets_only\
a3e13ef3
RW
1252 }]\
1253 [<\
1254 " FRR_IP_REDIST_STR_ZEBRA "$type_str\
ecffa493 1255 |ospf$type_str (1-65535)$ospf_instance_id\
a3e13ef3 1256 >]\
ecffa493 1257 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
a3e13ef3 1258 [{\
ecffa493
RW
1259 tag (1-4294967295)\
1260 |X:X::X:X/M$prefix longer-prefixes\
a3e13ef3
RW
1261 }]\
1262 [" FRR_IP6_REDIST_STR_ZEBRA "$type_str]\
ecffa493
RW
1263 >\
1264 [json$json]",
8f527c5e
FL
1265 SHOW_STR
1266 IP_STR
87a88962 1267 "IP forwarding table\n"
8f527c5e 1268 "IP routing table\n"
ecffa493 1269 VRF_FULL_CMD_HELP_STR
8f527c5e 1270 "Show only routes with tag\n"
acb25e73
DW
1271 "Tag value\n"
1272 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1273 "Show route matching the specified Network/Mask pair only\n"
1274 "Show supernet entries only\n"
1275 FRR_IP_REDIST_HELP_STR_ZEBRA
1276 "Open Shortest Path First (OSPFv2)\n"
1277 "Instance ID\n"
ecffa493
RW
1278 IPV6_STR
1279 "IP forwarding table\n"
1280 "IP routing table\n"
1281 VRF_FULL_CMD_HELP_STR
1282 "Show only routes with tag\n"
1283 "Tag value\n"
1284 "IPv6 prefix\n"
1285 "Show route matching the specified Network/Mask pair only\n"
1286 FRR_IP6_REDIST_HELP_STR_ZEBRA
acb25e73 1287 JSON_STR)
8f527c5e 1288{
ecffa493 1289 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
d62a17ae 1290 struct vrf *vrf;
d62a17ae 1291 int type = 0;
d62a17ae 1292
ecffa493
RW
1293 if (type_str) {
1294 type = proto_redistnum(afi, type_str);
d62a17ae 1295 if (type < 0) {
1296 vty_out(vty, "Unknown route type\n");
1297 return CMD_WARNING;
1298 }
1299 }
1300
1301 if (vrf_all) {
a2addae8 1302 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
ecffa493
RW
1303 struct zebra_vrf *zvrf;
1304 struct route_table *table;
1305
d62a17ae 1306 if ((zvrf = vrf->info) == NULL
ecffa493 1307 || (table = zvrf->table[afi][SAFI_UNICAST]) == NULL)
d62a17ae 1308 continue;
1309
1310 do_show_ip_route(
ecffa493
RW
1311 vty, zvrf_name(zvrf), afi, SAFI_UNICAST, !!fib,
1312 !!json, tag, prefix_str ? prefix : NULL,
1313 !!supernets_only, type, ospf_instance_id);
d62a17ae 1314 }
1315 } else {
ecffa493
RW
1316 vrf_id_t vrf_id = VRF_DEFAULT;
1317
1318 if (vrf_name)
ec1db588 1319 VRF_GET_ID(vrf_id, vrf_name, !!json);
d62a17ae 1320 vrf = vrf_lookup_by_id(vrf_id);
ecffa493
RW
1321 do_show_ip_route(vty, vrf->name, afi, SAFI_UNICAST, !!fib,
1322 !!json, tag, prefix_str ? prefix : NULL,
1323 !!supernets_only, type, ospf_instance_id);
d62a17ae 1324 }
ecffa493 1325
d62a17ae 1326 return CMD_SUCCESS;
8f527c5e
FL
1327}
1328
5ce91022
RW
1329DEFPY (show_route_detail,
1330 show_route_detail_cmd,
1331 "show\
1332 <\
6a794a7e 1333 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
5ce91022
RW
1334 <\
1335 A.B.C.D$address\
1336 |A.B.C.D/M$prefix\
1337 >\
6a794a7e 1338 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
5ce91022
RW
1339 <\
1340 X:X::X:X$address\
1341 |X:X::X:X/M$prefix\
1342 >\
96d71e38
AD
1343 >\
1344 [json$json]",
8f527c5e
FL
1345 SHOW_STR
1346 IP_STR
6a794a7e 1347 "IPv6 forwarding table\n"
8f527c5e 1348 "IP routing table\n"
5ce91022
RW
1349 VRF_FULL_CMD_HELP_STR
1350 "Network in the IP routing table to display\n"
1351 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1352 IP6_STR
6a794a7e
AD
1353 "IPv6 forwarding table\n"
1354 "IPv6 routing table\n"
5ce91022
RW
1355 VRF_FULL_CMD_HELP_STR
1356 "IPv6 Address\n"
96d71e38
AD
1357 "IPv6 prefix\n"
1358 JSON_STR)
8f527c5e 1359{
5ce91022 1360 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
d62a17ae 1361 struct route_table *table;
5ce91022 1362 struct prefix p;
d62a17ae 1363 struct route_node *rn;
3a3be633
AD
1364 bool use_fib = !!fib;
1365 rib_dest_t *dest;
ad2e7233 1366 bool network_found = false;
d511d7f1 1367
5ce91022
RW
1368 if (address_str)
1369 prefix_str = address_str;
1370 if (str2prefix(prefix_str, &p) < 0) {
1371 vty_out(vty, "%% Malformed address\n");
d62a17ae 1372 return CMD_WARNING;
1373 }
8f527c5e 1374
5ce91022
RW
1375 if (vrf_all) {
1376 struct vrf *vrf;
1377 struct zebra_vrf *zvrf;
8f527c5e 1378
996c9314 1379 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
5ce91022
RW
1380 if ((zvrf = vrf->info) == NULL
1381 || (table = zvrf->table[afi][SAFI_UNICAST]) == NULL)
1382 continue;
1383
1384 rn = route_node_match(table, &p);
1385 if (!rn)
1386 continue;
1387 if (!address_str && rn->p.prefixlen != p.prefixlen) {
1388 route_unlock_node(rn);
1389 continue;
1390 }
1391
ad2e7233
AD
1392 dest = rib_dest_from_rnode(rn);
1393 if (use_fib && !dest->selected_fib) {
1394 route_unlock_node(rn);
1395 continue;
1396 }
1397
1398 network_found = true;
96d71e38 1399 if (json)
3a3be633
AD
1400 vty_show_ip_route_detail_json(vty, rn,
1401 use_fib);
96d71e38 1402 else
3a3be633 1403 vty_show_ip_route_detail(vty, rn, 0, use_fib);
5ce91022
RW
1404
1405 route_unlock_node(rn);
1406 }
ad2e7233
AD
1407
1408 if (!network_found) {
1409 if (json)
1410 vty_out(vty, "{}\n");
1411 else {
1412 if (use_fib)
1413 vty_out(vty,
1414 "%% Network not in FIB\n");
1415 else
1416 vty_out(vty,
1417 "%% Network not in RIB\n");
1418 }
1419 return CMD_WARNING;
1420 }
5ce91022
RW
1421 } else {
1422 vrf_id_t vrf_id = VRF_DEFAULT;
1423
1424 if (vrf_name)
ec1db588 1425 VRF_GET_ID(vrf_id, vrf_name, false);
5ce91022
RW
1426
1427 table = zebra_vrf_table(afi, SAFI_UNICAST, vrf_id);
1428 if (!table)
1429 return CMD_SUCCESS;
8f527c5e 1430
5ce91022 1431 rn = route_node_match(table, &p);
ad2e7233
AD
1432 if (rn)
1433 dest = rib_dest_from_rnode(rn);
1434
1435 if (!rn || (!address_str && rn->p.prefixlen != p.prefixlen) ||
1436 (use_fib && dest && !dest->selected_fib)) {
1437 if (json)
1438 vty_out(vty, "{}\n");
1439 else {
1440 if (use_fib)
1441 vty_out(vty,
1442 "%% Network not in FIB\n");
1443 else
1444 vty_out(vty,
1445 "%% Network not in table\n");
1446 }
1447 if (rn)
1448 route_unlock_node(rn);
5ce91022
RW
1449 return CMD_WARNING;
1450 }
8f527c5e 1451
96d71e38 1452 if (json)
3a3be633 1453 vty_show_ip_route_detail_json(vty, rn, use_fib);
96d71e38 1454 else
3a3be633 1455 vty_show_ip_route_detail(vty, rn, 0, use_fib);
5ce91022
RW
1456
1457 route_unlock_node(rn);
1458 }
8f527c5e 1459
d62a17ae 1460 return CMD_SUCCESS;
8f527c5e
FL
1461}
1462
5ce91022
RW
1463DEFPY (show_route_summary,
1464 show_route_summary_cmd,
ae813e21
DS
1465 "show <ip$ipv4|ipv6$ipv6> route [vrf <NAME$vrf_name|all$vrf_all>] \
1466 summary [table (1-4294967295)$table_id] [prefix$prefix]",
8f527c5e
FL
1467 SHOW_STR
1468 IP_STR
5ce91022
RW
1469 IP6_STR
1470 "IP routing table\n"
1471 VRF_FULL_CMD_HELP_STR
1472 "Summary of all routes\n"
ae813e21
DS
1473 "Table to display summary for\n"
1474 "The table number\n"
5ce91022 1475 "Prefix routes\n")
8f527c5e 1476{
5ce91022 1477 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
d62a17ae 1478 struct route_table *table;
d62a17ae 1479
ae813e21
DS
1480 if (table_id == 0)
1481 table_id = RT_TABLE_MAIN;
1482
5ce91022
RW
1483 if (vrf_all) {
1484 struct vrf *vrf;
1485 struct zebra_vrf *zvrf;
d511d7f1 1486
996c9314 1487 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
ae813e21
DS
1488 if ((zvrf = vrf->info) == NULL)
1489 continue;
1490
1491 table = zebra_vrf_table_with_table_id(afi,
1492 SAFI_UNICAST,
1493 zvrf->vrf->vrf_id,
1494 table_id);
1495 if (!table)
5ce91022 1496 continue;
8f527c5e 1497
5ce91022
RW
1498 if (prefix)
1499 vty_show_ip_route_summary_prefix(vty, table);
1500 else
1501 vty_show_ip_route_summary(vty, table);
1502 }
1503 } else {
1504 vrf_id_t vrf_id = VRF_DEFAULT;
8f527c5e 1505
5ce91022 1506 if (vrf_name)
ec1db588 1507 VRF_GET_ID(vrf_id, vrf_name, false);
8f527c5e 1508
ae813e21
DS
1509 table = zebra_vrf_table_with_table_id(afi,
1510 SAFI_UNICAST,
1511 vrf_id, table_id);
5ce91022
RW
1512 if (!table)
1513 return CMD_SUCCESS;
8f527c5e 1514
5ce91022
RW
1515 if (prefix)
1516 vty_show_ip_route_summary_prefix(vty, table);
1517 else
1518 vty_show_ip_route_summary(vty, table);
1519 }
8f527c5e 1520
d62a17ae 1521 return CMD_SUCCESS;
8f527c5e
FL
1522}
1523
d62a17ae 1524static void vty_show_ip_route_summary(struct vty *vty,
1525 struct route_table *table)
8f527c5e 1526{
d62a17ae 1527 struct route_node *rn;
1528 struct route_entry *re;
8f527c5e
FL
1529#define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1530#define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
d7c0a89a
QY
1531 uint32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1532 uint32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1533 uint32_t i;
1534 uint32_t is_ibgp;
d62a17ae 1535
1536 memset(&rib_cnt, 0, sizeof(rib_cnt));
1537 memset(&fib_cnt, 0, sizeof(fib_cnt));
1538 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
a2addae8 1539 RNODE_FOREACH_RE (rn, re) {
d62a17ae 1540 is_ibgp = (re->type == ZEBRA_ROUTE_BGP
1541 && CHECK_FLAG(re->flags, ZEBRA_FLAG_IBGP));
1542
1543 rib_cnt[ZEBRA_ROUTE_TOTAL]++;
1544 if (is_ibgp)
1545 rib_cnt[ZEBRA_ROUTE_IBGP]++;
1546 else
1547 rib_cnt[re->type]++;
1548
6f875a36 1549 if (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED)) {
d62a17ae 1550 fib_cnt[ZEBRA_ROUTE_TOTAL]++;
1551
1552 if (is_ibgp)
1553 fib_cnt[ZEBRA_ROUTE_IBGP]++;
1554 else
1555 fib_cnt[re->type]++;
1556 }
1557 }
1558
1559 vty_out(vty, "%-20s %-20s %s (vrf %s)\n", "Route Source", "Routes",
6ca30e9e 1560 "FIB", zvrf_name(((rib_table_info_t *)route_table_get_info(table))->zvrf));
d62a17ae 1561
1562 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
9d303b37
DL
1563 if ((rib_cnt[i] > 0) || (i == ZEBRA_ROUTE_BGP
1564 && rib_cnt[ZEBRA_ROUTE_IBGP] > 0)) {
d62a17ae 1565 if (i == ZEBRA_ROUTE_BGP) {
1566 vty_out(vty, "%-20s %-20d %-20d \n", "ebgp",
1567 rib_cnt[ZEBRA_ROUTE_BGP],
1568 fib_cnt[ZEBRA_ROUTE_BGP]);
1569 vty_out(vty, "%-20s %-20d %-20d \n", "ibgp",
1570 rib_cnt[ZEBRA_ROUTE_IBGP],
1571 fib_cnt[ZEBRA_ROUTE_IBGP]);
1572 } else
1573 vty_out(vty, "%-20s %-20d %-20d \n",
1574 zebra_route_string(i), rib_cnt[i],
1575 fib_cnt[i]);
1576 }
1577 }
1578
1579 vty_out(vty, "------\n");
1580 vty_out(vty, "%-20s %-20d %-20d \n", "Totals",
1581 rib_cnt[ZEBRA_ROUTE_TOTAL], fib_cnt[ZEBRA_ROUTE_TOTAL]);
1582 vty_out(vty, "\n");
8f527c5e
FL
1583}
1584
1585/*
1586 * Implementation of the ip route summary prefix command.
1587 *
1588 * This command prints the primary prefixes that have been installed by various
1589 * protocols on the box.
1590 *
1591 */
d62a17ae 1592static void vty_show_ip_route_summary_prefix(struct vty *vty,
1593 struct route_table *table)
8f527c5e 1594{
d62a17ae 1595 struct route_node *rn;
1596 struct route_entry *re;
1597 struct nexthop *nexthop;
8f527c5e
FL
1598#define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1599#define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
d7c0a89a
QY
1600 uint32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1601 uint32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1602 uint32_t i;
d62a17ae 1603 int cnt;
1604
1605 memset(&rib_cnt, 0, sizeof(rib_cnt));
1606 memset(&fib_cnt, 0, sizeof(fib_cnt));
1607 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
a2addae8 1608 RNODE_FOREACH_RE (rn, re) {
d62a17ae 1609
1610 /*
1611 * In case of ECMP, count only once.
1612 */
1613 cnt = 0;
677c1dd5
DS
1614 if (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED)) {
1615 fib_cnt[ZEBRA_ROUTE_TOTAL]++;
1616 fib_cnt[re->type]++;
1617 }
6b468511 1618 for (nexthop = re->ng->nexthop; (!cnt && nexthop);
d62a17ae 1619 nexthop = nexthop->next) {
1620 cnt++;
1621 rib_cnt[ZEBRA_ROUTE_TOTAL]++;
1622 rib_cnt[re->type]++;
d62a17ae 1623 if (re->type == ZEBRA_ROUTE_BGP
1624 && CHECK_FLAG(re->flags, ZEBRA_FLAG_IBGP)) {
1625 rib_cnt[ZEBRA_ROUTE_IBGP]++;
677c1dd5
DS
1626 if (CHECK_FLAG(re->status,
1627 ROUTE_ENTRY_INSTALLED))
d62a17ae 1628 fib_cnt[ZEBRA_ROUTE_IBGP]++;
1629 }
1630 }
1631 }
1632
1633 vty_out(vty, "%-20s %-20s %s (vrf %s)\n", "Route Source",
1634 "Prefix Routes", "FIB",
6ca30e9e 1635 zvrf_name(((rib_table_info_t *)route_table_get_info(table))->zvrf));
d62a17ae 1636
1637 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
1638 if (rib_cnt[i] > 0) {
1639 if (i == ZEBRA_ROUTE_BGP) {
1640 vty_out(vty, "%-20s %-20d %-20d \n", "ebgp",
1641 rib_cnt[ZEBRA_ROUTE_BGP]
1642 - rib_cnt[ZEBRA_ROUTE_IBGP],
1643 fib_cnt[ZEBRA_ROUTE_BGP]
1644 - fib_cnt[ZEBRA_ROUTE_IBGP]);
1645 vty_out(vty, "%-20s %-20d %-20d \n", "ibgp",
1646 rib_cnt[ZEBRA_ROUTE_IBGP],
1647 fib_cnt[ZEBRA_ROUTE_IBGP]);
1648 } else
1649 vty_out(vty, "%-20s %-20d %-20d \n",
1650 zebra_route_string(i), rib_cnt[i],
1651 fib_cnt[i]);
1652 }
1653 }
1654
1655 vty_out(vty, "------\n");
1656 vty_out(vty, "%-20s %-20d %-20d \n", "Totals",
1657 rib_cnt[ZEBRA_ROUTE_TOTAL], fib_cnt[ZEBRA_ROUTE_TOTAL]);
1658 vty_out(vty, "\n");
9343ce83
DS
1659}
1660
cddf391b
B
1661/*
1662 * Show IPv6 mroute command.Used to dump
1663 * the Multicast routing table.
1664 */
cddf391b
B
1665DEFUN (show_ipv6_mroute,
1666 show_ipv6_mroute_cmd,
9bf96c84 1667 "show ipv6 mroute [vrf NAME]",
cddf391b
B
1668 SHOW_STR
1669 IP_STR
9bf96c84
DW
1670 "IPv6 Multicast routing table\n"
1671 VRF_CMD_HELP_STR)
cddf391b 1672{
d62a17ae 1673 struct route_table *table;
1674 struct route_node *rn;
1675 struct route_entry *re;
1676 int first = 1;
1677 vrf_id_t vrf_id = VRF_DEFAULT;
1678
1679 if (argc == 5)
ec1db588 1680 VRF_GET_ID(vrf_id, argv[4]->arg, false);
d62a17ae 1681
1682 table = zebra_vrf_table(AFI_IP6, SAFI_MULTICAST, vrf_id);
1683 if (!table)
1684 return CMD_SUCCESS;
1685
1686 /* Show all IPv6 route. */
1687 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
a2addae8 1688 RNODE_FOREACH_RE (rn, re) {
d62a17ae 1689 if (first) {
1690 vty_out(vty, SHOW_ROUTE_V6_HEADER);
1691 first = 0;
1692 }
941e261c 1693 vty_show_ip_route(vty, rn, re, NULL, false);
d62a17ae 1694 }
1695 return CMD_SUCCESS;
cddf391b
B
1696}
1697
af41b63a
FL
1698DEFUN (show_ipv6_mroute_vrf_all,
1699 show_ipv6_mroute_vrf_all_cmd,
5bebf568 1700 "show ipv6 mroute vrf all",
af41b63a
FL
1701 SHOW_STR
1702 IP_STR
1703 "IPv6 Multicast routing table\n"
1704 VRF_ALL_CMD_HELP_STR)
1705{
d62a17ae 1706 struct route_table *table;
1707 struct route_node *rn;
1708 struct route_entry *re;
1709 struct vrf *vrf;
1710 struct zebra_vrf *zvrf;
1711 int first = 1;
1712
a2addae8 1713 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
d62a17ae 1714 if ((zvrf = vrf->info) == NULL
1715 || (table = zvrf->table[AFI_IP6][SAFI_MULTICAST]) == NULL)
1716 continue;
1717
1718 /* Show all IPv6 route. */
1719 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
a2addae8 1720 RNODE_FOREACH_RE (rn, re) {
d62a17ae 1721 if (first) {
1722 vty_out(vty, SHOW_ROUTE_V6_HEADER);
1723 first = 0;
1724 }
941e261c 1725 vty_show_ip_route(vty, rn, re, NULL, false);
d62a17ae 1726 }
1727 }
1728 return CMD_SUCCESS;
af41b63a
FL
1729}
1730
6baf7bb8
DS
1731DEFUN (allow_external_route_update,
1732 allow_external_route_update_cmd,
1733 "allow-external-route-update",
17d990c1 1734 "Allow FRR routes to be overwritten by external processes\n")
6baf7bb8 1735{
d62a17ae 1736 allow_delete = 1;
6baf7bb8 1737
d62a17ae 1738 return CMD_SUCCESS;
6baf7bb8
DS
1739}
1740
1741DEFUN (no_allow_external_route_update,
1742 no_allow_external_route_update_cmd,
1743 "no allow-external-route-update",
17d990c1
DS
1744 NO_STR
1745 "Allow FRR routes to be overwritten by external processes\n")
6baf7bb8 1746{
d62a17ae 1747 allow_delete = 0;
6baf7bb8 1748
d62a17ae 1749 return CMD_SUCCESS;
6baf7bb8
DS
1750}
1751
12f6fb97
DS
1752/* show vrf */
1753DEFUN (show_vrf,
1754 show_vrf_cmd,
1755 "show vrf",
1756 SHOW_STR
1757 "VRF\n")
1758{
d62a17ae 1759 struct vrf *vrf;
1760 struct zebra_vrf *zvrf;
12f6fb97 1761
b73823ef
PG
1762 if (vrf_is_backend_netns())
1763 vty_out(vty, "netns-based vrfs\n");
1764
a2addae8 1765 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
d62a17ae 1766 if (!(zvrf = vrf->info))
1767 continue;
90ac32c2 1768 if (zvrf_id(zvrf) == VRF_DEFAULT)
d62a17ae 1769 continue;
1770
1771 vty_out(vty, "vrf %s ", zvrf_name(zvrf));
996c9314 1772 if (zvrf_id(zvrf) == VRF_UNKNOWN || !zvrf_is_active(zvrf))
d62a17ae 1773 vty_out(vty, "inactive");
81c9005f 1774 else if (zvrf_ns_name(zvrf))
996c9314
LB
1775 vty_out(vty, "id %u netns %s", zvrf_id(zvrf),
1776 zvrf_ns_name(zvrf));
d62a17ae 1777 else
1778 vty_out(vty, "id %u table %u", zvrf_id(zvrf),
1779 zvrf->table_id);
22bd3e94 1780 if (vrf_is_user_cfged(vrf))
1781 vty_out(vty, " (configured)");
d62a17ae 1782 vty_out(vty, "\n");
1783 }
12f6fb97 1784
d62a17ae 1785 return CMD_SUCCESS;
12f6fb97
DS
1786}
1787
8f2ff1b5 1788DEFUN (default_vrf_vni_mapping,
e8d26197 1789 default_vrf_vni_mapping_cmd,
c48d9f5f 1790 "vni " CMD_VNI_RANGE "[prefix-routes-only]",
e8d26197 1791 "VNI corresponding to the DEFAULT VRF\n"
c48d9f5f
MK
1792 "VNI-ID\n"
1793 "Prefix routes only \n")
e8d26197
MK
1794{
1795 int ret = 0;
1796 char err[ERR_STR_SZ];
1797 struct zebra_vrf *zvrf = NULL;
1798 vni_t vni = strtoul(argv[1]->arg, NULL, 10);
c48d9f5f 1799 int filter = 0;
e8d26197
MK
1800
1801 zvrf = vrf_info_lookup(VRF_DEFAULT);
1802 if (!zvrf)
1803 return CMD_WARNING;
1804
c48d9f5f
MK
1805 if (argc == 3)
1806 filter = 1;
1807
1808 ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ,
1809 filter, 1);
e8d26197
MK
1810 if (ret != 0) {
1811 vty_out(vty, "%s\n", err);
1812 return CMD_WARNING;
1813 }
1814
1815 return CMD_SUCCESS;
1816}
1817
8f2ff1b5 1818DEFUN (no_default_vrf_vni_mapping,
e8d26197
MK
1819 no_default_vrf_vni_mapping_cmd,
1820 "no vni " CMD_VNI_RANGE,
1821 NO_STR
1822 "VNI corresponding to DEFAULT VRF\n"
1823 "VNI-ID")
1824{
1825 int ret = 0;
1826 char err[ERR_STR_SZ];
1827 vni_t vni = strtoul(argv[2]->arg, NULL, 10);
1828 struct zebra_vrf *zvrf = NULL;
1829
1830 zvrf = vrf_info_lookup(VRF_DEFAULT);
1831 if (!zvrf)
1832 return CMD_WARNING;
1833
c48d9f5f 1834 ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ, 0, 0);
e8d26197
MK
1835 if (ret != 0) {
1836 vty_out(vty, "%s\n", err);
1837 return CMD_WARNING;
1838 }
1839
1840 return CMD_SUCCESS;
1841}
1842
b7cfce93
MK
1843DEFUN (vrf_vni_mapping,
1844 vrf_vni_mapping_cmd,
c48d9f5f 1845 "vni " CMD_VNI_RANGE "[prefix-routes-only]",
e8d26197 1846 "VNI corresponding to tenant VRF\n"
c48d9f5f
MK
1847 "VNI-ID\n"
1848 "prefix-routes-only\n")
b7cfce93
MK
1849{
1850 int ret = 0;
c48d9f5f 1851 int filter = 0;
b7cfce93
MK
1852
1853 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
1854 vni_t vni = strtoul(argv[1]->arg, NULL, 10);
1855 char err[ERR_STR_SZ];
1856
1857 assert(vrf);
1858 assert(zvrf);
1859
c48d9f5f
MK
1860 if (argc == 3)
1861 filter = 1;
1862
317f1fe0 1863 /* Mark as having FRR configuration */
1864 vrf_set_user_cfged(vrf);
c48d9f5f
MK
1865 ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ,
1866 filter, 1);
b7cfce93
MK
1867 if (ret != 0) {
1868 vty_out(vty, "%s\n", err);
1869 return CMD_WARNING;
1870 }
1871
1872 return CMD_SUCCESS;
1873}
1874
1875DEFUN (no_vrf_vni_mapping,
1876 no_vrf_vni_mapping_cmd,
cf299714 1877 "no vni " CMD_VNI_RANGE "[prefix-routes-only]",
b7cfce93 1878 NO_STR
e8d26197 1879 "VNI corresponding to tenant VRF\n"
cf299714
MK
1880 "VNI-ID\n"
1881 "prefix-routes-only\n")
b7cfce93
MK
1882{
1883 int ret = 0;
cf299714 1884 int filter = 0;
b7cfce93
MK
1885 char err[ERR_STR_SZ];
1886 vni_t vni = strtoul(argv[2]->arg, NULL, 10);
1887
1888 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
1889
1890 assert(vrf);
1891 assert(zvrf);
1892
cf299714
MK
1893 if (argc == 4)
1894 filter = 1;
1895
1896 ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err,
1897 ERR_STR_SZ, filter, 0);
b7cfce93
MK
1898 if (ret != 0) {
1899 vty_out(vty, "%s\n", err);
1900 return CMD_WARNING;
1901 }
1902
22bd3e94 1903 /* If no other FRR config for this VRF, mark accordingly. */
1904 if (!zebra_vrf_has_config(zvrf))
1905 vrf_reset_user_cfged(vrf);
1906
b7cfce93
MK
1907 return CMD_SUCCESS;
1908}
1909
1910/* show vrf */
1911DEFUN (show_vrf_vni,
1912 show_vrf_vni_cmd,
35be5542 1913 "show vrf vni [json]",
b7cfce93
MK
1914 SHOW_STR
1915 "VRF\n"
35be5542
MK
1916 "VNI\n"
1917 JSON_STR)
b7cfce93
MK
1918{
1919 struct vrf *vrf;
1920 struct zebra_vrf *zvrf;
35be5542
MK
1921 json_object *json = NULL;
1922 json_object *json_vrfs = NULL;
9f049418 1923 bool uj = use_json(argc, argv);
35be5542
MK
1924
1925 if (uj) {
1926 json = json_object_new_object();
1927 json_vrfs = json_object_new_array();
1928 }
b7cfce93 1929
4cce389e 1930 if (!uj)
996c9314
LB
1931 vty_out(vty, "%-37s %-10s %-20s %-20s %-5s %-18s\n", "VRF",
1932 "VNI", "VxLAN IF", "L3-SVI", "State", "Rmac");
4cce389e 1933
996c9314 1934 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
b7cfce93
MK
1935 zvrf = vrf->info;
1936 if (!zvrf)
1937 continue;
1938
4cce389e 1939 zebra_vxlan_print_vrf_vni(vty, zvrf, json_vrfs);
35be5542
MK
1940 }
1941
1942 if (uj) {
1943 json_object_object_add(json, "vrfs", json_vrfs);
1944 vty_out(vty, "%s\n", json_object_to_json_string_ext(
1945 json, JSON_C_TO_STRING_PRETTY));
1946 json_object_free(json);
b7cfce93
MK
1947 }
1948
1949 return CMD_SUCCESS;
1950}
1951
4cce389e
MK
1952DEFUN (show_evpn_global,
1953 show_evpn_global_cmd,
1954 "show evpn [json]",
1955 SHOW_STR
1956 "EVPN\n"
1957 JSON_STR)
1958{
9f049418 1959 bool uj = use_json(argc, argv);
4cce389e
MK
1960
1961 zebra_vxlan_print_evpn(vty, uj);
1962 return CMD_SUCCESS;
1963}
1964
cec2e17d 1965DEFUN (show_evpn_vni,
1966 show_evpn_vni_cmd,
cd233079 1967 "show evpn vni [json]",
cec2e17d 1968 SHOW_STR
1969 "EVPN\n"
09af6961 1970 "VxLAN Network Identifier\n"
bd592158 1971 JSON_STR)
cec2e17d 1972{
d62a17ae 1973 struct zebra_vrf *zvrf;
9f049418 1974 bool uj = use_json(argc, argv);
cec2e17d 1975
530db8dc 1976 zvrf = zebra_vrf_get_evpn();
cd233079 1977 zebra_vxlan_print_vnis(vty, zvrf, uj);
d62a17ae 1978 return CMD_SUCCESS;
cec2e17d 1979}
1980
09af6961
NS
1981DEFUN (show_evpn_vni_detail, show_evpn_vni_detail_cmd,
1982 "show evpn vni detail [json]",
1983 SHOW_STR
1984 "EVPN\n"
1985 "VxLAN Network Identifier\n"
1986 "Detailed Information On Each VNI\n"
1987 JSON_STR)
1988{
1989 struct zebra_vrf *zvrf;
1990 bool uj = use_json(argc, argv);
1991
530db8dc 1992 zvrf = zebra_vrf_get_evpn();
09af6961
NS
1993 zebra_vxlan_print_vnis_detail(vty, zvrf, uj);
1994 return CMD_SUCCESS;
1995}
1996
cec2e17d 1997DEFUN (show_evpn_vni_vni,
1998 show_evpn_vni_vni_cmd,
cd233079 1999 "show evpn vni " CMD_VNI_RANGE "[json]",
cec2e17d 2000 SHOW_STR
2001 "EVPN\n"
2002 "VxLAN Network Identifier\n"
cd233079 2003 "VNI number\n"
bd592158 2004 JSON_STR)
cec2e17d 2005{
d62a17ae 2006 struct zebra_vrf *zvrf;
2007 vni_t vni;
9f049418 2008 bool uj = use_json(argc, argv);
cec2e17d 2009
d62a17ae 2010 vni = strtoul(argv[3]->arg, NULL, 10);
530db8dc 2011 zvrf = zebra_vrf_get_evpn();
cd233079 2012 zebra_vxlan_print_vni(vty, zvrf, vni, uj);
d62a17ae 2013 return CMD_SUCCESS;
cec2e17d 2014}
2015
4cce389e
MK
2016DEFUN (show_evpn_rmac_vni_mac,
2017 show_evpn_rmac_vni_mac_cmd,
2018 "show evpn rmac vni " CMD_VNI_RANGE " mac WORD [json]",
9aa741ea
MK
2019 SHOW_STR
2020 "EVPN\n"
2021 "RMAC\n"
4cce389e 2022 "L3 VNI\n"
9aa741ea
MK
2023 "VNI number\n"
2024 "MAC\n"
316f4ca4
MK
2025 "mac-address (e.g. 0a:0a:0a:0a:0a:0a)\n"
2026 JSON_STR)
9aa741ea
MK
2027{
2028 vni_t l3vni = 0;
2029 struct ethaddr mac;
9f049418 2030 bool uj = use_json(argc, argv);
9aa741ea
MK
2031
2032 l3vni = strtoul(argv[4]->arg, NULL, 10);
2033 if (!prefix_str2mac(argv[6]->arg, &mac)) {
2034 vty_out(vty, "%% Malformed MAC address\n");
2035 return CMD_WARNING;
2036 }
316f4ca4 2037 zebra_vxlan_print_specific_rmac_l3vni(vty, l3vni, &mac, uj);
9aa741ea
MK
2038 return CMD_SUCCESS;
2039}
2040
4cce389e
MK
2041DEFUN (show_evpn_rmac_vni,
2042 show_evpn_rmac_vni_cmd,
2043 "show evpn rmac vni " CMD_VNI_RANGE "[json]",
b7cfce93
MK
2044 SHOW_STR
2045 "EVPN\n"
2046 "RMAC\n"
4cce389e 2047 "L3 VNI\n"
b7cfce93
MK
2048 "VNI number\n"
2049 JSON_STR)
2050{
2051 vni_t l3vni = 0;
9f049418 2052 bool uj = use_json(argc, argv);
b7cfce93
MK
2053
2054 l3vni = strtoul(argv[4]->arg, NULL, 10);
2055 zebra_vxlan_print_rmacs_l3vni(vty, l3vni, uj);
2056
2057 return CMD_SUCCESS;
2058}
2059
4cce389e
MK
2060DEFUN (show_evpn_rmac_vni_all,
2061 show_evpn_rmac_vni_all_cmd,
2062 "show evpn rmac vni all [json]",
b7cfce93
MK
2063 SHOW_STR
2064 "EVPN\n"
2065 "RMAC addresses\n"
4cce389e 2066 "L3 VNI\n"
b7cfce93
MK
2067 "All VNIs\n"
2068 JSON_STR)
2069{
9f049418 2070 bool uj = use_json(argc, argv);
b7cfce93
MK
2071
2072 zebra_vxlan_print_rmacs_all_l3vni(vty, uj);
2073
2074 return CMD_SUCCESS;
2075}
2076
4cce389e
MK
2077DEFUN (show_evpn_nh_vni_ip,
2078 show_evpn_nh_vni_ip_cmd,
2079 "show evpn next-hops vni " CMD_VNI_RANGE " ip WORD [json]",
9aa741ea
MK
2080 SHOW_STR
2081 "EVPN\n"
2082 "Remote Vteps\n"
4cce389e 2083 "L3 VNI\n"
9aa741ea
MK
2084 "VNI number\n"
2085 "Ip address\n"
c0e519d3
MK
2086 "Host address (ipv4 or ipv6)\n"
2087 JSON_STR)
9aa741ea
MK
2088{
2089 vni_t l3vni;
9aa741ea 2090 struct ipaddr ip;
9f049418 2091 bool uj = use_json(argc, argv);
9aa741ea
MK
2092
2093 l3vni = strtoul(argv[4]->arg, NULL, 10);
2094 if (str2ipaddr(argv[6]->arg, &ip) != 0) {
2095 if (!uj)
2096 vty_out(vty, "%% Malformed Neighbor address\n");
2097 return CMD_WARNING;
2098 }
c0e519d3 2099 zebra_vxlan_print_specific_nh_l3vni(vty, l3vni, &ip, uj);
9aa741ea
MK
2100
2101 return CMD_SUCCESS;
2102}
2103
4cce389e
MK
2104DEFUN (show_evpn_nh_vni,
2105 show_evpn_nh_vni_cmd,
2106 "show evpn next-hops vni " CMD_VNI_RANGE "[json]",
b7cfce93
MK
2107 SHOW_STR
2108 "EVPN\n"
2109 "Remote Vteps\n"
4cce389e 2110 "L3 VNI\n"
b7cfce93
MK
2111 "VNI number\n"
2112 JSON_STR)
2113{
2114 vni_t l3vni;
9f049418 2115 bool uj = use_json(argc, argv);
b7cfce93
MK
2116
2117 l3vni = strtoul(argv[4]->arg, NULL, 10);
2118 zebra_vxlan_print_nh_l3vni(vty, l3vni, uj);
2119
2120 return CMD_SUCCESS;
2121}
2122
4cce389e
MK
2123DEFUN (show_evpn_nh_vni_all,
2124 show_evpn_nh_vni_all_cmd,
2125 "show evpn next-hops vni all [json]",
b7cfce93
MK
2126 SHOW_STR
2127 "EVPN\n"
2128 "Remote VTEPs\n"
4cce389e 2129 "L3 VNI\n"
b7cfce93
MK
2130 "All VNIs\n"
2131 JSON_STR)
2132{
9f049418 2133 bool uj = use_json(argc, argv);
b7cfce93
MK
2134
2135 zebra_vxlan_print_nh_all_l3vni(vty, uj);
2136
2137 return CMD_SUCCESS;
2138}
2139
cec2e17d 2140DEFUN (show_evpn_mac_vni,
2141 show_evpn_mac_vni_cmd,
cd233079 2142 "show evpn mac vni " CMD_VNI_RANGE "[json]",
cec2e17d 2143 SHOW_STR
2144 "EVPN\n"
2145 "MAC addresses\n"
2146 "VxLAN Network Identifier\n"
cd233079 2147 "VNI number\n"
bd592158 2148 JSON_STR)
cec2e17d 2149{
d62a17ae 2150 struct zebra_vrf *zvrf;
2151 vni_t vni;
9f049418 2152 bool uj = use_json(argc, argv);
cec2e17d 2153
d62a17ae 2154 vni = strtoul(argv[4]->arg, NULL, 10);
530db8dc 2155 zvrf = zebra_vrf_get_evpn();
cd233079 2156 zebra_vxlan_print_macs_vni(vty, zvrf, vni, uj);
d62a17ae 2157 return CMD_SUCCESS;
cec2e17d 2158}
2159
2160DEFUN (show_evpn_mac_vni_all,
2161 show_evpn_mac_vni_all_cmd,
cd233079 2162 "show evpn mac vni all [json]",
cec2e17d 2163 SHOW_STR
2164 "EVPN\n"
2165 "MAC addresses\n"
2166 "VxLAN Network Identifier\n"
cd233079 2167 "All VNIs\n"
bd592158 2168 JSON_STR)
cec2e17d 2169{
d62a17ae 2170 struct zebra_vrf *zvrf;
9f049418 2171 bool uj = use_json(argc, argv);
cec2e17d 2172
530db8dc 2173 zvrf = zebra_vrf_get_evpn();
1374d4db 2174 zebra_vxlan_print_macs_all_vni(vty, zvrf, false, uj);
d62a17ae 2175 return CMD_SUCCESS;
cec2e17d 2176}
2177
cffe7580
NS
2178DEFUN (show_evpn_mac_vni_all_detail, show_evpn_mac_vni_all_detail_cmd,
2179 "show evpn mac vni all detail [json]",
2180 SHOW_STR
2181 "EVPN\n"
2182 "MAC addresses\n"
2183 "VxLAN Network Identifier\n"
2184 "All VNIs\n"
2185 "Detailed Information On Each VNI MAC\n"
2186 JSON_STR)
2187{
2188 struct zebra_vrf *zvrf;
2189 bool uj = use_json(argc, argv);
2190
530db8dc 2191 zvrf = zebra_vrf_get_evpn();
cffe7580
NS
2192 zebra_vxlan_print_macs_all_vni_detail(vty, zvrf, false, uj);
2193 return CMD_SUCCESS;
2194}
2195
cec2e17d 2196DEFUN (show_evpn_mac_vni_all_vtep,
2197 show_evpn_mac_vni_all_vtep_cmd,
cd233079 2198 "show evpn mac vni all vtep A.B.C.D [json]",
cec2e17d 2199 SHOW_STR
2200 "EVPN\n"
2201 "MAC addresses\n"
2202 "VxLAN Network Identifier\n"
2203 "All VNIs\n"
2204 "Remote VTEP\n"
cd233079 2205 "Remote VTEP IP address\n"
bd592158 2206 JSON_STR)
cec2e17d 2207{
d62a17ae 2208 struct zebra_vrf *zvrf;
2209 struct in_addr vtep_ip;
9f049418 2210 bool uj = use_json(argc, argv);
cec2e17d 2211
d62a17ae 2212 if (!inet_aton(argv[6]->arg, &vtep_ip)) {
cd233079
CS
2213 if (!uj)
2214 vty_out(vty, "%% Malformed VTEP IP address\n");
d62a17ae 2215 return CMD_WARNING;
2216 }
530db8dc 2217 zvrf = zebra_vrf_get_evpn();
cd233079 2218 zebra_vxlan_print_macs_all_vni_vtep(vty, zvrf, vtep_ip, uj);
cec2e17d 2219
d62a17ae 2220 return CMD_SUCCESS;
cec2e17d 2221}
2222
2223
2224DEFUN (show_evpn_mac_vni_mac,
2225 show_evpn_mac_vni_mac_cmd,
24cdbd0d 2226 "show evpn mac vni " CMD_VNI_RANGE " mac WORD [json]",
cec2e17d 2227 SHOW_STR
2228 "EVPN\n"
2229 "MAC addresses\n"
2230 "VxLAN Network Identifier\n"
2231 "VNI number\n"
2232 "MAC\n"
24cdbd0d
DS
2233 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2234 JSON_STR)
2235
cec2e17d 2236{
d62a17ae 2237 struct zebra_vrf *zvrf;
2238 vni_t vni;
2239 struct ethaddr mac;
24cdbd0d 2240 bool uj = use_json(argc, argv);
cec2e17d 2241
d62a17ae 2242 vni = strtoul(argv[4]->arg, NULL, 10);
2243 if (!prefix_str2mac(argv[6]->arg, &mac)) {
2244 vty_out(vty, "%% Malformed MAC address");
2245 return CMD_WARNING;
2246 }
530db8dc 2247 zvrf = zebra_vrf_get_evpn();
24cdbd0d 2248 zebra_vxlan_print_specific_mac_vni(vty, zvrf, vni, &mac, uj);
d62a17ae 2249 return CMD_SUCCESS;
cec2e17d 2250}
2251
2252DEFUN (show_evpn_mac_vni_vtep,
2253 show_evpn_mac_vni_vtep_cmd,
cd233079 2254 "show evpn mac vni " CMD_VNI_RANGE " vtep A.B.C.D" "[json]",
cec2e17d 2255 SHOW_STR
2256 "EVPN\n"
2257 "MAC addresses\n"
2258 "VxLAN Network Identifier\n"
2259 "VNI number\n"
2260 "Remote VTEP\n"
cd233079 2261 "Remote VTEP IP address\n"
bd592158 2262 JSON_STR)
cec2e17d 2263{
d62a17ae 2264 struct zebra_vrf *zvrf;
2265 vni_t vni;
2266 struct in_addr vtep_ip;
9f049418 2267 bool uj = use_json(argc, argv);
cec2e17d 2268
d62a17ae 2269 vni = strtoul(argv[4]->arg, NULL, 10);
2270 if (!inet_aton(argv[6]->arg, &vtep_ip)) {
cd233079
CS
2271 if (!uj)
2272 vty_out(vty, "%% Malformed VTEP IP address\n");
d62a17ae 2273 return CMD_WARNING;
2274 }
cec2e17d 2275
530db8dc 2276 zvrf = zebra_vrf_get_evpn();
cd233079 2277 zebra_vxlan_print_macs_vni_vtep(vty, zvrf, vni, vtep_ip, uj);
d62a17ae 2278 return CMD_SUCCESS;
cec2e17d 2279}
2280
1374d4db
CS
2281DEFPY (show_evpn_mac_vni_all_dad,
2282 show_evpn_mac_vni_all_dad_cmd,
2283 "show evpn mac vni all duplicate [json]",
2284 SHOW_STR
2285 "EVPN\n"
2286 "MAC addresses\n"
2287 "VxLAN Network Identifier\n"
2288 "All VNIs\n"
2289 "Duplicate address list\n"
2290 JSON_STR)
2291{
2292 struct zebra_vrf *zvrf;
2293 bool uj = use_json(argc, argv);
2294
530db8dc 2295 zvrf = zebra_vrf_get_evpn();
1374d4db
CS
2296 zebra_vxlan_print_macs_all_vni(vty, zvrf, true, uj);
2297 return CMD_SUCCESS;
2298}
2299
2300
2301DEFPY (show_evpn_mac_vni_dad,
2302 show_evpn_mac_vni_dad_cmd,
b41b3f7b 2303 "show evpn mac vni " CMD_VNI_RANGE " duplicate [json]",
1374d4db
CS
2304 SHOW_STR
2305 "EVPN\n"
2306 "MAC addresses\n"
2307 "VxLAN Network Identifier\n"
2308 "VNI number\n"
2309 "Duplicate address list\n"
2310 JSON_STR)
2311{
2312 struct zebra_vrf *zvrf;
1374d4db
CS
2313 bool uj = use_json(argc, argv);
2314
530db8dc 2315 zvrf = zebra_vrf_get_evpn();
1374d4db
CS
2316
2317 zebra_vxlan_print_macs_vni_dad(vty, zvrf, vni, uj);
2318
2319 return CMD_SUCCESS;
2320}
2321
2322DEFPY (show_evpn_neigh_vni_dad,
2323 show_evpn_neigh_vni_dad_cmd,
b41b3f7b 2324 "show evpn arp-cache vni " CMD_VNI_RANGE "duplicate [json]",
1374d4db
CS
2325 SHOW_STR
2326 "EVPN\n"
2327 "ARP and ND cache\n"
2328 "VxLAN Network Identifier\n"
2329 "VNI number\n"
2330 "Duplicate address list\n"
2331 JSON_STR)
2332{
2333 struct zebra_vrf *zvrf;
1374d4db
CS
2334 bool uj = use_json(argc, argv);
2335
530db8dc 2336 zvrf = zebra_vrf_get_evpn();
1374d4db
CS
2337 zebra_vxlan_print_neigh_vni_dad(vty, zvrf, vni, uj);
2338 return CMD_SUCCESS;
2339}
2340
2341DEFPY (show_evpn_neigh_vni_all_dad,
2342 show_evpn_neigh_vni_all_dad_cmd,
2343 "show evpn arp-cache vni all duplicate [json]",
2344 SHOW_STR
2345 "EVPN\n"
2346 "ARP and ND cache\n"
2347 "VxLAN Network Identifier\n"
2348 "All VNIs\n"
2349 "Duplicate address list\n"
2350 JSON_STR)
2351{
2352 struct zebra_vrf *zvrf;
2353 bool uj = use_json(argc, argv);
2354
530db8dc 2355 zvrf = zebra_vrf_get_evpn();
1374d4db
CS
2356 zebra_vxlan_print_neigh_all_vni(vty, zvrf, true, uj);
2357 return CMD_SUCCESS;
2358}
2359
2360
cec2e17d 2361DEFUN (show_evpn_neigh_vni,
2362 show_evpn_neigh_vni_cmd,
cd233079 2363 "show evpn arp-cache vni " CMD_VNI_RANGE "[json]",
cec2e17d 2364 SHOW_STR
2365 "EVPN\n"
2366 "ARP and ND cache\n"
2367 "VxLAN Network Identifier\n"
cd233079 2368 "VNI number\n"
bd592158 2369 JSON_STR)
cec2e17d 2370{
d62a17ae 2371 struct zebra_vrf *zvrf;
2372 vni_t vni;
9f049418 2373 bool uj = use_json(argc, argv);
cec2e17d 2374
d62a17ae 2375 vni = strtoul(argv[4]->arg, NULL, 10);
530db8dc 2376 zvrf = zebra_vrf_get_evpn();
cd233079 2377 zebra_vxlan_print_neigh_vni(vty, zvrf, vni, uj);
d62a17ae 2378 return CMD_SUCCESS;
cec2e17d 2379}
2380
2381DEFUN (show_evpn_neigh_vni_all,
2382 show_evpn_neigh_vni_all_cmd,
cd233079 2383 "show evpn arp-cache vni all [json]",
cec2e17d 2384 SHOW_STR
2385 "EVPN\n"
2386 "ARP and ND cache\n"
2387 "VxLAN Network Identifier\n"
cd233079 2388 "All VNIs\n"
bd592158 2389 JSON_STR)
cec2e17d 2390{
d62a17ae 2391 struct zebra_vrf *zvrf;
9f049418 2392 bool uj = use_json(argc, argv);
cec2e17d 2393
530db8dc 2394 zvrf = zebra_vrf_get_evpn();
1374d4db 2395 zebra_vxlan_print_neigh_all_vni(vty, zvrf, false, uj);
d62a17ae 2396 return CMD_SUCCESS;
cec2e17d 2397}
2398
e3fac919
NS
2399DEFUN (show_evpn_neigh_vni_all_detail, show_evpn_neigh_vni_all_detail_cmd,
2400 "show evpn arp-cache vni all detail [json]",
2401 SHOW_STR
2402 "EVPN\n"
2403 "ARP and ND cache\n"
2404 "VxLAN Network Identifier\n"
2405 "All VNIs\n"
2406 "Neighbor details for all vnis in detail\n" JSON_STR)
2407{
2408 struct zebra_vrf *zvrf;
2409 bool uj = use_json(argc, argv);
2410
530db8dc 2411 zvrf = zebra_vrf_get_evpn();
e3fac919
NS
2412 zebra_vxlan_print_neigh_all_vni_detail(vty, zvrf, false, uj);
2413 return CMD_SUCCESS;
2414}
2415
cec2e17d 2416DEFUN (show_evpn_neigh_vni_neigh,
2417 show_evpn_neigh_vni_neigh_cmd,
cd233079 2418 "show evpn arp-cache vni " CMD_VNI_RANGE " ip WORD [json]",
cec2e17d 2419 SHOW_STR
2420 "EVPN\n"
2421 "ARP and ND cache\n"
2422 "VxLAN Network Identifier\n"
2423 "VNI number\n"
2424 "Neighbor\n"
cd233079 2425 "Neighbor address (IPv4 or IPv6 address)\n"
bd592158 2426 JSON_STR)
cec2e17d 2427{
d62a17ae 2428 struct zebra_vrf *zvrf;
2429 vni_t vni;
2430 struct ipaddr ip;
9f049418 2431 bool uj = use_json(argc, argv);
cec2e17d 2432
d62a17ae 2433 vni = strtoul(argv[4]->arg, NULL, 10);
2434 if (str2ipaddr(argv[6]->arg, &ip) != 0) {
cd233079
CS
2435 if (!uj)
2436 vty_out(vty, "%% Malformed Neighbor address\n");
d62a17ae 2437 return CMD_WARNING;
2438 }
530db8dc 2439 zvrf = zebra_vrf_get_evpn();
cd233079 2440 zebra_vxlan_print_specific_neigh_vni(vty, zvrf, vni, &ip, uj);
d62a17ae 2441 return CMD_SUCCESS;
cec2e17d 2442}
2443
2444DEFUN (show_evpn_neigh_vni_vtep,
2445 show_evpn_neigh_vni_vtep_cmd,
cd233079 2446 "show evpn arp-cache vni " CMD_VNI_RANGE " vtep A.B.C.D [json]",
cec2e17d 2447 SHOW_STR
2448 "EVPN\n"
2449 "ARP and ND cache\n"
2450 "VxLAN Network Identifier\n"
2451 "VNI number\n"
2452 "Remote VTEP\n"
cd233079 2453 "Remote VTEP IP address\n"
bd592158 2454 JSON_STR)
cec2e17d 2455{
d62a17ae 2456 struct zebra_vrf *zvrf;
2457 vni_t vni;
2458 struct in_addr vtep_ip;
9f049418 2459 bool uj = use_json(argc, argv);
cec2e17d 2460
d62a17ae 2461 vni = strtoul(argv[4]->arg, NULL, 10);
2462 if (!inet_aton(argv[6]->arg, &vtep_ip)) {
cd233079
CS
2463 if (!uj)
2464 vty_out(vty, "%% Malformed VTEP IP address\n");
d62a17ae 2465 return CMD_WARNING;
2466 }
cec2e17d 2467
530db8dc 2468 zvrf = zebra_vrf_get_evpn();
cd233079 2469 zebra_vxlan_print_neigh_vni_vtep(vty, zvrf, vni, vtep_ip, uj);
d62a17ae 2470 return CMD_SUCCESS;
cec2e17d 2471}
2472
586f4ccf
PG
2473/* policy routing contexts */
2474DEFUN (show_pbr_ipset,
2475 show_pbr_ipset_cmd,
2476 "show pbr ipset [WORD]",
2477 SHOW_STR
2478 "Policy-Based Routing\n"
2479 "IPset Context information\n"
2480 "IPset Name information\n")
2481{
2482 int idx = 0;
2483 int found = 0;
2484 found = argv_find(argv, argc, "WORD", &idx);
2485 if (!found)
2486 zebra_pbr_show_ipset_list(vty, NULL);
2487 else
2488 zebra_pbr_show_ipset_list(vty, argv[idx]->arg);
2489 return CMD_SUCCESS;
2490}
2491
2492/* policy routing contexts */
2493DEFUN (show_pbr_iptable,
2494 show_pbr_iptable_cmd,
7929821a 2495 "show pbr iptable [WORD]",
586f4ccf
PG
2496 SHOW_STR
2497 "Policy-Based Routing\n"
7929821a
PG
2498 "IPtable Context information\n"
2499 "IPtable Name information\n")
586f4ccf 2500{
7929821a
PG
2501 int idx = 0;
2502 int found = 0;
2503
2504 found = argv_find(argv, argc, "WORD", &idx);
2505 if (!found)
2506 zebra_pbr_show_iptable(vty, NULL);
2507 else
2508 zebra_pbr_show_iptable(vty, argv[idx]->arg);
586f4ccf
PG
2509 return CMD_SUCCESS;
2510}
2511
09de9258
CS
2512DEFPY (clear_evpn_dup_addr,
2513 clear_evpn_dup_addr_cmd,
f65d330c 2514 "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
2515 CLEAR_STR
2516 "EVPN\n"
2517 "Duplicate address \n"
2518 "VxLAN Network Identifier\n"
2519 "VNI number\n"
2520 "All VNIs\n"
2521 "MAC\n"
2522 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2523 "IP\n"
2524 "IPv4 address\n"
2525 "IPv6 address\n")
2526{
2527 struct zebra_vrf *zvrf;
09de9258 2528 struct ipaddr host_ip = {.ipa_type = IPADDR_NONE };
1883de66 2529 int ret = CMD_SUCCESS;
09de9258 2530
530db8dc 2531 zvrf = zebra_vrf_get_evpn();
b41b3f7b 2532 if (vni_str) {
155b4398 2533 if (!is_zero_mac(&mac->eth_addr)) {
1883de66
CS
2534 ret = zebra_vxlan_clear_dup_detect_vni_mac(vty, zvrf,
2535 vni,
f65d330c 2536 &mac->eth_addr);
1883de66 2537 } else if (ip) {
09de9258
CS
2538 if (sockunion_family(ip) == AF_INET) {
2539 host_ip.ipa_type = IPADDR_V4;
2540 host_ip.ipaddr_v4.s_addr = sockunion2ip(ip);
2541 } else {
2542 host_ip.ipa_type = IPADDR_V6;
2543 memcpy(&host_ip.ipaddr_v6, &ip->sin6.sin6_addr,
2544 sizeof(struct in6_addr));
2545 }
1883de66
CS
2546 ret = zebra_vxlan_clear_dup_detect_vni_ip(vty, zvrf,
2547 vni,
2548 &host_ip);
09de9258 2549 } else
1883de66 2550 ret = zebra_vxlan_clear_dup_detect_vni(vty, zvrf, vni);
09de9258
CS
2551
2552 } else {
1883de66 2553 ret = zebra_vxlan_clear_dup_detect_vni_all(vty, zvrf);
09de9258
CS
2554 }
2555
1883de66 2556 return ret;
09de9258
CS
2557}
2558
718e3744 2559/* Static ip route configuration write function. */
d62a17ae 2560static int zebra_ip_config(struct vty *vty)
718e3744 2561{
d62a17ae 2562 int write = 0;
718e3744 2563
fe257ae7 2564 write += zebra_import_table_config(vty, VRF_DEFAULT);
37728041 2565
d62a17ae 2566 return write;
718e3744 2567}
2568
7a4bb9c5
DS
2569DEFUN (ip_zebra_import_table_distance,
2570 ip_zebra_import_table_distance_cmd,
12dcf78e 2571 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
8902474b
DS
2572 IP_STR
2573 "import routes from non-main kernel table\n"
2574 "kernel routing table id\n"
2575 "Distance for imported routes\n"
2576 "Default distance value\n"
2577 "route-map for filtering\n"
2578 "route-map name\n")
2579{
d7c0a89a 2580 uint32_t table_id = 0;
8902474b 2581
d62a17ae 2582 table_id = strtoul(argv[2]->arg, NULL, 10);
2583 int distance = ZEBRA_TABLE_DISTANCE_DEFAULT;
2584 char *rmap =
2585 strmatch(argv[argc - 2]->text, "route-map")
2586 ? XSTRDUP(MTYPE_ROUTE_MAP_NAME, argv[argc - 1]->arg)
2587 : NULL;
2588 int ret;
d722f26e 2589
d62a17ae 2590 if (argc == 7 || (argc == 5 && !rmap))
2591 distance = strtoul(argv[4]->arg, NULL, 10);
8902474b 2592
d62a17ae 2593 if (!is_zebra_valid_kernel_table(table_id)) {
2594 vty_out(vty,
2595 "Invalid routing table ID, %d. Must be in range 1-252\n",
2596 table_id);
0af35d90
RW
2597 if (rmap)
2598 XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
d62a17ae 2599 return CMD_WARNING;
2600 }
8902474b 2601
d62a17ae 2602 if (is_zebra_main_routing_table(table_id)) {
2603 vty_out(vty,
2604 "Invalid routing table ID, %d. Must be non-default table\n",
2605 table_id);
0af35d90
RW
2606 if (rmap)
2607 XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
d62a17ae 2608 return CMD_WARNING;
2609 }
8902474b 2610
fe257ae7
DS
2611 ret = zebra_import_table(AFI_IP, VRF_DEFAULT, table_id,
2612 distance, rmap, 1);
d62a17ae 2613 if (rmap)
2614 XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
d722f26e 2615
d62a17ae 2616 return ret;
8902474b
DS
2617}
2618
62d52ded
DS
2619DEFUN_HIDDEN (zebra_packet_process,
2620 zebra_packet_process_cmd,
2621 "zebra zapi-packets (1-10000)",
2622 ZEBRA_STR
2623 "Zapi Protocol\n"
2624 "Number of packets to process before relinquishing thread\n")
2625{
2626 uint32_t packets = strtoul(argv[2]->arg, NULL, 10);
2627
5ec5a716 2628 atomic_store_explicit(&zrouter.packets_to_process, packets,
ccd51bd2 2629 memory_order_relaxed);
62d52ded
DS
2630
2631 return CMD_SUCCESS;
2632}
2633
2634DEFUN_HIDDEN (no_zebra_packet_process,
2635 no_zebra_packet_process_cmd,
2636 "no zebra zapi-packets [(1-10000)]",
2637 NO_STR
2638 ZEBRA_STR
2639 "Zapi Protocol\n"
2640 "Number of packets to process before relinquishing thread\n")
2641{
5ec5a716 2642 atomic_store_explicit(&zrouter.packets_to_process,
ccd51bd2
QY
2643 ZEBRA_ZAPI_PACKETS_TO_PROCESS,
2644 memory_order_relaxed);
62d52ded
DS
2645
2646 return CMD_SUCCESS;
2647}
2648
3a30f50f
DS
2649DEFUN_HIDDEN (zebra_workqueue_timer,
2650 zebra_workqueue_timer_cmd,
2651 "zebra work-queue (0-10000)",
2652 ZEBRA_STR
2653 "Work Queue\n"
2654 "Time in milliseconds\n")
2655{
996c9314 2656 uint32_t timer = strtoul(argv[2]->arg, NULL, 10);
489a9614 2657 zrouter.ribq->spec.hold = timer;
3a30f50f 2658
996c9314 2659 return CMD_SUCCESS;
3a30f50f
DS
2660}
2661
2662DEFUN_HIDDEN (no_zebra_workqueue_timer,
2663 no_zebra_workqueue_timer_cmd,
2664 "no zebra work-queue [(0-10000)]",
2665 NO_STR
2666 ZEBRA_STR
2667 "Work Queue\n"
2668 "Time in milliseconds\n")
2669{
489a9614 2670 zrouter.ribq->spec.hold = ZEBRA_RIB_PROCESS_HOLD_TIME;
3a30f50f 2671
996c9314 2672 return CMD_SUCCESS;
3a30f50f
DS
2673}
2674
7a4bb9c5
DS
2675DEFUN (no_ip_zebra_import_table,
2676 no_ip_zebra_import_table_cmd,
b62ecea5 2677 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
7a4bb9c5
DS
2678 NO_STR
2679 IP_STR
2680 "import routes from non-main kernel table\n"
3a2d747c
QY
2681 "kernel routing table id\n"
2682 "Distance for imported routes\n"
2683 "Default distance value\n"
2684 "route-map for filtering\n"
2685 "route-map name\n")
7a4bb9c5 2686{
d7c0a89a 2687 uint32_t table_id = 0;
d62a17ae 2688 table_id = strtoul(argv[3]->arg, NULL, 10);
7a4bb9c5 2689
d62a17ae 2690 if (!is_zebra_valid_kernel_table(table_id)) {
2691 vty_out(vty,
2692 "Invalid routing table ID. Must be in range 1-252\n");
2693 return CMD_WARNING;
2694 }
7a4bb9c5 2695
d62a17ae 2696 if (is_zebra_main_routing_table(table_id)) {
2697 vty_out(vty,
2698 "Invalid routing table ID, %d. Must be non-default table\n",
2699 table_id);
2700 return CMD_WARNING;
2701 }
7a4bb9c5 2702
fe257ae7 2703 if (!is_zebra_import_table_enabled(AFI_IP, VRF_DEFAULT, table_id))
d62a17ae 2704 return CMD_SUCCESS;
7a4bb9c5 2705
fe257ae7 2706 return (zebra_import_table(AFI_IP, VRF_DEFAULT, table_id, 0, NULL, 0));
7a4bb9c5
DS
2707}
2708
d62a17ae 2709static int config_write_protocol(struct vty *vty)
6baf7bb8 2710{
d62a17ae 2711 if (allow_delete)
2712 vty_out(vty, "allow-external-route-update\n");
6baf7bb8 2713
489a9614
DS
2714 if (zrouter.ribq->spec.hold != ZEBRA_RIB_PROCESS_HOLD_TIME)
2715 vty_out(vty, "zebra work-queue %u\n", zrouter.ribq->spec.hold);
3a30f50f 2716
5ec5a716 2717 if (zrouter.packets_to_process != ZEBRA_ZAPI_PACKETS_TO_PROCESS)
996c9314 2718 vty_out(vty, "zebra zapi-packets %u\n",
5ec5a716 2719 zrouter.packets_to_process);
62d52ded 2720
d62a17ae 2721 enum multicast_mode ipv4_multicast_mode = multicast_mode_ipv4_get();
4623d897 2722
d62a17ae 2723 if (ipv4_multicast_mode != MCAST_NO_CONFIG)
2724 vty_out(vty, "ip multicast rpf-lookup-mode %s\n",
2725 ipv4_multicast_mode == MCAST_URIB_ONLY
2726 ? "urib-only"
2727 : ipv4_multicast_mode == MCAST_MRIB_ONLY
2728 ? "mrib-only"
2729 : ipv4_multicast_mode
2730 == MCAST_MIX_MRIB_FIRST
2731 ? "mrib-then-urib"
2732 : ipv4_multicast_mode
2733 == MCAST_MIX_DISTANCE
2734 ? "lower-distance"
2735 : "longer-prefix");
f26730e1
MS
2736
2737 /* Include dataplane info */
2738 dplane_config_write_helper(vty);
2739
d62a17ae 2740 return 1;
6baf7bb8
DS
2741}
2742
c0d136ae
DS
2743DEFUN (show_zebra,
2744 show_zebra_cmd,
2745 "show zebra",
2746 SHOW_STR
2747 ZEBRA_STR)
2748{
2749 struct vrf *vrf;
2750
2751 vty_out(vty,
2752 " Route Route Neighbor LSP LSP\n");
2753 vty_out(vty,
2754 "VRF Installs Removals Updates Installs Removals\n");
2755
996c9314 2756 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
c0d136ae
DS
2757 struct zebra_vrf *zvrf = vrf->info;
2758
2759 vty_out(vty, "%-25s %10" PRIu64 " %10" PRIu64 " %10" PRIu64
2760 " %10" PRIu64 " %10" PRIu64 "\n",
2761 vrf->name, zvrf->installs, zvrf->removals,
2762 zvrf->neigh_updates, zvrf->lsp_installs,
2763 zvrf->lsp_removals);
2764 }
2765
2766 return CMD_SUCCESS;
2767}
2768
2769DEFUN (ip_forwarding,
2770 ip_forwarding_cmd,
2771 "ip forwarding",
2772 IP_STR
2773 "Turn on IP forwarding\n")
2774{
2775 int ret;
2776
2777 ret = ipforward();
2778 if (ret == 0)
2779 ret = ipforward_on();
2780
2781 if (ret == 0) {
2782 vty_out(vty, "Can't turn on IP forwarding\n");
2783 return CMD_WARNING_CONFIG_FAILED;
2784 }
2785
2786 return CMD_SUCCESS;
2787}
2788
2789DEFUN (no_ip_forwarding,
2790 no_ip_forwarding_cmd,
2791 "no ip forwarding",
2792 NO_STR
2793 IP_STR
2794 "Turn off IP forwarding\n")
2795{
2796 int ret;
2797
2798 ret = ipforward();
2799 if (ret != 0)
2800 ret = ipforward_off();
2801
2802 if (ret != 0) {
2803 vty_out(vty, "Can't turn off IP forwarding\n");
2804 return CMD_WARNING_CONFIG_FAILED;
2805 }
2806
2807 return CMD_SUCCESS;
2808}
2809
2810/* Only display ip forwarding is enabled or not. */
2811DEFUN (show_ip_forwarding,
2812 show_ip_forwarding_cmd,
2813 "show ip forwarding",
2814 SHOW_STR
2815 IP_STR
2816 "IP forwarding status\n")
2817{
2818 int ret;
2819
2820 ret = ipforward();
2821
2822 if (ret == 0)
2823 vty_out(vty, "IP forwarding is off\n");
2824 else
2825 vty_out(vty, "IP forwarding is on\n");
2826 return CMD_SUCCESS;
2827}
2828
2829/* Only display ipv6 forwarding is enabled or not. */
2830DEFUN (show_ipv6_forwarding,
2831 show_ipv6_forwarding_cmd,
2832 "show ipv6 forwarding",
2833 SHOW_STR
2834 "IPv6 information\n"
2835 "Forwarding status\n")
2836{
2837 int ret;
2838
2839 ret = ipforward_ipv6();
2840
2841 switch (ret) {
2842 case -1:
2843 vty_out(vty, "ipv6 forwarding is unknown\n");
2844 break;
2845 case 0:
2846 vty_out(vty, "ipv6 forwarding is %s\n", "off");
2847 break;
2848 case 1:
2849 vty_out(vty, "ipv6 forwarding is %s\n", "on");
2850 break;
2851 default:
2852 vty_out(vty, "ipv6 forwarding is %s\n", "off");
2853 break;
2854 }
2855 return CMD_SUCCESS;
2856}
2857
2858DEFUN (ipv6_forwarding,
2859 ipv6_forwarding_cmd,
2860 "ipv6 forwarding",
2861 IPV6_STR
2862 "Turn on IPv6 forwarding\n")
2863{
2864 int ret;
2865
2866 ret = ipforward_ipv6();
2867 if (ret == 0)
2868 ret = ipforward_ipv6_on();
2869
2870 if (ret == 0) {
2871 vty_out(vty, "Can't turn on IPv6 forwarding\n");
2872 return CMD_WARNING_CONFIG_FAILED;
2873 }
2874
2875 return CMD_SUCCESS;
2876}
2877
2878DEFUN (no_ipv6_forwarding,
2879 no_ipv6_forwarding_cmd,
2880 "no ipv6 forwarding",
2881 NO_STR
2882 IPV6_STR
2883 "Turn off IPv6 forwarding\n")
2884{
2885 int ret;
2886
2887 ret = ipforward_ipv6();
2888 if (ret != 0)
2889 ret = ipforward_ipv6_off();
2890
2891 if (ret != 0) {
2892 vty_out(vty, "Can't turn off IPv6 forwarding\n");
2893 return CMD_WARNING_CONFIG_FAILED;
2894 }
2895
2896 return CMD_SUCCESS;
2897}
2898
1d11b21f
MS
2899/* Display dataplane info */
2900DEFUN (show_dataplane,
2901 show_dataplane_cmd,
2902 "show zebra dplane [detailed]",
2903 SHOW_STR
2904 ZEBRA_STR
2905 "Zebra dataplane information\n"
2906 "Detailed output\n")
2907{
2908 int idx = 0;
2909 bool detailed = false;
2910
2911 if (argv_find(argv, argc, "detailed", &idx))
2912 detailed = true;
2913
2914 return dplane_show_helper(vty, detailed);
2915}
2916
2917/* Display dataplane providers info */
2918DEFUN (show_dataplane_providers,
2919 show_dataplane_providers_cmd,
2920 "show zebra dplane providers [detailed]",
2921 SHOW_STR
2922 ZEBRA_STR
2923 "Zebra dataplane information\n"
2924 "Zebra dataplane provider information\n"
2925 "Detailed output\n")
2926{
2927 int idx = 0;
2928 bool detailed = false;
2929
2930 if (argv_find(argv, argc, "detailed", &idx))
2931 detailed = true;
2932
2933 return dplane_show_provs_helper(vty, detailed);
2934}
2935
91f16812
MS
2936/* Configure dataplane incoming queue limit */
2937DEFUN (zebra_dplane_queue_limit,
2938 zebra_dplane_queue_limit_cmd,
2939 "zebra dplane limit (0-10000)",
2940 ZEBRA_STR
2941 "Zebra dataplane\n"
2942 "Limit incoming queued updates\n"
2943 "Number of queued updates\n")
2944{
2945 uint32_t limit = 0;
2946
2947 limit = strtoul(argv[3]->arg, NULL, 10);
2948
2949 dplane_set_in_queue_limit(limit, true);
2950
2951 return CMD_SUCCESS;
2952}
2953
2954/* Reset dataplane queue limit to default value */
2955DEFUN (no_zebra_dplane_queue_limit,
2956 no_zebra_dplane_queue_limit_cmd,
2957 "no zebra dplane limit [(0-10000)]",
2958 NO_STR
2959 ZEBRA_STR
2960 "Zebra dataplane\n"
2961 "Limit incoming queued updates\n"
2962 "Number of queued updates\n")
2963{
2964 dplane_set_in_queue_limit(0, false);
2965
2966 return CMD_SUCCESS;
2967}
1d11b21f 2968
ac5aa23f
DS
2969DEFUN (zebra_show_routing_tables_summary,
2970 zebra_show_routing_tables_summary_cmd,
2971 "show zebra router table summary",
2972 SHOW_STR
2973 ZEBRA_STR
2974 "The Zebra Router Information\n"
2975 "Table Information about this Zebra Router\n"
2976 "Summary Information\n")
2977{
2978 zebra_router_show_table_summary(vty);
2979
2980 return CMD_SUCCESS;
2981}
2982
c0d136ae
DS
2983/* Table configuration write function. */
2984static int config_write_table(struct vty *vty)
2985{
c0d136ae
DS
2986 return 0;
2987}
2988
2989/* IPForwarding configuration write function. */
2990static int config_write_forwarding(struct vty *vty)
2991{
2992 /* FIXME: Find better place for that. */
2993 router_id_write(vty);
2994
2995 if (!ipforward())
2996 vty_out(vty, "no ip forwarding\n");
2997 if (!ipforward_ipv6())
2998 vty_out(vty, "no ipv6 forwarding\n");
2999 vty_out(vty, "!\n");
3000 return 0;
3001}
3002
d2f5903b
DS
3003DEFUN_HIDDEN (show_frr,
3004 show_frr_cmd,
3005 "show frr",
3006 SHOW_STR
3007 "FRR\n")
3008{
3009 vty_out(vty, "........ .. . .. . ..... ...77:................................................\n");
3010 vty_out(vty, ".............................7777:..............................................\n");
3011 vty_out(vty, ".............................777777,............................................\n");
3012 vty_out(vty, "... .........................77777777,..........................................\n");
3013 vty_out(vty, "............................=7777777777:........................................\n");
3014 vty_out(vty, "........................:7777777777777777,......................................\n");
3015 vty_out(vty, ".................... ~7777777777777?~,..........................................\n");
3016 vty_out(vty, "...................I7777777777+.................................................\n");
3017 vty_out(vty, "................,777777777?............ .......................................\n");
3018 vty_out(vty, "..............:77777777?..........~?77777.......................................\n");
3019 vty_out(vty, ".............77777777~........=7777777777.......................................\n");
3020 vty_out(vty, ".......... +7777777,.......?7777777777777.......................................\n");
3021 vty_out(vty, "..........7777777~......:7777777777777777......77?,.............................\n");
3022 vty_out(vty, "........:777777?......+777777777777777777......777777I,.........................\n");
3023 vty_out(vty, ".......?777777,.....+77777777777777777777......777777777?.......................\n");
3024 vty_out(vty, "......?777777......7777777777777777777777......,?777777777?.....................\n");
3025 vty_out(vty, ".....?77777?.....=7777777777777777777I~............,I7777777~...................\n");
3026 vty_out(vty, "....+77777+.....I77777777777777777:...................+777777I..................\n");
3027 vty_out(vty, "...~77777+.....7777777777777777=........................?777777...... .......\n");
3028 vty_out(vty, "...77777I.....I77777777777777~.........:?................,777777.....I777.......\n");
3029 vty_out(vty, "..777777.....I7777777777777I .......?7777..................777777.....777?......\n");
3030 vty_out(vty, ".~77777,....=7777777777777:......,7777777..................,77777+....+777......\n");
3031 vty_out(vty, ".77777I.....7777777777777,......777777777.......ONNNN.......=77777.....777~.....\n");
3032 vty_out(vty, ",77777.....I777777777777,.....:7777777777......DNNNNNN.......77777+ ...7777.....\n");
3033 vty_out(vty, "I7777I.....777777777777=.....~77777777777......NNNNNNN~......=7777I....=777.....\n");
3034 vty_out(vty, "77777:....=777777777777.....,777777777777......$NNNNND ......:77777....:777.....\n");
3035 vty_out(vty, "77777. ...777777777777~.....7777777777777........7DZ,........:77777.....777.....\n");
3036 vty_out(vty, "????? . ..777777777777.....,7777777777777....................:77777I....777.....\n");
3037 vty_out(vty, "....... ..777777777777.....+7777777777777....................=7777777+...?7.....\n");
3038 vty_out(vty, "..........77777777777I.....I7777777777777....................7777777777:........\n");
3039 vty_out(vty, "..........77777777777I.....?7777777777777...................~777777777777.......\n");
3040 vty_out(vty, "..........777777777777.....~7777777777777..................,77777777777777+.....\n");
3041 vty_out(vty, "..........777777777777......7777777777777..................77777777777777777,...\n");
3042 vty_out(vty, "..... ....?77777777777I.....~777777777777................,777777.....,:+77777I..\n");
3043 vty_out(vty, "........ .:777777777777,.....?77777777777...............?777777..............,:=\n");
3044 vty_out(vty, ".......... 7777777777777..... ?7777777777.............=7777777.....~777I........\n");
3045 vty_out(vty, "...........:777777777777I......~777777777...........I7777777~.....+777I.........\n");
3046 vty_out(vty, "..... ......7777777777777I.......I7777777.......+777777777I......7777I..........\n");
3047 vty_out(vty, ".............77777777777777........?77777......777777777?......=7777=...........\n");
3048 vty_out(vty, ".............,77777777777777+.........~77......777777I,......:77777.............\n");
3049 vty_out(vty, "..............~777777777777777~................777777......:77777=..............\n");
3050 vty_out(vty, "...............:7777777777777777?..............:777777,.....=77=................\n");
3051 vty_out(vty, "................,777777777777777777?,...........,777777:.....,..................\n");
3052 vty_out(vty, "........... ......I777777777777777777777I.........777777~.......................\n");
3053 vty_out(vty, "...................,777777777777777777777..........777777+......................\n");
3054 vty_out(vty, ".....................+7777777777777777777...........777777?.....................\n");
3055 vty_out(vty, ".......................=77777777777777777............777777I....................\n");
3056 vty_out(vty, ".........................:777777777777777.............I77777I...................\n");
3057 vty_out(vty, "............................~777777777777..............+777777..................\n");
3058 vty_out(vty, "................................~77777777...............=777777.................\n");
3059 vty_out(vty, ".....................................:=?I................~777777................\n");
3060 vty_out(vty, "..........................................................:777777,..............\n");
3061 vty_out(vty, ".... ... ... . . .... ....... ....... ....................:777777..............\n");
3062
3063 return CMD_SUCCESS;
3064}
3065
718e3744 3066/* IP node for static routes. */
d62a17ae 3067static struct cmd_node ip_node = {IP_NODE, "", 1};
3068static struct cmd_node protocol_node = {PROTOCOL_NODE, "", 1};
c0d136ae
DS
3069/* table node for routing tables. */
3070static struct cmd_node table_node = {TABLE_NODE,
3071 "", /* This node has no interface. */
3072 1};
3073static struct cmd_node forwarding_node = {FORWARDING_NODE,
3074 "", /* This node has no interface. */
3075 1};
718e3744 3076
3077/* Route VTY. */
d62a17ae 3078void zebra_vty_init(void)
3079{
c0d136ae
DS
3080 /* Install configuration write function. */
3081 install_node(&table_node, config_write_table);
3082 install_node(&forwarding_node, config_write_forwarding);
3083
3084 install_element(VIEW_NODE, &show_ip_forwarding_cmd);
3085 install_element(CONFIG_NODE, &ip_forwarding_cmd);
3086 install_element(CONFIG_NODE, &no_ip_forwarding_cmd);
3087 install_element(ENABLE_NODE, &show_zebra_cmd);
3088
c0d136ae
DS
3089 install_element(VIEW_NODE, &show_ipv6_forwarding_cmd);
3090 install_element(CONFIG_NODE, &ipv6_forwarding_cmd);
3091 install_element(CONFIG_NODE, &no_ipv6_forwarding_cmd);
3092
3093 /* Route-map */
3094 zebra_route_map_init();
3095
d62a17ae 3096 install_node(&ip_node, zebra_ip_config);
3097 install_node(&protocol_node, config_write_protocol);
3098
3099 install_element(CONFIG_NODE, &allow_external_route_update_cmd);
3100 install_element(CONFIG_NODE, &no_allow_external_route_update_cmd);
7e24fdf3 3101
d62a17ae 3102 install_element(CONFIG_NODE, &ip_multicast_mode_cmd);
3103 install_element(CONFIG_NODE, &no_ip_multicast_mode_cmd);
b3b08602 3104
d62a17ae 3105 install_element(CONFIG_NODE, &ip_zebra_import_table_distance_cmd);
3106 install_element(CONFIG_NODE, &no_ip_zebra_import_table_cmd);
3a30f50f
DS
3107 install_element(CONFIG_NODE, &zebra_workqueue_timer_cmd);
3108 install_element(CONFIG_NODE, &no_zebra_workqueue_timer_cmd);
62d52ded
DS
3109 install_element(CONFIG_NODE, &zebra_packet_process_cmd);
3110 install_element(CONFIG_NODE, &no_zebra_packet_process_cmd);
d62a17ae 3111
21be1364
DS
3112 install_element(VIEW_NODE, &show_nexthop_group_cmd);
3113
d62a17ae 3114 install_element(VIEW_NODE, &show_vrf_cmd);
b7cfce93 3115 install_element(VIEW_NODE, &show_vrf_vni_cmd);
ecffa493 3116 install_element(VIEW_NODE, &show_route_cmd);
ae825b8b 3117 install_element(VIEW_NODE, &show_route_table_cmd);
87d6ac7a
PG
3118 if (vrf_is_backend_netns())
3119 install_element(VIEW_NODE, &show_route_table_vrf_cmd);
16c42fba 3120 install_element(VIEW_NODE, &show_route_all_table_vrf_cmd);
5ce91022
RW
3121 install_element(VIEW_NODE, &show_route_detail_cmd);
3122 install_element(VIEW_NODE, &show_route_summary_cmd);
d62a17ae 3123 install_element(VIEW_NODE, &show_ip_nht_cmd);
d62a17ae 3124
3125 install_element(VIEW_NODE, &show_ip_rpf_cmd);
3126 install_element(VIEW_NODE, &show_ip_rpf_addr_cmd);
3127
d62a17ae 3128 install_element(CONFIG_NODE, &ip_nht_default_route_cmd);
3129 install_element(CONFIG_NODE, &no_ip_nht_default_route_cmd);
3130 install_element(CONFIG_NODE, &ipv6_nht_default_route_cmd);
3131 install_element(CONFIG_NODE, &no_ipv6_nht_default_route_cmd);
214e5c26 3132 install_element(VRF_NODE, &ip_nht_default_route_cmd);
3133 install_element(VRF_NODE, &no_ip_nht_default_route_cmd);
3134 install_element(VRF_NODE, &ipv6_nht_default_route_cmd);
3135 install_element(VRF_NODE, &no_ipv6_nht_default_route_cmd);
d62a17ae 3136 install_element(VIEW_NODE, &show_ipv6_mroute_cmd);
3137
3138 /* Commands for VRF */
d62a17ae 3139 install_element(VIEW_NODE, &show_ipv6_mroute_vrf_all_cmd);
3140
d2f5903b 3141 install_element(VIEW_NODE, &show_frr_cmd);
4cce389e 3142 install_element(VIEW_NODE, &show_evpn_global_cmd);
d62a17ae 3143 install_element(VIEW_NODE, &show_evpn_vni_cmd);
09af6961 3144 install_element(VIEW_NODE, &show_evpn_vni_detail_cmd);
d62a17ae 3145 install_element(VIEW_NODE, &show_evpn_vni_vni_cmd);
4cce389e
MK
3146 install_element(VIEW_NODE, &show_evpn_rmac_vni_mac_cmd);
3147 install_element(VIEW_NODE, &show_evpn_rmac_vni_cmd);
3148 install_element(VIEW_NODE, &show_evpn_rmac_vni_all_cmd);
3149 install_element(VIEW_NODE, &show_evpn_nh_vni_ip_cmd);
3150 install_element(VIEW_NODE, &show_evpn_nh_vni_cmd);
3151 install_element(VIEW_NODE, &show_evpn_nh_vni_all_cmd);
d62a17ae 3152 install_element(VIEW_NODE, &show_evpn_mac_vni_cmd);
3153 install_element(VIEW_NODE, &show_evpn_mac_vni_all_cmd);
cffe7580 3154 install_element(VIEW_NODE, &show_evpn_mac_vni_all_detail_cmd);
d62a17ae 3155 install_element(VIEW_NODE, &show_evpn_mac_vni_all_vtep_cmd);
3156 install_element(VIEW_NODE, &show_evpn_mac_vni_mac_cmd);
3157 install_element(VIEW_NODE, &show_evpn_mac_vni_vtep_cmd);
1374d4db
CS
3158 install_element(VIEW_NODE, &show_evpn_mac_vni_dad_cmd);
3159 install_element(VIEW_NODE, &show_evpn_mac_vni_all_dad_cmd);
d62a17ae 3160 install_element(VIEW_NODE, &show_evpn_neigh_vni_cmd);
3161 install_element(VIEW_NODE, &show_evpn_neigh_vni_all_cmd);
e3fac919 3162 install_element(VIEW_NODE, &show_evpn_neigh_vni_all_detail_cmd);
d62a17ae 3163 install_element(VIEW_NODE, &show_evpn_neigh_vni_neigh_cmd);
3164 install_element(VIEW_NODE, &show_evpn_neigh_vni_vtep_cmd);
1374d4db
CS
3165 install_element(VIEW_NODE, &show_evpn_neigh_vni_dad_cmd);
3166 install_element(VIEW_NODE, &show_evpn_neigh_vni_all_dad_cmd);
09de9258 3167 install_element(ENABLE_NODE, &clear_evpn_dup_addr_cmd);
b7cfce93 3168
586f4ccf
PG
3169 install_element(VIEW_NODE, &show_pbr_ipset_cmd);
3170 install_element(VIEW_NODE, &show_pbr_iptable_cmd);
3171
e8d26197
MK
3172 install_element(CONFIG_NODE, &default_vrf_vni_mapping_cmd);
3173 install_element(CONFIG_NODE, &no_default_vrf_vni_mapping_cmd);
b7cfce93
MK
3174 install_element(VRF_NODE, &vrf_vni_mapping_cmd);
3175 install_element(VRF_NODE, &no_vrf_vni_mapping_cmd);
4060008b 3176
1d11b21f
MS
3177 install_element(VIEW_NODE, &show_dataplane_cmd);
3178 install_element(VIEW_NODE, &show_dataplane_providers_cmd);
91f16812
MS
3179 install_element(CONFIG_NODE, &zebra_dplane_queue_limit_cmd);
3180 install_element(CONFIG_NODE, &no_zebra_dplane_queue_limit_cmd);
ac5aa23f
DS
3181
3182 install_element(VIEW_NODE, &zebra_show_routing_tables_summary_cmd);
718e3744 3183}