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