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