]> git.proxmox.com Git - mirror_frr.git/blame - zebra/zebra_vty.c
*: use ->text and strmatch where appropriate
[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);
241a2f56
DS
1420 else if (argv_find (argv, argc, "babel", &idx))
1421 type = proto_redistnum (AFI_IP, argv[idx]->text);
acb25e73
DW
1422 else if (argv_find (argv, argc, "connected", &idx))
1423 type = proto_redistnum (AFI_IP, argv[idx]->text);
1424 else if (argv_find (argv, argc, "static", &idx))
1425 type = proto_redistnum (AFI_IP, argv[idx]->text);
1426 else if (argv_find (argv, argc, "rip", &idx))
1427 type = proto_redistnum (AFI_IP, argv[idx]->text);
1428 else if (argv_find (argv, argc, "ospf", &idx))
1429 type = proto_redistnum (AFI_IP, argv[idx]->text);
1430 else if (argv_find (argv, argc, "isis", &idx))
1431 type = proto_redistnum (AFI_IP, argv[idx]->text);
1432 else if (argv_find (argv, argc, "bgp", &idx))
1433 type = proto_redistnum (AFI_IP, argv[idx]->text);
1434 else if (argv_find (argv, argc, "pim", &idx))
1435 type = proto_redistnum (AFI_IP, argv[idx]->text);
1436 else if (argv_find (argv, argc, "eigrp", &idx))
1437 type = proto_redistnum (AFI_IP, argv[idx]->text);
1438 else if (argv_find (argv, argc, "nhrp", &idx))
1439 type = proto_redistnum (AFI_IP, argv[idx]->text);
1440 else if (argv_find (argv, argc, "table", &idx))
1441 type = proto_redistnum (AFI_IP, argv[idx]->text);
1442 else if (argv_find (argv, argc, "vnc", &idx))
1443 type = proto_redistnum (AFI_IP, argv[idx]->text);
1444
1445 if (argv_find (argv, argc, "(1-65535)", &idx))
1446 VTY_GET_INTEGER ("Instance", ospf_instance_id, argv[idx]->arg);
1447
1448 if (type < 0)
1449 {
1450 vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
1451 return CMD_WARNING;
1452 }
9bf96c84 1453 }
d511d7f1 1454
acb25e73 1455 if (vrf_all)
8f527c5e 1456 {
acb25e73
DW
1457 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
1458 {
1459 if ((zvrf = vrf->info) == NULL ||
1460 (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
1461 continue;
d511d7f1 1462
acb25e73
DW
1463 do_show_ip_route (vty, zvrf_name (zvrf), AFI_IP, SAFI_UNICAST, uf, uj, tag,
1464 longer_prefixes ? &p : NULL, supernets_only, type, ospf_instance_id);
1465 }
1466 }
1467 else
8f527c5e 1468 {
acb25e73
DW
1469 vrf = vrf_lookup_by_id (vrf_id);
1470 do_show_ip_route (vty, vrf->name, AFI_IP, SAFI_UNICAST, uf, uj, tag,
1471 longer_prefixes ? &p : NULL, supernets_only, type, ospf_instance_id);
8f527c5e 1472 }
8f527c5e
FL
1473 return CMD_SUCCESS;
1474}
1475
1476DEFUN (show_ip_route_addr,
1477 show_ip_route_addr_cmd,
9bf96c84 1478 "show ip route [vrf NAME] A.B.C.D",
8f527c5e
FL
1479 SHOW_STR
1480 IP_STR
1481 "IP routing table\n"
9bf96c84 1482 VRF_CMD_HELP_STR
8f527c5e
FL
1483 "Network in the IP routing table to display\n")
1484{
1485 int ret;
1486 struct prefix_ipv4 p;
1487 struct route_table *table;
1488 struct route_node *rn;
1489 vrf_id_t vrf_id = VRF_DEFAULT;
1490
412e5cd9 1491 if (strmatch(argv[3]->text, "vrf"))
d511d7f1 1492 {
9bf96c84
DW
1493 VRF_GET_ID (vrf_id, argv[4]->arg);
1494 ret = str2prefix_ipv4 (argv[5]->arg, &p);
d511d7f1
DS
1495 }
1496 else
9bf96c84
DW
1497 {
1498 ret = str2prefix_ipv4 (argv[3]->arg, &p);
1499 }
d511d7f1 1500
8f527c5e
FL
1501 if (ret <= 0)
1502 {
1503 vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
1504 return CMD_WARNING;
1505 }
1506
8f527c5e
FL
1507 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
1508 if (! table)
1509 return CMD_SUCCESS;
1510
1511 rn = route_node_match (table, (struct prefix *) &p);
1512 if (! rn)
1513 {
1514 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
1515 return CMD_WARNING;
1516 }
1517
65dd94cf 1518 vty_show_ip_route_detail (vty, rn, 0);
8f527c5e
FL
1519
1520 route_unlock_node (rn);
1521
1522 return CMD_SUCCESS;
1523}
1524
8f527c5e
FL
1525DEFUN (show_ip_route_prefix,
1526 show_ip_route_prefix_cmd,
9bf96c84 1527 "show ip route [vrf NAME] A.B.C.D/M",
8f527c5e
FL
1528 SHOW_STR
1529 IP_STR
1530 "IP routing table\n"
9bf96c84 1531 VRF_CMD_HELP_STR
8f527c5e
FL
1532 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
1533{
1534 int ret;
1535 struct prefix_ipv4 p;
1536 struct route_table *table;
1537 struct route_node *rn;
1538 vrf_id_t vrf_id = VRF_DEFAULT;
1539
412e5cd9 1540 if (strmatch(argv[3]->text, "vrf"))
d511d7f1 1541 {
9bf96c84
DW
1542 VRF_GET_ID (vrf_id, argv[4]->arg);
1543 ret = str2prefix_ipv4 (argv[5]->arg, &p);
d511d7f1
DS
1544 }
1545 else
9bf96c84
DW
1546 {
1547 ret = str2prefix_ipv4 (argv[3]->arg, &p);
1548 }
d511d7f1 1549
8f527c5e
FL
1550 if (ret <= 0)
1551 {
1552 vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
1553 return CMD_WARNING;
1554 }
1555
8f527c5e
FL
1556 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
1557 if (! table)
1558 return CMD_SUCCESS;
1559
1560 rn = route_node_match (table, (struct prefix *) &p);
1561 if (! rn || rn->p.prefixlen != p.prefixlen)
1562 {
1563 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
1564 return CMD_WARNING;
1565 }
1566
65dd94cf 1567 vty_show_ip_route_detail (vty, rn, 0);
8f527c5e
FL
1568
1569 route_unlock_node (rn);
1570
1571 return CMD_SUCCESS;
1572}
1573
8f527c5e
FL
1574
1575static void
1576vty_show_ip_route_summary (struct vty *vty, struct route_table *table)
1577{
1578 struct route_node *rn;
f0f77c9a 1579 struct route_entry *re;
8f527c5e
FL
1580#define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1581#define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1582 u_int32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1583 u_int32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1584 u_int32_t i;
1ff0858e 1585 u_int32_t is_ibgp;
8f527c5e
FL
1586
1587 memset (&rib_cnt, 0, sizeof(rib_cnt));
1588 memset (&fib_cnt, 0, sizeof(fib_cnt));
05737783 1589 for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
f0f77c9a 1590 RNODE_FOREACH_RE (rn, re)
1ff0858e 1591 {
f0f77c9a
DS
1592 is_ibgp = (re->type == ZEBRA_ROUTE_BGP &&
1593 CHECK_FLAG (re->flags, ZEBRA_FLAG_IBGP));
1ff0858e
DD
1594
1595 rib_cnt[ZEBRA_ROUTE_TOTAL]++;
1596 if (is_ibgp)
1597 rib_cnt[ZEBRA_ROUTE_IBGP]++;
1598 else
f0f77c9a 1599 rib_cnt[re->type]++;
1ff0858e 1600
f0f77c9a 1601 if (CHECK_FLAG (re->flags, ZEBRA_FLAG_SELECTED))
1ff0858e
DD
1602 {
1603 fib_cnt[ZEBRA_ROUTE_TOTAL]++;
1604
1605 if (is_ibgp)
1606 fib_cnt[ZEBRA_ROUTE_IBGP]++;
1607 else
f0f77c9a 1608 fib_cnt[re->type]++;
1ff0858e
DD
1609 }
1610 }
8f527c5e 1611
5fe74770 1612 vty_out (vty, "%-20s %-20s %s (vrf %s)%s",
8f527c5e 1613 "Route Source", "Routes", "FIB",
53dc2b05 1614 zvrf_name (((rib_table_info_t *)table->info)->zvrf),
8f527c5e
FL
1615 VTY_NEWLINE);
1616
1ff0858e 1617 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
8f527c5e 1618 {
3ff86133
DS
1619 if ((rib_cnt[i] > 0) ||
1620 (i == ZEBRA_ROUTE_BGP && rib_cnt[ZEBRA_ROUTE_IBGP] > 0))
1ff0858e
DD
1621 {
1622 if (i == ZEBRA_ROUTE_BGP)
1623 {
1624 vty_out (vty, "%-20s %-20d %-20d %s", "ebgp",
00cbc1f5 1625 rib_cnt[ZEBRA_ROUTE_BGP], fib_cnt[ZEBRA_ROUTE_BGP],
1ff0858e
DD
1626 VTY_NEWLINE);
1627 vty_out (vty, "%-20s %-20d %-20d %s", "ibgp",
1628 rib_cnt[ZEBRA_ROUTE_IBGP], fib_cnt[ZEBRA_ROUTE_IBGP],
1629 VTY_NEWLINE);
1630 }
1631 else
1632 vty_out (vty, "%-20s %-20d %-20d %s", zebra_route_string(i),
1633 rib_cnt[i], fib_cnt[i], VTY_NEWLINE);
1634 }
8f527c5e
FL
1635 }
1636
1637 vty_out (vty, "------%s", VTY_NEWLINE);
1ff0858e
DD
1638 vty_out (vty, "%-20s %-20d %-20d %s", "Totals", rib_cnt[ZEBRA_ROUTE_TOTAL],
1639 fib_cnt[ZEBRA_ROUTE_TOTAL], VTY_NEWLINE);
8f527c5e
FL
1640 vty_out (vty, "%s", VTY_NEWLINE);
1641}
1642
1643/*
1644 * Implementation of the ip route summary prefix command.
1645 *
1646 * This command prints the primary prefixes that have been installed by various
1647 * protocols on the box.
1648 *
1649 */
1650static void
1651vty_show_ip_route_summary_prefix (struct vty *vty, struct route_table *table)
1652{
1653 struct route_node *rn;
f0f77c9a 1654 struct route_entry *re;
8f527c5e
FL
1655 struct nexthop *nexthop;
1656#define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1657#define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1658 u_int32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1659 u_int32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1660 u_int32_t i;
1661 int cnt;
1662
1663 memset (&rib_cnt, 0, sizeof(rib_cnt));
1664 memset (&fib_cnt, 0, sizeof(fib_cnt));
05737783 1665 for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
f0f77c9a 1666 RNODE_FOREACH_RE (rn, re)
8f527c5e
FL
1667 {
1668
1669 /*
1670 * In case of ECMP, count only once.
1671 */
1672 cnt = 0;
f0f77c9a 1673 for (nexthop = re->nexthop; (!cnt && nexthop); nexthop = nexthop->next)
8f527c5e
FL
1674 {
1675 cnt++;
1676 rib_cnt[ZEBRA_ROUTE_TOTAL]++;
f0f77c9a 1677 rib_cnt[re->type]++;
9343ce83
DS
1678 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
1679 {
1680 fib_cnt[ZEBRA_ROUTE_TOTAL]++;
f0f77c9a 1681 fib_cnt[re->type]++;
9343ce83 1682 }
f0f77c9a
DS
1683 if (re->type == ZEBRA_ROUTE_BGP &&
1684 CHECK_FLAG (re->flags, ZEBRA_FLAG_IBGP))
9343ce83
DS
1685 {
1686 rib_cnt[ZEBRA_ROUTE_IBGP]++;
1687 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
1688 fib_cnt[ZEBRA_ROUTE_IBGP]++;
1689 }
1690 }
1691 }
1692
d511d7f1 1693 vty_out (vty, "%-20s %-20s %s (vrf %s)%s",
af41b63a 1694 "Route Source", "Prefix Routes", "FIB",
53dc2b05 1695 zvrf_name (((rib_table_info_t *)table->info)->zvrf),
af41b63a 1696 VTY_NEWLINE);
9343ce83
DS
1697
1698 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
1699 {
1700 if (rib_cnt[i] > 0)
1701 {
1702 if (i == ZEBRA_ROUTE_BGP)
1703 {
1704 vty_out (vty, "%-20s %-20d %-20d %s", "ebgp",
1705 rib_cnt[ZEBRA_ROUTE_BGP] - rib_cnt[ZEBRA_ROUTE_IBGP],
1706 fib_cnt[ZEBRA_ROUTE_BGP] - fib_cnt[ZEBRA_ROUTE_IBGP],
1707 VTY_NEWLINE);
1708 vty_out (vty, "%-20s %-20d %-20d %s", "ibgp",
1709 rib_cnt[ZEBRA_ROUTE_IBGP], fib_cnt[ZEBRA_ROUTE_IBGP],
1710 VTY_NEWLINE);
1711 }
1712 else
1713 vty_out (vty, "%-20s %-20d %-20d %s", zebra_route_string(i),
1714 rib_cnt[i], fib_cnt[i], VTY_NEWLINE);
1715 }
1716 }
1717
1718 vty_out (vty, "------%s", VTY_NEWLINE);
1719 vty_out (vty, "%-20s %-20d %-20d %s", "Totals", rib_cnt[ZEBRA_ROUTE_TOTAL],
1720 fib_cnt[ZEBRA_ROUTE_TOTAL], VTY_NEWLINE);
af41b63a 1721 vty_out (vty, "%s", VTY_NEWLINE);
9343ce83
DS
1722}
1723
718e3744 1724/* Show route summary. */
1725DEFUN (show_ip_route_summary,
1726 show_ip_route_summary_cmd,
9bf96c84 1727 "show ip route [vrf NAME] summary",
718e3744 1728 SHOW_STR
1729 IP_STR
1730 "IP routing table\n"
9bf96c84 1731 VRF_CMD_HELP_STR
718e3744 1732 "Summary of all routes\n")
1733{
61691c91 1734 struct route_table *table;
af41b63a 1735 vrf_id_t vrf_id = VRF_DEFAULT;
718e3744 1736
412e5cd9 1737 if (strmatch(argv[3]->text, "vrf"))
9bf96c84 1738 VRF_GET_ID (vrf_id, argv[4]->arg);
af41b63a
FL
1739
1740 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
61691c91
ST
1741 if (! table)
1742 return CMD_SUCCESS;
718e3744 1743
61691c91 1744 vty_show_ip_route_summary (vty, table);
718e3744 1745
1746 return CMD_SUCCESS;
1747}
1748
9343ce83
DS
1749/* Show route summary prefix. */
1750DEFUN (show_ip_route_summary_prefix,
1751 show_ip_route_summary_prefix_cmd,
9bf96c84 1752 "show ip route [vrf NAME] summary prefix",
9343ce83
DS
1753 SHOW_STR
1754 IP_STR
1755 "IP routing table\n"
9bf96c84 1756 VRF_CMD_HELP_STR
9343ce83
DS
1757 "Summary of all routes\n"
1758 "Prefix routes\n")
1759{
1760 struct route_table *table;
af41b63a 1761 vrf_id_t vrf_id = VRF_DEFAULT;
9343ce83 1762
412e5cd9 1763 if (strmatch(argv[3]->text, "vrf"))
9bf96c84 1764 VRF_GET_ID (vrf_id, argv[4]->arg);
af41b63a
FL
1765
1766 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
9343ce83
DS
1767 if (! table)
1768 return CMD_SUCCESS;
1769
1770 vty_show_ip_route_summary_prefix (vty, table);
1771
1772 return CMD_SUCCESS;
1773}
1774
af41b63a 1775
acb25e73
DW
1776DEFUN (show_ip_route_vrf_all_addr,
1777 show_ip_route_vrf_all_addr_cmd,
1778 "show ip route vrf all A.B.C.D",
af41b63a
FL
1779 SHOW_STR
1780 IP_STR
1781 "IP routing table\n"
acb25e73
DW
1782 VRF_ALL_CMD_HELP_STR
1783 "Network in the IP routing table to display\n")
af41b63a 1784{
acb25e73
DW
1785 int idx_ipv4 = 5;
1786 int ret;
1787 struct prefix_ipv4 p;
af41b63a
FL
1788 struct route_table *table;
1789 struct route_node *rn;
53dc2b05 1790 struct vrf *vrf;
af41b63a 1791 struct zebra_vrf *zvrf;
acb25e73
DW
1792
1793 ret = str2prefix_ipv4 (argv[idx_ipv4]->arg, &p);
1794 if (ret <= 0)
1795 {
1796 vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
1797 return CMD_WARNING;
1798 }
af41b63a 1799
53dc2b05 1800 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
af41b63a 1801 {
53dc2b05 1802 if ((zvrf = vrf->info) == NULL ||
af41b63a
FL
1803 (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
1804 continue;
1805
acb25e73
DW
1806 rn = route_node_match (table, (struct prefix *) &p);
1807 if (! rn)
1808 continue;
d511d7f1 1809
acb25e73
DW
1810 vty_show_ip_route_detail (vty, rn, 0);
1811
1812 route_unlock_node (rn);
8f527c5e
FL
1813 }
1814
1815 return CMD_SUCCESS;
1816}
1817
d511d7f1
DS
1818DEFUN (show_ip_route_vrf_all_prefix,
1819 show_ip_route_vrf_all_prefix_cmd,
5bebf568 1820 "show ip route vrf all A.B.C.D/M",
8f527c5e
FL
1821 SHOW_STR
1822 IP_STR
1823 "IP routing table\n"
d511d7f1
DS
1824 VRF_ALL_CMD_HELP_STR
1825 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
8f527c5e 1826{
7c022376 1827 int idx_ipv4_prefixlen = 5;
8f527c5e
FL
1828 int ret;
1829 struct prefix_ipv4 p;
1830 struct route_table *table;
1831 struct route_node *rn;
53dc2b05 1832 struct vrf *vrf;
8f527c5e 1833 struct zebra_vrf *zvrf;
8f527c5e 1834
7c022376 1835 ret = str2prefix_ipv4 (argv[idx_ipv4_prefixlen]->arg, &p);
8f527c5e
FL
1836 if (ret <= 0)
1837 {
1838 vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
1839 return CMD_WARNING;
1840 }
1841
53dc2b05 1842 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
8f527c5e 1843 {
53dc2b05 1844 if ((zvrf = vrf->info) == NULL ||
8f527c5e
FL
1845 (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
1846 continue;
1847
1848 rn = route_node_match (table, (struct prefix *) &p);
1849 if (! rn)
1850 continue;
1851 if (rn->p.prefixlen != p.prefixlen)
1852 {
1853 route_unlock_node (rn);
1854 continue;
1855 }
1856
65dd94cf 1857 vty_show_ip_route_detail (vty, rn, 0);
8f527c5e
FL
1858
1859 route_unlock_node (rn);
1860 }
1861
1862 return CMD_SUCCESS;
1863}
1864
d511d7f1
DS
1865DEFUN (show_ip_route_vrf_all_summary,
1866 show_ip_route_vrf_all_summary_cmd,
5bebf568 1867 "show ip route vrf all summary ",
8f527c5e
FL
1868 SHOW_STR
1869 IP_STR
1870 "IP routing table\n"
d511d7f1
DS
1871 VRF_ALL_CMD_HELP_STR
1872 "Summary of all routes\n")
8f527c5e 1873{
53dc2b05 1874 struct vrf *vrf;
8f527c5e 1875 struct zebra_vrf *zvrf;
8f527c5e 1876
53dc2b05
DL
1877 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
1878 if ((zvrf = vrf->info) != NULL)
8f527c5e
FL
1879 vty_show_ip_route_summary (vty, zvrf->table[AFI_IP][SAFI_UNICAST]);
1880
1881 return CMD_SUCCESS;
1882}
1883
d511d7f1
DS
1884DEFUN (show_ip_route_vrf_all_summary_prefix,
1885 show_ip_route_vrf_all_summary_prefix_cmd,
5bebf568 1886 "show ip route vrf all summary prefix",
8f527c5e
FL
1887 SHOW_STR
1888 IP_STR
1889 "IP routing table\n"
d511d7f1 1890 VRF_ALL_CMD_HELP_STR
8f527c5e 1891 "Summary of all routes\n"
d511d7f1 1892 "Prefix routes\n")
8f527c5e 1893{
53dc2b05 1894 struct vrf *vrf;
8f527c5e 1895 struct zebra_vrf *zvrf;
8f527c5e 1896
53dc2b05
DL
1897 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
1898 if ((zvrf = vrf->info) != NULL)
8f527c5e
FL
1899 vty_show_ip_route_summary_prefix (vty, zvrf->table[AFI_IP][SAFI_UNICAST]);
1900
1901 return CMD_SUCCESS;
1902}
1903
9de498ec 1904/* Write static route configuration. */
8f527c5e 1905static int
9de498ec 1906static_config (struct vty *vty, afi_t afi, safi_t safi, const char *cmd)
8f527c5e
FL
1907{
1908 struct route_node *rn;
be5e48ab 1909 struct static_route *si;
8f527c5e 1910 struct route_table *stable;
53dc2b05 1911 struct vrf *vrf;
8f527c5e 1912 struct zebra_vrf *zvrf;
9de498ec 1913 char buf[SRCDEST2STR_BUFFER];
b9f1114e 1914 int write =0;
8f527c5e 1915
53dc2b05 1916 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
8f527c5e 1917 {
53dc2b05
DL
1918 if (!(zvrf = vrf->info))
1919 continue;
9de498ec 1920 if ((stable = zvrf->stable[afi][safi]) == NULL)
8f527c5e
FL
1921 continue;
1922
9de498ec 1923 for (rn = route_top (stable); rn; rn = srcdest_route_next (rn))
8f527c5e 1924 for (si = rn->info; si; si = si->next)
af41b63a 1925 {
9de498ec 1926 vty_out (vty, "%s %s", cmd, srcdest_rnode2str (rn, buf, sizeof buf));
af41b63a 1927
8f527c5e 1928 switch (si->type)
af41b63a 1929 {
8f527c5e 1930 case STATIC_IPV4_GATEWAY:
be5e48ab 1931 vty_out (vty, " %s", inet_ntoa (si->addr.ipv4));
8f527c5e 1932 break;
9de498ec 1933 case STATIC_IPV6_GATEWAY:
6201488a 1934 vty_out (vty, " %s", inet_ntop (AF_INET6, &si->addr.ipv6, buf, sizeof buf));
9de498ec 1935 break;
ba779241 1936 case STATIC_IFINDEX:
fb148af4 1937 vty_out (vty, " %s", si->ifname);
8f527c5e 1938 break;
e9e190f2 1939 case STATIC_BLACKHOLE:
8f527c5e
FL
1940 vty_out (vty, " Null0");
1941 break;
9de498ec
DS
1942 case STATIC_IPV6_GATEWAY_IFINDEX:
1943 vty_out (vty, " %s %s",
6201488a 1944 inet_ntop (AF_INET6, &si->addr.ipv6, buf, sizeof buf),
9de498ec
DS
1945 ifindex2ifname (si->ifindex, si->vrf_id));
1946 break;
8f527c5e
FL
1947 }
1948
e9e190f2
QY
1949 /* flags are incompatible with STATIC_BLACKHOLE */
1950 if (si->type != STATIC_BLACKHOLE)
8f527c5e
FL
1951 {
1952 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_REJECT))
1953 vty_out (vty, " %s", "reject");
1954
1955 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_BLACKHOLE))
1956 vty_out (vty, " %s", "blackhole");
af41b63a 1957 }
8f527c5e
FL
1958
1959 if (si->tag)
d64ff607 1960 vty_out (vty, " tag %"ROUTE_TAG_PRI, si->tag);
8f527c5e
FL
1961
1962 if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT)
1963 vty_out (vty, " %d", si->distance);
1964
1965 if (si->vrf_id != VRF_DEFAULT)
9de498ec 1966 vty_out (vty, " vrf %s", zvrf_name (zvrf));
8f527c5e 1967
d64ff607
QY
1968 /* Label information */
1969 if (si->snh_label.num_labels)
1970 vty_out (vty, " label %s",
1971 mpls_label2str (si->snh_label.num_labels,
4caac24b 1972 si->snh_label.label, buf, sizeof buf, 0));
d64ff607 1973
8f527c5e
FL
1974 vty_out (vty, "%s", VTY_NEWLINE);
1975
1976 write = 1;
af41b63a
FL
1977 }
1978 }
8f527c5e
FL
1979 return write;
1980}
1981
8f527c5e 1982/* General fucntion for IPv6 static route. */
e52702f2 1983int
8f527c5e 1984static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str,
c423229b 1985 const char *src_str,
e52702f2
QY
1986 const char *gate_str, const char *ifname,
1987 const char *flag_str, const char *tag_str,
1988 const char *distance_str, const char *vrf_id_str,
1989 const char *label_str)
af41b63a
FL
1990{
1991 int ret;
8f527c5e 1992 u_char distance;
c423229b
CF
1993 struct prefix p, src;
1994 struct prefix_ipv6 *src_p = NULL;
8f527c5e
FL
1995 struct in6_addr *gate = NULL;
1996 struct in6_addr gate_addr;
e9e190f2 1997 u_char type = STATIC_BLACKHOLE;
8f527c5e 1998 u_char flag = 0;
e52702f2 1999 route_tag_t tag = 0;
ba779241
DS
2000 unsigned int ifindex = 0;
2001 struct interface *ifp = NULL;
b9f1114e 2002 struct zebra_vrf *zvrf;
e52702f2
QY
2003 struct static_nh_label snh_label;
2004
8f527c5e 2005 ret = str2prefix (dest_str, &p);
af41b63a
FL
2006 if (ret <= 0)
2007 {
8f527c5e 2008 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
af41b63a
FL
2009 return CMD_WARNING;
2010 }
2011
c423229b
CF
2012 if (src_str)
2013 {
2014 ret = str2prefix (src_str, &src);
2015 if (ret <= 0 || src.family != AF_INET6)
2016 {
2017 vty_out (vty, "%% Malformed source address%s", VTY_NEWLINE);
2018 return CMD_WARNING;
2019 }
2020 src_p = (struct prefix_ipv6*)&src;
2021 }
2022
8f527c5e
FL
2023 /* Apply mask for given prefix. */
2024 apply_mask (&p);
af41b63a 2025
8f527c5e
FL
2026 /* Administrative distance. */
2027 if (distance_str)
2028 distance = atoi (distance_str);
2029 else
2030 distance = ZEBRA_STATIC_DISTANCE_DEFAULT;
af41b63a 2031
d64ff607
QY
2032 /* tag */
2033 if (tag_str)
b6f1faf0 2034 VTY_GET_INTEGER_RANGE("tag", tag, tag_str, 0, 4294967295);
8f527c5e 2035
8f527c5e
FL
2036 /* When gateway is valid IPv6 addrees, then gate is treated as
2037 nexthop address other case gate is treated as interface name. */
2038 ret = inet_pton (AF_INET6, gate_str, &gate_addr);
2039
21efedeb 2040 /* VRF id */
53dc2b05 2041 zvrf = zebra_vrf_lookup_by_name (vrf_id_str);
b9f1114e
DS
2042
2043 if (!zvrf)
2044 {
2045 vty_out (vty, "%% vrf %s is not defined%s", vrf_id_str, VTY_NEWLINE);
2046 return CMD_WARNING;
2047 }
21efedeb 2048
e52702f2
QY
2049 /* Labels */
2050 memset (&snh_label, 0, sizeof (struct static_nh_label));
2051 if (label_str)
2052 {
d64ff607
QY
2053 if (!mpls_enabled)
2054 {
2055 vty_out (vty, "%% MPLS not turned on in kernel, ignoring command%s",
2056 VTY_NEWLINE);
2057 return CMD_WARNING;
2058 }
8062bf1c
QY
2059 int rc = mpls_str2label (label_str, &snh_label.num_labels,
2060 snh_label.label);
2061 if (rc < 0)
e52702f2 2062 {
8062bf1c
QY
2063 switch (rc) {
2064 case -1:
2065 vty_out (vty, "%% Malformed label(s)%s", VTY_NEWLINE);
2066 break;
2067 case -2:
2068 vty_out (vty, "%% Cannot use reserved label(s) (%d-%d)%s",
2069 MPLS_MIN_RESERVED_LABEL, MPLS_MAX_RESERVED_LABEL,
2070 VTY_NEWLINE);
2071 break;
2072 case -3:
2073 vty_out (vty, "%% Too many labels. Enter %d or fewer%s",
2074 MPLS_MAX_LABELS, VTY_NEWLINE);
2075 break;
2076 }
e52702f2
QY
2077 return CMD_WARNING;
2078 }
2079 }
2080
e9e190f2
QY
2081 /* Null0 static route. */
2082 if ((gate_str != NULL) && (strncasecmp (gate_str, "Null0", strlen (gate_str)) == 0))
2083 {
2084 if (flag_str)
2085 {
2086 vty_out (vty, "%% can not have flag %s with Null0%s", flag_str, VTY_NEWLINE);
2087 return CMD_WARNING;
2088 }
2089 if (add_cmd)
c423229b 2090 static_add_route (AFI_IP6, SAFI_UNICAST, type, &p, NULL, NULL, ifindex, ifname,
e9e190f2
QY
2091 ZEBRA_FLAG_BLACKHOLE, tag, distance, zvrf, &snh_label);
2092 else
c423229b 2093 static_delete_route (AFI_IP6, SAFI_UNICAST, type, &p, NULL, NULL, ifindex, tag,
e9e190f2
QY
2094 distance, zvrf, &snh_label);
2095 return CMD_SUCCESS;
2096 }
2097
2098 /* Route flags */
2099 if (flag_str) {
2100 switch(flag_str[0]) {
2101 case 'r':
2102 case 'R': /* XXX */
2103 SET_FLAG (flag, ZEBRA_FLAG_REJECT);
2104 break;
2105 case 'b':
2106 case 'B': /* XXX */
2107 SET_FLAG (flag, ZEBRA_FLAG_BLACKHOLE);
2108 break;
2109 default:
2110 vty_out (vty, "%% Malformed flag %s %s", flag_str, VTY_NEWLINE);
2111 return CMD_WARNING;
2112 }
2113 }
2114
d64ff607 2115 if (ifname)
8f527c5e
FL
2116 {
2117 /* When ifname is specified. It must be come with gateway
2118 address. */
2119 if (ret != 1)
e52702f2
QY
2120 {
2121 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
2122 return CMD_WARNING;
2123 }
ba779241 2124 type = STATIC_IPV6_GATEWAY_IFINDEX;
8f527c5e 2125 gate = &gate_addr;
1306c09a 2126 ifp = if_lookup_by_name (ifname, zvrf_id (zvrf));
ba779241 2127 if (!ifp)
e52702f2
QY
2128 {
2129 vty_out (vty, "%% Malformed Interface name %s%s", ifname, VTY_NEWLINE);
2130 return CMD_WARNING;
2131 }
ba779241 2132 ifindex = ifp->ifindex;
8f527c5e
FL
2133 }
2134 else
2135 {
2136 if (ret == 1)
e52702f2
QY
2137 {
2138 type = STATIC_IPV6_GATEWAY;
2139 gate = &gate_addr;
2140 }
8f527c5e 2141 else
e52702f2
QY
2142 {
2143 type = STATIC_IFINDEX;
1306c09a 2144 ifp = if_lookup_by_name (gate_str, zvrf_id (zvrf));
e52702f2
QY
2145 if (!ifp)
2146 {
2147 vty_out (vty, "%% Malformed Interface name %s%s", gate_str, VTY_NEWLINE);
a3d21ef3 2148 ifindex = IFINDEX_DELETED;
e52702f2 2149 }
a3d21ef3 2150 else
e52702f2
QY
2151 ifindex = ifp->ifindex;
2152 ifname = gate_str;
2153 }
9343ce83
DS
2154 }
2155
8f527c5e 2156 if (add_cmd)
c423229b 2157 static_add_route (AFI_IP6, SAFI_UNICAST, type, &p, src_p, (union g_addr *)gate,
e52702f2 2158 ifindex, ifname, flag, tag, distance, zvrf, &snh_label);
8f527c5e 2159 else
c423229b 2160 static_delete_route (AFI_IP6, SAFI_UNICAST, type, &p, src_p, (union g_addr *)gate,
e52702f2 2161 ifindex, tag, distance, zvrf, &snh_label);
8f527c5e 2162
af41b63a 2163 return CMD_SUCCESS;
9343ce83
DS
2164}
2165
8f527c5e
FL
2166DEFUN (ipv6_route,
2167 ipv6_route_cmd,
c423229b 2168 "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
2169 IP_STR
2170 "Establish static routes\n"
2171 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
c423229b
CF
2172 "IPv6 source-dest route\n"
2173 "IPv6 source prefix\n"
8f527c5e
FL
2174 "IPv6 gateway address\n"
2175 "IPv6 gateway interface name\n"
e9e190f2 2176 "Null interface\n"
8f527c5e 2177 "Set tag for this route\n"
96121d19
DS
2178 "Tag value\n"
2179 "Distance value for this prefix\n"
e52702f2 2180 VRF_CMD_HELP_STR
6feb1a21 2181 MPLS_LABEL_HELPSTR)
8f527c5e 2182{
7c022376 2183 int idx_ipv6_prefixlen = 2;
c423229b
CF
2184 int idx_ipv6_ifname;
2185 int idx_curr;
2186 char *src, *tag, *distance, *vrf;
2187
7e045c3d 2188 if (strmatch(argv[3]->text, "from"))
c423229b
CF
2189 {
2190 src = argv[4]->arg;
2191 idx_ipv6_ifname = 5;
2192 idx_curr = 6;
2193 }
2194 else
2195 {
2196 src = NULL;
2197 idx_ipv6_ifname = 3;
2198 idx_curr = 4;
2199 }
af41b63a 2200
96121d19 2201 tag = distance = vrf = NULL;
e52702f2 2202 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
af41b63a 2203
96121d19
DS
2204 return static_ipv6_func (vty, 1,
2205 argv[idx_ipv6_prefixlen]->arg,
c423229b 2206 src,
96121d19
DS
2207 argv[idx_ipv6_ifname]->arg,
2208 NULL, NULL,
e52702f2 2209 tag, distance, vrf, NULL);
8f527c5e 2210}
af41b63a 2211
96121d19
DS
2212DEFUN (ipv6_route_flags,
2213 ipv6_route_flags_cmd,
c423229b 2214 "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
2215 IP_STR
2216 "Establish static routes\n"
2217 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
c423229b
CF
2218 "IPv6 source-dest route\n"
2219 "IPv6 source prefix\n"
8f527c5e
FL
2220 "IPv6 gateway address\n"
2221 "IPv6 gateway interface name\n"
2222 "Emit an ICMP unreachable when matched\n"
2223 "Silently discard pkts when matched\n"
8f527c5e
FL
2224 "Silently discard pkts when matched\n"
2225 "Set tag for this route\n"
2226 "Tag value\n"
96121d19 2227 "Distance value for this prefix\n"
e52702f2 2228 VRF_CMD_HELP_STR
6feb1a21 2229 MPLS_LABEL_HELPSTR)
8f527c5e 2230{
7c022376 2231 int idx_ipv6_prefixlen = 2;
c423229b
CF
2232 int idx_ipv6_ifname;
2233 int idx_reject_blackhole;
2234 int idx_curr;
2235 char *src, *tag, *distance, *vrf;
2236
7e045c3d 2237 if (strmatch(argv[3]->text, "from"))
c423229b
CF
2238 {
2239 src = argv[4]->arg;
2240 idx_ipv6_ifname = 5;
2241 idx_reject_blackhole = 6;
2242 idx_curr = 7;
2243 }
2244 else
2245 {
2246 src = NULL;
2247 idx_ipv6_ifname = 3;
2248 idx_reject_blackhole = 4;
2249 idx_curr = 5;
2250 }
718e3744 2251
96121d19 2252 tag = distance = vrf = NULL;
e52702f2 2253 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
96121d19
DS
2254
2255 return static_ipv6_func (vty, 1,
2256 argv[idx_ipv6_prefixlen]->arg,
c423229b 2257 src,
96121d19
DS
2258 argv[idx_ipv6_ifname]->arg,
2259 NULL,
2260 argv[idx_reject_blackhole]->arg,
e52702f2 2261 tag, distance, vrf, NULL);
8f527c5e 2262}
7021c425 2263
96121d19
DS
2264DEFUN (ipv6_route_ifname,
2265 ipv6_route_ifname_cmd,
c423229b 2266 "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
2267 IP_STR
2268 "Establish static routes\n"
2269 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
c423229b
CF
2270 "IPv6 source-dest route\n"
2271 "IPv6 source prefix\n"
8f527c5e
FL
2272 "IPv6 gateway address\n"
2273 "IPv6 gateway interface name\n"
2274 "Set tag for this route\n"
2275 "Tag value\n"
96121d19 2276 "Distance value for this prefix\n"
e52702f2 2277 VRF_CMD_HELP_STR
6feb1a21 2278 MPLS_LABEL_HELPSTR)
8f527c5e 2279{
7c022376
DW
2280 int idx_ipv6_prefixlen = 2;
2281 int idx_ipv6 = 3;
2282 int idx_interface = 4;
96121d19 2283 int idx_curr = 5;
c423229b
CF
2284 char *src, *tag, *distance, *vrf;
2285
7e045c3d 2286 if (strmatch(argv[3]->text, "from"))
c423229b
CF
2287 {
2288 src = argv[4]->arg;
2289 idx_ipv6 = 5;
2290 idx_interface = 6;
2291 idx_curr = 7;
2292 }
2293 else
2294 {
2295 src = NULL;
2296 idx_ipv6 = 3;
2297 idx_interface = 4;
2298 idx_curr = 5;
2299 }
718e3744 2300
96121d19 2301 tag = distance = vrf = NULL;
e52702f2 2302 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
96121d19
DS
2303
2304 return static_ipv6_func (vty, 1,
2305 argv[idx_ipv6_prefixlen]->arg,
c423229b 2306 src,
96121d19
DS
2307 argv[idx_ipv6]->arg,
2308 argv[idx_interface]->arg,
2309 NULL,
e52702f2 2310 tag, distance, vrf, NULL);
9343ce83
DS
2311}
2312
96121d19
DS
2313DEFUN (ipv6_route_ifname_flags,
2314 ipv6_route_ifname_flags_cmd,
c423229b 2315 "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
2316 IP_STR
2317 "Establish static routes\n"
2318 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
c423229b
CF
2319 "IPv6 source-dest route\n"
2320 "IPv6 source prefix\n"
8f527c5e
FL
2321 "IPv6 gateway address\n"
2322 "IPv6 gateway interface name\n"
2323 "Emit an ICMP unreachable when matched\n"
2324 "Silently discard pkts when matched\n"
2325 "Set tag for this route\n"
2326 "Tag value\n"
96121d19 2327 "Distance value for this prefix\n"
e52702f2 2328 VRF_CMD_HELP_STR
6feb1a21 2329 MPLS_LABEL_HELPSTR)
718e3744 2330{
7c022376 2331 int idx_ipv6_prefixlen = 2;
c423229b
CF
2332 int idx_ipv6;
2333 int idx_interface;
2334 int idx_reject_blackhole;
2335 int idx_curr;
2336 char *src, *tag, *distance, *vrf;
2337
7e045c3d 2338 if (strmatch(argv[3]->text, "from"))
c423229b
CF
2339 {
2340 src = argv[4]->arg;
2341 idx_ipv6 = 5;
2342 idx_interface = 6;
2343 idx_reject_blackhole = 7;
2344 idx_curr = 8;
2345 }
2346 else
2347 {
2348 src = NULL;
2349 idx_ipv6 = 3;
2350 idx_interface = 4;
2351 idx_reject_blackhole = 5;
2352 idx_curr = 6;
2353 }
96121d19
DS
2354
2355 tag = distance = vrf = NULL;
e52702f2 2356 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
96121d19
DS
2357
2358 return static_ipv6_func (vty, 1,
2359 argv[idx_ipv6_prefixlen]->arg,
c423229b 2360 src,
96121d19
DS
2361 argv[idx_ipv6]->arg,
2362 argv[idx_interface]->arg,
2363 argv[idx_reject_blackhole]->arg,
e52702f2 2364 tag, distance, vrf, NULL);
8f527c5e 2365}
7021c425 2366
8f527c5e
FL
2367DEFUN (no_ipv6_route,
2368 no_ipv6_route_cmd,
c423229b 2369 "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 2370 NO_STR
2371 IP_STR
2372 "Establish static routes\n"
2373 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
c423229b
CF
2374 "IPv6 source-dest route\n"
2375 "IPv6 source prefix\n"
81dfcaa2 2376 "IPv6 gateway address\n"
2377 "IPv6 gateway interface name\n"
e9e190f2 2378 "Null interface\n"
0d9551dc 2379 "Set tag for this route\n"
8f527c5e 2380 "Tag value\n"
8f527c5e 2381 "Distance value for this prefix\n"
e52702f2 2382 VRF_CMD_HELP_STR
6feb1a21 2383 MPLS_LABEL_HELPSTR)
718e3744 2384{
7c022376 2385 int idx_ipv6_prefixlen = 3;
c423229b
CF
2386 int idx_ipv6_ifname;
2387 int idx_curr;
2388 char *src, *tag, *distance, *vrf;
2389
7e045c3d 2390 if (strmatch(argv[4]->text, "from"))
c423229b
CF
2391 {
2392 src = argv[5]->arg;
2393 idx_ipv6_ifname = 6;
2394 idx_curr = 7;
2395 }
2396 else
2397 {
2398 src = NULL;
2399 idx_ipv6_ifname = 4;
2400 idx_curr = 5;
2401 }
0d9551dc 2402
28dadafc 2403 tag = distance = vrf = NULL;
e52702f2 2404 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
81dfcaa2 2405
28dadafc
DS
2406 return static_ipv6_func (vty, 0,
2407 argv[idx_ipv6_prefixlen]->arg,
c423229b 2408 src,
28dadafc
DS
2409 argv[idx_ipv6_ifname]->arg,
2410 NULL, NULL,
e52702f2 2411 tag, distance, vrf, NULL);
0d9551dc
DS
2412}
2413
28dadafc
DS
2414DEFUN (no_ipv6_route_flags,
2415 no_ipv6_route_flags_cmd,
c423229b 2416 "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
2417 NO_STR
2418 IP_STR
2419 "Establish static routes\n"
2420 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
c423229b
CF
2421 "IPv6 source-dest route\n"
2422 "IPv6 source prefix\n"
0d9551dc
DS
2423 "IPv6 gateway address\n"
2424 "IPv6 gateway interface name\n"
2425 "Emit an ICMP unreachable when matched\n"
2426 "Silently discard pkts when matched\n"
2427 "Set tag for this route\n"
2428 "Tag value\n"
8f527c5e 2429 "Distance value for this prefix\n"
e52702f2 2430 VRF_CMD_HELP_STR
6feb1a21 2431 MPLS_LABEL_HELPSTR)
0d9551dc 2432{
7c022376 2433 int idx_ipv6_prefixlen = 3;
c423229b
CF
2434 int idx_ipv6_ifname;
2435 int idx_reject_blackhole;
2436 int idx_curr;
2437 char *src, *tag, *distance, *vrf;
2438
7e045c3d 2439 if (strmatch(argv[4]->text, "from"))
c423229b
CF
2440 {
2441 src = argv[5]->arg;
2442 idx_ipv6_ifname = 6;
2443 idx_reject_blackhole = 7;
2444 idx_curr = 8;
2445 }
2446 else
2447 {
2448 src = NULL;
2449 idx_ipv6_ifname = 4;
2450 idx_reject_blackhole = 5;
2451 idx_curr = 6;
2452 }
718e3744 2453
28dadafc 2454 tag = distance = vrf = NULL;
e52702f2 2455 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
28dadafc
DS
2456
2457 return static_ipv6_func (vty, 0,
2458 argv[idx_ipv6_prefixlen]->arg,
c423229b 2459 src,
28dadafc
DS
2460 argv[idx_ipv6_ifname]->arg,
2461 NULL,
2462 argv[idx_reject_blackhole]->arg,
e52702f2 2463 tag, distance, vrf, NULL);
0d9551dc
DS
2464}
2465
28dadafc
DS
2466DEFUN (no_ipv6_route_ifname,
2467 no_ipv6_route_ifname_cmd,
c423229b 2468 "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
2469 NO_STR
2470 IP_STR
2471 "Establish static routes\n"
2472 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
c423229b
CF
2473 "IPv6 source-dest route\n"
2474 "IPv6 source prefix\n"
0d9551dc
DS
2475 "IPv6 gateway address\n"
2476 "IPv6 gateway interface name\n"
2477 "Set tag for this route\n"
2478 "Tag value\n"
8f527c5e 2479 "Distance value for this prefix\n"
e52702f2 2480 VRF_CMD_HELP_STR
6feb1a21 2481 MPLS_LABEL_HELPSTR)
0d9551dc 2482{
7c022376 2483 int idx_ipv6_prefixlen = 3;
c423229b
CF
2484 int idx_ipv6;
2485 int idx_interface;
2486 int idx_curr;
2487 char *src, *tag, *distance, *vrf;
2488
7e045c3d 2489 if (strmatch(argv[4]->text, "from"))
c423229b
CF
2490 {
2491 src = argv[5]->arg;
2492 idx_ipv6 = 6;
2493 idx_interface = 7;
2494 idx_curr = 8;
2495 }
2496 else
2497 {
2498 src = NULL;
2499 idx_ipv6 = 4;
2500 idx_interface = 5;
2501 idx_curr = 6;
2502 }
81dfcaa2 2503
28dadafc 2504 tag = distance = vrf = NULL;
e52702f2 2505 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
28dadafc
DS
2506
2507 return static_ipv6_func (vty, 0,
2508 argv[idx_ipv6_prefixlen]->arg,
c423229b 2509 src,
28dadafc
DS
2510 argv[idx_ipv6]->arg,
2511 argv[idx_interface]->arg,
2512 NULL,
e52702f2 2513 tag, distance, vrf, NULL);
0d9551dc
DS
2514}
2515
28dadafc
DS
2516DEFUN (no_ipv6_route_ifname_flags,
2517 no_ipv6_route_ifname_flags_cmd,
c423229b 2518 "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
2519 NO_STR
2520 IP_STR
2521 "Establish static routes\n"
2522 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
c423229b
CF
2523 "IPv6 source-dest route\n"
2524 "IPv6 source prefix\n"
0d9551dc
DS
2525 "IPv6 gateway address\n"
2526 "IPv6 gateway interface name\n"
2527 "Emit an ICMP unreachable when matched\n"
2528 "Silently discard pkts when matched\n"
2529 "Set tag for this route\n"
2530 "Tag value\n"
8f527c5e 2531 "Distance value for this prefix\n"
e52702f2 2532 VRF_CMD_HELP_STR
6feb1a21 2533 MPLS_LABEL_HELPSTR)
0d9551dc 2534{
7c022376 2535 int idx_ipv6_prefixlen = 3;
c423229b
CF
2536 int idx_ipv6;
2537 int idx_interface;
2538 int idx_reject_blackhole;
2539 int idx_curr;
2540 char *src, *tag, *distance, *vrf;
2541
7e045c3d 2542 if (strmatch(argv[4]->text, "from"))
c423229b
CF
2543 {
2544 src = argv[5]->arg;
2545 idx_ipv6 = 6;
2546 idx_interface = 7;
2547 idx_reject_blackhole = 8;
2548 idx_curr = 9;
2549 }
2550 else
2551 {
2552 src = NULL;
2553 idx_ipv6 = 4;
2554 idx_interface = 5;
2555 idx_reject_blackhole = 6;
2556 idx_curr = 7;
2557 }
28dadafc
DS
2558
2559 tag = distance = vrf = NULL;
e52702f2 2560 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
28dadafc
DS
2561
2562 return static_ipv6_func (vty, 0,
2563 argv[idx_ipv6_prefixlen]->arg,
c423229b 2564 src,
28dadafc
DS
2565 argv[idx_ipv6]->arg,
2566 argv[idx_interface]->arg,
2567 argv[idx_reject_blackhole]->arg,
e52702f2 2568 tag, distance, vrf, NULL);
718e3744 2569}
2570
acb25e73 2571// dwalton duplicate to here
718e3744 2572DEFUN (show_ipv6_route,
2573 show_ipv6_route_cmd,
acb25e73 2574 "show ipv6 <fib|route> [vrf NAME] [tag (1-4294967295)|X:X::X:X/M longer-prefixes|" FRR_IP6_REDIST_STR_ZEBRA "] [json]",
718e3744 2575 SHOW_STR
2576 IP_STR
acb25e73
DW
2577 "IP forwarding table\n"
2578 "IP routing table\n"
b62ecea5 2579 VRF_CMD_HELP_STR
acb25e73
DW
2580 "Show only routes with tag\n"
2581 "Tag value\n"
2582 "IPv6 prefix\n"
2583 "Show route matching the specified Network/Mask pair only\n"
2584 FRR_IP6_REDIST_HELP_STR_ZEBRA
2585 JSON_STR)
718e3744 2586{
acb25e73 2587 bool uf = use_fib(argv[2]);
718e3744 2588 struct route_table *table;
acb25e73
DW
2589 int vrf_all = 0;
2590 route_tag_t tag = 0;
af41b63a 2591 vrf_id_t vrf_id = VRF_DEFAULT;
acb25e73
DW
2592 struct vrf *vrf;
2593 struct zebra_vrf *zvrf;
2594 int uj = use_json(argc, argv);
2595 int idx = 0;
2596 struct prefix p;
2597 bool longer_prefixes = false;
2598 bool supernets_only = false;
2599 int type = 0;
010c141f 2600
acb25e73
DW
2601 if (argv_find (argv, argc, "vrf", &idx))
2602 {
2603 if (strmatch(argv[idx+1]->arg, "all"))
2604 vrf_all = 1;
2605 else
2606 VRF_GET_ID (vrf_id, argv[idx+1]->arg);
2607 }
b62ecea5 2608
acb25e73
DW
2609 if (argv_find (argv, argc, "tag", &idx))
2610 VTY_GET_INTEGER_RANGE("tag", tag, argv[idx+1]->arg, 0, 4294967295);
af41b63a 2611
acb25e73 2612 else if (argv_find (argv, argc, "X:X::X:X/M", &idx))
18a4ded2 2613 {
acb25e73
DW
2614 str2prefix (argv[idx]->arg, &p);
2615 longer_prefixes = true;
18a4ded2
DW
2616 }
2617
acb25e73 2618 else
18a4ded2 2619 {
acb25e73
DW
2620 if (argv_find (argv, argc, "kernel", &idx))
2621 type = proto_redistnum (AFI_IP6, argv[idx]->text);
241a2f56
DS
2622 else if (argv_find (argv, argc, "babel", &idx))
2623 type = proto_redistnum (AFI_IP6, argv[idx]->text);
acb25e73
DW
2624 else if (argv_find (argv, argc, "connected", &idx))
2625 type = proto_redistnum (AFI_IP6, argv[idx]->text);
2626 else if (argv_find (argv, argc, "static", &idx))
2627 type = proto_redistnum (AFI_IP6, argv[idx]->text);
2628 else if (argv_find (argv, argc, "ripng", &idx))
2629 type = proto_redistnum (AFI_IP6, argv[idx]->text);
2630 else if (argv_find (argv, argc, "ospf6", &idx))
2631 type = proto_redistnum (AFI_IP6, argv[idx]->text);
2632 else if (argv_find (argv, argc, "isis", &idx))
2633 type = proto_redistnum (AFI_IP6, argv[idx]->text);
2634 else if (argv_find (argv, argc, "bgp", &idx))
2635 type = proto_redistnum (AFI_IP6, argv[idx]->text);
2636 else if (argv_find (argv, argc, "nhrp", &idx))
2637 type = proto_redistnum (AFI_IP6, argv[idx]->text);
2638 else if (argv_find (argv, argc, "table", &idx))
2639 type = proto_redistnum (AFI_IP6, argv[idx]->text);
2640 else if (argv_find (argv, argc, "vnc", &idx))
2641 type = proto_redistnum (AFI_IP6, argv[idx]->text);
2642
2643 if (type < 0)
2644 {
2645 vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
2646 return CMD_WARNING;
2647 }
2648 }
18a4ded2 2649
acb25e73
DW
2650 if (vrf_all)
2651 {
2652 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
18a4ded2 2653 {
acb25e73
DW
2654 if ((zvrf = vrf->info) == NULL ||
2655 (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
2656 continue;
18a4ded2 2657
acb25e73
DW
2658 do_show_ip_route (vty, zvrf_name (zvrf), AFI_IP6, SAFI_UNICAST, uf, uj, tag,
2659 longer_prefixes ? &p : NULL, supernets_only, type, 0);
18a4ded2 2660 }
18a4ded2
DW
2661 }
2662 else
2663 {
acb25e73
DW
2664 vrf = vrf_lookup_by_id (vrf_id);
2665 do_show_ip_route (vty, vrf->name, AFI_IP6, SAFI_UNICAST, uf, uj, tag,
2666 longer_prefixes ? &p : NULL, supernets_only, type, 0);
18a4ded2 2667 }
718e3744 2668 return CMD_SUCCESS;
2669}
2670
2671DEFUN (show_ipv6_route_addr,
2672 show_ipv6_route_addr_cmd,
9bf96c84 2673 "show ipv6 route [vrf NAME] X:X::X:X",
718e3744 2674 SHOW_STR
2675 IP_STR
2676 "IPv6 routing table\n"
9bf96c84 2677 VRF_CMD_HELP_STR
718e3744 2678 "IPv6 Address\n")
2679{
2680 int ret;
2681 struct prefix_ipv6 p;
2682 struct route_table *table;
2683 struct route_node *rn;
af41b63a 2684 vrf_id_t vrf_id = VRF_DEFAULT;
718e3744 2685
412e5cd9 2686 if (strmatch(argv[3]->text, "vrf"))
d511d7f1 2687 {
9bf96c84
DW
2688 VRF_GET_ID (vrf_id, argv[4]->arg);
2689 ret = str2prefix_ipv6 (argv[5]->arg, &p);
d511d7f1
DS
2690 }
2691 else
9bf96c84
DW
2692 {
2693 ret = str2prefix_ipv6 (argv[3]->arg, &p);
2694 }
d511d7f1 2695
718e3744 2696 if (ret <= 0)
2697 {
2698 vty_out (vty, "Malformed IPv6 address%s", VTY_NEWLINE);
2699 return CMD_WARNING;
2700 }
2701
af41b63a 2702 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
718e3744 2703 if (! table)
2704 return CMD_SUCCESS;
2705
2706 rn = route_node_match (table, (struct prefix *) &p);
2707 if (! rn)
2708 {
2709 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
2710 return CMD_WARNING;
2711 }
2712
196aecef 2713 vty_show_ip_route_detail (vty, rn, 0);
718e3744 2714
2715 route_unlock_node (rn);
2716
2717 return CMD_SUCCESS;
2718}
2719
2720DEFUN (show_ipv6_route_prefix,
2721 show_ipv6_route_prefix_cmd,
9bf96c84 2722 "show ipv6 route [vrf NAME] X:X::X:X/M",
718e3744 2723 SHOW_STR
2724 IP_STR
2725 "IPv6 routing table\n"
9bf96c84 2726 VRF_CMD_HELP_STR
718e3744 2727 "IPv6 prefix\n")
2728{
2729 int ret;
2730 struct prefix_ipv6 p;
2731 struct route_table *table;
2732 struct route_node *rn;
af41b63a 2733 vrf_id_t vrf_id = VRF_DEFAULT;
718e3744 2734
412e5cd9 2735 if (strmatch(argv[3]->text, "vrf"))
d511d7f1 2736 {
9bf96c84
DW
2737 VRF_GET_ID (vrf_id, argv[4]->arg);
2738 ret = str2prefix_ipv6 (argv[5]->arg, &p);
d511d7f1
DS
2739 }
2740 else
9bf96c84 2741 ret = str2prefix_ipv6 (argv[3]->arg, &p);
d511d7f1 2742
718e3744 2743 if (ret <= 0)
2744 {
2745 vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE);
2746 return CMD_WARNING;
2747 }
2748
af41b63a 2749 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
718e3744 2750 if (! table)
2751 return CMD_SUCCESS;
2752
2753 rn = route_node_match (table, (struct prefix *) &p);
2754 if (! rn || rn->p.prefixlen != p.prefixlen)
2755 {
2756 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
2757 return CMD_WARNING;
2758 }
2759
196aecef 2760 vty_show_ip_route_detail (vty, rn, 0);
718e3744 2761
2762 route_unlock_node (rn);
2763
2764 return CMD_SUCCESS;
2765}
2766
af41b63a 2767
61691c91
ST
2768/* Show route summary. */
2769DEFUN (show_ipv6_route_summary,
2770 show_ipv6_route_summary_cmd,
9bf96c84 2771 "show ipv6 route [vrf NAME] summary",
61691c91
ST
2772 SHOW_STR
2773 IP_STR
2774 "IPv6 routing table\n"
9bf96c84 2775 VRF_CMD_HELP_STR
61691c91
ST
2776 "Summary of all IPv6 routes\n")
2777{
2778 struct route_table *table;
af41b63a 2779 vrf_id_t vrf_id = VRF_DEFAULT;
61691c91 2780
412e5cd9 2781 if (strmatch(argv[3]->text, "vrf"))
9bf96c84 2782 VRF_GET_ID (vrf_id, argv[4]->arg);
61691c91 2783
af41b63a 2784 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
61691c91
ST
2785 if (! table)
2786 return CMD_SUCCESS;
2787
2788 vty_show_ip_route_summary (vty, table);
2789
2790 return CMD_SUCCESS;
2791}
2792
af41b63a 2793
9343ce83
DS
2794/* Show ipv6 route summary prefix. */
2795DEFUN (show_ipv6_route_summary_prefix,
2796 show_ipv6_route_summary_prefix_cmd,
9bf96c84 2797 "show ipv6 route [vrf NAME] summary prefix",
9343ce83
DS
2798 SHOW_STR
2799 IP_STR
2800 "IPv6 routing table\n"
9bf96c84 2801 VRF_CMD_HELP_STR
9343ce83
DS
2802 "Summary of all IPv6 routes\n"
2803 "Prefix routes\n")
2804{
2805 struct route_table *table;
af41b63a 2806 vrf_id_t vrf_id = VRF_DEFAULT;
9343ce83 2807
412e5cd9 2808 if (strmatch(argv[3]->text, "vrf"))
9bf96c84 2809 VRF_GET_ID (vrf_id, argv[4]->arg);
9343ce83 2810
af41b63a 2811 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
9343ce83
DS
2812 if (! table)
2813 return CMD_SUCCESS;
2814
2815 vty_show_ip_route_summary_prefix (vty, table);
2816
2817 return CMD_SUCCESS;
2818}
2819
af41b63a 2820
cddf391b
B
2821/*
2822 * Show IPv6 mroute command.Used to dump
2823 * the Multicast routing table.
2824 */
cddf391b
B
2825DEFUN (show_ipv6_mroute,
2826 show_ipv6_mroute_cmd,
9bf96c84 2827 "show ipv6 mroute [vrf NAME]",
cddf391b
B
2828 SHOW_STR
2829 IP_STR
9bf96c84
DW
2830 "IPv6 Multicast routing table\n"
2831 VRF_CMD_HELP_STR)
cddf391b
B
2832{
2833 struct route_table *table;
2834 struct route_node *rn;
f0f77c9a 2835 struct route_entry *re;
cddf391b 2836 int first = 1;
af41b63a
FL
2837 vrf_id_t vrf_id = VRF_DEFAULT;
2838
313605cb 2839 if (argc == 5)
9bf96c84 2840 VRF_GET_ID (vrf_id, argv[4]->arg);
cddf391b 2841
af41b63a 2842 table = zebra_vrf_table (AFI_IP6, SAFI_MULTICAST, vrf_id);
cddf391b
B
2843 if (! table)
2844 return CMD_SUCCESS;
2845
2846 /* Show all IPv6 route. */
05737783 2847 for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
f0f77c9a 2848 RNODE_FOREACH_RE (rn, re)
cddf391b
B
2849 {
2850 if (first)
2851 {
cb32fd69 2852 vty_out (vty, SHOW_ROUTE_V6_HEADER);
cddf391b
B
2853 first = 0;
2854 }
f0f77c9a 2855 vty_show_ip_route (vty, rn, re, NULL);
cddf391b
B
2856 }
2857 return CMD_SUCCESS;
2858}
2859
d511d7f1
DS
2860DEFUN (show_ipv6_route_vrf_all_addr,
2861 show_ipv6_route_vrf_all_addr_cmd,
5bebf568 2862 "show ipv6 route vrf all X:X::X:X",
af41b63a
FL
2863 SHOW_STR
2864 IP_STR
2865 "IPv6 routing table\n"
d511d7f1
DS
2866 VRF_ALL_CMD_HELP_STR
2867 "IPv6 Address\n")
af41b63a 2868{
7c022376 2869 int idx_ipv6 = 5;
af41b63a
FL
2870 int ret;
2871 struct prefix_ipv6 p;
2872 struct route_table *table;
2873 struct route_node *rn;
1a1a7065 2874 struct vrf *vrf;
af41b63a 2875 struct zebra_vrf *zvrf;
af41b63a 2876
7c022376 2877 ret = str2prefix_ipv6 (argv[idx_ipv6]->arg, &p);
af41b63a
FL
2878 if (ret <= 0)
2879 {
2880 vty_out (vty, "Malformed IPv6 address%s", VTY_NEWLINE);
2881 return CMD_WARNING;
2882 }
2883
a62c4901 2884 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
af41b63a 2885 {
1a1a7065 2886 if ((zvrf = vrf->info) == NULL ||
af41b63a
FL
2887 (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
2888 continue;
2889
2890 rn = route_node_match (table, (struct prefix *) &p);
2891 if (! rn)
2892 continue;
2893
196aecef 2894 vty_show_ip_route_detail (vty, rn, 0);
af41b63a
FL
2895
2896 route_unlock_node (rn);
2897 }
2898
2899 return CMD_SUCCESS;
2900}
2901
d511d7f1
DS
2902DEFUN (show_ipv6_route_vrf_all_prefix,
2903 show_ipv6_route_vrf_all_prefix_cmd,
5bebf568 2904 "show ipv6 route vrf all X:X::X:X/M",
af41b63a
FL
2905 SHOW_STR
2906 IP_STR
2907 "IPv6 routing table\n"
d511d7f1
DS
2908 VRF_ALL_CMD_HELP_STR
2909 "IPv6 prefix\n")
af41b63a 2910{
7c022376 2911 int idx_ipv6_prefixlen = 5;
af41b63a
FL
2912 int ret;
2913 struct prefix_ipv6 p;
2914 struct route_table *table;
2915 struct route_node *rn;
1a1a7065 2916 struct vrf *vrf;
af41b63a 2917 struct zebra_vrf *zvrf;
af41b63a 2918
7c022376 2919 ret = str2prefix_ipv6 (argv[idx_ipv6_prefixlen]->arg, &p);
af41b63a
FL
2920 if (ret <= 0)
2921 {
2922 vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE);
2923 return CMD_WARNING;
2924 }
2925
a62c4901 2926 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
af41b63a 2927 {
1a1a7065 2928 if ((zvrf = vrf->info) == NULL ||
af41b63a
FL
2929 (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
2930 continue;
2931
2932 rn = route_node_match (table, (struct prefix *) &p);
2933 if (! rn)
2934 continue;
2935 if (rn->p.prefixlen != p.prefixlen)
2936 {
2937 route_unlock_node (rn);
2938 continue;
2939 }
2940
196aecef 2941 vty_show_ip_route_detail (vty, rn, 0);
af41b63a
FL
2942
2943 route_unlock_node (rn);
2944 }
2945
2946 return CMD_SUCCESS;
2947}
2948
d511d7f1
DS
2949DEFUN (show_ipv6_route_vrf_all_summary,
2950 show_ipv6_route_vrf_all_summary_cmd,
5bebf568 2951 "show ipv6 route vrf all summary",
af41b63a
FL
2952 SHOW_STR
2953 IP_STR
2954 "IPv6 routing table\n"
d511d7f1
DS
2955 VRF_ALL_CMD_HELP_STR
2956 "Summary of all IPv6 routes\n")
af41b63a 2957{
1a1a7065 2958 struct vrf *vrf;
af41b63a 2959 struct zebra_vrf *zvrf;
af41b63a 2960
a62c4901 2961 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
1a1a7065 2962 if ((zvrf = vrf->info) != NULL)
af41b63a
FL
2963 vty_show_ip_route_summary (vty, zvrf->table[AFI_IP6][SAFI_UNICAST]);
2964
2965 return CMD_SUCCESS;
2966}
2967
2968DEFUN (show_ipv6_mroute_vrf_all,
2969 show_ipv6_mroute_vrf_all_cmd,
5bebf568 2970 "show ipv6 mroute vrf all",
af41b63a
FL
2971 SHOW_STR
2972 IP_STR
2973 "IPv6 Multicast routing table\n"
2974 VRF_ALL_CMD_HELP_STR)
2975{
2976 struct route_table *table;
2977 struct route_node *rn;
f0f77c9a 2978 struct route_entry *re;
1a1a7065 2979 struct vrf *vrf;
af41b63a 2980 struct zebra_vrf *zvrf;
af41b63a
FL
2981 int first = 1;
2982
a62c4901 2983 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
af41b63a 2984 {
1a1a7065 2985 if ((zvrf = vrf->info) == NULL ||
10dad424 2986 (table = zvrf->table[AFI_IP6][SAFI_MULTICAST]) == NULL)
af41b63a
FL
2987 continue;
2988
2989 /* Show all IPv6 route. */
05737783 2990 for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
f0f77c9a 2991 RNODE_FOREACH_RE (rn, re)
af41b63a
FL
2992 {
2993 if (first)
2994 {
2995 vty_out (vty, SHOW_ROUTE_V6_HEADER);
2996 first = 0;
2997 }
f0f77c9a 2998 vty_show_ip_route (vty, rn, re, NULL);
af41b63a
FL
2999 }
3000 }
3001 return CMD_SUCCESS;
3002}
3003
d511d7f1
DS
3004DEFUN (show_ipv6_route_vrf_all_summary_prefix,
3005 show_ipv6_route_vrf_all_summary_prefix_cmd,
5bebf568 3006 "show ipv6 route vrf all summary prefix",
af41b63a
FL
3007 SHOW_STR
3008 IP_STR
3009 "IPv6 routing table\n"
d511d7f1 3010 VRF_ALL_CMD_HELP_STR
af41b63a 3011 "Summary of all IPv6 routes\n"
d511d7f1 3012 "Prefix routes\n")
af41b63a 3013{
1a1a7065 3014 struct vrf *vrf;
af41b63a 3015 struct zebra_vrf *zvrf;
af41b63a 3016
a62c4901 3017 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
1a1a7065 3018 if ((zvrf = vrf->info) != NULL)
af41b63a
FL
3019 vty_show_ip_route_summary_prefix (vty, zvrf->table[AFI_IP6][SAFI_UNICAST]);
3020
3021 return CMD_SUCCESS;
3022}
3023
6baf7bb8
DS
3024DEFUN (allow_external_route_update,
3025 allow_external_route_update_cmd,
3026 "allow-external-route-update",
17d990c1 3027 "Allow FRR routes to be overwritten by external processes\n")
6baf7bb8
DS
3028{
3029 allow_delete = 1;
3030
3031 return CMD_SUCCESS;
3032}
3033
3034DEFUN (no_allow_external_route_update,
3035 no_allow_external_route_update_cmd,
3036 "no allow-external-route-update",
17d990c1
DS
3037 NO_STR
3038 "Allow FRR routes to be overwritten by external processes\n")
6baf7bb8
DS
3039{
3040 allow_delete = 0;
3041
3042 return CMD_SUCCESS;
3043}
3044
12f6fb97
DS
3045/* show vrf */
3046DEFUN (show_vrf,
3047 show_vrf_cmd,
3048 "show vrf",
3049 SHOW_STR
3050 "VRF\n")
3051{
51bdc5f8 3052 struct vrf *vrf;
12f6fb97 3053 struct zebra_vrf *zvrf;
12f6fb97 3054
806f8760 3055 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
12f6fb97 3056 {
53dc2b05
DL
3057 if (!(zvrf = vrf->info))
3058 continue;
3059 if (!zvrf_id (zvrf))
12f6fb97
DS
3060 continue;
3061
661512bf
RW
3062 vty_out (vty, "vrf %s ", zvrf_name (zvrf));
3063 if (zvrf_id (zvrf) == VRF_UNKNOWN)
825649bd 3064 vty_out (vty, "inactive");
3065 else
661512bf 3066 vty_out (vty, "id %u table %u", zvrf_id (zvrf), zvrf->table_id);
825649bd 3067 vty_out (vty, "%s", VTY_NEWLINE);
12f6fb97
DS
3068
3069 }
3070
3071 return CMD_SUCCESS;
3072}
3073
718e3744 3074/* Static ip route configuration write function. */
a1ac18c4 3075static int
718e3744 3076zebra_ip_config (struct vty *vty)
3077{
3078 int write = 0;
3079
9de498ec
DS
3080 write += static_config (vty, AFI_IP, SAFI_UNICAST, "ip route");
3081 write += static_config (vty, AFI_IP, SAFI_MULTICAST, "ip mroute");
3082 write += static_config (vty, AFI_IP6, SAFI_UNICAST, "ipv6 route");
718e3744 3083
7a4bb9c5 3084 write += zebra_import_table_config (vty);
718e3744 3085 return write;
3086}
3087
7a4bb9c5
DS
3088DEFUN (ip_zebra_import_table_distance,
3089 ip_zebra_import_table_distance_cmd,
12dcf78e 3090 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
8902474b
DS
3091 IP_STR
3092 "import routes from non-main kernel table\n"
3093 "kernel routing table id\n"
3094 "Distance for imported routes\n"
3095 "Default distance value\n"
3096 "route-map for filtering\n"
3097 "route-map name\n")
3098{
3099 u_int32_t table_id = 0;
8902474b 3100
b62ecea5
QY
3101 VTY_GET_INTEGER("table", table_id, argv[2]->arg);
3102 int distance = ZEBRA_TABLE_DISTANCE_DEFAULT;
3103 char *rmap = strmatch (argv[argc - 2]->text, "route-map") ?
3104 XSTRDUP(MTYPE_ROUTE_MAP_NAME, argv[argc - 1]->arg) : NULL;
d722f26e
DS
3105 int ret;
3106
b62ecea5
QY
3107 if (argc == 7 || (argc == 5 && !rmap))
3108 VTY_GET_INTEGER_RANGE("distance", distance, argv[4]->arg, 1, 255);
8902474b
DS
3109
3110 if (!is_zebra_valid_kernel_table(table_id))
3111 {
3112 vty_out(vty, "Invalid routing table ID, %d. Must be in range 1-252%s",
3113 table_id, VTY_NEWLINE);
3114 return CMD_WARNING;
3115 }
3116
3117 if (is_zebra_main_routing_table(table_id))
3118 {
3119 vty_out(vty, "Invalid routing table ID, %d. Must be non-default table%s",
b62ecea5 3120 table_id, VTY_NEWLINE);
8902474b
DS
3121 return CMD_WARNING;
3122 }
3123
d722f26e
DS
3124 ret = zebra_import_table(AFI_IP, table_id, distance, rmap, 1);
3125 if (rmap)
3126 XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
3127
3128 return ret;
8902474b
DS
3129}
3130
7a4bb9c5
DS
3131DEFUN (no_ip_zebra_import_table,
3132 no_ip_zebra_import_table_cmd,
b62ecea5 3133 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
7a4bb9c5
DS
3134 NO_STR
3135 IP_STR
3136 "import routes from non-main kernel table\n"
3a2d747c
QY
3137 "kernel routing table id\n"
3138 "Distance for imported routes\n"
3139 "Default distance value\n"
3140 "route-map for filtering\n"
3141 "route-map name\n")
7a4bb9c5
DS
3142{
3143 u_int32_t table_id = 0;
b62ecea5 3144 VTY_GET_INTEGER("table", table_id, argv[3]->arg);
7a4bb9c5
DS
3145
3146 if (!is_zebra_valid_kernel_table(table_id))
3147 {
3148 vty_out(vty, "Invalid routing table ID. Must be in range 1-252%s",
3149 VTY_NEWLINE);
3150 return CMD_WARNING;
3151 }
3152
3153 if (is_zebra_main_routing_table(table_id))
3154 {
3155 vty_out(vty, "Invalid routing table ID, %d. Must be non-default table%s",
3156 table_id, VTY_NEWLINE);
3157 return CMD_WARNING;
3158 }
3159
3160 if (!is_zebra_import_table_enabled(AFI_IP, table_id))
3161 return CMD_SUCCESS;
3162
8902474b 3163 return (zebra_import_table(AFI_IP, table_id, 0, NULL, 0));
7a4bb9c5
DS
3164}
3165
6baf7bb8
DS
3166static int
3167config_write_protocol (struct vty *vty)
3168{
3169 if (allow_delete)
3170 vty_out(vty, "allow-external-route-update%s", VTY_NEWLINE);
3171
3172 if (zebra_rnh_ip_default_route)
3173 vty_out(vty, "ip nht resolve-via-default%s", VTY_NEWLINE);
3174
3175 if (zebra_rnh_ipv6_default_route)
3176 vty_out(vty, "ipv6 nht resolve-via-default%s", VTY_NEWLINE);
3177
4623d897
DL
3178 enum multicast_mode ipv4_multicast_mode = multicast_mode_ipv4_get ();
3179
3180 if (ipv4_multicast_mode != MCAST_NO_CONFIG)
3181 vty_out (vty, "ip multicast rpf-lookup-mode %s%s",
3182 ipv4_multicast_mode == MCAST_URIB_ONLY ? "urib-only" :
3183 ipv4_multicast_mode == MCAST_MRIB_ONLY ? "mrib-only" :
3184 ipv4_multicast_mode == MCAST_MIX_MRIB_FIRST ? "mrib-then-urib" :
3185 ipv4_multicast_mode == MCAST_MIX_DISTANCE ? "lower-distance" :
3186 "longer-prefix",
3187 VTY_NEWLINE);
3188
6baf7bb8
DS
3189 zebra_routemap_config_write_protocol(vty);
3190
3191 return 1;
3192}
3193
718e3744 3194/* IP node for static routes. */
7fc626de 3195static struct cmd_node ip_node = { IP_NODE, "", 1 };
6baf7bb8 3196static struct cmd_node protocol_node = { PROTOCOL_NODE, "", 1 };
718e3744 3197
3198/* Route VTY. */
3199void
a1ac18c4 3200zebra_vty_init (void)
718e3744 3201{
3202 install_node (&ip_node, zebra_ip_config);
6baf7bb8 3203 install_node (&protocol_node, config_write_protocol);
718e3744 3204
6baf7bb8
DS
3205 install_element (CONFIG_NODE, &allow_external_route_update_cmd);
3206 install_element (CONFIG_NODE, &no_allow_external_route_update_cmd);
b8a96915 3207 install_element (CONFIG_NODE, &ip_mroute_dist_cmd);
b8a96915 3208 install_element (CONFIG_NODE, &no_ip_mroute_dist_cmd);
4623d897
DL
3209 install_element (CONFIG_NODE, &ip_multicast_mode_cmd);
3210 install_element (CONFIG_NODE, &no_ip_multicast_mode_cmd);
718e3744 3211 install_element (CONFIG_NODE, &ip_route_cmd);
81dfcaa2 3212 install_element (CONFIG_NODE, &ip_route_flags_cmd);
718e3744 3213 install_element (CONFIG_NODE, &ip_route_mask_cmd);
81dfcaa2 3214 install_element (CONFIG_NODE, &ip_route_mask_flags_cmd);
718e3744 3215 install_element (CONFIG_NODE, &no_ip_route_cmd);
3216 install_element (CONFIG_NODE, &no_ip_route_mask_cmd);
7a4bb9c5
DS
3217 install_element (CONFIG_NODE, &ip_zebra_import_table_distance_cmd);
3218 install_element (CONFIG_NODE, &no_ip_zebra_import_table_cmd);
718e3744 3219
12f6fb97 3220 install_element (VIEW_NODE, &show_vrf_cmd);
718e3744 3221 install_element (VIEW_NODE, &show_ip_route_cmd);
fb018d25 3222 install_element (VIEW_NODE, &show_ip_nht_cmd);
d511d7f1 3223 install_element (VIEW_NODE, &show_ip_nht_vrf_all_cmd);
fb018d25 3224 install_element (VIEW_NODE, &show_ipv6_nht_cmd);
d511d7f1 3225 install_element (VIEW_NODE, &show_ipv6_nht_vrf_all_cmd);
718e3744 3226 install_element (VIEW_NODE, &show_ip_route_addr_cmd);
3227 install_element (VIEW_NODE, &show_ip_route_prefix_cmd);
61691c91 3228 install_element (VIEW_NODE, &show_ip_route_summary_cmd);
9343ce83 3229 install_element (VIEW_NODE, &show_ip_route_summary_prefix_cmd);
718e3744 3230
b78a80d7 3231 install_element (VIEW_NODE, &show_ip_rpf_cmd);
65dd94cf 3232 install_element (VIEW_NODE, &show_ip_rpf_addr_cmd);
cddf391b 3233
af41b63a
FL
3234 /* Commands for VRF */
3235
fb5b479d
DS
3236 install_element (CONFIG_NODE, &no_ip_route_flags_cmd);
3237 install_element (CONFIG_NODE, &no_ip_route_mask_flags_cmd);
8f527c5e 3238
d511d7f1
DS
3239 install_element (VIEW_NODE, &show_ip_route_vrf_all_addr_cmd);
3240 install_element (VIEW_NODE, &show_ip_route_vrf_all_prefix_cmd);
d511d7f1
DS
3241 install_element (VIEW_NODE, &show_ip_route_vrf_all_summary_cmd);
3242 install_element (VIEW_NODE, &show_ip_route_vrf_all_summary_prefix_cmd);
af41b63a 3243
718e3744 3244 install_element (CONFIG_NODE, &ipv6_route_cmd);
81dfcaa2 3245 install_element (CONFIG_NODE, &ipv6_route_flags_cmd);
718e3744 3246 install_element (CONFIG_NODE, &ipv6_route_ifname_cmd);
81dfcaa2 3247 install_element (CONFIG_NODE, &ipv6_route_ifname_flags_cmd);
718e3744 3248 install_element (CONFIG_NODE, &no_ipv6_route_cmd);
81dfcaa2 3249 install_element (CONFIG_NODE, &no_ipv6_route_flags_cmd);
718e3744 3250 install_element (CONFIG_NODE, &no_ipv6_route_ifname_cmd);
81dfcaa2 3251 install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_cmd);
a50b580a
DS
3252 install_element (CONFIG_NODE, &ip_nht_default_route_cmd);
3253 install_element (CONFIG_NODE, &no_ip_nht_default_route_cmd);
3254 install_element (CONFIG_NODE, &ipv6_nht_default_route_cmd);
3255 install_element (CONFIG_NODE, &no_ipv6_nht_default_route_cmd);
718e3744 3256 install_element (VIEW_NODE, &show_ipv6_route_cmd);
61691c91 3257 install_element (VIEW_NODE, &show_ipv6_route_summary_cmd);
9343ce83 3258 install_element (VIEW_NODE, &show_ipv6_route_summary_prefix_cmd);
718e3744 3259 install_element (VIEW_NODE, &show_ipv6_route_addr_cmd);
3260 install_element (VIEW_NODE, &show_ipv6_route_prefix_cmd);
cddf391b 3261 install_element (VIEW_NODE, &show_ipv6_mroute_cmd);
af41b63a
FL
3262
3263 /* Commands for VRF */
d511d7f1
DS
3264 install_element (VIEW_NODE, &show_ipv6_route_vrf_all_summary_cmd);
3265 install_element (VIEW_NODE, &show_ipv6_route_vrf_all_summary_prefix_cmd);
d511d7f1
DS
3266 install_element (VIEW_NODE, &show_ipv6_route_vrf_all_addr_cmd);
3267 install_element (VIEW_NODE, &show_ipv6_route_vrf_all_prefix_cmd);
af41b63a 3268
af41b63a 3269 install_element (VIEW_NODE, &show_ipv6_mroute_vrf_all_cmd);
718e3744 3270}