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