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