]> git.proxmox.com Git - mirror_frr.git/blame - zebra/zebra_vty.c
Merge pull request #2397 from pacovn/Coverity_1469896_Dereference_after_null_check
[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
PG
1073 NULL, gate_str, ifname, flag, tag_str, distance_str, label,
1074 NULL);
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
4a7371e9 1201 if (re->vrf_id != nexthop->vrf_id) {
2793a098 1202 struct vrf *vrf =
4a7371e9 1203 vrf_lookup_by_id(nexthop->vrf_id);
2793a098 1204
4c66767c
DS
1205 if (vrf)
1206 vty_out(vty, "(vrf %s)", vrf->name);
1207 else
1208 vty_out(vty, "(vrf UKNOWN)");
2793a098
DS
1209 }
1210
eaf5150f
DS
1211 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE))
1212 vty_out(vty, " (duplicate nexthop removed)");
1213
d62a17ae 1214 if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1215 vty_out(vty, " inactive");
1216
1217 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK))
1218 vty_out(vty, " onlink");
1219
1220 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
1221 vty_out(vty, " (recursive)");
1222
1223 switch (nexthop->type) {
1224 case NEXTHOP_TYPE_IPV4:
1225 case NEXTHOP_TYPE_IPV4_IFINDEX:
1226 if (nexthop->src.ipv4.s_addr) {
1227 if (inet_ntop(AF_INET,
1228 &nexthop->src.ipv4,
1229 addrstr, sizeof addrstr))
1230 vty_out(vty, ", src %s",
1231 addrstr);
1232 }
1233 break;
1234 case NEXTHOP_TYPE_IPV6:
1235 case NEXTHOP_TYPE_IPV6_IFINDEX:
1236 if (!IPV6_ADDR_SAME(&nexthop->src.ipv6,
1237 &in6addr_any)) {
1238 if (inet_ntop(AF_INET6,
1239 &nexthop->src.ipv6,
1240 addrstr, sizeof addrstr))
1241 vty_out(vty, ", src %s",
1242 addrstr);
1243 }
1244 break;
1245 default:
1246 break;
1247 }
1248
1994ae60
JB
1249 if (re->nexthop_mtu)
1250 vty_out(vty, ", mtu %u", re->nexthop_mtu);
1251
d62a17ae 1252 /* Label information */
1253 if (nexthop->nh_label
1254 && nexthop->nh_label->num_labels) {
1255 vty_out(vty, ", label %s",
1256 mpls_label2str(
1257 nexthop->nh_label->num_labels,
1258 nexthop->nh_label->label, buf,
1259 sizeof buf, 1));
1260 }
1261
1262 vty_out(vty, "\n");
1263 }
1264 vty_out(vty, "\n");
1265 }
1266}
1267
1268static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
1269 struct route_entry *re, json_object *json)
1270{
1271 struct nexthop *nexthop;
1272 int len = 0;
1273 char buf[SRCDEST2STR_BUFFER];
1274 json_object *json_nexthops = NULL;
1275 json_object *json_nexthop = NULL;
1276 json_object *json_route = NULL;
1277 json_object *json_labels = NULL;
14a481d9
DS
1278 time_t uptime;
1279 struct tm *tm;
1280
1281 uptime = time(NULL);
1282 uptime -= re->uptime;
1283 tm = gmtime(&uptime);
d62a17ae 1284
1285 if (json) {
1286 json_route = json_object_new_object();
1287 json_nexthops = json_object_new_array();
1288
1289 json_object_string_add(json_route, "prefix",
1290 srcdest_rnode2str(rn, buf, sizeof buf));
1291 json_object_string_add(json_route, "protocol",
1292 zebra_route_string(re->type));
1293
1294 if (re->instance)
1295 json_object_int_add(json_route, "instance",
1296 re->instance);
1297
1298 if (re->vrf_id)
1299 json_object_int_add(json_route, "vrfId", re->vrf_id);
1300
1301 if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED))
1302 json_object_boolean_true_add(json_route, "selected");
1303
925c2f88 1304 if (re->type != ZEBRA_ROUTE_CONNECT) {
d62a17ae 1305 json_object_int_add(json_route, "distance",
1306 re->distance);
1307 json_object_int_add(json_route, "metric", re->metric);
1308 }
1309
f03098f9
DS
1310 json_object_int_add(json_route, "internalStatus",
1311 re->status);
1312 json_object_int_add(json_route, "internalFlags",
1313 re->flags);
14a481d9 1314 if (uptime < ONE_DAY_SECOND)
996c9314
LB
1315 sprintf(buf, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min,
1316 tm->tm_sec);
14a481d9 1317 else if (uptime < ONE_WEEK_SECOND)
996c9314
LB
1318 sprintf(buf, "%dd%02dh%02dm", tm->tm_yday, tm->tm_hour,
1319 tm->tm_min);
14a481d9
DS
1320 else
1321 sprintf(buf, "%02dw%dd%02dh", tm->tm_yday / 7,
1322 tm->tm_yday - ((tm->tm_yday / 7) * 7),
1323 tm->tm_hour);
1324
1325 json_object_string_add(json_route, "uptime", buf);
d62a17ae 1326
7ee30f28 1327 for (ALL_NEXTHOPS(re->ng, nexthop)) {
d62a17ae 1328 json_nexthop = json_object_new_object();
1329
f03098f9
DS
1330 json_object_int_add(json_nexthop, "flags",
1331 nexthop->flags);
1332
eaf5150f
DS
1333 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE))
1334 json_object_boolean_true_add(json_nexthop,
1335 "duplicate");
1336
d62a17ae 1337 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB))
1338 json_object_boolean_true_add(json_nexthop,
1339 "fib");
1340
1341 switch (nexthop->type) {
1342 case NEXTHOP_TYPE_IPV4:
1343 case NEXTHOP_TYPE_IPV4_IFINDEX:
1344 json_object_string_add(
1345 json_nexthop, "ip",
1346 inet_ntoa(nexthop->gate.ipv4));
1347 json_object_string_add(json_nexthop, "afi",
1348 "ipv4");
1349
1350 if (nexthop->ifindex) {
1351 json_object_int_add(json_nexthop,
1352 "interfaceIndex",
1353 nexthop->ifindex);
1354 json_object_string_add(
1355 json_nexthop, "interfaceName",
4a7371e9
DS
1356 ifindex2ifname(
1357 nexthop->ifindex,
1358 nexthop->vrf_id));
d62a17ae 1359 }
1360 break;
1361 case NEXTHOP_TYPE_IPV6:
1362 case NEXTHOP_TYPE_IPV6_IFINDEX:
1363 json_object_string_add(
1364 json_nexthop, "ip",
1365 inet_ntop(AF_INET6, &nexthop->gate.ipv6,
1366 buf, sizeof buf));
1367 json_object_string_add(json_nexthop, "afi",
1368 "ipv6");
1369
1370 if (nexthop->ifindex) {
1371 json_object_int_add(json_nexthop,
1372 "interfaceIndex",
1373 nexthop->ifindex);
1374 json_object_string_add(
1375 json_nexthop, "interfaceName",
4a7371e9
DS
1376 ifindex2ifname(
1377 nexthop->ifindex,
1378 nexthop->vrf_id));
d62a17ae 1379 }
1380 break;
1381
1382 case NEXTHOP_TYPE_IFINDEX:
1383 json_object_boolean_true_add(
1384 json_nexthop, "directlyConnected");
1385 json_object_int_add(json_nexthop,
1386 "interfaceIndex",
1387 nexthop->ifindex);
1388 json_object_string_add(
1389 json_nexthop, "interfaceName",
1390 ifindex2ifname(nexthop->ifindex,
4a7371e9 1391 nexthop->vrf_id));
d62a17ae 1392 break;
1393 case NEXTHOP_TYPE_BLACKHOLE:
1394 json_object_boolean_true_add(json_nexthop,
a8309422
DL
1395 "unreachable");
1396 switch (nexthop->bh_type) {
1397 case BLACKHOLE_REJECT:
1398 json_object_boolean_true_add(
60466a63 1399 json_nexthop, "reject");
a8309422
DL
1400 break;
1401 case BLACKHOLE_ADMINPROHIB:
1402 json_object_boolean_true_add(
60466a63
QY
1403 json_nexthop,
1404 "admin-prohibited");
a8309422
DL
1405 break;
1406 case BLACKHOLE_NULL:
1407 json_object_boolean_true_add(
60466a63 1408 json_nexthop, "blackhole");
a8309422
DL
1409 break;
1410 case BLACKHOLE_UNSPEC:
1411 break;
1412 }
d62a17ae 1413 break;
1414 default:
1415 break;
1416 }
1417
4a7371e9 1418 if (nexthop->vrf_id != re->vrf_id) {
2793a098 1419 struct vrf *vrf =
4a7371e9 1420 vrf_lookup_by_id(nexthop->vrf_id);
2793a098 1421
996c9314 1422 json_object_string_add(json_nexthop, "vrf",
2793a098
DS
1423 vrf->name);
1424 }
eaf5150f
DS
1425 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE))
1426 json_object_boolean_true_add(json_nexthop,
1427 "duplicate");
1428
d62a17ae 1429 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1430 json_object_boolean_true_add(json_nexthop,
1431 "active");
1432
1433 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK))
1434 json_object_boolean_true_add(json_nexthop,
1435 "onLink");
1436
1437 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
1438 json_object_boolean_true_add(json_nexthop,
1439 "recursive");
1440
1441 switch (nexthop->type) {
1442 case NEXTHOP_TYPE_IPV4:
1443 case NEXTHOP_TYPE_IPV4_IFINDEX:
1444 if (nexthop->src.ipv4.s_addr) {
1445 if (inet_ntop(AF_INET,
1446 &nexthop->src.ipv4, buf,
1447 sizeof buf))
1448 json_object_string_add(
1449 json_nexthop, "source",
1450 buf);
1451 }
1452 break;
1453 case NEXTHOP_TYPE_IPV6:
1454 case NEXTHOP_TYPE_IPV6_IFINDEX:
1455 if (!IPV6_ADDR_SAME(&nexthop->src.ipv6,
1456 &in6addr_any)) {
1457 if (inet_ntop(AF_INET6,
1458 &nexthop->src.ipv6, buf,
1459 sizeof buf))
1460 json_object_string_add(
1461 json_nexthop, "source",
1462 buf);
1463 }
1464 break;
1465 default:
1466 break;
1467 }
1468
1469 if (nexthop->nh_label
1470 && nexthop->nh_label->num_labels) {
1471 json_labels = json_object_new_array();
1472
1473 for (int label_index = 0;
1474 label_index
1475 < nexthop->nh_label->num_labels;
1476 label_index++)
1477 json_object_array_add(
1478 json_labels,
1479 json_object_new_int(
1480 nexthop->nh_label->label
1481 [label_index]));
1482
1483 json_object_object_add(json_nexthop, "labels",
1484 json_labels);
1485 }
1486
1487 json_object_array_add(json_nexthops, json_nexthop);
1488 }
1489
1490 json_object_object_add(json_route, "nexthops", json_nexthops);
1491 json_object_array_add(json, json_route);
1492 return;
1493 }
1494
1495 /* Nexthop information. */
7ee30f28
DS
1496 for (ALL_NEXTHOPS(re->ng, nexthop)) {
1497 if (nexthop == re->ng.nexthop) {
d62a17ae 1498 /* Prefix information. */
1499 len = vty_out(vty, "%c", zebra_route_char(re->type));
1500 if (re->instance)
1501 len += vty_out(vty, "[%d]", re->instance);
1502 len += vty_out(
1503 vty, "%c%c %s",
1504 CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED)
1505 ? '>'
1506 : ' ',
1507 CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)
1508 ? '*'
1509 : ' ',
1510 srcdest_rnode2str(rn, buf, sizeof buf));
1511
1512 /* Distance and metric display. */
925c2f88 1513 if (re->type != ZEBRA_ROUTE_CONNECT)
8526b842 1514 len += vty_out(vty, " [%u/%u]", re->distance,
d62a17ae 1515 re->metric);
eaf5150f 1516 } else {
d62a17ae 1517 vty_out(vty, " %c%*c",
1518 CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)
996c9314
LB
1519 ? CHECK_FLAG(nexthop->flags,
1520 NEXTHOP_FLAG_DUPLICATE)
1521 ? ' '
1522 : '*'
d62a17ae 1523 : ' ',
1524 len - 3 + (2 * nexthop_level(nexthop)), ' ');
eaf5150f 1525 }
d62a17ae 1526
1527 switch (nexthop->type) {
1528 case NEXTHOP_TYPE_IPV4:
1529 case NEXTHOP_TYPE_IPV4_IFINDEX:
1530 vty_out(vty, " via %s", inet_ntoa(nexthop->gate.ipv4));
1531 if (nexthop->ifindex)
1532 vty_out(vty, ", %s",
1533 ifindex2ifname(nexthop->ifindex,
4a7371e9 1534 nexthop->vrf_id));
d62a17ae 1535 break;
1536 case NEXTHOP_TYPE_IPV6:
1537 case NEXTHOP_TYPE_IPV6_IFINDEX:
1538 vty_out(vty, " via %s",
1539 inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf,
1540 sizeof buf));
1541 if (nexthop->ifindex)
1542 vty_out(vty, ", %s",
1543 ifindex2ifname(nexthop->ifindex,
4a7371e9 1544 nexthop->vrf_id));
d62a17ae 1545 break;
1546
1547 case NEXTHOP_TYPE_IFINDEX:
1548 vty_out(vty, " is directly connected, %s",
99b9d960 1549 ifindex2ifname(nexthop->ifindex,
4a7371e9 1550 nexthop->vrf_id));
d62a17ae 1551 break;
1552 case NEXTHOP_TYPE_BLACKHOLE:
a8309422
DL
1553 vty_out(vty, " unreachable");
1554 switch (nexthop->bh_type) {
1555 case BLACKHOLE_REJECT:
1556 vty_out(vty, " (ICMP unreachable)");
1557 break;
1558 case BLACKHOLE_ADMINPROHIB:
1559 vty_out(vty, " (ICMP admin-prohibited)");
1560 break;
1561 case BLACKHOLE_NULL:
1562 vty_out(vty, " (blackhole)");
1563 break;
1564 case BLACKHOLE_UNSPEC:
1565 break;
1566 }
d62a17ae 1567 break;
1568 default:
1569 break;
1570 }
2793a098 1571
4a7371e9
DS
1572 if (nexthop->vrf_id != re->vrf_id) {
1573 struct vrf *vrf = vrf_lookup_by_id(nexthop->vrf_id);
2793a098 1574
4c66767c
DS
1575 if (vrf)
1576 vty_out(vty, "(vrf %s)", vrf->name);
1577 else
1578 vty_out(vty, "(vrf UKNOWN)");
2793a098
DS
1579 }
1580
d62a17ae 1581 if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1582 vty_out(vty, " inactive");
1583
1584 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK))
1585 vty_out(vty, " onlink");
1586
1587 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
1588 vty_out(vty, " (recursive)");
1589
1590 switch (nexthop->type) {
1591 case NEXTHOP_TYPE_IPV4:
1592 case NEXTHOP_TYPE_IPV4_IFINDEX:
1593 if (nexthop->src.ipv4.s_addr) {
1594 if (inet_ntop(AF_INET, &nexthop->src.ipv4, buf,
1595 sizeof buf))
1596 vty_out(vty, ", src %s", buf);
1597 }
1598 break;
1599 case NEXTHOP_TYPE_IPV6:
1600 case NEXTHOP_TYPE_IPV6_IFINDEX:
1601 if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any)) {
1602 if (inet_ntop(AF_INET6, &nexthop->src.ipv6, buf,
1603 sizeof buf))
1604 vty_out(vty, ", src %s", buf);
1605 }
1606 break;
1607 default:
1608 break;
1609 }
1610
1611 /* Label information */
1612 if (nexthop->nh_label && nexthop->nh_label->num_labels) {
1613 vty_out(vty, ", label %s",
1614 mpls_label2str(nexthop->nh_label->num_labels,
1615 nexthop->nh_label->label, buf,
1616 sizeof buf, 1));
1617 }
1618
14a481d9
DS
1619 if (uptime < ONE_DAY_SECOND)
1620 vty_out(vty, ", %02d:%02d:%02d", tm->tm_hour,
1621 tm->tm_min, tm->tm_sec);
1622 else if (uptime < ONE_WEEK_SECOND)
1623 vty_out(vty, ", %dd%02dh%02dm", tm->tm_yday,
1624 tm->tm_hour, tm->tm_min);
1625 else
1626 vty_out(vty, ", %02dw%dd%02dh", tm->tm_yday / 7,
1627 tm->tm_yday - ((tm->tm_yday / 7) * 7),
1628 tm->tm_hour);
d62a17ae 1629 vty_out(vty, "\n");
1630 }
1631}
1632
ae825b8b
DS
1633static void do_show_route_helper(struct vty *vty, struct zebra_vrf *zvrf,
1634 struct route_table *table, afi_t afi,
1635 bool use_fib, route_tag_t tag,
1636 const struct prefix *longer_prefix_p,
1637 bool supernets_only, int type,
d7c0a89a
QY
1638 unsigned short ospf_instance_id,
1639 uint8_t use_json)
d62a17ae 1640{
d62a17ae 1641 struct route_node *rn;
1642 struct route_entry *re;
1643 int first = 1;
ae825b8b 1644 rib_dest_t *dest;
d62a17ae 1645 json_object *json = NULL;
1646 json_object *json_prefix = NULL;
ae825b8b
DS
1647 uint32_t addr;
1648 char buf[BUFSIZ];
d62a17ae 1649
1650 if (use_json)
1651 json = json_object_new_object();
1652
1653 /* Show all routes. */
1654 for (rn = route_top(table); rn; rn = route_next(rn)) {
5f7a4718
DS
1655 dest = rib_dest_from_rnode(rn);
1656
a2addae8 1657 RNODE_FOREACH_RE (rn, re) {
996c9314 1658 if (use_fib && re != dest->selected_fib)
d62a17ae 1659 continue;
1660
1661 if (tag && re->tag != tag)
1662 continue;
1663
1664 if (longer_prefix_p
1665 && !prefix_match(longer_prefix_p, &rn->p))
1666 continue;
1667
1668 /* This can only be true when the afi is IPv4 */
1669 if (supernets_only) {
1670 addr = ntohl(rn->p.u.prefix4.s_addr);
1671
1672 if (IN_CLASSC(addr) && rn->p.prefixlen >= 24)
1673 continue;
1674
1675 if (IN_CLASSB(addr) && rn->p.prefixlen >= 16)
1676 continue;
1677
1678 if (IN_CLASSA(addr) && rn->p.prefixlen >= 8)
1679 continue;
1680 }
1681
1682 if (type && re->type != type)
1683 continue;
1684
1685 if (ospf_instance_id
1686 && (re->type != ZEBRA_ROUTE_OSPF
1687 || re->instance != ospf_instance_id))
1688 continue;
1689
1690 if (use_json) {
1691 if (!json_prefix)
1692 json_prefix = json_object_new_array();
1693 } else {
1694 if (first) {
1695 if (afi == AFI_IP)
1696 vty_out(vty,
1697 SHOW_ROUTE_V4_HEADER);
1698 else
1699 vty_out(vty,
1700 SHOW_ROUTE_V6_HEADER);
1701
1702 if (zvrf_id(zvrf) != VRF_DEFAULT)
1703 vty_out(vty, "\nVRF %s:\n",
1704 zvrf_name(zvrf));
1705
1706 first = 0;
1707 }
1708 }
1709
1710 vty_show_ip_route(vty, rn, re, json_prefix);
1711 }
1712
1713 if (json_prefix) {
1714 prefix2str(&rn->p, buf, sizeof buf);
1715 json_object_object_add(json, buf, json_prefix);
1716 json_prefix = NULL;
1717 }
1718 }
1719
1720 if (use_json) {
9d303b37
DL
1721 vty_out(vty, "%s\n", json_object_to_json_string_ext(
1722 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 1723 json_object_free(json);
1724 }
ae825b8b
DS
1725}
1726
1727static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi,
d7c0a89a 1728 safi_t safi, bool use_fib, uint8_t use_json,
ae825b8b
DS
1729 route_tag_t tag,
1730 const struct prefix *longer_prefix_p,
1731 bool supernets_only, int type,
d7c0a89a 1732 unsigned short ospf_instance_id)
ae825b8b
DS
1733{
1734 struct route_table *table;
1735 struct zebra_vrf *zvrf = NULL;
1736
1737 if (!(zvrf = zebra_vrf_lookup_by_name(vrf_name))) {
1738 if (use_json)
1739 vty_out(vty, "{}\n");
1740 else
1741 vty_out(vty, "vrf %s not defined\n", vrf_name);
1742 return CMD_SUCCESS;
1743 }
1744
1745 if (zvrf_id(zvrf) == VRF_UNKNOWN) {
1746 if (use_json)
1747 vty_out(vty, "{}\n");
1748 else
1749 vty_out(vty, "vrf %s inactive\n", vrf_name);
1750 return CMD_SUCCESS;
1751 }
1752
1753 table = zebra_vrf_table(afi, safi, zvrf_id(zvrf));
1754 if (!table) {
1755 if (use_json)
1756 vty_out(vty, "{}\n");
1757 return CMD_SUCCESS;
1758 }
1759
1760 do_show_route_helper(vty, zvrf, table, afi, use_fib, tag,
1761 longer_prefix_p, supernets_only, type,
1762 ospf_instance_id, use_json);
1763
1764 return CMD_SUCCESS;
1765}
1766
1767DEFPY (show_route_table,
1768 show_route_table_cmd,
1769 "show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table [json$json]",
1770 SHOW_STR
1771 IP_STR
1772 IP6_STR
1773 "IP routing table\n"
1774 "Table to display\n"
1775 "The table number to display, if available\n"
1776 JSON_STR)
1777{
1778 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
1779 struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
1780 struct route_table *t;
1781
1782 t = zebra_ns_find_table(zvrf->zns, table, afi);
1783 if (t)
1784 do_show_route_helper(vty, zvrf, t, afi, false, 0, false, false,
1785 0, 0, !!json);
d62a17ae 1786
1787 return CMD_SUCCESS;
abbda2d4 1788}
d511d7f1 1789
87d6ac7a
PG
1790DEFPY (show_route_table_vrf,
1791 show_route_table_vrf_cmd,
1792 "show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table vrf NAME$vrf_name [json$json]",
1793 SHOW_STR
1794 IP_STR
1795 IP6_STR
1796 "IP routing table\n"
1797 "Table to display\n"
1798 "The table number to display, if available\n"
1799 VRF_CMD_HELP_STR
1800 JSON_STR)
1801{
1802 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
1803 struct zebra_vrf *zvrf;
1804 struct route_table *t;
1805 vrf_id_t vrf_id = VRF_DEFAULT;
1806
1807 if (vrf_name)
1808 VRF_GET_ID(vrf_id, vrf_name);
1809 zvrf = zebra_vrf_lookup_by_id(vrf_id);
1810
1811 t = zebra_ns_find_table(zvrf->zns, table, afi);
1812 if (t)
1813 do_show_route_helper(vty, zvrf, t, afi, false, 0, false, false,
1814 0, 0, !!json);
1815
1816 return CMD_SUCCESS;
1817}
1818
8f527c5e
FL
1819DEFUN (show_ip_nht,
1820 show_ip_nht_cmd,
9bf96c84 1821 "show ip nht [vrf NAME]",
8f527c5e
FL
1822 SHOW_STR
1823 IP_STR
9bf96c84
DW
1824 "IP nexthop tracking table\n"
1825 VRF_CMD_HELP_STR)
8f527c5e 1826{
d62a17ae 1827 int idx_vrf = 4;
1828 vrf_id_t vrf_id = VRF_DEFAULT;
12f6fb97 1829
d62a17ae 1830 if (argc == 5)
1831 VRF_GET_ID(vrf_id, argv[idx_vrf]->arg);
12f6fb97 1832
d62a17ae 1833 zebra_print_rnh_table(vrf_id, AF_INET, vty, RNH_NEXTHOP_TYPE);
1834 return CMD_SUCCESS;
8f527c5e
FL
1835}
1836
12f6fb97 1837
d511d7f1
DS
1838DEFUN (show_ip_nht_vrf_all,
1839 show_ip_nht_vrf_all_cmd,
5bebf568 1840 "show ip nht vrf all",
d511d7f1
DS
1841 SHOW_STR
1842 IP_STR
1843 "IP nexthop tracking table\n"
1844 VRF_ALL_CMD_HELP_STR)
1845{
d62a17ae 1846 struct vrf *vrf;
1847 struct zebra_vrf *zvrf;
d511d7f1 1848
a2addae8
RW
1849 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
1850 if ((zvrf = vrf->info) != NULL) {
1851 vty_out(vty, "\nVRF %s:\n", zvrf_name(zvrf));
1852 zebra_print_rnh_table(zvrf_id(zvrf), AF_INET, vty,
1853 RNH_NEXTHOP_TYPE);
1854 }
d511d7f1 1855
d62a17ae 1856 return CMD_SUCCESS;
d511d7f1
DS
1857}
1858
8f527c5e
FL
1859DEFUN (show_ipv6_nht,
1860 show_ipv6_nht_cmd,
9bf96c84 1861 "show ipv6 nht [vrf NAME]",
8f527c5e 1862 SHOW_STR
689e6694 1863 IPV6_STR
9bf96c84
DW
1864 "IPv6 nexthop tracking table\n"
1865 VRF_CMD_HELP_STR)
8f527c5e 1866{
d62a17ae 1867 int idx_vrf = 4;
1868 vrf_id_t vrf_id = VRF_DEFAULT;
12f6fb97 1869
d62a17ae 1870 if (argc == 5)
1871 VRF_GET_ID(vrf_id, argv[idx_vrf]->arg);
12f6fb97 1872
d62a17ae 1873 zebra_print_rnh_table(vrf_id, AF_INET6, vty, RNH_NEXTHOP_TYPE);
1874 return CMD_SUCCESS;
8f527c5e
FL
1875}
1876
12f6fb97 1877
d511d7f1
DS
1878DEFUN (show_ipv6_nht_vrf_all,
1879 show_ipv6_nht_vrf_all_cmd,
5bebf568 1880 "show ipv6 nht vrf all",
d511d7f1
DS
1881 SHOW_STR
1882 IP_STR
1883 "IPv6 nexthop tracking table\n"
1884 VRF_ALL_CMD_HELP_STR)
1885{
d62a17ae 1886 struct vrf *vrf;
1887 struct zebra_vrf *zvrf;
d511d7f1 1888
a2addae8
RW
1889 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
1890 if ((zvrf = vrf->info) != NULL) {
1891 vty_out(vty, "\nVRF %s:\n", zvrf_name(zvrf));
1892 zebra_print_rnh_table(zvrf_id(zvrf), AF_INET6, vty,
1893 RNH_NEXTHOP_TYPE);
1894 }
d511d7f1 1895
d62a17ae 1896 return CMD_SUCCESS;
d511d7f1
DS
1897}
1898
8f527c5e
FL
1899DEFUN (ip_nht_default_route,
1900 ip_nht_default_route_cmd,
1901 "ip nht resolve-via-default",
1902 IP_STR
1903 "Filter Next Hop tracking route resolution\n"
1904 "Resolve via default route\n")
1905{
d62a17ae 1906 if (zebra_rnh_ip_default_route)
1907 return CMD_SUCCESS;
8f527c5e 1908
d62a17ae 1909 zebra_rnh_ip_default_route = 1;
90ac32c2 1910 zebra_evaluate_rnh(VRF_DEFAULT, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
d62a17ae 1911 return CMD_SUCCESS;
8f527c5e
FL
1912}
1913
1914DEFUN (no_ip_nht_default_route,
1915 no_ip_nht_default_route_cmd,
1916 "no ip nht resolve-via-default",
1917 NO_STR
1918 IP_STR
1919 "Filter Next Hop tracking route resolution\n"
1920 "Resolve via default route\n")
1921{
d62a17ae 1922 if (!zebra_rnh_ip_default_route)
1923 return CMD_SUCCESS;
8f527c5e 1924
d62a17ae 1925 zebra_rnh_ip_default_route = 0;
90ac32c2 1926 zebra_evaluate_rnh(VRF_DEFAULT, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
d62a17ae 1927 return CMD_SUCCESS;
8f527c5e
FL
1928}
1929
1930DEFUN (ipv6_nht_default_route,
1931 ipv6_nht_default_route_cmd,
1932 "ipv6 nht resolve-via-default",
1933 IP6_STR
1934 "Filter Next Hop tracking route resolution\n"
1935 "Resolve via default route\n")
1936{
d62a17ae 1937 if (zebra_rnh_ipv6_default_route)
1938 return CMD_SUCCESS;
8f527c5e 1939
d62a17ae 1940 zebra_rnh_ipv6_default_route = 1;
90ac32c2 1941 zebra_evaluate_rnh(VRF_DEFAULT, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL);
d62a17ae 1942 return CMD_SUCCESS;
8f527c5e
FL
1943}
1944
1945DEFUN (no_ipv6_nht_default_route,
1946 no_ipv6_nht_default_route_cmd,
1947 "no ipv6 nht resolve-via-default",
1948 NO_STR
1949 IP6_STR
1950 "Filter Next Hop tracking route resolution\n"
1951 "Resolve via default route\n")
1952{
d62a17ae 1953 if (!zebra_rnh_ipv6_default_route)
1954 return CMD_SUCCESS;
8f527c5e 1955
d62a17ae 1956 zebra_rnh_ipv6_default_route = 0;
90ac32c2 1957 zebra_evaluate_rnh(VRF_DEFAULT, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL);
d62a17ae 1958 return CMD_SUCCESS;
8f527c5e
FL
1959}
1960
ecffa493
RW
1961DEFPY (show_route,
1962 show_route_cmd,
1963 "show\
1964 <\
1965 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
a3e13ef3 1966 [{\
ecffa493
RW
1967 tag (1-4294967295)\
1968 |A.B.C.D/M$prefix longer-prefixes\
1969 |supernets-only$supernets_only\
a3e13ef3
RW
1970 }]\
1971 [<\
1972 " FRR_IP_REDIST_STR_ZEBRA "$type_str\
ecffa493 1973 |ospf$type_str (1-65535)$ospf_instance_id\
a3e13ef3 1974 >]\
ecffa493 1975 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
a3e13ef3 1976 [{\
ecffa493
RW
1977 tag (1-4294967295)\
1978 |X:X::X:X/M$prefix longer-prefixes\
a3e13ef3
RW
1979 }]\
1980 [" FRR_IP6_REDIST_STR_ZEBRA "$type_str]\
ecffa493
RW
1981 >\
1982 [json$json]",
8f527c5e
FL
1983 SHOW_STR
1984 IP_STR
87a88962 1985 "IP forwarding table\n"
8f527c5e 1986 "IP routing table\n"
ecffa493 1987 VRF_FULL_CMD_HELP_STR
8f527c5e 1988 "Show only routes with tag\n"
acb25e73
DW
1989 "Tag value\n"
1990 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1991 "Show route matching the specified Network/Mask pair only\n"
1992 "Show supernet entries only\n"
1993 FRR_IP_REDIST_HELP_STR_ZEBRA
1994 "Open Shortest Path First (OSPFv2)\n"
1995 "Instance ID\n"
ecffa493
RW
1996 IPV6_STR
1997 "IP forwarding table\n"
1998 "IP routing table\n"
1999 VRF_FULL_CMD_HELP_STR
2000 "Show only routes with tag\n"
2001 "Tag value\n"
2002 "IPv6 prefix\n"
2003 "Show route matching the specified Network/Mask pair only\n"
2004 FRR_IP6_REDIST_HELP_STR_ZEBRA
acb25e73 2005 JSON_STR)
8f527c5e 2006{
ecffa493 2007 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
d62a17ae 2008 struct vrf *vrf;
d62a17ae 2009 int type = 0;
d62a17ae 2010
ecffa493
RW
2011 if (type_str) {
2012 type = proto_redistnum(afi, type_str);
d62a17ae 2013 if (type < 0) {
2014 vty_out(vty, "Unknown route type\n");
2015 return CMD_WARNING;
2016 }
2017 }
2018
2019 if (vrf_all) {
a2addae8 2020 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
ecffa493
RW
2021 struct zebra_vrf *zvrf;
2022 struct route_table *table;
2023
d62a17ae 2024 if ((zvrf = vrf->info) == NULL
ecffa493 2025 || (table = zvrf->table[afi][SAFI_UNICAST]) == NULL)
d62a17ae 2026 continue;
2027
2028 do_show_ip_route(
ecffa493
RW
2029 vty, zvrf_name(zvrf), afi, SAFI_UNICAST, !!fib,
2030 !!json, tag, prefix_str ? prefix : NULL,
2031 !!supernets_only, type, ospf_instance_id);
d62a17ae 2032 }
2033 } else {
ecffa493
RW
2034 vrf_id_t vrf_id = VRF_DEFAULT;
2035
2036 if (vrf_name)
2037 VRF_GET_ID(vrf_id, vrf_name);
d62a17ae 2038 vrf = vrf_lookup_by_id(vrf_id);
ecffa493
RW
2039 do_show_ip_route(vty, vrf->name, afi, SAFI_UNICAST, !!fib,
2040 !!json, tag, prefix_str ? prefix : NULL,
2041 !!supernets_only, type, ospf_instance_id);
d62a17ae 2042 }
ecffa493 2043
d62a17ae 2044 return CMD_SUCCESS;
8f527c5e
FL
2045}
2046
5ce91022
RW
2047DEFPY (show_route_detail,
2048 show_route_detail_cmd,
2049 "show\
2050 <\
2051 ip$ipv4 route [vrf <NAME$vrf_name|all$vrf_all>]\
2052 <\
2053 A.B.C.D$address\
2054 |A.B.C.D/M$prefix\
2055 >\
2056 |ipv6$ipv6 route [vrf <NAME$vrf_name|all$vrf_all>]\
2057 <\
2058 X:X::X:X$address\
2059 |X:X::X:X/M$prefix\
2060 >\
2061 >",
8f527c5e
FL
2062 SHOW_STR
2063 IP_STR
2064 "IP routing table\n"
5ce91022
RW
2065 VRF_FULL_CMD_HELP_STR
2066 "Network in the IP routing table to display\n"
2067 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
2068 IP6_STR
2069 "IP routing table\n"
2070 VRF_FULL_CMD_HELP_STR
2071 "IPv6 Address\n"
2072 "IPv6 prefix\n")
8f527c5e 2073{
5ce91022 2074 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
d62a17ae 2075 struct route_table *table;
5ce91022 2076 struct prefix p;
d62a17ae 2077 struct route_node *rn;
d511d7f1 2078
5ce91022
RW
2079 if (address_str)
2080 prefix_str = address_str;
2081 if (str2prefix(prefix_str, &p) < 0) {
2082 vty_out(vty, "%% Malformed address\n");
d62a17ae 2083 return CMD_WARNING;
2084 }
8f527c5e 2085
5ce91022
RW
2086 if (vrf_all) {
2087 struct vrf *vrf;
2088 struct zebra_vrf *zvrf;
8f527c5e 2089
996c9314 2090 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
5ce91022
RW
2091 if ((zvrf = vrf->info) == NULL
2092 || (table = zvrf->table[afi][SAFI_UNICAST]) == NULL)
2093 continue;
2094
2095 rn = route_node_match(table, &p);
2096 if (!rn)
2097 continue;
2098 if (!address_str && rn->p.prefixlen != p.prefixlen) {
2099 route_unlock_node(rn);
2100 continue;
2101 }
2102
2103 vty_show_ip_route_detail(vty, rn, 0);
2104
2105 route_unlock_node(rn);
2106 }
2107 } else {
2108 vrf_id_t vrf_id = VRF_DEFAULT;
2109
2110 if (vrf_name)
2111 VRF_GET_ID(vrf_id, vrf_name);
2112
2113 table = zebra_vrf_table(afi, SAFI_UNICAST, vrf_id);
2114 if (!table)
2115 return CMD_SUCCESS;
8f527c5e 2116
5ce91022
RW
2117 rn = route_node_match(table, &p);
2118 if (!rn) {
2119 vty_out(vty, "%% Network not in table\n");
2120 return CMD_WARNING;
2121 }
2122 if (!address_str && rn->p.prefixlen != p.prefixlen) {
2123 vty_out(vty, "%% Network not in table\n");
2124 route_unlock_node(rn);
2125 return CMD_WARNING;
2126 }
8f527c5e 2127
5ce91022
RW
2128 vty_show_ip_route_detail(vty, rn, 0);
2129
2130 route_unlock_node(rn);
2131 }
8f527c5e 2132
d62a17ae 2133 return CMD_SUCCESS;
8f527c5e
FL
2134}
2135
5ce91022
RW
2136DEFPY (show_route_summary,
2137 show_route_summary_cmd,
2138 "show\
2139 <\
2140 ip$ipv4 route [vrf <NAME$vrf_name|all$vrf_all>]\
2141 summary [prefix$prefix]\
2142 |ipv6$ipv6 route [vrf <NAME$vrf_name|all$vrf_all>]\
2143 summary [prefix$prefix]\
2144 >",
8f527c5e
FL
2145 SHOW_STR
2146 IP_STR
2147 "IP routing table\n"
5ce91022
RW
2148 VRF_FULL_CMD_HELP_STR
2149 "Summary of all routes\n"
2150 "Prefix routes\n"
2151 IP6_STR
2152 "IP routing table\n"
2153 VRF_FULL_CMD_HELP_STR
2154 "Summary of all routes\n"
2155 "Prefix routes\n")
8f527c5e 2156{
5ce91022 2157 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
d62a17ae 2158 struct route_table *table;
d62a17ae 2159
5ce91022
RW
2160 if (vrf_all) {
2161 struct vrf *vrf;
2162 struct zebra_vrf *zvrf;
d511d7f1 2163
996c9314 2164 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
5ce91022
RW
2165 if ((zvrf = vrf->info) == NULL
2166 || (table = zvrf->table[afi][SAFI_UNICAST]) == NULL)
2167 continue;
8f527c5e 2168
5ce91022
RW
2169 if (prefix)
2170 vty_show_ip_route_summary_prefix(vty, table);
2171 else
2172 vty_show_ip_route_summary(vty, table);
2173 }
2174 } else {
2175 vrf_id_t vrf_id = VRF_DEFAULT;
8f527c5e 2176
5ce91022
RW
2177 if (vrf_name)
2178 VRF_GET_ID(vrf_id, vrf_name);
8f527c5e 2179
5ce91022
RW
2180 table = zebra_vrf_table(afi, SAFI_UNICAST, vrf_id);
2181 if (!table)
2182 return CMD_SUCCESS;
8f527c5e 2183
5ce91022
RW
2184 if (prefix)
2185 vty_show_ip_route_summary_prefix(vty, table);
2186 else
2187 vty_show_ip_route_summary(vty, table);
2188 }
8f527c5e 2189
d62a17ae 2190 return CMD_SUCCESS;
8f527c5e
FL
2191}
2192
d62a17ae 2193static void vty_show_ip_route_summary(struct vty *vty,
2194 struct route_table *table)
8f527c5e 2195{
d62a17ae 2196 struct route_node *rn;
2197 struct route_entry *re;
8f527c5e
FL
2198#define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
2199#define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
d7c0a89a
QY
2200 uint32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
2201 uint32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
2202 uint32_t i;
2203 uint32_t is_ibgp;
d62a17ae 2204
2205 memset(&rib_cnt, 0, sizeof(rib_cnt));
2206 memset(&fib_cnt, 0, sizeof(fib_cnt));
2207 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
a2addae8 2208 RNODE_FOREACH_RE (rn, re) {
d62a17ae 2209 is_ibgp = (re->type == ZEBRA_ROUTE_BGP
2210 && CHECK_FLAG(re->flags, ZEBRA_FLAG_IBGP));
2211
2212 rib_cnt[ZEBRA_ROUTE_TOTAL]++;
2213 if (is_ibgp)
2214 rib_cnt[ZEBRA_ROUTE_IBGP]++;
2215 else
2216 rib_cnt[re->type]++;
2217
2218 if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED)) {
2219 fib_cnt[ZEBRA_ROUTE_TOTAL]++;
2220
2221 if (is_ibgp)
2222 fib_cnt[ZEBRA_ROUTE_IBGP]++;
2223 else
2224 fib_cnt[re->type]++;
2225 }
2226 }
2227
2228 vty_out(vty, "%-20s %-20s %s (vrf %s)\n", "Route Source", "Routes",
2229 "FIB", zvrf_name(((rib_table_info_t *)table->info)->zvrf));
2230
2231 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
9d303b37
DL
2232 if ((rib_cnt[i] > 0) || (i == ZEBRA_ROUTE_BGP
2233 && rib_cnt[ZEBRA_ROUTE_IBGP] > 0)) {
d62a17ae 2234 if (i == ZEBRA_ROUTE_BGP) {
2235 vty_out(vty, "%-20s %-20d %-20d \n", "ebgp",
2236 rib_cnt[ZEBRA_ROUTE_BGP],
2237 fib_cnt[ZEBRA_ROUTE_BGP]);
2238 vty_out(vty, "%-20s %-20d %-20d \n", "ibgp",
2239 rib_cnt[ZEBRA_ROUTE_IBGP],
2240 fib_cnt[ZEBRA_ROUTE_IBGP]);
2241 } else
2242 vty_out(vty, "%-20s %-20d %-20d \n",
2243 zebra_route_string(i), rib_cnt[i],
2244 fib_cnt[i]);
2245 }
2246 }
2247
2248 vty_out(vty, "------\n");
2249 vty_out(vty, "%-20s %-20d %-20d \n", "Totals",
2250 rib_cnt[ZEBRA_ROUTE_TOTAL], fib_cnt[ZEBRA_ROUTE_TOTAL]);
2251 vty_out(vty, "\n");
8f527c5e
FL
2252}
2253
2254/*
2255 * Implementation of the ip route summary prefix command.
2256 *
2257 * This command prints the primary prefixes that have been installed by various
2258 * protocols on the box.
2259 *
2260 */
d62a17ae 2261static void vty_show_ip_route_summary_prefix(struct vty *vty,
2262 struct route_table *table)
8f527c5e 2263{
d62a17ae 2264 struct route_node *rn;
2265 struct route_entry *re;
2266 struct nexthop *nexthop;
8f527c5e
FL
2267#define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
2268#define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
d7c0a89a
QY
2269 uint32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
2270 uint32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
2271 uint32_t i;
d62a17ae 2272 int cnt;
2273
2274 memset(&rib_cnt, 0, sizeof(rib_cnt));
2275 memset(&fib_cnt, 0, sizeof(fib_cnt));
2276 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
a2addae8 2277 RNODE_FOREACH_RE (rn, re) {
d62a17ae 2278
2279 /*
2280 * In case of ECMP, count only once.
2281 */
2282 cnt = 0;
7ee30f28 2283 for (nexthop = re->ng.nexthop; (!cnt && nexthop);
d62a17ae 2284 nexthop = nexthop->next) {
2285 cnt++;
2286 rib_cnt[ZEBRA_ROUTE_TOTAL]++;
2287 rib_cnt[re->type]++;
2288 if (CHECK_FLAG(nexthop->flags,
2289 NEXTHOP_FLAG_FIB)) {
2290 fib_cnt[ZEBRA_ROUTE_TOTAL]++;
2291 fib_cnt[re->type]++;
2292 }
2293 if (re->type == ZEBRA_ROUTE_BGP
2294 && CHECK_FLAG(re->flags, ZEBRA_FLAG_IBGP)) {
2295 rib_cnt[ZEBRA_ROUTE_IBGP]++;
2296 if (CHECK_FLAG(nexthop->flags,
2297 NEXTHOP_FLAG_FIB))
2298 fib_cnt[ZEBRA_ROUTE_IBGP]++;
2299 }
2300 }
2301 }
2302
2303 vty_out(vty, "%-20s %-20s %s (vrf %s)\n", "Route Source",
2304 "Prefix Routes", "FIB",
2305 zvrf_name(((rib_table_info_t *)table->info)->zvrf));
2306
2307 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
2308 if (rib_cnt[i] > 0) {
2309 if (i == ZEBRA_ROUTE_BGP) {
2310 vty_out(vty, "%-20s %-20d %-20d \n", "ebgp",
2311 rib_cnt[ZEBRA_ROUTE_BGP]
2312 - rib_cnt[ZEBRA_ROUTE_IBGP],
2313 fib_cnt[ZEBRA_ROUTE_BGP]
2314 - fib_cnt[ZEBRA_ROUTE_IBGP]);
2315 vty_out(vty, "%-20s %-20d %-20d \n", "ibgp",
2316 rib_cnt[ZEBRA_ROUTE_IBGP],
2317 fib_cnt[ZEBRA_ROUTE_IBGP]);
2318 } else
2319 vty_out(vty, "%-20s %-20d %-20d \n",
2320 zebra_route_string(i), rib_cnt[i],
2321 fib_cnt[i]);
2322 }
2323 }
2324
2325 vty_out(vty, "------\n");
2326 vty_out(vty, "%-20s %-20d %-20d \n", "Totals",
2327 rib_cnt[ZEBRA_ROUTE_TOTAL], fib_cnt[ZEBRA_ROUTE_TOTAL]);
2328 vty_out(vty, "\n");
9343ce83
DS
2329}
2330
9de498ec 2331/* Write static route configuration. */
996c9314
LB
2332int static_config(struct vty *vty, struct zebra_vrf *zvrf, afi_t afi,
2333 safi_t safi, const char *cmd)
d62a17ae 2334{
4060008b
DS
2335 struct static_hold_route *shr;
2336 struct listnode *node;
37728041 2337 char spacing[100];
d62a17ae 2338 struct route_node *rn;
2339 struct static_route *si;
2340 struct route_table *stable;
d62a17ae 2341 char buf[SRCDEST2STR_BUFFER];
2342 int write = 0;
2343
37728041
DS
2344 if ((stable = zvrf->stable[afi][safi]) == NULL)
2345 return write;
d62a17ae 2346
996c9314 2347 sprintf(spacing, "%s%s", (zvrf->vrf->vrf_id == VRF_DEFAULT) ? "" : " ",
37728041 2348 cmd);
d62a17ae 2349
4060008b
DS
2350 /*
2351 * Static routes for vrfs not fully inited
2352 */
2353 for (ALL_LIST_ELEMENTS_RO(static_list, node, shr)) {
2354 if (shr->afi != afi || shr->safi != safi)
2355 continue;
2356
2357 if (strcmp(zvrf->vrf->name, shr->vrf_name) != 0)
2358 continue;
2359
cd4b15a5
QY
2360 char dest_str[PREFIX_STRLEN];
2361
2362 prefix2str(&shr->dest, dest_str, sizeof(dest_str));
2363
4060008b
DS
2364 vty_out(vty, "%s ", spacing);
2365 if (shr->dest_str)
cd4b15a5 2366 vty_out(vty, "%s ", dest_str);
4060008b
DS
2367 if (shr->src_str)
2368 vty_out(vty, "from %s ", shr->src_str);
2369 if (shr->gate_str)
2370 vty_out(vty, "%s ", shr->gate_str);
2371 if (shr->ifname)
2372 vty_out(vty, "%s ", shr->ifname);
2373 if (shr->flag_str)
2374 vty_out(vty, "%s ", shr->flag_str);
2375 if (shr->tag_str)
be627102 2376 vty_out(vty, "tag %s ", shr->tag_str);
4060008b
DS
2377 if (shr->distance_str)
2378 vty_out(vty, "%s ", shr->distance_str);
2379 if (shr->label_str)
2380 vty_out(vty, "label %s ", shr->label_str);
b3b08602
PG
2381 if (shr->table_str)
2382 vty_out(vty, "table %s ", shr->table_str);
4060008b
DS
2383 if (strcmp(shr->vrf_name, shr->nhvrf_name) != 0)
2384 vty_out(vty, "nexthop-vrf %s", shr->nhvrf_name);
2385 vty_out(vty, "\n");
2386 }
2387
37728041
DS
2388 for (rn = route_top(stable); rn; rn = srcdest_route_next(rn))
2389 for (si = rn->info; si; si = si->next) {
2390 vty_out(vty, "%s %s", spacing,
2391 srcdest_rnode2str(rn, buf, sizeof buf));
2392
2393 switch (si->type) {
2394 case STATIC_IPV4_GATEWAY:
996c9314 2395 vty_out(vty, " %s", inet_ntoa(si->addr.ipv4));
37728041
DS
2396 break;
2397 case STATIC_IPV6_GATEWAY:
2398 vty_out(vty, " %s",
996c9314 2399 inet_ntop(AF_INET6, &si->addr.ipv6, buf,
37728041
DS
2400 sizeof buf));
2401 break;
2402 case STATIC_IFNAME:
2403 vty_out(vty, " %s", si->ifname);
2404 break;
2405 case STATIC_BLACKHOLE:
2406 switch (si->bh_type) {
2407 case STATIC_BLACKHOLE_DROP:
2408 vty_out(vty, " blackhole");
d62a17ae 2409 break;
37728041
DS
2410 case STATIC_BLACKHOLE_NULL:
2411 vty_out(vty, " Null0");
599186ad 2412 break;
37728041
DS
2413 case STATIC_BLACKHOLE_REJECT:
2414 vty_out(vty, " reject");
d62a17ae 2415 break;
2416 }
37728041
DS
2417 break;
2418 case STATIC_IPV4_GATEWAY_IFNAME:
2419 vty_out(vty, " %s %s",
996c9314 2420 inet_ntop(AF_INET, &si->addr.ipv4, buf,
37728041
DS
2421 sizeof buf),
2422 si->ifname);
2423 break;
2424 case STATIC_IPV6_GATEWAY_IFNAME:
2425 vty_out(vty, " %s %s",
996c9314 2426 inet_ntop(AF_INET6, &si->addr.ipv6, buf,
37728041
DS
2427 sizeof buf),
2428 si->ifname);
2429 break;
2430 }
d62a17ae 2431
37728041 2432 if (si->tag)
996c9314 2433 vty_out(vty, " tag %" ROUTE_TAG_PRI, si->tag);
d62a17ae 2434
996c9314 2435 if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT)
37728041 2436 vty_out(vty, " %d", si->distance);
d62a17ae 2437
d7ca6374
QY
2438 /* Label information */
2439 if (si->snh_label.num_labels)
2440 vty_out(vty, " label %s",
2441 mpls_label2str(si->snh_label.num_labels,
2442 si->snh_label.label, buf,
2443 sizeof buf, 0));
2444
37728041 2445 if (si->nh_vrf_id != si->vrf_id) {
15da01e9 2446 vty_out(vty, " nexthop-vrf %s", si->nh_vrfname);
37728041 2447 }
d62a17ae 2448
e9748a89
PG
2449 /* table ID from VRF overrides configured
2450 */
00384b5f
PG
2451 if (si->table_id && zvrf->table_id == RT_TABLE_MAIN)
2452 vty_out(vty, " table %u", si->table_id);
2453
2454 vty_out(vty, "\n");
2455
2456 write = 1;
2457 }
2458 return write;
b3b08602
PG
2459}
2460
00384b5f
PG
2461DEFPY(ipv6_route_blackhole,
2462 ipv6_route_blackhole_cmd,
b3b08602
PG
2463 "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
2464 <Null0|reject|blackhole>$flag \
2465 [{ \
2466 tag (1-4294967295) \
2467 |(1-255)$distance \
2468 |vrf NAME \
2469 |label WORD \
2470 |table (1-4294967295) \
2471 }]",
2472 NO_STR
2473 IPV6_STR
2474 "Establish static routes\n"
2475 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2476 "IPv6 source-dest route\n"
2477 "IPv6 source prefix\n"
2478 "Null interface\n"
2479 "Emit an ICMP unreachable when matched\n"
2480 "Silently discard pkts when matched\n"
2481 "Set tag for this route\n"
2482 "Tag value\n"
2483 "Distance value for this prefix\n"
2484 VRF_CMD_HELP_STR
2485 MPLS_LABEL_HELPSTR
2486 "Table to configure\n"
2487 "The table number to configure\n")
2488{
00384b5f
PG
2489 if (table_str && !vrf_is_backend_netns()) {
2490 vty_out(vty,
2491 "%% table param only available when running on netns-based vrfs\n");
2492 return CMD_WARNING_CONFIG_FAILED;
2493 }
2494
b3b08602
PG
2495 return zebra_static_route(vty, AFI_IP6, SAFI_UNICAST, no, prefix_str,
2496 NULL, from_str, NULL, NULL, flag, tag_str,
2497 distance_str, vrf, label, table_str);
1e058f38
DW
2498}
2499
b2ffa06b
DS
2500DEFPY(ipv6_route_blackhole_vrf,
2501 ipv6_route_blackhole_vrf_cmd,
b3b08602
PG
2502 "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
2503 <Null0|reject|blackhole>$flag \
2504 [{ \
2505 tag (1-4294967295) \
2506 |(1-255)$distance \
2507 |label WORD \
2508 |table (1-4294967295) \
2509 }]",
2510 NO_STR
2511 IPV6_STR
2512 "Establish static routes\n"
2513 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2514 "IPv6 source-dest route\n"
2515 "IPv6 source prefix\n"
2516 "Null interface\n"
2517 "Emit an ICMP unreachable when matched\n"
2518 "Silently discard pkts when matched\n"
2519 "Set tag for this route\n"
2520 "Tag value\n"
2521 "Distance value for this prefix\n"
2522 MPLS_LABEL_HELPSTR
2523 "Table to configure\n"
2524 "The table number to configure\n")
2525{
2526 VTY_DECLVAR_CONTEXT(vrf, vrf);
2527 struct zebra_vrf *zvrf = vrf->info;
2528
00384b5f
PG
2529 if (table_str && !vrf_is_backend_netns()) {
2530 vty_out(vty,
2531 "%% table param only available when running on netns-based vrfs\n");
2532 return CMD_WARNING_CONFIG_FAILED;
2533 }
b3b08602
PG
2534 /*
2535 * Coverity is complaining that prefix could
2536 * be dereferenced, but we know that prefix will
2537 * valid. Add an assert to make it happy
2538 */
2539 assert(prefix);
2540 return zebra_static_route_leak(
2541 vty, zvrf, zvrf, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL,
2542 from_str, NULL, NULL, flag, tag_str, distance_str, label,
2543 table_str);
b2ffa06b
DS
2544}
2545
1e058f38
DW
2546DEFPY(ipv6_route_address_interface,
2547 ipv6_route_address_interface_cmd,
b3b08602
PG
2548 "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
2549 X:X::X:X$gate \
2550 INTERFACE$ifname \
2551 [{ \
2552 tag (1-4294967295) \
2553 |(1-255)$distance \
2554 |vrf NAME \
2555 |label WORD \
2556 |table (1-4294967295) \
2557 |nexthop-vrf NAME \
2558 }]",
2559 NO_STR
2560 IPV6_STR
2561 "Establish static routes\n"
2562 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2563 "IPv6 source-dest route\n"
2564 "IPv6 source prefix\n"
2565 "IPv6 gateway address\n"
2566 "IPv6 gateway interface name\n"
2567 "Set tag for this route\n"
2568 "Tag value\n"
2569 "Distance value for this prefix\n"
2570 VRF_CMD_HELP_STR
2571 MPLS_LABEL_HELPSTR
2572 "Table to configure\n"
2573 "The table number to configure\n"
2574 VRF_CMD_HELP_STR)
2575{
2576 struct zebra_vrf *zvrf;
2577 struct zebra_vrf *nh_zvrf;
2578
00384b5f
PG
2579 if (table_str && !vrf_is_backend_netns()) {
2580 vty_out(vty,
2581 "%% table param only available when running on netns-based vrfs\n");
2582 return CMD_WARNING_CONFIG_FAILED;
2583 }
2584
b3b08602
PG
2585 zvrf = zebra_vty_get_unknown_vrf(vty, vrf);
2586 if (!zvrf) {
2587 vty_out(vty, "%% vrf %s is not defined\n", vrf);
2588 return CMD_WARNING_CONFIG_FAILED;
2589 }
2590
2591 if (nexthop_vrf)
2592 nh_zvrf = zebra_vty_get_unknown_vrf(vty, nexthop_vrf);
2593 else
2594 nh_zvrf = zvrf;
2595
2596 if (!nh_zvrf) {
2597 vty_out(vty, "%% nexthop vrf %s is not defined\n", nexthop_vrf);
2598 return CMD_WARNING_CONFIG_FAILED;
2599 }
2600
2601 return zebra_static_route_leak(
2602 vty, zvrf, nh_zvrf, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL,
2603 from_str, gate_str, ifname, NULL, tag_str, distance_str, label,
2604 table_str);
1e058f38
DW
2605}
2606
b2ffa06b
DS
2607DEFPY(ipv6_route_address_interface_vrf,
2608 ipv6_route_address_interface_vrf_cmd,
b3b08602
PG
2609 "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
2610 X:X::X:X$gate \
2611 INTERFACE$ifname \
2612 [{ \
2613 tag (1-4294967295) \
2614 |(1-255)$distance \
2615 |label WORD \
2616 |table (1-4294967295) \
2617 |nexthop-vrf NAME \
2618 }]",
2619 NO_STR
2620 IPV6_STR
2621 "Establish static routes\n"
2622 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2623 "IPv6 source-dest route\n"
2624 "IPv6 source prefix\n"
2625 "IPv6 gateway address\n"
2626 "IPv6 gateway interface name\n"
2627 "Set tag for this route\n"
2628 "Tag value\n"
2629 "Distance value for this prefix\n"
2630 MPLS_LABEL_HELPSTR
2631 "Table to configure\n"
2632 "The table number to configure\n"
2633 VRF_CMD_HELP_STR)
2634{
2635 VTY_DECLVAR_CONTEXT(vrf, vrf);
2636 struct zebra_vrf *zvrf = vrf->info;
2637 struct zebra_vrf *nh_zvrf;
2638
00384b5f
PG
2639 if (table_str && !vrf_is_backend_netns()) {
2640 vty_out(vty,
2641 "%% table param only available when running on netns-based vrfs\n");
61408536
DS
2642 return CMD_WARNING_CONFIG_FAILED;
2643 }
2644
2481e732 2645 if (nexthop_vrf)
e7f96f74 2646 nh_zvrf = zebra_vty_get_unknown_vrf(vty, nexthop_vrf);
2481e732
DS
2647 else
2648 nh_zvrf = zvrf;
2649
61408536 2650 if (!nh_zvrf) {
996c9314 2651 vty_out(vty, "%% nexthop vrf %s is not defined\n", nexthop_vrf);
61408536
DS
2652 return CMD_WARNING_CONFIG_FAILED;
2653 }
2654
996c9314
LB
2655 return zebra_static_route_leak(
2656 vty, zvrf, nh_zvrf, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL,
b3b08602 2657 from_str, gate_str, ifname, NULL, tag_str, distance_str, label,
00384b5f 2658 table_str);
b3b08602
PG
2659}
2660
00384b5f
PG
2661DEFPY(ipv6_route,
2662 ipv6_route_cmd,
b3b08602
PG
2663 "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
2664 <X:X::X:X$gate|INTERFACE$ifname> \
2665 [{ \
2666 tag (1-4294967295) \
2667 |(1-255)$distance \
2668 |vrf NAME \
2669 |label WORD \
2670 |table (1-4294967295) \
2671 |nexthop-vrf NAME \
2672 }]",
2673 NO_STR
2674 IPV6_STR
2675 "Establish static routes\n"
2676 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2677 "IPv6 source-dest route\n"
2678 "IPv6 source prefix\n"
2679 "IPv6 gateway address\n"
2680 "IPv6 gateway interface name\n"
2681 "Set tag for this route\n"
2682 "Tag value\n"
2683 "Distance value for this prefix\n"
2684 VRF_CMD_HELP_STR
2685 MPLS_LABEL_HELPSTR
2686 "Table to configure\n"
2687 "The table number to configure\n"
2688 VRF_CMD_HELP_STR)
2689{
2690 struct zebra_vrf *zvrf;
2691 struct zebra_vrf *nh_zvrf;
2692
00384b5f
PG
2693 if (table_str && !vrf_is_backend_netns()) {
2694 vty_out(vty,
2695 "%% table param only available when running on netns-based vrfs\n");
2696 return CMD_WARNING_CONFIG_FAILED;
2697 }
2698
b3b08602
PG
2699 zvrf = zebra_vty_get_unknown_vrf(vty, vrf);
2700 if (!zvrf) {
2701 vty_out(vty, "%% vrf %s is not defined\n", vrf);
2702 return CMD_WARNING_CONFIG_FAILED;
2703 }
2704
2705 if (nexthop_vrf)
2706 nh_zvrf = zebra_vty_get_unknown_vrf(vty, nexthop_vrf);
2707 else
2708 nh_zvrf = zvrf;
2709
2710 if (!nh_zvrf) {
2711 vty_out(vty, "%% nexthop vrf %s is not defined\n", nexthop_vrf);
2712 return CMD_WARNING_CONFIG_FAILED;
2713 }
2714
2715 return zebra_static_route_leak(
2716 vty, zvrf, nh_zvrf, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL,
2717 from_str, gate_str, ifname, NULL, tag_str, distance_str, label,
2718 table_str);
0d9551dc
DS
2719}
2720
b2ffa06b
DS
2721DEFPY(ipv6_route_vrf,
2722 ipv6_route_vrf_cmd,
b3b08602
PG
2723 "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
2724 <X:X::X:X$gate|INTERFACE$ifname> \
2725 [{ \
2726 tag (1-4294967295) \
2727 |(1-255)$distance \
2728 |label WORD \
2729 |table (1-4294967295) \
2730 |nexthop-vrf NAME \
2731 }]",
2732 NO_STR
2733 IPV6_STR
2734 "Establish static routes\n"
2735 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2736 "IPv6 source-dest route\n"
2737 "IPv6 source prefix\n"
2738 "IPv6 gateway address\n"
2739 "IPv6 gateway interface name\n"
2740 "Set tag for this route\n"
2741 "Tag value\n"
2742 "Distance value for this prefix\n"
2743 MPLS_LABEL_HELPSTR
2744 "Table to configure\n"
2745 "The table number to configure\n"
2746 VRF_CMD_HELP_STR)
2747{
2748 VTY_DECLVAR_CONTEXT(vrf, vrf);
2749 struct zebra_vrf *zvrf = vrf->info;
2750 struct zebra_vrf *nh_zvrf;
2751
00384b5f
PG
2752 if (table_str && !vrf_is_backend_netns()) {
2753 vty_out(vty,
2754 "%% table param only available when running on netns-based vrfs\n");
2755 return CMD_WARNING_CONFIG_FAILED;
2756 }
2757
b3b08602
PG
2758 if (nexthop_vrf)
2759 nh_zvrf = zebra_vty_get_unknown_vrf(vty, nexthop_vrf);
2760 else
2761 nh_zvrf = zvrf;
2762
2763 if (!nh_zvrf) {
2764 vty_out(vty, "%% nexthop vrf %s is not defined\n", nexthop_vrf);
2765 return CMD_WARNING_CONFIG_FAILED;
2766 }
2767
2768 return zebra_static_route_leak(
2769 vty, zvrf, nh_zvrf, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL,
2770 from_str, gate_str, ifname, NULL, tag_str, distance_str, label,
2771 table_str);
0d9551dc
DS
2772}
2773
cddf391b
B
2774/*
2775 * Show IPv6 mroute command.Used to dump
2776 * the Multicast routing table.
2777 */
cddf391b
B
2778DEFUN (show_ipv6_mroute,
2779 show_ipv6_mroute_cmd,
9bf96c84 2780 "show ipv6 mroute [vrf NAME]",
cddf391b
B
2781 SHOW_STR
2782 IP_STR
9bf96c84
DW
2783 "IPv6 Multicast routing table\n"
2784 VRF_CMD_HELP_STR)
cddf391b 2785{
d62a17ae 2786 struct route_table *table;
2787 struct route_node *rn;
2788 struct route_entry *re;
2789 int first = 1;
2790 vrf_id_t vrf_id = VRF_DEFAULT;
2791
2792 if (argc == 5)
2793 VRF_GET_ID(vrf_id, argv[4]->arg);
2794
2795 table = zebra_vrf_table(AFI_IP6, SAFI_MULTICAST, vrf_id);
2796 if (!table)
2797 return CMD_SUCCESS;
2798
2799 /* Show all IPv6 route. */
2800 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
a2addae8 2801 RNODE_FOREACH_RE (rn, re) {
d62a17ae 2802 if (first) {
2803 vty_out(vty, SHOW_ROUTE_V6_HEADER);
2804 first = 0;
2805 }
2806 vty_show_ip_route(vty, rn, re, NULL);
2807 }
2808 return CMD_SUCCESS;
cddf391b
B
2809}
2810
af41b63a
FL
2811DEFUN (show_ipv6_mroute_vrf_all,
2812 show_ipv6_mroute_vrf_all_cmd,
5bebf568 2813 "show ipv6 mroute vrf all",
af41b63a
FL
2814 SHOW_STR
2815 IP_STR
2816 "IPv6 Multicast routing table\n"
2817 VRF_ALL_CMD_HELP_STR)
2818{
d62a17ae 2819 struct route_table *table;
2820 struct route_node *rn;
2821 struct route_entry *re;
2822 struct vrf *vrf;
2823 struct zebra_vrf *zvrf;
2824 int first = 1;
2825
a2addae8 2826 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
d62a17ae 2827 if ((zvrf = vrf->info) == NULL
2828 || (table = zvrf->table[AFI_IP6][SAFI_MULTICAST]) == NULL)
2829 continue;
2830
2831 /* Show all IPv6 route. */
2832 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
a2addae8 2833 RNODE_FOREACH_RE (rn, re) {
d62a17ae 2834 if (first) {
2835 vty_out(vty, SHOW_ROUTE_V6_HEADER);
2836 first = 0;
2837 }
2838 vty_show_ip_route(vty, rn, re, NULL);
2839 }
2840 }
2841 return CMD_SUCCESS;
af41b63a
FL
2842}
2843
6baf7bb8
DS
2844DEFUN (allow_external_route_update,
2845 allow_external_route_update_cmd,
2846 "allow-external-route-update",
17d990c1 2847 "Allow FRR routes to be overwritten by external processes\n")
6baf7bb8 2848{
d62a17ae 2849 allow_delete = 1;
6baf7bb8 2850
d62a17ae 2851 return CMD_SUCCESS;
6baf7bb8
DS
2852}
2853
2854DEFUN (no_allow_external_route_update,
2855 no_allow_external_route_update_cmd,
2856 "no allow-external-route-update",
17d990c1
DS
2857 NO_STR
2858 "Allow FRR routes to be overwritten by external processes\n")
6baf7bb8 2859{
d62a17ae 2860 allow_delete = 0;
6baf7bb8 2861
d62a17ae 2862 return CMD_SUCCESS;
6baf7bb8
DS
2863}
2864
12f6fb97
DS
2865/* show vrf */
2866DEFUN (show_vrf,
2867 show_vrf_cmd,
2868 "show vrf",
2869 SHOW_STR
2870 "VRF\n")
2871{
d62a17ae 2872 struct vrf *vrf;
2873 struct zebra_vrf *zvrf;
12f6fb97 2874
b73823ef
PG
2875 if (vrf_is_backend_netns())
2876 vty_out(vty, "netns-based vrfs\n");
2877
a2addae8 2878 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
d62a17ae 2879 if (!(zvrf = vrf->info))
2880 continue;
90ac32c2 2881 if (zvrf_id(zvrf) == VRF_DEFAULT)
d62a17ae 2882 continue;
2883
2884 vty_out(vty, "vrf %s ", zvrf_name(zvrf));
996c9314 2885 if (zvrf_id(zvrf) == VRF_UNKNOWN || !zvrf_is_active(zvrf))
d62a17ae 2886 vty_out(vty, "inactive");
81c9005f 2887 else if (zvrf_ns_name(zvrf))
996c9314
LB
2888 vty_out(vty, "id %u netns %s", zvrf_id(zvrf),
2889 zvrf_ns_name(zvrf));
d62a17ae 2890 else
2891 vty_out(vty, "id %u table %u", zvrf_id(zvrf),
2892 zvrf->table_id);
22bd3e94 2893 if (vrf_is_user_cfged(vrf))
2894 vty_out(vty, " (configured)");
d62a17ae 2895 vty_out(vty, "\n");
2896 }
12f6fb97 2897
d62a17ae 2898 return CMD_SUCCESS;
12f6fb97
DS
2899}
2900
e8d26197
MK
2901DEFUN (default_vrf_vni_mapping,
2902 default_vrf_vni_mapping_cmd,
c48d9f5f 2903 "vni " CMD_VNI_RANGE "[prefix-routes-only]",
e8d26197 2904 "VNI corresponding to the DEFAULT VRF\n"
c48d9f5f
MK
2905 "VNI-ID\n"
2906 "Prefix routes only \n")
e8d26197
MK
2907{
2908 int ret = 0;
2909 char err[ERR_STR_SZ];
2910 struct zebra_vrf *zvrf = NULL;
2911 vni_t vni = strtoul(argv[1]->arg, NULL, 10);
c48d9f5f 2912 int filter = 0;
e8d26197
MK
2913
2914 zvrf = vrf_info_lookup(VRF_DEFAULT);
2915 if (!zvrf)
2916 return CMD_WARNING;
2917
c48d9f5f
MK
2918 if (argc == 3)
2919 filter = 1;
2920
2921 ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ,
2922 filter, 1);
e8d26197
MK
2923 if (ret != 0) {
2924 vty_out(vty, "%s\n", err);
2925 return CMD_WARNING;
2926 }
2927
2928 return CMD_SUCCESS;
2929}
2930
2931DEFUN (no_default_vrf_vni_mapping,
2932 no_default_vrf_vni_mapping_cmd,
2933 "no vni " CMD_VNI_RANGE,
2934 NO_STR
2935 "VNI corresponding to DEFAULT VRF\n"
2936 "VNI-ID")
2937{
2938 int ret = 0;
2939 char err[ERR_STR_SZ];
2940 vni_t vni = strtoul(argv[2]->arg, NULL, 10);
2941 struct zebra_vrf *zvrf = NULL;
2942
2943 zvrf = vrf_info_lookup(VRF_DEFAULT);
2944 if (!zvrf)
2945 return CMD_WARNING;
2946
c48d9f5f 2947 ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ, 0, 0);
e8d26197
MK
2948 if (ret != 0) {
2949 vty_out(vty, "%s\n", err);
2950 return CMD_WARNING;
2951 }
2952
2953 return CMD_SUCCESS;
2954}
2955
b7cfce93
MK
2956DEFUN (vrf_vni_mapping,
2957 vrf_vni_mapping_cmd,
c48d9f5f 2958 "vni " CMD_VNI_RANGE "[prefix-routes-only]",
e8d26197 2959 "VNI corresponding to tenant VRF\n"
c48d9f5f
MK
2960 "VNI-ID\n"
2961 "prefix-routes-only\n")
b7cfce93
MK
2962{
2963 int ret = 0;
c48d9f5f 2964 int filter = 0;
b7cfce93
MK
2965
2966 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
2967 vni_t vni = strtoul(argv[1]->arg, NULL, 10);
2968 char err[ERR_STR_SZ];
2969
2970 assert(vrf);
2971 assert(zvrf);
2972
c48d9f5f
MK
2973 if (argc == 3)
2974 filter = 1;
2975
317f1fe0 2976 /* Mark as having FRR configuration */
2977 vrf_set_user_cfged(vrf);
c48d9f5f
MK
2978 ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ,
2979 filter, 1);
b7cfce93
MK
2980 if (ret != 0) {
2981 vty_out(vty, "%s\n", err);
2982 return CMD_WARNING;
2983 }
2984
2985 return CMD_SUCCESS;
2986}
2987
2988DEFUN (no_vrf_vni_mapping,
2989 no_vrf_vni_mapping_cmd,
cf299714 2990 "no vni " CMD_VNI_RANGE "[prefix-routes-only]",
b7cfce93 2991 NO_STR
e8d26197 2992 "VNI corresponding to tenant VRF\n"
cf299714
MK
2993 "VNI-ID\n"
2994 "prefix-routes-only\n")
b7cfce93
MK
2995{
2996 int ret = 0;
cf299714 2997 int filter = 0;
b7cfce93
MK
2998 char err[ERR_STR_SZ];
2999 vni_t vni = strtoul(argv[2]->arg, NULL, 10);
3000
3001 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
3002
3003 assert(vrf);
3004 assert(zvrf);
3005
cf299714
MK
3006 if (argc == 4)
3007 filter = 1;
3008
3009 ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err,
3010 ERR_STR_SZ, filter, 0);
b7cfce93
MK
3011 if (ret != 0) {
3012 vty_out(vty, "%s\n", err);
3013 return CMD_WARNING;
3014 }
3015
22bd3e94 3016 /* If no other FRR config for this VRF, mark accordingly. */
3017 if (!zebra_vrf_has_config(zvrf))
3018 vrf_reset_user_cfged(vrf);
3019
b7cfce93
MK
3020 return CMD_SUCCESS;
3021}
3022
3023/* show vrf */
3024DEFUN (show_vrf_vni,
3025 show_vrf_vni_cmd,
35be5542 3026 "show vrf vni [json]",
b7cfce93
MK
3027 SHOW_STR
3028 "VRF\n"
35be5542
MK
3029 "VNI\n"
3030 JSON_STR)
b7cfce93
MK
3031{
3032 struct vrf *vrf;
3033 struct zebra_vrf *zvrf;
35be5542
MK
3034 json_object *json = NULL;
3035 json_object *json_vrfs = NULL;
d7c0a89a 3036 uint8_t uj = use_json(argc, argv);
35be5542
MK
3037
3038 if (uj) {
3039 json = json_object_new_object();
3040 json_vrfs = json_object_new_array();
3041 }
b7cfce93 3042
4cce389e 3043 if (!uj)
996c9314
LB
3044 vty_out(vty, "%-37s %-10s %-20s %-20s %-5s %-18s\n", "VRF",
3045 "VNI", "VxLAN IF", "L3-SVI", "State", "Rmac");
4cce389e 3046
996c9314 3047 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
b7cfce93
MK
3048 zvrf = vrf->info;
3049 if (!zvrf)
3050 continue;
3051
4cce389e 3052 zebra_vxlan_print_vrf_vni(vty, zvrf, json_vrfs);
35be5542
MK
3053 }
3054
3055 if (uj) {
3056 json_object_object_add(json, "vrfs", json_vrfs);
3057 vty_out(vty, "%s\n", json_object_to_json_string_ext(
3058 json, JSON_C_TO_STRING_PRETTY));
3059 json_object_free(json);
b7cfce93
MK
3060 }
3061
3062 return CMD_SUCCESS;
3063}
3064
4cce389e
MK
3065DEFUN (show_evpn_global,
3066 show_evpn_global_cmd,
3067 "show evpn [json]",
3068 SHOW_STR
3069 "EVPN\n"
3070 JSON_STR)
3071{
d7c0a89a 3072 uint8_t uj = use_json(argc, argv);
4cce389e
MK
3073
3074 zebra_vxlan_print_evpn(vty, uj);
3075 return CMD_SUCCESS;
3076}
3077
cec2e17d 3078DEFUN (show_evpn_vni,
3079 show_evpn_vni_cmd,
cd233079 3080 "show evpn vni [json]",
cec2e17d 3081 SHOW_STR
3082 "EVPN\n"
cd233079 3083 "VxLAN information\n"
bd592158 3084 JSON_STR)
cec2e17d 3085{
d62a17ae 3086 struct zebra_vrf *zvrf;
d7c0a89a 3087 uint8_t uj = use_json(argc, argv);
cec2e17d 3088
d62a17ae 3089 zvrf = vrf_info_lookup(VRF_DEFAULT);
cd233079 3090 zebra_vxlan_print_vnis(vty, zvrf, uj);
d62a17ae 3091 return CMD_SUCCESS;
cec2e17d 3092}
3093
3094DEFUN (show_evpn_vni_vni,
3095 show_evpn_vni_vni_cmd,
cd233079 3096 "show evpn vni " CMD_VNI_RANGE "[json]",
cec2e17d 3097 SHOW_STR
3098 "EVPN\n"
3099 "VxLAN Network Identifier\n"
cd233079 3100 "VNI number\n"
bd592158 3101 JSON_STR)
cec2e17d 3102{
d62a17ae 3103 struct zebra_vrf *zvrf;
3104 vni_t vni;
d7c0a89a 3105 uint8_t uj = use_json(argc, argv);
cec2e17d 3106
d62a17ae 3107 vni = strtoul(argv[3]->arg, NULL, 10);
3108 zvrf = vrf_info_lookup(VRF_DEFAULT);
cd233079 3109 zebra_vxlan_print_vni(vty, zvrf, vni, uj);
d62a17ae 3110 return CMD_SUCCESS;
cec2e17d 3111}
3112
4cce389e
MK
3113DEFUN (show_evpn_rmac_vni_mac,
3114 show_evpn_rmac_vni_mac_cmd,
3115 "show evpn rmac vni " CMD_VNI_RANGE " mac WORD [json]",
9aa741ea
MK
3116 SHOW_STR
3117 "EVPN\n"
3118 "RMAC\n"
4cce389e 3119 "L3 VNI\n"
9aa741ea
MK
3120 "VNI number\n"
3121 "MAC\n"
316f4ca4
MK
3122 "mac-address (e.g. 0a:0a:0a:0a:0a:0a)\n"
3123 JSON_STR)
9aa741ea
MK
3124{
3125 vni_t l3vni = 0;
3126 struct ethaddr mac;
d7c0a89a 3127 uint8_t uj = use_json(argc, argv);
9aa741ea
MK
3128
3129 l3vni = strtoul(argv[4]->arg, NULL, 10);
3130 if (!prefix_str2mac(argv[6]->arg, &mac)) {
3131 vty_out(vty, "%% Malformed MAC address\n");
3132 return CMD_WARNING;
3133 }
316f4ca4 3134 zebra_vxlan_print_specific_rmac_l3vni(vty, l3vni, &mac, uj);
9aa741ea
MK
3135 return CMD_SUCCESS;
3136}
3137
4cce389e
MK
3138DEFUN (show_evpn_rmac_vni,
3139 show_evpn_rmac_vni_cmd,
3140 "show evpn rmac vni " CMD_VNI_RANGE "[json]",
b7cfce93
MK
3141 SHOW_STR
3142 "EVPN\n"
3143 "RMAC\n"
4cce389e 3144 "L3 VNI\n"
b7cfce93
MK
3145 "VNI number\n"
3146 JSON_STR)
3147{
3148 vni_t l3vni = 0;
d7c0a89a 3149 uint8_t uj = use_json(argc, argv);
b7cfce93
MK
3150
3151 l3vni = strtoul(argv[4]->arg, NULL, 10);
3152 zebra_vxlan_print_rmacs_l3vni(vty, l3vni, uj);
3153
3154 return CMD_SUCCESS;
3155}
3156
4cce389e
MK
3157DEFUN (show_evpn_rmac_vni_all,
3158 show_evpn_rmac_vni_all_cmd,
3159 "show evpn rmac vni all [json]",
b7cfce93
MK
3160 SHOW_STR
3161 "EVPN\n"
3162 "RMAC addresses\n"
4cce389e 3163 "L3 VNI\n"
b7cfce93
MK
3164 "All VNIs\n"
3165 JSON_STR)
3166{
d7c0a89a 3167 uint8_t uj = use_json(argc, argv);
b7cfce93
MK
3168
3169 zebra_vxlan_print_rmacs_all_l3vni(vty, uj);
3170
3171 return CMD_SUCCESS;
3172}
3173
4cce389e
MK
3174DEFUN (show_evpn_nh_vni_ip,
3175 show_evpn_nh_vni_ip_cmd,
3176 "show evpn next-hops vni " CMD_VNI_RANGE " ip WORD [json]",
9aa741ea
MK
3177 SHOW_STR
3178 "EVPN\n"
3179 "Remote Vteps\n"
4cce389e 3180 "L3 VNI\n"
9aa741ea
MK
3181 "VNI number\n"
3182 "Ip address\n"
c0e519d3
MK
3183 "Host address (ipv4 or ipv6)\n"
3184 JSON_STR)
9aa741ea
MK
3185{
3186 vni_t l3vni;
9aa741ea 3187 struct ipaddr ip;
d7c0a89a 3188 uint8_t uj = use_json(argc, argv);
9aa741ea
MK
3189
3190 l3vni = strtoul(argv[4]->arg, NULL, 10);
3191 if (str2ipaddr(argv[6]->arg, &ip) != 0) {
3192 if (!uj)
3193 vty_out(vty, "%% Malformed Neighbor address\n");
3194 return CMD_WARNING;
3195 }
c0e519d3 3196 zebra_vxlan_print_specific_nh_l3vni(vty, l3vni, &ip, uj);
9aa741ea
MK
3197
3198 return CMD_SUCCESS;
3199}
3200
4cce389e
MK
3201DEFUN (show_evpn_nh_vni,
3202 show_evpn_nh_vni_cmd,
3203 "show evpn next-hops vni " CMD_VNI_RANGE "[json]",
b7cfce93
MK
3204 SHOW_STR
3205 "EVPN\n"
3206 "Remote Vteps\n"
4cce389e 3207 "L3 VNI\n"
b7cfce93
MK
3208 "VNI number\n"
3209 JSON_STR)
3210{
3211 vni_t l3vni;
d7c0a89a 3212 uint8_t uj = use_json(argc, argv);
b7cfce93
MK
3213
3214 l3vni = strtoul(argv[4]->arg, NULL, 10);
3215 zebra_vxlan_print_nh_l3vni(vty, l3vni, uj);
3216
3217 return CMD_SUCCESS;
3218}
3219
4cce389e
MK
3220DEFUN (show_evpn_nh_vni_all,
3221 show_evpn_nh_vni_all_cmd,
3222 "show evpn next-hops vni all [json]",
b7cfce93
MK
3223 SHOW_STR
3224 "EVPN\n"
3225 "Remote VTEPs\n"
4cce389e 3226 "L3 VNI\n"
b7cfce93
MK
3227 "All VNIs\n"
3228 JSON_STR)
3229{
d7c0a89a 3230 uint8_t uj = use_json(argc, argv);
b7cfce93
MK
3231
3232 zebra_vxlan_print_nh_all_l3vni(vty, uj);
3233
3234 return CMD_SUCCESS;
3235}
3236
cec2e17d 3237DEFUN (show_evpn_mac_vni,
3238 show_evpn_mac_vni_cmd,
cd233079 3239 "show evpn mac vni " CMD_VNI_RANGE "[json]",
cec2e17d 3240 SHOW_STR
3241 "EVPN\n"
3242 "MAC addresses\n"
3243 "VxLAN Network Identifier\n"
cd233079 3244 "VNI number\n"
bd592158 3245 JSON_STR)
cec2e17d 3246{
d62a17ae 3247 struct zebra_vrf *zvrf;
3248 vni_t vni;
d7c0a89a 3249 uint8_t uj = use_json(argc, argv);
cec2e17d 3250
d62a17ae 3251 vni = strtoul(argv[4]->arg, NULL, 10);
3252 zvrf = vrf_info_lookup(VRF_DEFAULT);
cd233079 3253 zebra_vxlan_print_macs_vni(vty, zvrf, vni, uj);
d62a17ae 3254 return CMD_SUCCESS;
cec2e17d 3255}
3256
3257DEFUN (show_evpn_mac_vni_all,
3258 show_evpn_mac_vni_all_cmd,
cd233079 3259 "show evpn mac vni all [json]",
cec2e17d 3260 SHOW_STR
3261 "EVPN\n"
3262 "MAC addresses\n"
3263 "VxLAN Network Identifier\n"
cd233079 3264 "All VNIs\n"
bd592158 3265 JSON_STR)
cec2e17d 3266{
d62a17ae 3267 struct zebra_vrf *zvrf;
d7c0a89a 3268 uint8_t uj = use_json(argc, argv);
cec2e17d 3269
d62a17ae 3270 zvrf = vrf_info_lookup(VRF_DEFAULT);
cd233079 3271 zebra_vxlan_print_macs_all_vni(vty, zvrf, uj);
d62a17ae 3272 return CMD_SUCCESS;
cec2e17d 3273}
3274
3275DEFUN (show_evpn_mac_vni_all_vtep,
3276 show_evpn_mac_vni_all_vtep_cmd,
cd233079 3277 "show evpn mac vni all vtep A.B.C.D [json]",
cec2e17d 3278 SHOW_STR
3279 "EVPN\n"
3280 "MAC addresses\n"
3281 "VxLAN Network Identifier\n"
3282 "All VNIs\n"
3283 "Remote VTEP\n"
cd233079 3284 "Remote VTEP IP address\n"
bd592158 3285 JSON_STR)
cec2e17d 3286{
d62a17ae 3287 struct zebra_vrf *zvrf;
3288 struct in_addr vtep_ip;
d7c0a89a 3289 uint8_t uj = use_json(argc, argv);
cec2e17d 3290
d62a17ae 3291 if (!inet_aton(argv[6]->arg, &vtep_ip)) {
cd233079
CS
3292 if (!uj)
3293 vty_out(vty, "%% Malformed VTEP IP address\n");
d62a17ae 3294 return CMD_WARNING;
3295 }
3296 zvrf = vrf_info_lookup(VRF_DEFAULT);
cd233079 3297 zebra_vxlan_print_macs_all_vni_vtep(vty, zvrf, vtep_ip, uj);
cec2e17d 3298
d62a17ae 3299 return CMD_SUCCESS;
cec2e17d 3300}
3301
3302
3303DEFUN (show_evpn_mac_vni_mac,
3304 show_evpn_mac_vni_mac_cmd,
3305 "show evpn mac vni " CMD_VNI_RANGE " mac WORD",
3306 SHOW_STR
3307 "EVPN\n"
3308 "MAC addresses\n"
3309 "VxLAN Network Identifier\n"
3310 "VNI number\n"
3311 "MAC\n"
3312 "MAC address (e.g., 00:e0:ec:20:12:62)\n")
3313{
d62a17ae 3314 struct zebra_vrf *zvrf;
3315 vni_t vni;
3316 struct ethaddr mac;
cec2e17d 3317
d62a17ae 3318 vni = strtoul(argv[4]->arg, NULL, 10);
3319 if (!prefix_str2mac(argv[6]->arg, &mac)) {
3320 vty_out(vty, "%% Malformed MAC address");
3321 return CMD_WARNING;
3322 }
3323 zvrf = vrf_info_lookup(VRF_DEFAULT);
3324 zebra_vxlan_print_specific_mac_vni(vty, zvrf, vni, &mac);
3325 return CMD_SUCCESS;
cec2e17d 3326}
3327
3328DEFUN (show_evpn_mac_vni_vtep,
3329 show_evpn_mac_vni_vtep_cmd,
cd233079 3330 "show evpn mac vni " CMD_VNI_RANGE " vtep A.B.C.D" "[json]",
cec2e17d 3331 SHOW_STR
3332 "EVPN\n"
3333 "MAC addresses\n"
3334 "VxLAN Network Identifier\n"
3335 "VNI number\n"
3336 "Remote VTEP\n"
cd233079 3337 "Remote VTEP IP address\n"
bd592158 3338 JSON_STR)
cec2e17d 3339{
d62a17ae 3340 struct zebra_vrf *zvrf;
3341 vni_t vni;
3342 struct in_addr vtep_ip;
d7c0a89a 3343 uint8_t uj = use_json(argc, argv);
cec2e17d 3344
d62a17ae 3345 vni = strtoul(argv[4]->arg, NULL, 10);
3346 if (!inet_aton(argv[6]->arg, &vtep_ip)) {
cd233079
CS
3347 if (!uj)
3348 vty_out(vty, "%% Malformed VTEP IP address\n");
d62a17ae 3349 return CMD_WARNING;
3350 }
cec2e17d 3351
d62a17ae 3352 zvrf = vrf_info_lookup(VRF_DEFAULT);
cd233079 3353 zebra_vxlan_print_macs_vni_vtep(vty, zvrf, vni, vtep_ip, uj);
d62a17ae 3354 return CMD_SUCCESS;
cec2e17d 3355}
3356
3357DEFUN (show_evpn_neigh_vni,
3358 show_evpn_neigh_vni_cmd,
cd233079 3359 "show evpn arp-cache vni " CMD_VNI_RANGE "[json]",
cec2e17d 3360 SHOW_STR
3361 "EVPN\n"
3362 "ARP and ND cache\n"
3363 "VxLAN Network Identifier\n"
cd233079 3364 "VNI number\n"
bd592158 3365 JSON_STR)
cec2e17d 3366{
d62a17ae 3367 struct zebra_vrf *zvrf;
3368 vni_t vni;
d7c0a89a 3369 uint8_t uj = use_json(argc, argv);
cec2e17d 3370
d62a17ae 3371 vni = strtoul(argv[4]->arg, NULL, 10);
3372 zvrf = vrf_info_lookup(VRF_DEFAULT);
cd233079 3373 zebra_vxlan_print_neigh_vni(vty, zvrf, vni, uj);
d62a17ae 3374 return CMD_SUCCESS;
cec2e17d 3375}
3376
3377DEFUN (show_evpn_neigh_vni_all,
3378 show_evpn_neigh_vni_all_cmd,
cd233079 3379 "show evpn arp-cache vni all [json]",
cec2e17d 3380 SHOW_STR
3381 "EVPN\n"
3382 "ARP and ND cache\n"
3383 "VxLAN Network Identifier\n"
cd233079 3384 "All VNIs\n"
bd592158 3385 JSON_STR)
cec2e17d 3386{
d62a17ae 3387 struct zebra_vrf *zvrf;
d7c0a89a 3388 uint8_t uj = use_json(argc, argv);
cec2e17d 3389
d62a17ae 3390 zvrf = vrf_info_lookup(VRF_DEFAULT);
cd233079 3391 zebra_vxlan_print_neigh_all_vni(vty, zvrf, uj);
d62a17ae 3392 return CMD_SUCCESS;
cec2e17d 3393}
3394
3395DEFUN (show_evpn_neigh_vni_neigh,
3396 show_evpn_neigh_vni_neigh_cmd,
cd233079 3397 "show evpn arp-cache vni " CMD_VNI_RANGE " ip WORD [json]",
cec2e17d 3398 SHOW_STR
3399 "EVPN\n"
3400 "ARP and ND cache\n"
3401 "VxLAN Network Identifier\n"
3402 "VNI number\n"
3403 "Neighbor\n"
cd233079 3404 "Neighbor address (IPv4 or IPv6 address)\n"
bd592158 3405 JSON_STR)
cec2e17d 3406{
d62a17ae 3407 struct zebra_vrf *zvrf;
3408 vni_t vni;
3409 struct ipaddr ip;
d7c0a89a 3410 uint8_t uj = use_json(argc, argv);
cec2e17d 3411
d62a17ae 3412 vni = strtoul(argv[4]->arg, NULL, 10);
3413 if (str2ipaddr(argv[6]->arg, &ip) != 0) {
cd233079
CS
3414 if (!uj)
3415 vty_out(vty, "%% Malformed Neighbor address\n");
d62a17ae 3416 return CMD_WARNING;
3417 }
3418 zvrf = vrf_info_lookup(VRF_DEFAULT);
cd233079 3419 zebra_vxlan_print_specific_neigh_vni(vty, zvrf, vni, &ip, uj);
d62a17ae 3420 return CMD_SUCCESS;
cec2e17d 3421}
3422
3423DEFUN (show_evpn_neigh_vni_vtep,
3424 show_evpn_neigh_vni_vtep_cmd,
cd233079 3425 "show evpn arp-cache vni " CMD_VNI_RANGE " vtep A.B.C.D [json]",
cec2e17d 3426 SHOW_STR
3427 "EVPN\n"
3428 "ARP and ND cache\n"
3429 "VxLAN Network Identifier\n"
3430 "VNI number\n"
3431 "Remote VTEP\n"
cd233079 3432 "Remote VTEP IP address\n"
bd592158 3433 JSON_STR)
cec2e17d 3434{
d62a17ae 3435 struct zebra_vrf *zvrf;
3436 vni_t vni;
3437 struct in_addr vtep_ip;
d7c0a89a 3438 uint8_t uj = use_json(argc, argv);
cec2e17d 3439
d62a17ae 3440 vni = strtoul(argv[4]->arg, NULL, 10);
3441 if (!inet_aton(argv[6]->arg, &vtep_ip)) {
cd233079
CS
3442 if (!uj)
3443 vty_out(vty, "%% Malformed VTEP IP address\n");
d62a17ae 3444 return CMD_WARNING;
3445 }
cec2e17d 3446
d62a17ae 3447 zvrf = vrf_info_lookup(VRF_DEFAULT);
cd233079 3448 zebra_vxlan_print_neigh_vni_vtep(vty, zvrf, vni, vtep_ip, uj);
d62a17ae 3449 return CMD_SUCCESS;
cec2e17d 3450}
3451
586f4ccf
PG
3452/* policy routing contexts */
3453DEFUN (show_pbr_ipset,
3454 show_pbr_ipset_cmd,
3455 "show pbr ipset [WORD]",
3456 SHOW_STR
3457 "Policy-Based Routing\n"
3458 "IPset Context information\n"
3459 "IPset Name information\n")
3460{
3461 int idx = 0;
3462 int found = 0;
3463 found = argv_find(argv, argc, "WORD", &idx);
3464 if (!found)
3465 zebra_pbr_show_ipset_list(vty, NULL);
3466 else
3467 zebra_pbr_show_ipset_list(vty, argv[idx]->arg);
3468 return CMD_SUCCESS;
3469}
3470
3471/* policy routing contexts */
3472DEFUN (show_pbr_iptable,
3473 show_pbr_iptable_cmd,
3474 "show pbr iptable",
3475 SHOW_STR
3476 "Policy-Based Routing\n"
3477 "IPtable Context information\n")
3478{
3479 zebra_pbr_show_iptable(vty);
3480 return CMD_SUCCESS;
3481}
3482
718e3744 3483/* Static ip route configuration write function. */
d62a17ae 3484static int zebra_ip_config(struct vty *vty)
718e3744 3485{
d62a17ae 3486 int write = 0;
718e3744 3487
d62a17ae 3488 write += zebra_import_table_config(vty);
37728041 3489
d62a17ae 3490 return write;
718e3744 3491}
3492
7a4bb9c5
DS
3493DEFUN (ip_zebra_import_table_distance,
3494 ip_zebra_import_table_distance_cmd,
12dcf78e 3495 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
8902474b
DS
3496 IP_STR
3497 "import routes from non-main kernel table\n"
3498 "kernel routing table id\n"
3499 "Distance for imported routes\n"
3500 "Default distance value\n"
3501 "route-map for filtering\n"
3502 "route-map name\n")
3503{
d7c0a89a 3504 uint32_t table_id = 0;
8902474b 3505
d62a17ae 3506 table_id = strtoul(argv[2]->arg, NULL, 10);
3507 int distance = ZEBRA_TABLE_DISTANCE_DEFAULT;
3508 char *rmap =
3509 strmatch(argv[argc - 2]->text, "route-map")
3510 ? XSTRDUP(MTYPE_ROUTE_MAP_NAME, argv[argc - 1]->arg)
3511 : NULL;
3512 int ret;
d722f26e 3513
d62a17ae 3514 if (argc == 7 || (argc == 5 && !rmap))
3515 distance = strtoul(argv[4]->arg, NULL, 10);
8902474b 3516
d62a17ae 3517 if (!is_zebra_valid_kernel_table(table_id)) {
3518 vty_out(vty,
3519 "Invalid routing table ID, %d. Must be in range 1-252\n",
3520 table_id);
0af35d90
RW
3521 if (rmap)
3522 XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
d62a17ae 3523 return CMD_WARNING;
3524 }
8902474b 3525
d62a17ae 3526 if (is_zebra_main_routing_table(table_id)) {
3527 vty_out(vty,
3528 "Invalid routing table ID, %d. Must be non-default table\n",
3529 table_id);
0af35d90
RW
3530 if (rmap)
3531 XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
d62a17ae 3532 return CMD_WARNING;
3533 }
8902474b 3534
d62a17ae 3535 ret = zebra_import_table(AFI_IP, table_id, distance, rmap, 1);
3536 if (rmap)
3537 XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
d722f26e 3538
d62a17ae 3539 return ret;
8902474b
DS
3540}
3541
62d52ded
DS
3542DEFUN_HIDDEN (zebra_packet_process,
3543 zebra_packet_process_cmd,
3544 "zebra zapi-packets (1-10000)",
3545 ZEBRA_STR
3546 "Zapi Protocol\n"
3547 "Number of packets to process before relinquishing thread\n")
3548{
3549 uint32_t packets = strtoul(argv[2]->arg, NULL, 10);
3550
ccd51bd2
QY
3551 atomic_store_explicit(&zebrad.packets_to_process, packets,
3552 memory_order_relaxed);
62d52ded
DS
3553
3554 return CMD_SUCCESS;
3555}
3556
3557DEFUN_HIDDEN (no_zebra_packet_process,
3558 no_zebra_packet_process_cmd,
3559 "no zebra zapi-packets [(1-10000)]",
3560 NO_STR
3561 ZEBRA_STR
3562 "Zapi Protocol\n"
3563 "Number of packets to process before relinquishing thread\n")
3564{
ccd51bd2
QY
3565 atomic_store_explicit(&zebrad.packets_to_process,
3566 ZEBRA_ZAPI_PACKETS_TO_PROCESS,
3567 memory_order_relaxed);
62d52ded
DS
3568
3569 return CMD_SUCCESS;
3570}
3571
3a30f50f
DS
3572DEFUN_HIDDEN (zebra_workqueue_timer,
3573 zebra_workqueue_timer_cmd,
3574 "zebra work-queue (0-10000)",
3575 ZEBRA_STR
3576 "Work Queue\n"
3577 "Time in milliseconds\n")
3578{
996c9314
LB
3579 uint32_t timer = strtoul(argv[2]->arg, NULL, 10);
3580 zebrad.ribq->spec.hold = timer;
3a30f50f 3581
996c9314 3582 return CMD_SUCCESS;
3a30f50f
DS
3583}
3584
3585DEFUN_HIDDEN (no_zebra_workqueue_timer,
3586 no_zebra_workqueue_timer_cmd,
3587 "no zebra work-queue [(0-10000)]",
3588 NO_STR
3589 ZEBRA_STR
3590 "Work Queue\n"
3591 "Time in milliseconds\n")
3592{
996c9314 3593 zebrad.ribq->spec.hold = ZEBRA_RIB_PROCESS_HOLD_TIME;
3a30f50f 3594
996c9314 3595 return CMD_SUCCESS;
3a30f50f
DS
3596}
3597
7a4bb9c5
DS
3598DEFUN (no_ip_zebra_import_table,
3599 no_ip_zebra_import_table_cmd,
b62ecea5 3600 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
7a4bb9c5
DS
3601 NO_STR
3602 IP_STR
3603 "import routes from non-main kernel table\n"
3a2d747c
QY
3604 "kernel routing table id\n"
3605 "Distance for imported routes\n"
3606 "Default distance value\n"
3607 "route-map for filtering\n"
3608 "route-map name\n")
7a4bb9c5 3609{
d7c0a89a 3610 uint32_t table_id = 0;
d62a17ae 3611 table_id = strtoul(argv[3]->arg, NULL, 10);
7a4bb9c5 3612
d62a17ae 3613 if (!is_zebra_valid_kernel_table(table_id)) {
3614 vty_out(vty,
3615 "Invalid routing table ID. Must be in range 1-252\n");
3616 return CMD_WARNING;
3617 }
7a4bb9c5 3618
d62a17ae 3619 if (is_zebra_main_routing_table(table_id)) {
3620 vty_out(vty,
3621 "Invalid routing table ID, %d. Must be non-default table\n",
3622 table_id);
3623 return CMD_WARNING;
3624 }
7a4bb9c5 3625
d62a17ae 3626 if (!is_zebra_import_table_enabled(AFI_IP, table_id))
3627 return CMD_SUCCESS;
7a4bb9c5 3628
d62a17ae 3629 return (zebra_import_table(AFI_IP, table_id, 0, NULL, 0));
7a4bb9c5
DS
3630}
3631
d62a17ae 3632static int config_write_protocol(struct vty *vty)
6baf7bb8 3633{
d62a17ae 3634 if (allow_delete)
3635 vty_out(vty, "allow-external-route-update\n");
6baf7bb8 3636
d62a17ae 3637 if (zebra_rnh_ip_default_route)
3638 vty_out(vty, "ip nht resolve-via-default\n");
6baf7bb8 3639
d62a17ae 3640 if (zebra_rnh_ipv6_default_route)
3641 vty_out(vty, "ipv6 nht resolve-via-default\n");
6baf7bb8 3642
3a30f50f
DS
3643 if (zebrad.ribq->spec.hold != ZEBRA_RIB_PROCESS_HOLD_TIME)
3644 vty_out(vty, "zebra work-queue %u\n", zebrad.ribq->spec.hold);
3645
62d52ded 3646 if (zebrad.packets_to_process != ZEBRA_ZAPI_PACKETS_TO_PROCESS)
996c9314
LB
3647 vty_out(vty, "zebra zapi-packets %u\n",
3648 zebrad.packets_to_process);
62d52ded 3649
d62a17ae 3650 enum multicast_mode ipv4_multicast_mode = multicast_mode_ipv4_get();
4623d897 3651
d62a17ae 3652 if (ipv4_multicast_mode != MCAST_NO_CONFIG)
3653 vty_out(vty, "ip multicast rpf-lookup-mode %s\n",
3654 ipv4_multicast_mode == MCAST_URIB_ONLY
3655 ? "urib-only"
3656 : ipv4_multicast_mode == MCAST_MRIB_ONLY
3657 ? "mrib-only"
3658 : ipv4_multicast_mode
3659 == MCAST_MIX_MRIB_FIRST
3660 ? "mrib-then-urib"
3661 : ipv4_multicast_mode
3662 == MCAST_MIX_DISTANCE
3663 ? "lower-distance"
3664 : "longer-prefix");
4623d897 3665
d62a17ae 3666 zebra_routemap_config_write_protocol(vty);
6baf7bb8 3667
d62a17ae 3668 return 1;
6baf7bb8
DS
3669}
3670
c0d136ae
DS
3671#ifdef HAVE_NETLINK
3672/* Display default rtm_table for all clients. */
3673DEFUN (show_table,
3674 show_table_cmd,
3675 "show table",
3676 SHOW_STR
3677 "default routing table to use for all clients\n")
3678{
3679 vty_out(vty, "table %d\n", zebrad.rtm_table_default);
3680 return CMD_SUCCESS;
3681}
3682
3683DEFUN (config_table,
3684 config_table_cmd,
3685 "table TABLENO",
3686 "Configure target kernel routing table\n"
3687 "TABLE integer\n")
3688{
3689 zebrad.rtm_table_default = strtol(argv[1]->arg, (char **)0, 10);
3690 return CMD_SUCCESS;
3691}
3692
3693DEFUN (no_config_table,
3694 no_config_table_cmd,
3695 "no table [TABLENO]",
3696 NO_STR
3697 "Configure target kernel routing table\n"
3698 "TABLE integer\n")
3699{
3700 zebrad.rtm_table_default = 0;
3701 return CMD_SUCCESS;
3702}
3703#endif
3704
3705DEFUN (show_zebra,
3706 show_zebra_cmd,
3707 "show zebra",
3708 SHOW_STR
3709 ZEBRA_STR)
3710{
3711 struct vrf *vrf;
3712
3713 vty_out(vty,
3714 " Route Route Neighbor LSP LSP\n");
3715 vty_out(vty,
3716 "VRF Installs Removals Updates Installs Removals\n");
3717
996c9314 3718 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
c0d136ae
DS
3719 struct zebra_vrf *zvrf = vrf->info;
3720
3721 vty_out(vty, "%-25s %10" PRIu64 " %10" PRIu64 " %10" PRIu64
3722 " %10" PRIu64 " %10" PRIu64 "\n",
3723 vrf->name, zvrf->installs, zvrf->removals,
3724 zvrf->neigh_updates, zvrf->lsp_installs,
3725 zvrf->lsp_removals);
3726 }
3727
3728 return CMD_SUCCESS;
3729}
3730
3731DEFUN (ip_forwarding,
3732 ip_forwarding_cmd,
3733 "ip forwarding",
3734 IP_STR
3735 "Turn on IP forwarding\n")
3736{
3737 int ret;
3738
3739 ret = ipforward();
3740 if (ret == 0)
3741 ret = ipforward_on();
3742
3743 if (ret == 0) {
3744 vty_out(vty, "Can't turn on IP forwarding\n");
3745 return CMD_WARNING_CONFIG_FAILED;
3746 }
3747
3748 return CMD_SUCCESS;
3749}
3750
3751DEFUN (no_ip_forwarding,
3752 no_ip_forwarding_cmd,
3753 "no ip forwarding",
3754 NO_STR
3755 IP_STR
3756 "Turn off IP forwarding\n")
3757{
3758 int ret;
3759
3760 ret = ipforward();
3761 if (ret != 0)
3762 ret = ipforward_off();
3763
3764 if (ret != 0) {
3765 vty_out(vty, "Can't turn off IP forwarding\n");
3766 return CMD_WARNING_CONFIG_FAILED;
3767 }
3768
3769 return CMD_SUCCESS;
3770}
3771
3772/* Only display ip forwarding is enabled or not. */
3773DEFUN (show_ip_forwarding,
3774 show_ip_forwarding_cmd,
3775 "show ip forwarding",
3776 SHOW_STR
3777 IP_STR
3778 "IP forwarding status\n")
3779{
3780 int ret;
3781
3782 ret = ipforward();
3783
3784 if (ret == 0)
3785 vty_out(vty, "IP forwarding is off\n");
3786 else
3787 vty_out(vty, "IP forwarding is on\n");
3788 return CMD_SUCCESS;
3789}
3790
3791/* Only display ipv6 forwarding is enabled or not. */
3792DEFUN (show_ipv6_forwarding,
3793 show_ipv6_forwarding_cmd,
3794 "show ipv6 forwarding",
3795 SHOW_STR
3796 "IPv6 information\n"
3797 "Forwarding status\n")
3798{
3799 int ret;
3800
3801 ret = ipforward_ipv6();
3802
3803 switch (ret) {
3804 case -1:
3805 vty_out(vty, "ipv6 forwarding is unknown\n");
3806 break;
3807 case 0:
3808 vty_out(vty, "ipv6 forwarding is %s\n", "off");
3809 break;
3810 case 1:
3811 vty_out(vty, "ipv6 forwarding is %s\n", "on");
3812 break;
3813 default:
3814 vty_out(vty, "ipv6 forwarding is %s\n", "off");
3815 break;
3816 }
3817 return CMD_SUCCESS;
3818}
3819
3820DEFUN (ipv6_forwarding,
3821 ipv6_forwarding_cmd,
3822 "ipv6 forwarding",
3823 IPV6_STR
3824 "Turn on IPv6 forwarding\n")
3825{
3826 int ret;
3827
3828 ret = ipforward_ipv6();
3829 if (ret == 0)
3830 ret = ipforward_ipv6_on();
3831
3832 if (ret == 0) {
3833 vty_out(vty, "Can't turn on IPv6 forwarding\n");
3834 return CMD_WARNING_CONFIG_FAILED;
3835 }
3836
3837 return CMD_SUCCESS;
3838}
3839
3840DEFUN (no_ipv6_forwarding,
3841 no_ipv6_forwarding_cmd,
3842 "no ipv6 forwarding",
3843 NO_STR
3844 IPV6_STR
3845 "Turn off IPv6 forwarding\n")
3846{
3847 int ret;
3848
3849 ret = ipforward_ipv6();
3850 if (ret != 0)
3851 ret = ipforward_ipv6_off();
3852
3853 if (ret != 0) {
3854 vty_out(vty, "Can't turn off IPv6 forwarding\n");
3855 return CMD_WARNING_CONFIG_FAILED;
3856 }
3857
3858 return CMD_SUCCESS;
3859}
3860
3861/* Table configuration write function. */
3862static int config_write_table(struct vty *vty)
3863{
3864 if (zebrad.rtm_table_default)
3865 vty_out(vty, "table %d\n", zebrad.rtm_table_default);
3866 return 0;
3867}
3868
3869/* IPForwarding configuration write function. */
3870static int config_write_forwarding(struct vty *vty)
3871{
3872 /* FIXME: Find better place for that. */
3873 router_id_write(vty);
3874
3875 if (!ipforward())
3876 vty_out(vty, "no ip forwarding\n");
3877 if (!ipforward_ipv6())
3878 vty_out(vty, "no ipv6 forwarding\n");
3879 vty_out(vty, "!\n");
3880 return 0;
3881}
3882
718e3744 3883/* IP node for static routes. */
d62a17ae 3884static struct cmd_node ip_node = {IP_NODE, "", 1};
3885static struct cmd_node protocol_node = {PROTOCOL_NODE, "", 1};
c0d136ae
DS
3886/* table node for routing tables. */
3887static struct cmd_node table_node = {TABLE_NODE,
3888 "", /* This node has no interface. */
3889 1};
3890static struct cmd_node forwarding_node = {FORWARDING_NODE,
3891 "", /* This node has no interface. */
3892 1};
718e3744 3893
3894/* Route VTY. */
d62a17ae 3895void zebra_vty_init(void)
3896{
c0d136ae
DS
3897 /* Install configuration write function. */
3898 install_node(&table_node, config_write_table);
3899 install_node(&forwarding_node, config_write_forwarding);
3900
3901 install_element(VIEW_NODE, &show_ip_forwarding_cmd);
3902 install_element(CONFIG_NODE, &ip_forwarding_cmd);
3903 install_element(CONFIG_NODE, &no_ip_forwarding_cmd);
3904 install_element(ENABLE_NODE, &show_zebra_cmd);
3905
3906#ifdef HAVE_NETLINK
3907 install_element(VIEW_NODE, &show_table_cmd);
3908 install_element(CONFIG_NODE, &config_table_cmd);
3909 install_element(CONFIG_NODE, &no_config_table_cmd);
3910#endif /* HAVE_NETLINK */
3911
3912 install_element(VIEW_NODE, &show_ipv6_forwarding_cmd);
3913 install_element(CONFIG_NODE, &ipv6_forwarding_cmd);
3914 install_element(CONFIG_NODE, &no_ipv6_forwarding_cmd);
3915
3916 /* Route-map */
3917 zebra_route_map_init();
3918
d62a17ae 3919 install_node(&ip_node, zebra_ip_config);
3920 install_node(&protocol_node, config_write_protocol);
3921
3922 install_element(CONFIG_NODE, &allow_external_route_update_cmd);
3923 install_element(CONFIG_NODE, &no_allow_external_route_update_cmd);
3924 install_element(CONFIG_NODE, &ip_mroute_dist_cmd);
d62a17ae 3925 install_element(CONFIG_NODE, &ip_multicast_mode_cmd);
3926 install_element(CONFIG_NODE, &no_ip_multicast_mode_cmd);
00384b5f
PG
3927 install_element(CONFIG_NODE, &ip_route_blackhole_cmd);
3928 install_element(CONFIG_NODE,
3929 &ip_route_address_interface_cmd);
3930 install_element(CONFIG_NODE, &ip_route_cmd);
3931 install_element(VRF_NODE, &ip_route_blackhole_vrf_cmd);
3932 install_element(VRF_NODE, &ip_route_address_interface_vrf_cmd);
3933 install_element(VRF_NODE, &ip_route_vrf_cmd);
b3b08602 3934
d62a17ae 3935 install_element(CONFIG_NODE, &ip_zebra_import_table_distance_cmd);
3936 install_element(CONFIG_NODE, &no_ip_zebra_import_table_cmd);
3a30f50f
DS
3937 install_element(CONFIG_NODE, &zebra_workqueue_timer_cmd);
3938 install_element(CONFIG_NODE, &no_zebra_workqueue_timer_cmd);
62d52ded
DS
3939 install_element(CONFIG_NODE, &zebra_packet_process_cmd);
3940 install_element(CONFIG_NODE, &no_zebra_packet_process_cmd);
d62a17ae 3941
3942 install_element(VIEW_NODE, &show_vrf_cmd);
b7cfce93 3943 install_element(VIEW_NODE, &show_vrf_vni_cmd);
ecffa493 3944 install_element(VIEW_NODE, &show_route_cmd);
ae825b8b 3945 install_element(VIEW_NODE, &show_route_table_cmd);
87d6ac7a
PG
3946 if (vrf_is_backend_netns())
3947 install_element(VIEW_NODE, &show_route_table_vrf_cmd);
5ce91022
RW
3948 install_element(VIEW_NODE, &show_route_detail_cmd);
3949 install_element(VIEW_NODE, &show_route_summary_cmd);
d62a17ae 3950 install_element(VIEW_NODE, &show_ip_nht_cmd);
3951 install_element(VIEW_NODE, &show_ip_nht_vrf_all_cmd);
3952 install_element(VIEW_NODE, &show_ipv6_nht_cmd);
3953 install_element(VIEW_NODE, &show_ipv6_nht_vrf_all_cmd);
d62a17ae 3954
3955 install_element(VIEW_NODE, &show_ip_rpf_cmd);
3956 install_element(VIEW_NODE, &show_ip_rpf_addr_cmd);
3957
00384b5f
PG
3958 install_element(CONFIG_NODE,
3959 &ipv6_route_blackhole_cmd);
3960 install_element(CONFIG_NODE,
3961 &ipv6_route_address_interface_cmd);
3962 install_element(CONFIG_NODE, &ipv6_route_cmd);
3963 install_element(VRF_NODE, &ipv6_route_blackhole_vrf_cmd);
3964 install_element(VRF_NODE,
3965 &ipv6_route_address_interface_vrf_cmd);
3966 install_element(VRF_NODE, &ipv6_route_vrf_cmd);
d62a17ae 3967 install_element(CONFIG_NODE, &ip_nht_default_route_cmd);
3968 install_element(CONFIG_NODE, &no_ip_nht_default_route_cmd);
3969 install_element(CONFIG_NODE, &ipv6_nht_default_route_cmd);
3970 install_element(CONFIG_NODE, &no_ipv6_nht_default_route_cmd);
d62a17ae 3971 install_element(VIEW_NODE, &show_ipv6_mroute_cmd);
3972
3973 /* Commands for VRF */
d62a17ae 3974 install_element(VIEW_NODE, &show_ipv6_mroute_vrf_all_cmd);
3975
4cce389e 3976 install_element(VIEW_NODE, &show_evpn_global_cmd);
d62a17ae 3977 install_element(VIEW_NODE, &show_evpn_vni_cmd);
3978 install_element(VIEW_NODE, &show_evpn_vni_vni_cmd);
4cce389e
MK
3979 install_element(VIEW_NODE, &show_evpn_rmac_vni_mac_cmd);
3980 install_element(VIEW_NODE, &show_evpn_rmac_vni_cmd);
3981 install_element(VIEW_NODE, &show_evpn_rmac_vni_all_cmd);
3982 install_element(VIEW_NODE, &show_evpn_nh_vni_ip_cmd);
3983 install_element(VIEW_NODE, &show_evpn_nh_vni_cmd);
3984 install_element(VIEW_NODE, &show_evpn_nh_vni_all_cmd);
d62a17ae 3985 install_element(VIEW_NODE, &show_evpn_mac_vni_cmd);
3986 install_element(VIEW_NODE, &show_evpn_mac_vni_all_cmd);
3987 install_element(VIEW_NODE, &show_evpn_mac_vni_all_vtep_cmd);
3988 install_element(VIEW_NODE, &show_evpn_mac_vni_mac_cmd);
3989 install_element(VIEW_NODE, &show_evpn_mac_vni_vtep_cmd);
3990 install_element(VIEW_NODE, &show_evpn_neigh_vni_cmd);
3991 install_element(VIEW_NODE, &show_evpn_neigh_vni_all_cmd);
3992 install_element(VIEW_NODE, &show_evpn_neigh_vni_neigh_cmd);
3993 install_element(VIEW_NODE, &show_evpn_neigh_vni_vtep_cmd);
b7cfce93 3994
586f4ccf
PG
3995 install_element(VIEW_NODE, &show_pbr_ipset_cmd);
3996 install_element(VIEW_NODE, &show_pbr_iptable_cmd);
3997
e8d26197
MK
3998 install_element(CONFIG_NODE, &default_vrf_vni_mapping_cmd);
3999 install_element(CONFIG_NODE, &no_default_vrf_vni_mapping_cmd);
b7cfce93
MK
4000 install_element(VRF_NODE, &vrf_vni_mapping_cmd);
4001 install_element(VRF_NODE, &no_vrf_vni_mapping_cmd);
4060008b
DS
4002
4003 static_list = list_new();
4004 static_list->cmp = (int (*)(void *, void *))static_list_compare;
4005 static_list->del = (void (*)(void *))static_list_delete;
718e3744 4006}