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