]> git.proxmox.com Git - mirror_frr.git/blame - zebra/zebra_vty.c
zebra: Start breakup of zns into zrouter and zns
[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
cec2e17d 71/* VNI range as per RFC 7432 */
72#define CMD_VNI_RANGE "(1-16777215)"
73
4623d897
DL
74DEFUN (ip_multicast_mode,
75 ip_multicast_mode_cmd,
6147e2c6 76 "ip multicast rpf-lookup-mode <urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>",
4623d897
DL
77 IP_STR
78 "Multicast options\n"
79 "RPF lookup behavior\n"
80 "Lookup in unicast RIB only\n"
81 "Lookup in multicast RIB only\n"
82 "Try multicast RIB first, fall back to unicast RIB\n"
83 "Lookup both, use entry with lower distance\n"
84 "Lookup both, use entry with longer prefix\n")
85{
d62a17ae 86 char *mode = argv[3]->text;
87
88 if (strmatch(mode, "urib-only"))
89 multicast_mode_ipv4_set(MCAST_URIB_ONLY);
90 else if (strmatch(mode, "mrib-only"))
91 multicast_mode_ipv4_set(MCAST_MRIB_ONLY);
92 else if (strmatch(mode, "mrib-then-urib"))
93 multicast_mode_ipv4_set(MCAST_MIX_MRIB_FIRST);
94 else if (strmatch(mode, "lower-distance"))
95 multicast_mode_ipv4_set(MCAST_MIX_DISTANCE);
96 else if (strmatch(mode, "longer-prefix"))
97 multicast_mode_ipv4_set(MCAST_MIX_PFXLEN);
98 else {
99 vty_out(vty, "Invalid mode specified\n");
100 return CMD_WARNING_CONFIG_FAILED;
101 }
4623d897 102
d62a17ae 103 return CMD_SUCCESS;
4623d897
DL
104}
105
106DEFUN (no_ip_multicast_mode,
107 no_ip_multicast_mode_cmd,
b62ecea5 108 "no ip multicast rpf-lookup-mode [<urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>]",
4623d897
DL
109 NO_STR
110 IP_STR
111 "Multicast options\n"
112 "RPF lookup behavior\n"
113 "Lookup in unicast RIB only\n"
114 "Lookup in multicast RIB only\n"
115 "Try multicast RIB first, fall back to unicast RIB\n"
116 "Lookup both, use entry with lower distance\n"
117 "Lookup both, use entry with longer prefix\n")
118{
d62a17ae 119 multicast_mode_ipv4_set(MCAST_NO_CONFIG);
120 return CMD_SUCCESS;
4623d897
DL
121}
122
4623d897 123
b78a80d7
EM
124DEFUN (show_ip_rpf,
125 show_ip_rpf_cmd,
acb25e73 126 "show ip rpf [json]",
b78a80d7
EM
127 SHOW_STR
128 IP_STR
acb25e73
DW
129 "Display RPF information for multicast source\n"
130 JSON_STR)
b78a80d7 131{
9f049418 132 bool uj = use_json(argc, argv);
d62a17ae 133 return do_show_ip_route(vty, VRF_DEFAULT_NAME, AFI_IP, SAFI_MULTICAST,
fba31af2 134 false, uj, 0, NULL, false, 0, 0);
b78a80d7
EM
135}
136
65dd94cf
DL
137DEFUN (show_ip_rpf_addr,
138 show_ip_rpf_addr_cmd,
139 "show ip rpf A.B.C.D",
140 SHOW_STR
141 IP_STR
142 "Display RPF information for multicast source\n"
143 "IP multicast source address (e.g. 10.0.0.0)\n")
144{
d62a17ae 145 int idx_ipv4 = 3;
146 struct in_addr addr;
147 struct route_node *rn;
148 struct route_entry *re;
149 int ret;
150
151 ret = inet_aton(argv[idx_ipv4]->arg, &addr);
152 if (ret == 0) {
153 vty_out(vty, "%% Malformed address\n");
154 return CMD_WARNING;
155 }
156
157 re = rib_match_ipv4_multicast(VRF_DEFAULT, addr, &rn);
158
159 if (re)
160 vty_show_ip_route_detail(vty, rn, 1);
161 else
162 vty_out(vty, "%% No match for RPF lookup\n");
163
164 return CMD_SUCCESS;
165}
166
8f527c5e 167/* New RIB. Detailed information for IPv4 route. */
d62a17ae 168static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn,
169 int mcast)
170{
171 struct route_entry *re;
172 struct nexthop *nexthop;
173 char buf[SRCDEST2STR_BUFFER];
174 struct zebra_vrf *zvrf;
175
a2addae8 176 RNODE_FOREACH_RE (rn, re) {
d62a17ae 177 const char *mcast_info = "";
178 if (mcast) {
179 rib_table_info_t *info = srcdest_rnode_table_info(rn);
180 mcast_info = (info->safi == SAFI_MULTICAST)
181 ? " using Multicast RIB"
182 : " using Unicast RIB";
183 }
184
185 vty_out(vty, "Routing entry for %s%s\n",
186 srcdest_rnode2str(rn, buf, sizeof(buf)), mcast_info);
187 vty_out(vty, " Known via \"%s", zebra_route_string(re->type));
188 if (re->instance)
189 vty_out(vty, "[%d]", re->instance);
190 vty_out(vty, "\"");
191 vty_out(vty, ", distance %u, metric %u", re->distance,
192 re->metric);
0efb5e9b 193 if (re->tag) {
8526b842 194 vty_out(vty, ", tag %u", re->tag);
0efb5e9b
DS
195#if defined(SUPPORT_REALMS)
196 if (re->tag > 0 && re->tag <= 255)
197 vty_out(vty, "(realm)");
198#endif
199 }
d62a17ae 200 if (re->mtu)
201 vty_out(vty, ", mtu %u", re->mtu);
202 if (re->vrf_id != VRF_DEFAULT) {
203 zvrf = vrf_info_lookup(re->vrf_id);
204 vty_out(vty, ", vrf %s", zvrf_name(zvrf));
205 }
206 if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED))
207 vty_out(vty, ", best");
d62a17ae 208 vty_out(vty, "\n");
209
14a481d9
DS
210 time_t uptime;
211 struct tm *tm;
212
213 uptime = time(NULL);
214 uptime -= re->uptime;
215 tm = gmtime(&uptime);
216
217 vty_out(vty, " Last update ");
218
219 if (uptime < ONE_DAY_SECOND)
996c9314
LB
220 vty_out(vty, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min,
221 tm->tm_sec);
14a481d9 222 else if (uptime < ONE_WEEK_SECOND)
996c9314
LB
223 vty_out(vty, "%dd%02dh%02dm", tm->tm_yday, tm->tm_hour,
224 tm->tm_min);
14a481d9
DS
225 else
226 vty_out(vty, "%02dw%dd%02dh", tm->tm_yday / 7,
227 tm->tm_yday - ((tm->tm_yday / 7) * 7),
228 tm->tm_hour);
229 vty_out(vty, " ago\n");
d62a17ae 230
7ee30f28 231 for (ALL_NEXTHOPS(re->ng, nexthop)) {
d62a17ae 232 char addrstr[32];
233
234 vty_out(vty, " %c%s",
235 CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)
996c9314
LB
236 ? CHECK_FLAG(nexthop->flags,
237 NEXTHOP_FLAG_DUPLICATE)
238 ? ' '
239 : '*'
d62a17ae 240 : ' ',
241 nexthop->rparent ? " " : "");
242
243 switch (nexthop->type) {
244 case NEXTHOP_TYPE_IPV4:
245 case NEXTHOP_TYPE_IPV4_IFINDEX:
246 vty_out(vty, " %s",
247 inet_ntoa(nexthop->gate.ipv4));
248 if (nexthop->ifindex)
249 vty_out(vty, ", via %s",
4a7371e9
DS
250 ifindex2ifname(
251 nexthop->ifindex,
252 nexthop->vrf_id));
d62a17ae 253 break;
254 case NEXTHOP_TYPE_IPV6:
255 case NEXTHOP_TYPE_IPV6_IFINDEX:
256 vty_out(vty, " %s",
257 inet_ntop(AF_INET6, &nexthop->gate.ipv6,
258 buf, sizeof buf));
259 if (nexthop->ifindex)
260 vty_out(vty, ", via %s",
4a7371e9
DS
261 ifindex2ifname(
262 nexthop->ifindex,
263 nexthop->vrf_id));
d62a17ae 264 break;
265 case NEXTHOP_TYPE_IFINDEX:
266 vty_out(vty, " directly connected, %s",
267 ifindex2ifname(nexthop->ifindex,
4a7371e9 268 nexthop->vrf_id));
d62a17ae 269 break;
270 case NEXTHOP_TYPE_BLACKHOLE:
a8309422
DL
271 vty_out(vty, " unreachable");
272 switch (nexthop->bh_type) {
273 case BLACKHOLE_REJECT:
274 vty_out(vty, " (ICMP unreachable)");
275 break;
276 case BLACKHOLE_ADMINPROHIB:
60466a63
QY
277 vty_out(vty,
278 " (ICMP admin-prohibited)");
a8309422
DL
279 break;
280 case BLACKHOLE_NULL:
281 vty_out(vty, " (blackhole)");
282 break;
283 case BLACKHOLE_UNSPEC:
284 break;
285 }
d62a17ae 286 break;
287 default:
288 break;
289 }
2793a098 290
fc132690 291 if ((re->vrf_id != nexthop->vrf_id)
bbde7a0f 292 && (nexthop->type != NEXTHOP_TYPE_BLACKHOLE)) {
2793a098 293 struct vrf *vrf =
4a7371e9 294 vrf_lookup_by_id(nexthop->vrf_id);
2793a098 295
4c66767c
DS
296 if (vrf)
297 vty_out(vty, "(vrf %s)", vrf->name);
298 else
299 vty_out(vty, "(vrf UKNOWN)");
2793a098
DS
300 }
301
eaf5150f
DS
302 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE))
303 vty_out(vty, " (duplicate nexthop removed)");
304
d62a17ae 305 if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
306 vty_out(vty, " inactive");
307
308 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK))
309 vty_out(vty, " onlink");
310
311 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
312 vty_out(vty, " (recursive)");
313
314 switch (nexthop->type) {
315 case NEXTHOP_TYPE_IPV4:
316 case NEXTHOP_TYPE_IPV4_IFINDEX:
317 if (nexthop->src.ipv4.s_addr) {
318 if (inet_ntop(AF_INET,
319 &nexthop->src.ipv4,
320 addrstr, sizeof addrstr))
321 vty_out(vty, ", src %s",
322 addrstr);
323 }
324 break;
325 case NEXTHOP_TYPE_IPV6:
326 case NEXTHOP_TYPE_IPV6_IFINDEX:
327 if (!IPV6_ADDR_SAME(&nexthop->src.ipv6,
328 &in6addr_any)) {
329 if (inet_ntop(AF_INET6,
330 &nexthop->src.ipv6,
331 addrstr, sizeof addrstr))
332 vty_out(vty, ", src %s",
333 addrstr);
334 }
335 break;
336 default:
337 break;
338 }
339
1994ae60
JB
340 if (re->nexthop_mtu)
341 vty_out(vty, ", mtu %u", re->nexthop_mtu);
342
d62a17ae 343 /* Label information */
344 if (nexthop->nh_label
345 && nexthop->nh_label->num_labels) {
346 vty_out(vty, ", label %s",
347 mpls_label2str(
348 nexthop->nh_label->num_labels,
349 nexthop->nh_label->label, buf,
350 sizeof buf, 1));
351 }
352
353 vty_out(vty, "\n");
354 }
355 vty_out(vty, "\n");
356 }
357}
358
359static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
360 struct route_entry *re, json_object *json)
361{
362 struct nexthop *nexthop;
363 int len = 0;
364 char buf[SRCDEST2STR_BUFFER];
365 json_object *json_nexthops = NULL;
366 json_object *json_nexthop = NULL;
367 json_object *json_route = NULL;
368 json_object *json_labels = NULL;
14a481d9
DS
369 time_t uptime;
370 struct tm *tm;
371
372 uptime = time(NULL);
373 uptime -= re->uptime;
374 tm = gmtime(&uptime);
d62a17ae 375
376 if (json) {
377 json_route = json_object_new_object();
378 json_nexthops = json_object_new_array();
379
380 json_object_string_add(json_route, "prefix",
381 srcdest_rnode2str(rn, buf, sizeof buf));
382 json_object_string_add(json_route, "protocol",
383 zebra_route_string(re->type));
384
385 if (re->instance)
386 json_object_int_add(json_route, "instance",
387 re->instance);
388
389 if (re->vrf_id)
390 json_object_int_add(json_route, "vrfId", re->vrf_id);
391
392 if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED))
393 json_object_boolean_true_add(json_route, "selected");
394
925c2f88 395 if (re->type != ZEBRA_ROUTE_CONNECT) {
d62a17ae 396 json_object_int_add(json_route, "distance",
397 re->distance);
398 json_object_int_add(json_route, "metric", re->metric);
399 }
400
96d71e38
AD
401 if (re->tag)
402 json_object_int_add(json_route, "tag", re->tag);
403
f03098f9
DS
404 json_object_int_add(json_route, "internalStatus",
405 re->status);
406 json_object_int_add(json_route, "internalFlags",
407 re->flags);
14a481d9 408 if (uptime < ONE_DAY_SECOND)
996c9314
LB
409 sprintf(buf, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min,
410 tm->tm_sec);
14a481d9 411 else if (uptime < ONE_WEEK_SECOND)
996c9314
LB
412 sprintf(buf, "%dd%02dh%02dm", tm->tm_yday, tm->tm_hour,
413 tm->tm_min);
14a481d9
DS
414 else
415 sprintf(buf, "%02dw%dd%02dh", tm->tm_yday / 7,
416 tm->tm_yday - ((tm->tm_yday / 7) * 7),
417 tm->tm_hour);
418
419 json_object_string_add(json_route, "uptime", buf);
d62a17ae 420
7ee30f28 421 for (ALL_NEXTHOPS(re->ng, nexthop)) {
d62a17ae 422 json_nexthop = json_object_new_object();
423
f03098f9
DS
424 json_object_int_add(json_nexthop, "flags",
425 nexthop->flags);
426
eaf5150f
DS
427 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE))
428 json_object_boolean_true_add(json_nexthop,
429 "duplicate");
430
d62a17ae 431 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB))
432 json_object_boolean_true_add(json_nexthop,
433 "fib");
434
435 switch (nexthop->type) {
436 case NEXTHOP_TYPE_IPV4:
437 case NEXTHOP_TYPE_IPV4_IFINDEX:
438 json_object_string_add(
439 json_nexthop, "ip",
440 inet_ntoa(nexthop->gate.ipv4));
441 json_object_string_add(json_nexthop, "afi",
442 "ipv4");
443
444 if (nexthop->ifindex) {
445 json_object_int_add(json_nexthop,
446 "interfaceIndex",
447 nexthop->ifindex);
448 json_object_string_add(
449 json_nexthop, "interfaceName",
4a7371e9
DS
450 ifindex2ifname(
451 nexthop->ifindex,
452 nexthop->vrf_id));
d62a17ae 453 }
454 break;
455 case NEXTHOP_TYPE_IPV6:
456 case NEXTHOP_TYPE_IPV6_IFINDEX:
457 json_object_string_add(
458 json_nexthop, "ip",
459 inet_ntop(AF_INET6, &nexthop->gate.ipv6,
460 buf, sizeof buf));
461 json_object_string_add(json_nexthop, "afi",
462 "ipv6");
463
464 if (nexthop->ifindex) {
465 json_object_int_add(json_nexthop,
466 "interfaceIndex",
467 nexthop->ifindex);
468 json_object_string_add(
469 json_nexthop, "interfaceName",
4a7371e9
DS
470 ifindex2ifname(
471 nexthop->ifindex,
472 nexthop->vrf_id));
d62a17ae 473 }
474 break;
475
476 case NEXTHOP_TYPE_IFINDEX:
477 json_object_boolean_true_add(
478 json_nexthop, "directlyConnected");
479 json_object_int_add(json_nexthop,
480 "interfaceIndex",
481 nexthop->ifindex);
482 json_object_string_add(
483 json_nexthop, "interfaceName",
484 ifindex2ifname(nexthop->ifindex,
4a7371e9 485 nexthop->vrf_id));
d62a17ae 486 break;
487 case NEXTHOP_TYPE_BLACKHOLE:
488 json_object_boolean_true_add(json_nexthop,
a8309422
DL
489 "unreachable");
490 switch (nexthop->bh_type) {
491 case BLACKHOLE_REJECT:
492 json_object_boolean_true_add(
60466a63 493 json_nexthop, "reject");
a8309422
DL
494 break;
495 case BLACKHOLE_ADMINPROHIB:
496 json_object_boolean_true_add(
60466a63
QY
497 json_nexthop,
498 "admin-prohibited");
a8309422
DL
499 break;
500 case BLACKHOLE_NULL:
501 json_object_boolean_true_add(
60466a63 502 json_nexthop, "blackhole");
a8309422
DL
503 break;
504 case BLACKHOLE_UNSPEC:
505 break;
506 }
d62a17ae 507 break;
508 default:
509 break;
510 }
511
fc132690 512 if ((nexthop->vrf_id != re->vrf_id)
bbde7a0f 513 && (nexthop->type != NEXTHOP_TYPE_BLACKHOLE)) {
2793a098 514 struct vrf *vrf =
4a7371e9 515 vrf_lookup_by_id(nexthop->vrf_id);
2793a098 516
996c9314 517 json_object_string_add(json_nexthop, "vrf",
2793a098
DS
518 vrf->name);
519 }
eaf5150f
DS
520 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE))
521 json_object_boolean_true_add(json_nexthop,
522 "duplicate");
523
d62a17ae 524 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
525 json_object_boolean_true_add(json_nexthop,
526 "active");
527
528 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK))
529 json_object_boolean_true_add(json_nexthop,
530 "onLink");
531
532 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
533 json_object_boolean_true_add(json_nexthop,
534 "recursive");
535
536 switch (nexthop->type) {
537 case NEXTHOP_TYPE_IPV4:
538 case NEXTHOP_TYPE_IPV4_IFINDEX:
539 if (nexthop->src.ipv4.s_addr) {
540 if (inet_ntop(AF_INET,
541 &nexthop->src.ipv4, buf,
542 sizeof buf))
543 json_object_string_add(
544 json_nexthop, "source",
545 buf);
546 }
547 break;
548 case NEXTHOP_TYPE_IPV6:
549 case NEXTHOP_TYPE_IPV6_IFINDEX:
550 if (!IPV6_ADDR_SAME(&nexthop->src.ipv6,
551 &in6addr_any)) {
552 if (inet_ntop(AF_INET6,
553 &nexthop->src.ipv6, buf,
554 sizeof buf))
555 json_object_string_add(
556 json_nexthop, "source",
557 buf);
558 }
559 break;
560 default:
561 break;
562 }
563
564 if (nexthop->nh_label
565 && nexthop->nh_label->num_labels) {
566 json_labels = json_object_new_array();
567
568 for (int label_index = 0;
569 label_index
570 < nexthop->nh_label->num_labels;
571 label_index++)
572 json_object_array_add(
573 json_labels,
574 json_object_new_int(
575 nexthop->nh_label->label
576 [label_index]));
577
578 json_object_object_add(json_nexthop, "labels",
579 json_labels);
580 }
581
582 json_object_array_add(json_nexthops, json_nexthop);
583 }
584
585 json_object_object_add(json_route, "nexthops", json_nexthops);
586 json_object_array_add(json, json_route);
587 return;
588 }
589
590 /* Nexthop information. */
7ee30f28
DS
591 for (ALL_NEXTHOPS(re->ng, nexthop)) {
592 if (nexthop == re->ng.nexthop) {
d62a17ae 593 /* Prefix information. */
594 len = vty_out(vty, "%c", zebra_route_char(re->type));
595 if (re->instance)
596 len += vty_out(vty, "[%d]", re->instance);
597 len += vty_out(
598 vty, "%c%c %s",
599 CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED)
600 ? '>'
601 : ' ',
602 CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)
603 ? '*'
604 : ' ',
605 srcdest_rnode2str(rn, buf, sizeof buf));
606
607 /* Distance and metric display. */
925c2f88 608 if (re->type != ZEBRA_ROUTE_CONNECT)
8526b842 609 len += vty_out(vty, " [%u/%u]", re->distance,
d62a17ae 610 re->metric);
eaf5150f 611 } else {
d62a17ae 612 vty_out(vty, " %c%*c",
613 CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)
996c9314
LB
614 ? CHECK_FLAG(nexthop->flags,
615 NEXTHOP_FLAG_DUPLICATE)
616 ? ' '
617 : '*'
d62a17ae 618 : ' ',
619 len - 3 + (2 * nexthop_level(nexthop)), ' ');
eaf5150f 620 }
d62a17ae 621
622 switch (nexthop->type) {
623 case NEXTHOP_TYPE_IPV4:
624 case NEXTHOP_TYPE_IPV4_IFINDEX:
625 vty_out(vty, " via %s", inet_ntoa(nexthop->gate.ipv4));
626 if (nexthop->ifindex)
627 vty_out(vty, ", %s",
628 ifindex2ifname(nexthop->ifindex,
4a7371e9 629 nexthop->vrf_id));
d62a17ae 630 break;
631 case NEXTHOP_TYPE_IPV6:
632 case NEXTHOP_TYPE_IPV6_IFINDEX:
633 vty_out(vty, " via %s",
634 inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf,
635 sizeof buf));
636 if (nexthop->ifindex)
637 vty_out(vty, ", %s",
638 ifindex2ifname(nexthop->ifindex,
4a7371e9 639 nexthop->vrf_id));
d62a17ae 640 break;
641
642 case NEXTHOP_TYPE_IFINDEX:
643 vty_out(vty, " is directly connected, %s",
99b9d960 644 ifindex2ifname(nexthop->ifindex,
4a7371e9 645 nexthop->vrf_id));
d62a17ae 646 break;
647 case NEXTHOP_TYPE_BLACKHOLE:
a8309422
DL
648 vty_out(vty, " unreachable");
649 switch (nexthop->bh_type) {
650 case BLACKHOLE_REJECT:
651 vty_out(vty, " (ICMP unreachable)");
652 break;
653 case BLACKHOLE_ADMINPROHIB:
654 vty_out(vty, " (ICMP admin-prohibited)");
655 break;
656 case BLACKHOLE_NULL:
657 vty_out(vty, " (blackhole)");
658 break;
659 case BLACKHOLE_UNSPEC:
660 break;
661 }
d62a17ae 662 break;
663 default:
664 break;
665 }
2793a098 666
fc132690 667 if ((nexthop->vrf_id != re->vrf_id)
bbde7a0f 668 && (nexthop->type != NEXTHOP_TYPE_BLACKHOLE)) {
4a7371e9 669 struct vrf *vrf = vrf_lookup_by_id(nexthop->vrf_id);
2793a098 670
4c66767c
DS
671 if (vrf)
672 vty_out(vty, "(vrf %s)", vrf->name);
673 else
674 vty_out(vty, "(vrf UKNOWN)");
2793a098
DS
675 }
676
d62a17ae 677 if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
678 vty_out(vty, " inactive");
679
680 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK))
681 vty_out(vty, " onlink");
682
683 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
684 vty_out(vty, " (recursive)");
685
686 switch (nexthop->type) {
687 case NEXTHOP_TYPE_IPV4:
688 case NEXTHOP_TYPE_IPV4_IFINDEX:
689 if (nexthop->src.ipv4.s_addr) {
690 if (inet_ntop(AF_INET, &nexthop->src.ipv4, buf,
691 sizeof buf))
692 vty_out(vty, ", src %s", buf);
693 }
694 break;
695 case NEXTHOP_TYPE_IPV6:
696 case NEXTHOP_TYPE_IPV6_IFINDEX:
697 if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any)) {
698 if (inet_ntop(AF_INET6, &nexthop->src.ipv6, buf,
699 sizeof buf))
700 vty_out(vty, ", src %s", buf);
701 }
702 break;
703 default:
704 break;
705 }
706
707 /* Label information */
708 if (nexthop->nh_label && nexthop->nh_label->num_labels) {
709 vty_out(vty, ", label %s",
710 mpls_label2str(nexthop->nh_label->num_labels,
711 nexthop->nh_label->label, buf,
712 sizeof buf, 1));
713 }
714
14a481d9
DS
715 if (uptime < ONE_DAY_SECOND)
716 vty_out(vty, ", %02d:%02d:%02d", tm->tm_hour,
717 tm->tm_min, tm->tm_sec);
718 else if (uptime < ONE_WEEK_SECOND)
719 vty_out(vty, ", %dd%02dh%02dm", tm->tm_yday,
720 tm->tm_hour, tm->tm_min);
721 else
722 vty_out(vty, ", %02dw%dd%02dh", tm->tm_yday / 7,
723 tm->tm_yday - ((tm->tm_yday / 7) * 7),
724 tm->tm_hour);
d62a17ae 725 vty_out(vty, "\n");
726 }
727}
728
96d71e38
AD
729static void vty_show_ip_route_detail_json(struct vty *vty,
730 struct route_node *rn)
731{
732 json_object *json = NULL;
733 json_object *json_prefix = NULL;
734 struct route_entry *re;
735 char buf[BUFSIZ];
736
737 json = json_object_new_object();
738
739 RNODE_FOREACH_RE (rn, re) {
740 json_prefix = json_object_new_array();
741 vty_show_ip_route(vty, rn, re, json_prefix);
742 prefix2str(&rn->p, buf, sizeof buf);
743 json_object_object_add(json, buf, json_prefix);
744 json_prefix = NULL;
745 }
746
747 vty_out(vty, "%s\n", json_object_to_json_string_ext(
748 json, JSON_C_TO_STRING_PRETTY));
749 json_object_free(json);
750}
751
ae825b8b
DS
752static void do_show_route_helper(struct vty *vty, struct zebra_vrf *zvrf,
753 struct route_table *table, afi_t afi,
754 bool use_fib, route_tag_t tag,
755 const struct prefix *longer_prefix_p,
756 bool supernets_only, int type,
9f049418 757 unsigned short ospf_instance_id, bool use_json)
d62a17ae 758{
d62a17ae 759 struct route_node *rn;
760 struct route_entry *re;
761 int first = 1;
ae825b8b 762 rib_dest_t *dest;
d62a17ae 763 json_object *json = NULL;
764 json_object *json_prefix = NULL;
ae825b8b
DS
765 uint32_t addr;
766 char buf[BUFSIZ];
d62a17ae 767
768 if (use_json)
769 json = json_object_new_object();
770
771 /* Show all routes. */
c9591045 772 for (rn = route_top(table); rn; rn = srcdest_route_next(rn)) {
5f7a4718
DS
773 dest = rib_dest_from_rnode(rn);
774
a2addae8 775 RNODE_FOREACH_RE (rn, re) {
996c9314 776 if (use_fib && re != dest->selected_fib)
d62a17ae 777 continue;
778
779 if (tag && re->tag != tag)
780 continue;
781
782 if (longer_prefix_p
783 && !prefix_match(longer_prefix_p, &rn->p))
784 continue;
785
786 /* This can only be true when the afi is IPv4 */
787 if (supernets_only) {
788 addr = ntohl(rn->p.u.prefix4.s_addr);
789
790 if (IN_CLASSC(addr) && rn->p.prefixlen >= 24)
791 continue;
792
793 if (IN_CLASSB(addr) && rn->p.prefixlen >= 16)
794 continue;
795
796 if (IN_CLASSA(addr) && rn->p.prefixlen >= 8)
797 continue;
798 }
799
800 if (type && re->type != type)
801 continue;
802
803 if (ospf_instance_id
804 && (re->type != ZEBRA_ROUTE_OSPF
805 || re->instance != ospf_instance_id))
806 continue;
807
808 if (use_json) {
809 if (!json_prefix)
810 json_prefix = json_object_new_array();
811 } else {
812 if (first) {
813 if (afi == AFI_IP)
814 vty_out(vty,
815 SHOW_ROUTE_V4_HEADER);
816 else
817 vty_out(vty,
818 SHOW_ROUTE_V6_HEADER);
819
820 if (zvrf_id(zvrf) != VRF_DEFAULT)
821 vty_out(vty, "\nVRF %s:\n",
822 zvrf_name(zvrf));
823
824 first = 0;
825 }
826 }
827
828 vty_show_ip_route(vty, rn, re, json_prefix);
829 }
830
831 if (json_prefix) {
96d71e38 832 prefix2str(&rn->p, buf, sizeof(buf));
d62a17ae 833 json_object_object_add(json, buf, json_prefix);
834 json_prefix = NULL;
835 }
836 }
837
838 if (use_json) {
96d71e38
AD
839 vty_out(vty, "%s\n", json_object_to_json_string_ext(json,
840 JSON_C_TO_STRING_PRETTY));
d62a17ae 841 json_object_free(json);
842 }
ae825b8b
DS
843}
844
845static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi,
9f049418 846 safi_t safi, bool use_fib, bool use_json,
ae825b8b
DS
847 route_tag_t tag,
848 const struct prefix *longer_prefix_p,
849 bool supernets_only, int type,
d7c0a89a 850 unsigned short ospf_instance_id)
ae825b8b
DS
851{
852 struct route_table *table;
853 struct zebra_vrf *zvrf = NULL;
854
855 if (!(zvrf = zebra_vrf_lookup_by_name(vrf_name))) {
856 if (use_json)
857 vty_out(vty, "{}\n");
858 else
859 vty_out(vty, "vrf %s not defined\n", vrf_name);
860 return CMD_SUCCESS;
861 }
862
863 if (zvrf_id(zvrf) == VRF_UNKNOWN) {
864 if (use_json)
865 vty_out(vty, "{}\n");
866 else
867 vty_out(vty, "vrf %s inactive\n", vrf_name);
868 return CMD_SUCCESS;
869 }
870
871 table = zebra_vrf_table(afi, safi, zvrf_id(zvrf));
872 if (!table) {
873 if (use_json)
874 vty_out(vty, "{}\n");
875 return CMD_SUCCESS;
876 }
877
878 do_show_route_helper(vty, zvrf, table, afi, use_fib, tag,
879 longer_prefix_p, supernets_only, type,
880 ospf_instance_id, use_json);
881
882 return CMD_SUCCESS;
883}
884
885DEFPY (show_route_table,
886 show_route_table_cmd,
887 "show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table [json$json]",
888 SHOW_STR
889 IP_STR
890 IP6_STR
891 "IP routing table\n"
892 "Table to display\n"
893 "The table number to display, if available\n"
894 JSON_STR)
895{
896 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
897 struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
898 struct route_table *t;
899
89272910 900 t = zebra_router_find_table(zvrf, table, afi, SAFI_UNICAST);
ae825b8b
DS
901 if (t)
902 do_show_route_helper(vty, zvrf, t, afi, false, 0, false, false,
903 0, 0, !!json);
d62a17ae 904
905 return CMD_SUCCESS;
abbda2d4 906}
d511d7f1 907
87d6ac7a
PG
908DEFPY (show_route_table_vrf,
909 show_route_table_vrf_cmd,
910 "show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table vrf NAME$vrf_name [json$json]",
911 SHOW_STR
912 IP_STR
913 IP6_STR
914 "IP routing table\n"
915 "Table to display\n"
916 "The table number to display, if available\n"
917 VRF_CMD_HELP_STR
918 JSON_STR)
919{
920 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
921 struct zebra_vrf *zvrf;
922 struct route_table *t;
923 vrf_id_t vrf_id = VRF_DEFAULT;
924
925 if (vrf_name)
ec1db588 926 VRF_GET_ID(vrf_id, vrf_name, !!json);
87d6ac7a
PG
927 zvrf = zebra_vrf_lookup_by_id(vrf_id);
928
89272910 929 t = zebra_router_find_table(zvrf, table, afi, SAFI_UNICAST);
87d6ac7a
PG
930 if (t)
931 do_show_route_helper(vty, zvrf, t, afi, false, 0, false, false,
932 0, 0, !!json);
933
934 return CMD_SUCCESS;
935}
936
8f527c5e
FL
937DEFUN (show_ip_nht,
938 show_ip_nht_cmd,
9bf96c84 939 "show ip nht [vrf NAME]",
8f527c5e
FL
940 SHOW_STR
941 IP_STR
9bf96c84
DW
942 "IP nexthop tracking table\n"
943 VRF_CMD_HELP_STR)
8f527c5e 944{
d62a17ae 945 int idx_vrf = 4;
946 vrf_id_t vrf_id = VRF_DEFAULT;
12f6fb97 947
d62a17ae 948 if (argc == 5)
ec1db588 949 VRF_GET_ID(vrf_id, argv[idx_vrf]->arg, false);
12f6fb97 950
d62a17ae 951 zebra_print_rnh_table(vrf_id, AF_INET, vty, RNH_NEXTHOP_TYPE);
952 return CMD_SUCCESS;
8f527c5e
FL
953}
954
12f6fb97 955
d511d7f1
DS
956DEFUN (show_ip_nht_vrf_all,
957 show_ip_nht_vrf_all_cmd,
5bebf568 958 "show ip nht vrf all",
d511d7f1
DS
959 SHOW_STR
960 IP_STR
961 "IP nexthop tracking table\n"
962 VRF_ALL_CMD_HELP_STR)
963{
d62a17ae 964 struct vrf *vrf;
965 struct zebra_vrf *zvrf;
d511d7f1 966
a2addae8
RW
967 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
968 if ((zvrf = vrf->info) != NULL) {
969 vty_out(vty, "\nVRF %s:\n", zvrf_name(zvrf));
970 zebra_print_rnh_table(zvrf_id(zvrf), AF_INET, vty,
971 RNH_NEXTHOP_TYPE);
972 }
d511d7f1 973
d62a17ae 974 return CMD_SUCCESS;
d511d7f1
DS
975}
976
8f527c5e
FL
977DEFUN (show_ipv6_nht,
978 show_ipv6_nht_cmd,
9bf96c84 979 "show ipv6 nht [vrf NAME]",
8f527c5e 980 SHOW_STR
689e6694 981 IPV6_STR
9bf96c84
DW
982 "IPv6 nexthop tracking table\n"
983 VRF_CMD_HELP_STR)
8f527c5e 984{
d62a17ae 985 int idx_vrf = 4;
986 vrf_id_t vrf_id = VRF_DEFAULT;
12f6fb97 987
d62a17ae 988 if (argc == 5)
ec1db588 989 VRF_GET_ID(vrf_id, argv[idx_vrf]->arg, false);
12f6fb97 990
d62a17ae 991 zebra_print_rnh_table(vrf_id, AF_INET6, vty, RNH_NEXTHOP_TYPE);
992 return CMD_SUCCESS;
8f527c5e
FL
993}
994
12f6fb97 995
d511d7f1
DS
996DEFUN (show_ipv6_nht_vrf_all,
997 show_ipv6_nht_vrf_all_cmd,
5bebf568 998 "show ipv6 nht vrf all",
d511d7f1
DS
999 SHOW_STR
1000 IP_STR
1001 "IPv6 nexthop tracking table\n"
1002 VRF_ALL_CMD_HELP_STR)
1003{
d62a17ae 1004 struct vrf *vrf;
1005 struct zebra_vrf *zvrf;
d511d7f1 1006
a2addae8
RW
1007 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
1008 if ((zvrf = vrf->info) != NULL) {
1009 vty_out(vty, "\nVRF %s:\n", zvrf_name(zvrf));
1010 zebra_print_rnh_table(zvrf_id(zvrf), AF_INET6, vty,
1011 RNH_NEXTHOP_TYPE);
1012 }
d511d7f1 1013
d62a17ae 1014 return CMD_SUCCESS;
d511d7f1
DS
1015}
1016
8f527c5e
FL
1017DEFUN (ip_nht_default_route,
1018 ip_nht_default_route_cmd,
1019 "ip nht resolve-via-default",
1020 IP_STR
1021 "Filter Next Hop tracking route resolution\n"
1022 "Resolve via default route\n")
1023{
214e5c26 1024 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
6d53d7b1 1025
1026 if (!zvrf)
1027 return CMD_WARNING;
1028
214e5c26 1029 if (zebra_rnh_ip_default_route)
1030 return CMD_SUCCESS;
1031
d62a17ae 1032 zebra_rnh_ip_default_route = 1;
214e5c26 1033
6d53d7b1 1034 zebra_evaluate_rnh(zvrf, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
d62a17ae 1035 return CMD_SUCCESS;
8f527c5e
FL
1036}
1037
1038DEFUN (no_ip_nht_default_route,
1039 no_ip_nht_default_route_cmd,
1040 "no ip nht resolve-via-default",
1041 NO_STR
1042 IP_STR
1043 "Filter Next Hop tracking route resolution\n"
1044 "Resolve via default route\n")
1045{
214e5c26 1046 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
6d53d7b1 1047
1048 if (!zvrf)
1049 return CMD_WARNING;
1050
214e5c26 1051 if (!zebra_rnh_ip_default_route)
1052 return CMD_SUCCESS;
1053
d62a17ae 1054 zebra_rnh_ip_default_route = 0;
6d53d7b1 1055 zebra_evaluate_rnh(zvrf, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
d62a17ae 1056 return CMD_SUCCESS;
8f527c5e
FL
1057}
1058
1059DEFUN (ipv6_nht_default_route,
1060 ipv6_nht_default_route_cmd,
1061 "ipv6 nht resolve-via-default",
1062 IP6_STR
1063 "Filter Next Hop tracking route resolution\n"
1064 "Resolve via default route\n")
1065{
214e5c26 1066 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
6d53d7b1 1067
1068 if (!zvrf)
1069 return CMD_WARNING;
1070
214e5c26 1071 if (zebra_rnh_ipv6_default_route)
1072 return CMD_SUCCESS;
1073
d62a17ae 1074 zebra_rnh_ipv6_default_route = 1;
6d53d7b1 1075 zebra_evaluate_rnh(zvrf, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL);
d62a17ae 1076 return CMD_SUCCESS;
8f527c5e
FL
1077}
1078
1079DEFUN (no_ipv6_nht_default_route,
1080 no_ipv6_nht_default_route_cmd,
1081 "no ipv6 nht resolve-via-default",
1082 NO_STR
1083 IP6_STR
1084 "Filter Next Hop tracking route resolution\n"
1085 "Resolve via default route\n")
1086{
8f527c5e 1087
214e5c26 1088 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
6d53d7b1 1089
1090 if (!zvrf)
1091 return CMD_WARNING;
1092
214e5c26 1093 if (!zebra_rnh_ipv6_default_route)
1094 return CMD_SUCCESS;
1095
d62a17ae 1096 zebra_rnh_ipv6_default_route = 0;
6d53d7b1 1097 zebra_evaluate_rnh(zvrf, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL);
d62a17ae 1098 return CMD_SUCCESS;
8f527c5e
FL
1099}
1100
ecffa493
RW
1101DEFPY (show_route,
1102 show_route_cmd,
1103 "show\
1104 <\
1105 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
a3e13ef3 1106 [{\
ecffa493
RW
1107 tag (1-4294967295)\
1108 |A.B.C.D/M$prefix longer-prefixes\
1109 |supernets-only$supernets_only\
a3e13ef3
RW
1110 }]\
1111 [<\
1112 " FRR_IP_REDIST_STR_ZEBRA "$type_str\
ecffa493 1113 |ospf$type_str (1-65535)$ospf_instance_id\
a3e13ef3 1114 >]\
ecffa493 1115 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
a3e13ef3 1116 [{\
ecffa493
RW
1117 tag (1-4294967295)\
1118 |X:X::X:X/M$prefix longer-prefixes\
a3e13ef3
RW
1119 }]\
1120 [" FRR_IP6_REDIST_STR_ZEBRA "$type_str]\
ecffa493
RW
1121 >\
1122 [json$json]",
8f527c5e
FL
1123 SHOW_STR
1124 IP_STR
87a88962 1125 "IP forwarding table\n"
8f527c5e 1126 "IP routing table\n"
ecffa493 1127 VRF_FULL_CMD_HELP_STR
8f527c5e 1128 "Show only routes with tag\n"
acb25e73
DW
1129 "Tag value\n"
1130 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1131 "Show route matching the specified Network/Mask pair only\n"
1132 "Show supernet entries only\n"
1133 FRR_IP_REDIST_HELP_STR_ZEBRA
1134 "Open Shortest Path First (OSPFv2)\n"
1135 "Instance ID\n"
ecffa493
RW
1136 IPV6_STR
1137 "IP forwarding table\n"
1138 "IP routing table\n"
1139 VRF_FULL_CMD_HELP_STR
1140 "Show only routes with tag\n"
1141 "Tag value\n"
1142 "IPv6 prefix\n"
1143 "Show route matching the specified Network/Mask pair only\n"
1144 FRR_IP6_REDIST_HELP_STR_ZEBRA
acb25e73 1145 JSON_STR)
8f527c5e 1146{
ecffa493 1147 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
d62a17ae 1148 struct vrf *vrf;
d62a17ae 1149 int type = 0;
d62a17ae 1150
ecffa493
RW
1151 if (type_str) {
1152 type = proto_redistnum(afi, type_str);
d62a17ae 1153 if (type < 0) {
1154 vty_out(vty, "Unknown route type\n");
1155 return CMD_WARNING;
1156 }
1157 }
1158
1159 if (vrf_all) {
a2addae8 1160 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
ecffa493
RW
1161 struct zebra_vrf *zvrf;
1162 struct route_table *table;
1163
d62a17ae 1164 if ((zvrf = vrf->info) == NULL
ecffa493 1165 || (table = zvrf->table[afi][SAFI_UNICAST]) == NULL)
d62a17ae 1166 continue;
1167
1168 do_show_ip_route(
ecffa493
RW
1169 vty, zvrf_name(zvrf), afi, SAFI_UNICAST, !!fib,
1170 !!json, tag, prefix_str ? prefix : NULL,
1171 !!supernets_only, type, ospf_instance_id);
d62a17ae 1172 }
1173 } else {
ecffa493
RW
1174 vrf_id_t vrf_id = VRF_DEFAULT;
1175
1176 if (vrf_name)
ec1db588 1177 VRF_GET_ID(vrf_id, vrf_name, !!json);
d62a17ae 1178 vrf = vrf_lookup_by_id(vrf_id);
ecffa493
RW
1179 do_show_ip_route(vty, vrf->name, afi, SAFI_UNICAST, !!fib,
1180 !!json, tag, prefix_str ? prefix : NULL,
1181 !!supernets_only, type, ospf_instance_id);
d62a17ae 1182 }
ecffa493 1183
d62a17ae 1184 return CMD_SUCCESS;
8f527c5e
FL
1185}
1186
5ce91022
RW
1187DEFPY (show_route_detail,
1188 show_route_detail_cmd,
1189 "show\
1190 <\
1191 ip$ipv4 route [vrf <NAME$vrf_name|all$vrf_all>]\
1192 <\
1193 A.B.C.D$address\
1194 |A.B.C.D/M$prefix\
1195 >\
1196 |ipv6$ipv6 route [vrf <NAME$vrf_name|all$vrf_all>]\
1197 <\
1198 X:X::X:X$address\
1199 |X:X::X:X/M$prefix\
1200 >\
96d71e38
AD
1201 >\
1202 [json$json]",
8f527c5e
FL
1203 SHOW_STR
1204 IP_STR
1205 "IP routing table\n"
5ce91022
RW
1206 VRF_FULL_CMD_HELP_STR
1207 "Network in the IP routing table to display\n"
1208 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1209 IP6_STR
1210 "IP routing table\n"
1211 VRF_FULL_CMD_HELP_STR
1212 "IPv6 Address\n"
96d71e38
AD
1213 "IPv6 prefix\n"
1214 JSON_STR)
8f527c5e 1215{
5ce91022 1216 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
d62a17ae 1217 struct route_table *table;
5ce91022 1218 struct prefix p;
d62a17ae 1219 struct route_node *rn;
d511d7f1 1220
5ce91022
RW
1221 if (address_str)
1222 prefix_str = address_str;
1223 if (str2prefix(prefix_str, &p) < 0) {
1224 vty_out(vty, "%% Malformed address\n");
d62a17ae 1225 return CMD_WARNING;
1226 }
8f527c5e 1227
5ce91022
RW
1228 if (vrf_all) {
1229 struct vrf *vrf;
1230 struct zebra_vrf *zvrf;
8f527c5e 1231
996c9314 1232 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
5ce91022
RW
1233 if ((zvrf = vrf->info) == NULL
1234 || (table = zvrf->table[afi][SAFI_UNICAST]) == NULL)
1235 continue;
1236
1237 rn = route_node_match(table, &p);
1238 if (!rn)
1239 continue;
1240 if (!address_str && rn->p.prefixlen != p.prefixlen) {
1241 route_unlock_node(rn);
1242 continue;
1243 }
1244
96d71e38
AD
1245 if (json)
1246 vty_show_ip_route_detail_json(vty, rn);
1247 else
1248 vty_show_ip_route_detail(vty, rn, 0);
5ce91022
RW
1249
1250 route_unlock_node(rn);
1251 }
1252 } else {
1253 vrf_id_t vrf_id = VRF_DEFAULT;
1254
1255 if (vrf_name)
ec1db588 1256 VRF_GET_ID(vrf_id, vrf_name, false);
5ce91022
RW
1257
1258 table = zebra_vrf_table(afi, SAFI_UNICAST, vrf_id);
1259 if (!table)
1260 return CMD_SUCCESS;
8f527c5e 1261
5ce91022
RW
1262 rn = route_node_match(table, &p);
1263 if (!rn) {
1264 vty_out(vty, "%% Network not in table\n");
1265 return CMD_WARNING;
1266 }
1267 if (!address_str && rn->p.prefixlen != p.prefixlen) {
1268 vty_out(vty, "%% Network not in table\n");
1269 route_unlock_node(rn);
1270 return CMD_WARNING;
1271 }
8f527c5e 1272
96d71e38
AD
1273 if (json)
1274 vty_show_ip_route_detail_json(vty, rn);
1275 else
1276 vty_show_ip_route_detail(vty, rn, 0);
5ce91022
RW
1277
1278 route_unlock_node(rn);
1279 }
8f527c5e 1280
d62a17ae 1281 return CMD_SUCCESS;
8f527c5e
FL
1282}
1283
5ce91022
RW
1284DEFPY (show_route_summary,
1285 show_route_summary_cmd,
1286 "show\
1287 <\
1288 ip$ipv4 route [vrf <NAME$vrf_name|all$vrf_all>]\
1289 summary [prefix$prefix]\
1290 |ipv6$ipv6 route [vrf <NAME$vrf_name|all$vrf_all>]\
1291 summary [prefix$prefix]\
1292 >",
8f527c5e
FL
1293 SHOW_STR
1294 IP_STR
1295 "IP routing table\n"
5ce91022
RW
1296 VRF_FULL_CMD_HELP_STR
1297 "Summary of all routes\n"
1298 "Prefix routes\n"
1299 IP6_STR
1300 "IP routing table\n"
1301 VRF_FULL_CMD_HELP_STR
1302 "Summary of all routes\n"
1303 "Prefix routes\n")
8f527c5e 1304{
5ce91022 1305 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
d62a17ae 1306 struct route_table *table;
d62a17ae 1307
5ce91022
RW
1308 if (vrf_all) {
1309 struct vrf *vrf;
1310 struct zebra_vrf *zvrf;
d511d7f1 1311
996c9314 1312 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
5ce91022
RW
1313 if ((zvrf = vrf->info) == NULL
1314 || (table = zvrf->table[afi][SAFI_UNICAST]) == NULL)
1315 continue;
8f527c5e 1316
5ce91022
RW
1317 if (prefix)
1318 vty_show_ip_route_summary_prefix(vty, table);
1319 else
1320 vty_show_ip_route_summary(vty, table);
1321 }
1322 } else {
1323 vrf_id_t vrf_id = VRF_DEFAULT;
8f527c5e 1324
5ce91022 1325 if (vrf_name)
ec1db588 1326 VRF_GET_ID(vrf_id, vrf_name, false);
8f527c5e 1327
5ce91022
RW
1328 table = zebra_vrf_table(afi, SAFI_UNICAST, vrf_id);
1329 if (!table)
1330 return CMD_SUCCESS;
8f527c5e 1331
5ce91022
RW
1332 if (prefix)
1333 vty_show_ip_route_summary_prefix(vty, table);
1334 else
1335 vty_show_ip_route_summary(vty, table);
1336 }
8f527c5e 1337
d62a17ae 1338 return CMD_SUCCESS;
8f527c5e
FL
1339}
1340
d62a17ae 1341static void vty_show_ip_route_summary(struct vty *vty,
1342 struct route_table *table)
8f527c5e 1343{
d62a17ae 1344 struct route_node *rn;
1345 struct route_entry *re;
8f527c5e
FL
1346#define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1347#define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
d7c0a89a
QY
1348 uint32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1349 uint32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1350 uint32_t i;
1351 uint32_t is_ibgp;
d62a17ae 1352
1353 memset(&rib_cnt, 0, sizeof(rib_cnt));
1354 memset(&fib_cnt, 0, sizeof(fib_cnt));
1355 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
a2addae8 1356 RNODE_FOREACH_RE (rn, re) {
d62a17ae 1357 is_ibgp = (re->type == ZEBRA_ROUTE_BGP
1358 && CHECK_FLAG(re->flags, ZEBRA_FLAG_IBGP));
1359
1360 rib_cnt[ZEBRA_ROUTE_TOTAL]++;
1361 if (is_ibgp)
1362 rib_cnt[ZEBRA_ROUTE_IBGP]++;
1363 else
1364 rib_cnt[re->type]++;
1365
1366 if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED)) {
1367 fib_cnt[ZEBRA_ROUTE_TOTAL]++;
1368
1369 if (is_ibgp)
1370 fib_cnt[ZEBRA_ROUTE_IBGP]++;
1371 else
1372 fib_cnt[re->type]++;
1373 }
1374 }
1375
1376 vty_out(vty, "%-20s %-20s %s (vrf %s)\n", "Route Source", "Routes",
6ca30e9e 1377 "FIB", zvrf_name(((rib_table_info_t *)route_table_get_info(table))->zvrf));
d62a17ae 1378
1379 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
9d303b37
DL
1380 if ((rib_cnt[i] > 0) || (i == ZEBRA_ROUTE_BGP
1381 && rib_cnt[ZEBRA_ROUTE_IBGP] > 0)) {
d62a17ae 1382 if (i == ZEBRA_ROUTE_BGP) {
1383 vty_out(vty, "%-20s %-20d %-20d \n", "ebgp",
1384 rib_cnt[ZEBRA_ROUTE_BGP],
1385 fib_cnt[ZEBRA_ROUTE_BGP]);
1386 vty_out(vty, "%-20s %-20d %-20d \n", "ibgp",
1387 rib_cnt[ZEBRA_ROUTE_IBGP],
1388 fib_cnt[ZEBRA_ROUTE_IBGP]);
1389 } else
1390 vty_out(vty, "%-20s %-20d %-20d \n",
1391 zebra_route_string(i), rib_cnt[i],
1392 fib_cnt[i]);
1393 }
1394 }
1395
1396 vty_out(vty, "------\n");
1397 vty_out(vty, "%-20s %-20d %-20d \n", "Totals",
1398 rib_cnt[ZEBRA_ROUTE_TOTAL], fib_cnt[ZEBRA_ROUTE_TOTAL]);
1399 vty_out(vty, "\n");
8f527c5e
FL
1400}
1401
1402/*
1403 * Implementation of the ip route summary prefix command.
1404 *
1405 * This command prints the primary prefixes that have been installed by various
1406 * protocols on the box.
1407 *
1408 */
d62a17ae 1409static void vty_show_ip_route_summary_prefix(struct vty *vty,
1410 struct route_table *table)
8f527c5e 1411{
d62a17ae 1412 struct route_node *rn;
1413 struct route_entry *re;
1414 struct nexthop *nexthop;
8f527c5e
FL
1415#define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1416#define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
d7c0a89a
QY
1417 uint32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1418 uint32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1419 uint32_t i;
d62a17ae 1420 int cnt;
1421
1422 memset(&rib_cnt, 0, sizeof(rib_cnt));
1423 memset(&fib_cnt, 0, sizeof(fib_cnt));
1424 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
a2addae8 1425 RNODE_FOREACH_RE (rn, re) {
d62a17ae 1426
1427 /*
1428 * In case of ECMP, count only once.
1429 */
1430 cnt = 0;
7ee30f28 1431 for (nexthop = re->ng.nexthop; (!cnt && nexthop);
d62a17ae 1432 nexthop = nexthop->next) {
1433 cnt++;
1434 rib_cnt[ZEBRA_ROUTE_TOTAL]++;
1435 rib_cnt[re->type]++;
1436 if (CHECK_FLAG(nexthop->flags,
1437 NEXTHOP_FLAG_FIB)) {
1438 fib_cnt[ZEBRA_ROUTE_TOTAL]++;
1439 fib_cnt[re->type]++;
1440 }
1441 if (re->type == ZEBRA_ROUTE_BGP
1442 && CHECK_FLAG(re->flags, ZEBRA_FLAG_IBGP)) {
1443 rib_cnt[ZEBRA_ROUTE_IBGP]++;
1444 if (CHECK_FLAG(nexthop->flags,
1445 NEXTHOP_FLAG_FIB))
1446 fib_cnt[ZEBRA_ROUTE_IBGP]++;
1447 }
1448 }
1449 }
1450
1451 vty_out(vty, "%-20s %-20s %s (vrf %s)\n", "Route Source",
1452 "Prefix Routes", "FIB",
6ca30e9e 1453 zvrf_name(((rib_table_info_t *)route_table_get_info(table))->zvrf));
d62a17ae 1454
1455 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
1456 if (rib_cnt[i] > 0) {
1457 if (i == ZEBRA_ROUTE_BGP) {
1458 vty_out(vty, "%-20s %-20d %-20d \n", "ebgp",
1459 rib_cnt[ZEBRA_ROUTE_BGP]
1460 - rib_cnt[ZEBRA_ROUTE_IBGP],
1461 fib_cnt[ZEBRA_ROUTE_BGP]
1462 - fib_cnt[ZEBRA_ROUTE_IBGP]);
1463 vty_out(vty, "%-20s %-20d %-20d \n", "ibgp",
1464 rib_cnt[ZEBRA_ROUTE_IBGP],
1465 fib_cnt[ZEBRA_ROUTE_IBGP]);
1466 } else
1467 vty_out(vty, "%-20s %-20d %-20d \n",
1468 zebra_route_string(i), rib_cnt[i],
1469 fib_cnt[i]);
1470 }
1471 }
1472
1473 vty_out(vty, "------\n");
1474 vty_out(vty, "%-20s %-20d %-20d \n", "Totals",
1475 rib_cnt[ZEBRA_ROUTE_TOTAL], fib_cnt[ZEBRA_ROUTE_TOTAL]);
1476 vty_out(vty, "\n");
9343ce83
DS
1477}
1478
cddf391b
B
1479/*
1480 * Show IPv6 mroute command.Used to dump
1481 * the Multicast routing table.
1482 */
cddf391b
B
1483DEFUN (show_ipv6_mroute,
1484 show_ipv6_mroute_cmd,
9bf96c84 1485 "show ipv6 mroute [vrf NAME]",
cddf391b
B
1486 SHOW_STR
1487 IP_STR
9bf96c84
DW
1488 "IPv6 Multicast routing table\n"
1489 VRF_CMD_HELP_STR)
cddf391b 1490{
d62a17ae 1491 struct route_table *table;
1492 struct route_node *rn;
1493 struct route_entry *re;
1494 int first = 1;
1495 vrf_id_t vrf_id = VRF_DEFAULT;
1496
1497 if (argc == 5)
ec1db588 1498 VRF_GET_ID(vrf_id, argv[4]->arg, false);
d62a17ae 1499
1500 table = zebra_vrf_table(AFI_IP6, SAFI_MULTICAST, vrf_id);
1501 if (!table)
1502 return CMD_SUCCESS;
1503
1504 /* Show all IPv6 route. */
1505 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
a2addae8 1506 RNODE_FOREACH_RE (rn, re) {
d62a17ae 1507 if (first) {
1508 vty_out(vty, SHOW_ROUTE_V6_HEADER);
1509 first = 0;
1510 }
1511 vty_show_ip_route(vty, rn, re, NULL);
1512 }
1513 return CMD_SUCCESS;
cddf391b
B
1514}
1515
af41b63a
FL
1516DEFUN (show_ipv6_mroute_vrf_all,
1517 show_ipv6_mroute_vrf_all_cmd,
5bebf568 1518 "show ipv6 mroute vrf all",
af41b63a
FL
1519 SHOW_STR
1520 IP_STR
1521 "IPv6 Multicast routing table\n"
1522 VRF_ALL_CMD_HELP_STR)
1523{
d62a17ae 1524 struct route_table *table;
1525 struct route_node *rn;
1526 struct route_entry *re;
1527 struct vrf *vrf;
1528 struct zebra_vrf *zvrf;
1529 int first = 1;
1530
a2addae8 1531 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
d62a17ae 1532 if ((zvrf = vrf->info) == NULL
1533 || (table = zvrf->table[AFI_IP6][SAFI_MULTICAST]) == NULL)
1534 continue;
1535
1536 /* Show all IPv6 route. */
1537 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
a2addae8 1538 RNODE_FOREACH_RE (rn, re) {
d62a17ae 1539 if (first) {
1540 vty_out(vty, SHOW_ROUTE_V6_HEADER);
1541 first = 0;
1542 }
1543 vty_show_ip_route(vty, rn, re, NULL);
1544 }
1545 }
1546 return CMD_SUCCESS;
af41b63a
FL
1547}
1548
6baf7bb8
DS
1549DEFUN (allow_external_route_update,
1550 allow_external_route_update_cmd,
1551 "allow-external-route-update",
17d990c1 1552 "Allow FRR routes to be overwritten by external processes\n")
6baf7bb8 1553{
d62a17ae 1554 allow_delete = 1;
6baf7bb8 1555
d62a17ae 1556 return CMD_SUCCESS;
6baf7bb8
DS
1557}
1558
1559DEFUN (no_allow_external_route_update,
1560 no_allow_external_route_update_cmd,
1561 "no allow-external-route-update",
17d990c1
DS
1562 NO_STR
1563 "Allow FRR routes to be overwritten by external processes\n")
6baf7bb8 1564{
d62a17ae 1565 allow_delete = 0;
6baf7bb8 1566
d62a17ae 1567 return CMD_SUCCESS;
6baf7bb8
DS
1568}
1569
12f6fb97
DS
1570/* show vrf */
1571DEFUN (show_vrf,
1572 show_vrf_cmd,
1573 "show vrf",
1574 SHOW_STR
1575 "VRF\n")
1576{
d62a17ae 1577 struct vrf *vrf;
1578 struct zebra_vrf *zvrf;
12f6fb97 1579
b73823ef
PG
1580 if (vrf_is_backend_netns())
1581 vty_out(vty, "netns-based vrfs\n");
1582
a2addae8 1583 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
d62a17ae 1584 if (!(zvrf = vrf->info))
1585 continue;
90ac32c2 1586 if (zvrf_id(zvrf) == VRF_DEFAULT)
d62a17ae 1587 continue;
1588
1589 vty_out(vty, "vrf %s ", zvrf_name(zvrf));
996c9314 1590 if (zvrf_id(zvrf) == VRF_UNKNOWN || !zvrf_is_active(zvrf))
d62a17ae 1591 vty_out(vty, "inactive");
81c9005f 1592 else if (zvrf_ns_name(zvrf))
996c9314
LB
1593 vty_out(vty, "id %u netns %s", zvrf_id(zvrf),
1594 zvrf_ns_name(zvrf));
d62a17ae 1595 else
1596 vty_out(vty, "id %u table %u", zvrf_id(zvrf),
1597 zvrf->table_id);
22bd3e94 1598 if (vrf_is_user_cfged(vrf))
1599 vty_out(vty, " (configured)");
d62a17ae 1600 vty_out(vty, "\n");
1601 }
12f6fb97 1602
d62a17ae 1603 return CMD_SUCCESS;
12f6fb97
DS
1604}
1605
62710e2b 1606DEFUN_HIDDEN (default_vrf_vni_mapping,
e8d26197 1607 default_vrf_vni_mapping_cmd,
c48d9f5f 1608 "vni " CMD_VNI_RANGE "[prefix-routes-only]",
e8d26197 1609 "VNI corresponding to the DEFAULT VRF\n"
c48d9f5f
MK
1610 "VNI-ID\n"
1611 "Prefix routes only \n")
e8d26197
MK
1612{
1613 int ret = 0;
1614 char err[ERR_STR_SZ];
1615 struct zebra_vrf *zvrf = NULL;
1616 vni_t vni = strtoul(argv[1]->arg, NULL, 10);
c48d9f5f 1617 int filter = 0;
e8d26197
MK
1618
1619 zvrf = vrf_info_lookup(VRF_DEFAULT);
1620 if (!zvrf)
1621 return CMD_WARNING;
1622
c48d9f5f
MK
1623 if (argc == 3)
1624 filter = 1;
1625
1626 ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ,
1627 filter, 1);
e8d26197
MK
1628 if (ret != 0) {
1629 vty_out(vty, "%s\n", err);
1630 return CMD_WARNING;
1631 }
1632
1633 return CMD_SUCCESS;
1634}
1635
62710e2b 1636DEFUN_HIDDEN (no_default_vrf_vni_mapping,
e8d26197
MK
1637 no_default_vrf_vni_mapping_cmd,
1638 "no vni " CMD_VNI_RANGE,
1639 NO_STR
1640 "VNI corresponding to DEFAULT VRF\n"
1641 "VNI-ID")
1642{
1643 int ret = 0;
1644 char err[ERR_STR_SZ];
1645 vni_t vni = strtoul(argv[2]->arg, NULL, 10);
1646 struct zebra_vrf *zvrf = NULL;
1647
1648 zvrf = vrf_info_lookup(VRF_DEFAULT);
1649 if (!zvrf)
1650 return CMD_WARNING;
1651
c48d9f5f 1652 ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ, 0, 0);
e8d26197
MK
1653 if (ret != 0) {
1654 vty_out(vty, "%s\n", err);
1655 return CMD_WARNING;
1656 }
1657
1658 return CMD_SUCCESS;
1659}
1660
b7cfce93
MK
1661DEFUN (vrf_vni_mapping,
1662 vrf_vni_mapping_cmd,
c48d9f5f 1663 "vni " CMD_VNI_RANGE "[prefix-routes-only]",
e8d26197 1664 "VNI corresponding to tenant VRF\n"
c48d9f5f
MK
1665 "VNI-ID\n"
1666 "prefix-routes-only\n")
b7cfce93
MK
1667{
1668 int ret = 0;
c48d9f5f 1669 int filter = 0;
b7cfce93
MK
1670
1671 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
1672 vni_t vni = strtoul(argv[1]->arg, NULL, 10);
1673 char err[ERR_STR_SZ];
1674
1675 assert(vrf);
1676 assert(zvrf);
1677
c48d9f5f
MK
1678 if (argc == 3)
1679 filter = 1;
1680
317f1fe0 1681 /* Mark as having FRR configuration */
1682 vrf_set_user_cfged(vrf);
c48d9f5f
MK
1683 ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ,
1684 filter, 1);
b7cfce93
MK
1685 if (ret != 0) {
1686 vty_out(vty, "%s\n", err);
1687 return CMD_WARNING;
1688 }
1689
1690 return CMD_SUCCESS;
1691}
1692
1693DEFUN (no_vrf_vni_mapping,
1694 no_vrf_vni_mapping_cmd,
cf299714 1695 "no vni " CMD_VNI_RANGE "[prefix-routes-only]",
b7cfce93 1696 NO_STR
e8d26197 1697 "VNI corresponding to tenant VRF\n"
cf299714
MK
1698 "VNI-ID\n"
1699 "prefix-routes-only\n")
b7cfce93
MK
1700{
1701 int ret = 0;
cf299714 1702 int filter = 0;
b7cfce93
MK
1703 char err[ERR_STR_SZ];
1704 vni_t vni = strtoul(argv[2]->arg, NULL, 10);
1705
1706 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
1707
1708 assert(vrf);
1709 assert(zvrf);
1710
cf299714
MK
1711 if (argc == 4)
1712 filter = 1;
1713
1714 ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err,
1715 ERR_STR_SZ, filter, 0);
b7cfce93
MK
1716 if (ret != 0) {
1717 vty_out(vty, "%s\n", err);
1718 return CMD_WARNING;
1719 }
1720
22bd3e94 1721 /* If no other FRR config for this VRF, mark accordingly. */
1722 if (!zebra_vrf_has_config(zvrf))
1723 vrf_reset_user_cfged(vrf);
1724
b7cfce93
MK
1725 return CMD_SUCCESS;
1726}
1727
1728/* show vrf */
1729DEFUN (show_vrf_vni,
1730 show_vrf_vni_cmd,
35be5542 1731 "show vrf vni [json]",
b7cfce93
MK
1732 SHOW_STR
1733 "VRF\n"
35be5542
MK
1734 "VNI\n"
1735 JSON_STR)
b7cfce93
MK
1736{
1737 struct vrf *vrf;
1738 struct zebra_vrf *zvrf;
35be5542
MK
1739 json_object *json = NULL;
1740 json_object *json_vrfs = NULL;
9f049418 1741 bool uj = use_json(argc, argv);
35be5542
MK
1742
1743 if (uj) {
1744 json = json_object_new_object();
1745 json_vrfs = json_object_new_array();
1746 }
b7cfce93 1747
4cce389e 1748 if (!uj)
996c9314
LB
1749 vty_out(vty, "%-37s %-10s %-20s %-20s %-5s %-18s\n", "VRF",
1750 "VNI", "VxLAN IF", "L3-SVI", "State", "Rmac");
4cce389e 1751
996c9314 1752 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
b7cfce93
MK
1753 zvrf = vrf->info;
1754 if (!zvrf)
1755 continue;
1756
4cce389e 1757 zebra_vxlan_print_vrf_vni(vty, zvrf, json_vrfs);
35be5542
MK
1758 }
1759
1760 if (uj) {
1761 json_object_object_add(json, "vrfs", json_vrfs);
1762 vty_out(vty, "%s\n", json_object_to_json_string_ext(
1763 json, JSON_C_TO_STRING_PRETTY));
1764 json_object_free(json);
b7cfce93
MK
1765 }
1766
1767 return CMD_SUCCESS;
1768}
1769
4cce389e
MK
1770DEFUN (show_evpn_global,
1771 show_evpn_global_cmd,
1772 "show evpn [json]",
1773 SHOW_STR
1774 "EVPN\n"
1775 JSON_STR)
1776{
9f049418 1777 bool uj = use_json(argc, argv);
4cce389e
MK
1778
1779 zebra_vxlan_print_evpn(vty, uj);
1780 return CMD_SUCCESS;
1781}
1782
cec2e17d 1783DEFUN (show_evpn_vni,
1784 show_evpn_vni_cmd,
cd233079 1785 "show evpn vni [json]",
cec2e17d 1786 SHOW_STR
1787 "EVPN\n"
cd233079 1788 "VxLAN information\n"
bd592158 1789 JSON_STR)
cec2e17d 1790{
d62a17ae 1791 struct zebra_vrf *zvrf;
9f049418 1792 bool uj = use_json(argc, argv);
cec2e17d 1793
d62a17ae 1794 zvrf = vrf_info_lookup(VRF_DEFAULT);
cd233079 1795 zebra_vxlan_print_vnis(vty, zvrf, uj);
d62a17ae 1796 return CMD_SUCCESS;
cec2e17d 1797}
1798
1799DEFUN (show_evpn_vni_vni,
1800 show_evpn_vni_vni_cmd,
cd233079 1801 "show evpn vni " CMD_VNI_RANGE "[json]",
cec2e17d 1802 SHOW_STR
1803 "EVPN\n"
1804 "VxLAN Network Identifier\n"
cd233079 1805 "VNI number\n"
bd592158 1806 JSON_STR)
cec2e17d 1807{
d62a17ae 1808 struct zebra_vrf *zvrf;
1809 vni_t vni;
9f049418 1810 bool uj = use_json(argc, argv);
cec2e17d 1811
d62a17ae 1812 vni = strtoul(argv[3]->arg, NULL, 10);
1813 zvrf = vrf_info_lookup(VRF_DEFAULT);
cd233079 1814 zebra_vxlan_print_vni(vty, zvrf, vni, uj);
d62a17ae 1815 return CMD_SUCCESS;
cec2e17d 1816}
1817
4cce389e
MK
1818DEFUN (show_evpn_rmac_vni_mac,
1819 show_evpn_rmac_vni_mac_cmd,
1820 "show evpn rmac vni " CMD_VNI_RANGE " mac WORD [json]",
9aa741ea
MK
1821 SHOW_STR
1822 "EVPN\n"
1823 "RMAC\n"
4cce389e 1824 "L3 VNI\n"
9aa741ea
MK
1825 "VNI number\n"
1826 "MAC\n"
316f4ca4
MK
1827 "mac-address (e.g. 0a:0a:0a:0a:0a:0a)\n"
1828 JSON_STR)
9aa741ea
MK
1829{
1830 vni_t l3vni = 0;
1831 struct ethaddr mac;
9f049418 1832 bool uj = use_json(argc, argv);
9aa741ea
MK
1833
1834 l3vni = strtoul(argv[4]->arg, NULL, 10);
1835 if (!prefix_str2mac(argv[6]->arg, &mac)) {
1836 vty_out(vty, "%% Malformed MAC address\n");
1837 return CMD_WARNING;
1838 }
316f4ca4 1839 zebra_vxlan_print_specific_rmac_l3vni(vty, l3vni, &mac, uj);
9aa741ea
MK
1840 return CMD_SUCCESS;
1841}
1842
4cce389e
MK
1843DEFUN (show_evpn_rmac_vni,
1844 show_evpn_rmac_vni_cmd,
1845 "show evpn rmac vni " CMD_VNI_RANGE "[json]",
b7cfce93
MK
1846 SHOW_STR
1847 "EVPN\n"
1848 "RMAC\n"
4cce389e 1849 "L3 VNI\n"
b7cfce93
MK
1850 "VNI number\n"
1851 JSON_STR)
1852{
1853 vni_t l3vni = 0;
9f049418 1854 bool uj = use_json(argc, argv);
b7cfce93
MK
1855
1856 l3vni = strtoul(argv[4]->arg, NULL, 10);
1857 zebra_vxlan_print_rmacs_l3vni(vty, l3vni, uj);
1858
1859 return CMD_SUCCESS;
1860}
1861
4cce389e
MK
1862DEFUN (show_evpn_rmac_vni_all,
1863 show_evpn_rmac_vni_all_cmd,
1864 "show evpn rmac vni all [json]",
b7cfce93
MK
1865 SHOW_STR
1866 "EVPN\n"
1867 "RMAC addresses\n"
4cce389e 1868 "L3 VNI\n"
b7cfce93
MK
1869 "All VNIs\n"
1870 JSON_STR)
1871{
9f049418 1872 bool uj = use_json(argc, argv);
b7cfce93
MK
1873
1874 zebra_vxlan_print_rmacs_all_l3vni(vty, uj);
1875
1876 return CMD_SUCCESS;
1877}
1878
4cce389e
MK
1879DEFUN (show_evpn_nh_vni_ip,
1880 show_evpn_nh_vni_ip_cmd,
1881 "show evpn next-hops vni " CMD_VNI_RANGE " ip WORD [json]",
9aa741ea
MK
1882 SHOW_STR
1883 "EVPN\n"
1884 "Remote Vteps\n"
4cce389e 1885 "L3 VNI\n"
9aa741ea
MK
1886 "VNI number\n"
1887 "Ip address\n"
c0e519d3
MK
1888 "Host address (ipv4 or ipv6)\n"
1889 JSON_STR)
9aa741ea
MK
1890{
1891 vni_t l3vni;
9aa741ea 1892 struct ipaddr ip;
9f049418 1893 bool uj = use_json(argc, argv);
9aa741ea
MK
1894
1895 l3vni = strtoul(argv[4]->arg, NULL, 10);
1896 if (str2ipaddr(argv[6]->arg, &ip) != 0) {
1897 if (!uj)
1898 vty_out(vty, "%% Malformed Neighbor address\n");
1899 return CMD_WARNING;
1900 }
c0e519d3 1901 zebra_vxlan_print_specific_nh_l3vni(vty, l3vni, &ip, uj);
9aa741ea
MK
1902
1903 return CMD_SUCCESS;
1904}
1905
4cce389e
MK
1906DEFUN (show_evpn_nh_vni,
1907 show_evpn_nh_vni_cmd,
1908 "show evpn next-hops vni " CMD_VNI_RANGE "[json]",
b7cfce93
MK
1909 SHOW_STR
1910 "EVPN\n"
1911 "Remote Vteps\n"
4cce389e 1912 "L3 VNI\n"
b7cfce93
MK
1913 "VNI number\n"
1914 JSON_STR)
1915{
1916 vni_t l3vni;
9f049418 1917 bool uj = use_json(argc, argv);
b7cfce93
MK
1918
1919 l3vni = strtoul(argv[4]->arg, NULL, 10);
1920 zebra_vxlan_print_nh_l3vni(vty, l3vni, uj);
1921
1922 return CMD_SUCCESS;
1923}
1924
4cce389e
MK
1925DEFUN (show_evpn_nh_vni_all,
1926 show_evpn_nh_vni_all_cmd,
1927 "show evpn next-hops vni all [json]",
b7cfce93
MK
1928 SHOW_STR
1929 "EVPN\n"
1930 "Remote VTEPs\n"
4cce389e 1931 "L3 VNI\n"
b7cfce93
MK
1932 "All VNIs\n"
1933 JSON_STR)
1934{
9f049418 1935 bool uj = use_json(argc, argv);
b7cfce93
MK
1936
1937 zebra_vxlan_print_nh_all_l3vni(vty, uj);
1938
1939 return CMD_SUCCESS;
1940}
1941
cec2e17d 1942DEFUN (show_evpn_mac_vni,
1943 show_evpn_mac_vni_cmd,
cd233079 1944 "show evpn mac vni " CMD_VNI_RANGE "[json]",
cec2e17d 1945 SHOW_STR
1946 "EVPN\n"
1947 "MAC addresses\n"
1948 "VxLAN Network Identifier\n"
cd233079 1949 "VNI number\n"
bd592158 1950 JSON_STR)
cec2e17d 1951{
d62a17ae 1952 struct zebra_vrf *zvrf;
1953 vni_t vni;
9f049418 1954 bool uj = use_json(argc, argv);
cec2e17d 1955
d62a17ae 1956 vni = strtoul(argv[4]->arg, NULL, 10);
1957 zvrf = vrf_info_lookup(VRF_DEFAULT);
cd233079 1958 zebra_vxlan_print_macs_vni(vty, zvrf, vni, uj);
d62a17ae 1959 return CMD_SUCCESS;
cec2e17d 1960}
1961
1962DEFUN (show_evpn_mac_vni_all,
1963 show_evpn_mac_vni_all_cmd,
cd233079 1964 "show evpn mac vni all [json]",
cec2e17d 1965 SHOW_STR
1966 "EVPN\n"
1967 "MAC addresses\n"
1968 "VxLAN Network Identifier\n"
cd233079 1969 "All VNIs\n"
bd592158 1970 JSON_STR)
cec2e17d 1971{
d62a17ae 1972 struct zebra_vrf *zvrf;
9f049418 1973 bool uj = use_json(argc, argv);
cec2e17d 1974
d62a17ae 1975 zvrf = vrf_info_lookup(VRF_DEFAULT);
cd233079 1976 zebra_vxlan_print_macs_all_vni(vty, zvrf, uj);
d62a17ae 1977 return CMD_SUCCESS;
cec2e17d 1978}
1979
1980DEFUN (show_evpn_mac_vni_all_vtep,
1981 show_evpn_mac_vni_all_vtep_cmd,
cd233079 1982 "show evpn mac vni all vtep A.B.C.D [json]",
cec2e17d 1983 SHOW_STR
1984 "EVPN\n"
1985 "MAC addresses\n"
1986 "VxLAN Network Identifier\n"
1987 "All VNIs\n"
1988 "Remote VTEP\n"
cd233079 1989 "Remote VTEP IP address\n"
bd592158 1990 JSON_STR)
cec2e17d 1991{
d62a17ae 1992 struct zebra_vrf *zvrf;
1993 struct in_addr vtep_ip;
9f049418 1994 bool uj = use_json(argc, argv);
cec2e17d 1995
d62a17ae 1996 if (!inet_aton(argv[6]->arg, &vtep_ip)) {
cd233079
CS
1997 if (!uj)
1998 vty_out(vty, "%% Malformed VTEP IP address\n");
d62a17ae 1999 return CMD_WARNING;
2000 }
2001 zvrf = vrf_info_lookup(VRF_DEFAULT);
cd233079 2002 zebra_vxlan_print_macs_all_vni_vtep(vty, zvrf, vtep_ip, uj);
cec2e17d 2003
d62a17ae 2004 return CMD_SUCCESS;
cec2e17d 2005}
2006
2007
2008DEFUN (show_evpn_mac_vni_mac,
2009 show_evpn_mac_vni_mac_cmd,
2010 "show evpn mac vni " CMD_VNI_RANGE " mac WORD",
2011 SHOW_STR
2012 "EVPN\n"
2013 "MAC addresses\n"
2014 "VxLAN Network Identifier\n"
2015 "VNI number\n"
2016 "MAC\n"
2017 "MAC address (e.g., 00:e0:ec:20:12:62)\n")
2018{
d62a17ae 2019 struct zebra_vrf *zvrf;
2020 vni_t vni;
2021 struct ethaddr mac;
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);
2029 zebra_vxlan_print_specific_mac_vni(vty, zvrf, vni, &mac);
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
2571/* Table configuration write function. */
2572static int config_write_table(struct vty *vty)
2573{
2574 if (zebrad.rtm_table_default)
2575 vty_out(vty, "table %d\n", zebrad.rtm_table_default);
2576 return 0;
2577}
2578
2579/* IPForwarding configuration write function. */
2580static int config_write_forwarding(struct vty *vty)
2581{
2582 /* FIXME: Find better place for that. */
2583 router_id_write(vty);
2584
2585 if (!ipforward())
2586 vty_out(vty, "no ip forwarding\n");
2587 if (!ipforward_ipv6())
2588 vty_out(vty, "no ipv6 forwarding\n");
2589 vty_out(vty, "!\n");
2590 return 0;
2591}
2592
718e3744 2593/* IP node for static routes. */
d62a17ae 2594static struct cmd_node ip_node = {IP_NODE, "", 1};
2595static struct cmd_node protocol_node = {PROTOCOL_NODE, "", 1};
c0d136ae
DS
2596/* table node for routing tables. */
2597static struct cmd_node table_node = {TABLE_NODE,
2598 "", /* This node has no interface. */
2599 1};
2600static struct cmd_node forwarding_node = {FORWARDING_NODE,
2601 "", /* This node has no interface. */
2602 1};
718e3744 2603
2604/* Route VTY. */
d62a17ae 2605void zebra_vty_init(void)
2606{
c0d136ae
DS
2607 /* Install configuration write function. */
2608 install_node(&table_node, config_write_table);
2609 install_node(&forwarding_node, config_write_forwarding);
2610
2611 install_element(VIEW_NODE, &show_ip_forwarding_cmd);
2612 install_element(CONFIG_NODE, &ip_forwarding_cmd);
2613 install_element(CONFIG_NODE, &no_ip_forwarding_cmd);
2614 install_element(ENABLE_NODE, &show_zebra_cmd);
2615
2616#ifdef HAVE_NETLINK
2617 install_element(VIEW_NODE, &show_table_cmd);
2618 install_element(CONFIG_NODE, &config_table_cmd);
2619 install_element(CONFIG_NODE, &no_config_table_cmd);
2620#endif /* HAVE_NETLINK */
2621
2622 install_element(VIEW_NODE, &show_ipv6_forwarding_cmd);
2623 install_element(CONFIG_NODE, &ipv6_forwarding_cmd);
2624 install_element(CONFIG_NODE, &no_ipv6_forwarding_cmd);
2625
2626 /* Route-map */
2627 zebra_route_map_init();
2628
d62a17ae 2629 install_node(&ip_node, zebra_ip_config);
2630 install_node(&protocol_node, config_write_protocol);
2631
2632 install_element(CONFIG_NODE, &allow_external_route_update_cmd);
2633 install_element(CONFIG_NODE, &no_allow_external_route_update_cmd);
7e24fdf3 2634
d62a17ae 2635 install_element(CONFIG_NODE, &ip_multicast_mode_cmd);
2636 install_element(CONFIG_NODE, &no_ip_multicast_mode_cmd);
b3b08602 2637
d62a17ae 2638 install_element(CONFIG_NODE, &ip_zebra_import_table_distance_cmd);
2639 install_element(CONFIG_NODE, &no_ip_zebra_import_table_cmd);
3a30f50f
DS
2640 install_element(CONFIG_NODE, &zebra_workqueue_timer_cmd);
2641 install_element(CONFIG_NODE, &no_zebra_workqueue_timer_cmd);
62d52ded
DS
2642 install_element(CONFIG_NODE, &zebra_packet_process_cmd);
2643 install_element(CONFIG_NODE, &no_zebra_packet_process_cmd);
d62a17ae 2644
2645 install_element(VIEW_NODE, &show_vrf_cmd);
b7cfce93 2646 install_element(VIEW_NODE, &show_vrf_vni_cmd);
ecffa493 2647 install_element(VIEW_NODE, &show_route_cmd);
ae825b8b 2648 install_element(VIEW_NODE, &show_route_table_cmd);
87d6ac7a
PG
2649 if (vrf_is_backend_netns())
2650 install_element(VIEW_NODE, &show_route_table_vrf_cmd);
5ce91022
RW
2651 install_element(VIEW_NODE, &show_route_detail_cmd);
2652 install_element(VIEW_NODE, &show_route_summary_cmd);
d62a17ae 2653 install_element(VIEW_NODE, &show_ip_nht_cmd);
2654 install_element(VIEW_NODE, &show_ip_nht_vrf_all_cmd);
2655 install_element(VIEW_NODE, &show_ipv6_nht_cmd);
2656 install_element(VIEW_NODE, &show_ipv6_nht_vrf_all_cmd);
d62a17ae 2657
2658 install_element(VIEW_NODE, &show_ip_rpf_cmd);
2659 install_element(VIEW_NODE, &show_ip_rpf_addr_cmd);
2660
d62a17ae 2661 install_element(CONFIG_NODE, &ip_nht_default_route_cmd);
2662 install_element(CONFIG_NODE, &no_ip_nht_default_route_cmd);
2663 install_element(CONFIG_NODE, &ipv6_nht_default_route_cmd);
2664 install_element(CONFIG_NODE, &no_ipv6_nht_default_route_cmd);
214e5c26 2665 install_element(VRF_NODE, &ip_nht_default_route_cmd);
2666 install_element(VRF_NODE, &no_ip_nht_default_route_cmd);
2667 install_element(VRF_NODE, &ipv6_nht_default_route_cmd);
2668 install_element(VRF_NODE, &no_ipv6_nht_default_route_cmd);
d62a17ae 2669 install_element(VIEW_NODE, &show_ipv6_mroute_cmd);
2670
2671 /* Commands for VRF */
d62a17ae 2672 install_element(VIEW_NODE, &show_ipv6_mroute_vrf_all_cmd);
2673
4cce389e 2674 install_element(VIEW_NODE, &show_evpn_global_cmd);
d62a17ae 2675 install_element(VIEW_NODE, &show_evpn_vni_cmd);
2676 install_element(VIEW_NODE, &show_evpn_vni_vni_cmd);
4cce389e
MK
2677 install_element(VIEW_NODE, &show_evpn_rmac_vni_mac_cmd);
2678 install_element(VIEW_NODE, &show_evpn_rmac_vni_cmd);
2679 install_element(VIEW_NODE, &show_evpn_rmac_vni_all_cmd);
2680 install_element(VIEW_NODE, &show_evpn_nh_vni_ip_cmd);
2681 install_element(VIEW_NODE, &show_evpn_nh_vni_cmd);
2682 install_element(VIEW_NODE, &show_evpn_nh_vni_all_cmd);
d62a17ae 2683 install_element(VIEW_NODE, &show_evpn_mac_vni_cmd);
2684 install_element(VIEW_NODE, &show_evpn_mac_vni_all_cmd);
2685 install_element(VIEW_NODE, &show_evpn_mac_vni_all_vtep_cmd);
2686 install_element(VIEW_NODE, &show_evpn_mac_vni_mac_cmd);
2687 install_element(VIEW_NODE, &show_evpn_mac_vni_vtep_cmd);
2688 install_element(VIEW_NODE, &show_evpn_neigh_vni_cmd);
2689 install_element(VIEW_NODE, &show_evpn_neigh_vni_all_cmd);
2690 install_element(VIEW_NODE, &show_evpn_neigh_vni_neigh_cmd);
2691 install_element(VIEW_NODE, &show_evpn_neigh_vni_vtep_cmd);
b7cfce93 2692
586f4ccf
PG
2693 install_element(VIEW_NODE, &show_pbr_ipset_cmd);
2694 install_element(VIEW_NODE, &show_pbr_iptable_cmd);
2695
e8d26197
MK
2696 install_element(CONFIG_NODE, &default_vrf_vni_mapping_cmd);
2697 install_element(CONFIG_NODE, &no_default_vrf_vni_mapping_cmd);
b7cfce93
MK
2698 install_element(VRF_NODE, &vrf_vni_mapping_cmd);
2699 install_element(VRF_NODE, &no_vrf_vni_mapping_cmd);
4060008b 2700
7e24fdf3 2701
718e3744 2702}