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