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