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