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