]> git.proxmox.com Git - mirror_frr.git/blob - zebra/zebra_vty.c
*: Switchover to 3.0
[mirror_frr.git] / zebra / zebra_vty.c
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 *
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING. If not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
20 */
21
22 #include <zebra.h>
23
24 #include "memory.h"
25 #include "zebra_memory.h"
26 #include "if.h"
27 #include "prefix.h"
28 #include "command.h"
29 #include "table.h"
30 #include "rib.h"
31 #include "nexthop.h"
32 #include "vrf.h"
33 #include "mpls.h"
34 #include "routemap.h"
35 #include "srcdest_table.h"
36
37 #include "zebra/zserv.h"
38 #include "zebra/zebra_vrf.h"
39 #include "zebra/zebra_mpls.h"
40 #include "zebra/zebra_rnh.h"
41 #include "zebra/redistribute.h"
42 #include "zebra/zebra_routemap.h"
43 #include "zebra/zebra_static.h"
44 #include "lib/json.h"
45
46 extern int allow_delete;
47
48 static int do_show_ip_route(struct vty *vty, const char *vrf_name,
49 safi_t safi, u_char use_json);
50 static void vty_show_ip_route_detail (struct vty *vty, struct route_node *rn,
51 int mcast);
52
53 #define ONE_DAY_SECOND 60*60*24
54 #define ONE_WEEK_SECOND 60*60*24*7
55
56 /* General function for static route. */
57 int
58 zebra_static_ipv4 (struct vty *vty, safi_t safi, int add_cmd,
59 const char *dest_str, const char *mask_str,
60 const char *gate_str, const char *flag_str,
61 const char *tag_str, const char *distance_str,
62 const char *vrf_id_str, const char *label_str)
63 {
64 int ret;
65 u_char distance;
66 struct prefix p;
67 struct in_addr gate;
68 struct in_addr mask;
69 u_char flag = 0;
70 route_tag_t tag = 0;
71 struct zebra_vrf *zvrf = NULL;
72 unsigned int ifindex = 0;
73 const char *ifname = NULL;
74 u_char type = STATIC_BLACKHOLE;
75 struct static_nh_label snh_label;
76
77 memset (&snh_label, 0, sizeof (struct static_nh_label));
78 ret = str2prefix (dest_str, &p);
79 if (ret <= 0)
80 {
81 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
82 return CMD_WARNING;
83 }
84
85 /* Cisco like mask notation. */
86 if (mask_str)
87 {
88 ret = inet_aton (mask_str, &mask);
89 if (ret == 0)
90 {
91 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
92 return CMD_WARNING;
93 }
94 p.prefixlen = ip_masklen (mask);
95 }
96
97 /* Apply mask for given prefix. */
98 apply_mask (&p);
99
100 /* Administrative distance. */
101 if (distance_str)
102 distance = atoi (distance_str);
103 else
104 distance = ZEBRA_STATIC_DISTANCE_DEFAULT;
105
106 /* tag */
107 if (tag_str)
108 VTY_GET_INTEGER_RANGE("tag", tag, tag_str, 0, 4294967295);
109
110 /* VRF id */
111 zvrf = zebra_vrf_lookup_by_name (vrf_id_str);
112
113 if (!zvrf)
114 {
115 vty_out (vty, "%% vrf %s is not defined%s", vrf_id_str, VTY_NEWLINE);
116 return CMD_WARNING;
117 }
118
119 /* Labels */
120 if (label_str)
121 {
122 if (!mpls_enabled)
123 {
124 vty_out (vty, "%% MPLS not turned on in kernel, ignoring command%s",
125 VTY_NEWLINE);
126 return CMD_WARNING;
127 }
128 if (mpls_str2label (label_str, &snh_label.num_labels,
129 snh_label.label))
130 {
131 vty_out (vty, "%% Malformed label(s)%s", VTY_NEWLINE);
132 return CMD_WARNING;
133 }
134 }
135
136 /* Null0 static route. */
137 if ((gate_str != NULL) && (strncasecmp (gate_str, "Null0", strlen (gate_str)) == 0))
138 {
139 if (flag_str)
140 {
141 vty_out (vty, "%% can not have flag %s with Null0%s", flag_str, VTY_NEWLINE);
142 return CMD_WARNING;
143 }
144 if (add_cmd)
145 static_add_route (AFI_IP, safi, type, &p, NULL, NULL, ifindex, ifname,
146 ZEBRA_FLAG_BLACKHOLE, tag, distance, zvrf, &snh_label);
147 else
148 static_delete_route (AFI_IP, safi, type, &p, NULL, NULL, ifindex, tag,
149 distance, zvrf, &snh_label);
150 return CMD_SUCCESS;
151 }
152
153 /* Route flags */
154 if (flag_str) {
155 switch(flag_str[0]) {
156 case 'r':
157 case 'R': /* XXX */
158 SET_FLAG (flag, ZEBRA_FLAG_REJECT);
159 break;
160 case 'b':
161 case 'B': /* XXX */
162 SET_FLAG (flag, ZEBRA_FLAG_BLACKHOLE);
163 break;
164 default:
165 vty_out (vty, "%% Malformed flag %s %s", flag_str, VTY_NEWLINE);
166 return CMD_WARNING;
167 }
168 }
169
170 if (gate_str == NULL)
171 {
172 if (add_cmd)
173 static_add_route (AFI_IP, safi, type, &p, NULL, NULL, ifindex, ifname, flag,
174 tag, distance, zvrf, &snh_label);
175 else
176 static_delete_route (AFI_IP, safi, type, &p, NULL, NULL, ifindex, tag, distance,
177 zvrf, &snh_label);
178
179 return CMD_SUCCESS;
180 }
181
182 /* When gateway is A.B.C.D format, gate is treated as nexthop
183 address other case gate is treated as interface name. */
184 ret = inet_aton (gate_str, &gate);
185 if (!ret)
186 {
187 struct interface *ifp = if_lookup_by_name (gate_str, zvrf_id (zvrf));
188 if (!ifp)
189 {
190 vty_out (vty, "%% Unknown interface: %s%s", gate_str, VTY_NEWLINE);
191 ifindex = IFINDEX_DELETED;
192 }
193 else
194 ifindex = ifp->ifindex;
195 ifname = gate_str;
196 type = STATIC_IFINDEX;
197 }
198 else
199 type = STATIC_IPV4_GATEWAY;
200
201 if (add_cmd)
202 static_add_route (AFI_IP, safi, type, &p, NULL,
203 ifindex ? NULL : (union g_addr *)&gate, ifindex, ifname,
204 flag, tag, distance, zvrf, &snh_label);
205 else
206 static_delete_route (AFI_IP, safi, type, &p, NULL,
207 ifindex ? NULL : (union g_addr *)&gate, ifindex, tag,
208 distance, zvrf, &snh_label);
209
210 return CMD_SUCCESS;
211 }
212
213 /* Static unicast routes for multicast RPF lookup. */
214 DEFUN (ip_mroute_dist,
215 ip_mroute_dist_cmd,
216 "ip mroute A.B.C.D/M <A.B.C.D|INTERFACE> [(1-255)]",
217 IP_STR
218 "Configure static unicast route into MRIB for multicast RPF lookup\n"
219 "IP destination prefix (e.g. 10.0.0.0/8)\n"
220 "Nexthop address\n"
221 "Nexthop interface name\n"
222 "Distance\n")
223 {
224 char *destprefix = argv[2]->arg;
225 char *nexthop = argv[3]->arg;
226 char *distance = (argc == 5) ? argv[4]->arg : NULL;
227
228 return zebra_static_ipv4 (vty, SAFI_MULTICAST, 1, destprefix, NULL, nexthop, NULL, NULL, distance, NULL, NULL);
229 }
230
231 DEFUN (no_ip_mroute_dist,
232 no_ip_mroute_dist_cmd,
233 "no ip mroute A.B.C.D/M <A.B.C.D|INTERFACE> [(1-255)]",
234 NO_STR
235 IP_STR
236 "Configure static unicast route into MRIB for multicast RPF lookup\n"
237 "IP destination prefix (e.g. 10.0.0.0/8)\n"
238 "Nexthop address\n"
239 "Nexthop interface name\n"
240 "Distance\n")
241 {
242 char *destprefix = argv[3]->arg;
243 char *nexthop = argv[4]->arg;
244 char *distance = (argc == 6) ? argv[5]->arg : NULL;
245
246 return zebra_static_ipv4 (vty, SAFI_MULTICAST, 0, destprefix, NULL, nexthop, NULL, NULL, distance, NULL, NULL);
247 }
248
249 DEFUN (ip_multicast_mode,
250 ip_multicast_mode_cmd,
251 "ip multicast rpf-lookup-mode <urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>",
252 IP_STR
253 "Multicast options\n"
254 "RPF lookup behavior\n"
255 "Lookup in unicast RIB only\n"
256 "Lookup in multicast RIB only\n"
257 "Try multicast RIB first, fall back to unicast RIB\n"
258 "Lookup both, use entry with lower distance\n"
259 "Lookup both, use entry with longer prefix\n")
260 {
261 char *mode = argv[3]->text;
262
263 if (strmatch (mode, "urib-only"))
264 multicast_mode_ipv4_set (MCAST_URIB_ONLY);
265 else if (strmatch (mode, "mrib-only"))
266 multicast_mode_ipv4_set (MCAST_MRIB_ONLY);
267 else if (strmatch (mode, "mrib-then-urib"))
268 multicast_mode_ipv4_set (MCAST_MIX_MRIB_FIRST);
269 else if (strmatch (mode, "lower-distance"))
270 multicast_mode_ipv4_set (MCAST_MIX_DISTANCE);
271 else if (strmatch (mode, "longer-prefix"))
272 multicast_mode_ipv4_set (MCAST_MIX_PFXLEN);
273 else
274 {
275 vty_out (vty, "Invalid mode specified%s", VTY_NEWLINE);
276 return CMD_WARNING;
277 }
278
279 return CMD_SUCCESS;
280 }
281
282 DEFUN (no_ip_multicast_mode,
283 no_ip_multicast_mode_cmd,
284 "no ip multicast rpf-lookup-mode [<urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>]",
285 NO_STR
286 IP_STR
287 "Multicast options\n"
288 "RPF lookup behavior\n"
289 "Lookup in unicast RIB only\n"
290 "Lookup in multicast RIB only\n"
291 "Try multicast RIB first, fall back to unicast RIB\n"
292 "Lookup both, use entry with lower distance\n"
293 "Lookup both, use entry with longer prefix\n")
294 {
295 multicast_mode_ipv4_set (MCAST_NO_CONFIG);
296 return CMD_SUCCESS;
297 }
298
299
300 DEFUN (show_ip_rpf,
301 show_ip_rpf_cmd,
302 "show ip rpf",
303 SHOW_STR
304 IP_STR
305 "Display RPF information for multicast source\n")
306 {
307 return do_show_ip_route(vty, VRF_DEFAULT_NAME, SAFI_MULTICAST, 0);
308 }
309
310 DEFUN (show_ip_rpf_addr,
311 show_ip_rpf_addr_cmd,
312 "show ip rpf A.B.C.D",
313 SHOW_STR
314 IP_STR
315 "Display RPF information for multicast source\n"
316 "IP multicast source address (e.g. 10.0.0.0)\n")
317 {
318 int idx_ipv4 = 3;
319 struct in_addr addr;
320 struct route_node *rn;
321 struct rib *rib;
322 int ret;
323
324 ret = inet_aton (argv[idx_ipv4]->arg, &addr);
325 if (ret == 0)
326 {
327 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
328 return CMD_WARNING;
329 }
330
331 rib = rib_match_ipv4_multicast (VRF_DEFAULT, addr, &rn);
332
333 if (rib)
334 vty_show_ip_route_detail (vty, rn, 1);
335 else
336 vty_out (vty, "%% No match for RPF lookup%s", VTY_NEWLINE);
337
338 return CMD_SUCCESS;
339 }
340
341 static void
342 zebra_vty_ip_route_tdv_helper (int argc, struct cmd_token *argv[],
343 int idx_curr, char **tag,
344 char **distance, char **vrf, char **labels)
345 {
346 *distance = NULL;
347 while (idx_curr < argc)
348 {
349 if (strmatch (argv[idx_curr]->text, "tag"))
350 {
351 if (tag)
352 *tag = argv[idx_curr+1]->arg;
353 idx_curr += 2;
354 }
355 else if (strmatch (argv[idx_curr]->text, "vrf"))
356 {
357 if (vrf)
358 *vrf = argv[idx_curr+1]->arg;
359 idx_curr += 2;
360 }
361 else if (strmatch (argv[idx_curr]->text, "label"))
362 {
363 if (labels)
364 *labels = argv[idx_curr+1]->arg;
365 idx_curr += 2;
366 }
367 else
368 {
369 if (distance)
370 *distance = argv[idx_curr]->arg;
371 idx_curr++;
372 }
373 }
374
375 return;
376 }
377
378 /* Static route configuration. */
379 DEFUN (ip_route,
380 ip_route_cmd,
381 "ip route A.B.C.D/M <A.B.C.D|INTERFACE|null0> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
382 IP_STR
383 "Establish static routes\n"
384 "IP destination prefix (e.g. 10.0.0.0/8)\n"
385 "IP gateway address\n"
386 "IP gateway interface name\n"
387 "Null interface\n"
388 "Set tag for this route\n"
389 "Tag value\n"
390 "Distance value for this route\n"
391 VRF_CMD_HELP_STR)
392 {
393 int idx_ipv4_prefixlen = 2;
394 int idx_ipv4_ifname_null = 3;
395 int idx_curr = 4;
396 char *tag, *distance, *vrf;
397
398 tag = distance = vrf = NULL;
399 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
400
401 return zebra_static_ipv4 (vty, SAFI_UNICAST, 1,
402 argv[idx_ipv4_prefixlen]->arg,
403 NULL,
404 argv[idx_ipv4_ifname_null]->arg,
405 NULL,
406 tag, distance, vrf, NULL);
407 }
408
409 DEFUN (ip_route_flags,
410 ip_route_flags_cmd,
411 "ip route A.B.C.D/M <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
412 IP_STR
413 "Establish static routes\n"
414 "IP destination prefix (e.g. 10.0.0.0/8)\n"
415 "Emit an ICMP unreachable when matched\n"
416 "Silently discard pkts when matched\n"
417 "Set tag for this route\n"
418 "Tag value\n"
419 "Distance value for this route\n"
420 VRF_CMD_HELP_STR
421 "Specify labels for this route\n"
422 "One or more labels separated by '/'\n")
423 {
424 int idx_ipv4_prefixlen = 2;
425 int idx_reject_blackhole = 3;
426 int idx_curr = 4;
427 char *tag, *distance, *vrf;
428
429 tag = distance = vrf = NULL;
430 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
431
432 return zebra_static_ipv4 (vty, SAFI_UNICAST, 1,
433 argv[idx_ipv4_prefixlen]->arg,
434 NULL,
435 NULL,
436 argv[idx_reject_blackhole]->arg,
437 tag, distance, vrf, NULL);
438 }
439
440 /* Mask as A.B.C.D format. */
441 DEFUN (ip_route_mask,
442 ip_route_mask_cmd,
443 "ip route A.B.C.D A.B.C.D <A.B.C.D|INTERFACE|null0> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
444 IP_STR
445 "Establish static routes\n"
446 "IP destination prefix\n"
447 "IP destination prefix mask\n"
448 "IP gateway address\n"
449 "IP gateway interface name\n"
450 "Null interface\n"
451 "Set tag for this route\n"
452 "Tag value\n"
453 "Distance value for this route\n"
454 VRF_CMD_HELP_STR
455 "Specify labels for this route\n"
456 "One or more labels separated by '/'\n")
457 {
458 int idx_ipv4 = 2;
459 int idx_ipv4_2 = 3;
460 int idx_ipv4_ifname_null = 4;
461 int idx_curr = 5;
462 char *tag, *distance, *vrf;
463
464 tag = distance = vrf = NULL;
465 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
466
467 return zebra_static_ipv4 (vty, SAFI_UNICAST, 1,
468 argv[idx_ipv4]->arg,
469 argv[idx_ipv4_2]->arg,
470 argv[idx_ipv4_ifname_null]->arg,
471 NULL, tag, distance, vrf, NULL);
472 }
473
474 DEFUN (ip_route_mask_flags,
475 ip_route_mask_flags_cmd,
476 "ip route A.B.C.D A.B.C.D <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
477 IP_STR
478 "Establish static routes\n"
479 "IP destination prefix\n"
480 "IP destination prefix mask\n"
481 "Emit an ICMP unreachable when matched\n"
482 "Silently discard pkts when matched\n"
483 "Set tag for this route\n"
484 "Tag value\n"
485 "Distance value for this route\n"
486 VRF_CMD_HELP_STR
487 "Specify labels for this route\n"
488 "One or more labels separated by '/'\n")
489 {
490 int idx_ipv4 = 2;
491 int idx_ipv4_2 = 3;
492 int idx_reject_blackhole = 4;
493 int idx_curr = 5;
494 char *tag, *distance, *vrf;
495
496 tag = distance = vrf = NULL;
497 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
498
499 return zebra_static_ipv4 (vty, SAFI_UNICAST, 1,
500 argv[idx_ipv4]->arg,
501 argv[idx_ipv4_2]->arg,
502 NULL,
503 argv[idx_reject_blackhole]->arg,
504 tag, distance, vrf, NULL);
505 }
506
507 DEFUN (no_ip_route,
508 no_ip_route_cmd,
509 "no ip route A.B.C.D/M <A.B.C.D|INTERFACE|null0> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
510 NO_STR
511 IP_STR
512 "Establish static routes\n"
513 "IP destination prefix (e.g. 10.0.0.0/8)\n"
514 "IP gateway address\n"
515 "IP gateway interface name\n"
516 "Null interface\n"
517 "Tag of this route\n"
518 "Tag value\n"
519 "Distance value for this route\n"
520 VRF_CMD_HELP_STR
521 "Specify labels for this route\n"
522 "One or more labels separated by '/'\n")
523 {
524 int idx_ipv4_prefixlen = 3;
525 int idx_ipv4_ifname_null = 4;
526 int idx_curr = 5;
527 char *tag, *distance, *vrf;
528
529 tag = distance = vrf = NULL;
530 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
531
532 return zebra_static_ipv4 (vty, SAFI_UNICAST, 0,
533 argv[idx_ipv4_prefixlen]->arg,
534 NULL,
535 argv[idx_ipv4_ifname_null]->arg,
536 NULL,
537 tag, distance, vrf, NULL);
538 }
539
540 DEFUN (no_ip_route_flags,
541 no_ip_route_flags_cmd,
542 "no ip route A.B.C.D/M <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
543 NO_STR
544 IP_STR
545 "Establish static routes\n"
546 "IP destination prefix (e.g. 10.0.0.0/8)\n"
547 "Emit an ICMP unreachable when matched\n"
548 "Silently discard pkts when matched\n"
549 "Tag of this route\n"
550 "Tag value\n"
551 "Distance value for this route\n"
552 VRF_CMD_HELP_STR
553 "Specify labels for this route\n"
554 "One or more labels separated by '/'\n")
555 {
556 int idx_ipv4_prefixlen = 3;
557 int idx_curr = 5;
558 char *tag, *distance, *vrf;
559
560 tag = distance = vrf = NULL;
561 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
562
563 return zebra_static_ipv4 (vty, SAFI_UNICAST, 0,
564 argv[idx_ipv4_prefixlen]->arg,
565 NULL, NULL, NULL,
566 tag, distance, vrf, NULL);
567 }
568
569 DEFUN (no_ip_route_mask,
570 no_ip_route_mask_cmd,
571 "no ip route A.B.C.D A.B.C.D <A.B.C.D|INTERFACE|null0> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
572 NO_STR
573 IP_STR
574 "Establish static routes\n"
575 "IP destination prefix\n"
576 "IP destination prefix mask\n"
577 "IP gateway address\n"
578 "IP gateway interface name\n"
579 "Null interface\n"
580 "Tag of this route\n"
581 "Tag value\n"
582 "Distance value for this route\n"
583 VRF_CMD_HELP_STR
584 "Specify labels for this route\n"
585 "One or more labels separated by '/'\n")
586 {
587 int idx_ipv4 = 3;
588 int idx_ipv4_2 = 4;
589 int idx_ipv4_ifname_null = 5;
590 int idx_curr = 6;
591 char *tag, *distance, *vrf;
592
593 tag = distance = vrf = NULL;
594 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
595
596 return zebra_static_ipv4 (vty, SAFI_UNICAST, 0,
597 argv[idx_ipv4]->arg,
598 argv[idx_ipv4_2]->arg,
599 argv[idx_ipv4_ifname_null]->arg,
600 NULL,
601 tag, distance, vrf, NULL);
602 }
603
604 DEFUN (no_ip_route_mask_flags,
605 no_ip_route_mask_flags_cmd,
606 "no ip route A.B.C.D A.B.C.D <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
607 NO_STR
608 IP_STR
609 "Establish static routes\n"
610 "IP destination prefix\n"
611 "IP destination prefix mask\n"
612 "Emit an ICMP unreachable when matched\n"
613 "Silently discard pkts when matched\n"
614 "Tag of this route\n"
615 "Tag value\n"
616 "Distance value for this route\n"
617 VRF_CMD_HELP_STR
618 "Specify labels for this route\n"
619 "One or more labels separated by '/'\n")
620 {
621 int idx_ipv4 = 3;
622 int idx_ipv4_2 = 4;
623 int idx_curr = 6;
624 char *tag, *distance, *vrf;
625
626 tag = distance = vrf = NULL;
627 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
628
629 return zebra_static_ipv4 (vty, SAFI_UNICAST, 0,
630 argv[idx_ipv4]->arg,
631 argv[idx_ipv4_2]->arg,
632 NULL, NULL,
633 tag, distance, vrf, NULL);
634 }
635
636 /* New RIB. Detailed information for IPv4 route. */
637 static void
638 vty_show_ip_route_detail (struct vty *vty, struct route_node *rn, int mcast)
639 {
640 struct rib *rib;
641 struct nexthop *nexthop, *tnexthop;
642 int recursing;
643 char buf[SRCDEST2STR_BUFFER];
644 struct zebra_vrf *zvrf;
645
646 RNODE_FOREACH_RIB (rn, rib)
647 {
648 const char *mcast_info = "";
649 if (mcast)
650 {
651 rib_table_info_t *info = srcdest_rnode_table_info(rn);
652 mcast_info = (info->safi == SAFI_MULTICAST)
653 ? " using Multicast RIB"
654 : " using Unicast RIB";
655 }
656
657 vty_out (vty, "Routing entry for %s%s%s",
658 srcdest_rnode2str(rn, buf, sizeof(buf)), mcast_info,
659 VTY_NEWLINE);
660 vty_out (vty, " Known via \"%s", zebra_route_string (rib->type));
661 if (rib->instance)
662 vty_out (vty, "[%d]", rib->instance);
663 vty_out (vty, "\"");
664 vty_out (vty, ", distance %u, metric %u", rib->distance, rib->metric);
665 if (rib->tag)
666 vty_out (vty, ", tag %d", rib->tag);
667 if (rib->mtu)
668 vty_out (vty, ", mtu %u", rib->mtu);
669 if (rib->vrf_id != VRF_DEFAULT)
670 {
671 zvrf = vrf_info_lookup(rib->vrf_id);
672 vty_out (vty, ", vrf %s", zvrf_name (zvrf));
673 }
674 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
675 vty_out (vty, ", best");
676 if (rib->refcnt)
677 vty_out (vty, ", refcnt %ld", rib->refcnt);
678 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
679 vty_out (vty, ", blackhole");
680 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
681 vty_out (vty, ", reject");
682 vty_out (vty, "%s", VTY_NEWLINE);
683
684 if (rib->type == ZEBRA_ROUTE_RIP
685 || rib->type == ZEBRA_ROUTE_OSPF
686 || rib->type == ZEBRA_ROUTE_ISIS
687 || rib->type == ZEBRA_ROUTE_NHRP
688 || rib->type == ZEBRA_ROUTE_TABLE
689 || rib->type == ZEBRA_ROUTE_BGP)
690 {
691 time_t uptime;
692 struct tm *tm;
693
694 uptime = time (NULL);
695 uptime -= rib->uptime;
696 tm = gmtime (&uptime);
697
698 vty_out (vty, " Last update ");
699
700 if (uptime < ONE_DAY_SECOND)
701 vty_out (vty, "%02d:%02d:%02d",
702 tm->tm_hour, tm->tm_min, tm->tm_sec);
703 else if (uptime < ONE_WEEK_SECOND)
704 vty_out (vty, "%dd%02dh%02dm",
705 tm->tm_yday, tm->tm_hour, tm->tm_min);
706 else
707 vty_out (vty, "%02dw%dd%02dh",
708 tm->tm_yday/7,
709 tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
710 vty_out (vty, " ago%s", VTY_NEWLINE);
711 }
712
713 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
714 {
715 char addrstr[32];
716
717 vty_out (vty, " %c%s",
718 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? '*' : ' ',
719 recursing ? " " : "");
720
721 switch (nexthop->type)
722 {
723 case NEXTHOP_TYPE_IPV4:
724 case NEXTHOP_TYPE_IPV4_IFINDEX:
725 vty_out (vty, " %s", inet_ntoa (nexthop->gate.ipv4));
726 if (nexthop->ifindex)
727 vty_out (vty, ", via %s",
728 ifindex2ifname (nexthop->ifindex, rib->vrf_id));
729 break;
730 case NEXTHOP_TYPE_IPV6:
731 case NEXTHOP_TYPE_IPV6_IFINDEX:
732 vty_out (vty, " %s",
733 inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
734 if (nexthop->ifindex)
735 vty_out (vty, ", via %s",
736 ifindex2ifname (nexthop->ifindex, rib->vrf_id));
737 break;
738 case NEXTHOP_TYPE_IFINDEX:
739 vty_out (vty, " directly connected, %s",
740 ifindex2ifname (nexthop->ifindex, rib->vrf_id));
741 break;
742 case NEXTHOP_TYPE_BLACKHOLE:
743 vty_out (vty, " directly connected, Null0");
744 break;
745 default:
746 break;
747 }
748 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
749 vty_out (vty, " inactive");
750
751 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK))
752 vty_out (vty, " onlink");
753
754 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
755 vty_out (vty, " (recursive)");
756
757 switch (nexthop->type)
758 {
759 case NEXTHOP_TYPE_IPV4:
760 case NEXTHOP_TYPE_IPV4_IFINDEX:
761 if (nexthop->src.ipv4.s_addr)
762 {
763 if (inet_ntop(AF_INET, &nexthop->src.ipv4, addrstr,
764 sizeof addrstr))
765 vty_out (vty, ", src %s", addrstr);
766 }
767 break;
768 case NEXTHOP_TYPE_IPV6:
769 case NEXTHOP_TYPE_IPV6_IFINDEX:
770 if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any))
771 {
772 if (inet_ntop(AF_INET6, &nexthop->src.ipv6, addrstr,
773 sizeof addrstr))
774 vty_out (vty, ", src %s", addrstr);
775 }
776 break;
777 default:
778 break;
779 }
780
781 /* Label information */
782 if (nexthop->nh_label && nexthop->nh_label->num_labels)
783 {
784 vty_out (vty, " label %s",
785 mpls_label2str (nexthop->nh_label->num_labels,
786 nexthop->nh_label->label, buf, BUFSIZ));
787 }
788
789 vty_out (vty, "%s", VTY_NEWLINE);
790 }
791 vty_out (vty, "%s", VTY_NEWLINE);
792 }
793 }
794
795 static void
796 vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib,
797 json_object *json)
798 {
799 struct nexthop *nexthop, *tnexthop;
800 int recursing;
801 int len = 0;
802 char buf[SRCDEST2STR_BUFFER];
803 json_object *json_nexthops = NULL;
804 json_object *json_nexthop = NULL;
805 json_object *json_route = NULL;
806
807 if (json)
808 {
809 json_route = json_object_new_object();
810 json_nexthops = json_object_new_array();
811
812 json_object_string_add(json_route, "prefix", srcdest_rnode2str (rn, buf, sizeof buf));
813 json_object_string_add(json_route, "protocol", zebra_route_string(rib->type));
814
815 if (rib->instance)
816 json_object_int_add(json_route, "instance", rib->instance);
817
818 if (rib->vrf_id)
819 json_object_int_add(json_route, "vrfId", rib->vrf_id);
820
821 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
822 json_object_boolean_true_add(json_route, "selected");
823
824 if (rib->type != ZEBRA_ROUTE_CONNECT && rib->type != ZEBRA_ROUTE_KERNEL)
825 {
826 json_object_int_add(json_route, "distance", rib->distance);
827 json_object_int_add(json_route, "metric", rib->metric);
828 }
829
830 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
831 json_object_boolean_true_add(json_route, "blackhole");
832
833 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
834 json_object_boolean_true_add(json_route, "reject");
835
836 if (rib->type == ZEBRA_ROUTE_RIP
837 || rib->type == ZEBRA_ROUTE_OSPF
838 || rib->type == ZEBRA_ROUTE_ISIS
839 || rib->type == ZEBRA_ROUTE_NHRP
840 || rib->type == ZEBRA_ROUTE_TABLE
841 || rib->type == ZEBRA_ROUTE_BGP)
842 {
843 time_t uptime;
844 struct tm *tm;
845
846 uptime = time (NULL);
847 uptime -= rib->uptime;
848 tm = gmtime (&uptime);
849
850 if (uptime < ONE_DAY_SECOND)
851 sprintf(buf, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min, tm->tm_sec);
852 else if (uptime < ONE_WEEK_SECOND)
853 sprintf(buf, "%dd%02dh%02dm", tm->tm_yday, tm->tm_hour, tm->tm_min);
854 else
855 sprintf(buf, "%02dw%dd%02dh", tm->tm_yday/7, tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
856
857 json_object_string_add(json_route, "uptime", buf);
858 }
859
860 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
861 {
862 json_nexthop = json_object_new_object();
863
864 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
865 json_object_boolean_true_add(json_nexthop, "fib");
866
867 switch (nexthop->type)
868 {
869 case NEXTHOP_TYPE_IPV4:
870 case NEXTHOP_TYPE_IPV4_IFINDEX:
871 json_object_string_add(json_nexthop, "ip", inet_ntoa (nexthop->gate.ipv4));
872 json_object_string_add(json_nexthop, "afi", "ipv4");
873
874 if (nexthop->ifindex)
875 {
876 json_object_int_add(json_nexthop, "interfaceIndex", nexthop->ifindex);
877 json_object_string_add(json_nexthop, "interfaceName", ifindex2ifname (nexthop->ifindex, rib->vrf_id));
878 }
879 break;
880 case NEXTHOP_TYPE_IPV6:
881 case NEXTHOP_TYPE_IPV6_IFINDEX:
882 json_object_string_add(json_nexthop, "ip", inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
883 json_object_string_add(json_nexthop, "afi", "ipv6");
884
885 if (nexthop->ifindex)
886 {
887 json_object_int_add(json_nexthop, "interfaceIndex", nexthop->ifindex);
888 json_object_string_add(json_nexthop, "interfaceName", ifindex2ifname (nexthop->ifindex, rib->vrf_id));
889 }
890 break;
891
892 case NEXTHOP_TYPE_IFINDEX:
893 json_object_boolean_true_add(json_nexthop, "directlyConnected");
894 json_object_int_add(json_nexthop, "interfaceIndex", nexthop->ifindex);
895 json_object_string_add(json_nexthop, "interfaceName", ifindex2ifname (nexthop->ifindex, rib->vrf_id));
896 break;
897 case NEXTHOP_TYPE_BLACKHOLE:
898 json_object_boolean_true_add(json_nexthop, "blackhole");
899 break;
900 default:
901 break;
902 }
903
904 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
905 json_object_boolean_true_add(json_nexthop, "active");
906
907 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK))
908 json_object_boolean_true_add(json_nexthop, "onLink");
909
910 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
911 json_object_boolean_true_add(json_nexthop, "recursive");
912
913 switch (nexthop->type)
914 {
915 case NEXTHOP_TYPE_IPV4:
916 case NEXTHOP_TYPE_IPV4_IFINDEX:
917 if (nexthop->src.ipv4.s_addr)
918 {
919 if (inet_ntop(AF_INET, &nexthop->src.ipv4, buf, sizeof buf))
920 json_object_string_add(json_nexthop, "source", buf);
921 }
922 break;
923 case NEXTHOP_TYPE_IPV6:
924 case NEXTHOP_TYPE_IPV6_IFINDEX:
925 if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any))
926 {
927 if (inet_ntop(AF_INET6, &nexthop->src.ipv6, buf, sizeof buf))
928 json_object_string_add(json_nexthop, "source", buf);
929 }
930 break;
931 default:
932 break;
933 }
934
935 json_object_array_add(json_nexthops, json_nexthop);
936 }
937
938 json_object_object_add(json_route, "nexthops", json_nexthops);
939 json_object_array_add(json, json_route);
940 return;
941 }
942
943 /* Nexthop information. */
944 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
945 {
946 if (nexthop == rib->nexthop)
947 {
948 /* Prefix information. */
949 len = vty_out (vty, "%c", zebra_route_char (rib->type));
950 if (rib->instance)
951 len += vty_out (vty, "[%d]", rib->instance);
952 len += vty_out (vty, "%c%c %s",
953 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)
954 ? '>' : ' ',
955 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
956 ? '*' : ' ',
957 srcdest_rnode2str (rn, buf, sizeof buf));
958
959 /* Distance and metric display. */
960 if (rib->type != ZEBRA_ROUTE_CONNECT
961 && rib->type != ZEBRA_ROUTE_KERNEL)
962 len += vty_out (vty, " [%d/%d]", rib->distance,
963 rib->metric);
964 }
965 else
966 vty_out (vty, " %c%*c",
967 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
968 ? '*' : ' ',
969 len - 3 + (2 * recursing), ' ');
970
971 switch (nexthop->type)
972 {
973 case NEXTHOP_TYPE_IPV4:
974 case NEXTHOP_TYPE_IPV4_IFINDEX:
975 vty_out (vty, " via %s", inet_ntoa (nexthop->gate.ipv4));
976 if (nexthop->ifindex)
977 vty_out (vty, ", %s",
978 ifindex2ifname (nexthop->ifindex, rib->vrf_id));
979 break;
980 case NEXTHOP_TYPE_IPV6:
981 case NEXTHOP_TYPE_IPV6_IFINDEX:
982 vty_out (vty, " via %s",
983 inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
984 if (nexthop->ifindex)
985 vty_out (vty, ", %s",
986 ifindex2ifname (nexthop->ifindex, rib->vrf_id));
987 break;
988
989 case NEXTHOP_TYPE_IFINDEX:
990 vty_out (vty, " is directly connected, %s",
991 ifindex2ifname (nexthop->ifindex, rib->vrf_id));
992 break;
993 case NEXTHOP_TYPE_BLACKHOLE:
994 vty_out (vty, " is directly connected, Null0");
995 break;
996 default:
997 break;
998 }
999 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1000 vty_out (vty, " inactive");
1001
1002 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK))
1003 vty_out (vty, " onlink");
1004
1005 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
1006 vty_out (vty, " (recursive)");
1007
1008 switch (nexthop->type)
1009 {
1010 case NEXTHOP_TYPE_IPV4:
1011 case NEXTHOP_TYPE_IPV4_IFINDEX:
1012 if (nexthop->src.ipv4.s_addr)
1013 {
1014 if (inet_ntop(AF_INET, &nexthop->src.ipv4, buf, sizeof buf))
1015 vty_out (vty, ", src %s", buf);
1016 }
1017 break;
1018 case NEXTHOP_TYPE_IPV6:
1019 case NEXTHOP_TYPE_IPV6_IFINDEX:
1020 if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any))
1021 {
1022 if (inet_ntop(AF_INET6, &nexthop->src.ipv6, buf, sizeof buf))
1023 vty_out (vty, ", src %s", buf);
1024 }
1025 break;
1026 default:
1027 break;
1028 }
1029
1030 /* Label information */
1031 if (nexthop->nh_label && nexthop->nh_label->num_labels)
1032 {
1033 vty_out (vty, " label %s",
1034 mpls_label2str (nexthop->nh_label->num_labels,
1035 nexthop->nh_label->label, buf, BUFSIZ));
1036 }
1037
1038 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
1039 vty_out (vty, ", bh");
1040 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
1041 vty_out (vty, ", rej");
1042
1043 if (rib->type == ZEBRA_ROUTE_RIP
1044 || rib->type == ZEBRA_ROUTE_OSPF
1045 || rib->type == ZEBRA_ROUTE_ISIS
1046 || rib->type == ZEBRA_ROUTE_NHRP
1047 || rib->type == ZEBRA_ROUTE_TABLE
1048 || rib->type == ZEBRA_ROUTE_BGP)
1049 {
1050 time_t uptime;
1051 struct tm *tm;
1052
1053 uptime = time (NULL);
1054 uptime -= rib->uptime;
1055 tm = gmtime (&uptime);
1056
1057 if (uptime < ONE_DAY_SECOND)
1058 vty_out (vty, ", %02d:%02d:%02d",
1059 tm->tm_hour, tm->tm_min, tm->tm_sec);
1060 else if (uptime < ONE_WEEK_SECOND)
1061 vty_out (vty, ", %dd%02dh%02dm",
1062 tm->tm_yday, tm->tm_hour, tm->tm_min);
1063 else
1064 vty_out (vty, ", %02dw%dd%02dh",
1065 tm->tm_yday/7,
1066 tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
1067 }
1068 vty_out (vty, "%s", VTY_NEWLINE);
1069 }
1070 }
1071
1072 DEFUN (show_ip_route,
1073 show_ip_route_cmd,
1074 "show ip route [json]",
1075 SHOW_STR
1076 IP_STR
1077 "IP routing table\n"
1078 JSON_STR)
1079 {
1080 return do_show_ip_route (vty, VRF_DEFAULT_NAME, SAFI_UNICAST, use_json(argc, argv));
1081 }
1082
1083 static int
1084 do_show_ip_route (struct vty *vty, const char *vrf_name, safi_t safi,
1085 u_char use_json)
1086 {
1087 struct route_table *table;
1088 struct route_node *rn;
1089 struct rib *rib;
1090 int first = 1;
1091 struct zebra_vrf *zvrf = NULL;
1092 char buf[BUFSIZ];
1093 json_object *json = NULL;
1094 json_object *json_prefix = NULL;
1095
1096 if (!(zvrf = zebra_vrf_lookup_by_name (vrf_name)))
1097 {
1098 if (use_json)
1099 vty_out (vty, "{}%s", VTY_NEWLINE);
1100 else
1101 vty_out (vty, "vrf %s not defined%s", vrf_name, VTY_NEWLINE);
1102 return CMD_SUCCESS;
1103 }
1104
1105 if (zvrf_id (zvrf) == VRF_UNKNOWN)
1106 {
1107 if (use_json)
1108 vty_out (vty, "{}%s", VTY_NEWLINE);
1109 else
1110 vty_out (vty, "vrf %s inactive%s", vrf_name, VTY_NEWLINE);
1111 return CMD_SUCCESS;
1112 }
1113
1114 table = zebra_vrf_table (AFI_IP, safi, zvrf_id (zvrf));
1115 if (! table)
1116 {
1117 if (use_json)
1118 vty_out (vty, "{}%s", VTY_NEWLINE);
1119 return CMD_SUCCESS;
1120 }
1121
1122 if (use_json)
1123 {
1124 json = json_object_new_object();
1125
1126 /* Show all IPv4 routes. */
1127 for (rn = route_top (table); rn; rn = route_next (rn))
1128 {
1129 RNODE_FOREACH_RIB (rn, rib)
1130 {
1131 if (!json_prefix)
1132 json_prefix = json_object_new_array();
1133 vty_show_ip_route (vty, rn, rib, json_prefix);
1134 }
1135
1136 if (json_prefix)
1137 {
1138 prefix2str (&rn->p, buf, sizeof buf);
1139 json_object_object_add(json, buf, json_prefix);
1140 json_prefix = NULL;
1141 }
1142 }
1143
1144 vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
1145 json_object_free(json);
1146 }
1147 else
1148 {
1149 /* Show all IPv4 routes. */
1150 for (rn = route_top (table); rn; rn = route_next (rn))
1151 {
1152 RNODE_FOREACH_RIB (rn, rib)
1153 {
1154 if (first)
1155 {
1156 vty_out (vty, SHOW_ROUTE_V4_HEADER);
1157 first = 0;
1158 }
1159 vty_show_ip_route (vty, rn, rib, NULL);
1160 }
1161 }
1162 }
1163
1164 return CMD_SUCCESS;
1165 }
1166
1167 DEFUN (show_ip_route_vrf,
1168 show_ip_route_vrf_cmd,
1169 "show ip route vrf NAME [json]",
1170 SHOW_STR
1171 IP_STR
1172 "IP routing table\n"
1173 VRF_CMD_HELP_STR
1174 JSON_STR)
1175 {
1176 int idx_vrf = 4;
1177 u_char uj = use_json(argc, argv);
1178
1179 return do_show_ip_route (vty, argv[idx_vrf]->arg, SAFI_UNICAST, uj);
1180 }
1181
1182 DEFUN (show_ip_nht,
1183 show_ip_nht_cmd,
1184 "show ip nht [vrf NAME]",
1185 SHOW_STR
1186 IP_STR
1187 "IP nexthop tracking table\n"
1188 VRF_CMD_HELP_STR)
1189 {
1190 int idx_vrf = 4;
1191 vrf_id_t vrf_id = VRF_DEFAULT;
1192
1193 if (argc == 5)
1194 VRF_GET_ID (vrf_id, argv[idx_vrf]->arg);
1195
1196 zebra_print_rnh_table(vrf_id, AF_INET, vty, RNH_NEXTHOP_TYPE);
1197 return CMD_SUCCESS;
1198 }
1199
1200
1201 DEFUN (show_ip_nht_vrf_all,
1202 show_ip_nht_vrf_all_cmd,
1203 "show ip nht vrf all",
1204 SHOW_STR
1205 IP_STR
1206 "IP nexthop tracking table\n"
1207 VRF_ALL_CMD_HELP_STR)
1208 {
1209 struct vrf *vrf;
1210 struct zebra_vrf *zvrf;
1211
1212 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
1213 if ((zvrf = vrf->info) != NULL)
1214 {
1215 vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE);
1216 zebra_print_rnh_table(zvrf_id (zvrf), AF_INET, vty, RNH_NEXTHOP_TYPE);
1217 }
1218
1219 return CMD_SUCCESS;
1220 }
1221
1222 DEFUN (show_ipv6_nht,
1223 show_ipv6_nht_cmd,
1224 "show ipv6 nht [vrf NAME]",
1225 SHOW_STR
1226 IPV6_STR
1227 "IPv6 nexthop tracking table\n"
1228 VRF_CMD_HELP_STR)
1229 {
1230 int idx_vrf = 4;
1231 vrf_id_t vrf_id = VRF_DEFAULT;
1232
1233 if (argc == 5)
1234 VRF_GET_ID (vrf_id, argv[idx_vrf]->arg);
1235
1236 zebra_print_rnh_table(vrf_id, AF_INET6, vty, RNH_NEXTHOP_TYPE);
1237 return CMD_SUCCESS;
1238 }
1239
1240
1241 DEFUN (show_ipv6_nht_vrf_all,
1242 show_ipv6_nht_vrf_all_cmd,
1243 "show ipv6 nht vrf all",
1244 SHOW_STR
1245 IP_STR
1246 "IPv6 nexthop tracking table\n"
1247 VRF_ALL_CMD_HELP_STR)
1248 {
1249 struct vrf *vrf;
1250 struct zebra_vrf *zvrf;
1251
1252 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
1253 if ((zvrf = vrf->info) != NULL)
1254 {
1255 vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE);
1256 zebra_print_rnh_table(zvrf_id (zvrf), AF_INET6, vty, RNH_NEXTHOP_TYPE);
1257 }
1258
1259 return CMD_SUCCESS;
1260 }
1261
1262 DEFUN (ip_nht_default_route,
1263 ip_nht_default_route_cmd,
1264 "ip nht resolve-via-default",
1265 IP_STR
1266 "Filter Next Hop tracking route resolution\n"
1267 "Resolve via default route\n")
1268 {
1269 if (zebra_rnh_ip_default_route)
1270 return CMD_SUCCESS;
1271
1272 zebra_rnh_ip_default_route = 1;
1273 zebra_evaluate_rnh(0, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
1274 return CMD_SUCCESS;
1275 }
1276
1277 DEFUN (no_ip_nht_default_route,
1278 no_ip_nht_default_route_cmd,
1279 "no ip nht resolve-via-default",
1280 NO_STR
1281 IP_STR
1282 "Filter Next Hop tracking route resolution\n"
1283 "Resolve via default route\n")
1284 {
1285 if (!zebra_rnh_ip_default_route)
1286 return CMD_SUCCESS;
1287
1288 zebra_rnh_ip_default_route = 0;
1289 zebra_evaluate_rnh(0, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
1290 return CMD_SUCCESS;
1291 }
1292
1293 DEFUN (ipv6_nht_default_route,
1294 ipv6_nht_default_route_cmd,
1295 "ipv6 nht resolve-via-default",
1296 IP6_STR
1297 "Filter Next Hop tracking route resolution\n"
1298 "Resolve via default route\n")
1299 {
1300 if (zebra_rnh_ipv6_default_route)
1301 return CMD_SUCCESS;
1302
1303 zebra_rnh_ipv6_default_route = 1;
1304 zebra_evaluate_rnh(0, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL);
1305 return CMD_SUCCESS;
1306 }
1307
1308 DEFUN (no_ipv6_nht_default_route,
1309 no_ipv6_nht_default_route_cmd,
1310 "no ipv6 nht resolve-via-default",
1311 NO_STR
1312 IP6_STR
1313 "Filter Next Hop tracking route resolution\n"
1314 "Resolve via default route\n")
1315 {
1316 if (!zebra_rnh_ipv6_default_route)
1317 return CMD_SUCCESS;
1318
1319 zebra_rnh_ipv6_default_route = 0;
1320 zebra_evaluate_rnh(0, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL);
1321 return CMD_SUCCESS;
1322 }
1323
1324 DEFUN (show_ip_route_tag,
1325 show_ip_route_tag_cmd,
1326 "show ip route [vrf NAME] tag (1-4294967295)",
1327 SHOW_STR
1328 IP_STR
1329 "IP routing table\n"
1330 VRF_CMD_HELP_STR
1331 "Show only routes with tag\n"
1332 "Tag value\n")
1333 {
1334 int idx_vrf = 3;
1335 int idx_name = 4;
1336 int idx_tag = 6;
1337 struct route_table *table;
1338 struct route_node *rn;
1339 struct rib *rib;
1340 int first = 1;
1341 route_tag_t tag = 0;
1342 vrf_id_t vrf_id = VRF_DEFAULT;
1343
1344 if (strmatch(argv[idx_vrf]->text, "vrf"))
1345 {
1346 VRF_GET_ID (vrf_id, argv[idx_name]->arg);
1347 VTY_GET_INTEGER_RANGE("tag", tag, argv[idx_tag]->arg, 0, 4294967295);
1348 }
1349 else
1350 {
1351 idx_tag -= 2;
1352 VTY_GET_INTEGER_RANGE("tag", tag, argv[idx_tag]->arg, 0, 4294967295);
1353 }
1354
1355 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
1356 if (! table)
1357 return CMD_SUCCESS;
1358
1359 /* Show all IPv4 routes with matching tag value. */
1360 for (rn = route_top (table); rn; rn = route_next (rn))
1361 RNODE_FOREACH_RIB (rn, rib)
1362 {
1363 if (rib->tag != tag)
1364 continue;
1365
1366 if (first)
1367 {
1368 vty_out (vty, SHOW_ROUTE_V4_HEADER);
1369 first = 0;
1370 }
1371 vty_show_ip_route (vty, rn, rib, NULL);
1372 }
1373 return CMD_SUCCESS;
1374 }
1375
1376 DEFUN (show_ip_route_prefix_longer,
1377 show_ip_route_prefix_longer_cmd,
1378 "show ip route [vrf NAME] A.B.C.D/M longer-prefixes",
1379 SHOW_STR
1380 IP_STR
1381 "IP routing table\n"
1382 VRF_CMD_HELP_STR
1383 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1384 "Show route matching the specified Network/Mask pair only\n")
1385 {
1386 struct route_table *table;
1387 struct route_node *rn;
1388 struct rib *rib;
1389 struct prefix p;
1390 int ret;
1391 int first = 1;
1392 vrf_id_t vrf_id = VRF_DEFAULT;
1393
1394 if (strmatch(argv[3]->text, "vrf"))
1395 {
1396 VRF_GET_ID (vrf_id, argv[4]->arg);
1397 ret = str2prefix (argv[5]->arg, &p);
1398 }
1399 else
1400 {
1401 ret = str2prefix (argv[3]->arg, &p);
1402 }
1403
1404 if (! ret)
1405 {
1406 vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE);
1407 return CMD_WARNING;
1408 }
1409
1410 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
1411 if (! table)
1412 return CMD_SUCCESS;
1413
1414 /* Show matched type IPv4 routes. */
1415 for (rn = route_top (table); rn; rn = route_next (rn))
1416 RNODE_FOREACH_RIB (rn, rib)
1417 if (prefix_match (&p, &rn->p))
1418 {
1419 if (first)
1420 {
1421 vty_out (vty, SHOW_ROUTE_V4_HEADER);
1422 first = 0;
1423 }
1424 vty_show_ip_route (vty, rn, rib, NULL);
1425 }
1426 return CMD_SUCCESS;
1427 }
1428
1429 DEFUN (show_ip_route_supernets,
1430 show_ip_route_supernets_cmd,
1431 "show ip route [vrf NAME] supernets-only",
1432 SHOW_STR
1433 IP_STR
1434 "IP routing table\n"
1435 VRF_CMD_HELP_STR
1436 "Show supernet entries only\n")
1437 {
1438 struct route_table *table;
1439 struct route_node *rn;
1440 struct rib *rib;
1441 u_int32_t addr;
1442 int first = 1;
1443 vrf_id_t vrf_id = VRF_DEFAULT;
1444
1445 if (strmatch(argv[3]->text, "vrf"))
1446 VRF_GET_ID (vrf_id, argv[4]->arg);
1447
1448 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
1449 if (! table)
1450 return CMD_SUCCESS;
1451
1452 /* Show matched type IPv4 routes. */
1453 for (rn = route_top (table); rn; rn = route_next (rn))
1454 RNODE_FOREACH_RIB (rn, rib)
1455 {
1456 addr = ntohl (rn->p.u.prefix4.s_addr);
1457
1458 if ((IN_CLASSC (addr) && rn->p.prefixlen < 24)
1459 || (IN_CLASSB (addr) && rn->p.prefixlen < 16)
1460 || (IN_CLASSA (addr) && rn->p.prefixlen < 8))
1461 {
1462 if (first)
1463 {
1464 vty_out (vty, SHOW_ROUTE_V4_HEADER);
1465 first = 0;
1466 }
1467 vty_show_ip_route (vty, rn, rib, NULL);
1468 }
1469 }
1470 return CMD_SUCCESS;
1471 }
1472
1473 DEFUN (show_ip_route_protocol,
1474 show_ip_route_protocol_cmd,
1475 "show ip route [vrf NAME] " FRR_IP_REDIST_STR_ZEBRA,
1476 SHOW_STR
1477 IP_STR
1478 "IP routing table\n"
1479 VRF_CMD_HELP_STR
1480 FRR_IP_REDIST_HELP_STR_ZEBRA)
1481 {
1482 int type;
1483 struct route_table *table;
1484 struct route_node *rn;
1485 struct rib *rib;
1486 int first = 1;
1487 vrf_id_t vrf_id = VRF_DEFAULT;
1488
1489 int idx = 0;
1490 if (argv_find (argv, argc, "NAME", &idx))
1491 VRF_GET_ID (vrf_id, argv[idx]->arg);
1492
1493 char *proto = argv[argc - 1]->text;
1494 type = proto_redistnum (AFI_IP, proto);
1495
1496 if (type < 0)
1497 {
1498 vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
1499 return CMD_WARNING;
1500 }
1501
1502 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
1503 if (! table)
1504 return CMD_SUCCESS;
1505
1506 /* Show matched type IPv4 routes. */
1507 for (rn = route_top (table); rn; rn = route_next (rn))
1508 RNODE_FOREACH_RIB (rn, rib)
1509 if (rib->type == type)
1510 {
1511 if (first)
1512 {
1513 vty_out (vty, SHOW_ROUTE_V4_HEADER);
1514 first = 0;
1515 }
1516 vty_show_ip_route (vty, rn, rib, NULL);
1517 }
1518 return CMD_SUCCESS;
1519 }
1520
1521
1522 DEFUN (show_ip_route_ospf_instance,
1523 show_ip_route_ospf_instance_cmd,
1524 "show ip route ospf (1-65535)",
1525 SHOW_STR
1526 IP_STR
1527 "IP routing table\n"
1528 "Open Shortest Path First (OSPFv2)\n"
1529 "Instance ID\n")
1530 {
1531 int idx_number = 4;
1532 struct route_table *table;
1533 struct route_node *rn;
1534 struct rib *rib;
1535 int first = 1;
1536 u_short instance = 0;
1537
1538 VTY_GET_INTEGER ("Instance", instance, argv[idx_number]->arg);
1539
1540 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT);
1541 if (! table)
1542 return CMD_SUCCESS;
1543
1544 /* Show matched type IPv4 routes. */
1545 for (rn = route_top (table); rn; rn = route_next (rn))
1546 RNODE_FOREACH_RIB (rn, rib)
1547 if (rib->type == ZEBRA_ROUTE_OSPF && rib->instance == instance)
1548 {
1549 if (first)
1550 {
1551 vty_out (vty, SHOW_ROUTE_V4_HEADER);
1552 first = 0;
1553 }
1554 vty_show_ip_route (vty, rn, rib, NULL);
1555 }
1556 return CMD_SUCCESS;
1557 }
1558
1559 DEFUN (show_ip_route_addr,
1560 show_ip_route_addr_cmd,
1561 "show ip route [vrf NAME] A.B.C.D",
1562 SHOW_STR
1563 IP_STR
1564 "IP routing table\n"
1565 VRF_CMD_HELP_STR
1566 "Network in the IP routing table to display\n")
1567 {
1568 int ret;
1569 struct prefix_ipv4 p;
1570 struct route_table *table;
1571 struct route_node *rn;
1572 vrf_id_t vrf_id = VRF_DEFAULT;
1573
1574 if (strmatch(argv[3]->text, "vrf"))
1575 {
1576 VRF_GET_ID (vrf_id, argv[4]->arg);
1577 ret = str2prefix_ipv4 (argv[5]->arg, &p);
1578 }
1579 else
1580 {
1581 ret = str2prefix_ipv4 (argv[3]->arg, &p);
1582 }
1583
1584 if (ret <= 0)
1585 {
1586 vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
1587 return CMD_WARNING;
1588 }
1589
1590 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
1591 if (! table)
1592 return CMD_SUCCESS;
1593
1594 rn = route_node_match (table, (struct prefix *) &p);
1595 if (! rn)
1596 {
1597 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
1598 return CMD_WARNING;
1599 }
1600
1601 vty_show_ip_route_detail (vty, rn, 0);
1602
1603 route_unlock_node (rn);
1604
1605 return CMD_SUCCESS;
1606 }
1607
1608 DEFUN (show_ip_route_prefix,
1609 show_ip_route_prefix_cmd,
1610 "show ip route [vrf NAME] A.B.C.D/M",
1611 SHOW_STR
1612 IP_STR
1613 "IP routing table\n"
1614 VRF_CMD_HELP_STR
1615 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
1616 {
1617 int ret;
1618 struct prefix_ipv4 p;
1619 struct route_table *table;
1620 struct route_node *rn;
1621 vrf_id_t vrf_id = VRF_DEFAULT;
1622
1623 if (strmatch(argv[3]->text, "vrf"))
1624 {
1625 VRF_GET_ID (vrf_id, argv[4]->arg);
1626 ret = str2prefix_ipv4 (argv[5]->arg, &p);
1627 }
1628 else
1629 {
1630 ret = str2prefix_ipv4 (argv[3]->arg, &p);
1631 }
1632
1633 if (ret <= 0)
1634 {
1635 vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
1636 return CMD_WARNING;
1637 }
1638
1639 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
1640 if (! table)
1641 return CMD_SUCCESS;
1642
1643 rn = route_node_match (table, (struct prefix *) &p);
1644 if (! rn || rn->p.prefixlen != p.prefixlen)
1645 {
1646 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
1647 return CMD_WARNING;
1648 }
1649
1650 vty_show_ip_route_detail (vty, rn, 0);
1651
1652 route_unlock_node (rn);
1653
1654 return CMD_SUCCESS;
1655 }
1656
1657
1658 static void
1659 vty_show_ip_route_summary (struct vty *vty, struct route_table *table)
1660 {
1661 struct route_node *rn;
1662 struct rib *rib;
1663 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1664 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1665 u_int32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1666 u_int32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1667 u_int32_t i;
1668 u_int32_t is_ibgp;
1669
1670 memset (&rib_cnt, 0, sizeof(rib_cnt));
1671 memset (&fib_cnt, 0, sizeof(fib_cnt));
1672 for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
1673 RNODE_FOREACH_RIB (rn, rib)
1674 {
1675 is_ibgp = (rib->type == ZEBRA_ROUTE_BGP &&
1676 CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP));
1677
1678 rib_cnt[ZEBRA_ROUTE_TOTAL]++;
1679 if (is_ibgp)
1680 rib_cnt[ZEBRA_ROUTE_IBGP]++;
1681 else
1682 rib_cnt[rib->type]++;
1683
1684 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1685 {
1686 fib_cnt[ZEBRA_ROUTE_TOTAL]++;
1687
1688 if (is_ibgp)
1689 fib_cnt[ZEBRA_ROUTE_IBGP]++;
1690 else
1691 fib_cnt[rib->type]++;
1692 }
1693 }
1694
1695 vty_out (vty, "%-20s %-20s %s (vrf %s)%s",
1696 "Route Source", "Routes", "FIB",
1697 zvrf_name (((rib_table_info_t *)table->info)->zvrf),
1698 VTY_NEWLINE);
1699
1700 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
1701 {
1702 if ((rib_cnt[i] > 0) ||
1703 (i == ZEBRA_ROUTE_BGP && rib_cnt[ZEBRA_ROUTE_IBGP] > 0))
1704 {
1705 if (i == ZEBRA_ROUTE_BGP)
1706 {
1707 vty_out (vty, "%-20s %-20d %-20d %s", "ebgp",
1708 rib_cnt[ZEBRA_ROUTE_BGP], fib_cnt[ZEBRA_ROUTE_BGP],
1709 VTY_NEWLINE);
1710 vty_out (vty, "%-20s %-20d %-20d %s", "ibgp",
1711 rib_cnt[ZEBRA_ROUTE_IBGP], fib_cnt[ZEBRA_ROUTE_IBGP],
1712 VTY_NEWLINE);
1713 }
1714 else
1715 vty_out (vty, "%-20s %-20d %-20d %s", zebra_route_string(i),
1716 rib_cnt[i], fib_cnt[i], VTY_NEWLINE);
1717 }
1718 }
1719
1720 vty_out (vty, "------%s", VTY_NEWLINE);
1721 vty_out (vty, "%-20s %-20d %-20d %s", "Totals", rib_cnt[ZEBRA_ROUTE_TOTAL],
1722 fib_cnt[ZEBRA_ROUTE_TOTAL], VTY_NEWLINE);
1723 vty_out (vty, "%s", VTY_NEWLINE);
1724 }
1725
1726 /*
1727 * Implementation of the ip route summary prefix command.
1728 *
1729 * This command prints the primary prefixes that have been installed by various
1730 * protocols on the box.
1731 *
1732 */
1733 static void
1734 vty_show_ip_route_summary_prefix (struct vty *vty, struct route_table *table)
1735 {
1736 struct route_node *rn;
1737 struct rib *rib;
1738 struct nexthop *nexthop;
1739 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1740 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1741 u_int32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1742 u_int32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1743 u_int32_t i;
1744 int cnt;
1745
1746 memset (&rib_cnt, 0, sizeof(rib_cnt));
1747 memset (&fib_cnt, 0, sizeof(fib_cnt));
1748 for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
1749 RNODE_FOREACH_RIB (rn, rib)
1750 {
1751
1752 /*
1753 * In case of ECMP, count only once.
1754 */
1755 cnt = 0;
1756 for (nexthop = rib->nexthop; (!cnt && nexthop); nexthop = nexthop->next)
1757 {
1758 cnt++;
1759 rib_cnt[ZEBRA_ROUTE_TOTAL]++;
1760 rib_cnt[rib->type]++;
1761 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
1762 {
1763 fib_cnt[ZEBRA_ROUTE_TOTAL]++;
1764 fib_cnt[rib->type]++;
1765 }
1766 if (rib->type == ZEBRA_ROUTE_BGP &&
1767 CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
1768 {
1769 rib_cnt[ZEBRA_ROUTE_IBGP]++;
1770 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
1771 fib_cnt[ZEBRA_ROUTE_IBGP]++;
1772 }
1773 }
1774 }
1775
1776 vty_out (vty, "%-20s %-20s %s (vrf %s)%s",
1777 "Route Source", "Prefix Routes", "FIB",
1778 zvrf_name (((rib_table_info_t *)table->info)->zvrf),
1779 VTY_NEWLINE);
1780
1781 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
1782 {
1783 if (rib_cnt[i] > 0)
1784 {
1785 if (i == ZEBRA_ROUTE_BGP)
1786 {
1787 vty_out (vty, "%-20s %-20d %-20d %s", "ebgp",
1788 rib_cnt[ZEBRA_ROUTE_BGP] - rib_cnt[ZEBRA_ROUTE_IBGP],
1789 fib_cnt[ZEBRA_ROUTE_BGP] - fib_cnt[ZEBRA_ROUTE_IBGP],
1790 VTY_NEWLINE);
1791 vty_out (vty, "%-20s %-20d %-20d %s", "ibgp",
1792 rib_cnt[ZEBRA_ROUTE_IBGP], fib_cnt[ZEBRA_ROUTE_IBGP],
1793 VTY_NEWLINE);
1794 }
1795 else
1796 vty_out (vty, "%-20s %-20d %-20d %s", zebra_route_string(i),
1797 rib_cnt[i], fib_cnt[i], VTY_NEWLINE);
1798 }
1799 }
1800
1801 vty_out (vty, "------%s", VTY_NEWLINE);
1802 vty_out (vty, "%-20s %-20d %-20d %s", "Totals", rib_cnt[ZEBRA_ROUTE_TOTAL],
1803 fib_cnt[ZEBRA_ROUTE_TOTAL], VTY_NEWLINE);
1804 vty_out (vty, "%s", VTY_NEWLINE);
1805 }
1806
1807 /* Show route summary. */
1808 DEFUN (show_ip_route_summary,
1809 show_ip_route_summary_cmd,
1810 "show ip route [vrf NAME] summary",
1811 SHOW_STR
1812 IP_STR
1813 "IP routing table\n"
1814 VRF_CMD_HELP_STR
1815 "Summary of all routes\n")
1816 {
1817 struct route_table *table;
1818 vrf_id_t vrf_id = VRF_DEFAULT;
1819
1820 if (strmatch(argv[3]->text, "vrf"))
1821 VRF_GET_ID (vrf_id, argv[4]->arg);
1822
1823 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
1824 if (! table)
1825 return CMD_SUCCESS;
1826
1827 vty_show_ip_route_summary (vty, table);
1828
1829 return CMD_SUCCESS;
1830 }
1831
1832 /* Show route summary prefix. */
1833 DEFUN (show_ip_route_summary_prefix,
1834 show_ip_route_summary_prefix_cmd,
1835 "show ip route [vrf NAME] summary prefix",
1836 SHOW_STR
1837 IP_STR
1838 "IP routing table\n"
1839 VRF_CMD_HELP_STR
1840 "Summary of all routes\n"
1841 "Prefix routes\n")
1842 {
1843 struct route_table *table;
1844 vrf_id_t vrf_id = VRF_DEFAULT;
1845
1846 if (strmatch(argv[3]->text, "vrf"))
1847 VRF_GET_ID (vrf_id, argv[4]->arg);
1848
1849 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
1850 if (! table)
1851 return CMD_SUCCESS;
1852
1853 vty_show_ip_route_summary_prefix (vty, table);
1854
1855 return CMD_SUCCESS;
1856 }
1857
1858
1859 DEFUN (show_ip_route_vrf_all,
1860 show_ip_route_vrf_all_cmd,
1861 "show ip route vrf all",
1862 SHOW_STR
1863 IP_STR
1864 "IP routing table\n"
1865 VRF_ALL_CMD_HELP_STR)
1866 {
1867 struct route_table *table;
1868 struct route_node *rn;
1869 struct rib *rib;
1870 struct vrf *vrf;
1871 struct zebra_vrf *zvrf;
1872 int first = 1;
1873 int vrf_header = 1;
1874
1875 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
1876 {
1877 if ((zvrf = vrf->info) == NULL ||
1878 (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
1879 continue;
1880
1881 /* Show all IPv4 routes. */
1882 for (rn = route_top (table); rn; rn = route_next (rn))
1883 RNODE_FOREACH_RIB (rn, rib)
1884 {
1885 if (first)
1886 {
1887 vty_out (vty, SHOW_ROUTE_V4_HEADER);
1888 first = 0;
1889 }
1890
1891 if (vrf_header)
1892 {
1893 vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE);
1894 vrf_header = 0;
1895 }
1896 vty_show_ip_route (vty, rn, rib, NULL);
1897 }
1898 vrf_header = 1;
1899 }
1900
1901 return CMD_SUCCESS;
1902 }
1903
1904 DEFUN (show_ip_route_vrf_all_tag,
1905 show_ip_route_vrf_all_tag_cmd,
1906 "show ip route vrf all tag (1-4294967295)",
1907 SHOW_STR
1908 IP_STR
1909 "IP routing table\n"
1910 VRF_ALL_CMD_HELP_STR
1911 "Show only routes with tag\n"
1912 "Tag value\n")
1913 {
1914 int idx_number = 6;
1915 struct route_table *table;
1916 struct route_node *rn;
1917 struct rib *rib;
1918 struct vrf *vrf;
1919 struct zebra_vrf *zvrf;
1920 int first = 1;
1921 int vrf_header = 1;
1922 route_tag_t tag = 0;
1923
1924 if (argv[idx_number]->arg)
1925 VTY_GET_INTEGER_RANGE("tag", tag, argv[idx_number]->arg, 0, 4294967295);
1926
1927 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
1928 {
1929 if ((zvrf = vrf->info) == NULL ||
1930 (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
1931 continue;
1932
1933 /* Show all IPv4 routes with matching tag value. */
1934 for (rn = route_top (table); rn; rn = route_next (rn))
1935 RNODE_FOREACH_RIB (rn, rib)
1936 {
1937 if (rib->tag != tag)
1938 continue;
1939
1940 if (first)
1941 {
1942 vty_out (vty, SHOW_ROUTE_V4_HEADER);
1943 first = 0;
1944 }
1945
1946 if (vrf_header)
1947 {
1948 vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE);
1949 vrf_header = 0;
1950 }
1951 vty_show_ip_route (vty, rn, rib, NULL);
1952 }
1953 vrf_header = 1;
1954 }
1955 return CMD_SUCCESS;
1956 }
1957
1958 DEFUN (show_ip_route_vrf_all_prefix_longer,
1959 show_ip_route_vrf_all_prefix_longer_cmd,
1960 "show ip route vrf all A.B.C.D/M longer-prefixes",
1961 SHOW_STR
1962 IP_STR
1963 "IP routing table\n"
1964 VRF_ALL_CMD_HELP_STR
1965 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1966 "Show route matching the specified Network/Mask pair only\n")
1967 {
1968 int idx_ipv4_prefixlen = 5;
1969 struct route_table *table;
1970 struct route_node *rn;
1971 struct rib *rib;
1972 struct prefix p;
1973 struct vrf *vrf;
1974 struct zebra_vrf *zvrf;
1975 int ret;
1976 int first = 1;
1977 int vrf_header = 1;
1978
1979 ret = str2prefix (argv[idx_ipv4_prefixlen]->arg, &p);
1980 if (! ret)
1981 {
1982 vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE);
1983 return CMD_WARNING;
1984 }
1985
1986 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
1987 {
1988 if ((zvrf = vrf->info) == NULL ||
1989 (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
1990 continue;
1991
1992 /* Show matched type IPv4 routes. */
1993 for (rn = route_top (table); rn; rn = route_next (rn))
1994 RNODE_FOREACH_RIB (rn, rib)
1995 if (prefix_match (&p, &rn->p))
1996 {
1997 if (first)
1998 {
1999 vty_out (vty, SHOW_ROUTE_V4_HEADER);
2000 first = 0;
2001 }
2002
2003 if (vrf_header)
2004 {
2005 vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE);
2006 vrf_header = 0;
2007 }
2008 vty_show_ip_route (vty, rn, rib, NULL);
2009 }
2010 vrf_header = 1;
2011 }
2012
2013 return CMD_SUCCESS;
2014 }
2015
2016 DEFUN (show_ip_route_vrf_all_supernets,
2017 show_ip_route_vrf_all_supernets_cmd,
2018 "show ip route vrf all supernets-only",
2019 SHOW_STR
2020 IP_STR
2021 "IP routing table\n"
2022 VRF_ALL_CMD_HELP_STR
2023 "Show supernet entries only\n")
2024 {
2025 struct route_table *table;
2026 struct route_node *rn;
2027 struct rib *rib;
2028 struct vrf *vrf;
2029 struct zebra_vrf *zvrf;
2030 u_int32_t addr;
2031 int first = 1;
2032 int vrf_header = 1;
2033
2034 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
2035 {
2036 if ((zvrf = vrf->info) == NULL ||
2037 (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
2038 continue;
2039
2040 /* Show matched type IPv4 routes. */
2041 for (rn = route_top (table); rn; rn = route_next (rn))
2042 RNODE_FOREACH_RIB (rn, rib)
2043 {
2044 addr = ntohl (rn->p.u.prefix4.s_addr);
2045
2046 if ((IN_CLASSC (addr) && rn->p.prefixlen < 24)
2047 || (IN_CLASSB (addr) && rn->p.prefixlen < 16)
2048 || (IN_CLASSA (addr) && rn->p.prefixlen < 8))
2049 {
2050 if (first)
2051 {
2052 vty_out (vty, SHOW_ROUTE_V4_HEADER);
2053 first = 0;
2054 }
2055 if (vrf_header)
2056 {
2057 vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE);
2058 vrf_header = 0;
2059 }
2060 vty_show_ip_route (vty, rn, rib, NULL);
2061 }
2062 }
2063 vrf_header = 1;
2064 }
2065
2066 return CMD_SUCCESS;
2067 }
2068
2069 DEFUN (show_ip_route_vrf_all_protocol,
2070 show_ip_route_vrf_all_protocol_cmd,
2071 "show ip route vrf all " FRR_IP_REDIST_STR_ZEBRA,
2072 SHOW_STR
2073 IP_STR
2074 "IP routing table\n"
2075 VRF_ALL_CMD_HELP_STR
2076 FRR_IP_REDIST_HELP_STR_ZEBRA"\n")
2077 {
2078 int type;
2079 struct route_table *table;
2080 struct route_node *rn;
2081 struct rib *rib;
2082 struct vrf *vrf;
2083 struct zebra_vrf *zvrf;
2084 int first = 1;
2085 int vrf_header = 1;
2086
2087 char *proto = argv[argc - 1]->text;
2088 type = proto_redistnum (AFI_IP, proto);
2089
2090 if (type < 0)
2091 {
2092 vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
2093 return CMD_WARNING;
2094 }
2095
2096 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
2097 {
2098 if ((zvrf = vrf->info) == NULL ||
2099 (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
2100 continue;
2101
2102 /* Show matched type IPv4 routes. */
2103 for (rn = route_top (table); rn; rn = route_next (rn))
2104 RNODE_FOREACH_RIB (rn, rib)
2105 if (rib->type == type)
2106 {
2107 if (first)
2108 {
2109 vty_out (vty, SHOW_ROUTE_V4_HEADER);
2110 first = 0;
2111 }
2112
2113 if (vrf_header)
2114 {
2115 vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE);
2116 vrf_header = 0;
2117 }
2118 vty_show_ip_route (vty, rn, rib, NULL);
2119 }
2120 vrf_header = 1;
2121 }
2122
2123 return CMD_SUCCESS;
2124 }
2125
2126 DEFUN (show_ip_route_vrf_all_addr,
2127 show_ip_route_vrf_all_addr_cmd,
2128 "show ip route vrf all A.B.C.D",
2129 SHOW_STR
2130 IP_STR
2131 "IP routing table\n"
2132 VRF_ALL_CMD_HELP_STR
2133 "Network in the IP routing table to display\n")
2134 {
2135 int idx_ipv4 = 5;
2136 int ret;
2137 struct prefix_ipv4 p;
2138 struct route_table *table;
2139 struct route_node *rn;
2140 struct vrf *vrf;
2141 struct zebra_vrf *zvrf;
2142
2143 ret = str2prefix_ipv4 (argv[idx_ipv4]->arg, &p);
2144 if (ret <= 0)
2145 {
2146 vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
2147 return CMD_WARNING;
2148 }
2149
2150 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
2151 {
2152 if ((zvrf = vrf->info) == NULL ||
2153 (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
2154 continue;
2155
2156 rn = route_node_match (table, (struct prefix *) &p);
2157 if (! rn)
2158 continue;
2159
2160 vty_show_ip_route_detail (vty, rn, 0);
2161
2162 route_unlock_node (rn);
2163 }
2164
2165 return CMD_SUCCESS;
2166 }
2167
2168 DEFUN (show_ip_route_vrf_all_prefix,
2169 show_ip_route_vrf_all_prefix_cmd,
2170 "show ip route vrf all A.B.C.D/M",
2171 SHOW_STR
2172 IP_STR
2173 "IP routing table\n"
2174 VRF_ALL_CMD_HELP_STR
2175 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
2176 {
2177 int idx_ipv4_prefixlen = 5;
2178 int ret;
2179 struct prefix_ipv4 p;
2180 struct route_table *table;
2181 struct route_node *rn;
2182 struct vrf *vrf;
2183 struct zebra_vrf *zvrf;
2184
2185 ret = str2prefix_ipv4 (argv[idx_ipv4_prefixlen]->arg, &p);
2186 if (ret <= 0)
2187 {
2188 vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
2189 return CMD_WARNING;
2190 }
2191
2192 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
2193 {
2194 if ((zvrf = vrf->info) == NULL ||
2195 (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
2196 continue;
2197
2198 rn = route_node_match (table, (struct prefix *) &p);
2199 if (! rn)
2200 continue;
2201 if (rn->p.prefixlen != p.prefixlen)
2202 {
2203 route_unlock_node (rn);
2204 continue;
2205 }
2206
2207 vty_show_ip_route_detail (vty, rn, 0);
2208
2209 route_unlock_node (rn);
2210 }
2211
2212 return CMD_SUCCESS;
2213 }
2214
2215 DEFUN (show_ip_route_vrf_all_summary,
2216 show_ip_route_vrf_all_summary_cmd,
2217 "show ip route vrf all summary ",
2218 SHOW_STR
2219 IP_STR
2220 "IP routing table\n"
2221 VRF_ALL_CMD_HELP_STR
2222 "Summary of all routes\n")
2223 {
2224 struct vrf *vrf;
2225 struct zebra_vrf *zvrf;
2226
2227 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
2228 if ((zvrf = vrf->info) != NULL)
2229 vty_show_ip_route_summary (vty, zvrf->table[AFI_IP][SAFI_UNICAST]);
2230
2231 return CMD_SUCCESS;
2232 }
2233
2234 DEFUN (show_ip_route_vrf_all_summary_prefix,
2235 show_ip_route_vrf_all_summary_prefix_cmd,
2236 "show ip route vrf all summary prefix",
2237 SHOW_STR
2238 IP_STR
2239 "IP routing table\n"
2240 VRF_ALL_CMD_HELP_STR
2241 "Summary of all routes\n"
2242 "Prefix routes\n")
2243 {
2244 struct vrf *vrf;
2245 struct zebra_vrf *zvrf;
2246
2247 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
2248 if ((zvrf = vrf->info) != NULL)
2249 vty_show_ip_route_summary_prefix (vty, zvrf->table[AFI_IP][SAFI_UNICAST]);
2250
2251 return CMD_SUCCESS;
2252 }
2253
2254 /* Write IPv4 static route configuration. */
2255 static int
2256 static_config_ipv4 (struct vty *vty, safi_t safi, const char *cmd)
2257 {
2258 struct route_node *rn;
2259 struct static_route *si;
2260 struct route_table *stable;
2261 struct vrf *vrf;
2262 struct zebra_vrf *zvrf;
2263 char buf[BUFSIZ];
2264 int write =0;
2265
2266 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
2267 {
2268 if (!(zvrf = vrf->info))
2269 continue;
2270 if ((stable = zvrf->stable[AFI_IP][safi]) == NULL)
2271 continue;
2272
2273 for (rn = route_top (stable); rn; rn = route_next (rn))
2274 for (si = rn->info; si; si = si->next)
2275 {
2276 vty_out (vty, "%s %s", cmd, prefix2str (&rn->p, buf, sizeof buf));
2277
2278 switch (si->type)
2279 {
2280 case STATIC_IPV4_GATEWAY:
2281 vty_out (vty, " %s", inet_ntoa (si->addr.ipv4));
2282 break;
2283 case STATIC_IFINDEX:
2284 vty_out (vty, " %s", si->ifname);
2285 break;
2286 case STATIC_BLACKHOLE:
2287 vty_out (vty, " Null0");
2288 break;
2289 case STATIC_IPV6_GATEWAY:
2290 vty_out (vty, " %s", inet_ntop (AF_INET6, &si->addr.ipv6, buf, BUFSIZ));
2291 break;
2292 case STATIC_IPV6_GATEWAY_IFINDEX:
2293 vty_out (vty, " %s %s",
2294 inet_ntop (AF_INET6, &si->addr.ipv6, buf, BUFSIZ),
2295 ifindex2ifname (si->ifindex, si->vrf_id));
2296 break;
2297 }
2298
2299 /* flags are incompatible with STATIC_BLACKHOLE */
2300 if (si->type != STATIC_BLACKHOLE)
2301 {
2302 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_REJECT))
2303 vty_out (vty, " %s", "reject");
2304
2305 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_BLACKHOLE))
2306 vty_out (vty, " %s", "blackhole");
2307 }
2308
2309 if (si->tag)
2310 vty_out (vty, " tag %"ROUTE_TAG_PRI, si->tag);
2311
2312 if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT)
2313 vty_out (vty, " %d", si->distance);
2314
2315 if (si->vrf_id != VRF_DEFAULT)
2316 vty_out (vty, " vrf %s", zvrf ? zvrf_name (zvrf) : "");
2317
2318 /* Label information */
2319 if (si->snh_label.num_labels)
2320 vty_out (vty, " label %s",
2321 mpls_label2str (si->snh_label.num_labels,
2322 si->snh_label.label, buf, sizeof buf));
2323
2324 vty_out (vty, "%s", VTY_NEWLINE);
2325
2326 write = 1;
2327 }
2328 }
2329 return write;
2330 }
2331
2332 /* General fucntion for IPv6 static route. */
2333 int
2334 static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str,
2335 const char *src_str,
2336 const char *gate_str, const char *ifname,
2337 const char *flag_str, const char *tag_str,
2338 const char *distance_str, const char *vrf_id_str,
2339 const char *label_str)
2340 {
2341 int ret;
2342 u_char distance;
2343 struct prefix p, src;
2344 struct prefix_ipv6 *src_p = NULL;
2345 struct in6_addr *gate = NULL;
2346 struct in6_addr gate_addr;
2347 u_char type = STATIC_BLACKHOLE;
2348 u_char flag = 0;
2349 route_tag_t tag = 0;
2350 unsigned int ifindex = 0;
2351 struct interface *ifp = NULL;
2352 struct zebra_vrf *zvrf;
2353 struct static_nh_label snh_label;
2354
2355 ret = str2prefix (dest_str, &p);
2356 if (ret <= 0)
2357 {
2358 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
2359 return CMD_WARNING;
2360 }
2361
2362 if (src_str)
2363 {
2364 ret = str2prefix (src_str, &src);
2365 if (ret <= 0 || src.family != AF_INET6)
2366 {
2367 vty_out (vty, "%% Malformed source address%s", VTY_NEWLINE);
2368 return CMD_WARNING;
2369 }
2370 src_p = (struct prefix_ipv6*)&src;
2371 }
2372
2373 /* Apply mask for given prefix. */
2374 apply_mask (&p);
2375
2376 /* Administrative distance. */
2377 if (distance_str)
2378 distance = atoi (distance_str);
2379 else
2380 distance = ZEBRA_STATIC_DISTANCE_DEFAULT;
2381
2382 /* tag */
2383 if (tag_str)
2384 VTY_GET_INTEGER_RANGE("tag", tag, tag_str, 0, 4294967295);
2385
2386 /* When gateway is valid IPv6 addrees, then gate is treated as
2387 nexthop address other case gate is treated as interface name. */
2388 ret = inet_pton (AF_INET6, gate_str, &gate_addr);
2389
2390 /* VRF id */
2391 zvrf = zebra_vrf_lookup_by_name (vrf_id_str);
2392
2393 if (!zvrf)
2394 {
2395 vty_out (vty, "%% vrf %s is not defined%s", vrf_id_str, VTY_NEWLINE);
2396 return CMD_WARNING;
2397 }
2398
2399 /* Labels */
2400 memset (&snh_label, 0, sizeof (struct static_nh_label));
2401 if (label_str)
2402 {
2403 if (!mpls_enabled)
2404 {
2405 vty_out (vty, "%% MPLS not turned on in kernel, ignoring command%s",
2406 VTY_NEWLINE);
2407 return CMD_WARNING;
2408 }
2409 if (mpls_str2label (label_str, &snh_label.num_labels,
2410 snh_label.label))
2411 {
2412 vty_out (vty, "%% Malformed label(s)%s", VTY_NEWLINE);
2413 return CMD_WARNING;
2414 }
2415 }
2416
2417 /* Null0 static route. */
2418 if ((gate_str != NULL) && (strncasecmp (gate_str, "Null0", strlen (gate_str)) == 0))
2419 {
2420 if (flag_str)
2421 {
2422 vty_out (vty, "%% can not have flag %s with Null0%s", flag_str, VTY_NEWLINE);
2423 return CMD_WARNING;
2424 }
2425 if (add_cmd)
2426 static_add_route (AFI_IP6, SAFI_UNICAST, type, &p, NULL, NULL, ifindex, ifname,
2427 ZEBRA_FLAG_BLACKHOLE, tag, distance, zvrf, &snh_label);
2428 else
2429 static_delete_route (AFI_IP6, SAFI_UNICAST, type, &p, NULL, NULL, ifindex, tag,
2430 distance, zvrf, &snh_label);
2431 return CMD_SUCCESS;
2432 }
2433
2434 /* Route flags */
2435 if (flag_str) {
2436 switch(flag_str[0]) {
2437 case 'r':
2438 case 'R': /* XXX */
2439 SET_FLAG (flag, ZEBRA_FLAG_REJECT);
2440 break;
2441 case 'b':
2442 case 'B': /* XXX */
2443 SET_FLAG (flag, ZEBRA_FLAG_BLACKHOLE);
2444 break;
2445 default:
2446 vty_out (vty, "%% Malformed flag %s %s", flag_str, VTY_NEWLINE);
2447 return CMD_WARNING;
2448 }
2449 }
2450
2451 if (ifname)
2452 {
2453 /* When ifname is specified. It must be come with gateway
2454 address. */
2455 if (ret != 1)
2456 {
2457 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
2458 return CMD_WARNING;
2459 }
2460 type = STATIC_IPV6_GATEWAY_IFINDEX;
2461 gate = &gate_addr;
2462 ifp = if_lookup_by_name (ifname, zvrf_id (zvrf));
2463 if (!ifp)
2464 {
2465 vty_out (vty, "%% Malformed Interface name %s%s", ifname, VTY_NEWLINE);
2466 return CMD_WARNING;
2467 }
2468 ifindex = ifp->ifindex;
2469 }
2470 else
2471 {
2472 if (ret == 1)
2473 {
2474 type = STATIC_IPV6_GATEWAY;
2475 gate = &gate_addr;
2476 }
2477 else
2478 {
2479 type = STATIC_IFINDEX;
2480 ifp = if_lookup_by_name (gate_str, zvrf_id (zvrf));
2481 if (!ifp)
2482 {
2483 vty_out (vty, "%% Malformed Interface name %s%s", gate_str, VTY_NEWLINE);
2484 ifindex = IFINDEX_DELETED;
2485 }
2486 else
2487 ifindex = ifp->ifindex;
2488 ifname = gate_str;
2489 }
2490 }
2491
2492 if (add_cmd)
2493 static_add_route (AFI_IP6, SAFI_UNICAST, type, &p, src_p, (union g_addr *)gate,
2494 ifindex, ifname, flag, tag, distance, zvrf, &snh_label);
2495 else
2496 static_delete_route (AFI_IP6, SAFI_UNICAST, type, &p, src_p, (union g_addr *)gate,
2497 ifindex, tag, distance, zvrf, &snh_label);
2498
2499 return CMD_SUCCESS;
2500 }
2501
2502 DEFUN (ipv6_route,
2503 ipv6_route_cmd,
2504 "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]",
2505 IP_STR
2506 "Establish static routes\n"
2507 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2508 "IPv6 source-dest route\n"
2509 "IPv6 source prefix\n"
2510 "IPv6 gateway address\n"
2511 "IPv6 gateway interface name\n"
2512 "Null interface\n"
2513 "Null interface\n"
2514 "Set tag for this route\n"
2515 "Tag value\n"
2516 "Distance value for this prefix\n"
2517 VRF_CMD_HELP_STR
2518 "Specify labels for this route\n"
2519 "One or more labels separated by '/'\n")
2520 {
2521 int idx_ipv6_prefixlen = 2;
2522 int idx_ipv6_ifname;
2523 int idx_curr;
2524 char *src, *tag, *distance, *vrf;
2525
2526 if (!strcmp(argv[3]->text, "from"))
2527 {
2528 src = argv[4]->arg;
2529 idx_ipv6_ifname = 5;
2530 idx_curr = 6;
2531 }
2532 else
2533 {
2534 src = NULL;
2535 idx_ipv6_ifname = 3;
2536 idx_curr = 4;
2537 }
2538
2539 tag = distance = vrf = NULL;
2540 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
2541
2542 return static_ipv6_func (vty, 1,
2543 argv[idx_ipv6_prefixlen]->arg,
2544 src,
2545 argv[idx_ipv6_ifname]->arg,
2546 NULL, NULL,
2547 tag, distance, vrf, NULL);
2548 }
2549
2550 DEFUN (ipv6_route_flags,
2551 ipv6_route_flags_cmd,
2552 "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]",
2553 IP_STR
2554 "Establish static routes\n"
2555 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2556 "IPv6 source-dest route\n"
2557 "IPv6 source prefix\n"
2558 "IPv6 gateway address\n"
2559 "IPv6 gateway interface name\n"
2560 "Emit an ICMP unreachable when matched\n"
2561 "Silently discard pkts when matched\n"
2562 "Silently discard pkts when matched\n"
2563 "Set tag for this route\n"
2564 "Tag value\n"
2565 "Distance value for this prefix\n"
2566 VRF_CMD_HELP_STR
2567 "Specify labels for this route\n"
2568 "One or more labels separated by '/'\n")
2569 {
2570 int idx_ipv6_prefixlen = 2;
2571 int idx_ipv6_ifname;
2572 int idx_reject_blackhole;
2573 int idx_curr;
2574 char *src, *tag, *distance, *vrf;
2575
2576 if (!strcmp(argv[3]->text, "from"))
2577 {
2578 src = argv[4]->arg;
2579 idx_ipv6_ifname = 5;
2580 idx_reject_blackhole = 6;
2581 idx_curr = 7;
2582 }
2583 else
2584 {
2585 src = NULL;
2586 idx_ipv6_ifname = 3;
2587 idx_reject_blackhole = 4;
2588 idx_curr = 5;
2589 }
2590
2591 tag = distance = vrf = NULL;
2592 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
2593
2594 return static_ipv6_func (vty, 1,
2595 argv[idx_ipv6_prefixlen]->arg,
2596 src,
2597 argv[idx_ipv6_ifname]->arg,
2598 NULL,
2599 argv[idx_reject_blackhole]->arg,
2600 tag, distance, vrf, NULL);
2601 }
2602
2603 DEFUN (ipv6_route_ifname,
2604 ipv6_route_ifname_cmd,
2605 "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]",
2606 IP_STR
2607 "Establish static routes\n"
2608 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2609 "IPv6 source-dest route\n"
2610 "IPv6 source prefix\n"
2611 "IPv6 gateway address\n"
2612 "IPv6 gateway interface name\n"
2613 "Set tag for this route\n"
2614 "Tag value\n"
2615 "Distance value for this prefix\n"
2616 VRF_CMD_HELP_STR
2617 "Specify labels for this route\n"
2618 "One or more labels separated by '/'\n")
2619 {
2620 int idx_ipv6_prefixlen = 2;
2621 int idx_ipv6 = 3;
2622 int idx_interface = 4;
2623 int idx_curr = 5;
2624 char *src, *tag, *distance, *vrf;
2625
2626 if (!strcmp(argv[3]->text, "from"))
2627 {
2628 src = argv[4]->arg;
2629 idx_ipv6 = 5;
2630 idx_interface = 6;
2631 idx_curr = 7;
2632 }
2633 else
2634 {
2635 src = NULL;
2636 idx_ipv6 = 3;
2637 idx_interface = 4;
2638 idx_curr = 5;
2639 }
2640
2641 tag = distance = vrf = NULL;
2642 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
2643
2644 return static_ipv6_func (vty, 1,
2645 argv[idx_ipv6_prefixlen]->arg,
2646 src,
2647 argv[idx_ipv6]->arg,
2648 argv[idx_interface]->arg,
2649 NULL,
2650 tag, distance, vrf, NULL);
2651 }
2652
2653 DEFUN (ipv6_route_ifname_flags,
2654 ipv6_route_ifname_flags_cmd,
2655 "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]",
2656 IP_STR
2657 "Establish static routes\n"
2658 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2659 "IPv6 source-dest route\n"
2660 "IPv6 source prefix\n"
2661 "IPv6 gateway address\n"
2662 "IPv6 gateway interface name\n"
2663 "Emit an ICMP unreachable when matched\n"
2664 "Silently discard pkts when matched\n"
2665 "Set tag for this route\n"
2666 "Tag value\n"
2667 "Distance value for this prefix\n"
2668 VRF_CMD_HELP_STR
2669 "Specify labels for this route\n"
2670 "One or more labels separated by '/'\n")
2671 {
2672 int idx_ipv6_prefixlen = 2;
2673 int idx_ipv6;
2674 int idx_interface;
2675 int idx_reject_blackhole;
2676 int idx_curr;
2677 char *src, *tag, *distance, *vrf;
2678
2679 if (!strcmp(argv[3]->text, "from"))
2680 {
2681 src = argv[4]->arg;
2682 idx_ipv6 = 5;
2683 idx_interface = 6;
2684 idx_reject_blackhole = 7;
2685 idx_curr = 8;
2686 }
2687 else
2688 {
2689 src = NULL;
2690 idx_ipv6 = 3;
2691 idx_interface = 4;
2692 idx_reject_blackhole = 5;
2693 idx_curr = 6;
2694 }
2695
2696 tag = distance = vrf = NULL;
2697 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
2698
2699 return static_ipv6_func (vty, 1,
2700 argv[idx_ipv6_prefixlen]->arg,
2701 src,
2702 argv[idx_ipv6]->arg,
2703 argv[idx_interface]->arg,
2704 argv[idx_reject_blackhole]->arg,
2705 tag, distance, vrf, NULL);
2706 }
2707
2708 DEFUN (no_ipv6_route,
2709 no_ipv6_route_cmd,
2710 "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]",
2711 NO_STR
2712 IP_STR
2713 "Establish static routes\n"
2714 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2715 "IPv6 source-dest route\n"
2716 "IPv6 source prefix\n"
2717 "IPv6 gateway address\n"
2718 "IPv6 gateway interface name\n"
2719 "Null interface\n"
2720 "Set tag for this route\n"
2721 "Tag value\n"
2722 "Distance value for this prefix\n"
2723 VRF_CMD_HELP_STR
2724 "Specify labels for this route\n"
2725 "One or more labels separated by '/'\n")
2726 {
2727 int idx_ipv6_prefixlen = 3;
2728 int idx_ipv6_ifname;
2729 int idx_curr;
2730 char *src, *tag, *distance, *vrf;
2731
2732 if (!strcmp(argv[4]->text, "from"))
2733 {
2734 src = argv[5]->arg;
2735 idx_ipv6_ifname = 6;
2736 idx_curr = 7;
2737 }
2738 else
2739 {
2740 src = NULL;
2741 idx_ipv6_ifname = 4;
2742 idx_curr = 5;
2743 }
2744
2745 tag = distance = vrf = NULL;
2746 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
2747
2748 return static_ipv6_func (vty, 0,
2749 argv[idx_ipv6_prefixlen]->arg,
2750 src,
2751 argv[idx_ipv6_ifname]->arg,
2752 NULL, NULL,
2753 tag, distance, vrf, NULL);
2754 }
2755
2756 DEFUN (no_ipv6_route_flags,
2757 no_ipv6_route_flags_cmd,
2758 "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]",
2759 NO_STR
2760 IP_STR
2761 "Establish static routes\n"
2762 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2763 "IPv6 source-dest route\n"
2764 "IPv6 source prefix\n"
2765 "IPv6 gateway address\n"
2766 "IPv6 gateway interface name\n"
2767 "Emit an ICMP unreachable when matched\n"
2768 "Silently discard pkts when matched\n"
2769 "Set tag for this route\n"
2770 "Tag value\n"
2771 "Distance value for this prefix\n"
2772 VRF_CMD_HELP_STR
2773 "Specify labels for this route\n"
2774 "One or more labels separated by '/'\n")
2775 {
2776 int idx_ipv6_prefixlen = 3;
2777 int idx_ipv6_ifname;
2778 int idx_reject_blackhole;
2779 int idx_curr;
2780 char *src, *tag, *distance, *vrf;
2781
2782 if (!strcmp(argv[4]->text, "from"))
2783 {
2784 src = argv[5]->arg;
2785 idx_ipv6_ifname = 6;
2786 idx_reject_blackhole = 7;
2787 idx_curr = 8;
2788 }
2789 else
2790 {
2791 src = NULL;
2792 idx_ipv6_ifname = 4;
2793 idx_reject_blackhole = 5;
2794 idx_curr = 6;
2795 }
2796
2797 tag = distance = vrf = NULL;
2798 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
2799
2800 return static_ipv6_func (vty, 0,
2801 argv[idx_ipv6_prefixlen]->arg,
2802 src,
2803 argv[idx_ipv6_ifname]->arg,
2804 NULL,
2805 argv[idx_reject_blackhole]->arg,
2806 tag, distance, vrf, NULL);
2807 }
2808
2809 DEFUN (no_ipv6_route_ifname,
2810 no_ipv6_route_ifname_cmd,
2811 "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]",
2812 NO_STR
2813 IP_STR
2814 "Establish static routes\n"
2815 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2816 "IPv6 source-dest route\n"
2817 "IPv6 source prefix\n"
2818 "IPv6 gateway address\n"
2819 "IPv6 gateway interface name\n"
2820 "Set tag for this route\n"
2821 "Tag value\n"
2822 "Distance value for this prefix\n"
2823 VRF_CMD_HELP_STR
2824 "Specify labels for this route\n"
2825 "One or more labels separated by '/'\n")
2826 {
2827 int idx_ipv6_prefixlen = 3;
2828 int idx_ipv6;
2829 int idx_interface;
2830 int idx_curr;
2831 char *src, *tag, *distance, *vrf;
2832
2833 if (!strcmp(argv[4]->text, "from"))
2834 {
2835 src = argv[5]->arg;
2836 idx_ipv6 = 6;
2837 idx_interface = 7;
2838 idx_curr = 8;
2839 }
2840 else
2841 {
2842 src = NULL;
2843 idx_ipv6 = 4;
2844 idx_interface = 5;
2845 idx_curr = 6;
2846 }
2847
2848 tag = distance = vrf = NULL;
2849 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
2850
2851 return static_ipv6_func (vty, 0,
2852 argv[idx_ipv6_prefixlen]->arg,
2853 src,
2854 argv[idx_ipv6]->arg,
2855 argv[idx_interface]->arg,
2856 NULL,
2857 tag, distance, vrf, NULL);
2858 }
2859
2860 DEFUN (no_ipv6_route_ifname_flags,
2861 no_ipv6_route_ifname_flags_cmd,
2862 "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]",
2863 NO_STR
2864 IP_STR
2865 "Establish static routes\n"
2866 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2867 "IPv6 source-dest route\n"
2868 "IPv6 source prefix\n"
2869 "IPv6 gateway address\n"
2870 "IPv6 gateway interface name\n"
2871 "Emit an ICMP unreachable when matched\n"
2872 "Silently discard pkts when matched\n"
2873 "Set tag for this route\n"
2874 "Tag value\n"
2875 "Distance value for this prefix\n"
2876 VRF_CMD_HELP_STR
2877 "Specify labels for this route\n"
2878 "One or more labels separated by '/'\n")
2879 {
2880 int idx_ipv6_prefixlen = 3;
2881 int idx_ipv6;
2882 int idx_interface;
2883 int idx_reject_blackhole;
2884 int idx_curr;
2885 char *src, *tag, *distance, *vrf;
2886
2887 if (!strcmp(argv[4]->text, "from"))
2888 {
2889 src = argv[5]->arg;
2890 idx_ipv6 = 6;
2891 idx_interface = 7;
2892 idx_reject_blackhole = 8;
2893 idx_curr = 9;
2894 }
2895 else
2896 {
2897 src = NULL;
2898 idx_ipv6 = 4;
2899 idx_interface = 5;
2900 idx_reject_blackhole = 6;
2901 idx_curr = 7;
2902 }
2903
2904 tag = distance = vrf = NULL;
2905 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
2906
2907 return static_ipv6_func (vty, 0,
2908 argv[idx_ipv6_prefixlen]->arg,
2909 src,
2910 argv[idx_ipv6]->arg,
2911 argv[idx_interface]->arg,
2912 argv[idx_reject_blackhole]->arg,
2913 tag, distance, vrf, NULL);
2914 }
2915
2916 DEFUN (show_ipv6_route,
2917 show_ipv6_route_cmd,
2918 "show ipv6 route [vrf NAME] [json]",
2919 SHOW_STR
2920 IP_STR
2921 "IPv6 routing table\n"
2922 VRF_CMD_HELP_STR
2923 "Output JSON\n")
2924 {
2925 struct route_table *table;
2926 struct route_node *rn;
2927 struct rib *rib;
2928 int first = 1;
2929 vrf_id_t vrf_id = VRF_DEFAULT;
2930 struct zebra_vrf *zvrf = NULL;
2931 char buf[SRCDEST2STR_BUFFER];
2932 json_object *json = NULL;
2933 json_object *json_prefix = NULL;
2934
2935 int vrf = (argc > 3 && strmatch (argv[3]->text, "vrf"));
2936 int uj = vrf ? argc == 6 : argc == 4;
2937 char *vrfname = vrf ? argv[4]->arg : NULL;
2938
2939 if (vrf)
2940 {
2941 if (!(zvrf = zebra_vrf_lookup_by_name (vrfname)))
2942 {
2943 if (uj)
2944 vty_out (vty, "{}%s", VTY_NEWLINE);
2945 else
2946 vty_out (vty, "vrf %s not defined%s", vrfname, VTY_NEWLINE);
2947 return CMD_SUCCESS;
2948 }
2949
2950 if (zvrf_id (zvrf) == VRF_UNKNOWN)
2951 {
2952 if (uj)
2953 vty_out (vty, "{}%s", VTY_NEWLINE);
2954 else
2955 vty_out (vty, "vrf %s inactive%s", vrfname, VTY_NEWLINE);
2956 return CMD_SUCCESS;
2957 }
2958 else
2959 vrf_id = zvrf_id (zvrf);
2960 }
2961
2962 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2963 if (!table)
2964 {
2965 if (uj)
2966 vty_out (vty, "{}%s", VTY_NEWLINE);
2967 return CMD_SUCCESS;
2968 }
2969
2970 if (uj)
2971 {
2972 json = json_object_new_object();
2973
2974 /* Show all IPv6 route. */
2975 for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
2976 {
2977 RNODE_FOREACH_RIB (rn, rib)
2978 {
2979 if (!json_prefix)
2980 json_prefix = json_object_new_array();
2981 vty_show_ip_route (vty, rn, rib, json_prefix);
2982 }
2983
2984 if (json_prefix)
2985 {
2986 srcdest_rnode2str (rn, buf, sizeof buf);
2987 json_object_object_add(json, buf, json_prefix);
2988 json_prefix = NULL;
2989 }
2990 }
2991
2992 vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
2993 json_object_free(json);
2994 }
2995 else
2996 {
2997 /* Show all IPv6 route. */
2998 for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
2999 {
3000 RNODE_FOREACH_RIB (rn, rib)
3001 {
3002 if (first)
3003 {
3004 vty_out (vty, SHOW_ROUTE_V6_HEADER);
3005 first = 0;
3006 }
3007 vty_show_ip_route (vty, rn, rib, NULL);
3008 }
3009 }
3010 }
3011
3012 return CMD_SUCCESS;
3013 }
3014
3015 DEFUN (show_ipv6_route_tag,
3016 show_ipv6_route_tag_cmd,
3017 "show ipv6 route [vrf NAME] tag (1-4294967295)",
3018 SHOW_STR
3019 IP_STR
3020 "IPv6 routing table\n"
3021 VRF_CMD_HELP_STR
3022 "Show only routes with tag\n"
3023 "Tag value\n")
3024 {
3025 int idx_vrf = 3;
3026 int idx_name = 4;
3027 int idx_tag = 6;
3028 struct route_table *table;
3029 struct route_node *rn;
3030 struct rib *rib;
3031 int first = 1;
3032 route_tag_t tag = 0;
3033 vrf_id_t vrf_id = VRF_DEFAULT;
3034
3035 if (strmatch(argv[idx_vrf]->text, "vrf"))
3036 {
3037 VRF_GET_ID (vrf_id, argv[idx_name]->arg);
3038 VTY_GET_INTEGER_RANGE("tag", tag, argv[idx_tag]->arg, 0, 4294967295);
3039 }
3040 else
3041 {
3042 idx_tag -= 2;
3043 VTY_GET_INTEGER_RANGE("tag", tag, argv[idx_tag]->arg, 0, 4294967295);
3044 }
3045
3046 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
3047 if (! table)
3048 return CMD_SUCCESS;
3049
3050 /* Show all IPv6 routes with matching tag value. */
3051 for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
3052 RNODE_FOREACH_RIB (rn, rib)
3053 {
3054 if (rib->tag != tag)
3055 continue;
3056
3057 if (first)
3058 {
3059 vty_out (vty, SHOW_ROUTE_V6_HEADER);
3060 first = 0;
3061 }
3062 vty_show_ip_route (vty, rn, rib, NULL);
3063 }
3064 return CMD_SUCCESS;
3065 }
3066
3067 DEFUN (show_ipv6_route_prefix_longer,
3068 show_ipv6_route_prefix_longer_cmd,
3069 "show ipv6 route [vrf NAME] X:X::X:X/M longer-prefixes",
3070 SHOW_STR
3071 IP_STR
3072 "IPv6 routing table\n"
3073 VRF_CMD_HELP_STR
3074 "IPv6 prefix\n"
3075 "Show route matching the specified Network/Mask pair only\n")
3076 {
3077 struct route_table *table;
3078 struct route_node *rn;
3079 struct rib *rib;
3080 struct prefix p;
3081 int ret;
3082 int first = 1;
3083 vrf_id_t vrf_id = VRF_DEFAULT;
3084
3085 if (strmatch(argv[3]->text, "vrf"))
3086 {
3087 VRF_GET_ID (vrf_id, argv[4]->arg);
3088 ret = str2prefix (argv[5]->arg, &p);
3089 }
3090 else
3091 {
3092 ret = str2prefix (argv[3]->arg, &p);
3093 }
3094
3095 if (! ret)
3096 {
3097 vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE);
3098 return CMD_WARNING;
3099 }
3100
3101 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
3102 if (! table)
3103 return CMD_SUCCESS;
3104
3105 /* Show matched type IPv6 routes. */
3106 for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
3107 RNODE_FOREACH_RIB (rn, rib)
3108 {
3109 struct prefix *p, *src_p;
3110 srcdest_rnode_prefixes(rn, &p, &src_p);
3111
3112 if (prefix_match (p, &rn->p))
3113 {
3114 if (first)
3115 {
3116 vty_out (vty, SHOW_ROUTE_V6_HEADER);
3117 first = 0;
3118 }
3119 vty_show_ip_route (vty, rn, rib, NULL);
3120 }
3121 }
3122 return CMD_SUCCESS;
3123 }
3124
3125 DEFUN (show_ipv6_route_protocol,
3126 show_ipv6_route_protocol_cmd,
3127 "show ipv6 route [vrf NAME] " FRR_IP6_REDIST_STR_ZEBRA,
3128 SHOW_STR
3129 IP_STR
3130 "IP routing table\n"
3131 VRF_CMD_HELP_STR
3132 FRR_IP6_REDIST_HELP_STR_ZEBRA)
3133 {
3134 int type;
3135 struct route_table *table;
3136 struct route_node *rn;
3137 struct rib *rib;
3138 int first = 1;
3139 vrf_id_t vrf_id = VRF_DEFAULT;
3140
3141 int idx = 0;
3142 if (argv_find (argv, argc, "NAME", &idx))
3143 VRF_GET_ID (vrf_id, argv[idx]->arg);
3144
3145 char *proto = argv[argc - 1]->text;
3146 type = proto_redistnum (AFI_IP6, proto);
3147
3148 if (type < 0)
3149 {
3150 vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
3151 return CMD_WARNING;
3152 }
3153
3154 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
3155 if (! table)
3156 return CMD_SUCCESS;
3157
3158 /* Show matched type IPv6 routes. */
3159 for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
3160 RNODE_FOREACH_RIB (rn, rib)
3161 if (rib->type == type)
3162 {
3163 if (first)
3164 {
3165 vty_out (vty, SHOW_ROUTE_V6_HEADER);
3166 first = 0;
3167 }
3168 vty_show_ip_route (vty, rn, rib, NULL);
3169 }
3170 return CMD_SUCCESS;
3171 }
3172
3173 DEFUN (show_ipv6_route_addr,
3174 show_ipv6_route_addr_cmd,
3175 "show ipv6 route [vrf NAME] X:X::X:X",
3176 SHOW_STR
3177 IP_STR
3178 "IPv6 routing table\n"
3179 VRF_CMD_HELP_STR
3180 "IPv6 Address\n")
3181 {
3182 int ret;
3183 struct prefix_ipv6 p;
3184 struct route_table *table;
3185 struct route_node *rn;
3186 vrf_id_t vrf_id = VRF_DEFAULT;
3187
3188 if (strmatch(argv[3]->text, "vrf"))
3189 {
3190 VRF_GET_ID (vrf_id, argv[4]->arg);
3191 ret = str2prefix_ipv6 (argv[5]->arg, &p);
3192 }
3193 else
3194 {
3195 ret = str2prefix_ipv6 (argv[3]->arg, &p);
3196 }
3197
3198 if (ret <= 0)
3199 {
3200 vty_out (vty, "Malformed IPv6 address%s", VTY_NEWLINE);
3201 return CMD_WARNING;
3202 }
3203
3204 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
3205 if (! table)
3206 return CMD_SUCCESS;
3207
3208 rn = route_node_match (table, (struct prefix *) &p);
3209 if (! rn)
3210 {
3211 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
3212 return CMD_WARNING;
3213 }
3214
3215 vty_show_ip_route_detail (vty, rn, 0);
3216
3217 route_unlock_node (rn);
3218
3219 return CMD_SUCCESS;
3220 }
3221
3222 DEFUN (show_ipv6_route_prefix,
3223 show_ipv6_route_prefix_cmd,
3224 "show ipv6 route [vrf NAME] X:X::X:X/M",
3225 SHOW_STR
3226 IP_STR
3227 "IPv6 routing table\n"
3228 VRF_CMD_HELP_STR
3229 "IPv6 prefix\n")
3230 {
3231 int ret;
3232 struct prefix_ipv6 p;
3233 struct route_table *table;
3234 struct route_node *rn;
3235 vrf_id_t vrf_id = VRF_DEFAULT;
3236
3237 if (strmatch(argv[3]->text, "vrf"))
3238 {
3239 VRF_GET_ID (vrf_id, argv[4]->arg);
3240 ret = str2prefix_ipv6 (argv[5]->arg, &p);
3241 }
3242 else
3243 ret = str2prefix_ipv6 (argv[3]->arg, &p);
3244
3245 if (ret <= 0)
3246 {
3247 vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE);
3248 return CMD_WARNING;
3249 }
3250
3251 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
3252 if (! table)
3253 return CMD_SUCCESS;
3254
3255 rn = route_node_match (table, (struct prefix *) &p);
3256 if (! rn || rn->p.prefixlen != p.prefixlen)
3257 {
3258 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
3259 return CMD_WARNING;
3260 }
3261
3262 vty_show_ip_route_detail (vty, rn, 0);
3263
3264 route_unlock_node (rn);
3265
3266 return CMD_SUCCESS;
3267 }
3268
3269
3270 /* Show route summary. */
3271 DEFUN (show_ipv6_route_summary,
3272 show_ipv6_route_summary_cmd,
3273 "show ipv6 route [vrf NAME] summary",
3274 SHOW_STR
3275 IP_STR
3276 "IPv6 routing table\n"
3277 VRF_CMD_HELP_STR
3278 "Summary of all IPv6 routes\n")
3279 {
3280 struct route_table *table;
3281 vrf_id_t vrf_id = VRF_DEFAULT;
3282
3283 if (strmatch(argv[3]->text, "vrf"))
3284 VRF_GET_ID (vrf_id, argv[4]->arg);
3285
3286 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
3287 if (! table)
3288 return CMD_SUCCESS;
3289
3290 vty_show_ip_route_summary (vty, table);
3291
3292 return CMD_SUCCESS;
3293 }
3294
3295
3296 /* Show ipv6 route summary prefix. */
3297 DEFUN (show_ipv6_route_summary_prefix,
3298 show_ipv6_route_summary_prefix_cmd,
3299 "show ipv6 route [vrf NAME] summary prefix",
3300 SHOW_STR
3301 IP_STR
3302 "IPv6 routing table\n"
3303 VRF_CMD_HELP_STR
3304 "Summary of all IPv6 routes\n"
3305 "Prefix routes\n")
3306 {
3307 struct route_table *table;
3308 vrf_id_t vrf_id = VRF_DEFAULT;
3309
3310 if (strmatch(argv[3]->text, "vrf"))
3311 VRF_GET_ID (vrf_id, argv[4]->arg);
3312
3313 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
3314 if (! table)
3315 return CMD_SUCCESS;
3316
3317 vty_show_ip_route_summary_prefix (vty, table);
3318
3319 return CMD_SUCCESS;
3320 }
3321
3322
3323 /*
3324 * Show IPv6 mroute command.Used to dump
3325 * the Multicast routing table.
3326 */
3327 DEFUN (show_ipv6_mroute,
3328 show_ipv6_mroute_cmd,
3329 "show ipv6 mroute [vrf NAME]",
3330 SHOW_STR
3331 IP_STR
3332 "IPv6 Multicast routing table\n"
3333 VRF_CMD_HELP_STR)
3334 {
3335 struct route_table *table;
3336 struct route_node *rn;
3337 struct rib *rib;
3338 int first = 1;
3339 vrf_id_t vrf_id = VRF_DEFAULT;
3340
3341 if (strmatch(argv[3]->text, "vrf"))
3342 VRF_GET_ID (vrf_id, argv[4]->arg);
3343
3344 table = zebra_vrf_table (AFI_IP6, SAFI_MULTICAST, vrf_id);
3345 if (! table)
3346 return CMD_SUCCESS;
3347
3348 /* Show all IPv6 route. */
3349 for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
3350 RNODE_FOREACH_RIB (rn, rib)
3351 {
3352 if (first)
3353 {
3354 vty_out (vty, SHOW_ROUTE_V6_HEADER);
3355 first = 0;
3356 }
3357 vty_show_ip_route (vty, rn, rib, NULL);
3358 }
3359 return CMD_SUCCESS;
3360 }
3361
3362
3363 DEFUN (show_ipv6_route_vrf_all,
3364 show_ipv6_route_vrf_all_cmd,
3365 "show ipv6 route vrf all",
3366 SHOW_STR
3367 IP_STR
3368 "IPv6 routing table\n"
3369 VRF_ALL_CMD_HELP_STR)
3370 {
3371 struct route_table *table;
3372 struct route_node *rn;
3373 struct rib *rib;
3374 struct vrf *vrf;
3375 struct zebra_vrf *zvrf;
3376 int first = 1;
3377 int vrf_header = 1;
3378
3379 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
3380 {
3381 if ((zvrf = vrf->info) == NULL ||
3382 (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
3383 continue;
3384
3385 /* Show all IPv6 route. */
3386 for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
3387 RNODE_FOREACH_RIB (rn, rib)
3388 {
3389 if (first)
3390 {
3391 vty_out (vty, SHOW_ROUTE_V6_HEADER);
3392 first = 0;
3393 }
3394
3395 if (vrf_header)
3396 {
3397 vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE);
3398 vrf_header = 0;
3399 }
3400 vty_show_ip_route (vty, rn, rib, NULL);
3401 }
3402 vrf_header = 1;
3403 }
3404
3405 return CMD_SUCCESS;
3406 }
3407
3408 DEFUN (show_ipv6_route_vrf_all_tag,
3409 show_ipv6_route_vrf_all_tag_cmd,
3410 "show ipv6 route vrf all tag (1-4294967295)",
3411 SHOW_STR
3412 IP_STR
3413 "IPv6 routing table\n"
3414 VRF_ALL_CMD_HELP_STR
3415 "Show only routes with tag\n"
3416 "Tag value\n")
3417 {
3418 int idx_number = 6;
3419 struct route_table *table;
3420 struct route_node *rn;
3421 struct rib *rib;
3422 struct vrf *vrf;
3423 struct zebra_vrf *zvrf;
3424 int first = 1;
3425 int vrf_header = 1;
3426 route_tag_t tag = 0;
3427
3428 if (argv[idx_number]->arg)
3429 VTY_GET_INTEGER_RANGE("tag", tag, argv[idx_number]->arg, 0, 4294967295);
3430
3431 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
3432 {
3433 if ((zvrf = vrf->info) == NULL ||
3434 (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
3435 continue;
3436
3437 /* Show all IPv6 routes with matching tag value. */
3438 for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
3439 RNODE_FOREACH_RIB (rn, rib)
3440 {
3441 if (rib->tag != tag)
3442 continue;
3443
3444 if (first)
3445 {
3446 vty_out (vty, SHOW_ROUTE_V6_HEADER);
3447 first = 0;
3448 }
3449
3450 if (vrf_header)
3451 {
3452 vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE);
3453 vrf_header = 0;
3454 }
3455 vty_show_ip_route (vty, rn, rib, NULL);
3456 }
3457 vrf_header = 1;
3458 }
3459
3460 return CMD_SUCCESS;
3461 }
3462
3463 DEFUN (show_ipv6_route_vrf_all_prefix_longer,
3464 show_ipv6_route_vrf_all_prefix_longer_cmd,
3465 "show ipv6 route vrf all X:X::X:X/M longer-prefixes",
3466 SHOW_STR
3467 IP_STR
3468 "IPv6 routing table\n"
3469 VRF_ALL_CMD_HELP_STR
3470 "IPv6 prefix\n"
3471 "Show route matching the specified Network/Mask pair only\n")
3472 {
3473 int idx_ipv6_prefixlen = 5;
3474 struct route_table *table;
3475 struct route_node *rn;
3476 struct rib *rib;
3477 struct prefix p;
3478 struct vrf *vrf;
3479 struct zebra_vrf *zvrf;
3480 int ret;
3481 int first = 1;
3482 int vrf_header = 1;
3483
3484 ret = str2prefix (argv[idx_ipv6_prefixlen]->arg, &p);
3485 if (! ret)
3486 {
3487 vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE);
3488 return CMD_WARNING;
3489 }
3490
3491 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
3492 {
3493 if ((zvrf = vrf->info) == NULL ||
3494 (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
3495 continue;
3496
3497 /* Show matched type IPv6 routes. */
3498 for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
3499 RNODE_FOREACH_RIB (rn, rib)
3500 {
3501 struct prefix *p, *src_p;
3502 srcdest_rnode_prefixes(rn, &p, &src_p);
3503 if (prefix_match (p, &rn->p))
3504 {
3505 if (first)
3506 {
3507 vty_out (vty, SHOW_ROUTE_V6_HEADER);
3508 first = 0;
3509 }
3510
3511 if (vrf_header)
3512 {
3513 vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE);
3514 vrf_header = 0;
3515 }
3516 vty_show_ip_route (vty, rn, rib, NULL);
3517 }
3518 }
3519 vrf_header = 1;
3520 }
3521
3522 return CMD_SUCCESS;
3523 }
3524
3525 DEFUN (show_ipv6_route_vrf_all_protocol,
3526 show_ipv6_route_vrf_all_protocol_cmd,
3527 "show ipv6 route vrf all " FRR_IP6_REDIST_STR_ZEBRA,
3528 SHOW_STR
3529 IP_STR
3530 "IP routing table\n"
3531 VRF_ALL_CMD_HELP_STR
3532 FRR_IP6_REDIST_HELP_STR_ZEBRA)
3533 {
3534 int type;
3535 struct route_table *table;
3536 struct route_node *rn;
3537 struct rib *rib;
3538 struct vrf *vrf;
3539 struct zebra_vrf *zvrf;
3540 int first = 1;
3541 int vrf_header = 1;
3542
3543 char *proto = argv[argc - 1]->text;
3544 type = proto_redistnum (AFI_IP6, proto);
3545
3546 if (type < 0)
3547 {
3548 vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
3549 return CMD_WARNING;
3550 }
3551
3552 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
3553 {
3554 if ((zvrf = vrf->info) == NULL ||
3555 (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
3556 continue;
3557
3558 /* Show matched type IPv6 routes. */
3559 for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
3560 RNODE_FOREACH_RIB (rn, rib)
3561 if (rib->type == type)
3562 {
3563 if (first)
3564 {
3565 vty_out (vty, SHOW_ROUTE_V6_HEADER);
3566 first = 0;
3567 }
3568
3569 if (vrf_header)
3570 {
3571 vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE);
3572 vrf_header = 0;
3573 }
3574 vty_show_ip_route (vty, rn, rib, NULL);
3575 }
3576 vrf_header = 1;
3577 }
3578
3579 return CMD_SUCCESS;
3580 }
3581
3582 DEFUN (show_ipv6_route_vrf_all_addr,
3583 show_ipv6_route_vrf_all_addr_cmd,
3584 "show ipv6 route vrf all X:X::X:X",
3585 SHOW_STR
3586 IP_STR
3587 "IPv6 routing table\n"
3588 VRF_ALL_CMD_HELP_STR
3589 "IPv6 Address\n")
3590 {
3591 int idx_ipv6 = 5;
3592 int ret;
3593 struct prefix_ipv6 p;
3594 struct route_table *table;
3595 struct route_node *rn;
3596 struct vrf *vrf;
3597 struct zebra_vrf *zvrf;
3598
3599 ret = str2prefix_ipv6 (argv[idx_ipv6]->arg, &p);
3600 if (ret <= 0)
3601 {
3602 vty_out (vty, "Malformed IPv6 address%s", VTY_NEWLINE);
3603 return CMD_WARNING;
3604 }
3605
3606 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
3607 {
3608 if ((zvrf = vrf->info) == NULL ||
3609 (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
3610 continue;
3611
3612 rn = route_node_match (table, (struct prefix *) &p);
3613 if (! rn)
3614 continue;
3615
3616 vty_show_ip_route_detail (vty, rn, 0);
3617
3618 route_unlock_node (rn);
3619 }
3620
3621 return CMD_SUCCESS;
3622 }
3623
3624 DEFUN (show_ipv6_route_vrf_all_prefix,
3625 show_ipv6_route_vrf_all_prefix_cmd,
3626 "show ipv6 route vrf all X:X::X:X/M",
3627 SHOW_STR
3628 IP_STR
3629 "IPv6 routing table\n"
3630 VRF_ALL_CMD_HELP_STR
3631 "IPv6 prefix\n")
3632 {
3633 int idx_ipv6_prefixlen = 5;
3634 int ret;
3635 struct prefix_ipv6 p;
3636 struct route_table *table;
3637 struct route_node *rn;
3638 struct vrf *vrf;
3639 struct zebra_vrf *zvrf;
3640
3641 ret = str2prefix_ipv6 (argv[idx_ipv6_prefixlen]->arg, &p);
3642 if (ret <= 0)
3643 {
3644 vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE);
3645 return CMD_WARNING;
3646 }
3647
3648 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
3649 {
3650 if ((zvrf = vrf->info) == NULL ||
3651 (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
3652 continue;
3653
3654 rn = route_node_match (table, (struct prefix *) &p);
3655 if (! rn)
3656 continue;
3657 if (rn->p.prefixlen != p.prefixlen)
3658 {
3659 route_unlock_node (rn);
3660 continue;
3661 }
3662
3663 vty_show_ip_route_detail (vty, rn, 0);
3664
3665 route_unlock_node (rn);
3666 }
3667
3668 return CMD_SUCCESS;
3669 }
3670
3671 DEFUN (show_ipv6_route_vrf_all_summary,
3672 show_ipv6_route_vrf_all_summary_cmd,
3673 "show ipv6 route vrf all summary",
3674 SHOW_STR
3675 IP_STR
3676 "IPv6 routing table\n"
3677 VRF_ALL_CMD_HELP_STR
3678 "Summary of all IPv6 routes\n")
3679 {
3680 struct vrf *vrf;
3681 struct zebra_vrf *zvrf;
3682
3683 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
3684 if ((zvrf = vrf->info) != NULL)
3685 vty_show_ip_route_summary (vty, zvrf->table[AFI_IP6][SAFI_UNICAST]);
3686
3687 return CMD_SUCCESS;
3688 }
3689
3690 DEFUN (show_ipv6_mroute_vrf_all,
3691 show_ipv6_mroute_vrf_all_cmd,
3692 "show ipv6 mroute vrf all",
3693 SHOW_STR
3694 IP_STR
3695 "IPv6 Multicast routing table\n"
3696 VRF_ALL_CMD_HELP_STR)
3697 {
3698 struct route_table *table;
3699 struct route_node *rn;
3700 struct rib *rib;
3701 struct vrf *vrf;
3702 struct zebra_vrf *zvrf;
3703 int first = 1;
3704
3705 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
3706 {
3707 if ((zvrf = vrf->info) == NULL ||
3708 (table = zvrf->table[AFI_IP6][SAFI_MULTICAST]) == NULL)
3709 continue;
3710
3711 /* Show all IPv6 route. */
3712 for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
3713 RNODE_FOREACH_RIB (rn, rib)
3714 {
3715 if (first)
3716 {
3717 vty_out (vty, SHOW_ROUTE_V6_HEADER);
3718 first = 0;
3719 }
3720 vty_show_ip_route (vty, rn, rib, NULL);
3721 }
3722 }
3723 return CMD_SUCCESS;
3724 }
3725
3726 DEFUN (show_ipv6_route_vrf_all_summary_prefix,
3727 show_ipv6_route_vrf_all_summary_prefix_cmd,
3728 "show ipv6 route vrf all summary prefix",
3729 SHOW_STR
3730 IP_STR
3731 "IPv6 routing table\n"
3732 VRF_ALL_CMD_HELP_STR
3733 "Summary of all IPv6 routes\n"
3734 "Prefix routes\n")
3735 {
3736 struct vrf *vrf;
3737 struct zebra_vrf *zvrf;
3738
3739 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
3740 if ((zvrf = vrf->info) != NULL)
3741 vty_show_ip_route_summary_prefix (vty, zvrf->table[AFI_IP6][SAFI_UNICAST]);
3742
3743 return CMD_SUCCESS;
3744 }
3745
3746 /* Write IPv6 static route configuration. */
3747 static int
3748 static_config_ipv6 (struct vty *vty)
3749 {
3750 struct route_node *rn;
3751 struct static_route *si;
3752 int write = 0;
3753 char buf[SRCDEST2STR_BUFFER];
3754 struct route_table *stable;
3755 struct vrf *vrf;
3756 struct zebra_vrf *zvrf;
3757
3758 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
3759 {
3760 if (!(zvrf = vrf->info))
3761 continue;
3762 if ((stable = zvrf->stable[AFI_IP6][SAFI_UNICAST]) == NULL)
3763 continue;
3764
3765 for (rn = route_top (stable); rn; rn = srcdest_route_next (rn))
3766 for (si = rn->info; si; si = si->next)
3767 {
3768 vty_out (vty, "ipv6 route %s", srcdest_rnode2str (rn, buf, sizeof buf));
3769
3770 switch (si->type)
3771 {
3772 case STATIC_IPV4_GATEWAY:
3773 vty_out (vty, " %s", inet_ntoa (si->addr.ipv4));
3774 break;
3775 case STATIC_IPV6_GATEWAY:
3776 vty_out (vty, " %s", inet_ntop (AF_INET6, &si->addr.ipv6, buf, BUFSIZ));
3777 break;
3778 case STATIC_IFINDEX:
3779 vty_out (vty, " %s", si->ifname);
3780 break;
3781 case STATIC_BLACKHOLE:
3782 vty_out (vty, " Null0" );
3783 break;
3784 case STATIC_IPV6_GATEWAY_IFINDEX:
3785 vty_out (vty, " %s %s",
3786 inet_ntop (AF_INET6, &si->addr.ipv6, buf, BUFSIZ),
3787 ifindex2ifname (si->ifindex, si->vrf_id));
3788 break;
3789 }
3790
3791 /* flags are incompatible with STATIC_BLACKHOLE */
3792 if (si->type != STATIC_BLACKHOLE)
3793 {
3794 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_REJECT))
3795 vty_out (vty, " %s", "reject");
3796 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_BLACKHOLE))
3797 vty_out (vty, " %s", "blackhole");
3798 }
3799
3800 if (si->tag)
3801 vty_out (vty, " tag %"ROUTE_TAG_PRI, si->tag);
3802
3803 if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT)
3804 vty_out (vty, " %d", si->distance);
3805
3806 if (si->vrf_id != VRF_DEFAULT)
3807 {
3808 vty_out (vty, " vrf %s", zvrf_name (zvrf));
3809 }
3810
3811 /* Label information */
3812 if (si->snh_label.num_labels)
3813 vty_out (vty, " label %s",
3814 mpls_label2str (si->snh_label.num_labels,
3815 si->snh_label.label, buf, sizeof buf));
3816
3817 vty_out (vty, "%s", VTY_NEWLINE);
3818
3819 write = 1;
3820 }
3821 }
3822 return write;
3823 }
3824
3825 DEFUN (allow_external_route_update,
3826 allow_external_route_update_cmd,
3827 "allow-external-route-update",
3828 "Allow FRR routes to be overwritten by external processes\n")
3829 {
3830 allow_delete = 1;
3831
3832 return CMD_SUCCESS;
3833 }
3834
3835 DEFUN (no_allow_external_route_update,
3836 no_allow_external_route_update_cmd,
3837 "no allow-external-route-update",
3838 NO_STR
3839 "Allow FRR routes to be overwritten by external processes\n")
3840 {
3841 allow_delete = 0;
3842
3843 return CMD_SUCCESS;
3844 }
3845
3846 /* show vrf */
3847 DEFUN (show_vrf,
3848 show_vrf_cmd,
3849 "show vrf",
3850 SHOW_STR
3851 "VRF\n")
3852 {
3853 struct vrf *vrf;
3854 struct zebra_vrf *zvrf;
3855
3856 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
3857 {
3858 if (!(zvrf = vrf->info))
3859 continue;
3860 if (!zvrf_id (zvrf))
3861 continue;
3862
3863 vty_out (vty, "vrf %s ", zvrf_name (zvrf));
3864 if (zvrf_id (zvrf) == VRF_UNKNOWN)
3865 vty_out (vty, "inactive");
3866 else
3867 vty_out (vty, "id %u table %u", zvrf_id (zvrf), zvrf->table_id);
3868 vty_out (vty, "%s", VTY_NEWLINE);
3869
3870 }
3871
3872 return CMD_SUCCESS;
3873 }
3874
3875 /* Static ip route configuration write function. */
3876 static int
3877 zebra_ip_config (struct vty *vty)
3878 {
3879 int write = 0;
3880
3881 write += static_config_ipv4 (vty, SAFI_UNICAST, "ip route");
3882 write += static_config_ipv4 (vty, SAFI_MULTICAST, "ip mroute");
3883 write += static_config_ipv6 (vty);
3884
3885 write += zebra_import_table_config (vty);
3886 return write;
3887 }
3888
3889 DEFUN (ip_zebra_import_table_distance,
3890 ip_zebra_import_table_distance_cmd,
3891 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
3892 IP_STR
3893 "import routes from non-main kernel table\n"
3894 "kernel routing table id\n"
3895 "Distance for imported routes\n"
3896 "Default distance value\n"
3897 "route-map for filtering\n"
3898 "route-map name\n")
3899 {
3900 u_int32_t table_id = 0;
3901
3902 VTY_GET_INTEGER("table", table_id, argv[2]->arg);
3903 int distance = ZEBRA_TABLE_DISTANCE_DEFAULT;
3904 char *rmap = strmatch (argv[argc - 2]->text, "route-map") ?
3905 XSTRDUP(MTYPE_ROUTE_MAP_NAME, argv[argc - 1]->arg) : NULL;
3906 if (argc == 7 || (argc == 5 && !rmap))
3907 VTY_GET_INTEGER_RANGE("distance", distance, argv[4]->arg, 1, 255);
3908
3909 if (!is_zebra_valid_kernel_table(table_id))
3910 {
3911 vty_out(vty, "Invalid routing table ID, %d. Must be in range 1-252%s",
3912 table_id, VTY_NEWLINE);
3913 return CMD_WARNING;
3914 }
3915
3916 if (is_zebra_main_routing_table(table_id))
3917 {
3918 vty_out(vty, "Invalid routing table ID, %d. Must be non-default table%s",
3919 table_id, VTY_NEWLINE);
3920 return CMD_WARNING;
3921 }
3922
3923 return (zebra_import_table(AFI_IP, table_id, distance, rmap, 1));
3924 }
3925
3926 DEFUN (no_ip_zebra_import_table,
3927 no_ip_zebra_import_table_cmd,
3928 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
3929 NO_STR
3930 IP_STR
3931 "import routes from non-main kernel table\n"
3932 "kernel routing table id\n"
3933 "Distance for imported routes\n"
3934 "Default distance value\n"
3935 "route-map for filtering\n"
3936 "route-map name\n")
3937 {
3938 u_int32_t table_id = 0;
3939 VTY_GET_INTEGER("table", table_id, argv[3]->arg);
3940
3941 if (!is_zebra_valid_kernel_table(table_id))
3942 {
3943 vty_out(vty, "Invalid routing table ID. Must be in range 1-252%s",
3944 VTY_NEWLINE);
3945 return CMD_WARNING;
3946 }
3947
3948 if (is_zebra_main_routing_table(table_id))
3949 {
3950 vty_out(vty, "Invalid routing table ID, %d. Must be non-default table%s",
3951 table_id, VTY_NEWLINE);
3952 return CMD_WARNING;
3953 }
3954
3955 if (!is_zebra_import_table_enabled(AFI_IP, table_id))
3956 return CMD_SUCCESS;
3957
3958 return (zebra_import_table(AFI_IP, table_id, 0, NULL, 0));
3959 }
3960
3961 static int
3962 config_write_protocol (struct vty *vty)
3963 {
3964 if (allow_delete)
3965 vty_out(vty, "allow-external-route-update%s", VTY_NEWLINE);
3966
3967 if (zebra_rnh_ip_default_route)
3968 vty_out(vty, "ip nht resolve-via-default%s", VTY_NEWLINE);
3969
3970 if (zebra_rnh_ipv6_default_route)
3971 vty_out(vty, "ipv6 nht resolve-via-default%s", VTY_NEWLINE);
3972
3973 enum multicast_mode ipv4_multicast_mode = multicast_mode_ipv4_get ();
3974
3975 if (ipv4_multicast_mode != MCAST_NO_CONFIG)
3976 vty_out (vty, "ip multicast rpf-lookup-mode %s%s",
3977 ipv4_multicast_mode == MCAST_URIB_ONLY ? "urib-only" :
3978 ipv4_multicast_mode == MCAST_MRIB_ONLY ? "mrib-only" :
3979 ipv4_multicast_mode == MCAST_MIX_MRIB_FIRST ? "mrib-then-urib" :
3980 ipv4_multicast_mode == MCAST_MIX_DISTANCE ? "lower-distance" :
3981 "longer-prefix",
3982 VTY_NEWLINE);
3983
3984 zebra_routemap_config_write_protocol(vty);
3985
3986 return 1;
3987 }
3988
3989 /* IP node for static routes. */
3990 static struct cmd_node ip_node = { IP_NODE, "", 1 };
3991 static struct cmd_node protocol_node = { PROTOCOL_NODE, "", 1 };
3992
3993 /* Route VTY. */
3994 void
3995 zebra_vty_init (void)
3996 {
3997 install_node (&ip_node, zebra_ip_config);
3998 install_node (&protocol_node, config_write_protocol);
3999
4000 install_element (CONFIG_NODE, &allow_external_route_update_cmd);
4001 install_element (CONFIG_NODE, &no_allow_external_route_update_cmd);
4002 install_element (CONFIG_NODE, &ip_mroute_dist_cmd);
4003 install_element (CONFIG_NODE, &no_ip_mroute_dist_cmd);
4004 install_element (CONFIG_NODE, &ip_multicast_mode_cmd);
4005 install_element (CONFIG_NODE, &no_ip_multicast_mode_cmd);
4006 install_element (CONFIG_NODE, &ip_route_cmd);
4007 install_element (CONFIG_NODE, &ip_route_flags_cmd);
4008 install_element (CONFIG_NODE, &ip_route_mask_cmd);
4009 install_element (CONFIG_NODE, &ip_route_mask_flags_cmd);
4010 install_element (CONFIG_NODE, &no_ip_route_cmd);
4011 install_element (CONFIG_NODE, &no_ip_route_mask_cmd);
4012 install_element (CONFIG_NODE, &ip_zebra_import_table_distance_cmd);
4013 install_element (CONFIG_NODE, &no_ip_zebra_import_table_cmd);
4014
4015 install_element (VIEW_NODE, &show_vrf_cmd);
4016 install_element (VIEW_NODE, &show_ip_route_cmd);
4017 install_element (VIEW_NODE, &show_ip_route_ospf_instance_cmd);
4018 install_element (VIEW_NODE, &show_ip_route_tag_cmd);
4019 install_element (VIEW_NODE, &show_ip_nht_cmd);
4020 install_element (VIEW_NODE, &show_ip_nht_vrf_all_cmd);
4021 install_element (VIEW_NODE, &show_ipv6_nht_cmd);
4022 install_element (VIEW_NODE, &show_ipv6_nht_vrf_all_cmd);
4023 install_element (VIEW_NODE, &show_ip_route_addr_cmd);
4024 install_element (VIEW_NODE, &show_ip_route_prefix_cmd);
4025 install_element (VIEW_NODE, &show_ip_route_prefix_longer_cmd);
4026 install_element (VIEW_NODE, &show_ip_route_protocol_cmd);
4027 install_element (VIEW_NODE, &show_ip_route_supernets_cmd);
4028 install_element (VIEW_NODE, &show_ip_route_summary_cmd);
4029 install_element (VIEW_NODE, &show_ip_route_summary_prefix_cmd);
4030
4031 install_element (VIEW_NODE, &show_ip_rpf_cmd);
4032 install_element (VIEW_NODE, &show_ip_rpf_addr_cmd);
4033
4034 /* Commands for VRF */
4035
4036 install_element (CONFIG_NODE, &no_ip_route_flags_cmd);
4037 install_element (CONFIG_NODE, &no_ip_route_mask_flags_cmd);
4038
4039 install_element (VIEW_NODE, &show_ip_route_vrf_cmd);
4040
4041 install_element (VIEW_NODE, &show_ip_route_vrf_all_cmd);
4042 install_element (VIEW_NODE, &show_ip_route_vrf_all_tag_cmd);
4043 install_element (VIEW_NODE, &show_ip_route_vrf_all_addr_cmd);
4044 install_element (VIEW_NODE, &show_ip_route_vrf_all_prefix_cmd);
4045 install_element (VIEW_NODE, &show_ip_route_vrf_all_prefix_longer_cmd);
4046 install_element (VIEW_NODE, &show_ip_route_vrf_all_protocol_cmd);
4047 install_element (VIEW_NODE, &show_ip_route_vrf_all_supernets_cmd);
4048 install_element (VIEW_NODE, &show_ip_route_vrf_all_summary_cmd);
4049 install_element (VIEW_NODE, &show_ip_route_vrf_all_summary_prefix_cmd);
4050
4051 install_element (CONFIG_NODE, &ipv6_route_cmd);
4052 install_element (CONFIG_NODE, &ipv6_route_flags_cmd);
4053 install_element (CONFIG_NODE, &ipv6_route_ifname_cmd);
4054 install_element (CONFIG_NODE, &ipv6_route_ifname_flags_cmd);
4055 install_element (CONFIG_NODE, &no_ipv6_route_cmd);
4056 install_element (CONFIG_NODE, &no_ipv6_route_flags_cmd);
4057 install_element (CONFIG_NODE, &no_ipv6_route_ifname_cmd);
4058 install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_cmd);
4059 install_element (CONFIG_NODE, &ip_nht_default_route_cmd);
4060 install_element (CONFIG_NODE, &no_ip_nht_default_route_cmd);
4061 install_element (CONFIG_NODE, &ipv6_nht_default_route_cmd);
4062 install_element (CONFIG_NODE, &no_ipv6_nht_default_route_cmd);
4063 install_element (VIEW_NODE, &show_ipv6_route_cmd);
4064 install_element (VIEW_NODE, &show_ipv6_route_tag_cmd);
4065 install_element (VIEW_NODE, &show_ipv6_route_summary_cmd);
4066 install_element (VIEW_NODE, &show_ipv6_route_summary_prefix_cmd);
4067 install_element (VIEW_NODE, &show_ipv6_route_protocol_cmd);
4068 install_element (VIEW_NODE, &show_ipv6_route_addr_cmd);
4069 install_element (VIEW_NODE, &show_ipv6_route_prefix_cmd);
4070 install_element (VIEW_NODE, &show_ipv6_route_prefix_longer_cmd);
4071
4072 install_element (VIEW_NODE, &show_ipv6_mroute_cmd);
4073
4074 /* Commands for VRF */
4075 install_element (VIEW_NODE, &show_ipv6_route_vrf_all_cmd);
4076 install_element (VIEW_NODE, &show_ipv6_route_vrf_all_tag_cmd);
4077 install_element (VIEW_NODE, &show_ipv6_route_vrf_all_summary_cmd);
4078 install_element (VIEW_NODE, &show_ipv6_route_vrf_all_summary_prefix_cmd);
4079 install_element (VIEW_NODE, &show_ipv6_route_vrf_all_protocol_cmd);
4080 install_element (VIEW_NODE, &show_ipv6_route_vrf_all_addr_cmd);
4081 install_element (VIEW_NODE, &show_ipv6_route_vrf_all_prefix_cmd);
4082 install_element (VIEW_NODE, &show_ipv6_route_vrf_all_prefix_longer_cmd);
4083
4084 install_element (VIEW_NODE, &show_ipv6_mroute_vrf_all_cmd);
4085 }