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