]> git.proxmox.com Git - mirror_frr.git/blob - zebra/zebra_vty.c
88778e491ba96764e649e0294e86c25d85b2830e
[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 afi_t afi, safi_t safi, bool use_fib, u_char use_json,
49 route_tag_t tag, struct prefix *longer_prefix_p,
50 bool supernets_only, int type, u_short ospf_instance_id);
51 static void vty_show_ip_route_detail (struct vty *vty, struct route_node *rn,
52 int mcast);
53
54 #define ONE_DAY_SECOND 60*60*24
55 #define ONE_WEEK_SECOND 60*60*24*7
56
57 /* General function for static route. */
58 int
59 zebra_static_ipv4 (struct vty *vty, safi_t safi, int add_cmd,
60 const char *dest_str, const char *mask_str,
61 const char *gate_str, const char *flag_str,
62 const char *tag_str, const char *distance_str,
63 const char *vrf_id_str, const char *label_str)
64 {
65 int ret;
66 u_char distance;
67 struct prefix p;
68 struct in_addr gate;
69 struct in_addr mask;
70 u_char flag = 0;
71 route_tag_t tag = 0;
72 struct zebra_vrf *zvrf = NULL;
73 unsigned int ifindex = 0;
74 const char *ifname = NULL;
75 u_char type = STATIC_BLACKHOLE;
76 struct static_nh_label snh_label;
77
78 memset (&snh_label, 0, sizeof (struct static_nh_label));
79 ret = str2prefix (dest_str, &p);
80 if (ret <= 0)
81 {
82 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
83 return CMD_WARNING;
84 }
85
86 /* Cisco like mask notation. */
87 if (mask_str)
88 {
89 ret = inet_aton (mask_str, &mask);
90 if (ret == 0)
91 {
92 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
93 return CMD_WARNING;
94 }
95 p.prefixlen = ip_masklen (mask);
96 }
97
98 /* Apply mask for given prefix. */
99 apply_mask (&p);
100
101 /* Administrative distance. */
102 if (distance_str)
103 distance = atoi (distance_str);
104 else
105 distance = ZEBRA_STATIC_DISTANCE_DEFAULT;
106
107 /* tag */
108 if (tag_str)
109 VTY_GET_INTEGER_RANGE("tag", tag, tag_str, 0, 4294967295);
110
111 /* VRF id */
112 zvrf = zebra_vrf_lookup_by_name (vrf_id_str);
113
114 if (!zvrf)
115 {
116 vty_out (vty, "%% vrf %s is not defined%s", vrf_id_str, VTY_NEWLINE);
117 return CMD_WARNING;
118 }
119
120 /* Labels */
121 if (label_str)
122 {
123 if (!mpls_enabled)
124 {
125 vty_out (vty, "%% MPLS not turned on in kernel, ignoring command%s",
126 VTY_NEWLINE);
127 return CMD_WARNING;
128 }
129 int rc = mpls_str2label (label_str, &snh_label.num_labels,
130 snh_label.label);
131 if (rc < 0)
132 {
133 switch (rc) {
134 case -1:
135 vty_out (vty, "%% Malformed label(s)%s", VTY_NEWLINE);
136 break;
137 case -2:
138 vty_out (vty, "%% Cannot use reserved label(s) (%d-%d)%s",
139 MPLS_MIN_RESERVED_LABEL, MPLS_MAX_RESERVED_LABEL,
140 VTY_NEWLINE);
141 break;
142 case -3:
143 vty_out (vty, "%% Too many labels. Enter %d or fewer%s",
144 MPLS_MAX_LABELS, VTY_NEWLINE);
145 break;
146 }
147 return CMD_WARNING;
148 }
149 }
150
151 /* Null0 static route. */
152 if ((gate_str != NULL) && (strncasecmp (gate_str, "Null0", strlen (gate_str)) == 0))
153 {
154 if (flag_str)
155 {
156 vty_out (vty, "%% can not have flag %s with Null0%s", flag_str, VTY_NEWLINE);
157 return CMD_WARNING;
158 }
159 if (add_cmd)
160 static_add_route (AFI_IP, safi, type, &p, NULL, NULL, ifindex, ifname,
161 ZEBRA_FLAG_BLACKHOLE, tag, distance, zvrf, &snh_label);
162 else
163 static_delete_route (AFI_IP, safi, type, &p, NULL, NULL, ifindex, tag,
164 distance, zvrf, &snh_label);
165 return CMD_SUCCESS;
166 }
167
168 /* Route flags */
169 if (flag_str) {
170 switch(flag_str[0]) {
171 case 'r':
172 case 'R': /* XXX */
173 SET_FLAG (flag, ZEBRA_FLAG_REJECT);
174 break;
175 case 'b':
176 case 'B': /* XXX */
177 SET_FLAG (flag, ZEBRA_FLAG_BLACKHOLE);
178 break;
179 default:
180 vty_out (vty, "%% Malformed flag %s %s", flag_str, VTY_NEWLINE);
181 return CMD_WARNING;
182 }
183 }
184
185 if (gate_str == NULL)
186 {
187 if (add_cmd)
188 static_add_route (AFI_IP, safi, type, &p, NULL, NULL, ifindex, ifname, flag,
189 tag, distance, zvrf, &snh_label);
190 else
191 static_delete_route (AFI_IP, safi, type, &p, NULL, NULL, ifindex, tag, distance,
192 zvrf, &snh_label);
193
194 return CMD_SUCCESS;
195 }
196
197 /* When gateway is A.B.C.D format, gate is treated as nexthop
198 address other case gate is treated as interface name. */
199 ret = inet_aton (gate_str, &gate);
200 if (!ret)
201 {
202 struct interface *ifp = if_lookup_by_name (gate_str, zvrf_id (zvrf));
203 if (!ifp)
204 {
205 vty_out (vty, "%% Unknown interface: %s%s", gate_str, VTY_NEWLINE);
206 ifindex = IFINDEX_DELETED;
207 }
208 else
209 ifindex = ifp->ifindex;
210 ifname = gate_str;
211 type = STATIC_IFINDEX;
212 }
213 else
214 type = STATIC_IPV4_GATEWAY;
215
216 if (add_cmd)
217 static_add_route (AFI_IP, safi, type, &p, NULL,
218 ifindex ? NULL : (union g_addr *)&gate, ifindex, ifname,
219 flag, tag, distance, zvrf, &snh_label);
220 else
221 static_delete_route (AFI_IP, safi, type, &p, NULL,
222 ifindex ? NULL : (union g_addr *)&gate, ifindex, tag,
223 distance, zvrf, &snh_label);
224
225 return CMD_SUCCESS;
226 }
227
228 /* Static unicast routes for multicast RPF lookup. */
229 DEFUN (ip_mroute_dist,
230 ip_mroute_dist_cmd,
231 "ip mroute A.B.C.D/M <A.B.C.D|INTERFACE> [(1-255)]",
232 IP_STR
233 "Configure static unicast route into MRIB for multicast RPF lookup\n"
234 "IP destination prefix (e.g. 10.0.0.0/8)\n"
235 "Nexthop address\n"
236 "Nexthop interface name\n"
237 "Distance\n")
238 {
239 char *destprefix = argv[2]->arg;
240 char *nexthop = argv[3]->arg;
241 char *distance = (argc == 5) ? argv[4]->arg : NULL;
242
243 return zebra_static_ipv4 (vty, SAFI_MULTICAST, 1, destprefix, NULL, nexthop, NULL, NULL, distance, NULL, NULL);
244 }
245
246 DEFUN (no_ip_mroute_dist,
247 no_ip_mroute_dist_cmd,
248 "no ip mroute A.B.C.D/M <A.B.C.D|INTERFACE> [(1-255)]",
249 NO_STR
250 IP_STR
251 "Configure static unicast route into MRIB for multicast RPF lookup\n"
252 "IP destination prefix (e.g. 10.0.0.0/8)\n"
253 "Nexthop address\n"
254 "Nexthop interface name\n"
255 "Distance\n")
256 {
257 char *destprefix = argv[3]->arg;
258 char *nexthop = argv[4]->arg;
259 char *distance = (argc == 6) ? argv[5]->arg : NULL;
260
261 return zebra_static_ipv4 (vty, SAFI_MULTICAST, 0, destprefix, NULL, nexthop, NULL, NULL, distance, NULL, NULL);
262 }
263
264 DEFUN (ip_multicast_mode,
265 ip_multicast_mode_cmd,
266 "ip multicast rpf-lookup-mode <urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>",
267 IP_STR
268 "Multicast options\n"
269 "RPF lookup behavior\n"
270 "Lookup in unicast RIB only\n"
271 "Lookup in multicast RIB only\n"
272 "Try multicast RIB first, fall back to unicast RIB\n"
273 "Lookup both, use entry with lower distance\n"
274 "Lookup both, use entry with longer prefix\n")
275 {
276 char *mode = argv[3]->text;
277
278 if (strmatch (mode, "urib-only"))
279 multicast_mode_ipv4_set (MCAST_URIB_ONLY);
280 else if (strmatch (mode, "mrib-only"))
281 multicast_mode_ipv4_set (MCAST_MRIB_ONLY);
282 else if (strmatch (mode, "mrib-then-urib"))
283 multicast_mode_ipv4_set (MCAST_MIX_MRIB_FIRST);
284 else if (strmatch (mode, "lower-distance"))
285 multicast_mode_ipv4_set (MCAST_MIX_DISTANCE);
286 else if (strmatch (mode, "longer-prefix"))
287 multicast_mode_ipv4_set (MCAST_MIX_PFXLEN);
288 else
289 {
290 vty_out (vty, "Invalid mode specified%s", VTY_NEWLINE);
291 return CMD_WARNING;
292 }
293
294 return CMD_SUCCESS;
295 }
296
297 DEFUN (no_ip_multicast_mode,
298 no_ip_multicast_mode_cmd,
299 "no ip multicast rpf-lookup-mode [<urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>]",
300 NO_STR
301 IP_STR
302 "Multicast options\n"
303 "RPF lookup behavior\n"
304 "Lookup in unicast RIB only\n"
305 "Lookup in multicast RIB only\n"
306 "Try multicast RIB first, fall back to unicast RIB\n"
307 "Lookup both, use entry with lower distance\n"
308 "Lookup both, use entry with longer prefix\n")
309 {
310 multicast_mode_ipv4_set (MCAST_NO_CONFIG);
311 return CMD_SUCCESS;
312 }
313
314
315 DEFUN (show_ip_rpf,
316 show_ip_rpf_cmd,
317 "show ip rpf [json]",
318 SHOW_STR
319 IP_STR
320 "Display RPF information for multicast source\n"
321 JSON_STR)
322 {
323 int uj = use_json(argc, argv);
324 return do_show_ip_route (vty, VRF_DEFAULT_NAME, AFI_IP, SAFI_MULTICAST, false, uj, 0, NULL, false, -1, 0);
325 }
326
327 DEFUN (show_ip_rpf_addr,
328 show_ip_rpf_addr_cmd,
329 "show ip rpf A.B.C.D",
330 SHOW_STR
331 IP_STR
332 "Display RPF information for multicast source\n"
333 "IP multicast source address (e.g. 10.0.0.0)\n")
334 {
335 int idx_ipv4 = 3;
336 struct in_addr addr;
337 struct route_node *rn;
338 struct route_entry *re;
339 int ret;
340
341 ret = inet_aton (argv[idx_ipv4]->arg, &addr);
342 if (ret == 0)
343 {
344 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
345 return CMD_WARNING;
346 }
347
348 re = rib_match_ipv4_multicast (VRF_DEFAULT, addr, &rn);
349
350 if (re)
351 vty_show_ip_route_detail (vty, rn, 1);
352 else
353 vty_out (vty, "%% No match for RPF lookup%s", VTY_NEWLINE);
354
355 return CMD_SUCCESS;
356 }
357
358 static void
359 zebra_vty_ip_route_tdv_helper (int argc, struct cmd_token *argv[],
360 int idx_curr, char **tag,
361 char **distance, char **vrf, char **labels)
362 {
363 *distance = NULL;
364 while (idx_curr < argc)
365 {
366 if (strmatch (argv[idx_curr]->text, "tag"))
367 {
368 if (tag)
369 *tag = argv[idx_curr+1]->arg;
370 idx_curr += 2;
371 }
372 else if (strmatch (argv[idx_curr]->text, "vrf"))
373 {
374 if (vrf)
375 *vrf = argv[idx_curr+1]->arg;
376 idx_curr += 2;
377 }
378 else if (strmatch (argv[idx_curr]->text, "label"))
379 {
380 if (labels)
381 *labels = argv[idx_curr+1]->arg;
382 idx_curr += 2;
383 }
384 else
385 {
386 if (distance)
387 *distance = argv[idx_curr]->arg;
388 idx_curr++;
389 }
390 }
391
392 return;
393 }
394
395 /* Static route configuration. */
396 DEFUN (ip_route,
397 ip_route_cmd,
398 "ip route A.B.C.D/M <A.B.C.D|INTERFACE|null0> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
399 IP_STR
400 "Establish static routes\n"
401 "IP destination prefix (e.g. 10.0.0.0/8)\n"
402 "IP gateway address\n"
403 "IP gateway interface name\n"
404 "Null interface\n"
405 "Set tag for this route\n"
406 "Tag value\n"
407 "Distance value for this route\n"
408 VRF_CMD_HELP_STR)
409 {
410 int idx_ipv4_prefixlen = 2;
411 int idx_ipv4_ifname_null = 3;
412 int idx_curr = 4;
413 char *tag, *distance, *vrf;
414
415 tag = distance = vrf = NULL;
416 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
417
418 return zebra_static_ipv4 (vty, SAFI_UNICAST, 1,
419 argv[idx_ipv4_prefixlen]->arg,
420 NULL,
421 argv[idx_ipv4_ifname_null]->arg,
422 NULL,
423 tag, distance, vrf, NULL);
424 }
425
426 DEFUN (ip_route_flags,
427 ip_route_flags_cmd,
428 "ip route A.B.C.D/M <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
429 IP_STR
430 "Establish static routes\n"
431 "IP destination prefix (e.g. 10.0.0.0/8)\n"
432 "Emit an ICMP unreachable when matched\n"
433 "Silently discard pkts when matched\n"
434 "Set tag for this route\n"
435 "Tag value\n"
436 "Distance value for this route\n"
437 VRF_CMD_HELP_STR
438 MPLS_LABEL_HELPSTR)
439 {
440 int idx_ipv4_prefixlen = 2;
441 int idx_reject_blackhole = 3;
442 int idx_curr = 4;
443 char *tag, *distance, *vrf;
444
445 tag = distance = vrf = NULL;
446 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
447
448 return zebra_static_ipv4 (vty, SAFI_UNICAST, 1,
449 argv[idx_ipv4_prefixlen]->arg,
450 NULL,
451 NULL,
452 argv[idx_reject_blackhole]->arg,
453 tag, distance, vrf, NULL);
454 }
455
456 /* Mask as A.B.C.D format. */
457 DEFUN (ip_route_mask,
458 ip_route_mask_cmd,
459 "ip route A.B.C.D A.B.C.D <A.B.C.D|INTERFACE|null0> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
460 IP_STR
461 "Establish static routes\n"
462 "IP destination prefix\n"
463 "IP destination prefix mask\n"
464 "IP gateway address\n"
465 "IP gateway interface name\n"
466 "Null interface\n"
467 "Set tag for this route\n"
468 "Tag value\n"
469 "Distance value for this route\n"
470 VRF_CMD_HELP_STR
471 MPLS_LABEL_HELPSTR)
472 {
473 int idx_ipv4 = 2;
474 int idx_ipv4_2 = 3;
475 int idx_ipv4_ifname_null = 4;
476 int idx_curr = 5;
477 char *tag, *distance, *vrf;
478
479 tag = distance = vrf = NULL;
480 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
481
482 return zebra_static_ipv4 (vty, SAFI_UNICAST, 1,
483 argv[idx_ipv4]->arg,
484 argv[idx_ipv4_2]->arg,
485 argv[idx_ipv4_ifname_null]->arg,
486 NULL, tag, distance, vrf, NULL);
487 }
488
489 DEFUN (ip_route_mask_flags,
490 ip_route_mask_flags_cmd,
491 "ip route A.B.C.D A.B.C.D <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
492 IP_STR
493 "Establish static routes\n"
494 "IP destination prefix\n"
495 "IP destination prefix mask\n"
496 "Emit an ICMP unreachable when matched\n"
497 "Silently discard pkts when matched\n"
498 "Set tag for this route\n"
499 "Tag value\n"
500 "Distance value for this route\n"
501 VRF_CMD_HELP_STR
502 MPLS_LABEL_HELPSTR)
503 {
504 int idx_ipv4 = 2;
505 int idx_ipv4_2 = 3;
506 int idx_reject_blackhole = 4;
507 int idx_curr = 5;
508 char *tag, *distance, *vrf;
509
510 tag = distance = vrf = NULL;
511 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
512
513 return zebra_static_ipv4 (vty, SAFI_UNICAST, 1,
514 argv[idx_ipv4]->arg,
515 argv[idx_ipv4_2]->arg,
516 NULL,
517 argv[idx_reject_blackhole]->arg,
518 tag, distance, vrf, NULL);
519 }
520
521 DEFUN (no_ip_route,
522 no_ip_route_cmd,
523 "no ip route A.B.C.D/M <A.B.C.D|INTERFACE|null0> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
524 NO_STR
525 IP_STR
526 "Establish static routes\n"
527 "IP destination prefix (e.g. 10.0.0.0/8)\n"
528 "IP gateway address\n"
529 "IP gateway interface name\n"
530 "Null interface\n"
531 "Tag of this route\n"
532 "Tag value\n"
533 "Distance value for this route\n"
534 VRF_CMD_HELP_STR
535 MPLS_LABEL_HELPSTR)
536 {
537 int idx_ipv4_prefixlen = 3;
538 int idx_ipv4_ifname_null = 4;
539 int idx_curr = 5;
540 char *tag, *distance, *vrf;
541
542 tag = distance = vrf = NULL;
543 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
544
545 return zebra_static_ipv4 (vty, SAFI_UNICAST, 0,
546 argv[idx_ipv4_prefixlen]->arg,
547 NULL,
548 argv[idx_ipv4_ifname_null]->arg,
549 NULL,
550 tag, distance, vrf, NULL);
551 }
552
553 DEFUN (no_ip_route_flags,
554 no_ip_route_flags_cmd,
555 "no ip route A.B.C.D/M <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
556 NO_STR
557 IP_STR
558 "Establish static routes\n"
559 "IP destination prefix (e.g. 10.0.0.0/8)\n"
560 "Emit an ICMP unreachable when matched\n"
561 "Silently discard pkts when matched\n"
562 "Tag of this route\n"
563 "Tag value\n"
564 "Distance value for this route\n"
565 VRF_CMD_HELP_STR
566 MPLS_LABEL_HELPSTR)
567 {
568 int idx_ipv4_prefixlen = 3;
569 int idx_curr = 5;
570 char *tag, *distance, *vrf;
571
572 tag = distance = vrf = NULL;
573 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
574
575 return zebra_static_ipv4 (vty, SAFI_UNICAST, 0,
576 argv[idx_ipv4_prefixlen]->arg,
577 NULL, NULL, NULL,
578 tag, distance, vrf, NULL);
579 }
580
581 DEFUN (no_ip_route_mask,
582 no_ip_route_mask_cmd,
583 "no ip route A.B.C.D A.B.C.D <A.B.C.D|INTERFACE|null0> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
584 NO_STR
585 IP_STR
586 "Establish static routes\n"
587 "IP destination prefix\n"
588 "IP destination prefix mask\n"
589 "IP gateway address\n"
590 "IP gateway interface name\n"
591 "Null interface\n"
592 "Tag of this route\n"
593 "Tag value\n"
594 "Distance value for this route\n"
595 VRF_CMD_HELP_STR
596 MPLS_LABEL_HELPSTR)
597 {
598 int idx_ipv4 = 3;
599 int idx_ipv4_2 = 4;
600 int idx_ipv4_ifname_null = 5;
601 int idx_curr = 6;
602 char *tag, *distance, *vrf;
603
604 tag = distance = vrf = NULL;
605 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
606
607 return zebra_static_ipv4 (vty, SAFI_UNICAST, 0,
608 argv[idx_ipv4]->arg,
609 argv[idx_ipv4_2]->arg,
610 argv[idx_ipv4_ifname_null]->arg,
611 NULL,
612 tag, distance, vrf, NULL);
613 }
614
615 DEFUN (no_ip_route_mask_flags,
616 no_ip_route_mask_flags_cmd,
617 "no ip route A.B.C.D A.B.C.D <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
618 NO_STR
619 IP_STR
620 "Establish static routes\n"
621 "IP destination prefix\n"
622 "IP destination prefix mask\n"
623 "Emit an ICMP unreachable when matched\n"
624 "Silently discard pkts when matched\n"
625 "Tag of this route\n"
626 "Tag value\n"
627 "Distance value for this route\n"
628 VRF_CMD_HELP_STR
629 MPLS_LABEL_HELPSTR)
630 {
631 int idx_ipv4 = 3;
632 int idx_ipv4_2 = 4;
633 int idx_curr = 6;
634 char *tag, *distance, *vrf;
635
636 tag = distance = vrf = NULL;
637 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
638
639 return zebra_static_ipv4 (vty, SAFI_UNICAST, 0,
640 argv[idx_ipv4]->arg,
641 argv[idx_ipv4_2]->arg,
642 NULL, NULL,
643 tag, distance, vrf, NULL);
644 }
645
646 /* New RIB. Detailed information for IPv4 route. */
647 static void
648 vty_show_ip_route_detail (struct vty *vty, struct route_node *rn, int mcast)
649 {
650 struct route_entry *re;
651 struct nexthop *nexthop, *tnexthop;
652 int recursing;
653 char buf[SRCDEST2STR_BUFFER];
654 struct zebra_vrf *zvrf;
655
656 RNODE_FOREACH_RE (rn, re)
657 {
658 const char *mcast_info = "";
659 if (mcast)
660 {
661 rib_table_info_t *info = srcdest_rnode_table_info(rn);
662 mcast_info = (info->safi == SAFI_MULTICAST)
663 ? " using Multicast RIB"
664 : " using Unicast RIB";
665 }
666
667 vty_out (vty, "Routing entry for %s%s%s",
668 srcdest_rnode2str(rn, buf, sizeof(buf)), mcast_info,
669 VTY_NEWLINE);
670 vty_out (vty, " Known via \"%s", zebra_route_string (re->type));
671 if (re->instance)
672 vty_out (vty, "[%d]", re->instance);
673 vty_out (vty, "\"");
674 vty_out (vty, ", distance %u, metric %u", re->distance, re->metric);
675 if (re->tag)
676 vty_out (vty, ", tag %d", re->tag);
677 if (re->mtu)
678 vty_out (vty, ", mtu %u", re->mtu);
679 if (re->vrf_id != VRF_DEFAULT)
680 {
681 zvrf = vrf_info_lookup(re->vrf_id);
682 vty_out (vty, ", vrf %s", zvrf_name (zvrf));
683 }
684 if (CHECK_FLAG (re->flags, ZEBRA_FLAG_SELECTED))
685 vty_out (vty, ", best");
686 if (re->refcnt)
687 vty_out (vty, ", refcnt %ld", re->refcnt);
688 if (CHECK_FLAG (re->flags, ZEBRA_FLAG_BLACKHOLE))
689 vty_out (vty, ", blackhole");
690 if (CHECK_FLAG (re->flags, ZEBRA_FLAG_REJECT))
691 vty_out (vty, ", reject");
692 vty_out (vty, "%s", VTY_NEWLINE);
693
694 if (re->type == ZEBRA_ROUTE_RIP
695 || re->type == ZEBRA_ROUTE_OSPF
696 || re->type == ZEBRA_ROUTE_ISIS
697 || re->type == ZEBRA_ROUTE_NHRP
698 || re->type == ZEBRA_ROUTE_TABLE
699 || re->type == ZEBRA_ROUTE_BGP)
700 {
701 time_t uptime;
702 struct tm *tm;
703
704 uptime = time (NULL);
705 uptime -= re->uptime;
706 tm = gmtime (&uptime);
707
708 vty_out (vty, " Last update ");
709
710 if (uptime < ONE_DAY_SECOND)
711 vty_out (vty, "%02d:%02d:%02d",
712 tm->tm_hour, tm->tm_min, tm->tm_sec);
713 else if (uptime < ONE_WEEK_SECOND)
714 vty_out (vty, "%dd%02dh%02dm",
715 tm->tm_yday, tm->tm_hour, tm->tm_min);
716 else
717 vty_out (vty, "%02dw%dd%02dh",
718 tm->tm_yday/7,
719 tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
720 vty_out (vty, " ago%s", VTY_NEWLINE);
721 }
722
723 for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
724 {
725 char addrstr[32];
726
727 vty_out (vty, " %c%s",
728 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? '*' : ' ',
729 recursing ? " " : "");
730
731 switch (nexthop->type)
732 {
733 case NEXTHOP_TYPE_IPV4:
734 case NEXTHOP_TYPE_IPV4_IFINDEX:
735 vty_out (vty, " %s", inet_ntoa (nexthop->gate.ipv4));
736 if (nexthop->ifindex)
737 vty_out (vty, ", via %s",
738 ifindex2ifname (nexthop->ifindex, re->vrf_id));
739 break;
740 case NEXTHOP_TYPE_IPV6:
741 case NEXTHOP_TYPE_IPV6_IFINDEX:
742 vty_out (vty, " %s",
743 inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, sizeof buf));
744 if (nexthop->ifindex)
745 vty_out (vty, ", via %s",
746 ifindex2ifname (nexthop->ifindex, re->vrf_id));
747 break;
748 case NEXTHOP_TYPE_IFINDEX:
749 vty_out (vty, " directly connected, %s",
750 ifindex2ifname (nexthop->ifindex, re->vrf_id));
751 break;
752 case NEXTHOP_TYPE_BLACKHOLE:
753 vty_out (vty, " directly connected, Null0");
754 break;
755 default:
756 break;
757 }
758 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
759 vty_out (vty, " inactive");
760
761 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK))
762 vty_out (vty, " onlink");
763
764 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
765 vty_out (vty, " (recursive)");
766
767 switch (nexthop->type)
768 {
769 case NEXTHOP_TYPE_IPV4:
770 case NEXTHOP_TYPE_IPV4_IFINDEX:
771 if (nexthop->src.ipv4.s_addr)
772 {
773 if (inet_ntop(AF_INET, &nexthop->src.ipv4, addrstr,
774 sizeof addrstr))
775 vty_out (vty, ", src %s", addrstr);
776 }
777 break;
778 case NEXTHOP_TYPE_IPV6:
779 case NEXTHOP_TYPE_IPV6_IFINDEX:
780 if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any))
781 {
782 if (inet_ntop(AF_INET6, &nexthop->src.ipv6, addrstr,
783 sizeof addrstr))
784 vty_out (vty, ", src %s", addrstr);
785 }
786 break;
787 default:
788 break;
789 }
790
791 /* Label information */
792 if (nexthop->nh_label && nexthop->nh_label->num_labels)
793 {
794 vty_out (vty, ", label %s",
795 mpls_label2str (nexthop->nh_label->num_labels,
796 nexthop->nh_label->label, buf, sizeof buf, 1));
797 }
798
799 vty_out (vty, "%s", VTY_NEWLINE);
800 }
801 vty_out (vty, "%s", VTY_NEWLINE);
802 }
803 }
804
805 static void
806 vty_show_ip_route (struct vty *vty, struct route_node *rn, struct route_entry *re,
807 json_object *json)
808 {
809 struct nexthop *nexthop, *tnexthop;
810 int recursing;
811 int len = 0;
812 char buf[SRCDEST2STR_BUFFER];
813 json_object *json_nexthops = NULL;
814 json_object *json_nexthop = NULL;
815 json_object *json_route = NULL;
816 json_object *json_labels = NULL;
817
818 if (json)
819 {
820 json_route = json_object_new_object();
821 json_nexthops = json_object_new_array();
822
823 json_object_string_add(json_route, "prefix", srcdest_rnode2str (rn, buf, sizeof buf));
824 json_object_string_add(json_route, "protocol", zebra_route_string(re->type));
825
826 if (re->instance)
827 json_object_int_add(json_route, "instance", re->instance);
828
829 if (re->vrf_id)
830 json_object_int_add(json_route, "vrfId", re->vrf_id);
831
832 if (CHECK_FLAG (re->flags, ZEBRA_FLAG_SELECTED))
833 json_object_boolean_true_add(json_route, "selected");
834
835 if (re->type != ZEBRA_ROUTE_CONNECT && re->type != ZEBRA_ROUTE_KERNEL)
836 {
837 json_object_int_add(json_route, "distance", re->distance);
838 json_object_int_add(json_route, "metric", re->metric);
839 }
840
841 if (CHECK_FLAG (re->flags, ZEBRA_FLAG_BLACKHOLE))
842 json_object_boolean_true_add(json_route, "blackhole");
843
844 if (CHECK_FLAG (re->flags, ZEBRA_FLAG_REJECT))
845 json_object_boolean_true_add(json_route, "reject");
846
847 if (re->type == ZEBRA_ROUTE_RIP
848 || re->type == ZEBRA_ROUTE_OSPF
849 || re->type == ZEBRA_ROUTE_ISIS
850 || re->type == ZEBRA_ROUTE_NHRP
851 || re->type == ZEBRA_ROUTE_TABLE
852 || re->type == ZEBRA_ROUTE_BGP)
853 {
854 time_t uptime;
855 struct tm *tm;
856
857 uptime = time (NULL);
858 uptime -= re->uptime;
859 tm = gmtime (&uptime);
860
861 if (uptime < ONE_DAY_SECOND)
862 sprintf(buf, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min, tm->tm_sec);
863 else if (uptime < ONE_WEEK_SECOND)
864 sprintf(buf, "%dd%02dh%02dm", tm->tm_yday, tm->tm_hour, tm->tm_min);
865 else
866 sprintf(buf, "%02dw%dd%02dh", tm->tm_yday/7, tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
867
868 json_object_string_add(json_route, "uptime", buf);
869 }
870
871 for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
872 {
873 json_nexthop = json_object_new_object();
874
875 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
876 json_object_boolean_true_add(json_nexthop, "fib");
877
878 switch (nexthop->type)
879 {
880 case NEXTHOP_TYPE_IPV4:
881 case NEXTHOP_TYPE_IPV4_IFINDEX:
882 json_object_string_add(json_nexthop, "ip", inet_ntoa (nexthop->gate.ipv4));
883 json_object_string_add(json_nexthop, "afi", "ipv4");
884
885 if (nexthop->ifindex)
886 {
887 json_object_int_add(json_nexthop, "interfaceIndex", nexthop->ifindex);
888 json_object_string_add(json_nexthop, "interfaceName", ifindex2ifname (nexthop->ifindex, re->vrf_id));
889 }
890 break;
891 case NEXTHOP_TYPE_IPV6:
892 case NEXTHOP_TYPE_IPV6_IFINDEX:
893 json_object_string_add(json_nexthop, "ip", inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, sizeof buf));
894 json_object_string_add(json_nexthop, "afi", "ipv6");
895
896 if (nexthop->ifindex)
897 {
898 json_object_int_add(json_nexthop, "interfaceIndex", nexthop->ifindex);
899 json_object_string_add(json_nexthop, "interfaceName", ifindex2ifname (nexthop->ifindex, re->vrf_id));
900 }
901 break;
902
903 case NEXTHOP_TYPE_IFINDEX:
904 json_object_boolean_true_add(json_nexthop, "directlyConnected");
905 json_object_int_add(json_nexthop, "interfaceIndex", nexthop->ifindex);
906 json_object_string_add(json_nexthop, "interfaceName", ifindex2ifname (nexthop->ifindex, re->vrf_id));
907 break;
908 case NEXTHOP_TYPE_BLACKHOLE:
909 json_object_boolean_true_add(json_nexthop, "blackhole");
910 break;
911 default:
912 break;
913 }
914
915 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
916 json_object_boolean_true_add(json_nexthop, "active");
917
918 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK))
919 json_object_boolean_true_add(json_nexthop, "onLink");
920
921 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
922 json_object_boolean_true_add(json_nexthop, "recursive");
923
924 switch (nexthop->type)
925 {
926 case NEXTHOP_TYPE_IPV4:
927 case NEXTHOP_TYPE_IPV4_IFINDEX:
928 if (nexthop->src.ipv4.s_addr)
929 {
930 if (inet_ntop(AF_INET, &nexthop->src.ipv4, buf, sizeof buf))
931 json_object_string_add(json_nexthop, "source", buf);
932 }
933 break;
934 case NEXTHOP_TYPE_IPV6:
935 case NEXTHOP_TYPE_IPV6_IFINDEX:
936 if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any))
937 {
938 if (inet_ntop(AF_INET6, &nexthop->src.ipv6, buf, sizeof buf))
939 json_object_string_add(json_nexthop, "source", buf);
940 }
941 break;
942 default:
943 break;
944 }
945
946 if (nexthop->nh_label && nexthop->nh_label->num_labels)
947 {
948 json_labels = json_object_new_array();
949
950 for (int label_index = 0; label_index < nexthop->nh_label->num_labels; label_index++)
951 json_object_array_add(json_labels, json_object_new_int(nexthop->nh_label->label[label_index]));
952
953 json_object_object_add(json_nexthop, "labels", json_labels);
954 }
955
956 json_object_array_add(json_nexthops, json_nexthop);
957 }
958
959 json_object_object_add(json_route, "nexthops", json_nexthops);
960 json_object_array_add(json, json_route);
961 return;
962 }
963
964 /* Nexthop information. */
965 for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
966 {
967 if (nexthop == re->nexthop)
968 {
969 /* Prefix information. */
970 len = vty_out (vty, "%c", zebra_route_char (re->type));
971 if (re->instance)
972 len += vty_out (vty, "[%d]", re->instance);
973 len += vty_out (vty, "%c%c %s",
974 CHECK_FLAG (re->flags, ZEBRA_FLAG_SELECTED)
975 ? '>' : ' ',
976 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
977 ? '*' : ' ',
978 srcdest_rnode2str (rn, buf, sizeof buf));
979
980 /* Distance and metric display. */
981 if (re->type != ZEBRA_ROUTE_CONNECT
982 && re->type != ZEBRA_ROUTE_KERNEL)
983 len += vty_out (vty, " [%d/%d]", re->distance,
984 re->metric);
985 }
986 else
987 vty_out (vty, " %c%*c",
988 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
989 ? '*' : ' ',
990 len - 3 + (2 * recursing), ' ');
991
992 switch (nexthop->type)
993 {
994 case NEXTHOP_TYPE_IPV4:
995 case NEXTHOP_TYPE_IPV4_IFINDEX:
996 vty_out (vty, " via %s", inet_ntoa (nexthop->gate.ipv4));
997 if (nexthop->ifindex)
998 vty_out (vty, ", %s",
999 ifindex2ifname (nexthop->ifindex, re->vrf_id));
1000 break;
1001 case NEXTHOP_TYPE_IPV6:
1002 case NEXTHOP_TYPE_IPV6_IFINDEX:
1003 vty_out (vty, " via %s",
1004 inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, sizeof buf));
1005 if (nexthop->ifindex)
1006 vty_out (vty, ", %s",
1007 ifindex2ifname (nexthop->ifindex, re->vrf_id));
1008 break;
1009
1010 case NEXTHOP_TYPE_IFINDEX:
1011 vty_out (vty, " is directly connected, %s",
1012 ifindex2ifname (nexthop->ifindex, re->vrf_id));
1013 break;
1014 case NEXTHOP_TYPE_BLACKHOLE:
1015 vty_out (vty, " is directly connected, Null0");
1016 break;
1017 default:
1018 break;
1019 }
1020 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1021 vty_out (vty, " inactive");
1022
1023 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK))
1024 vty_out (vty, " onlink");
1025
1026 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
1027 vty_out (vty, " (recursive)");
1028
1029 switch (nexthop->type)
1030 {
1031 case NEXTHOP_TYPE_IPV4:
1032 case NEXTHOP_TYPE_IPV4_IFINDEX:
1033 if (nexthop->src.ipv4.s_addr)
1034 {
1035 if (inet_ntop(AF_INET, &nexthop->src.ipv4, buf, sizeof buf))
1036 vty_out (vty, ", src %s", buf);
1037 }
1038 break;
1039 case NEXTHOP_TYPE_IPV6:
1040 case NEXTHOP_TYPE_IPV6_IFINDEX:
1041 if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any))
1042 {
1043 if (inet_ntop(AF_INET6, &nexthop->src.ipv6, buf, sizeof buf))
1044 vty_out (vty, ", src %s", buf);
1045 }
1046 break;
1047 default:
1048 break;
1049 }
1050
1051 /* Label information */
1052 if (nexthop->nh_label && nexthop->nh_label->num_labels)
1053 {
1054 vty_out (vty, ", label %s",
1055 mpls_label2str (nexthop->nh_label->num_labels,
1056 nexthop->nh_label->label, buf, sizeof buf, 1));
1057 }
1058
1059 if (CHECK_FLAG (re->flags, ZEBRA_FLAG_BLACKHOLE))
1060 vty_out (vty, ", bh");
1061 if (CHECK_FLAG (re->flags, ZEBRA_FLAG_REJECT))
1062 vty_out (vty, ", rej");
1063
1064 if (re->type == ZEBRA_ROUTE_RIP
1065 || re->type == ZEBRA_ROUTE_OSPF
1066 || re->type == ZEBRA_ROUTE_ISIS
1067 || re->type == ZEBRA_ROUTE_NHRP
1068 || re->type == ZEBRA_ROUTE_TABLE
1069 || re->type == ZEBRA_ROUTE_BGP)
1070 {
1071 time_t uptime;
1072 struct tm *tm;
1073
1074 uptime = time (NULL);
1075 uptime -= re->uptime;
1076 tm = gmtime (&uptime);
1077
1078 if (uptime < ONE_DAY_SECOND)
1079 vty_out (vty, ", %02d:%02d:%02d",
1080 tm->tm_hour, tm->tm_min, tm->tm_sec);
1081 else if (uptime < ONE_WEEK_SECOND)
1082 vty_out (vty, ", %dd%02dh%02dm",
1083 tm->tm_yday, tm->tm_hour, tm->tm_min);
1084 else
1085 vty_out (vty, ", %02dw%dd%02dh",
1086 tm->tm_yday/7,
1087 tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
1088 }
1089 vty_out (vty, "%s", VTY_NEWLINE);
1090 }
1091 }
1092
1093 static bool
1094 use_fib (struct cmd_token *token)
1095 {
1096 return strncmp(token->arg, "route", strlen(token->arg));
1097 }
1098
1099 static int
1100 do_show_ip_route (struct vty *vty, const char *vrf_name, afi_t afi, safi_t safi,
1101 bool use_fib, u_char use_json, route_tag_t tag,
1102 struct prefix *longer_prefix_p, bool supernets_only,
1103 int type, u_short ospf_instance_id)
1104 {
1105 struct route_table *table;
1106 struct route_node *rn;
1107 struct route_entry *re;
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 u_int32_t addr;
1114
1115 if (!(zvrf = zebra_vrf_lookup_by_name (vrf_name)))
1116 {
1117 if (use_json)
1118 vty_out (vty, "{}%s", VTY_NEWLINE);
1119 else
1120 vty_out (vty, "vrf %s not defined%s", vrf_name, VTY_NEWLINE);
1121 return CMD_SUCCESS;
1122 }
1123
1124 if (zvrf_id (zvrf) == VRF_UNKNOWN)
1125 {
1126 if (use_json)
1127 vty_out (vty, "{}%s", VTY_NEWLINE);
1128 else
1129 vty_out (vty, "vrf %s inactive%s", vrf_name, VTY_NEWLINE);
1130 return CMD_SUCCESS;
1131 }
1132
1133 table = zebra_vrf_table (afi, safi, zvrf_id (zvrf));
1134 if (! table)
1135 {
1136 if (use_json)
1137 vty_out (vty, "{}%s", VTY_NEWLINE);
1138 return CMD_SUCCESS;
1139 }
1140
1141 if (use_json)
1142 json = json_object_new_object();
1143
1144 /* Show all routes. */
1145 for (rn = route_top (table); rn; rn = route_next (rn))
1146 {
1147 RNODE_FOREACH_RE (rn, re)
1148 {
1149 if (use_fib && !CHECK_FLAG(re->status, ROUTE_ENTRY_SELECTED_FIB))
1150 continue;
1151
1152 if (tag && re->tag != tag)
1153 continue;
1154
1155 if (longer_prefix_p && ! prefix_match (longer_prefix_p, &rn->p))
1156 continue;
1157
1158 /* This can only be true when the afi is IPv4 */
1159 if (supernets_only)
1160 {
1161 addr = ntohl (rn->p.u.prefix4.s_addr);
1162
1163 if (IN_CLASSC (addr) && rn->p.prefixlen >= 24)
1164 continue;
1165
1166 if (IN_CLASSB (addr) && rn->p.prefixlen >= 16)
1167 continue;
1168
1169 if (IN_CLASSA (addr) && rn->p.prefixlen >= 8)
1170 continue;
1171 }
1172
1173 if (type && re->type != type)
1174 continue;
1175
1176 if (ospf_instance_id && (re->type != ZEBRA_ROUTE_OSPF || re->instance != ospf_instance_id))
1177 continue;
1178
1179 if (use_json)
1180 {
1181 if (!json_prefix)
1182 json_prefix = json_object_new_array();
1183 }
1184 else
1185 {
1186 if (first)
1187 {
1188 if (afi == AFI_IP)
1189 vty_out (vty, SHOW_ROUTE_V4_HEADER);
1190 else
1191 vty_out (vty, SHOW_ROUTE_V6_HEADER);
1192
1193 if (zvrf_id (zvrf) != VRF_DEFAULT)
1194 vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE);
1195
1196 first = 0;
1197 }
1198 }
1199
1200 vty_show_ip_route (vty, rn, re, json_prefix);
1201 }
1202
1203 if (json_prefix)
1204 {
1205 prefix2str (&rn->p, buf, sizeof buf);
1206 json_object_object_add(json, buf, json_prefix);
1207 json_prefix = NULL;
1208 }
1209 }
1210
1211 if (use_json)
1212 {
1213 vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
1214 json_object_free(json);
1215 }
1216
1217 return CMD_SUCCESS;
1218 }
1219
1220 DEFUN (show_ip_nht,
1221 show_ip_nht_cmd,
1222 "show ip nht [vrf NAME]",
1223 SHOW_STR
1224 IP_STR
1225 "IP nexthop tracking table\n"
1226 VRF_CMD_HELP_STR)
1227 {
1228 int idx_vrf = 4;
1229 vrf_id_t vrf_id = VRF_DEFAULT;
1230
1231 if (argc == 5)
1232 VRF_GET_ID (vrf_id, argv[idx_vrf]->arg);
1233
1234 zebra_print_rnh_table(vrf_id, AF_INET, vty, RNH_NEXTHOP_TYPE);
1235 return CMD_SUCCESS;
1236 }
1237
1238
1239 DEFUN (show_ip_nht_vrf_all,
1240 show_ip_nht_vrf_all_cmd,
1241 "show ip nht vrf all",
1242 SHOW_STR
1243 IP_STR
1244 "IP nexthop tracking table\n"
1245 VRF_ALL_CMD_HELP_STR)
1246 {
1247 struct vrf *vrf;
1248 struct zebra_vrf *zvrf;
1249
1250 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
1251 if ((zvrf = vrf->info) != NULL)
1252 {
1253 vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE);
1254 zebra_print_rnh_table(zvrf_id (zvrf), AF_INET, vty, RNH_NEXTHOP_TYPE);
1255 }
1256
1257 return CMD_SUCCESS;
1258 }
1259
1260 DEFUN (show_ipv6_nht,
1261 show_ipv6_nht_cmd,
1262 "show ipv6 nht [vrf NAME]",
1263 SHOW_STR
1264 IPV6_STR
1265 "IPv6 nexthop tracking table\n"
1266 VRF_CMD_HELP_STR)
1267 {
1268 int idx_vrf = 4;
1269 vrf_id_t vrf_id = VRF_DEFAULT;
1270
1271 if (argc == 5)
1272 VRF_GET_ID (vrf_id, argv[idx_vrf]->arg);
1273
1274 zebra_print_rnh_table(vrf_id, AF_INET6, vty, RNH_NEXTHOP_TYPE);
1275 return CMD_SUCCESS;
1276 }
1277
1278
1279 DEFUN (show_ipv6_nht_vrf_all,
1280 show_ipv6_nht_vrf_all_cmd,
1281 "show ipv6 nht vrf all",
1282 SHOW_STR
1283 IP_STR
1284 "IPv6 nexthop tracking table\n"
1285 VRF_ALL_CMD_HELP_STR)
1286 {
1287 struct vrf *vrf;
1288 struct zebra_vrf *zvrf;
1289
1290 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
1291 if ((zvrf = vrf->info) != NULL)
1292 {
1293 vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE);
1294 zebra_print_rnh_table(zvrf_id (zvrf), AF_INET6, vty, RNH_NEXTHOP_TYPE);
1295 }
1296
1297 return CMD_SUCCESS;
1298 }
1299
1300 DEFUN (ip_nht_default_route,
1301 ip_nht_default_route_cmd,
1302 "ip nht resolve-via-default",
1303 IP_STR
1304 "Filter Next Hop tracking route resolution\n"
1305 "Resolve via default route\n")
1306 {
1307 if (zebra_rnh_ip_default_route)
1308 return CMD_SUCCESS;
1309
1310 zebra_rnh_ip_default_route = 1;
1311 zebra_evaluate_rnh(0, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
1312 return CMD_SUCCESS;
1313 }
1314
1315 DEFUN (no_ip_nht_default_route,
1316 no_ip_nht_default_route_cmd,
1317 "no ip nht resolve-via-default",
1318 NO_STR
1319 IP_STR
1320 "Filter Next Hop tracking route resolution\n"
1321 "Resolve via default route\n")
1322 {
1323 if (!zebra_rnh_ip_default_route)
1324 return CMD_SUCCESS;
1325
1326 zebra_rnh_ip_default_route = 0;
1327 zebra_evaluate_rnh(0, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
1328 return CMD_SUCCESS;
1329 }
1330
1331 DEFUN (ipv6_nht_default_route,
1332 ipv6_nht_default_route_cmd,
1333 "ipv6 nht resolve-via-default",
1334 IP6_STR
1335 "Filter Next Hop tracking route resolution\n"
1336 "Resolve via default route\n")
1337 {
1338 if (zebra_rnh_ipv6_default_route)
1339 return CMD_SUCCESS;
1340
1341 zebra_rnh_ipv6_default_route = 1;
1342 zebra_evaluate_rnh(0, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL);
1343 return CMD_SUCCESS;
1344 }
1345
1346 DEFUN (no_ipv6_nht_default_route,
1347 no_ipv6_nht_default_route_cmd,
1348 "no ipv6 nht resolve-via-default",
1349 NO_STR
1350 IP6_STR
1351 "Filter Next Hop tracking route resolution\n"
1352 "Resolve via default route\n")
1353 {
1354 if (!zebra_rnh_ipv6_default_route)
1355 return CMD_SUCCESS;
1356
1357 zebra_rnh_ipv6_default_route = 0;
1358 zebra_evaluate_rnh(0, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL);
1359 return CMD_SUCCESS;
1360 }
1361
1362 // dwalton one "show ip route" to rule them all
1363 DEFUN (show_ip_route,
1364 show_ip_route_cmd,
1365 "show ip <fib|route> [vrf NAME] [tag (1-4294967295)|A.B.C.D/M longer-prefixes|supernets-only|" FRR_IP_REDIST_STR_ZEBRA "|ospf (1-65535)] [json]",
1366 SHOW_STR
1367 IP_STR
1368 "IP forwarding table\n"
1369 "IP routing table\n"
1370 VRF_CMD_HELP_STR
1371 "Show only routes with tag\n"
1372 "Tag value\n"
1373 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1374 "Show route matching the specified Network/Mask pair only\n"
1375 "Show supernet entries only\n"
1376 FRR_IP_REDIST_HELP_STR_ZEBRA
1377 "Open Shortest Path First (OSPFv2)\n"
1378 "Instance ID\n"
1379 JSON_STR)
1380 {
1381 bool uf = use_fib(argv[2]);
1382 struct route_table *table;
1383 int vrf_all = 0;
1384 route_tag_t tag = 0;
1385 vrf_id_t vrf_id = VRF_DEFAULT;
1386 struct vrf *vrf;
1387 struct zebra_vrf *zvrf;
1388 int uj = use_json(argc, argv);
1389 int idx = 0;
1390 struct prefix p;
1391 bool longer_prefixes = false;
1392 bool supernets_only = false;
1393 int type = 0;
1394 u_short ospf_instance_id = 0;
1395
1396 if (argv_find (argv, argc, "vrf", &idx))
1397 {
1398 if (strmatch(argv[idx+1]->arg, "all"))
1399 vrf_all = 1;
1400 else
1401 VRF_GET_ID (vrf_id, argv[idx+1]->arg);
1402 }
1403
1404 if (argv_find (argv, argc, "tag", &idx))
1405 VTY_GET_INTEGER_RANGE("tag", tag, argv[idx+1]->arg, 0, 4294967295);
1406
1407 else if (argv_find (argv, argc, "A.B.C.D/M", &idx))
1408 {
1409 str2prefix (argv[idx]->arg, &p);
1410 longer_prefixes = true;
1411 }
1412
1413 else if (argv_find (argv, argc, "supernets_only", &idx))
1414 supernets_only = true;
1415
1416 else
1417 {
1418 if (argv_find (argv, argc, "kernel", &idx))
1419 type = proto_redistnum (AFI_IP, argv[idx]->text);
1420 else if (argv_find (argv, argc, "babel", &idx))
1421 type = proto_redistnum (AFI_IP, argv[idx]->text);
1422 else if (argv_find (argv, argc, "connected", &idx))
1423 type = proto_redistnum (AFI_IP, argv[idx]->text);
1424 else if (argv_find (argv, argc, "static", &idx))
1425 type = proto_redistnum (AFI_IP, argv[idx]->text);
1426 else if (argv_find (argv, argc, "rip", &idx))
1427 type = proto_redistnum (AFI_IP, argv[idx]->text);
1428 else if (argv_find (argv, argc, "ospf", &idx))
1429 type = proto_redistnum (AFI_IP, argv[idx]->text);
1430 else if (argv_find (argv, argc, "isis", &idx))
1431 type = proto_redistnum (AFI_IP, argv[idx]->text);
1432 else if (argv_find (argv, argc, "bgp", &idx))
1433 type = proto_redistnum (AFI_IP, argv[idx]->text);
1434 else if (argv_find (argv, argc, "pim", &idx))
1435 type = proto_redistnum (AFI_IP, argv[idx]->text);
1436 else if (argv_find (argv, argc, "eigrp", &idx))
1437 type = proto_redistnum (AFI_IP, argv[idx]->text);
1438 else if (argv_find (argv, argc, "nhrp", &idx))
1439 type = proto_redistnum (AFI_IP, argv[idx]->text);
1440 else if (argv_find (argv, argc, "table", &idx))
1441 type = proto_redistnum (AFI_IP, argv[idx]->text);
1442 else if (argv_find (argv, argc, "vnc", &idx))
1443 type = proto_redistnum (AFI_IP, argv[idx]->text);
1444
1445 if (argv_find (argv, argc, "(1-65535)", &idx))
1446 VTY_GET_INTEGER ("Instance", ospf_instance_id, argv[idx]->arg);
1447
1448 if (type < 0)
1449 {
1450 vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
1451 return CMD_WARNING;
1452 }
1453 }
1454
1455 if (vrf_all)
1456 {
1457 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
1458 {
1459 if ((zvrf = vrf->info) == NULL ||
1460 (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
1461 continue;
1462
1463 do_show_ip_route (vty, zvrf_name (zvrf), AFI_IP, SAFI_UNICAST, uf, uj, tag,
1464 longer_prefixes ? &p : NULL, supernets_only, type, ospf_instance_id);
1465 }
1466 }
1467 else
1468 {
1469 vrf = vrf_lookup_by_id (vrf_id);
1470 do_show_ip_route (vty, vrf->name, AFI_IP, SAFI_UNICAST, uf, uj, tag,
1471 longer_prefixes ? &p : NULL, supernets_only, type, ospf_instance_id);
1472 }
1473 return CMD_SUCCESS;
1474 }
1475
1476 DEFUN (show_ip_route_addr,
1477 show_ip_route_addr_cmd,
1478 "show ip route [vrf NAME] A.B.C.D",
1479 SHOW_STR
1480 IP_STR
1481 "IP routing table\n"
1482 VRF_CMD_HELP_STR
1483 "Network in the IP routing table to display\n")
1484 {
1485 int ret;
1486 struct prefix_ipv4 p;
1487 struct route_table *table;
1488 struct route_node *rn;
1489 vrf_id_t vrf_id = VRF_DEFAULT;
1490
1491 if (strmatch(argv[3]->text, "vrf"))
1492 {
1493 VRF_GET_ID (vrf_id, argv[4]->arg);
1494 ret = str2prefix_ipv4 (argv[5]->arg, &p);
1495 }
1496 else
1497 {
1498 ret = str2prefix_ipv4 (argv[3]->arg, &p);
1499 }
1500
1501 if (ret <= 0)
1502 {
1503 vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
1504 return CMD_WARNING;
1505 }
1506
1507 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
1508 if (! table)
1509 return CMD_SUCCESS;
1510
1511 rn = route_node_match (table, (struct prefix *) &p);
1512 if (! rn)
1513 {
1514 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
1515 return CMD_WARNING;
1516 }
1517
1518 vty_show_ip_route_detail (vty, rn, 0);
1519
1520 route_unlock_node (rn);
1521
1522 return CMD_SUCCESS;
1523 }
1524
1525 DEFUN (show_ip_route_prefix,
1526 show_ip_route_prefix_cmd,
1527 "show ip route [vrf NAME] A.B.C.D/M",
1528 SHOW_STR
1529 IP_STR
1530 "IP routing table\n"
1531 VRF_CMD_HELP_STR
1532 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
1533 {
1534 int ret;
1535 struct prefix_ipv4 p;
1536 struct route_table *table;
1537 struct route_node *rn;
1538 vrf_id_t vrf_id = VRF_DEFAULT;
1539
1540 if (strmatch(argv[3]->text, "vrf"))
1541 {
1542 VRF_GET_ID (vrf_id, argv[4]->arg);
1543 ret = str2prefix_ipv4 (argv[5]->arg, &p);
1544 }
1545 else
1546 {
1547 ret = str2prefix_ipv4 (argv[3]->arg, &p);
1548 }
1549
1550 if (ret <= 0)
1551 {
1552 vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
1553 return CMD_WARNING;
1554 }
1555
1556 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
1557 if (! table)
1558 return CMD_SUCCESS;
1559
1560 rn = route_node_match (table, (struct prefix *) &p);
1561 if (! rn || rn->p.prefixlen != p.prefixlen)
1562 {
1563 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
1564 return CMD_WARNING;
1565 }
1566
1567 vty_show_ip_route_detail (vty, rn, 0);
1568
1569 route_unlock_node (rn);
1570
1571 return CMD_SUCCESS;
1572 }
1573
1574
1575 static void
1576 vty_show_ip_route_summary (struct vty *vty, struct route_table *table)
1577 {
1578 struct route_node *rn;
1579 struct route_entry *re;
1580 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1581 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1582 u_int32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1583 u_int32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1584 u_int32_t i;
1585 u_int32_t is_ibgp;
1586
1587 memset (&rib_cnt, 0, sizeof(rib_cnt));
1588 memset (&fib_cnt, 0, sizeof(fib_cnt));
1589 for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
1590 RNODE_FOREACH_RE (rn, re)
1591 {
1592 is_ibgp = (re->type == ZEBRA_ROUTE_BGP &&
1593 CHECK_FLAG (re->flags, ZEBRA_FLAG_IBGP));
1594
1595 rib_cnt[ZEBRA_ROUTE_TOTAL]++;
1596 if (is_ibgp)
1597 rib_cnt[ZEBRA_ROUTE_IBGP]++;
1598 else
1599 rib_cnt[re->type]++;
1600
1601 if (CHECK_FLAG (re->flags, ZEBRA_FLAG_SELECTED))
1602 {
1603 fib_cnt[ZEBRA_ROUTE_TOTAL]++;
1604
1605 if (is_ibgp)
1606 fib_cnt[ZEBRA_ROUTE_IBGP]++;
1607 else
1608 fib_cnt[re->type]++;
1609 }
1610 }
1611
1612 vty_out (vty, "%-20s %-20s %s (vrf %s)%s",
1613 "Route Source", "Routes", "FIB",
1614 zvrf_name (((rib_table_info_t *)table->info)->zvrf),
1615 VTY_NEWLINE);
1616
1617 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
1618 {
1619 if ((rib_cnt[i] > 0) ||
1620 (i == ZEBRA_ROUTE_BGP && rib_cnt[ZEBRA_ROUTE_IBGP] > 0))
1621 {
1622 if (i == ZEBRA_ROUTE_BGP)
1623 {
1624 vty_out (vty, "%-20s %-20d %-20d %s", "ebgp",
1625 rib_cnt[ZEBRA_ROUTE_BGP], fib_cnt[ZEBRA_ROUTE_BGP],
1626 VTY_NEWLINE);
1627 vty_out (vty, "%-20s %-20d %-20d %s", "ibgp",
1628 rib_cnt[ZEBRA_ROUTE_IBGP], fib_cnt[ZEBRA_ROUTE_IBGP],
1629 VTY_NEWLINE);
1630 }
1631 else
1632 vty_out (vty, "%-20s %-20d %-20d %s", zebra_route_string(i),
1633 rib_cnt[i], fib_cnt[i], VTY_NEWLINE);
1634 }
1635 }
1636
1637 vty_out (vty, "------%s", VTY_NEWLINE);
1638 vty_out (vty, "%-20s %-20d %-20d %s", "Totals", rib_cnt[ZEBRA_ROUTE_TOTAL],
1639 fib_cnt[ZEBRA_ROUTE_TOTAL], VTY_NEWLINE);
1640 vty_out (vty, "%s", VTY_NEWLINE);
1641 }
1642
1643 /*
1644 * Implementation of the ip route summary prefix command.
1645 *
1646 * This command prints the primary prefixes that have been installed by various
1647 * protocols on the box.
1648 *
1649 */
1650 static void
1651 vty_show_ip_route_summary_prefix (struct vty *vty, struct route_table *table)
1652 {
1653 struct route_node *rn;
1654 struct route_entry *re;
1655 struct nexthop *nexthop;
1656 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1657 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1658 u_int32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1659 u_int32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1660 u_int32_t i;
1661 int cnt;
1662
1663 memset (&rib_cnt, 0, sizeof(rib_cnt));
1664 memset (&fib_cnt, 0, sizeof(fib_cnt));
1665 for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
1666 RNODE_FOREACH_RE (rn, re)
1667 {
1668
1669 /*
1670 * In case of ECMP, count only once.
1671 */
1672 cnt = 0;
1673 for (nexthop = re->nexthop; (!cnt && nexthop); nexthop = nexthop->next)
1674 {
1675 cnt++;
1676 rib_cnt[ZEBRA_ROUTE_TOTAL]++;
1677 rib_cnt[re->type]++;
1678 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
1679 {
1680 fib_cnt[ZEBRA_ROUTE_TOTAL]++;
1681 fib_cnt[re->type]++;
1682 }
1683 if (re->type == ZEBRA_ROUTE_BGP &&
1684 CHECK_FLAG (re->flags, ZEBRA_FLAG_IBGP))
1685 {
1686 rib_cnt[ZEBRA_ROUTE_IBGP]++;
1687 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
1688 fib_cnt[ZEBRA_ROUTE_IBGP]++;
1689 }
1690 }
1691 }
1692
1693 vty_out (vty, "%-20s %-20s %s (vrf %s)%s",
1694 "Route Source", "Prefix Routes", "FIB",
1695 zvrf_name (((rib_table_info_t *)table->info)->zvrf),
1696 VTY_NEWLINE);
1697
1698 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
1699 {
1700 if (rib_cnt[i] > 0)
1701 {
1702 if (i == ZEBRA_ROUTE_BGP)
1703 {
1704 vty_out (vty, "%-20s %-20d %-20d %s", "ebgp",
1705 rib_cnt[ZEBRA_ROUTE_BGP] - rib_cnt[ZEBRA_ROUTE_IBGP],
1706 fib_cnt[ZEBRA_ROUTE_BGP] - fib_cnt[ZEBRA_ROUTE_IBGP],
1707 VTY_NEWLINE);
1708 vty_out (vty, "%-20s %-20d %-20d %s", "ibgp",
1709 rib_cnt[ZEBRA_ROUTE_IBGP], fib_cnt[ZEBRA_ROUTE_IBGP],
1710 VTY_NEWLINE);
1711 }
1712 else
1713 vty_out (vty, "%-20s %-20d %-20d %s", zebra_route_string(i),
1714 rib_cnt[i], fib_cnt[i], VTY_NEWLINE);
1715 }
1716 }
1717
1718 vty_out (vty, "------%s", VTY_NEWLINE);
1719 vty_out (vty, "%-20s %-20d %-20d %s", "Totals", rib_cnt[ZEBRA_ROUTE_TOTAL],
1720 fib_cnt[ZEBRA_ROUTE_TOTAL], VTY_NEWLINE);
1721 vty_out (vty, "%s", VTY_NEWLINE);
1722 }
1723
1724 /* Show route summary. */
1725 DEFUN (show_ip_route_summary,
1726 show_ip_route_summary_cmd,
1727 "show ip route [vrf NAME] summary",
1728 SHOW_STR
1729 IP_STR
1730 "IP routing table\n"
1731 VRF_CMD_HELP_STR
1732 "Summary of all routes\n")
1733 {
1734 struct route_table *table;
1735 vrf_id_t vrf_id = VRF_DEFAULT;
1736
1737 if (strmatch(argv[3]->text, "vrf"))
1738 VRF_GET_ID (vrf_id, argv[4]->arg);
1739
1740 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
1741 if (! table)
1742 return CMD_SUCCESS;
1743
1744 vty_show_ip_route_summary (vty, table);
1745
1746 return CMD_SUCCESS;
1747 }
1748
1749 /* Show route summary prefix. */
1750 DEFUN (show_ip_route_summary_prefix,
1751 show_ip_route_summary_prefix_cmd,
1752 "show ip route [vrf NAME] summary prefix",
1753 SHOW_STR
1754 IP_STR
1755 "IP routing table\n"
1756 VRF_CMD_HELP_STR
1757 "Summary of all routes\n"
1758 "Prefix routes\n")
1759 {
1760 struct route_table *table;
1761 vrf_id_t vrf_id = VRF_DEFAULT;
1762
1763 if (strmatch(argv[3]->text, "vrf"))
1764 VRF_GET_ID (vrf_id, argv[4]->arg);
1765
1766 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
1767 if (! table)
1768 return CMD_SUCCESS;
1769
1770 vty_show_ip_route_summary_prefix (vty, table);
1771
1772 return CMD_SUCCESS;
1773 }
1774
1775
1776 DEFUN (show_ip_route_vrf_all_addr,
1777 show_ip_route_vrf_all_addr_cmd,
1778 "show ip route vrf all A.B.C.D",
1779 SHOW_STR
1780 IP_STR
1781 "IP routing table\n"
1782 VRF_ALL_CMD_HELP_STR
1783 "Network in the IP routing table to display\n")
1784 {
1785 int idx_ipv4 = 5;
1786 int ret;
1787 struct prefix_ipv4 p;
1788 struct route_table *table;
1789 struct route_node *rn;
1790 struct vrf *vrf;
1791 struct zebra_vrf *zvrf;
1792
1793 ret = str2prefix_ipv4 (argv[idx_ipv4]->arg, &p);
1794 if (ret <= 0)
1795 {
1796 vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
1797 return CMD_WARNING;
1798 }
1799
1800 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
1801 {
1802 if ((zvrf = vrf->info) == NULL ||
1803 (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
1804 continue;
1805
1806 rn = route_node_match (table, (struct prefix *) &p);
1807 if (! rn)
1808 continue;
1809
1810 vty_show_ip_route_detail (vty, rn, 0);
1811
1812 route_unlock_node (rn);
1813 }
1814
1815 return CMD_SUCCESS;
1816 }
1817
1818 DEFUN (show_ip_route_vrf_all_prefix,
1819 show_ip_route_vrf_all_prefix_cmd,
1820 "show ip route vrf all A.B.C.D/M",
1821 SHOW_STR
1822 IP_STR
1823 "IP routing table\n"
1824 VRF_ALL_CMD_HELP_STR
1825 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
1826 {
1827 int idx_ipv4_prefixlen = 5;
1828 int ret;
1829 struct prefix_ipv4 p;
1830 struct route_table *table;
1831 struct route_node *rn;
1832 struct vrf *vrf;
1833 struct zebra_vrf *zvrf;
1834
1835 ret = str2prefix_ipv4 (argv[idx_ipv4_prefixlen]->arg, &p);
1836 if (ret <= 0)
1837 {
1838 vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
1839 return CMD_WARNING;
1840 }
1841
1842 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
1843 {
1844 if ((zvrf = vrf->info) == NULL ||
1845 (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
1846 continue;
1847
1848 rn = route_node_match (table, (struct prefix *) &p);
1849 if (! rn)
1850 continue;
1851 if (rn->p.prefixlen != p.prefixlen)
1852 {
1853 route_unlock_node (rn);
1854 continue;
1855 }
1856
1857 vty_show_ip_route_detail (vty, rn, 0);
1858
1859 route_unlock_node (rn);
1860 }
1861
1862 return CMD_SUCCESS;
1863 }
1864
1865 DEFUN (show_ip_route_vrf_all_summary,
1866 show_ip_route_vrf_all_summary_cmd,
1867 "show ip route vrf all summary ",
1868 SHOW_STR
1869 IP_STR
1870 "IP routing table\n"
1871 VRF_ALL_CMD_HELP_STR
1872 "Summary of all routes\n")
1873 {
1874 struct vrf *vrf;
1875 struct zebra_vrf *zvrf;
1876
1877 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
1878 if ((zvrf = vrf->info) != NULL)
1879 vty_show_ip_route_summary (vty, zvrf->table[AFI_IP][SAFI_UNICAST]);
1880
1881 return CMD_SUCCESS;
1882 }
1883
1884 DEFUN (show_ip_route_vrf_all_summary_prefix,
1885 show_ip_route_vrf_all_summary_prefix_cmd,
1886 "show ip route vrf all summary prefix",
1887 SHOW_STR
1888 IP_STR
1889 "IP routing table\n"
1890 VRF_ALL_CMD_HELP_STR
1891 "Summary of all routes\n"
1892 "Prefix routes\n")
1893 {
1894 struct vrf *vrf;
1895 struct zebra_vrf *zvrf;
1896
1897 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
1898 if ((zvrf = vrf->info) != NULL)
1899 vty_show_ip_route_summary_prefix (vty, zvrf->table[AFI_IP][SAFI_UNICAST]);
1900
1901 return CMD_SUCCESS;
1902 }
1903
1904 /* Write static route configuration. */
1905 static int
1906 static_config (struct vty *vty, afi_t afi, safi_t safi, const char *cmd)
1907 {
1908 struct route_node *rn;
1909 struct static_route *si;
1910 struct route_table *stable;
1911 struct vrf *vrf;
1912 struct zebra_vrf *zvrf;
1913 char buf[SRCDEST2STR_BUFFER];
1914 int write =0;
1915
1916 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
1917 {
1918 if (!(zvrf = vrf->info))
1919 continue;
1920 if ((stable = zvrf->stable[afi][safi]) == NULL)
1921 continue;
1922
1923 for (rn = route_top (stable); rn; rn = srcdest_route_next (rn))
1924 for (si = rn->info; si; si = si->next)
1925 {
1926 vty_out (vty, "%s %s", cmd, srcdest_rnode2str (rn, buf, sizeof buf));
1927
1928 switch (si->type)
1929 {
1930 case STATIC_IPV4_GATEWAY:
1931 vty_out (vty, " %s", inet_ntoa (si->addr.ipv4));
1932 break;
1933 case STATIC_IPV6_GATEWAY:
1934 vty_out (vty, " %s", inet_ntop (AF_INET6, &si->addr.ipv6, buf, sizeof buf));
1935 break;
1936 case STATIC_IFINDEX:
1937 vty_out (vty, " %s", si->ifname);
1938 break;
1939 case STATIC_BLACKHOLE:
1940 vty_out (vty, " Null0");
1941 break;
1942 case STATIC_IPV6_GATEWAY_IFINDEX:
1943 vty_out (vty, " %s %s",
1944 inet_ntop (AF_INET6, &si->addr.ipv6, buf, sizeof buf),
1945 ifindex2ifname (si->ifindex, si->vrf_id));
1946 break;
1947 }
1948
1949 /* flags are incompatible with STATIC_BLACKHOLE */
1950 if (si->type != STATIC_BLACKHOLE)
1951 {
1952 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_REJECT))
1953 vty_out (vty, " %s", "reject");
1954
1955 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_BLACKHOLE))
1956 vty_out (vty, " %s", "blackhole");
1957 }
1958
1959 if (si->tag)
1960 vty_out (vty, " tag %"ROUTE_TAG_PRI, si->tag);
1961
1962 if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT)
1963 vty_out (vty, " %d", si->distance);
1964
1965 if (si->vrf_id != VRF_DEFAULT)
1966 vty_out (vty, " vrf %s", zvrf_name (zvrf));
1967
1968 /* Label information */
1969 if (si->snh_label.num_labels)
1970 vty_out (vty, " label %s",
1971 mpls_label2str (si->snh_label.num_labels,
1972 si->snh_label.label, buf, sizeof buf, 0));
1973
1974 vty_out (vty, "%s", VTY_NEWLINE);
1975
1976 write = 1;
1977 }
1978 }
1979 return write;
1980 }
1981
1982 /* General fucntion for IPv6 static route. */
1983 int
1984 static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str,
1985 const char *src_str,
1986 const char *gate_str, const char *ifname,
1987 const char *flag_str, const char *tag_str,
1988 const char *distance_str, const char *vrf_id_str,
1989 const char *label_str)
1990 {
1991 int ret;
1992 u_char distance;
1993 struct prefix p, src;
1994 struct prefix_ipv6 *src_p = NULL;
1995 struct in6_addr *gate = NULL;
1996 struct in6_addr gate_addr;
1997 u_char type = STATIC_BLACKHOLE;
1998 u_char flag = 0;
1999 route_tag_t tag = 0;
2000 unsigned int ifindex = 0;
2001 struct interface *ifp = NULL;
2002 struct zebra_vrf *zvrf;
2003 struct static_nh_label snh_label;
2004
2005 ret = str2prefix (dest_str, &p);
2006 if (ret <= 0)
2007 {
2008 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
2009 return CMD_WARNING;
2010 }
2011
2012 if (src_str)
2013 {
2014 ret = str2prefix (src_str, &src);
2015 if (ret <= 0 || src.family != AF_INET6)
2016 {
2017 vty_out (vty, "%% Malformed source address%s", VTY_NEWLINE);
2018 return CMD_WARNING;
2019 }
2020 src_p = (struct prefix_ipv6*)&src;
2021 }
2022
2023 /* Apply mask for given prefix. */
2024 apply_mask (&p);
2025
2026 /* Administrative distance. */
2027 if (distance_str)
2028 distance = atoi (distance_str);
2029 else
2030 distance = ZEBRA_STATIC_DISTANCE_DEFAULT;
2031
2032 /* tag */
2033 if (tag_str)
2034 VTY_GET_INTEGER_RANGE("tag", tag, tag_str, 0, 4294967295);
2035
2036 /* When gateway is valid IPv6 addrees, then gate is treated as
2037 nexthop address other case gate is treated as interface name. */
2038 ret = inet_pton (AF_INET6, gate_str, &gate_addr);
2039
2040 /* VRF id */
2041 zvrf = zebra_vrf_lookup_by_name (vrf_id_str);
2042
2043 if (!zvrf)
2044 {
2045 vty_out (vty, "%% vrf %s is not defined%s", vrf_id_str, VTY_NEWLINE);
2046 return CMD_WARNING;
2047 }
2048
2049 /* Labels */
2050 memset (&snh_label, 0, sizeof (struct static_nh_label));
2051 if (label_str)
2052 {
2053 if (!mpls_enabled)
2054 {
2055 vty_out (vty, "%% MPLS not turned on in kernel, ignoring command%s",
2056 VTY_NEWLINE);
2057 return CMD_WARNING;
2058 }
2059 int rc = mpls_str2label (label_str, &snh_label.num_labels,
2060 snh_label.label);
2061 if (rc < 0)
2062 {
2063 switch (rc) {
2064 case -1:
2065 vty_out (vty, "%% Malformed label(s)%s", VTY_NEWLINE);
2066 break;
2067 case -2:
2068 vty_out (vty, "%% Cannot use reserved label(s) (%d-%d)%s",
2069 MPLS_MIN_RESERVED_LABEL, MPLS_MAX_RESERVED_LABEL,
2070 VTY_NEWLINE);
2071 break;
2072 case -3:
2073 vty_out (vty, "%% Too many labels. Enter %d or fewer%s",
2074 MPLS_MAX_LABELS, VTY_NEWLINE);
2075 break;
2076 }
2077 return CMD_WARNING;
2078 }
2079 }
2080
2081 /* Null0 static route. */
2082 if ((gate_str != NULL) && (strncasecmp (gate_str, "Null0", strlen (gate_str)) == 0))
2083 {
2084 if (flag_str)
2085 {
2086 vty_out (vty, "%% can not have flag %s with Null0%s", flag_str, VTY_NEWLINE);
2087 return CMD_WARNING;
2088 }
2089 if (add_cmd)
2090 static_add_route (AFI_IP6, SAFI_UNICAST, type, &p, NULL, NULL, ifindex, ifname,
2091 ZEBRA_FLAG_BLACKHOLE, tag, distance, zvrf, &snh_label);
2092 else
2093 static_delete_route (AFI_IP6, SAFI_UNICAST, type, &p, NULL, NULL, ifindex, tag,
2094 distance, zvrf, &snh_label);
2095 return CMD_SUCCESS;
2096 }
2097
2098 /* Route flags */
2099 if (flag_str) {
2100 switch(flag_str[0]) {
2101 case 'r':
2102 case 'R': /* XXX */
2103 SET_FLAG (flag, ZEBRA_FLAG_REJECT);
2104 break;
2105 case 'b':
2106 case 'B': /* XXX */
2107 SET_FLAG (flag, ZEBRA_FLAG_BLACKHOLE);
2108 break;
2109 default:
2110 vty_out (vty, "%% Malformed flag %s %s", flag_str, VTY_NEWLINE);
2111 return CMD_WARNING;
2112 }
2113 }
2114
2115 if (ifname)
2116 {
2117 /* When ifname is specified. It must be come with gateway
2118 address. */
2119 if (ret != 1)
2120 {
2121 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
2122 return CMD_WARNING;
2123 }
2124 type = STATIC_IPV6_GATEWAY_IFINDEX;
2125 gate = &gate_addr;
2126 ifp = if_lookup_by_name (ifname, zvrf_id (zvrf));
2127 if (!ifp)
2128 {
2129 vty_out (vty, "%% Malformed Interface name %s%s", ifname, VTY_NEWLINE);
2130 return CMD_WARNING;
2131 }
2132 ifindex = ifp->ifindex;
2133 }
2134 else
2135 {
2136 if (ret == 1)
2137 {
2138 type = STATIC_IPV6_GATEWAY;
2139 gate = &gate_addr;
2140 }
2141 else
2142 {
2143 type = STATIC_IFINDEX;
2144 ifp = if_lookup_by_name (gate_str, zvrf_id (zvrf));
2145 if (!ifp)
2146 {
2147 vty_out (vty, "%% Malformed Interface name %s%s", gate_str, VTY_NEWLINE);
2148 ifindex = IFINDEX_DELETED;
2149 }
2150 else
2151 ifindex = ifp->ifindex;
2152 ifname = gate_str;
2153 }
2154 }
2155
2156 if (add_cmd)
2157 static_add_route (AFI_IP6, SAFI_UNICAST, type, &p, src_p, (union g_addr *)gate,
2158 ifindex, ifname, flag, tag, distance, zvrf, &snh_label);
2159 else
2160 static_delete_route (AFI_IP6, SAFI_UNICAST, type, &p, src_p, (union g_addr *)gate,
2161 ifindex, tag, distance, zvrf, &snh_label);
2162
2163 return CMD_SUCCESS;
2164 }
2165
2166 DEFUN (ipv6_route,
2167 ipv6_route_cmd,
2168 "ipv6 route X:X::X:X/M [from X:X::X:X/M] <X:X::X:X|INTERFACE|null0> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
2169 IP_STR
2170 "Establish static routes\n"
2171 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2172 "IPv6 source-dest route\n"
2173 "IPv6 source prefix\n"
2174 "IPv6 gateway address\n"
2175 "IPv6 gateway interface name\n"
2176 "Null interface\n"
2177 "Set tag for this route\n"
2178 "Tag value\n"
2179 "Distance value for this prefix\n"
2180 VRF_CMD_HELP_STR
2181 MPLS_LABEL_HELPSTR)
2182 {
2183 int idx_ipv6_prefixlen = 2;
2184 int idx_ipv6_ifname;
2185 int idx_curr;
2186 char *src, *tag, *distance, *vrf;
2187
2188 if (!strcmp(argv[3]->text, "from"))
2189 {
2190 src = argv[4]->arg;
2191 idx_ipv6_ifname = 5;
2192 idx_curr = 6;
2193 }
2194 else
2195 {
2196 src = NULL;
2197 idx_ipv6_ifname = 3;
2198 idx_curr = 4;
2199 }
2200
2201 tag = distance = vrf = NULL;
2202 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
2203
2204 return static_ipv6_func (vty, 1,
2205 argv[idx_ipv6_prefixlen]->arg,
2206 src,
2207 argv[idx_ipv6_ifname]->arg,
2208 NULL, NULL,
2209 tag, distance, vrf, NULL);
2210 }
2211
2212 DEFUN (ipv6_route_flags,
2213 ipv6_route_flags_cmd,
2214 "ipv6 route X:X::X:X/M [from X:X::X:X/M] <X:X::X:X|INTERFACE> <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
2215 IP_STR
2216 "Establish static routes\n"
2217 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2218 "IPv6 source-dest route\n"
2219 "IPv6 source prefix\n"
2220 "IPv6 gateway address\n"
2221 "IPv6 gateway interface name\n"
2222 "Emit an ICMP unreachable when matched\n"
2223 "Silently discard pkts when matched\n"
2224 "Silently discard pkts when matched\n"
2225 "Set tag for this route\n"
2226 "Tag value\n"
2227 "Distance value for this prefix\n"
2228 VRF_CMD_HELP_STR
2229 MPLS_LABEL_HELPSTR)
2230 {
2231 int idx_ipv6_prefixlen = 2;
2232 int idx_ipv6_ifname;
2233 int idx_reject_blackhole;
2234 int idx_curr;
2235 char *src, *tag, *distance, *vrf;
2236
2237 if (!strcmp(argv[3]->text, "from"))
2238 {
2239 src = argv[4]->arg;
2240 idx_ipv6_ifname = 5;
2241 idx_reject_blackhole = 6;
2242 idx_curr = 7;
2243 }
2244 else
2245 {
2246 src = NULL;
2247 idx_ipv6_ifname = 3;
2248 idx_reject_blackhole = 4;
2249 idx_curr = 5;
2250 }
2251
2252 tag = distance = vrf = NULL;
2253 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
2254
2255 return static_ipv6_func (vty, 1,
2256 argv[idx_ipv6_prefixlen]->arg,
2257 src,
2258 argv[idx_ipv6_ifname]->arg,
2259 NULL,
2260 argv[idx_reject_blackhole]->arg,
2261 tag, distance, vrf, NULL);
2262 }
2263
2264 DEFUN (ipv6_route_ifname,
2265 ipv6_route_ifname_cmd,
2266 "ipv6 route X:X::X:X/M [from X:X::X:X/M] X:X::X:X INTERFACE [tag (1-4294967295)] [(1-255)] [vrf NAME]",
2267 IP_STR
2268 "Establish static routes\n"
2269 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2270 "IPv6 source-dest route\n"
2271 "IPv6 source prefix\n"
2272 "IPv6 gateway address\n"
2273 "IPv6 gateway interface name\n"
2274 "Set tag for this route\n"
2275 "Tag value\n"
2276 "Distance value for this prefix\n"
2277 VRF_CMD_HELP_STR
2278 MPLS_LABEL_HELPSTR)
2279 {
2280 int idx_ipv6_prefixlen = 2;
2281 int idx_ipv6 = 3;
2282 int idx_interface = 4;
2283 int idx_curr = 5;
2284 char *src, *tag, *distance, *vrf;
2285
2286 if (!strcmp(argv[3]->text, "from"))
2287 {
2288 src = argv[4]->arg;
2289 idx_ipv6 = 5;
2290 idx_interface = 6;
2291 idx_curr = 7;
2292 }
2293 else
2294 {
2295 src = NULL;
2296 idx_ipv6 = 3;
2297 idx_interface = 4;
2298 idx_curr = 5;
2299 }
2300
2301 tag = distance = vrf = NULL;
2302 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
2303
2304 return static_ipv6_func (vty, 1,
2305 argv[idx_ipv6_prefixlen]->arg,
2306 src,
2307 argv[idx_ipv6]->arg,
2308 argv[idx_interface]->arg,
2309 NULL,
2310 tag, distance, vrf, NULL);
2311 }
2312
2313 DEFUN (ipv6_route_ifname_flags,
2314 ipv6_route_ifname_flags_cmd,
2315 "ipv6 route X:X::X:X/M [from X:X::X:X/M] X:X::X:X INTERFACE <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
2316 IP_STR
2317 "Establish static routes\n"
2318 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2319 "IPv6 source-dest route\n"
2320 "IPv6 source prefix\n"
2321 "IPv6 gateway address\n"
2322 "IPv6 gateway interface name\n"
2323 "Emit an ICMP unreachable when matched\n"
2324 "Silently discard pkts when matched\n"
2325 "Set tag for this route\n"
2326 "Tag value\n"
2327 "Distance value for this prefix\n"
2328 VRF_CMD_HELP_STR
2329 MPLS_LABEL_HELPSTR)
2330 {
2331 int idx_ipv6_prefixlen = 2;
2332 int idx_ipv6;
2333 int idx_interface;
2334 int idx_reject_blackhole;
2335 int idx_curr;
2336 char *src, *tag, *distance, *vrf;
2337
2338 if (!strcmp(argv[3]->text, "from"))
2339 {
2340 src = argv[4]->arg;
2341 idx_ipv6 = 5;
2342 idx_interface = 6;
2343 idx_reject_blackhole = 7;
2344 idx_curr = 8;
2345 }
2346 else
2347 {
2348 src = NULL;
2349 idx_ipv6 = 3;
2350 idx_interface = 4;
2351 idx_reject_blackhole = 5;
2352 idx_curr = 6;
2353 }
2354
2355 tag = distance = vrf = NULL;
2356 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
2357
2358 return static_ipv6_func (vty, 1,
2359 argv[idx_ipv6_prefixlen]->arg,
2360 src,
2361 argv[idx_ipv6]->arg,
2362 argv[idx_interface]->arg,
2363 argv[idx_reject_blackhole]->arg,
2364 tag, distance, vrf, NULL);
2365 }
2366
2367 DEFUN (no_ipv6_route,
2368 no_ipv6_route_cmd,
2369 "no ipv6 route X:X::X:X/M [from X:X::X:X/M] <X:X::X:X|INTERFACE|null0> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
2370 NO_STR
2371 IP_STR
2372 "Establish static routes\n"
2373 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2374 "IPv6 source-dest route\n"
2375 "IPv6 source prefix\n"
2376 "IPv6 gateway address\n"
2377 "IPv6 gateway interface name\n"
2378 "Null interface\n"
2379 "Set tag for this route\n"
2380 "Tag value\n"
2381 "Distance value for this prefix\n"
2382 VRF_CMD_HELP_STR
2383 MPLS_LABEL_HELPSTR)
2384 {
2385 int idx_ipv6_prefixlen = 3;
2386 int idx_ipv6_ifname;
2387 int idx_curr;
2388 char *src, *tag, *distance, *vrf;
2389
2390 if (!strcmp(argv[4]->text, "from"))
2391 {
2392 src = argv[5]->arg;
2393 idx_ipv6_ifname = 6;
2394 idx_curr = 7;
2395 }
2396 else
2397 {
2398 src = NULL;
2399 idx_ipv6_ifname = 4;
2400 idx_curr = 5;
2401 }
2402
2403 tag = distance = vrf = NULL;
2404 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
2405
2406 return static_ipv6_func (vty, 0,
2407 argv[idx_ipv6_prefixlen]->arg,
2408 src,
2409 argv[idx_ipv6_ifname]->arg,
2410 NULL, NULL,
2411 tag, distance, vrf, NULL);
2412 }
2413
2414 DEFUN (no_ipv6_route_flags,
2415 no_ipv6_route_flags_cmd,
2416 "no ipv6 route X:X::X:X/M [from X:X::X:X/M] <X:X::X:X|INTERFACE> <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
2417 NO_STR
2418 IP_STR
2419 "Establish static routes\n"
2420 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2421 "IPv6 source-dest route\n"
2422 "IPv6 source prefix\n"
2423 "IPv6 gateway address\n"
2424 "IPv6 gateway interface name\n"
2425 "Emit an ICMP unreachable when matched\n"
2426 "Silently discard pkts when matched\n"
2427 "Set tag for this route\n"
2428 "Tag value\n"
2429 "Distance value for this prefix\n"
2430 VRF_CMD_HELP_STR
2431 MPLS_LABEL_HELPSTR)
2432 {
2433 int idx_ipv6_prefixlen = 3;
2434 int idx_ipv6_ifname;
2435 int idx_reject_blackhole;
2436 int idx_curr;
2437 char *src, *tag, *distance, *vrf;
2438
2439 if (!strcmp(argv[4]->text, "from"))
2440 {
2441 src = argv[5]->arg;
2442 idx_ipv6_ifname = 6;
2443 idx_reject_blackhole = 7;
2444 idx_curr = 8;
2445 }
2446 else
2447 {
2448 src = NULL;
2449 idx_ipv6_ifname = 4;
2450 idx_reject_blackhole = 5;
2451 idx_curr = 6;
2452 }
2453
2454 tag = distance = vrf = NULL;
2455 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
2456
2457 return static_ipv6_func (vty, 0,
2458 argv[idx_ipv6_prefixlen]->arg,
2459 src,
2460 argv[idx_ipv6_ifname]->arg,
2461 NULL,
2462 argv[idx_reject_blackhole]->arg,
2463 tag, distance, vrf, NULL);
2464 }
2465
2466 DEFUN (no_ipv6_route_ifname,
2467 no_ipv6_route_ifname_cmd,
2468 "no ipv6 route X:X::X:X/M [from X:X::X:X/M] X:X::X:X INTERFACE [tag (1-4294967295)] [(1-255)] [vrf NAME]",
2469 NO_STR
2470 IP_STR
2471 "Establish static routes\n"
2472 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2473 "IPv6 source-dest route\n"
2474 "IPv6 source prefix\n"
2475 "IPv6 gateway address\n"
2476 "IPv6 gateway interface name\n"
2477 "Set tag for this route\n"
2478 "Tag value\n"
2479 "Distance value for this prefix\n"
2480 VRF_CMD_HELP_STR
2481 MPLS_LABEL_HELPSTR)
2482 {
2483 int idx_ipv6_prefixlen = 3;
2484 int idx_ipv6;
2485 int idx_interface;
2486 int idx_curr;
2487 char *src, *tag, *distance, *vrf;
2488
2489 if (!strcmp(argv[4]->text, "from"))
2490 {
2491 src = argv[5]->arg;
2492 idx_ipv6 = 6;
2493 idx_interface = 7;
2494 idx_curr = 8;
2495 }
2496 else
2497 {
2498 src = NULL;
2499 idx_ipv6 = 4;
2500 idx_interface = 5;
2501 idx_curr = 6;
2502 }
2503
2504 tag = distance = vrf = NULL;
2505 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
2506
2507 return static_ipv6_func (vty, 0,
2508 argv[idx_ipv6_prefixlen]->arg,
2509 src,
2510 argv[idx_ipv6]->arg,
2511 argv[idx_interface]->arg,
2512 NULL,
2513 tag, distance, vrf, NULL);
2514 }
2515
2516 DEFUN (no_ipv6_route_ifname_flags,
2517 no_ipv6_route_ifname_flags_cmd,
2518 "no ipv6 route X:X::X:X/M [from X:X::X:X/M] X:X::X:X INTERFACE <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
2519 NO_STR
2520 IP_STR
2521 "Establish static routes\n"
2522 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2523 "IPv6 source-dest route\n"
2524 "IPv6 source prefix\n"
2525 "IPv6 gateway address\n"
2526 "IPv6 gateway interface name\n"
2527 "Emit an ICMP unreachable when matched\n"
2528 "Silently discard pkts when matched\n"
2529 "Set tag for this route\n"
2530 "Tag value\n"
2531 "Distance value for this prefix\n"
2532 VRF_CMD_HELP_STR
2533 MPLS_LABEL_HELPSTR)
2534 {
2535 int idx_ipv6_prefixlen = 3;
2536 int idx_ipv6;
2537 int idx_interface;
2538 int idx_reject_blackhole;
2539 int idx_curr;
2540 char *src, *tag, *distance, *vrf;
2541
2542 if (!strcmp(argv[4]->text, "from"))
2543 {
2544 src = argv[5]->arg;
2545 idx_ipv6 = 6;
2546 idx_interface = 7;
2547 idx_reject_blackhole = 8;
2548 idx_curr = 9;
2549 }
2550 else
2551 {
2552 src = NULL;
2553 idx_ipv6 = 4;
2554 idx_interface = 5;
2555 idx_reject_blackhole = 6;
2556 idx_curr = 7;
2557 }
2558
2559 tag = distance = vrf = NULL;
2560 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
2561
2562 return static_ipv6_func (vty, 0,
2563 argv[idx_ipv6_prefixlen]->arg,
2564 src,
2565 argv[idx_ipv6]->arg,
2566 argv[idx_interface]->arg,
2567 argv[idx_reject_blackhole]->arg,
2568 tag, distance, vrf, NULL);
2569 }
2570
2571 // dwalton duplicate to here
2572 DEFUN (show_ipv6_route,
2573 show_ipv6_route_cmd,
2574 "show ipv6 <fib|route> [vrf NAME] [tag (1-4294967295)|X:X::X:X/M longer-prefixes|" FRR_IP6_REDIST_STR_ZEBRA "] [json]",
2575 SHOW_STR
2576 IP_STR
2577 "IP forwarding table\n"
2578 "IP routing table\n"
2579 VRF_CMD_HELP_STR
2580 "Show only routes with tag\n"
2581 "Tag value\n"
2582 "IPv6 prefix\n"
2583 "Show route matching the specified Network/Mask pair only\n"
2584 FRR_IP6_REDIST_HELP_STR_ZEBRA
2585 JSON_STR)
2586 {
2587 bool uf = use_fib(argv[2]);
2588 struct route_table *table;
2589 int vrf_all = 0;
2590 route_tag_t tag = 0;
2591 vrf_id_t vrf_id = VRF_DEFAULT;
2592 struct vrf *vrf;
2593 struct zebra_vrf *zvrf;
2594 int uj = use_json(argc, argv);
2595 int idx = 0;
2596 struct prefix p;
2597 bool longer_prefixes = false;
2598 bool supernets_only = false;
2599 int type = 0;
2600
2601 if (argv_find (argv, argc, "vrf", &idx))
2602 {
2603 if (strmatch(argv[idx+1]->arg, "all"))
2604 vrf_all = 1;
2605 else
2606 VRF_GET_ID (vrf_id, argv[idx+1]->arg);
2607 }
2608
2609 if (argv_find (argv, argc, "tag", &idx))
2610 VTY_GET_INTEGER_RANGE("tag", tag, argv[idx+1]->arg, 0, 4294967295);
2611
2612 else if (argv_find (argv, argc, "X:X::X:X/M", &idx))
2613 {
2614 str2prefix (argv[idx]->arg, &p);
2615 longer_prefixes = true;
2616 }
2617
2618 else
2619 {
2620 if (argv_find (argv, argc, "kernel", &idx))
2621 type = proto_redistnum (AFI_IP6, argv[idx]->text);
2622 else if (argv_find (argv, argc, "babel", &idx))
2623 type = proto_redistnum (AFI_IP6, argv[idx]->text);
2624 else if (argv_find (argv, argc, "connected", &idx))
2625 type = proto_redistnum (AFI_IP6, argv[idx]->text);
2626 else if (argv_find (argv, argc, "static", &idx))
2627 type = proto_redistnum (AFI_IP6, argv[idx]->text);
2628 else if (argv_find (argv, argc, "ripng", &idx))
2629 type = proto_redistnum (AFI_IP6, argv[idx]->text);
2630 else if (argv_find (argv, argc, "ospf6", &idx))
2631 type = proto_redistnum (AFI_IP6, argv[idx]->text);
2632 else if (argv_find (argv, argc, "isis", &idx))
2633 type = proto_redistnum (AFI_IP6, argv[idx]->text);
2634 else if (argv_find (argv, argc, "bgp", &idx))
2635 type = proto_redistnum (AFI_IP6, argv[idx]->text);
2636 else if (argv_find (argv, argc, "nhrp", &idx))
2637 type = proto_redistnum (AFI_IP6, argv[idx]->text);
2638 else if (argv_find (argv, argc, "table", &idx))
2639 type = proto_redistnum (AFI_IP6, argv[idx]->text);
2640 else if (argv_find (argv, argc, "vnc", &idx))
2641 type = proto_redistnum (AFI_IP6, argv[idx]->text);
2642
2643 if (type < 0)
2644 {
2645 vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
2646 return CMD_WARNING;
2647 }
2648 }
2649
2650 if (vrf_all)
2651 {
2652 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
2653 {
2654 if ((zvrf = vrf->info) == NULL ||
2655 (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
2656 continue;
2657
2658 do_show_ip_route (vty, zvrf_name (zvrf), AFI_IP6, SAFI_UNICAST, uf, uj, tag,
2659 longer_prefixes ? &p : NULL, supernets_only, type, 0);
2660 }
2661 }
2662 else
2663 {
2664 vrf = vrf_lookup_by_id (vrf_id);
2665 do_show_ip_route (vty, vrf->name, AFI_IP6, SAFI_UNICAST, uf, uj, tag,
2666 longer_prefixes ? &p : NULL, supernets_only, type, 0);
2667 }
2668 return CMD_SUCCESS;
2669 }
2670
2671 DEFUN (show_ipv6_route_addr,
2672 show_ipv6_route_addr_cmd,
2673 "show ipv6 route [vrf NAME] X:X::X:X",
2674 SHOW_STR
2675 IP_STR
2676 "IPv6 routing table\n"
2677 VRF_CMD_HELP_STR
2678 "IPv6 Address\n")
2679 {
2680 int ret;
2681 struct prefix_ipv6 p;
2682 struct route_table *table;
2683 struct route_node *rn;
2684 vrf_id_t vrf_id = VRF_DEFAULT;
2685
2686 if (strmatch(argv[3]->text, "vrf"))
2687 {
2688 VRF_GET_ID (vrf_id, argv[4]->arg);
2689 ret = str2prefix_ipv6 (argv[5]->arg, &p);
2690 }
2691 else
2692 {
2693 ret = str2prefix_ipv6 (argv[3]->arg, &p);
2694 }
2695
2696 if (ret <= 0)
2697 {
2698 vty_out (vty, "Malformed IPv6 address%s", VTY_NEWLINE);
2699 return CMD_WARNING;
2700 }
2701
2702 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2703 if (! table)
2704 return CMD_SUCCESS;
2705
2706 rn = route_node_match (table, (struct prefix *) &p);
2707 if (! rn)
2708 {
2709 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
2710 return CMD_WARNING;
2711 }
2712
2713 vty_show_ip_route_detail (vty, rn, 0);
2714
2715 route_unlock_node (rn);
2716
2717 return CMD_SUCCESS;
2718 }
2719
2720 DEFUN (show_ipv6_route_prefix,
2721 show_ipv6_route_prefix_cmd,
2722 "show ipv6 route [vrf NAME] X:X::X:X/M",
2723 SHOW_STR
2724 IP_STR
2725 "IPv6 routing table\n"
2726 VRF_CMD_HELP_STR
2727 "IPv6 prefix\n")
2728 {
2729 int ret;
2730 struct prefix_ipv6 p;
2731 struct route_table *table;
2732 struct route_node *rn;
2733 vrf_id_t vrf_id = VRF_DEFAULT;
2734
2735 if (strmatch(argv[3]->text, "vrf"))
2736 {
2737 VRF_GET_ID (vrf_id, argv[4]->arg);
2738 ret = str2prefix_ipv6 (argv[5]->arg, &p);
2739 }
2740 else
2741 ret = str2prefix_ipv6 (argv[3]->arg, &p);
2742
2743 if (ret <= 0)
2744 {
2745 vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE);
2746 return CMD_WARNING;
2747 }
2748
2749 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2750 if (! table)
2751 return CMD_SUCCESS;
2752
2753 rn = route_node_match (table, (struct prefix *) &p);
2754 if (! rn || rn->p.prefixlen != p.prefixlen)
2755 {
2756 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
2757 return CMD_WARNING;
2758 }
2759
2760 vty_show_ip_route_detail (vty, rn, 0);
2761
2762 route_unlock_node (rn);
2763
2764 return CMD_SUCCESS;
2765 }
2766
2767
2768 /* Show route summary. */
2769 DEFUN (show_ipv6_route_summary,
2770 show_ipv6_route_summary_cmd,
2771 "show ipv6 route [vrf NAME] summary",
2772 SHOW_STR
2773 IP_STR
2774 "IPv6 routing table\n"
2775 VRF_CMD_HELP_STR
2776 "Summary of all IPv6 routes\n")
2777 {
2778 struct route_table *table;
2779 vrf_id_t vrf_id = VRF_DEFAULT;
2780
2781 if (strmatch(argv[3]->text, "vrf"))
2782 VRF_GET_ID (vrf_id, argv[4]->arg);
2783
2784 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2785 if (! table)
2786 return CMD_SUCCESS;
2787
2788 vty_show_ip_route_summary (vty, table);
2789
2790 return CMD_SUCCESS;
2791 }
2792
2793
2794 /* Show ipv6 route summary prefix. */
2795 DEFUN (show_ipv6_route_summary_prefix,
2796 show_ipv6_route_summary_prefix_cmd,
2797 "show ipv6 route [vrf NAME] summary prefix",
2798 SHOW_STR
2799 IP_STR
2800 "IPv6 routing table\n"
2801 VRF_CMD_HELP_STR
2802 "Summary of all IPv6 routes\n"
2803 "Prefix routes\n")
2804 {
2805 struct route_table *table;
2806 vrf_id_t vrf_id = VRF_DEFAULT;
2807
2808 if (strmatch(argv[3]->text, "vrf"))
2809 VRF_GET_ID (vrf_id, argv[4]->arg);
2810
2811 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2812 if (! table)
2813 return CMD_SUCCESS;
2814
2815 vty_show_ip_route_summary_prefix (vty, table);
2816
2817 return CMD_SUCCESS;
2818 }
2819
2820
2821 /*
2822 * Show IPv6 mroute command.Used to dump
2823 * the Multicast routing table.
2824 */
2825 DEFUN (show_ipv6_mroute,
2826 show_ipv6_mroute_cmd,
2827 "show ipv6 mroute [vrf NAME]",
2828 SHOW_STR
2829 IP_STR
2830 "IPv6 Multicast routing table\n"
2831 VRF_CMD_HELP_STR)
2832 {
2833 struct route_table *table;
2834 struct route_node *rn;
2835 struct route_entry *re;
2836 int first = 1;
2837 vrf_id_t vrf_id = VRF_DEFAULT;
2838
2839 if (argc == 5)
2840 VRF_GET_ID (vrf_id, argv[4]->arg);
2841
2842 table = zebra_vrf_table (AFI_IP6, SAFI_MULTICAST, vrf_id);
2843 if (! table)
2844 return CMD_SUCCESS;
2845
2846 /* Show all IPv6 route. */
2847 for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
2848 RNODE_FOREACH_RE (rn, re)
2849 {
2850 if (first)
2851 {
2852 vty_out (vty, SHOW_ROUTE_V6_HEADER);
2853 first = 0;
2854 }
2855 vty_show_ip_route (vty, rn, re, NULL);
2856 }
2857 return CMD_SUCCESS;
2858 }
2859
2860 DEFUN (show_ipv6_route_vrf_all_addr,
2861 show_ipv6_route_vrf_all_addr_cmd,
2862 "show ipv6 route vrf all X:X::X:X",
2863 SHOW_STR
2864 IP_STR
2865 "IPv6 routing table\n"
2866 VRF_ALL_CMD_HELP_STR
2867 "IPv6 Address\n")
2868 {
2869 int idx_ipv6 = 5;
2870 int ret;
2871 struct prefix_ipv6 p;
2872 struct route_table *table;
2873 struct route_node *rn;
2874 struct vrf *vrf;
2875 struct zebra_vrf *zvrf;
2876
2877 ret = str2prefix_ipv6 (argv[idx_ipv6]->arg, &p);
2878 if (ret <= 0)
2879 {
2880 vty_out (vty, "Malformed IPv6 address%s", VTY_NEWLINE);
2881 return CMD_WARNING;
2882 }
2883
2884 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
2885 {
2886 if ((zvrf = vrf->info) == NULL ||
2887 (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
2888 continue;
2889
2890 rn = route_node_match (table, (struct prefix *) &p);
2891 if (! rn)
2892 continue;
2893
2894 vty_show_ip_route_detail (vty, rn, 0);
2895
2896 route_unlock_node (rn);
2897 }
2898
2899 return CMD_SUCCESS;
2900 }
2901
2902 DEFUN (show_ipv6_route_vrf_all_prefix,
2903 show_ipv6_route_vrf_all_prefix_cmd,
2904 "show ipv6 route vrf all X:X::X:X/M",
2905 SHOW_STR
2906 IP_STR
2907 "IPv6 routing table\n"
2908 VRF_ALL_CMD_HELP_STR
2909 "IPv6 prefix\n")
2910 {
2911 int idx_ipv6_prefixlen = 5;
2912 int ret;
2913 struct prefix_ipv6 p;
2914 struct route_table *table;
2915 struct route_node *rn;
2916 struct vrf *vrf;
2917 struct zebra_vrf *zvrf;
2918
2919 ret = str2prefix_ipv6 (argv[idx_ipv6_prefixlen]->arg, &p);
2920 if (ret <= 0)
2921 {
2922 vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE);
2923 return CMD_WARNING;
2924 }
2925
2926 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
2927 {
2928 if ((zvrf = vrf->info) == NULL ||
2929 (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
2930 continue;
2931
2932 rn = route_node_match (table, (struct prefix *) &p);
2933 if (! rn)
2934 continue;
2935 if (rn->p.prefixlen != p.prefixlen)
2936 {
2937 route_unlock_node (rn);
2938 continue;
2939 }
2940
2941 vty_show_ip_route_detail (vty, rn, 0);
2942
2943 route_unlock_node (rn);
2944 }
2945
2946 return CMD_SUCCESS;
2947 }
2948
2949 DEFUN (show_ipv6_route_vrf_all_summary,
2950 show_ipv6_route_vrf_all_summary_cmd,
2951 "show ipv6 route vrf all summary",
2952 SHOW_STR
2953 IP_STR
2954 "IPv6 routing table\n"
2955 VRF_ALL_CMD_HELP_STR
2956 "Summary of all IPv6 routes\n")
2957 {
2958 struct vrf *vrf;
2959 struct zebra_vrf *zvrf;
2960
2961 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
2962 if ((zvrf = vrf->info) != NULL)
2963 vty_show_ip_route_summary (vty, zvrf->table[AFI_IP6][SAFI_UNICAST]);
2964
2965 return CMD_SUCCESS;
2966 }
2967
2968 DEFUN (show_ipv6_mroute_vrf_all,
2969 show_ipv6_mroute_vrf_all_cmd,
2970 "show ipv6 mroute vrf all",
2971 SHOW_STR
2972 IP_STR
2973 "IPv6 Multicast routing table\n"
2974 VRF_ALL_CMD_HELP_STR)
2975 {
2976 struct route_table *table;
2977 struct route_node *rn;
2978 struct route_entry *re;
2979 struct vrf *vrf;
2980 struct zebra_vrf *zvrf;
2981 int first = 1;
2982
2983 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
2984 {
2985 if ((zvrf = vrf->info) == NULL ||
2986 (table = zvrf->table[AFI_IP6][SAFI_MULTICAST]) == NULL)
2987 continue;
2988
2989 /* Show all IPv6 route. */
2990 for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
2991 RNODE_FOREACH_RE (rn, re)
2992 {
2993 if (first)
2994 {
2995 vty_out (vty, SHOW_ROUTE_V6_HEADER);
2996 first = 0;
2997 }
2998 vty_show_ip_route (vty, rn, re, NULL);
2999 }
3000 }
3001 return CMD_SUCCESS;
3002 }
3003
3004 DEFUN (show_ipv6_route_vrf_all_summary_prefix,
3005 show_ipv6_route_vrf_all_summary_prefix_cmd,
3006 "show ipv6 route vrf all summary prefix",
3007 SHOW_STR
3008 IP_STR
3009 "IPv6 routing table\n"
3010 VRF_ALL_CMD_HELP_STR
3011 "Summary of all IPv6 routes\n"
3012 "Prefix routes\n")
3013 {
3014 struct vrf *vrf;
3015 struct zebra_vrf *zvrf;
3016
3017 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
3018 if ((zvrf = vrf->info) != NULL)
3019 vty_show_ip_route_summary_prefix (vty, zvrf->table[AFI_IP6][SAFI_UNICAST]);
3020
3021 return CMD_SUCCESS;
3022 }
3023
3024 DEFUN (allow_external_route_update,
3025 allow_external_route_update_cmd,
3026 "allow-external-route-update",
3027 "Allow FRR routes to be overwritten by external processes\n")
3028 {
3029 allow_delete = 1;
3030
3031 return CMD_SUCCESS;
3032 }
3033
3034 DEFUN (no_allow_external_route_update,
3035 no_allow_external_route_update_cmd,
3036 "no allow-external-route-update",
3037 NO_STR
3038 "Allow FRR routes to be overwritten by external processes\n")
3039 {
3040 allow_delete = 0;
3041
3042 return CMD_SUCCESS;
3043 }
3044
3045 /* show vrf */
3046 DEFUN (show_vrf,
3047 show_vrf_cmd,
3048 "show vrf",
3049 SHOW_STR
3050 "VRF\n")
3051 {
3052 struct vrf *vrf;
3053 struct zebra_vrf *zvrf;
3054
3055 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
3056 {
3057 if (!(zvrf = vrf->info))
3058 continue;
3059 if (!zvrf_id (zvrf))
3060 continue;
3061
3062 vty_out (vty, "vrf %s ", zvrf_name (zvrf));
3063 if (zvrf_id (zvrf) == VRF_UNKNOWN)
3064 vty_out (vty, "inactive");
3065 else
3066 vty_out (vty, "id %u table %u", zvrf_id (zvrf), zvrf->table_id);
3067 vty_out (vty, "%s", VTY_NEWLINE);
3068
3069 }
3070
3071 return CMD_SUCCESS;
3072 }
3073
3074 /* Static ip route configuration write function. */
3075 static int
3076 zebra_ip_config (struct vty *vty)
3077 {
3078 int write = 0;
3079
3080 write += static_config (vty, AFI_IP, SAFI_UNICAST, "ip route");
3081 write += static_config (vty, AFI_IP, SAFI_MULTICAST, "ip mroute");
3082 write += static_config (vty, AFI_IP6, SAFI_UNICAST, "ipv6 route");
3083
3084 write += zebra_import_table_config (vty);
3085 return write;
3086 }
3087
3088 DEFUN (ip_zebra_import_table_distance,
3089 ip_zebra_import_table_distance_cmd,
3090 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
3091 IP_STR
3092 "import routes from non-main kernel table\n"
3093 "kernel routing table id\n"
3094 "Distance for imported routes\n"
3095 "Default distance value\n"
3096 "route-map for filtering\n"
3097 "route-map name\n")
3098 {
3099 u_int32_t table_id = 0;
3100
3101 VTY_GET_INTEGER("table", table_id, argv[2]->arg);
3102 int distance = ZEBRA_TABLE_DISTANCE_DEFAULT;
3103 char *rmap = strmatch (argv[argc - 2]->text, "route-map") ?
3104 XSTRDUP(MTYPE_ROUTE_MAP_NAME, argv[argc - 1]->arg) : NULL;
3105 int ret;
3106
3107 if (argc == 7 || (argc == 5 && !rmap))
3108 VTY_GET_INTEGER_RANGE("distance", distance, argv[4]->arg, 1, 255);
3109
3110 if (!is_zebra_valid_kernel_table(table_id))
3111 {
3112 vty_out(vty, "Invalid routing table ID, %d. Must be in range 1-252%s",
3113 table_id, VTY_NEWLINE);
3114 return CMD_WARNING;
3115 }
3116
3117 if (is_zebra_main_routing_table(table_id))
3118 {
3119 vty_out(vty, "Invalid routing table ID, %d. Must be non-default table%s",
3120 table_id, VTY_NEWLINE);
3121 return CMD_WARNING;
3122 }
3123
3124 ret = zebra_import_table(AFI_IP, table_id, distance, rmap, 1);
3125 if (rmap)
3126 XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
3127
3128 return ret;
3129 }
3130
3131 DEFUN (no_ip_zebra_import_table,
3132 no_ip_zebra_import_table_cmd,
3133 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
3134 NO_STR
3135 IP_STR
3136 "import routes from non-main kernel table\n"
3137 "kernel routing table id\n"
3138 "Distance for imported routes\n"
3139 "Default distance value\n"
3140 "route-map for filtering\n"
3141 "route-map name\n")
3142 {
3143 u_int32_t table_id = 0;
3144 VTY_GET_INTEGER("table", table_id, argv[3]->arg);
3145
3146 if (!is_zebra_valid_kernel_table(table_id))
3147 {
3148 vty_out(vty, "Invalid routing table ID. Must be in range 1-252%s",
3149 VTY_NEWLINE);
3150 return CMD_WARNING;
3151 }
3152
3153 if (is_zebra_main_routing_table(table_id))
3154 {
3155 vty_out(vty, "Invalid routing table ID, %d. Must be non-default table%s",
3156 table_id, VTY_NEWLINE);
3157 return CMD_WARNING;
3158 }
3159
3160 if (!is_zebra_import_table_enabled(AFI_IP, table_id))
3161 return CMD_SUCCESS;
3162
3163 return (zebra_import_table(AFI_IP, table_id, 0, NULL, 0));
3164 }
3165
3166 static int
3167 config_write_protocol (struct vty *vty)
3168 {
3169 if (allow_delete)
3170 vty_out(vty, "allow-external-route-update%s", VTY_NEWLINE);
3171
3172 if (zebra_rnh_ip_default_route)
3173 vty_out(vty, "ip nht resolve-via-default%s", VTY_NEWLINE);
3174
3175 if (zebra_rnh_ipv6_default_route)
3176 vty_out(vty, "ipv6 nht resolve-via-default%s", VTY_NEWLINE);
3177
3178 enum multicast_mode ipv4_multicast_mode = multicast_mode_ipv4_get ();
3179
3180 if (ipv4_multicast_mode != MCAST_NO_CONFIG)
3181 vty_out (vty, "ip multicast rpf-lookup-mode %s%s",
3182 ipv4_multicast_mode == MCAST_URIB_ONLY ? "urib-only" :
3183 ipv4_multicast_mode == MCAST_MRIB_ONLY ? "mrib-only" :
3184 ipv4_multicast_mode == MCAST_MIX_MRIB_FIRST ? "mrib-then-urib" :
3185 ipv4_multicast_mode == MCAST_MIX_DISTANCE ? "lower-distance" :
3186 "longer-prefix",
3187 VTY_NEWLINE);
3188
3189 zebra_routemap_config_write_protocol(vty);
3190
3191 return 1;
3192 }
3193
3194 /* IP node for static routes. */
3195 static struct cmd_node ip_node = { IP_NODE, "", 1 };
3196 static struct cmd_node protocol_node = { PROTOCOL_NODE, "", 1 };
3197
3198 /* Route VTY. */
3199 void
3200 zebra_vty_init (void)
3201 {
3202 install_node (&ip_node, zebra_ip_config);
3203 install_node (&protocol_node, config_write_protocol);
3204
3205 install_element (CONFIG_NODE, &allow_external_route_update_cmd);
3206 install_element (CONFIG_NODE, &no_allow_external_route_update_cmd);
3207 install_element (CONFIG_NODE, &ip_mroute_dist_cmd);
3208 install_element (CONFIG_NODE, &no_ip_mroute_dist_cmd);
3209 install_element (CONFIG_NODE, &ip_multicast_mode_cmd);
3210 install_element (CONFIG_NODE, &no_ip_multicast_mode_cmd);
3211 install_element (CONFIG_NODE, &ip_route_cmd);
3212 install_element (CONFIG_NODE, &ip_route_flags_cmd);
3213 install_element (CONFIG_NODE, &ip_route_mask_cmd);
3214 install_element (CONFIG_NODE, &ip_route_mask_flags_cmd);
3215 install_element (CONFIG_NODE, &no_ip_route_cmd);
3216 install_element (CONFIG_NODE, &no_ip_route_mask_cmd);
3217 install_element (CONFIG_NODE, &ip_zebra_import_table_distance_cmd);
3218 install_element (CONFIG_NODE, &no_ip_zebra_import_table_cmd);
3219
3220 install_element (VIEW_NODE, &show_vrf_cmd);
3221 install_element (VIEW_NODE, &show_ip_route_cmd);
3222 install_element (VIEW_NODE, &show_ip_nht_cmd);
3223 install_element (VIEW_NODE, &show_ip_nht_vrf_all_cmd);
3224 install_element (VIEW_NODE, &show_ipv6_nht_cmd);
3225 install_element (VIEW_NODE, &show_ipv6_nht_vrf_all_cmd);
3226 install_element (VIEW_NODE, &show_ip_route_addr_cmd);
3227 install_element (VIEW_NODE, &show_ip_route_prefix_cmd);
3228 install_element (VIEW_NODE, &show_ip_route_summary_cmd);
3229 install_element (VIEW_NODE, &show_ip_route_summary_prefix_cmd);
3230
3231 install_element (VIEW_NODE, &show_ip_rpf_cmd);
3232 install_element (VIEW_NODE, &show_ip_rpf_addr_cmd);
3233
3234 /* Commands for VRF */
3235
3236 install_element (CONFIG_NODE, &no_ip_route_flags_cmd);
3237 install_element (CONFIG_NODE, &no_ip_route_mask_flags_cmd);
3238
3239 install_element (VIEW_NODE, &show_ip_route_vrf_all_addr_cmd);
3240 install_element (VIEW_NODE, &show_ip_route_vrf_all_prefix_cmd);
3241 install_element (VIEW_NODE, &show_ip_route_vrf_all_summary_cmd);
3242 install_element (VIEW_NODE, &show_ip_route_vrf_all_summary_prefix_cmd);
3243
3244 install_element (CONFIG_NODE, &ipv6_route_cmd);
3245 install_element (CONFIG_NODE, &ipv6_route_flags_cmd);
3246 install_element (CONFIG_NODE, &ipv6_route_ifname_cmd);
3247 install_element (CONFIG_NODE, &ipv6_route_ifname_flags_cmd);
3248 install_element (CONFIG_NODE, &no_ipv6_route_cmd);
3249 install_element (CONFIG_NODE, &no_ipv6_route_flags_cmd);
3250 install_element (CONFIG_NODE, &no_ipv6_route_ifname_cmd);
3251 install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_cmd);
3252 install_element (CONFIG_NODE, &ip_nht_default_route_cmd);
3253 install_element (CONFIG_NODE, &no_ip_nht_default_route_cmd);
3254 install_element (CONFIG_NODE, &ipv6_nht_default_route_cmd);
3255 install_element (CONFIG_NODE, &no_ipv6_nht_default_route_cmd);
3256 install_element (VIEW_NODE, &show_ipv6_route_cmd);
3257 install_element (VIEW_NODE, &show_ipv6_route_summary_cmd);
3258 install_element (VIEW_NODE, &show_ipv6_route_summary_prefix_cmd);
3259 install_element (VIEW_NODE, &show_ipv6_route_addr_cmd);
3260 install_element (VIEW_NODE, &show_ipv6_route_prefix_cmd);
3261 install_element (VIEW_NODE, &show_ipv6_mroute_cmd);
3262
3263 /* Commands for VRF */
3264 install_element (VIEW_NODE, &show_ipv6_route_vrf_all_summary_cmd);
3265 install_element (VIEW_NODE, &show_ipv6_route_vrf_all_summary_prefix_cmd);
3266 install_element (VIEW_NODE, &show_ipv6_route_vrf_all_addr_cmd);
3267 install_element (VIEW_NODE, &show_ipv6_route_vrf_all_prefix_cmd);
3268
3269 install_element (VIEW_NODE, &show_ipv6_mroute_vrf_all_cmd);
3270 }