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