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