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