]> git.proxmox.com Git - mirror_frr.git/blame - zebra/zebra_vty.c
zebra: vrf aware routmap is missing in Zebra #2802(Part 2 of 4)
[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,
9f049418 58 safi_t safi, bool use_fib, bool 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{
9f049418 138 bool uj = use_json(argc, argv);
d62a17ae 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
305 vty_out(vty, "(vrf UKNOWN)");
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
680 vty_out(vty, "(vrf UKNOWN)");
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,
9f049418 763 unsigned short ospf_instance_id, bool use_json)
d62a17ae 764{
d62a17ae 765 struct route_node *rn;
766 struct route_entry *re;
767 int first = 1;
ae825b8b 768 rib_dest_t *dest;
d62a17ae 769 json_object *json = NULL;
770 json_object *json_prefix = NULL;
ae825b8b
DS
771 uint32_t addr;
772 char buf[BUFSIZ];
d62a17ae 773
774 if (use_json)
775 json = json_object_new_object();
776
777 /* Show all routes. */
c9591045 778 for (rn = route_top(table); rn; rn = srcdest_route_next(rn)) {
5f7a4718
DS
779 dest = rib_dest_from_rnode(rn);
780
a2addae8 781 RNODE_FOREACH_RE (rn, re) {
996c9314 782 if (use_fib && re != dest->selected_fib)
d62a17ae 783 continue;
784
785 if (tag && re->tag != tag)
786 continue;
787
788 if (longer_prefix_p
789 && !prefix_match(longer_prefix_p, &rn->p))
790 continue;
791
792 /* This can only be true when the afi is IPv4 */
793 if (supernets_only) {
794 addr = ntohl(rn->p.u.prefix4.s_addr);
795
796 if (IN_CLASSC(addr) && rn->p.prefixlen >= 24)
797 continue;
798
799 if (IN_CLASSB(addr) && rn->p.prefixlen >= 16)
800 continue;
801
802 if (IN_CLASSA(addr) && rn->p.prefixlen >= 8)
803 continue;
804 }
805
806 if (type && re->type != type)
807 continue;
808
809 if (ospf_instance_id
810 && (re->type != ZEBRA_ROUTE_OSPF
811 || re->instance != ospf_instance_id))
812 continue;
813
814 if (use_json) {
815 if (!json_prefix)
816 json_prefix = json_object_new_array();
817 } else {
818 if (first) {
819 if (afi == AFI_IP)
820 vty_out(vty,
821 SHOW_ROUTE_V4_HEADER);
822 else
823 vty_out(vty,
824 SHOW_ROUTE_V6_HEADER);
825
826 if (zvrf_id(zvrf) != VRF_DEFAULT)
827 vty_out(vty, "\nVRF %s:\n",
828 zvrf_name(zvrf));
829
830 first = 0;
831 }
832 }
833
834 vty_show_ip_route(vty, rn, re, json_prefix);
835 }
836
837 if (json_prefix) {
96d71e38 838 prefix2str(&rn->p, buf, sizeof(buf));
d62a17ae 839 json_object_object_add(json, buf, json_prefix);
840 json_prefix = NULL;
841 }
842 }
843
844 if (use_json) {
96d71e38
AD
845 vty_out(vty, "%s\n", json_object_to_json_string_ext(json,
846 JSON_C_TO_STRING_PRETTY));
d62a17ae 847 json_object_free(json);
848 }
ae825b8b
DS
849}
850
851static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi,
9f049418 852 safi_t safi, bool use_fib, bool use_json,
ae825b8b
DS
853 route_tag_t tag,
854 const struct prefix *longer_prefix_p,
855 bool supernets_only, int type,
d7c0a89a 856 unsigned short ospf_instance_id)
ae825b8b
DS
857{
858 struct route_table *table;
859 struct zebra_vrf *zvrf = NULL;
860
861 if (!(zvrf = zebra_vrf_lookup_by_name(vrf_name))) {
862 if (use_json)
863 vty_out(vty, "{}\n");
864 else
865 vty_out(vty, "vrf %s not defined\n", vrf_name);
866 return CMD_SUCCESS;
867 }
868
869 if (zvrf_id(zvrf) == VRF_UNKNOWN) {
870 if (use_json)
871 vty_out(vty, "{}\n");
872 else
873 vty_out(vty, "vrf %s inactive\n", vrf_name);
874 return CMD_SUCCESS;
875 }
876
877 table = zebra_vrf_table(afi, safi, zvrf_id(zvrf));
878 if (!table) {
879 if (use_json)
880 vty_out(vty, "{}\n");
881 return CMD_SUCCESS;
882 }
883
884 do_show_route_helper(vty, zvrf, table, afi, use_fib, tag,
885 longer_prefix_p, supernets_only, type,
886 ospf_instance_id, use_json);
887
888 return CMD_SUCCESS;
889}
890
891DEFPY (show_route_table,
892 show_route_table_cmd,
893 "show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table [json$json]",
894 SHOW_STR
895 IP_STR
896 IP6_STR
897 "IP routing table\n"
898 "Table to display\n"
899 "The table number to display, if available\n"
900 JSON_STR)
901{
902 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
903 struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
904 struct route_table *t;
905
906 t = zebra_ns_find_table(zvrf->zns, table, afi);
907 if (t)
908 do_show_route_helper(vty, zvrf, t, afi, false, 0, false, false,
909 0, 0, !!json);
d62a17ae 910
911 return CMD_SUCCESS;
abbda2d4 912}
d511d7f1 913
87d6ac7a
PG
914DEFPY (show_route_table_vrf,
915 show_route_table_vrf_cmd,
916 "show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table vrf NAME$vrf_name [json$json]",
917 SHOW_STR
918 IP_STR
919 IP6_STR
920 "IP routing table\n"
921 "Table to display\n"
922 "The table number to display, if available\n"
923 VRF_CMD_HELP_STR
924 JSON_STR)
925{
926 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
927 struct zebra_vrf *zvrf;
928 struct route_table *t;
929 vrf_id_t vrf_id = VRF_DEFAULT;
930
931 if (vrf_name)
ec1db588 932 VRF_GET_ID(vrf_id, vrf_name, !!json);
87d6ac7a
PG
933 zvrf = zebra_vrf_lookup_by_id(vrf_id);
934
935 t = zebra_ns_find_table(zvrf->zns, table, afi);
936 if (t)
937 do_show_route_helper(vty, zvrf, t, afi, false, 0, false, false,
938 0, 0, !!json);
939
940 return CMD_SUCCESS;
941}
942
8f527c5e
FL
943DEFUN (show_ip_nht,
944 show_ip_nht_cmd,
9bf96c84 945 "show ip nht [vrf NAME]",
8f527c5e
FL
946 SHOW_STR
947 IP_STR
9bf96c84
DW
948 "IP nexthop tracking table\n"
949 VRF_CMD_HELP_STR)
8f527c5e 950{
d62a17ae 951 int idx_vrf = 4;
952 vrf_id_t vrf_id = VRF_DEFAULT;
12f6fb97 953
d62a17ae 954 if (argc == 5)
ec1db588 955 VRF_GET_ID(vrf_id, argv[idx_vrf]->arg, false);
12f6fb97 956
d62a17ae 957 zebra_print_rnh_table(vrf_id, AF_INET, vty, RNH_NEXTHOP_TYPE);
958 return CMD_SUCCESS;
8f527c5e
FL
959}
960
12f6fb97 961
d511d7f1
DS
962DEFUN (show_ip_nht_vrf_all,
963 show_ip_nht_vrf_all_cmd,
5bebf568 964 "show ip nht vrf all",
d511d7f1
DS
965 SHOW_STR
966 IP_STR
967 "IP nexthop tracking table\n"
968 VRF_ALL_CMD_HELP_STR)
969{
d62a17ae 970 struct vrf *vrf;
971 struct zebra_vrf *zvrf;
d511d7f1 972
a2addae8
RW
973 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
974 if ((zvrf = vrf->info) != NULL) {
975 vty_out(vty, "\nVRF %s:\n", zvrf_name(zvrf));
976 zebra_print_rnh_table(zvrf_id(zvrf), AF_INET, vty,
977 RNH_NEXTHOP_TYPE);
978 }
d511d7f1 979
d62a17ae 980 return CMD_SUCCESS;
d511d7f1
DS
981}
982
8f527c5e
FL
983DEFUN (show_ipv6_nht,
984 show_ipv6_nht_cmd,
9bf96c84 985 "show ipv6 nht [vrf NAME]",
8f527c5e 986 SHOW_STR
689e6694 987 IPV6_STR
9bf96c84
DW
988 "IPv6 nexthop tracking table\n"
989 VRF_CMD_HELP_STR)
8f527c5e 990{
d62a17ae 991 int idx_vrf = 4;
992 vrf_id_t vrf_id = VRF_DEFAULT;
12f6fb97 993
d62a17ae 994 if (argc == 5)
ec1db588 995 VRF_GET_ID(vrf_id, argv[idx_vrf]->arg, false);
12f6fb97 996
d62a17ae 997 zebra_print_rnh_table(vrf_id, AF_INET6, vty, RNH_NEXTHOP_TYPE);
998 return CMD_SUCCESS;
8f527c5e
FL
999}
1000
12f6fb97 1001
d511d7f1
DS
1002DEFUN (show_ipv6_nht_vrf_all,
1003 show_ipv6_nht_vrf_all_cmd,
5bebf568 1004 "show ipv6 nht vrf all",
d511d7f1
DS
1005 SHOW_STR
1006 IP_STR
1007 "IPv6 nexthop tracking table\n"
1008 VRF_ALL_CMD_HELP_STR)
1009{
d62a17ae 1010 struct vrf *vrf;
1011 struct zebra_vrf *zvrf;
d511d7f1 1012
a2addae8
RW
1013 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
1014 if ((zvrf = vrf->info) != NULL) {
1015 vty_out(vty, "\nVRF %s:\n", zvrf_name(zvrf));
1016 zebra_print_rnh_table(zvrf_id(zvrf), AF_INET6, vty,
1017 RNH_NEXTHOP_TYPE);
1018 }
d511d7f1 1019
d62a17ae 1020 return CMD_SUCCESS;
d511d7f1
DS
1021}
1022
8f527c5e
FL
1023DEFUN (ip_nht_default_route,
1024 ip_nht_default_route_cmd,
1025 "ip nht resolve-via-default",
1026 IP_STR
1027 "Filter Next Hop tracking route resolution\n"
1028 "Resolve via default route\n")
1029{
d62a17ae 1030 if (zebra_rnh_ip_default_route)
1031 return CMD_SUCCESS;
8f527c5e 1032
6d53d7b1 1033 struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
1034
1035 if (!zvrf)
1036 return CMD_WARNING;
1037
d62a17ae 1038 zebra_rnh_ip_default_route = 1;
6d53d7b1 1039 zebra_evaluate_rnh(zvrf, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
d62a17ae 1040 return CMD_SUCCESS;
8f527c5e
FL
1041}
1042
1043DEFUN (no_ip_nht_default_route,
1044 no_ip_nht_default_route_cmd,
1045 "no ip nht resolve-via-default",
1046 NO_STR
1047 IP_STR
1048 "Filter Next Hop tracking route resolution\n"
1049 "Resolve via default route\n")
1050{
d62a17ae 1051 if (!zebra_rnh_ip_default_route)
1052 return CMD_SUCCESS;
8f527c5e 1053
6d53d7b1 1054 struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
1055
1056 if (!zvrf)
1057 return CMD_WARNING;
1058
d62a17ae 1059 zebra_rnh_ip_default_route = 0;
6d53d7b1 1060 zebra_evaluate_rnh(zvrf, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
d62a17ae 1061 return CMD_SUCCESS;
8f527c5e
FL
1062}
1063
1064DEFUN (ipv6_nht_default_route,
1065 ipv6_nht_default_route_cmd,
1066 "ipv6 nht resolve-via-default",
1067 IP6_STR
1068 "Filter Next Hop tracking route resolution\n"
1069 "Resolve via default route\n")
1070{
d62a17ae 1071 if (zebra_rnh_ipv6_default_route)
1072 return CMD_SUCCESS;
8f527c5e 1073
6d53d7b1 1074 struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
1075
1076 if (!zvrf)
1077 return CMD_WARNING;
1078
d62a17ae 1079 zebra_rnh_ipv6_default_route = 1;
6d53d7b1 1080 zebra_evaluate_rnh(zvrf, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL);
d62a17ae 1081 return CMD_SUCCESS;
8f527c5e
FL
1082}
1083
1084DEFUN (no_ipv6_nht_default_route,
1085 no_ipv6_nht_default_route_cmd,
1086 "no ipv6 nht resolve-via-default",
1087 NO_STR
1088 IP6_STR
1089 "Filter Next Hop tracking route resolution\n"
1090 "Resolve via default route\n")
1091{
d62a17ae 1092 if (!zebra_rnh_ipv6_default_route)
1093 return CMD_SUCCESS;
8f527c5e 1094
6d53d7b1 1095 struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
1096
1097 if (!zvrf)
1098 return CMD_WARNING;
1099
d62a17ae 1100 zebra_rnh_ipv6_default_route = 0;
6d53d7b1 1101 zebra_evaluate_rnh(zvrf, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL);
d62a17ae 1102 return CMD_SUCCESS;
8f527c5e
FL
1103}
1104
ecffa493
RW
1105DEFPY (show_route,
1106 show_route_cmd,
1107 "show\
1108 <\
1109 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
a3e13ef3 1110 [{\
ecffa493
RW
1111 tag (1-4294967295)\
1112 |A.B.C.D/M$prefix longer-prefixes\
1113 |supernets-only$supernets_only\
a3e13ef3
RW
1114 }]\
1115 [<\
1116 " FRR_IP_REDIST_STR_ZEBRA "$type_str\
ecffa493 1117 |ospf$type_str (1-65535)$ospf_instance_id\
a3e13ef3 1118 >]\
ecffa493 1119 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
a3e13ef3 1120 [{\
ecffa493
RW
1121 tag (1-4294967295)\
1122 |X:X::X:X/M$prefix longer-prefixes\
a3e13ef3
RW
1123 }]\
1124 [" FRR_IP6_REDIST_STR_ZEBRA "$type_str]\
ecffa493
RW
1125 >\
1126 [json$json]",
8f527c5e
FL
1127 SHOW_STR
1128 IP_STR
87a88962 1129 "IP forwarding table\n"
8f527c5e 1130 "IP routing table\n"
ecffa493 1131 VRF_FULL_CMD_HELP_STR
8f527c5e 1132 "Show only routes with tag\n"
acb25e73
DW
1133 "Tag value\n"
1134 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1135 "Show route matching the specified Network/Mask pair only\n"
1136 "Show supernet entries only\n"
1137 FRR_IP_REDIST_HELP_STR_ZEBRA
1138 "Open Shortest Path First (OSPFv2)\n"
1139 "Instance ID\n"
ecffa493
RW
1140 IPV6_STR
1141 "IP forwarding table\n"
1142 "IP routing table\n"
1143 VRF_FULL_CMD_HELP_STR
1144 "Show only routes with tag\n"
1145 "Tag value\n"
1146 "IPv6 prefix\n"
1147 "Show route matching the specified Network/Mask pair only\n"
1148 FRR_IP6_REDIST_HELP_STR_ZEBRA
acb25e73 1149 JSON_STR)
8f527c5e 1150{
ecffa493 1151 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
d62a17ae 1152 struct vrf *vrf;
d62a17ae 1153 int type = 0;
d62a17ae 1154
ecffa493
RW
1155 if (type_str) {
1156 type = proto_redistnum(afi, type_str);
d62a17ae 1157 if (type < 0) {
1158 vty_out(vty, "Unknown route type\n");
1159 return CMD_WARNING;
1160 }
1161 }
1162
1163 if (vrf_all) {
a2addae8 1164 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
ecffa493
RW
1165 struct zebra_vrf *zvrf;
1166 struct route_table *table;
1167
d62a17ae 1168 if ((zvrf = vrf->info) == NULL
ecffa493 1169 || (table = zvrf->table[afi][SAFI_UNICAST]) == NULL)
d62a17ae 1170 continue;
1171
1172 do_show_ip_route(
ecffa493
RW
1173 vty, zvrf_name(zvrf), afi, SAFI_UNICAST, !!fib,
1174 !!json, tag, prefix_str ? prefix : NULL,
1175 !!supernets_only, type, ospf_instance_id);
d62a17ae 1176 }
1177 } else {
ecffa493
RW
1178 vrf_id_t vrf_id = VRF_DEFAULT;
1179
1180 if (vrf_name)
ec1db588 1181 VRF_GET_ID(vrf_id, vrf_name, !!json);
d62a17ae 1182 vrf = vrf_lookup_by_id(vrf_id);
ecffa493
RW
1183 do_show_ip_route(vty, vrf->name, afi, SAFI_UNICAST, !!fib,
1184 !!json, tag, prefix_str ? prefix : NULL,
1185 !!supernets_only, type, ospf_instance_id);
d62a17ae 1186 }
ecffa493 1187
d62a17ae 1188 return CMD_SUCCESS;
8f527c5e
FL
1189}
1190
5ce91022
RW
1191DEFPY (show_route_detail,
1192 show_route_detail_cmd,
1193 "show\
1194 <\
1195 ip$ipv4 route [vrf <NAME$vrf_name|all$vrf_all>]\
1196 <\
1197 A.B.C.D$address\
1198 |A.B.C.D/M$prefix\
1199 >\
1200 |ipv6$ipv6 route [vrf <NAME$vrf_name|all$vrf_all>]\
1201 <\
1202 X:X::X:X$address\
1203 |X:X::X:X/M$prefix\
1204 >\
96d71e38
AD
1205 >\
1206 [json$json]",
8f527c5e
FL
1207 SHOW_STR
1208 IP_STR
1209 "IP routing table\n"
5ce91022
RW
1210 VRF_FULL_CMD_HELP_STR
1211 "Network in the IP routing table to display\n"
1212 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1213 IP6_STR
1214 "IP routing table\n"
1215 VRF_FULL_CMD_HELP_STR
1216 "IPv6 Address\n"
96d71e38
AD
1217 "IPv6 prefix\n"
1218 JSON_STR)
8f527c5e 1219{
5ce91022 1220 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
d62a17ae 1221 struct route_table *table;
5ce91022 1222 struct prefix p;
d62a17ae 1223 struct route_node *rn;
d511d7f1 1224
5ce91022
RW
1225 if (address_str)
1226 prefix_str = address_str;
1227 if (str2prefix(prefix_str, &p) < 0) {
1228 vty_out(vty, "%% Malformed address\n");
d62a17ae 1229 return CMD_WARNING;
1230 }
8f527c5e 1231
5ce91022
RW
1232 if (vrf_all) {
1233 struct vrf *vrf;
1234 struct zebra_vrf *zvrf;
8f527c5e 1235
996c9314 1236 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
5ce91022
RW
1237 if ((zvrf = vrf->info) == NULL
1238 || (table = zvrf->table[afi][SAFI_UNICAST]) == NULL)
1239 continue;
1240
1241 rn = route_node_match(table, &p);
1242 if (!rn)
1243 continue;
1244 if (!address_str && rn->p.prefixlen != p.prefixlen) {
1245 route_unlock_node(rn);
1246 continue;
1247 }
1248
96d71e38
AD
1249 if (json)
1250 vty_show_ip_route_detail_json(vty, rn);
1251 else
1252 vty_show_ip_route_detail(vty, rn, 0);
5ce91022
RW
1253
1254 route_unlock_node(rn);
1255 }
1256 } else {
1257 vrf_id_t vrf_id = VRF_DEFAULT;
1258
1259 if (vrf_name)
ec1db588 1260 VRF_GET_ID(vrf_id, vrf_name, false);
5ce91022
RW
1261
1262 table = zebra_vrf_table(afi, SAFI_UNICAST, vrf_id);
1263 if (!table)
1264 return CMD_SUCCESS;
8f527c5e 1265
5ce91022
RW
1266 rn = route_node_match(table, &p);
1267 if (!rn) {
1268 vty_out(vty, "%% Network not in table\n");
1269 return CMD_WARNING;
1270 }
1271 if (!address_str && rn->p.prefixlen != p.prefixlen) {
1272 vty_out(vty, "%% Network not in table\n");
1273 route_unlock_node(rn);
1274 return CMD_WARNING;
1275 }
8f527c5e 1276
96d71e38
AD
1277 if (json)
1278 vty_show_ip_route_detail_json(vty, rn);
1279 else
1280 vty_show_ip_route_detail(vty, rn, 0);
5ce91022
RW
1281
1282 route_unlock_node(rn);
1283 }
8f527c5e 1284
d62a17ae 1285 return CMD_SUCCESS;
8f527c5e
FL
1286}
1287
5ce91022
RW
1288DEFPY (show_route_summary,
1289 show_route_summary_cmd,
1290 "show\
1291 <\
1292 ip$ipv4 route [vrf <NAME$vrf_name|all$vrf_all>]\
1293 summary [prefix$prefix]\
1294 |ipv6$ipv6 route [vrf <NAME$vrf_name|all$vrf_all>]\
1295 summary [prefix$prefix]\
1296 >",
8f527c5e
FL
1297 SHOW_STR
1298 IP_STR
1299 "IP routing table\n"
5ce91022
RW
1300 VRF_FULL_CMD_HELP_STR
1301 "Summary of all routes\n"
1302 "Prefix routes\n"
1303 IP6_STR
1304 "IP routing table\n"
1305 VRF_FULL_CMD_HELP_STR
1306 "Summary of all routes\n"
1307 "Prefix routes\n")
8f527c5e 1308{
5ce91022 1309 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
d62a17ae 1310 struct route_table *table;
d62a17ae 1311
5ce91022
RW
1312 if (vrf_all) {
1313 struct vrf *vrf;
1314 struct zebra_vrf *zvrf;
d511d7f1 1315
996c9314 1316 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
5ce91022
RW
1317 if ((zvrf = vrf->info) == NULL
1318 || (table = zvrf->table[afi][SAFI_UNICAST]) == NULL)
1319 continue;
8f527c5e 1320
5ce91022
RW
1321 if (prefix)
1322 vty_show_ip_route_summary_prefix(vty, table);
1323 else
1324 vty_show_ip_route_summary(vty, table);
1325 }
1326 } else {
1327 vrf_id_t vrf_id = VRF_DEFAULT;
8f527c5e 1328
5ce91022 1329 if (vrf_name)
ec1db588 1330 VRF_GET_ID(vrf_id, vrf_name, false);
8f527c5e 1331
5ce91022
RW
1332 table = zebra_vrf_table(afi, SAFI_UNICAST, vrf_id);
1333 if (!table)
1334 return CMD_SUCCESS;
8f527c5e 1335
5ce91022
RW
1336 if (prefix)
1337 vty_show_ip_route_summary_prefix(vty, table);
1338 else
1339 vty_show_ip_route_summary(vty, table);
1340 }
8f527c5e 1341
d62a17ae 1342 return CMD_SUCCESS;
8f527c5e
FL
1343}
1344
d62a17ae 1345static void vty_show_ip_route_summary(struct vty *vty,
1346 struct route_table *table)
8f527c5e 1347{
d62a17ae 1348 struct route_node *rn;
1349 struct route_entry *re;
8f527c5e
FL
1350#define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1351#define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
d7c0a89a
QY
1352 uint32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1353 uint32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1354 uint32_t i;
1355 uint32_t is_ibgp;
d62a17ae 1356
1357 memset(&rib_cnt, 0, sizeof(rib_cnt));
1358 memset(&fib_cnt, 0, sizeof(fib_cnt));
1359 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
a2addae8 1360 RNODE_FOREACH_RE (rn, re) {
d62a17ae 1361 is_ibgp = (re->type == ZEBRA_ROUTE_BGP
1362 && CHECK_FLAG(re->flags, ZEBRA_FLAG_IBGP));
1363
1364 rib_cnt[ZEBRA_ROUTE_TOTAL]++;
1365 if (is_ibgp)
1366 rib_cnt[ZEBRA_ROUTE_IBGP]++;
1367 else
1368 rib_cnt[re->type]++;
1369
1370 if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED)) {
1371 fib_cnt[ZEBRA_ROUTE_TOTAL]++;
1372
1373 if (is_ibgp)
1374 fib_cnt[ZEBRA_ROUTE_IBGP]++;
1375 else
1376 fib_cnt[re->type]++;
1377 }
1378 }
1379
1380 vty_out(vty, "%-20s %-20s %s (vrf %s)\n", "Route Source", "Routes",
6ca30e9e 1381 "FIB", zvrf_name(((rib_table_info_t *)route_table_get_info(table))->zvrf));
d62a17ae 1382
1383 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
9d303b37
DL
1384 if ((rib_cnt[i] > 0) || (i == ZEBRA_ROUTE_BGP
1385 && rib_cnt[ZEBRA_ROUTE_IBGP] > 0)) {
d62a17ae 1386 if (i == ZEBRA_ROUTE_BGP) {
1387 vty_out(vty, "%-20s %-20d %-20d \n", "ebgp",
1388 rib_cnt[ZEBRA_ROUTE_BGP],
1389 fib_cnt[ZEBRA_ROUTE_BGP]);
1390 vty_out(vty, "%-20s %-20d %-20d \n", "ibgp",
1391 rib_cnt[ZEBRA_ROUTE_IBGP],
1392 fib_cnt[ZEBRA_ROUTE_IBGP]);
1393 } else
1394 vty_out(vty, "%-20s %-20d %-20d \n",
1395 zebra_route_string(i), rib_cnt[i],
1396 fib_cnt[i]);
1397 }
1398 }
1399
1400 vty_out(vty, "------\n");
1401 vty_out(vty, "%-20s %-20d %-20d \n", "Totals",
1402 rib_cnt[ZEBRA_ROUTE_TOTAL], fib_cnt[ZEBRA_ROUTE_TOTAL]);
1403 vty_out(vty, "\n");
8f527c5e
FL
1404}
1405
1406/*
1407 * Implementation of the ip route summary prefix command.
1408 *
1409 * This command prints the primary prefixes that have been installed by various
1410 * protocols on the box.
1411 *
1412 */
d62a17ae 1413static void vty_show_ip_route_summary_prefix(struct vty *vty,
1414 struct route_table *table)
8f527c5e 1415{
d62a17ae 1416 struct route_node *rn;
1417 struct route_entry *re;
1418 struct nexthop *nexthop;
8f527c5e
FL
1419#define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1420#define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
d7c0a89a
QY
1421 uint32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1422 uint32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1423 uint32_t i;
d62a17ae 1424 int cnt;
1425
1426 memset(&rib_cnt, 0, sizeof(rib_cnt));
1427 memset(&fib_cnt, 0, sizeof(fib_cnt));
1428 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
a2addae8 1429 RNODE_FOREACH_RE (rn, re) {
d62a17ae 1430
1431 /*
1432 * In case of ECMP, count only once.
1433 */
1434 cnt = 0;
7ee30f28 1435 for (nexthop = re->ng.nexthop; (!cnt && nexthop);
d62a17ae 1436 nexthop = nexthop->next) {
1437 cnt++;
1438 rib_cnt[ZEBRA_ROUTE_TOTAL]++;
1439 rib_cnt[re->type]++;
1440 if (CHECK_FLAG(nexthop->flags,
1441 NEXTHOP_FLAG_FIB)) {
1442 fib_cnt[ZEBRA_ROUTE_TOTAL]++;
1443 fib_cnt[re->type]++;
1444 }
1445 if (re->type == ZEBRA_ROUTE_BGP
1446 && CHECK_FLAG(re->flags, ZEBRA_FLAG_IBGP)) {
1447 rib_cnt[ZEBRA_ROUTE_IBGP]++;
1448 if (CHECK_FLAG(nexthop->flags,
1449 NEXTHOP_FLAG_FIB))
1450 fib_cnt[ZEBRA_ROUTE_IBGP]++;
1451 }
1452 }
1453 }
1454
1455 vty_out(vty, "%-20s %-20s %s (vrf %s)\n", "Route Source",
1456 "Prefix Routes", "FIB",
6ca30e9e 1457 zvrf_name(((rib_table_info_t *)route_table_get_info(table))->zvrf));
d62a17ae 1458
1459 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
1460 if (rib_cnt[i] > 0) {
1461 if (i == ZEBRA_ROUTE_BGP) {
1462 vty_out(vty, "%-20s %-20d %-20d \n", "ebgp",
1463 rib_cnt[ZEBRA_ROUTE_BGP]
1464 - rib_cnt[ZEBRA_ROUTE_IBGP],
1465 fib_cnt[ZEBRA_ROUTE_BGP]
1466 - fib_cnt[ZEBRA_ROUTE_IBGP]);
1467 vty_out(vty, "%-20s %-20d %-20d \n", "ibgp",
1468 rib_cnt[ZEBRA_ROUTE_IBGP],
1469 fib_cnt[ZEBRA_ROUTE_IBGP]);
1470 } else
1471 vty_out(vty, "%-20s %-20d %-20d \n",
1472 zebra_route_string(i), rib_cnt[i],
1473 fib_cnt[i]);
1474 }
1475 }
1476
1477 vty_out(vty, "------\n");
1478 vty_out(vty, "%-20s %-20d %-20d \n", "Totals",
1479 rib_cnt[ZEBRA_ROUTE_TOTAL], fib_cnt[ZEBRA_ROUTE_TOTAL]);
1480 vty_out(vty, "\n");
9343ce83
DS
1481}
1482
cddf391b
B
1483/*
1484 * Show IPv6 mroute command.Used to dump
1485 * the Multicast routing table.
1486 */
cddf391b
B
1487DEFUN (show_ipv6_mroute,
1488 show_ipv6_mroute_cmd,
9bf96c84 1489 "show ipv6 mroute [vrf NAME]",
cddf391b
B
1490 SHOW_STR
1491 IP_STR
9bf96c84
DW
1492 "IPv6 Multicast routing table\n"
1493 VRF_CMD_HELP_STR)
cddf391b 1494{
d62a17ae 1495 struct route_table *table;
1496 struct route_node *rn;
1497 struct route_entry *re;
1498 int first = 1;
1499 vrf_id_t vrf_id = VRF_DEFAULT;
1500
1501 if (argc == 5)
ec1db588 1502 VRF_GET_ID(vrf_id, argv[4]->arg, false);
d62a17ae 1503
1504 table = zebra_vrf_table(AFI_IP6, SAFI_MULTICAST, vrf_id);
1505 if (!table)
1506 return CMD_SUCCESS;
1507
1508 /* Show all IPv6 route. */
1509 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
a2addae8 1510 RNODE_FOREACH_RE (rn, re) {
d62a17ae 1511 if (first) {
1512 vty_out(vty, SHOW_ROUTE_V6_HEADER);
1513 first = 0;
1514 }
1515 vty_show_ip_route(vty, rn, re, NULL);
1516 }
1517 return CMD_SUCCESS;
cddf391b
B
1518}
1519
af41b63a
FL
1520DEFUN (show_ipv6_mroute_vrf_all,
1521 show_ipv6_mroute_vrf_all_cmd,
5bebf568 1522 "show ipv6 mroute vrf all",
af41b63a
FL
1523 SHOW_STR
1524 IP_STR
1525 "IPv6 Multicast routing table\n"
1526 VRF_ALL_CMD_HELP_STR)
1527{
d62a17ae 1528 struct route_table *table;
1529 struct route_node *rn;
1530 struct route_entry *re;
1531 struct vrf *vrf;
1532 struct zebra_vrf *zvrf;
1533 int first = 1;
1534
a2addae8 1535 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
d62a17ae 1536 if ((zvrf = vrf->info) == NULL
1537 || (table = zvrf->table[AFI_IP6][SAFI_MULTICAST]) == NULL)
1538 continue;
1539
1540 /* Show all IPv6 route. */
1541 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
a2addae8 1542 RNODE_FOREACH_RE (rn, re) {
d62a17ae 1543 if (first) {
1544 vty_out(vty, SHOW_ROUTE_V6_HEADER);
1545 first = 0;
1546 }
1547 vty_show_ip_route(vty, rn, re, NULL);
1548 }
1549 }
1550 return CMD_SUCCESS;
af41b63a
FL
1551}
1552
6baf7bb8
DS
1553DEFUN (allow_external_route_update,
1554 allow_external_route_update_cmd,
1555 "allow-external-route-update",
17d990c1 1556 "Allow FRR routes to be overwritten by external processes\n")
6baf7bb8 1557{
d62a17ae 1558 allow_delete = 1;
6baf7bb8 1559
d62a17ae 1560 return CMD_SUCCESS;
6baf7bb8
DS
1561}
1562
1563DEFUN (no_allow_external_route_update,
1564 no_allow_external_route_update_cmd,
1565 "no allow-external-route-update",
17d990c1
DS
1566 NO_STR
1567 "Allow FRR routes to be overwritten by external processes\n")
6baf7bb8 1568{
d62a17ae 1569 allow_delete = 0;
6baf7bb8 1570
d62a17ae 1571 return CMD_SUCCESS;
6baf7bb8
DS
1572}
1573
12f6fb97
DS
1574/* show vrf */
1575DEFUN (show_vrf,
1576 show_vrf_cmd,
1577 "show vrf",
1578 SHOW_STR
1579 "VRF\n")
1580{
d62a17ae 1581 struct vrf *vrf;
1582 struct zebra_vrf *zvrf;
12f6fb97 1583
b73823ef
PG
1584 if (vrf_is_backend_netns())
1585 vty_out(vty, "netns-based vrfs\n");
1586
a2addae8 1587 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
d62a17ae 1588 if (!(zvrf = vrf->info))
1589 continue;
90ac32c2 1590 if (zvrf_id(zvrf) == VRF_DEFAULT)
d62a17ae 1591 continue;
1592
1593 vty_out(vty, "vrf %s ", zvrf_name(zvrf));
996c9314 1594 if (zvrf_id(zvrf) == VRF_UNKNOWN || !zvrf_is_active(zvrf))
d62a17ae 1595 vty_out(vty, "inactive");
81c9005f 1596 else if (zvrf_ns_name(zvrf))
996c9314
LB
1597 vty_out(vty, "id %u netns %s", zvrf_id(zvrf),
1598 zvrf_ns_name(zvrf));
d62a17ae 1599 else
1600 vty_out(vty, "id %u table %u", zvrf_id(zvrf),
1601 zvrf->table_id);
22bd3e94 1602 if (vrf_is_user_cfged(vrf))
1603 vty_out(vty, " (configured)");
d62a17ae 1604 vty_out(vty, "\n");
1605 }
12f6fb97 1606
d62a17ae 1607 return CMD_SUCCESS;
12f6fb97
DS
1608}
1609
62710e2b 1610DEFUN_HIDDEN (default_vrf_vni_mapping,
e8d26197 1611 default_vrf_vni_mapping_cmd,
c48d9f5f 1612 "vni " CMD_VNI_RANGE "[prefix-routes-only]",
e8d26197 1613 "VNI corresponding to the DEFAULT VRF\n"
c48d9f5f
MK
1614 "VNI-ID\n"
1615 "Prefix routes only \n")
e8d26197
MK
1616{
1617 int ret = 0;
1618 char err[ERR_STR_SZ];
1619 struct zebra_vrf *zvrf = NULL;
1620 vni_t vni = strtoul(argv[1]->arg, NULL, 10);
c48d9f5f 1621 int filter = 0;
e8d26197
MK
1622
1623 zvrf = vrf_info_lookup(VRF_DEFAULT);
1624 if (!zvrf)
1625 return CMD_WARNING;
1626
c48d9f5f
MK
1627 if (argc == 3)
1628 filter = 1;
1629
1630 ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ,
1631 filter, 1);
e8d26197
MK
1632 if (ret != 0) {
1633 vty_out(vty, "%s\n", err);
1634 return CMD_WARNING;
1635 }
1636
1637 return CMD_SUCCESS;
1638}
1639
62710e2b 1640DEFUN_HIDDEN (no_default_vrf_vni_mapping,
e8d26197
MK
1641 no_default_vrf_vni_mapping_cmd,
1642 "no vni " CMD_VNI_RANGE,
1643 NO_STR
1644 "VNI corresponding to DEFAULT VRF\n"
1645 "VNI-ID")
1646{
1647 int ret = 0;
1648 char err[ERR_STR_SZ];
1649 vni_t vni = strtoul(argv[2]->arg, NULL, 10);
1650 struct zebra_vrf *zvrf = NULL;
1651
1652 zvrf = vrf_info_lookup(VRF_DEFAULT);
1653 if (!zvrf)
1654 return CMD_WARNING;
1655
c48d9f5f 1656 ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ, 0, 0);
e8d26197
MK
1657 if (ret != 0) {
1658 vty_out(vty, "%s\n", err);
1659 return CMD_WARNING;
1660 }
1661
1662 return CMD_SUCCESS;
1663}
1664
b7cfce93
MK
1665DEFUN (vrf_vni_mapping,
1666 vrf_vni_mapping_cmd,
c48d9f5f 1667 "vni " CMD_VNI_RANGE "[prefix-routes-only]",
e8d26197 1668 "VNI corresponding to tenant VRF\n"
c48d9f5f
MK
1669 "VNI-ID\n"
1670 "prefix-routes-only\n")
b7cfce93
MK
1671{
1672 int ret = 0;
c48d9f5f 1673 int filter = 0;
b7cfce93
MK
1674
1675 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
1676 vni_t vni = strtoul(argv[1]->arg, NULL, 10);
1677 char err[ERR_STR_SZ];
1678
1679 assert(vrf);
1680 assert(zvrf);
1681
c48d9f5f
MK
1682 if (argc == 3)
1683 filter = 1;
1684
317f1fe0 1685 /* Mark as having FRR configuration */
1686 vrf_set_user_cfged(vrf);
c48d9f5f
MK
1687 ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ,
1688 filter, 1);
b7cfce93
MK
1689 if (ret != 0) {
1690 vty_out(vty, "%s\n", err);
1691 return CMD_WARNING;
1692 }
1693
1694 return CMD_SUCCESS;
1695}
1696
1697DEFUN (no_vrf_vni_mapping,
1698 no_vrf_vni_mapping_cmd,
cf299714 1699 "no vni " CMD_VNI_RANGE "[prefix-routes-only]",
b7cfce93 1700 NO_STR
e8d26197 1701 "VNI corresponding to tenant VRF\n"
cf299714
MK
1702 "VNI-ID\n"
1703 "prefix-routes-only\n")
b7cfce93
MK
1704{
1705 int ret = 0;
cf299714 1706 int filter = 0;
b7cfce93
MK
1707 char err[ERR_STR_SZ];
1708 vni_t vni = strtoul(argv[2]->arg, NULL, 10);
1709
1710 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
1711
1712 assert(vrf);
1713 assert(zvrf);
1714
cf299714
MK
1715 if (argc == 4)
1716 filter = 1;
1717
1718 ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err,
1719 ERR_STR_SZ, filter, 0);
b7cfce93
MK
1720 if (ret != 0) {
1721 vty_out(vty, "%s\n", err);
1722 return CMD_WARNING;
1723 }
1724
22bd3e94 1725 /* If no other FRR config for this VRF, mark accordingly. */
1726 if (!zebra_vrf_has_config(zvrf))
1727 vrf_reset_user_cfged(vrf);
1728
b7cfce93
MK
1729 return CMD_SUCCESS;
1730}
1731
1732/* show vrf */
1733DEFUN (show_vrf_vni,
1734 show_vrf_vni_cmd,
35be5542 1735 "show vrf vni [json]",
b7cfce93
MK
1736 SHOW_STR
1737 "VRF\n"
35be5542
MK
1738 "VNI\n"
1739 JSON_STR)
b7cfce93
MK
1740{
1741 struct vrf *vrf;
1742 struct zebra_vrf *zvrf;
35be5542
MK
1743 json_object *json = NULL;
1744 json_object *json_vrfs = NULL;
9f049418 1745 bool uj = use_json(argc, argv);
35be5542
MK
1746
1747 if (uj) {
1748 json = json_object_new_object();
1749 json_vrfs = json_object_new_array();
1750 }
b7cfce93 1751
4cce389e 1752 if (!uj)
996c9314
LB
1753 vty_out(vty, "%-37s %-10s %-20s %-20s %-5s %-18s\n", "VRF",
1754 "VNI", "VxLAN IF", "L3-SVI", "State", "Rmac");
4cce389e 1755
996c9314 1756 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
b7cfce93
MK
1757 zvrf = vrf->info;
1758 if (!zvrf)
1759 continue;
1760
4cce389e 1761 zebra_vxlan_print_vrf_vni(vty, zvrf, json_vrfs);
35be5542
MK
1762 }
1763
1764 if (uj) {
1765 json_object_object_add(json, "vrfs", json_vrfs);
1766 vty_out(vty, "%s\n", json_object_to_json_string_ext(
1767 json, JSON_C_TO_STRING_PRETTY));
1768 json_object_free(json);
b7cfce93
MK
1769 }
1770
1771 return CMD_SUCCESS;
1772}
1773
4cce389e
MK
1774DEFUN (show_evpn_global,
1775 show_evpn_global_cmd,
1776 "show evpn [json]",
1777 SHOW_STR
1778 "EVPN\n"
1779 JSON_STR)
1780{
9f049418 1781 bool uj = use_json(argc, argv);
4cce389e
MK
1782
1783 zebra_vxlan_print_evpn(vty, uj);
1784 return CMD_SUCCESS;
1785}
1786
cec2e17d 1787DEFUN (show_evpn_vni,
1788 show_evpn_vni_cmd,
cd233079 1789 "show evpn vni [json]",
cec2e17d 1790 SHOW_STR
1791 "EVPN\n"
cd233079 1792 "VxLAN information\n"
bd592158 1793 JSON_STR)
cec2e17d 1794{
d62a17ae 1795 struct zebra_vrf *zvrf;
9f049418 1796 bool uj = use_json(argc, argv);
cec2e17d 1797
d62a17ae 1798 zvrf = vrf_info_lookup(VRF_DEFAULT);
cd233079 1799 zebra_vxlan_print_vnis(vty, zvrf, uj);
d62a17ae 1800 return CMD_SUCCESS;
cec2e17d 1801}
1802
1803DEFUN (show_evpn_vni_vni,
1804 show_evpn_vni_vni_cmd,
cd233079 1805 "show evpn vni " CMD_VNI_RANGE "[json]",
cec2e17d 1806 SHOW_STR
1807 "EVPN\n"
1808 "VxLAN Network Identifier\n"
cd233079 1809 "VNI number\n"
bd592158 1810 JSON_STR)
cec2e17d 1811{
d62a17ae 1812 struct zebra_vrf *zvrf;
1813 vni_t vni;
9f049418 1814 bool uj = use_json(argc, argv);
cec2e17d 1815
d62a17ae 1816 vni = strtoul(argv[3]->arg, NULL, 10);
1817 zvrf = vrf_info_lookup(VRF_DEFAULT);
cd233079 1818 zebra_vxlan_print_vni(vty, zvrf, vni, uj);
d62a17ae 1819 return CMD_SUCCESS;
cec2e17d 1820}
1821
4cce389e
MK
1822DEFUN (show_evpn_rmac_vni_mac,
1823 show_evpn_rmac_vni_mac_cmd,
1824 "show evpn rmac vni " CMD_VNI_RANGE " mac WORD [json]",
9aa741ea
MK
1825 SHOW_STR
1826 "EVPN\n"
1827 "RMAC\n"
4cce389e 1828 "L3 VNI\n"
9aa741ea
MK
1829 "VNI number\n"
1830 "MAC\n"
316f4ca4
MK
1831 "mac-address (e.g. 0a:0a:0a:0a:0a:0a)\n"
1832 JSON_STR)
9aa741ea
MK
1833{
1834 vni_t l3vni = 0;
1835 struct ethaddr mac;
9f049418 1836 bool uj = use_json(argc, argv);
9aa741ea
MK
1837
1838 l3vni = strtoul(argv[4]->arg, NULL, 10);
1839 if (!prefix_str2mac(argv[6]->arg, &mac)) {
1840 vty_out(vty, "%% Malformed MAC address\n");
1841 return CMD_WARNING;
1842 }
316f4ca4 1843 zebra_vxlan_print_specific_rmac_l3vni(vty, l3vni, &mac, uj);
9aa741ea
MK
1844 return CMD_SUCCESS;
1845}
1846
4cce389e
MK
1847DEFUN (show_evpn_rmac_vni,
1848 show_evpn_rmac_vni_cmd,
1849 "show evpn rmac vni " CMD_VNI_RANGE "[json]",
b7cfce93
MK
1850 SHOW_STR
1851 "EVPN\n"
1852 "RMAC\n"
4cce389e 1853 "L3 VNI\n"
b7cfce93
MK
1854 "VNI number\n"
1855 JSON_STR)
1856{
1857 vni_t l3vni = 0;
9f049418 1858 bool uj = use_json(argc, argv);
b7cfce93
MK
1859
1860 l3vni = strtoul(argv[4]->arg, NULL, 10);
1861 zebra_vxlan_print_rmacs_l3vni(vty, l3vni, uj);
1862
1863 return CMD_SUCCESS;
1864}
1865
4cce389e
MK
1866DEFUN (show_evpn_rmac_vni_all,
1867 show_evpn_rmac_vni_all_cmd,
1868 "show evpn rmac vni all [json]",
b7cfce93
MK
1869 SHOW_STR
1870 "EVPN\n"
1871 "RMAC addresses\n"
4cce389e 1872 "L3 VNI\n"
b7cfce93
MK
1873 "All VNIs\n"
1874 JSON_STR)
1875{
9f049418 1876 bool uj = use_json(argc, argv);
b7cfce93
MK
1877
1878 zebra_vxlan_print_rmacs_all_l3vni(vty, uj);
1879
1880 return CMD_SUCCESS;
1881}
1882
4cce389e
MK
1883DEFUN (show_evpn_nh_vni_ip,
1884 show_evpn_nh_vni_ip_cmd,
1885 "show evpn next-hops vni " CMD_VNI_RANGE " ip WORD [json]",
9aa741ea
MK
1886 SHOW_STR
1887 "EVPN\n"
1888 "Remote Vteps\n"
4cce389e 1889 "L3 VNI\n"
9aa741ea
MK
1890 "VNI number\n"
1891 "Ip address\n"
c0e519d3
MK
1892 "Host address (ipv4 or ipv6)\n"
1893 JSON_STR)
9aa741ea
MK
1894{
1895 vni_t l3vni;
9aa741ea 1896 struct ipaddr ip;
9f049418 1897 bool uj = use_json(argc, argv);
9aa741ea
MK
1898
1899 l3vni = strtoul(argv[4]->arg, NULL, 10);
1900 if (str2ipaddr(argv[6]->arg, &ip) != 0) {
1901 if (!uj)
1902 vty_out(vty, "%% Malformed Neighbor address\n");
1903 return CMD_WARNING;
1904 }
c0e519d3 1905 zebra_vxlan_print_specific_nh_l3vni(vty, l3vni, &ip, uj);
9aa741ea
MK
1906
1907 return CMD_SUCCESS;
1908}
1909
4cce389e
MK
1910DEFUN (show_evpn_nh_vni,
1911 show_evpn_nh_vni_cmd,
1912 "show evpn next-hops vni " CMD_VNI_RANGE "[json]",
b7cfce93
MK
1913 SHOW_STR
1914 "EVPN\n"
1915 "Remote Vteps\n"
4cce389e 1916 "L3 VNI\n"
b7cfce93
MK
1917 "VNI number\n"
1918 JSON_STR)
1919{
1920 vni_t l3vni;
9f049418 1921 bool uj = use_json(argc, argv);
b7cfce93
MK
1922
1923 l3vni = strtoul(argv[4]->arg, NULL, 10);
1924 zebra_vxlan_print_nh_l3vni(vty, l3vni, uj);
1925
1926 return CMD_SUCCESS;
1927}
1928
4cce389e
MK
1929DEFUN (show_evpn_nh_vni_all,
1930 show_evpn_nh_vni_all_cmd,
1931 "show evpn next-hops vni all [json]",
b7cfce93
MK
1932 SHOW_STR
1933 "EVPN\n"
1934 "Remote VTEPs\n"
4cce389e 1935 "L3 VNI\n"
b7cfce93
MK
1936 "All VNIs\n"
1937 JSON_STR)
1938{
9f049418 1939 bool uj = use_json(argc, argv);
b7cfce93
MK
1940
1941 zebra_vxlan_print_nh_all_l3vni(vty, uj);
1942
1943 return CMD_SUCCESS;
1944}
1945
cec2e17d 1946DEFUN (show_evpn_mac_vni,
1947 show_evpn_mac_vni_cmd,
cd233079 1948 "show evpn mac vni " CMD_VNI_RANGE "[json]",
cec2e17d 1949 SHOW_STR
1950 "EVPN\n"
1951 "MAC addresses\n"
1952 "VxLAN Network Identifier\n"
cd233079 1953 "VNI number\n"
bd592158 1954 JSON_STR)
cec2e17d 1955{
d62a17ae 1956 struct zebra_vrf *zvrf;
1957 vni_t vni;
9f049418 1958 bool uj = use_json(argc, argv);
cec2e17d 1959
d62a17ae 1960 vni = strtoul(argv[4]->arg, NULL, 10);
1961 zvrf = vrf_info_lookup(VRF_DEFAULT);
cd233079 1962 zebra_vxlan_print_macs_vni(vty, zvrf, vni, uj);
d62a17ae 1963 return CMD_SUCCESS;
cec2e17d 1964}
1965
1966DEFUN (show_evpn_mac_vni_all,
1967 show_evpn_mac_vni_all_cmd,
cd233079 1968 "show evpn mac vni all [json]",
cec2e17d 1969 SHOW_STR
1970 "EVPN\n"
1971 "MAC addresses\n"
1972 "VxLAN Network Identifier\n"
cd233079 1973 "All VNIs\n"
bd592158 1974 JSON_STR)
cec2e17d 1975{
d62a17ae 1976 struct zebra_vrf *zvrf;
9f049418 1977 bool uj = use_json(argc, argv);
cec2e17d 1978
d62a17ae 1979 zvrf = vrf_info_lookup(VRF_DEFAULT);
cd233079 1980 zebra_vxlan_print_macs_all_vni(vty, zvrf, uj);
d62a17ae 1981 return CMD_SUCCESS;
cec2e17d 1982}
1983
1984DEFUN (show_evpn_mac_vni_all_vtep,
1985 show_evpn_mac_vni_all_vtep_cmd,
cd233079 1986 "show evpn mac vni all vtep A.B.C.D [json]",
cec2e17d 1987 SHOW_STR
1988 "EVPN\n"
1989 "MAC addresses\n"
1990 "VxLAN Network Identifier\n"
1991 "All VNIs\n"
1992 "Remote VTEP\n"
cd233079 1993 "Remote VTEP IP address\n"
bd592158 1994 JSON_STR)
cec2e17d 1995{
d62a17ae 1996 struct zebra_vrf *zvrf;
1997 struct in_addr vtep_ip;
9f049418 1998 bool uj = use_json(argc, argv);
cec2e17d 1999
d62a17ae 2000 if (!inet_aton(argv[6]->arg, &vtep_ip)) {
cd233079
CS
2001 if (!uj)
2002 vty_out(vty, "%% Malformed VTEP IP address\n");
d62a17ae 2003 return CMD_WARNING;
2004 }
2005 zvrf = vrf_info_lookup(VRF_DEFAULT);
cd233079 2006 zebra_vxlan_print_macs_all_vni_vtep(vty, zvrf, vtep_ip, uj);
cec2e17d 2007
d62a17ae 2008 return CMD_SUCCESS;
cec2e17d 2009}
2010
2011
2012DEFUN (show_evpn_mac_vni_mac,
2013 show_evpn_mac_vni_mac_cmd,
2014 "show evpn mac vni " CMD_VNI_RANGE " mac WORD",
2015 SHOW_STR
2016 "EVPN\n"
2017 "MAC addresses\n"
2018 "VxLAN Network Identifier\n"
2019 "VNI number\n"
2020 "MAC\n"
2021 "MAC address (e.g., 00:e0:ec:20:12:62)\n")
2022{
d62a17ae 2023 struct zebra_vrf *zvrf;
2024 vni_t vni;
2025 struct ethaddr mac;
cec2e17d 2026
d62a17ae 2027 vni = strtoul(argv[4]->arg, NULL, 10);
2028 if (!prefix_str2mac(argv[6]->arg, &mac)) {
2029 vty_out(vty, "%% Malformed MAC address");
2030 return CMD_WARNING;
2031 }
2032 zvrf = vrf_info_lookup(VRF_DEFAULT);
2033 zebra_vxlan_print_specific_mac_vni(vty, zvrf, vni, &mac);
2034 return CMD_SUCCESS;
cec2e17d 2035}
2036
2037DEFUN (show_evpn_mac_vni_vtep,
2038 show_evpn_mac_vni_vtep_cmd,
cd233079 2039 "show evpn mac vni " CMD_VNI_RANGE " vtep A.B.C.D" "[json]",
cec2e17d 2040 SHOW_STR
2041 "EVPN\n"
2042 "MAC addresses\n"
2043 "VxLAN Network Identifier\n"
2044 "VNI number\n"
2045 "Remote VTEP\n"
cd233079 2046 "Remote VTEP IP address\n"
bd592158 2047 JSON_STR)
cec2e17d 2048{
d62a17ae 2049 struct zebra_vrf *zvrf;
2050 vni_t vni;
2051 struct in_addr vtep_ip;
9f049418 2052 bool uj = use_json(argc, argv);
cec2e17d 2053
d62a17ae 2054 vni = strtoul(argv[4]->arg, NULL, 10);
2055 if (!inet_aton(argv[6]->arg, &vtep_ip)) {
cd233079
CS
2056 if (!uj)
2057 vty_out(vty, "%% Malformed VTEP IP address\n");
d62a17ae 2058 return CMD_WARNING;
2059 }
cec2e17d 2060
d62a17ae 2061 zvrf = vrf_info_lookup(VRF_DEFAULT);
cd233079 2062 zebra_vxlan_print_macs_vni_vtep(vty, zvrf, vni, vtep_ip, uj);
d62a17ae 2063 return CMD_SUCCESS;
cec2e17d 2064}
2065
2066DEFUN (show_evpn_neigh_vni,
2067 show_evpn_neigh_vni_cmd,
cd233079 2068 "show evpn arp-cache vni " CMD_VNI_RANGE "[json]",
cec2e17d 2069 SHOW_STR
2070 "EVPN\n"
2071 "ARP and ND cache\n"
2072 "VxLAN Network Identifier\n"
cd233079 2073 "VNI number\n"
bd592158 2074 JSON_STR)
cec2e17d 2075{
d62a17ae 2076 struct zebra_vrf *zvrf;
2077 vni_t vni;
9f049418 2078 bool uj = use_json(argc, argv);
cec2e17d 2079
d62a17ae 2080 vni = strtoul(argv[4]->arg, NULL, 10);
2081 zvrf = vrf_info_lookup(VRF_DEFAULT);
cd233079 2082 zebra_vxlan_print_neigh_vni(vty, zvrf, vni, uj);
d62a17ae 2083 return CMD_SUCCESS;
cec2e17d 2084}
2085
2086DEFUN (show_evpn_neigh_vni_all,
2087 show_evpn_neigh_vni_all_cmd,
cd233079 2088 "show evpn arp-cache vni all [json]",
cec2e17d 2089 SHOW_STR
2090 "EVPN\n"
2091 "ARP and ND cache\n"
2092 "VxLAN Network Identifier\n"
cd233079 2093 "All VNIs\n"
bd592158 2094 JSON_STR)
cec2e17d 2095{
d62a17ae 2096 struct zebra_vrf *zvrf;
9f049418 2097 bool uj = use_json(argc, argv);
cec2e17d 2098
d62a17ae 2099 zvrf = vrf_info_lookup(VRF_DEFAULT);
cd233079 2100 zebra_vxlan_print_neigh_all_vni(vty, zvrf, uj);
d62a17ae 2101 return CMD_SUCCESS;
cec2e17d 2102}
2103
2104DEFUN (show_evpn_neigh_vni_neigh,
2105 show_evpn_neigh_vni_neigh_cmd,
cd233079 2106 "show evpn arp-cache vni " CMD_VNI_RANGE " ip WORD [json]",
cec2e17d 2107 SHOW_STR
2108 "EVPN\n"
2109 "ARP and ND cache\n"
2110 "VxLAN Network Identifier\n"
2111 "VNI number\n"
2112 "Neighbor\n"
cd233079 2113 "Neighbor address (IPv4 or IPv6 address)\n"
bd592158 2114 JSON_STR)
cec2e17d 2115{
d62a17ae 2116 struct zebra_vrf *zvrf;
2117 vni_t vni;
2118 struct ipaddr ip;
9f049418 2119 bool uj = use_json(argc, argv);
cec2e17d 2120
d62a17ae 2121 vni = strtoul(argv[4]->arg, NULL, 10);
2122 if (str2ipaddr(argv[6]->arg, &ip) != 0) {
cd233079
CS
2123 if (!uj)
2124 vty_out(vty, "%% Malformed Neighbor address\n");
d62a17ae 2125 return CMD_WARNING;
2126 }
2127 zvrf = vrf_info_lookup(VRF_DEFAULT);
cd233079 2128 zebra_vxlan_print_specific_neigh_vni(vty, zvrf, vni, &ip, uj);
d62a17ae 2129 return CMD_SUCCESS;
cec2e17d 2130}
2131
2132DEFUN (show_evpn_neigh_vni_vtep,
2133 show_evpn_neigh_vni_vtep_cmd,
cd233079 2134 "show evpn arp-cache vni " CMD_VNI_RANGE " vtep A.B.C.D [json]",
cec2e17d 2135 SHOW_STR
2136 "EVPN\n"
2137 "ARP and ND cache\n"
2138 "VxLAN Network Identifier\n"
2139 "VNI number\n"
2140 "Remote VTEP\n"
cd233079 2141 "Remote VTEP IP address\n"
bd592158 2142 JSON_STR)
cec2e17d 2143{
d62a17ae 2144 struct zebra_vrf *zvrf;
2145 vni_t vni;
2146 struct in_addr vtep_ip;
9f049418 2147 bool uj = use_json(argc, argv);
cec2e17d 2148
d62a17ae 2149 vni = strtoul(argv[4]->arg, NULL, 10);
2150 if (!inet_aton(argv[6]->arg, &vtep_ip)) {
cd233079
CS
2151 if (!uj)
2152 vty_out(vty, "%% Malformed VTEP IP address\n");
d62a17ae 2153 return CMD_WARNING;
2154 }
cec2e17d 2155
d62a17ae 2156 zvrf = vrf_info_lookup(VRF_DEFAULT);
cd233079 2157 zebra_vxlan_print_neigh_vni_vtep(vty, zvrf, vni, vtep_ip, uj);
d62a17ae 2158 return CMD_SUCCESS;
cec2e17d 2159}
2160
586f4ccf
PG
2161/* policy routing contexts */
2162DEFUN (show_pbr_ipset,
2163 show_pbr_ipset_cmd,
2164 "show pbr ipset [WORD]",
2165 SHOW_STR
2166 "Policy-Based Routing\n"
2167 "IPset Context information\n"
2168 "IPset Name information\n")
2169{
2170 int idx = 0;
2171 int found = 0;
2172 found = argv_find(argv, argc, "WORD", &idx);
2173 if (!found)
2174 zebra_pbr_show_ipset_list(vty, NULL);
2175 else
2176 zebra_pbr_show_ipset_list(vty, argv[idx]->arg);
2177 return CMD_SUCCESS;
2178}
2179
2180/* policy routing contexts */
2181DEFUN (show_pbr_iptable,
2182 show_pbr_iptable_cmd,
7929821a 2183 "show pbr iptable [WORD]",
586f4ccf
PG
2184 SHOW_STR
2185 "Policy-Based Routing\n"
7929821a
PG
2186 "IPtable Context information\n"
2187 "IPtable Name information\n")
586f4ccf 2188{
7929821a
PG
2189 int idx = 0;
2190 int found = 0;
2191
2192 found = argv_find(argv, argc, "WORD", &idx);
2193 if (!found)
2194 zebra_pbr_show_iptable(vty, NULL);
2195 else
2196 zebra_pbr_show_iptable(vty, argv[idx]->arg);
586f4ccf
PG
2197 return CMD_SUCCESS;
2198}
2199
718e3744 2200/* Static ip route configuration write function. */
d62a17ae 2201static int zebra_ip_config(struct vty *vty)
718e3744 2202{
d62a17ae 2203 int write = 0;
718e3744 2204
d62a17ae 2205 write += zebra_import_table_config(vty);
37728041 2206
d62a17ae 2207 return write;
718e3744 2208}
2209
7a4bb9c5
DS
2210DEFUN (ip_zebra_import_table_distance,
2211 ip_zebra_import_table_distance_cmd,
12dcf78e 2212 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
8902474b
DS
2213 IP_STR
2214 "import routes from non-main kernel table\n"
2215 "kernel routing table id\n"
2216 "Distance for imported routes\n"
2217 "Default distance value\n"
2218 "route-map for filtering\n"
2219 "route-map name\n")
2220{
d7c0a89a 2221 uint32_t table_id = 0;
8902474b 2222
d62a17ae 2223 table_id = strtoul(argv[2]->arg, NULL, 10);
2224 int distance = ZEBRA_TABLE_DISTANCE_DEFAULT;
2225 char *rmap =
2226 strmatch(argv[argc - 2]->text, "route-map")
2227 ? XSTRDUP(MTYPE_ROUTE_MAP_NAME, argv[argc - 1]->arg)
2228 : NULL;
2229 int ret;
d722f26e 2230
d62a17ae 2231 if (argc == 7 || (argc == 5 && !rmap))
2232 distance = strtoul(argv[4]->arg, NULL, 10);
8902474b 2233
d62a17ae 2234 if (!is_zebra_valid_kernel_table(table_id)) {
2235 vty_out(vty,
2236 "Invalid routing table ID, %d. Must be in range 1-252\n",
2237 table_id);
0af35d90
RW
2238 if (rmap)
2239 XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
d62a17ae 2240 return CMD_WARNING;
2241 }
8902474b 2242
d62a17ae 2243 if (is_zebra_main_routing_table(table_id)) {
2244 vty_out(vty,
2245 "Invalid routing table ID, %d. Must be non-default table\n",
2246 table_id);
0af35d90
RW
2247 if (rmap)
2248 XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
d62a17ae 2249 return CMD_WARNING;
2250 }
8902474b 2251
d62a17ae 2252 ret = zebra_import_table(AFI_IP, table_id, distance, rmap, 1);
2253 if (rmap)
2254 XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
d722f26e 2255
d62a17ae 2256 return ret;
8902474b
DS
2257}
2258
62d52ded
DS
2259DEFUN_HIDDEN (zebra_packet_process,
2260 zebra_packet_process_cmd,
2261 "zebra zapi-packets (1-10000)",
2262 ZEBRA_STR
2263 "Zapi Protocol\n"
2264 "Number of packets to process before relinquishing thread\n")
2265{
2266 uint32_t packets = strtoul(argv[2]->arg, NULL, 10);
2267
ccd51bd2
QY
2268 atomic_store_explicit(&zebrad.packets_to_process, packets,
2269 memory_order_relaxed);
62d52ded
DS
2270
2271 return CMD_SUCCESS;
2272}
2273
2274DEFUN_HIDDEN (no_zebra_packet_process,
2275 no_zebra_packet_process_cmd,
2276 "no zebra zapi-packets [(1-10000)]",
2277 NO_STR
2278 ZEBRA_STR
2279 "Zapi Protocol\n"
2280 "Number of packets to process before relinquishing thread\n")
2281{
ccd51bd2
QY
2282 atomic_store_explicit(&zebrad.packets_to_process,
2283 ZEBRA_ZAPI_PACKETS_TO_PROCESS,
2284 memory_order_relaxed);
62d52ded
DS
2285
2286 return CMD_SUCCESS;
2287}
2288
3a30f50f
DS
2289DEFUN_HIDDEN (zebra_workqueue_timer,
2290 zebra_workqueue_timer_cmd,
2291 "zebra work-queue (0-10000)",
2292 ZEBRA_STR
2293 "Work Queue\n"
2294 "Time in milliseconds\n")
2295{
996c9314
LB
2296 uint32_t timer = strtoul(argv[2]->arg, NULL, 10);
2297 zebrad.ribq->spec.hold = timer;
3a30f50f 2298
996c9314 2299 return CMD_SUCCESS;
3a30f50f
DS
2300}
2301
2302DEFUN_HIDDEN (no_zebra_workqueue_timer,
2303 no_zebra_workqueue_timer_cmd,
2304 "no zebra work-queue [(0-10000)]",
2305 NO_STR
2306 ZEBRA_STR
2307 "Work Queue\n"
2308 "Time in milliseconds\n")
2309{
996c9314 2310 zebrad.ribq->spec.hold = ZEBRA_RIB_PROCESS_HOLD_TIME;
3a30f50f 2311
996c9314 2312 return CMD_SUCCESS;
3a30f50f
DS
2313}
2314
7a4bb9c5
DS
2315DEFUN (no_ip_zebra_import_table,
2316 no_ip_zebra_import_table_cmd,
b62ecea5 2317 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
7a4bb9c5
DS
2318 NO_STR
2319 IP_STR
2320 "import routes from non-main kernel table\n"
3a2d747c
QY
2321 "kernel routing table id\n"
2322 "Distance for imported routes\n"
2323 "Default distance value\n"
2324 "route-map for filtering\n"
2325 "route-map name\n")
7a4bb9c5 2326{
d7c0a89a 2327 uint32_t table_id = 0;
d62a17ae 2328 table_id = strtoul(argv[3]->arg, NULL, 10);
7a4bb9c5 2329
d62a17ae 2330 if (!is_zebra_valid_kernel_table(table_id)) {
2331 vty_out(vty,
2332 "Invalid routing table ID. Must be in range 1-252\n");
2333 return CMD_WARNING;
2334 }
7a4bb9c5 2335
d62a17ae 2336 if (is_zebra_main_routing_table(table_id)) {
2337 vty_out(vty,
2338 "Invalid routing table ID, %d. Must be non-default table\n",
2339 table_id);
2340 return CMD_WARNING;
2341 }
7a4bb9c5 2342
d62a17ae 2343 if (!is_zebra_import_table_enabled(AFI_IP, table_id))
2344 return CMD_SUCCESS;
7a4bb9c5 2345
d62a17ae 2346 return (zebra_import_table(AFI_IP, table_id, 0, NULL, 0));
7a4bb9c5
DS
2347}
2348
d62a17ae 2349static int config_write_protocol(struct vty *vty)
6baf7bb8 2350{
d62a17ae 2351 if (allow_delete)
2352 vty_out(vty, "allow-external-route-update\n");
6baf7bb8 2353
d62a17ae 2354 if (zebra_rnh_ip_default_route)
2355 vty_out(vty, "ip nht resolve-via-default\n");
6baf7bb8 2356
d62a17ae 2357 if (zebra_rnh_ipv6_default_route)
2358 vty_out(vty, "ipv6 nht resolve-via-default\n");
6baf7bb8 2359
3a30f50f
DS
2360 if (zebrad.ribq->spec.hold != ZEBRA_RIB_PROCESS_HOLD_TIME)
2361 vty_out(vty, "zebra work-queue %u\n", zebrad.ribq->spec.hold);
2362
62d52ded 2363 if (zebrad.packets_to_process != ZEBRA_ZAPI_PACKETS_TO_PROCESS)
996c9314
LB
2364 vty_out(vty, "zebra zapi-packets %u\n",
2365 zebrad.packets_to_process);
62d52ded 2366
d62a17ae 2367 enum multicast_mode ipv4_multicast_mode = multicast_mode_ipv4_get();
4623d897 2368
d62a17ae 2369 if (ipv4_multicast_mode != MCAST_NO_CONFIG)
2370 vty_out(vty, "ip multicast rpf-lookup-mode %s\n",
2371 ipv4_multicast_mode == MCAST_URIB_ONLY
2372 ? "urib-only"
2373 : ipv4_multicast_mode == MCAST_MRIB_ONLY
2374 ? "mrib-only"
2375 : ipv4_multicast_mode
2376 == MCAST_MIX_MRIB_FIRST
2377 ? "mrib-then-urib"
2378 : ipv4_multicast_mode
2379 == MCAST_MIX_DISTANCE
2380 ? "lower-distance"
2381 : "longer-prefix");
4623d897 2382
d62a17ae 2383 zebra_routemap_config_write_protocol(vty);
6baf7bb8 2384
d62a17ae 2385 return 1;
6baf7bb8
DS
2386}
2387
c0d136ae
DS
2388#ifdef HAVE_NETLINK
2389/* Display default rtm_table for all clients. */
2390DEFUN (show_table,
2391 show_table_cmd,
2392 "show table",
2393 SHOW_STR
2394 "default routing table to use for all clients\n")
2395{
2396 vty_out(vty, "table %d\n", zebrad.rtm_table_default);
2397 return CMD_SUCCESS;
2398}
2399
2400DEFUN (config_table,
2401 config_table_cmd,
2402 "table TABLENO",
2403 "Configure target kernel routing table\n"
2404 "TABLE integer\n")
2405{
2406 zebrad.rtm_table_default = strtol(argv[1]->arg, (char **)0, 10);
2407 return CMD_SUCCESS;
2408}
2409
2410DEFUN (no_config_table,
2411 no_config_table_cmd,
2412 "no table [TABLENO]",
2413 NO_STR
2414 "Configure target kernel routing table\n"
2415 "TABLE integer\n")
2416{
2417 zebrad.rtm_table_default = 0;
2418 return CMD_SUCCESS;
2419}
2420#endif
2421
2422DEFUN (show_zebra,
2423 show_zebra_cmd,
2424 "show zebra",
2425 SHOW_STR
2426 ZEBRA_STR)
2427{
2428 struct vrf *vrf;
2429
2430 vty_out(vty,
2431 " Route Route Neighbor LSP LSP\n");
2432 vty_out(vty,
2433 "VRF Installs Removals Updates Installs Removals\n");
2434
996c9314 2435 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
c0d136ae
DS
2436 struct zebra_vrf *zvrf = vrf->info;
2437
2438 vty_out(vty, "%-25s %10" PRIu64 " %10" PRIu64 " %10" PRIu64
2439 " %10" PRIu64 " %10" PRIu64 "\n",
2440 vrf->name, zvrf->installs, zvrf->removals,
2441 zvrf->neigh_updates, zvrf->lsp_installs,
2442 zvrf->lsp_removals);
2443 }
2444
2445 return CMD_SUCCESS;
2446}
2447
2448DEFUN (ip_forwarding,
2449 ip_forwarding_cmd,
2450 "ip forwarding",
2451 IP_STR
2452 "Turn on IP forwarding\n")
2453{
2454 int ret;
2455
2456 ret = ipforward();
2457 if (ret == 0)
2458 ret = ipforward_on();
2459
2460 if (ret == 0) {
2461 vty_out(vty, "Can't turn on IP forwarding\n");
2462 return CMD_WARNING_CONFIG_FAILED;
2463 }
2464
2465 return CMD_SUCCESS;
2466}
2467
2468DEFUN (no_ip_forwarding,
2469 no_ip_forwarding_cmd,
2470 "no ip forwarding",
2471 NO_STR
2472 IP_STR
2473 "Turn off IP forwarding\n")
2474{
2475 int ret;
2476
2477 ret = ipforward();
2478 if (ret != 0)
2479 ret = ipforward_off();
2480
2481 if (ret != 0) {
2482 vty_out(vty, "Can't turn off IP forwarding\n");
2483 return CMD_WARNING_CONFIG_FAILED;
2484 }
2485
2486 return CMD_SUCCESS;
2487}
2488
2489/* Only display ip forwarding is enabled or not. */
2490DEFUN (show_ip_forwarding,
2491 show_ip_forwarding_cmd,
2492 "show ip forwarding",
2493 SHOW_STR
2494 IP_STR
2495 "IP forwarding status\n")
2496{
2497 int ret;
2498
2499 ret = ipforward();
2500
2501 if (ret == 0)
2502 vty_out(vty, "IP forwarding is off\n");
2503 else
2504 vty_out(vty, "IP forwarding is on\n");
2505 return CMD_SUCCESS;
2506}
2507
2508/* Only display ipv6 forwarding is enabled or not. */
2509DEFUN (show_ipv6_forwarding,
2510 show_ipv6_forwarding_cmd,
2511 "show ipv6 forwarding",
2512 SHOW_STR
2513 "IPv6 information\n"
2514 "Forwarding status\n")
2515{
2516 int ret;
2517
2518 ret = ipforward_ipv6();
2519
2520 switch (ret) {
2521 case -1:
2522 vty_out(vty, "ipv6 forwarding is unknown\n");
2523 break;
2524 case 0:
2525 vty_out(vty, "ipv6 forwarding is %s\n", "off");
2526 break;
2527 case 1:
2528 vty_out(vty, "ipv6 forwarding is %s\n", "on");
2529 break;
2530 default:
2531 vty_out(vty, "ipv6 forwarding is %s\n", "off");
2532 break;
2533 }
2534 return CMD_SUCCESS;
2535}
2536
2537DEFUN (ipv6_forwarding,
2538 ipv6_forwarding_cmd,
2539 "ipv6 forwarding",
2540 IPV6_STR
2541 "Turn on IPv6 forwarding\n")
2542{
2543 int ret;
2544
2545 ret = ipforward_ipv6();
2546 if (ret == 0)
2547 ret = ipforward_ipv6_on();
2548
2549 if (ret == 0) {
2550 vty_out(vty, "Can't turn on IPv6 forwarding\n");
2551 return CMD_WARNING_CONFIG_FAILED;
2552 }
2553
2554 return CMD_SUCCESS;
2555}
2556
2557DEFUN (no_ipv6_forwarding,
2558 no_ipv6_forwarding_cmd,
2559 "no ipv6 forwarding",
2560 NO_STR
2561 IPV6_STR
2562 "Turn off IPv6 forwarding\n")
2563{
2564 int ret;
2565
2566 ret = ipforward_ipv6();
2567 if (ret != 0)
2568 ret = ipforward_ipv6_off();
2569
2570 if (ret != 0) {
2571 vty_out(vty, "Can't turn off IPv6 forwarding\n");
2572 return CMD_WARNING_CONFIG_FAILED;
2573 }
2574
2575 return CMD_SUCCESS;
2576}
2577
2578/* Table configuration write function. */
2579static int config_write_table(struct vty *vty)
2580{
2581 if (zebrad.rtm_table_default)
2582 vty_out(vty, "table %d\n", zebrad.rtm_table_default);
2583 return 0;
2584}
2585
2586/* IPForwarding configuration write function. */
2587static int config_write_forwarding(struct vty *vty)
2588{
2589 /* FIXME: Find better place for that. */
2590 router_id_write(vty);
2591
2592 if (!ipforward())
2593 vty_out(vty, "no ip forwarding\n");
2594 if (!ipforward_ipv6())
2595 vty_out(vty, "no ipv6 forwarding\n");
2596 vty_out(vty, "!\n");
2597 return 0;
2598}
2599
718e3744 2600/* IP node for static routes. */
d62a17ae 2601static struct cmd_node ip_node = {IP_NODE, "", 1};
2602static struct cmd_node protocol_node = {PROTOCOL_NODE, "", 1};
c0d136ae
DS
2603/* table node for routing tables. */
2604static struct cmd_node table_node = {TABLE_NODE,
2605 "", /* This node has no interface. */
2606 1};
2607static struct cmd_node forwarding_node = {FORWARDING_NODE,
2608 "", /* This node has no interface. */
2609 1};
718e3744 2610
2611/* Route VTY. */
d62a17ae 2612void zebra_vty_init(void)
2613{
c0d136ae
DS
2614 /* Install configuration write function. */
2615 install_node(&table_node, config_write_table);
2616 install_node(&forwarding_node, config_write_forwarding);
2617
2618 install_element(VIEW_NODE, &show_ip_forwarding_cmd);
2619 install_element(CONFIG_NODE, &ip_forwarding_cmd);
2620 install_element(CONFIG_NODE, &no_ip_forwarding_cmd);
2621 install_element(ENABLE_NODE, &show_zebra_cmd);
2622
2623#ifdef HAVE_NETLINK
2624 install_element(VIEW_NODE, &show_table_cmd);
2625 install_element(CONFIG_NODE, &config_table_cmd);
2626 install_element(CONFIG_NODE, &no_config_table_cmd);
2627#endif /* HAVE_NETLINK */
2628
2629 install_element(VIEW_NODE, &show_ipv6_forwarding_cmd);
2630 install_element(CONFIG_NODE, &ipv6_forwarding_cmd);
2631 install_element(CONFIG_NODE, &no_ipv6_forwarding_cmd);
2632
2633 /* Route-map */
2634 zebra_route_map_init();
2635
d62a17ae 2636 install_node(&ip_node, zebra_ip_config);
2637 install_node(&protocol_node, config_write_protocol);
2638
2639 install_element(CONFIG_NODE, &allow_external_route_update_cmd);
2640 install_element(CONFIG_NODE, &no_allow_external_route_update_cmd);
7e24fdf3 2641
d62a17ae 2642 install_element(CONFIG_NODE, &ip_multicast_mode_cmd);
2643 install_element(CONFIG_NODE, &no_ip_multicast_mode_cmd);
b3b08602 2644
d62a17ae 2645 install_element(CONFIG_NODE, &ip_zebra_import_table_distance_cmd);
2646 install_element(CONFIG_NODE, &no_ip_zebra_import_table_cmd);
3a30f50f
DS
2647 install_element(CONFIG_NODE, &zebra_workqueue_timer_cmd);
2648 install_element(CONFIG_NODE, &no_zebra_workqueue_timer_cmd);
62d52ded
DS
2649 install_element(CONFIG_NODE, &zebra_packet_process_cmd);
2650 install_element(CONFIG_NODE, &no_zebra_packet_process_cmd);
d62a17ae 2651
2652 install_element(VIEW_NODE, &show_vrf_cmd);
b7cfce93 2653 install_element(VIEW_NODE, &show_vrf_vni_cmd);
ecffa493 2654 install_element(VIEW_NODE, &show_route_cmd);
ae825b8b 2655 install_element(VIEW_NODE, &show_route_table_cmd);
87d6ac7a
PG
2656 if (vrf_is_backend_netns())
2657 install_element(VIEW_NODE, &show_route_table_vrf_cmd);
5ce91022
RW
2658 install_element(VIEW_NODE, &show_route_detail_cmd);
2659 install_element(VIEW_NODE, &show_route_summary_cmd);
d62a17ae 2660 install_element(VIEW_NODE, &show_ip_nht_cmd);
2661 install_element(VIEW_NODE, &show_ip_nht_vrf_all_cmd);
2662 install_element(VIEW_NODE, &show_ipv6_nht_cmd);
2663 install_element(VIEW_NODE, &show_ipv6_nht_vrf_all_cmd);
d62a17ae 2664
2665 install_element(VIEW_NODE, &show_ip_rpf_cmd);
2666 install_element(VIEW_NODE, &show_ip_rpf_addr_cmd);
2667
d62a17ae 2668 install_element(CONFIG_NODE, &ip_nht_default_route_cmd);
2669 install_element(CONFIG_NODE, &no_ip_nht_default_route_cmd);
2670 install_element(CONFIG_NODE, &ipv6_nht_default_route_cmd);
2671 install_element(CONFIG_NODE, &no_ipv6_nht_default_route_cmd);
d62a17ae 2672 install_element(VIEW_NODE, &show_ipv6_mroute_cmd);
2673
2674 /* Commands for VRF */
d62a17ae 2675 install_element(VIEW_NODE, &show_ipv6_mroute_vrf_all_cmd);
2676
4cce389e 2677 install_element(VIEW_NODE, &show_evpn_global_cmd);
d62a17ae 2678 install_element(VIEW_NODE, &show_evpn_vni_cmd);
2679 install_element(VIEW_NODE, &show_evpn_vni_vni_cmd);
4cce389e
MK
2680 install_element(VIEW_NODE, &show_evpn_rmac_vni_mac_cmd);
2681 install_element(VIEW_NODE, &show_evpn_rmac_vni_cmd);
2682 install_element(VIEW_NODE, &show_evpn_rmac_vni_all_cmd);
2683 install_element(VIEW_NODE, &show_evpn_nh_vni_ip_cmd);
2684 install_element(VIEW_NODE, &show_evpn_nh_vni_cmd);
2685 install_element(VIEW_NODE, &show_evpn_nh_vni_all_cmd);
d62a17ae 2686 install_element(VIEW_NODE, &show_evpn_mac_vni_cmd);
2687 install_element(VIEW_NODE, &show_evpn_mac_vni_all_cmd);
2688 install_element(VIEW_NODE, &show_evpn_mac_vni_all_vtep_cmd);
2689 install_element(VIEW_NODE, &show_evpn_mac_vni_mac_cmd);
2690 install_element(VIEW_NODE, &show_evpn_mac_vni_vtep_cmd);
2691 install_element(VIEW_NODE, &show_evpn_neigh_vni_cmd);
2692 install_element(VIEW_NODE, &show_evpn_neigh_vni_all_cmd);
2693 install_element(VIEW_NODE, &show_evpn_neigh_vni_neigh_cmd);
2694 install_element(VIEW_NODE, &show_evpn_neigh_vni_vtep_cmd);
b7cfce93 2695
586f4ccf
PG
2696 install_element(VIEW_NODE, &show_pbr_ipset_cmd);
2697 install_element(VIEW_NODE, &show_pbr_iptable_cmd);
2698
e8d26197
MK
2699 install_element(CONFIG_NODE, &default_vrf_vni_mapping_cmd);
2700 install_element(CONFIG_NODE, &no_default_vrf_vni_mapping_cmd);
b7cfce93
MK
2701 install_element(VRF_NODE, &vrf_vni_mapping_cmd);
2702 install_element(VRF_NODE, &no_vrf_vni_mapping_cmd);
4060008b 2703
7e24fdf3 2704
718e3744 2705}